Skip to content

Commit 2ae4e40

Browse files
committed
RDKB-59986: Retrieve available radio metrics and sta metrics using NL commands
Reason for change: To retrieve metrics data for supported ones as part of Easymesh's metrics collection Test Procedure: Ensure client device is connected. Risks: Medium Priority: P1 Signed-off-by: Nikita Hakai <[email protected]>
1 parent 969ffa2 commit 2ae4e40

File tree

1 file changed

+189
-3
lines changed

1 file changed

+189
-3
lines changed

platform/raspberry-pi/platform_pi.c

Lines changed: 189 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,163 @@ int wifi_setApRetrylimit(void *priv)
369369
return 0;
370370
}
371371

372+
static int get_channel_stats_handler(struct nl_msg *msg, void *arg)
373+
{
374+
int i, rem;
375+
unsigned int freq;
376+
unsigned char channel;
377+
struct nlattr *tb[NL80211_ATTR_MAX + 1];
378+
struct nlattr *survey_info[NL80211_SURVEY_INFO_MAX + 1];
379+
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
380+
static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
381+
[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
382+
[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_S32 },
383+
[NL80211_SURVEY_INFO_TIME] = { .type = NLA_U64 },
384+
[NL80211_SURVEY_INFO_TIME_BUSY] = { .type = NLA_U64 },
385+
[NL80211_SURVEY_INFO_TIME_EXT_BUSY] = { .type = NLA_U64 },
386+
[NL80211_SURVEY_INFO_TIME_RX] = { .type = NLA_U64 },
387+
[NL80211_SURVEY_INFO_TIME_TX] = { .type = NLA_U64 },
388+
[NL80211_SURVEY_INFO_TIME_SCAN] = { .type = NLA_U64 },
389+
[NL80211_SURVEY_INFO_TIME_BSS_RX] = { .type = NLA_U64 },
390+
};
391+
channel_stats_arr_t *stats = (channel_stats_arr_t *)arg;
392+
393+
for (i = 0; i < stats->arr_size; i++) {
394+
wifi_hal_dbg_print("%s:%d stats->arr[%d].ch_number : %d\n", __func__, __LINE__,
395+
i, stats->arr[i].ch_number);
396+
}
397+
398+
399+
if (nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0),
400+
NULL) < 0) {
401+
wifi_hal_error_print("%s:%d Failed to parse survey data\n", __func__, __LINE__);
402+
return NL_SKIP;
403+
}
404+
405+
if (!tb[NL80211_ATTR_SURVEY_INFO]) {
406+
wifi_hal_error_print("%s:%d Failed to get survey info attribute\n", __func__, __LINE__);
407+
return NL_SKIP;
408+
}
409+
410+
if (nla_parse_nested(survey_info, NL80211_SURVEY_INFO_MAX, tb[NL80211_ATTR_SURVEY_INFO], survey_policy)) {
411+
wifi_hal_error_print("%s:%d Failed to parse nested attributes\n", __func__, __LINE__);
412+
return NL_SKIP;
413+
}
414+
415+
for (i = 0; i <= NL80211_SURVEY_INFO_MAX; i++) {
416+
if (survey_policy[i].type != 0 && survey_info[i] == NULL) {
417+
wifi_hal_stats_error_print("%s:%d Survey info attribute %d is missing\n", __func__,
418+
__LINE__, i);
419+
}
420+
}
421+
422+
freq = nla_get_u32(survey_info[NL80211_SURVEY_INFO_FREQUENCY]);
423+
if (ieee80211_freq_to_chan(freq, &channel) == NUM_HOSTAPD_MODES) {
424+
wifi_hal_stats_error_print("%s:%d Failed to convert frequency %u to channel\n", __func__,
425+
__LINE__, freq);
426+
return NL_SKIP;
427+
}
428+
429+
for (i = 0; i < stats->arr_size && stats->arr[i].ch_number != channel; i++);
430+
if (i == stats->arr_size) {
431+
//continue;
432+
wifi_hal_dbg_print("%s:%d continue - return\n", __func__, __LINE__);
433+
return NL_SKIP;
434+
}
435+
436+
if (survey_info[NL80211_SURVEY_INFO_FREQUENCY]) {
437+
wifi_hal_dbg_print("%s:%d FREQUENCY: %u MHz\n", __func__, __LINE__,
438+
nla_get_u32(survey_info[NL80211_SURVEY_INFO_FREQUENCY]));
439+
}
440+
if (survey_info[NL80211_SURVEY_INFO_NOISE]) {
441+
stats->arr[i].ch_noise =
442+
nla_get_s32(survey_info[NL80211_SURVEY_INFO_NOISE]);
443+
}
444+
if (survey_info[NL80211_SURVEY_INFO_TIME]) {
445+
stats->arr[i].ch_utilization_total =
446+
nla_get_u64(survey_info[NL80211_SURVEY_INFO_TIME]);
447+
}
448+
if (survey_info[NL80211_SURVEY_INFO_TIME_BUSY]) {
449+
stats->arr[i].ch_utilization_busy =
450+
nla_get_u64(survey_info[NL80211_SURVEY_INFO_TIME_BUSY]);
451+
}
452+
453+
if (survey_info[NL80211_SURVEY_INFO_TIME_TX]) {
454+
stats->arr[i].ch_utilization_busy_tx =
455+
nla_get_u64(survey_info[NL80211_SURVEY_INFO_TIME_TX]);
456+
}
457+
458+
if (survey_info[NL80211_SURVEY_INFO_TIME_EXT_BUSY]) {
459+
stats->arr[i].ch_utilization_busy_ext =
460+
nla_get_u64(survey_info[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
461+
}
462+
463+
if (survey_info[NL80211_SURVEY_INFO_TIME_RX]) {
464+
stats->arr[i].ch_utilization_busy_rx =
465+
nla_get_u64(survey_info[NL80211_SURVEY_INFO_TIME_RX]);
466+
}
467+
468+
if (survey_info[NL80211_SURVEY_INFO_TIME_SCAN]) {
469+
}
470+
471+
if (survey_info[NL80211_SURVEY_INFO_TIME_BSS_RX]) {
472+
}
473+
474+
return NL_SKIP;
475+
}
476+
477+
static int get_channel_stats(wifi_interface_info_t *interface,
478+
wifi_channelStats_t *channel_stats_arr, int channel_stats_arr_size)
479+
{
480+
struct nl_msg *msg;
481+
int ret = RETURN_ERR;
482+
channel_stats_arr_t stats = { .arr = channel_stats_arr, .arr_size = channel_stats_arr_size };
483+
484+
msg = nl80211_drv_cmd_msg(g_wifi_hal.nl80211_id, interface, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
485+
if (msg == NULL) {
486+
wifi_hal_stats_error_print("%s:%d Failed to create NL command\n", __func__, __LINE__);
487+
return RETURN_ERR;
488+
}
489+
490+
ret = nl80211_send_and_recv(msg, get_channel_stats_handler, &stats, NULL, NULL);
491+
if (ret) {
492+
wifi_hal_stats_error_print("%s:%d Failed to send NL message\n", __func__, __LINE__);
493+
return RETURN_ERR;
494+
}
495+
496+
return RETURN_OK;
497+
}
372498

373499
INT wifi_getRadioChannelStats(INT radioIndex, wifi_channelStats_t *input_output_channelStats_array,
374500
INT array_size)
375501
{
502+
wifi_radio_info_t *radio;
503+
wifi_interface_info_t *interface;
504+
505+
wifi_hal_stats_dbg_print("%s:%d: Get radio stats for index: %d\n", __func__, __LINE__,
506+
radioIndex);
507+
508+
radio = get_radio_by_rdk_index(radioIndex);
509+
if (radio == NULL) {
510+
wifi_hal_stats_error_print("%s:%d: Failed to get radio for index: %d\n", __func__, __LINE__,
511+
radioIndex);
512+
return RETURN_ERR;
513+
}
514+
515+
interface = get_primary_interface(radio);
516+
if (interface == NULL) {
517+
wifi_hal_stats_error_print("%s:%d: Failed to get interface for radio index: %d\n", __func__,
518+
__LINE__, radioIndex);
519+
return RETURN_ERR;
520+
}
521+
if (get_channel_stats(interface, input_output_channelStats_array, array_size)) {
522+
wifi_hal_stats_error_print("%s:%d: Failed to get channel stats for radio index: %d\n", __func__,
523+
__LINE__, radioIndex);
524+
return RETURN_ERR;
525+
}
376526
return RETURN_OK;
377527
}
528+
378529
//--------------------------------------------------------------------------------------------------
379530
INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
380531
{
@@ -518,43 +669,78 @@ static int get_sta_stats_handler(struct nl_msg *msg, void *arg)
518669
}
519670

520671
if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, tb[NL80211_ATTR_STA_INFO], stats_policy)) {
521-
wifi_hal_error_print("%s:%d Failed to parse nested attributes\n", __func__, __LINE__);
672+
wifi_hal_error_print("%s:%d Failed to parse nested attributes\n", __func__, __LINE__);
522673
return NL_SKIP;
523674
}
524675

