diff --git a/source/apps/whix/wifi_whix.c b/source/apps/whix/wifi_whix.c index 15aa1cf67..a2481242e 100644 --- a/source/apps/whix/wifi_whix.c +++ b/source/apps/whix/wifi_whix.c @@ -556,74 +556,135 @@ static void upload_client_debug_stats_acs_stats(INT apIndex) } } +int telemetry_stats_timeout_handler(void *arg) +{ + whix_stats_op_t *guard = (whix_stats_op_t *)arg; + + if (guard != NULL && guard->is_done == false) { + if (guard->fp != NULL) { + wifi_util_error_print(WIFI_APPS, + "WIFI_TELEMETRY: dmesg hang detected! Force-closing pipe.\n"); + v_secure_pclose(guard->fp); + guard->fp = NULL; + } + } + return 0; +} + static void upload_client_debug_stats_sta_fa_info(INT apIndex, sta_data_t *sta) { INT len = 0; char *value = NULL; char *saveptr = NULL; char *ptr = NULL; - FILE *fp = NULL; - char tmp[128] = {0}; + FILE *fp = NULL; + char tmp[128] = { 0 }; sta_key_t sta_key; - char buf[CLIENT_STATS_MAX_LEN_BUF] = {0}; + char buf[CLIENT_STATS_MAX_LEN_BUF] = { 0 }; + wifi_ctrl_t *ctrl = (wifi_ctrl_t *)get_wifictrl_obj(); + int timer_id = -1; - memset (buf, 0, CLIENT_STATS_MAX_LEN_BUF); + memset(buf, 0, CLIENT_STATS_MAX_LEN_BUF); if (sta != NULL) { - fp = (FILE *)v_secure_popen("r", "dmesg | grep FA_INFO_%s | tail -1", to_sta_key(sta->sta_mac, sta_key)); + whix_stats_op_t *guard = (whix_stats_op_t *)malloc(sizeof(whix_stats_op_t)); + if (guard == NULL) + return; + + fp = (FILE *)v_secure_popen("r", "dmesg | grep FA_INFO_%s | tail -1", + to_sta_key(sta->sta_mac, sta_key)); + if (fp) { - fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp); - v_secure_pclose(fp); - len = strlen(buf); - if (len) { + guard->fp = fp; + guard->is_done = false; + + // start the 2-second safe Timer + scheduler_add_timer_task(ctrl->sched, FALSE, &timer_id, + telemetry_stats_timeout_handler, guard, 2000, 1, FALSE); + + // This is the line that used to hang forever. + // Now, if it hangs, the scheduler will close 'fp' after 2s, + // causing fgets to return NULL and allow the thread to continue. + if (fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp) != NULL) { + len = strlen(buf); + } + + guard->is_done = true; + // Cancel the timer task if it hasn't fired yet + if (timer_id != -1) { + scheduler_cancel_timer_task(ctrl->sched, timer_id); + } + + // Close the pipe if the safety handler didn't do it already + if (guard->fp) { + v_secure_pclose(guard->fp); + } + + if (len > 0) { ptr = buf + len; while (len-- && ptr-- && *ptr != ':'); ptr++; + value = strtok_r(ptr, ",", &saveptr); - memset(tmp, 0, sizeof(tmp)); - get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_AID_%d:%s", tmp, apIndex+1, value); + if (value) { + memset(tmp, 0, sizeof(tmp)); + get_formatted_time(tmp); + write_to_file(wifi_health_log, "\n%s WIFI_AID_%d:%s", tmp, apIndex + 1, value); + } + value = strtok_r(NULL, ",", &saveptr); - memset(tmp, 0, sizeof(tmp)); - get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_TIM_%d:%s", tmp, apIndex+1, value); + if (value) { + memset(tmp, 0, sizeof(tmp)); + get_formatted_time(tmp); + write_to_file(wifi_health_log, "\n%s WIFI_TIM_%d:%s", tmp, apIndex + 1, value); + } + value = strtok_r(NULL, ",", &saveptr); - memset(tmp, 0, sizeof(tmp)); - get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_BMP_SET_CNT_%d:%s", tmp, - apIndex+1, value); + if (value) { + memset(tmp, 0, sizeof(tmp)); + get_formatted_time(tmp); + write_to_file(wifi_health_log, "\n%s WIFI_BMP_SET_CNT_%d:%s", tmp, apIndex + 1, + value); + } + value = strtok_r(NULL, ",", &saveptr); - memset(tmp, 0, sizeof(tmp)); - get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_BMP_CLR_CNT_%d:%s", tmp, - apIndex+1, value); + if (value) { + memset(tmp, 0, sizeof(tmp)); + get_formatted_time(tmp); + write_to_file(wifi_health_log, "\n%s WIFI_BMP_CLR_CNT_%d:%s", tmp, apIndex + 1, + value); + } + value = strtok_r(NULL, ",", &saveptr); - memset(tmp, 0, sizeof(tmp)); - get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_TX_PKTS_CNT_%d:%s", tmp, - apIndex+1, value); + if (value) { + memset(tmp, 0, sizeof(tmp)); + get_formatted_time(tmp); + write_to_file(wifi_health_log, "\n%s WIFI_TX_PKTS_CNT_%d:%s", tmp, apIndex + 1, + value); + } + value = strtok_r(NULL, ",", &saveptr); - memset(tmp, 0, sizeof(tmp)); - get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_TX_DISCARDS_CNT_%d:%s", tmp, - apIndex+1, value); + if (value) { + memset(tmp, 0, sizeof(tmp)); + get_formatted_time(tmp); + write_to_file(wifi_health_log, "\n%s WIFI_TX_DISCARDS_CNT_%d:%s", tmp, + apIndex + 1, value); + } + + // Process WIFI_UAPSD value = strtok_r(NULL, ",", &saveptr); - memset(tmp, 0, sizeof(tmp)); - get_formatted_time(tmp); - write_to_file(wifi_health_log, "\n%s WIFI_UAPSD_%d:%s", tmp, - apIndex+1, value); + if (value) { + memset(tmp, 0, sizeof(tmp)); + get_formatted_time(tmp); + write_to_file(wifi_health_log, "\n%s WIFI_UAPSD_%d:%s", tmp, apIndex + 1, + value); + } } - } - else { + } else { wifi_util_error_print(WIFI_APPS, " %s Failed to run popen command\n", __FUNCTION__); } - } - else { + + free(guard); + } else { wifi_util_error_print(WIFI_APPS, "%s NULL sta\n", __FUNCTION__); } } @@ -631,62 +692,75 @@ static void upload_client_debug_stats_sta_fa_info(INT apIndex, sta_data_t *sta) static void upload_client_debug_stats_sta_fa_lmac_data_stats(INT apIndex, sta_data_t *sta) { INT len = 0; - char *value = NULL; - char *saveptr = NULL; - char *ptr = NULL; - FILE *fp = NULL; - char tmp[128] = {0}; + char *value = NULL, *saveptr = NULL, *ptr = NULL; + FILE *fp = NULL; + char tmp[128] = { 0 }; sta_key_t sta_key; - char buf[CLIENT_STATS_MAX_LEN_BUF] = {0}; - memset (buf, 0, CLIENT_STATS_MAX_LEN_BUF); + char buf[CLIENT_STATS_MAX_LEN_BUF] = { 0 }; + wifi_ctrl_t *ctrl = (wifi_ctrl_t *)get_wifictrl_obj(); + int timer_id = -1; if (sta != NULL) { - fp = (FILE *)v_secure_popen("r", "dmesg | grep FA_LMAC_DATA_STATS_%s | tail -1", to_sta_key(sta->sta_mac, sta_key)); + whix_stats_op_t *guard = (whix_stats_op_t *)malloc(sizeof(whix_stats_op_t)); + if (guard == NULL) + return; + + fp = (FILE *)v_secure_popen("r", "dmesg | grep FA_LMAC_DATA_STATS_%s | tail -1", + to_sta_key(sta->sta_mac, sta_key)); if (fp) { - fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp); - v_secure_pclose(fp); - len = strlen(buf); - if (len) { + guard->fp = fp; + guard->is_done = false; + + scheduler_add_timer_task(ctrl->sched, FALSE, &timer_id, telemetry_stats_timeout_handler, + guard, 2000, 1, TRUE); + + if (fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp) != NULL) { + len = strlen(buf); + } + + guard->is_done = true; + if (timer_id != -1) { + scheduler_cancel_timer_task(ctrl->sched, timer_id); + } + + if (guard->fp) + v_secure_pclose(guard->fp); + + if (len > 0) { ptr = buf + len; while (len-- && ptr-- && *ptr != ':'); ptr++; value = strtok_r(ptr, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_DATA_QUEUED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_DATA_QUEUED_CNT_%d:%s", tmp, apIndex + 1, + value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_DATA_DROPPED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_DATA_DROPPED_CNT_%d:%s", tmp, apIndex + 1, + value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_DATA_DEQUED_TX_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_DATA_DEQUED_TX_CNT_%d:%s", tmp, + apIndex + 1, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_DATA_DEQUED_DROPPED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_DATA_DEQUED_DROPPED_CNT_%d:%s", tmp, + apIndex + 1, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_DATA_EXP_DROPPED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_DATA_EXP_DROPPED_CNT_%d:%s", tmp, + apIndex + 1, value); } - } - else { + } else { wifi_util_error_print(WIFI_APPS, "%s Failed to run popen command\n", __FUNCTION__); } - } - else { + free(guard); + } else { wifi_util_error_print(WIFI_APPS, "%s NULL sta\n", __FUNCTION__); } } @@ -697,60 +771,80 @@ static void upload_client_debug_stats_sta_fa_lmac_mgmt_stats(INT apIndex, sta_da char *value = NULL; char *saveptr = NULL; char *ptr = NULL; - FILE *fp = NULL; + FILE *fp = NULL; sta_key_t sta_key; - char tmp[128] = {0}; - char buf[CLIENT_STATS_MAX_LEN_BUF] = {0}; - memset (buf, 0, CLIENT_STATS_MAX_LEN_BUF); + char tmp[128] = { 0 }; + char buf[CLIENT_STATS_MAX_LEN_BUF] = { 0 }; + wifi_ctrl_t *ctrl = (wifi_ctrl_t *)get_wifictrl_obj(); + int timer_id = -1; + + memset(buf, 0, CLIENT_STATS_MAX_LEN_BUF); + + if (sta != NULL) { + whix_stats_op_t *guard = (whix_stats_op_t *)malloc(sizeof(whix_stats_op_t)); + if (guard == NULL) + return; + + fp = (FILE *)v_secure_popen("r", "dmesg | grep FA_LMAC_MGMT_STATS_%s | tail -1", + to_sta_key(sta->sta_mac, sta_key)); - if(sta != NULL) { - fp = (FILE *)v_secure_popen("r", "dmesg | grep FA_LMAC_MGMT_STATS_%s | tail -1", to_sta_key(sta->sta_mac, sta_key)); if (fp) { - fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp); - v_secure_pclose(fp); - len = strlen(buf); - if (len) - { + guard->fp = fp; + guard->is_done = false; + + scheduler_add_timer_task(ctrl->sched, FALSE, &timer_id, telemetry_stats_timeout_handler, + guard, 2000, 1, TRUE); + + if (fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp) != NULL) { + len = strlen(buf); + } + + guard->is_done = true; + + if (timer_id != -1) { + scheduler_cancel_timer_task(ctrl->sched, timer_id); + } + + if (guard->fp) { + v_secure_pclose(guard->fp); + guard->fp = NULL; + } + + if (len) { ptr = buf + len; while (len-- && ptr-- && *ptr != ':'); ptr++; value = strtok_r(ptr, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_MGMT_QUEUED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_MGMT_QUEUED_CNT_%d:%s", tmp, apIndex + 1, + value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_MGMT_DROPPED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_MGMT_DROPPED_CNT_%d:%s", tmp, apIndex + 1, + value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_MGMT_DEQUED_TX_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_MGMT_DEQUED_TX_CNT_%d:%s", tmp, + apIndex + 1, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_MGMT_DEQUED_DROPPED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_MGMT_DEQUED_DROPPED_CNT_%d:%s", tmp, + apIndex + 1, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, - "\n%s WIFI_MGMT_EXP_DROPPED_CNT_%d:%s", tmp, - apIndex+1, value); + write_to_file(wifi_health_log, "\n%s WIFI_MGMT_EXP_DROPPED_CNT_%d:%s", tmp, + apIndex + 1, value); } + } else { + wifi_util_error_print(WIFI_APPS, "%s Failed to run popen command\n", __FUNCTION__); } - else { - wifi_util_error_print(WIFI_APPS, "%s Failed to run popen command\n", __FUNCTION__ ); - } - } - else { + free(guard); + } else { wifi_util_error_print(WIFI_APPS, "%s NULL sta\n", __FUNCTION__); } } @@ -764,14 +858,41 @@ static void upload_client_debug_stats_sta_vap_activity_stats(INT apIndex) FILE *fp = NULL; char tmp[128] = {0}; char buf[CLIENT_STATS_MAX_LEN_BUF] = {0}; + wifi_ctrl_t *ctrl = (wifi_ctrl_t *)get_wifictrl_obj(); + int timer_id = -1; + + // Use apIndex 0 for ath0 if (0 == apIndex) { memset (buf, 0, CLIENT_STATS_MAX_LEN_BUF); + + whix_stats_op_t *guard = (whix_stats_op_t *)malloc(sizeof(whix_stats_op_t)); + if (guard == NULL) return; + fp = (FILE *)v_secure_popen("r", "dmesg | grep VAP_ACTIVITY_ath0 | tail -1"); if (fp) { - fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp); - v_secure_pclose(fp); - len = strlen(buf); + guard->fp = fp; + guard->is_done = false; + + // Start 2s safety timer + scheduler_add_timer_task(ctrl->sched, FALSE, &timer_id, + telemetry_stats_timeout_handler, guard, + 2000, 1, TRUE); + + if (fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp) != NULL) { + len = strlen(buf); + } + + guard->is_done = true; + if (timer_id != -1) { + scheduler_cancel_timer_task(ctrl->sched, timer_id); + } + + if (guard->fp) { + v_secure_pclose(guard->fp); + guard->fp = NULL; + } + if (len) { ptr = buf + len; @@ -784,37 +905,59 @@ static void upload_client_debug_stats_sta_vap_activity_stats(INT apIndex) value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_LEN_1:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_LEN_1:%s\n", tmp, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_BYTES_1:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_BYTES_1:%s\n", tmp, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_LEN_1:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_LEN_1:%s\n", tmp, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_COUNT_1:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_COUNT_1:%s\n", tmp, value); } } else { wifi_util_error_print(WIFI_APPS, "%s Failed to run popen command\n", __FUNCTION__ ); } + free(guard); } + + // Use apIndex 1 for ath1 if (1 == apIndex) { memset (buf, 0, CLIENT_STATS_MAX_LEN_BUF); + + whix_stats_op_t *guard = (whix_stats_op_t *)malloc(sizeof(whix_stats_op_t)); + if (guard == NULL) return; + fp = (FILE *)v_secure_popen("r", "dmesg | grep VAP_ACTIVITY_ath1 | tail -1"); if (fp) { - fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp); - v_secure_pclose(fp); - len = strlen(buf); + guard->fp = fp; + guard->is_done = false; + timer_id = -1; // Reset for second case + + scheduler_add_timer_task(ctrl->sched, FALSE, &timer_id, + telemetry_stats_timeout_handler, guard, + 2000, 1, TRUE); + + if (fgets(buf, CLIENT_STATS_MAX_LEN_BUF, fp) != NULL) { + len = strlen(buf); + } + + guard->is_done = true; + if (timer_id != -1) { + scheduler_cancel_timer_task(ctrl->sched, timer_id); + } + + if (guard->fp) { + v_secure_pclose(guard->fp); + guard->fp = NULL; + } + if (len) { ptr = buf + len; @@ -827,29 +970,26 @@ static void upload_client_debug_stats_sta_vap_activity_stats(INT apIndex) value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_LEN_2:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_LEN_2:%s\n", tmp, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_BYTES_2:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_QUEUE_BYTES_2:%s\n", tmp, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_LEN_2:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_LEN_2:%s\n", tmp, value); value = strtok_r(NULL, ",", &saveptr); memset(tmp, 0, sizeof(tmp)); get_formatted_time(tmp); - write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_COUNT_2:%s\n", tmp, - value); + write_to_file(wifi_health_log, "%s WIFI_PS_CLIENTS_DATA_FRAME_COUNT_2:%s\n", tmp, value); } } else { wifi_util_error_print(WIFI_APPS, "%s Failed to run popen command\n", __FUNCTION__); } + free(guard); } } /* diff --git a/source/apps/whix/wifi_whix.h b/source/apps/whix/wifi_whix.h index 16dec1266..2f6b0f7b7 100644 --- a/source/apps/whix/wifi_whix.h +++ b/source/apps/whix/wifi_whix.h @@ -39,4 +39,9 @@ typedef struct { hash_map_t *last_stats_map; //wifi_associated_dev3_t } whix_data_t; +typedef struct { + FILE *fp; + bool is_done; +} whix_stats_op_t; + #endif //_WIFI_WHIX_H_