/*
 * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
 *
 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
 *
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

/*
 * This file was originally distributed by Qualcomm Atheros, Inc.
 * under proprietary terms before Copyright ownership was assigned
 * to the Linux Foundation.
 */

/*===========================================================================

                      b a p A p i D a t a . C
                                               
  OVERVIEW:
  
  This software unit holds the implementation of the WLAN BAP modules
  "platform independent" Data path functions.
  
  The functions externalized by this module are to be called ONLY by other 
  WLAN modules (HDD) that properly register with the BAP Layer initially.

  DEPENDENCIES: 

  Are listed for each API below. 
  
  
===========================================================================*/

/*===========================================================================

                      EDIT HISTORY FOR FILE


  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.


   $Header: /cygdrive/e/Builds/M7201JSDCAAPAD52240B/WM/platform/msm7200/Src/Drivers/SD/ClientDrivers/WLAN/QCT/CORE/BAP/src/bapApiData.c,v 1.4 2008/11/10 22:34:22 jzmuda Exp jzmuda $$DateTime$$Author: jzmuda $


  when        who     what, where, why
----------    ---    --------------------------------------------------------
2008-09-15    jez     Created module

===========================================================================*/

/*----------------------------------------------------------------------------
 * Include Files
 * -------------------------------------------------------------------------*/
//#include "wlan_qct_tl.h"
#include "vos_trace.h"
//I need the TL types and API
#include "wlan_qct_tl.h"

#include "wlan_qct_hal.h"

/* BT-AMP PAL API header file */ 
#include "bapApi.h" 
#include "bapInternal.h" 
#include "bapApiTimer.h"

//#define BAP_DEBUG
/*----------------------------------------------------------------------------
 * Preprocessor Definitions and Constants
 * -------------------------------------------------------------------------*/
/*Endian-ness definitions*/

#undef BAP_LITTLE_BIT_ENDIAN
#define BAP_LITTLE_BIT_ENDIAN

/*LLC header definitions*/

/* Length of the LLC header*/
#define WLANBAP_LLC_HEADER_LEN   8 
#if 0
/*Offset of the OUI field inside the LLC/SNAP header*/
#define WLANBAP_LLC_OUI_OFFSET                 3

/*Size of the OUI type field inside the LLC/SNAP header*/
#define WLANBAP_LLC_OUI_SIZE                   3

/*Offset of the protocol type field inside the LLC/SNAP header*/
#define WLANBAP_LLC_PROTO_TYPE_OFFSET  (WLANBAP_LLC_OUI_OFFSET +  WLANBAP_LLC_OUI_SIZE)

/*Size of the protocol type field inside the LLC/SNAP header*/
#define WLANBAP_LLC_PROTO_TYPE_SIZE            2
#endif

/*BT-AMP protocol type values*/
/*BT-AMP packet of type data*/
#define WLANBAP_BT_AMP_TYPE_DATA       0x0001

/*BT-AMP packet of type activity report*/
#define WLANBAP_BT_AMP_TYPE_AR         0x0002

/*BT-AMP packet of type security frame*/
#define WLANBAP_BT_AMP_TYPE_SEC        0x0003

/*802.3 header definitions*/
#define  WLANBAP_802_3_HEADER_LEN             14

/* Offset of DA field in a 802.3 header*/
#define  WLANBAP_802_3_HEADER_DA_OFFSET        0

//*BT-AMP packet LLC OUI value*/
const v_U8_t WLANBAP_BT_AMP_OUI[] =  {0x00, 0x19, 0x58 };

/*LLC header value*/
static v_U8_t WLANBAP_LLC_HEADER[] =  {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00 };

/* HCI header definitions*/

// Define the length of the ACL data packet HCI header
#define WLANBAP_HCI_ACL_HEADER_LEN    4

