📄 wmgr.c
字号:
*
-*/
VOID
vMgrObjectInit(
IN HANDLE hDeviceContext
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
int ii;
pMgmt->pbyPSPacketPool = &pMgmt->byPSPacketPool[0];
pMgmt->pbyMgmtPacketPool = &pMgmt->byMgmtPacketPool[0];
pMgmt->uCurrChannel = pDevice->uChannel;
for(ii=0;ii<WLAN_BSSID_LEN;ii++) {
pMgmt->abyDesireBSSID[ii] = 0xFF;
}
pMgmt->sAssocInfo.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
//memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN +1);
pMgmt->byCSSPK = KEY_CTL_NONE;
pMgmt->byCSSGK = KEY_CTL_NONE;
pMgmt->wIBSSBeaconPeriod = DEFAULT_IBSS_BI;
BSSvClearBSSList((HANDLE)pDevice, FALSE);
return;
}
/*+
*
* Routine Description:
* Initializes timer object
*
* Return Value:
* Ndis_staus.
*
-*/
void
vMgrTimerInit(
IN HANDLE hDeviceContext
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
init_timer(&pMgmt->sTimerSecondCallback);
pMgmt->sTimerSecondCallback.data = (ULONG)pDevice;
pMgmt->sTimerSecondCallback.function = (TimerFunction)BSSvSecondCallBack;
pMgmt->sTimerSecondCallback.expires = RUN_AT(HZ);
init_timer(&pDevice->sTimerCommand);
pDevice->sTimerCommand.data = (ULONG)pDevice;
pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer;
pDevice->sTimerCommand.expires = RUN_AT(HZ);
pDevice->cbFreeCmdQueue = CMD_Q_SIZE;
pDevice->uCmdDequeueIdx = 0;
pDevice->uCmdEnqueueIdx = 0;
return;
}
/*+
*
* Routine Description:
* Reset the management object structure.
*
* Return Value:
* None.
*
-*/
VOID
vMgrObjectReset(
IN HANDLE hDeviceContext
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSMgmtObject pMgmt = pDevice->pMgmt;
pMgmt->eCurrMode = WMAC_MODE_STANDBY;
pMgmt->eCurrState = WMAC_STATE_IDLE;
pDevice->bEnablePSMode = FALSE;
// TODO: timer
return;
}
/*+
*
* Routine Description:
* Start the station association procedure. Namely, send an
* association request frame to the AP.
*
* Return Value:
* None.
*
-*/
VOID
vMgrAssocBeginSta(
IN HANDLE hDeviceContext,
IN PSMgmtObject pMgmt,
OUT PCMD_STATUS pStatus
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSTxMgmtPacket pTxPacket;
pMgmt->wCurrCapInfo = 0;
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
if (pDevice->bEncryptionEnable) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
}
// always allow receive short preamble
//if (pDevice->byPreambleType == 1) {
// pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
//}
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
if (pMgmt->wListenInterval == 0)
pMgmt->wListenInterval = 1; // at least one.
// ERP Phy (802.11g) should support short preamble.
if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
if (CARDbIsShorSlotTime(pMgmt->pAdapter) == TRUE) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
}
} else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
if (CARDbIsShortPreamble(pMgmt->pAdapter) == TRUE) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
}
}
if (pMgmt->b11hEnable == TRUE)
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
/* build an assocreq frame and send it */
pTxPacket = s_MgrMakeAssocRequest
(
pDevice,
pMgmt,
pMgmt->abyCurrBSSID,
pMgmt->wCurrCapInfo,
pMgmt->wListenInterval,
(PWLAN_IE_SSID)pMgmt->abyCurrSSID,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
);
if (pTxPacket != NULL ){
/* send the frame */
*pStatus = csMgmt_xmit(pDevice, pTxPacket);
if (*pStatus == CMD_STATUS_PENDING) {
pMgmt->eCurrState = WMAC_STATE_ASSOCPENDING;
*pStatus = CMD_STATUS_SUCCESS;
}
}
else
*pStatus = CMD_STATUS_RESOURCES;
return ;
}
/*+
*
* Routine Description:
* Start the station re-association procedure.
*
* Return Value:
* None.
*
-*/
VOID
vMgrReAssocBeginSta(
IN HANDLE hDeviceContext,
IN PSMgmtObject pMgmt,
OUT PCMD_STATUS pStatus
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSTxMgmtPacket pTxPacket;
pMgmt->wCurrCapInfo = 0;
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_ESS(1);
if (pDevice->bEncryptionEnable) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_PRIVACY(1);
}
//if (pDevice->byPreambleType == 1) {
// pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
//}
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
if (pMgmt->wListenInterval == 0)
pMgmt->wListenInterval = 1; // at least one.
// ERP Phy (802.11g) should support short preamble.
if (pMgmt->eCurrentPHYMode == PHY_TYPE_11G) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
if (CARDbIsShorSlotTime(pMgmt->pAdapter) == TRUE) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTSLOTTIME(1);
}
} else if (pMgmt->eCurrentPHYMode == PHY_TYPE_11B) {
if (CARDbIsShortPreamble(pMgmt->pAdapter) == TRUE) {
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SHORTPREAMBLE(1);
}
}
if (pMgmt->b11hEnable == TRUE)
pMgmt->wCurrCapInfo |= WLAN_SET_CAP_INFO_SPECTRUMMNG(1);
pTxPacket = s_MgrMakeReAssocRequest
(
pDevice,
pMgmt,
pMgmt->abyCurrBSSID,
pMgmt->wCurrCapInfo,
pMgmt->wListenInterval,
(PWLAN_IE_SSID)pMgmt->abyCurrSSID,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates,
(PWLAN_IE_SUPP_RATES)pMgmt->abyCurrExtSuppRates
);
if (pTxPacket != NULL ){
/* send the frame */
*pStatus = csMgmt_xmit(pDevice, pTxPacket);
if (*pStatus != CMD_STATUS_PENDING) {
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n");
}
else {
DEVICE_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n");
}
}
return ;
}
/*+
*
* Routine Description:
* Send an dis-association request frame to the AP.
*
* Return Value:
* None.
*
-*/
VOID
vMgrDisassocBeginSta(
IN HANDLE hDeviceContext,
IN PSMgmtObject pMgmt,
IN PBYTE abyDestAddress,
IN WORD wReason,
OUT PCMD_STATUS pStatus
)
{
PSDevice pDevice = (PSDevice)hDeviceContext;
PSTxMgmtPacket pTxPacket = NULL;
WLAN_FR_DISASSOC sFrame;
pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_DISASSOC_FR_MAXLEN);
pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket));
// Setup the sFrame structure
sFrame.pBuf = (PBYTE)pTxPacket->p80211Header;
sFrame.len = WLAN_DISASSOC_FR_MAXLEN;
// format fixed field frame structure
vMgrEncodeDisassociation(&sFrame);
// Setup the header
sFrame.pHdr->sA3.wFrameCtl = cpu_to_le16(
(
WLAN_SET_FC_FTYPE(WLAN_TYPE_MGR) |
WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DISASSOC)
));
memcpy( sFrame.pHdr->sA3.abyAddr1, abyDestAddress, WLAN_ADDR_LEN);
memcpy( sFrame.pHdr->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN);
memcpy( sFrame.pHdr->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);
// Set reason code
*(sFrame.pwReason) = cpu_to_le16(wReason);
pTxPacket->cbMPDULen = sFrame.len;
pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN;
// send the frame
*pStatus = csMgmt_xmit(pDevice, pTxPacket);
if (*pStatus == CMD_STATUS_PENDING) {
pMgmt->eCurrState = WMAC_STATE_IDLE;
*pStatus = CMD_STATUS_SUCCESS;
};
return;
}
/*+
*
* Routine Description:(AP function)
* Handle incoming station association request frames.
*
* Return Value:
* None.
*
-*/
static
VOID
s_vMgrRxAssocRequest(
IN PSDevice pDevice,
IN PSMgmtObject pMgmt,
IN PSRxMgmtPacket pRxPacket,
IN UINT uNodeIndex
)
{
WLAN_FR_ASSOCREQ sFrame;
CMD_STATUS Status;
PSTxMgmtPacket pTxPacket;
WORD wAssocStatus = 0;
WORD wAssocAID = 0;
UINT uRateLen = WLAN_RATES_MAXLEN;
BYTE abyCurrSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
BYTE abyCurrExtSuppRates[WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1];
if (pMgmt->eCurrMode != WMAC_MODE_ESS_AP)
return;
// node index not found
if (!uNodeIndex)
return;
//check if node is authenticated
//decode the frame
memset(&sFrame, 0, sizeof(WLAN_FR_ASSOCREQ));
memset(abyCurrSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
memset(abyCurrExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1);
sFrame.len = pRxPacket->cbMPDULen;
sFrame.pBuf = (PBYTE)pRxPacket->p80211Header;
vMgrDecodeAssocRequest(&sFrame);
if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState >= NODE_AUTH) {
pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC;
pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo);
pMgmt->sNodeDBTable[uNodeIndex].wListenInterval = cpu_to_le16(*sFrame.pwListenInterval);
pMgmt->sNodeDBTable[uNodeIndex].bPSEnable =
WLAN_GET_FC_PWRMGT(sFrame.pHdr->sA3.wFrameCtl) ? TRUE : FALSE;
// Todo: check sta basic rate, if ap can't support, set status code
if (pDevice->eCurrentPHYType == PHY_TYPE_11B) {
uRateLen = WLAN_RATES_MAXLEN_11B;
}
abyCurrSuppRates[0] = WLAN_EID_SUPP_RATES;
abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates,
(PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
uRateLen);
abyCurrExtSuppRates[0] = WLAN_EID_EXTSUPP_RATES;
if (pDevice->eCurrentPHYType == PHY_TYPE_11G) {
abyCurrExtSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pExtSuppRates,
(PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
uRateLen);
} else {
abyCurrExtSuppRates[1] = 0;
}
RATEvParseMaxRate((PVOID)pDevice,
(PWLAN_IE_SUPP_RATES)abyCurrSuppRates,
(PWLAN_IE_SUPP_RATES)abyCurrExtSuppRates,
FALSE, // do not change our basic rate
&(pMgmt->sNodeDBTable[uNodeIndex].wMaxBasicRate),
&(pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate),
&(pMgmt->sNodeDBTable[uNodeIndex].wSuppRate),
&(pMgmt->sNodeDBTable[uNodeIndex].byTopCCKBasicRate),
&(pMgmt->sNodeDBTable[uNodeIndex].byTopOFDMBasicRate)
);
// set max tx rate
pMgmt->sNodeDBTable[uNodeIndex].wTxDataRate =
pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -