/********************************************************************* * @fn RunningSensor_processAppMsg * * @brief Process an incoming callback from a profile. * * @param pMsg - message to process * * @return none */ static void RunningSensor_processAppMsg(rscEvt_t *pMsg) { switch (pMsg->hdr.event) { case RSC_STATE_CHANGE_EVT: RunningSensor_processStateChangeEvt((gaprole_States_t)pMsg->hdr.state); break; case RSC_KEY_CHANGE_EVT: RunningSensor_handleKeys(0, pMsg->hdr.state); break; // Running service callback event. case RSC_SERVICE_EVT: RunningSensor_processServiceEvt(pMsg->hdr.event, (uint32_t)*pMsg->pData); ICall_free(pMsg->pData); break; // Running service control point write event. case RSC_CMD_SEND_IND_EVT: RunningService_sendRSCCmdIndication(selfEntity); break; default: // Do nothing. break; } }
/********************************************************************* * @fn Util_enqueueMsg * * @brief Creates a queue node and puts the node in RTOS queue. * * @param msgQueue - queue handle. * @param sem - thread's event processing semaphore that queue is * associated with. * @param pMsg - pointer to message to be queued * * @return TRUE if message was queued, FALSE otherwise. */ uint8_t Util_enqueueMsg(Queue_Handle msgQueue, Semaphore_Handle sem, uint8_t *pMsg) { queueRec_t *pRec; // Allocated space for queue node. #ifdef USE_ICALL if (pRec = ICall_malloc(sizeof(queueRec_t))) #else if (pRec = (queueRec_t *)malloc(sizeof(queueRec_t))) #endif { pRec->pData = pMsg; Queue_enqueue(msgQueue, &pRec->_elem); // Wake up the application thread event handler. if (sem) { Semaphore_post(sem); } return TRUE; } // Free the message. #ifdef USE_ICALL ICall_free(pMsg); #else free(pMsg); #endif return FALSE; }
/********************************************************************* * @fn CyclingSensor_processAppMsg * * @brief Process an incoming callback from a profile. * * @param pMsg - message to process * * @return none */ static void CyclingSensor_processAppMsg(cscEvt_t *pMsg) { switch (pMsg->hdr.event) { case CSC_STATE_CHANGE_EVT: CyclingSensor_processStateChangeEvt((gaprole_States_t)pMsg->hdr.state); break; case CSC_KEY_CHANGE_EVT: CyclingSensor_handleKeys(0, pMsg->hdr.state); break; // Cycling service callback event. case CSC_SERVICE_EVT: { uint32_t cummVal = *((uint32_t*)(pMsg->pData)); CyclingSensor_processServiceEvt(pMsg->hdr.state, cummVal); ICall_free(pMsg->pData); } break; default: // Do nothing. break; } }
/********************************************************************* * @fn OADTarget_addService * * @brief Initializes the OAD Service by registering GATT attributes * with the GATT server. Only call this function once. * * @return The return value of GATTServApp_RegisterForMsg(). */ bStatus_t OADTarget_addService(void) { // Allocate Client Characteristic Configuration table oadImgIdentifyConfig = (gattCharCfg_t *)ICall_malloc(sizeof(gattCharCfg_t) * linkDBNumConns); if (oadImgIdentifyConfig == NULL) { return (bleMemAllocError); } // Allocate Client Characteristic Configuration table oadImgBlockConfig = (gattCharCfg_t *)ICall_malloc(sizeof(gattCharCfg_t) * linkDBNumConns); if (oadImgBlockConfig == NULL) { // Free already allocated data ICall_free(oadImgIdentifyConfig); return (bleMemAllocError); } // Initialize Client Characteristic Configuration attributes GATTServApp_InitCharCfg(INVALID_CONNHANDLE, oadImgIdentifyConfig); GATTServApp_InitCharCfg(INVALID_CONNHANDLE, oadImgBlockConfig); return GATTServApp_RegisterService(oadAttrTbl, GATT_NUM_ATTRS(oadAttrTbl), GATT_MAX_ENCRYPT_KEY_SIZE, &oadCBs); }
/******************************************************************************* * @fn SensorTagOad_processEvent * * @brief Process the write events to the OAD characteristics * * @param a0, a1 (not used) * * @return none */ void SensorTagOad_processEvent(void) { while (!Queue_empty(hOadQ)) { oadTargetWrite_t *oadWriteEvt = Queue_dequeue(hOadQ); // Identify new image. if (oadWriteEvt->event == OAD_WRITE_IDENTIFY_REQ) { // Request image identification 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); } }
/********************************************************************* * @fn Thermometer_processAppMsg * * @brief Process an incoming stack message. * * @param pMsg - message to process * * @return none */ static void Thermometer_processAppMsg(thermometerEvt_t *pMsg) { switch (pMsg->hdr.event) { case THERMOMETER_STATE_CHANGE_EVT: Thermometer_processStateChangeEvt((gaprole_States_t)pMsg->hdr.state); break; case THERMOMETER_KEY_CHANGE_EVT: Thermometer_handleKeys(0, pMsg->hdr.state); break; // Passcode event. case THERMOMETER_PASSCODE_EVT: Thermometer_processPasscodeEvt(thermometer_connHandle); break; // Pair state event. case THERMOMETER_PAIR_STATE_EVT: Thermometer_processPairStateEvt(pMsg->hdr.state, *pMsg->pData); ICall_free(pMsg->pData); break; // Thermometer event. case THERMOMETER_SERVICE_EVT: Thermometer_processServiceEvt(pMsg->hdr.state); break; default: // Do nothing. break; } }
// Pass in the pointer to a buffer allocated by SNP_malloc to free the buffer. void SNP_free(void* pointer) { #ifdef SNP_LOCAL ICall_free(pointer); #else //!SNP_LOCAL free(pointer); #endif //SNP_LOCAL }
/********************************************************************* * @fn SimpleBLECentral_processRoleEvent * * @brief Central role event processing function. * * @param pEvent - pointer to event structure * * @return none */ static void SimpleBLEPeripheralObserver_processRoleEvent(gapPeripheralObserverRoleEvent_t *pEvent) { switch (pEvent->gap.opcode) { case GAP_DEVICE_INFO_EVENT: { //Print scan response data otherwise advertising data if(pEvent->deviceInfo.eventType == GAP_ADRPT_SCAN_RSP) { Display_print1(dispHandle, 4, 0, "Scan Response Addr: %s", Util_convertBdAddr2Str(pEvent->deviceInfo.addr)); Display_print1(dispHandle, 5, 0, "Scan Response Data: %s", Util_convertBytes2Str(pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen)); } else { deviceInfoCnt++; Display_print2(dispHandle, 6, 0, "Advertising Addr: %s Advertising Type: %s", Util_convertBdAddr2Str(pEvent->deviceInfo.addr), AdvTypeStrings[pEvent->deviceInfo.eventType]); Display_print1(dispHandle, 7, 0, "Advertising Data: %s", Util_convertBytes2Str(pEvent->deviceInfo.pEvtData, pEvent->deviceInfo.dataLen)); } ICall_free(pEvent->deviceInfo.pEvtData); ICall_free(pEvent); } break; case GAP_DEVICE_DISCOVERY_EVENT: { // discovery complete scanningStarted = FALSE; deviceInfoCnt = 0; //Display_print0(dispHandle, 7, 0, "GAP_DEVICE_DISC_EVENT"); Display_print1(dispHandle, 5, 0, "Devices discovered: %d", pEvent->discCmpl.numDevs); Display_print0(dispHandle, 4, 0, "Scanning Off"); ICall_free(pEvent->discCmpl.pDevList); ICall_free(pEvent); } break; default: break; } }
/********************************************************************* * @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 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; } }
/** * SNP_setAdvData * */ uint8_t SNP_setAdvData(snpSetAdvDataReq_t *pReq, uint8_t len) { uint8_t status = 0; uint8_t *pDataPtr; //Device must be started, or the set adv command will failed. VOID GAPRole_StartDevice(&SNP_gapRoleCBs); if(pReq->type < SNP_ADV_DATA_MAX_IDX) { pDataPtr = advPtrTable[pReq->type].pData; if(pDataPtr) { ICall_free(advPtrTable[pReq->type].pData); } advPtrTable[pReq->type].pData = pDataPtr = ICall_malloc(len); if(pDataPtr) { advPtrTable[pReq->type].length = len; memcpy(pDataPtr, pReq->pData, len); if(pReq->type == SNP_ADV_DATA_SCAN_RSP_IDX) { status = GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, len, pDataPtr); } else if(pReq->type == SNP_ADV_DATA_NON_CONN_IDX) { status = GAPRole_SetParameter(GAPROLE_ADVERT_DATA, len, pDataPtr); } else if(pReq->type == SNP_ADV_DATA_CONN_IDX) { uint8_t value; GAPRole_GetParameter(GAPROLE_STATE, &value); if(value == GAPROLE_CONNECTED_ADV) { status = GAPRole_SetParameter(GAPROLE_ADVERT_DATA, len, pDataPtr); } } } else { status = SNP_OUT_OF_RESOURCES; } } else { //Error, bad type status = SNP_INVALID_PARAMS; } return status; }
/********************************************************************* * @fn Util_enqueueMsg * * @brief Creates a queue node and puts the node in RTOS queue. * * @param msgQueue - queue handle. * @param sem - thread's event processing semaphore that queue is * associated with. * @param pMsg - pointer to message to be queued * * @return TRUE if message was queued, FALSE otherwise. */ uint8_t Util_enqueueMsg(Queue_Handle msgQueue, #ifdef ICALL_EVENTS Event_Handle event, #else //!ICALL_EVENTS Semaphore_Handle sem, #endif //ICALL_EVENTS uint8_t *pMsg) { queueRec_t *pRec; // Allocated space for queue node. #ifdef USE_ICALL if ((pRec = ICall_malloc(sizeof(queueRec_t)))) #else if ((pRec = (queueRec_t *)malloc(sizeof(queueRec_t)))) #endif { pRec->pData = pMsg; // This is an atomic operation Queue_put(msgQueue, &pRec->_elem); // Wake up the application thread event handler. #ifdef ICALL_EVENTS if (event) { Event_post(event, UTIL_QUEUE_EVENT_ID); } #else //!ICALL_EVENTS if (sem) { Semaphore_post(sem); } #endif //ICALL_EVENTS return TRUE; } // Free the message. #ifdef USE_ICALL ICall_free(pMsg); #else free(pMsg); #endif return FALSE; }
/********************************************************************* * @fn BloodPressure_AddService * * @brief Initializes the BloodPressure service by registering * GATT attributes with the GATT server. * * @param services - services to add. This is a bit map and can * contain more than one service. * * @return Success or Failure */ bStatus_t BloodPressure_AddService(uint32 services) { uint8 status; // Allocate Client Characteristic Configuration table bloodPressureMeasConfig = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) * linkDBNumConns ); if ( bloodPressureMeasConfig == NULL ) { return ( bleMemAllocError ); } // Allocate Client Characteristic Configuration table bloodPressureIMeasConfig = (gattCharCfg_t *)ICall_malloc( sizeof(gattCharCfg_t) * linkDBNumConns ); if ( bloodPressureIMeasConfig == NULL ) { // Free already allocated data ICall_free( bloodPressureMeasConfig ); return ( bleMemAllocError ); } // Initialize Client Characteristic Configuration attributes. GATTServApp_InitCharCfg(INVALID_CONNHANDLE, bloodPressureMeasConfig); GATTServApp_InitCharCfg(INVALID_CONNHANDLE, bloodPressureIMeasConfig); if (services & BLOODPRESSURE_SERVICE) { // Register GATT attribute list and CBs with GATT Server App. status = GATTServApp_RegisterService(bloodPressureAttrTbl, GATT_NUM_ATTRS(bloodPressureAttrTbl), GATT_MAX_ENCRYPT_KEY_SIZE, &bloodPressureCBs); } else { status = SUCCESS; } return (status); }
/********************************************************************* * @fn Util_dequeueMsg * * @brief Dequeues the message from the RTOS queue. * * @param msgQueue - queue handle. * * @return pointer to dequeued message, NULL otherwise. */ uint8_t *Util_dequeueMsg(Queue_Handle msgQueue) { if (!Queue_empty(msgQueue)) { queueRec_t *pRec = Queue_dequeue(msgQueue); uint8_t *pData = pRec->pData; // Free the queue node // Note: this does not free space allocated by data within the node. #ifdef USE_ICALL ICall_free(pRec); #else free(pRec); #endif return pData; } return NULL; }
// ---------------------------------------------------------------------------- //! \brief Collects MT message buffer. Used during serial data receipt. //! //! | SOP | Data Length | CMD | Data | FCS | //! | 1 | 1 | 2 | 0-Len | 1 | //! //! \return void // ---------------------------------------------------------------------------- void NPIFrame_collectFrameData(void) { uint8_t ch; uint8_t uint8_tsInRxBuffer; while (NPIRxBuf_GetRxBufCount()) { NPIRxBuf_ReadFromRxBuf(&ch, 1); switch (state) { case NPIFRAMEMT_SOP_STATE: if (ch == MT_SOF) { state = NPIFRAMEMT_LEN_STATE; } break; case NPIFRAMEMT_LEN_STATE: LEN_Token = ch; tempDataLen = 0; /* Allocate memory for the data */ pMsg = (uint8_t *) ICall_allocMsg(MTRPC_FRAME_HDR_SZ + LEN_Token); if (pMsg) { pMsg[MTRPC_POS_LEN] = LEN_Token; state = NPIFRAMEMT_CMD_STATE1; } else { state = NPIFRAMEMT_SOP_STATE; return; } break; case NPIFRAMEMT_CMD_STATE1: pMsg[MTRPC_POS_CMD0] = ch; state = NPIFRAMEMT_CMD_STATE2; break; case NPIFRAMEMT_CMD_STATE2: pMsg[MTRPC_POS_CMD1] = ch; /* If there is no data, skip to FCS state */ if (LEN_Token) { state = NPIFRAMEMT_DATA_STATE; } else { state = NPIFRAMEMT_FCS_STATE; } break; case NPIFRAMEMT_DATA_STATE: /* Fill in the buffer the first uint8_t of the data */ pMsg[MTRPC_FRAME_HDR_SZ + tempDataLen++] = ch; /* Check number of uint8_ts left in the Rx buffer */ uint8_tsInRxBuffer = NPIRxBuf_GetRxBufCount(); /* If the remain of the data is there, read them all, otherwise, just read enough */ if (uint8_tsInRxBuffer <= LEN_Token - tempDataLen) { NPIRxBuf_ReadFromRxBuf(&pMsg[MTRPC_FRAME_HDR_SZ + tempDataLen], uint8_tsInRxBuffer); tempDataLen += uint8_tsInRxBuffer; } else { NPIRxBuf_ReadFromRxBuf(&pMsg[MTRPC_FRAME_HDR_SZ + tempDataLen], LEN_Token - tempDataLen); tempDataLen += (LEN_Token - tempDataLen); } /* If number of uint8_ts read is equal to data length, time to move on to FCS */ if (tempDataLen == LEN_Token) { state = NPIFRAMEMT_FCS_STATE; } break; case NPIFRAMEMT_FCS_STATE: FSC_Token = ch; /* Make sure it's correct */ if ((npiframe_calcMTFCS((uint8_t *)&pMsg[0], MTRPC_FRAME_HDR_SZ + LEN_Token) == FSC_Token)) { /* Determine if it's a SYNC or ASYNC message */ NPIMSG_Type msgType; #if defined(NPI_SREQRSP) if ((pMsg[1] & MTRPC_CMD_TYPE_MASK) == MTRPC_CMD_SREQ) { msgType = NPIMSG_Type_SYNCREQ; } else { msgType = NPIMSG_Type_ASYNC; } #else msgType = NPIMSG_Type_ASYNC; #endif // NPI_SREQRSP if ( incomingFrameCBFunc ) { incomingFrameCBFunc(MTRPC_FRAME_HDR_SZ + LEN_Token, pMsg, msgType); } } else { /* deallocate the msg */ ICall_free(pMsg); } /* Reset the state, send or discard the buffers at this point */ state = NPIFRAMEMT_SOP_STATE; break; default: 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 DevInfo_SetParameter * * @brief Set a Device Information parameter. * * @param param - Profile parameter ID * @param len - length of data to write * @param value - pointer to data to write. This is dependent on * the parameter ID and WILL be cast to the appropriate * data type (example: data type of uint16 will be cast to * uint16 pointer). * * @return bStatus_t */ bStatus_t DevInfo_SetParameter( uint8 param, uint8 len, void *value ) { bStatus_t ret = SUCCESS; switch ( param ) { case DEVINFO_SYSTEM_ID: // verify length if (len == sizeof(devInfoSystemId)) { memcpy(devInfoSystemId, value, len); } else { ret = bleInvalidRange; } break; case DEVINFO_MODEL_NUMBER: // verify length, leave room for null-terminate char if (len <= DEVINFO_STR_ATTR_LEN) { memset(devInfoModelNumber, 0, DEVINFO_STR_ATTR_LEN+1); memcpy(devInfoModelNumber, value, len); } else { ret = bleInvalidRange; } break; case DEVINFO_SERIAL_NUMBER: // verify length, leave room for null-terminate char if (len <= DEVINFO_STR_ATTR_LEN) { memset(devInfoSerialNumber, 0, DEVINFO_STR_ATTR_LEN+1); memcpy(devInfoSerialNumber, value, len); } else { ret = bleInvalidRange; } break; case DEVINFO_FIRMWARE_REV: // verify length, leave room for null-terminate char if (len <= DEVINFO_STR_ATTR_LEN) { memset(devInfoFirmwareRev, 0, DEVINFO_STR_ATTR_LEN+1); memcpy(devInfoFirmwareRev, value, len); } else { ret = bleInvalidRange; } break; case DEVINFO_HARDWARE_REV: // verify length, leave room for null-terminate char if (len <= DEVINFO_STR_ATTR_LEN) { memset(devInfoHardwareRev, 0, DEVINFO_STR_ATTR_LEN+1); memcpy(devInfoHardwareRev, value, len); } else { ret = bleInvalidRange; } break; case DEVINFO_SOFTWARE_REV: // verify length, leave room for null-terminate char if (len <= DEVINFO_STR_ATTR_LEN) { memset(devInfoSoftwareRev, 0, DEVINFO_STR_ATTR_LEN+1); memcpy(devInfoSoftwareRev, value, len); } else { ret = bleInvalidRange; } break; case DEVINFO_MANUFACTURER_NAME: // verify length, leave room for null-terminate char if (len <= DEVINFO_STR_ATTR_LEN) { memset(devInfoMfrName, 0, DEVINFO_STR_ATTR_LEN+1); memcpy(devInfoMfrName, value, len); } else { ret = bleInvalidRange; } break; case DEVINFO_11073_CERT_DATA: { // Allocate buffer for new certification uint8 *pCert = ICall_malloc(len); if (pCert != NULL) { if (devInfo11073Cert != defaultDevInfo11073Cert) { // Free existing certification buffer ICall_free(devInfo11073Cert); } // Copy over new certification memcpy(pCert, value, len); // Update our globals devInfo11073Cert = pCert; devInfo11073CertLen = len; } else { ret = bleMemAllocError; } } break; case DEVINFO_PNP_ID: // verify length if (len == sizeof(devInfoPnpId)) { memcpy(devInfoPnpId, value, len); } else { ret = bleInvalidRange; } break; default: ret = INVALIDPARAMETER; break; } return ( ret ); }
/********************************************************************* * @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 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 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 osal_mem_free * * @brief This function implements the OSAL dynamic memory de-allocation functionality. * * input parameters * * @param ptr - A valid pointer (i.e. a pointer returned by osal_mem_alloc()) to the memory to free. * * output parameters * * None. * * @return None. */ #ifdef DPRINTF_OSALHEAPTRACE void osal_mem_free_dbg(void *ptr, const char *fname, unsigned lnum) #else /* DPRINTF_OSALHEAPTRACE */ void osal_mem_free(void *ptr) #endif /* DPRINTF_OSALHEAPTRACE */ { ICall_free(ptr); }
/******************************************************************************* * @fn userAppPro * * @brief user Application event process * * @param evnet * * @return none */ void userAppPro(void) { if (userEvents & USER_10MS_EVT) { userEvents &= ~USER_10MS_EVT; Util_startClock(&periodicClock_10ms); KEY_Scan_10ms(); ChangeTime10mSec(); Pollint100mSec(); } #ifdef INCLUDE_CLKSTOP while (!Queue_empty(keyMsgQueue)) { KEY_stEvt_t *pMsg = (KEY_stEvt_t *)Util_dequeueMsg(keyMsgQueue); if (pMsg) { // Process message. switch(pMsg->GPIOName) { case KEY_NAME_3V3: if (KEY_HIGH == pMsg->GPIOStatus) { wifiPowerOn(); uartWriteDebug("poweron3v3", 10); OLED_ShowString(40,32, "WiCore"); userAppShowCharge(); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } Util_startClock(&periodicClock_10ms); } else { wifiPowerDown(); uartWriteDebug("powerdown3v3", 12); // 清低电闪烁 systemState.lowBatteryFlag = 0; OLED_Clear(); // 这个执行时间较长 打乱了定时周期,所以stopClock是没有用的 //Util_stopClock(&periodicClock_10ms); // 服务器的按键开关机 设置一个按键放开标志位,等待1s后没有放开 // 就清标志位,关闭时钟 systemState.keyUpFlag = 3; // 2 为电源按键 等待按键放开标志,3为 服务器按键 systemState.delayCnt = 10; // 有链接,关闭 GAPRole_TerminateConnection(); } break; case KEY_POWER: if (KEY_IQR == pMsg->GPIOStatus) { KEY_DisableIRQ(); uartWriteDebug("tttt", 4); systemState.powerOffFlag = 1; systemState.delayPowerOffTime = 5; // 延时5s 判断是否是按键长按 Util_startClock(&periodicClock_10ms); } else if (KEY_LONG == pMsg->GPIOStatus) { if (1 == systemState.powerOffFlag) { systemState.powerOffFlag = 0; systemState.delayPowerOffTime = 0; wifiPowerOn(); userAppShowCharge(); OLED_ShowString(40,32, "WiCore"); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } uartWriteDebug("poweron", 7); } else { //系统断电 wifiPowerDown(); uartWriteDebug("powerdown", 9); OLED_Clear(); systemState.lowBatteryFlag = 0; // 清低电闪烁 systemState.keyUpFlag = 2; // 2 为电源按键 等待按键放开标志,3为 服务器按键 // 有链接,关闭 GAPRole_TerminateConnection(); } systemState.keyShortFlag = 0; // 忽略短按事件 } else if (KEY_LOW == pMsg->GPIOStatus)// 松开 { if (2 == systemState.keyUpFlag) // 长按松开,关机 { systemState.keyUpFlag = 0; //开启外部中断 KEY_EnableIRQ(); { // 关闭广播 uint8_t initialAdvertEnable = FALSE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } Util_stopClock(&periodicClock_10ms); } else if (1 == systemState.keyShortFlag)// 短按松开 产生一次短按完整事件 { //短按事件处理 uartWriteDebug("短按", 4); } } else if (KEY_HIGH == pMsg->GPIOStatus) // 短按 { if (1 == systemState.powerOffFlag) // 等待长按事件 忽略此时的短按事件 { systemState.delayPowerOffTime = 5; // 防止timout 剩2s时又产生长按事件 } else { systemState.keyShortFlag = 1; } } break; default: break; } // Free the space from the message. ICall_free(pMsg); } } #else while (!Queue_empty(keyMsgQueue)) { KEY_stEvt_t *pMsg = (KEY_stEvt_t *)Util_dequeueMsg(keyMsgQueue); if (pMsg) { // Process message. switch(pMsg->GPIOName) { case KEY_NAME_3V3: if (KEY_HIGH == pMsg->GPIOStatus) { wifiPowerOn(); uartWriteDebug("poweron3v3", 10); OLED_ShowString(40,32, "WiCore"); userAppShowCharge(); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } systemState.powerOffFlag = 0; } else { wifiPowerDown(); uartWriteDebug("powerdown3v3", 12); // 清低电闪烁 systemState.lowBatteryFlag = 0; OLED_Clear(); // 这个执行时间较长 打乱了定时周期,所以stopClock是没有用的 // 有链接,关闭 GAPRole_TerminateConnection(); systemState.powerOffFlag = 1; } break; case KEY_POWER: if (KEY_LONG == pMsg->GPIOStatus) { if (1 == systemState.powerOffFlag) { systemState.powerOffFlag = 0; systemState.delayPowerOffTime = 0; systemState.keyUpFlag=0; wifiPowerOn(); userAppShowCharge(); OLED_ShowString(40,32, "WiCore"); // 启动广播 { uint8_t initialAdvertEnable = TRUE; GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initialAdvertEnable); } uartWriteDebug("poweron", 7); } else { //系统断电 systemState.keyUpFlag=0; systemState.powerOffFlag = 1; wifiPowerDown(); uartWriteDebug("powerdown", 9); OLED_Clear(); systemState.lowBatteryFlag = 0; // 清低电闪烁 // 有链接,关闭 GAPRole_TerminateConnection(); } systemState.keyShortFlag = 0; // 忽略短按事件 } else if (KEY_LOW == pMsg->GPIOStatus)// 松开 { if (1 == systemState.keyShortFlag)// 短按松开 产生一次短按完整事件 { //短按事件处理 uartWriteDebug("短按", 4); systemState.keyShortFlag = 0; } } else if (KEY_HIGH == pMsg->GPIOStatus) // 短按 { if (1 == systemState.powerOffFlag) // 等待长按事件 忽略此时的短按事件 { // 关机中 不处理 } else { systemState.keyShortFlag = 1; } } break; default: break; } // Free the space from the message. ICall_free(pMsg); } } #endif }
/********************************************************************* * @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 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(); } } } }