// Debug related defines
//#define DBGLOG printf
#define DUMPLOG_ON
#ifdef DUMPLOG_ON
#define DUMPLOG(n, name1, name2, aStr, size) do {                       \
        int i;                                                          \
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"%d. %s: %s = \n", n, name1, name2); \
        for (i = 0; i < size; i++)                                      \
            VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,"\n");      \
    } while (0)
#else
#define DUMPLOG(n, name1, name2, aStr, size)
#endif

#if 0
// Debug related defines
#define DBGLOG printf
#define DUMPLOG
#if defined DUMPLOG
#define DUMPLOG(n, name1, name2, aStr, size) do {                       \
        int i;                                                          \
        DBGLOG("%d. %s: %s = \n", n, name1, name2);                     \
        for (i = 0; i < size; i++)                                      \
            DBGLOG("%2.2x%s", ((unsigned char *)aStr)[i], i % 16 == 15 ? "\n" : " "); \
        DBGLOG("\n");                                                   \
    } while (0)
#else
#define DUMPLOG(n, name1, name2, aStr, size)
#endif
#endif

/*----------------------------------------------------------------------------
 * Type Declarations
 * -------------------------------------------------------------------------*/
// Don't we have this type defined somewhere?
#if 0
/* 802.3 header */
typedef struct 
{
 /* Destination address field */
 v_U8_t   vDA[VOS_MAC_ADDR_SIZE];

 /* Source address field */
 v_U8_t   vSA[VOS_MAC_ADDR_SIZE];

 /* Length field */
 v_U16_t  usLenType;  /* Num bytes in info field (i.e., exclude 802.3 hdr) */
                      /* Max length 1500 (0x5dc) (What about 0x5ee? That
                       * includes 802.3 Header and FCS.) */
}WLANBAP_8023HeaderType;
#endif

/**
 * \brief HCI ACL Data packet format
 *
 *     0      7 8      15 16    23 24    31
 *    +--------+----+----+--------+--------+
 *    | phy_   |log_| PB/|   Data Total    |
 *    | link_  |lnk_| BC |      Length     |
 *    | handle |hndl|Flag|                 |
 *    +--------+----+----+--------+--------+
 *    |                                    |
 *    |                Data                |
 *    ~                                    ~
 *    +--------+---------+--------+--------+
 *
 *  NB: 
 *  This is in little-endian
 *  1) phy_link_handle is the first 8 bits
 *  2) log_link_handle is the next 4 bits 
 *  3) PB flag is the next 2 bits
 *  4) BC flags is the next 2 bits
 *  5) Total length of the data field is the next 16 bits
 *
 */

typedef struct 
{

#ifndef BAP_LITTLE_BIT_ENDIAN

   v_U8_t phyLinkHandle; /* do I have to reverse the byte? I think so... */

   v_U8_t BCFlag :2;
   v_U8_t PBFlag :2;
   v_U8_t logLinkHandle :4;

   v_U16_t dataLength;  /* do I have to reverse each byte? and then reverse the two bytes?  I think so... */

#else

   v_U8_t phyLinkHandle;

   v_U8_t logLinkHandle :4;
   v_U8_t PBFlag :2;
   v_U8_t BCFlag :2;

   v_U16_t dataLength;  /* Max length WLANBAP_MAX_80211_PAL_PDU_SIZE (1492) */

#endif

} WLANBAP_HCIACLHeaderType;



/*----------------------------------------------------------------------------
 * Global Data Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Static Variable Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Static Function Declarations and Definitions
 * -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Externalized Function Definitions
* -------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
 * Function Declarations and Documentation
 * -------------------------------------------------------------------------*/

#define WLANBAP_DEBUG_FRAME_BYTE_PER_LINE    16
#define WLANBAP_DEBUG_FRAME_BYTE_PER_BYTE    4

