diff --git a/src/cntlr_map.c b/src/cntlr_map.c index b26ba55cc82d9b3365a6f1ba0667ddce3a639b5f..cd2e937ac68573f336a2883b411d39c0347c4e2d 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -456,6 +456,112 @@ int handle_topology_response(void *cntlr, struct cmdu_buff *cmdu, struct node *n } } + /* MAP_TLV_ASSOCIATED_CLIENTS */ + if (tv[8][0]) { + struct tlv_assoc_client *tlv; + uint8_t *tv_data; + int i, offset = 0; + + tlv = (struct tlv_assoc_client *)tv[8][0]->data; + if (!tlv) + return -1; + + tv_data = (uint8_t *)tlv; + + offset += 1; /* Num_BSS */ + + for (i = 0; i < tlv->num_bss; i++) { + uint8_t bssid[6] = {0}; + struct node *nd = NULL; + uint16_t num_client = 0; + bool bssid_found = false; + int j; + + memcpy(bssid, &tv_data[offset], 6); + offset += 6; /* AP_MAC */ + + num_client = BUF_GET_BE16(tv_data[offset]); + offset += 2; /* Num_Client */ + + nd = cntlr_find_node_with_bssid(c, bssid); + if (nd) + bssid_found = true; + + for (j = 0; j < num_client; j++) { + uint8_t mac[6] = {0}; + struct sta *s = NULL; + uint16_t conn_time = 0; + + memcpy(mac, &tv_data[offset], 6); + offset += 6; /* STA_MAC */ + + conn_time = tv_data[offset]; + offset += 2; /* Assoc_time */ + + s = cntlr_find_sta(c->sta_table, mac); + + if (s) { + bool overwritten = false; + time_t now; + + dbg("%s: sta " MACFMT " %s (bssid=" MACFMT ", conn_time=%d)\n", + __func__, MAC2STR(s->de_sta->macaddr), + s->state == STA_ASSOCIATED ? "associated" : "disassociated", + MAC2STR(s->bssid), s->de_sta->conn_time); + + time(&now); + + if (bssid_found) { + + if (s->state != STA_ASSOCIATED) { + s->state = STA_ASSOCIATED; + overwritten = true; + } + + if (memcmp(s->bssid, bssid, 6)) { + memcpy(s->bssid, bssid, 6); + overwritten = true; + } + + if (abs(s->de_sta->conn_time - conn_time) > 5) { + s->de_sta->conn_time = conn_time; + overwritten = true; + } + + if (overwritten && + abs(difftime(s->assoc_time, now) - conn_time) > 5.0) + s->assoc_time = now - conn_time; + + } else { + if (s->state == STA_ASSOCIATED) { + s->state = STA_DISCONNECTED; + overwritten = true; + } + + if (!hwaddr_is_zero(s->bssid)) { + memset(s->bssid, 0, sizeof(s->bssid)); + overwritten = true; + } + + if (s->de_sta->conn_time) { + s->de_sta->conn_time = 0; + overwritten = true; + } + + if (overwritten && difftime(now, s->disassoc_time) > 5.0) + s->disassoc_time = now; + } + + if (overwritten) + dbg("%s: updated sta " MACFMT " %s (bssid=" MACFMT ", conn_time=%d)\n", + __func__, MAC2STR(s->de_sta->macaddr), + s->state == STA_ASSOCIATED ? "associated" : "disassociated", + MAC2STR(s->bssid), s->de_sta->conn_time); + } + } + } + } + /* map profile info stored for each node */ if (tv[TOPOLOGY_RESPONSE_MULTIAP_PROFILE_IDX][0]) dbg("\t agent profile %d\n", n->map_profile);