/********************************************************************* * @fn zdo_MTCB_MgmtBindRspCB() * * @brief * * Called to send MT callback response for Management Network * Discover response * * @param SrcAddr - Source address * @param Status - response status * * @return none */ void zdo_MTCB_MgmtBindRspCB( uint16 SrcAddr, byte Status, byte BindCount, byte StartIndex, byte BindListCount, apsBindingItem_t *pList ) { byte *msgPtr; byte *msg; byte len; byte x; uint8 protoVer = NLME_GetProtocolVersion(); /*Allocate a message of size equivalent to the corresponding SPI message (plus a couple of bytes for MT use)so that the same buffer can be sent by MT to the test tool by simply setting the header bytes.*/ /*In order to allocate the message , we need to know the length and this has to be calculated before we allocate the message*/ // One more byte for clusterID and DstAddrMode len = 2 + 1 + 1 + 1 + 1 + ( ( ZDP_BIND_DISCRIPTOR_SIZE + 1 + 1 ) * ZDO_MAX_BIND_ITEMS); // SrcAddr + Status + BindCount + StartIndex + BindListCount // + (maximum entries * size of struct) msgPtr = osal_mem_alloc( len ); if ( msgPtr ) { msg = msgPtr; //Fill up the data bytes *msg++ = HI_UINT16( SrcAddr ); *msg++ = LO_UINT16( SrcAddr ); *msg++ = Status; *msg++ = BindCount; *msg++ = StartIndex; *msg++ = BindListCount; osal_memset( msg, 0, ( ( ZDP_BIND_DISCRIPTOR_SIZE + 1 + 1) * ZDO_MAX_BIND_ITEMS) ); for ( x = 0; x < ZDO_MAX_BIND_ITEMS; x++ ) { if ( x < BindListCount ) { msg = zdo_MT_CopyRevExtAddr( msg, pList->srcAddr ); *msg++ = pList->srcEP; if ( protoVer == ZB_PROT_V1_0 ) { *msg++ = LO_UINT16( pList->clusterID); msg = zdo_MT_CopyRevExtAddr( msg, pList->dstAddr.addr.extAddr ); *msg++ = pList->dstEP; } else { *msg++ = HI_UINT16( pList->clusterID); *msg++ = LO_UINT16( pList->clusterID); *msg++ = pList->dstAddr.addrMode; if ( pList->dstAddr.addrMode == Addr64Bit ) { msg = zdo_MT_CopyRevExtAddr( msg, pList->dstAddr.addr.extAddr ); *msg++ = pList->dstEP; } else { *msg++ = HI_UINT16( pList->dstAddr.addr.shortAddr ); *msg++ = LO_UINT16( pList->dstAddr.addr.shortAddr ); // DstEndpoint will not present if DstAddrMode is not 64-bit extAddr } } pList++; } } MT_BuildAndSendZToolCB( SPI_CB_ZDO_MGMT_BIND_RSP, len, msgPtr ); osal_mem_free( msgPtr ); } }
/********************************************************************* * @fn Time_discCurrTime() * * @brief Current time service and characteristic discovery. * * @param state - Discovery state. * @param pMsg - GATT message. * * @return New discovery state. */ static uint8_t Time_discCurrTime(uint8_t state, gattMsgEvent_t *pMsg) { uint8_t newState = state; switch (state) { case DISC_CURR_TIME_START: { uint8_t uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(CURRENT_TIME_SERV_UUID), HI_UINT16(CURRENT_TIME_SERV_UUID) }; // Initialize service discovery variables Time_svcStartHdl = Time_svcEndHdl = 0; Time_endHdlIdx = 0; // Discover service by UUID GATT_DiscPrimaryServiceByUUID(Time_connHandle, uuid, ATT_BT_UUID_SIZE, ICall_getEntityId()); newState = DISC_CURR_TIME_SVC; } break; case DISC_CURR_TIME_SVC: // Service found, store handles if (pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->msg.findByTypeValueRsp.numInfo > 0) { Time_svcStartHdl = ATT_ATTR_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); Time_svcEndHdl = ATT_GRP_END_HANDLE(pMsg->msg.findByTypeValueRsp.pHandlesInfo, 0); } // If procedure complete if ((pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->hdr.status == bleProcedureComplete) || (pMsg->method == ATT_ERROR_RSP)) { // If service found if (Time_svcStartHdl != 0) { // Discover all characteristics GATT_DiscAllChars(Time_connHandle, Time_svcStartHdl, Time_svcEndHdl, ICall_getEntityId()); newState = DISC_CURR_TIME_CHAR; } else { // Service not found newState = DISC_FAILED; } } break; case DISC_CURR_TIME_CHAR: { // Characteristics found if (pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 && pMsg->msg.readByTypeRsp.len == CHAR_DESC_HDL_UUID16_LEN) { uint8_t i; uint8_t *p; uint16_t handle; uint16_t uuid; // For each characteristic declaration p = pMsg->msg.readByTypeRsp.pDataList; for (i = pMsg->msg.readByTypeRsp.numPairs; i > 0; i--) { // Parse characteristic declaration handle = BUILD_UINT16(p[3], p[4]); uuid = BUILD_UINT16(p[5], p[6]); // If looking for end handle if (Time_endHdlIdx != 0) { // End handle is one less than handle of characteristic // declaration. Time_handleCache[Time_endHdlIdx] = BUILD_UINT16(p[0], p[1]) - 1; Time_endHdlIdx = 0; } // If UUID is of interest, store handle switch (uuid) { case CURRENT_TIME_UUID: Time_handleCache[HDL_CURR_TIME_CT_TIME_START] = handle; Time_endHdlIdx = HDL_CURR_TIME_CT_TIME_END; break; default: break; } p += CHAR_DESC_HDL_UUID16_LEN; } } // If procedure complete if ((pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->hdr.status == bleProcedureComplete) || (pMsg->method == ATT_ERROR_RSP)) { // Special case of end handle at end of service if (Time_endHdlIdx != 0) { Time_handleCache[Time_endHdlIdx] = Time_svcEndHdl; Time_endHdlIdx = 0; } // If didn't find time characteristic if (Time_handleCache[HDL_CURR_TIME_CT_TIME_START] == 0) { newState = DISC_FAILED; } else if (Time_handleCache[HDL_CURR_TIME_CT_TIME_START] < Time_handleCache[HDL_CURR_TIME_CT_TIME_END]) { // Discover characteristic descriptors GATT_DiscAllCharDescs(Time_connHandle, Time_handleCache[HDL_CURR_TIME_CT_TIME_START] + 1, Time_handleCache[HDL_CURR_TIME_CT_TIME_END], ICall_getEntityId()); newState = DISC_CURR_TIME_CT_TIME_CCCD; } else { newState = DISC_IDLE; } } } break; case DISC_CURR_TIME_CT_TIME_CCCD: { // Characteristic descriptors found if (pMsg->method == ATT_FIND_INFO_RSP && pMsg->msg.findInfoRsp.numInfo > 0 && pMsg->msg.findInfoRsp.format == ATT_HANDLE_BT_UUID_TYPE) { uint8_t i; // For each handle/uuid pair for (i = 0; i < pMsg->msg.findInfoRsp.numInfo; i++) { // Look for CCCD if (ATT_BT_PAIR_UUID(pMsg->msg.findInfoRsp.pInfo, i) == GATT_CLIENT_CHAR_CFG_UUID) { // CCCD found Time_handleCache[HDL_CURR_TIME_CT_TIME_CCCD] = ATT_BT_PAIR_HANDLE(pMsg->msg.findInfoRsp.pInfo, i); break; } } } // If procedure complete if ((pMsg->method == ATT_FIND_INFO_RSP && pMsg->hdr.status == bleProcedureComplete) || (pMsg->method == ATT_ERROR_RSP)) { newState = DISC_IDLE; } } break; default: break; } return newState; }
'o', 'm', 'e', 't', 'e', 'r', 'S', 'e', 'n', 's', 'o', 'r', // connection interval range 0x05, // length of this data GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE, LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // Tx power level GAP_ADTYPE_POWER_LEVEL, 0 // 0dBm }; // Advertisement data. static uint8_t advertData[] = { // Flags; this sets the device to use limited discoverable // mode (advertises for 30 seconds at a time) instead of general // discoverable mode (advertises indefinitely).
* CONSTANTS */ #define SERVAPP_NUM_ATTR_SUPPORTED 5 /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // SK Service UUID: 0x1800 CONST uint8 skServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(SK_SERV_UUID), HI_UINT16(SK_SERV_UUID) }; // Key Pressed UUID: 0x1801 CONST uint8 keyPressedUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(SK_KEYPRESSED_UUID), HI_UINT16(SK_KEYPRESSED_UUID) }; /********************************************************************* * EXTERNAL VARIABLES */ /********************************************************************* * EXTERNAL FUNCTIONS */
* CONSTANTS */ #define SERVAPP_NUM_ATTR_SUPPORTED 25 /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // iBeacon Service UUID: CONST uint8 iBeaconServUUID[ATT_UUID_SIZE] = { UUID_BASE_TAIL, LO_UINT16(IBEACON_SERV_UUID), HI_UINT16(IBEACON_SERV_UUID), UUID_BASE_HEAD, }; // Characteristic 1 UUID: CONST uint8 iBeaconChar1UUID[ATT_UUID_SIZE] = { UUID_BASE_TAIL, LO_UINT16(IBEACON_CHAR1_UUID), HI_UINT16(IBEACON_CHAR1_UUID), UUID_BASE_HEAD, }; // Characteristic 2 UUID: CONST uint8 iBeaconChar2UUID[ATT_UUID_SIZE] = { UUID_BASE_TAIL,
/** * GATT Characteristic Descriptions */ #define GATT_DESC_LENGTH_UUID 0x3111 // Used with Unit percent /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // Battery service CONST uint8 battServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(BATT_SERV_UUID), HI_UINT16(BATT_SERV_UUID) }; // Battery level characteristic CONST uint8 battLevelUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(BATT_LEVEL_UUID), HI_UINT16(BATT_LEVEL_UUID) }; /********************************************************************* * EXTERNAL VARIABLES */ /********************************************************************* * EXTERNAL FUNCTIONS */
/********************************************************************* * @fn zclDiagnostic_ReadWriteAttrCB * * @brief Handle Diagnostics attributes. * * @param clusterId - cluster that attribute belongs to * @param attrId - attribute to be read or written * @param oper - ZCL_OPER_LEN, ZCL_OPER_READ, or ZCL_OPER_WRITE * @param pValue - pointer to attribute value, OTA endian * @param pLen - length of attribute value read, native endian * * @return status */ ZStatus_t zclDiagnostic_ReadWriteAttrCB( uint16 clusterId, uint16 attrId, uint8 oper, uint8 *pValue, uint16 *pLen ) { ZStatus_t status = ZSuccess; uint16 tempAttr; uint32 attrValue; afIncomingMSGPacket_t *origPkt; origPkt = zcl_getRawAFMsg(); switch ( oper ) { case ZCL_OPER_LEN: if ( ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_LQI ) || ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_RSSI ) ) { *pLen = 1; } else if ( attrId == ATTRID_DIAGNOSTIC_AVERAGE_MAC_RETRY_PER_APS_MESSAGE_SENT ) { *pLen = 2; } // The next function call only returns the length for attributes that are defined // in lower layers else if ( zclDiagnostic_GetAttribData( attrId, &tempAttr, pLen ) != ZSuccess ) { *pLen = 0; status = ZFailure; // invalid length } break; case ZCL_OPER_READ: // Identify if incoming msg is LQI or RSSI attribute // and return the LQI and RSSI of the incoming values if ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_LQI ) { *pLen = 1; attrValue = origPkt->LinkQuality; } else if ( attrId == ATTRID_DIAGNOSTIC_LAST_MESSAGE_RSSI ) { //origPkt = zcl_getRawAFMsg(); *pLen = 1; attrValue = origPkt->rssi; } else if ( zclDiagnostic_GetStatsAttr( attrId, &attrValue, pLen ) == ZSuccess ) { if ( ( attrId == ATTRID_DIAGNOSTIC_MAC_TX_UCAST_RETRY ) || ( attrId == ATTRID_DIAGNOSTIC_MAC_TX_UCAST_FAIL ) ) { // The lower layer counter is a 32 bit counter, report the higher 16 bit value // util the lower layer counter wraps-up if ( attrValue > 0x0000FFFF ) { attrValue = 0x0000FFFF; } } } else { *pLen = 0; status = ZFailure; // invalid attribute } if ( *pLen == 1 ) { pValue[0] = BREAK_UINT32( attrValue, 0 ); } else if ( *pLen == 2 ) { pValue[0] = LO_UINT16( attrValue ); pValue[1] = HI_UINT16( attrValue ); } else if ( *pLen == 4 ) { pValue[0] = BREAK_UINT32( attrValue, 0 ); pValue[1] = BREAK_UINT32( attrValue, 1 ); pValue[2] = BREAK_UINT32( attrValue, 2 ); pValue[3] = BREAK_UINT32( attrValue, 3 ); } break; case ZCL_OPER_WRITE: status = ZFailure; // All attributes in Diagnostics cluster are READ ONLY break; } return ( status ); }
' ', 'A', 'p', 'p' }; static uint8 timeAppAdvData[] = { // flags 0x02, GAP_ADTYPE_FLAGS, GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, // service solicitation 0x0D, GAP_ADTYPE_SERVICES_LIST_16BIT, LO_UINT16(CURRENT_TIME_SERV_UUID), HI_UINT16(CURRENT_TIME_SERV_UUID), LO_UINT16(REF_TIME_UPDATE_SERV_UUID), HI_UINT16(REF_TIME_UPDATE_SERV_UUID), LO_UINT16(NEXT_DST_CHANGE_SERV_UUID), HI_UINT16(NEXT_DST_CHANGE_SERV_UUID), LO_UINT16(NWA_SERV_UUID), HI_UINT16(NWA_SERV_UUID), LO_UINT16(ALERT_NOTIF_SERV_UUID), HI_UINT16(ALERT_NOTIF_SERV_UUID), LO_UINT16(BATT_SERV_UUID), HI_UINT16(BATT_SERV_UUID) }; // Device name attribute value static uint8 timeAppDeviceName[GAP_DEVICE_NAME_LEN] = "Time App";
/********************************************************************* * @fn timeAppConfigNext() * * @brief Perform the characteristic configuration read or * write procedure. * * @param state - Configuration state. * * @return New configuration state. */ uint8 timeAppConfigNext( uint8 state ) { attReadReq_t readReq; attWriteReq_t writeReq; bool read; static uint8 alertNtfCtrlCmd; // Find next non-zero cached handle of interest while ( state < TIMEAPP_CONFIG_MAX && timeAppHdlCache[timeAppConfigList[state]] == 0 ) { state++; } // Return if reached end of list if ( state == TIMEAPP_CONFIG_MAX ) { return TIMEAPP_CONFIG_CMPL; } // Determine what to do with characteristic switch ( timeAppConfigList[state] ) { // Read these characteristics case HDL_CURR_TIME_LOC_INFO: case HDL_CURR_TIME_REF_INFO: case HDL_DST_CHG_TIME_DST: case HDL_NWA_NWA_START: case HDL_CURR_TIME_CT_TIME_START: case HDL_ALERT_NTF_NEW_CAT: case HDL_ALERT_NTF_UNREAD_CAT: case HDL_PAS_ALERT_START: case HDL_PAS_RINGER_START: case HDL_REF_TIME_UPD_STATE: read = TRUE; break; // Set notification for these characteristics case HDL_CURR_TIME_CT_TIME_CCCD: case HDL_ALERT_NTF_UNREAD_CCCD: case HDL_ALERT_NTF_NEW_CCCD: case HDL_BATT_LEVEL_CCCD: case HDL_PAS_ALERT_CCCD: case HDL_PAS_RINGER_CCCD: read = FALSE; writeReq.len = 2; writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_NOTIFY); writeReq.sig = 0; writeReq.cmd = 0; break; // Set indication for these characteristics case HDL_NWA_NWA_CCCD: read = FALSE; writeReq.len = 2; writeReq.value[0] = LO_UINT16(GATT_CLIENT_CFG_INDICATE); writeReq.value[1] = HI_UINT16(GATT_CLIENT_CFG_INDICATE); writeReq.sig = 0; writeReq.cmd = 0; break; // Alert notification control point case HDL_ALERT_NTF_CTRL: // initialize control point command if (state == TIMEAPP_ALERT_NTF_CTRL_START) { alertNtfCtrlCmd = ALERT_NOTIF_ENABLE_NEW; } read = FALSE; writeReq.len = 2; writeReq.value[0] = alertNtfCtrlCmd; writeReq.value[1] = ALERT_NOTIF_CAT_ALL; writeReq.sig = 0; writeReq.cmd = 0; // set next command to send if (alertNtfCtrlCmd == ALERT_NOTIF_ENABLE_NEW) { alertNtfCtrlCmd = ALERT_NOTIF_NOTIFY_NEW; } else if (alertNtfCtrlCmd == ALERT_NOTIF_NOTIFY_NEW) { alertNtfCtrlCmd = ALERT_NOTIF_ENABLE_UNREAD; } else if (alertNtfCtrlCmd == ALERT_NOTIF_ENABLE_UNREAD) { alertNtfCtrlCmd = ALERT_NOTIF_NOTIFY_UNREAD; } break; default: break; } // Do a GATT read or write if ( read ) { readReq.handle = timeAppHdlCache[timeAppConfigList[state]]; GATT_ReadCharValue( timeAppConnHandle, &readReq, timeAppTaskId ); } else { writeReq.handle = timeAppHdlCache[timeAppConfigList[state]]; GATT_WriteCharValue( timeAppConnHandle, &writeReq, timeAppTaskId ); } return state; }
#define PP_DEFAULT_PATH_LOSS 0x7F #define SERVAPP_NUM_ATTR_SUPPORTED 5 /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // Link Loss Service UUID CONST uint8 linkLossServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16( LINK_LOSS_SERV_UUID ), HI_UINT16( LINK_LOSS_SERV_UUID ) }; // Immediate Alert Service UUID CONST uint8 imAlertServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16( IMMEDIATE_ALERT_SERV_UUID ), HI_UINT16( IMMEDIATE_ALERT_SERV_UUID ) }; // Tx Power Level Service UUID CONST uint8 txPwrLevelServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16( TX_PWR_LEVEL_SERV_UUID ), HI_UINT16( TX_PWR_LEVEL_SERV_UUID ) }; // Alert Level Attribute UUID
/********************************************************************* * @fn TimeAppDiscCurrTime() * * @brief Current time service and characteristic discovery. * * @param state - Discovery state. * @param pMsg - GATT message. * * @return New discovery state. */ static uint8 TimeAppDiscCurrTime( uint8 state, gattMsgEvent_t *pMsg ) { uint8 newState = state; switch ( state ) { case DISC_CURR_TIME_START: { uint8 uuid[ATT_BT_UUID_SIZE] = { LO_UINT16(CURRENT_TIME_SVC_UUID), HI_UINT16(CURRENT_TIME_SVC_UUID) }; // Initialize service discovery variables timeAppSvcStartHdl = timeAppSvcEndHdl = 0; timeAppEndHdlIdx = 0; // Discover service by UUID GATT_DiscPrimaryServiceByUUID( gapConnHandle, uuid, ATT_BT_UUID_SIZE, bloodPressureTaskId ); newState = DISC_CURR_TIME_SVC; } break; case DISC_CURR_TIME_SVC: // Service found, store handles if ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->msg.findByTypeValueRsp.numInfo > 0 ) { timeAppSvcStartHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].handle; timeAppSvcEndHdl = pMsg->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle; } // If procedure complete if ( ( pMsg->method == ATT_FIND_BY_TYPE_VALUE_RSP && pMsg->hdr.status == bleProcedureComplete ) || ( pMsg->method == ATT_ERROR_RSP ) ) { // If service found if ( timeAppSvcStartHdl != 0 ) { // Discover all characteristics GATT_DiscAllChars( gapConnHandle, timeAppSvcStartHdl, timeAppSvcEndHdl, bloodPressureTaskId ); newState = DISC_CURR_TIME_CHAR; } else { // Service not found newState = DISC_FAILED; } } break; case DISC_CURR_TIME_CHAR: { // Characteristics found if ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->msg.readByTypeRsp.numPairs > 0 && pMsg->msg.readByTypeRsp.len == CHAR_DESC_HDL_UUID16_LEN) { uint8 i; uint8 *p; uint16 handle; uint16 uuid; // For each characteristic declaration p = pMsg->msg.readByTypeRsp.dataList; for ( i = pMsg->msg.readByTypeRsp.numPairs; i > 0; i-- ) { // Parse characteristic declaration handle = BUILD_UINT16(p[3], p[4]); uuid = BUILD_UINT16(p[5], p[6]); // If looking for end handle if ( timeAppEndHdlIdx != 0 ) { // End handle is one less than handle of characteristic declaration timeAppHdlCache[timeAppEndHdlIdx] = BUILD_UINT16(p[0], p[1]) - 1; timeAppEndHdlIdx = 0; } // If UUID is of interest, store handle switch ( uuid ) { case CT_TIME_UUID: timeAppHdlCache[HDL_CURR_TIME_CT_TIME_START] = handle; timeAppEndHdlIdx = HDL_CURR_TIME_CT_TIME_END; break; default: break; } p += CHAR_DESC_HDL_UUID16_LEN; } } // If procedure complete if ( ( pMsg->method == ATT_READ_BY_TYPE_RSP && pMsg->hdr.status == bleProcedureComplete ) || ( pMsg->method == ATT_ERROR_RSP ) ) { // Special case of end handle at end of service if ( timeAppEndHdlIdx != 0 ) { timeAppHdlCache[timeAppEndHdlIdx] = timeAppSvcEndHdl; timeAppEndHdlIdx = 0; } // If didn't find time characteristic if ( timeAppHdlCache[HDL_CURR_TIME_CT_TIME_START] == 0 ) { newState = DISC_FAILED; } else if ( timeAppHdlCache[HDL_CURR_TIME_CT_TIME_START] <timeAppHdlCache[HDL_CURR_TIME_CT_TIME_END] ) { // Discover characteristic descriptors GATT_DiscAllCharDescs( gapConnHandle, timeAppHdlCache[HDL_CURR_TIME_CT_TIME_START] + 1, timeAppHdlCache[HDL_CURR_TIME_CT_TIME_END], bloodPressureTaskId ); newState = DISC_CURR_TIME_CT_TIME_CCCD; } else { newState = DISC_IDLE; } } } break; case DISC_CURR_TIME_CT_TIME_CCCD: { // Characteristic descriptors found if ( pMsg->method == ATT_FIND_INFO_RSP && pMsg->msg.findInfoRsp.numInfo > 0 && pMsg->msg.findInfoRsp.format == ATT_HANDLE_BT_UUID_TYPE ) { uint8 i; // For each handle/uuid pair for ( i = 0; i < pMsg->msg.findInfoRsp.numInfo; i++ ) { // Look for CCCD if ( (pMsg->msg.findInfoRsp.info.btPair[i].uuid[0] == LO_UINT16(GATT_CLIENT_CHAR_CFG_UUID)) && (pMsg->msg.findInfoRsp.info.btPair[i].uuid[1] == HI_UINT16(GATT_CLIENT_CHAR_CFG_UUID)) ) { // CCCD found timeAppHdlCache[HDL_CURR_TIME_CT_TIME_CCCD] = pMsg->msg.findInfoRsp.info.btPair[i].handle; break; } } } // If procedure complete if ( ( pMsg->method == ATT_FIND_INFO_RSP && pMsg->hdr.status == bleProcedureComplete ) || ( pMsg->method == ATT_ERROR_RSP ) ) { newState = DISC_IDLE; } } break; default: break; } return newState; }
/********************************************************************* * @fn zdo_MTCB_MgmtLqiRspCB() * * @brief * * Called to send MT callback response for Management LQI response * * @param type - binding type (end device, bind, unbind) * @param SrcAddr - Source address * @param Status - response status * * @return none */ void zdo_MTCB_MgmtLqiRspCB( uint16 SrcAddr, byte Status, byte NeighborLqiEntries, byte StartIndex, byte NeighborLqiCount, neighborLqiItem_t *pList ) { byte *msgPtr; byte *msg; byte len; byte x; byte proVer = NLME_GetProtocolVersion(); /*Allocate a message of size equivalent to the corresponding SPI message (plus a couple of bytes for MT use)so that the same buffer can be sent by MT to the test tool by simply setting the header bytes.*/ /*In order to allocate the message , we need to know the length and this has to be calculated before we allocate the message*/ len = 2 + 1 + 1 + 1 + 1 + (ZDP_NEIGHBORLQI_SIZE * ZDO_MAX_LQI_ITEMS ); // SrcAddr + Status + NeighborLqiEntries + StartIndex + NeighborLqiCount // + (maximum entries * size of struct) msgPtr = osal_mem_alloc( len ); if ( msgPtr ) { msg = msgPtr; //Fill up the data bytes *msg++ = HI_UINT16( SrcAddr ); *msg++ = LO_UINT16( SrcAddr ); *msg++ = Status; *msg++ = NeighborLqiEntries; *msg++ = StartIndex; *msg++ = NeighborLqiCount; osal_memset( msg, 0, (ZDP_NEIGHBORLQI_SIZE * ZDO_MAX_LQI_ITEMS) ); for ( x = 0; x < ZDO_MAX_LQI_ITEMS; x++ ) { if ( x < NeighborLqiCount ) { if ( proVer == ZB_PROT_V1_0 ) { *msg++ = HI_UINT16( pList->PANId ); *msg++ = LO_UINT16( pList->PANId ); } else { osal_cpyExtAddr(msg, pList->extPANId); msg += Z_EXTADDR_LEN; } *msg++ = HI_UINT16( pList->nwkAddr ); *msg++ = LO_UINT16( pList->nwkAddr ); *msg++ = pList->rxLqi; *msg++ = pList->txQuality; pList++; } } MT_BuildAndSendZToolCB( SPI_CB_ZDO_MGMT_LQI_RSP, len, msgPtr ); osal_mem_free( msgPtr ); } }
/********************************************************************* * @fn zdo_MTCB_SimpleDescRspCB() * * @brief * * Called by ZDO when a Simple_Desc_rsp message is received. * * @param SrcAddr - Source address * @param Status - response status * @param nwkAddr - 16 bit network address of device * @param EPIntf - Endpoint/Interface for description * @param pSimpleDesc - pointer to the devices Simple Descriptor * NULL if Status != ZDP_SUCCESS * * @return none */ void zdo_MTCB_SimpleDescRspCB( zAddrType_t *SrcAddr, byte Status, uint16 nwkAddr, byte EPIntf, SimpleDescriptionFormat_t *pSimpleDesc ) { byte *msgPtr; byte *msg; byte x; msgPtr = osal_mem_alloc( ZDO_SIMPLE_DESC_CB_LEN ); if ( msgPtr ) { msg = msgPtr; //Fill up the data bytes *msg++ = Status; *msg++ = HI_UINT16( SrcAddr->addr.shortAddr ); *msg++ = LO_UINT16( SrcAddr->addr.shortAddr ); *msg++ = HI_UINT16( nwkAddr ); *msg++ = LO_UINT16( nwkAddr ); *msg++ = EPIntf; *msg++ = HI_UINT16( pSimpleDesc->AppProfId ); *msg++ = LO_UINT16( pSimpleDesc->AppProfId ); *msg++ = HI_UINT16( pSimpleDesc->AppDeviceId ); *msg++ = LO_UINT16( pSimpleDesc->AppDeviceId ); *msg++ = pSimpleDesc->AppDevVer; *msg++ = pSimpleDesc->Reserved; *msg++ = pSimpleDesc->AppNumInClusters; // ZTool supports 16 bits the code has taken it into account for ( x = 0; x < 16; x++ ) { if ( x < pSimpleDesc->AppNumInClusters ) { *msg++ = HI_UINT16( pSimpleDesc->pAppInClusterList[x]); *msg++ = LO_UINT16( pSimpleDesc->pAppInClusterList[x]); } else { *msg++ = 0; *msg++ = 0; } } *msg++ = pSimpleDesc->AppNumOutClusters; for ( x = 0; x < 16; x++ ) { if ( x < pSimpleDesc->AppNumOutClusters ) { *msg++ = HI_UINT16( pSimpleDesc->pAppOutClusterList[x]); *msg++ = LO_UINT16( pSimpleDesc->pAppOutClusterList[x]); } else { *msg++ = 0; *msg++ = 0; } } MT_BuildAndSendZToolCB( SPI_CB_ZDO_SIMPLE_DESC_RSP, ZDO_SIMPLE_DESC_CB_LEN, msgPtr ); osal_mem_free( msgPtr ); } }
/********************************************************************* * @fn zdo_MTCB_NwkIEEEAddrRspCB * * @brief * * Called by ZDO when a NWK_addr_rsp message is received. * * @param SrcAddr - Source address * @param Status - response status * @param IEEEAddr - 64 bit IEEE address of device * @param nwkAddr - 16 bit network address of device * @param NumAssocDev - number of associated devices to reporting device * @param AssocDevList - array short addresses of associated devices * * @return none */ void zdo_MTCB_NwkIEEEAddrRspCB( uint16 type, zAddrType_t *SrcAddr, byte Status, byte *IEEEAddr, uint16 nwkAddr, byte NumAssocDev, byte StartIndex, uint16 *AssocDevList ) { byte *pBuf; byte *msg; byte len; byte x; /*Allocate a message of size equivalent to the corresponding SPI message (plus a couple of bytes for MT use)so that the same buffer can be sent by MT to the test tool by simply setting the header bytes.*/ /*In order to allocate the message , we need to know the length and this has to be calculated before we allocate the message*/ if ( type == SPI_CB_ZDO_NWK_ADDR_RSP ) { len = 1 + Z_EXTADDR_LEN + 1 + Z_EXTADDR_LEN + 2 + 1 + 1 + (2*8); // Addrmode + SrcAddr + Status + IEEEAddr + nwkAddr + NumAssocDev + StartIndex } else { len = 1 + Z_EXTADDR_LEN + 1 + Z_EXTADDR_LEN + 1 + 1 + (2*8); // Addrmode + SrcAddr + Status + IEEEAddr + NumAssocDev + StartIndex } pBuf = osal_mem_alloc( len ); if ( pBuf ) { msg = pBuf; //First fill in details if ( SrcAddr->addrMode == Addr16Bit ) { *msg++ = Addr16Bit; for ( x = 0; x < (Z_EXTADDR_LEN - 2); x++ ) *msg++ = 0; *msg++ = HI_UINT16( SrcAddr->addr.shortAddr ); *msg++ = LO_UINT16( SrcAddr->addr.shortAddr ); } else { *msg++ = Addr64Bit; msg = zdo_MT_CopyRevExtAddr( msg, SrcAddr->addr.extAddr ); } *msg++ = Status; msg = zdo_MT_CopyRevExtAddr( msg, IEEEAddr ); if ( type == SPI_CB_ZDO_NWK_ADDR_RSP ) { *msg++ = HI_UINT16( nwkAddr ); *msg++ = LO_UINT16( nwkAddr ); } *msg++ = NumAssocDev; *msg++ = StartIndex; byte cnt = NumAssocDev - StartIndex; for ( x = 0; x < 8; x++ ) { if ( x < cnt ) { *msg++ = HI_UINT16( *AssocDevList ); *msg++ = LO_UINT16( *AssocDevList ); AssocDevList++; } else { *msg++ = 0; *msg++ = 0; } } MT_BuildAndSendZToolCB( type, len, pBuf ); osal_mem_free( pBuf ); } }
/** \brief Processes the \ref GET_STATUS request (returns status for the specified recipient) * * The recipient bits in \ref USB_SETUP_HEADER.requestType specify the desired recipient. This is either the * (one and only) device, a specific interface, or a specific endpoint. Some of the status bits can be * changed with the SET_FEATURE and CLEAR_FEATURE requests. * * <b>Parameters</b>: * - VALUE: Always 0 * - INDEX: Depends upon the recipient: * - DEVICE: Always 0 * - INTERFACE: Interface number * - ENDPOINT: Endpoint address * - LENGTH: Always 2 * * <b>Data (IN)</b>: * Depends upon the recipient (the bit field illustrations are MSB first, LSB last): * - DEVICE: <tt>00000000.000000RS</tt>, where R(1) = DEVICE_REMOTE_WAKEUP and S(0) = SELF_POWERED * - INTERFACE: <tt>00000000.00000000</tt> (all bits are reserved) * - ENDPOINT: <tt>00000000.0000000H</tt>, where H(0) = ENDPOINT_HALT */ void usbsrGetStatus(void) { uint8 endpoint; static uint16 __xdata status; // Common sanity check if (usbSetupHeader.value || HI_UINT16(usbSetupHeader.index) || (usbSetupHeader.length != 2)) { usbfwData.ep0Status = EP_STALL; // Return status for device, interface, or endpoint } else { switch (usbSetupHeader.requestType) { // Device status: // Bit 0: Self powered // Bit 1: Remote wake-up allowed case RT_IN_DEVICE: // Sanity check if (LO_UINT16(usbSetupHeader.index)) { usbfwData.ep0Status = EP_STALL; // Get the bit values from the USBFW_DATA struct } else { // Self powered? status = usbfwData.selfPowered ? 0x0001 : 0x0000; // Remote wakeup? if (usbfwData.remoteWakeup) status |= 0x0002; } break; // Interface status: // All bits are reserved case RT_IN_INTERFACE: // Sanity check if (usbfwData.usbState != DEV_CONFIGURED) { usbfwData.ep0Status = EP_STALL; } else { status = 0x0000; } break; // Endpoint status: // Bit 0: Endpoint halted case RT_IN_ENDPOINT: endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F; // Sanity check if ((usbfwData.usbState != DEV_CONFIGURED) || (endpoint > 5)) { usbfwData.ep0Status = EP_STALL; // Translate endpoint address to status index and return the status } else { // IN if (LO_UINT16(usbSetupHeader.index) & 0x80) { status = (usbfwData.pEpInStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000; // OUT } else { status = (usbfwData.pEpOutStatus[endpoint - 1] == EP_HALT) ? 0x0001 : 0x0000; } } break; default: usbfwData.ep0Status = EP_STALL; break; } if (usbfwData.ep0Status != EP_STALL) { // Send it usbSetupData.pBuffer = (uint8 __generic *)&status; usbSetupData.bytesLeft = 2; usbfwData.ep0Status = EP_TX; } } } // usbsrGetStatus
'r', 'd' }; // Advertising data static uint8 advData[] = { // flags 0x02, // length of this data GAP_ADTYPE_FLAGS, GAP_ADTYPE_FLAGS_LIMITED | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, // appearance 0x03, // length of this data GAP_ADTYPE_APPEARANCE, LO_UINT16(GAP_APPEARE_HID_KEYBOARD), HI_UINT16(GAP_APPEARE_HID_KEYBOARD), // service UUIDs 0x05, // length of this data GAP_ADTYPE_16BIT_MORE, LO_UINT16(HID_SERV_UUID), HI_UINT16(HID_SERV_UUID), LO_UINT16(BATT_SERV_UUID), HI_UINT16(BATT_SERV_UUID) }; // Device name attribute value static CONST uint8 attDeviceName[GAP_DEVICE_NAME_LEN] = "HID Keyboard"; // HID Dev configuration
*/ // Position of heart rate measurement value in attribute array #define HEARTRATE_MEAS_VALUE_POS 2 /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // Heart rate service CONST uint8 heartRateServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(HEARTRATE_SERV_UUID), HI_UINT16(HEARTRATE_SERV_UUID) }; // Heart rate measurement characteristic CONST uint8 heartRateMeasUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(HEARTRATE_MEAS_UUID), HI_UINT16(HEARTRATE_MEAS_UUID) }; // Sensor location characteristic CONST uint8 heartRateSensLocUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(BODY_SENSOR_LOC_UUID), HI_UINT16(BODY_SENSOR_LOC_UUID) }; // Command characteristic
/********************************************************************* * CONSTANTS */ /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // Device information service CONST uint8 devInfoServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(DEVINFO_SERV_UUID), HI_UINT16(DEVINFO_SERV_UUID) }; // System ID CONST uint8 devInfoSystemIdUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(SYSTEM_ID_UUID), HI_UINT16(SYSTEM_ID_UUID) }; // Model Number String CONST uint8 devInfoModelNumberUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(MODEL_NUMBER_UUID), HI_UINT16(MODEL_NUMBER_UUID) }; // Serial Number String
'e', 'P', 'r', 'o', 'p', 'B', 'e', 'a', 'c', 'o', 'n', // connection interval range 0x05, // length of this data GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE, LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), }; // GAP GATT Attributes static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Prop"; // Globals used for ATT Response retransmission static gattMsgEvent_t *pAttRsp = NULL; static uint8_t rspTxRetry = 0; /********************************************************************* * LOCAL FUNCTIONS
/*************************************************************************************************** * @fn MT_UtilGetDeviceInfo * * @brief The Get Device Info serial message. * * @param None. * * @return void ***************************************************************************************************/ void MT_UtilGetDeviceInfo(void) { uint8 *buf; uint8 *pBuf; uint8 bufLen = MT_UTIL_DEVICE_INFO_RESPONSE_LEN; uint16 *assocList = NULL; #if !defined NONWK uint8 assocCnt = 0; if (ZG_DEVICE_RTR_TYPE) { assocList = AssocMakeList( &assocCnt ); bufLen += (assocCnt * sizeof(uint16)); } #endif buf = osal_mem_alloc( bufLen ); if ( buf ) { pBuf = buf; *pBuf++ = ZSUCCESS; // Status osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf ); pBuf += Z_EXTADDR_LEN; #if defined NONWK // Skip past ZStack only parameters for NONWK *pBuf++ = 0; *pBuf++ = 0; *pBuf++ = 0; *pBuf++ = 0; *pBuf = 0; #else { uint16 shortAddr = NLME_GetShortAddr(); *pBuf++ = LO_UINT16( shortAddr ); *pBuf++ = HI_UINT16( shortAddr ); } /* Return device type */ *pBuf++ = ZSTACK_DEVICE_BUILD; /*Return device state */ *pBuf++ = (uint8)devState; if (ZG_DEVICE_RTR_TYPE) { *pBuf++ = assocCnt; if ( assocCnt ) { uint8 x; uint16 *puint16 = assocList; for ( x = 0; x < assocCnt; x++, puint16++ ) { *pBuf++ = LO_UINT16( *puint16 ); *pBuf++ = HI_UINT16( *puint16 ); } } } else { *pBuf++ = 0; } #endif MT_BuildAndSendZToolResponse( ((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_GET_DEVICE_INFO, bufLen, buf ); osal_mem_free( buf ); } if ( assocList ) { osal_mem_free( assocList ); } }
*/ // Position of heart rate measurement value in attribute array #define HEARTRATE_MEAS_VALUE_POS 2 /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // Heart rate service CONST uint8 heartRateServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(HEARTRATE_SERV_UUID), HI_UINT16(HEARTRATE_SERV_UUID) }; // Heart rate measurement characteristic CONST uint8 heartRateMeasUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(HEARTRATE_MEAS_UUID), HI_UINT16(HEARTRATE_MEAS_UUID) }; // Sensor location characteristic CONST uint8 heartRateSensLocUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(HEARTRATE_SENS_LOC_UUID), HI_UINT16(HEARTRATE_SENS_LOC_UUID) }; // Command characteristic
/*************************************************************************************************** * @fn MT_UtilGetNvInfo * * @brief The Get NV Info serial message. * * @param None. * * @return void ***************************************************************************************************/ void MT_UtilGetNvInfo(void) { uint8 len; uint8 stat; uint8 *buf; uint8 *pBuf; uint16 tmp16; uint32 tmp32; /* Get required length of buffer Status + ExtAddr + ChanList + PanID + SecLevel + PreCfgKey */ len = 1 + Z_EXTADDR_LEN + 4 + 2 + 1 + SEC_KEY_LEN; buf = osal_mem_alloc( len ); if ( buf ) { /* Assume NV not available */ osal_memset( buf, 0xFF, len ); /* Skip over status */ pBuf = buf + 1; /* Start with 64-bit extended address */ stat = osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf ); if ( stat ) stat = 0x01; pBuf += Z_EXTADDR_LEN; /* Scan channel list (bit mask) */ if ( osal_nv_read( ZCD_NV_CHANLIST, 0, sizeof( tmp32 ), &tmp32 ) ) stat |= 0x02; else { pBuf[0] = BREAK_UINT32( tmp32, 3 ); pBuf[1] = BREAK_UINT32( tmp32, 2 ); pBuf[2] = BREAK_UINT32( tmp32, 1 ); pBuf[3] = BREAK_UINT32( tmp32, 0 ); } pBuf += sizeof( tmp32 ); /* ZigBee PanID */ if ( osal_nv_read( ZCD_NV_PANID, 0, sizeof( tmp16 ), &tmp16 ) ) stat |= 0x04; else { pBuf[0] = LO_UINT16( tmp16 ); pBuf[1] = HI_UINT16( tmp16 ); } pBuf += sizeof( tmp16 ); /* Security level */ if ( osal_nv_read( ZCD_NV_SECURITY_LEVEL, 0, sizeof( uint8 ), pBuf++ ) ) stat |= 0x08; /* Pre-configured security key */ if ( osal_nv_read( ZCD_NV_PRECFGKEY, 0, SEC_KEY_LEN, pBuf ) ) stat |= 0x10; /* Status bit mask - bit=1 indicates failure */ *buf = stat; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_GET_NV_INFO, len, buf ); osal_mem_free( buf ); } }
'n', 's', 'o', 'r' }; static uint8 advertData[] = { // flags 0x02, GAP_ADTYPE_FLAGS, GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED, // service UUIDs 0x05, GAP_ADTYPE_16BIT_MORE, LO_UINT16(HEARTRATE_SERV_UUID), HI_UINT16(HEARTRATE_SERV_UUID), LO_UINT16(BATT_SERV_UUID), HI_UINT16(BATT_SERV_UUID) }; // Device name attribute value static uint8 attDeviceName[GAP_DEVICE_NAME_LEN] = "Heart Rate Sensor"; // GAP connection handle static uint16 gapConnHandle; // Components of heart rate measurement structure static uint8 heartRateBpm = BPM_DEFAULT; static uint16 heartRateEnergy = 0; static uint16 heartRateRrInterval1 = HEARTRATE_BPM_TO_RR(BPM_DEFAULT);
/****************************************************************************** * @fn modbus_insert_msg */ void modbus_insert_msg( uint8 *pBuf, uint8 len) { uint8 index = 0; afAddrType_t destAddr; destAddr.addrMode = afAddr16Bit; destAddr.addr.shortAddr = 0; destAddr.endPoint = 10; signalStrength_t* pSigStren; initCRC16(); // uint8 *pInsertBuf = osal_mem_alloc( modbusDataLength*2); if( firstAddr < 21) index = 45 - 2*firstAddr; else //index = (modbusStartAddr-20)*2 + 1; index = 3; for (uint8 i=0; i<modbusDataLength; i++) { if( i+modbusStartAddr == MODBUS_PANID) { pBuf[index++] = HI_UINT16( _NIB.nwkPanId); pBuf[index++] = LO_UINT16( _NIB.nwkPanId); } else if( i + modbusStartAddr == MODBUS_DEVICE_TYPE) { pBuf[index++] = ZERO; pBuf[index++] = zgDeviceLogicalType; } else if( i + modbusStartAddr == MODBUS_CHANNEL_LIST_HI) { pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 3); pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 2); } else if( i + modbusStartAddr == MODBUS_CHANNEL_LIST_LO) { pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 1); pBuf[index++] = BREAK_UINT32(zgDefaultChannelList, 0); } else if( i + modbusStartAddr == MODBUS_SOFTWARE_REV) { pBuf[index++] = ZERO; pBuf[index++] = ZIG_SOFTWARE_VER; } else if( (i + modbusStartAddr >= MODBUS_EXTENDED_ADDR_HI) && (i + modbusStartAddr <= MODBUS_EXTENDED_ADDR_LO)) { pBuf[index++] = ZERO; pBuf[index++] = aExtendedAddress[ i+modbusStartAddr-MODBUS_EXTENDED_ADDR_HI]; } else if( (i + modbusStartAddr >= MODBUS_SECURITY_KEY_START) && (i + modbusStartAddr <= MODBUS_SECURITY_KEY_END)) { pBuf[index++] = ZERO; pBuf[index++] = defaultKey[ i+modbusStartAddr-MODBUS_SECURITY_KEY_START]; } else if( i + modbusStartAddr == MODBUS_TSTAT_NUM) { pBuf[index++] = ZERO; pBuf[index++] = numSignalStren; } else if( (i + modbusStartAddr >= MODBUS_FIRST_TSTAT_ID) && ( i+ modbusStartAddr <= MODBUS_LAST_TSTAT_ID)) { if( i + modbusStartAddr == MODBUS_FIRST_TSTAT_ID) { pSigStren = pSignalStren; } else { pSigStren = pSignalStren; for( uint8 j=0; j<((i+modbusStartAddr)-MODBUS_FIRST_TSTAT_ID); j++) { if(pSigStren) pSigStren = pSigStren->next; } } pBuf[index++] = ZERO; if(pSigStren != NULL) { pBuf[index++] = pSigStren->modbus_id; } else pBuf[index++] = ZERO; } else if( (i + modbusStartAddr >= MODBUS_FIRST_SIG_STREN) && ( i+ modbusStartAddr <= MODBUS_LAST_SIG_STREN)) { if( i + modbusStartAddr == MODBUS_FIRST_SIG_STREN) { pSigStren = pSignalStren; } else { pSigStren = pSignalStren; for( uint8 j=0; j<((i+modbusStartAddr)-MODBUS_FIRST_SIG_STREN); j++) { if(pSigStren) pSigStren = pSigStren->next; } } pBuf[index++] = ZERO; if(pSigStren != NULL) { pBuf[index++] = pSigStren->rssi; } else pBuf[index++] = ZERO; } else { pBuf[index++] = ZERO; pBuf[index++] = ZERO; } } for( uint8 i=0; i<len-2; i++) CRC16_byte(pBuf[i]); pBuf[len-2] = CRChi; pBuf[len-1] = CRClo; AF_DataRequest( &destAddr, &temco_epDesc, TEMCO_CLUSTERID, len, pBuf, &temcoApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ); modbusStartAddr = 0; modbusDataLength = 0; }
/****************************************************************************** * @fn modbus_process_msg * * @brief Process modbus message * * @param uint8 - the pointer the buffer * uint8 - length * * @return none */ static void modbus_process_msg( uint8 *data_buffer, uint8 len) { uint8 num, tempByte; uint8 zero = 0; uint16 i; uint16 address; boatMonitor_t *pTempMonitor; UTCTime utcSecs; UTCTimeStruct utcTime; utcSecs = osal_getClock(); osal_ConvertUTCTime( &utcTime, utcSecs ); address = BUILD_UINT16( data_buffer[3], data_buffer[2]); if(( data_buffer[0] == modbus_id) || ( data_buffer[0] == 255)) { if(data_buffer[1] == MODBUS_SINGLE_WRITE) { HalUARTWrite( 0, data_buffer, len); if( address == MODBUS_ADDRESS) { modbus_id = data_buffer[5]; osal_nv_write( ZCD_NV_MODBUS_ID, 0, sizeof(modbus_id), &modbus_id); } if( address == MODBUS_BAUDRATE) { if((data_buffer[5] >=0) &&(data_buffer[5] <= 4)) { modbus_set_baudrate = data_buffer[5]; osal_nv_write( ZCD_NV_BAUDRATE, 0, sizeof(modbus_set_baudrate), &modbus_set_baudrate); restore_factory_setting(); } } } else if( data_buffer[1] == MODBUS_MULTI_WRITE) { if( address == MODBUS_SERIALNUMBER_LOWORD) { if(data_buffer[6] == 8) { for( uint8 k=0;k<4;k++) { ttt[k] = data_buffer[2*k+8]; osal_nv_write( ZCD_NV_SERIAL_NUM, 0, sizeof(ttt), ttt); } } } // write system UTC if( address == MODBUS_SYS_HOUR) { if( data_buffer[6] >= 12) modbus_setUtcTime( &data_buffer[7]); } } else if( data_buffer[1] == MODBUS_SINGLE_READ) { num = data_buffer[5]; uint8 *pBuf; uint8 index=0; pBuf = osal_mem_alloc(num*2+5); if( pBuf != NULL) { pBuf[index++] = data_buffer[0]; pBuf[index++] = data_buffer[1]; pBuf[index++] = num*2; //modbus_send_byte( data_buffer[0], CRC_NO); //modbus_send_byte( data_buffer[1], CRC_NO); //modbus_send_byte( num*2, CRC_NO); for( i = 0; i < num; i++) { if ( i + address <= MODBUS_SERIALNUMBER_LOWORD + 3) { //modbus_send_byte( zero, CRC_NO); pBuf[index++] = zero; pBuf[index++] = ttt[ i + address - MODBUS_SERIALNUMBER_LOWORD]; } else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_LO) { pBuf[index++] = zero; pBuf[index++] = ttt[4]; } else if( i + address == MODBUS_FIRMWARE_VERSION_NUMBER_HI) { pBuf[index++] = zero; pBuf[index++] = ttt[5]; } else if( i + address == MODBUS_ADDRESS) { pBuf[index++] = zero; pBuf[index++] = modbus_id; } else if( i + address == MODBUS_PRODUCT_ID) { pBuf[index++] = zero; pBuf[index++] = 210; } // System UTC Time else if( i + address == MODBUS_SYS_HOUR) { pBuf[index++] = zero; pBuf[index++] = utcTime.hour; } else if( i + address == MODBUS_SYS_MINUTES) { pBuf[index++] = zero; pBuf[index++] = utcTime.minutes; } else if( i + address == MODBUS_SYS_SECONDS) { pBuf[index++] = zero; pBuf[index++] = utcTime.seconds; } else if( i + address == MODBUS_SYS_MONTH) { tempByte = utcTime.month + 1; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_SYS_DAY) { tempByte = utcTime.day + 1; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_SYS_YEAR) { tempByte = HI_UINT16( utcTime.year); pBuf[index++] = tempByte; tempByte = LO_UINT16( utcTime.year); pBuf[index++] = tempByte; } /*else if( i + address == MODBUS_WATER_SWITCH) { if(leaveTimeCounter){ tempByte = water_switch; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_DETECT_POWER) { uint16 power_temp; if(leaveTimeCounter){ power_temp = (ad_power-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70; //leaveTimeCounter = 0; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_ID) { if(leaveTimeCounter){ tempByte = water_id; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_RSSI) { if(leaveTimeCounter){ tempByte = (uint8)water_rssi; } else tempByte = zero; pBuf[index++] = 255; pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_SWITCH1) { if(leaveTimeCounter1){ tempByte = water_switch1; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_DETECT_POWER1) { uint16 power_temp; if(leaveTimeCounter1){ power_temp = (ad_power1-196)*10/10.57+90;//(ad_power-186)*100/74+90;//((ad_power-644)*64)/100+70; //leaveTimeCounter = 0; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else if( i + address == MODBUS_WATER_ID1) { if(leaveTimeCounter1){ tempByte = water_id1; //leaveTimeCounter=0; } else tempByte = zero; pBuf[index++] = zero; pBuf[index++] = tempByte; }*/ else if( i + address == MODBUS_BAUDRATE) { tempByte = modbus_set_baudrate; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_PANID) { tempByte = HI_UINT16( _NIB.nwkPanId); pBuf[index++] = tempByte; tempByte = LO_UINT16( _NIB.nwkPanId); pBuf[index++] = tempByte; } else if( i + address == MODBUS_DEVICE_TYPE) { tempByte = zgDeviceLogicalType; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( i + address == MODBUS_CHANNEL_LIST_HI) { tempByte = BREAK_UINT32(zgDefaultChannelList, 3); pBuf[index++] = tempByte; tempByte = BREAK_UINT32(zgDefaultChannelList, 2); pBuf[index++] = tempByte; } else if( i + address == MODBUS_CHANNEL_LIST_LO) { tempByte = BREAK_UINT32(zgDefaultChannelList, 1); pBuf[index++] = tempByte; tempByte = BREAK_UINT32(zgDefaultChannelList, 0); pBuf[index++] = tempByte; } else if( (i + address >= MODBUS_EXTENDED_ADDR_HI) && (i + address <= MODBUS_EXTENDED_ADDR_LO)) { tempByte = aExtendedAddress[ i+address-MODBUS_EXTENDED_ADDR_HI]; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( (i + address >= MODBUS_SECURITY_KEY_START) && (i + address <= MODBUS_SECURITY_KEY_END)) { tempByte = defaultKey[ i+address-MODBUS_SECURITY_KEY_START]; pBuf[index++] = zero; pBuf[index++] = tempByte; } /*else if( i + address == MODBUS_DETECT_PIN1) { uint16 power_temp; if(leaveTimeCounter){ power_temp = detectPin1; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else if( i + address == MODBUS_DETECT_PIN2) { uint16 power_temp; if(leaveTimeCounter){ power_temp = detectPin2; //leaveTimeCounter=0; }else power_temp = 0; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; }*/ else if( i + address == MODBUS_MONITOR_NUM) { tempByte = numMonitor; pBuf[index++] = zero; pBuf[index++] = tempByte; } else if( (i + address >= MODBUS_FIRST_MONITOR_ID) && ( i+ address <= MODBUS_LAST_MONITOR_ID)) { if( i + address == MODBUS_FIRST_MONITOR_ID) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_MONITOR_ID); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } pBuf[index++]= zero; if(pTempMonitor != NULL) { pBuf[index++]= pTempMonitor->modbus_id; } else pBuf[index++]= zero; } else if( (i + address >= MODBUS_FIRST_DETECT_POWER) && ( i+ address <= MODBUS_LAST_DETECT_POWER)) { if( i + address == MODBUS_FIRST_DETECT_POWER) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_POWER); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor != NULL) { uint16 power_temp; power_temp = (pTempMonitor->ad_power-196)*10/10.57+90; tempByte = HI_UINT16( power_temp); pBuf[index++] = tempByte; tempByte = LO_UINT16( power_temp); pBuf[index++] = tempByte; } else { pBuf[index++]= zero; pBuf[index++]= zero; } } else if( (i + address >= MODBUS_FIRST_WATER_SWITCH) && ( i+ address <= MODBUS_LAST_WATER_SWITCH)) { if( i + address == MODBUS_FIRST_WATER_SWITCH) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_WATER_SWITCH); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } pBuf[index++]= zero; if(pTempMonitor != NULL) { pBuf[index++]= pTempMonitor->water_switch; } else pBuf[index++]= zero; } else if((i + address >= MODBUS_FIRST_DETECT_PIN1) && ( i+ address <= MODBUS_LAST_DETECT_PIN1)) { if( i + address == MODBUS_FIRST_DETECT_PIN1) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN1); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor != NULL) { tempByte = HI_UINT16( pTempMonitor->detectPin1); pBuf[index++] = tempByte; tempByte = LO_UINT16( pTempMonitor->detectPin1); pBuf[index++] = tempByte; } else { pBuf[index++]= zero; pBuf[index++]= zero; } } else if((i + address >= MODBUS_FIRST_DETECT_PIN2) && ( i+ address <= MODBUS_LAST_DETECT_PIN2)) { if( i + address == MODBUS_FIRST_DETECT_PIN2) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_DETECT_PIN2); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor != NULL) { tempByte = HI_UINT16( pTempMonitor->detectPin2); pBuf[index++] = tempByte; tempByte = LO_UINT16( pTempMonitor->detectPin2); pBuf[index++] = tempByte; } else { pBuf[index++]= zero; pBuf[index++]= zero; } } else if( (i + address >= MODBUS_FIRST_RSSI) && ( i+ address <= MODBUS_LAST_RSSI)) { if( i + address == MODBUS_FIRST_RSSI) { pTempMonitor = pBoatMonitor; } else { pTempMonitor = pBoatMonitor; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_RSSI); j++) { if(pTempMonitor) pTempMonitor = pTempMonitor->next; } } if(pTempMonitor->rssi>=0) pBuf[index++] = 0; else pBuf[index++]= 0xff; if(pTempMonitor != NULL) { pBuf[index++]= pTempMonitor->rssi; } else pBuf[index++]= zero; } else { pBuf[index++] = zero; pBuf[index++] = zero; } } for( i=0; i<num*2+3; i++) CRC16_byte(pBuf[i]); pBuf[num*2+3] = CRChi; pBuf[num*2+4] = CRClo; P1_0 = 1; send_str_Uart( pBuf, num*2+5, 0); P1_0 = 0; osal_mem_free(pBuf); } else{ send_str_Uart( pBuf, num*2+5, 0); } } } }
static void modbus_process_msg( uint8 *data_buffer, uint8 len) { uint8 num, tempByte; uint8 zero = 0; uint16 i; uint16 address; signalStrength_t* pSigStren; afAddrType_t destAddr; destAddr.addrMode = afAddrBroadcast; destAddr.addr.shortAddr = 0xffff; destAddr.endPoint = 10; address = BUILD_UINT16( data_buffer[3], data_buffer[2]); if( data_buffer[0] == modbus_id) { if(data_buffer[1] == MODBUS_SINGLE_WRITE) { HalUARTWrite( 0, data_buffer, len); if (address == MODBUS_DEVICE_TYPE) { zgDeviceLogicalType = data_buffer[5]; osal_nv_write( ZCD_NV_LOGICAL_TYPE, 0, sizeof(zgDeviceLogicalType), &zgDeviceLogicalType); restore_factory_setting(); } else if( address == MODBUS_FACTORY_RESTORE) { if( address == MODBUS_FACTORY_RESTORE) { if(data_buffer[5] == 1) { restore_factory_setting(); } } } } else if(data_buffer[1] == MODBUS_MULTI_WRITE) { } else if( data_buffer[1] == MODBUS_SINGLE_READ) { num = data_buffer[5]; modbus_send_byte( data_buffer[0], CRC_NO); modbus_send_byte( data_buffer[1], CRC_NO); modbus_send_byte( num*2, CRC_NO); for( i = 0; i < num; i++) { if( i + address == MODBUS_PANID) { tempByte = HI_UINT16( _NIB.nwkPanId); modbus_send_byte( tempByte, CRC_NO); tempByte = LO_UINT16( _NIB.nwkPanId); modbus_send_byte( tempByte, CRC_NO); } else if( i + address == MODBUS_DEVICE_TYPE) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( zgDeviceLogicalType, CRC_NO); } else if( i + address == MODBUS_CHANNEL_LIST_HI) { tempByte = HI_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); tempByte = LO_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); } else if( i + address == MODBUS_CHANNEL_LIST_LO) { tempByte = HI_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); tempByte = LO_UINT16(zgConfigPANID); modbus_send_byte( zero, CRC_NO); } else if( i + address == MODBUS_SOFTWARE_REV) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( zSoftwareRev, CRC_NO); } else if( (i + address >= MODBUS_EXTENDED_ADDR_HI) && (i + address <= MODBUS_EXTENDED_ADDR_LO)) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( aExtendedAddress[ i+modbusStartAddr-MODBUS_EXTENDED_ADDR_HI], CRC_NO); } else if( (i + address >= MODBUS_SECURITY_KEY_START) && (i + address <= MODBUS_SECURITY_KEY_END)) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( defaultKey[ i+modbusStartAddr-MODBUS_SECURITY_KEY_START], CRC_NO); } else if( i + address == MODBUS_TSTAT_NUM) { modbus_send_byte( zero, CRC_NO); modbus_send_byte( numSignalStren, CRC_NO); } else if( (i + address >= MODBUS_FIRST_TSTAT_ID) && ( i+ address <= MODBUS_LAST_TSTAT_ID)) { if( i + address == MODBUS_FIRST_TSTAT_ID) { pSigStren = pSignalStren; } else { pSigStren = pSignalStren; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_TSTAT_ID); j++) { if(pSigStren) pSigStren = pSigStren->next; } } modbus_send_byte( zero, CRC_NO); if(pSigStren != NULL) { modbus_send_byte( pSigStren->modbus_id, CRC_NO); } else modbus_send_byte( zero, CRC_NO); } else if( (i + address >= MODBUS_FIRST_SIG_STREN) && ( i+ address <= MODBUS_LAST_SIG_STREN)) { if( i + address == MODBUS_FIRST_SIG_STREN) { pSigStren = pSignalStren; } else { pSigStren = pSignalStren; for( uint8 j=0; j<((i+address)-MODBUS_FIRST_SIG_STREN); j++) { if(pSigStren) pSigStren = pSigStren->next; } } modbus_send_byte( zero, CRC_NO); if(pSigStren != NULL) { modbus_send_byte( pSigStren->rssi, CRC_NO); } else modbus_send_byte( zero, CRC_NO); } else { modbus_send_byte( 0, CRC_NO); modbus_send_byte( 1, CRC_NO); } } modbus_send_byte( CRChi, CRC_YES); modbus_send_byte( CRClo, CRC_YES); } } else { AF_DataRequest( &destAddr, &temco_epDesc, TEMCO_CLUSTERID, len, data_buffer, &temcoApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ); } }
#define BLOODPRESSURE_MEAS_VALUE_POS 2 #define BLOODPRESSURE_MEAS_CONFIG_POS 3 #define BLOODPRESSURE_IMEAS_VALUE_POS 5 #define BLOODPRESSURE_IMEAS_CONFIG_POS 6 /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ // BloodPressure service CONST uint8 bloodPressureServUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(BLOODPRESSURE_SERV_UUID), HI_UINT16(BLOODPRESSURE_SERV_UUID) }; // BloodPressure temperature characteristic CONST uint8 bloodPressureTempUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(BLOODPRESSURE_MEAS_UUID), HI_UINT16(BLOODPRESSURE_MEAS_UUID) }; // BloodPressure Intermediate Cuff Pressure CONST uint8 bloodPressureImeasUUID[ATT_BT_UUID_SIZE] = { LO_UINT16(IMEDIATE_CUFF_PRESSURE_UUID), HI_UINT16(IMEDIATE_CUFF_PRESSURE_UUID) }; // BloodPressure Feature
/** \brief Internal function used for the very similar \ref SET_FEATURE and \ref CLEAR_FEATURE requests * * This function either sets or clears the specified feature on the specified recipient. * * \param[in] set * When TRUE, the feature is set. When FALSE, the feature is cleared. * * \return * TRUE if the selected feature is supported by the USB library. FALSE to indicate that * \ref usbsrHookClearFeature() or \ref usbsrHookSetFeature() must be called. */ static uint8 ChangeFeature(uint8 set) { uint8 endpoint; // Sanity check if (usbSetupHeader.length || (usbfwData.usbState != DEV_CONFIGURED) && (usbSetupHeader.index != 0)) { usbfwData.ep0Status = EP_STALL; // Handle based on recipient } else { switch (usbSetupHeader.requestType & RT_MASK_RECIP) { // Device case RT_RECIP_DEV: // Sanity check if (LO_UINT16(usbSetupHeader.value) != DEVICE_REMOTE_WAKEUP) { return FALSE; } else { usbfwData.remoteWakeup = set; usbsrHookProcessEvent(set ? USBSR_EVENT_REMOTE_WAKEUP_ENABLED : USBSR_EVENT_REMOTE_WAKEUP_DISABLED, 0); } break; // Endpoint case RT_RECIP_IF: return FALSE; // Endpoint case RT_RECIP_EP: endpoint = LO_UINT16(usbSetupHeader.index) & 0x7F; // Sanity check if (LO_UINT16(usbSetupHeader.value) != ENDPOINT_HALT) { return FALSE; } else if (endpoint > 5) { usbfwData.ep0Status = EP_STALL; } else { USBFW_SELECT_ENDPOINT(endpoint); // IN if (LO_UINT16(usbSetupHeader.index) & 0x80) { USBCSIL = set ? USBCSIL_SEND_STALL : USBCSIL_CLR_DATA_TOG; usbfwData.pEpInStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE; usbsrHookProcessEvent(set ? USBSR_EVENT_EPIN_STALL_SET : USBSR_EVENT_EPIN_STALL_CLEARED, endpoint); // OUT } else { USBCSOL = set ? USBCSOL_SEND_STALL : USBCSOL_CLR_DATA_TOG; usbfwData.pEpOutStatus[endpoint - 1] = set ? EP_HALT : EP_IDLE; usbsrHookProcessEvent(set ? USBSR_EVENT_EPOUT_STALL_SET : USBSR_EVENT_EPOUT_STALL_CLEARED, endpoint); } USBFW_SELECT_ENDPOINT(0); } break; default: usbfwData.ep0Status = EP_STALL; break; } } return TRUE; } // ChangeFeature
/********************************************************************* * @fn Thermometer_handleKeys * * @brief Handles all key events for this device. * * @param shift - true if in shift/alt. * @param keys - bit field for key events. * * @return none */ static void Thermometer_handleKeys(uint8_t shift, uint8_t keys) { bStatus_t status; uint8_t notify_interval; if (keys & KEY_UP) { // Set simulated measurement flag index. thermometerFlagsIdx+=1; if (thermometerFlagsIdx == FLAGS_IDX_MAX) { thermometerFlagsIdx = 0; } } // Read stored interval value. Thermometer_GetParameter(THERMOMETER_INTERVAL, ¬ify_interval); if(notify_interval == 0) { thMeasTimerRunning = FALSE; } if (keys & KEY_RIGHT) { // If device is not in a connection, pressing the right key should toggle // advertising on and off. If timer is running, then will adv when meas is // ready. if((gapProfileState != GAPROLE_CONNECTED) && (thMeasTimerRunning == FALSE)) { uint8_t current_adv_enabled_status; uint8_t new_adv_enabled_status; // Find the current GAP advertisement status. GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, ¤t_adv_enabled_status); if(current_adv_enabled_status == FALSE) { new_adv_enabled_status = TRUE; } else { new_adv_enabled_status = FALSE; } // Change the GAP advertisement status to opposite of current status. GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &new_adv_enabled_status); } // Timer is running, so allow simulated changes. else { // Change temperature, remove single precision. if((thermometerCelcius) < 0x000175) { thermometerCelcius += 1; } else { uint16_t thInterval = 30; thermometerCelcius = 0x000173; // Simulate interval change. Thermometer_SetParameter(THERMOMETER_INTERVAL, THERMOMETER_INTERVAL_LEN, &thInterval); if(temperatureIntervalConfig == true) { attHandleValueInd_t intervalInd; intervalInd.pValue = GATT_bm_alloc(thermometer_connHandle, ATT_HANDLE_VALUE_IND, THERMOMETER_INTERVAL_LEN, NULL); if (intervalInd.pValue != NULL) { intervalInd.len = THERMOMETER_INTERVAL_LEN; intervalInd.pValue[0] = LO_UINT16(thInterval); intervalInd.pValue[1] = HI_UINT16(thInterval); intervalInd.handle = THERMOMETER_INTERVAL_VALUE_POS; status = Thermometer_IntervalIndicate(thermometer_connHandle, &intervalInd, ICall_getEntityId()); // We can fail if there was pending meas or not connected. if (status != SUCCESS) { // Queue indication. Thermometer_storeIndications(&intervalInd); } } } } } } }
/********************************************************************* * @fn zdo_MTCB_MgmtNwkDiscRspCB() * * @brief * * Called to send MT callback response for Management Network * Discover response * * @param SrcAddr - Source address * @param Status - response status * * @return none */ void zdo_MTCB_MgmtNwkDiscRspCB( uint16 SrcAddr, byte Status, byte NetworkCount, byte StartIndex, byte networkListCount, mgmtNwkDiscItem_t *pList ) { byte *msgPtr; byte *msg; byte len; byte x; byte proVer = NLME_GetProtocolVersion(); /*Allocate a message of size equivalent to the corresponding SPI message (plus a couple of bytes for MT use)so that the same buffer can be sent by MT to the test tool by simply setting the header bytes.*/ /*In order to allocate the message , we need to know the length and this has to be calculated before we allocate the message*/ if ( proVer == ZB_PROT_V1_0 ) { len = 2 + 1 + 1 + 1 + 1 + (ZDP_NETWORK_DISCRIPTOR_SIZE * ZDO_MAX_NWKDISC_ITEMS); // SrcAddr + Status + NetworkCount + StartIndex + networkListCount // + (maximum entries * size of struct) } else { len = 2 + 1 + 1 + 1 + 1 + (ZDP_NETWORK_EXTENDED_DISCRIPTOR_SIZE * ZDO_MAX_NWKDISC_ITEMS); } msgPtr = osal_mem_alloc( len ); if ( msgPtr ) { msg = msgPtr; //Fill up the data bytes *msg++ = HI_UINT16( SrcAddr ); *msg++ = LO_UINT16( SrcAddr ); *msg++ = Status; *msg++ = NetworkCount; *msg++ = StartIndex; *msg++ = networkListCount; osal_memset( msg, 0, (ZDP_NETWORK_DISCRIPTOR_SIZE * ZDO_MAX_NWKDISC_ITEMS) ); for ( x = 0; x < ZDO_MAX_NWKDISC_ITEMS; x++ ) { if ( x < networkListCount ) { if ( proVer == ZB_PROT_V1_0 ) { *msg++ = HI_UINT16( pList->PANId ); *msg++ = LO_UINT16( pList->PANId ); } else { osal_cpyExtAddr( msg, pList->extendedPANID ); msg += Z_EXTADDR_LEN; } *msg++ = pList->logicalChannel; *msg++ = pList->stackProfile; *msg++ = pList->version; *msg++ = pList->beaconOrder; *msg++ = pList->superFrameOrder; *msg++ = pList->permitJoining; pList++; } } MT_BuildAndSendZToolCB( SPI_CB_ZDO_MGMT_NWKDISC_RSP, len, msgPtr ); osal_mem_free( msgPtr ); } }