/*===========================================================================

  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*/
    uintptr_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", __func__);
        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",
                __func__, 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", __func__);
        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,
                __func__);

        // 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",
                __func__);

        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->ac = *pucAC;
    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 = (uintptr_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_GetAcFromTxDataPkt

  DESCRIPTION 

    HDD will call this API when it has a HCI Data Packet (SKB) and it wants 
    to find AC type of the data frame from the HCI header on the data pkt
    - to be send using TL.


  PARAMETERS 

    btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl.
 
    pHciData: Pointer to the HCI data frame
 
    pucAC:       Pointer to return the access category 
   
  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_GetAcFromTxDataPkt
( 
  ptBtampHandle     btampHandle,  /* Used by BAP to identify the actual session
                                    and therefore addresses */
  void              *pHciData,     /* Pointer to the HCI data frame */
  WLANTL_ACEnumType *pucAC        /* Return the AC here */
)
{
    ptBtampContext           pBtampCtx; 
    tpBtampLogLinkCtx        pLogLinkContext;
    WLANBAP_HCIACLHeaderType hciACLHeader;
    /*------------------------------------------------------------------------
        Sanity check params
      ------------------------------------------------------------------------*/
    if (( NULL == btampHandle) || (NULL == pHciData) || (NULL == pucAC))
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "Invalid params in %s", __func__);
        return VOS_STATUS_E_FAULT;
    }
    pBtampCtx = (ptBtampContext) btampHandle;

    vos_mem_copy( &hciACLHeader, pHciData, WLANBAP_HCI_ACL_HEADER_LEN);
    // 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", 
                hciACLHeader.logLinkHandle,
                __func__);

        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 ]);

    // 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",
                __func__);

        return VOS_STATUS_E_INVAL;
    }

    // Return the AC

    // Now copy the AC values from the Logical Link context
    *pucAC = pLogLinkContext->btampAC;

    return VOS_STATUS_SUCCESS;
}

/*===========================================================================

  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", __func__);
        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", __func__);
        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", __func__);
        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", __func__);
        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    WLANBAP_STAFetchPktCB 

  DESCRIPTION   
    The fetch packet callback registered with TL. 
    
    It is called by the TL when the scheduling algorithms allows for 
    transmission of another packet to the module. 
    It will be called in the context of the BAL fetch transmit packet 
    function, initiated by the bus lower layer. 


  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 

    IN/OUT
    pucSTAId:       the Id of the station for which TL is requesting a 
                    packet, in case HDD does not maintain per station 
                    queues it can give the next packet in its queue 
                    and put in the right value for the 
    pucAC:          access category requested by TL, if HDD does not have 
                    packets on this AC it can choose to service another AC 
                    queue in the order of priority

    OUT
    vosDataBuff:   pointer to the VOSS data buffer that was transmitted 
    tlMetaInfo:    meta info related to the data frame


  
  RETURN VALUE 
    The result code associated with performing the operation

----------------------------------------------------------------------------*/
VOS_STATUS 
WLANBAP_STAFetchPktCB 
( 
  v_PVOID_t             pvosGCtx,
  v_U8_t*               pucSTAId,
  v_U8_t                ucAC,
  vos_pkt_t**           vosDataBuff,
  WLANTL_MetaInfoType*  tlMetaInfo
)
{
    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 */

    /* Lookup the BSL and BAP contexts using the StaId */ 

    vosStatus = WLANBAP_GetCtxFromStaId ( 
            *pucSTAId,  /* 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_STAFetchPktCB");
      return VOS_STATUS_E_FAULT;
    }

    /* Invoke the callback that BSL registered with me */ 
    vosStatus = (*bapContext->pfnBtampFetchPktCB)( 
            pHddHdl, 
            (WLANTL_ACEnumType)   ucAC, /* typecast it for now */ 
            vosDataBuff, 
            tlMetaInfo);    
    if ( VOS_STATUS_SUCCESS != vosStatus ) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO,
                "Callback registered by BSL failed to fetch pkt in WLANNBAP_STAFetchPktCB");
        return VOS_STATUS_E_FAULT;
    }

    return vosStatus;
} /* WLANBAP_STAFetchPktCB */ 

