6#include "dawn/proto/nimble/prph_custom.hxx"
12#include "host/ble_hs_mbuf.h"
13#include "host/ble_uuid.h"
14#include "os/os_mbuf.h"
18#ifdef CONFIG_DAWN_IO_NOTIFY
19int CProtoNimblePrphCustom::notifierCb(
void *priv,
io_ddata_t *data)
21 SCustomCharCb *ccb =
static_cast<SCustomCharCb *
>(priv);
23 if (ccb ==
nullptr || ccb->io ==
nullptr || ccb->data ==
nullptr)
28 std::memcpy(ccb->data->getDataPtr(), data->
getDataPtr(), ccb->data->getDataSize());
29 ble_gatts_chr_updated(ccb->handle);
34int CProtoNimblePrphCustom::callback(uint16_t conn_handle,
36 struct ble_gatt_access_ctxt *ctxt,
39 SCustomCharCb *ccb =
static_cast<SCustomCharCb *
>(arg);
42 if (ccb ==
nullptr || ccb->io ==
nullptr || ccb->data ==
nullptr)
44 return BLE_ATT_ERR_UNLIKELY;
49 case BLE_GATT_ACCESS_OP_READ_CHR:
51 ret = ccb->io->getData(*ccb->data, 1);
54 return BLE_ATT_ERR_UNLIKELY;
57 ret = os_mbuf_append(ctxt->om, ccb->data->getDataPtr(), ccb->data->getDataSize());
58 return ret < 0 ? BLE_ATT_ERR_UNLIKELY : 0;
61 case BLE_GATT_ACCESS_OP_WRITE_CHR:
66 ble_hs_mbuf_to_flat(ctxt->om, ccb->data->getDataPtr(), ccb->data->getDataSize(), &len);
69 return BLE_ATT_ERR_UNLIKELY;
72 ret = ccb->io->setData(*ccb->data);
73 return ret < 0 ? BLE_ATT_ERR_UNLIKELY : 0;
77 return BLE_ATT_ERR_UNLIKELY;
88 std::memset(&svc, 0,
sizeof(svc));
91CProtoNimblePrphCustom::~CProtoNimblePrphCustom()
98 const SProtoNimblePrphCustomSvc *blob;
101 blob =
reinterpret_cast<const SProtoNimblePrphCustomSvc *
>(item->
data);
104 svc.type = BLE_GATT_SVC_TYPE_PRIMARY;
105 svc.includes =
nullptr;
108 for (uint32_t i = 0; i < count; i++)
111 entry.objid = blob->chr[i].objid.v;
112 entry.flags =
static_cast<uint8_t
>(blob->chr[i].flags & 0xff);
113 std::memcpy(entry.uuid, blob->chr[i].uuid,
sizeof(entry.uuid));
114 vchars.push_back(entry);
116 vio.push_back(entry.objid);
120int CProtoNimblePrphCustom::allocCustom()
122 const SProtoNimblePrphCustomSvc *blob;
124 blob =
reinterpret_cast<const SProtoNimblePrphCustomSvc *
>(
desc->
data);
126 chrs =
new (std::nothrow) ble_gatt_chr_def[vchars.size() + 1]();
132 ble_uuid128_t *svc_uuid =
new (std::nothrow) ble_uuid128_t{};
133 if (svc_uuid ==
nullptr)
140 svc_uuid->u.type = BLE_UUID_TYPE_128;
141 std::memcpy(svc_uuid->value, blob->uuid,
sizeof(svc_uuid->value));
142 svc.uuid = &svc_uuid->u;
143 svc.characteristics = chrs;
147int CProtoNimblePrphCustom::createCustom()
149 for (
size_t i = 0; i < vchars.size(); i++)
153 uint8_t effective = 0;
160 if (vchars[i].flags & CUSTOM_CHR_F_READ && io->
isRead())
162 effective |= BLE_GATT_CHR_F_READ;
165 if (vchars[i].flags & CUSTOM_CHR_F_WRITE && io->
isWrite())
167 effective |= BLE_GATT_CHR_F_WRITE;
170#ifdef CONFIG_DAWN_IO_NOTIFY
171 if (vchars[i].flags & CUSTOM_CHR_F_NOTIFY && io->
isNotify())
173 effective |= BLE_GATT_CHR_F_NOTIFY;
182 ble_uuid128_t *chr_uuid =
new (std::nothrow) ble_uuid128_t{};
183 ccb =
new (std::nothrow) SCustomCharCb{};
184 if (chr_uuid ==
nullptr || ccb ==
nullptr)
191 chr_uuid->u.type = BLE_UUID_TYPE_128;
192 std::memcpy(chr_uuid->value, vchars[i].uuid,
sizeof(chr_uuid->value));
197 if (ccb->data ==
nullptr)
204#ifdef CONFIG_DAWN_IO_NOTIFY
205 if (effective & BLE_GATT_CHR_F_NOTIFY)
207 int ret = io->setNotifier(notifierCb, 0, ccb);
220 chrs[i].uuid = &chr_uuid->u;
221 chrs[i].access_cb = callback;
223 chrs[i].descriptors =
nullptr;
224 chrs[i].flags = effective;
225 chrs[i].min_key_size = 0;
226 chrs[i].val_handle = (effective & BLE_GATT_CHR_F_NOTIFY) ? &ccb->handle : nullptr;
232void CProtoNimblePrphCustom::deleteCustom()
234 for (
auto *ccb : vcbs)
238#ifdef CONFIG_DAWN_IO_NOTIFY
239 if (ccb->io !=
nullptr && ccb->io->isNotify())
241 ccb->io->setNotifier(
nullptr, 0,
nullptr);
245 if (ccb->data !=
nullptr)
256 for (
size_t i = 0; i < vchars.size(); i++)
258 if (chrs[i].uuid !=
nullptr)
260 delete reinterpret_cast<const ble_uuid128_t *
>(chrs[i].uuid);
268 if (svc.uuid !=
nullptr)
270 delete reinterpret_cast<const ble_uuid128_t *
>(svc.uuid);
274 svc.characteristics =
nullptr;
290 return id < 0 ? -EIO : OK;
308 ret = createCustom();
Base class for all I/O objects.
virtual bool isWrite() const =0
Check if IO supports write operations.
virtual bool isNotify() const =0
Check if IO supports notifications.
io_ddata_t * ddata_alloc(size_t batch, size_t chunk_size=0)
Allocate data buffer for this I/O.
virtual bool isRead() const =0
Check if IO supports read operations.
int deinit()
Deinitialize service.
int init()
Initialize service.
int start()
Start service.
Interface for BLE peripheral services with GATT characteristics.
virtual int startService(int id)=0
Start a specific service.
virtual CIOCommon * getObject(SObjectId::ObjectId id)=0
Get protocol object by ID.
virtual int serviceRegister(struct ble_gatt_svc_def *svc)=0
Register a GATT service with the peripheral.
virtual void regObject(SObjectId::ObjectId id)=0
Register an I/O object for this service.
virtual int stopService(int id)=0
Stop a specific service.
Base interface for GATT services exposed by BLE peripheral.
std::vector< SObjectId::ObjectId > vio
Vector of I/O objects exposed by this service.
const SObjectCfg::SObjectCfgItem * desc
Configuration descriptor for this service.
IProtoNimblePrphCb * cb
Callback interface to peripheral.
Out-of-tree user-extension hooks for Dawn.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
Heap-allocated dynamic I/O data buffer.
void * getDataPtr(size_t batch=0)
Get pointer to data only (skips timestamp if present).