Bluetooth: services: Refacter OTS dir list to avoid circular dependency

Refactors the OTS directory listing object implementation to avoid
circular dependency.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2021-03-15 12:57:22 +01:00 committed by Carles Cufí
commit a3b6bc212f
7 changed files with 199 additions and 200 deletions

View file

@ -33,9 +33,6 @@ extern "C" {
/** @brief Length of OTS object ID string (in bytes). */ /** @brief Length of OTS object ID string (in bytes). */
#define BT_OTS_OBJ_ID_STR_LEN 15 #define BT_OTS_OBJ_ID_STR_LEN 15
/** @brief ID of the Directory Listing Object */
#define OTS_OBJ_ID_DIR_LIST 0x000000000000
/** @brief Type of an OTS object. */ /** @brief Type of an OTS object. */
struct bt_ots_obj_type { struct bt_ots_obj_type {
union { union {
@ -196,124 +193,6 @@ enum {
#define BT_OTS_OBJ_GET_PROP_MARKED(prop) \ #define BT_OTS_OBJ_GET_PROP_MARKED(prop) \
((prop) & BIT(BT_OTS_OBJ_PROP_MARKED)) ((prop) & BIT(BT_OTS_OBJ_PROP_MARKED))
/** @brief Directory Listing record flag field. */
enum {
/** Bit 0 Object Type UUID Size 0: 16bit 1: 128bit*/
BT_OTS_DIR_LIST_FLAG_TYPE_128 = 0,
/** Bit 1 Current Size Present*/
BT_OTS_DIR_LIST_FLAG_CUR_SIZE = 1,
/** Bit 2 Allocated Size Present */
BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE = 2,
/** Bit 3 Object First-Created Present*/
BT_OTS_DIR_LIST_FLAG_FIRST_CREATED = 3,
/** Bit 4 Object Last-Modified Present*/
BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED = 4,
/** Bit 5 Object Properties Present*/
BT_OTS_DIR_LIST_FLAG_PROPERTIES = 5,
/** Bit 6 RFU*/
BT_OTS_DIR_LIST_FLAG_RFU = 6,
/** Bit 7 Extended Flags Present*/
BT_OTS_DIR_LIST_FLAG_EXTENDED = 7,
};
/** @brief Set @ref BT_OTS_DIR_LIST_SET_FLAG_TYPE_128 flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_TYPE_128(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_TYPE_128, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_CUR_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_CUR_SIZE(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_CUR_SIZE, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_ALLOC_SIZE(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_FIRST_CREATED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_FIRST_CREATED(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_FIRST_CREATED, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_LAST_MODIFIED(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_PROPERTIES flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_PROPERTIES(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_PROPERTIES, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_EXTENDED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_EXTENDED(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_EXTENDED, 1)
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_TYPE_128 flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_TYPE_128(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_TYPE_128))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_CUR_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_CUR_SIZE(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_CUR_SIZE))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_ALLOC_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_ALLOC_SIZE(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_FIRST_CREATED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_FIRST_CREATED(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_FIRST_CREATED))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_LAST_MODIFIED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_LAST_MODIFIED(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_PROPERTIES flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_PROPERTIES(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_PROPERTIES))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_EXTENDED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_EXTENDED(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_EXTENDED))
/** @brief Descriptor for OTS Object Size parameter. */ /** @brief Descriptor for OTS Object Size parameter. */
struct bt_ots_obj_size { struct bt_ots_obj_size {
/* Current Size */ /* Current Size */

View file

@ -168,12 +168,11 @@ int bt_ots_obj_add(struct bt_ots *ots,
int err; int err;
struct bt_gatt_ots_object *obj; struct bt_gatt_ots_object *obj;
#if IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) && ots->dir_list &&
if (ots->dir_list->dir_list_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) { ots->dir_list->dir_list_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) {
LOG_DBG("Directory Listing Object is being read"); LOG_DBG("Directory Listing Object is being read");
return -EBUSY; return -EBUSY;
} }
#endif /* CONFIG_BT_OTS_DIR_LIST_OBJ */
err = bt_gatt_ots_obj_manager_obj_add(ots->obj_manager, &obj); err = bt_gatt_ots_obj_manager_obj_add(ots->obj_manager, &obj);
if (err) { if (err) {
@ -185,7 +184,7 @@ int bt_ots_obj_add(struct bt_ots *ots,
memcpy(&obj->metadata, obj_init, sizeof(obj->metadata)); memcpy(&obj->metadata, obj_init, sizeof(obj->metadata));
if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) { if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
bt_ots_dir_list_obj_add(ots, obj); bt_ots_dir_list_obj_add(ots->dir_list, ots->obj_manager, ots->cur_obj, obj);
} }
/* Request object data. */ /* Request object data. */
@ -195,7 +194,8 @@ int bt_ots_obj_add(struct bt_ots *ots,
bt_gatt_ots_obj_manager_obj_delete(obj); bt_gatt_ots_obj_manager_obj_delete(obj);
if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) { if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
bt_ots_dir_list_obj_remove(ots, obj); bt_ots_dir_list_obj_remove(ots->dir_list, ots->obj_manager,
ots->cur_obj, obj);
} }
return err; return err;
@ -227,12 +227,11 @@ int bt_ots_obj_delete(struct bt_ots *ots, uint64_t id)
ots->cur_obj = NULL; ots->cur_obj = NULL;
} }
#if IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) && ots->dir_list &&
if (ots->dir_list->dir_list_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) { ots->dir_list->dir_list_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) {
LOG_DBG("Directory Listing Object is being read"); LOG_DBG("Directory Listing Object is being read");
return -EBUSY; return -EBUSY;
} }
#endif /* CONFIG_BT_OTS_DIR_LIST_OBJ */
err = bt_gatt_ots_obj_manager_obj_delete(obj); err = bt_gatt_ots_obj_manager_obj_delete(obj);
if (err) { if (err) {
@ -240,7 +239,7 @@ int bt_ots_obj_delete(struct bt_ots *ots, uint64_t id)
} }
if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) { if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
bt_ots_dir_list_obj_remove(ots, obj); bt_ots_dir_list_obj_remove(ots->dir_list, ots->obj_manager, ots->cur_obj, obj);
} }
if (ots->cb->obj_deleted) { if (ots->cb->obj_deleted) {
@ -304,7 +303,7 @@ int bt_ots_init(struct bt_ots *ots,
} }
if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) { if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
bt_ots_dir_list_init(ots); bt_ots_dir_list_init(&ots->dir_list, ots->obj_manager);
} }
LOG_DBG("Initialized OTS"); LOG_DBG("Initialized OTS");

View file

@ -14,6 +14,7 @@
#include <bluetooth/services/ots.h> #include <bluetooth/services/ots.h>
#include "ots_internal.h" #include "ots_internal.h"
#include "ots_obj_manager_internal.h" #include "ots_obj_manager_internal.h"
#include "ots_dir_list_internal.h"
#include <logging/log.h> #include <logging/log.h>
@ -67,52 +68,52 @@ static void dir_list_object_encode(struct bt_gatt_ots_object *obj,
sys_put_le16(net_buf_simple_tail(net_buf) - start, start); sys_put_le16(net_buf_simple_tail(net_buf) - start, start);
} }
void bt_ots_dir_list_obj_add(struct bt_ots *ots, void bt_ots_dir_list_obj_add(struct bt_ots_dir_list *dir_list, void *obj_manager,
struct bt_gatt_ots_object *obj) struct bt_gatt_ots_object *cur_obj, struct bt_gatt_ots_object *obj)
{ {
__ASSERT(ots->dir_list->dir_list_obj != obj, __ASSERT(dir_list->dir_list_obj != obj,
"Cannot add Directory Listing Object"); "Cannot add Directory Listing Object");
__ASSERT(bt_gatt_ots_obj_manager_obj_contains(ots->obj_manager, obj), __ASSERT(bt_gatt_ots_obj_manager_obj_contains(obj_manager, obj),
"Object not part of OTS instance"); "Object not part of OTS instance");
if (ots->dir_list->dir_list_obj != ots->cur_obj) { if (dir_list->dir_list_obj != cur_obj) {
/* We only need to update the object directory listing if it is currently selected, /* We only need to update the object directory listing if it is currently selected,
* as we otherwise only create it when it is selected. * as we otherwise only create it when it is selected.
*/ */
return; return;
} }
dir_list_object_encode(obj, &ots->dir_list->net_buf); dir_list_object_encode(obj, &dir_list->net_buf);
/*re-encode the Directory Listing Object size with the is new size*/ /*re-encode the Directory Listing Object size with the is new size*/
sys_put_le16(ots->dir_list->net_buf.len, ots->dir_list->net_buf.data); sys_put_le16(dir_list->net_buf.len, dir_list->net_buf.data);
/* Update Directory Listing Object metadata size */ /* Update Directory Listing Object metadata size */
ots->dir_list->dir_list_obj->metadata.size.cur = ots->dir_list->net_buf.len; dir_list->dir_list_obj->metadata.size.cur = dir_list->net_buf.len;
} }
void bt_ots_dir_list_obj_remove(struct bt_ots *ots, void bt_ots_dir_list_obj_remove(struct bt_ots_dir_list *dir_list, void *obj_manager,
struct bt_gatt_ots_object *obj) struct bt_gatt_ots_object *cur_obj, struct bt_gatt_ots_object *obj)
{ {
uint16_t offset = 0; uint16_t offset = 0;
__ASSERT(ots->dir_list->dir_list_obj != obj, __ASSERT(dir_list->dir_list_obj != obj,
"Cannot remove Directory Listing Object"); "Cannot remove Directory Listing Object");
__ASSERT(bt_gatt_ots_obj_manager_obj_contains(ots->obj_manager, obj), __ASSERT(bt_gatt_ots_obj_manager_obj_contains(obj_manager, obj),
"Object not part of OTS instance"); "Object not part of OTS instance");
if (ots->dir_list->dir_list_obj != ots->cur_obj) { if (dir_list->dir_list_obj != cur_obj) {
/* We only need to update the object directory listing if it is currently selected, /* We only need to update the object directory listing if it is currently selected,
* as we otherwise only create it when it is selected. * as we otherwise only create it when it is selected.
*/ */
return; return;
} }
while (offset < ots->dir_list->net_buf.len) { while (offset < dir_list->net_buf.len) {
uint16_t len = sys_get_le16(ots->dir_list->net_buf.data + offset); uint16_t len = sys_get_le16(dir_list->net_buf.data + offset);
uint64_t id = sys_get_le64(ots->dir_list->net_buf.data + offset + sizeof(len)); uint64_t id = sys_get_le64(dir_list->net_buf.data + offset + sizeof(len));
__ASSERT(len, "Invalid object length"); __ASSERT(len, "Invalid object length");
@ -120,113 +121,112 @@ void bt_ots_dir_list_obj_remove(struct bt_ots *ots,
/* Delete object by moving memory after the object to /* Delete object by moving memory after the object to
* the objects current location * the objects current location
*/ */
memmove(ots->dir_list->net_buf.data + offset, memmove(dir_list->net_buf.data + offset,
ots->dir_list->net_buf.data + offset + len, dir_list->net_buf.data + offset + len,
ots->dir_list->net_buf.len - (offset + len)); dir_list->net_buf.len - (offset + len));
/* Decrement net_buf len to new length */ /* Decrement net_buf len to new length */
ots->dir_list->net_buf.len -= len; dir_list->net_buf.len -= len;
break; break;
} }
offset += len; offset += len;
} }
__ASSERT(offset <= ots->dir_list->net_buf.len, "Object was not removed"); __ASSERT(offset <= dir_list->net_buf.len, "Object was not removed");
/*re-encode the Directory Listing Object size with the is new size*/ /*re-encode the Directory Listing Object size with the is new size*/
sys_put_le16(ots->dir_list->net_buf.len, ots->dir_list->net_buf.data); sys_put_le16(dir_list->net_buf.len, dir_list->net_buf.data);
/* Update Directory Listing Object metadata size */ /* Update Directory Listing Object metadata size */
ots->dir_list->dir_list_obj->metadata.size.cur = ots->dir_list->net_buf.len; dir_list->dir_list_obj->metadata.size.cur = dir_list->net_buf.len;
} }
static void dir_list_encode(struct bt_ots *ots) static void dir_list_encode(struct bt_ots_dir_list *dir_list, void *obj_manager)
{ {
struct bt_gatt_ots_object *obj; struct bt_gatt_ots_object *obj;
int err; int err;
err = bt_gatt_ots_obj_manager_first_obj_get(ots->obj_manager, &obj); err = bt_gatt_ots_obj_manager_first_obj_get(obj_manager, &obj);
__ASSERT(err == 0 && first_obj == ots->dir_list->dir_list_obj, __ASSERT(err == 0 && first_obj == dir_list->dir_list_obj,
"Expecting first object to be the Directory Listing Object"); "Expecting first object to be the Directory Listing Object");
/* Init with len = 0 to reset data */ /* Init with len = 0 to reset data */
net_buf_simple_init_with_data(&ots->dir_list->net_buf, net_buf_simple_init_with_data(&dir_list->net_buf, dir_list->_content,
ots->dir_list->_content, sizeof(dir_list->_content));
sizeof(ots->dir_list->_content)); dir_list->net_buf.len = 0;
ots->dir_list->net_buf.len = 0;
do { do {
dir_list_object_encode(obj, &ots->dir_list->net_buf); dir_list_object_encode(obj, &dir_list->net_buf);
err = bt_gatt_ots_obj_manager_next_obj_get(ots->obj_manager, obj, &obj); err = bt_gatt_ots_obj_manager_next_obj_get(obj_manager, obj, &obj);
} while (!err); } while (!err);
/*re-encode the Directory Listing Object size with the is new size*/ /*re-encode the Directory Listing Object size with the is new size*/
sys_put_le16(ots->dir_list->net_buf.len, ots->dir_list->net_buf.data); sys_put_le16(dir_list->net_buf.len, dir_list->net_buf.data);
/* Update Directory Listing Object metadata size */ /* Update Directory Listing Object metadata size */
ots->dir_list->dir_list_obj->metadata.size.cur = ots->dir_list->net_buf.len; dir_list->dir_list_obj->metadata.size.cur = dir_list->net_buf.len;
} }
void bt_ots_dir_list_selected(struct bt_ots *ots) void bt_ots_dir_list_selected(struct bt_ots_dir_list *dir_list, void *obj_manager,
struct bt_gatt_ots_object *cur_obj)
{ {
if (ots->dir_list->dir_list_obj != ots->cur_obj) { if (dir_list->dir_list_obj != cur_obj) {
/* We only need to update the object directory listing if it is currently selected, /* We only need to update the object directory listing if it is currently selected,
* as we otherwise only create it when it is selected. * as we otherwise only create it when it is selected.
*/ */
return; return;
} }
dir_list_encode(ots); dir_list_encode(dir_list, obj_manager);
} }
void bt_ots_dir_list_init(struct bt_ots *ots) void bt_ots_dir_list_init(struct bt_ots_dir_list **dir_list, void *obj_manager)
{ {
struct bt_gatt_ots_object *dir_list_obj; struct bt_gatt_ots_object *dir_list_obj;
int err; int err;
static char *dir_list_obj_name = CONFIG_BT_OTS_DIR_LIST_OBJ_NAME; static char *dir_list_obj_name = CONFIG_BT_OTS_DIR_LIST_OBJ_NAME;
if (!ots->dir_list) { __ASSERT(*dir_list, "Already initialized");
for (int i = 0; i < ARRAY_SIZE(dir_lists); i++) {
if (!dir_lists[i].dir_list_obj) { for (int i = 0; i < ARRAY_SIZE(dir_lists); i++) {
ots->dir_list = &dir_lists[i]; if (!dir_lists[i].dir_list_obj) {
} *dir_list = &dir_lists[i];
} }
} }
__ASSERT(ots->dir_list, __ASSERT(*dir_list, "Could not assign Directory Listing Object");
"Could not assign Directory Listing Object to OTS instance %p", ots);
__ASSERT(strlen(dir_list_obj_name) < UINT8_MAX, __ASSERT(strlen(dir_list_obj_name) < UINT8_MAX,
"BT_OTS_DIR_LIST_OBJ_NAME shall be less than 255 octets"); "BT_OTS_DIR_LIST_OBJ_NAME shall be less than 255 octets");
err = bt_gatt_ots_obj_manager_obj_add(ots->obj_manager, &dir_list_obj); err = bt_gatt_ots_obj_manager_obj_add(obj_manager, &dir_list_obj);
__ASSERT(!err, "Could not add Directory Listing Object for object manager %p", obj_man); __ASSERT(!err, "Could not add Directory Listing Object for object manager %p", obj_man);
memset(&dir_list_obj->metadata, 0, sizeof(dir_list_obj->metadata)); memset(&dir_list_obj->metadata, 0, sizeof(dir_list_obj->metadata));
dir_list_obj->metadata.name = dir_list_obj_name; dir_list_obj->metadata.name = dir_list_obj_name;
dir_list_obj->metadata.size.alloc = sizeof(ots->dir_list->_content); dir_list_obj->metadata.size.alloc = sizeof((*dir_list)->_content);
dir_list_obj->metadata.type.uuid.type = BT_UUID_TYPE_16; dir_list_obj->metadata.type.uuid.type = BT_UUID_TYPE_16;
dir_list_obj->metadata.type.uuid_16.val = BT_UUID_OTS_DIRECTORY_LISTING_VAL; dir_list_obj->metadata.type.uuid_16.val = BT_UUID_OTS_DIRECTORY_LISTING_VAL;
BT_OTS_OBJ_SET_PROP_READ(dir_list_obj->metadata.props); BT_OTS_OBJ_SET_PROP_READ(dir_list_obj->metadata.props);
ots->dir_list->dir_list_obj = dir_list_obj; (*dir_list)->dir_list_obj = dir_list_obj;
/* Set size in dir_list_encode */ /* Set size in dir_list_encode */
dir_list_encode(ots); dir_list_encode(*dir_list, obj_manager);
} }
int bt_ots_dir_list_content_get(struct bt_ots *ots, uint8_t **data, int bt_ots_dir_list_content_get(struct bt_ots_dir_list *dir_list, uint8_t **data,
uint32_t len, uint32_t offset) uint32_t len, uint32_t offset)
{ {
if (offset >= ots->dir_list->net_buf.len) { if (offset >= dir_list->net_buf.len) {
*data = NULL; *data = NULL;
return 0; return 0;
} }
*data = ots->dir_list->net_buf.data + offset; *data = dir_list->net_buf.data + offset;
return MIN(len, ots->dir_list->net_buf.len - offset); return MIN(len, dir_list->net_buf.len - offset);
} }