/*----------------------------------------------------------------------------

  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",__func__,
                 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",
                     __func__,protoType);
          btampHandle = (ptBtampHandle)bapContext; 
          vosStatus = WLANBAP_RxProcLsPkt(
                        btampHandle,
                        bapContext->phy_link_handle,
                        protoType,
                        vosDataBuff
                        );
    }  

    return vosStatus;
} /* WLANBAP_STARxCB */


/*----------------------------------------------------------------------------

  FUNCTION    WLANBAP_TxCompCB

  DESCRIPTION   
    The tx complete callback registered with TL. 
    
    TL will call this to notify the client when a transmission for a 
    packet  has ended. 

  PARAMETERS 

    IN
    pvosGCtx:       pointer to the global vos context; a handle to 
                    TL/HAL/PE/BAP/HDD control block can be extracted from 
                    its context 
    vosDataBuff:   pointer to the VOSS data buffer that was transmitted 
    wTxSTAtus:      status of the transmission 

  
  RETURN VALUE 
    The result code associated with performing the operation

----------------------------------------------------------------------------*/
VOS_STATUS 
WLANBAP_TxCompCB
( 
  v_PVOID_t      pvosGCtx,
  vos_pkt_t*     vosDataBuff,
  VOS_STATUS     wTxSTAtus 
)
{
    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 */
    v_PVOID_t      pvlogLinkHandle = NULL;
    uintptr_t       value;

    WLANBAP_HCIACLHeaderType hciACLHeader;

    /* retrieve the BSL and BAP contexts */ 

    /* I don't really know how to do this - in the general case. */
    /* So, for now, I will just use something that works. */
    /* (In general, I will have to keep a list of the outstanding transmit */
    /* buffers, in order to determine which assoc they are with.) */
    //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 */
    /* Temporarily we do the following*/ 
    //bapHdl = &btampCtx;
    bapHdl = (v_PVOID_t)gpBtampCtx;
    /* Typecast the handle into a context. Works as we have only one link*/ 
    bapContext = ((ptBtampContext) bapHdl);  

    /*------------------------------------------------------------------------
      Sanity check params
    ------------------------------------------------------------------------*/
    if ( NULL == vosDataBuff) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Invalid vosDataBuff value in %s", __func__);
        return VOS_STATUS_E_FAULT;
    }

    if ( NULL == bapContext) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Invalid bapContext value in %s", __func__);
        vos_pkt_return_packet( vosDataBuff ); 
        return VOS_STATUS_E_FAULT;
    }

    pHddHdl = bapContext->pHddHdl;
    vosStatus = VOS_STATUS_SUCCESS;
    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_TxCompCB");
      vos_pkt_return_packet( vosDataBuff ); 
      return VOS_STATUS_E_FAULT;
    }

    /*Get the logical link handle from the vos user data*/
    vos_pkt_get_user_data_ptr( vosDataBuff, VOS_PKT_USER_DATA_ID_BAP,
                               &pvlogLinkHandle);

    value = (uintptr_t)pvlogLinkHandle;
    hciACLHeader.logLinkHandle = value;

#ifdef BAP_DEBUG
    /* Trace the bapContext referenced. */
    VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH,
              "WLAN BAP Context Monitor: bapContext value = %pK in %s:%d. vosDataBuff=%pK", bapContext, __func__, __LINE__, vosDataBuff );
#endif //BAP_DEBUG

    // Sanity check the log_link_handle value 
// JEZ100722: Temporary changes.
    if (BTAMP_VALID_LOG_LINK( hciACLHeader.logLinkHandle))
    {
       vos_atomic_increment_U32(
           &bapContext->btampLogLinkCtx[hciACLHeader.logLinkHandle].uTxPktCompleted);
//           &bapContext->btampLogLinkCtx[0].uTxPktCompleted);
//       vos_atomic_increment_U32(
//           &bapContext->btampLogLinkCtx[1].uTxPktCompleted);
    } else 
    {
       VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                   "In %s:%d: Invalid logical link handle: %d", __func__, __LINE__, hciACLHeader.logLinkHandle);
    }

    /* Invoke the callback that BSL registered with me */ 
    vosStatus = (*bapContext->pfnBtampTxCompCB)( 
            pHddHdl,
            vosDataBuff,
            wTxSTAtus);

    return vosStatus;
} /* WLANBAP_TxCompCB */

