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