Merge pull request #147 from Telecominfraproject/staging-client-events-refactoring

opensync: Major refactoring/bug fixes for client events
This commit is contained in:
RickSommerville
2021-01-05 10:56:15 -05:00
committed by GitHub
8 changed files with 1735 additions and 2887 deletions

View File

@@ -1,7 +1,5 @@
Index: hostapd-2020-06-08-5a8b3662/hostapd/main.c
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/hostapd/main.c
+++ hostapd-2020-06-08-5a8b3662/hostapd/main.c
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -41,7 +41,7 @@ struct hapd_global {
static struct hapd_global global;
static int daemonize = 0;
@@ -11,10 +9,8 @@ Index: hostapd-2020-06-08-5a8b3662/hostapd/main.c
#ifndef CONFIG_NO_HOSTAPD_LOGGER
static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
Index: hostapd-2020-06-08-5a8b3662/src/ap/hostapd.h
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/hostapd.h
+++ hostapd-2020-06-08-5a8b3662/src/ap/hostapd.h
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -97,6 +97,10 @@ struct hostapd_probereq_cb {
};
@@ -26,10 +22,8 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/hostapd.h
struct hostapd_rate_data {
int rate; /* rate in 100 kbps */
Index: hostapd-2020-06-08-5a8b3662/src/ap/ieee802_11.c
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/ieee802_11.c
+++ hostapd-2020-06-08-5a8b3662/src/ap/ieee802_11.c
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -4928,6 +4928,7 @@ int ieee802_11_mgmt(struct hostapd_data
int ret = 0;
unsigned int freq;
@@ -116,10 +110,8 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/ieee802_11.c
return ret;
}
Index: hostapd-2020-06-08-5a8b3662/src/ap/sta_info.c
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/sta_info.c
+++ hostapd-2020-06-08-5a8b3662/src/ap/sta_info.c
--- a/src/ap/sta_info.c
+++ b/src/ap/sta_info.c
@@ -423,8 +423,14 @@ void ap_handle_timer(void *eloop_ctx, vo
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_INFO, "deauthenticated due to "
@@ -167,10 +159,8 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/sta_info.c
mlme_disassociate_indication(hapd, sta, reason);
break;
case STA_DEAUTH:
Index: hostapd-2020-06-08-5a8b3662/src/ap/sta_info.h
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/sta_info.h
+++ hostapd-2020-06-08-5a8b3662/src/ap/sta_info.h
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -77,6 +77,9 @@ struct sta_info {
u8 supported_rates[WLAN_SUPP_RATES_MAX];
int supported_rates_len;
@@ -181,10 +171,8 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/sta_info.h
#ifdef CONFIG_MESH
enum mesh_plink_state plink_state;
Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.c
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/ubus.c
+++ hostapd-2020-06-08-5a8b3662/src/ap/ubus.c
--- a/src/ap/ubus.c
+++ b/src/ap/ubus.c
@@ -24,7 +24,10 @@
static struct ubus_context *ctx;
@@ -222,7 +210,7 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.c
+};
+
+static const struct blobmsg_policy client_session_del_policy[__CSESS_REQ_MAX] = {
+ [CSESS_REQ_SESS_ID] = { .name = "session_id", .type = BLOBMSG_TYPE_STRING },
+ [CSESS_REQ_SESS_ID] = { .name = "session_id", .type = BLOBMSG_TYPE_INT64 },
+};
+
+static int hostapd_clear_session(struct ubus_context *ctx,
@@ -243,10 +231,10 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.c
+ if (!tb[CSESS_REQ_SESS_ID])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ session_id = blobmsg_get_u64(tb[CSESS_REQ_SESS_ID]);
+ /* remove from AVL and ubus session object) */
+ avl_for_each_element_safe(&hapd->ubus.rt_events, rec, avl, rec_next)
+ {
+ session_id = strtoll(blobmsg_get_string(tb[CSESS_REQ_SESS_ID]), NULL, 10);
+ if (session_id == rec->session_id) {
+ /* dec counter and delete */
+ cached_events_nr -= rec->rec_nr;
@@ -444,10 +432,10 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.c
+
+ /* create reply */
+ blob_buf_init(&b_ev, 0);
+ a = blobmsg_open_table(&b_ev, "bss_list");
+ a = blobmsg_open_array(&b_ev, "bss_list");
+ /* check bss list from hapd */
+ for (size_t i = 0; i < bss_nr; i++) {
+ b = blobmsg_open_table(&b_ev, "bss");
+ b = blobmsg_open_table(&b_ev, NULL);
+ blobmsg_add_string(&b_ev, "name", bss_lst[i]);
+ blobmsg_close_table(&b_ev, b);
+ }
@@ -704,10 +692,8 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.c
int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req)
{
struct ubus_banned_client *ban;
Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.h
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/ubus.h
+++ hostapd-2020-06-08-5a8b3662/src/ap/ubus.h
--- a/src/ap/ubus.h
+++ b/src/ap/ubus.h
@@ -12,6 +12,11 @@ enum hostapd_ubus_event_type {
HOSTAPD_UBUS_PROBE_REQ,
HOSTAPD_UBUS_AUTH_REQ,
@@ -833,10 +819,8 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/ubus.h
static inline void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac)
{
Index: hostapd-2020-06-08-5a8b3662/src/ap/hostapd.c
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/hostapd.c
+++ hostapd-2020-06-08-5a8b3662/src/ap/hostapd.c
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1406,19 +1406,22 @@ static int hostapd_setup_bss(struct host
"Generic snooping infrastructure initialization failed");
return -1;
@@ -867,10 +851,8 @@ Index: hostapd-2020-06-08-5a8b3662/src/ap/hostapd.c
if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
wpa_printf(MSG_ERROR, "VLAN initialization failed.");
Index: hostapd-2020-06-08-5a8b3662/src/ap/dhcp_snoop.c
===================================================================
--- hostapd-2020-06-08-5a8b3662.orig/src/ap/dhcp_snoop.c
+++ hostapd-2020-06-08-5a8b3662/src/ap/dhcp_snoop.c
--- a/src/ap/dhcp_snoop.c
+++ b/src/ap/dhcp_snoop.c
@@ -40,6 +40,7 @@ static void handle_dhcp(void *ctx, const
int res, msgtype = 0, prefixlen = 32;
u32 subnet_mask = 0;

View File

@@ -88,17 +88,17 @@ Index: opensync-2.0.5.0/interfaces/opensync_stats.proto
}
message ClientReport {
@@ -664,6 +668,128 @@ message VideoVoiceReport {
@@ -664,6 +668,137 @@ message VideoVoiceReport {
optional uint64 timestamp_ms = 7;
}
+message EventReport {
+ /* Client Association Event */
+ message ClientAssocEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ optional string ssid = 3;
+ optional RadioBandType band = 4;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ required string ssid = 3;
+ required RadioBandType band = 4;
+ optional AssocType assoc_type = 5;
+ optional uint32 status = 6;
+ optional int32 rssi = 7;
@@ -106,21 +106,23 @@ Index: opensync-2.0.5.0/interfaces/opensync_stats.proto
+ optional bool using11k = 9;
+ optional bool using11r = 10;
+ optional bool using11v = 11;
+ optional uint32 timestamp_ms = 12;
+ }
+
+ /* Client Authentication Event */
+ message ClientAuthEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ optional string ssid = 3;
+ optional RadioBandType band = 4;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ required string ssid = 3;
+ required RadioBandType band = 4;
+ optional uint32 auth_status = 5;
+ optional uint32 timestamp_ms = 6;
+ }
+
+ /* Client Disconnect Event */
+ message ClientDisconnectEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ optional uint32 reason = 3;
+ optional DeviceType dev_type = 4;
+ optional FrameType fr_type = 5;
@@ -128,17 +130,18 @@ Index: opensync-2.0.5.0/interfaces/opensync_stats.proto
+ optional uint64 lrcv_up_ts_in_us = 7;
+ optional uint32 internal_rc = 8;
+ optional int32 rssi = 9;
+ optional string ssid = 10;
+ optional RadioBandType band = 11;
+ required string ssid = 10;
+ required RadioBandType band = 11;
+ optional uint32 timestamp_ms = 12;
+ }
+
+ /* Client Connnect Event */
+ message ClientConnectEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ optional RadioBandType band = 3;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ required RadioBandType band = 3;
+ optional AssocType assoc_type = 4;
+ optional string ssid = 5;
+ required string ssid = 5;
+ optional SecurityType sec_type = 6;
+ optional bool fbt_used = 7;
+ optional bytes ip_addr = 8;
@@ -154,60 +157,66 @@ Index: opensync-2.0.5.0/interfaces/opensync_stats.proto
+ optional bool using11v = 18;
+ optional int64 ev_time_bootup_in_us_ip = 19;
+ optional int32 assoc_rssi = 20;
+ optional uint32 timestamp_ms = 21;
+ }
+
+ /* Client Failure Event */
+ message ClientFailureEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ optional string ssid = 3;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ required string ssid = 3;
+ optional int32 reason_code = 4;
+ optional string reason_str = 5;
+ optional uint32 timestamp_ms = 6;
+ }
+
+ /* Client First Data Event */
+ message ClientFirstDataEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ optional uint64 fdata_tx_up_ts_in_us = 3;
+ optional uint64 fdata_rx_up_ts_in_us = 4;
+ optional uint32 timestamp_ms = 5;
+ }
+
+ /* Client Id Event */
+ message ClientIdEvent {
+ optional string clt_mac = 1;
+ optional uint64 session_id = 2;
+ required string clt_mac = 1;
+ required uint64 session_id = 2;
+ optional string clt_id = 3;
+ optional uint32 timestamp_ms = 4;
+ }
+
+ /* Client IP Event */
+ message ClientIpEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ optional bytes ip_addr = 3;
+ optional uint32 timestamp_ms = 4;
+ }
+
+ /* Client Timeout Event */
+ message ClientTimeoutEvent {
+ optional string sta_mac = 1;
+ optional uint64 session_id = 2;
+ required string sta_mac = 1;
+ required uint64 session_id = 2;
+ optional CTReasonType r_code = 3;
+ optional uint64 last_sent_up_ts_in_us = 4;
+ optional uint64 last_rcv_up_ts_in_us = 5;
+ optional uint32 timestamp_ms = 6;
+ }
+
+ /* Client Session */
+ message ClientSession {
+ required uint64 session_id = 1;
+ repeated ClientAssocEvent client_assoc_event = 2;
+ repeated ClientAuthEvent client_auth_event = 3;
+ repeated ClientDisconnectEvent client_disconnect_event = 4;
+ repeated ClientFailureEvent client_failure_event = 5;
+ repeated ClientFirstDataEvent client_first_data_event = 6;
+ repeated ClientIdEvent client_id_event = 7;
+ repeated ClientIpEvent client_ip_event = 8;
+ repeated ClientTimeoutEvent client_timeout_event = 9;
+ repeated ClientConnectEvent client_connect_event = 10;
+ optional ClientAssocEvent client_assoc_event = 2;
+ optional ClientAuthEvent client_auth_event = 3;
+ optional ClientDisconnectEvent client_disconnect_event = 4;
+ optional ClientFailureEvent client_failure_event = 5;
+ optional ClientFirstDataEvent client_first_data_event = 6;
+ optional ClientIdEvent client_id_event = 7;
+ optional ClientIpEvent client_ip_event = 8;
+ optional ClientTimeoutEvent client_timeout_event = 9;
+ optional ClientConnectEvent client_connect_event = 10;
+ }
+
+ /* Multiple Client Sessions */
@@ -217,7 +226,7 @@ Index: opensync-2.0.5.0/interfaces/opensync_stats.proto
////////////////////////////////////////////////////////////////////////////////
//
// Overall report that might contain all individual stats reports
@@ -680,4 +806,5 @@ message Report {
@@ -680,4 +815,5 @@ message Report {
repeated RssiReport rssi_report = 8;
repeated VideoVoiceReport video_voice_report = 9;
repeated NetworkProbe network_probe = 101;

File diff suppressed because it is too large Load Diff

View File

@@ -1,254 +0,0 @@
Index: opensync-2.0.5.0/interfaces/opensync_stats.proto
===================================================================
--- opensync-2.0.5.0.orig/interfaces/opensync_stats.proto
+++ opensync-2.0.5.0/interfaces/opensync_stats.proto
@@ -692,6 +692,7 @@ message EventReport {
optional bool using11k = 9;
optional bool using11r = 10;
optional bool using11v = 11;
+ optional uint32 timestamp_ms = 12;
}
/* Client Authentication Event */
@@ -701,6 +702,7 @@ message EventReport {
optional string ssid = 3;
optional RadioBandType band = 4;
optional uint32 auth_status = 5;
+ optional uint32 timestamp_ms = 6;
}
/* Client Disconnect Event */
@@ -716,6 +718,7 @@ message EventReport {
optional int32 rssi = 9;
optional string ssid = 10;
optional RadioBandType band = 11;
+ optional uint32 timestamp_ms = 12;
}
/* Client Connnect Event */
@@ -740,6 +743,7 @@ message EventReport {
optional bool using11v = 18;
optional int64 ev_time_bootup_in_us_ip = 19;
optional int32 assoc_rssi = 20;
+ optional uint32 timestamp_ms = 21;
}
/* Client Failure Event */
@@ -749,6 +753,7 @@ message EventReport {
optional string ssid = 3;
optional int32 reason_code = 4;
optional string reason_str = 5;
+ optional uint32 timestamp_ms = 6;
}
/* Client First Data Event */
@@ -757,6 +762,7 @@ message EventReport {
optional uint64 session_id = 2;
optional uint64 fdata_tx_up_ts_in_us = 3;
optional uint64 fdata_rx_up_ts_in_us = 4;
+ optional uint32 timestamp_ms = 5;
}
/* Client Id Event */
@@ -764,6 +770,7 @@ message EventReport {
optional string clt_mac = 1;
optional uint64 session_id = 2;
optional string clt_id = 3;
+ optional uint32 timestamp_ms = 4;
}
/* Client IP Event */
@@ -771,6 +778,7 @@ message EventReport {
optional string sta_mac = 1;
optional uint64 session_id = 2;
optional bytes ip_addr = 3;
+ optional uint32 timestamp_ms = 4;
}
/* Client Timeout Event */
@@ -780,6 +788,7 @@ message EventReport {
optional CTReasonType r_code = 3;
optional uint64 last_sent_up_ts_in_us = 4;
optional uint64 last_rcv_up_ts_in_us = 5;
+ optional uint32 timestamp_ms = 6;
}
/* Client Session */
Index: opensync-2.0.5.0/src/lib/datapipeline/src/dppline.c
===================================================================
--- opensync-2.0.5.0.orig/src/lib/datapipeline/src/dppline.c
+++ opensync-2.0.5.0/src/lib/datapipeline/src/dppline.c
@@ -2617,7 +2617,8 @@ static void dppline_add_stat_ucc(Sts__Re
sizeof(ucc->record.sip_call_start.provider_domain));
sr->call_start->channel = ucc->record.sip_call_start.channel;
sr->call_start->has_channel = true;
- sr->call_start->band = dppline_to_proto_radio(ucc->record.sip_call_start.band);
+ sr->call_start->band =
+ dppline_to_proto_radio(ucc->record.sip_call_start.band);
break;
case PKT_TYPE_CALL_STOP:
@@ -2652,16 +2653,18 @@ static void dppline_add_stat_ucc(Sts__Re
sr->call_stop->has_reason = true;
sr->call_stop->channel = ucc->record.sip_call_stop.channel;
sr->call_stop->has_channel = true;
- sr->call_stop->band = dppline_to_proto_radio(ucc->record.sip_call_stop.band);
+ sr->call_stop->band =
+ dppline_to_proto_radio(ucc->record.sip_call_stop.band);
- sr->call_stop->provider_domain = malloc(sizeof(ucc->record.sip_call_stop.provider_domain));
+ sr->call_stop->provider_domain = malloc(
+ sizeof(ucc->record.sip_call_stop.provider_domain));
size += sizeof(ucc->record.sip_call_stop.provider_domain);
assert(sr->call_stop->provider_domain);
memcpy(sr->call_stop->provider_domain,
- ucc->record.sip_call_stop.provider_domain,
- sizeof(ucc->record.sip_call_stop.provider_domain));
+ ucc->record.sip_call_stop.provider_domain,
+ sizeof(ucc->record.sip_call_stop.provider_domain));
break;
@@ -2698,16 +2701,18 @@ static void dppline_add_stat_ucc(Sts__Re
sr->call_report->has_reason = true;
sr->call_report->channel = ucc->record.sip_call_report.channel;
sr->call_report->has_channel = true;
- sr->call_report->band = dppline_to_proto_radio(ucc->record.sip_call_report.band);
+ sr->call_report->band = dppline_to_proto_radio(
+ ucc->record.sip_call_report.band);
- sr->call_report->provider_domain = malloc(sizeof(ucc->record.sip_call_report.provider_domain));
+ sr->call_report->provider_domain = malloc(
+ sizeof(ucc->record.sip_call_report.provider_domain));
size += sizeof(ucc->record.sip_call_report.provider_domain);
assert(sr->call_report->provider_domain);
memcpy(sr->call_report->provider_domain,
- ucc->record.sip_call_report.provider_domain,
- sizeof(ucc->record.sip_call_report.provider_domain));
+ ucc->record.sip_call_report.provider_domain,
+ sizeof(ucc->record.sip_call_report.provider_domain));
break;
default:
@@ -2931,6 +2936,7 @@ static void dppline_add_stat_events(Sts_
}
drx->ssid = strdup(srx->ssid);
+ LOG(INFO, "drx->ssid: %s", drx->ssid);
if (srx->band) {
drx->band = dppline_to_proto_radio(
@@ -2974,6 +2980,13 @@ static void dppline_add_stat_events(Sts_
drx->using11v = srx->using11v;
drx->has_using11v = true;
}
+
+ LOG(INFO, "srx->timestamp: %d", srx->timestamp);
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
+ LOG(INFO, "drx->timestamp_ms: %d", drx->timestamp_ms);
}
/* Client Auth Event */
@@ -3032,6 +3045,11 @@ static void dppline_add_stat_events(Sts_
drx->auth_status = srx->auth_status;
drx->has_auth_status = true;
}
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
/* Client Disconnect Event */
@@ -3130,6 +3148,11 @@ static void dppline_add_stat_events(Sts_
srx->band);
drx->has_band = true;
}
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
/* Client Connect Event */
@@ -3286,6 +3309,11 @@ static void dppline_add_stat_events(Sts_
drx->assoc_rssi = srx->assoc_rssi;
drx->has_assoc_rssi = true;
}
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
/* Client Failure Event */
@@ -3344,6 +3372,11 @@ static void dppline_add_stat_events(Sts_
}
drx->reason_str = strdup(srx->reason_str);
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
/* Client First Data Event */
@@ -3405,6 +3438,11 @@ static void dppline_add_stat_events(Sts_
srx->fdata_rx_up_ts_in_us;
drx->has_fdata_rx_up_ts_in_us = true;
}
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
/* Client Id Event */
@@ -3452,6 +3490,11 @@ static void dppline_add_stat_events(Sts_
}
drx->clt_id = strdup(srx->clt_id);
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
/* Client Ip Event */
@@ -3503,6 +3546,11 @@ static void dppline_add_stat_events(Sts_
drx->ip_addr.len = 16;
drx->has_ip_addr = true;
}
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
/* Client Timeout Event */
@@ -3571,6 +3619,11 @@ static void dppline_add_stat_events(Sts_
srx->last_recv_up_ts_in_us;
drx->has_last_rcv_up_ts_in_us = true;
}
+
+ if (srx->timestamp) {
+ drx->timestamp_ms = srx->timestamp;
+ drx->has_timestamp_ms = true;
+ }
}
}
}

View File

@@ -55,8 +55,6 @@ typedef struct {
bool using11k;
bool using11r;
bool using11v;
ds_dlist_node_t node;
} dpp_event_record_assoc_t;
/* proto: ClientAuthEvent */
@@ -68,8 +66,6 @@ typedef struct {
radio_essid_t ssid;
radio_type_t band;
uint32_t auth_status;
ds_dlist_node_t node;
} dpp_event_record_auth_t;
/* proto: ClientDisconnectEvent */
@@ -87,8 +83,6 @@ typedef struct {
int32_t rssi;
radio_essid_t ssid;
radio_type_t band;
ds_dlist_node_t node;
} dpp_event_record_disconnect_t;
/* proto: ClientConnectEvent */
@@ -115,8 +109,6 @@ typedef struct {
bool using11v;
int64_t ev_time_bootup_in_us_ip;
int32_t assoc_rssi;
ds_dlist_node_t node;
} dpp_event_record_connect_t;
/* proto: ClientFailureEvent */
@@ -128,8 +120,6 @@ typedef struct {
radio_essid_t ssid;
int32_t reason;
char reason_str[DPP_REASON_STR_LEN];
ds_dlist_node_t node;
} dpp_event_record_failure_t;
/* proto: ClientFirstDataEvent */
@@ -140,8 +130,6 @@ typedef struct {
uint32_t timestamp;
uint64_t fdata_tx_up_ts_in_us;
uint64_t fdata_rx_up_ts_in_us;
ds_dlist_node_t node;
} dpp_event_record_first_data_t;
/* proto: ClientIdEvent */
@@ -151,8 +139,6 @@ typedef struct {
uint64_t session_id;
uint32_t timestamp;
char clt_id[DPP_CLT_ID_LEN];
ds_dlist_node_t node;
} dpp_event_record_id_t;
/* proto: ClientIpEvent */
@@ -162,8 +148,6 @@ typedef struct {
uint64_t session_id;
uint32_t timestamp;
uint8_t ip_addr[16];
ds_dlist_node_t node;
} dpp_event_record_ip_t;
/* proto: ClientTimeoutEvent */
@@ -175,29 +159,27 @@ typedef struct {
ct_reason_t r_code;
uint64_t last_sent_up_ts_in_us;
uint64_t last_recv_up_ts_in_us;
ds_dlist_node_t node;
} dpp_event_record_timeout_t;
/* proto: ClientSession */
typedef struct {
uint64_t session_id;
ds_dlist_t assoc_list; /* dpp_event_record_assoc_t */
ds_dlist_t auth_list; /* dpp_event_record_auth_t */
ds_dlist_t disconnect_list; /* dpp_event_record_disconnect_t */
ds_dlist_t failure_list; /* dpp_event_record_failure_t */
ds_dlist_t first_data_list; /* dpp_event_record_first_data_t */
ds_dlist_t id_list; /* dpp_event_record_id_t */
ds_dlist_t ip_list; /* dpp_event_record_ip_t */
ds_dlist_t timeout_list; /* dpp_event_record_timeout_t */
ds_dlist_t connect_list; /* dpp_event_record_connect_t */
dpp_event_record_assoc_t *assoc_event; /* dpp_event_record_assoc_t */
dpp_event_record_auth_t *auth_event; /* dpp_event_record_auth_t */
dpp_event_record_disconnect_t *disconnect_event; /* dpp_event_record_disconnect_t */
dpp_event_record_failure_t *failure_event; /* dpp_event_record_failure_t */
dpp_event_record_first_data_t *first_data_event; /* dpp_event_record_first_data_t */
dpp_event_record_id_t *id_event; /* dpp_event_record_id_t */
dpp_event_record_ip_t *ip_event; /* dpp_event_record_ip_t */
dpp_event_record_timeout_t *timeout_event; /* dpp_event_record_timeout_t */
dpp_event_record_connect_t *connect_event; /* dpp_event_record_connect_t */
ds_dlist_node_t node;
} dpp_event_record_session_t;
/* event record */
typedef struct {
ds_dlist_t client_session; /* dpp_event_record_session_t */
dpp_event_record_session_t client_session; /* dpp_event_record_session_t */
bool hasSMProcessed;
ds_dlist_node_t node;
} dpp_event_record_t;
@@ -448,9 +430,31 @@ dpp_event_client_session_record_free(dpp_event_record_session_t *record)
}
}
static inline dpp_event_record_t *
dpp_event_record_alloc()
{
dpp_event_record_t *record = NULL;
record = calloc(1, sizeof(dpp_event_record_t));
if (record) {
memset(record, 0, sizeof(dpp_event_record_t));
}
return record;
}
/* free */
static inline void
dpp_event_record_free(dpp_event_record_t *record)
{
if (NULL != record) {
free(record);
}
}
/* Events report type */
typedef struct {
ds_dlist_t list; /* dpp_event_record_t */
ds_dlist_t client_event_list; /* dpp_event_record_t */
} dpp_event_report_data_t;
#endif /* DPP_EVENTS_H_INCLUDED */