/*==========================================================================

  FUNCTION    WLANBAP_RegisterDataPlane

  DESCRIPTION 
    The HDD calls this routine to register the "data plane" routines
    for Tx, Rx, and Tx complete with BT-AMP.  For now, with only one
    physical association supported at a time, this COULD be called 
    by HDD at the same time as WLANBAP_GetNewHndl.  But, in general
    it needs to be called upon each new physical link establishment.
    
    This registration is really two part.  The routines themselves are
    registered here.  But, the mapping between the BSL context and the
    actual physical link takes place during WLANBAP_PhysicalLinkCreate. 
    
  DEPENDENCIES 
    
  PARAMETERS 

    IN
    btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl.
   
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_E_FAULT:  pointer to BAP cb is NULL ; access would cause a page 
                         fault  
    VOS_STATUS_SUCCESS:  Everything is good :) 

  SIDE EFFECTS 
  
============================================================================*/
VOS_STATUS 
WLANBAP_RegisterDataPlane
( 
  ptBtampHandle btampHandle,  /* BTAMP context */ 
  WLANBAP_STAFetchPktCBType pfnBtampFetchPktCB, 
  WLANBAP_STARxCBType pfnBtamp_STARxCB,
  WLANBAP_TxCompCBType pfnBtampTxCompCB,
  // phy_link_handle, of course, doesn't come until much later.  At Physical Link create.
  v_PVOID_t      pHddHdl   /* BSL specific context */
)
{
    ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; 

  
    /*------------------------------------------------------------------------
      Sanity check params
     ------------------------------------------------------------------------*/
    if ( NULL == pBtampCtx) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "Invalid BAP handle value in WLANBAP_RegisterDataPlane");
        return VOS_STATUS_E_FAULT;
    }

    // Include the HDD BAP Shim Layer callbacks for Fetch, TxComp, and RxPkt
    pBtampCtx->pfnBtampFetchPktCB = pfnBtampFetchPktCB; 
    pBtampCtx->pfnBtamp_STARxCB = pfnBtamp_STARxCB;
    pBtampCtx->pfnBtampTxCompCB = pfnBtampTxCompCB;

    // (Right now, there is only one)
    pBtampCtx->pHddHdl = pHddHdl;
    /* Set the default data transfer mode */ 
    pBtampCtx->ucDataTrafficMode = WLANBAP_FLOW_CONTROL_MODE_BLOCK_BASED;

    return VOS_STATUS_SUCCESS;
} /* WLANBAP_RegisterDataPlane */


/*===========================================================================

  FUNCTION    WLANBAP_STAPktPending

  DESCRIPTION 

    HDD will call this API when a packet is pending transmission in its 
    queues. HDD uses this instead of WLANTL_STAPktPending because he is
    not aware of the mapping from session to STA ID.

  DEPENDENCIES 

    HDD must have called WLANBAP_GetNewHndl before calling this API.

  PARAMETERS 

    btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl.
                 BSL can obtain this from the physical handle value in the
                 downgoing HCI Data Packet. He, after all, was there
                 when the PhysicalLink was created. He knew the btampHandle 
                 value returned by WLANBAP_GetNewHndl. He knows as well, his
                 own pHddHdl (see next).
    phy_link_handle: Used by BAP to indentify the WLAN assoc. (StaId)
    ucAc:        The access category for the pending frame
   
  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_STAPktPending 
( 
  ptBtampHandle  btampHandle,  /* Used by BAP to identify the app context and VOSS ctx (!?) */ 
  v_U8_t         phy_link_handle,  /* Used by BAP to indentify the WLAN assoc. (StaId) */
  WLANTL_ACEnumType ucAc   /* This is the first instance of a TL type in bapApi.h */
)
{
    VOS_STATUS     vosStatus; 
    ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; 
    v_PVOID_t      pvosGCtx;
    v_U8_t         ucSTAId;  /* The StaId (used by TL, PE, and HAL) */
    v_PVOID_t      pHddHdl; /* Handle to return BSL context in */

  
#ifdef BAP_DEBUG
    /* Trace the tBtampCtx being passed in. */
    VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_INFO_HIGH,
              "WLAN BAP Context Monitor: pBtampCtx value = %pK in %s:%d", pBtampCtx, __func__, __LINE__ );