525676
if (stats[NL80211_STA_INFO_RX_BYTES]) {
677+
wifi_hal_dbg_print("%s:%d cli_BytesReceived: %d\n", __func__, __LINE__, nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]));
526678
dev->cli_BytesReceived = nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
527679
}
528680
if (stats[NL80211_STA_INFO_TX_BYTES]) {
681+
wifi_hal_dbg_print("%s:%d cli_BytesSent: %d\n", __func__, __LINE__, nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]));
529682
dev->cli_BytesSent = nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
530683
}
531684
if (stats[NL80211_STA_INFO_RX_PACKETS]) {
685+
wifi_hal_dbg_print("%s:%d cli_PacketsReceived: %d\n", __func__, __LINE__, nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]));
532686
dev->cli_PacketsReceived = nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
533687
}
534688
if (stats[NL80211_STA_INFO_TX_PACKETS]) {
689+
wifi_hal_dbg_print("%s:%d cli_PacketsSent: %d\n", __func__, __LINE__, nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]));
535690
dev->cli_PacketsSent = nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
536691
}
537692
if (stats[NL80211_STA_INFO_TX_FAILED]) {
693+
wifi_hal_dbg_print("%s:%d cli_ErrorsSent: %d\n", __func__, __LINE__, nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]));
538694
dev->cli_ErrorsSent = nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
539695
}
540696

