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:
parent
0cc408a9ac
commit
a3b6bc212f
7 changed files with 199 additions and 200 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue