/****************************************************************************** ##Function Name: CyBle_BassGetCharacteristicValue ******************************************************************************* Summary: Gets a characteristic value of the Battery service, which is identified by charIndex. Parameters: serviceIndex: The index of the service instance. e.g. If two Battery Services are supported in your design, then first service will be identified by serviceIndex of 0 and the second by serviceIndex of 1. charIndex: The index of a service characteristic of type CYBLE_BAS_CHAR_INDEX_T. attrSize: The size of the characteristic value attribute. A battery level characteristic has a 1 byte length. *attrValue: The pointer to the location where characteristic value data should be stored. 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_API_RESULT_T CyBle_BassGetCharacteristicValue(uint8 serviceIndex, CYBLE_BAS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK; CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; if((serviceIndex >= CYBLE_BASS_SERVICE_COUNT) || (charIndex >= CYBLE_BAS_CHAR_COUNT) || (attrSize != CYBLE_BAS_BATTERY_LEVEL_LEN) ) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else { /* Read characteristic value from database */ locHandleValuePair.attrHandle = cyBle_bass[serviceIndex].batteryLevelHandle; locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; if(CYBLE_GATT_ERR_NONE != CyBle_GattsReadAttributeValue(&locHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_BassGetCharacteristicDescriptor ******************************************************************************* Summary: Gets a characteristic descriptor of a specified characteristic of the Battery service from the local GATT database. Parameters: serviceIndex: The index of the service instance. e.g. If two Battery Services are supported in your design, then first service will be identified by serviceIndex of 0 and the second by serviceIndex of 1. charIndex: The index of a service characteristic of type CYBLE_BAS_CHAR_INDEX_T. descrIndex: The index of a service characteristic descriptor of type CYBLE_BAS_DESCR_INDEX_T. attrSize: The size of the characteristic descriptor attribute. *attrValue: The pointer to the location where characteristic descriptor value data should be stored. 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_API_RESULT_T CyBle_BassGetCharacteristicDescriptor(uint8 serviceIndex, CYBLE_BAS_CHAR_INDEX_T charIndex, CYBLE_BAS_DESCR_INDEX_T descrIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK; CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; if((serviceIndex >= CYBLE_BASS_SERVICE_COUNT) || (charIndex >= CYBLE_BAS_CHAR_COUNT) || (descrIndex >= CYBLE_BAS_DESCR_COUNT)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else { /* Get data from database */ if(descrIndex == CYBLE_BAS_BATTERY_LEVEL_CCCD) { locHandleValuePair.attrHandle = cyBle_bass[serviceIndex].cccdHandle; } else { locHandleValuePair.attrHandle = cyBle_bass[serviceIndex].cpfdHandle; } locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; if(CYBLE_GATT_ERR_NONE != CyBle_GattsReadAttributeValue(&locHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_HrssGetCharacteristicValue ******************************************************************************* Summary: Gets the local characteristic value of specified Heart Rate Service characteristic. Parameters: charIndex: The index of a service characteristic. attrSize: The size of the characteristic value attribute. The Heart Rate Measurement characteristic has a 20 byte length (by default). The Body Sensor Location and Control Point characteristic both have 1 byte length. *attrValue: The pointer to the location where characteristic value data should be stored. 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_GATT_DB_INVALID_ATTR_HANDLE - Optional characteristic is absent ******************************************************************************/ CYBLE_API_RESULT_T CyBle_HrssGetCharacteristicValue(CYBLE_HRS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK; CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; if(charIndex >= CYBLE_HRS_CHAR_COUNT) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else if((charIndex == CYBLE_HRS_BSL) && (!CYBLE_HRS_IS_BSL_SUPPORTED)) { apiResult = CYBLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE; } else { /* Get characteristic value from GATT database */ locHandleValuePair.attrHandle = cyBle_hrss.charHandle[charIndex]; locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; if(CYBLE_GATT_ERR_NONE != CyBle_GattsReadAttributeValue(&locHandleValuePair, 0u, CYBLE_GATT_DB_READ | CYBLE_GATT_DB_LOCALLY_INITIATED)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_GlssGetCharacteristicValue ******************************************************************************* Summary: Gets a characteristic value of the service, which is identified by charIndex. Parameters: charIndex: The index of a service characteristic. attrSize: The size of the characteristic value attribute. *attrValue: Pointer to the location where Characteristic value data should be stored. 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_GATT_DB_INVALID_ATTR_HANDLE - Optional characteristic is absent ******************************************************************************/ CYBLE_API_RESULT_T CyBle_GlssGetCharacteristicValue(CYBLE_GLS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult; /* Check the parameters */ if(charIndex >= CYBLE_GLS_CHAR_COUNT) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else if(CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE == cyBle_glss.charInfo[charIndex].charHandle) { apiResult = CYBLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE; } else { CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; /* Get characteristic value from GATT database */ locHandleValuePair.attrHandle = cyBle_glss.charInfo[charIndex].charHandle; locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; if(CYBLE_GATT_ERR_NONE != CyBle_GattsReadAttributeValue(&locHandleValuePair, 0u, CYBLE_GATT_DB_LOCALLY_INITIATED)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else { apiResult = CYBLE_ERROR_OK; } } return (apiResult); }
/****************************************************************************** * Function Name: CyBle_AnssGetCharacteristicDescriptor ***************************************************************************//** * * Gets a characteristic descriptor of the specified characteristic of Alert * Notification Service. * * \param charIndex: The index of the service characteristic of type CYBLE_ANS_CHAR_INDEX_T. * The valid values are, * * CYBLE_ANS_NEW_ALERT * * CYBLE_ANS_UNREAD_ALERT_STATUS * \param descrIndex: The index of the service characteristic descriptor of type * CYBLE_ANS_DESCR_INDEX_T. The valid value is, * * CYBLE_ANS_CCCD * \param attrSize: The size of the characteristic descriptor attribute. * \param attrValue: The pointer to the location where characteristic descriptor value * data should be stored. * * \return * Return value is of type CYBLE_API_RESULT_T. * * CYBLE_ERROR_OK - The request is handled successfully. * * CYBLE_ERROR_INVALID_PARAMETER - Validation of the input parameter failed. * ******************************************************************************/ CYBLE_API_RESULT_T CyBle_AnssGetCharacteristicDescriptor(CYBLE_ANS_CHAR_INDEX_T charIndex, CYBLE_ANS_DESCR_INDEX_T descrIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_INVALID_PARAMETER; CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; if(((charIndex == CYBLE_ANS_NEW_ALERT) || (charIndex == CYBLE_ANS_UNREAD_ALERT_STATUS)) && (descrIndex == CYBLE_ANS_CCCD)) { if(cyBle_anss.charInfo[charIndex].descrHandle[descrIndex] != CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE) { locHandleValuePair.attrHandle = cyBle_anss.charInfo[charIndex].descrHandle[descrIndex]; locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; if(CyBle_GattsReadAttributeValue(&locHandleValuePair,0u, CYBLE_GATT_DB_LOCALLY_INITIATED) == CYBLE_GATT_ERR_NONE) { apiResult = CYBLE_ERROR_OK; } } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_BcssGetCharacteristicDescriptor ******************************************************************************* Summary: Reads a a characteristic descriptor of a specified characteristic of the Body Composition Service from the GATT database. Parameters: charIndex: The index of the characteristic. descrIndex: The index of the descriptor. attrSize: The size of the descriptor value. *attrValue: The pointer to the location where characteristic descriptor value data should be stored. Return: Return value is of type CYBLE_API_RESULT_T. * CYBLE_ERROR_OK - The request handled successfully. * CYBLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE - Optional descriptor is absent. ******************************************************************************/ CYBLE_API_RESULT_T CyBle_BcssGetCharacteristicDescriptor(CYBLE_BCS_CHAR_INDEX_T charIndex, CYBLE_BCS_DESCR_INDEX_T descrIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_INVALID_PARAMETER; CYBLE_GATT_HANDLE_VALUE_PAIR_T wssHandleValuePair; if((charIndex == CYBLE_BCS_BODY_COMPOSITION_MEASUREMENT) && (descrIndex == CYBLE_BCS_CCCD) && (NULL != attrValue)) { if(cyBle_bcss.charInfo[CYBLE_BCS_BODY_COMPOSITION_MEASUREMENT].descrHandle[CYBLE_BCS_CCCD] != CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE) { wssHandleValuePair.attrHandle = cyBle_bcss.charInfo[CYBLE_BCS_BODY_COMPOSITION_MEASUREMENT].descrHandle[CYBLE_BCS_CCCD]; wssHandleValuePair.value.len = attrSize; wssHandleValuePair.value.val = attrValue; /* Get characteristic value from GATT database */ if(CYBLE_GATT_ERR_NONE == CyBle_GattsReadAttributeValue(&wssHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED)) { /* Indicate success */ apiResult = CYBLE_ERROR_OK; } } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_BcssGetCharacteristicValue ******************************************************************************* Summary: Reads a characteristic value of the Body Composition Service, which is identified by charIndex from the GATT database. Parameters: charIndex: The index of the Body Composition Service characteristic. attrSize: The size of the Body Composition Service characteristic value attribute. *attrValue: The pointer to the location where characteristic value data should be stored. Return: Return value is of type CYBLE_API_RESULT_T. * CYBLE_ERROR_OK - The characteristic value was read successfully. * CYBLE_ERROR_INVALID_PARAMETER - Validation of the input parameters failed. ******************************************************************************/ CYBLE_API_RESULT_T CyBle_BcssGetCharacteristicValue(CYBLE_BCS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_GATT_DB_ATTR_HANDLE_T tmpCharHandle; CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_INVALID_PARAMETER; CYBLE_GATT_HANDLE_VALUE_PAIR_T wssHandleValuePair; if((NULL != attrValue) && (charIndex < CYBLE_BCS_CHAR_COUNT)) { if(charIndex == CYBLE_BCS_BODY_COMPOSITION_FEATURE) { tmpCharHandle = cyBle_bcss.charInfo[CYBLE_BCS_BODY_COMPOSITION_FEATURE].charHandle; } else { tmpCharHandle = cyBle_bcss.charInfo[CYBLE_BCS_BODY_COMPOSITION_MEASUREMENT].charHandle; } wssHandleValuePair.attrHandle = tmpCharHandle; wssHandleValuePair.value.len = attrSize; wssHandleValuePair.value.val = attrValue; /* Get characteristic value from GATT database */ if(CYBLE_GATT_ERR_NONE == CyBle_GattsReadAttributeValue(&wssHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED)) { /* Indicate success */ apiResult = CYBLE_ERROR_OK; } } /* Return status */ return(apiResult); }
/****************************************************************************** ##Function Name: CyBle_HtssGetCharacteristicDescriptor ******************************************************************************* Summary: Gets the characteristic descriptor of the specified characteristic. Parameters: charIndex: The index of the service characteristic. descrIndex: The index of the service characteristic descriptor. attrSize: The size of the characteristic descriptor attribute. *attrValue: The pointer to the location where characteristic descriptor value data should be stored. 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_API_RESULT_T CyBle_HtssGetCharacteristicDescriptor(CYBLE_HTS_CHAR_INDEX_T charIndex, CYBLE_HTS_DESCR_INDEX_T descrIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK; CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; if((charIndex >= CYBLE_HTS_CHAR_COUNT) || (descrIndex >= CYBLE_HTS_DESCR_COUNT)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else { locHandleValuePair.attrHandle = cyBle_htss.charInfo[charIndex].descrHandle[descrIndex]; if(locHandleValuePair.attrHandle != CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE) { locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; if(CYBLE_GATT_ERR_NONE != CyBle_GattsReadAttributeValue(&locHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } } else { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } } return (apiResult); }
/****************************************************************************** * Function Name: CyBle_AnssGetCharacteristicValue ***************************************************************************//** * * Gets a characteristic value of Alert Notification Service. The value is * identified by charIndex. * * \param charIndex: The index of the service characteristic of type CYBLE_ANS_CHAR_INDEX_T. * The valid values are, * * CYBLE_ANS_NEW_ALERT * * CYBLE_ANS_UNREAD_ALERT_STATUS * \param attrSize: The size of the characteristic value attribute. * \param attrValue: The pointer to the location where characteristic value data * should be stored. * * \return * Return value is of type CYBLE_API_RESULT_T. * * CYBLE_ERROR_OK - The request is handled successfully. * * CYBLE_ERROR_INVALID_PARAMETER - Validation of the input parameter failed. * ******************************************************************************/ CYBLE_API_RESULT_T CyBle_AnssGetCharacteristicValue(CYBLE_ANS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_INVALID_PARAMETER; CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; if(charIndex < CYBLE_ANS_CHAR_COUNT) { locHandleValuePair.attrHandle = cyBle_anss.charInfo[charIndex].charHandle; locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; /* Read characteristic value from database */ if(CyBle_GattsReadAttributeValue(&locHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED) == CYBLE_GATT_ERR_NONE) { apiResult = CYBLE_ERROR_OK; } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_LlssGetCharacteristicValue ******************************************************************************* Summary: Gets an Alert Level characteristic value of the service, which is identified by charIndex. Parameters: charIndex: The index of an Alert Level characteristic. attrSize: The size of the Alert Level characteristic value attribute. *attrValue: The pointer to the location where an Alert Level characteristic value data should be stored. Return: Return value is of type CYBLE_API_RESULT_T. * CYBLE_ERROR_OK - The characteristic value was read successfully * CYBLE_ERROR_INVALID_PARAMETER - Validation of the input parameters failed ******************************************************************************/ CYBLE_API_RESULT_T CyBle_LlssGetCharacteristicValue(CYBLE_LLS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_GATT_HANDLE_VALUE_PAIR_T llsHandleValuePair; CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_INVALID_PARAMETER; if((NULL != attrValue) && (CYBLE_LLS_ALERT_LEVEL == charIndex) && (CYBLE_LLS_ALERT_LEVEL_SIZE == attrSize)) { llsHandleValuePair.attrHandle = cyBle_llss.alertLevelCharHandle; llsHandleValuePair.value.len = attrSize; llsHandleValuePair.value.val = attrValue; /* Get Alert Level characteristic value from GATT database */ if(CYBLE_GATT_ERR_NONE == CyBle_GattsReadAttributeValue(&llsHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED)) { /* Indicate success */ apiResult = CYBLE_ERROR_OK; } } /* Return status */ return(apiResult); }
/****************************************************************************** ##Function Name: CyBle_WptssGetCharacteristicDescriptor ******************************************************************************* Summary: Reads a a characteristic descriptor of a specified characteristic of the Wireless Power Transfer Service from the GATT database. Parameters: charIndex: The index of a service characteristic of type CYBLE_WPTS_CHAR_INDEX_T. descrIndex: The index of a service characteristic descriptor of type CYBLE_WPTS_DESCR_INDEX_T. attrSize: The size of the characteristic descriptor attribute. *attrValue: The pointer to the location where characteristic descriptor value data should be stored. 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_API_RESULT_T CyBle_WptssGetCharacteristicDescriptor(CYBLE_WPTS_CHAR_INDEX_T charIndex, CYBLE_WPTS_DESCR_INDEX_T descrIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_INVALID_PARAMETER; CYBLE_GATT_HANDLE_VALUE_PAIR_T wssHandleValuePair; if((charIndex < CYBLE_WPTS_CHAR_COUNT) && (descrIndex < CYBLE_WPTS_DESCR_COUNT) && (attrValue != NULL)) { wssHandleValuePair.attrHandle = cyBle_wptss.charInfo[charIndex].descrHandle[descrIndex]; wssHandleValuePair.value.len = attrSize; wssHandleValuePair.value.val = attrValue; /* Get characteristic value from GATT database */ if(CyBle_GattsReadAttributeValue(&wssHandleValuePair, NULL, CYBLE_GATT_DB_LOCALLY_INITIATED) == CYBLE_GATT_ERR_NONE) { /* Indicate success */ apiResult = CYBLE_ERROR_OK; } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_HrssGetCharacteristicDescriptor ******************************************************************************* Summary: Gets the local characteristic descriptor of the specified Heart Rate Service characteristic. Parameters: charIndex: The index of the characteristic. descrIndex: The index of the descriptor. attrSize: The size of the descriptor value attribute. The Heart Rate Measurement characteristic client configuration descriptor has 2 bytes length. *attrValue: The pointer to the location where characteristic descriptor value data should be stored. 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_GATT_DB_INVALID_ATTR_HANDLE - Optional descriptor is absent ******************************************************************************/ CYBLE_API_RESULT_T CyBle_HrssGetCharacteristicDescriptor(CYBLE_HRS_CHAR_INDEX_T charIndex, CYBLE_HRS_DESCR_INDEX_T descrIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult; CYBLE_GATT_HANDLE_VALUE_PAIR_T locHandleValuePair; if((charIndex >= CYBLE_HRS_CHAR_COUNT) || (descrIndex >= CYBLE_HRS_DESCR_COUNT)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else if((charIndex != CYBLE_HRS_HRM) || (descrIndex != CYBLE_HRS_HRM_CCCD)) { apiResult = CYBLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE; } else { /* Get data from database */ locHandleValuePair.attrHandle = cyBle_hrss.hrmCccdHandle; locHandleValuePair.value.len = attrSize; locHandleValuePair.value.val = attrValue; if(CYBLE_GATT_ERR_NONE != CyBle_GattsReadAttributeValue(&locHandleValuePair, 0u, CYBLE_GATT_DB_READ | CYBLE_GATT_DB_LOCALLY_INITIATED)) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else { apiResult = CYBLE_ERROR_OK; } } return (apiResult); }
/******************************************************************************* * Function Name: ProcessWriteReq ******************************************************************************** * * Summary: * Process all GATT level write requests and responds with appropriate status * * Parameters: * CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T: GATT write command request prameter * * Return: * None * *******************************************************************************/ void ProcessWriteReq(CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T writeCmdReq) { bool value_val; uint8 status = LOCKED, key_buf[LOCK_CODE_LENGTH]; uint16 beaconPeriod = 0; CYBLE_GATT_HANDLE_VALUE_PAIR_T valuePairT; /* Reset error send flag */ errorSent = false; /* Retrieve the LOCK status from the GATT DB */ valuePairT.attrHandle = CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE; valuePairT.value.val = (uint8 *)&value_val; valuePairT.value.len = sizeof(bool); CyBle_GattsReadAttributeValue( &valuePairT, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED ); /* Check the LOCK status */ if(valuePairT.value.val[0] == UNLOCKED) { /*URL Data*/ if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE) { /* First byte should be scheme prefix and length should be less than * or equal to MAX_URL_LENGTH */ if( (writeCmdReq.handleValPair.value.len <= MAX_URL_LENGTH) && (writeCmdReq.handleValPair.value.val[0] < URL_PREFIX_MAX) ) { uint8 TempURL[MAX_URL_LENGTH]; memset(TempURL, 0, MAX_URL_LENGTH); memcpy( TempURL, writeCmdReq.handleValPair.value.val, writeCmdReq.handleValPair.value.len ); if( CYBLE_GATT_ERR_NONE == WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ) ) { /* Update the length as per the new URL data */ URLLength = writeCmdReq.handleValPair.value.len; cyBle_attValuesLen[16].actualLength = URLLength; /* Update the URL data */ memcpy(CurrentURL, TempURL, MAX_URL_LENGTH); } } else if (writeCmdReq.handleValPair.value.len > MAX_URL_LENGTH) { /* Invalid length. Send error response */ SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN ); } } /* Lock Characteristic */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE) { if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); /* Update the LOCK characteristic */ status = LOCKED; WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE, sizeof(bool), &status, CYBLE_GATT_DB_LOCALLY_INITIATED ); } else { /* Invalid length. Send error response */ SendErrorResponse(CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN); } } /* Advertised Tx power level */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE) { if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL) { /* Update Tx Power levels */ memcpy ( currentTxPowerLevels, writeCmdReq.handleValPair.value.val, MAX_NUM_PWR_LVL ); } else { SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN ); } } else { /* Invalid length. Send error response */ SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN ); } } /* Tx Power Mode */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE) { if(writeCmdReq.handleValPair.value.val[0] <= 0x03) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); currentTxmode = writeCmdReq.handleValPair.value.val[0]; UpdateTxPower(currentTxmode); } else /* Invalid value. Write not permitted. */ { SendErrorResponse ( CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE, CYBLE_GATT_ERR_WRITE_NOT_PERMITTED ); } } /* Beacon Period */ else if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE) { beaconPeriod = CyBle_Get16ByPtr(writeCmdReq.handleValPair.value.val); /* Disable URL FRAMES */ if(beaconPeriod == 0) { eddystoneImplenmentation = EDDYSTONE_UID; WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); } /* Values in valid range */ else if((beaconPeriod >= MIN_BEACON_PERIOD) && (beaconPeriod <= MAX_BEACON_PERIOD)) { WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE, writeCmdReq.handleValPair.value.len, writeCmdReq.handleValPair.value.val, CYBLE_GATT_DB_PEER_INITIATED ); CurrentAdvPeriod = beaconPeriod / 0.625; eddystoneImplenmentation = EDDYSTONE_URL; } else { uint16 temp = MIN_BEACON_PERIOD; /* Values not supportes. Write default values */ WriteAttributeValue( CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE, sizeof(temp), (uint8 *)&temp, CYBLE_GATT_DB_PEER_INITIATED); CurrentAdvPeriod = CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN; eddystoneImplenmentation = EDDYSTONE_URL; } } /* Reset the Configurations to default */ else if((writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_RESET_CHAR_HANDLE) && (writeCmdReq.handleValPair.value.val[0] != 0)) { ResetGattDb(); } } else if(valuePairT.value.val[0] == LOCKED) { if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE) { /* Accesing the lock in LOCKED state */ SendErrorResponse(writeCmdReq.handleValPair.attrHandle, CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION); } } if(writeCmdReq.handleValPair.attrHandle == CYBLE_EDDYSTONE_CONFIGURATION_UNLOCK_CHAR_HANDLE) { if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH) { if(valuePairT.value.val[0] == LOCKED) { int compareResult; valuePairT.attrHandle = CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE; valuePairT.value.val = key_buf; valuePairT.value.len = sizeof(LOCK); CyBle_GattsReadAttributeValue(&valuePairT, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED); compareResult = memcmp ( valuePairT.value.val, writeCmdReq.handleValPair.value.val, LOCK_CODE_LENGTH ); if(compareResult == 0) { status = UNLOCKED; /* Update the LOCK STATE */ WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE, sizeof(bool), &status, CYBLE_GATT_DB_LOCALLY_INITIATED ); /* Reset the LOCK */ WriteAttributeValue ( CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE, sizeof(LOCK), (uint8 *)LOCK, CYBLE_GATT_DB_LOCALLY_INITIATED ); } else /* LOCK not matched */ { SendErrorResponse(writeCmdReq.handleValPair.attrHandle, CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION); } } } else /* Invalid length */ { SendErrorResponse(writeCmdReq.handleValPair.attrHandle, CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN); } } if (errorSent == false) { CyBle_GattsWriteRsp(cyBle_connHandle); } }