Пример #1
0
/*********************************************************************
 * @fn      simpleTopology_freeAttRsp
 *
 * @brief   Free ATT response message.
 *
 * @param   status - response transmit status
 *
 * @return  none
 */
static void simpleTopology_freeAttRsp(uint8_t status)
{
  // See if there's a pending ATT response message
  if (pAttRsp != NULL)
  {
    // See if the response was sent out successfully
    if (status == SUCCESS)
    {
      LCD_WRITE_STRING_VALUE("Rsp sent, retry:", rspTxRetry, 10, LCD_PAGE6);
    }
    else
    {
      // Free response payload
      GATT_bm_free(&pAttRsp->msg, pAttRsp->method);
      
      LCD_WRITE_STRING_VALUE("Rsp retry failed:", rspTxRetry, 10, LCD_PAGE6);
    }
    
    // Free response message
    ICall_freeMsg(pAttRsp);
    
    // Reset our globals
    pAttRsp = NULL;
    rspTxRetry = 0;
  }
}
Пример #2
0
/*********************************************************************
 * @fn      SimplePropBeacon_freeAttRsp
 *
 * @brief   Free ATT response message.
 *
 * @param   status - response transmit status
 *
 * @return  none
 */
static void SimplePropBeacon_freeAttRsp(uint8_t status)
{
  // See if there's a pending ATT response message
  if (pAttRsp != NULL)
  {
    // See if the response was sent out successfully
    if (status == SUCCESS)
    {
      Display_print1(dispHandle, 5, 0, "Rsp sent retry: %d", rspTxRetry);
    }
    else
    {
      // Free response payload
      GATT_bm_free(&pAttRsp->msg, pAttRsp->method);

      Display_print1(dispHandle, 5, 0, "Rsp retry failed: %d", rspTxRetry);
    }

    // Free response message
    ICall_freeMsg(pAttRsp);

    // Reset our globals
    pAttRsp = NULL;
    rspTxRetry = 0;
  }
}
/**
 * @brief   Task entry point for the GAP Peripheral Role.
 *
 * @param   a0 - first argument
 * @param   a1 - second argument
 *
 * @return  none
 */
static void gapCentralRole_taskFxn(UArg a0, UArg a1)
{
  // Initialize profile
  gapCentralRole_init();
  
  // Profile main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;
      
      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        uint8_t safeToDealloc = TRUE;
              
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          ICall_Event *pEvt = (ICall_Event *)pMsg;
          
          // Check for BLE stack events first
          if (pEvt->signature == 0xffff)
          {
            if (pEvt->event_flag & GAP_EVENT_SIGN_COUNTER_CHANGED)
            {
              // Sign counter changed, save it to NV
              VOID osal_snv_write(BLE_NVID_SIGNCOUNTER, sizeof(uint32_t), 
                                  &gapCentralRoleSignCounter);
            }
          }
          else
          {
            // Process inter-task message
            safeToDealloc = gapCentralRole_processStackMsg((ICall_Hdr *)pMsg);
          }
        }

        if (pMsg && safeToDealloc)
        {
          ICall_freeMsg(pMsg);
        }
      }
    }
  }
}
Пример #4
0
/*********************************************************************
 * @fn      SimpleBLEBroadcaster_processEvent
 *
 * @brief   Application task entry point for the Simple BLE Broadcaster.
 *
 * @param   none
 *
 * @return  none
 */
