static void log_sysinfo(void) { struct rx_meas_stat *meas = &ms->meas; struct gsm48_sysinfo *s = &sysinfo; int8_t rxlev; char ta_str[32] = ""; if (log_si.ta != 0xff) sprintf(ta_str, " TA=%d", log_si.ta); LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n", arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str); LOGFILE("[sysinfo]\n"); LOGFILE("arfcn %d\n", s->arfcn); log_time(); log_gps(); LOGFILE("bsic %d,%d\n", s->bsic >> 3, s->bsic & 7); rxlev = meas->rxlev / meas->frames - 110; LOGFILE("rxlev %d\n", rxlev); if (s->si1) log_frame("si1", s->si1_msg); if (s->si2) log_frame("si2", s->si2_msg); if (s->si2bis) log_frame("si2bis", s->si2b_msg); if (s->si2ter) log_frame("si2ter", s->si2t_msg); if (s->si3) log_frame("si3", s->si3_msg); if (s->si4) log_frame("si4", s->si4_msg); if (log_si.ta != 0xff) LOGFILE("ta %d\n", log_si.ta); LOGFILE("\n"); LOGFLUSH(); }
void kml_meas(FILE *outfp, struct node_meas *meas, int n, uint16_t mcc, uint16_t mnc, uint16_t lac, uint16_t cellid) { struct tm *tm = localtime(&meas->gmt); fprintf(outfp, "\t\t\t\t\t<Placemark>\n"); fprintf(outfp, "\t\t\t\t\t\t<name>%d: %d</name>\n", n, meas->rxlev); fprintf(outfp, "\t\t\t\t\t\t<description>\n"); fprintf(outfp, "MCC=%s MNC=%s\nLAC=%04x CELL-ID=%04x\n(%s %s)\n", gsm_print_mcc(mcc), gsm_print_mnc(mnc), lac, cellid, gsm_get_mcc(mcc), gsm_get_mnc(mcc, mnc)); fprintf(outfp, "\n%s", asctime(tm)); fprintf(outfp, "RX-LEV %d dBm\n", meas->rxlev); if (meas->ta_valid) fprintf(outfp, "TA=%d (%d-%d meter)\n", meas->ta, (int)(GSM_TA_M * meas->ta), (int)(GSM_TA_M * (meas->ta + 1))); fprintf(outfp, "\t\t\t\t\t\t</description>\n"); fprintf(outfp, "\t\t\t\t\t\t<LookAt>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<longitude>%.8f</longitude>\n", meas->longitude); fprintf(outfp, "\t\t\t\t\t\t\t<latitude>%.8f</latitude>\n", meas->latitude); fprintf(outfp, "\t\t\t\t\t\t\t<altitude>0</altitude>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<tilt>0</tilt>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<altitudeMode>relativeToGround" "</altitudeMode>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<gx:altitudeMode>relativeToSeaFloor" "</gx:altitudeMode>\n"); fprintf(outfp, "\t\t\t\t\t\t</LookAt>\n"); fprintf(outfp, "\t\t\t\t\t\t<styleUrl>#msn_placemark_circle" "</styleUrl>\n"); fprintf(outfp, "\t\t\t\t\t\t<Point>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<coordinates>%.8f,%.8f</coordinates>\n", meas->longitude, meas->latitude); fprintf(outfp, "\t\t\t\t\t\t</Point>\n"); fprintf(outfp, "\t\t\t\t\t</Placemark>\n"); }
int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn, void (*print)(void *, const char *, ...), void *priv) { char buffer[81]; int i, j, k; /* available sysinfos */ print(priv, "ARFCN = %d\n", arfcn); print(priv, "Available SYSTEM INFORMATIONS ="); if (s->si1) print(priv, " 1"); if (s->si2) print(priv, " 2"); if (s->si2bis) print(priv, " 2bis"); if (s->si2ter) print(priv, " 2ter"); if (s->si3) print(priv, " 3"); if (s->si4) print(priv, " 4"); if (s->si5) print(priv, " 5"); if (s->si5bis) print(priv, " 5bis"); if (s->si5ter) print(priv, " 5ter"); if (s->si6) print(priv, " 6"); print(priv, "\n"); print(priv, "\n"); /* frequency list */ j = 0; k = 0; for (i = 0; i < 1024; i++) { if ((s->freq[i].mask & FREQ_TYPE_SERV)) { if (!k) { sprintf(buffer, "serv. cell : "); j = strlen(buffer); } if (j >= 75) { buffer[j - 1] = '\0'; print(priv, "%s\n", buffer); sprintf(buffer, " "); j = strlen(buffer); } sprintf(buffer + j, "%d,", i); j = strlen(buffer); k++; } } if (j) { buffer[j - 1] = '\0'; print(priv, "%s\n", buffer); } j = 0; k = 0; for (i = 0; i < 1024; i++) { if ((s->freq[i].mask & FREQ_TYPE_NCELL)) { if (!k) { sprintf(buffer, "SI2 (neigh.): "); j = strlen(buffer); } if (j >= 75) { buffer[j - 1] = '\0'; print(priv, "%s\n", buffer); sprintf(buffer, " "); j = strlen(buffer); } sprintf(buffer + j, "%d,", i); j = strlen(buffer); k++; } } if (j) { buffer[j - 1] = '\0'; print(priv, "%s\n", buffer); } j = 0; k = 0; for (i = 0; i < 1024; i++) { if ((s->freq[i].mask & FREQ_TYPE_REP)) { if (!k) { sprintf(buffer, "SI5 (report): "); j = strlen(buffer); } if (j >= 75) { buffer[j - 1] = '\0'; print(priv, "%s\n", buffer); sprintf(buffer, " "); j = strlen(buffer); } sprintf(buffer + j, "%d,", i); j = strlen(buffer); k++; } } if (j) { buffer[j - 1] = '\0'; print(priv, "%s\n", buffer); } print(priv, "\n"); /* frequency map */ for (i = 0; i < 1024; i += 64) { if (i < 10) sprintf(buffer, " %d ", i); else if (i < 100) sprintf(buffer, " %d ", i); else sprintf(buffer, " %d ", i); for (j = 0; j < 64; j++) { if ((s->freq[i+j].mask & FREQ_TYPE_SERV)) buffer[j + 5] = 'S'; else if ((s->freq[i+j].mask & (FREQ_TYPE_NCELL & FREQ_TYPE_REP))) buffer[j + 5] = 'b'; else if ((s->freq[i+j].mask & FREQ_TYPE_NCELL)) buffer[j + 5] = 'n'; else if ((s->freq[i+j].mask & FREQ_TYPE_REP)) buffer[j + 5] = 'r'; else buffer[j + 5] = '.'; } sprintf(buffer + 69, " %d", i + 63); print(priv, "%s\n", buffer); } print(priv, " 'S' = serv. cell 'n' = SI2 (neigh.) 'r' = SI5 (rep.) " "'b' = SI2+SI5\n\n"); /* serving cell */ print(priv, "Serving Cell:\n"); print(priv, " MCC = %s MNC = %s LAC = 0x%04x Cell ID = 0x%04x " "(%s, %s)\n", gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac, s->cell_id, gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc)); print(priv, " MAX_RETRANS = %d TX_INTEGER = %d re-establish = %s\n", s->max_retrans, s->tx_integer, (s->reest_denied) ? "denied" : "allowed"); print(priv, " Cell barred = %s barred classes =", (s->cell_barr ? "yes" : "no")); for (i = 0; i < 16; i++) { if ((s->class_barr & (1 << i))) print(priv, " C%d", i); } print(priv, "\n"); if (s->sp) print(priv, " CBQ = %d CRO = %d TEMP_OFFSET = %d " "PENALTY_TIME = %d\n", s->sp_cbq, s->sp_cro, s->sp_to, s->sp_pt); print(priv, "\n"); /* neighbor cell */ print(priv, "Neighbor Cell:\n"); print(priv, " MAX_RETRANS = %d TX_INTEGER = %d re-establish = %s\n", s->nb_max_retrans, s->nb_tx_integer, (s->nb_reest_denied) ? "denied" : "allowed"); print(priv, " Cell barred = %s barred classes =", (s->nb_cell_barr ? "yes" : "no")); for (i = 0; i < 16; i++) { if ((s->nb_class_barr & (1 << i))) print(priv, " C%d", i); } print(priv, "\n"); print(priv, "\n"); /* cell selection */ print(priv, "MX_TXPWR_MAX_CCCH = %d CRH = %d RXLEV_MIN = %d " "NECI = %d ACS = %d\n", s->ms_txpwr_max_cch, s->cell_resel_hyst_db, s->rxlev_acc_min_db, s->neci, s->acs); /* bcch options */ print(priv, "BCCH link timeout = %d DTX = %d PWRC = %d\n", s->bcch_radio_link_timeout, s->bcch_dtx, s->bcch_pwrc); /* sacch options */ print(priv, "SACCH link timeout = %d DTX = %d PWRC = %d\n", s->sacch_radio_link_timeout, s->sacch_dtx, s->sacch_pwrc); /* control channel */ switch(s->ccch_conf) { case 0: print(priv, "CCCH Config = 1 CCCH"); break; case 1: print(priv, "CCCH Config = 1 CCCH + SDCCH"); break; case 2: print(priv, "CCCH Config = 2 CCCH"); break; case 4: print(priv, "CCCH Config = 3 CCCH"); break; case 6: print(priv, "CCCH Config = 4 CCCH"); break; default: print(priv, "CCCH Config = reserved"); } print(priv, " BS-PA-MFMS = %d Attachment = %s\n", s->pag_mf_periods, (s->att_allowed) ? "allowed" : "denied"); print(priv, "BS-AG_BLKS_RES = %d\n", s->bs_ag_blks_res); /* channel description */ if (s->h) print(priv, "chan_nr = 0x%02x TSC = %d MAIO = %d HSN = %d\n", s->chan_nr, s->tsc, s->maio, s->hsn); else print(priv, "chan_nr = 0x%02x TSC = %d ARFCN = %d\n", s->chan_nr, s->tsc, s->arfcn); print(priv, "\n"); return 0; }
int main(int argc, char *argv[]) { FILE *infp, *outfp; int type, n, i; char *p; struct node_mcc *mcc; struct node_mnc *mnc; struct node_lac *lac; struct node_cell *cell; struct node_meas *meas; log_init(&log_info, NULL); stderr_target = log_target_create_stderr(); log_add_target(stderr_target); log_set_all_filter(stderr_target, 1); log_parse_category_mask(stderr_target, "Dxxx"); log_set_log_level(stderr_target, LOGL_INFO); if (argc <= 2) { usage: fprintf(stderr, "Usage: %s <file.log> <file.kml> " "[lines] [debug]\n", argv[0]); fprintf(stderr, "lines: Add lines between cell and " "Measurement point\n"); fprintf(stderr, "debug: Add debugging of location algorithm.\n" ); return 0; } for (i = 3; i < argc; i++) { if (!strcmp(argv[i], "lines")) log_lines = 1; else if (!strcmp(argv[i], "debug")) log_debug = 1; else goto usage; } infp = fopen(argv[1], "r"); if (!infp) { fprintf(stderr, "Failed to open '%s' for reading\n", argv[1]); return -EIO; } while ((type = read_log(infp))) { switch (type) { case LOG_TYPE_SYSINFO: add_sysinfo(); break; case LOG_TYPE_POWER: add_power(); break; } } fclose(infp); if (!strcmp(argv[2], "-")) outfp = stdout; else outfp = fopen(argv[2], "w"); if (!outfp) { fprintf(stderr, "Failed to open '%s' for writing\n", argv[2]); return -EIO; } /* document name */ p = argv[2]; while (strchr(p, '/')) p = strchr(p, '/') + 1; kml_header(outfp, p); mcc = node_mcc_first; while (mcc) { printf("MCC: %02x\n", mcc->mcc); /* folder open */ fprintf(outfp, "\t<Folder>\n"); fprintf(outfp, "\t\t<name>MCC %s (%s)</name>\n", gsm_print_mcc(mcc->mcc), gsm_get_mcc(mcc->mcc)); fprintf(outfp, "\t\t<open>0</open>\n"); mnc = mcc->mnc; while (mnc) { printf(" MNC: %02x\n", mnc->mnc); /* folder open */ fprintf(outfp, "\t\t<Folder>\n"); fprintf(outfp, "\t\t\t<name>MNC %s (%s)</name>\n", gsm_print_mnc(mnc->mnc), gsm_get_mnc(mcc->mcc, mnc->mnc)); fprintf(outfp, "\t\t\t<open>0</open>\n"); lac = mnc->lac; while (lac) { printf(" LAC: %04x\n", lac->lac); /* folder open */ fprintf(outfp, "\t\t\t<Folder>\n"); fprintf(outfp, "\t\t\t\t<name>LAC %04x</name>\n", lac->lac); fprintf(outfp, "\t\t\t\t<open>0</open>\n"); cell = lac->cell; while (cell) { printf(" CELL: %04x\n", cell->cellid); fprintf(outfp, "\t\t\t\t<Folder>\n"); fprintf(outfp, "\t\t\t\t\t<name>CELL-ID %04x</name>\n", cell->cellid); fprintf(outfp, "\t\t\t\t\t<open>0</open>\n"); meas = cell->meas; n = 0; while (meas) { if (meas->ta_valid) printf(" TA: %d\n", meas->ta); if (meas->gps_valid) kml_meas(outfp, meas, ++n, mcc->mcc, mnc->mnc, lac->lac, cell->cellid); meas = meas->next; } kml_cell(outfp, cell); /* folder close */ fprintf(outfp, "\t\t\t\t</Folder>\n"); cell = cell->next; } /* folder close */ fprintf(outfp, "\t\t\t</Folder>\n"); lac = lac->next; } /* folder close */ fprintf(outfp, "\t\t</Folder>\n"); mnc = mnc->next; } /* folder close */ fprintf(outfp, "\t</Folder>\n"); mcc = mcc->next; } #if 0 FIXME: power /* folder open */ fprintf(outfp, "\t<Folder>\n"); fprintf(outfp, "\t\t<name>Power</name>\n"); fprintf(outfp, "\t\t<open>0</open>\n"); power = node_power_first; n = 0; while (power) { /* folder open */ fprintf(outfp, "\t\t<Folder>\n"); fprintf(outfp, "\t\t\t<name>Power %d</name>\n", ++n); fprintf(outfp, "\t\t\t<open>0</open>\n"); /* folder close */ fprintf(outfp, "\t\t</Folder>\n"); power = power->next; } /* folder close */ fprintf(outfp, "\t</Folder>\n"); #endif kml_footer(outfp); fclose(outfp); return 0; }
void kml_cell(FILE *outfp, struct node_cell *cell) { struct node_meas *meas; double x, y, z, sum_x = 0, sum_y = 0, sum_z = 0, longitude, latitude; int n, known = 0; meas = cell->meas; n = 0; while (meas) { if (meas->gps_valid && meas->ta_valid) { geo2space(&x, &y, &z, meas->longitude, meas->latitude); sum_x += x; sum_y += y; sum_z += z; n++; } meas = meas->next; } if (!n) return; if (n < 3) { x = sum_x / n; y = sum_y / n; z = sum_z / n; space2geo(&longitude, &latitude, x, y, z); } else { struct probe *probe_first = NULL, *probe, **probe_last_p = &probe_first; double x_scale; /* translate to flat surface */ meas = cell->meas; x_scale = 1.0 / cos(meas->latitude / 180.0 * PI); longitude = meas->longitude; latitude = meas->latitude; debug_x_scale = x_scale; debug_long = longitude; debug_lat = latitude; debug_fp = outfp; while (meas) { if (meas->gps_valid && meas->ta_valid) { probe = calloc(1, sizeof(struct probe)); if (!probe) nomem(); probe->x = (meas->longitude - longitude) / x_scale; if (x < -180) x += 360; else if (x > 180) x -= 360; probe->y = meas->latitude - latitude; probe->dist = GSM_TA_M * (0.5 + (double)meas->ta) / (EQUATOR_RADIUS * PI / 180.0); *probe_last_p = probe; probe_last_p = &probe->next; } meas = meas->next; } /* locate */ locate_cell(probe_first, &x, &y); /* translate from flat surface */ longitude += x * x_scale; if (longitude < 0) longitude += 360; else if (longitude >= 360) longitude -= 360; latitude += y; /* remove probes */ while (probe_first) { probe = probe_first; probe_first = probe->next; free(probe); } known = 1; } if (!known) return; fprintf(outfp, "\t\t\t\t\t<Placemark>\n"); fprintf(outfp, "\t\t\t\t\t\t<name>MCC=%s MNC=%s\nLAC=%04x " "CELL-ID=%04x\n(%s %s)</name>\n", gsm_print_mcc(cell->s.mcc), gsm_print_mnc(cell->s.mnc), cell->s.lac, cell->s.cell_id, gsm_get_mcc(cell->s.mcc), gsm_get_mnc(cell->s.mcc, cell->s.mnc)); fprintf(outfp, "\t\t\t\t\t\t<description>\n"); gsm48_sysinfo_dump(&cell->s, cell->sysinfo.arfcn, print_si, outfp, NULL); fprintf(outfp, "\t\t\t\t\t\t</description>\n"); fprintf(outfp, "\t\t\t\t\t\t<LookAt>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<longitude>%.8f</longitude>\n", longitude); fprintf(outfp, "\t\t\t\t\t\t\t<latitude>%.8f</latitude>\n", latitude); fprintf(outfp, "\t\t\t\t\t\t\t<altitude>0</altitude>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<tilt>0</tilt>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<altitudeMode>relativeToGround" "</altitudeMode>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<gx:altitudeMode>relativeToSeaFloor" "</gx:altitudeMode>\n"); fprintf(outfp, "\t\t\t\t\t\t</LookAt>\n"); if (known) fprintf(outfp, "\t\t\t\t\t\t<styleUrl>#msn_placemark_grn_" "pushpin</styleUrl>\n"); else fprintf(outfp, "\t\t\t\t\t\t<styleUrl>#msn_placemark_red_" "pushpin</styleUrl>\n"); fprintf(outfp, "\t\t\t\t\t\t<Point>\n"); fprintf(outfp, "\t\t\t\t\t\t\t<coordinates>%.8f,%.8f</coordinates>\n", longitude, latitude); fprintf(outfp, "\t\t\t\t\t\t</Point>\n"); fprintf(outfp, "\t\t\t\t\t</Placemark>\n"); if (!log_lines) return; fprintf(outfp, "\t<Folder>\n"); fprintf(outfp, "\t\t<name>Lines</name>\n"); fprintf(outfp, "\t\t<open>0</open>\n"); fprintf(outfp, "\t\t<visibility>0</visibility>\n"); geo2space(&x, &y, &z, longitude, latitude); meas = cell->meas; n = 0; while (meas) { if (meas->gps_valid) { double mx, my, mz, dist; geo2space(&mx, &my, &mz, meas->longitude, meas->latitude); dist = distinspace(x, y, z, mx, my, mz); fprintf(outfp, "\t\t<Placemark>\n"); fprintf(outfp, "\t\t\t<name>Range</name>\n"); fprintf(outfp, "\t\t\t<description>\n"); fprintf(outfp, "Distance: %d\n", (int)dist); fprintf(outfp, "TA=%d (%d-%d meter)\n", meas->ta, (int)(GSM_TA_M * meas->ta), (int)(GSM_TA_M * (meas->ta + 1))); fprintf(outfp, "\t\t\t</description>\n"); fprintf(outfp, "\t\t\t<visibility>0</visibility>\n"); fprintf(outfp, "\t\t\t<LineString>\n"); fprintf(outfp, "\t\t\t\t<tessellate>1</tessellate>\n"); fprintf(outfp, "\t\t\t\t<coordinates>\n"); fprintf(outfp, "%.8f,%.8f\n", longitude, latitude); fprintf(outfp, "%.8f,%.8f\n", meas->longitude, meas->latitude); fprintf(outfp, "\t\t\t\t</coordinates>\n"); fprintf(outfp, "\t\t\t</LineString>\n"); fprintf(outfp, "\t\t</Placemark>\n"); } meas = meas->next; } fprintf(outfp, "\t</Folder>\n"); }