答:
可以通过“iwpriv ra0 show stainfo ”命令的输出结果来观察。该命令列出了当前AP记录的WIFI客户端列表;如果某个客户端和AP之间的通讯断开超出一定时间,AP就会从客户端列表中将该客户端删除(支持省电模式的客户端不适应该策略)。Ralink driver中默认的超时时间为300秒(#define MAC_TABLE_AGEOUT_TIME 300 /* unit: sec */);其中“Idle”表示还剩多少秒会超时。如果客户端处于active状态的话,该值通常会大于250;
下面的例子中将一个camera的电源断开一段时间后,camera就被从AP的WIFI列表中删除了。
所以,如果“Idle”的数值一直变小,可能就需要考虑客户端和AP之间的连接是否出现了问题。
# # iwpriv ra0 show stainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -23 -28 0 HTMIX 40M 7 0 1 300 135 4638 , 50999, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -54 -49 0 HTMIX 40M 7 0 1 300 135 12977 , 63879, 79% 20:F8:5E:A0:21:65 3 0 0 0 0 -54 -49 0 CCK 20M 3 0 0 270 11 579 , 589, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -46 0 HTMIX 40M 7 0 0 297 135 21759 , 21907, 0% 54:2A:A2:04:07:F9 5 0 0 1 3 -48 -49 0 HTMIX 20M 7 0 0 300 65 9983 , 10043, 0% 00:95:69:08:00:19 6 0 0 1 3 -51 -47 0 HTMIX 40M 7 0 1 300 135 20763 , 68704, 69% 00:95:69:07:4D:E6 7 0 0 1 3 -20 -28 0 HTMIX 40M 7 0 1 300 135 15509 , 60244, 74%
#
MAC: 客户端的WIFI MAC address; AID: 客户端ID,由AP维护; BSS: BSS的标识符,MT7620是支持多SSID的;每个SSID对应不同的MAC,也就是不同的BSS;该AP只使用了一个,因此这里为0; PSM: power save mode 省电模式; WMM:WMM(Wi-Fi多媒体)全面定义了四种连接内容,其中包括语音、视频、best effort以及background,以此优化网络通信的质量,以保障这些应用与网络资源建立稳定连接。 MIMOPS: MIMO 的power save mode; RSSI0,RSSI1,RSSI2:记录了最近几次的客户端的WIFI发送信号强度,单位dbm,数值越大,信号越强;例如“-10”时信号强于“-50”;该数值可能受OPU wifi检测电路精度影响,所以数值不太精确,但具有有一定的参考作用; PhMd:物理层采用的WIFI技术; BW: BandWidth 带宽,40M或者20M SGI:是否使能Short Guard Interval;射频芯片在使用OFDM调制方式发送数据时,整个帧是被划分成不同的数据块进行发送的,为了数据传输的可靠性,数据块之间会有GI(Guard Interval),用以保证接收侧能够正确的解析出各个数据块。无线信号在空间传输会因多径等因素在接收侧形成时延,如果后续数据块发送过快,会和前一个数据块形成干扰,而GI就是用来规避这个干扰的。11a/g的GI时长为800us,而Short GI时长为400us,在使用Short GI的情况下,可提高10%的速率。另外,Short GI与带宽无关,支持20MHz、40MHz带宽。在配置WLAN的参数界面,一般会有一个SGI使能的选项,如果不勾选,则使用GI间隔--800us;而勾选SGI使能后,使用400us间隔。间隔小能提高速率,但是如果遇到干扰或环境不好时,容易增加信息传输错误,反而使性能恶化。 Idle:表示还剩多少秒会因为一直处于Idle而超时被AP踢掉。该数值表示客户端WIFI的活跃程度;如果该值一直变小,可能就需要考虑客户端和AP之间的连接是否断开了。 Rate:当前客户端和AP之间的数据传输速度; “4638 , 50999, 90%”这样的几个数据表示FIFO overflow rate,通过这几个数值来反馈硬件发送数据速率和上层期望发送速率之间差异; 这几个数值分别对应如下的代码行: printk("%-10d, %d, %d%%\n",pEntry->DebugFIFOCount, pEntry->DebugTxCount, (pEntry->DebugTxCount) ?((pEntry->DebugTxCount-pEntry->DebugFIFOCount)*100/pEntry->DebugTxCount): 0); DebugTxCount 由APHardTransmit调用的RTMP_FillTxBlkInfo函数中pMacEntry->DebugTxCount++;说明AP每发送一帧数据时就会增加该计数;用于表明上层期望发送的数据包数量; DebugFIFOCount由NICUpdateFifoStaCounters中更新,用于表示底层实际发送了多少数据包(ignore NoACK and MGMT frame use 0xFF as WCI,后面应该就是多播的管理帧); STBC: 空时编码方式,源码中对应的数值如下: /* STBC */ #define STBC_NONE 0 #ifdef DOT11_N_SUPPORT #define STBC_USE 1 /* limited use in rt2860b phy */ #define RXSTBC_ONE 1 /* rx support of one spatial stream */ #define RXSTBC_TWO 2 /* rx support of 1 and 2 spatial stream */ #define RXSTBC_THR 3 /* rx support of 1~3 spatial stream */
//拔掉MAC为54:2A:A2:04:07:F9的摄像头的电源,观察Idle的数值变化 # # iwpriv ra0 showstainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -26 -30 0 HTMIX 40M 7 0 1 300 135 4873 , 51947, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -53 -49 0 HTMIX 40M 7 0 1 300 135 13101 , 64807, 79% 20:F8:5E:A0:21:65 3 0 0 0 0 -51 -46 0 CCK 20M 3 0 0 272 11 584 , 594, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -47 0 HTMIX 40M 7 0 0 292 135 22227 , 22376, 0% 54:2A:A2:04:07:F9 5 0 0 1 3 -51 -49 0 HTMIX 20M 7 0 0 271 65 10304 , 10364, 0% 00:95:69:08:00:19 6 0 0 1 3 -49 -47 0 HTMIX 40M 7 0 1 300 135 21031 , 69818, 69% 00:95:69:07:4D:E6 7 0 0 1 3 -21 -27 0 HTMIX 40M 7 0 1 300 135 15852 , 61359, 74%
# # iwpriv ra0 showstainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -23 -27 0 HTMIX 40M 7 0 1 300 135 4881 , 52294, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -52 -47 0 HTMIX 40M 7 0 1 299 135 13109 , 65133, 79% 20:F8:5E:A0:21:65 3 0 0 0 0 -50 -47 0 CCK 20M 3 0 0 297 11 587 , 597, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -47 0 HTMIX 40M 7 0 0 291 135 22231 , 22380, 0% 54:2A:A2:04:07:F9 5 0 0 1 3 -51 -49 0 HTMIX 20M 7 0 0 206 65 10311 , 10371, 0% 00:95:69:08:00:19 6 0 0 1 3 -49 -48 0 HTMIX 40M 7 0 1 299 135 21040 , 70158, 70% 00:95:69:07:4D:E6 7 0 0 1 3 -18 -26 0 HTMIX 40M 7 0 1 299 135 15860 , 61777, 74%
# iwpriv ra0 showstainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -25 -26 0 HTMIX 40M 7 0 1 300 135 4897 , 52491, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -51 -50 0 HTMIX 40M 7 0 1 300 135 13119 , 65416, 79% 20:F8:5E:A0:21:65 3 0 0 0 0 -50 -47 0 CCK 20M 3 0 0 294 11 588 , 598, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -47 0 HTMIX 40M 7 0 0 299 135 22235 , 22384, 0% 54:2A:A2:04:07:F9 5 0 0 1 3 -51 -49 0 HTMIX 20M 7 0 0 150 65 10311 , 10371, 0% 00:95:69:08:00:19 6 0 0 1 3 -48 -48 0 HTMIX 40M 7 0 1 300 135 21049 , 70513, 70% 00:95:69:07:4D:E6 7 0 0 1 3 -21 -30 0 HTMIX 40M 7 0 1 299 135 15868 , 62160, 74%
# # iwpriv ra0 showstainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -18 -28 0 HTMIX 40M 7 0 1 300 135 4912 , 52958, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -53 -46 0 HTMIX 40M 7 0 1 300 135 13137 , 66036, 80% 20:F8:5E:A0:21:65 3 0 0 0 0 -52 -49 0 CCK 20M 3 0 0 299 11 591 , 601, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -47 0 HTMIX 40M 7 0 0 298 135 22240 , 22390, 0% 54:2A:A2:04:07:F9 5 0 0 1 3 -51 -49 0 HTMIX 20M 7 0 0 60 65 10311 , 10371, 0% 00:95:69:08:00:19 6 0 0 1 3 -48 -47 0 HTMIX 40M 7 0 1 300 135 21061 , 70899, 70% 00:95:69:07:4D:E6 7 0 0 1 3 -20 -32 0 HTMIX 40M 7 0 1 300 135 15883 , 62620, 74%
# # # iwpriv ra0 showstainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -19 -28 0 HTMIX 40M 7 0 1 300 135 4913 , 53047, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -53 -49 0 HTMIX 40M 7 0 1 300 135 13139 , 66126, 80% 20:F8:5E:A0:21:65 3 0 0 0 0 -46 -47 0 CCK 20M 3 0 0 299 11 592 , 602, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -46 0 HTMIX 40M 7 0 0 286 135 22241 , 22391, 0% 54:2A:A2:04:07:F9 5 0 0 1 3 -51 -49 0 HTMIX 20M 7 0 0 41 65 10311 , 10371, 0% 00:95:69:08:00:19 6 0 0 1 3 -47 -45 0 HTMIX 40M 7 0 1 300 135 21064 , 71038, 70% 00:95:69:07:4D:E6 7 0 0 1 3 -19 -32 0 HTMIX 40M 7 0 1 300 135 15886 , 62697, 74%
# # # # iwpriv ra0 showstainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -19 -29 0 HTMIX 40M 7 0 1 300 135 4920 , 53341, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -53 -51 0 HTMIX 40M 7 0 1 300 135 13146 , 66389, 80% 20:F8:5E:A0:21:65 3 0 0 0 0 -48 -47 0 CCK 20M 3 0 0 295 11 594 , 604, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -47 0 HTMIX 40M 7 0 0 298 135 22245 , 22395, 0% 00:95:69:08:00:19 6 0 0 1 3 -49 -49 0 HTMIX 40M 7 0 1 300 135 21072 , 71292, 70% 00:95:69:07:4D:E6 7 0 0 1 3 -20 -33 0 HTMIX 40M 7 0 1 300 135 15893 , 62956, 74%
#
# //将MAC为54:2A:A2:04:07:F9的摄像头重新上电,该设备会重新通过WIFI连上AP,出现在AP客户端列表中,成对密码交换过程会有输出log # # MIC Different in pairwise msg 2 of 4-way handshake! WPAInstallPairwiseKey : Pairwisekey Cipher Alg (4) AP SETKEYS DONE - WPA2, AuthMode(7)=WPA2PSK, WepStatus(6)=AES, GroupWepStatus(6)=AES
Rcv Wcid(5) AddBAReq Start Seq = 00000000 Rcv Wcid(5) AddBAReq Start Seq = 00000001
# # iwpriv ra0 showstainfo BackOff Slot : long slot time, BKOFF_SLOT_CFG(0x1104)= 0x00000214 HT Operating Mode :3
MAC AID BSS PSM WMM MIMOPS RSSI0 RSSI1 RSSI2 PhMd BW MCS SGI STBC Idle Rate C0:56:E3:9F:08:75 1 0 0 1 3 -24 -28 0 HTMIX 40M 7 0 1 300 135 4958 , 54565, 90% C0:56:E3:9F:08:6B 2 0 0 1 3 -53 -48 0 HTMIX 40M 7 0 1 300 135 13185 , 67914, 80% 20:F8:5E:A0:21:65 3 0 0 0 0 -51 -48 0 CCK 20M 3 0 0 271 11 602 , 612, 1% 00:1A:97:01:A1:47 4 0 0 1 3 -43 -47 0 HTMIX 40M 7 0 0 295 135 22267 , 22417, 0% 54:2A:A2:04:07:F9 5 0 0 1 3 -48 -53 0 HTMIX 20M 7 0 0 300 65 205 , 212, 3% 00:95:69:08:00:19 6 0 0 1 3 -49 -49 0 HTMIX 40M 7 0 1 300 135 21110 , 72899, 71% 00:95:69:07:4D:E6 7 0 0 1 3 -24 -30 0 HTMIX 40M 7 0 1 300 135 15930 , 64177, 75%
#
Ralink wifi driver的源码中:AP 会在MacTableMaintenance这个函数中维护客户端列表,必要时会踢掉一些客户端 当客户端连续idle超过ageout时间,默认这个时间为MAC_TABLE_AGEOUT_TIME(300秒);也可以通过如下配置项指定;以及iwpriv ra0 set IdleTimeout=Value 4.1.62 IdleTimeout=Value AP(▼), STA() Description: It indicates the maximum number of consecutive seconds of idle connection allowed to the user before termination of the session or prompt. Value: 60 ~ 65536. The unit is second.
#define MAC_TABLE_AGEOUT_TIME 300 /* unit: sec */ #define MAC_TABLE_MIN_AGEOUT_TIME 60 /* unit: sec */
/* AP shall drop the sta if contine Tx fail count reach it. */ #define MAC_ENTRY_LIFE_CHECK_CNT 1024 /* packet cnt. */
相关的源代码线索: #define MAC_TABLE_AGEOUT_TIME 300 /* unit: sec */ #define MAC_TABLE_MIN_AGEOUT_TIME 60 /* unit: sec */ #define MAC_TABLE_ASSOC_TIMEOUT 5 /* unit: sec */ #define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE)
/* AP shall drop the sta if contine Tx fail count reach it. */ #define MAC_ENTRY_LIFE_CHECK_CNT 1024 /* packet cnt. */
typedef struct _MAC_TABLE_ENTRY {
..... ULONG NoDataIdleCount; UINT16 StationKeepAliveCount; /* unit: second */ ULONG PsQIdleCount; QUEUE_HEADER PsQueue;
UINT32 StaConnectTime; /* the live time of this station since associated with AP */ UINT32 StaIdleTimeout; /* idle timeout per entry */
ULONG AssocDeadLine;
/* ========================================================================== Description: This routine is called by APMlmePeriodicExec() every second to check if 1. any associated client in PSM. If yes, then TX MCAST/BCAST should be out in DTIM only 2. any client being idle for too long and should be aged-out from MAC table 3. garbage collect PSQ ========================================================================== */ VOID MacTableMaintenance( IN PRTMP_ADAPTER pAd)
#ifdef CONFIG_AP_SUPPORT typedef struct _MULTISSID_STRUCT { ...... BOOLEAN bHideSsid; UINT16 StationKeepAliveTime; /* unit: second */
......
/* detect the station alive status */ if ((pAd->ApCfg.MBSSID[pEntry->apidx].StationKeepAliveTime > 0) && (pEntry->NoDataIdleCount >= pAd->ApCfg.MBSSID[pEntry->apidx].StationKeepAliveTime)) { MULTISSID_STRUCT *pMbss = &pAd->ApCfg.MBSSID[pEntry->apidx];
/* If no any data success between ap and the station for StationKeepAliveTime, try to detect whether the station is still alive.
Note: Just only keepalive station function, no disassociation function if too many no response. */
/* For example as below:
1. Station in ACTIVE mode,
...... sam> tx ok! sam> count = 1! ==> 1 second after the Null Frame is acked sam> count = 2! ==> 2 second after the Null Frame is acked sam> count = 3! sam> count = 4! sam> count = 5! sam> count = 6! sam> count = 7! sam> count = 8! sam> count = 9! sam> count = 10! sam> count = 11! sam> count = 12! sam> count = 13! sam> count = 14! sam> count = 15! ==> 15 second after the Null Frame is acked sam> tx ok! ==> (KeepAlive Mechanism) send a Null Frame to detect the STA life status sam> count = 1! ==> 1 second after the Null Frame is acked sam> count = 2! sam> count = 3! sam> count = 4! ......
If the station acknowledges the QoS Null Frame, the NoDataIdleCount will be reset to 0.
2. Station in legacy PS mode,
We will set TIM bit after 15 seconds, the station will send a PS-Poll frame and we will send a QoS Null frame to it. If the station acknowledges the QoS Null Frame, the NoDataIdleCount will be reset to 0.
3. Station in legacy UAPSD mode,
Currently we do not support the keep alive mechanism. So if your station is in UAPSD mode, the station will be kicked out after 300 seconds.
Note: the rate of QoS Null frame can not be 1M of 2.4GHz or 6M of 5GHz, or no any statistics count will occur. */
/* 2. delete those MAC entry that has been idle for a long time */ if (pEntry->NoDataIdleCount >= pEntry->StaIdleTimeout) { bDisconnectSta = TRUE; DBGPRINT(RT_DEBUG_WARN, ("ageout %02x:%02x:%02x:%02x:%02x:%02x after %d-sec silence\n", pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3], pEntry->Addr[4],pEntry->Addr[5],pEntry->StaIdleTimeout)); ApLogEvent(pAd, pEntry->Addr, EVENT_AGED_OUT); } else if (pEntry->ContinueTxFailCnt >= pAd->ApCfg.EntryLifeCheck) { /* AP have no way to know that the PwrSaving STA is leaving or not. So do not disconnect for PwrSaving STA. */ if (pEntry->PsMode != PWR_SAVE) { bDisconnectSta = TRUE; DBGPRINT(RT_DEBUG_WARN, ("STA-%02x:%02x:%02x:%02x:%02x:%02x had left (%d %lu)\n", pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2],pEntry->Addr[3], pEntry->Addr[4],pEntry->Addr[5], pEntry->ContinueTxFailCnt, pAd->ApCfg.EntryLifeCheck)); } }
if (bDisconnectSta) { /* send wireless event - for ageout */ RTMPSendWirelessEvent(pAd, IW_AGEOUT_EVENT_FLAG, pEntry->Addr, 0, 0);
pEntry->ContinueTxFailCnt 这个在如下函数中进行更新;失败就pEntry->ContinueTxFailCnt ++; 成功就pEntry->ContinueTxFailCnt=0;
VOID NICUpdateFifoStaCounters( IN PRTMP_ADAPTER pAd) { …… do { RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
if (StaFifo.field.bValid == 0) break;
wcid = (UCHAR)StaFifo.field.wcid;
#ifdef DBG_CTRL_SUPPORT #ifdef INCLUDE_DEBUG_QUEUE if (pAd->CommonCfg.DebugFlags & DBF_DBQ_TXFIFO) { dbQueueEnqueue(0x73, (UCHAR *)(&StaFifo.word)); } #endif /* INCLUDE_DEBUG_QUEUE */ #endif /* DBG_CTRL_SUPPORT */
/* ignore NoACK and MGMT frame use 0xFF as WCID */ if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MaxWcidNum)) { i++; continue; }
/* PID store Tx MCS Rate */ pid = (UCHAR)StaFifo.field.PidType;
pEntry = &pAd->MacTab.Content[wcid]; /* 这里记录的应该是底层缓冲区纪录的实际发送数据包数量,包括成功和失败的;不包括广播以及不需要ACK回应的包 */ pEntry->DebugFIFOCount++;
……. if (!StaFifo.field.TxSuccess) {//发送失败 pEntry->FIFOCount++; pEntry->OneSecTxFailCount++;
……. } else { …… pEntry->FIFOCount = 0; pEntry->OneSecTxNoRetryOkCount++;
/* update NoDataIdleCount when sucessful send packet to STA.*/ pEntry->NoDataIdleCount = 0; pEntry->ContinueTxFailCnt = 0; ……
}
INT ApCfg_Set_IdleTimeout_Proc( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { LONG idle_time;
idle_time = simple_strtol(arg, 0, 10);
if (idle_time < MAC_TABLE_MIN_AGEOUT_TIME) pAd->ApCfg.StaIdleTimeout = MAC_TABLE_MIN_AGEOUT_TIME; else pAd->ApCfg.StaIdleTimeout = idle_time;
DBGPRINT(RT_DEBUG_TRACE, ("%s : IdleTimeout=%d\n", __FUNCTION__, pAd->ApCfg.StaIdleTimeout));
return TRUE; }
/* ======================================================================== Routine Description: Initialize port configuration structure Arguments: Adapter Pointer to our adapter Return Value: None IRQL = PASSIVE_LEVEL Note: ======================================================================== */ VOID UserCfgInit( IN PRTMP_ADAPTER pAd) { ......
pAd->ApCfg.StaIdleTimeout = MAC_TABLE_AGEOUT_TIME;
......
#ifdef CONFIG_AP_SUPPORT pAd->ApCfg.EntryLifeCheck = MAC_ENTRY_LIFE_CHECK_CNT; #endif /* CONFIG_AP_SUPPORT */
|