/** * aniAsfPacketAppend16 * * FUNCTION: * Appends a ANI_U16 to the end of the packet. * All host to network byte order translation is also taken care of. * * @param packet the packet to write to * @param val the value to append * * @return ANI_OK if the operation succeeds */ int aniAsfPacketAppend16(tAniPacket *packet, v_U16_t val) { v_U8_t *p8; if (packet == NULL) return ANI_E_NULL_VALUE; if (TAIL_SPACE(packet) < 2) return ANI_E_FAILED; val = vos_cpu_to_be16( val ); p8 = (v_U8_t *)&val; packet->tail[0] = p8[0]; packet->tail[1] = p8[1]; aniAsfPacketMoveRight(packet, 2); return ANI_OK; }
/** * aniAsfPacketPrepend16 * * FUNCTION: * Prepends a ANI_U16 to the start of the packet. * All host to network byte order translation is also taken care of. * * @param packet the packet to write to * @param val the value to prepend * * @return ANI_OK if the operation succeeds */ int aniAsfPacketPrepend16(tAniPacket *packet, v_U16_t val) { v_U8_t *p8; if (packet == NULL) return ANI_E_NULL_VALUE; if (HEAD_SPACE(packet) < 2) return ANI_E_FAILED; aniAsfPacketMoveLeft(packet, 2); val = vos_cpu_to_be16( val ); p8 = (v_U8_t *)&val; packet->head[0] = p8[0]; packet->head[1] = p8[1]; return ANI_OK; }
/*=========================================================================== FUNCTION WLANBAP_XlateTxDataPkt DESCRIPTION HDD will call this API when it has a HCI Data Packet and it wants to translate it into a 802.3 LLC frame - ready to send using TL. PARAMETERS btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl. phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId) pucAC: Pointer to return the access category vosDataBuff: The data buffer containing the BT-AMP packet to be translated to an 802.3 LLC frame tlMetaInfo: return meta info gleaned from the outgoing frame, here. 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_XlateTxDataPkt ( ptBtampHandle btampHandle, /* Used by BAP to identify the actual session and therefore addresses */ v_U8_t phy_link_handle, /* Used by BAP to indentify the WLAN assoc. (StaId) */ WLANTL_ACEnumType *pucAC, /* Return the AC here */ WLANTL_MetaInfoType *tlMetaInfo, /* Return the MetaInfo here. An assist to WLANBAP_STAFetchPktCBType */ vos_pkt_t *vosDataBuff ) { ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; tpBtampLogLinkCtx pLogLinkContext; WLANBAP_8023HeaderType w8023Header; WLANBAP_HCIACLHeaderType hciACLHeader; v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; VOS_STATUS vosStatus; v_U8_t ucSTAId; /* The StaId (used by TL, PE, and HAL) */ v_PVOID_t pHddHdl; /* Handle to return BSL context in */ v_U16_t headerLength; /* The 802.3 frame length*/ v_U16_t protoType = WLANBAP_BT_AMP_TYPE_DATA; /* The protocol type bytes*/ v_U32_t value = 0; /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ /*------------------------------------------------------------------------ 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 // HCI ACL Data packet that I am being handed. vosStatus = vos_pkt_pop_head( vosDataBuff, &hciACLHeader, WLANBAP_HCI_ACL_HEADER_LEN); if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLAN BAP: Failed to pop HCI ACL header from packet %d", vosStatus); return vosStatus; } // JEZ081003: Remove this after debugging // Sanity check the phy_link_handle value if ( phy_link_handle != hciACLHeader.phyLinkHandle ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLAN BAP: phy_link_handle mismatch in %s phy_link_handle=%d hciACLHeader.phyLinkHandle=%d", __FUNCTION__, phy_link_handle, hciACLHeader.phyLinkHandle); return VOS_STATUS_E_INVAL; } /* Lookup the StaId using the phy_link_handle and the BAP context */ vosStatus = WLANBAP_GetStaIdFromLinkCtx ( btampHandle, /* btampHandle value in */ phy_link_handle, /* phy_link_handle value in */ &ucSTAId, /* The StaId (used by TL, PE, and HAL) */ &pHddHdl); /* Handle to return BSL context */ if ( VOS_STATUS_SUCCESS != vosStatus ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO, "Unable to retrieve STA Id from BAP context and phy_link_handle in %s", __FUNCTION__); return VOS_STATUS_E_FAULT; } // JEZ081003: Remove this after debugging // Sanity check the log_link_handle value if (!BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle)) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLAN BAP: Invalid logical link handle (%d) in %s. Corrected.", hciACLHeader.logLinkHandle, __FUNCTION__); // JEZ090123: Insure that the logical link value is good hciACLHeader.logLinkHandle = 1; //return VOS_STATUS_E_INVAL; } /* Use the log_link_handle to retrieve the logical link context */ /* JEZ081006: abstract this with a proc. So you can change the impl later */ pLogLinkContext = &(pBtampCtx->btampLogLinkCtx[ hciACLHeader.logLinkHandle ]); // JEZ081003: Remove this after debugging // Sanity check the log_link_handle value // JEZ081113: I changed this to fail on an UNOCCUPIED entry if ( pLogLinkContext->present != VOS_TRUE) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLAN BAP: Invalid logical link entry in %s", __FUNCTION__); return VOS_STATUS_E_INVAL; } // Return the AC and MetaInfo // Now copy the AC values from the Logical Link context *pucAC = pLogLinkContext->btampAC; // Now copy the values from the Logical Link context to the MetaInfo tlMetaInfo->ucTID = pLogLinkContext->ucTID; tlMetaInfo->ucUP = pLogLinkContext->ucUP; tlMetaInfo->ucIsEapol = VOS_FALSE; tlMetaInfo->ucDisableFrmXtl = VOS_FALSE; tlMetaInfo->ucBcast = VOS_FALSE; /* hciACLHeader.BCFlag; */ /* Don't I want to use the BCFlag? */ tlMetaInfo->ucMcast = VOS_FALSE; tlMetaInfo->ucType = 0x00; /* What is this really ?? */ // tlMetaInfo->usTimeStamp = 0x00; /* Ravi, shouldn't you be setting this? It's in the VOS packet. */ // Form the 802.3 header vos_mem_copy( w8023Header.vDA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE); vos_mem_copy( w8023Header.vSA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE); /* Now this length passed down in HCI...is in little-endian */ headerLength = vos_le16_to_cpu(hciACLHeader.dataLength); headerLength += WLANBAP_LLC_HEADER_LEN; /* Now the 802.3 length field is big-endian?! */ w8023Header.usLenType = vos_cpu_to_be16(headerLength); /* Now adjust the protocol type bytes*/ protoType = vos_cpu_to_be16( protoType); /* Now form the LLC header */ vos_mem_copy(aucLLCHeader, WLANBAP_LLC_HEADER, sizeof(WLANBAP_LLC_HEADER)); vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], WLANBAP_BT_AMP_OUI, WLANBAP_LLC_OUI_SIZE); vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], &protoType, //WLANBAP_BT_AMP_TYPE_DATA WLANBAP_LLC_PROTO_TYPE_SIZE); /* Push on the LLC header */ vos_pkt_push_head(vosDataBuff, aucLLCHeader, WLANBAP_LLC_HEADER_LEN); /* Push on the 802.3 header */ vos_pkt_push_head(vosDataBuff, &w8023Header, sizeof(w8023Header)); /*Set the logical link handle as user data so that we can retrieve it on Tx Complete */ value = (v_U32_t)hciACLHeader.logLinkHandle; vos_pkt_set_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP, (v_VOID_t *)value); return VOS_STATUS_SUCCESS; }/*WLANBAP_XlateTxDataPkt*/
/*=========================================================================== 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 */
/*---------------------------------------------------------------------------- * Function Declarations and Documentation * -------------------------------------------------------------------------*/ VOS_STATUS WLANBAP_AcquireLSPacket( ptBtampContext pBtampCtx, vos_pkt_t **ppPacket, v_U16_t size, tANI_BOOLEAN isLsReq ) { VOS_STATUS vosStatus; vos_pkt_t *pPacket; WLANBAP_8023HeaderType w8023Header; v_U8_t aucLLCHeader[WLANBAP_LLC_HEADER_LEN]; v_U16_t headerLength; /* The 802.3 frame length*/ v_U16_t protoType; v_U8_t *pData = NULL; if(isLsReq) { protoType = WLANTL_BT_AMP_TYPE_LS_REQ; } else { protoType = WLANTL_BT_AMP_TYPE_LS_REP; } //If success, vosTxLsPacket is the packet and pData points to the head. vosStatus = vos_pkt_get_packet( &pPacket, VOS_PKT_TYPE_TX_802_11_MGMT,size, 1, VOS_TRUE, NULL, NULL ); if( VOS_IS_STATUS_SUCCESS( vosStatus ) ) { vosStatus = vos_pkt_reserve_head( pPacket, (v_VOID_t *)&pData, size ); if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "%s: failed to reserve size = %d\n",__FUNCTION__, size ); vos_pkt_return_packet( pPacket ); } } if( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) { VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR, "WLANBAP_LinkSupervisionTimerHandler failed to get vos_pkt\n" ); return vosStatus; } // Form the 802.3 header vos_mem_copy( w8023Header.vDA, pBtampCtx->peer_mac_addr, VOS_MAC_ADDR_SIZE); vos_mem_copy( w8023Header.vSA, pBtampCtx->self_mac_addr, VOS_MAC_ADDR_SIZE); headerLength = WLANBAP_LLC_HEADER_LEN; /* Now the 802.3 length field is big-endian?! */ w8023Header.usLenType = vos_cpu_to_be16(headerLength); /* Now adjust the protocol type bytes*/ protoType = vos_cpu_to_be16( protoType); /* Now form the LLC header */ vos_mem_copy(aucLLCHeader, WLANBAP_LLC_HEADER, sizeof(WLANBAP_LLC_HEADER)); vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_OUI_OFFSET], WLANBAP_BT_AMP_OUI, WLANBAP_LLC_OUI_SIZE); vos_mem_copy(&aucLLCHeader[WLANBAP_LLC_PROTO_TYPE_OFFSET], &protoType, //WLANBAP_BT_AMP_TYPE_LS_REQ WLANBAP_LLC_PROTO_TYPE_SIZE); /* Push on the LLC header */ vos_pkt_push_head(pPacket, aucLLCHeader, WLANBAP_LLC_HEADER_LEN); /* Push on the 802.3 header */ vos_pkt_push_head(pPacket, &w8023Header, sizeof(w8023Header)); *ppPacket = pPacket; return vosStatus; }