static int32_t topology_status_creator(struct status_handl *handl, void *data) { struct avl_node *it = NULL; struct orig_node *on; uint32_t stsize = 0; uint32_t i = 0; struct topology_status *status = NULL; while (data ? (on = data) : (on = avl_iterate_item(&orig_tree, &it))) { topology_msgs = 0; topology_msg = NULL; uint32_t m = 0; process_description_tlvs(NULL, on, on->desc, TLV_OP_CUSTOM_TOPOLOGY, BMX_DSC_TLV_TOPOLOGY, NULL, NULL); for (m=0; topology_msg && m < topology_msgs; m++) { struct orig_node *non; struct avl_node *nan = NULL; while ((non = avl_iterate_item(&orig_tree, &nan)) && memcmp(&non->global_id.pkid, &topology_msg[m].pkid, sizeof(PKID_T))); if (non) { stsize += sizeof(struct topology_status); status = ((struct topology_status*) (handl->data = debugRealloc(handl->data, stsize, -300366))); memset(&status[i], 0, sizeof(struct topology_status)); status[i].name = on->global_id.name; status[i].id = &on->global_id; status[i].primaryIp = on->primary_ip; status[i].blocked = on->blocked || non->blocked; status[i].lastDesc = (bmx_time - on->updated_timestamp) / 1000; status[i].txBw = fmetric_u8_to_umetric(topology_msg[m].txBw); status[i].rxBw = fmetric_u8_to_umetric(topology_msg[m].rxBw); status[i].txRate = topology_msg[m].txRate; status[i].rxRate = topology_msg[m].rxRate; status[i].neighName = non->global_id.name; status[i].neighId = &non->global_id; status[i].neighIp = non->primary_ip; i++; } } if(data) break; } return stsize; }
STATIC_FUNC int create_description_sms(struct tx_frame_iterator *it) { struct avl_node *an = NULL; struct json_sms *sms; uint8_t *data = tx_iterator_cache_msg_ptr(it); uint16_t max_size = tx_iterator_cache_data_space_max(it); int pos = 0; while ((sms = avl_iterate_item(&json_sms_tree, &an))) { if (pos + sizeof (struct description_msg_sms) + sms->text_len > max_size) { dbgf_sys(DBGT_ERR, "Failed adding descriptionSms=%s/%s", smsTx_dir, sms->name); continue; } struct description_msg_sms *msg = (struct description_msg_sms*) (data + pos); memset(msg, 0, sizeof (struct description_msg_sms)); strcpy(msg->name, sms->name); msg->text_len = htons(sms->text_len); memcpy(msg->text, sms->text, sms->text_len); pos += (sizeof (struct description_msg_sms) + sms->text_len); dbgf_track(DBGT_INFO, "added descriptionSms=%s/%s text_len=%d total_len=%d", smsTx_dir, sms->name, sms->text_len, pos); } return pos; }
STATIC_FUNC void check_local_topology_cache(void *nothing) { assertion(-500000, (my_topology_period < MAX_TOPOLOGY_PERIOD)); struct avl_node *local_it; struct local_node *local; uint32_t m = 0; for (local_it = NULL; (local = avl_iterate_item(&local_tree, &local_it));) { if (local->neigh && local->neigh->dhn->on && local->best_tp_lndev) { struct local_topology_node *ltn = avl_find_item(&local_topology_tree, &local->neigh->dhn->on->global_id.pkid); struct local_topology_node tmp; if (!ltn) { my_description_changed = YES; return; } set_local_topology_node(&tmp, local); if ( (bmx_time - self->updated_timestamp) > ((uint32_t)my_topology_period * 10) && ( check_value_deviation(ltn->txBw, tmp.txBw, 0) || check_value_deviation(ltn->rxBw, tmp.rxBw, 0) || check_value_deviation(ltn->txRate, tmp.txRate, 0) || check_value_deviation(ltn->rxRate, tmp.rxRate, 0) ) ) { my_description_changed = YES; return; } else if ( check_value_deviation(ltn->txBw, tmp.txBw, my_topology_hysteresis) || check_value_deviation(ltn->rxBw, tmp.rxBw, my_topology_hysteresis) || check_value_deviation(ltn->txRate, tmp.txRate, my_topology_hysteresis) || check_value_deviation(ltn->rxRate, tmp.rxRate, my_topology_hysteresis) ) { my_description_changed = YES; return; } m++; } } if (local_topology_tree.items != m) { my_description_changed = YES; return; } task_register(my_topology_period/10, check_local_topology_cache, NULL, -300000); }
STATIC_FUNC int create_description_topology(struct tx_frame_iterator *it) { struct avl_node *local_it = NULL; struct local_node *local; int32_t m = 0; struct description_msg_topology *msg = (struct description_msg_topology *) tx_iterator_cache_msg_ptr(it); destroy_local_topology_cache(); if (my_topology_period >= MAX_TOPOLOGY_PERIOD) return TLV_TX_DATA_IGNORED; task_remove(check_local_topology_cache, NULL); task_register(my_topology_period, check_local_topology_cache, NULL, -300000); while ((local = avl_iterate_item(&local_tree, &local_it)) && m < tx_iterator_cache_msg_space_max(it)) { if (local->neigh && local->neigh->dhn->on && local->best_tp_lndev) { struct local_topology_node *ltn = debugMallocReset(sizeof(struct local_topology_node), -300000); set_local_topology_node(ltn, local); ltn->pkid = local->neigh->dhn->on->global_id.pkid; avl_insert(&local_topology_tree, ltn, -300000); msg[m].pkid = ltn->pkid; msg[m].txBw = umetric_to_fmu8( <n->txBw); msg[m].rxBw = umetric_to_fmu8(<n->rxBw); msg[m].txRate = ltn->txRate; msg[m].rxRate = ltn->rxRate; msg[m].type = 0; msg[m].reserved = 0; m++; } } if (m) return m * sizeof(struct description_msg_topology); return TLV_TX_DATA_IGNORED; }
STATIC_FUNC void check_for_changed_sms(void *unused) { uint16_t found_sms = 0; uint16_t matching_sms = 0; struct opt_type *opt = get_option( 0, 0, ARG_SMS ); struct opt_parent *p = NULL; struct json_sms * sms = NULL; struct avl_node *an = NULL; char name[MAX_JSON_SMS_NAME_LEN]; char data[MAX_JSON_SMS_DATA_LEN + 1]; dbgf_all(DBGT_INFO, "checking..."); if (extensions_fd == -1) { task_remove(check_for_changed_sms, NULL); task_register(SMS_POLLING_INTERVAL, check_for_changed_sms, NULL, 300000); } while ((sms = avl_iterate_item(&json_sms_tree, &an))) { sms->stale = 1; } while ((p = list_iterate(&opt->d.parents_instance_list, p))) { int len = 0; memset(name, 0, sizeof (name)); strcpy(name, p->val); int fd = -1; char path_name[MAX_PATH_SIZE + 20] = ""; sprintf(path_name, "%s/%s", smsTx_dir, p->val); if ((fd = open(path_name, O_RDONLY, 0)) < 0) { dbgf_all(DBGT_INFO, "could not open %s - %s", path_name, strerror(errno)); continue; } else if ((len = read(fd, data, sizeof (data))) < 0 || len > MAX_JSON_SMS_DATA_LEN) { dbgf_sys(DBGT_ERR, "sms=%s data_len>=%d MUST BE <=%d bytes! errno: %s", path_name, len, MAX_JSON_SMS_DATA_LEN, strerror(errno)); close(fd); continue; } else if ((sms = avl_find_item(&json_sms_tree, name)) && sms->text_len == len && !memcmp(sms->text, data, len)) { matching_sms++; sms->stale = 0; close(fd); } else { if (sms) { avl_remove(&json_sms_tree, sms->name, -300378); debugFree(sms, -300369); } sms = debugMalloc(sizeof (struct json_sms) +len, -300370); memset(sms, 0, sizeof (struct json_sms) +len); strcpy(sms->name, name); sms->text_len = len; sms->stale = 0; memcpy(sms->text, data, len); avl_insert(&json_sms_tree, sms, -300371); close(fd); dbgf_track(DBGT_INFO, "new sms=%s size=%d! updating description..-", path_name, sms->text_len); } found_sms++; } if (found_sms != matching_sms || found_sms != json_sms_tree.items) { dbgf_all(DBGT_INFO, "sms found=%d matching=%d items=%d", found_sms, matching_sms, json_sms_tree.items); memset(name, 0, sizeof (name)); while ((sms = avl_next_item(&json_sms_tree, name))) { memcpy(name, sms->name, sizeof (sms->name)); if (sms->stale) { dbgf_track(DBGT_INFO, "removed sms=%s/%s size=%d! updating description...", smsTx_dir, sms->name, sms->text_len); avl_remove(&json_sms_tree, sms->name, -300373); debugFree(sms, -300374); } } my_description_changed = YES; } }