Exemple #1
0
/*********************************************************************
 * @fn      gapCentralRole_ProcessOSALMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapCentralRole_ProcessOSALMsg( osal_event_hdr_t *pMsg )
{
  switch ( pMsg->event )
  {
    case HCI_GAP_EVENT_EVENT:
      if ( pMsg->status == HCI_COMMAND_COMPLETE_EVENT_CODE )
      {
        hciEvt_CmdComplete_t *pPkt = (hciEvt_CmdComplete_t *) pMsg;

        if ( pPkt->cmdOpcode == HCI_READ_RSSI )
        {
          uint16 connHandle = BUILD_UINT16( pPkt->pReturnParam[1], pPkt->pReturnParam[2] );
          int8 rssi = (int8) pPkt->pReturnParam[3];

          // Report RSSI to app
          if ( pGapCentralRoleCB && pGapCentralRoleCB->rssiCB )
          {
            pGapCentralRoleCB->rssiCB( connHandle, rssi );
          }
        }
      }
      break;

    case GAP_MSG_EVENT:
      gapCentralRole_ProcessGAPMsg( (gapEventHdr_t *) pMsg );
      break;

    case GAPCENTRALROLE_RSSI_MSG_EVT:
      {
        gapCentralRoleRssi_t *pRssi = ((gapCentralRoleRssiEvent_t *) pMsg)->pRssi;

        // If link is up and RSSI reads active
        if (pRssi->connHandle != GAP_CONNHANDLE_ALL &&
            linkDB_Up(pRssi->connHandle))
        {
          // Restart timer
          osal_CbTimerStart( gapCentralRole_timerCB, (uint8 *) pRssi,
                             pRssi->period, &pRssi->timerId );

          // Read RSSI
          VOID HCI_ReadRssiCmd( pRssi->connHandle );
        }
      }
      break;

    default:
      break;
  }
}
/*********************************************************************
 * @brief   Task Event Processor function.
 *
 * Internal function defined in peripheral.h.
 */
uint16 GAPRole_ProcessEvent( uint8 task_id, uint16 events )
{
  VOID task_id; // OSAL required parameter that isn't used in this function
  
  if ( events & SYS_EVENT_MSG )
  {
    uint8 *pMsg;

    if ( (pMsg = osal_msg_receive( gapRole_TaskID )) != NULL )
    {
      gapRole_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );

      // Release the OSAL message
      VOID osal_msg_deallocate( pMsg );
    }

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
  }

  if ( events & GAP_EVENT_SIGN_COUNTER_CHANGED )
  {
    // Sign counter changed, save it to NV
    VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter );

    return ( events ^ GAP_EVENT_SIGN_COUNTER_CHANGED );
  }
  
  if ( events & START_ADVERTISING_EVT )
  {
    if ( gapRole_AdvEnabled )
    {
      gapAdvertisingParams_t params;

      // Setup advertisement parameters
      if ( gapRole_state == GAPROLE_CONNECTED )
      {
        // While in a connection, we can only advertise non-connectable undirected.
        params.eventType = GAP_ADTYPE_ADV_NONCONN_IND;
      }
      else
      {
        params.eventType = gapRole_AdvEventType;
        params.initiatorAddrType = gapRole_AdvDirectType;
        VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );
      }
      params.channelMap = gapRole_AdvChanMap;
      params.filterPolicy = gapRole_AdvFilterPolicy;

      if ( GAP_MakeDiscoverable( gapRole_TaskID, &params ) != SUCCESS )
      {
        gapRole_state = GAPROLE_ERROR;
        if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
        {
          pGapRoles_AppCGs->pfnStateChange( gapRole_state );
        }
      }
    }
    return ( events ^ START_ADVERTISING_EVT );
  }

  if ( events & RSSI_READ_EVT )
  {
    // Only get RSSI when in a connection
    if ( (gapRole_state == GAPROLE_CONNECTED)
        || (gapRole_state == GAPROLE_CONNECTED_ADV) )
    {
      // Ask for RSSI
      VOID HCI_ReadRssiCmd( gapRole_ConnectionHandle );

      // Setup next event
      if ( gapRole_RSSIReadRate )
      {
        VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
      }
    }
    return ( events ^ RSSI_READ_EVT );
  }

  if ( events & UPDATE_PARAMS_TIMEOUT_EVT )
  {
    // Clear an existing timeout
    if ( osal_get_timeoutEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT ) )
    {
      VOID osal_stop_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT );
    }

    // The Update Parameters Timeout occurred - Terminate connection
    VOID GAP_TerminateLinkReq( gapRole_TaskID, gapRole_ConnectionHandle, 
                               HCI_DISCONNECT_REMOTE_USER_TERM );

    return ( events ^ UPDATE_PARAMS_TIMEOUT_EVT );
  }

  // Discard unknown events
  return 0;
}
Exemple #3
0
/*********************************************************************
 * @brief   Task Event Processor function.
 *
 * Internal function defined in peripheral.h.
 */