697+
if (stats[NL80211_STA_INFO_RX_DROP_MISC]) {
698+
dev->cli_RxErrors = nla_get_u32(stats[NL80211_STA_INFO_RX_DROP_MISC]);
699+
wifi_hal_dbg_print("%s:%d cli_RxErrors: %d\n", __func__, __LINE__, dev->cli_RxErrors);
700+
}
701+
702+
if (stats[NL80211_STA_INFO_TX_RETRIES]) {
703+
dev->cli_RetransCount = nla_get_s32(stats[NL80211_STA_INFO_TX_RETRIES]);
704+
wifi_hal_dbg_print("%s:%d cli_RetransCount: %d\n", __func__, __LINE__, dev->cli_RetransCount);
705+
}
706+
707+
if (stats[NL80211_STA_INFO_SIGNAL_AVG]) {
708+
dev->cli_RSSI = nla_get_s32(stats[NL80211_STA_INFO_SIGNAL_AVG]);
709+
dev->cli_SignalStrength = dev->cli_RSSI;
710+
wifi_hal_dbg_print("%s:%d cli_RSSI: %d\n", __func__, __LINE__, dev->cli_RSSI);
711+
}
712+
541713
if (stats[NL80211_STA_INFO_TX_BITRATE] &&
542714
nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], rate_policy) == 0) {
543715
if (rate[NL80211_RATE_INFO_BITRATE32]){
544-
dev->cli_LastDataDownlinkRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]) * 100;
716+
wifi_hal_dbg_print("%s:%d cli_LastDataDownlinkRate: %d\n", __func__, __LINE__, nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]));
717+
dev->cli_LastDataDownlinkRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]) * 1000;
545718
}
546719
}
720+
547721
if (stats[NL80211_STA_INFO_RX_BITRATE] &&
548722
nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], rate_policy) == 0) {
549723
if (rate[NL80211_RATE_INFO_BITRATE32]) {
550-
dev->cli_LastDataUplinkRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]) * 100;
724+
wifi_hal_dbg_print("%s:%d cli_LastDataUplinkRate: %d\n", __func__, __LINE__, nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]));
725+
dev->cli_LastDataUplinkRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]) * 1000;
551726
}
552727
}
553728

729+
if (stats[NL80211_STA_INFO_TX_DURATION]) {
730+
wifi_hal_dbg_print("%s:%d tx duration: %d\n", __func__, __LINE__, nla_get_u32(stats[NL80211_STA_INFO_TX_DURATION]));
731+
dev->cli_tx_duration = nla_get_u32(stats[NL80211_STA_INFO_TX_DURATION]);
732+
}
733+
734+
if (stats[NL80211_STA_INFO_RX_DURATION]) {
735+
wifi_hal_dbg_print("%s:%d rx duration: %d\n", __func__, __LINE__, nla_get_u32(stats[NL80211_STA_INFO_RX_DURATION]));
736+
dev->cli_rx_duration = nla_get_u32(stats[NL80211_STA_INFO_RX_DURATION]);
737+
}
738+
554739
if (stats[NL80211_STA_INFO_STA_FLAGS]) {
555740
sta_flags = nla_data(stats[NL80211_STA_INFO_STA_FLAGS]);
556741
dev->cli_AuthenticationState = sta_flags->mask & (1 << NL80211_STA_FLAG_AUTHORIZED) &&
557742
sta_flags->set & (1 << NL80211_STA_FLAG_AUTHORIZED);
743+
wifi_hal_dbg_print("%s:%d cli_AuthenticationState: %d\n", __func__, __LINE__, dev->cli_AuthenticationState);
558744
}
559745

560746
return NL_OK;

0 commit comments

Comments
 (0)