/********************************************************************* * @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; } }
/********************************************************************* * @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); } } } } }
/********************************************************************* * @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); }
/********************************************************************* * @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); }
/********************************************************************* * @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); } } } } }
/** * @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; } }
/********************************************************************* * @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; } }
/********************************************************************* * @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(); } } }
/********************************************************************* * @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(); } } } }
/********************************************************************* * @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(); } } } } } }
/********************************************************************* * @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(); } } }
/******************************************************************************* * @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 }
/********************************************************************* * @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); } } }
/********************************************************************* * @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, ¶ms) != SUCCESS) { gapRole_abort(); } } } if (events & CONN_PARAM_TIMEOUT_EVT) { events &= ~CONN_PARAM_TIMEOUT_EVT; // Unsuccessful in updating connection parameters gapRole_HandleParamUpdateNoSuccess(); } } // for }
/********************************************************************* * @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(); } } } }