text: /*************************************************************************************************/
  /*!
   *  \file   hci_vs.c
   *
   *  \brief  HCI vendor specific functions for generic controllers.
   *
   *          $Date: 2017-02-28 11:31:38 -0600 (Tue, 28 Feb 2017) $
   *          $Revision: 11299 $
   *
   *  Copyright (c) 2011-2017 ARM Ltd., all rights reserved.
   *  ARM Ltd. confidential and proprietary.
   *
   *  IMPORTANT.  Your use of this file is governed by a Software License Agreement
   *  ("Agreement") that must be accepted in order to download or otherwise receive a
   *  copy of this file.  You may not use or copy this file for any purpose other than
   *  as described in the Agreement.  If you do not agree to all of the terms of the
   *  Agreement do not use this file and delete all copies in your possession or control;
   *  if you do not have a copy of the Agreement, you must contact ARM Ltd. prior
   *  to any use, copying or further distribution of this software.
   */
  /*************************************************************************************************/
  
  #include <string.h>
  #include "wsf_types.h"
  #include "wsf_msg.h"
  #include "wsf_trace.h"
  #include "bda.h"
  #include "bstream.h"
  #include "hci_core.h"
  #include "hci_api.h"
  #include "hci_main.h"
  #include "hci_cmd.h"
  #include "hci_apollo_config.h"
  
  #if HCI_VS_TARGET == HCI_VS_GENERIC
  
  /**************************************************************************************************
    Local Functions
  **************************************************************************************************/
  
  static void hciCoreReadResolvingListSize(void);
  static void hciCoreReadMaxDataLen(void);
  
  /*************************************************************************************************/
  /*!
   *  \fn     hciCoreReadResolvingListSize
   *
   *  \brief  Read resolving list command.
   *
   *  \return None.
   */
  /*************************************************************************************************/
  static void hciCoreReadResolvingListSize(void)
  {
    /* if LL Privacy is supported by Controller and included */
    if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_PRIVACY) &&
        (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_PRIVACY))
    {
      /* send next command in sequence */
      HciLeReadResolvingListSize();
    }
    else
    {
      hciCoreCb.resListSize = 0;
  
      /* send next command in sequence */
      hciCoreReadMaxDataLen();
    }
  }
  
  /*************************************************************************************************/
  /*!
   *  \fn     hciCoreReadMaxDataLen
   *
   *  \brief  Read maximum data length command.
   *
   *  \return None.
   */
  /*************************************************************************************************/
  static void hciCoreReadMaxDataLen(void)
  {
    /* if LE Data Packet Length Extensions is supported by Controller and included */
    if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) &&
        (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_DATA_LEN_EXT))
    {
      /* send next command in sequence */
      HciLeReadMaxDataLen();
    }
    else
    {
      /* send next command in sequence */
      HciLeRandCmd();
    }
  }
  
  /*************************************************************************************************/
  /*!
   *  \fn     hciCoreResetStart
   *
   *  \brief  Start the HCI reset sequence.
   *
   *  \return None.
   */
  /*************************************************************************************************/
  void hciCoreResetStart(void)
  {
    /* send an HCI Reset command to start the sequence */
    HciResetCmd();
  }
  
  /*************************************************************************************************/
  /*!
   *  \fn     hciCoreResetSequence
   *
   *  \brief  Implement the HCI reset sequence.
   *
   *  \param  pMsg    HCI event message from previous command in the sequence.
   *
   *  \return None.
   */
  /*************************************************************************************************/
  void hciCoreResetSequence(uint8_t *pMsg)
  {
    uint16_t       opcode;
    wsfMsgHdr_t    hdr;
    static uint8_t randCnt;
  
    /* if event is a command complete event */
    if (*pMsg == HCI_CMD_CMPL_EVT)
    {
      /* parse parameters */
      pMsg += HCI_EVT_HDR_LEN;
      pMsg++;                   /* skip num packets */
      BSTREAM_TO_UINT16(opcode, pMsg);
      pMsg++;                   /* skip status */
  
      /* decode opcode */
      switch (opcode)
      {
        case HCI_OPCODE_RESET:
          /* initialize rand command count */
          randCnt = 0;
  
  #ifdef AM_BSP_GPIO_EM9304_RESET
          // set the BD address after HCI reset for EM device
          extern void HciVsEM_SetBDAddress(void);
  
          HciVsEM_SetBDAddress();
  #endif
  
  
  #ifdef AM_BSP_NATIONZ_IOM
          extern uint8_t g_BLEMacAddress[6];
          HciVendorSpecificCmd(0xFC32, 6, g_BLEMacAddress);
  #endif
  
          /* send next command in sequence */
          HciSetEventMaskCmd((uint8_t *) hciEventMask);
          break;
  
        case HCI_OPCODE_SET_EVENT_MASK:
          /* send next command in sequence */
          HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask);
          break;
  
        case HCI_OPCODE_LE_SET_EVENT_MASK:
          /* send next command in sequence */
          HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2);
          break;
  
        case HCI_OPCODE_SET_EVENT_MASK_PAGE2:
          /* send next command in sequence */
          HciReadBdAddrCmd();
          break;
  
        case HCI_OPCODE_READ_BD_ADDR:
          /* parse and store event parameters */
          BdaCpy(hciCoreCb.bdAddr, pMsg);
  
          /* send next command in sequence */
          HciLeReadBufSizeCmd();
          break;
  
        case HCI_OPCODE_LE_READ_BUF_SIZE:
          /* parse and store event parameters */
          BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg);
          BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg);
  
  
          /* initialize ACL buffer accounting */
          #ifdef AM_PART_APOLLO3
          hciCoreCb.numBufs--;
          #endif
          hciCoreCb.availBufs = hciCoreCb.numBufs;
  
          /* send next command in sequence */
          HciLeReadSupStatesCmd();
          break;
  
        case HCI_OPCODE_LE_READ_SUP_STATES:
          /* parse and store event parameters */
          memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN);
  
          /* send next command in sequence */
          HciLeReadWhiteListSizeCmd();
          break;
  
        case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE:
          /* parse and store event parameters */
          BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg);
  
          /* send next command in sequence */
          HciLeReadLocalSupFeatCmd();
          break;
  
        case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT:
          /* parse and store event parameters */
          BSTREAM_TO_UINT16(hciCoreCb.leSupFeat, pMsg);
  
          /* send next command in sequence */
          hciCoreReadResolvingListSize();
          break;
  
        case HCI_OPCODE_LE_READ_RES_LIST_SIZE:
          /* parse and store event parameters */
          BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg);
  
          /* send next command in sequence */
          hciCoreReadMaxDataLen();
          break;
  
        case HCI_OPCODE_LE_READ_MAX_DATA_LEN:
          {
            uint16_t maxTxOctets;
            uint16_t maxTxTime;
  
            BSTREAM_TO_UINT16(maxTxOctets, pMsg);
            BSTREAM_TO_UINT16(maxTxTime, pMsg);
  
            /* use Controller's maximum supported payload octets and packet duration times
             * for transmission as Host's suggested values for maximum transmission number
             * of payload octets and maximum packet transmission time for new connections.
             */
            HciLeWriteDefDataLen(maxTxOctets, maxTxTime);
          }
          break;
  
        case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN:
          if (hciCoreCb.extResetSeq)
          {
            /* send first extended command */
            (*hciCoreCb.extResetSeq)(pMsg, opcode);
          }
          else
          {
            /* initialize extended parameters */
            hciCoreCb.maxAdvDataLen = 0;
            hciCoreCb.numSupAdvSets = 0;
            hciCoreCb.perAdvListSize = 0;
  
            /* send next command in sequence */
            HciLeRandCmd();
          }
          break;
  
        case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN:
        case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS:
        case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE:
          if (hciCoreCb.extResetSeq)
          {
            /* send next extended command in sequence */
            (*hciCoreCb.extResetSeq)(pMsg, opcode);
          }
          break;
  
        case HCI_OPCODE_LE_RAND:
          /* check if need to send second rand command */
          if (randCnt < (HCI_RESET_RAND_CNT-1))
          {
            randCnt++;
            HciLeRandCmd();
          }
          else
          {
            /* last command in sequence; set resetting state and call callback */
            hciCb.resetting = FALSE;
            hdr.param = 0;
            hdr.event = HCI_RESET_SEQ_CMPL_CBACK_EVT;
            (*hciCb.evtCback)((hciEvt_t *) &hdr);
          }
          break;
  
        default:
          break;
      }
    }
  }
  
  /*************************************************************************************************/
  /*!
   *  \fn     hciCoreVsCmdCmplRcvd
   *
   *  \brief  Perform internal HCI processing of vendor specific command complete events.
   *
   *  \param  opcode  HCI command opcode.
   *  \param  pMsg    Pointer to input HCI event parameter byte stream.
   *  \param  len     Parameter byte stream length.
   *
   *  \return HCI callback event code or zero.
   */
  /*************************************************************************************************/
  uint8_t hciCoreVsCmdCmplRcvd(uint16_t opcode, uint8_t *pMsg, uint8_t len)
  {
    return HCI_VENDOR_SPEC_CMD_CMPL_CBACK_EVT;
  }
  
  /*************************************************************************************************/
  /*!
   *  \fn     hciCoreVsEvtRcvd
   *
   *  \brief  Perform internal HCI processing of vendor specific HCI events.
   *
   *  \param  p       Pointer to input HCI event parameter byte stream.
   *  \param  len     Parameter byte stream length.
   *
   *  \return HCI callback event code or zero.
   */
  /*************************************************************************************************/
  uint8_t hciCoreVsEvtRcvd(uint8_t *p, uint8_t len)
  {
    return HCI_VENDOR_SPEC_EVT;
  }
  
  /*************************************************************************************************/
  /*!
   *  \fn     hciCoreHwErrorRcvd
   *
   *  \brief  Perform internal HCI processing of hardware error event.
   *
   *  \param  p       Pointer to input HCI event parameter byte stream.
   *
   *  \return HCI callback event code or zero.
   */
  /*************************************************************************************************/
  uint8_t hciCoreHwErrorRcvd(uint8_t *p)
  {
    return 0;
  }
  
  /*************************************************************************************************/
  /*!
   *  \fn     HciVsInit
   *
   *  \brief  Vendor-specific controller initialization function.
   *
   *  \param  param    Vendor-specific parameter.
   *
   *  \return None.
   */
  /*************************************************************************************************/
  void HciVsInit(uint8_t param)
  {
  
  }
  
  
  #endif
  