/********************************************************************* * @fn OADTarget_rejectImage * * @brief Reject the Image identified by the OAD manager, send back * active image version, length and UID to manager. * * @param connHandle - connection message was received on. * @param pImgHdr - pointer to the img_hdr_t data to send. * * @return None. */ static void OADTarget_rejectImage(uint16_t connHandle, img_hdr_t *pImgHdr) { uint16_t value = GATTServApp_ReadCharCfg(connHandle, oadImgIdentifyConfig); // If notifications enabled if (value & GATT_CLIENT_CFG_NOTIFY) { attHandleValueNoti_t noti; noti.pValue = GATT_bm_alloc(connHandle, ATT_HANDLE_VALUE_NOTI, 8, NULL); if (noti.pValue != NULL) { gattAttribute_t *pAttr = GATTServApp_FindAttr(oadAttrTbl, GATT_NUM_ATTRS(oadAttrTbl), oadCharVals+OAD_CHAR_IMG_IDENTIFY); noti.handle = pAttr->handle; noti.len = OAD_IMG_HDR_SIZE; noti.pValue[0] = LO_UINT16(pImgHdr->ver); noti.pValue[1] = HI_UINT16(pImgHdr->ver); noti.pValue[2] = LO_UINT16(pImgHdr->len); noti.pValue[3] = HI_UINT16(pImgHdr->len); (void)memcpy(noti.pValue+4, pImgHdr->uid, sizeof(pImgHdr->uid)); if (GATT_Notification(connHandle, ¬i, FALSE) != SUCCESS) { GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI); } } } }
/********************************************************************* * @fn OADTarget_getNextBlockReq * * @brief Process the Request for next image block. * * @param connHandle - connection message was received on * @param blkNum - block number to request from OAD Manager. * * @return None */ static void OADTarget_getNextBlockReq(uint16_t connHandle, uint16_t blkNum) { uint16_t value = GATTServApp_ReadCharCfg(connHandle, oadImgBlockConfig); // If notifications enabled if (value & GATT_CLIENT_CFG_NOTIFY) { attHandleValueNoti_t noti; noti.pValue = GATT_bm_alloc(connHandle, ATT_HANDLE_VALUE_NOTI, 2, NULL); if (noti.pValue != NULL) { gattAttribute_t *pAttr = GATTServApp_FindAttr(oadAttrTbl, GATT_NUM_ATTRS(oadAttrTbl), oadCharVals+OAD_CHAR_IMG_BLOCK); noti.handle = pAttr->handle; noti.len = 2; noti.pValue[0] = LO_UINT16(blkNum); noti.pValue[1] = HI_UINT16(blkNum); if (GATT_Notification(connHandle, ¬i, FALSE) != SUCCESS) { GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI); } } } }
/********************************************************************* * @fn simpleProfile_ProcessCharCfg * * @brief Process Client Charateristic Configuration change. * * @param charCfgTbl - characteristic configuration table * @param pValue - pointer to attribute value * @param authenticated - whether an authenticated link is required * * @return none */ static void simpleProfile_ProcessCharCfg( gattCharCfg_t *charCfgTbl, uint8 *pValue, uint8 authenticated ) { for ( uint8 i = 0; i < GATT_MAX_NUM_CONN; i++ ) { gattCharCfg_t *pItem = &(charCfgTbl[i]); if ( ( pItem->connHandle != INVALID_CONNHANDLE ) && ( pItem->value != GATT_CFG_NO_OPERATION ) ) { gattAttribute_t *pAttr; // Find the characteristic value attribute pAttr = GATTServApp_FindAttr( simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ), pValue ); if ( pAttr != NULL ) { attHandleValueNoti_t noti; // If the attribute value is longer than (ATT_MTU - 3) octets, then // only the first (ATT_MTU - 3) octets of this attributes value can // be sent in a notification. if ( simpleProfile_ReadAttrCB( pItem->connHandle, pAttr, noti.value, ¬i.len, 0, (ATT_MTU_SIZE-3) ) == SUCCESS ) { noti.handle = pAttr->handle; if ( pItem->value & GATT_CLIENT_CFG_NOTIFY ) { VOID GATT_Notification( pItem->connHandle, ¬i, authenticated ); } } } } } // for }
/********************************************************************* * @fn battNotifyCB * * @brief Send a notification of the level state characteristic. * * @param connHandle - linkDB item * * @return None. */ static void battNotifyCB( linkDBItem_t *pLinkItem ) { if ( pLinkItem->stateFlags & LINK_CONNECTED ) { uint16 value = GATTServApp_ReadCharCfg( pLinkItem->connectionHandle, battLevelClientCharCfg ); if ( value & GATT_CLIENT_CFG_NOTIFY ) { attHandleValueNoti_t noti; noti.pValue = GATT_bm_alloc( pLinkItem->connectionHandle, ATT_HANDLE_VALUE_NOTI, BATT_LEVEL_VALUE_LEN, NULL ); if ( noti.pValue != NULL ) { noti.handle = battAttrTbl[BATT_LEVEL_VALUE_IDX].handle; noti.len = BATT_LEVEL_VALUE_LEN; noti.pValue[0] = battLevel; if ( GATT_Notification( pLinkItem->connectionHandle, ¬i, FALSE ) != SUCCESS ) { GATT_bm_free( (gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI ); } } } } }
/********************************************************************* * @fn performPeriodicTask * * @brief Perform a periodic application task. This function gets * called every five seconds as a result of the SBP_PERIODIC_EVT * OSAL event. In this example, the value of the third * characteristic in the SimpleGATTProfile service is retrieved * from the profile, and then copied into the value of the * the fourth characteristic. * * @param none * * @return none */ static void performPeriodicTask( void ) { uint8 valueToCopy; uint8 stat; static attHandleValueNoti_t pReport; pReport.len = 2; pReport.handle = 0x2E; osal_memcpy(pReport.value, "ab", 2); GATT_Notification( 0, &pReport, FALSE ); // Call to retrieve the value of the third characteristic in the profile stat = SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &valueToCopy); if( stat == SUCCESS ) { /* * Call to set that value of the fourth characteristic in the profile. Note * that if notifications of the fourth characteristic have been enabled by * a GATT client device, then a notification will be sent every time this * function is called. */ SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy); } }
/********************************************************************* * @fn ScanParam_RefreshNotify * * @brief Notify the peer to refresh the scan parameters. * * @param connHandle - connection handle * * @return None */ void ScanParam_RefreshNotify( uint16 connHandle ) { uint16 value; value = GATTServApp_ReadCharCfg( connHandle, scanParamRefreshClientCharCfg ); if ( value & GATT_CLIENT_CFG_NOTIFY ) { attHandleValueNoti_t noti; noti.pValue = GATT_bm_alloc( connHandle, ATT_HANDLE_VALUE_NOTI, SCAN_PARAM_REFRESH_LEN, NULL ); if (noti.pValue != NULL) { // send notification noti.handle = scanParamAttrTbl[SCAN_PARAM_REFRESH_CCCD_IDX].handle; noti.len = SCAN_PARAM_REFRESH_LEN; noti.pValue[0] = SCAN_PARAM_REFRESH_REQ; if ( GATT_Notification( connHandle, ¬i, FALSE ) != SUCCESS ) { GATT_bm_free( (gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI ); } } } }
void sbpSerialAppSendNoti(uint8 *pBuffer,uint16 length) { static attHandleValueNoti_t pReport; pReport.len = length; osal_memcpy(pReport.value, pBuffer, length); GATT_Notification( 0, &pReport, FALSE ); }
bStatus_t HeartRate_FallNotify(uint16 connHandle, attHandleValueNoti_t *pNoti) { // Set the handle. pNoti->handle = heartRateAttrTbl[HEARTRATE_FALL_VALUE_POS].handle; // Send the notification. return GATT_Notification(connHandle, pNoti, FALSE); }
void ECG_Notify(uint16 connHandle, uint8 *ptr) { attHandleValueNoti_t ecgNotify; uint16 value = GATTServApp_ReadCharCfg(connHandle, valueConfigCoordinates); ecgNotify.handle = ecgAttrTbl[4].handle; ecgNotify.len = ECG_NOTIFY_BUFFER_SIZE; VOID osal_memcpy((uint8 *)&(ecgNotify.value[0]), ptr, ECG_NOTIFY_BUFFER_SIZE); if (value & GATT_CLIENT_CFG_NOTIFY) { GATT_Notification(connHandle, &ecgNotify, FALSE ); } }
// Callback function invoked by app logic // to notify temperature update void Temp_NotifyTemperature(uint16 connHandle, struct temp *tBuf) { attHandleValueNoti_t tempNotify; uint16 value = GATTServApp_ReadCharCfg(connHandle, valueConfigCoordinates); tempNotify.handle = tempAttrTbl[2].handle; tempNotify.len = sizeof(struct temp); VOID osal_memcpy((uint8 *)&(tempNotify.value[0]), (uint8 *)tBuf, sizeof(struct temp)); if (value & GATT_CLIENT_CFG_NOTIFY) { GATT_Notification(connHandle, &tempNotify, FALSE ); } }
/********************************************************************* * @fn ClimbProfile_SetParameter * * @brief Set a Simple Profile 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 ClimbProfile_SetParameter(uint8 param, uint8 len, void *value) { bStatus_t ret = SUCCESS; switch (param) { case CLIMBPROFILE_CHAR1: //NO CHECK ON CCCD IS PERFORMED!!! if (len <= CLIMBPROFILE_CHAR1_LEN) { //VOID memcpy(climbProfileChar1, value, len); //save locally ((attHandleValueNoti_t*)value)->handle = climbProfileAttrTbl[2].handle; // attHandleValueNoti_t noti; // //bStatus_t status = SUCCESS; // noti.handle = climbProfileAttrTbl[2].handle; // noti.len = (uint16) len; // // noti.pValue = (uint8 *)value;//(uint8 *) GATT_bm_alloc(0, ATT_HANDLE_VALUE_NOTI, GATT_MAX_MTU, (uint16*) (&len)); //if (noti.pValue != NULL) //if allocated //{ // VOID memcpy(noti.pValue, value, noti.len); ret = GATT_Notification(0, (attHandleValueNoti_t*)value, 0); //attempt to send // if (status != SUCCESS) //if noti not sent // { // GATT_bm_free((gattMsg_t *) ¬i, ATT_HANDLE_VALUE_NOTI); // } //} else { // ret = bleNoResources; //no resources... //} // climbProfileChar1 = (uint8*) value; // // attHandleValueNoti_t noti; // noti.len = len; // noti.handle = climbProfileAttrTbl[2].handle; // ret = GATT_Notification(0, ¬i, FALSE); // // GATTServApp_ProcessCharCfg(climbProfileChar1Config, climbProfileChar1, FALSE, climbProfileAttrTbl, GATT_NUM_ATTRS(climbProfileAttrTbl), // INVALID_TASK_ID, climbProfile_ReadAttrCB); } else { ret = bleInvalidRange; } break; default: ret = INVALIDPARAMETER; break; } return (ret); }
/*--------------------------------------------------------------------------- * Application event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * - task_id: The OSAL assigned task ID. * - events: Events to process. This is a bit map and can contain more * than one event. *-------------------------------------------------------------------------*/ uint16 PMD_processEvent( uint8 taskId, uint16 events ) { if ( events & START_STREAMING) { attHandleValueNoti_t nData2; nData2.len = 20; nData2.handle = 20; getNameWithAddressInfo(nData2); GATT_Notification( 0, &nData2, FALSE ); return (events ^ START_STREAMING); } if ( events & SYS_EVENT_MSG ) { uint8 *pMsg; if ( (pMsg = osal_msg_receive( pmd.taskId )) != NULL ) { processOSALMsg( (osal_event_hdr_t *)pMsg ); VOID osal_msg_deallocate( pMsg ); } return (events ^ SYS_EVENT_MSG); } if ( events & PMD_START_DEVICE_EVT ) { // Start the Device VOID GAPRole_StartDevice( &peripheralRoleCallbacks ); // Start Bond Manager VOID GAPBondMgr_Register( &bondMgrCallbacks ); // Flash red LED twice //cbLED_flash(cbLED_RED, 2, 250, 500); PMD_INT_init(); return ( events ^ PMD_START_DEVICE_EVT ); } // Discard unknown events return 0; }
/********************************************************************* * @fn Thermometer_IMeasNotify * * @brief Send a notification containing a thermometer * measurement. * * @param connHandle - connection handle * @param pNoti - pointer to notification structure * * @return Success or Failure */ bStatus_t Thermometer_IMeasNotify( uint16 connHandle, attHandleValueNoti_t *pNoti) { uint16 value = GATTServApp_ReadCharCfg( connHandle, thermometerIMeasConfig ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { // Set the handle pNoti->handle = thermometerAttrTbl[THERMOMETER_IMEAS_VALUE_POS].handle; // Send the Notification return GATT_Notification( connHandle, pNoti, FALSE ); } return bleIncorrectMode; }
/** * @fn battNotifyCB * * @brief Send a notification of the level state characteristic. * * @param connHandle - linkDB item * * @return None. */ static void battNotifyCB(linkDBItem_t *pLinkItem) { if (pLinkItem->stateFlags & LINK_CONNECTED) { uint16 value = GATTServApp_ReadCharCfg(pLinkItem->connectionHandle, battLevelClientCharCfg); if (value & GATT_CLIENT_CFG_NOTIFY) { attHandleValueNoti_t noti; noti.handle = battAttrTbl[BATT_LEVEL_VALUE_IDX].handle; noti.len = 1; noti.value[0] = battLevel; GATT_Notification(pLinkItem->connectionHandle, ¬i, FALSE); } } }
// << Wayne >> << dBCmd Service >> -- // << Wayne >> << RepeatCmd >> ++ static bool repeatCmdSendData(uint8* data, uint8 len) { attHandleValueNoti_t noti; //dummy handle noti.handle = 0x2F; noti.len = len; uint8 i; for (i= 0; i < len; i++) { noti.value[i] = data[i]; } return (!GATT_Notification(0, ¬i, FALSE)); }
/********************************************************************* * @fn HidMouse_SetParameter * * @brief Set a Simple Profile parameter. * * @param param - Profile parameter ID * @param len - length of data to right * @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 HidMouse_SetParameter(uint8 param, uint8 len, void *value) { bStatus_t ret = SUCCESS; const uint8 MOUSE_LEN = 4; switch (param) { case HIDMOUSE_DATA: if (len == MOUSE_LEN) { memcpy(hidMouseData, value, MOUSE_LEN); // Send notification if enabled if ((hidMouseDataCharConfig == GATT_CLIENT_CFG_NOTIFY) && (hidMouseConnHandle != INVALID_CONNHANDLE)) { gattAttribute_t *attr; // Find the characteristic value attribute attr = GATTServApp_FindAttr(hidMouseAttrTbl, GATT_NUM_ATTRS(hidMouseAttrTbl), hidMouseData); if (attr != NULL) { attHandleValueNoti_t notify; // Send the notification notify.handle = attr->handle; notify.len = MOUSE_LEN; memcpy(notify.value, hidMouseData, MOUSE_LEN); ret = GATT_Notification(hidMouseConnHandle, ¬ify, FALSE); } } } else { ret = bleInvalidRange; } break; default: ret = INVALIDPARAMETER; break; } return (ret); }
/********************************************************************* * @fn simpleProfile_StateNotify * * @brief Send a notification containing a rate * measurement. * * @param connHandle - connection handle * @param pNoti - pointer to notification structure * * @return Success or Failure */ bStatus_t simpleProfile_StateNotify( uint16 connHandle, attHandleValueNoti_t *pNoti ) { uint16 value = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar4Config ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { // Set the handle pNoti->handle = simpleProfileAttrTbl[12].handle; // Send the notification return GATT_Notification( connHandle, pNoti, FALSE ); } return bleIncorrectMode; }
/********************************************************************* * @fn Glucose_ContextSend * * @brief Send a glucose measurement context. * * @param connHandle - connection handle * @param pNoti - pointer to notification structure * * @return Success or Failure */ bStatus_t Glucose_ContextSend( uint16 connHandle, attHandleValueNoti_t *pNoti, uint8 taskId ) { uint16 value = GATTServApp_ReadCharCfg( connHandle, glucoseContextConfig ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { // Set the handle pNoti->handle = glucoseAttrTbl[GLUCOSE_CONTEXT_VALUE_POS].handle; // Send the Indication return GATT_Notification( connHandle, pNoti, FALSE ); } return bleNotReady; }
/********************************************************************* * @fn ScanParam_RefreshNotify * * @brief Notify the peer to refresh the scan parameters. * * @param connHandle - connection handle * * @return None */ void ScanParam_RefreshNotify( uint16 connHandle ) { attHandleValueNoti_t noti; uint16 value; value = GATTServApp_ReadCharCfg( connHandle, scanParamRefreshClientCharCfg ); if ( value & GATT_CLIENT_CFG_NOTIFY ) { // send notification noti.handle = scanParamAttrTbl[SCAN_PARAM_REFRESH_CCCD_IDX].handle; noti.len = SCAN_PARAM_REFRESH_LEN; noti.value[0] = SCAN_PARAM_REFRESH_REQ; GATT_Notification( connHandle, ¬i, FALSE ); } }
/********************************************************************* * @fn Cycling_MeasNotify * * @brief Send a notification containing a CSC * measurement. * * @param connHandle - connection handle * @param pNoti - pointer to notification structure * * @return Success or Failure */ bStatus_t Cycling_MeasNotify( uint16 connHandle, attHandleValueNoti_t *pNoti ) { uint16 value = GATTServApp_ReadCharCfg( connHandle, cyclingMeasClientCharCfg ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { // Set the handle pNoti->handle = cyclingAttrTbl[CSC_MEAS_VALUE_POS].handle; // Send the notification return GATT_Notification( connHandle, pNoti, FALSE ); } return bleIncorrectMode; }
/********************************************************************* * @fn HeartRate_MeasNotify * * @brief Send a notification containing a heart rate * measurement. * * @param connHandle - connection handle * @param pNoti - pointer to notification structure * * @return Success or Failure */ bStatus_t HeartRate_MeasNotify(uint16 connHandle, attHandleValueNoti_t *pNoti) { uint16 value = GATTServApp_ReadCharCfg(connHandle, heartRateMeasClientCharCfg); // If notifications enabled if (value & GATT_CLIENT_CFG_NOTIFY) { // Set the handle. pNoti->handle = heartRateAttrTbl[HEARTRATE_MEAS_VALUE_POS].handle; // Send the notification. return GATT_Notification(connHandle, pNoti, FALSE); } return bleIncorrectMode; }
/********************************************************************* * @fn BloodPressure_IMeasNotify * * @brief Send a notification containing a bloodPressure * measurement. * * @param connHandle - connection handle * @param pNoti - pointer to notification structure * * @return Success or Failure */ bStatus_t BloodPressure_IMeasNotify( uint16 connHandle, attHandleValueNoti_t *pNoti, uint8 taskId ) { uint16 value = GATTServApp_ReadCharCfg( connHandle, bloodPressureIMeasConfig ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { // Set the handle pNoti->handle = bloodPressureAttrTbl[BLOODPRESSURE_IMEAS_VALUE_POS].handle; // Send the Indication return GATT_Notification( connHandle, pNoti, FALSE); } return bleIncorrectMode; }
/********************************************************************* * @fn oadImgIdentifyReq * * @brief Process the Image Identify Request. * * @param connHandle - connection message was received on * @param pImgHdr - Pointer to the img_hdr_t data to send. * * @return None */ static void oadImgBlockReq(uint16 connHandle, uint16 blkNum) { uint16 value = GATTServApp_ReadCharCfg( connHandle, oadImgBlockConfig ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { attHandleValueNoti_t noti; gattAttribute_t *pAttr = GATTServApp_FindAttr(oadAttrTbl, GATT_NUM_ATTRS(oadAttrTbl), oadCharVals+OAD_CHAR_IMG_BLOCK); noti.handle = pAttr->handle; noti.len = 2; noti.value[0] = LO_UINT16(blkNum); noti.value[1] = HI_UINT16(blkNum); VOID GATT_Notification(connHandle, ¬i, FALSE); } }
/********************************************************************* * @fn gattServApp_SendNotiInd * * @brief Send an ATT Notification/Indication. * * @param connHandle - connection handle to use. * @param cccValue - client characteristic configuration value. * @param authenticated - whether an authenticated link is required. * @param pAttr - pointer to attribute record. * @param taskId - task to be notified of confirmation. * @param pfnReadAttrCB - read callback function pointer. * * @return Success or Failure */ static bStatus_t gattServApp_SendNotiInd( uint16 connHandle, uint8 cccValue, uint8 authenticated, gattAttribute_t *pAttr, uint8 taskId, pfnGATTReadAttrCB_t pfnReadAttrCB ) { attHandleValueNoti_t noti; uint16 len; bStatus_t status; // If the attribute value is longer than (ATT_MTU - 3) octets, then // only the first (ATT_MTU - 3) octets of this attributes value can // be sent in a notification. noti.pValue = (uint8 *)GATT_bm_alloc( connHandle, ATT_HANDLE_VALUE_NOTI, GATT_MAX_MTU, &len ); if ( noti.pValue != NULL ) { status = (*pfnReadAttrCB)( connHandle, pAttr, noti.pValue, ¬i.len, 0, len, GATT_LOCAL_READ ); if ( status == SUCCESS ) { noti.handle = pAttr->handle; if ( cccValue & GATT_CLIENT_CFG_NOTIFY ) { status = GATT_Notification( connHandle, ¬i, authenticated ); } else // GATT_CLIENT_CFG_INDICATE { status = GATT_Indication( connHandle, (attHandleValueInd_t *)¬i, authenticated, taskId ); } } if ( status != SUCCESS ) { GATT_bm_free( (gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI ); } } else { status = bleNoResources; } return ( status ); }
/********************************************************************* * @fn HidDev_SetParameter * * @brief Set a HID Dev parameter. * * @param param - Profile parameter ID * @param len - length of data to right * @param pValue - 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 HidDev_SetParameter( uint8 param, uint8 len, void *pValue ) { bStatus_t ret = SUCCESS; switch ( param ) { case HIDDEV_ERASE_ALLBONDS: if ( len == 0 ) { // See if the last report sent out wasn't a release key if ( osal_isbufset( lastNoti.value, 0x00, lastNoti.len ) == FALSE ) { // Send a release report before disconnecting, otherwise // the last pressed key would get 'stuck' on the HID Host. osal_memset( lastNoti.value, 0x00, lastNoti.len ); GATT_Notification( gapConnHandle, &lastNoti, FALSE ); } // Drop connection if ( hidDevGapState == GAPROLE_CONNECTED ) { GAPRole_TerminateConnection(); } // Flush report queue firstQIdx = lastQIdx = 0; // Erase bonding info GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS, 0, NULL ); } else { ret = bleInvalidRange; } break; default: ret = INVALIDPARAMETER; break; } return ( ret ); }
bStatus_t char4_notify(uint8 state) { attHandleValueNoti_t Report; GAPRole_GetParameter(GAPROLE_CONNHANDLE, &connHandle); uint16 value = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar4Config); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { // Set the handle Report.handle = simpleProfileAttrTbl[14].handle; Report.len = 1; osal_memcpy(Report.value, &state, 1); // Send the notification return GATT_Notification( connHandle, &Report, FALSE ); } return bleIncorrectMode; }
/********************************************************************* * @fn performPeriodicTask * * @brief Perform a periodic application task. This function gets * called every five seconds as a result of the SBP_PERIODIC_EVT * OSAL event. In this example, the value of the third * characteristic in the SimpleGATTProfile service is retrieved * from the profile, and then copied into the value of the * the fourth characteristic. * * @param none * * @return none */ static void performPeriodicTask( void ) { uint8 data[20]; SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN, randomGen_Max20bytes(SIMPLEPROFILE_CHAR2_LEN) ); SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR2, &data ); //data[1] = exchange_DHM(data); //SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN, data); attHandleValueNoti_t noti; //dummy handle noti.handle = 0x28; noti.len = 20; uint8 i; for (i= 0; i < 20; i++) { noti.value[i] = data[i]; } GATT_Notification(0, ¬i, FALSE); //uint8 valueToCopy = 0x08; //uint8 stat; // //Call to retrieve the value of the third characteristic in the profile //stat = SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR3, &valueToCopy); //if( stat == SUCCESS ) //{ /* * Call to set that value of the fourth characteristic in the profile. Note * that if notifications of the fourth characteristic have been enabled by * a GATT client device, then a notification will be sent every time this * function is called. */ // SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy); //} }
/******************************************************************************************************** * @fn ServerNotificationCallBack() * * @brief when connected, send notification automaticly!!. * * @param connHandle - connection handle * @param changeType - type of change * * @return none *********************************************************************************************************/ static void ServerNotificationCallBack(linkDBItem_t *pLinkItem) { if( pLinkItem->stateFlags & LINK_CONNECTED ){ uint16 value = GATTServApp_ReadCharCfg( pLinkItem->connectionHandle,simpleProfileChar2Config ); if ( value & GATT_CLIENT_CFG_NOTIFY ){ attHandleValueNoti_t noti; noti.handle = simpleProfileAttrTbl[CHAR2_CONFIG_INDEX].handle; noti.len = SIMPLEPROFILE_CHAR2_ATCLEN; // noti.value = simpleProfileChar2; osal_memcpy(noti.value, simpleProfileChar2, SIMPLEPROFILE_CHAR2_ATCLEN ); uint8 return_status; if(return_status = GATT_Notification( pLinkItem->connectionHandle, ¬i, FALSE )) LCDPrintText("Notif error",return_status,PRINT_VALUE); //else //LCDPrintText("Notif ok",0,PRINT_STRING); } } }
/********************************************************************* * @fn hidDevSendReport * * @brief Send a HID report. * * @param id - HID report ID. * @param type - HID report type. * @param len - Length of report. * @param pData - Report data. * * @return None. */ static void hidDevSendReport( uint8 id, uint8 type, uint8 len, uint8 *pData ) { hidRptMap_t *pRpt; gattAttribute_t *pAttr; uint16 retHandle; // get att handle for report if ( (pRpt = hidDevRptById(id, type)) != NULL ) { // if notifications are enabled if ( (pAttr = GATT_FindHandle(pRpt->cccdHandle, &retHandle)) != NULL ) { uint16 value; value = GATTServApp_ReadCharCfg( gapConnHandle, (gattCharCfg_t *) pAttr->pValue ); if ( value & GATT_CLIENT_CFG_NOTIFY ) { // After service discovery and encryption, the HID Device should request to // change to the preferred connection parameters that best suit its use case. if ( updateConnParams ) { GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_REQ, sizeof( uint8 ), &updateConnParams ); updateConnParams = FALSE; } // send notification lastNoti.handle = pRpt->handle; lastNoti.len = len; osal_memcpy(lastNoti.value, pData, len); GATT_Notification( gapConnHandle, &lastNoti, FALSE ); // start idle timer hidDevStartIdleTimer(); } } } }
/********************************************************************* * @fn oadImgIdentifyReq * * @brief Process the Image Identify Request. * * @param connHandle - connection message was received on * @param pImgHdr - Pointer to the img_hdr_t data to send. * * @return None */ static void oadImgIdentifyReq(uint16 connHandle, img_hdr_t *pImgHdr) { uint16 value = GATTServApp_ReadCharCfg( connHandle, oadImgIdentifyConfig ); // If notifications enabled if ( value & GATT_CLIENT_CFG_NOTIFY ) { attHandleValueNoti_t noti; gattAttribute_t *pAttr = GATTServApp_FindAttr(oadAttrTbl, GATT_NUM_ATTRS(oadAttrTbl), oadCharVals+OAD_CHAR_IMG_IDENTIFY); noti.handle = pAttr->handle; noti.len = OAD_IMG_HDR_SIZE; noti.value[0] = LO_UINT16(pImgHdr->ver); noti.value[1] = HI_UINT16(pImgHdr->ver); noti.value[2] = LO_UINT16(pImgHdr->len); noti.value[3] = HI_UINT16(pImgHdr->len); (void)osal_memcpy(noti.value+4, pImgHdr->uid, sizeof(pImgHdr->uid)); VOID GATT_Notification(connHandle, ¬i, FALSE); } }