static void SimpleBLEBroadcaster_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  SimpleBLEBroadcaster_init();
  
  // Application main loop
  for (;;)
  {
    // Get the ticks since startup
    uint32_t tickStart = Clock_getTicks();

    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;
      
      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message
          SimpleBLEBroadcaster_processStackMsg((ICall_Hdr *)pMsg);
        }
                
        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      while (!Queue_empty(appMsgQueue))
      {
        sbbEvt_t *pMsg = (sbbEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          SimpleBLEBroadcaster_processAppMsg(pMsg);
          
          // Free the space from the message.
          ICall_free(pMsg);
        }
      }
    }
  }
}
// ----------------------------------------------------------------------------
//! \brief      Bundles message into Transport Layer frame and NPIMSG_msg_t
//!             container.  This is the MT specific version of this function.
//!
//!             This function frames the passed in buffer with an MT SOF and FCS
//!             bytes.  It then bundles the message in an NPIMSG_msg_t
//!             container.
//!
//!             Note: becauase the SOF and FCS are added, the passed in buffer
//!             is copied to a new buffer and then the passed in buffer is
//!             free'd.
//!
//! \param  pIncomingMsg     Pointer to message buffer.
//!
//! \return     void
// ----------------------------------------------------------------------------
NPIMSG_msg_t *NPIFrame_frameMsg(uint8_t *pIncomingMsg)
{
    uint8_t *payload;

    NPIMSG_msg_t *npiMsg = (NPIMSG_msg_t *)ICall_malloc(sizeof(NPIMSG_msg_t));

    if(npiMsg != NULL)
    {
        // extract the message length from the MT header bytes.
        uint8_t inMsgLen = pIncomingMsg[MTRPC_POS_LEN] + MTRPC_FRAME_HDR_SZ;

        // allocate a new buffer that is the incoming buffer length + 2
        // additional bytes for the SOF and FCS bytes.
        if((npiMsg->pBuf = (uint8_t *)ICall_allocMsg(inMsgLen + 2)) != NULL)
        {
            // mark the start of frame.
            npiMsg->pBuf[0] = MT_SOF;
            payload = npiMsg->pBuf + 1;

            // copy the incoming buffer into the newly created buffer
            memcpy(payload, pIncomingMsg, inMsgLen);

            // calculate and capture the FCS in the final byte.
            npiMsg->pBuf[inMsgLen + 1] = npiframe_calcMTFCS(npiMsg->pBuf + 1,
                                                            inMsgLen);
#if defined(NPI_SREQRSP)
            // document message type (SYNC or ASYNC) in the NPI container.
            if((pIncomingMsg[MTRPC_POS_CMD0] & MTRPC_CMD_TYPE_MASK) == MTRPC_CMD_SRSP)
            {
                npiMsg->msgType = NPIMSG_Type_SYNCRSP;
            }
            else
            {
                npiMsg->msgType = NPIMSG_Type_ASYNC;
            }
#else
            npiMsg->msgType = NPIMSG_Type_ASYNC;
#endif
            // capture the included buffer size in the NPI container.
            npiMsg->pBufSize = inMsgLen + 2;
        }
        else
        {
            // abort and free allocated memory.
            ICall_free(npiMsg);
            npiMsg = NULL;
        }
    }

    /* No matter what happened, give back incoming buffer */
    ICall_freeMsg(pIncomingMsg);

    return(npiMsg);
}
Пример #6
0
/*********************************************************************
 * @fn      SimpleBLEPeripheral_ObserverStateChangeCB
 *
 * @brief   Peripheral observer event callback function.
 *
 * @param   pEvent - pointer to event structure
 *
 * @return  TRUE if safe to deallocate event message, FALSE otherwise.
 */
