v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket ) { VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; v_BOOL_t fEAPOL = VOS_FALSE; void *pBuffer = NULL; vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET, &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE ); if (VOS_IS_STATUS_SUCCESS( vosStatus ) ) { if ( vos_be16_to_cpu( *(unsigned short*)pBuffer ) == HDD_ETHERTYPE_802_1_X ) { fEAPOL = VOS_TRUE; } } return fEAPOL; }
v_BOOL_t hdd_IsWAIPacket( vos_pkt_t *pVosPacket ) { VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; v_BOOL_t fIsWAI = VOS_FALSE; void *pBuffer = NULL; // Need to update this function vosStatus = vos_pkt_peek_data( pVosPacket, (v_SIZE_t)HDD_ETHERTYPE_802_1_X_FRAME_OFFSET, &pBuffer, HDD_ETHERTYPE_802_1_X_SIZE ); if (VOS_IS_STATUS_SUCCESS( vosStatus ) ) { if ( vos_be16_to_cpu( *(unsigned short*)pBuffer ) == HDD_ETHERTYPE_WAI) { fIsWAI = VOS_TRUE; } } return fIsWAI; }
/** * aniAsfPacketGet16 * * FUNCTION: * Reads a ANI_U16 out of the packet and returns it. The packet's head * is advanced and its length decremented by the appropriate length. * All network to host byte order translation is also taken care of. * * @param packet the packet to read from * @param val the value to fill in * * @return ANI_OK if the operation succeeds */ int aniAsfPacketGet16(tAniPacket *packet, v_U16_t *val) { v_U8_t u16Arr[2]; if (packet == NULL) return ANI_E_NULL_VALUE; if (val == NULL) return ANI_E_NULL_VALUE; if (packet->len < 2) return ANI_E_SHORT_PACKET; u16Arr[0] = packet->head[0]; u16Arr[1] = packet->head[1]; *val = vos_be16_to_cpu( *(v_U16_t *)u16Arr ); aniAsfPacketTruncateFromFront(packet, 2); return ANI_OK; }
int hdd_mon_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { v_U16_t rt_hdr_len; struct ieee80211_hdr *hdr; hdd_adapter_t *pPgBkAdapter, *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); struct ieee80211_radiotap_header *rtap_hdr = (struct ieee80211_radiotap_header *)skb->data; /*Supplicant sends the EAPOL packet on monitor interface*/ pPgBkAdapter = pAdapter->sessionCtx.monitor.pAdapterForTx; if(pPgBkAdapter == NULL) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: No Adapter to piggy back. Dropping the pkt on monitor inf", __func__); goto fail; /* too short to be possibly valid */ } /* check if toal skb length is greater then radio tab header length of not */ if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header))) goto fail; /* too short to be possibly valid */ /* check if radio tap header version is correct or not */ if (unlikely(rtap_hdr->it_version)) goto fail; /* only version 0 is supported */ /*Strip off the radio tap header*/ rt_hdr_len = ieee80211_get_radiotap_len(skb->data); /* check if skb length if greator then total radio tap header length ot not*/ if (unlikely(skb->len < rt_hdr_len)) goto fail; /* Update the trans_start for this netdev */ dev->trans_start = jiffies; /* * fix up the pointers accounting for the radiotap * header still being in there. */ skb_set_mac_header(skb, rt_hdr_len); skb_set_network_header(skb, rt_hdr_len); skb_set_transport_header(skb, rt_hdr_len); /* Pull rtap header out of the skb */ skb_pull(skb, rt_hdr_len); /*Supplicant adds: radiotap Hdr + radiotap data + 80211 Header. So after * radio tap header and 802.11 header starts */ hdr = (struct ieee80211_hdr *)skb->data; /* Send data frames through the normal Data path. In this path we will * conver rcvd 802.11 packet to 802.3 packet */ if ( (hdr->frame_control & HDD_FRAME_TYPE_MASK) == HDD_FRAME_TYPE_DATA) { v_U8_t da[6]; v_U8_t sa[6]; memcpy (da, hdr->addr1, VOS_MAC_ADDR_SIZE); memcpy (sa, hdr->addr2, VOS_MAC_ADDR_SIZE); /* Pull 802.11 MAC header */ skb_pull(skb, HDD_80211_HEADER_LEN); if ( HDD_FRAME_SUBTYPE_QOSDATA == (hdr->frame_control & HDD_FRAME_SUBTYPE_MASK)) { skb_pull(skb, HDD_80211_HEADER_QOS_CTL); } /* Pull LLC header */ skb_pull(skb, HDD_LLC_HDR_LEN); /* Create space for Ethernet header */ skb_push(skb, HDD_MAC_HDR_SIZE*2); memcpy(&skb->data[0], da, HDD_MAC_HDR_SIZE); memcpy(&skb->data[HDD_DEST_ADDR_OFFSET], sa, HDD_MAC_HDR_SIZE); /* Only EAPOL Data packets are allowed through monitor interface */ if (vos_be16_to_cpu( (*(unsigned short*)&skb->data[HDD_ETHERTYPE_802_1_X_FRAME_OFFSET]) ) != HDD_ETHERTYPE_802_1_X) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: Not a Eapol packet. Drop this frame", __func__); //If not EAPOL frames, drop them. kfree_skb(skb); return NETDEV_TX_OK; } skb->protocol = htons(HDD_ETHERTYPE_802_1_X); hdd_hostapd_select_queue(pPgBkAdapter->dev, skb); return hdd_softap_hard_start_xmit( skb, pPgBkAdapter->dev ); } else { VOS_STATUS status; WLANTL_ACEnumType ac = 0; skb_list_node_t *pktNode = NULL; v_SIZE_t pktListSize = 0; spin_lock(&pAdapter->wmm_tx_queue[ac].lock); //If we have already reached the max queue size, disable the TX queue if ( pAdapter->wmm_tx_queue[ac].count == pAdapter->wmm_tx_queue[ac].max_size) { /* We want to process one packet at a time, so lets disable all TX queues * and re-enable the queues once we get TX feedback for this packet */ netif_tx_stop_all_queues(pAdapter->dev); pAdapter->isTxSuspended[ac] = VOS_TRUE; spin_unlock(&pAdapter->wmm_tx_queue[ac].lock); return NETDEV_TX_BUSY; } spin_unlock(&pAdapter->wmm_tx_queue[ac].lock); //Use the skb->cb field to hold the list node information pktNode = (skb_list_node_t *)&skb->cb; //Stick the OS packet inside this node. pktNode->skb = skb; INIT_LIST_HEAD(&pktNode->anchor); //Insert the OS packet into the appropriate AC queue spin_lock(&pAdapter->wmm_tx_queue[ac].lock); status = hdd_list_insert_back_size( &pAdapter->wmm_tx_queue[ac], &pktNode->anchor, &pktListSize ); spin_unlock(&pAdapter->wmm_tx_queue[ac].lock); if ( !VOS_IS_STATUS_SUCCESS( status ) ) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:Insert Tx queue failed. Pkt dropped", __FUNCTION__); kfree_skb(skb); return NETDEV_TX_OK; } if ( pktListSize == 1 ) { /* In this context we cannot acquire any mutex etc. And to transmit * this packet we need to call SME API. So to take care of this we will * schedule a workqueue */ schedule_work(&pPgBkAdapter->monTxWorkQueue); } return NETDEV_TX_OK; } fail: VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "%s: Packet Rcvd at Monitor interface is not proper," " Dropping the packet", __func__); kfree_skb(skb); return NETDEV_TX_OK; }
/*---------------------------------------------------------------------------- FUNCTION WLANBAP_STARxCB DESCRIPTION The receive callback registered with TL. TL will call this to notify the client when a packet was received for a registered STA. PARAMETERS IN pvosGCtx: pointer to the global vos context; a handle to TL's or HDD's control block can be extracted from its context vosDataBuff: pointer to the VOSS data buffer that was received (it may be a linked list) ucSTAId: station id pRxMetaInfo: meta info for the received packet(s) RETURN VALUE The result code associated with performing the operation ----------------------------------------------------------------------------*/ VOS_STATUS WLANBAP_STARxCB ( v_PVOID_t pvosGCtx, vos_pkt_t* vosDataBuff, v_U8_t ucSTAId, WLANTL_RxMetaInfoType* pRxMetaInfo ) { VOS_STATUS vosStatus; ptBtampHandle bapHdl; /* holds ptBtampHandle value returned */ ptBtampContext bapContext; /* Holds the btampContext value returned */ v_PVOID_t pHddHdl; /* Handle to return BSL context in */ ptBtampHandle btampHandle; WLANBAP_8023HeaderType w8023Header; v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; v_U16_t protoType ; v_SIZE_t llcHeaderLen = WLANBAP_LLC_HEADER_LEN ; VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "In WLANBAP_STARxCB"); /* Lookup the BSL and BAP contexts using the StaId */ vosStatus = WLANBAP_GetCtxFromStaId ( ucSTAId, /* The StaId (used by TL, PE, and HAL) */ &bapHdl, /* "handle" to return ptBtampHandle value in */ &bapContext, /* "handle" to return ptBtampContext value in */ &pHddHdl); /* "handle" to return BSL context in */ if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Unable to retrieve BSL or BAP context from STA Id in WLANBAP_STARxCB"); /* Drop packet */ vos_pkt_return_packet(vosDataBuff); return VOS_STATUS_E_FAULT; } vosStatus = vos_pkt_extract_data( vosDataBuff, sizeof(w8023Header), (v_VOID_t *)aucLLCHeader, &llcHeaderLen); if ( NULL == aucLLCHeader/*LLC Header*/ ) { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "WLANBAP_STARxCB:Cannot extract LLC header"); /* Drop packet */ vos_pkt_return_packet(vosDataBuff); return VOS_STATUS_E_FAULT; } vos_mem_copy(&protoType,&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET],WLANBAP_LLC_PROTO_TYPE_SIZE); protoType = vos_be16_to_cpu(protoType); VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "%s: received : %d, => BAP",__FUNCTION__, protoType); if(WLANBAP_BT_AMP_TYPE_DATA == protoType) { if (bapContext->bapLinkSupervisionTimerInterval) { /* Reset Link Supervision timer */ //vosStatus = WLANBAP_StopLinkSupervisionTimer(bapContext); //vosStatus = WLANBAP_StartLinkSupervisionTimer(bapContext,7000); bapContext->dataPktPending = VOS_TRUE;//Indication for LinkSupervision module that data is pending /* Invoke the callback that BSL registered with me */ vosStatus = (*bapContext->pfnBtamp_STARxCB)( pHddHdl, vosDataBuff, pRxMetaInfo); } else { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_FATAL, "WLANBAP_STARxCB:bapLinkSupervisionTimerInterval is 0"); /* Drop packet */ vos_pkt_return_packet(vosDataBuff); } } else { VOS_TRACE( VOS_MODULE_ID_TL, VOS_TRACE_LEVEL_ERROR, "%s: link Supervision packet received over TL: %d, => BAP", __FUNCTION__,protoType); btampHandle = (ptBtampHandle)bapContext; vosStatus = WLANBAP_RxProcLsPkt( btampHandle, bapContext->phy_link_handle, protoType, vosDataBuff ); } return vosStatus; } /* WLANBAP_STARxCB */
/*=========================================================================== FUNCTION WLANBAP_XlateRxDataPkt DESCRIPTION HDD will call this API when it has received a 802.3 (TL/UMA has Xlated from 802.11) frame from TL and it wants to form a BT HCI Data Packet - ready to signal up to the BT stack application. PARAMETERS btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. pucAC: Pointer to return the access category vosDataBuff: The data buffer containing the 802.3 frame to be translated to BT HCI Data Packet RETURN VALUE The result code associated with performing the operation VOS_STATUS_E_INVAL: Input parameters are invalid VOS_STATUS_E_FAULT: BAP handle is NULL VOS_STATUS_SUCCESS: Everything is good :) SIDE EFFECTS ============================================================================*/ VOS_STATUS WLANBAP_XlateRxDataPkt ( ptBtampHandle btampHandle, v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ WLANTL_ACEnumType *pucAC, /* Return the AC here. I don't think this is needed */ vos_pkt_t *vosDataBuff ) { WLANBAP_8023HeaderType w8023Header; WLANBAP_HCIACLHeaderType hciACLHeader; v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; VOS_STATUS vosStatus; //v_PVOID_t pHddHdl; /* Handle to return BSL context in */ v_U16_t hciDataLength; /* The HCI packet data length*/ v_U16_t protoType = WLANBAP_BT_AMP_TYPE_DATA; /* The protocol type bytes*/ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /*------------------------------------------------------------------------ Sanity check params ------------------------------------------------------------------------*/ if ( NULL == pBtampCtx) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Invalid BAP handle value in %s", __FUNCTION__); return VOS_STATUS_E_FAULT; } // Here, I have to make the assumption that this is an // 802.3 header followed by an LLC/SNAP packet. vos_mem_set( &w8023Header, sizeof(w8023Header), 0 ); vosStatus = vos_pkt_pop_head( vosDataBuff, &w8023Header, sizeof(w8023Header)); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLAN BAP: Failed to pop 802.3 header from packet %d", vosStatus); return vosStatus; } // Here, is that LLC/SNAP header. // With the BT SIG OUI that I am being handed. vos_mem_set( aucLLCHeader, WLANBAP_LLC_HEADER_LEN, 0 ); vosStatus = vos_pkt_pop_head( vosDataBuff, aucLLCHeader, WLANBAP_LLC_HEADER_LEN); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLAN BAP: Failed to pop LLC/SNAP header from packet %d", vosStatus); return vosStatus; } #ifdef BAP_DEBUG // JEZ081003: Remove this after debugging // Should I double check that I am getting the BT SIG OUI ? if ( !(vos_mem_compare( aucLLCHeader, WLANBAP_LLC_HEADER, sizeof(WLANBAP_LLC_HEADER) - WLANBAP_LLC_OUI_SIZE) /* Don't check the last three bytes here */ && vos_mem_compare( &aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], (v_VOID_t*)WLANBAP_BT_AMP_OUI, WLANBAP_LLC_OUI_SIZE))) /* check them here */ { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Invalid LLC header for BT-AMP packet in %s", __FUNCTION__); return VOS_STATUS_E_FAULT; } #endif //BAP_DEBUG /* Now adjust the protocol type bytes*/ protoType = vos_cpu_to_be16( protoType); // check if this is a data frame or other, internal to BAP, type... // we are only handling data frames in here... // The others (Security and AR) are handled by TLs BAP client API. // (Verify with TL) if ( !(vos_mem_compare( &aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], &protoType, //WLANBAP_BT_AMP_TYPE_DATA WLANBAP_LLC_PROTO_TYPE_SIZE))) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "Invalid (non-data) frame type in %s", __FUNCTION__); return VOS_STATUS_E_FAULT; } #ifdef BAP_DEBUG // JEZ081003: Remove this after debugging /*------------------------------------------------------------------------ Sanity check the MAC address in the physical link context against the value in the incoming Rx Frame. ------------------------------------------------------------------------*/ if ( !(vos_mem_compare( w8023Header.vDA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE) && vos_mem_compare( w8023Header.vSA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE))) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "MAC address mismatch in %s", __FUNCTION__); return VOS_STATUS_E_FAULT; } #endif //BAP_DEBUG /* No lookup is needed. Because TL has already told WLANBAP_STARxCB * the StaId. And I told WLANBAP_STARxCBType the corresponding BSL context * Which he used to lookup the phy_link_handle value. */ // Start filling in the HCI header hciACLHeader.phyLinkHandle = phy_link_handle; // Continue filling in the HCI header //JEZ100913: On Rx the Logical Link is ALWAYS 0. See Vol 2, Sec E, 5.4.2 of spec. hciACLHeader.logLinkHandle = 0; hciACLHeader.PBFlag = WLANBAP_HCI_PKT_AMP; hciACLHeader.BCFlag = 0; /* Now the length field is big-endian?! */ hciDataLength = vos_be16_to_cpu(w8023Header.usLenType); /* Max length WLANBAP_MAX_80211_PAL_PDU_SIZE (1492) */ hciDataLength -= WLANBAP_LLC_HEADER_LEN; /* The HCI packet data length is Little-endian */ hciACLHeader.dataLength = vos_cpu_to_le16(hciDataLength); /* Return the AC here. * (I can't because there is no way to figure out what it is.) */ *pucAC = 0; /* Push on the HCI header */ vos_pkt_push_head(vosDataBuff, &hciACLHeader, WLANBAP_HCI_ACL_HEADER_LEN); return VOS_STATUS_SUCCESS; } /* WLANBAP_XlateRxDataPkt */