Dawn Framework 1.0
Universal data acquisition framework for embedded systems
prph_ots.hxx
1// dawn/include/dawn/proto/nimble/prph_ots.hxx
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5
6#pragma once
7
8#include <map>
9#include <vector>
10
11#include "dawn/porting/config.hxx"
12#include "dawn/proto/nimble/iprph.hxx"
13#include "host/ble_gatt.h"
14#include "host/ble_l2cap.h"
15
16namespace dawn
17{
42{
43public:
46 constexpr static uint16_t UUID16_OTS = 0x1825;
47
50 constexpr static uint16_t UUID16_FEATURE = 0x2abd;
51
54 constexpr static uint16_t UUID16_OBJ_NAME = 0x2abe;
55
58 constexpr static uint16_t UUID16_OBJ_TYPE = 0x2abf;
59
62 constexpr static uint16_t UUID16_OBJ_SIZE = 0x2ac0;
63
66 constexpr static uint16_t UUID16_OBJ_ID = 0x2ac3;
67
70 constexpr static uint16_t UUID16_OBJ_PROPS = 0x2ac4;
71
74 constexpr static uint16_t UUID16_OACP = 0x2ac5;
75
78 constexpr static uint16_t UUID16_OLCP = 0x2ac6;
79
82 constexpr static uint16_t OBJ_TYPE_UNSPECIFIED = 0x2aca;
83
92 constexpr static uint16_t OBJ_TYPE_DESCRIPTOR = 0xffe0;
93
101 constexpr static uint16_t OBJ_TYPE_CAPS = 0xffe1;
102
105 constexpr static uint16_t L2CAP_PSM_OTS = 0x0025;
106
109 constexpr static uint16_t L2CAP_MTU_OTS = 512;
110
113 enum
114 {
115 OBJ_PROP_DELETE = 1u << 0,
116 OBJ_PROP_EXECUTE = 1u << 1,
117 OBJ_PROP_READ = 1u << 2,
118 OBJ_PROP_WRITE = 1u << 3,
119 OBJ_PROP_APPEND = 1u << 4,
120 OBJ_PROP_TRUNC = 1u << 5,
121 OBJ_PROP_PATCH = 1u << 6,
122 OBJ_PROP_MARKED = 1u << 7
123 };
124
127 enum
128 {
129 OACP_OP_CREATE = 0x01,
130 OACP_OP_DELETE = 0x02,
131 OACP_OP_READ = 0x04,
132 OACP_OP_EXECUTE = 0x05,
133 OACP_OP_WRITE = 0x06,
134 OACP_OP_ABORT = 0x07,
135 OACP_OP_RESPONSE = 0x60
136 };
137
140 enum
141 {
142 OACP_RES_SUCCESS = 0x01,
144 OACP_RES_INVALID_PARAM = 0x03,
145 OACP_RES_INSUF_RES = 0x04,
146 OACP_RES_INVALID_OBJ = 0x05,
147 OACP_RES_CHANNEL_UNAVAIL = 0x06,
148 OACP_RES_PROC_NOT_PERM = 0x07,
149 OACP_RES_OBJ_LOCKED = 0x08,
150 OACP_RES_OPER_FAILED = 0x0a
151 };
152
155 enum
156 {
157 OLCP_OP_FIRST = 0x01,
158 OLCP_OP_LAST = 0x02,
159 OLCP_OP_PREVIOUS = 0x03,
160 OLCP_OP_NEXT = 0x04,
161 OLCP_OP_GOTO = 0x05,
162 OLCP_OP_ORDER = 0x06,
163 OLCP_OP_REQ_NUM = 0x07,
164 OLCP_OP_CLEAR_MK = 0x08,
165 OLCP_OP_RESPONSE = 0x70
166 };
167
170 enum
171 {
172 OLCP_RES_SUCCESS = 0x01,
173 OLCP_RES_OPCODE_NS = 0x02,
174 OLCP_RES_INVALID_PARAM = 0x03,
175 OLCP_RES_OPER_FAILED = 0x04,
177 OLCP_RES_NO_OBJECT = 0x06,
178 OLCP_RES_OBJECT_ID_NF = 0x07
179 };
180
183 enum
184 {
185 PRPH_OTS_TYPE_FILE = 0,
186 PRPH_OTS_TYPE_DESCRIPTOR = 1,
187 PRPH_OTS_TYPE_CAPS = 2
188 };
189
192 enum
193 {
194 PRPH_OTS_ACCESS_READ = 0,
195 PRPH_OTS_ACCESS_WRITE = 1,
196 PRPH_OTS_ACCESS_RW = 2
197 };
198
201 constexpr static uint8_t CFG_TYPE_SHIFT = 0;
202 constexpr static uint8_t CFG_TYPE_MASK = 0xf;
203 constexpr static uint8_t CFG_ACCESS_SHIFT = 4;
204 constexpr static uint8_t CFG_ACCESS_MASK = 0x3;
205
208 constexpr static uint8_t OBJ_NAME_MAX = 16;
209
223
231 struct
232 {
233 uint32_t cfg0;
234 uint32_t cfg1;
235 uint32_t cfg2;
236
239
241
242 ~CProtoNimblePrphOts() override;
243
244 int init() override;
245 int deinit() override;
246 int start() override;
247 int stop() override;
248
249private:
252 struct SOtsObjectMeta
253 {
254 char name[OBJ_NAME_MAX];
255 uint16_t typeUuid;
256 uint8_t access;
257 uint8_t kind;
259 };
260
263 struct SOtsConnState
264 {
265 int16_t cursor;
266 uint8_t mode;
267 uint32_t offset;
268 uint32_t remaining;
269 struct ble_l2cap_chan *chan;
270
271 SOtsConnState()
272 : cursor(-1)
273 , mode(0)
274 , offset(0)
275 , remaining(0)
276 , chan(nullptr)
277 {
278 }
279 };
280
281 static constexpr uint8_t MODE_IDLE = 0;
282 static constexpr uint8_t MODE_READING = 1;
283 static constexpr uint8_t MODE_WRITING = 2;
284
285 int id;
286 bool created;
287 struct ble_gatt_svc_def svc;
288 struct ble_gatt_chr_def *chrs;
289 uint16_t hOacp;
290 uint16_t hOlcp;
291 io_ddata_t *xferBuf;
292 std::vector<SOtsObjectMeta> vmeta;
293 std::map<uint16_t, SOtsConnState> vconn;
294
295 void configureDesc(const SObjectCfg::SObjectCfgItem *item);
296 void allocObject(const SProtoNimblePrphIOBindOtsObjid &entry);
297 int allocOTS();
298 int createOTS();
299 void deleteOTS();
300 int setChrDef(size_t idx,
301 uint16_t uuid16,
302 ble_gatt_access_fn *cb_,
303 uint16_t flags,
304 uint16_t *valHandle);
305
306 // GATT access callbacks (one per characteristic)
307
308 static int featureCb(uint16_t conn_handle,
309 uint16_t attr_handle,
310 struct ble_gatt_access_ctxt *ctxt,
311 void *arg);
312
313 static int nameCb(uint16_t conn_handle,
314 uint16_t attr_handle,
315 struct ble_gatt_access_ctxt *ctxt,
316 void *arg);
317
318 static int typeCb(uint16_t conn_handle,
319 uint16_t attr_handle,
320 struct ble_gatt_access_ctxt *ctxt,
321 void *arg);
322
323 static int sizeCb(uint16_t conn_handle,
324 uint16_t attr_handle,
325 struct ble_gatt_access_ctxt *ctxt,
326 void *arg);
327
328 static int idCb(uint16_t conn_handle,
329 uint16_t attr_handle,
330 struct ble_gatt_access_ctxt *ctxt,
331 void *arg);
332
333 static int propsCb(uint16_t conn_handle,
334 uint16_t attr_handle,
335 struct ble_gatt_access_ctxt *ctxt,
336 void *arg);
337
338 static int oacpCb(uint16_t conn_handle,
339 uint16_t attr_handle,
340 struct ble_gatt_access_ctxt *ctxt,
341 void *arg);
342
343 static int olcpCb(uint16_t conn_handle,
344 uint16_t attr_handle,
345 struct ble_gatt_access_ctxt *ctxt,
346 void *arg);
347
348 // L2CAP CoC server event handler
349
350 static int l2capEventCb(struct ble_l2cap_event *event, void *arg);
351 void onL2capRx(struct ble_l2cap_event *event);
352
353 // OACP / OLCP handlers (per connection state)
354
355 int handleOacpRead(uint16_t conn, uint32_t off, uint32_t len);
356 int handleOacpWrite(uint16_t conn, uint32_t off, uint32_t len, uint8_t mode);
357 int handleOacpAbort(uint16_t conn);
358 uint8_t oacpValidate(uint16_t conn, bool wantWrite, SOtsConnState *&st, CIOCommon *&io);
359
360 int handleOlcpFirst(uint16_t conn);
361 int handleOlcpLast(uint16_t conn);
362 int handleOlcpPrev(uint16_t conn);
363 int handleOlcpNext(uint16_t conn);
364 int handleOlcpGoto(uint16_t conn, uint64_t obj_id);
365 int olcpSeekAbs(uint16_t conn, uint8_t op, size_t idx);
366 int olcpStep(uint16_t conn, uint8_t op, int delta);
367
368 // Helpers
369
370 void sendCpResponse(uint16_t conn,
371 uint16_t handle,
372 uint8_t respOp,
373 uint8_t reqOp,
374 uint8_t result);
375 void sendOacpResponse(uint16_t conn, uint8_t req_op, uint8_t result);
376 void sendOlcpResponse(uint16_t conn, uint8_t req_op, uint8_t result);
377
378 static int metaPrologue(uint16_t conn,
379 ble_gatt_access_ctxt *ctxt,
380 void *arg,
381 CProtoNimblePrphOts **self,
382 SOtsObjectMeta **meta,
383 int16_t *cursorOut);
384 int pumpRead(uint16_t conn);
385 bool selected(uint16_t conn, SOtsConnState *&state, SOtsObjectMeta *&meta);
386
387 static uint8_t cfgGetType(uint32_t cfg)
388 {
389 return (cfg >> CFG_TYPE_SHIFT) & CFG_TYPE_MASK;
390 }
391
392 static uint8_t cfgGetAccess(uint32_t cfg)
393 {
394 return (cfg >> CFG_ACCESS_SHIFT) & CFG_ACCESS_MASK;
395 }
396
397 static uint32_t cfgPack(uint8_t type, uint8_t access)
398 {
399 return ((type & CFG_TYPE_MASK) << CFG_TYPE_SHIFT) |
400 ((access & CFG_ACCESS_MASK) << CFG_ACCESS_SHIFT);
401 }
402};
403
404} // namespace dawn
Object Transfer Service (OTS) for BLE Peripheral.
Definition prph_ots.hxx:42
static uint16_t UUID16_OBJ_PROPS
Object Properties characteristic.
Definition prph_ots.hxx:70
int start()
Start service.
Definition prph_ots.cxx:372
@ OACP_RES_OPCODE_NS
Opcode Not Supported.
Definition prph_ots.hxx:143
@ OLCP_RES_OOR
Out Of Bounds.
Definition prph_ots.hxx:176
static uint16_t UUID16_OTS
OTS Service UUID (Bluetooth SIG).
Definition prph_ots.hxx:46
int stop()
Stop service.
Definition prph_ots.cxx:402
static uint16_t OBJ_TYPE_DESCRIPTOR
Object Type for a Dawn descriptor blob (Dawn-private UUID16).
Definition prph_ots.hxx:92
static uint8_t OBJ_NAME_MAX
OTS object name length (bytes, fixed).
Definition prph_ots.hxx:208
static uint16_t L2CAP_PSM_OTS
L2CAP PSM for OTS bulk data (Bluetooth SIG-assigned).
Definition prph_ots.hxx:105
static uint16_t UUID16_OBJ_NAME
Object Name characteristic.
Definition prph_ots.hxx:54
static uint16_t UUID16_OBJ_SIZE
Object Size characteristic (current + allocated, 8 bytes).
Definition prph_ots.hxx:62
int init()
Initialize service.
Definition prph_ots.cxx:341
static uint16_t UUID16_OLCP
Object List Control Point characteristic.
Definition prph_ots.hxx:78
static uint16_t L2CAP_MTU_OTS
L2CAP CoC MTU for OTS data channel.
Definition prph_ots.hxx:109
static uint16_t OBJ_TYPE_UNSPECIFIED
Object Type for an "Unspecified" file (Bluetooth SIG).
Definition prph_ots.hxx:82
static uint16_t UUID16_OBJ_ID
Object ID characteristic (48-bit).
Definition prph_ots.hxx:66
static uint16_t UUID16_OACP
Object Action Control Point characteristic.
Definition prph_ots.hxx:74
static uint8_t CFG_TYPE_SHIFT
Per-object cfg word layout (lower bits of obj.cfg).
Definition prph_ots.hxx:201
int deinit()
Deinitialize service.
Definition prph_ots.cxx:363
static uint16_t UUID16_FEATURE
OTS Feature characteristic.
Definition prph_ots.hxx:50
static uint16_t UUID16_OBJ_TYPE
Object Type characteristic.
Definition prph_ots.hxx:58
static uint16_t OBJ_TYPE_CAPS
Object Type for a Dawn capabilities blob (Dawn-private UUID16).
Definition prph_ots.hxx:101
Interface for BLE peripheral services with GATT characteristics.
Definition iprph.hxx:24
Base interface for GATT services exposed by BLE peripheral.
Definition iprph.hxx:467
Out-of-tree user-extension hooks for Dawn.
Definition bindable.hxx:13
SObjectId::UObjectId objid
I/O object ID for backing storage.
Definition prph_ots.hxx:221
uint32_t cfg0
Number of objects in obj[].
Definition prph_ots.hxx:233
Single configuration item within object.
uint32_t ObjectId
ObjectID type - single 32-bit value.
Definition objectid.hxx:44
32-bit encoded object identifier (union with bit field).
Definition objectid.hxx:218