static void SimpleBLEPeripheral_ObserverStateChangeCB(gapPeripheralObserverRoleEvent_t *pEvent)
{

  sbpEvt_t *pMsg;

  // Create dynamic pointer to message.
  if ((pMsg = ICall_malloc(sizeof(sbpEvt_t))))
  {
    pMsg->hdr.event = SBP_OBSERVER_STATE_CHANGE_EVT;
    pMsg->hdr.state = SUCCESS;

    switch(pEvent->gap.opcode)
    {
    case GAP_DEVICE_INFO_EVENT:
      {
        gapDeviceInfoEvent_t *pDevInfoMsg;

        pDevInfoMsg = ICall_malloc(sizeof(gapDeviceInfoEvent_t));
        memcpy(pDevInfoMsg, pEvent, sizeof(gapDeviceInfoEvent_t));

        pDevInfoMsg->pEvtData = ICall_malloc(pEvent->deviceInfo.dataLen);
        memcpy(pDevInfoMsg->pEvtData, pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen);
        
        pMsg->pData = (uint8 *)pDevInfoMsg;
      }
      break;

    case GAP_DEVICE_DISCOVERY_EVENT:
      {
        gapDevDiscEvent_t *pDevDiscMsg;

        pDevDiscMsg = ICall_malloc(sizeof(gapDevDiscEvent_t));
        memcpy(pDevDiscMsg, pEvent, sizeof(gapDevDiscEvent_t));

        pDevDiscMsg->pDevList = ICall_malloc((pEvent->discCmpl.numDevs)*sizeof(gapDevRec_t));
        memcpy(pDevDiscMsg->pDevList, pEvent->discCmpl.pDevList, (pEvent->discCmpl.numDevs)*sizeof(gapDevRec_t));
        
        pMsg->pData = (uint8 *)pDevDiscMsg;
      }
      break;

    default:
      break;
    }

    // Enqueue the message.
    Util_enqueueMsg(appMsgQueue, sem, (uint8*)pMsg);
  }

  // Free the stack message
  ICall_freeMsg(pEvent);
}
Пример #7
0
/*********************************************************************
 * @fn      simpleTopology_processAppMsg
 *
 * @brief   Process an incoming callback from a profile.
 *
 * @param   pMsg - message to process
 *
 * @return  None.
 */
static void simpleTopology_processAppMsg(sbtEvt_t *pMsg)
{
	switch (pMsg->event)
	{
	case SBT_STATE_CHANGE_EVT:
		simpleTopology_processStackMsg((ICall_Hdr *)pMsg->pData);
		// Free the stack message
		ICall_freeMsg(pMsg->pData);
		break;

	default:
		// Do nothing.
		break;
	}
}
/*********************************************************************
 * @fn      HostTestApp_taskFxn
 *
 * @brief   Application task entry point for the Host Test App.
 *
 * @param   none
 *
 * @return  none
 */
static void HostTestApp_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  HostTestApp_init();

  // Application main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest,
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        bool dealloc = true;

        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process incoming messages
          switch (pMsg->hdr.event)
          {
            case HCI_GAP_EVENT_EVENT:
              HostTestApp_processGapEvent(pMsg);
              break;
              
            default:
              break;
          }
        }

        if (dealloc == true)
        {
          ICall_freeMsg(pMsg);
        }
      }
    }
  }
}
Пример #9
0
/**
 * @brief   Task entry point for the GAP Observer Role.
 *
 * @param   a0 - first argument
 * @param   a1 - second argument
 *
 * @return  none
 */
static void gapObserverRole_taskFxn(UArg a0, UArg a1)
{
  // Initialize profile
  gapObserverRole_init();
  
  // Profile main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;
      
      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        uint8_t safeToDealloc = TRUE;
              
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message
          safeToDealloc = gapObserverRole_processStackMsg((ICall_Hdr *)pMsg);
        }

        if (pMsg && safeToDealloc)
        {
          ICall_freeMsg(pMsg);
        }
      }
    }
  }
}
/*********************************************************************
 * @fn      glucCollCentral_processAppMsg
 *
 * @brief   Central application event processing function.
 *
 * @param   pMsg - pointer to event structure
 *
 * @return  none
 */
static void glucCollCentral_processAppMsg(glucCollEvt_t *pMsg)
{
  switch (pMsg->hdr.event)
  {
    case GLUCOLL_STATE_CHANGE_EVT:
      glucCollCentral_processStackMsg((ICall_Hdr *)pMsg->pData);

      // Free the stack message
      ICall_freeMsg(pMsg->pData);
      break;
      
    case GLUCOLL_KEY_CHANGE_EVT:
      glucCollCentral_handleKeys(0, pMsg->hdr.state); 
      break;
      
    case GLUCOLL_PASSCODE_NEEDED_EVT:
      {
        glucCollCentral_processPasscode(glucCollConnHandle, pMsg->pData[0], pMsg->pData[1]);
      
        // Free data.
        ICall_free(pMsg->pData);
      }
      break;
      
    case GLUCOLL_PAIRING_STATE_EVT:
      {
        glucCollCentral_processPairState(glucCollConnHandle, pMsg->hdr.state, pMsg->pData[0]);
        
        // Free data.
        ICall_free(pMsg->pData);
      }
      break;
      
    default:
      // Do nothing.
      break;
  }
}
Пример #11
0
/*********************************************************************
 * @fn      simpleTopology_processAppMsg
 *
 * @brief   Process an incoming callback from a profile.
 *
 * @param   pMsg - message to process
 *
 * @return  None.
 */
static void simpleTopology_processAppMsg(sbtEvt_t *pMsg)
{
  switch (pMsg->event)
  {
    case SBT_STATE_CHANGE_EVT:
      simpleTopology_processStackMsg((ICall_Hdr *)pMsg->pData);
      // Free the stack message
      ICall_freeMsg(pMsg->pData);
      break;

    case SBT_CHAR_CHANGE_EVT:
      simpleTopology_processCharValueChangeEvt(pMsg->status);
      break;

    case SBT_KEY_CHANGE_EVT:
      simpleTopology_handleKeys(0, pMsg->status);
      break;
      
    default:
      // Do nothing.
      break;
  }
}
Пример #12
0
/*********************************************************************
 * @fn      simpleTopology_taskFxn
 *
 * @brief   Application task entry point for the Simple BLE Multi.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 */
static void simpleTopology_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  simpleTopology_init();

  // Application main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest,
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        uint8 safeToDealloc = TRUE;
        
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          ICall_Event *pEvt = (ICall_Event *)pMsg;
          
          // Check for BLE stack events first
          if (pEvt->signature == 0xffff)
          {
            if (pEvt->event_flag & SBT_CONN_EVT_END_EVT)
            {
              // Try to retransmit pending ATT Response (if any)
              simpleTopology_sendAttRsp();
            }
          }
          else
          {
            // Process inter-task message
            safeToDealloc = simpleTopology_processStackMsg((ICall_Hdr *)pMsg);
          }
        }

        if (pMsg && safeToDealloc)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      while (!Queue_empty(appMsgQueue))
      {
        sbtEvt_t *pMsg = (sbtEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          simpleTopology_processAppMsg(pMsg);

          // Free the space from the message.
          ICall_free(pMsg);
        }
      }
    }

    if (events & SBT_START_DISCOVERY_EVT)
    {      
      events &= ~SBT_START_DISCOVERY_EVT;
      
      simpleTopology_startDiscovery();
    }  
  }
}
Пример #13
0
/*********************************************************************
 * @fn      Thermometer_taskFxn
 *
 * @brief   Thermometer Application Task entry point.  This function
 *          is called to initialize and then process all events for the task.
 *          Events include timers, messages and any other user defined events.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 */
void Thermometer_taskFxn(UArg a0, UArg a1)
{ 
  // Initialize the application.
  Thermometer_init();
    
  // Application main loop.
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.  
    // Note that the semaphore associated with a thread is signaled when a 
    // message is queued to the message receive queue of the thread or when 
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL; 
      
      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message.
          Thermometer_processStackMsg((ICall_Hdr *)pMsg);
        }
                
        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }
    }
    
    // If RTOS queue is not empty, process app message.
    while (!Queue_empty(appMsgQueue))
    {
      thermometerEvt_t *pMsg = (thermometerEvt_t*)Util_dequeueMsg(appMsgQueue);
      if (pMsg)
      {
        // Process message.
        Thermometer_processAppMsg(pMsg);
        
        // Free the space from the message.
        ICall_free(pMsg);
      }
    }
    
    if (events)
    {
      // Start discovery event.
      if (events & THERMOMETER_START_DISC_EVT)
      {
        events &= ~THERMOMETER_START_DISC_EVT;
        
        Thermometer_startDiscEvt();
      }
      
      // Thermometer periodic measurement event.
      if (events & THERMOMETER_PERIODIC_MEAS_EVT)
      {
        events &= ~THERMOMETER_PERIODIC_MEAS_EVT;
        
        Thermometer_performPeriodicTask();
      }
      
      // Thermometer periodic I-measurement event.
      if (events & THERMOMETER_PERIODIC_IMEAS_EVT)
      {
        events &= ~THERMOMETER_PERIODIC_IMEAS_EVT;
        
        Thermometer_performPeriodicImeasTask();
      }
      
      // Disconnect event.
      if (events & THERMOMETER_DISCONNECT_EVT)
      {
        events &= ~THERMOMETER_DISCONNECT_EVT;
        
        Thermometer_disconnectEvt();
      }
    }
  }
}
Пример #14
0
/*********************************************************************
 * @fn      SimplePropBeacon_taskFxn
 *
 * @brief   Application task entry point for the Simple Proprietary Beacon.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 */
static void SimplePropBeacon_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  SimplePropBeacon_init();

  // Application main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest,
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        uint8 safeToDealloc = TRUE;

        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;

          // Check for BLE stack events first
          if (pEvt->signature == 0xffff)
          {
            if (pEvt->event_flag & SPB_CONN_EVT_END_EVT)
            {
              // Try to retransmit pending ATT Response (if any)
              SimplePropBeacon_sendAttRsp();
            }
          }
          else
          {
            // Process inter-task message
            safeToDealloc = SimplePropBeacon_processStackMsg((ICall_Hdr *)pMsg);

          }
        }

        if (pMsg && safeToDealloc)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      while (!Queue_empty(appMsgQueue))
      {
        spbEvt_t *pMsg = (spbEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          SimplePropBeacon_processAppMsg(pMsg);

          // Free the space from the message.
          ICall_free(pMsg);
        }
      }
    }

#ifdef FEATURE_OAD
    while (!Queue_empty(hOadQ))
    {
      oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ);

      // Identify new image.
      if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
      {
        OAD_imgIdentifyWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
      }
      // Write a next block request.
      else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
      {
        OAD_imgBlockWrite(oadWriteEvt->connHandle, oadWriteEvt->pData);
      }

      // Free buffer.
      ICall_free(oadWriteEvt);
    }
#endif //FEATURE_OAD
  }
}
/*********************************************************************
 * @fn     glucCollCentral_taskFxn
 *
 * @brief   Application task entry point for the Glucose collector.
 *
 * @param   a0, a1 - not used
 *
 * @return  none
 */
static void glucCollCentral_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  glucCollCentral_Init();

  // Application main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message
          glucCollCentral_processStackMsg((ICall_Hdr *)pMsg);
        }

        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      while (!Queue_empty(appMsgQueue))
      {
        glucCollEvt_t *pMsg = (glucCollEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          glucCollCentral_processAppMsg(pMsg);

          // Free the space from the message.
          ICall_free(pMsg);
        }
      }

      if (events)
      {
        if (events & GLUCOLL_PROCEDURE_TIMEOUT_EVT)
        {
          events &= ~GLUCOLL_PROCEDURE_TIMEOUT_EVT;
          
          if (glucCollState == BLE_STATE_CONNECTED)
          {
            // disconnect
            glucCollState = BLE_STATE_DISCONNECTING;
            
            GAPCentralRole_TerminateLink(glucCollConnHandle);
            
            LCD_WRITE_STRING("Timeout", LCD_PAGE0); 
            LCD_WRITE_STRING("", LCD_PAGE1);
            LCD_WRITE_STRING("", LCD_PAGE2);
          }
        }

        if (events & GLUCOLL_START_DISCOVERY_EVT)
        {
          events &= ~GLUCOLL_START_DISCOVERY_EVT;
          
          if (glucCollPairingStarted)
          {
            // Postpone discovery until pairing completes
            glucCollDiscPostponed = TRUE;
          }
          else
          {
            glucCollCentral_startDiscovery();
          }  
        }
      }
    }
  }
}
Пример #16
0
/*********************************************************************
 * @fn      trainingTag_taskFxn
 *
 * @brief   Application task entry point for the Simple BLE Peripheral.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 */
static void trainingTag_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  trainingTag_init();

  // Application main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest,
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message
          trainingTag_processStackMsg((ICall_Hdr *)pMsg);
        }

        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      if (!Queue_empty(appMsgQueue))
      {
        tTagEvt_t *pMsg = (tTagEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          trainingTag_processAppMsg(pMsg);

          // Free the space from the message.
          ICall_free(pMsg);
        }
      }
    }

    if (events & TTG_PERIODIC_EVT)
    {
      events &= ~TTG_PERIODIC_EVT;

      Util_startClock(&periodicClock);

      // Perform periodic application task
      trainingTag_performPeriodicTask();
    }
  }
}
Пример #17
0
/*******************************************************************************
 * @fn      SensorTag_taskFxn
 *
 * @brief   Application task entry point for the SensorTag
 *
 * @param   a0, a1 (not used)
 *
 * @return  none
 */
static void SensorTag_taskFxn(UArg a0, UArg a1)
{
  // Initialize application
  SensorTag_init();

  // Application main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signalled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;

      if (ICall_fetchServiceMsg(&src, &dest,
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message
          SensorTag_processStackMsg((ICall_Hdr *)pMsg);
        }

        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      while (!Queue_empty(appMsgQueue))
      {
        stEvt_t *pMsg = (stEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          SensorTag_processAppMsg(pMsg);

          // Free the space from the message.
          ICall_free(pMsg);
        }
      }

      // Process new data if available
      SensorTagKeys_processEvent();
      SensorTagOpt_processSensorEvent();
      SensorTagMov_processSensorEvent();
    }

    if (!!(events & ST_PERIODIC_EVT))
    {
      events &= ~ST_PERIODIC_EVT;

      if (gapProfileState == GAPROLE_CONNECTED
          || gapProfileState == GAPROLE_ADVERTISING)
      {
        Util_startClock(&periodicClock);
      }

      // Perform periodic application task
      if (gapProfileState == GAPROLE_CONNECTED)
      {
        SensorTag_performPeriodicTask();
      }

      // Blink green LED when advertising
      if (gapProfileState == GAPROLE_ADVERTISING)
      {
        SensorTag_blinkLed(Board_LED2,1);
        #ifdef FEATURE_LCD
        SensorTag_displayBatteryVoltage();
        #endif
      }
    }

    #ifdef FEATURE_OAD
    while (!Queue_empty(hOadQ))
    {
      oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ);

      // Identify new image.
      if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ)
      {
        OAD_imgIdentifyWrite(oadWriteEvt->connHandle,
                             oadWriteEvt->pData);
      }
      // Write a next block request.
      else if (oadWriteEvt->event == OAD_WRITE_BLOCK_REQ)
      {
        OAD_imgBlockWrite(oadWriteEvt->connHandle,
                          oadWriteEvt->pData);
      }

      // Free buffer.
      ICall_free(oadWriteEvt);
    }
    #endif //FEATURE_OAD
  } // task loop
}
Пример #18
0
/*********************************************************************
 * @fn      simpleTopology_taskFxn
 *
 * @brief   Application task entry point for the Simple BLE Multi.
 *
 * @param   a0, a1 - not used.
 *
 * @return  None.
 */
static void simpleTopology_taskFxn(UArg a0, UArg a1)
{
	// Initialize application
	simpleTopology_init();

	// Application main loop
	for (;;)
	{
		// Waits for a signal to the semaphore associated with the calling thread.
		// Note that the semaphore associated with a thread is signaled when a
		// message is queued to the message receive queue of the thread or when
		// ICall_signal() function is called onto the semaphore.
		ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

		if (errno == ICALL_ERRNO_SUCCESS)
		{
			ICall_EntityID dest;
			ICall_ServiceEnum src;
			ICall_HciExtEvt *pMsg = NULL;

			if (ICall_fetchServiceMsg(&src, &dest,
					(void **)&pMsg) == ICALL_ERRNO_SUCCESS)
			{
				uint8 safeToDealloc = TRUE;

				if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
				{
					// Process inter-task message
					safeToDealloc = simpleTopology_processStackMsg((ICall_Hdr *)pMsg);
				}

				if (pMsg && safeToDealloc)
				{
					ICall_freeMsg(pMsg);
				}
			}

			// If RTOS queue is not empty, process app message.
			while (!Queue_empty(appMsgQueue))
			{
				sbtEvt_t *pMsg = (sbtEvt_t *)Util_dequeueMsg(appMsgQueue);
				if (pMsg)
				{
					// Process message.
					simpleTopology_processAppMsg(pMsg);

					// Free the space from the message.
					ICall_free(pMsg);
				}
			}
		}

		// the trigger was a periodic event
		// trigger was the SCAN_EVENT
		if (!!(events & SCAN_EVENT))
		{
			// effectively mark off the event as "handled"
			events &= ~SCAN_EVENT;
			// now start discovery.
			// CJ: I think that the scan parameters are set in such a way
			// that it will start and stop itself
			scanningStarted = true;
			GAPRole_StartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN,
					DEFAULT_DISCOVERY_WHITE_LIST);
		}
	}
}
Пример #19
0
/*********************************************************************
 * @fn      gapRole_taskFxn
 *
 * @brief   Task entry point for the GAP Peripheral Role.
 *
 * @param   a0 - first argument
 * @param   a1 - second argument
 *
 * @return  none
 */
static void gapRole_taskFxn(UArg a0, UArg a1)
{  
  // Initialize profile
  gapRole_init();
  
  // Profile main loop
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;
      
      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        uint8_t safeToDealloc = TRUE;
        
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;
          
          // Check for BLE stack events first
          if (pEvt->signature == 0xffff)
          {
            if (pEvt->event_flag & GAP_EVENT_SIGN_COUNTER_CHANGED)
            {
              // Sign counter changed, save it to NV
              VOID osal_snv_write(BLE_NVID_SIGNCOUNTER, sizeof(uint32_t), 
                                  &gapRole_signCounter);
            }
          }
          else
          {
            // Process inter-task message
            safeToDealloc = gapRole_processStackMsg((ICall_Hdr *)pMsg);
          }
        }

        if (pMsg && safeToDealloc)
        {
          ICall_freeMsg(pMsg);
        }
      }
    }

    if (events & START_ADVERTISING_EVT)
    { 
      events &= ~START_ADVERTISING_EVT;
      
      if (gapRole_AdvEnabled || gapRole_AdvNonConnEnabled)
      {
        gapAdvertisingParams_t params;

        // Setup advertisement parameters
        if (gapRole_AdvNonConnEnabled)
        {
          // Only advertise non-connectable undirected.
          params.eventType = GAP_ADTYPE_ADV_NONCONN_IND;
        }
        else
        {
          params.eventType = gapRole_AdvEventType;
          params.initiatorAddrType = gapRole_AdvDirectType;
          VOID memcpy(params.initiatorAddr, gapRole_AdvDirectAddr, B_ADDR_LEN);
        }
        
        params.channelMap = gapRole_AdvChanMap;
        params.filterPolicy = gapRole_AdvFilterPolicy;

        if (GAP_MakeDiscoverable(selfEntity, &params) != SUCCESS)
        {
          gapRole_abort();
        }
      }
    }
    if (events & CONN_PARAM_TIMEOUT_EVT)
    {
      events &= ~CONN_PARAM_TIMEOUT_EVT;

      // Unsuccessful in updating connection parameters
      gapRole_HandleParamUpdateNoSuccess();
    }    
  } // for
}
Пример #20
0
/*********************************************************************
 * @fn      HeartRate_taskFxn
 *
 * @brief   Application task entry point for the Heart Rate.
 *
 * @param   none
 *
 * @return  none
 */     
