static gint parse_key_end(gpointer ptr) { read_ctx_t *ctx = (read_ctx_t*)ptr; if(ctx->level == LEVEL_NETWORK+1 && ctx->level_signals == TRUE) { /* Assume that all signal samples are sorted by timestamp */ if(ctx->signal && ctx->signal->timestamp && ctx->network.signals) { signals_append(ctx->network.signals, ctx->signal); } else g_free(ctx->signal); ctx->signal = NULL; } else if(ctx->level == LEVEL_NETWORK) { if(ctx->network.address) { mtscan_model_add(ui.model, &ctx->network, ctx->merge); ctx->changed = TRUE; } network_free_null(&ctx->network); } ctx->level--; return 1; }
gint model_update_network(mtscan_model_t *model, network_t *net) { GtkTreeIter *iter_ptr; GtkTreeIter iter; gint64 *address; gchar *current_ssid; gchar *current_radioname; gint8 current_maxrssi; guint8 current_state; gboolean new_network_found; gfloat distance = NAN; if(g_hash_table_lookup_extended(model->map, &net->address, (gpointer*)&address, (gpointer*)&iter_ptr)) { /* Update a network, check current values first */ gtk_tree_model_get(GTK_TREE_MODEL(model->store), iter_ptr, COL_STATE, ¤t_state, COL_SSID, ¤t_ssid, COL_RADIONAME, ¤t_radioname, COL_MAXRSSI, ¤t_maxrssi, COL_SIGNALS, &net->signals, -1); /* Update state to active (keep MODEL_STATE_NEW untouched) */ if(current_state == MODEL_STATE_INACTIVE) current_state = MODEL_STATE_ACTIVE; /* Preserve hidden SSIDs */ if((net->ssid && !net->ssid[0]) || !net->ssid) { g_free(net->ssid); net->ssid = current_ssid; } else { g_free(current_ssid); } /* ... and Radio Names */ if((net->radioname && !net->radioname[0]) || !net->radioname) { g_free(net->radioname); net->radioname = current_radioname; } else { g_free(current_radioname); } #if MIKROTIK_LOW_SIGNAL_BUGFIX if(net->rssi >= -12 && net->rssi <= -10 && current_maxrssi <= -15) net->rssi = current_maxrssi; #endif #if MIKROTIK_HIGH_SIGNAL_BUGFIX if(net->rssi >= 10) net->rssi = current_maxrssi; #endif if(conf_get_preferences_signals()) signals_append(net->signals, signals_node_new(net->firstseen, net->rssi, net->latitude, net->longitude, net->azimuth)); /* At new signal peak, update additionally COL_MAXRSSI, COL_LATITUDE, COL_LONGITUDE, COL_AZIMUTH and COL_DISTANCE */ if(net->rssi > current_maxrssi) { if(conf_get_interface_geoloc()) geoloc_match(net->address, net->ssid, net->azimuth, FALSE, &distance); gtk_list_store_set(model->store, iter_ptr, COL_STATE, current_state, COL_FREQUENCY, net->frequency, COL_CHANNEL, (net->channel ? net->channel : ""), COL_STREAMS, net->streams, COL_MODE, (net->mode ? net->mode : ""), COL_SSID, (net->ssid ? net->ssid : ""), COL_RADIONAME, (net->radioname ? net->radioname : ""), COL_MAXRSSI, net->rssi, COL_RSSI, net->rssi, COL_NOISE, net->noise, COL_PRIVACY, net->flags.privacy, COL_ROUTEROS, net->flags.routeros, COL_NSTREME, net->flags.nstreme, COL_TDMA, net->flags.tdma, COL_WDS, net->flags.wds, COL_BRIDGE, net->flags.bridge, COL_ROUTEROS_VER, (net->routeros_ver ? net->routeros_ver : ""), COL_AIRMAX, net->ubnt_airmax, COL_AIRMAX_AC_PTP, net->ubnt_ptp, COL_AIRMAX_AC_PTMP, net->ubnt_ptmp, COL_AIRMAX_AC_MIXED, net->ubnt_mixed, COL_LASTLOG, net->firstseen, COL_LATITUDE, net->latitude, COL_LONGITUDE, net->longitude, COL_AZIMUTH, net->azimuth, COL_DISTANCE, distance, -1); } else { gtk_list_store_set(model->store, iter_ptr, COL_STATE, current_state, COL_FREQUENCY, net->frequency, COL_CHANNEL, (net->channel ? net->channel : ""), COL_STREAMS, net->streams, COL_MODE, (net->mode ? net->mode : ""), COL_SSID, (net->ssid ? net->ssid : ""), COL_RADIONAME, (net->radioname ? net->radioname : ""), COL_RSSI, net->rssi, COL_NOISE, net->noise, COL_PRIVACY, net->flags.privacy, COL_ROUTEROS, net->flags.routeros, COL_NSTREME, net->flags.nstreme, COL_TDMA, net->flags.tdma, COL_WDS, net->flags.wds, COL_BRIDGE, net->flags.bridge, COL_ROUTEROS_VER, (net->routeros_ver ? net->routeros_ver : ""), COL_AIRMAX, net->ubnt_airmax, COL_AIRMAX_AC_PTP, net->ubnt_ptp, COL_AIRMAX_AC_PTMP, net->ubnt_ptmp, COL_AIRMAX_AC_MIXED, net->ubnt_mixed, COL_LASTLOG, net->firstseen, -1); } /* Add address to the active network list */ g_hash_table_insert(model->active, address, iter_ptr); new_network_found = MODEL_NETWORK_UPDATE; } else { /* Add a new network */ if(conf_get_interface_geoloc()) geoloc_match(net->address, net->ssid, net->azimuth, conf_get_preferences_location_wigle(), &distance); net->signals = signals_new(); if(conf_get_preferences_signals()) signals_append(net->signals, signals_node_new(net->firstseen, net->rssi, net->latitude, net->longitude, net->azimuth)); gtk_list_store_insert_with_values(model->store, &iter, -1, COL_STATE, MODEL_STATE_NEW, COL_ADDRESS, net->address, COL_FREQUENCY, net->frequency, COL_CHANNEL, (net->channel ? net->channel : ""), COL_STREAMS, net->streams, COL_MODE, (net->mode ? net->mode : ""), COL_SSID, (net->ssid ? net->ssid : ""), COL_RADIONAME, (net->radioname ? net->radioname : ""), COL_MAXRSSI, net->rssi, COL_RSSI, net->rssi, COL_NOISE, net->noise, COL_PRIVACY, net->flags.privacy, COL_ROUTEROS, net->flags.routeros, COL_NSTREME, net->flags.nstreme, COL_TDMA, net->flags.tdma, COL_WDS, net->flags.wds, COL_BRIDGE, net->flags.bridge, COL_ROUTEROS_VER, (net->routeros_ver ? net->routeros_ver : ""), COL_AIRMAX, net->ubnt_airmax, COL_AIRMAX_AC_PTP, net->ubnt_ptp, COL_AIRMAX_AC_PTMP, net->ubnt_ptmp, COL_AIRMAX_AC_MIXED, net->ubnt_mixed, COL_FIRSTLOG, net->firstseen, COL_LASTLOG, net->firstseen, COL_LATITUDE, net->latitude, COL_LONGITUDE, net->longitude, COL_AZIMUTH, net->azimuth, COL_DISTANCE, distance, COL_SIGNALS, net->signals, -1); iter_ptr = gtk_tree_iter_copy(&iter); address = gint64dup(&net->address); g_hash_table_insert(model->map, address, iter_ptr); g_hash_table_insert(model->active, address, iter_ptr); if(conf_get_preferences_alarmlist_enabled() && conf_get_preferences_alarmlist(*address)) { new_network_found = MODEL_NETWORK_NEW_ALARM; if(conf_get_preferences_events_new_network()) mtscan_exec(conf_get_preferences_events_new_network_exec(), 2, model_format_address(*address, FALSE), "ALARM"); } else if(conf_get_preferences_highlightlist_enabled() && conf_get_preferences_highlightlist(*address)) { new_network_found = MODEL_NETWORK_NEW_HIGHLIGHT; if(conf_get_preferences_events_new_network()) mtscan_exec(conf_get_preferences_events_new_network_exec(), 2, model_format_address(*address, FALSE), "HIGHLIGHT"); } else { new_network_found = MODEL_NETWORK_NEW; if(conf_get_preferences_events_new_network()) mtscan_exec(conf_get_preferences_events_new_network_exec(), 2, model_format_address(*address, FALSE), "NORMAL"); } } /* Signals are stored in GtkListStore just as pointer, so set it to NULL before freeing the struct */ net->signals = NULL; return new_network_found; }