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