View file

@ -15,13 +15,139 @@ extern "C" {
#include <zephyr/types.h> #include <zephyr/types.h>
#include <bluetooth/gatt.h> #include <bluetooth/gatt.h>
#include <bluetooth/services/ots.h> #include <bluetooth/services/ots.h>
#include "ots_internal.h"
void bt_ots_dir_list_obj_add(struct bt_ots *ots, struct bt_gatt_ots_object *obj); struct bt_ots_dir_list {
void bt_ots_dir_list_obj_remove(struct bt_ots *ots, struct bt_gatt_ots_object *obj); struct net_buf_simple net_buf;
void bt_ots_dir_list_selected(struct bt_ots *ots); struct bt_gatt_ots_object *dir_list_obj;
void bt_ots_dir_list_init(struct bt_ots *ots); uint8_t _content[DIR_LIST_MAX_SIZE];
int bt_ots_dir_list_content_get(struct bt_ots *ots, uint8_t **data, };
/** @brief Directory Listing record flag field. */
enum {
/** Bit 0 Object Type UUID Size 0: 16bit 1: 128bit*/
BT_OTS_DIR_LIST_FLAG_TYPE_128 = 0,
/** Bit 1 Current Size Present*/
BT_OTS_DIR_LIST_FLAG_CUR_SIZE = 1,
/** Bit 2 Allocated Size Present */
BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE = 2,
/** Bit 3 Object First-Created Present*/
BT_OTS_DIR_LIST_FLAG_FIRST_CREATED = 3,
/** Bit 4 Object Last-Modified Present*/
BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED = 4,
/** Bit 5 Object Properties Present*/
BT_OTS_DIR_LIST_FLAG_PROPERTIES = 5,
/** Bit 6 RFU*/
BT_OTS_DIR_LIST_FLAG_RFU = 6,
/** Bit 7 Extended Flags Present*/
BT_OTS_DIR_LIST_FLAG_EXTENDED = 7,
};
/** @brief Set @ref BT_OTS_DIR_LIST_SET_FLAG_TYPE_128 flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_TYPE_128(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_TYPE_128, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_CUR_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_CUR_SIZE(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_CUR_SIZE, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_ALLOC_SIZE(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_FIRST_CREATED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_FIRST_CREATED(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_FIRST_CREATED, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_LAST_MODIFIED(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_PROPERTIES flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_PROPERTIES(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_PROPERTIES, 1)
/** @brief Set @ref BT_OTS_DIR_LIST_FLAG_EXTENDED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_SET_FLAG_EXTENDED(flags) \
WRITE_BIT((flags), BT_OTS_DIR_LIST_FLAG_EXTENDED, 1)
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_TYPE_128 flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_TYPE_128(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_TYPE_128))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_CUR_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_CUR_SIZE(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_CUR_SIZE))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_ALLOC_SIZE flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_ALLOC_SIZE(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_ALLOC_SIZE))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_FIRST_CREATED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_FIRST_CREATED(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_FIRST_CREATED))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_LAST_MODIFIED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_LAST_MODIFIED(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_LAST_MODIFIED))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_PROPERTIES flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_PROPERTIES(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_PROPERTIES))
/** @brief Get @ref BT_OTS_DIR_LIST_GET_FLAG_EXTENDED flag.
*
* @param flags Directory Listing Object flags.
*/
#define BT_OTS_DIR_LIST_GET_FLAG_EXTENDED(flags) \
((flags) & BIT(BT_OTS_DIR_LIST_FLAG_EXTENDED))
void bt_ots_dir_list_obj_add(struct bt_ots_dir_list *dir_list, void *obj_manager,
struct bt_gatt_ots_object *cur_obj, struct bt_gatt_ots_object *objj);
void bt_ots_dir_list_obj_remove(struct bt_ots_dir_list *dir_list, void *obj_manager,
struct bt_gatt_ots_object *cur_obj, struct bt_gatt_ots_object *obj);
void bt_ots_dir_list_selected(struct bt_ots_dir_list *dir_list, void *obj_manager,
struct bt_gatt_ots_object *cur_obj);
void bt_ots_dir_list_init(struct bt_ots_dir_list **dir_list, void *obj_manager);
int bt_ots_dir_list_content_get(struct bt_ots_dir_list *dir_list, uint8_t **data,
uint32_t len, uint32_t offset); uint32_t len, uint32_t offset);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -20,6 +20,9 @@ extern "C" {
#define DIR_LIST_OBJ_RECORD_MAX_SIZE 172 #define DIR_LIST_OBJ_RECORD_MAX_SIZE 172
#define DIR_LIST_MAX_SIZE (DIR_LIST_OBJ_RECORD_MAX_SIZE * CONFIG_BT_OTS_MAX_OBJ_CNT) #define DIR_LIST_MAX_SIZE (DIR_LIST_OBJ_RECORD_MAX_SIZE * CONFIG_BT_OTS_MAX_OBJ_CNT)
/** @brief ID of the Directory Listing Object */
#define OTS_OBJ_ID_DIR_LIST 0x000000000000
/**@brief OTS Attribute Protocol Application Error codes. */ /**@brief OTS Attribute Protocol Application Error codes. */
enum bt_gatt_ots_att_err_codes { enum bt_gatt_ots_att_err_codes {
/** An attempt was made to write a value that is invalid or /** An attempt was made to write a value that is invalid or
@ -70,12 +73,6 @@ struct bt_gatt_ots_indicate {
bool is_enabled; bool is_enabled;
}; };
struct bt_ots_dir_list {
struct net_buf_simple net_buf;
struct bt_gatt_ots_object *dir_list_obj;
uint8_t _content[DIR_LIST_MAX_SIZE];
};
struct bt_ots { struct bt_ots {
struct bt_ots_feat features; struct bt_ots_feat features;
struct bt_gatt_ots_object *cur_obj; struct bt_gatt_ots_object *cur_obj;
@ -84,9 +81,7 @@ struct bt_ots {
struct bt_gatt_ots_indicate olcp_ind; struct bt_gatt_ots_indicate olcp_ind;
struct bt_gatt_ots_l2cap l2cap; struct bt_gatt_ots_l2cap l2cap;
struct bt_ots_cb *cb; struct bt_ots_cb *cb;
#if defined(CONFIG_BT_OTS_DIR_LIST_OBJ)
struct bt_ots_dir_list *dir_list; struct bt_ots_dir_list *dir_list;
#endif /* CONFIG_BT_OTS_DIR_LIST_OBJ */
void *obj_manager; void *obj_manager;
}; };

View file

@ -212,7 +212,7 @@ static void oacp_read_proc_cb(struct bt_gatt_ots_l2cap *l2cap_ctx,
len = read_op->oacp_params.len - read_op->sent_len; len = read_op->oacp_params.len - read_op->sent_len;
if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) && if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) { ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
len = bt_ots_dir_list_content_get(ots, &obj_chunk, len, offset); len = bt_ots_dir_list_content_get(ots->dir_list, &obj_chunk, len, offset);
} else { } else {
len = ots->cb->obj_read(ots, conn, ots->cur_obj->id, &obj_chunk, len = ots->cb->obj_read(ots, conn, ots->cur_obj->id, &obj_chunk,
len, offset); len, offset);

View file

@ -285,7 +285,7 @@ ssize_t bt_gatt_ots_olcp_write(struct bt_conn *conn,
log_strdup(id)); log_strdup(id));
if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) { if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ)) {
bt_ots_dir_list_selected(ots); bt_ots_dir_list_selected(ots->dir_list, ots->obj_manager, ots->cur_obj);
} }
if (ots->cb->obj_selected) { if (ots->cb->obj_selected) {