/****************************************************************************** * Function Name: CyBle_BassWriteEventHandler ***************************************************************************//** * * Handles the Write Request Event for Battery service. * * \param void *eventParam: the pointer to the data structure specified by the event. * * \return * Return value is of type CYBLE_GATT_ERR_CODE_T. * * CYBLE_GATT_ERR_NONE - Write request is handled successfully. * * CYBLE_GATT_ERR_REQUEST_NOT_SUPPORTED - Notification isn't supported. * * CYBLE_GATT_ERR_UNLIKELY_ERROR - Internal error while writing attribute * value. * ******************************************************************************/ CYBLE_GATT_ERR_CODE_T CyBle_BassWriteEventHandler(CYBLE_GATTS_WRITE_REQ_PARAM_T *eventParam) { uint8 locServIndex = 0u; CYBLE_BAS_CHAR_VALUE_T locCharIndex; CYBLE_GATT_ERR_CODE_T gattErr = CYBLE_GATT_ERR_NONE; if(NULL != CyBle_BasApplCallback) { do { /* Client Characteristic Configuration descriptor write request */ if(eventParam->handleValPair.attrHandle == cyBle_bass[locServIndex].cccdHandle) { /* Verify that optional notification property is enabled for Battery Level characteristic */ if(CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_bass[locServIndex].batteryLevelHandle)) { gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED); if(CYBLE_GATT_ERR_NONE == gattErr) { locCharIndex.connHandle = eventParam->connHandle; locCharIndex.serviceIndex = locServIndex; locCharIndex.charIndex = CYBLE_BAS_BATTERY_LEVEL; locCharIndex.value = NULL; if(CYBLE_IS_NOTIFICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val)) { CyBle_BasApplCallback((uint32)CYBLE_EVT_BASS_NOTIFICATION_ENABLED, &locCharIndex); } else { CyBle_BasApplCallback((uint32)CYBLE_EVT_BASS_NOTIFICATION_DISABLED, &locCharIndex); } #if((CYBLE_GAP_ROLE_PERIPHERAL || CYBLE_GAP_ROLE_CENTRAL) && \ (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES)) /* Set flag to store bonding data to flash */ if(cyBle_peerBonding == CYBLE_GAP_BONDING) { cyBle_pendingFlashWrite |= CYBLE_PENDING_CCCD_FLASH_WRITE_BIT; } #endif /* (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES) */ } } else { gattErr = CYBLE_GATT_ERR_REQUEST_NOT_SUPPORTED; } cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK; break; } locServIndex++; }while(locServIndex < CYBLE_BASS_SERVICE_COUNT); } return (gattErr); }
/****************************************************************************** ##Function Name: CyBle_CtssWriteEventHandler ******************************************************************************* Summary: Handles the Write Request Event for the Current Time Service. Parameters: eventParam: The pointer to the data that came with a write request for the Current Time Service. Return: Return a value of type CYBLE_GATT_ERR_CODE_T: * CYBLE_GATT_ERR_NONE - Function terminated successfully. * CYBLE_GATT_ERR_INVALID_HANDLE - The Handle of the Current Time Client Configuration Characteristic Descriptor is not valid. * CYBLE_GATT_ERR_UNLIKELY_ERROR - An Internal Stack error occurred. * CYBLE_GATT_ERR_REQUEST_NOT_SUPPORTED - The notification property of the Current Time Client Configuration Characteristic Descriptor is disabled. ******************************************************************************/ CYBLE_GATT_ERR_CODE_T CyBle_CtssWriteEventHandler(CYBLE_GATTS_WRITE_REQ_PARAM_T *eventParam) { CYBLE_CTS_CHAR_VALUE_T wrReqParam; CYBLE_GATT_ERR_CODE_T gattErr = CYBLE_GATT_ERR_NONE; uint32 event = (uint32)CYBLE_EVT_CTSS_NOTIFICATION_DISABLED; if(CyBle_CtsApplCallback != NULL) { wrReqParam.connHandle = eventParam->connHandle; wrReqParam.value = &eventParam->handleValPair.value; /* Client Characteristic Configuration descriptor write request */ if(eventParam->handleValPair.attrHandle == cyBle_ctss.currTimeCccdHandle) { /* Verify that optional notification property is enabled for Current Time * Characteristic. */ if(CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_ctss.currTimeCharHandle)) { if(CYBLE_IS_NOTIFICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val)) { event = (uint32)CYBLE_EVT_CTSS_NOTIFICATION_ENABLED; } gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED); if(CYBLE_GATT_ERR_NONE == gattErr) { wrReqParam.charIndex = CYBLE_CTS_CURRENT_TIME; wrReqParam.value = NULL; CyBle_CtsApplCallback(event, &wrReqParam); } #if((CYBLE_GAP_ROLE_PERIPHERAL || CYBLE_GAP_ROLE_CENTRAL) && \ (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES)) /* Set flag to store bonding data to flash */ cyBle_pendingFlashWrite |= CYBLE_PENDING_CCCD_FLASH_WRITE_BIT; #endif /* (CYBLE_GAP_ROLE_PERIPHERAL || CYBLE_GAP_ROLE_CENTRAL) && \ * (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES) */ } else { gattErr = CYBLE_GATT_ERR_REQUEST_NOT_SUPPORTED; } /* Clear the callback flag indicating that request was handled */ cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK; }
/****************************************************************************** ##Function Name: CyBle_WptssSendNotification ******************************************************************************* Summary: Sends notification with a characteristic value of the WPTS, which is a value specified by charIndex, to the Client device. Parameters: connHandle: The connection handle charIndex: The index of a service characteristic of type CYBLE_WPTS_CHAR_INDEX_T. attrSize: The size of the characteristic value attribute. *attrValue: The pointer to the characteristic value data that should be sent to the Client device. Return: Return value is of type CYBLE_API_RESULT_T. * CYBLE_ERROR_OK - The request handled successfully * CYBLE_ERROR_INVALID_PARAMETER - Validation of the input parameter failed * CYBLE_ERROR_INVALID_OPERATION - This operation is not permitted * CYBLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE - Optional characteristic is absent * CYBLE_ERROR_INVALID_STATE - Connection with the Client is not established * CYBLE_ERROR_MEMORY_ALLOCATION_FAILED - Memory allocation failed. * CYBLE_ERROR_NTF_DISABLED - Notification is not enabled by the Client. ******************************************************************************/ CYBLE_API_RESULT_T CyBle_WptssSendNotification(CYBLE_CONN_HANDLE_T connHandle, CYBLE_WPTS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult; /* Send Notification if it is enabled and connected */ if(CyBle_GetState() != CYBLE_STATE_CONNECTED) { apiResult = CYBLE_ERROR_INVALID_STATE; } else if(charIndex >= CYBLE_WPTS_CHAR_COUNT) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else if(cyBle_wptss.charInfo[charIndex].charHandle == CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE) { apiResult = CYBLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE; } else if((!CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_wptss.charInfo[charIndex].charHandle)) || (!CYBLE_IS_NOTIFICATION_ENABLED(cyBle_wptss.charInfo[charIndex].descrHandle[CYBLE_WPTS_CCCD]))) { apiResult = CYBLE_ERROR_NTF_DISABLED; } else { CYBLE_GATTS_HANDLE_VALUE_NTF_T ntfReqParam; /* Fill all fields of write request structure ... */ ntfReqParam.attrHandle = cyBle_wptss.charInfo[charIndex].charHandle; ntfReqParam.value.val = attrValue; ntfReqParam.value.len = attrSize; /* Send notification to the Client using previously filled structure */ apiResult = CyBle_GattsNotification(connHandle, &ntfReqParam); } return (apiResult); }
/****************************************************************************** * Function Name: CyBle_AnssWriteEventHandler ***************************************************************************//** * * Handles Write Request Event for Alert Notification Service. * * \param eventParam: The pointer to the data that came with a write request for * Alert Notification Service. * * \return * Return a value of type CYBLE_GATT_ERR_CODE_T: * * CYBLE_GATT_ERR_NONE - The function terminated successfully. * * CYBLE_GATT_ERR_INVALID_HANDLE - The handle of Client Configuration * Characteristic Descriptor or Characteristic of Alert Notification Service * is not valid. * * CYBLE_GATT_ERR_UNLIKELY_ERROR - An Internal Stack error occurred. * * CYBLE_GATT_ERR_REQUEST_NOT_SUPPORTED - The notification property of a * specific characteristic of Alert Notification Service is disabled. * ******************************************************************************/ CYBLE_GATT_ERR_CODE_T CyBle_AnssWriteEventHandler(CYBLE_GATTS_WRITE_REQ_PARAM_T *eventParam) { CYBLE_ANS_CHAR_VALUE_T wrReqParam; CYBLE_GATT_DB_ATTR_HANDLE_T tmpHandle; CYBLE_GATT_ERR_CODE_T gattErr = CYBLE_GATT_ERR_NONE; uint8 flag = 0u; uint32 event = (uint32)CYBLE_EVT_ANSS_CHAR_WRITE; tmpHandle = eventParam->handleValPair.attrHandle; /* Client Characteristic Configuration Descriptor Write Request */ if((tmpHandle == cyBle_anss.charInfo[CYBLE_ANS_NEW_ALERT].descrHandle[CYBLE_ANS_CCCD]) || (tmpHandle == cyBle_anss.charInfo[CYBLE_ANS_UNREAD_ALERT_STATUS].descrHandle[CYBLE_ANS_CCCD])) { /* Verify that optional notification property is enabled for Characteristic */ if(CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_anss.charInfo[CYBLE_ANS_NEW_ALERT].charHandle) || CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_anss.charInfo[CYBLE_ANS_UNREAD_ALERT_STATUS].charHandle)) { if(CYBLE_IS_NOTIFICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val)) { event = (uint32)CYBLE_EVT_ANSS_NOTIFICATION_ENABLED; } else { event = (uint32)CYBLE_EVT_ANSS_NOTIFICATION_DISABLED; } if(tmpHandle == cyBle_anss.charInfo[CYBLE_ANS_NEW_ALERT].descrHandle[CYBLE_ANS_CCCD]) { wrReqParam.charIndex = CYBLE_ANS_NEW_ALERT; } else { wrReqParam.charIndex = CYBLE_ANS_UNREAD_ALERT_STATUS; } /* Value is NULL for descriptors */ wrReqParam.value = NULL; #if((CYBLE_GAP_ROLE_PERIPHERAL || CYBLE_GAP_ROLE_CENTRAL) && (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES)) /* Set flag to store bonding data to flash */ if(cyBle_peerBonding == CYBLE_GAP_BONDING) { cyBle_pendingFlashWrite |= CYBLE_PENDING_CCCD_FLASH_WRITE_BIT; } #endif /* (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES) */ } else { gattErr = CYBLE_GATT_ERR_REQUEST_NOT_SUPPORTED; } } else if(tmpHandle == cyBle_anss.charInfo[CYBLE_ANS_ALERT_NTF_CONTROL_POINT].charHandle) { /* Validate Command ID and Category ID ranges */ if((eventParam->handleValPair.value.val[0u] <= CYBLE_ANS_IMM_UNREAD_ALERT_STATUS_NTF) && ((eventParam->handleValPair.value.val[1u] <= CYBLE_ANS_CAT_ID_INSTANT_MESSAGE) || (eventParam->handleValPair.value.val[1u] == CYBLE_ANS_CAT_ID_ALL))) { wrReqParam.charIndex = CYBLE_ANS_ALERT_NTF_CONTROL_POINT; wrReqParam.value = &eventParam->handleValPair.value; } else /* Command ID or Category ID received is invalid */ { /* Erroneous request won't be notified to user but Error response will be sent. */ cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK; gattErr = CYBLE_GATT_ERR_ANS_COMMAND_NOT_SUPPORTED; } } else { /* Requested handle does not belong to Alert Notification Service Characteristic or Descriptor. */ flag = 1u; } if((gattErr == CYBLE_GATT_ERR_NONE) && (flag == 0u)) { /* Write value to GATT database */ gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED); if(gattErr == CYBLE_GATT_ERR_NONE) { wrReqParam.connHandle = eventParam->connHandle; cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK; if(NULL != CyBle_AnsApplCallback) { CyBle_AnsApplCallback(event, &wrReqParam); } } } if(CYBLE_GATT_ERR_NONE != gattErr) { /* Indicate that request was handled */ cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK; } return(gattErr); }
/****************************************************************************** ##Function Name: CyBle_WptssWriteEventHandler ******************************************************************************* Summary: Handles Write Request Event for Wireless Power Transfer Service. Parameters: void *eventParam: The pointer to the data structure specified by the event. Return: Return value is of type CYBLE_GATT_ERR_CODE_T. * CYBLE_GATT_ERR_NONE - Write is successful. * CYBLE_GATT_ERR_REQUEST_NOT_SUPPORTED - Request is not supported. * CYBLE_GATT_ERR_INVALID_HANDLE - 'handleValuePair.attrHandle' is not valid. * CYBLE_GATT_ERR_WRITE_NOT_PERMITTED - Write operation is not permitted on this attribute. * CYBLE_GATT_ERR_INVALID_OFFSET - Offset value is invalid. * CYBLE_GATT_ERR_UNLIKELY_ERROR - Some other error occurred. ******************************************************************************/ CYBLE_GATT_ERR_CODE_T CyBle_WptssWriteEventHandler(CYBLE_GATTS_WRITE_REQ_PARAM_T *eventParam) { CYBLE_WPTS_CHAR_INDEX_T locCharIndex; CYBLE_WPTS_CHAR_VALUE_T locCharValue; CYBLE_GATT_ERR_CODE_T gattErr = CYBLE_GATT_ERR_NONE; uint8 locReqHandle = 0u; if(CyBle_WptsApplCallback != NULL) { for(locCharIndex = CYBLE_WPTS_PRU_CONTROL; (locCharIndex < CYBLE_WPTS_CHAR_COUNT) && (locReqHandle == 0u); locCharIndex++) { if((eventParam->handleValPair.attrHandle == cyBle_wptss.charInfo[locCharIndex].descrHandle[CYBLE_WPTS_CCCD]) || (eventParam->handleValPair.attrHandle == cyBle_wptss.charInfo[locCharIndex].charHandle)) { locCharValue.connHandle = eventParam->connHandle; locCharValue.charIndex = locCharIndex; locCharValue.value = &eventParam->handleValPair.value; /* Store value to database */ gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED); if(gattErr == CYBLE_GATT_ERR_NONE) { /* Characteristic value write request */ if(eventParam->handleValPair.attrHandle == cyBle_wptss.charInfo[locCharIndex].charHandle) { CyBle_WptsApplCallback((uint32)CYBLE_EVT_WPTSS_WRITE_CHAR, &locCharValue); } else /* Client Characteristic Configuration descriptor write request */ { /* Check characteristic properties for Notification */ if(CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_wptss.charInfo[locCharIndex].charHandle)) { uint32 eventCode; if(CYBLE_IS_NOTIFICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val)) { eventCode = (uint32)CYBLE_EVT_WPTSS_NOTIFICATION_ENABLED; } else { eventCode = (uint32)CYBLE_EVT_WPTSS_NOTIFICATION_DISABLED; } CyBle_WptsApplCallback(eventCode, &locCharValue); } /* Check characteristic properties for Indication */ if(CYBLE_IS_INDICATION_SUPPORTED(cyBle_wptss.charInfo[locCharIndex].charHandle)) { uint32 eventCode; if(CYBLE_IS_INDICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val)) { eventCode = (uint32)CYBLE_EVT_WPTSS_INDICATION_ENABLED; } else { eventCode = (uint32)CYBLE_EVT_WPTSS_INDICATION_DISABLED; } CyBle_WptsApplCallback(eventCode, &locCharValue); } #if((CYBLE_GAP_ROLE_PERIPHERAL || CYBLE_GAP_ROLE_CENTRAL) && \ (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES)) /* Set flag to store bonding data to flash */ cyBle_pendingFlashWrite |= CYBLE_PENDING_CCCD_FLASH_WRITE_BIT; #endif /* (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES) */ } } cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK; locReqHandle = 1u; } } } return (gattErr); }
/****************************************************************************** ##Function Name: CyBle_HtssWriteEventHandler ******************************************************************************* Summary: Handles Write Request Event for HTS service. Parameters: void *eventParam: The pointer to the data structure specified by the event. Return: Return value is of type CYBLE_GATT_ERR_CODE_T. * CYBLE_GATT_ERR_NONE - Write is successful ******************************************************************************/ CYBLE_GATT_ERR_CODE_T CyBle_HtssWriteEventHandler(CYBLE_GATTS_WRITE_REQ_PARAM_T *eventParam) { CYBLE_HTS_CHAR_INDEX_T locCharIndex; CYBLE_HTS_CHAR_VALUE_T locCharValue; CYBLE_GATT_ERR_CODE_T gattErr = CYBLE_GATT_ERR_NONE; uint8 locReqHandle = 0u; if(NULL != CyBle_HtsApplCallback) { for(locCharIndex = CYBLE_HTS_TEMP_MEASURE; (locCharIndex < CYBLE_HTS_CHAR_COUNT) && (locReqHandle == 0u); locCharIndex++) { if((eventParam->handleValPair.attrHandle == cyBle_htss.charInfo[locCharIndex].descrHandle[CYBLE_HTS_CCCD]) || (eventParam->handleValPair.attrHandle == cyBle_htss.charInfo[locCharIndex].charHandle)) { locCharValue.connHandle = eventParam->connHandle; locCharValue.charIndex = locCharIndex; locCharValue.value = &eventParam->handleValPair.value; /* Characteristic value write request */ if(eventParam->handleValPair.attrHandle == cyBle_htss.charInfo[locCharIndex].charHandle) { /* Validate Measure Interval value */ if(locCharIndex == CYBLE_HTS_MEASURE_INTERVAL) { uint8 locAttrValue[CYBLE_HTS_VRD_LEN]; uint16 requestValue; requestValue = CyBle_Get16ByPtr(eventParam->handleValPair.value.val); if(requestValue != 0u) /* 0 is valid interval value for no periodic measurement */ { /* Check Valid range for Measure Interval characteristic value */ if(CYBLE_ERROR_OK == CyBle_HtssGetCharacteristicDescriptor(locCharIndex, CYBLE_HTS_VRD, CYBLE_HTS_VRD_LEN, locAttrValue)) { uint16 lowerValue; uint16 upperValue; lowerValue = CyBle_Get16ByPtr(locAttrValue); upperValue = CyBle_Get16ByPtr(locAttrValue + sizeof(lowerValue)); requestValue = CyBle_Get16ByPtr(eventParam->handleValPair.value.val); if((requestValue != 0u) && ((requestValue < lowerValue) || (requestValue > upperValue))) { gattErr = CYBLE_GATT_ERR_HTS_OUT_OF_RANGE; } } } } if(CYBLE_GATT_ERR_NONE == gattErr) { /* Store value to database */ gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED); if(CYBLE_GATT_ERR_NONE == gattErr) { CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_CHAR_WRITE, &locCharValue); } } } else /* Client Characteristic Configuration descriptor write request */ { /* Store value to database */ gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED); if(CYBLE_GATT_ERR_NONE == gattErr) { /* Check characteristic properties for Notification */ if(CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_htss.charInfo[locCharIndex].charHandle)) { if(CYBLE_IS_NOTIFICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val)) { CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_NOTIFICATION_ENABLED, &locCharValue); } else { CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_NOTIFICATION_DISABLED, &locCharValue); } } /* Check characteristic properties for Indication */ if(CYBLE_IS_INDICATION_SUPPORTED(cyBle_htss.charInfo[locCharIndex].charHandle)) { if(CYBLE_IS_INDICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val)) { CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_INDICATION_ENABLED, &locCharValue); } else { CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_INDICATION_DISABLED, &locCharValue); } } #if((CYBLE_GAP_ROLE_PERIPHERAL || CYBLE_GAP_ROLE_CENTRAL) && \ (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES)) /* Set flag to store bonding data to flash */ cyBle_pendingFlashWrite |= CYBLE_PENDING_CCCD_FLASH_WRITE_BIT; #endif /* (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES) */ } } cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK; locReqHandle = 1u; } } } return (gattErr); }