📄 dot11ksllib.c
字号:
* device has not been entered in the KSL. No checks against this assumption* are made.** RETURNS: Pointer to KSL entry, or NULL if not found** ERRNO: N/A*/LOCAL DOT11_KSL_ENTRY * dot11KslAdd ( DOT11_FW * pDot11, /* Pointer to device structure */ UINT8 * macAddr /* MAC Address of entry to add */ ) { DOT11_KSL_ENTRY * pKsl; if (dot11KslLock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslAdd: Cannot get lock\n", 0,0,0,0,0,0)); return NULL; } /* Allocate the new entry */ if ((pKsl = dot11KslEntryAlloc(pDot11)) == NULL) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslAdd: Error allocating memory\n", 0, 0, 0, 0, 0, 0)); dot11KslUnlock(pDot11); return NULL; } /* The hash bucket is empty */ if (pDot11->sme->ksl.list[DOT11_KSL_HASH(macAddr)] == NULL) { pDot11->sme->ksl.list[DOT11_KSL_HASH(macAddr)] = pKsl; pKsl->pNext = NULL; } else /* The hash buck is not empty - insert at head of queue */ { pKsl->pNext = pDot11->sme->ksl.list[DOT11_KSL_HASH(macAddr)]; pDot11->sme->ksl.list[DOT11_KSL_HASH(macAddr)] = pKsl; } bcopy((char*)macAddr, (char*)pKsl->macAddr, DOT11_ADDR_LEN); pKsl->timestamp = tickGet(); pKsl->uniEncryptIndex = DOT11_KEYINDEX_NONE; pKsl->uniDecryptIndex = DOT11_KEYINDEX_NONE; pKsl->type.ap.mode = pDot11->hdd->curMode; /* Set a default BSS */ pKsl->pBss = &pDot11->sme->bss[0]; pKsl->wepKeyMapping = FALSE; pKsl->accessControlled = FALSE; if (dot11KslUnlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslAdd: Cannot free lock\n", 0,0,0,0,0,0)); /* No point in returning NULL, since we may already have a valid KSL entry */ } /* We don't have to clear out the KSL RC table, since we used calloc above. If the use of calloc is optimized away, then it will become necessary to clear the packetRing array here */ return pKsl; }/***************************************************************************** dot11KslDelete - Deletes a specific KSL entry** This routine goes in and deletes a specific KSL entry, while preserving* the integrity of the rest of the list.** RETURNS: OK or ERROR if unable to delete.** ERRNO: N/A*/LOCAL STATUS dot11KslDelete ( DOT11_FW * pDot11, /* Pointer to DOT11 root object */ DOT11_KSL_ENTRY * pKsl /* KSL entry to delete */ ) { DOT11_KSL_ENTRY * pBug; /* Used to traverse hash bucket */ if ((pDot11 == NULL) || (pKsl == NULL)) { return ERROR; } DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslDelete: Deleting KSL for " DOT11_MAC_ADDR_STR "\n", DOT11_MAC_ADDR(pKsl->macAddr))); if (dot11KslLock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_SME, ("dot11KslAdd: Cannot get lock\n", 0,0,0,0,0,0)); return ERROR; } /* Get the hash bucket to which the entry should belong */ pBug = pDot11->sme->ksl.list[DOT11_KSL_HASH(pKsl->macAddr)]; /* Search through the list until we either reach the end or find the entry before the one we want to delete */ while ((pBug != NULL) && (pBug->pNext != pKsl)) { pBug = pBug->pNext; } /* Check if we exited because of a match. If this is the case, pBug is the entry before pKsl. */ if (pBug != NULL) { pBug->pNext = pKsl->pNext; dot11KslEntryFree(pDot11, pKsl); } if (dot11KslUnlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_SME, ("dot11KslDelete: Cannot free lock\n", 0,0,0,0,0,0)); /* No point in returning ERROR, since we already deleted it */ } if (pBug == NULL) { return ERROR; } else { return OK; } }/****************************************************************************** dot11KslSSIDLookup - Find an existing AP entry in the KSL by SSID** This func finds an existing entry by SSID in the KSL. If multiple entries* are found, then the one with the best signal strength is chosen.** RETURNS: Pointer to KSL entry, or NULL** ERRNO: N/A*/LOCAL DOT11_KSL_ENTRY * dot11KslSSIDLookup ( DOT11_FW * pDot11, /* Pointer to device structure */ char * ssid, /* SSID to look for */ int dot11Mode /* Mode to look for, NONE for any */ ) { int hash; DOT11_KSL_ENTRY * pKsl; DOT11_KSL_ENTRY * pFoundKsl; pFoundKsl = NULL; /* Check that we have a valid pDot11, KSL and SSID */ if ((ssid == NULL) || (pDot11 == NULL) || (strlen(ssid) > DOT11_SSID_LEN)) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslSSIDLookup: Bad parameters\n", 0, 0, 0, 0, 0, 0)); return NULL; } if (dot11KslLock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslSSIDLookup: Cannot get lock\n", 0,0,0,0,0,0)); return NULL; } DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslSSIDLookup: Looking for for ssid \"%s\" \n", (int)ssid, 0, 0, 0, 0, 0)); for (hash = 0; hash < DOT11_KSL_MAX_HASH; hash ++) { /* Start at the head of the hash bin */ pKsl = pDot11->sme->ksl.list[hash]; /* Now look for the right thing. In the following order, do the comparison: 1. Are we looking for a specific type of STA. If so, is this it? 2. Are we looking for a specific SSID? If so, do the lengths match. If so, are the names the same? */ while (pKsl != NULL) { if (((dot11Mode == DOT11_MODE_NONE) || (dot11Mode == pKsl->dot11Mode)) && ( (strlen(ssid) == 0) || ((strlen(ssid) == strlen(pKsl->ssid)) && (bcmp(ssid, pKsl->ssid, strlen(ssid)) == 0)))) { /* Before we declare a match, ensure that this one at least conforms to the current security policy, if enabled */ if (pKsl->pBss->secPol != DOT11_SECPOL_NONE) { /* Reject the match if it doesn't have a secPol, and isn't a legacy WEP AP that we can connect to because we're in a TSN */ if ((pKsl->negSecPol == DOT11_SECPOL_NONE) && !(((pKsl->pBss->secPol & DOT11_SECPOL_TSN) == 0) && ((pKsl->capabilities & DOT11_CPU_TO_LE_16(DOT11_CAP_PRIVACY)) == 0))) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslSSIDLookup: AP " DOT11_MAC_ADDR_STR " does not have a security policy set" " policy\n",DOT11_MAC_ADDR(pKsl->macAddr))); /* One of the policies was not met. Continue onwards */ pKsl = pKsl->pNext; continue; } /* Reject the match if a policy match wasn't negotiated when the AP's capabilities were scanned */ if ((pKsl->negAuthPol == 0) || (pKsl->uniEncryptType == 0) || ((pKsl->groupPol & pKsl->pBss->ciphPol) == 0)) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslSSIDLookup: AP " DOT11_MAC_ADDR_STR " does not conform to the current security" " policy\n", DOT11_MAC_ADDR(pKsl->macAddr))); /* One of the policies was not met. Continue onwards */ pKsl = pKsl->pNext; continue; } } DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslSSIDLookup: Match for ssid \"%s\" on " "channel %d SSID \"%s\"\n",(int)ssid, pKsl->type.ap.channel, (int)pKsl->ssid, 0, 0, 0)); /* Check if we have a previous search result */ if (pFoundKsl != NULL) { /* First, see if the previous result is "older" than this result. This is used to screen out results that rejected our attempts to communicate previously */ if (pFoundKsl->lastAttempt < pKsl->lastAttempt) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslSSIDLookup: AP " DOT11_MAC_ADDR_STR " rejected because newer AP found\n", DOT11_MAC_ADDR(pKsl->macAddr))); pKsl = pKsl->pNext; continue; } else if (pFoundKsl->lastAttempt > pKsl->lastAttempt) { pFoundKsl = pKsl; } /* Second, see if the old match had a lousy security policy match - TSN. If so, then if this one has better, it's a "better" AP, regardless of signal strength */ if (((pFoundKsl->negSecPol == 0) && (pKsl->negSecPol != 0)) || (((pFoundKsl->negSecPol & DOT11_SECPOL_TSN) != 0) && ((pKsl->negSecPol & DOT11_SECPOL_TSN) == 0))) { pFoundKsl = pKsl; } else { /* Since there is a previous search result, we need to decide which to keep */ switch (pKsl->dot11Mode) { case DOT11_MODE_AP: if (pFoundKsl->type.ap.ssi < pKsl->type.ap.ssi) { pFoundKsl = pKsl; } break; case DOT11_MODE_IBSS: if (pFoundKsl->type.ibss.ssi<pKsl->type.ibss.ssi) { pFoundKsl = pKsl; } break; case DOT11_MODE_ESS: /* We really shouldn't be doing this type of lookup on a station. Skip this entry */ break; default: /* Do nothing - use the old entry which may have been more filled in */ break; } } } else /* There is no previous result */ { /* If this is the only one we've found, then it is the best result so far */ pFoundKsl = pKsl; } } pKsl = pKsl->pNext; } } if (dot11KslUnlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslSSIDLookup: Cannot free lock\n", 0,0,0,0,0,0)); /* No point in returning NULL, since we may already have a valid KSL entry */ } if (pFoundKsl != NULL) { DOT11_LOG(DOT11_DEBUG_INFO, DOT11_AREA_SME, ("dot11KslSSIDLookup: Best ssid \"%s\" on " "channel %d SSID \"%s\"\n",(int)ssid, pFoundKsl->type.ap.channel, (int)pFoundKsl->ssid, 0, 0, 0)); pFoundKsl->lastAttempt = tickGet(); } return pFoundKsl; }/***************************************************************************** dot11KslRxUpdate - Finds and updates a KSL entry for a received packet** This routine is called for all valid ingress data packets. It updates the* timestamp and adds entries to the rxRate and ssi tables for this entry** RETURNS: Pointer to KSL entry or NULL if STA is unknown** ERRNO: N/A*/LOCAL DOT11_KSL_ENTRY * dot11KslRxUpdate ( DOT11_FW * pDot11, /* Pointer to device structure */ UINT8 * macAddr, /* MAC Address of newfound entity */ int rxRate, /* Rate in 500kb/s units */ int ssi /* Receive signal strength 0-100 */ ) { DOT11_KSL_ENTRY * pKsl; if (dot11KslLock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_ERROR, DOT11_AREA_SME, ("dot11KslRxUpdate: Cannot get lock.\n", 0, 0, 0, 0, 0, 0)); return NULL; } /* Check if this entry exists in the KSL */ if ((pKsl = dot11KslLookup(pDot11, macAddr)) == NULL) { /* It is not an error; it just means the entry was not present */ semGive(pDot11->sme->ksl.lockSem); dot11KslUnlock(pDot11); return NULL; } pKsl->timestamp = tickGet(); if (dot11KslUnlock(pDot11) != OK) { DOT11_LOG(DOT11_DEBUG_FATAL, DOT11_AREA_INIT, ("dot11KslRxUpdate: Cannot free lock\n", 0,0,0,0,0,0)); /* No point in returning NULL, since we may already have a valid KSL entry */ } return pKsl; }/***************************************************************************** dot11KslTxUpdate - Updates the Rate Control engine with a TX packet** This routine is called by the HDD to notify the upper layers of the status* of a transmit attempt. The status is codified by the nRetries parameter, * which should be 0 for a successful attempt, and DOT11_RETRY_FAIL_WEIGHT for* a failure. Otherwise it should be the number of retries before the packet* was sent. This info is used to maintain the Rate Control engine. ** RETURNS: OK or ERROR** ERRNO: N/A*/LOCAL DOT11_KSL_ENTRY * dot11KslTxUpdate ( DOT11_FW * pDot11, /* Pointer to device structure */ UINT8 * macAddr, /* MAC Address of newfound entity */ BOOL success, /* Whether packet was success (TRUE) or not */ UINT32 nRetries, /* Number of retries before succeeding */ UINT32 ackSSI /* Signal strength of ACK */ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -