/****************************************************************************** ##Function Name: CyBle_HtssSendIndication ******************************************************************************* Summary: Sends indication with a characteristic value of the Health Thermometer Service, which is a value specified by charIndex, to the Client device. Parameters: connHandle: The connection handle. charIndex: The index of the service characteristic. 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_INVALID_STATE - Connection with the client is not established * CYBLE_ERROR_MEMORY_ALLOCATION_FAILED - Memory allocation failed * CYBLE_ERROR_IND_DISABLED - Indication is not enabled by the client ******************************************************************************/ CYBLE_API_RESULT_T CyBle_HtssSendIndication(CYBLE_CONN_HANDLE_T connHandle, CYBLE_HTS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult; /* Send Notification if it is enabled and connected */ if(CYBLE_STATE_CONNECTED != CyBle_GetState()) { apiResult = CYBLE_ERROR_INVALID_STATE; } else if(!CYBLE_IS_INDICATION_ENABLED(cyBle_htss.charInfo[charIndex].descrHandle[CYBLE_HTS_CCCD])) { apiResult = CYBLE_ERROR_IND_DISABLED; } else { CYBLE_GATTS_HANDLE_VALUE_NTF_T ntfReqParam; /* Fill all fields of write request structure ... */ ntfReqParam.attrHandle = cyBle_htss.charInfo[charIndex].charHandle; ntfReqParam.value.val = attrValue; ntfReqParam.value.len = attrSize; /* Send indication to client using previously filled structure */ apiResult = CyBle_GattsIndication(connHandle, &ntfReqParam); /* Save handle to support service specific value confirmation response from client */ if(apiResult == CYBLE_ERROR_OK) { cyBle_htssReqHandle = ntfReqParam.attrHandle; } } return (apiResult); }
/***************************************************************************** * Function Name: _BLE_sendStatusFlags() ****************************************************************************** * Summary: * Send all the status flags. * * Parameters: * None. * * Return: * None. * * Note: * *****************************************************************************/ void _BLE_sendStatusFlags(void) { static uint8 Previous_Status_Ready = 0xFF; static uint8 Previous_Status_Acquiring = 0xFF; static uint8 Previous_Status_NoMoreSpace = 0xFF; static uint8 Previous_Status_DataAcquired = 0xFF; static uint8 Previous_Status_Sending = 0xFF; static uint8 Previous_Status_NoMoreData = 0xFF; uint8 StatusArray[NUM_STATUS]; CYBLE_GATTS_HANDLE_VALUE_NTF_T NotificationHandle; CYBLE_GATTS_HANDLE_VALUE_IND_T IndicationHandle; // Verify if the status changed since the last notification. // If so, send all the current status. if( Previous_Status_Ready != Status_Ready || Previous_Status_Acquiring != Status_Acquiring || Previous_Status_NoMoreSpace != Status_NoMoreSpace || Previous_Status_DataAcquired != Status_DataAcquired || Previous_Status_Sending != Status_Sending || Previous_Status_NoMoreData != Status_NoMoreData ) { // Fill the 'StatusArray' with the current status values. StatusArray[STATUS_READY_BYTE_MASK] = Status_Ready; StatusArray[STATUS_ACQUIRING_BYTE_MASK] = Status_Acquiring; StatusArray[STATUS_NO_MORE_SPACE_BYTE_MASK] = Status_NoMoreSpace; StatusArray[STATUS_DATA_ACQUIRED_BYTE_MASK] = Status_DataAcquired; StatusArray[STATUS_SENDING_BYTE_MASK] = Status_Sending; StatusArray[STATUS_NO_MORE_DATA_BYTE_MASK] = Status_NoMoreData; // Send the Status characteristic values to BLE client. if (sendStatusNotifications) { NotificationHandle.attrHandle = CYBLE_CAPSENSE_STATUS_CHAR_HANDLE; NotificationHandle.value.val = StatusArray; NotificationHandle.value.len = NUM_STATUS; CyBle_GattsNotification(connectionHandle, &NotificationHandle); } else if (sendStatusIndications) { IndicationHandle.attrHandle = CYBLE_CAPSENSE_STATUS_CHAR_HANDLE; IndicationHandle.value.val = StatusArray; IndicationHandle.value.len = NUM_STATUS; CyBle_GattsIndication(connectionHandle, &IndicationHandle); } // Set the 'Previous_*' static variables to the current status values. Previous_Status_Ready = Status_Ready; Previous_Status_Acquiring = Status_Acquiring; Previous_Status_NoMoreSpace = Status_NoMoreSpace; Previous_Status_DataAcquired = Status_DataAcquired; Previous_Status_Sending = Status_Sending; Previous_Status_NoMoreData = Status_NoMoreData; } }
/****************************************************************************** ##Function Name: CyBle_GlssSendIndication ******************************************************************************* Summary: Sends a indication of the specified characteristic to the client device, as defined by the charIndex value. Parameters: connHandle: The connection handle which consist of the device ID and ATT connection ID. charIndex: The index of the service characteristic. attrSize: The size of the characteristic value attribute. *attrValue: Pointer to the Characteristic value data that should be sent to 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 - Operation is invalid for this characteristic * 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_IND_DISABLED - Indication is not enabled by the client ******************************************************************************/ CYBLE_API_RESULT_T CyBle_GlssSendIndication(CYBLE_CONN_HANDLE_T connHandle, CYBLE_GLS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { CYBLE_API_RESULT_T apiResult; /* Send Indication if it is enabled and connected */ if(CYBLE_STATE_CONNECTED != CyBle_GetState()) { apiResult = CYBLE_ERROR_INVALID_STATE; } else if(charIndex >= CYBLE_GLS_CHAR_COUNT) { apiResult = CYBLE_ERROR_INVALID_PARAMETER; } else if(CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE == cyBle_glss.charInfo[charIndex].cccdHandle) { apiResult = CYBLE_ERROR_GATT_DB_INVALID_ATTR_HANDLE; } else if(!CYBLE_IS_INDICATION_ENABLED(cyBle_glss.charInfo[charIndex].cccdHandle)) { apiResult = CYBLE_ERROR_IND_DISABLED; } else { CYBLE_GATTS_HANDLE_VALUE_IND_T indParam; /* Fill all fields of write request structure ... */ indParam.attrHandle = cyBle_glss.charInfo[charIndex].charHandle; indParam.value.val = attrValue; indParam.value.len = attrSize; /* Send notification to client using previously filled structure */ apiResult = CyBle_GattsIndication(connHandle, &indParam); if(CYBLE_ERROR_OK == apiResult) { /* Save handle to support service specific value confirmation response from client */ cyBle_glssReqHandle = indParam.attrHandle; } } return (apiResult); }
/****************************************************************************** ##Function Name: CyBle_BcssSendIndication ******************************************************************************* Summary: Sends an indication with a characteristic value of the Body Composition Service, which is a value specified by charIndex, to the client's device. Parameters: connHandle: The connection handle. charIndex: The index of the service characteristic. attrSize: The size of the characteristic value attribute. *attrValue: The pointer to the characteristic value data that should be sent to the client's device. Return: A 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_INVALID_STATE - Connection with the client is not established * CYBLE_ERROR_MEMORY_ALLOCATION_FAILED - Memory allocation failed. * CYBLE_ERROR_IND_DISABLED - Indication is not enabled by the client. ******************************************************************************/ CYBLE_API_RESULT_T CyBle_BcssSendIndication(CYBLE_CONN_HANDLE_T connHandle, CYBLE_BCS_CHAR_INDEX_T charIndex, uint8 attrSize, uint8 *attrValue) { /* Store new data in database */ CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_INVALID_PARAMETER; if(charIndex == CYBLE_BCS_BODY_COMPOSITION_MEASUREMENT) { /* Send indication if it is enabled and connected */ if(CYBLE_STATE_CONNECTED != CyBle_GetState()) { apiResult = CYBLE_ERROR_INVALID_STATE; } else if(!CYBLE_IS_INDICATION_ENABLED( cyBle_bcss.charInfo[CYBLE_BCS_BODY_COMPOSITION_MEASUREMENT].descrHandle[CYBLE_BCS_CCCD])) { apiResult = CYBLE_ERROR_IND_DISABLED; } else { CYBLE_GATTS_HANDLE_VALUE_IND_T indReqParam; /* Fill all fields of write request structure ... */ indReqParam.attrHandle = cyBle_bcss.charInfo[CYBLE_BCS_BODY_COMPOSITION_MEASUREMENT].descrHandle[CYBLE_BCS_CCCD]; indReqParam.value.val = attrValue; indReqParam.value.len = attrSize; /* Send indication to client using previously filled structure */ apiResult = CyBle_GattsIndication(connHandle, &indReqParam); /* Save handle to support service specific value confirmation response from client */ if(apiResult == CYBLE_ERROR_OK) { cyBle_bcssReqHandle = indReqParam.attrHandle; } } } return (apiResult); }
/***************************************************************************** * Function Name: _BLE_sendCapSenseData() ****************************************************************************** * Summary: * Send the whole content of the vectors through BLE notifications * or indications. * * Parameters: * None. * * Return: * 'SUCCESS' if it succeeded. * 'NO_MORE_DATA' if the vector is empty * * Note: * *****************************************************************************/ uint8 _BLE_sendCapSenseData(void) { // Verify the presence of data to send. if ( vectorIsEmpty() ) return NO_MORE_DATA; uint16 rawData[CapSense_TOTAL_SENSOR_COUNT]; uint32 encodedData[CapSense_TOTAL_SENSOR_COUNT]; uint8 numBytes_OneData = sizeof(encodedData[0]); uint8 i; uint8 j; uint8 k; uint16 arrayIterator = 0; CYBLE_GATTS_HANDLE_VALUE_NTF_T NotificationHandle; CYBLE_GATTS_HANDLE_VALUE_IND_T IndicationHandle; uint16 numIterations; uint8 buffer[CYBLE_GATT_MTU]; numIterations = ( (vectorSize() * numBytes_OneData * CapSense_TOTAL_SENSOR_COUNT) < (negotiatedMtu - 3) ) ? vectorSize() : (negotiatedMtu - 3) / numBytes_OneData / CapSense_TOTAL_SENSOR_COUNT; uint16 numBytes_AllData = numIterations * numBytes_OneData * CapSense_TOTAL_SENSOR_COUNT; for( k = 0; k < numIterations; k++) { // Retrieve the front data in the vectors. popOutVector(rawData); // Encode the data with CRC. for (i = 0; i < CapSense_TOTAL_SENSOR_COUNT; i++) encodedData[i] = encodeCRC( rawData[i] ); // Transfer the encoded sensors values into an uint8 array. for (i = 0; i < CapSense_TOTAL_SENSOR_COUNT; i++) for (j = 0; j < numBytes_OneData; j++) buffer[arrayIterator++] = encodedData[i] >> ((numBytes_OneData - 1 - j) * 8) & 0xFF; } // Send the CapSense characteristic values to BLE client. if (sendDataNotifications) { NotificationHandle.attrHandle = CYBLE_CAPSENSE_SENSORS_CHAR_HANDLE; NotificationHandle.value.val = buffer; NotificationHandle.value.len = numBytes_AllData; CyBle_GattsNotification(connectionHandle, &NotificationHandle); } else if (sendDataIndications) { IndicationHandle.attrHandle = CYBLE_CAPSENSE_SENSORS_CHAR_HANDLE; IndicationHandle.value.val = buffer; IndicationHandle.value.len = numBytes_AllData; CyBle_GattsIndication(connectionHandle, &IndicationHandle); } // Verify if the vector is now empty. if ( vectorIsEmpty() ) return NO_MORE_DATA; return SUCCESS; }