#endif //BAP_DEBUG

    /*------------------------------------------------------------------------
      Sanity check params
     ------------------------------------------------------------------------*/
    if ( NULL == pBtampCtx) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                "Invalid BAP handle value in WLANBAP_STAPktPending"); 
        return VOS_STATUS_E_FAULT;
    }

    // Retrieve the VOSS context
    pvosGCtx = pBtampCtx->pvosGCtx;
 
    /* 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 WLANBAP_STAPktPending");
      return VOS_STATUS_E_FAULT;
    }


    // Let TL know we have a packet to send...
    vosStatus = WLANTL_STAPktPending( 
            pvosGCtx,
            ucSTAId,
            ucAc);
    if ( VOS_STATUS_SUCCESS != vosStatus ) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                        "Tx: Packet rejected by TL in WLANBAP_STAPktPending");
        return vosStatus;
    }            
    pBtampCtx->dataPktPending = VOS_TRUE;//Indication for LinkSupervision module that data is pending 
    return VOS_STATUS_SUCCESS;
} /* WLANBAP_STAPktPending */ 

/*----------------------------------------------------------------------------

  FUNCTION    WLAN_BAPRegisterBAPCallbacks() 

  DESCRIPTION 
    Register the BAP "Event" callbacks.
    Return the per instance handle.

  DEPENDENCIES 
    NA. 

  PARAMETERS 

    IN
    btampHandle: The BT-AMP PAL handle returned in WLANBAP_GetNewHndl.
    pBapHCIEventCB:  pointer to the Event callback
    pAppHdl:  The context passed in by caller. (I.E., BSL app specific context.)

   
  RETURN VALUE
    The result code associated with performing the operation  

    VOS_STATUS_E_FAULT:  pointer to pBapHCIEventCB is NULL 
    VOS_STATUS_SUCCESS:  Success
  
  SIDE EFFECTS 
  
----------------------------------------------------------------------------*/
VOS_STATUS  
WLAN_BAPRegisterBAPCallbacks 
( 
  ptBtampHandle           btampHandle, /* BSL uses my handle to talk to me */
                            /* Returned from WLANBAP_GetNewHndl() */
                            /* It's like each of us is using the other */
                            /* guys reference when invoking him. */
  tpWLAN_BAPEventCB       pBapHCIEventCB, /*Implements the callback for ALL asynchronous events. */ 
  v_PVOID_t               pAppHdl  // Per-app BSL context
)
{
    ptBtampContext pBtampCtx = (ptBtampContext) btampHandle; 

  
    /*------------------------------------------------------------------------
      Sanity check params
     ------------------------------------------------------------------------*/
    if ( NULL == pBtampCtx) 
    {
        VOS_TRACE( VOS_MODULE_ID_BAP, VOS_TRACE_LEVEL_ERROR,
                     "Invalid BAP handle value in WLAN_BAPRegisterBAPCallbacks");
        return VOS_STATUS_E_FAULT;
    }

    // Save the Event callback 
    pBtampCtx->pBapHCIEventCB = pBapHCIEventCB; 

    // (Right now, there is only one)
    pBtampCtx->pAppHdl = pAppHdl;

    return VOS_STATUS_SUCCESS;
} /* WLAN_BAPRegisterBAPCallbacks */


