blob: 71d046d7a9ff7cc797f8e2c7ee5831c7339addc9 [file] [log] [blame]
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +02001#include "framing.h"
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +02002#include "protocol.h"
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +02003#include "serial.h"
4
5#include <stdlib.h>
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +02006#include <stddef.h>
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +02007#include <stdio.h>
8#include <string.h>
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +02009#include <time.h>
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +020010
11#include <sys/stat.h>
12#include <fcntl.h>
13#include <unistd.h>
14#include <errno.h>
15
16char *DumpBYTEs(unsigned char *p, long n, int nBytesPerRow /* = 16 */, char *szLineSep /* = "\n" */, int bRaw /* = FALSE */, const char *szIndent /* = "" */)
17{
18 long i;
19 char szBuf[20];
20 static char szRes[4 * 1024];
21
22 szRes[0] = 0;
23
24 if(n == 0)
25 return szRes;
26
27 memset(szBuf, 0, sizeof(szBuf));
28 for(i = 0; i < n; i++)
29 {
30 if(i % nBytesPerRow == 0)
31 {
32 strcat(szRes, szIndent);
33 if(!bRaw)
34 sprintf(szRes + strlen(szRes), "%04d : ", i);
35 }
36
37 sprintf(szRes + strlen(szRes), "%02X ", p[i]);
38 szBuf[i % nBytesPerRow] = (char)((p[i] < 128 && p[i] >= ' ') ? p[i] : '.');
39
40 if((i + 1) % nBytesPerRow == 0)
41 {
42 if(bRaw)
43 sprintf(szRes + strlen(szRes), "%s", szLineSep);
44 else
45 sprintf(szRes + strlen(szRes), " %s%s", szBuf, szLineSep);
46 memset(szBuf, 0, sizeof(szBuf));
47 }
48 }
49
50 if(i % nBytesPerRow != 0)
51 {
52 if(bRaw)
53 sprintf(szRes + strlen(szRes), "%s", szLineSep);
54 else
55 {
56 n = nBytesPerRow - i % nBytesPerRow;
57 for(i = 0; i < n ; i++)
58 sprintf(szRes + strlen(szRes), " ");
59 sprintf(szRes + strlen(szRes), " %s%s", szBuf, szLineSep);
60 }
61 }
62
63 return szRes;
64}
65
66static int transmit_packet(int fd, const uint8_t *data, size_t data_len)
67{
68 int out_len, rc;
69 uint8_t packet[MAX_PACKET * 2];
70
71 out_len = frame_pack(data, data_len, packet, sizeof(packet));
72 if (out_len < 0) {
73 printf("Failed to pack packet\n");
74 return -1;
75 }
76
77 rc = write(fd, packet, out_len);
78 if (rc != out_len) {
79 printf("Short write on packet.\n");
80 return -1;
81 }
82
83 return 0;
84}
85
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +020086static int dump_log(const uint8_t *data, const size_t len)
87{
88 size_t i, file_len;
89 size_t params = 0;
90 const struct ext_log_msg *msg;
91 const char *file = NULL, *log;
92 struct tm *tm;
93 time_t now;
94 const size_t str_len = len - offsetof(struct ext_log_msg, data);
95
96 time(&now);
97 tm = localtime(&now);
98
99 if (len < sizeof(struct ext_log_msg)) {
100 printf("too short log message.\n");
101 return -1;
102 }
103
104 msg = (struct ext_log_msg *) data;
105 log = (const char *) msg->data;
106
107 /*
108 * Check if it is null terminated and how many parameters it
109 * might have. This counts all '%' but doesn't take '%%' into
110 * account.
111 */
112 for (i = 0; i < str_len; ++i) {
113 if (log[i] == '%')
114 params += 1;
115 else if (log[i] == '\0' && i + 1 < str_len) {
116 file = &log[i + 1];
117 file_len = str_len - i - 1;
118 break;
119 }
120 }
121
122 if (file_len == 0 || file[file_len - 1] != '\0') {
123 printf("File too short or not null terminated\n");
124 return -2;
125 }
126
127 if (params > 3) {
128 printf("Too many parameters in the log message.\n");
129 return -1;
130 }
131
132 if (!file) {
133 printf("The file is not present..\n");
134 return -2;
135 }
136
137 printf("%d:%d:%d %-20s: ",
138 tm->tm_hour, tm->tm_min, tm->tm_sec,
139 file);
140 printf(log, msg->params[0], msg->params[1], msg->params[2]);
141 printf("\n");
142 return 0;
143}
144
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +0200145static int do_read(int fd, uint8_t *data)
146{
147 uint8_t buf[MAX_PACKET];
148 int rc;
149
150 rc = read(fd, buf, sizeof(buf));
151 if (rc <= 0 ) {
152 printf("Short read!\n");
153 exit(EXIT_FAILURE);
154 }
155
156 rc = frame_unpack(buf, rc, data);
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +0200157 if (rc <= 0)
158 return 0;
159
160
161 switch (data[0]) {
162 case 0x79:
163 dump_log(data, rc);
164 break;
165 default:
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +0200166 printf("Got %d data of payload\n", rc);
167 printf("%s\n", DumpBYTEs(data, rc, 16, "\n", 0, ""));
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +0200168 break;
169 };
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +0200170
171 return rc;
172}
173
174static void do_configure(int fd)
175{
176 static uint8_t timestamp[] = { 0x1D };
177 static uint8_t enable_logging[] = {
178 0x73, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
179 0x05, 0x00, 0x00, 0x00, 0x28, 0x04, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00
197 };
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +0200198#if 0
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +0200199 static const uint8_t enable_evt_report[] = {
200 0x60, 0x01
201 };
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +0200202#endif
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +0200203 static const uint8_t disable_evt_report[] = {
204 0x60, 0x00
205 };
206 static const uint8_t extended_report_cfg[] = {
207 0x7D, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x02, 0x00, 0x00, 0x00,
209 };
210
211 uint8_t data[MAX_PACKET];
212
213 /* TODO: introduce a wait for response kind of method */
214 transmit_packet(fd, timestamp, sizeof(timestamp));
215 do_read(fd, data);
216
Holger Hans Peter Freyther93b625b2013-05-31 09:52:26 +0200217 /* enable|disable the event report */
218#if 0
219 transmit_packet(fd, enable_evt_report, sizeof(enable_evt_report));
220 do_read(fd, data);
221#endif
Holger Hans Peter Freytherae73a052013-05-31 09:51:53 +0200222 transmit_packet(fd, disable_evt_report, sizeof(disable_evt_report));
223 do_read(fd, data);
224
225 transmit_packet(fd, extended_report_cfg, sizeof(extended_report_cfg));
226 do_read(fd, data);
227
228 /* enable the logging */
229 transmit_packet(fd, enable_logging, sizeof(enable_logging));
230 do_read(fd, data);
231}
232
233int main(int argc, char **argv)
234{
235 uint8_t data[MAX_PACKET];
236 int flags;
237
238 int fd, rc;
239 if (argc < 2) {
240 printf("Invoke with %s PATH_TO_SERIAL\n",
241 argv[0]);
242 return EXIT_FAILURE;
243 }
244
245 /* Use nonblock as the device might block otherwise */
246 fd = open(argv[1], O_RDWR | O_NOCTTY | O_SYNC | O_NONBLOCK);
247 if (fd < 0) {
248 printf("Opening the serial failed: %d/%s\n",
249 errno, strerror(errno));
250 return EXIT_FAILURE;
251 }
252
253 flags = fcntl(fd, F_GETFL, 0);
254 if (flags < 0) {
255 printf("Failed to get the flags.\n");
256 return EXIT_FAILURE;
257 }
258
259 flags &= ~O_NONBLOCK;
260 rc = fcntl(fd, F_SETFL, flags);
261 if (rc != 0) {
262 printf("Failed to set the flags.\n");
263 return EXIT_FAILURE;
264 }
265
266 rc = serial_configure(fd);
267 if (rc != 0)
268 return EXIT_FAILURE;
269
270 do_configure(fd);
271
272 while (1)
273 do_read(fd, data);
274}