uint16 GAPRole_ProcessEvent( uint8 task_id, uint16 events )
{
  VOID task_id; // OSAL required parameter that isn't used in this function

  if ( events & SYS_EVENT_MSG )
  {
    uint8 *pMsg;

    if ( (pMsg = osal_msg_receive( gapRole_TaskID )) != NULL )
    {
      gapRole_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );

      // Release the OSAL message
      VOID osal_msg_deallocate( pMsg );
    }

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
  }

  if ( events & GAP_EVENT_SIGN_COUNTER_CHANGED )
  {
    // Sign counter changed, save it to NV
    VOID osal_snv_write( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter );

    return ( events ^ GAP_EVENT_SIGN_COUNTER_CHANGED );
  }

  if ( events & START_ADVERTISING_EVT )
  {
    if ( gapRole_AdvEnabled )
    {
      gapAdvertisingParams_t params;

      // Setup advertisement parameters
      params.eventType = gapRole_AdvEventType;
      params.initiatorAddrType = gapRole_AdvDirectType;
      VOID osal_memcpy( params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN );
      params.channelMap = gapRole_AdvChanMap;
      params.filterPolicy = gapRole_AdvFilterPolicy;

      if ( GAP_MakeDiscoverable( gapRole_TaskID, &params ) != SUCCESS )
      {
        gapRole_state = GAPROLE_ERROR;
        
        // Notify the application with the new state change
        if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
        {
          pGapRoles_AppCGs->pfnStateChange( gapRole_state );
        }
      }
    }
    return ( events ^ START_ADVERTISING_EVT );
  }

  if ( events & RSSI_READ_EVT )
  {
    // Only get RSSI when in a connection
    if ( gapRole_state == GAPROLE_CONNECTED )
    {
      // Ask for RSSI
      VOID HCI_ReadRssiCmd( gapRole_ConnectionHandle );

      // Setup next event
      if ( gapRole_RSSIReadRate )
      {
        VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
      }
    }
    return ( events ^ RSSI_READ_EVT );
  }

  if ( events & START_CONN_UPDATE_EVT )
  {
    // Start connection update procedure
    gapRole_startConnUpdate( GAPROLE_NO_ACTION );

    return ( events ^ START_CONN_UPDATE_EVT );
  }
  
  if ( events & CONN_PARAM_TIMEOUT_EVT )
  {
    // Unsuccessful in updating connection parameters
    gapRole_HandleParamUpdateNoSuccess();

    return ( events ^ CONN_PARAM_TIMEOUT_EVT );
  }
  
  // Discard unknown events
  return 0;
}
/**
 *  SNP_executeHCIcmd
 */
