diff --git a/src/cmdu.c b/src/cmdu.c index 99d21418a44c45bdd40f663bfc0c42deacd5d3d4..f26026eb1fbdbaa140082d1f0d6b547af41ec364 100644 --- a/src/cmdu.c +++ b/src/cmdu.c @@ -3016,7 +3016,6 @@ static int fill_client_capability_from_tlv(struct decollector_private *priv, struct wifi_sta_element *sta = NULL; struct wifi_assoc_event *event = NULL; struct tlv *tlvs[CLIENT_CAPABILITY_REPORT_NUM_OF_TLV_TYPES][TLV_MAXNUM] = {0}; - bool event_present = false; if (!map_cmdu_validate_parse(resp, tlvs, ARRAY_SIZE(tlvs), dev->map_profile)) { dbg("%s: map_cmdu_validate_parse failed, err = (%d) '%s'\n", @@ -3030,19 +3029,8 @@ static int fill_client_capability_from_tlv(struct decollector_private *priv, struct tlv_client_info *cl_info = (struct tlv_client_info *)tlvs[CLIENT_CAPABILITY_REPORT_CLIENT_INFO_IDX][0]->data; - /* check the sta & bssid in the assoc event list */ - /* TODO: why update assoc eventlist? if we have to, then should - * be from the tail ,) and only for entry missing the capability - * information. - */ - list_for_each_entry(event, &dev->ev.assoclist, list) { - if (hwaddr_equal(event->macaddr, cl_info->macaddr) && - hwaddr_equal(event->bssid, cl_info->bssid)) { - event_present = true; - break; - } - } - + /* check if the sta's last assoc-event is pending for this message */ + event = find_assoc_event(&dev->ev.assoclist, cl_info->macaddr, cl_info->bssid); sta = find_sta_in_bss(dev, cl_info->macaddr, cl_info->bssid); } @@ -3055,17 +3043,19 @@ static int fill_client_capability_from_tlv(struct decollector_private *priv, size_t frame_len = BUF_GET_BE16(t->len) - 1; if (report->result == SUCCESS) { - if (event_present) + if (event) { fill_assoc_sta_caps(report->frame, frame_len, &event->caps); + if (!!(event->pending & WIFI_ASSOC_EVENT_PENDING_CAPS)) { + event->pending &= ~WIFI_ASSOC_EVENT_PENDING_CAPS; + dev->ev.pending |= WIFI_STA_EV_ASSOC; + } + } if (sta) { fill_assoc_sta_caps(report->frame, frame_len, &sta->caps); fill_wifi6_caps(report->frame, frame_len, &sta->wifi6caps); fill_reassoc_frame(report->frame, frame_len, sta); } - - dev->ev.pending |= WIFI_STA_EV_ASSOC; - } else if (report->result == FAILURE) { /* Error Code TLV */ if (tlvs[CLIENT_CAPABILITY_REPORT_ERROR_CODE_IDX][0]) { @@ -3155,6 +3145,8 @@ static int decollector_handle_topology_notification(struct decollector_private * memcpy(n->macaddr, p->macaddr, 6); INIT_LIST_HEAD(&n->meas_reportlist); + INIT_LIST_HEAD(&n->tid_qsizelist); + list_add_tail(&n->list, &bss->stalist); bss->num_stations += 1; get_timestamp(NULL, n->tsp, sizeof(n->tsp)); @@ -3198,10 +3190,8 @@ static int decollector_handle_topology_notification(struct decollector_private * memcpy(e->bssid, p->bssid, 6); list_add_tail(&e->list, &dev->ev.assoclist); dev->ev.num_assoc++; - //ev->pending |= WIFI_STA_EV_ASSOC; - /* XXX: notify assoc event after knowing sta capability - * from following query. - */ + /* notify assoc event after knowing sta capability from following query */ + e->pending |= WIFI_ASSOC_EVENT_PENDING_CAPS; /* Send client capability query */ ret = prepare_client_cap_query(priv, p->macaddr, p->bssid, resp->origin); @@ -3244,30 +3234,57 @@ static int decollector_handle_topology_notification(struct decollector_private * memcpy(e->bssid, p->bssid, 6); list_add_tail(&e->list, &dev->ev.disassoclist); dev->ev.num_disassoc++; - //dev->ev.pending |= WIFI_STA_EV_DISASSOC; - /* XXX: notify this disassoc event after getting - * the related Client Disassociation Stats - * message. + /* notify disassoc event after getting the related + * Client Disassociation Stats message. */ + e->pending |= WIFI_DISASSOC_EVENT_PENDING_STATS; } } return 0; } +struct wifi_assoc_event *find_assoc_event(struct list_head *evlist, uint8_t *sta_macaddr, uint8_t *bssid) +{ + struct wifi_assoc_event *e = NULL; + + list_for_each_entry_reverse(e, evlist, list) { + if (hwaddr_equal(e->macaddr, sta_macaddr) && + hwaddr_equal(e->bssid, bssid)) { + return e; + } + } + + return NULL; +} + +struct wifi_disassoc_event *find_dissassoc_event(struct list_head *evlist, uint8_t *sta_macaddr, uint8_t *bssid) +{ + struct wifi_disassoc_event *e = NULL; + + list_for_each_entry_reverse(e, evlist, list) { + if (hwaddr_equal(e->macaddr, sta_macaddr) && + hwaddr_equal(e->bssid, bssid)) { + return e; + } + } + + return NULL; +} + static int fill_disassoc_stats(struct decollector_private *priv, struct wifi_network_device *dev, struct cmdu_buff *resp) { + struct tlv *tlvs[STA_DISASSOC_STATS_NUM_OF_TLV_TYPES][TLV_MAXNUM] = {0}; + struct wifi_apmld_element *apmld = NULL; + struct tlv_assoc_sta_traffic_stats *t; struct wifi_disassoc_event *e = NULL; struct wifi_bss_element *bss = NULL; - struct wifi_apmld_element *apmld = NULL; struct wifi_sta_element *sta = NULL; - struct tlv_assoc_sta_traffic_stats *t; struct tlv_reason_code *r; struct tlv_sta_mac *p; - struct tlv *tlvs[STA_DISASSOC_STATS_NUM_OF_TLV_TYPES][TLV_MAXNUM] = {0}; - uint16_t reason = 0; + uint8_t *bssid = NULL; #if (EASYMESH_VERSION >= 6) int index = 0; #endif /* (EASYMESH_VERSION >= 6) */ @@ -3279,39 +3296,44 @@ static int fill_disassoc_stats(struct decollector_private *priv, return -1; } - /* STA MAC ADDRESS TLV */ p = (struct tlv_sta_mac *)tlvs[STA_DISASSOC_STATS_STA_MAC_ADDR_IDX][0]->data; - /* REASON CODE TLV */ r = (struct tlv_reason_code *)tlvs[STA_DISASSOC_STATS_REASON_CODE_IDX][0]->data; - /* ASSOCIATED STA TRAFFIC_STATS TLV */ t = (struct tlv_assoc_sta_traffic_stats *) tlvs[STA_DISASSOC_STATS_ASSOCIATED_STA_TRAFFIC_STATS_IDX][0]->data; - reason = r->code; - /* add to sta eventlist */ - e = calloc(1, sizeof(*e)); - if (!e) { - dbg("%s: error -ENOMEM\n", __func__); - return -1; - } - bss = find_bssid_sta(dev, p->macaddr); if (bss) { - memcpy(e->bssid, bss->bssid, 6); + bssid = bss->bssid; } else { apmld = find_bssid_stamld(dev, p->macaddr); if (!apmld) { dbg("%s: No bssid found\n", __func__); return -1; } - memcpy(e->bssid, apmld->mld_macaddr, 6); + bssid = apmld->mld_macaddr; } - time(&e->tm); - get_timestamp(NULL, e->tsp, sizeof(e->tsp)); - memcpy(e->macaddr, p->macaddr, 6); - memcpy(e->sta.macaddr, p->macaddr, 6); - e->reason_code = reason; + /* add/update event in disassoc eventlist */ + e = find_dissassoc_event(&dev->ev.disassoclist, p->macaddr, bssid); + if (!e) { + e = calloc(1, sizeof(*e)); + if (!e) { + dbg("%s: -ENOMEM\n", __func__); + return -1; + } + + time(&e->tm); + get_timestamp(NULL, e->tsp, sizeof(e->tsp)); + memcpy(e->macaddr, p->macaddr, 6); + memcpy(e->sta.macaddr, p->macaddr, 6); + memcpy(e->bssid, bssid, 6); + e->pending |= WIFI_DISASSOC_EVENT_PENDING_STATS; + + list_add_tail(&e->list, &dev->ev.disassoclist); + dev->ev.num_disassoc++; + } + + e->reason_code = r->code; e->sta.tx_bytes = BUF_GET_BE32(t->tx_bytes); e->sta.rx_bytes = BUF_GET_BE32(t->rx_bytes); e->sta.tx_pkts = BUF_GET_BE32(t->tx_packets); @@ -3321,9 +3343,8 @@ static int fill_disassoc_stats(struct decollector_private *priv, e->sta.rtx_pkts = BUF_GET_BE32(t->rtx_packets); #if (EASYMESH_VERSION >= 6) - /* AFFILIATED STA METRICS TLV */ while (index < TLV_MAXNUM && - tlvs[STA_DISASSOC_STATS_AFFILIATED_STA_METRICS_IDX][index]) { + tlvs[STA_DISASSOC_STATS_AFFILIATED_STA_METRICS_IDX][index]) { struct tlv_affiliated_sta_metrics *v; v = (struct tlv_affiliated_sta_metrics *) @@ -3338,11 +3359,12 @@ static int fill_disassoc_stats(struct decollector_private *priv, e->num_affiliated_sta = index; #endif /* (EASYMESH_VERSION >= 6) */ - list_add_tail(&e->list, &dev->ev.disassoclist); - dev->ev.num_disassoc++; - dev->ev.pending |= WIFI_STA_EV_DISASSOC; + if (!!(e->pending & WIFI_DISASSOC_EVENT_PENDING_STATS)) { + e->pending &= ~WIFI_DISASSOC_EVENT_PENDING_STATS; + dev->ev.pending |= WIFI_STA_EV_DISASSOC; + } - /* client disassociation */ + /* remove sta */ sta = find_sta(dev, p->macaddr); if (sta) { /* delete sta entry in bss */ diff --git a/src/decollector.h b/src/decollector.h index dc2ef2b156877b56f5a4e05a47ab3ae907cf0e6e..ab8299ae907830b827e8b5030650089fda400143 100644 --- a/src/decollector.h +++ b/src/decollector.h @@ -121,79 +121,82 @@ struct assoc_req_body { void decollector_start_collection(void *arg); -extern int decollector_publish_object(struct decollector_private *p, const char *objname); -extern int decollector_register_events(struct decollector_private *p); -extern int decollector_subscribe_for_cmdus(struct decollector_private *priv); -extern uint32_t decollector_lookup_object(struct decollector_private *p, const char *objname); - -extern bool is_network_device_alive(struct wifi_network_device *dev); -extern struct wifi_network_device *find_network_device(struct wifi_data_element *dm, uint8_t *alid); -extern struct wifi_radio_element *find_radio(const struct wifi_network_device *dev, +int decollector_publish_object(struct decollector_private *p, const char *objname); +int decollector_register_events(struct decollector_private *p); +int decollector_subscribe_for_cmdus(struct decollector_private *priv); +uint32_t decollector_lookup_object(struct decollector_private *p, const char *objname); + +bool is_network_device_alive(struct wifi_network_device *dev); +struct wifi_network_device *find_network_device(struct wifi_data_element *dm, uint8_t *alid); +struct wifi_radio_element *find_radio(const struct wifi_network_device *dev, const uint8_t *macaddr); -extern int decollector_dump_all(struct decollector_private *p, struct blob_buf *bb); -extern int decollector_dump2_all(struct decollector_private *p, struct blob_buf *bb); -extern int decollector_event_dump(struct decollector_private *p, struct blob_buf *bb); -extern int decollector_notify_events(struct decollector_private *p, struct wifi_network_device *dev); -extern int decollector_collect_node(struct decollector_private *p, struct wifi_network_device *dev); -extern struct wifi_network_device *decollector_get_origin_dev( +struct wifi_assoc_event *find_assoc_event(struct list_head *evlist, uint8_t *sta_macaddr, uint8_t *bssid); +struct wifi_disassoc_event *find_dissassoc_event(struct list_head *evlist, uint8_t *sta_macaddr, uint8_t *bssid); + +int decollector_dump_all(struct decollector_private *p, struct blob_buf *bb); +int decollector_dump2_all(struct decollector_private *p, struct blob_buf *bb); +int decollector_event_dump(struct decollector_private *p, struct blob_buf *bb); +int decollector_notify_events(struct decollector_private *p, struct wifi_network_device *dev); +int decollector_collect_node(struct decollector_private *p, struct wifi_network_device *dev); +struct wifi_network_device *decollector_get_origin_dev( struct decollector_private *p, struct wifi_data_element *dm, uint8_t *origin); -extern int decollector_send_cmdu_request(struct decollector_private *priv, +int decollector_send_cmdu_request(struct decollector_private *priv, struct cmdu_buff *req, uint8_t *dst); -extern int decollector_get_deagents(struct decollector_private *p, int *num, uint8_t **macaddrs); -extern int decollector_get_ieee1905id(struct decollector_private *p); -extern int decollector_get_network_steer_stats(struct decollector_private *p); -extern int decollector_get_sta_steer_stats(struct decollector_private *p); -extern int decollector_get_policy_config(struct decollector_private *p); - - -extern int decollector_alloc_deagents(struct decollector_private *priv); -extern void decollector_getter_run(void *data); -extern void decollector_getter_run_init(struct decollector_private *p); -extern void decollector_refresh_all(struct decollector_private *priv); - -extern void decollector_free_dm(struct wifi_data_element *dm); -extern void free_network_device(struct wifi_network_device *dev); -extern void free_sta(struct wifi_sta_element *sta); -extern void free_bss(struct wifi_bss_element *bss); -extern void free_radio(struct wifi_radio_element *r); -extern void free_apmld(struct wifi_apmld_element *apmld); -extern void free_stamld(struct wifi_stamld_element *stamld); -extern void free_bstamld(struct wifi_network_device *dev); -extern void free_scanresults(struct wifi_scanres_element *scanres); -extern void free_anticipated_ch_usagelist(struct wifi_network_device *dev); -extern void free_wifi_cac_status(struct wifi_cac_status *cac_status); -extern void free_sta_meas_reportlist(struct wifi_sta_element *sta); -extern void clear_supported_opclasses(struct wifi_radio_element *radio); -extern void clear_current_opclasses(struct wifi_radio_element *radio); - -extern int prepare_autoconfig_search(struct decollector_private *priv, uint8_t band); - - -extern int decollector_alloc_getter(struct decollector_private *p, struct wifi_network_device *dev); -extern int decollector_free_getters(struct decollector_private *p); -extern int decollector_free_getter(struct wifi_network_device *dev); -extern int decollector_sched_getter(struct decollector_private *p, +int decollector_get_deagents(struct decollector_private *p, int *num, uint8_t **macaddrs); +int decollector_get_ieee1905id(struct decollector_private *p); +int decollector_get_network_steer_stats(struct decollector_private *p); +int decollector_get_sta_steer_stats(struct decollector_private *p); +int decollector_get_policy_config(struct decollector_private *p); + + +int decollector_alloc_deagents(struct decollector_private *priv); +void decollector_getter_run(void *data); +void decollector_getter_run_init(struct decollector_private *p); +void decollector_refresh_all(struct decollector_private *priv); + +void decollector_free_dm(struct wifi_data_element *dm); +void free_network_device(struct wifi_network_device *dev); +void free_sta(struct wifi_sta_element *sta); +void free_bss(struct wifi_bss_element *bss); +void free_radio(struct wifi_radio_element *r); +void free_apmld(struct wifi_apmld_element *apmld); +void free_stamld(struct wifi_stamld_element *stamld); +void free_bstamld(struct wifi_network_device *dev); +void free_scanresults(struct wifi_scanres_element *scanres); +void free_anticipated_ch_usagelist(struct wifi_network_device *dev); +void free_wifi_cac_status(struct wifi_cac_status *cac_status); +void free_sta_meas_reportlist(struct wifi_sta_element *sta); +void clear_supported_opclasses(struct wifi_radio_element *radio); +void clear_current_opclasses(struct wifi_radio_element *radio); + +int prepare_autoconfig_search(struct decollector_private *priv, uint8_t band); + + +int decollector_alloc_getter(struct decollector_private *p, struct wifi_network_device *dev); +int decollector_free_getters(struct decollector_private *p); +int decollector_free_getter(struct wifi_network_device *dev); +int decollector_sched_getter(struct decollector_private *p, struct wifi_network_device *dev, uint32_t after_ms); -extern void decollector_stop_collection(struct decollector_private *priv); +void decollector_stop_collection(struct decollector_private *priv); -extern int decollector_stop_getter(struct decollector_private *p, struct wifi_network_device *dev); -extern int decollector_reset_getter(struct decollector_private *p, struct wifi_network_device *dev); -extern void decollector_stop_getter_all(struct decollector_private *p); -extern int decollector_getter_running(struct decollector_private *p, struct wifi_network_device *dev); +int decollector_stop_getter(struct decollector_private *p, struct wifi_network_device *dev); +int decollector_reset_getter(struct decollector_private *p, struct wifi_network_device *dev); +void decollector_stop_getter_all(struct decollector_private *p); +int decollector_getter_running(struct decollector_private *p, struct wifi_network_device *dev); -extern int decollector_getter_get_state(struct decollector_private *p, +int decollector_getter_get_state(struct decollector_private *p, struct wifi_network_device *dev, uint8_t *state); -extern int decollector_getter_set_state(struct decollector_private *p, +int decollector_getter_set_state(struct decollector_private *p, struct wifi_network_device *dev, uint8_t state); -extern int prepare_1905_query(struct decollector_private *priv, uint16_t cmdu_type, +int prepare_1905_query(struct decollector_private *priv, uint16_t cmdu_type, struct wifi_network_device *dev, uint8_t *dst); #endif /* DECOLLECTOR_H */ diff --git a/src/dump.c b/src/dump.c index cf1d7d5ef447180c4857f556cc243ec92c193a12..8d71af99aa55607411bdcbd8c99621aa82608231 100644 --- a/src/dump.c +++ b/src/dump.c @@ -552,29 +552,23 @@ int decollector_dump_all(struct decollector_private *p, struct blob_buf *bb) int decollector_dump_assoc_event(struct wifi_assoc_event *e, struct blob_buf *bb) { - char macstr[18] = {0}; - size_t out_len; unsigned char caps_str[32]; - void *t1, *t2; unsigned char caps_str1[32]; - int str1_len = sizeof(caps_str1); int he_caps_len = 0; + size_t out_len; + void *t1; blobmsg_add_string(bb, "eventTime", e->tsp); t1 = blobmsg_open_table(bb, "wfa-dataelements:AssociationEvent"); - t2 = blobmsg_open_table(bb, "AssocData"); - memset(macstr, 0, sizeof(macstr)); - hwaddr_ntoa(e->bssid, macstr); - blobmsg_add_string(bb, "BSSID", macstr); - memset(macstr, 0, sizeof(macstr)); - hwaddr_ntoa(e->macaddr, macstr); - blobmsg_add_string(bb, "MACAddress", macstr); + //t2 = blobmsg_open_table(bb, "AssocData"); + blobmsg_add_macaddr(bb, "BSSID", e->bssid); + blobmsg_add_macaddr(bb, "MACAddress", e->macaddr); blobmsg_add_u32(bb, "StatusCode", e->status_code); //if (e->caps.valid & HT_CAP_VALID) { out_len = sizeof(caps_str); memset(caps_str, 0, sizeof(caps_str)); base64_encode(&e->caps.ht, sizeof(e->caps.ht), caps_str, &out_len); - remove_spec_char(caps_str1, str1_len, caps_str, out_len); + remove_spec_char(caps_str1, sizeof(caps_str1), caps_str, out_len); blobmsg_add_string(bb, "HTCapabilities", (char *)caps_str1); //} @@ -582,7 +576,7 @@ int decollector_dump_assoc_event(struct wifi_assoc_event *e, struct blob_buf *bb out_len = sizeof(caps_str); memset(caps_str, 0, sizeof(caps_str)); base64_encode(e->caps.vht, sizeof(e->caps.vht), caps_str, &out_len); - remove_spec_char(caps_str1, str1_len, caps_str, out_len); + remove_spec_char(caps_str1, sizeof(caps_str1), caps_str, out_len); blobmsg_add_string(bb, "VHTCapabilities", (char *)caps_str1); //} @@ -594,30 +588,24 @@ int decollector_dump_assoc_event(struct wifi_assoc_event *e, struct blob_buf *bb else he_caps_len = 4; base64_encode(&e->caps.he[0], he_caps_len, caps_str, &out_len); - remove_spec_char(caps_str1, str1_len, caps_str, out_len); + remove_spec_char(caps_str1, sizeof(caps_str1), caps_str, out_len); blobmsg_add_string(bb, "HECapabilities", (char *)caps_str1); //} + //blobmsg_close_table(bb, t2); blobmsg_close_table(bb, t1); - blobmsg_close_table(bb, t2); return 0; } int decollector_dump_disassoc_event(struct wifi_disassoc_event *e, struct blob_buf *bb) { - char macstr[18] = {0}; - void *t1; - void *arr; + void *t1, *arr; int i; blobmsg_add_string(bb, "eventTime", e->tsp); t1 = blobmsg_open_table(bb, "wfa-dataelements:DisassociationEvent.Disassociated"); - memset(macstr, 0, sizeof(macstr)); - hwaddr_ntoa(e->bssid, macstr); - blobmsg_add_string(bb, "BSSID", macstr); - memset(macstr, 0, sizeof(macstr)); - hwaddr_ntoa(e->sta.macaddr, macstr); - blobmsg_add_string(bb, "MACAddress", macstr); + blobmsg_add_macaddr(bb, "BSSID", e->bssid); + blobmsg_add_macaddr(bb, "MACAddress", e->macaddr); blobmsg_add_u32(bb, "ReasonCode", e->reason_code); blobmsg_add_u32(bb, "BytesSent", e->sta.tx_bytes); blobmsg_add_u32(bb, "BytesReceived", e->sta.rx_bytes); @@ -640,9 +628,7 @@ int decollector_dump_disassoc_event(struct wifi_disassoc_event *e, struct blob_b /* Device.WiFi.DataElements.DisassociationEvent.Disassociated.DisassociationLinkStats.{i} */ arr = blobmsg_open_array(bb, "DisassociationLinkStats"); for (i = 0; i < e->num_affiliated_sta; i++) { - memset(macstr, 0, sizeof(macstr)); - hwaddr_ntoa(e->affsta[i].macaddr, macstr); - blobmsg_add_string(bb, "MACAddress", macstr); + blobmsg_add_macaddr(bb, "MACAddress", e->affsta[i].macaddr); blobmsg_add_u32(bb, "BytesSent", e->affsta[i].tx_bytes); blobmsg_add_u32(bb, "BytesReceived", e->affsta[i].rx_bytes); blobmsg_add_u32(bb, "PacketsSent", e->affsta[i].tx_packets); @@ -650,7 +636,6 @@ int decollector_dump_disassoc_event(struct wifi_disassoc_event *e, struct blob_b blobmsg_add_u32(bb, "ErrorsSent", e->affsta[i].tx_errors); } blobmsg_close_array(bb, arr); // DisassociationLinkStats - blobmsg_close_table(bb, t1); return 0; @@ -696,6 +681,7 @@ int decollector_event_dump(struct decollector_private *p, struct blob_buf *bb) return 0; } +/* notify all non-pending events */ int decollector_notify_events(struct decollector_private *p, struct wifi_network_device *dev) { struct wifi_sta_events *ev = &dev->ev; @@ -704,30 +690,53 @@ int decollector_notify_events(struct decollector_private *p, struct wifi_network if (!!(ev->pending & WIFI_STA_EV_ASSOC)) { - /* latest event is at the tail */ + int reset_notify = 1; + list_for_each_entry_reverse(ea, &ev->assoclist, list) { struct blob_buf bb = {0}; + if (ea->delivered) + continue; + + if (ea->pending) { + reset_notify = 0; + continue; + } + + ea->delivered = 1; blob_buf_init(&bb, 0); decollector_dump_assoc_event(ea, &bb); ubus_send_event(p->ctx, "wifi.dataelements.Associated", bb.head); blob_buf_free(&bb); - break; } - ev->pending &= ~ WIFI_STA_EV_ASSOC; + + if (reset_notify) + ev->pending &= ~ WIFI_STA_EV_ASSOC; } if (!!(ev->pending & WIFI_STA_EV_DISASSOC)) { + int reset_notify = 1; + list_for_each_entry_reverse(eb, &ev->disassoclist, list) { struct blob_buf bb = {0}; + if (eb->delivered) + continue; + + if (eb->pending) { + reset_notify = 0; + continue; + } + + eb->delivered = 1; blob_buf_init(&bb, 0); decollector_dump_disassoc_event(eb, &bb); ubus_send_event(p->ctx, "wifi.dataelements.Disassociated", bb.head); blob_buf_free(&bb); - break; } - ev->pending &= ~ WIFI_STA_EV_DISASSOC; + + if (reset_notify) + ev->pending &= ~ WIFI_STA_EV_DISASSOC; } /* Free up the oldest entries, when either max-count reached, or diff --git a/src/wifi_dataelements.h b/src/wifi_dataelements.h index 9e03c8c298e49f316612b998db98e8fb1f6dc0ab..a100845908c810e083a5f7e8505a229e5216be56 100644 --- a/src/wifi_dataelements.h +++ b/src/wifi_dataelements.h @@ -917,7 +917,12 @@ struct wifi_data_element { struct wifi_network network; }; +#define WIFI_ASSOC_EVENT_PENDING_CAPS 0x1 +#define WIFI_DISASSOC_EVENT_PENDING_STATS 0x1 + struct wifi_assoc_event { + uint8_t delivered; /* event delivered */ + uint8_t pending; /* event data pending */ timestamp_t tsp; time_t tm; uint8_t macaddr[6]; @@ -928,6 +933,8 @@ struct wifi_assoc_event { }; struct wifi_disassoc_event { + uint8_t delivered; /* event delivered */ + uint8_t pending; /* event data pending */ timestamp_t tsp; time_t tm; uint8_t macaddr[6];