wlanconfig ath1 list
root@Archer_GE550:~# wlanconfig ath1 list
ADDR AID CHAN TXRATE RXRATE RSSI MINRSSI MAXRSSI IDLE TXSEQ RXSEQ CAPS XCAPS ACAPS ERP STATE MAXRATE(DOT11) HTCAPS VHTCAPS ASSOCTIME IEs MODE RXNSS TXNSS PSMODE
3a:e8:3c:eb:a4:f9 2 40 58M 72M -56 -63 -50 272 0 65535 EPSs BRIf NULL 0 b 65000 P 0gR 00:21:10 RSN WME IEEE80211_MODE_11NA_HT20 1 1 1
NR
RSSI is combined over chains in dBm
Minimum Tx Power : 0
Maximum Tx Power : 16
HT Capability : Yes
VHT Capability : No
MU capable : No
SNR : 39
Operating band : 5GHz
Current Operating class : 0
Supported Rates(Mbps) : 6 9 12 18 24 36 48 54
Max STA phymode : IEEE80211_MODE_11NA_HT20
MLO : No
36:33:c1:e7:b6:33 1 40 1297M 309M -39 -44 -32 0 0 65535 EPR EWBO NULL 0 b 2401900 AWPSM gGTRs 00:00:10 RSN WME IEEE80211_MODE_11AXA_HE160 2 2 1
LM NR BRP BRA BRT LCIM FTMRR
RSSI is combined over chains in dBm
Minimum Tx Power : 8
Maximum Tx Power : 22
HT Capability : Yes
VHT Capability : Yes
MU capable : Yes
SNR : 56
Operating band : 5GHz
Current Operating class : 129
Supported Operating classes : 81 83 84 115 116 117 118 119 120 124 125 126 127 128 130
Supported Rates(Mbps) : 6 9 12 18 24 36 48 54
Max STA phymode : IEEE80211_MODE_11AXA_HE160
MLO : No
root@Archer_GE550:~#
以上是wlanconfig ath1 list的输出修改以下代码,维护5G终端列表
记住第一行(表头)的字段名(不用体现在代码里),读取每一个客户端的信息,客户端信息的第一行用空格分割数据,在对应位置找到mac地址,AID,带宽模式,NSS,RSSI,(例如从第一行可以看出,mac地址是第一个字段,AID是第二个,RSSI是第六个,以此类推)
然后在下边对应行读出SNR信息
注意:ath1就是5G网口,读出来的终端都是5G无线终端,无需再作判断
#include "anti_jitter.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/wait.h>
#define MAX_LINE_LEN 512
/** 全局timeout变量声明 */
struct uloop_timeout timeout;
/** MAC地址验证函数 - 修复版本 */
bool is_valid_mac(const char *mac) {
int colon_count = 0;
const char *p = mac;
while (*p) {
if (isxdigit(*p) || *p == ':') {
if (*p == ':') colon_count++;
} else {
return false; /* 非法字符 */
}
p++;
}
return (colon_count == 5); /* 合法MAC应有5个冒号 */
}
/** 解析wlanconfig输出 */
int parse_wlanconfig_output(const char *output, ClientInfo **clients) {
if (!output || !clients || *output == '\0') return 0;
char *copy = strdup(output);
if (!copy) return 0;
ClientInfo *client_list = NULL;
int valid_count = 0;
ClientInfo current_client = {0};
char *line = strtok(copy, "\n");
HeaderIndices indices = {-1};
bool in_client_block = false;
bool header_parsed = false;
while (line != NULL) {
// 清理行
char *start = line;
while (*start == ' ') start++;
size_t len = strlen(start);
while (len > 0 && (start[len-1] == '\r' || start[len-1] == '\n' || start[len-1] == ' '))
start[--len] = '\0';
if (len == 0) {
line = strtok(NULL, "\n");
continue;
}
// 阶段1: 解析表头
if (!header_parsed && strstr(start, "ADDR") && strstr(start, "TXRATE")) {
char *token;
char *saveptr;
int idx = 0;
// 初始化索引位置
memset(&indices, -1, sizeof(HeaderIndices));
// 分割表头行
token = strtok_r(start, " ", &saveptr);
while (token != NULL) {
if (strcmp(token, "ADDR") == 0) indices.addr_idx = idx;
else if (strcmp(token, "AID") == 0) indices.aid_idx = idx;
else if (strcmp(token, "TXRATE") == 0) indices.txrate_idx = idx;
else if (strcmp(token, "RXRATE") == 0) indices.rxrate_idx = idx;
else if (strcmp(token, "RSSI") == 0) indices.rssi_idx = idx;
else if (strcmp(token, "MODE") == 0) indices.mode_idx = idx;
else if (strcmp(token, "RXNSS") == 0) indices.rxnss_idx = idx;
else if (strcmp(token, "TXNSS") == 0) indices.txnss_idx = idx;
token = strtok_r(NULL, " ", &saveptr);
idx++;
}
header_parsed = true;
}
// 阶段2: 解析客户端行
if (header_parsed && is_valid_mac(start)) {
// 保存前一个客户端
if (strlen(current_client.mac) > 0) {
ClientInfo *new_list = realloc(client_list, sizeof(ClientInfo) * (valid_count + 1));
if (new_list) {
client_list = new_list;
client_list[valid_count] = current_client;
valid_count++;
}
}
// 初始化新客户端
memset(¤t_client, 0, sizeof(ClientInfo));
in_client_block = true;
// 分割客户端行
char *tokens[64];
int token_count = 0;
char *token = strtok(start, " ");
while (token != NULL && token_count < 64) {
tokens[token_count] = token;
token_count++;
token = strtok(NULL, " ");
}
// 根据表头位置提取字段
if (indices.addr_idx >= 0 && indices.addr_idx < token_count)
strncpy(current_client.mac, tokens[indices.addr_idx], sizeof(current_client.mac)-1);
if (indices.aid_idx >= 0 && indices.aid_idx < token_count)
current_client.aid = atoi(tokens[indices.aid_idx]);
if (indices.rssi_idx >= 0 && indices.rssi_idx < token_count)
current_client.rssi = atoi(tokens[indices.rssi_idx]);
if (indices.txrate_idx >= 0 && indices.txrate_idx < token_count &&
indices.rxrate_idx >= 0 && indices.rxrate_idx < token_count) {
snprintf(current_client.negotiated_rate, sizeof(current_client.negotiated_rate),
"TX:%s RX:%s", tokens[indices.txrate_idx], tokens[indices.rxrate_idx]);
}
if (indices.mode_idx >= 0 && indices.mode_idx < token_count)
strncpy(current_client.phymode, tokens[indices.mode_idx], sizeof(current_client.phymode)-1);
if (indices.rxnss_idx >= 0 && indices.rxnss_idx < token_count)
current_client.rxnss = atoi(tokens[indices.rxnss_idx]);
if (indices.txnss_idx >= 0 && indices.txnss_idx < token_count)
current_client.txnss = atoi(tokens[indices.txnss_idx]);
}
// 阶段3: 客户端属性块解析
if (in_client_block) {
// 带宽模式提取
if (strstr(start, "Operating band")) {
char *colon = strchr(start, ':');
if (colon) {
char *band = colon + 1;
while (*band == ' ') band++;
strncpy(current_client.operating_band, band, sizeof(current_client.operating_band)-1);
}
}
// SNR值提取
else if (strstr(start, "SNR")) {
char *colon = strchr(start, ':');
if (colon) current_client.snr = atoi(colon + 1);
}
// 物理模式备用来源
else if (strstr(start, "Max STA phymode")) {
char *colon = strchr(start, ':');
if (colon) {
char *mode = colon + 1;
while (*mode == ' ') mode++;
if (strlen(current_client.phymode) == 0) {
strncpy(current_client.phymode, mode, sizeof(current_client.phymode)-1);
}
}
}
// 结束客户端块
else if (strncmp(start, "RSSI is combined", 16) == 0) {
in_client_block = false;
}
}
line = strtok(NULL, "\n");
}
// 保存最后一个客户端
if (strlen(current_client.mac) > 0) {
ClientInfo *new_list = realloc(client_list, sizeof(ClientInfo) * (valid_count + 1));
if (new_list) {
client_list = new_list;
client_list[valid_count] = current_client;
valid_count++;
}
}
*clients = client_list;
free(copy);
return valid_count;
}
/** 打印5GHz客户端信息 */
void print_5g_clients(ClientInfo *clients, int count) {
int found = 0;
for (int i = 0; i < count; i++) {
if (strstr(clients[i].operating_band, "5GHz") != NULL) {
found++;
printf("5G终端列表 (%d个客户端):\n", found);
printf("========= 客户端 %d =========\n", found);
printf("AID: %d\n", clients[i].aid);
printf("MAC地址: %s\n", clients[i].mac);
printf("带宽模式: %s\n", clients[i].operating_band);
printf("物理模式: %s\n", clients[i].phymode);
printf("协商速率: %s\n", clients[i].negotiated_rate);
printf("RXNSS: %d\n", clients[i].rxnss);
printf("TXNSS: %d\n", clients[i].txnss);
printf("RSSI: %d\n", clients[i].rssi);
printf("SNR: %d\n", clients[i].snr);
printf("============================\n\n");
}
}
if (found == 0) {
printf("未找到5G终端\n");
}
}
/** 释放客户端列表内存 */
void free_client_list(ClientInfo *clients) {
if (clients) free(clients);
}
/** 执行shell命令并获取输出 */
char *execute_command(const char *cmd) {
FILE *fp = popen(cmd, "r");
if (!fp) return NULL;
char buffer[4096];
char *result = malloc(65536);
if (!result) {
pclose(fp);
return NULL;
}
result[0] = '\0';
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
strcat(result, buffer);
}
pclose(fp);
return result;
}
/** 主循环定时器回调 */
void timer_cb(struct uloop_timeout *t) {
printf("正在扫描5G客户端...\n");
char *output = execute_command("wlanconfig ath1 list");
if (output) {
ClientInfo *clients = NULL;
int count = parse_wlanconfig_output(output, &clients);
if (count > 0) {
print_5g_clients(clients, count);
free_client_list(clients);
} else {
printf("未找到任何客户端\n");
}
free(output);
} else {
printf("命令执行失败\n");
}
/* 重新设置定时器 */
uloop_timeout_set(&timeout, 3000); /* 3秒间隔 */
}
int main(int argc, char **argv) {
printf("5G客户端监控程序启动\n");
uloop_init();
timeout.cb = timer_cb;
uloop_timeout_set(&timeout, 0); /* 立即启动 */
uloop_run();
uloop_done();
return 0;
}
#ifndef ANTI_JITTER_H
#define ANTI_JITTER_H
#include <libubox/uloop.h>
#include <stdbool.h>
#define MAX_BUFFER 4096
/** 客户端信息结构体 */
typedef struct {
int aid; /**< 客户端关联ID */
char mac[18]; /**< MAC地址 (xx:xx:xx:xx:xx:xx) */
char operating_band[32]; /**< Operating band值 */
char phymode[32]; /**< Max STA phymode */
char bandwidth_mode[32]; /**< 带宽模式 */
char negotiated_rate[64]; /**< 协商速率 */
int rxnss; /**< 接收NSS值 */
int txnss; /**< 发送NSS值 */
int rssi; /**< RSSI值 (dBm) */
int snr; /**< SNR值 (dB) */
} ClientInfo;
/** 全局定时器 */
extern struct uloop_timeout timer;
/** 检查MAC地址格式有效性 */
bool is_valid_mac(const char *str);
/** 解析wlanconfig输出并提取客户端信息 */
int parse_wlanconfig_output(const char *output, ClientInfo **clients);
/** 打印5G终端列表 */
void print_5g_clients(ClientInfo *clients, int count);
/** 定时器回调函数 */
void timer_cb(struct uloop_timeout *t);
#endif /* ANTI_JITTER_H */