Index: opensync-2.0.5.0/src/lib/datapipeline/inc/dpp_network_probe.h =================================================================== --- /dev/null +++ opensync-2.0.5.0/src/lib/datapipeline/inc/dpp_network_probe.h @@ -0,0 +1,77 @@ +#ifndef DPP_NETWORK_PROBE_H_INCLUDED +#define DPP_NETWORK_PROBE_H_INCLUDED + +#include "ds.h" +#include "ds_dlist.h" + +#include "dpp_types.h" + +#define MAX_IP_ADDR_SIZE 16 + +typedef enum +{ + SUD_down = 0, + SUD_up = 1, + SUD_error = 2 +}StateUpDown_t; + +/* dns probe metrics */ +typedef struct +{ + char serverIP[MAX_IP_ADDR_SIZE]; + StateUpDown_t state; + uint32_t latency; +} dpp_dns_metrics_t; + +/* VLAN probe metrics */ +typedef struct +{ + char* vlanIF; + StateUpDown_t dhcpState; + uint32_t dhcpLatency; + StateUpDown_t dnsState; + uint32_t dnsLatency; + StateUpDown_t obsV200_radiusState; + uint32_t obsV200_radiusLatency; + dpp_dns_metrics_t dnsProbeResults; + uint32_t dur_vlanIF; + uint32_t dur_dhcpState; + uint32_t dur_dhcpLatency; + uint32_t dur_dnsState; + uint32_t dur_dnsLatency; + uint32_t dur_dnsReport; +} dpp_vlan_metrics_t; + + +/* Radius probe metrics */ +typedef struct +{ + char serverIP[MAX_IP_ADDR_SIZE]; + uint32_t noAnswer; + uint32_t latencyMin; + uint32_t latencyMax; + uint32_t latencyAve; + + // -- duration + uint32_t dur_serverIP; //category Network + uint32_t dur_noAnswer; //category Network + uint32_t dur_latencyMin; //category Network + uint32_t dur_latencyMax; //category Network + uint32_t dur_latencyAve; //category Network +} dpp_radius_metrics_t; + +typedef struct +{ + dpp_dns_metrics_t dns_probe; + dpp_vlan_metrics_t vlan_probe; + dpp_radius_metrics_t radius_probe; +} dpp_network_probe_record_t; + + +typedef struct +{ + dpp_network_probe_record_t record; + uint64_t timestamp_ms; +} dpp_network_probe_report_data_t; + +#endif /* DPP_NETWORK_PROBE_H_INCLUDED */ 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 @@ -63,6 +63,7 @@ typedef enum DPP_T_DEVICE = 5, DPP_T_BS_CLIENT = 6, DPP_T_RSSI = 7, + DPP_T_NETWORK_PROBE =8, } DPP_STS_TYPE; uint32_t queue_depth; @@ -90,6 +91,13 @@ typedef struct uint64_t timestamp_ms; } dppline_client_stats_t; +typedef struct dpp_network_probe_stats +{ + dpp_network_probe_record_t record; + uint32_t qty; + uint64_t timestamp_ms; +} dppline_network_probe_stats_t; + typedef struct { radio_type_t radio_type; @@ -168,6 +176,7 @@ typedef struct dpp_stats dppline_device_stats_t device; dppline_bs_client_stats_t bs_client; dppline_rssi_stats_t rssi; + dppline_network_probe_stats_t network_probe; } u; } dppline_stats_t; @@ -221,6 +230,8 @@ static void dppline_free_stat(dppline_st } free(s->u.rssi.list); break; + case DPP_T_NETWORK_PROBE: + break; default:; } @@ -632,7 +643,13 @@ static bool dppline_copysts(dppline_stat } } break; - + case DPP_T_NETWORK_PROBE: + { + dpp_network_probe_report_data_t *report_data = sts; + memcpy(&dst->u.network_probe.record.dns_probe, &report_data->record.dns_probe, sizeof(dpp_dns_metrics_t)); + dst->u.network_probe.timestamp_ms = report_data->timestamp_ms; + } + break; default: LOG(ERR, "Failed to copy %d stats", dst->type); /* do nothing */ @@ -1566,6 +1583,44 @@ static void dppline_add_stat_capacity(St s->u.capacity.numrec * sizeof(**sr->queue_list)); */ } +static void dppline_add_stat_network_probe(Sts__Report *r, dppline_stats_t *s) +{ + Sts__NetworkProbe *sr = NULL; + int size = 0; + dppline_network_probe_stats_t *network_probe = &s->u.network_probe; + + // increase the number of devices + r->n_network_probe++; + + // allocate or extend the size of devices + r->network_probe = realloc(r->network_probe, + r->n_network_probe * sizeof(Sts__NetworkProbe*)); + size += sizeof(Sts__NetworkProbe*); + + // allocate new buffer Sts__Device + sr = malloc(sizeof(Sts__NetworkProbe)); + size += sizeof(Sts__NetworkProbe); + assert(sr); + r->network_probe[r->n_network_probe - 1] = sr; + + sts__network_probe__init(sr); + sr->timestamp_ms = network_probe->timestamp_ms; + sr->has_timestamp_ms = true; + + sr->dns_probe = malloc(sizeof(*sr->dns_probe)); + size += sizeof(*sr->dns_probe); + assert(sr->dns_probe); + sts__dnsprobe_metric__init(sr->dns_probe); + //memcpy(sr->dns_probe->serverip.data, network_probe->record.dns_probe.serverIP, 4); + sr->dns_probe->serverip = strdup(network_probe->record.dns_probe.serverIP); + size += strlen(network_probe->record.dns_probe.serverIP) + 1; + sr->dns_probe->state = network_probe->record.dns_probe.state; + sr->dns_probe->has_state = true; + sr->dns_probe->latency = network_probe->record.dns_probe.latency; + sr->dns_probe->has_latency = true; + +} + static void dppline_add_stat_bs_client(Sts__Report * r, dppline_stats_t * s) { Sts__BSReport *sr = NULL; @@ -1574,7 +1629,6 @@ static void dppline_add_stat_bs_client(S Sts__BSClient__BSEvent *er; dppline_bs_client_stats_t *bs_client = &s->u.bs_client; - uint32_t client, band, event, band_report; if (0 == bs_client->qty) { @@ -1967,6 +2021,9 @@ static void dppline_add_stat(Sts__Report case DPP_T_RSSI: dppline_add_stat_rssi(r, s); break; + case DPP_T_NETWORK_PROBE: + dppline_add_stat_network_probe(r, s); + break; default: LOG(ERR, "Failed to add %d to stats report", s->type); @@ -2124,6 +2181,14 @@ bool dpp_put_rssi(dpp_rssi_report_data_t } /* + * Put network probe stats to internal queue + */ +bool dpp_put_network_probe(dpp_network_probe_report_data_t * rpt) +{ + return dppline_put(DPP_T_NETWORK_PROBE, rpt); +} + +/* * Create the protobuf buff and copy it to given buffer */ #ifndef DPP_FAST_PACK Index: opensync-2.0.5.0/src/lib/target/inc/target_common.h =================================================================== --- opensync-2.0.5.0.orig/src/lib/target/inc/target_common.h +++ opensync-2.0.5.0/src/lib/target/inc/target_common.h @@ -559,6 +559,11 @@ bool target_stats_scan_get( /// @{ /****************************************************************************** + * NETWORK PROBE definitions + *****************************************************************************/ +bool target_stats_network_probe_get(dpp_network_probe_record_t *network_probe_report); + +/****************************************************************************** * DEVICE definitions *****************************************************************************/ Index: opensync-2.0.5.0/src/sm/src/sm.h =================================================================== --- opensync-2.0.5.0.orig/src/sm/src/sm.h +++ opensync-2.0.5.0/src/sm/src/sm.h @@ -155,6 +155,12 @@ bool sm_device_report_request( sm_stats_request_t *request); /****************************************************************************** + * NETWORK PROBE REPORT definitions + *****************************************************************************/ +bool sm_network_probe_report_request( + sm_stats_request_t *request); + +/****************************************************************************** * SURVEY_REPORT definitions *****************************************************************************/ bool sm_survey_report_request( @@ -264,6 +270,7 @@ typedef enum STS_REPORT_ESSID, STS_REPORT_DEVICE, STS_REPORT_RSSI, + STS_REPORT_NETWORK_PROBE, STS_REPORT_MAX, STS_REPORT_ERROR = STS_REPORT_MAX } sm_report_type_t; Index: opensync-2.0.5.0/src/sm/src/sm_network_probe_report.c =================================================================== --- /dev/null +++ opensync-2.0.5.0/src/sm/src/sm_network_probe_report.c @@ -0,0 +1,218 @@ +/* +Copyright (c) 2015, Plume Design Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the Plume Design Inc. nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Plume Design Inc. BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sm.h" + +#define MODULE_ID LOG_MODULE_ID_MAIN + + +/* new part */ +typedef struct +{ + bool initialized; + + /* Internal structure used to lower layer radio selection */ + ev_timer report_timer; + + /* Structure containing cloud request timer params */ + sm_stats_request_t request; + /* Structure pointing to upper layer network probe storage */ + dpp_network_probe_report_data_t report; + + /* Reporting start timestamp used for reporting timestamp calculation */ + uint64_t report_ts; +} sm_network_probe_ctx_t; + +/* Common place holder for all neighbor stat report contexts */ +static sm_network_probe_ctx_t g_sm_network_probe_ctx; + +/****************************************************************************** + * PROTECTED definitions + *****************************************************************************/ +static +bool dpp_network_probe_report_timer_set( + ev_timer *timer, + bool enable) +{ + if (enable) { + ev_timer_again(EV_DEFAULT, timer); + } + else { + ev_timer_stop(EV_DEFAULT, timer); + } + + return true; +} + + +static +bool dpp_network_probe_report_timer_restart( + ev_timer *timer) +{ + sm_network_probe_ctx_t *network_probe_ctx = + (sm_network_probe_ctx_t *) timer->data; + sm_stats_request_t *request_ctx = + &network_probe_ctx->request; + + if (request_ctx->reporting_count) { + request_ctx->reporting_count--; + + LOG(DEBUG, + "Updated network probe reporting count=%d", + request_ctx->reporting_count); + + /* If reporting_count becomes zero, then stop reporting */ + if (0 == request_ctx->reporting_count) { + dpp_network_probe_report_timer_set(timer, false); + + LOG(DEBUG, + "Stopped network probe reporting (count expired)"); + return true; + } + } + + return true; +} + +static +void sm_network_probe_report (EV_P_ ev_timer *w, int revents) +{ + bool rc; + + sm_network_probe_ctx_t *network_probe_ctx = + (sm_network_probe_ctx_t *) w->data; + dpp_network_probe_report_data_t *report_ctx = + &network_probe_ctx->report; + sm_stats_request_t *request_ctx = + &network_probe_ctx->request; + ev_timer *report_timer = + &network_probe_ctx->report_timer; + + dpp_network_probe_report_timer_restart(report_timer); + + /* Get network probe stats */ + rc = + target_stats_network_probe_get ( + &report_ctx->record); + if (true != rc) { + return; + } + + LOG(DEBUG, + "Sending network probe"); + + /* Report_timestamp is base-timestamp + relative start time offset */ + report_ctx->timestamp_ms = + request_ctx->reporting_timestamp - network_probe_ctx->report_ts + + get_timestamp(); + + LOG(INFO, + "Sending network probe report at '%s' , latency : '%d'", + sm_timestamp_ms_to_date(report_ctx->timestamp_ms), report_ctx->record.dns_probe.latency); + + dpp_put_network_probe(report_ctx); +} + + +/****************************************************************************** + * PUBLIC API definitions + *****************************************************************************/ +bool sm_network_probe_report_request( + sm_stats_request_t *request) +{ + sm_network_probe_ctx_t *network_probe_ctx = + &g_sm_network_probe_ctx; + sm_stats_request_t *request_ctx = + &network_probe_ctx->request; + dpp_network_probe_report_data_t *report_ctx = + &network_probe_ctx->report; + ev_timer *report_timer = + &network_probe_ctx->report_timer; + + + if (NULL == request) { + LOG(ERR, + "Initializing network probe reporting " + "(Invalid request config)"); + return false; + } + + /* Initialize global stats only once */ + if (!network_probe_ctx->initialized) { + memset(request_ctx, 0, sizeof(*request_ctx)); + memset(report_ctx, 0, sizeof(*report_ctx)); + + LOG(INFO, + "Initializing network probe reporting"); + + /* Initialize event lib timers and pass the global + internal cache + */ + ev_init (report_timer, sm_network_probe_report); + report_timer->data = network_probe_ctx; + + network_probe_ctx->initialized = true; + } + + /* Store and compare every request parameter ... + memcpy would be easier but we want some debug info + */ + REQUEST_VAL_UPDATE("network_probe", reporting_count, "%d"); + REQUEST_VAL_UPDATE("network_probe", reporting_interval, "%d"); + REQUEST_VAL_UPDATE("network_probe", reporting_timestamp, "%"PRIu64""); + + /* Restart timers with new parameters */ + dpp_network_probe_report_timer_set(report_timer, false); + + if (request_ctx->reporting_interval) { + network_probe_ctx->report_ts = get_timestamp(); + report_timer->repeat = request_ctx->reporting_interval; + dpp_network_probe_report_timer_set(report_timer, true); + + LOG(INFO, "Started network probe reporting"); + } + else { + LOG(INFO, "Stopped network probe reporting"); + memset(request_ctx, 0, sizeof(*request_ctx)); + } + + return true; +} Index: opensync-2.0.5.0/src/sm/src/sm_ovsdb.c =================================================================== --- opensync-2.0.5.0.orig/src/sm/src/sm_ovsdb.c +++ opensync-2.0.5.0/src/sm/src/sm_ovsdb.c @@ -61,6 +61,7 @@ char *sm_report_type_str[STS_REPORT_MAX] "essid", "device", "rssi", + "network_probe", }; #ifndef CONFIG_MANAGER_QM @@ -357,6 +358,9 @@ bool sm_update_stats_config(sm_stats_con case STS_REPORT_RSSI: sm_rssi_report_request(&radio->config, &req); break; + case STS_REPORT_NETWORK_PROBE: + sm_network_probe_report_request(&req); + break; default: return false; } Index: opensync-2.0.5.0/src/sm/unit.mk =================================================================== --- opensync-2.0.5.0.orig/src/sm/unit.mk +++ opensync-2.0.5.0/src/sm/unit.mk @@ -43,6 +43,7 @@ UNIT_SRC += src/sm_survey_report.c UNIT_SRC += src/sm_radio_config.c UNIT_SRC += src/sm_scan_schedule.c UNIT_SRC += src/sm_rssi_report.c +UNIT_SRC += src/sm_network_probe_report.c UNIT_SRC += src/sm_common.c ifeq ($(CONFIG_SM_CAPACITY_QUEUE_STATS),y) Index: opensync-2.0.5.0/src/lib/datapipeline/inc/dppline.h =================================================================== --- opensync-2.0.5.0.orig/src/lib/datapipeline/inc/dppline.h +++ opensync-2.0.5.0/src/lib/datapipeline/inc/dppline.h @@ -45,6 +45,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBI #include "dpp_client.h" #include "dpp_bs_client.h" #include "dpp_rssi.h" +#include "dpp_network_probe.h" #ifdef CONFIG_MANAGER_QM // QM does queue-ing of reports when offline on it's own, so dpp needs @@ -91,6 +92,11 @@ bool dpp_put_capacity(dpp_capacity_repor bool dpp_put_device(dpp_device_report_data_t * rpt); /* + * Insert network probe stats dpp internal queue + */ +bool dpp_put_network_probe(dpp_network_probe_report_data_t * rpt); + +/* * Insert band steering stats into dpp internal queue */ bool dpp_put_bs_client(dpp_bs_client_report_data_t * rpt);