static void HeartRate_taskFxn(UArg a0, UArg a1)
{
  // Initialize the application.
  HeartRate_init();
  
  // Application main loop.
  for(;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a 
    // message is queued to the message receive queue of the thread or when the
    // ICall_signal() function is called on the thread's respective semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
    
    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;
      
      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message.
          HeartRate_processStackMsg((ICall_Hdr *)pMsg);
        }
                
        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }
    }
    
    // If RTOS queue is not empty, process app message.
    while (!Queue_empty(appMsgQueue))
    {
      heartRateEvt_t *pMsg = (heartRateEvt_t*)Util_dequeueMsg(appMsgQueue);
      if (pMsg)
      {
        // Process message.
        HeartRate_processAppMsg(pMsg);
        
        // Free the space from the message.
        ICall_free(pMsg);
      }
    }
    
    // Heart rate service periodic task.
    if (events & HEARTRATE_MEAS_PERIODIC_EVT)
    {
      events &= ~HEARTRATE_MEAS_PERIODIC_EVT;
      
      HeartRate_measPerTask();
    }
    
    // Battery service periodic task.
    if (events & HEARTRATE_BATT_PERIODIC_EVT)
    {
      events &= ~HEARTRATE_BATT_PERIODIC_EVT;
      
      HeartRate_battPerTask();
    }
  }
}
/*********************************************************************
 * @fn      RunningSensor_taskFxn
 *
 * @brief   Running Application Task event processor.  This function
 *          is called to process all events for the task.  Events
 *          include timers, messages and any other user defined events.
 *
 * @param   a0, a1 - not used.
 *
 * @return  none
 */
void RunningSensor_taskFxn(UArg a0, UArg a1)
{
  // Initialize the application.
  RunningSensor_init();
  
  // Application main loop.
  for (;;)
  {
    // Waits for a signal to the semaphore associated with the calling thread.
    // Note that the semaphore associated with a thread is signaled when a
    // message is queued to the message receive queue of the thread or when
    // ICall_signal() function is called onto the semaphore.
    ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);

    if (errno == ICALL_ERRNO_SUCCESS)
    {
      ICall_EntityID dest;
      ICall_ServiceEnum src;
      ICall_HciExtEvt *pMsg = NULL;
      
      if (ICall_fetchServiceMsg(&src, &dest, 
                                (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
      {
        if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
        {
          // Process inter-task message.
          RunningSensor_processStackMsg((ICall_Hdr *)pMsg);
        }
                
        if (pMsg)
        {
          ICall_freeMsg(pMsg);
        }
      }

      // If RTOS queue is not empty, process app message.
      while (!Queue_empty(appMsgQueue))
      {
        rscEvt_t *pMsg = (rscEvt_t *)Util_dequeueMsg(appMsgQueue);
        if (pMsg)
        {
          // Process message.
          RunningSensor_processAppMsg(pMsg);
          
          // Free the space from the message.
          ICall_free(pMsg);
        }
      }
    }

    if (events)
    { 
      // Running sensor periodic event.
      if (events & RSC_PERIODIC_EVT)
      {
        events &= ~RSC_PERIODIC_EVT;
        
        // Perform periodic sensor's periodic task.
        RunningSensor_periodicTask();
      }

      // Parameter update event.
      if (events & RSC_CONN_PARAM_UPDATE_EVT)
      {
        events &= ~RSC_CONN_PARAM_UPDATE_EVT;
        
        // Send param update.  If it fails, retry until successful.
        GAPRole_SendUpdateParam(DEFAULT_DESIRED_MIN_CONN_INTERVAL, 
                                DEFAULT_DESIRED_MAX_CONN_INTERVAL,
                                DEFAULT_DESIRED_SLAVE_LATENCY, 
                                DEFAULT_DESIRED_CONN_TIMEOUT,
                                GAPROLE_RESEND_PARAM_UPDATE);

#if USING_NEGLECT_TIMEOUT
        // Assuming service discovery complete, start neglect timer.
        Util_startClock(&neglectClock);
#endif //USING_NEGLECT_TIMEOUT
      }

#if USING_NEGLECT_TIMEOUT
      // Neglect timer expired.
      if (events & RSC_NEGLECT_TIMEOUT_EVT)
      {
        events &= ~RSC_NEGLECT_TIMEOUT_EVT;
        
        // No user input, terminate connection.
        GAPRole_TerminateConnection();
      }
#endif //USING_NEGLECT_TIMEOUT
      
      // Soft reset event.
      if (events & RSC_RESET_EVT)
      {
        events &= ~RSC_RESET_EVT;
        
        RunningSensor_handleResetEvt();
      }
    }
  }
}