6#include "dawn/proto/nimble/prph.hxx"
12#include "dawn/proto/nimble/prph_aios.hxx"
13#include "dawn/proto/nimble/prph_bas.hxx"
14#include "dawn/proto/nimble/prph_custom.hxx"
15#include "dawn/proto/nimble/prph_dis.hxx"
16#include "dawn/proto/nimble/prph_ess.hxx"
17#include "dawn/proto/nimble/prph_imds.hxx"
18#include "dawn/proto/nimble/prph_ots.hxx"
19#include "host/ble_hs.h"
20#include "host/util/util.h"
21#include "nimble/nimble_npl.h"
22#include "nimble/nimble_port.h"
23#include "services/gap/ble_svc_gap.h"
24#include "services/gatt/ble_svc_gatt.h"
28#ifdef CONFIG_DAWN_PROTO_NIMBLE_TPS
29extern "C" void ble_svc_tps_init();
32int CProtoNimblePrph::configureDesc(
const CDescObject &desc)
37 for (
size_t i = 0; i < desc.
getSize(); i++)
43 DAWNERR(
"Unsupported Nimble config 0x%08" PRIx32
"\n", item->
cfgid.
v);
51 const char *name =
reinterpret_cast<const char *
>(item->
data);
53 CProtoNimbleAdv::setGapName(name, item->
cfgid.
s.
size * 4);
57#ifdef CONFIG_DAWN_PROTO_NIMBLE_DIS
62 vservices.push_back(tmp);
67#ifdef CONFIG_DAWN_PROTO_NIMBLE_BAS
72 vservices.push_back(tmp);
77#ifdef CONFIG_DAWN_PROTO_NIMBLE_AIOS
82 vservices.push_back(tmp);
87#ifdef CONFIG_DAWN_PROTO_NIMBLE_ESS
92 vservices.push_back(tmp);
97#ifdef CONFIG_DAWN_PROTO_NIMBLE_IMDS
102 vservices.push_back(tmp);
107#ifdef CONFIG_DAWN_PROTO_NIMBLE_OTS
112 vservices.push_back(tmp);
121 vservices.push_back(tmp);
127 DAWNERR(
"Unsupported Nimble config 0x%08" PRIx32
"\n", item->
cfgid.
v);
136void CProtoNimblePrph::servicesDefault()
146#ifdef CONFIG_DAWN_PROTO_NIMBLE_TPS
153int CProtoNimblePrph::servicesCount()
157 size_t count = std::count_if(
158 vSvcDefs.begin(), vSvcDefs.end(), [](
const ble_gatt_svc_def *svc) { return svc != nullptr; });
159 if (count > UCHAR_MAX - 1)
166 return static_cast<int>(count + 1);
169int CProtoNimblePrph::servicesInit()
173 ret = ble_gatts_count_cfg(svcDefs);
176 DAWNERR(
"ble_gatts_count_cfg failed: %d\n", ret);
180 ret = ble_gatts_add_svcs(svcDefs);
183 DAWNERR(
"ble_gatts_add_svcs failed: %d\n", ret);
190int CProtoNimblePrph::servicesCreate()
196 if (svcDefs !=
nullptr)
203 svcCount = servicesCount();
206 DAWNERR(
"servicesCount failed: %d\n", svcCount);
210 noAllocServices =
static_cast<uint8_t
>(svcCount);
214 svcDefs =
new (std::nothrow) ble_gatt_svc_def[noAllocServices]();
215 if (svcDefs ==
nullptr)
217 DAWNERR(
"Failed to allocate service definitions\n");
224 for (
const struct ble_gatt_svc_def *svc : vSvcDefs)
228 std::memcpy(&svcDefs[i], svc,
sizeof(
struct ble_gatt_svc_def));
235 ret = servicesInit();
238 DAWNERR(
"servicesInit failed: %d\n", ret);
248void CProtoNimblePrph::bleSyncCb()
255 ret = ble_hs_id_gen_rnd(1, &addr);
258 DAWNERR(
"ble_hs_id_gen_rnd failed: %d\n", ret);
264 ret = ble_hs_id_set_rnd(addr.val);
267 DAWNERR(
"ble_hs_id_set_rnd failed: %d\n", ret);
271 ret = ble_hs_util_ensure_addr(0);
274 DAWNERR(
"ble_hs_util_ensure_addr failed: %d\n", ret);
281 DAWNERR(
"ble_hs_id_infer_auto failed: %d\n", ret);
285 CProtoNimbleAdv::startAdvertise();
288CProtoNimblePrph::~CProtoNimblePrph()
294 for (
auto s : vservices)
310 ret = configureDesc(
getDesc());
313 DAWNERR(
"Nimble configure failed: %d\n", ret);
327 for (
auto s : vservices)
332 DAWNERR(
"failed to init service %p\n", s);
344 for (
auto s : vservices)
346 int ret = s->deinit();
349 DAWNERR(
"failed to deinit service %p\n", s);
353 if (svcDefs !=
nullptr)
367 for (
auto s : vservices)
369 int ret = s->start();
372 DAWNERR(
"failed to start service %p\n", s);
384 for (
auto s : vservices)
389 DAWNERR(
"failed to stop service %p\n", s);
398 return hci.isRunning() || host.isRunning();
406 if (vSvcDefs.size() >=
static_cast<size_t>(INT_MAX))
413 vSvcDefs.push_back(svc);
414 vstart.push_back(
false);
418 return static_cast<int>(vSvcDefs.size() - 1);
425 if (
id < 0 || (
size_t)
id >= vstart.size())
432 vstart.at(
id) =
true;
436 if (std::any_of(vstart.begin(), vstart.end(), [](
bool en) { return !en; }))
445 ret = servicesCreate();
448 DAWNERR(
"servicesCreate failed: %d\n", ret);
456 ble_hs_cfg.sync_cb = CProtoNimblePrph::bleSyncCb;
466 if (
id < 0 || (
size_t)
id >= vstart.size())
477 if (std::any_of(vstart.begin(), vstart.end(), [](
bool en) { return en; }))
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
CDescObject & getDesc()
Get descriptor object for this object.
@ PROTO_CLASS_NIMBLE_PRPH
BLE Peripheral using Apache NimBLE stack.
static char gapName[GAPNAME_MAX+1]
GAP device name visible during BLE discovery.
static uint8_t ownAddrType
BLE device address type (random/static/public).
Automation I/O Service (AIOS) for BLE Peripheral.
Battery Service (BAS) for BLE Peripheral.
Custom Service defined by user.
Device Information Service (DIS) for BLE Peripheral.
Environmental Sensing Service (ESS) for BLE Peripheral.
Industrial Measurement Device Service (IMDS) for BLE Peripheral.
Object Transfer Service (OTS) for BLE Peripheral.
int stopService(int id)
Stop a specific service.
int doStart()
Start implementation hook.
@ PROTO_NIMBLE_CFG_IOBIND_CUSTOM
Generic custom service binding.
@ PROTO_NIMBLE_CFG_IOBIND_OTS
Object Transfer Service binding.
@ PROTO_NIMBLE_CFG_IOBIND_ESS
Environmental Sensing Service binding.
@ PROTO_NIMBLE_CFG_IOBIND_AIOS
Automation I/O Service binding.
@ PROTO_NIMBLE_CFG_IOBIND_BAS
Battery Service binding.
@ PROTO_NIMBLE_CFG_IOBIND_DIS
Device Information Service binding.
@ PROTO_NIMBLE_CFG_GAPNAME
GAP device name configuration.
@ PROTO_NIMBLE_CFG_IOBIND_IMDS
Industrial Measurement Device Service binding.
int startService(int id)
Start a specific service.
int configure()
Configure object from descriptor data.
int serviceRegister(struct ble_gatt_svc_def *svc)
Register a GATT service with the peripheral.
int deinit()
De-initialize object.
bool hasThread() const
Check if a background thread is active.
int doStop()
Stop implementation hook.
Interface for BLE peripheral services with GATT characteristics.
Base interface for GATT services exposed by BLE 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).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.