View File

@@ -23,7 +23,7 @@
#define MODULE_ID LOG_MODULE_ID_MAIN
/* global list populated by ubus_collector */
extern dpp_event_report_data_t g_report_data;
extern dpp_event_report_data_t g_event_report;
/* new part */
typedef struct {
@@ -41,9 +41,6 @@ typedef struct {
/* Structure pointing to upper layer events storage */
dpp_event_report_data_t report;
/* event list (only one for now) */
ds_dlist_t record_list;
/* Reporting start timestamp used for reporting timestamp calculation */
uint64_t report_ts;
} sm_events_ctx_t;
@@ -88,24 +85,61 @@ static bool dpp_events_report_timer_restart(ev_timer *timer)
return true;
}
static void sm_events_report_clear(ds_dlist_t *report_list)
{
ds_dlist_iter_t record_iter;
if (ds_dlist_is_empty(report_list))
return;
dpp_event_record_t *record = NULL;
for (record = ds_dlist_ifirst(&record_iter, report_list);
record != NULL;
record = ds_dlist_inext(&record_iter)) {
ds_dlist_iremove(&record_iter);
dpp_event_record_free(record);
record = NULL;
}
}
static void sm_events_report(EV_P_ ev_timer *w, int revents)
{
sm_events_ctx_t *events_ctx = (sm_events_ctx_t *)w->data;
dpp_event_report_data_t *report_ctx = &events_ctx->report;
ev_timer *report_timer = &events_ctx->report_timer;
/* Event Record */
dpp_event_record_t *dpp_record = NULL;
dpp_event_record_t *sm_record = NULL;
ds_dlist_iter_t record_iter;
dpp_events_report_timer_restart(report_timer);
memcpy(report_ctx, &g_report_data, sizeof(dpp_event_report_data_t));
for (sm_record = ds_dlist_ifirst(&record_iter, &g_event_report.client_event_list); sm_record != NULL; sm_record = ds_dlist_inext(&record_iter)) {
dpp_record = dpp_event_record_alloc();
dpp_record->client_session.session_id = sm_record->client_session.session_id;
dpp_record->client_session.auth_event = sm_record->client_session.auth_event;
dpp_record->client_session.assoc_event = sm_record->client_session.assoc_event;
dpp_record->client_session.first_data_event = sm_record->client_session.first_data_event;
dpp_record->client_session.disconnect_event = sm_record->client_session.disconnect_event;
dpp_record->client_session.auth_event = sm_record->client_session.auth_event;
while (!ds_dlist_is_empty(&g_report_data.list)) {
ds_dlist_remove_head(&g_report_data.list);
/* Memset all event pointers in the global event record to NULL */
memset(&sm_record->client_session, 0, sizeof(dpp_event_record_session_t));
sm_record->hasSMProcessed = true;
if (ds_dlist_is_empty(&report_ctx->client_event_list)) {
ds_dlist_init(&report_ctx->client_event_list, dpp_event_record_t, node);
}
ds_dlist_insert_tail(&report_ctx->client_event_list, dpp_record);
}
LOG(INFO, "Sending events report...");
if (!ds_dlist_is_empty(&report_ctx->list)) {
if (!ds_dlist_is_empty(&report_ctx->client_event_list)) {
LOG(INFO, "Sending events report...");
dpp_put_events(report_ctx);
}
sm_events_report_clear(&report_ctx->client_event_list);
}
/******************************************************************************
@@ -136,11 +170,7 @@ bool sm_events_report_request(radio_entry_t *radio_cfg,
LOG(INFO, "Initializing events reporting");
/* Initialize report list */
ds_dlist_init(&report_ctx->list, dpp_event_record_t, node);
/* Initialize event list */
ds_dlist_init(&events_ctx->record_list, dpp_event_record_t,
node);
ds_dlist_init(&report_ctx->client_event_list, dpp_event_record_t, node);
/* Initialize event lib timers and pass the global
internal cache

View File

@@ -4,26 +4,32 @@
#include <inttypes.h>
/* Global list of events received from hostapd */
dpp_event_report_data_t g_report_data;
dpp_event_report_data_t g_event_report;
/* Internal list of processed events ready to be deleted from hostapd */
static dpp_event_report_data_t *deletion_pending = NULL;
static ds_dlist_t deletion_pending_list;
static ds_dlist_t bss_list;
static struct ubus_context *ubus = NULL;
static char *ubus_object = NULL;
typedef struct {
uint64_t session_id;
char *bss;
char bss[UBUS_OBJ_LEN];
ds_dlist_node_t node;
} delete_entry_t;
typedef struct {
char obj_name[UBUS_OBJ_LEN];
ds_dlist_node_t node;
} bss_obj_t;
static const struct blobmsg_policy ubus_collector_bss_list_policy[__BSS_LIST_DATA_MAX] = {
[BSS_LIST_BSS_LIST] = {.name = "bss_list", .type = BLOBMSG_TYPE_TABLE},
[BSS_LIST_BSS_LIST] = { .name = "bss_list", .type = BLOBMSG_TYPE_ARRAY },
};
static const struct blobmsg_policy ubus_collector_bss_table_policy[__BSS_TABLE_MAX] = {
[BSS_TABLE_BSS_NAME] = {.name = "name", .type = BLOBMSG_TYPE_STRING},
[BSS_OBJECT_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
};
static const struct blobmsg_policy ubus_collector_sessions_policy[__UBUS_SESSIONS_MAX] = {
@@ -81,6 +87,37 @@ static const struct blobmsg_policy client_first_data_event_policy[__CLIENT_FIRST
[CLIENT_FIRST_DATA_RX_TIMESTAMP] = {.name = "fdata_rx_up_ts_in_us", .type = BLOBMSG_TYPE_INT64},
};
static int frequency_to_channel(int freq)
{
/* see 802.11-2007 17.3.8.3.2 and Annex J */
if (freq == 2484)
return 14;
else if (freq < 2484)
return (freq - 2407) / 5;
else if (freq >= 4910 && freq <= 4980)
return (freq - 4000) / 5;
else if (freq <= 45000) /* DMG band lower limit */
return (freq - 5000) / 5;
else if (freq >= 58320 && freq <= 64800)
return (freq - 56160) / 2160;
else
return 0;
}
static radio_type_t frequency_to_band(int freq)
{
int chan = frequency_to_channel(freq);
if (chan <= 16)
return RADIO_TYPE_2G;
else if (chan >= 32 && chan <= 68)
return RADIO_TYPE_5GL;
else if (chan >= 96)
return RADIO_TYPE_5GU;
else
return RADIO_TYPE_NONE;
}
static int client_first_data_event_cb(struct blob_attr *msg,
dpp_event_record_session_t *dpp_session,
uint64_t event_session_id)
@@ -89,12 +126,9 @@ static int client_first_data_event_cb(struct blob_attr *msg,
struct blob_attr
*tb_client_first_data_event[__CLIENT_FIRST_DATA_MAX] = {};
char *mac_address = NULL;
uint64_t session_id = event_session_id;
uint32_t timestamp = 0;
uint64_t rx_ts = 0;
uint64_t tx_ts = 0;
int i = 0;
dpp_event_record_first_data_t *first_data_event_dpp = NULL;
if (NULL == dpp_session)
return -1;
error = blobmsg_parse(client_first_data_event_policy,
__CLIENT_FIRST_DATA_MAX,
@@ -103,42 +137,27 @@ static int client_first_data_event_cb(struct blob_attr *msg,
if (error)
return -1;
for (i = 0; i < __CLIENT_FIRST_DATA_MAX; i++) {
if (!tb_client_first_data_event[i]) {
LOG(INFO,
"ubus_collector: could not parse first_data event %s policy",
client_first_data_event_policy[i].name);
return -1;
}
}
dpp_session->first_data_event = dpp_event_client_first_data_record_alloc();
mac_address = blobmsg_get_string(
tb_client_first_data_event[CLIENT_FIRST_DATA_STA_MAC]);
if (!mac_address)
if (!dpp_session->first_data_event)
return -1;
timestamp = blobmsg_get_u32(
tb_client_first_data_event[CLIENT_FIRST_DATA_TIMESTAMP]);
rx_ts = blobmsg_get_u64(
tb_client_first_data_event[CLIENT_FIRST_DATA_RX_TIMESTAMP]);
tx_ts = blobmsg_get_u64(
tb_client_first_data_event[CLIENT_FIRST_DATA_TX_TIMESTAMP]);
dpp_session->first_data_event->session_id = event_session_id;
first_data_event_dpp = calloc(1, sizeof(dpp_event_record_first_data_t));
if (tb_client_first_data_event[CLIENT_FIRST_DATA_STA_MAC]) {
mac_address = blobmsg_get_string(tb_client_first_data_event[CLIENT_FIRST_DATA_STA_MAC]);
memcpy(dpp_session->first_data_event->sta_mac, mac_address, MAC_ADDRESS_STRING_LEN);
}
memcpy(first_data_event_dpp->sta_mac, mac_address,
MAC_ADDRESS_STRING_LEN);
first_data_event_dpp->session_id = session_id;
first_data_event_dpp->timestamp = timestamp;
first_data_event_dpp->fdata_tx_up_ts_in_us = tx_ts;
first_data_event_dpp->fdata_rx_up_ts_in_us = rx_ts;
if (tb_client_first_data_event[CLIENT_FIRST_DATA_TIMESTAMP])
dpp_session->first_data_event->timestamp = blobmsg_get_u32(tb_client_first_data_event[CLIENT_FIRST_DATA_TIMESTAMP]);
if (!ds_dlist_is_empty(&dpp_session->first_data_list))
ds_dlist_init(&dpp_session->first_data_list,
dpp_event_record_first_data_t, node);
if (tb_client_first_data_event[CLIENT_FIRST_DATA_TX_TIMESTAMP])
dpp_session->first_data_event->fdata_tx_up_ts_in_us = blobmsg_get_u64(tb_client_first_data_event[CLIENT_FIRST_DATA_TX_TIMESTAMP]);
if (tb_client_first_data_event[CLIENT_FIRST_DATA_RX_TIMESTAMP])
dpp_session->first_data_event->fdata_rx_up_ts_in_us = blobmsg_get_u64(tb_client_first_data_event[CLIENT_FIRST_DATA_RX_TIMESTAMP]);
ds_dlist_insert_tail(&dpp_session->first_data_list,
first_data_event_dpp);
return 0;
}
@@ -147,19 +166,12 @@ static int client_disconnect_event_cb(struct blob_attr *msg,
uint64_t event_session_id)
{
int error = 0;
int ssid_bytes = 0;
struct blob_attr
*tb_client_disconnect_event[__CLIENT_DISCONNECT_MAX] = {};
char *mac_address = NULL;
radio_essid_t ssid = {};
char *ssid_temp = NULL;
uint64_t session_id = event_session_id;
uint32_t timestamp = 0;
radio_type_t band = 0;
uint32_t rssi = 0;
uint32_t internal_rc = 0;
int i = 0;
dpp_event_record_disconnect_t *disconnect_event_dpp = NULL;
char *mac_address, *ssid = NULL;
if (NULL == dpp_session)
return -1;
error = blobmsg_parse(client_disconnect_event_policy,
__CLIENT_DISCONNECT_MAX,
@@ -168,52 +180,35 @@ static int client_disconnect_event_cb(struct blob_attr *msg,
if (error)
return -1;
for (i = 0; i < __CLIENT_DISCONNECT_MAX; i++) {
if (!tb_client_disconnect_event[i]) {
LOG(INFO,
"ubus_collector: could not parse disconnect event %s policy",
client_disconnect_event_policy[i].name);
return -1;
}
dpp_session->disconnect_event = dpp_event_client_disconnect_record_alloc();
if (!dpp_session->disconnect_event)
return -1;
dpp_session->disconnect_event->session_id = event_session_id;
if (tb_client_disconnect_event[CLIENT_DISCONNECT_STA_MAC]) {
mac_address = blobmsg_get_string(tb_client_disconnect_event[CLIENT_DISCONNECT_STA_MAC]);
memcpy(dpp_session->disconnect_event->sta_mac, mac_address, MAC_ADDRESS_STRING_LEN);
}
mac_address = blobmsg_get_string(
tb_client_disconnect_event[CLIENT_DISCONNECT_STA_MAC]);
if (!mac_address)
return -1;
if (tb_client_disconnect_event[CLIENT_DISCONNECT_BAND])
dpp_session->disconnect_event->band = frequency_to_band(blobmsg_get_u32(tb_client_disconnect_event[CLIENT_DISCONNECT_BAND]));
ssid_temp = blobmsg_get_string(
tb_client_disconnect_event[CLIENT_DISCONNECT_SSID]);
ssid_bytes = snprintf(ssid, RADIO_ESSID_LEN + 1, "%s", ssid_temp);
if (ssid_bytes > RADIO_ESSID_LEN)
return -1;
if (tb_client_disconnect_event[CLIENT_DISCONNECT_RSSI])
dpp_session->disconnect_event->rssi = blobmsg_get_u32(tb_client_disconnect_event[CLIENT_DISCONNECT_RSSI]);
band = blobmsg_get_u32(
tb_client_disconnect_event[CLIENT_DISCONNECT_BAND]);
rssi = blobmsg_get_u32(
tb_client_disconnect_event[CLIENT_DISCONNECT_RSSI]);
timestamp = blobmsg_get_u32(
tb_client_disconnect_event[CLIENT_DISCONNECT_TIMESTAMP]);
internal_rc = blobmsg_get_u32(
tb_client_disconnect_event[CLIENT_DISCONNECT_INTERNAL_RC]);
if (tb_client_disconnect_event[CLIENT_DISCONNECT_SSID]) {
ssid = blobmsg_get_string(tb_client_disconnect_event[CLIENT_DISCONNECT_SSID]);
memcpy(dpp_session->disconnect_event->ssid, ssid, RADIO_ESSID_LEN + 1);
}
disconnect_event_dpp = calloc(1, sizeof(dpp_event_record_disconnect_t));
if (tb_client_disconnect_event[CLIENT_DISCONNECT_TIMESTAMP])
dpp_session->disconnect_event->timestamp = blobmsg_get_u32(tb_client_disconnect_event[CLIENT_DISCONNECT_TIMESTAMP]);
memcpy(disconnect_event_dpp->sta_mac, mac_address,
MAC_ADDRESS_STRING_LEN);
memcpy(disconnect_event_dpp->ssid, ssid, ssid_bytes + 1);
disconnect_event_dpp->session_id = session_id;
disconnect_event_dpp->timestamp = timestamp;
disconnect_event_dpp->band = band;
disconnect_event_dpp->rssi = rssi;
disconnect_event_dpp->internal_rc = internal_rc;
if (tb_client_disconnect_event[CLIENT_DISCONNECT_INTERNAL_RC])
dpp_session->disconnect_event->internal_rc = blobmsg_get_u32(tb_client_disconnect_event[CLIENT_DISCONNECT_INTERNAL_RC]);
if (!ds_dlist_is_empty(&dpp_session->disconnect_list))
ds_dlist_init(&dpp_session->disconnect_list,
dpp_event_record_disconnect_t, node);
ds_dlist_insert_tail(&dpp_session->disconnect_list,
disconnect_event_dpp);
return 0;
}
@@ -222,17 +217,11 @@ static int client_auth_event_cb(struct blob_attr *msg,
uint64_t event_session_id)
{
int error = 0;
int ssid_bytes = 0;
struct blob_attr *tb_client_auth_event[__CLIENT_ASSOC_MAX] = {};
char *mac_address = NULL;
radio_essid_t ssid = {};
char *ssid_temp = NULL;
uint64_t session_id = event_session_id;
uint32_t timestamp = 0;
radio_type_t band = 0;
uint32_t auth_status = 0;
int i = 0;
dpp_event_record_auth_t *auth_event_dpp = NULL;
char *mac_address, *ssid = NULL;
if (NULL == dpp_session)
return -1;
error = blobmsg_parse(client_auth_event_policy, __CLIENT_AUTH_MAX,
tb_client_auth_event, blobmsg_data(msg),
@@ -240,47 +229,32 @@ static int client_auth_event_cb(struct blob_attr *msg,
if (error)
return -1;
for (i = 0; i < __CLIENT_AUTH_MAX; i++) {
if (!tb_client_auth_event[i]) {
LOG(INFO,
"ubus_collector: could not parse auth event %s policy",
client_auth_event_policy[i].name);
return -1;
}
dpp_session->auth_event = dpp_event_client_auth_record_alloc();
if (!dpp_session->auth_event)
return -1;
dpp_session->auth_event->session_id = event_session_id;
if (tb_client_auth_event[CLIENT_AUTH_STA_MAC]) {
mac_address = blobmsg_get_string(tb_client_auth_event[CLIENT_AUTH_STA_MAC]);
memcpy(dpp_session->auth_event->sta_mac, mac_address, MAC_ADDRESS_STRING_LEN);
}
mac_address =
blobmsg_get_string(tb_client_auth_event[CLIENT_AUTH_STA_MAC]);
if (!mac_address)
return -1;
if (tb_client_auth_event[CLIENT_AUTH_BAND])
dpp_session->auth_event->band = frequency_to_band(blobmsg_get_u32(tb_client_auth_event[CLIENT_AUTH_BAND]));
ssid_temp =
blobmsg_get_string(tb_client_auth_event[CLIENT_AUTH_AUTH_SSID]);
ssid_bytes = snprintf(ssid, RADIO_ESSID_LEN + 1, "%s", ssid_temp);
if (ssid_bytes > RADIO_ESSID_LEN)
return -1;
if (tb_client_auth_event[CLIENT_AUTH_AUTH_SSID]) {
ssid = blobmsg_get_string(tb_client_auth_event[CLIENT_AUTH_AUTH_SSID]);
memcpy(dpp_session->auth_event->ssid, ssid, RADIO_ESSID_LEN + 1);
}
timestamp =
blobmsg_get_u32(tb_client_auth_event[CLIENT_AUTH_TIMESTAMP]);
band = blobmsg_get_u32(tb_client_auth_event[CLIENT_AUTH_BAND]);
auth_status =
blobmsg_get_u32(tb_client_auth_event[CLIENT_AUTH_AUTH_STATUS]);
if (tb_client_auth_event[CLIENT_AUTH_TIMESTAMP])
dpp_session->auth_event->timestamp = blobmsg_get_u32(tb_client_auth_event[CLIENT_AUTH_TIMESTAMP]);
auth_event_dpp = calloc(1, sizeof(dpp_event_record_auth_t));
memset(auth_event_dpp, 0, sizeof(dpp_event_record_auth_t));
if (tb_client_auth_event[CLIENT_AUTH_AUTH_STATUS])
dpp_session->auth_event->auth_status = blobmsg_get_u32(tb_client_auth_event[CLIENT_AUTH_AUTH_STATUS]);
memcpy(auth_event_dpp->sta_mac, mac_address, MAC_ADDRESS_STRING_LEN);
memcpy(auth_event_dpp->ssid, ssid, ssid_bytes + 1);
auth_event_dpp->session_id = session_id;
auth_event_dpp->timestamp = timestamp;
auth_event_dpp->band = band;
auth_event_dpp->auth_status = auth_status;
if (!ds_dlist_is_empty(&dpp_session->auth_list))
ds_dlist_init(&dpp_session->auth_list, dpp_event_record_auth_t,
node);
ds_dlist_insert_tail(&dpp_session->auth_list, auth_event_dpp);
return 0;
}
@@ -289,22 +263,11 @@ static int client_assoc_event_cb(struct blob_attr *msg,
uint64_t event_session_id)
{
int error = 0;
int ssid_bytes = 0;
struct blob_attr *tb_client_assoc_event[__CLIENT_ASSOC_MAX] = {};
char *mac_address = NULL;
radio_essid_t ssid = {};
char *ssid_temp = NULL;
uint64_t session_id = event_session_id;
uint32_t timestamp = 0;
radio_type_t band = 0;
assoc_type_t assoc_type = 0;
uint32_t rssi = 0;
uint32_t internal_sc = 0;
bool using11k = false;
bool using11r = false;
bool using11v = false;
int i = 0;
dpp_event_record_assoc_t *assoc_event_dpp = NULL;
char *mac_address, *ssid = NULL;
if (NULL == dpp_session)
return -1;
error = blobmsg_parse(client_assoc_event_policy, __CLIENT_ASSOC_MAX,
tb_client_assoc_event, blobmsg_data(msg),
@@ -312,64 +275,51 @@ static int client_assoc_event_cb(struct blob_attr *msg,
if (error)
return -1;
for (i = 0; i < __CLIENT_ASSOC_MAX; i++) {
if (!tb_client_assoc_event[i]) {
LOG(INFO,
"ubus_collector: could not parse assoc event %s policy",
client_assoc_event_policy[i].name);
return -1;
}
dpp_session->assoc_event = dpp_event_client_assoc_record_alloc();
if (!dpp_session->assoc_event)
return -1;
dpp_session->assoc_event->session_id = event_session_id;
if (tb_client_assoc_event[CLIENT_ASSOC_STA_MAC]) {
mac_address = blobmsg_get_string(tb_client_assoc_event[CLIENT_ASSOC_STA_MAC]);
memcpy(dpp_session->assoc_event->sta_mac, mac_address, MAC_ADDRESS_STRING_LEN);
}
mac_address =
blobmsg_get_string(tb_client_assoc_event[CLIENT_ASSOC_STA_MAC]);
if (!mac_address)
return -1;
if (tb_client_assoc_event[CLIENT_ASSOC_SSID]) {
ssid = blobmsg_get_string(tb_client_assoc_event[CLIENT_ASSOC_SSID]);
memcpy(dpp_session->assoc_event->ssid, ssid, RADIO_ESSID_LEN + 1);
}
ssid_temp =
blobmsg_get_string(tb_client_assoc_event[CLIENT_ASSOC_SSID]);
ssid_bytes = snprintf(ssid, RADIO_ESSID_LEN + 1, "%s", ssid_temp);
if (ssid_bytes > RADIO_ESSID_LEN)
return -1;
if (tb_client_assoc_event[CLIENT_ASSOC_TIMESTAMP])
dpp_session->assoc_event->timestamp = blobmsg_get_u32(tb_client_assoc_event[CLIENT_ASSOC_TIMESTAMP]);
band = blobmsg_get_u32(tb_client_assoc_event[CLIENT_ASSOC_BAND]);
assoc_type =
blobmsg_get_u8(tb_client_assoc_event[CLIENT_ASSOC_ASSOC_TYPE]);
rssi = blobmsg_get_u32(tb_client_assoc_event[CLIENT_ASSOC_RSSI]);
timestamp =
blobmsg_get_u32(tb_client_assoc_event[CLIENT_ASSOC_TIMESTAMP]);
internal_sc = blobmsg_get_u32(
tb_client_assoc_event[CLIENT_ASSOC_INTERNAL_SC]);
using11k =
blobmsg_get_bool(tb_client_assoc_event[CLIENT_ASSOC_USING11K]);
using11r =
blobmsg_get_bool(tb_client_assoc_event[CLIENT_ASSOC_USING11R]);
using11v =
blobmsg_get_bool(tb_client_assoc_event[CLIENT_ASSOC_USING11V]);
if (tb_client_assoc_event[CLIENT_ASSOC_INTERNAL_SC])
dpp_session->assoc_event->internal_sc = blobmsg_get_u32(tb_client_assoc_event[CLIENT_ASSOC_INTERNAL_SC]);
assoc_event_dpp = calloc(1, sizeof(dpp_event_record_assoc_t));
if (tb_client_assoc_event[CLIENT_ASSOC_RSSI])
dpp_session->assoc_event->rssi = blobmsg_get_u32(tb_client_assoc_event[CLIENT_ASSOC_RSSI]);
strcpy(assoc_event_dpp->sta_mac, mac_address);
memcpy(assoc_event_dpp->ssid, ssid, ssid_bytes + 1);
assoc_event_dpp->session_id = session_id;
assoc_event_dpp->timestamp = timestamp;
assoc_event_dpp->band = band;
assoc_event_dpp->assoc_type = assoc_type;
assoc_event_dpp->rssi = rssi;
assoc_event_dpp->internal_sc = internal_sc;
assoc_event_dpp->using11k = using11k;
assoc_event_dpp->using11r = using11r;
assoc_event_dpp->using11v = using11v;
if (tb_client_assoc_event[CLIENT_ASSOC_BAND])
dpp_session->assoc_event->band = frequency_to_band(blobmsg_get_u32(tb_client_assoc_event[CLIENT_ASSOC_BAND]));
if (!ds_dlist_is_empty(&dpp_session->assoc_list))
ds_dlist_init(&dpp_session->assoc_list,
dpp_event_record_assoc_t, node);
if (tb_client_assoc_event[CLIENT_ASSOC_ASSOC_TYPE])
dpp_session->assoc_event->assoc_type = blobmsg_get_u8(tb_client_assoc_event[CLIENT_ASSOC_ASSOC_TYPE]);
if (tb_client_assoc_event[CLIENT_ASSOC_USING11K])
dpp_session->assoc_event->using11k = blobmsg_get_bool(tb_client_assoc_event[CLIENT_ASSOC_USING11K]);
if (tb_client_assoc_event[CLIENT_ASSOC_USING11R])
dpp_session->assoc_event->using11r = blobmsg_get_bool(tb_client_assoc_event[CLIENT_ASSOC_USING11R]);
if (tb_client_assoc_event[CLIENT_ASSOC_USING11V])
dpp_session->assoc_event->using11v = blobmsg_get_bool(tb_client_assoc_event[CLIENT_ASSOC_USING11V]);
ds_dlist_insert_tail(&dpp_session->assoc_list, assoc_event_dpp);
return 0;
}
static int (*event_handler_list[__CLIENT_EVENTS_MAX - 1])(
static int (*client_event_handler_list[__CLIENT_EVENTS_MAX - 1])(
struct blob_attr *msg, dpp_event_record_session_t *dpp_session,
uint64_t session_id) = {
client_assoc_event_cb, client_auth_event_cb,
@@ -377,7 +327,15 @@ static int (*event_handler_list[__CLIENT_EVENTS_MAX - 1])(
client_first_data_event_cb, NULL,
};
static void ubus_collector_cb(struct ubus_request *req, int type,
static void ubus_collector_complete_session_cb(struct ubus_request *req, int ret)
{
LOG(DEBUG, "ubus_collector_complete_session_cb");
if (req)
free(req);
}
static void ubus_collector_session_cb(struct ubus_request *req, int type,
struct blob_attr *msg)
{
int error = 0;
@@ -385,163 +343,143 @@ static void ubus_collector_cb(struct ubus_request *req, int type,
struct blob_attr *tb_sessions[__UBUS_SESSIONS_MAX] = {};
struct blob_attr *tb_session = NULL;
struct blob_attr *tb_client_events[__CLIENT_EVENTS_MAX] = {};
dpp_event_record_t *dpp_client_session = NULL;
dpp_event_record_session_t *dpp_session = NULL;
dpp_event_record_t *event_record = NULL;
uint64_t session_id = 0;
int session_no = 0;
char event_message[128] = {};
delete_entry_t *delete_entry = NULL;
char *bss = req->priv;
int i = 0;
(void)type;
if (!msg)
goto error_out;
char *ifname = (char *)req->priv;
LOG(INFO, "ubus_collector: received ubus collector message");
dpp_event_record_t *old_session = NULL;
ds_dlist_iter_t session_iter;
/* First remove all the old sessions from the global report which are already consumed by sm_events */
for (old_session = ds_dlist_ifirst(&session_iter, &g_event_report.client_event_list); old_session != NULL; old_session = ds_dlist_inext(&session_iter)) {
if (old_session && old_session->hasSMProcessed) {
ds_dlist_iremove(&session_iter);
dpp_event_record_free(old_session);
old_session = NULL;
}
}
if (!msg)
return;
error = blobmsg_parse(ubus_collector_sessions_policy,
__UBUS_SESSIONS_MAX, tb_sessions,
blobmsg_data(msg), blobmsg_data_len(msg));
if (error || !tb_sessions[UBUS_COLLECTOR_SESSIONS]) {
LOG(INFO,
"ubus_collector: failed while parsing session policy");
goto error_out;
LOG(ERR, "ubus_collector: failed while parsing session policy");
return;
}
dpp_client_session = calloc(1, sizeof(dpp_event_record_t));
if (!dpp_client_session) {
LOG(INFO,
"ubus_collector: not enough memory for dpp_client_session");
goto error_out;
}
ds_dlist_init(&dpp_client_session->client_session,
dpp_event_record_session_t, node);
/* Iterating on multiple ClientSession types */
blobmsg_for_each_attr(tb_session, tb_sessions[UBUS_COLLECTOR_SESSIONS],
rem)
{
dpp_session = calloc(1, sizeof(dpp_event_record_session_t));
if (!dpp_session) {
LOG(INFO,
"ubus_collector: not enough memory for dpp_session");
goto error_out;
}
error = blobmsg_parse(client_session_events_policy,
__CLIENT_EVENTS_MAX, tb_client_events,
blobmsg_data(tb_session),
blobmsg_data_len(tb_session));
if (error) {
LOG(INFO,
"ubus_collector: failed while parsing client session events policy");
goto error_out;
if (error || !tb_client_events[CLIENT_SESSION_ID]) {
LOG(ERR, "ubus_collector: failed while parsing client session events policy");
continue;
}
session_no++;
LOG(INFO, "ubus_collector: processing session no %d",
session_no);
event_record = dpp_event_record_alloc();
if (!tb_client_events[CLIENT_SESSION_ID]) {
LOG(INFO,
"ubus_collector: failed while getting client session_id");
goto error_out;
if (!event_record) {
LOG(ERR, "ubus_collector: not enough memory for event_record");
continue;
}
session_id =
blobmsg_get_u64(tb_client_events[CLIENT_SESSION_ID]);
dpp_session->session_id = session_id;
session_id = blobmsg_get_u64(tb_client_events[CLIENT_SESSION_ID]);
event_record->client_session.session_id = session_id;
for (i = 0; i < __CLIENT_EVENTS_MAX - 1; i++) {
if (tb_client_events[i]) {
snprintf(event_message, sizeof(event_message),
"%s",
client_session_events_policy[i].name);
LOG(INFO, "ubus_collector: processing %s",
event_message);
if (!event_handler_list[i]) {
snprintf(
event_message,
sizeof(event_message),
"Event %s - handler not implemented",
client_session_events_policy[i]
.name);
LOG(INFO, "ubus_collector: %s",
event_message);
if (!client_event_handler_list[i]) {
LOG(ERR, "ubus_collector: Event handler not implemented");
continue;
}
error = event_handler_list[i](
tb_client_events[i], dpp_session,
client_event_handler_list[i](
tb_client_events[i], &event_record->client_session,
session_id);
if (error) {
LOG(INFO,
"ubus_collector: failed in event handler");
goto error_out;
}
}
}
ds_dlist_insert_tail(&dpp_client_session->client_session,
dpp_session);
dpp_session = NULL;
event_record->hasSMProcessed = false;
ds_dlist_insert_tail(&g_event_report.client_event_list, event_record);
event_record = NULL;
/* Schedule session for deletion */
delete_entry = calloc(1, sizeof(delete_entry_t));
delete_entry->session_id = session_id;
delete_entry->bss = strdup(bss);
ds_dlist_insert_tail(&deletion_pending->list, delete_entry);
delete_entry = NULL;
if (delete_entry) {
memset(delete_entry, 0, sizeof(delete_entry_t));
delete_entry->session_id = session_id;
strncpy(delete_entry->bss, ifname, UBUS_OBJ_LEN);
ds_dlist_insert_tail(&deletion_pending_list, delete_entry);
delete_entry = NULL;
}
}
/* Move all the sessions received from hostapd to global list accessible from sm_events */
if (session_no)
ds_dlist_insert_tail(&g_report_data.list, dpp_client_session);
goto out;
error_out:
free(dpp_session);
free(dpp_client_session);
return;
out:
LOG(INFO, "ubus_collector: successfull parse for AP object");
}
static void ubus_collector_complete_cb(struct ubus_request *req, int ret)
static void ubus_collector_hostapd_invoke(void *object_path)
{
LOG(INFO, "ubus_collector: finished processing");
free(req);
return;
}
static void ubus_collector_hostapd_invoke(void *arg)
{
uint32_t ubus_object_id = 0;
const char *object_path = arg;
const char *obj_path = object_path;
const char *hostapd_method = "get_sessions";
struct ubus_request *req = malloc(sizeof(struct ubus_request));
if (ubus_lookup_id(ubus, object_path, &ubus_object_id)) {
LOG(INFO, "ubus_collector: could not find ubus object %s",
object_path);
free(req);
if (NULL == object_path) {
LOG(ERR, "ubus_collector_hostapd_invoke: Missing hostapd ubus object");
return;
}
LOG(INFO, "ubus_collector: requesting hostapd data");
ubus_invoke_async(ubus, ubus_object_id, hostapd_method, NULL, req);
struct ubus_request *request = malloc(sizeof(struct ubus_request));
req->data_cb = (ubus_data_handler_t)ubus_collector_cb;
req->complete_cb = (ubus_complete_handler_t)ubus_collector_complete_cb;
req->priv = arg;
if (!request) {
LOG(ERR, "ubus_collector_hostapd_invoke: Failed to allocate ubus request object");
return;
}
ubus_complete_request(ubus, req, 0);
if (ubus_lookup_id(ubus, obj_path, &ubus_object_id)) {
LOG(ERR, "ubus_collector: could not find ubus object %s",
obj_path);
if (request)
free(request);
return;
}
ubus_invoke_async(ubus, ubus_object_id, hostapd_method, NULL, request);
request->data_cb = ubus_collector_session_cb;
request->complete_cb = ubus_collector_complete_session_cb;
request->priv = object_path;
ubus_complete_request_async(ubus, request);
}
static void ubus_collector_complete_bss_cb(struct ubus_request *req, int ret)
{
LOG(DEBUG, "ubus_collector_complete_bss_cb");
if (req)
free(req);
}
static void get_sessions(void * arg)
{
bss_obj_t *bss_record = NULL;
ds_dlist_iter_t record_iter;
if (ds_dlist_is_empty(&bss_list)) {
LOG(NOTICE, "No BSSs to get sessions for");
evsched_task_reschedule();
return;
}
for (bss_record = ds_dlist_ifirst(&record_iter, &bss_list);
bss_record != NULL; bss_record = ds_dlist_inext(&record_iter)) {
ubus_collector_hostapd_invoke(bss_record->obj_name);
}
evsched_task_reschedule();
}
static void ubus_collector_bss_cb(struct ubus_request *req, int type,
@@ -550,157 +488,133 @@ static void ubus_collector_bss_cb(struct ubus_request *req, int type,
int error = 0;
int rem = 0;
struct blob_attr *tb_bss_lst[__BSS_LIST_DATA_MAX] = {};
struct blob_attr *tb_bss_table[__BSS_TABLE_MAX] = {};
struct blob_attr *tb_bss_tbl = NULL;
char *bss_name = NULL;
dpp_event_report_data_t *bss_list = NULL;
delete_entry_t *bss_record = NULL;
bss_obj_t *bss_record = NULL;
ds_dlist_iter_t record_iter;
if (!msg)
return;
LOG(INFO, "ubus_collector: received ubus collector bss message");
error = blobmsg_parse(ubus_collector_bss_list_policy,
__BSS_LIST_DATA_MAX, tb_bss_lst,
blobmsg_data(msg), blobmsg_data_len(msg));
if (error || !tb_bss_lst[BSS_LIST_BSS_LIST]) {
LOG(INFO,
LOG(ERR,
"ubus_collector: failed while parsing bss_list policy");
return;
}
bss_list = calloc(1, sizeof(dpp_event_report_data_t));
ds_dlist_init(&bss_list->list, delete_entry_t, node);
/* itereate bss list */
/* iterate bss list */
blobmsg_for_each_attr(tb_bss_tbl, tb_bss_lst[BSS_LIST_BSS_LIST], rem)
{
bool obj_exists = false;
struct blob_attr *tb_bss_table[__BSS_TABLE_MAX] = {};
error = blobmsg_parse(ubus_collector_bss_table_policy,
__BSS_TABLE_MAX, tb_bss_table,
blobmsg_data(tb_bss_tbl),
blobmsg_data_len(tb_bss_tbl));
if (error) {
LOG(INFO,
"ubus_collector_ failed while parsing bss table policy");
LOG(ERR, "ubus_collector_ failed while parsing bss table policy");
continue;
}
bss_name = strdup(
blobmsg_get_string(tb_bss_table[BSS_TABLE_BSS_NAME]));
if (!bss_name) {
LOG(INFO,
"ubus_collector: failed while getting bss_name");
if (!tb_bss_table[BSS_OBJECT_NAME])
continue;
char *obj_name = blobmsg_get_string(tb_bss_table[BSS_OBJECT_NAME]);
if (!ds_dlist_is_empty(&bss_list)) {
for (bss_record = ds_dlist_ifirst(&record_iter, &bss_list);
bss_record != NULL; bss_record = ds_dlist_inext(&record_iter)) {
if (!strcmp(obj_name, bss_record->obj_name)) {
obj_exists = true;
break;
}
}
}
if (!obj_exists) {
bss_record = calloc(1, sizeof(bss_obj_t));
strncpy(bss_record->obj_name, obj_name, UBUS_OBJ_LEN);
ds_dlist_insert_tail(&bss_list, bss_record);
}
bss_record = malloc(sizeof(delete_entry_t));
bss_record->bss = bss_name;
ds_dlist_insert_tail(&bss_list->list, bss_record);
}
if (ds_dlist_is_empty(&bss_list->list)) {
LOG(INFO, "ubus_collector: no bss entries found");
free(bss_list);
return;
}
/* get sessions from current bss */
for (bss_record = ds_dlist_ifirst(&record_iter, &bss_list->list);
bss_record != NULL; bss_record = ds_dlist_inext(&record_iter)) {
LOG(INFO, "ubus_collector: processing bss %s", bss_record->bss);
ubus_collector_hostapd_invoke(bss_record->bss);
free(bss_record);
}
LOG(INFO, "ubus_collector: scanned all bss objects");
free(bss_list);
return;
}
static void ubus_collector_hostapd_bss_invoke(void *arg)
{
uint32_t ubus_object_id = 0;
const char *object_path = "hostapd";
const char *hostapd_method = "get_bss_list";
struct ubus_request *req = malloc(sizeof(struct ubus_request));
if (ubus_lookup_id(ubus, object_path, &ubus_object_id)) {
LOG(INFO, "ubus_collector: could not find ubus object %s",
LOG(ERR, "ubus_collector: could not find ubus object %s",
object_path);
free(req);
evsched_task_reschedule();
return;
}
LOG(INFO, "ubus_collector: requesting hostapd bss data");
struct ubus_request *req = malloc(sizeof(struct ubus_request));
if (!req) {
LOG(ERR, "Failed to allocate req structure");
return;
}
ubus_invoke_async(ubus, ubus_object_id, hostapd_method, NULL, req);
req->data_cb = (ubus_data_handler_t)ubus_collector_bss_cb;
req->complete_cb = (ubus_complete_handler_t)ubus_collector_complete_cb;
req->data_cb = ubus_collector_bss_cb;
req->complete_cb = ubus_collector_complete_bss_cb;
ubus_complete_request(ubus, req, 0);
ubus_complete_request_async(ubus, req);
evsched_task_reschedule();
}
static void ubus_collector_hostapd_clear(uint64_t session_id, char *bss)
static void ubus_collector_hostapd_clear(uint64_t session_id, char *object_path)
{
uint32_t ubus_object_id = 0;
const char *object_path = bss;
if (NULL == object_path)
return;
const char *hostapd_method = "clear_session";
struct ubus_request *req = malloc(sizeof(struct ubus_request));
if (ubus_lookup_id(ubus, object_path, &ubus_object_id)) {
LOG(INFO,
"ubus_collector: could not find the designated ubus object [%s]",
object_path);
free(req);
LOG(ERR, "ubus_collector: could not find the designated ubus object [%s]", object_path);
return;
}
int l = snprintf(NULL, 0, "%" PRIi64, session_id);
char str[l + 1];
snprintf(str, l + 1, "%" PRIi64, session_id);
blob_buf_init(&b, 0);
blobmsg_add_string(&b, "session_id", str);
blobmsg_add_u64(&b, "session_id", session_id);
LOG(INFO, "ubus_collector: deleting session [%s]", str);
ubus_invoke_async(ubus, ubus_object_id, hostapd_method, b.head, req);
if (UBUS_STATUS_OK != ubus_invoke(ubus, ubus_object_id, hostapd_method, b.head, NULL, NULL, 1000)) {
LOG(ERR, "ubus call to clear session failed");
}
req->data_cb = NULL;
req->complete_cb = (ubus_complete_handler_t)ubus_collector_complete_cb;
ubus_complete_request_async(ubus, req);
}
static void ubus_garbage_collector(void *arg)
{
delete_entry_t *delete_entry = NULL;
if (ds_dlist_is_empty(&deletion_pending->list)) {
if (ds_dlist_is_empty(&deletion_pending_list)) {
evsched_task_reschedule();
return;
}
/* Remove a single session from the deletion list */
LOG(INFO, "ubus_collector: garbage collection");
delete_entry = ds_dlist_head(&deletion_pending->list);
delete_entry = ds_dlist_head(&deletion_pending_list);
if (delete_entry) {
if (delete_entry->session_id)
if (delete_entry->session_id) {
ubus_collector_hostapd_clear(delete_entry->session_id,
delete_entry->bss);
ds_dlist_remove_head(&deletion_pending->list);
free(delete_entry->bss);
delete_entry->bss);
}
ds_dlist_remove_head(&deletion_pending_list);
free(delete_entry);
delete_entry = NULL;
}
evsched_task_reschedule();
@@ -710,34 +624,40 @@ int ubus_collector_init(void)
{
int sched_status = 0;
LOG(INFO, "ubus_collector: initializing");
ubus = ubus_connect(UBUS_SOCKET);
if (!ubus) {
LOG(INFO, "ubus_collector: cannot find ubus socket");
LOG(ERR, "ubus_collector: cannot find ubus socket");
return -1;
}
/* Initialize the global events and event deletion lists */
ds_dlist_init(&g_report_data.list, dpp_event_record_session_t, node);
deletion_pending = calloc(1, sizeof(dpp_event_record_session_t));
ds_dlist_init(&deletion_pending->list, delete_entry_t, node);
/* Initialize the global events, session deletion and bss object lists */
ds_dlist_init(&g_event_report.client_event_list, dpp_event_record_t, node);
ds_dlist_init(&deletion_pending_list, delete_entry_t, node);
ds_dlist_init(&bss_list, bss_obj_t, node);
/* Schedule an event: invoke hostapd ubus get bss list method */
sched_status = evsched_task(&ubus_collector_hostapd_bss_invoke, NULL,
EVSCHED_SEC(UBUS_POLLING_DELAY));
EVSCHED_SEC(UBUS_BSS_POLLING_DELAY));
if (sched_status < 1) {
LOG(INFO, "ubus_collector: failed at task creation, status %d",
LOG(ERR, "ubus_collector: failed at task creation, status %d",
sched_status);
return -1;
}
/* Schedule an event: get sessions for all the BSSs */
sched_status = evsched_task(&get_sessions, NULL,
EVSCHED_SEC(UBUS_SESSIONS_POLLING_DELAY));
if (sched_status < 1) {
LOG(ERR, "ubus_collector: failed at task creation, status %d",
sched_status);
return -1;
}
/* Schedule an event: clear the hostapd sessions from opensync */
sched_status = evsched_task(&ubus_garbage_collector, NULL,
EVSCHED_SEC(UBUS_GARBAGE_COLLECTION_DELAY));
if (sched_status < 1) {
LOG(INFO, "ubus_collector: failed at task creation, status %d",
LOG(ERR, "ubus_collector: failed at task creation, status %d",
sched_status);
return -1;
}
@@ -747,8 +667,5 @@ int ubus_collector_init(void)
void ubus_collector_cleanup(void)
{
LOG(INFO, "ubus_collector: cleaning up ubus collector");
ubus_free(ubus);
free(deletion_pending);
free(ubus_object);
}

View File

@@ -22,22 +22,22 @@ void ubus_collector_cleanup(void);
#define UBUS_SOCKET "/var/run/ubus.sock"
/* Poll ubus after this many seconds */
#define UBUS_POLLING_DELAY 7
/* Poll bss list after this many seconds */
#define UBUS_BSS_POLLING_DELAY 7
/* Poll sessions after this many seconds */
#define UBUS_SESSIONS_POLLING_DELAY 9
/* Poll the session clearing 'garbage collector' after this many seconds */
#define UBUS_GARBAGE_COLLECTION_DELAY 1
#define UBUS_OBJ_LEN 64
enum {
UBUS_COLLECTOR_SESSIONS,
__UBUS_SESSIONS_MAX,
};
enum {
UBUS_CLIENT_SESSION,
__UBUS_SESSION_TYPES_MAX,
};
enum {
CLIENT_ASSOC_EVENT,
CLIENT_AUTH_EVENT,
@@ -100,7 +100,7 @@ enum {
};
enum {
BSS_TABLE_BSS_NAME,
BSS_OBJECT_NAME,
__BSS_TABLE_MAX,
};