uint8_t SNP_executeHCIcmd(snpHciCmdReq_t *pReq, uint16_t dataLen)
{  
  bStatus_t stat;   
  uint16_t opcode =  pReq->opcode;
  uint8_t *pData = (uint8_t*)&pReq->pData;
  uint8_t status = blePending; 
  
  if(snp_HCIstore.validity)
  {
    return SNP_CMD_ALREADY_IN_PROGRESS;
  }     
      
  switch (opcode)
  {     
    case SNP_HCI_OPCODE_EXT_RESET_SYSTEM:
    {
      stat =  HCI_EXT_ResetSystemCmd(LL_EXT_RESET_SYSTEM_HARD);
      if(stat == SUCCESS)
      {
        status = SNP_SUCCESS;
      }
      else
      {
        status = bleIncorrectMode;
      }
    }
    break;
    
    case SNP_HCI_OPCODE_READ_BDADDR:
    {
      stat = HCI_ReadBDADDRCmd();
      if(stat == SUCCESS)
      {
        // Set state to wait for the HCI event with the address
        snp_HCIstore.validity = TRUE;
        snp_HCIstore.opcode = opcode;
        status = blePending;
      }
      else
      {
        status = stat;
      }
    }
    break;
    
    case SNP_HCI_OPCODE_EXT_SET_BDADDR:
      {
        if(dataLen != B_ADDR_LEN) 
        {
          status = SNP_INVALID_PARAMS;
        }
        else
        {
          stat = HCI_EXT_SetBDADDRCmd(pData);
          if(stat == SUCCESS)
          {
            // Set state to wait for the HCI event with the address
            snp_HCIstore.validity = TRUE;
            snp_HCIstore.opcode = opcode;
            status = blePending;
          }
          else
          {
            status = stat;
          }
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_SET_TX_POWER:
      {
        if(dataLen != sizeof(uint8_t)) 
        {
          status = SNP_INVALID_PARAMS;
        }
        else
        {
          stat = HCI_EXT_SetTxPowerCmd(pData[0]);
          if(stat == SUCCESS)
          {
            // Set state to wait for the HCI event with the address
            snp_HCIstore.validity = TRUE;
            snp_HCIstore.opcode = opcode;
            status = blePending;
          }
          else
          {
            status = stat;
          }
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_SET_SCA:
      if(dataLen != sizeof(uint16_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_EXT_SetSCACmd((pData[0] &0xFF) +  (pData[1] << 8));
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_MODEM_TEST_TX:
      if(dataLen != 2*sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_EXT_ModemTestTxCmd(pData[0], pData[1]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_MODEM_HOP_TEST_TX:
      stat = HCI_EXT_ModemHopTestTxCmd();
      if(stat == SUCCESS)
      {
        // Set state to wait for the HCI event with the address
        snp_HCIstore.validity = TRUE;
        snp_HCIstore.opcode = opcode;
        status = blePending;
      }
      else
      {
        status = stat;
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_MODEM_TEST_RX:
      if(dataLen != sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_EXT_ModemTestRxCmd(pData[0]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_END_MODEM_TEST:
      stat = HCI_EXT_EndModemTestCmd();
      if(stat == SUCCESS)
      {
        // Set state to wait for the HCI event with the address
        snp_HCIstore.validity = TRUE;
        snp_HCIstore.opcode = opcode;
        status = blePending;
      }
      else
      {
        status = stat;
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_ENABLE_PTM:
      stat = HCI_EXT_EnablePTMCmd();
      if(stat == SUCCESS)
      {
        status = SNP_SUCCESS;
      }
      else
      {
        status = stat;
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_SET_MAX_DTM_TX_POWER:
      if(dataLen != sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_EXT_SetMaxDtmTxPowerCmd(pData[0]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_READ_RSSI:
      if(dataLen != sizeof(uint16_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_ReadRssiCmd((pData[0] &0xFF) +  (pData[1] << 8));
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_LE_RECEIVER_TEST:
      if(dataLen != sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_LE_ReceiverTestCmd(pData[0]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_LE_TRANSMITTER_TEST:
      if(dataLen != 3 * sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_LE_TransmitterTestCmd(pData[0], pData[1], pData[2]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_LE_TEST_END:
      stat = HCI_LE_TestEndCmd();
      if(stat == SUCCESS)
      {
        // Set state to wait for the HCI event with the address
        snp_HCIstore.validity = TRUE;
        snp_HCIstore.opcode = opcode;
        status = blePending;
      }
      else
      {
        status = stat;
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_PER:
      if(dataLen != (sizeof(uint8_t) + sizeof(uint16_t))) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        stat = HCI_EXT_PacketErrorRateCmd(pData[0] +  (pData[1] << 8),
                                          pData[2]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_DECRYPT:
      if(dataLen != (KEYLEN + KEYLEN)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        // reverse byte order of key (MSB..LSB required)
        SNP_ReverseBytes(&pData[0], KEYLEN);

        // reverse byte order of encText (MSB..LSB required)
        SNP_ReverseBytes(&pData[KEYLEN], KEYLEN);
        
        stat = HCI_EXT_DecryptCmd(&pData[0], &pData[KEYLEN]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_LE_ENCRYPT:
      if(dataLen != (KEYLEN + KEYLEN)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
        // reverse byte order of key (MSB..LSB required)
        SNP_ReverseBytes(&pData[0], KEYLEN);

        // reverse byte order of encText (MSB..LSB required)
        SNP_ReverseBytes(&pData[KEYLEN], KEYLEN);
        
        stat = HCI_LE_EncryptCmd(&pData[0], &pData[KEYLEN]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_OVERRIDE_SL:
      if(dataLen != sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {
      
        stat = HCI_EXT_SetSlaveLatencyOverrideCmd(pData[0]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_SET_FAST_TX_RESP_TIME:
      if(dataLen != sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {        
        stat = HCI_EXT_SetFastTxResponseTimeCmd(pData[0]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_ONE_PKT_PER_EVT:
      if(dataLen != sizeof(uint8_t)) 
      {
        status = SNP_INVALID_PARAMS;
      }
      else
      {        
        stat = HCI_EXT_OnePktPerEvtCmd(pData[0]);
        if(stat == SUCCESS)
        {
          // Set state to wait for the HCI event with the address
          snp_HCIstore.validity = TRUE;
          snp_HCIstore.opcode = opcode;
          status = blePending;
        }
        else
        {
          status = stat;
        }
      }
      break;
      
    case SNP_HCI_OPCODE_EXT_GET_CONNECTION_INFO:
      stat = HCI_EXT_GetConnInfoCmd(NULL, NULL, NULL);
      if(stat == SUCCESS)
      {
        // Set state to wait for the HCI event with the address
        snp_HCIstore.validity = TRUE;
        snp_HCIstore.opcode = opcode;
        status = blePending;
      }
      else
      {
        status = stat;
      }
      break;
  default:
      status = SNP_HCI_CMD_UNKNOWN;
      break;
  }
   return status;
}