treewide: remove FSF address
[osmocom-bb.git] / src / host / gsmmap / log.c
blob97bef49275d0ba950f9ed46bc90ceba69b17d8b7
1 /* Conversion of logged cells to KML file */
3 /* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
5 * All Rights Reserved
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
19 #include <stdio.h>
20 #include <stdlib.h>
22 #include <osmocom/bb/common/osmocom_data.h>
24 #include "log.h"
26 extern struct power power;
27 extern struct sysinfo sysinfo;
28 extern struct node_power *node_power_first;
29 extern struct node_power **node_power_last_p;
30 extern struct node_mcc *node_mcc_first;
32 struct node_mcc *get_node_mcc(uint16_t mcc)
34 struct node_mcc *node_mcc;
35 struct node_mcc **node_mcc_p = &node_mcc_first;
37 //printf("add mcc %d\n", mcc);
38 while (*node_mcc_p) {
39 /* found in list */
40 if ((*node_mcc_p)->mcc == mcc)
41 return *node_mcc_p;
42 /* insert into list */
43 if ((*node_mcc_p)->mcc > mcc)
44 break;
45 node_mcc_p = &((*node_mcc_p)->next);
48 //printf("new mcc %d\n", mcc);
49 /* append or insert to list */
50 node_mcc = calloc(1, sizeof(struct node_mcc));
51 if (!node_mcc)
52 return NULL;
53 node_mcc->mcc = mcc;
54 node_mcc->next = *node_mcc_p;
55 *node_mcc_p = node_mcc;
56 return node_mcc;
59 struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc)
61 struct node_mnc *node_mnc;
62 struct node_mnc **node_mnc_p = &mcc->mnc;
64 while (*node_mnc_p) {
65 /* found in list */
66 if ((*node_mnc_p)->mnc == mnc)
67 return *node_mnc_p;
68 /* insert into list */
69 if ((*node_mnc_p)->mnc > mnc)
70 break;
71 node_mnc_p = &((*node_mnc_p)->next);
74 /* append or insert to list */
75 node_mnc = calloc(1, sizeof(struct node_mnc));
76 if (!node_mnc)
77 return NULL;
78 node_mnc->mnc = mnc;
79 node_mnc->next = *node_mnc_p;
80 *node_mnc_p = node_mnc;
81 return node_mnc;
84 struct node_lac *get_node_lac(struct node_mnc *mnc, uint16_t lac)
86 struct node_lac *node_lac;
87 struct node_lac **node_lac_p = &mnc->lac;
89 while (*node_lac_p) {
90 /* found in list */
91 if ((*node_lac_p)->lac == lac)
92 return *node_lac_p;
93 /* insert into list */
94 if ((*node_lac_p)->lac > lac)
95 break;
96 node_lac_p = &((*node_lac_p)->next);
99 /* append or insert to list */
100 node_lac = calloc(1, sizeof(struct node_lac));
101 if (!node_lac)
102 return NULL;
103 node_lac->lac = lac;
104 node_lac->next = *node_lac_p;
105 *node_lac_p = node_lac;
106 return node_lac;
109 struct node_cell *get_node_cell(struct node_lac *lac, uint16_t cellid)
111 struct node_cell *node_cell;
112 struct node_cell **node_cell_p = &lac->cell;
114 while (*node_cell_p) {
115 /* found in list */
116 if ((*node_cell_p)->cellid == cellid)
117 return *node_cell_p;
118 /* insert into list */
119 if ((*node_cell_p)->cellid > cellid)
120 break;
121 node_cell_p = &((*node_cell_p)->next);
124 /* append or insert to list */
125 node_cell = calloc(1, sizeof(struct node_cell));
126 if (!node_cell)
127 return NULL;
128 node_cell->meas_last_p = &node_cell->meas;
129 node_cell->cellid = cellid;
130 node_cell->next = *node_cell_p;
131 *node_cell_p = node_cell;
132 return node_cell;
135 struct node_meas *add_node_meas(struct node_cell *cell)
137 struct node_meas *node_meas;
139 /* append to list */
140 node_meas = calloc(1, sizeof(struct node_meas));
141 if (!node_meas)
142 return NULL;
143 node_meas->gmt = sysinfo.gmt;
144 node_meas->rxlev = sysinfo.rxlev;
145 if (sysinfo.ta_valid) {
146 node_meas->ta_valid = 1;
147 node_meas->ta = sysinfo.ta;
149 if (sysinfo.gps_valid) {
150 node_meas->gps_valid = 1;
151 node_meas->longitude = sysinfo.longitude;
152 node_meas->latitude = sysinfo.latitude;
154 *cell->meas_last_p = node_meas;
155 cell->meas_last_p = &node_meas->next;
156 return node_meas;
159 /* read "<ncc>,<bcc>" */
160 static void read_log_bsic(char *buffer)
162 char *p;
163 uint8_t bsic;
165 /* skip first spaces */
166 while (*buffer == ' ')
167 buffer++;
169 /* read ncc */
170 p = buffer;
171 while (*p > ' ' && *p != ',')
172 p++;
173 if (*p == '\0')
174 return; /* no value */
175 *p++ = '\0';
176 bsic = atoi(buffer) << 3;
177 buffer = p;
179 /* read latitude */
180 bsic |= atoi(buffer);
182 sysinfo.bsic = bsic;
185 /* read "<longitude> <latitude>" */
186 static void read_log_pos(char *buffer, double *longitude, double *latitude,
187 uint8_t *valid)
189 char *p;
191 /* skip first spaces */
192 while (*buffer == ' ')
193 buffer++;
195 /* read longitude */
196 p = buffer;
197 while (*p > ' ')
198 p++;
199 if (*p == '\0')
200 return; /* no value after longitude */
201 *p++ = '\0';
202 *longitude = atof(buffer);
203 buffer = p;
205 /* skip second spaces */
206 while (*buffer == ' ')
207 buffer++;
209 /* read latitude */
210 *latitude = atof(buffer);
212 *valid = 1;
215 /* read "<arfcn> <value> <next value> ...." */
216 static void read_log_power(char *buffer)
218 char *p;
219 int arfcn;
221 /* skip first spaces */
222 while (*buffer == ' ')
223 buffer++;
225 /* read arfcn */
226 p = buffer;
227 while (*p > ' ')
228 p++;
229 if (*p == '\0')
230 return; /* no value after arfcn */
231 *p++ = '\0';
232 arfcn = atoi(buffer);
233 buffer = p;
235 while (*buffer) {
236 /* wrong arfcn */
237 if (arfcn < 0 || arfcn > 1023)
238 break;
239 /* skip spaces */
240 while (*buffer == ' ')
241 buffer++;
242 /* get value */
243 p = buffer;
244 while (*p > ' ')
245 p++;
246 /* last value */
247 if (*p == '\0') {
248 power.rxlev[arfcn] = atoi(buffer);
249 break;
251 *p++ = '\0';
252 power.rxlev[arfcn] = atoi(buffer);
253 arfcn++;
254 buffer = p;
258 /* read "xx xx xx xx xx...." */
259 static void read_log_si(char *buffer, uint8_t *data)
261 uint8_t si[23];
262 int i;
264 // printf("%s ", buffer);
265 for (i = 0; i < 23; i++) {
266 while (*buffer == ' ')
267 buffer++;
268 if (*buffer >= '0' && *buffer <= '9')
269 si[i] = (*buffer - '0') << 4;
270 else if (*buffer >= 'a' && *buffer <= 'f')
271 si[i] = (*buffer - 'a' + 10) << 4;
272 else if (*buffer >= 'A' && *buffer <= 'F')
273 si[i] = (*buffer - 'A' + 10) << 4;
274 else
275 break;
276 buffer++;
277 if (*buffer >= '0' && *buffer <= '9')
278 si[i] += *buffer - '0';
279 else if (*buffer >= 'a' && *buffer <= 'f')
280 si[i] += *buffer - 'a' + 10;
281 else if (*buffer >= 'A' && *buffer <= 'F')
282 si[i] += *buffer - 'A' + 10;
283 else
284 break;
285 buffer++;
286 // printf("%02x ", si[i]);
288 // printf("\n");
290 if (i == 23)
291 memcpy(data, si, 23);
294 /* read next record from log file */
295 int read_log(FILE *infp)
297 static int type = LOG_TYPE_NONE, ret;
298 char buffer[256];
300 memset(&sysinfo, 0, sizeof(sysinfo));
301 memset(&power, 0, sizeof(power));
302 memset(&power.rxlev, -128, sizeof(power.rxlev));
304 if (feof(infp))
305 return LOG_TYPE_NONE;
307 while (fgets(buffer, sizeof(buffer), infp)) {
308 buffer[sizeof(buffer) - 1] = 0;
309 if (buffer[0])
310 buffer[strlen(buffer) - 1] = '\0';
311 if (buffer[0] == '[') {
312 if (!strcmp(buffer, "[sysinfo]")) {
313 ret = type;
314 type = LOG_TYPE_SYSINFO;
315 if (ret != LOG_TYPE_NONE)
316 return ret;
317 } else
318 if (!strcmp(buffer, "[power]")) {
319 ret = type;
320 type = LOG_TYPE_POWER;
321 if (ret != LOG_TYPE_NONE)
322 return ret;
323 } else {
324 type = LOG_TYPE_NONE;
326 continue;
328 switch (type) {
329 case LOG_TYPE_SYSINFO:
330 if (!strncmp(buffer, "arfcn ", 6))
331 sysinfo.arfcn = atoi(buffer + 6);
332 else if (!strncmp(buffer, "si1 ", 4))
333 read_log_si(buffer + 4, sysinfo.si1);
334 else if (!strncmp(buffer, "si2 ", 4))
335 read_log_si(buffer + 4, sysinfo.si2);
336 else if (!strncmp(buffer, "si2bis ", 7))
337 read_log_si(buffer + 7, sysinfo.si2bis);
338 else if (!strncmp(buffer, "si2ter ", 7))
339 read_log_si(buffer + 7, sysinfo.si2ter);
340 else if (!strncmp(buffer, "si3 ", 4))
341 read_log_si(buffer + 4, sysinfo.si3);
342 else if (!strncmp(buffer, "si4 ", 4))
343 read_log_si(buffer + 4, sysinfo.si4);
344 else if (!strncmp(buffer, "time ", 5))
345 sysinfo.gmt = strtoul(buffer + 5, NULL, 0);
346 else if (!strncmp(buffer, "position ", 9))
347 read_log_pos(buffer + 9, &sysinfo.longitude,
348 &sysinfo.latitude, &sysinfo.gps_valid);
349 else if (!strncmp(buffer, "rxlev ", 5))
350 sysinfo.rxlev =
351 strtoul(buffer + 5, NULL, 0);
352 else if (!strncmp(buffer, "bsic ", 5))
353 read_log_bsic(buffer + 5);
354 else if (!strncmp(buffer, "ta ", 3)) {
355 sysinfo.ta_valid = 1;
356 sysinfo.ta = atoi(buffer + 3);
358 break;
359 case LOG_TYPE_POWER:
360 if (!strncmp(buffer, "arfcn ", 6))
361 read_log_power(buffer + 6);
362 else if (!strncmp(buffer, "time ", 5))
363 power.gmt = strtoul(buffer + 5, NULL, 0);
364 else if (!strncmp(buffer, "position ", 9))
365 read_log_pos(buffer + 9, &power.longitude,
366 &power.latitude, &sysinfo.gps_valid);
367 break;
371 return type;