Bluetooth: Mesh: Support for comp data page 2
Adds support for composition data page 2 & 130. In this implementation the responsibillity for filling the page 2 buffer is left to the application through the new comp page 2 cb API. Only the application can know/decide if the device is NLC compliant, and must thus be given the responsibillity for cheking the NLC profile requirements, defined in the NLC specs, and filling the response buffer for comp data page 2. Signed-off-by: Anders Storrø <anders.storro@nordicsemi.no>
This commit is contained in:
parent
e68de5bacc
commit
9d849736ef
5 changed files with 121 additions and 4 deletions
|
@ -1137,6 +1137,51 @@ struct bt_mesh_comp {
|
|||
struct bt_mesh_elem *elem; /**< List of elements. */
|
||||
};
|
||||
|
||||
/** Composition data page 2 record. */
|
||||
struct bt_mesh_comp2_record {
|
||||
/** Mesh profile ID. */
|
||||
uint16_t id;
|
||||
/** Mesh Profile Version. */
|
||||
struct {
|
||||
/** Major version. */
|
||||
uint8_t x;
|
||||
/** Minor version. */
|
||||
uint8_t y;
|
||||
/** Z version. */
|
||||
uint8_t z;
|
||||
} version;
|
||||
/** Element offset count. */
|
||||
uint8_t elem_offset_cnt;
|
||||
/** Element offset list. */
|
||||
const uint8_t *elem_offset;
|
||||
/** Length of additional data. */
|
||||
uint16_t data_len;
|
||||
/** Additional data. */
|
||||
const void *data;
|
||||
};
|
||||
|
||||
/** Node Composition data page 2 */
|
||||
struct bt_mesh_comp2 {
|
||||
/** The number of Mesh Profile records on a device. */
|
||||
size_t record_cnt;
|
||||
/** List of records. */
|
||||
const struct bt_mesh_comp2_record *record;
|
||||
};
|
||||
|
||||
/** @brief Register composition data page 2 of the device.
|
||||
*
|
||||
* Register Mesh Profiles information (Ref section 3.12 in
|
||||
* Bluetooth SIG Assigned Numbers) for composition data
|
||||
* page 2 of the device.
|
||||
*
|
||||
* @note There must be at least one record present in @c comp2
|
||||
*
|
||||
* @param comp2 Pointer to composition data page 2.
|
||||
*
|
||||
* @return Zero on success or (negative) error code otherwise.
|
||||
*/
|
||||
int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1373,6 +1373,11 @@ config BT_MESH_COMP_PAGE_1
|
|||
help
|
||||
Enable support for Composition Data Page 1.
|
||||
|
||||
config BT_MESH_COMP_PAGE_2
|
||||
bool "Support for Composition Data Page 2"
|
||||
help
|
||||
Enable support for Composition Data Page 2.
|
||||
|
||||
config BT_MESH_MODEL_EXTENSION_LIST_SIZE
|
||||
int "Model extensions list size"
|
||||
depends on BT_MESH_COMP_PAGE_1
|
||||
|
|
|
@ -53,6 +53,7 @@ struct comp_foreach_model_arg {
|
|||
};
|
||||
|
||||
static const struct bt_mesh_comp *dev_comp;
|
||||
static const struct bt_mesh_comp2 *dev_comp2;
|
||||
static uint16_t dev_primary_addr;
|
||||
static void (*msg_cb)(uint32_t opcode, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf);
|
||||
|
||||
|
@ -112,6 +113,9 @@ static const struct {
|
|||
#if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)
|
||||
{ "bt/mesh/cmp/1", 1, },
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)
|
||||
{ "bt/mesh/cmp/2", 2, },
|
||||
#endif
|
||||
};
|
||||
|
||||
void bt_mesh_model_foreach(void (*func)(struct bt_mesh_model *mod,
|
||||
|
@ -609,7 +613,7 @@ static size_t page1_elem_size(struct bt_mesh_elem *elem)
|
|||
return temp_size;
|
||||
}
|
||||
|
||||
int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf)
|
||||
static int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf)
|
||||
{
|
||||
const struct bt_mesh_comp *comp;
|
||||
uint8_t cor_id = 0;
|
||||
|
@ -660,6 +664,51 @@ int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bt_mesh_comp_data_get_page_2(struct net_buf_simple *buf)
|
||||
{
|
||||
if (!dev_comp2) {
|
||||
LOG_ERR("Composition data P2 not registered");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dev_comp2->record_cnt; i++) {
|
||||
if (net_buf_simple_tailroom(buf) <
|
||||
(8 + dev_comp2->record[i].elem_offset_cnt + dev_comp2->record[i].data_len +
|
||||
BT_MESH_MIC_SHORT)) {
|
||||
if (IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV)) {
|
||||
/* Mesh Profile 1.1 Section 4.4.1.2.2:
|
||||
* If the complete list of models does not fit in the Data field,
|
||||
* the element shall not be reported.
|
||||
*/
|
||||
LOG_DBG("Record 0x%04x didn't fit in the Data field",
|
||||
i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_ERR("Too large device composition");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
net_buf_simple_add_le16(buf, dev_comp2->record[i].id);
|
||||
net_buf_simple_add_u8(buf, dev_comp2->record[i].version.x);
|
||||
net_buf_simple_add_u8(buf, dev_comp2->record[i].version.y);
|
||||
net_buf_simple_add_u8(buf, dev_comp2->record[i].version.z);
|
||||
net_buf_simple_add_u8(buf, dev_comp2->record[i].elem_offset_cnt);
|
||||
if (dev_comp2->record[i].elem_offset_cnt) {
|
||||
net_buf_simple_add_mem(buf, dev_comp2->record[i].elem_offset,
|
||||
dev_comp2->record[i].elem_offset_cnt);
|
||||
}
|
||||
|
||||
net_buf_simple_add_le16(buf, dev_comp2->record[i].data_len);
|
||||
if (dev_comp2->record[i].data_len) {
|
||||
net_buf_simple_add_mem(buf, dev_comp2->record[i].data,
|
||||
dev_comp2->record[i].data_len);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t bt_mesh_model_pub_period_get(struct bt_mesh_model *mod)
|
||||
{
|
||||
int32_t period;
|
||||
|
@ -994,6 +1043,17 @@ int bt_mesh_comp_register(const struct bt_mesh_comp *comp)
|
|||
return err;
|
||||
}
|
||||
|
||||
int bt_mesh_comp2_register(const struct bt_mesh_comp2 *comp2)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_comp2 = comp2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bt_mesh_comp_provision(uint16_t addr)
|
||||
{
|
||||
int i;
|
||||
|
@ -2151,8 +2211,10 @@ int bt_mesh_comp_data_get_page(struct net_buf_simple *buf, size_t page, size_t o
|
|||
{
|
||||
if (page == 0 || page == 128) {
|
||||
return bt_mesh_comp_data_get_page_0(buf, offset);
|
||||
} else if (page == 1 || page == 129) {
|
||||
} else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) && (page == 1 || page == 129)) {
|
||||
return bt_mesh_comp_data_get_page_1(buf);
|
||||
} else if (IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) && (page == 2 || page == 130)) {
|
||||
return bt_mesh_comp_data_get_page_2(buf);
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
|
|
@ -27,7 +27,6 @@ size_t bt_mesh_comp_page_0_size(void);
|
|||
int bt_mesh_comp_data_get_page_0(struct net_buf_simple *buf, size_t offset);
|
||||
size_t bt_mesh_metadata_page_0_size(void);
|
||||
int bt_mesh_metadata_get_page_0(struct net_buf_simple *buf, size_t offset);
|
||||
int bt_mesh_comp_data_get_page_1(struct net_buf_simple *buf);
|
||||
|
||||
/* Find local element based on unicast address */
|
||||
struct bt_mesh_elem *bt_mesh_elem_find(uint16_t addr);
|
||||
|
|
|
@ -61,13 +61,19 @@ static int dev_comp_data_get(struct bt_mesh_model *model,
|
|||
|
||||
page = net_buf_simple_pull_u8(buf);
|
||||
|
||||
if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) &&
|
||||
if (page >= 130U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2) &&
|
||||
(atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
|
||||
IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
|
||||
page = 130U;
|
||||
} else if (page >= 129U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1) &&
|
||||
(atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
|
||||
IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
|
||||
page = 129U;
|
||||
} else if (page >= 128U && (atomic_test_bit(bt_mesh.flags, BT_MESH_COMP_DIRTY) ||
|
||||
IS_ENABLED(CONFIG_BT_MESH_RPR_SRV))) {
|
||||
page = 128U;
|
||||
} else if (page >= 2U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_2)) {
|
||||
page = 2U;
|
||||
} else if (page >= 1U && IS_ENABLED(CONFIG_BT_MESH_COMP_PAGE_1)) {
|
||||
page = 1U;
|
||||
} else if (page != 0U) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue