ljaynes wrote on June 13, 2019:
Here is my complete code for my ble service. I updated to the latest version of the release-1.5 and now I can only get it to work if I only add one characteristic.
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/*
* FreeRTOS includes.
*/
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "semphr.h"
#include "task.h"
/* AWS IoT include */
#include "iot_ble.h"
#include "SEGGER_RTT.h"
/*Characteristic Read Queues*/
xQueueHandle vehicle_meta_data_ble_queue;
xQueueHandle device_meta_data_ble_queue;
xQueueHandle auth_data_ble_queue;
/*Characteristic data storage*/
uint8_t vehicle_meta_data_buffer[256] = {0};
uint8_t device_meta_data_buffer[256] = {0};
uint8_t auth_data_buffer[256] = {0};
/*------------------------------------------------------------------------------------*/
#define app_SERVICE_BASE_UUID 0x00, 0xAA
#define app_SERVICE_UUID_MASK 0x32, 0xF9, 0x79, 0xE6, 0xB5, 0x83, 0xFB, 0x4E, 0xAF, 0x48, 0x68, 0x11, 0x7F, 0xAE
#define app_SERVICE_UUID {app_SERVICE_BASE_UUID, app_SERVICE_UUID_MASK }
/**
* @brief Service, characteristic and descriptor UUIDS for Device information Service
*/
#define app_CHAR_UUID_BASE app_SERVICE_UUID
#define app_VEHICLE_META_DATA { 0x01, 0xAA, app_SERVICE_UUID_MASK }
#define app_DEVICE_META_DATA { 0x02, 0xAA, app_SERVICE_UUID_MASK }
#define app_AUTH_DATA { 0x03, 0xAA, app_SERVICE_UUID_MASK }
#define app_SERIALIZED_DATA { 0x04, 0xAA, app_SERVICE_UUID_MASK }
#define app_CHAR_CFG_UUID 0x2902
/**
* @brief Structure used for Device Information Service
*/
typedef struct appService
{
BTService_t * pBLEService;
uint16_t CCFGVal;
uint16_t BLEConnId;
uint16_t BLEMtu;
} appService_t;
static appService_t app_service =
{
.pBLEService = NULL,
.BLEConnId = 65535,
.BLEMtu = 0,
.CCFGVal = 0
};
#define app_VEHICLE_META_UUID_TYPE \
{ \
.uu.uu128 = app_VEHICLE_META_DATA,\
.ucType = eBTuuidType128 \
}
#define app_DEVICE_META_UUID_TYPE \
{ \
.uu.uu128 = app_DEVICE_META_DATA,\
.ucType = eBTuuidType128 \
}
#define app_AUTH_DATA_UUID_TYPE \
{ \
.uu.uu128 = app_AUTH_DATA,\
.ucType = eBTuuidType128\
}
#define app_SERIALIZED_DATA_UUID_TYPE \
{ \
.uu.uu128 = app_SERIALIZED_DATA,\
.ucType = eBTuuidType128\
}
#define app_CHAR_CFG_UUID_TYPE \
{ \
.uu.uu16 = app_CHAR_CFG_UUID,\
.ucType = eBTuuidType16\
}
#define xappSvcUUID \
{ \
.uu.uu128 = app_SERVICE_UUID,\
.ucType = eBTuuidType128\
}
typedef enum {
ATTR_SERVICE,
ATTR_CHAR_VEH_META,
ATTR_VEH_META_DESCR,
ATTR_CHAR_DEV_META,
ATTR_DEV_META_DESCR,
ATTR_CHAR_AUTH_DATA,
ATTR_AUTH_DATA_DESCR,
ATTR_CHAR_SERIALIZED_DATA,
ATTR_SERIALIZED_DATA_DESCR,
ATTR_NUMBER
} app_attr_t;
static uint16_t app_handles_buffer[ATTR_NUMBER];
static const BTAttribute_t pAttributeTable[] = {
{
.xServiceUUID = xappSvcUUID
},
{
.xAttributeType = eBTDbCharacteristic,
.xCharacteristic =
{
.xUuid = app_VEHICLE_META_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM ),
.xProperties = ( eBTPropRead | eBTPropNotify )
}
},
{
.xAttributeType = eBTDbDescriptor,
.xCharacteristicDescr =
{
.xUuid = app_CHAR_CFG_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM )
}
},
{
.xAttributeType = eBTDbCharacteristic,
.xCharacteristic =
{
.xUuid = app_DEVICE_META_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM ),
.xProperties = ( eBTPropRead | eBTPropNotify )
}
},
{
.xAttributeType = eBTDbDescriptor,
.xCharacteristicDescr =
{
.xUuid = app_CHAR_CFG_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM )
}
},
{
.xAttributeType = eBTDbCharacteristic,
.xCharacteristic =
{
.xUuid = app_AUTH_DATA_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM ),
.xProperties = ( eBTPropRead | eBTPropNotify )
}
},
{
.xAttributeType = eBTDbDescriptor,
.xCharacteristicDescr =
{
.xUuid = app_CHAR_CFG_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM )
}
},
{
.xAttributeType = eBTDbCharacteristic,
.xCharacteristic =
{
.xUuid = app_SERIALIZED_DATA_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM ),
.xProperties = ( eBTPropRead | eBTPropNotify )
}
},
{
.xAttributeType = eBTDbDescriptor,
.xCharacteristicDescr =
{
.xUuid = app_CHAR_CFG_UUID_TYPE,
.xPermissions = ( IOT_BLE_CHAR_READ_PERM | IOT_BLE_CHAR_WRITE_PERM )
}
},
};
static const BTService_t appService =
{
.xNumberOfAttributes = ATTR_NUMBER,
.ucInstId = 0,
.xType = eBTServiceTypePrimary,
.pusHandlesBuffer = app_handles_buffer,
.pxBLEAttributes = (BTAttribute_t *)pAttributeTable
};
static void vehicle_meta_data_read_callback( IotBleAttributeEvent_t * pEventParam );
static void device_meta_data_read_callback( IotBleAttributeEvent_t * pEventParam );
static void auth_data_read_callback( IotBleAttributeEvent_t * pEventParam );
static void enable_characterisic_notifictions( IotBleAttributeEvent_t * pEventParam );
/**
* @brief Callback invoked MTU for the BLE connection changes.
*
* Updates the value for MTU characteristic. Sends a notification to GATT client if notification is enabled
* via Client Characteristic Configuration descriptoe
*
* @param connId[in] Connection Identifier
* @param usMtu[in] New MTU for the connection
*
*/
static void mtu_change_callback( uint16_t connId,
uint16_t usMtu );
/**
* @brief Callback invoked on a BLE connect and disconnect event
*
* Stores the connection ID of the BLE client for sending notifications.
*
* @param status BLE status of the operation
* @param connId Connection ID for the connection
* @param bConnected Is Connected or disconnected
* @param pxRemoteBdAddr Remote address of the client
*/
static void connection_callback( BTStatus_t status,
uint16_t connId,
bool bConnected,
BTBdaddr_t * pxRemoteBdAddr );
static const IotBleAttributeEventCallback_t pxCallBackArray[ATTR_NUMBER] =
{
NULL,
vehicle_meta_data_read_callback,
enable_characterisic_notifictions,
device_meta_data_read_callback,
enable_characterisic_notifictions,
auth_data_read_callback,
enable_characterisic_notifictions,
auth_data_read_callback,
enable_characterisic_notifictions,
};
/*-----------------------------------------------------------*/
void vehicle_meta_data_read_callback( IotBleAttributeEvent_t * pEventParam )
{
IotBleAttributeData_t attrData = { 0 };
IotBleEventResponse_t resp;
IotBleWriteEventParams_t * pxWriteParam;
uint8_t ucEvent;
resp.pAttrData = &attrData;
resp.rspErrorStatus = eBTRspErrorNone;
resp.eventStatus = eBTStatusFail;
resp.attrDataOffset = 0;
if( pEventParam->xEventType == eBLERead )
{
xQueueReceive(vehicle_meta_data_ble_queue, vehicle_meta_data_buffer, 0);
attrData.handle = pEventParam->pParamRead->attrHandle;
attrData.pData = vehicle_meta_data_buffer;
attrData.size = strlen( vehicle_meta_data_buffer );
IotBle_SendResponse( &resp, pEventParam->pParamRead->connId, pEventParam->pParamRead->transId );
}
}
void device_meta_data_read_callback( IotBleAttributeEvent_t * pEventParam )
{
IotBleAttributeData_t attrData = { 0 };
IotBleEventResponse_t resp;
if( pEventParam->xEventType == eBLERead )
{
xQueueReceive(device_meta_data_ble_queue, device_meta_data_buffer, 0);
attrData.handle = pEventParam->pParamRead->attrHandle;
attrData.pData = device_meta_data_buffer;
attrData.size = strlen( device_meta_data_buffer );
resp.pAttrData = &attrData;
resp.attrDataOffset = 0;
resp.eventStatus = eBTStatusSuccess;
resp.rspErrorStatus = eBTRspErrorNone;
IotBle_SendResponse( &resp, pEventParam->pParamRead->connId, pEventParam->pParamRead->transId );
}
}
void auth_data_read_callback( IotBleAttributeEvent_t * pEventParam )
{
IotBleAttributeData_t attrData = { 0 };
IotBleEventResponse_t resp;
if( pEventParam->xEventType == eBLERead )
{
xQueueReceive(auth_data_ble_queue, auth_data_buffer, 0);
attrData.handle = pEventParam->pParamRead->attrHandle;
attrData.pData = auth_data_buffer;
attrData.size = strlen( auth_data_buffer );
resp.pAttrData = &attrData;
resp.attrDataOffset = 0;
resp.eventStatus = eBTStatusSuccess;
resp.rspErrorStatus = eBTRspErrorNone;
IotBle_SendResponse( &resp, pEventParam->pParamRead->connId, pEventParam->pParamRead->transId );
}
}
/*-----------------------------------------------------------*/
void enable_characterisic_notifictions( IotBleAttributeEvent_t * pEventParam )
{
IotBleWriteEventParams_t * pWriteParam;
IotBleAttributeData_t attrData = { 0 };
IotBleEventResponse_t resp;
resp.pAttrData = &attrData;
resp.rspErrorStatus = eBTRspErrorNone;
resp.eventStatus = eBTStatusFail;
resp.attrDataOffset = 0;
if( ( pEventParam->xEventType == eBLEWrite ) || ( pEventParam->xEventType == eBLEWriteNoResponse ) )
{
pWriteParam = pEventParam->pParamWrite;
attrData.handle = pWriteParam->attrHandle;
if( pWriteParam->length == 2 )
{
app_service.CCFGVal = ( pWriteParam->pValue[ 1 ] << 8 ) | pWriteParam->pValue[ 0 ];
resp.eventStatus = eBTStatusSuccess;
}
if( pEventParam->xEventType == eBLEWrite )
{
attrData.pData = pWriteParam->pValue;
attrData.size = pWriteParam->length;
resp.attrDataOffset = pWriteParam->offset;
IotBle_SendResponse( &resp, pWriteParam->connId, pWriteParam->transId );
}
}
else if( pEventParam->xEventType == eBLERead )
{
attrData.handle = pEventParam->pParamRead->attrHandle;
attrData.pData = ( uint8_t * ) &app_service.CCFGVal;
attrData.size = 2;
resp.attrDataOffset = 0;
resp.eventStatus = eBTStatusSuccess;
IotBle_SendResponse( &resp, pEventParam->pParamRead->connId, pEventParam->pParamRead->transId );
}
}
static void mtu_change_callback( uint16_t connId,
uint16_t usMtu )
{
if( usMtu != app_service.BLEMtu )
{
SEGGER_RTT_printf(0, "MTU:%d
", usMtu);
}
}
static void connection_callback( BTStatus_t status,
uint16_t connId,
bool bConnected,
BTBdaddr_t * pxRemoteBdAddr )
{
if( status == eBTStatusSuccess )
{
if( bConnected == true )
{
app_service.BLEConnId = connId;
}
}
}
size_t app_ble_send(uint8_t attribute,
uint8_t * pData,
size_t len)
{
IotBleAttributeData_t attrData = { 0 };
IotBleEventResponse_t response =
{
.pAttrData = &attrData,
.attrDataOffset = 0,
.eventStatus = eBTStatusSuccess,
.rspErrorStatus = eBTRspErrorNone,
};
bool status = true;
attrData.handle = appService.pusHandlesBuffer[attribute];
attrData.uuid = appService.pxBLEAttributes[attribute].xCharacteristic.xUuid;
attrData.pData = pData;
attrData.size = len;
if( IotBle_SendIndication( &response, app_service.BLEConnId, false ) != eBTStatusSuccess )
{
status = false;
}
return status;
}
/*-----------------------------------------------------------*/
BaseType_t ble_init( void )
{
BTStatus_t status = eBTStatusFail;
BaseType_t error = pdFAIL;
IotBleEventsCallbacks_t callback;
/* Select the handle buffer. */
status = IotBle_CreateService( (BTService_t *)&appService, (IotBleAttributeEventCallback_t *)pxCallBackArray );
if( status == eBTStatusSuccess )
{
callback.pMtuChangedCb = mtu_change_callback;
status = IotBle_RegisterEventCb( eBLEMtuChanged, callback );
}
if( status == eBTStatusSuccess )
{
callback.pConnectionCb = connection_callback;
status = IotBle_RegisterEventCb( eBLEConnection, callback );
}
if( status == eBTStatusSuccess )
{
error = pdPASS;
vehicle_meta_data_ble_queue = xQueueCreate( 1, sizeof(vehicle_meta_data_buffer) );
device_meta_data_ble_queue = xQueueCreate( 1, sizeof(device_meta_data_buffer) );
auth_data_ble_queue = xQueueCreate( 1, sizeof(auth_data_buffer) );
}
return error;
}
/*-----------------------------------------------------------*/
void IotBle_AddCustomServicesCb(void)
{
ble_init();
}