1 /*
2 * Copyright (c) 2020-2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_OTS_H_
8 #define ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_OTS_H_
9
10 /**
11 * @brief Object Transfer Service (OTS)
12 * @defgroup bt_ots Object Transfer Service (OTS)
13 * @ingroup bluetooth
14 * @{
15 *
16 * [Experimental] Users should note that the APIs can change
17 * as a part of ongoing development.
18 */
19
20 #include <stdbool.h>
21 #include <stdint.h>
22
23 #include <sys/types.h>
24
25 #include <zephyr/sys/byteorder.h>
26 #include <zephyr/sys/util.h>
27 #include <zephyr/sys/crc.h>
28 #include <zephyr/bluetooth/conn.h>
29 #include <zephyr/bluetooth/uuid.h>
30 #include <zephyr/bluetooth/gatt.h>
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /** @brief Size of OTS object ID (in bytes). */
37 #define BT_OTS_OBJ_ID_SIZE 6
38
39 /** @brief Minimum allowed value for object ID (except ID for directory listing) */
40 #define BT_OTS_OBJ_ID_MIN 0x000000000100ULL
41
42 /** @brief Maximum allowed value for object ID (except ID for directory listing) */
43 #define BT_OTS_OBJ_ID_MAX 0xFFFFFFFFFFFFULL
44
45 /** @brief ID of the Directory Listing Object */
46 #define OTS_OBJ_ID_DIR_LIST 0x000000000000ULL
47
48 /** @brief Mask for OTS object IDs, preserving the 48 bits */
49 #define BT_OTS_OBJ_ID_MASK BIT64_MASK(48)
50
51 /** @brief Length of OTS object ID string (in bytes). */
52 #define BT_OTS_OBJ_ID_STR_LEN 15
53
54 /** @brief Type of an OTS object. */
55 struct bt_ots_obj_type {
56 union {
57 /* Used to indicate UUID type */
58 struct bt_uuid uuid;
59
60 /* 16-bit UUID value */
61 struct bt_uuid_16 uuid_16;
62
63 /* 128-bit UUID value */
64 struct bt_uuid_128 uuid_128;
65 };
66 };
67
68 /** @brief Properties of an OTS object. */
69 enum {
70 /** Bit 0 Deletion of this object is permitted */
71 BT_OTS_OBJ_PROP_DELETE = 0,
72
73 /** Bit 1 Execution of this object is permitted */
74 BT_OTS_OBJ_PROP_EXECUTE = 1,
75
76 /** Bit 2 Reading this object is permitted */
77 BT_OTS_OBJ_PROP_READ = 2,
78
79 /** Bit 3 Writing data to this object is permitted */
80 BT_OTS_OBJ_PROP_WRITE = 3,
81
82 /** @brief Bit 4 Appending data to this object is permitted.
83 *
84 * Appending data increases its Allocated Size.
85 */
86 BT_OTS_OBJ_PROP_APPEND = 4,
87
88 /** Bit 5 Truncation of this object is permitted */
89 BT_OTS_OBJ_PROP_TRUNCATE = 5,
90
91 /** @brief Bit 6 Patching this object is permitted
92 *
93 * Patching this object overwrites some of
94 * the object's existing contents.
95 */
96 BT_OTS_OBJ_PROP_PATCH = 6,
97
98 /** Bit 7 This object is a marked object */
99 BT_OTS_OBJ_PROP_MARKED = 7,
100 };
101
102 /** @brief Set @ref BT_OTS_OBJ_PROP_DELETE property.
103 *
104 * @param prop Object properties.
105 */
106 #define BT_OTS_OBJ_SET_PROP_DELETE(prop) \
107 WRITE_BIT(prop, BT_OTS_OBJ_PROP_DELETE, 1)
108
109 /** @brief Set @ref BT_OTS_OBJ_PROP_EXECUTE property.
110 *
111 * @param prop Object properties.
112 */
113 #define BT_OTS_OBJ_SET_PROP_EXECUTE(prop) \
114 WRITE_BIT(prop, BT_OTS_OBJ_PROP_EXECUTE, 1)
115
116 /** @brief Set @ref BT_OTS_OBJ_PROP_READ property.
117 *
118 * @param prop Object properties.
119 */
120 #define BT_OTS_OBJ_SET_PROP_READ(prop) \
121 WRITE_BIT(prop, BT_OTS_OBJ_PROP_READ, 1)
122
123 /** @brief Set @ref BT_OTS_OBJ_PROP_WRITE property.
124 *
125 * @param prop Object properties.
126 */
127 #define BT_OTS_OBJ_SET_PROP_WRITE(prop) \
128 WRITE_BIT(prop, BT_OTS_OBJ_PROP_WRITE, 1)
129
130 /** @brief Set @ref BT_OTS_OBJ_PROP_APPEND property.
131 *
132 * @param prop Object properties.
133 */
134 #define BT_OTS_OBJ_SET_PROP_APPEND(prop) \
135 WRITE_BIT(prop, BT_OTS_OBJ_PROP_APPEND, 1)
136
137 /** @brief Set @ref BT_OTS_OBJ_PROP_TRUNCATE property.
138 *
139 * @param prop Object properties.
140 */
141 #define BT_OTS_OBJ_SET_PROP_TRUNCATE(prop) \
142 WRITE_BIT(prop, BT_OTS_OBJ_PROP_TRUNCATE, 1)
143
144 /** @brief Set @ref BT_OTS_OBJ_PROP_PATCH property.
145 *
146 * @param prop Object properties.
147 */
148 #define BT_OTS_OBJ_SET_PROP_PATCH(prop) \
149 WRITE_BIT(prop, BT_OTS_OBJ_PROP_PATCH, 1)
150
151 /** @brief Set @ref BT_OTS_OBJ_SET_PROP_MARKED property.
152 *
153 * @param prop Object properties.
154 */
155 #define BT_OTS_OBJ_SET_PROP_MARKED(prop) \
156 WRITE_BIT(prop, BT_OTS_OBJ_PROP_MARKED, 1)
157
158 /** @brief Get @ref BT_OTS_OBJ_PROP_DELETE property.
159 *
160 * @param prop Object properties.
161 */
162 #define BT_OTS_OBJ_GET_PROP_DELETE(prop) \
163 ((prop) & BIT(BT_OTS_OBJ_PROP_DELETE))
164
165 /** @brief Get @ref BT_OTS_OBJ_PROP_EXECUTE property.
166 *
167 * @param prop Object properties.
168 */
169 #define BT_OTS_OBJ_GET_PROP_EXECUTE(prop) \
170 ((prop) & BIT(BT_OTS_OBJ_PROP_EXECUTE))
171
172 /** @brief Get @ref BT_OTS_OBJ_PROP_READ property.
173 *
174 * @param prop Object properties.
175 */
176 #define BT_OTS_OBJ_GET_PROP_READ(prop) \
177 ((prop) & BIT(BT_OTS_OBJ_PROP_READ))
178
179 /** @brief Get @ref BT_OTS_OBJ_PROP_WRITE property.
180 *
181 * @param prop Object properties.
182 */
183 #define BT_OTS_OBJ_GET_PROP_WRITE(prop) \
184 ((prop) & BIT(BT_OTS_OBJ_PROP_WRITE))
185
186 /** @brief Get @ref BT_OTS_OBJ_PROP_APPEND property.
187 *
188 * @param prop Object properties.
189 */
190 #define BT_OTS_OBJ_GET_PROP_APPEND(prop) \
191 ((prop) & BIT(BT_OTS_OBJ_PROP_APPEND))
192
193 /** @brief Get @ref BT_OTS_OBJ_PROP_TRUNCATE property.
194 *
195 * @param prop Object properties.
196 */
197 #define BT_OTS_OBJ_GET_PROP_TRUNCATE(prop) \
198 ((prop) & BIT(BT_OTS_OBJ_PROP_TRUNCATE))
199
200 /** @brief Get @ref BT_OTS_OBJ_PROP_PATCH property.
201 *
202 * @param prop Object properties.
203 */
204 #define BT_OTS_OBJ_GET_PROP_PATCH(prop) \
205 ((prop) & BIT(BT_OTS_OBJ_PROP_PATCH))
206
207 /** @brief Get @ref BT_OTS_OBJ_PROP_MARKED property.
208 *
209 * @param prop Object properties.
210 */
211 #define BT_OTS_OBJ_GET_PROP_MARKED(prop) \
212 ((prop) & BIT(BT_OTS_OBJ_PROP_MARKED))
213
214 /** @brief Descriptor for OTS Object Size parameter. */
215 struct bt_ots_obj_size {
216 /** @brief Current Size */
217 uint32_t cur;
218
219 /** @brief Allocated Size */
220 uint32_t alloc;
221 } __packed;
222
223 /** @brief Object Action Control Point Feature bits. */
224 enum {
225 /** Bit 0 OACP Create Op Code Supported */
226 BT_OTS_OACP_FEAT_CREATE = 0,
227
228 /** Bit 1 OACP Delete Op Code Supported */
229 BT_OTS_OACP_FEAT_DELETE = 1,
230
231 /** Bit 2 OACP Calculate Checksum Op Code Supported */
232 BT_OTS_OACP_FEAT_CHECKSUM = 2,
233
234 /** Bit 3 OACP Execute Op Code Supported */
235 BT_OTS_OACP_FEAT_EXECUTE = 3,
236
237 /** Bit 4 OACP Read Op Code Supported */
238 BT_OTS_OACP_FEAT_READ = 4,
239
240 /** Bit 5 OACP Write Op Code Supported */
241 BT_OTS_OACP_FEAT_WRITE = 5,
242
243 /** Bit 6 Appending Additional Data to Objects Supported */
244 BT_OTS_OACP_FEAT_APPEND = 6,
245
246 /** Bit 7 Truncation of Objects Supported */
247 BT_OTS_OACP_FEAT_TRUNCATE = 7,
248
249 /** Bit 8 Patching of Objects Supported */
250 BT_OTS_OACP_FEAT_PATCH = 8,
251
252 /** Bit 9 OACP Abort Op Code Supported */
253 BT_OTS_OACP_FEAT_ABORT = 9,
254 };
255
256 /*
257 * @enum bt_ots_oacp_write_op_mode
258 * @brief Mode Parameter for OACP Write Op Code.
259 */
260 enum bt_ots_oacp_write_op_mode {
261 BT_OTS_OACP_WRITE_OP_MODE_NONE = 0,
262 BT_OTS_OACP_WRITE_OP_MODE_TRUNCATE = BIT(1),
263 };
264
265 /** @brief Set @ref BT_OTS_OACP_SET_FEAT_CREATE feature.
266 *
267 * @param feat OTS features.
268 */
269 #define BT_OTS_OACP_SET_FEAT_CREATE(feat) \
270 WRITE_BIT(feat, BT_OTS_OACP_FEAT_CREATE, 1)
271
272 /** @brief Set @ref BT_OTS_OACP_FEAT_DELETE feature.
273 *
274 * @param feat OTS features.
275 */
276 #define BT_OTS_OACP_SET_FEAT_DELETE(feat) \
277 WRITE_BIT(feat, BT_OTS_OACP_FEAT_DELETE, 1)
278
279 /** @brief Set @ref BT_OTS_OACP_FEAT_CHECKSUM feature.
280 *
281 * @param feat OTS features.
282 */
283 #define BT_OTS_OACP_SET_FEAT_CHECKSUM(feat) \
284 WRITE_BIT(feat, BT_OTS_OACP_FEAT_CHECKSUM, 1)
285
286 /** @brief Set @ref BT_OTS_OACP_FEAT_EXECUTE feature.
287 *
288 * @param feat OTS features.
289 */
290 #define BT_OTS_OACP_SET_FEAT_EXECUTE(feat) \
291 WRITE_BIT(feat, BT_OTS_OACP_FEAT_EXECUTE, 1)
292
293 /** @brief Set @ref BT_OTS_OACP_FEAT_READ feature.
294 *
295 * @param feat OTS features.
296 */
297 #define BT_OTS_OACP_SET_FEAT_READ(feat) \
298 WRITE_BIT(feat, BT_OTS_OACP_FEAT_READ, 1)
299
300 /** @brief Set @ref BT_OTS_OACP_FEAT_WRITE feature.
301 *
302 * @param feat OTS features.
303 */
304 #define BT_OTS_OACP_SET_FEAT_WRITE(feat) \
305 WRITE_BIT(feat, BT_OTS_OACP_FEAT_WRITE, 1)
306
307 /** @brief Set @ref BT_OTS_OACP_FEAT_APPEND feature.
308 *
309 * @param feat OTS features.
310 */
311 #define BT_OTS_OACP_SET_FEAT_APPEND(feat) \
312 WRITE_BIT(feat, BT_OTS_OACP_FEAT_APPEND, 1)
313
314 /** @brief Set @ref BT_OTS_OACP_FEAT_TRUNCATE feature.
315 *
316 * @param feat OTS features.
317 */
318 #define BT_OTS_OACP_SET_FEAT_TRUNCATE(feat) \
319 WRITE_BIT(feat, BT_OTS_OACP_FEAT_TRUNCATE, 1)
320
321 /** @brief Set @ref BT_OTS_OACP_FEAT_PATCH feature.
322 *
323 * @param feat OTS features.
324 */
325 #define BT_OTS_OACP_SET_FEAT_PATCH(feat) \
326 WRITE_BIT(feat, BT_OTS_OACP_FEAT_PATCH, 1)
327
328 /** @brief Set @ref BT_OTS_OACP_FEAT_ABORT feature.
329 *
330 * @param feat OTS features.
331 */
332 #define BT_OTS_OACP_SET_FEAT_ABORT(feat) \
333 WRITE_BIT(feat, BT_OTS_OACP_FEAT_ABORT, 1)
334
335 /** @brief Get @ref BT_OTS_OACP_FEAT_CREATE feature.
336 *
337 * @param feat OTS features.
338 */
339 #define BT_OTS_OACP_GET_FEAT_CREATE(feat) \
340 ((feat) & BIT(BT_OTS_OACP_FEAT_CREATE))
341
342 /** @brief Get @ref BT_OTS_OACP_FEAT_DELETE feature.
343 *
344 * @param feat OTS features.
345 */
346 #define BT_OTS_OACP_GET_FEAT_DELETE(feat) \
347 ((feat) & BIT(BT_OTS_OACP_FEAT_DELETE))
348
349 /** @brief Get @ref BT_OTS_OACP_FEAT_CHECKSUM feature.
350 *
351 * @param feat OTS features.
352 */
353 #define BT_OTS_OACP_GET_FEAT_CHECKSUM(feat) \
354 ((feat) & BIT(BT_OTS_OACP_FEAT_CHECKSUM))
355
356 /** @brief Get @ref BT_OTS_OACP_FEAT_EXECUTE feature.
357 *
358 * @param feat OTS features.
359 */
360 #define BT_OTS_OACP_GET_FEAT_EXECUTE(feat) \
361 ((feat) & BIT(BT_OTS_OACP_FEAT_EXECUTE))
362
363 /** @brief Get @ref BT_OTS_OACP_FEAT_READ feature.
364 *
365 * @param feat OTS features.
366 */
367 #define BT_OTS_OACP_GET_FEAT_READ(feat) \
368 ((feat) & BIT(BT_OTS_OACP_FEAT_READ))
369
370 /** @brief Get @ref BT_OTS_OACP_FEAT_WRITE feature.
371 *
372 * @param feat OTS features.
373 */
374 #define BT_OTS_OACP_GET_FEAT_WRITE(feat) \
375 ((feat) & BIT(BT_OTS_OACP_FEAT_WRITE))
376
377 /** @brief Get @ref BT_OTS_OACP_FEAT_APPEND feature.
378 *
379 * @param feat OTS features.
380 */
381 #define BT_OTS_OACP_GET_FEAT_APPEND(feat) \
382 ((feat) & BIT(BT_OTS_OACP_FEAT_APPEND))
383
384 /** @brief Get @ref BT_OTS_OACP_FEAT_TRUNCATE feature.
385 *
386 * @param feat OTS features.
387 */
388 #define BT_OTS_OACP_GET_FEAT_TRUNCATE(feat) \
389 ((feat) & BIT(BT_OTS_OACP_FEAT_TRUNCATE))
390
391 /** @brief Get @ref BT_OTS_OACP_FEAT_PATCH feature.
392 *
393 * @param feat OTS features.
394 */
395 #define BT_OTS_OACP_GET_FEAT_PATCH(feat) \
396 ((feat) & BIT(BT_OTS_OACP_FEAT_PATCH))
397
398 /** @brief Get @ref BT_OTS_OACP_FEAT_ABORT feature.
399 *
400 * @param feat OTS features.
401 */
402 #define BT_OTS_OACP_GET_FEAT_ABORT(feat) \
403 ((feat) & BIT(BT_OTS_OACP_FEAT_ABORT))
404
405 /** @brief Object List Control Point Feature bits. */
406 enum {
407 /** Bit 0 OLCP Go To Op Code Supported */
408 BT_OTS_OLCP_FEAT_GO_TO = 0,
409
410 /** Bit 1 OLCP Order Op Code Supported */
411 BT_OTS_OLCP_FEAT_ORDER = 1,
412
413 /** Bit 2 OLCP Request Number of Objects Op Code Supported */
414 BT_OTS_OLCP_FEAT_NUM_REQ = 2,
415
416 /** Bit 3 OLCP Clear Marking Op Code Supported*/
417 BT_OTS_OLCP_FEAT_CLEAR = 3,
418 };
419
420 /** @brief Set @ref BT_OTS_OLCP_FEAT_GO_TO feature.
421 *
422 * @param feat OTS features.
423 */
424 #define BT_OTS_OLCP_SET_FEAT_GO_TO(feat) \
425 WRITE_BIT(feat, BT_OTS_OLCP_FEAT_GO_TO, 1)
426
427 /** @brief Set @ref BT_OTS_OLCP_FEAT_ORDER feature.
428 *
429 * @param feat OTS features.
430 */
431 #define BT_OTS_OLCP_SET_FEAT_ORDER(feat) \
432 WRITE_BIT(feat, BT_OTS_OLCP_FEAT_ORDER, 1)
433
434 /** @brief Set @ref BT_OTS_OLCP_FEAT_NUM_REQ feature.
435 *
436 * @param feat OTS features.
437 */
438 #define BT_OTS_OLCP_SET_FEAT_NUM_REQ(feat) \
439 WRITE_BIT(feat, BT_OTS_OLCP_FEAT_NUM_REQ, 1)
440
441 /** @brief Set @ref BT_OTS_OLCP_FEAT_CLEAR feature.
442 *
443 * @param feat OTS features.
444 */
445 #define BT_OTS_OLCP_SET_FEAT_CLEAR(feat) \
446 WRITE_BIT(feat, BT_OTS_OLCP_FEAT_CLEAR, 1)
447
448 /** @brief Get @ref BT_OTS_OLCP_GET_FEAT_GO_TO feature.
449 *
450 * @param feat OTS features.
451 */
452 #define BT_OTS_OLCP_GET_FEAT_GO_TO(feat) \
453 ((feat) & BIT(BT_OTS_OLCP_FEAT_GO_TO))
454
455 /** @brief Get @ref BT_OTS_OLCP_GET_FEAT_ORDER feature.
456 *
457 * @param feat OTS features.
458 */
459 #define BT_OTS_OLCP_GET_FEAT_ORDER(feat) \
460 ((feat) & BIT(BT_OTS_OLCP_FEAT_ORDER))
461
462 /** @brief Get @ref BT_OTS_OLCP_GET_FEAT_NUM_REQ feature.
463 *
464 * @param feat OTS features.
465 */
466 #define BT_OTS_OLCP_GET_FEAT_NUM_REQ(feat) \
467 ((feat) & BIT(BT_OTS_OLCP_FEAT_NUM_REQ))
468
469 /** @brief Get @ref BT_OTS_OLCP_GET_FEAT_CLEAR feature.
470 *
471 * @param feat OTS features.
472 */
473 #define BT_OTS_OLCP_GET_FEAT_CLEAR(feat) \
474 ((feat) & BIT(BT_OTS_OLCP_FEAT_CLEAR))
475
476 /**@brief Features of the OTS. */
477 struct bt_ots_feat {
478 /* OACP Features */
479 uint32_t oacp;
480
481 /* OLCP Features */
482 uint32_t olcp;
483 } __packed;
484
485 /** @brief Object metadata request bit field values */
486 enum {
487 /** @brief Request object name */
488 BT_OTS_METADATA_REQ_NAME = BIT(0),
489 /** @brief Request object type */
490 BT_OTS_METADATA_REQ_TYPE = BIT(1),
491 /** @brief Request object size */
492 BT_OTS_METADATA_REQ_SIZE = BIT(2),
493 /** @brief Request object first created time */
494 BT_OTS_METADATA_REQ_CREATED = BIT(3),
495 /** @brief Request object last modified time */
496 BT_OTS_METADATA_REQ_MODIFIED = BIT(4),
497 /** @brief Request object ID */
498 BT_OTS_METADATA_REQ_ID = BIT(5),
499 /** @brief Request object properties */
500 BT_OTS_METADATA_REQ_PROPS = BIT(6),
501 /** @brief Request all object metadata */
502 BT_OTS_METADATA_REQ_ALL = 0x7F,
503 };
504
505 /** @brief Date and Time structure */
506 struct bt_ots_date_time {
507 uint16_t year;
508 uint8_t month;
509 uint8_t day;
510 uint8_t hours;
511 uint8_t minutes;
512 uint8_t seconds;
513 };
514 #define BT_OTS_DATE_TIME_FIELD_SIZE 7
515
516 /** @brief Metadata of an OTS object
517 *
518 * Used by the server as a descriptor for OTS object initialization.
519 * Used by the client to present object metadata to the application.
520 */
521 struct bt_ots_obj_metadata {
522
523 #if defined(CONFIG_BT_OTS)
524 /** @brief Object Name */
525 char *name;
526 #endif /* CONFIG_BT_OTS */
527
528 #if defined(CONFIG_BT_OTS_CLIENT)
529 /* TODO: Unify client/server name */
530 /** @brief Object name (client) */
531 char name_c[CONFIG_BT_OTS_OBJ_MAX_NAME_LEN + 1];
532 #endif /* CONFIG_BT_OTS_CLIENT */
533
534 /** @brief Object Type */
535 struct bt_ots_obj_type type;
536
537 /** @brief Object Size */
538 struct bt_ots_obj_size size;
539
540 #if defined(CONFIG_BT_OTS_CLIENT)
541 /** @brief Object first created time */
542 struct bt_ots_date_time first_created;
543
544 /** @brief Object last modified time */
545 struct bt_ots_date_time modified;
546
547 /** @brief Object ID */
548 uint64_t id;
549 #endif /* CONFIG_BT_OTS_CLIENT */
550
551 /** @brief Object Properties */
552 uint32_t props;
553 };
554
555 /** @brief Opaque OTS instance. */
556 struct bt_ots;
557
558 /** @brief Descriptor for OTS object addition */
559 struct bt_ots_obj_add_param {
560 /** @brief Object size to allocate */
561 uint32_t size;
562
563 /** @brief Object type */
564 struct bt_ots_obj_type type;
565 };
566
567 /** @brief Descriptor for OTS created object.
568 *
569 * Descriptor for OTS object created by the application. This descriptor is
570 * returned by @ref bt_ots_cb.obj_created callback which contains further
571 * documentation on distinguishing between server and client object creation.
572 */
573 struct bt_ots_obj_created_desc {
574 /** @brief Object name
575 *
576 * The object name as a NULL terminated string.
577 *
578 * When the server creates a new object the name
579 * shall be > 0 and <= BT_OTS_OBJ_MAX_NAME_LEN
580 * When the client creates a new object the name
581 * shall be an empty string
582 */
583 char *name;
584
585 /** @brief Object size
586 *
587 * @ref bt_ots_obj_size.alloc shall be >= @ref bt_ots_obj_add_param.size
588 *
589 * When the server creates a new object @ref bt_ots_obj_size.cur
590 * shall be <= @ref bt_ots_obj_add_param.size
591 * When the client creates a new object @ref bt_ots_obj_size.cur
592 * shall be 0
593 */
594 struct bt_ots_obj_size size;
595
596 /** @brief Object properties */
597 uint32_t props;
598 };
599
600 /** @brief OTS callback structure. */
601 struct bt_ots_cb {
602 /** @brief Object created callback
603 *
604 * This callback is called whenever a new object is created.
605 * Application can reject this request by returning an error
606 * when it does not have necessary resources to hold this new
607 * object. This callback is also triggered when the server
608 * creates a new object with bt_ots_obj_add() API.
609 *
610 * @param ots OTS instance.
611 * @param conn The connection that is requesting object creation or
612 * NULL if object is created by bt_ots_obj_add().
613 * @param id Object ID.
614 * @param add_param Object creation requested parameters.
615 * @param created_desc Created object descriptor that shall be filled by the
616 * receiver of this callback.
617 *
618 * @return 0 in case of success or negative value in case of error.
619 * @return -ENOTSUP if object type is not supported
620 * @return -ENOMEM if no available space for new object.
621 * @return -EINVAL if an invalid parameter is provided
622 * @return other negative values are treated as a generic operation failure
623 */
624 int (*obj_created)(struct bt_ots *ots, struct bt_conn *conn, uint64_t id,
625 const struct bt_ots_obj_add_param *add_param,
626 struct bt_ots_obj_created_desc *created_desc);
627
628 /** @brief Object deleted callback
629 *
630 * This callback is called whenever an object is deleted. It is
631 * also triggered when the server deletes an object with
632 * bt_ots_obj_delete() API.
633 *
634 * @param ots OTS instance.
635 * @param conn The connection that deleted the object or NULL if
636 * this request came from the server.
637 * @param id Object ID.
638 *
639 * @retval When an error is indicated by using a negative value, the
640 * object delete procedure is aborted and a corresponding failed
641 * status is returned to the client.
642 * @return 0 in case of success.
643 * @return -EBUSY if the object is locked. This is generally not expected
644 * to be returned by the application as the OTS layer tracks object
645 * accesses. An object locked status is returned to the client.
646 * @return Other negative values in case of error. A generic operation
647 * failed status is returned to the client.
648 */
649 int (*obj_deleted)(struct bt_ots *ots, struct bt_conn *conn,
650 uint64_t id);
651
652 /** @brief Object selected callback
653 *
654 * This callback is called on successful object selection.
655 *
656 * @param ots OTS instance.
657 * @param conn The connection that selected new object.
658 * @param id Object ID.
659 */
660 void (*obj_selected)(struct bt_ots *ots, struct bt_conn *conn,
661 uint64_t id);
662
663 /** @brief Object read callback
664 *
665 * This callback is called multiple times during the Object read
666 * operation. OTS module will keep requesting successive Object
667 * fragments from the application until the read operation is
668 * completed. The end of read operation is indicated by NULL data
669 * parameter.
670 *
671 * @param ots OTS instance.
672 * @param conn The connection that read object.
673 * @param id Object ID.
674 * @param data In: NULL once the read operations is completed.
675 * Out: Next chunk of data to be sent.
676 * @param len Remaining length requested by the client.
677 * @param offset Object data offset.
678 *
679 * @return Data length to be sent via data parameter. This value
680 * shall be smaller or equal to the len parameter.
681 * @return Negative value in case of an error.
682 */
683 ssize_t (*obj_read)(struct bt_ots *ots, struct bt_conn *conn,
684 uint64_t id, void **data, size_t len,
685 off_t offset);
686
687 /** @brief Object write callback
688 *
689 * This callback is called multiple times during the Object write
690 * operation. OTS module will keep providing successive Object
691 * fragments to the application until the write operation is
692 * completed. The offset and length of each write fragment is
693 * validated by the OTS module to be within the allocated size
694 * of the object. The remaining length indicates data length
695 * remaining to be written and will decrease each write iteration
696 * until it reaches 0 in the last write fragment.
697 *
698 * @param ots OTS instance.
699 * @param conn The connection that wrote object.
700 * @param id Object ID.
701 * @param data Next chunk of data to be written.
702 * @param len Length of the current chunk of data in the buffer.
703 * @param offset Object data offset.
704 * @param rem Remaining length in the write operation.
705 *
706 * @return Number of bytes written in case of success, if the number
707 * of bytes written does not match len, -EIO is returned to
708 * the L2CAP layer.
709 * @return A negative value in case of an error.
710 * @return -EINPROGRESS has a special meaning and is unsupported at
711 * the moment. It should not be returned.
712 */
713 ssize_t (*obj_write)(struct bt_ots *ots, struct bt_conn *conn, uint64_t id,
714 const void *data, size_t len, off_t offset,
715 size_t rem);
716
717 /** @brief Object name written callback
718 *
719 * This callback is called when the object name is written.
720 * This is a notification to the application that the object name
721 * will be updated by the OTS service implementation.
722 *
723 * @param ots OTS instance.
724 * @param conn The connection that wrote object name.
725 * @param id Object ID.
726 * @param cur_name Current object name.
727 * @param new_name New object name.
728 */
729 void (*obj_name_written)(struct bt_ots *ots, struct bt_conn *conn,
730 uint64_t id, const char *cur_name, const char *new_name);
731
732 /** @brief Object Calculate checksum callback
733 *
734 * This callback is called when the OACP Calculate Checksum procedure is performed.
735 * Because object data is opaque to OTS, the application is the only one who
736 * knows where data is and should return pointer of actual object data.
737 *
738 * @param[in] ots OTS instance.
739 * @param[in] conn The connection that wrote object.
740 * @param[in] id Object ID.
741 * @param[in] offset The first octet of the object contents need to be calculated.
742 * @param[in] len The length number of octets object name.
743 * @param[out] data Pointer of actual object data.
744 *
745 * @return 0 to accept, or any negative value to reject.
746 */
747 int (*obj_cal_checksum)(struct bt_ots *ots, struct bt_conn *conn, uint64_t id,
748 off_t offset, size_t len, void **data);
749 };
750
751 /** @brief Descriptor for OTS initialization. */
752 struct bt_ots_init_param {
753 /* OTS features */
754 struct bt_ots_feat features;
755
756 /* Callbacks */
757 struct bt_ots_cb *cb;
758 };
759
760 /** @brief Add an object to the OTS instance.
761 *
762 * This function adds an object to the OTS database. When the
763 * object is being added, a callback obj_created() is called
764 * to notify the user about a new object ID.
765 *
766 * @param ots OTS instance.
767 * @param param Object addition parameters.
768 *
769 * @return ID of created object in case of success.
770 * @return negative value in case of error.
771 */
772 int bt_ots_obj_add(struct bt_ots *ots, const struct bt_ots_obj_add_param *param);
773
774 /** @brief Delete an object from the OTS instance.
775 *
776 * This function deletes an object from the OTS database. When the
777 * object is deleted a callback obj_deleted() is called
778 * to notify the user about this event. At this point, it is possible
779 * to free allocated buffer for object data.
780 *
781 * @param ots OTS instance.
782 * @param id ID of the object to be deleted (uint48).
783 *
784 * @return 0 in case of success or negative value in case of error.
785 */
786 int bt_ots_obj_delete(struct bt_ots *ots, uint64_t id);
787
788 /** @brief Get the service declaration attribute.
789 *
790 * This function is enabled for CONFIG_BT_OTS_SECONDARY_SVC configuration.
791 * The first service attribute can be included in any other GATT service.
792 *
793 * @param ots OTS instance.
794 *
795 * @return The first OTS attribute instance.
796 */
797 void *bt_ots_svc_decl_get(struct bt_ots *ots);
798
799 /** @brief Initialize the OTS instance.
800 *
801 * @param ots OTS instance.
802 * @param ots_init OTS initialization descriptor.
803 *
804 * @return 0 in case of success or negative value in case of error.
805 */
806 int bt_ots_init(struct bt_ots *ots, struct bt_ots_init_param *ots_init);
807
808 /** @brief Get a free instance of OTS from the pool.
809 *
810 * @return OTS instance in case of success or NULL in case of error.
811 */
812 struct bt_ots *bt_ots_free_instance_get(void);
813
814 #define BT_OTS_STOP 0
815 #define BT_OTS_CONTINUE 1
816
817 /* TODO: Merge server and client instance as opaque type */
818 /** @brief OTS client instance */
819 struct bt_ots_client {
820 uint16_t start_handle;
821 uint16_t end_handle;
822 uint16_t feature_handle;
823 uint16_t obj_name_handle;
824 uint16_t obj_type_handle;
825 uint16_t obj_size_handle;
826 uint16_t obj_properties_handle;
827 uint16_t obj_created_handle;
828 uint16_t obj_modified_handle;
829 uint16_t obj_id_handle;
830 uint16_t oacp_handle;
831 uint16_t olcp_handle;
832
833 struct bt_gatt_subscribe_params oacp_sub_params;
834 struct bt_gatt_discover_params oacp_sub_disc_params;
835 struct bt_gatt_subscribe_params olcp_sub_params;
836 struct bt_gatt_discover_params olcp_sub_disc_params;
837
838 struct bt_gatt_write_params write_params;
839 struct bt_gatt_read_params read_proc;
840 struct bt_ots_client_cb *cb;
841
842 struct bt_ots_feat features;
843
844 struct bt_ots_obj_metadata cur_object;
845 };
846
847 /** OTS client callback structure */
848 struct bt_ots_client_cb {
849 /** @brief Callback function when a new object is selected.
850 *
851 * Called when the a new object is selected and the current
852 * object has changed. The `cur_object` in `ots_inst` will
853 * have been reset, and metadata should be read again with
854 * bt_ots_client_read_object_metadata().
855 *
856 * @param ots_inst Pointer to the OTC instance.
857 * @param conn The connection to the peer device.
858 * @param err Error code (bt_ots_olcp_res_code).
859 */
860 void (*obj_selected)(struct bt_ots_client *ots_inst,
861 struct bt_conn *conn, int err);
862
863
864 /** @brief Callback function for the data of the selected
865 * object.
866 *
867 * Called when the data of the selected object are read using
868 * bt_ots_client_read_object_data().
869 *
870 * @param ots_inst Pointer to the OTC instance.
871 * @param conn The connection to the peer device.
872 * @param offset Offset of the received data.
873 * @param len Length of the received data.
874 * @param data_p Pointer to the received data.
875 * @param is_complete Indicate if the whole object has been received.
876 *
877 * @return int BT_OTS_STOP or BT_OTS_CONTINUE. BT_OTS_STOP can
878 * be used to stop reading.
879 */
880 int (*obj_data_read)(struct bt_ots_client *ots_inst,
881 struct bt_conn *conn, uint32_t offset,
882 uint32_t len, uint8_t *data_p, bool is_complete);
883
884 /** @brief Callback function for metadata of the selected object.
885 *
886 * Called when metadata of the selected object are read using
887 * bt_ots_client_read_object_metadata().
888 * Not all of the metadata may have been initialized.
889 *
890 * @param ots_inst Pointer to the OTC instance.
891 * @param conn The connection to the peer device.
892 * @param err Error value. 0 on success,
893 * GATT error or ERRNO on fail.
894 * @param metadata_read Bitfield of the metadata that was
895 * successfully read.
896 */
897 void (*obj_metadata_read)(struct bt_ots_client *ots_inst,
898 struct bt_conn *conn, int err,
899 uint8_t metadata_read);
900
901 /** @brief Callback function for the data of the write object.
902 *
903 * Called when the data of the selected object is written using
904 * bt_ots_client_write_object_data().
905 *
906 * @param ots_inst Pointer to the OTC instance.
907 * @param conn The connection to the peer device.
908 * @param len Length of the written data.
909 */
910 void (*obj_data_written)(struct bt_ots_client *ots_inst,
911 struct bt_conn *conn, size_t len);
912
913 /** @brief Callback function when checksum indication is received.
914 *
915 * Called when the oacp_ind_handler received response of
916 * OP BT_GATT_OTS_OACP_PROC_CHECKSUM_CALC.
917 *
918 * @param ots_inst Pointer to the OTC instance.
919 * @param conn The connection to the peer device.
920 * @param err Error code (bt_gatt_ots_oacp_res_code).
921 * @param checksum Checksum if error code is BT_GATT_OTS_OACP_RES_SUCCESS,
922 * otherwise 0.
923 */
924 void (*obj_checksum_calculated)(struct bt_ots_client *ots_inst, struct bt_conn *conn,
925 int err, uint32_t checksum);
926 };
927
928 /** @brief Register an Object Transfer Service Instance.
929 *
930 * Register an Object Transfer Service instance discovered on the peer.
931 * Call this function when an OTS instance is discovered
932 * (discovery is to be handled by the higher layer).
933 *
934 * @param[in] ots_inst Discovered OTS instance.
935 *
936 * @return int 0 if success, ERRNO on failure.
937 */
938 int bt_ots_client_register(struct bt_ots_client *ots_inst);
939
940 /** @brief Unregister an Object Transfer Service Instance.
941 *
942 * Unregister an Object Transfer Service instance when disconnect from the peer.
943 * Call this function when an ACL using OTS instance is disconnected.
944 *
945 * @param[in] index Index of OTS instance.
946 *
947 * @return int 0 if success, ERRNO on failure.
948 */
949 int bt_ots_client_unregister(uint8_t index);
950
951 /** @brief OTS Indicate Handler function.
952 *
953 * Set this function as callback for indicate handler when discovering OTS.
954 *
955 * @param conn Connection object. May be NULL, indicating that the
956 * peer is being unpaired.
957 * @param params Subscription parameters.
958 * @param data Attribute value data. If NULL then subscription was
959 * removed.
960 * @param length Attribute value length.
961 */
962 uint8_t bt_ots_client_indicate_handler(struct bt_conn *conn,
963 struct bt_gatt_subscribe_params *params,
964 const void *data, uint16_t length);
965
966 /** @brief Read the OTS feature characteristic.
967 *
968 * @param otc_inst Pointer to the OTC instance.
969 * @param conn Pointer to the connection object.
970 *
971 * @return int 0 if success, ERRNO on failure.
972 */
973 int bt_ots_client_read_feature(struct bt_ots_client *otc_inst,
974 struct bt_conn *conn);
975
976 /** @brief Select an object by its Object ID.
977 *
978 * @param otc_inst Pointer to the OTC instance.
979 * @param conn Pointer to the connection object.
980 * @param obj_id Object's ID.
981 *
982 * @return int 0 if success, ERRNO on failure.
983 */
984 int bt_ots_client_select_id(struct bt_ots_client *otc_inst,
985 struct bt_conn *conn,
986 uint64_t obj_id);
987
988 /** @brief Select the first object.
989 *
990 * @param otc_inst Pointer to the OTC instance.
991 * @param conn Pointer to the connection object.
992 *
993 * @return int 0 if success, ERRNO on failure.
994 */
995 int bt_ots_client_select_first(struct bt_ots_client *otc_inst,
996 struct bt_conn *conn);
997
998 /** @brief Select the last object.
999 *
1000 * @param otc_inst Pointer to the OTC instance.
1001 * @param conn Pointer to the connection object.
1002 *
1003 * @return int 0 if success, ERRNO on failure.
1004 */
1005 int bt_ots_client_select_last(struct bt_ots_client *otc_inst,
1006 struct bt_conn *conn);
1007
1008 /** @brief Select the next object.
1009 *
1010 * @param otc_inst Pointer to the OTC instance.
1011 * @param conn Pointer to the connection object.
1012 *
1013 * @return int 0 if success, ERRNO on failure.
1014 */
1015 int bt_ots_client_select_next(struct bt_ots_client *otc_inst,
1016 struct bt_conn *conn);
1017
1018 /** @brief Select the previous object.
1019 *
1020 * @param otc_inst Pointer to the OTC instance.
1021 * @param conn Pointer to the connection object.
1022 *
1023 * @return int 0 if success, ERRNO on failure.
1024 */
1025 int bt_ots_client_select_prev(struct bt_ots_client *otc_inst,
1026 struct bt_conn *conn);
1027
1028 /** @brief Read the metadata of the current object.
1029 *
1030 * The metadata are returned in the obj_metadata_read() callback.
1031 *
1032 * @param otc_inst Pointer to the OTC instance.
1033 * @param conn Pointer to the connection object.
1034 * @param metadata Bitfield (`BT_OTS_METADATA_REQ_*`) of the metadata
1035 * to read.
1036 *
1037 * @return int 0 if success, ERRNO on failure.
1038 */
1039 int bt_ots_client_read_object_metadata(struct bt_ots_client *otc_inst,
1040 struct bt_conn *conn,
1041 uint8_t metadata);
1042
1043 /** @brief Read the data of the current selected object.
1044 *
1045 * This will trigger an OACP read operation for the current size of the object
1046 * with a 0 offset and then expect receiving the content via the L2CAP CoC.
1047 *
1048 * The data of the object are returned in the obj_data_read() callback.
1049 *
1050 * @param otc_inst Pointer to the OTC instance.
1051 * @param conn Pointer to the connection object.
1052 *
1053 * @return int 0 if success, ERRNO on failure.
1054 */
1055 int bt_ots_client_read_object_data(struct bt_ots_client *otc_inst,
1056 struct bt_conn *conn);
1057
1058 /** @brief Write the data of the current selected object.
1059 *
1060 * This will trigger an OACP write operation for the current object
1061 * with a specified offset and then expect transferring the content via the L2CAP CoC.
1062 *
1063 * The length of the data written to object is returned in the obj_data_written() callback.
1064 *
1065 * @param otc_inst Pointer to the OTC instance.
1066 * @param conn Pointer to the connection object.
1067 * @param buf Pointer to the data buffer to be written.
1068 * @param len Size of data.
1069 * @param offset Offset to write, usually 0.
1070 * @param mode Mode Parameter for OACP Write Op Code. See @ref bt_ots_oacp_write_op_mode.
1071 *
1072 * @return int 0 if success, ERRNO on failure.
1073 */
1074 int bt_ots_client_write_object_data(struct bt_ots_client *otc_inst, struct bt_conn *conn,
1075 const void *buf, size_t len, off_t offset,
1076 enum bt_ots_oacp_write_op_mode mode);
1077
1078 /** @brief Get the checksum of the current selected object.
1079 *
1080 * This will trigger an OACP calculate checksum operation for the current object
1081 * with a specified offset and length.
1082 *
1083 * The checksum goes to OACP IND and obj_checksum_calculated() callback.
1084 *
1085 * @param otc_inst Pointer to the OTC instance.
1086 * @param conn Pointer to the connection object.
1087 * @param offset Offset to calculate, usually 0.
1088 * @param len Len of data to calculate checksum for. May be less than the current object's
1089 * size, but shall not be larger.
1090 *
1091 * @return int 0 if success, ERRNO on failure.
1092 */
1093 int bt_ots_client_get_object_checksum(struct bt_ots_client *otc_inst, struct bt_conn *conn,
1094 off_t offset, size_t len);
1095
1096 /** @brief Directory listing object metadata callback
1097 *
1098 * If a directory listing is decoded using bt_ots_client_decode_dirlisting(),
1099 * this callback will be called for each object in the directory listing.
1100 *
1101 * @param meta The metadata of the decoded object
1102 *
1103 * @return int BT_OTS_STOP or BT_OTS_CONTINUE. BT_OTS_STOP can be used to
1104 * stop the decoding.
1105 */
1106 typedef int (*bt_ots_client_dirlisting_cb)(struct bt_ots_obj_metadata *meta);
1107
1108 /** @brief Decode Directory Listing object into object metadata.
1109 *
1110 * If the Directory Listing object contains multiple objects, then the
1111 * callback will be called for each of them.
1112 *
1113 * @param data The data received for the directory listing object.
1114 * @param length Length of the data.
1115 * @param cb The callback that will be called for each object.
1116 */
1117 int bt_ots_client_decode_dirlisting(uint8_t *data, uint16_t length,
1118 bt_ots_client_dirlisting_cb cb);
1119
1120 /** @brief Converts binary OTS Object ID to string.
1121 *
1122 * @param obj_id Object ID.
1123 * @param str Address of user buffer with enough room to store
1124 * formatted string containing binary Object ID.
1125 * @param len Length of data to be copied to user string buffer.
1126 * Refer to BT_OTS_OBJ_ID_STR_LEN about
1127 * recommended value.
1128 *
1129 * @return Number of successfully formatted bytes from binary ID.
1130 */
bt_ots_obj_id_to_str(uint64_t obj_id,char * str,size_t len)1131 static inline int bt_ots_obj_id_to_str(uint64_t obj_id, char *str, size_t len)
1132 {
1133 uint8_t id[6];
1134
1135 sys_put_le48(obj_id, id);
1136
1137 return snprintk(str, len, "0x%02X%02X%02X%02X%02X%02X",
1138 id[5], id[4], id[3], id[2], id[1], id[0]);
1139 }
1140
1141 /** @brief Displays one or more object metadata as text with LOG_INF.
1142 *
1143 * @param metadata Pointer to the first (or only) metadata in an array.
1144 * @param count Number of metadata objects to display information of.
1145 */
1146 void bt_ots_metadata_display(struct bt_ots_obj_metadata *metadata,
1147 uint16_t count);
1148
1149 /**
1150 * @brief Generate IEEE conform CRC32 checksum.
1151 *
1152 * To abstract IEEE implementation to service layer.
1153 *
1154 * @param data Pointer to data on which the CRC should be calculated.
1155 * @param len Data length.
1156 *
1157 * @return CRC32 value.
1158 *
1159 */
1160 #if defined(CONFIG_BT_OTS_OACP_CHECKSUM_SUPPORT)
bt_ots_client_calc_checksum(const uint8_t * data,size_t len)1161 static inline uint32_t bt_ots_client_calc_checksum(const uint8_t *data, size_t len)
1162 {
1163 return crc32_ieee(data, len);
1164 }
1165 #endif
1166
1167 #ifdef __cplusplus
1168 }
1169 #endif
1170
1171 /**
1172 * @}
1173 */
1174
1175 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_SERVICES_OTS_H_ */
1176