For this example, the BLE stack VERSION was configure to create a Custom Profile with the KW40Z.
The Custom to create is the Humidity Sensor and is based on the Temperature Sensor.
The First thing to know is that the Generic Attribute Profile (GATT) establishes in detail how to exchange all profile and user data over a BLE connection. GATT deals only with actual data transfer procedures and formats. All standard BLE profiles are based on GATT and must comply with it to operate correctly. This makes GATT a key section of the BLE specification, because every single item of data relevant to applications and users must be formatted, packed, and sent according to the rules.
GATT defines two roles: Server and Client.
Figure 1. GATT Client-Server
GATT Database establishes a hierarchy to organize attributes. These are the Profile, Service, Characteristic and Descriptor. Profiles are high level definitions that define how services can be used to enable an application and Services are collections of characteristics. Descriptors are defined attributes that describe a characteristic value.
To define a GATT Database several macros are provided by the GATT_DB API.
Figure 2. GATT database
To know if the Profile or service is already defined on the specification, you have to look for on Bluetooth SIG profiles and check on the ble_sig_define module if is already declared on the code. In our case the Service is not declared(because is a Custom Profile) but the characteristic of the humidity it is on the specification but not on ble_sig_define.
/*! Humidity Charactristic UUID */
#define gBleSig_Humidity_d 0x2A6F
The Humidity Sensor is going to have the GATT Server, because is going to be the device that has all the information for the GATT Client.
The Application works like the Temperature Sensor, every time that you press the SW1 on USB is going to send the value.
On the Temperature Sensor demo have the Battery Service and Device Information, so you only have to change the Temperature Service to Humidity Service.
Figure 3. GATT database of Humidity Sensor
First thing to do is define the Humidity Server that has 16 bytes.
To define a new Server or a Characteristic is in gatt_uuid128.h which is located in the application folder.
All macros, function or structure in SDK have a common template which helps the application to act accordingly.
/* Humidity */
UUID128(uuid_service_humidity, 0xfe ,0x34 ,0x9b ,0x5f ,0x80 ,0x00 ,0x00 ,0x80 ,0x00 ,0x10 ,0x00 ,0x02 ,0x00 ,0xfa ,0x10 ,0x10)
All the Service and Characteristics is declared in gattdb.h. Descriptors are declared after the Characteristic Value declaration but before the next Characteristic declaration. In this case the permission is the CharPresFormatDescriptor that have specific description by the standard. The Units of the Humidity Characteristic is on Percentage that is 0x27AD.
Client Characteristic Configuration Descriptor(CCCD) is a descriptor where clients write some of the bits to activate Server notifications and/or indications
PRIMARY_SERVICE_UUID128(service_humidity, uuid_service_humidity)
CHARACTERISTIC(char_humidity, gBleSig_Humidity_d, (gGattCharPropNotify_c))
VALUE(value_humidity, gBleSig_Humidity_d, (gPermissionNone_c), 2, 0x00, 0x25)
DESCRIPTOR(desc_humidity, gBleSig_CharPresFormatDescriptor_d, (gPermissionFlagReadable_c), 7, 0x0E, 0x00, 0xAD, 0x27, 0x00, 0x00, 0x00)
CCCD(cccd_humidity)
After that, create a folder humidity in the next path C:\....\KW40Z_BLE_Software_1.1.2\ConnSw\bluetooth\profiles. Found the temperature folder, copy the temperature_service and paste inside of the humidity folder with another name (humidity_service)
Then go back and look for the interface folder, copy temperature_interface and change the name (humidity_interface) in the same path.
On the humidity_interface file should have the following code.
The Service structure has the service handle, and the initialization value.
/*! Humidity Service - Configuration */
typedef struct humsConfig_tag
{
uint16_t serviceHandle;
int16_t initialHumidity;
} humsConfig_t;
The next configuration structure is for the Client; in this case we don’t need it.
/*! Humidity Client - Configuration */
typedef struct humcConfig_tag
{
uint16_t hService;
uint16_t hHumidity;
uint16_t hHumCccd;
uint16_t hHumDesc;
gattDbCharPresFormat_t humFormat;
} humcConfig_t;
At minimum on humidity_service file, should have the following code.
The service stores the device identification for the connected client. This value is changed on subscription and non-subscription events.
/*! Humidity Service - Subscribed Client*/
static deviceId_t mHums_SubscribedClientId;
The initialization of the service is made by calling the start procedure. This function is usually called when the application is initialized. In this case is on the BleApp_Config(). On stop function, the unsubscribe function is called.
bleResult_t Hums_Start (humsConfig_t *pServiceConfig)
{
mHums_SubscribedClientId = gInvalidDeviceId_c;
return Hums_RecordHumidityMeasurement (pServiceConfig->serviceHandle,
pServiceConfig->initialHumidity);
}
bleResult_t Hums_Stop (humsConfig_t *pServiceConfig)
{
return Hums_Unsubscribe();
}
Depending on the complexity of the service, the API will implement additional functions. For the Humidity Sensor only have a one characteristic.
The measurement will be saving on the GATT database and send the notification to the client. This function will need the service handle and the new value as input parameters.
bleResult_t Hums_RecordHumidityMeasurement (uint16_t serviceHandle, int16_t humidity)
{
uint16_t handle;
bleResult_t result;
bleUuid_t uuid = Uuid16(gBleSig_Humidity_d);
/* Get handle of Humidity characteristic */
result = GattDb_FindCharValueHandleInService(serviceHandle,
gBleUuidType16_c, &uuid, &handle);
if (result != gBleSuccess_c)
return result;
/* Update characteristic value */
result = GattDb_WriteAttribute(handle, sizeof(uint16_t), (uint8_t*)&humidity);
if (result != gBleSuccess_c)
return result;
Hts_SendHumidityMeasurementNotification(handle);
return gBleSuccess_c;
}
After save the measurement on the GATT database with GattDb_WriteAttribute function we send the notification.
To send the notification, first have to get the CCCD and after check if the notification is active, if is active send the notification.
static void Hts_SendHumidityMeasurementNotification
(
uint16_t handle
)
{
uint16_t hCccd;
bool_t isNotificationActive;
/* Get handle of CCCD */
if (GattDb_FindCccdHandleForCharValueHandle(handle, &hCccd) != gBleSuccess_c)
return;
if (gBleSuccess_c == Gap_CheckNotificationStatus
(mHums_SubscribedClientId, hCccd, &isNotificationActive) &&
TRUE == isNotificationActive)
{
GattServer_SendNotification(mHums_SubscribedClientId, handle);
}
}
Steps to include the files into the demo.
1. Create a clone of the Temperature_Sensor with the name of Humidity_Sensor
2. Unzip the Humidity_Sensor folder.
3. In the fallowing path <kw40zConnSoft_intall_dir>\ConnSw\bluetooth\profiles\interface save the humidity_interface file.
4. In the <kw40zConnSoft_intall_dir>\ConnSw\bluetooth\profiles save the humidity folder
5. In the next directory <kw40zConnSoft_intall_dir>\ConnSw\examples\bluetooth\humidity_sensor\common replaces with the common folder.
Steps to include the paths into the demo using IAR Embedded Workbench
Once you already save the folders in the corresponding path you must to indicate in the demo where are they.
1. Drag the files into the corresponding folder. The principal menu is going to see like this.
Figure 4. Principal Menu
2. Then click Option
Figure 5. Option
3. Click on the C/C++ Compiler and then on the Preprocessor
Figure 6. Preposcessor Window
4. After that click on "..." button to edit the include directories and then click to add a new path.
Add the <kw40zConnSoft_intall_dir>\ConnSw\bluetooth\profile\humidity path.
Figure 7. Add a path
Finally compile and enjoy the demo!
NOTE: If you want to probe the demo using another board you must to run the humidity_collector demo too.
Figure 8. Example of the Humidity Sensor using the Humidity Collector demo.
josem.reyes.chaidez who else from your area can provide a quick review to this document to see if any comment/change is required?
After that this will be published.
Hello Karina, ilianatejeda will be reviewing this document this week to be published this week.
I followed this document for creating custom profile for my application in KW40Z development board
I am trying to change UUIDs in gatt_uuid128.h, but after changing no matter how many times i compile, i always see the old UUIDs when i discover services and characteristics using my mobile app, please explain am i missing something
FYI:
I am using the given bluetooth_wireless_uart_demo example code
I did not change anything other than the UUIDs
I am using IAR compiler (only supported tool now)
Hardware FRDM-KW40Z
Before :
UUID128(uuid_service_wireless_uart, 0xE0, 0x1C, 0x4B, 0x5E, 0x1E, 0xEB, 0xA1, 0x5C, 0xEE, 0xF4, 0x5E, 0xBA, 0x00, 0x01, 0xFF, 0x01)
UUID128(uuid_uart_stream, 0xE0, 0x1C, 0x4B, 0x5E, 0x1E, 0xEB, 0xA1, 0x5C, 0xEE, 0xF4, 0x5E, 0xBA, 0x01, 0x01, 0xFF, 0x01)
After:
UUID128(uuid_service_wireless_uart, 0xba, 0x1C, 0x4B, 0x5E, 0x1E, 0xEB, 0xA1, 0x5C, 0xEE, 0xF4, 0x5E, 0xBA, 0x00, 0x01, 0xFF, 0x01)
UUID128(uuid_uart_stream, 0xab, 0x1C, 0x4B, 0x5E, 0x1E, 0xEB, 0xA1, 0x5C, 0xEE, 0xF4, 0x5E, 0xBA, 0x01, 0x01, 0xFF, 0x01)
Hi chandramohanc,
Did you forget the previous paired device in your mobile app? I mean, could you please forget the device in your mobile application before make a reconnection to the device? We have seen that mobile devices used to keep the old information when connecting to devices that were paired before, it is because smartphones uses the address to identify such device.
On the other hand, I recommend to follow the next guide about custom profiles on NXP BLE stack:
Hi Jose,
Thanks for the response, i fixed the issue recently
1. If I clone the uart_wireless_demo using ConnectivitySoftwareProjectCloner choosing fullCodebase, modification in uuids doesn't take effect
2. If i clone the uart_wireless_demo using ConnectivitySoftwareProjectCloner choosing applicationFilesOnly fixes the issue
It is very strange that 1st option doesn't work
Hi Jose,
You are right, if i turn OFF and ON bluetooth in my mobile it catches the new changes related to GATT DB / UUIDs
thanks a lot !!