Trying to create a simple BLE service to notify with log messages

⚠️
Hi there.. thanks for coming to the forums. Exciting news! we’re now in the process of moving to our new forum platform that will offer better functionality and is contained within the main Dialog website. All posts and accounts have been migrated. We’re now accepting traffic on the new forum only - please POST any new threads at//www.wsdof.com/support. We’ll be fixing bugs / optimising the searching and tagging over the coming days.
3 posts / 0 new
Last post
alarner
Offline
Last seen:2 months 2 weeks ago
Joined:2017-05-27 02:11
Trying to create a simple BLE service to notify with log messages

Hello, I'm trying to create a simple BLE service that I can use to log messages to a mobile client. I'm working from the cts service but trying to simplify it. I've included the code below. The issue that I'm running into is that when I connect to the peripheral via my phone I do not see the service defined below. I do however see all of the other services that I've set up (device information, immediate alert, link loss, tx power, battery service, etc). What am I missing?

log_service.h

#include "osal.h"
#include "ble_service.h"
#include "ble_uuid.h"

#define UUID_SERVICE_LOG "6c8f78d9-292e-4b0d-b583-1616a777edbb"
#define UUID_CURRENT_LOG "b8ce3c4f-3ea0-47f3-8efb-f48732f99ba9"

typedef struct {
ble_service_t svc;

// handles
uint16_t log_val_h; // Current log value
} log_service_t;

ble_service_t *ls_init()
{
log_service_t *logService;
return &logService->svc;
uint16_t num_attr;
att_uuid_t uuid;

logService = OS_MALLOC(sizeof(*logService));
memset(logService, 0, sizeof(*logService));

/*
* one characteristic for the log value
*/
num_attr = ble_gatts_get_num_attr(0, 1, 0);

ble_uuid_create16(UUID_SERVICE_LOG, &uuid);
ble_gatts_add_service(&uuid, GATT_SERVICE_PRIMARY, num_attr);

// Write is optional, if set_time_cb is not NULL make characteristic READ/WRITE
ble_uuid_create16(UUID_CURRENT_LOG, &uuid);
ble_gatts_add_characteristic(&uuid, GATT_PROP_READ | GATT_PROP_NOTIFY,
ATT_PERM_READ, 512,
GATTS_FLAG_CHAR_READ_REQ, NULL, &logService->log_val_h);

ble_gatts_register_service(&logService->svc.start_h, &logService->log_val_h, 0);
logService->svc.end_h = logService->svc.start_h + num_attr;

ble_service_add(&logService->svc);

return &logService->svc;
}

bluetooth_task.c

...
ble_service_t *logService = ls_init();
...

Device:
alarner
Offline
Last seen:2 months 2 weeks ago
Joined:2017-05-27 02:11
Scratch that. I figured it

Scratch that. I figured it out. For anyone else trying to do something similar here is the most bare bones code I could come up with for the service:


#include
#include
#include "osal.h"
#include "ble_att.h"
#include "ble_bufops.h"
#include "ble_common.h"
#include "ble_gatts.h"
#include "ble_uuid.h"
#include "ble_storage.h"
#include "ble_service.h"

#define UUID_SERVICE_LOG "your service uuid"
#define UUID_CHARACTERISTIC_LOG "your characteristic uuid"

static const char log_desc[] = "Log Data";

typedef struct {
ble_service_t svc;
uint16_t log_val_h; // Current Time
uint16_t log_ccc_h;
} log_service_t;

static void cleanup(ble_service_t *svc)
{
log_service_t *ls = (log_service_t *) svc;

ble_storage_remove_all(ls->log_val_h);
ble_storage_remove_all(ls->log_ccc_h);

OS_FREE(svc);
}

static att_error_t handle_log_ccc_write(log_service_t *ls, uint16_t conn_idx,
uint16_t offset, uint16_t length, const uint8_t *value)
{
uint16_t ccc;

if (offset) {
return ATT_ERROR_ATTRIBUTE_NOT_LONG;
}

if (length != sizeof(ccc)) {
返回ATT_ERROR_APPLICATION_ERROR;
}

ccc = get_u16(value);

ble_storage_put_u32(conn_idx, ls->log_ccc_h, ccc, true);

return ATT_ERROR_OK;
}

静态孔隙handle_write_req (ble_service_t * svc, const ble_evt_gatts_write_req_t *evt)
{
log_service_t *ls = (log_service_t *) svc;
att_error_t status = ATT_ERROR_ATTRIBUTE_NOT_FOUND;
uint16_t handle = evt->handle;

if (handle == ls->log_ccc_h) {
status = handle_log_ccc_write(ls, evt->conn_idx, evt->offset, evt->length, evt->value);
}

ble_gatts_write_cfm(evt->conn_idx, evt->handle, status);
}

ble_service_t *log_init()
{
log_service_t *ls;
uint16_t num_attr, log_desc_h;
att_uuid_t uuid;

ls = OS_MALLOC(sizeof(*ls));
memset(ls, 0, sizeof(*ls));

num_attr = ble_gatts_get_num_attr(0, 1, 2);

ble_uuid_from_string(UUID_SERVICE_LOG, &uuid);
ble_gatts_add_service(&uuid, GATT_SERVICE_PRIMARY, num_attr);

ble_uuid_from_string(UUID_CHARACTERISTIC_LOG, &uuid);
ble_gatts_add_characteristic(
&uuid,
GATT_PROP_READ | GATT_PROP_NOTIFY,
ATT_PERM_READ,
512,
0,
NULL,
&ls->log_val_h
);

ble_uuid_create16(UUID_GATT_CLIENT_CHAR_CONFIGURATION, &uuid);
ble_gatts_add_descriptor(&uuid, ATT_PERM_RW, 2, 0, &ls->log_ccc_h);

ble_uuid_create16(UUID_GATT_CHAR_USER_DESCRIPTION, &uuid);
ble_gatts_add_descriptor(&uuid, ATT_PERM_READ, sizeof(log_desc), 0, &log_desc_h);

ble_gatts_register_service(&ls->svc.start_h, &ls->log_val_h, &ls->log_ccc_h, &log_desc_h, 0);

ble_gatts_set_value(ls->log_val_h, 4, "test");
ble_gatts_set_value(log_desc_h, sizeof(log_desc), log_desc);

ls->svc.cleanup = cleanup;
ls->svc.end_h = ls->svc.start_h + num_attr;
ls->svc.write_req = handle_write_req;

ble_service_add(&ls->svc);

return &ls->svc;
}

void log_notify(ble_service_t *svc, uint16_t conn_idx, uint8_t *data, uint16_t len) {
log_service_t *logService = (log_service_t *) svc;

ble_gatts_send_event(conn_idx, logService->log_val_h, GATT_EVENT_NOTIFICATION, len, data);
}

PM_Dialog
Offline
Last seen:14 hours 26 min ago
Staff
Joined:2018-02-08 11:03
Hi alarner,

Hi alarner,

Glad that you figured your issue out. Thanks for your indication and thanks for accepting your very useful answer for the other customers.

Thanks, PM_DIalog