Hi
I have created a code in segger for NRF 52840. I have created my custom service/characteristic and also the LED and Battery Level. Other Service like LED and Battery Level shows values in text or percentage. But my custom characteristic always shows in hexadecimal. Can i change it to long int or text? if so how do i? Also when i write values in any characteristic for example: if i write 123 the value shows as 7B,"{". why the extra bracket coming?
#include <stdint.h>
#include <string.h>
#include "nrf_gpio.h"
#include "our_service.h"
#include "ble_srv_common.h"
#include "app_error.h"
int32_t last_temperature = -1;
#define MAX_LEN 255
// ALREADY_DONE_FOR_YOU: Declaration of a function that will take care of some housekeeping of ble connections related to our service and characteristic
void ble_our_service_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
ble_os_t * p_our_service =(ble_os_t *) p_context;
// OUR_JOB: Step 3.D Implement switch case handling BLE events related to our service.
switch(p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
p_our_service->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
break;
case BLE_GAP_EVT_DISCONNECTED:
p_our_service->conn_handle = BLE_CONN_HANDLE_INVALID;
break;
default:
break;
}
}
/**@brief Function for adding our new characterstic to "Our service" that we initiated in the previous tutorial.
*
* @param[in] p_our_service Our Service structure.
*
*/
static uint32_t our_char_add(ble_os_t * p_our_service, char_type_t char_type)
{
// OUR_JOB: Step 2.A, Add a custom characteristic UUID
uint32_t err_code;
ble_uuid_t char_uuid;
ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
static uint8_t zero_init[MAX_LEN] = {0};
switch (char_type)
{
case hospital_char:
char_uuid.uuid = BLE_UUID_OUR_HOSPITAL_UUID;
break;
case branch_char:
char_uuid.uuid = BLE_UUID_OUR_BRANCH_UUID;
break;
case ward_char:
char_uuid.uuid = BLE_UUID_OUR_WARD_UUID;
break;
case bed_char:
char_uuid.uuid = BLE_UUID_OUR_BED_UUID;
break;
default:
break;
}
err_code = sd_ble_uuid_vs_add(&base_uuid, &char_uuid.type);
APP_ERROR_CHECK(err_code);
// OUR_JOB: Step 2.F Add read/write properties to our characteristic
ble_gatts_char_md_t char_md;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.read = 1;
char_md.char_props.write = 1;
// OUR_JOB: Step 3.A, Configuring Client Characteristic Configuration Descriptor metadata and add to char_md structure
ble_gatts_attr_md_t cccd_md;
memset(&cccd_md, 0, sizeof(cccd_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
char_md.p_cccd_md = &cccd_md;
char_md.char_props.notify = 1;
// OUR_JOB: Step 2.B, Configure the attribute metadata
ble_gatts_attr_md_t attr_md;
memset(&attr_md, 0, sizeof(attr_md));
attr_md.vloc = BLE_GATTS_VLOC_STACK;
// For example if you need Man In The Middle protection (MITM) or a passkey to access your attribute. We will circle back to this.
// OUR_JOB: Step 2.G, Set read/write security levels to our characteristic
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
// OUR_JOB: Step 2.C, Configure the characteristic value attribute
ble_gatts_attr_t attr_char_value;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &char_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.max_len = sizeof(uint8_t);
attr_char_value.init_len = sizeof(uint8_t);
//uint8_t value = 123;
//attr_char_value.p_value = &value;
attr_char_value.p_value = zero_init;
// OUR_JOB: Step 2.H, Set characteristic length in number of bytes
// OUR_JOB: Step 2.E, Add our new characteristic to the service
switch (char_type)
{
case hospital_char:
err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
&char_md,
&attr_char_value,
&p_our_service->char_hospital_handles);
APP_ERROR_CHECK(err_code);
break;
case branch_char:
err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
&char_md,
&attr_char_value,
&p_our_service->char_branch_handles);
APP_ERROR_CHECK(err_code);
break;
case ward_char:
err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
&char_md,
&attr_char_value,
&p_our_service->char_ward_handles);
APP_ERROR_CHECK(err_code);
break;
case bed_char:
err_code = sd_ble_gatts_characteristic_add(p_our_service->service_handle,
&char_md,
&attr_char_value,
&p_our_service->char_bed_handles);
APP_ERROR_CHECK(err_code);
break;
default:
break;
}
return NRF_SUCCESS;
}
/**@brief Function for initiating our new service.
*
* @param[in] p_our_service Our Service structure.
*
*/
void our_service_init(ble_os_t * p_our_service)
{
uint32_t err_code; // Variable to hold return codes from library and softdevice functions
// FROM_SERVICE_TUTORIAL: Declare 16-bit service and 128-bit base UUIDs and add them to the BLE stack
ble_uuid_t service_uuid;
ble_uuid128_t base_uuid = BLE_UUID_OUR_BASE_UUID;
service_uuid.uuid = BLE_UUID_OUR_SERVICE_UUID;
err_code = sd_ble_uuid_vs_add(&base_uuid, &service_uuid.type);
APP_ERROR_CHECK(err_code);
// OUR_JOB: Step 3.B, Set our service connection handle to default value. I.e. an invalid handle since we are not yet in a connection.
p_our_service->conn_handle = BLE_CONN_HANDLE_INVALID;
// FROM_SERVICE_TUTORIAL: Add our service
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
&service_uuid,
&p_our_service->service_handle);
APP_ERROR_CHECK(err_code);
// OUR_JOB: Call the function our_char_add() to add our new characteristic to the service.
our_char_add(p_our_service, hospital_char);
our_char_add(p_our_service, branch_char);
our_char_add(p_our_service, ward_char);
our_char_add(p_our_service, bed_char);
}
// ALREADY_DONE_FOR_YOU: Function to be called when updating characteristic value
void our_temperature_characteristic_update(ble_os_t *p_our_service, int32_t *temperature_value)
{
if (last_temperature != *temperature_value)
{
// OUR_JOB: Step 3.E, Update characteristic value
if (p_our_service->conn_handle != BLE_CONN_HANDLE_INVALID)
{
uint16_t len = 4;
ble_gatts_hvx_params_t hvx_params;
memset(&hvx_params, 0, sizeof(hvx_params));
hvx_params.handle = p_our_service->char_hospital_handles.value_handle;
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
hvx_params.offset = 0;
hvx_params.p_len = &len;
hvx_params.p_data = (uint8_t*) temperature_value;
sd_ble_gatts_hvx(p_our_service->conn_handle, &hvx_params);
}
}
last_temperature = *temperature_value;
}