📄 prism2sta.c
字号:
** Call context:* interrupt----------------------------------------------------------------*/void prism2sta_inf_chinforesults(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf){ hfa384x_t *hw = (hfa384x_t *)wlandev->priv; unsigned int i, n; DBFENTER; hw->channel_info.results.scanchannels = hfa384x2host_16(inf->info.chinforesult.scanchannels);#if 0 memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t));#endif for (i=0, n=0; i<HFA384x_CHINFORESULT_MAX; i++) { if (hw->channel_info.results.scanchannels & (1<<i)) { int channel=hfa384x2host_16(inf->info.chinforesult.result[n].chid)-1; hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel]; chinforesult->chid = channel; chinforesult->anl = hfa384x2host_16(inf->info.chinforesult.result[n].anl); chinforesult->pnl = hfa384x2host_16(inf->info.chinforesult.result[n].pnl); chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active); WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", channel+1, chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise", chinforesult->anl, chinforesult->pnl, chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0 ); n++; } } atomic_set(&hw->channel_info.done, 2); hw->channel_info.count = n; DBFEXIT; return;}void prism2sta_processing_defer(void *data){ hfa384x_t *hw = (hfa384x_t *) data; wlandevice_t *wlandev = hw->wlandev; hfa384x_bytestr32_t ssid; int result; DBFENTER; /* First let's process the auth frames */ { struct sk_buff *skb; hfa384x_InfFrame_t *inf; while ( (skb = skb_dequeue(&hw->authq)) ) { inf = (hfa384x_InfFrame_t *) skb->data; prism2sta_inf_authreq_defer(wlandev, inf); } } /* Now let's handle the linkstatus stuff */ if (hw->link_status == hw->link_status_new) goto failed; hw->link_status = hw->link_status_new; switch(hw->link_status) { case HFA384x_LINK_NOTCONNECTED: /* I'm currently assuming that this is the initial link * state. It should only be possible immediately * following an Enable command. * Response: * Block Transmits, Ignore receives of data frames */ netif_carrier_off(wlandev->netdev); WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n"); break; case HFA384x_LINK_CONNECTED: /* This one indicates a successful scan/join/auth/assoc. * When we have the full MLME complement, this event will * signify successful completion of both mlme_authenticate * and mlme_associate. State management will get a little * ugly here. * Response: * Indicate authentication and/or association * Enable Transmits, Receives and pass up data frames */ netif_carrier_on(wlandev->netdev); /* If we are joining a specific AP, set our state and reset retries */ if(hw->join_ap == 1) hw->join_ap = 2; hw->join_retries = 60; /* Don't call this in monitor mode */ if ( wlandev->netdev->type == ARPHRD_ETHER ) { UINT16 portstatus; WLAN_LOG_INFO("linkstatus=CONNECTED\n"); /* For non-usb devices, we can use the sync versions */ /* Collect the BSSID, and set state to allow tx */ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CURRENTBSSID, wlandev->bssid, WLAN_BSSID_LEN); if ( result ) { WLAN_LOG_DEBUG(1, "getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTBSSID, result); goto failed; } result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CURRENTSSID, &ssid, sizeof(ssid)); if ( result ) { WLAN_LOG_DEBUG(1, "getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTSSID, result); goto failed; } prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid, (p80211pstrd_t *) &wlandev->ssid); /* Collect the port status */ result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &portstatus); if ( result ) { WLAN_LOG_DEBUG(1, "getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_PORTSTATUS, result); goto failed; } wlandev->macmode = (portstatus == HFA384x_PSTATUS_CONN_IBSS) ? WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA; /* Get the ball rolling on the comms quality stuff */ prism2sta_commsqual_defer(hw); } break; case HFA384x_LINK_DISCONNECTED: /* This one indicates that our association is gone. We've * lost connection with the AP and/or been disassociated. * This indicates that the MAC has completely cleared it's * associated state. We * should send a deauth indication * (implying disassoc) up * to the MLME. * Response: * Indicate Deauthentication * Block Transmits, Ignore receives of data frames */ if(hw->join_ap == 2) { hfa384x_JoinRequest_data_t joinreq; joinreq = hw->joinreq; /* Send the join request */ hfa384x_drvr_setconfig( hw, HFA384x_RID_JOINREQUEST, &joinreq, HFA384x_RID_JOINREQUEST_LEN); WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n"); } else { if (wlandev->netdev->type == ARPHRD_ETHER) WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n"); } wlandev->macmode = WLAN_MACMODE_NONE; netif_carrier_off(wlandev->netdev); break; case HFA384x_LINK_AP_CHANGE: /* This one indicates that the MAC has decided to and * successfully completed a change to another AP. We * should probably implement a reassociation indication * in response to this one. I'm thinking that the the * p80211 layer needs to be notified in case of * buffering/queueing issues. User mode also needs to be * notified so that any BSS dependent elements can be * updated. * associated state. We * should send a deauth indication * (implying disassoc) up * to the MLME. * Response: * Indicate Reassociation * Enable Transmits, Receives and pass up data frames */ WLAN_LOG_INFO("linkstatus=AP_CHANGE\n"); result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CURRENTBSSID, wlandev->bssid, WLAN_BSSID_LEN); if ( result ) { WLAN_LOG_DEBUG(1, "getconfig(0x%02x) failed, result = %d\n", HFA384x_RID_CURRENTBSSID, result); goto failed; } hw->link_status = HFA384x_LINK_CONNECTED; netif_carrier_on(wlandev->netdev); break; case HFA384x_LINK_AP_OUTOFRANGE: /* This one indicates that the MAC has decided that the * AP is out of range, but hasn't found a better candidate * so the MAC maintains its "associated" state in case * we get back in range. We should block transmits and * receives in this state. Do we need an indication here? * Probably not since a polling user-mode element would * get this status from from p2PortStatus(FD40). What about * p80211? * Response: * Block Transmits, Ignore receives of data frames */ WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n"); netif_carrier_off(wlandev->netdev); break; case HFA384x_LINK_AP_INRANGE: /* This one indicates that the MAC has decided that the * AP is back in range. We continue working with our * existing association. * Response: * Enable Transmits, Receives and pass up data frames */ WLAN_LOG_INFO("linkstatus=AP_INRANGE\n"); hw->link_status = HFA384x_LINK_CONNECTED; netif_carrier_on(wlandev->netdev); break; case HFA384x_LINK_ASSOCFAIL: /* This one is actually a peer to CONNECTED. We've * requested a join for a given SSID and optionally BSSID. * We can use this one to indicate authentication and * association failures. The trick is going to be * 1) identifying the failure, and 2) state management. * Response: * Disable Transmits, Ignore receives of data frames */ if(hw->join_ap && --hw->join_retries > 0) { hfa384x_JoinRequest_data_t joinreq; joinreq = hw->joinreq; /* Send the join request */ hfa384x_drvr_setconfig( hw, HFA384x_RID_JOINREQUEST, &joinreq, HFA384x_RID_JOINREQUEST_LEN); WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n"); } else { WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n"); } netif_carrier_off(wlandev->netdev); break; default: /* This is bad, IO port problems? */ WLAN_LOG_WARNING( "unknown linkstatus=0x%02x\n", hw->link_status); goto failed; break; } failed: DBFEXIT;}/*----------------------------------------------------------------* prism2sta_inf_linkstatus** Handles the receipt of a Link Status info frame.** Arguments:* wlandev wlan device structure* inf ptr to info frame (contents in hfa384x order)** Returns: * nothing** Side effects:** Call context:* interrupt----------------------------------------------------------------*/void prism2sta_inf_linkstatus(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf){ hfa384x_t *hw = (hfa384x_t *)wlandev->priv; DBFENTER; hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus); schedule_work(&hw->link_bh); DBFEXIT; return;}/*----------------------------------------------------------------* prism2sta_inf_assocstatus** Handles the receipt of an Association Status info frame. Should * be present in APs only.** Arguments:* wlandev wlan device structure* inf ptr to info frame (contents in hfa384x order)** Returns: * nothing** Side effects:** Call context:* interrupt----------------------------------------------------------------*/void prism2sta_inf_assocstatus(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf){ hfa384x_t *hw = (hfa384x_t *)wlandev->priv; hfa384x_AssocStatus_t rec; int i; DBFENTER; memcpy(&rec, &inf->info.assocstatus, sizeof(rec)); rec.assocstatus = hfa384x2host_16(rec.assocstatus); rec.reason = hfa384x2host_16(rec.reason); /* ** Find the address in the list of authenticated stations. If it wasn't ** found, then this address has not been previously authenticated and ** something weird has happened if this is anything other than an ** "authentication failed" message. If the address was found, then ** set the "associated" flag for that station, based on whether the ** station is associating or losing its association. Something weird ** has also happened if we find the address in the list of authenticated ** stations but we are getting an "authentication failed" message. */ for (i = 0; i < hw->authlist.cnt; i++) if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0) break; if (i >= hw->authlist.cnt) { if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL) WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n"); } else { hw->authlist.assoc[i] = (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC || rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC); if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL) WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n"); } DBFEXIT; return;}/*----------------------------------------------------------------* prism2sta_inf_authreq** Handles the receipt of an Authentication Request info frame. Should * be present in APs only.** Arguments:* wlandev wlan device structure* inf ptr to info frame (contents in hfa384x order)** Returns: * nothing** Side effects:** Call context:* interrupt*----------------------------------------------------------------*/void prism2sta_inf_authreq( wlandevice_t *wlandev, hfa384x_InfFrame_t *inf){ hfa384x_t *hw = (hfa384x_t *)wlandev->priv; struct sk_buff *skb; DBFENTER; skb = dev_alloc_skb(sizeof(*inf)); if (skb) { skb_put(skb, sizeof(*inf)); memcpy(skb->data, inf, sizeof(*inf)); skb_queue_tail(&hw->authq, skb); schedule_work(&hw->link_bh); } DBFEXIT;}void prism2sta_inf_authreq_defer(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf){ hfa384x_t *hw = (hfa384x_t *)wlandev->priv; hfa384x_authenticateStation_data_t rec; int i, added, result, cnt; UINT8 *addr; DBFENTER; /* ** Build the AuthenticateStation record. Initialize it for denying ** authentication. */ memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN); rec.status = P80211ENUM_status_unspec_failure; /* ** Authenticate based on the access mode. */ switch (hw->accessmode) { case WLAN_ACCESS_NONE: /* ** Deny all new authentications. However, if a station ** is ALREADY authenticated, then accept it. */ for (i = 0; i < hw->authlist.cnt; i++) if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0) { rec.status = P80211ENUM_status_successful; break; } break; case WLAN_ACCESS_ALL: /* ** Allow all authentications. */ rec.status = P80211ENUM_status_successful; break; case WLAN_ACCESS_ALLOW: /* ** Only allow the authentication if the MAC address ** is in the list of allowed addresses. ** ** Since this is the interrupt handler, we may be here ** while the access list is in the middle of being
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -