host/mesh: post-sync fixes part 2

This commit is contained in:
Krzysztof Kopyściński
2021-11-10 06:24:00 +01:00
committed by Krzysztof Kopyściński
parent d22137b286
commit 1cc3b1daae
11 changed files with 170 additions and 140 deletions
+23 -22
View File
@@ -105,6 +105,8 @@ static inline void adv_send(struct os_mbuf *buf)
param.itvl_max = param.itvl_min; param.itvl_max = param.itvl_min;
param.conn_mode = BLE_GAP_CONN_MODE_NON; param.conn_mode = BLE_GAP_CONN_MODE_NON;
int64_t time = k_uptime_get();
err = bt_le_adv_start(&param, duration, &ad, 1, NULL, 0); err = bt_le_adv_start(&param, duration, &ad, 1, NULL, 0);
@@ -124,7 +126,7 @@ static inline void adv_send(struct os_mbuf *buf)
return; return;
} }
BT_DBG("Advertising stopped"); BT_DBG("Advertising stopped (%u ms)", (uint32_t) k_uptime_delta(&time));
} }
void void
@@ -136,30 +138,29 @@ mesh_adv_thread(void *args)
BT_DBG("started"); BT_DBG("started");
while (1) { while (1) {
#if (MYNEWT_VAL(BLE_MESH_PROXY)) if (MYNEWT_VAL(BLE_MESH_GATT_SERVER)) {
ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0); ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0);
while (!ev) { while (!ev) {
/* Adv timeout may be set by a call from proxy /* Adv timeout may be set by a call from proxy
* to bt_mesh_adv_start: * to bt_mesh_adv_start:
*/ */
adv_timeout = K_FOREVER; adv_timeout = K_FOREVER;
if (bt_mesh_is_provisioned()) { if (bt_mesh_is_provisioned()) {
if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) {
(void)bt_mesh_proxy_adv_start(); bt_mesh_proxy_adv_start();
BT_DBG("Proxy Advertising up to %d ms", (int) adv_timeout); BT_DBG("Proxy Advertising up to %d ms", (int) adv_timeout);
}
} else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
bt_mesh_pb_gatt_adv_start();
BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout);
} }
} else if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT)) {
(void)bt_mesh_pb_gatt_adv_start(); ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout);
BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout); bt_le_adv_stop();
} }
} else {
ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout); ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER);
bt_le_adv_stop();
} }
#else
ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER);
#endif
if (!ev || !ble_npl_event_get_arg(ev)) { if (!ev || !ble_npl_event_get_arg(ev)) {
continue; continue;
} }
+9 -8
View File
@@ -60,15 +60,16 @@ struct friend_pdu_info {
}; };
static struct friend_adv { static struct friend_adv {
struct bt_mesh_adv adv;
uint16_t app_idx; uint16_t app_idx;
} adv_pool[FRIEND_BUF_COUNT]; } adv_pool[FRIEND_BUF_COUNT];
#define FRIEND_ADV(buf) (*(struct friend_adv **)net_buf_user_data(buf)) #define FRIEND_ADV(buf) CONTAINER_OF(BT_MESH_ADV(buf), struct friend_adv, adv)
static struct friend_adv *adv_alloc(int id) static struct bt_mesh_adv *adv_alloc(int id)
{ {
adv_pool[id].app_idx = BT_MESH_KEY_UNUSED; adv_pool[id].app_idx = BT_MESH_KEY_UNUSED;
return &adv_pool[id]; return &adv_pool[id].adv;
} }
static bool friend_is_allocated(const struct bt_mesh_friend *frnd) static bool friend_is_allocated(const struct bt_mesh_friend *frnd)
@@ -308,13 +309,13 @@ static struct os_mbuf *create_friend_pdu(struct bt_mesh_friend *frnd,
{ {
struct os_mbuf *buf; struct os_mbuf *buf;
buf = os_mbuf_get_pkthdr(&friend_os_mbuf_pool, BT_MESH_ADV_USER_DATA_SIZE); buf = bt_mesh_adv_create_from_pool(&friend_os_mbuf_pool, adv_alloc,
BT_MESH_ADV_DATA,
FRIEND_XMIT, K_NO_WAIT);
if (!buf) { if (!buf) {
return NULL; return NULL;
} }
FRIEND_ADV(buf) = adv_alloc(net_buf_id(buf));
net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */ net_buf_add_u8(buf, (info->iv_index & 1) << 7); /* Will be reset in encryption */
if (info->ctl) { if (info->ctl) {
@@ -538,8 +539,8 @@ static struct os_mbuf *encode_friend_ctl(struct bt_mesh_friend *frnd,
info.src = bt_mesh_primary_addr(); info.src = bt_mesh_primary_addr();
info.dst = frnd->lpn; info.dst = frnd->lpn;
info.ctl = 1; info.ctl = 1U;
info.ttl = 0; info.ttl = 0U;
memset(info.seq, 0, sizeof(info.seq)); memset(info.seq, 0, sizeof(info.seq));
+14 -13
View File
@@ -105,6 +105,10 @@ net_buf_unref(struct os_mbuf *om)
} }
adv = BT_MESH_ADV(om); adv = BT_MESH_ADV(om);
if (adv->started && adv->cb && adv->cb->end) {
adv->cb->end(0, adv->cb_data);
}
if (--adv->ref_cnt > 0) { if (--adv->ref_cnt > 0) {
return; return;
} }
@@ -154,13 +158,13 @@ net_buf_simple_pull_le16(struct os_mbuf *om)
uint32_t uint32_t
net_buf_simple_pull_le24(struct os_mbuf *om) net_buf_simple_pull_le24(struct os_mbuf *om)
{ {
uint16_t val; uint32_t val;
struct os_mbuf *old = om; struct os_mbuf *old = om;
om = os_mbuf_pullup(om, sizeof(val)); om = os_mbuf_pullup(om, 3);
assert(om == old); assert(om == old);
val = get_le24(om->om_data); val = get_le24(om->om_data);
os_mbuf_adj(om, sizeof(val)); os_mbuf_adj(om, 3);
return val; return val;
} }
@@ -445,7 +449,7 @@ k_work_cancel_delayable(struct k_work_delayable *w)
void void
k_work_schedule(struct k_work_delayable *w, uint32_t ms) k_work_schedule(struct k_work_delayable *w, uint32_t ms)
{ {
uint32_t ticks; uint32_t ticks;
if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) {
@@ -457,15 +461,12 @@ k_work_schedule(struct k_work_delayable *w, uint32_t ms)
void void
k_work_reschedule(struct k_work_delayable *w, uint32_t ms) k_work_reschedule(struct k_work_delayable *w, uint32_t ms)
{ {
uint32_t ticks; uint32_t ticks;
if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) {
assert(0); assert(0);
} }
if (ms == 0) { ble_npl_callout_reset(&w->work, ticks);
ble_npl_callout_stop(&w->work);
}
ble_npl_callout_reset(&w->work, ticks);
} }
void void
@@ -825,7 +826,7 @@ bt_le_adv_start(const struct ble_gap_adv_params *param,
} }
} }
err = ble_gap_adv_start(g_mesh_addr_type, NULL, duration, param, err = ble_gap_adv_start(g_mesh_addr_type, NULL, BLE_HS_FOREVER, param,
NULL, NULL); NULL, NULL);
if (err) { if (err) {
BT_ERR("Advertising failed: err %d", err); BT_ERR("Advertising failed: err %d", err);
+4
View File
@@ -316,6 +316,10 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov,
return err; return err;
} }
#if (MYNEWT_VAL(BLE_MESH_PROXY))
bt_mesh_proxy_init();
#endif
#if (MYNEWT_VAL(BLE_MESH_PROV)) #if (MYNEWT_VAL(BLE_MESH_PROV))
err = bt_mesh_prov_init(prov); err = bt_mesh_prov_init(prov);
if (err) { if (err) {
+1 -8
View File
@@ -137,13 +137,6 @@ static int link_accept(const struct prov_bearer_cb *cb, void *cb_data)
return 0; return 0;
} }
static void buf_send_end(uint16_t conn_handle, void *user_data)
{
if (link.comp.cb) {
link.comp.cb(0, link.comp.cb_data);
}
}
static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb, static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb,
void *cb_data) void *cb_data)
{ {
@@ -156,7 +149,7 @@ static int buf_send(struct os_mbuf *buf, prov_bearer_send_complete_t cb,
k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT); k_work_reschedule(&link.prot_timer, PROTOCOL_TIMEOUT);
return bt_mesh_pb_gatt_send(link.conn_handle, buf, buf_send_end, NULL); return bt_mesh_pb_gatt_send(link.conn_handle, buf);
} }
static void clear_tx(void) static void clear_tx(void)
+38 -25
View File
@@ -75,17 +75,11 @@ ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade);
static bool prov_fast_adv; static bool prov_fast_adv;
static struct { struct svc_handles svc_handles;
uint16_t proxy_h; static atomic_t pending_notifications;
uint16_t proxy_data_out_h;
uint16_t prov_h;
uint16_t prov_data_in_h;
uint16_t prov_data_out_h;
} svc_handles;
static int gatt_send(uint16_t conn_handle, static int gatt_send(uint16_t conn_handle,
const void *data, uint16_t len, const void *data, uint16_t len);
void (*end)(uint16_t, void *), void *user_data);
static struct bt_mesh_proxy_role *cli; static struct bt_mesh_proxy_role *cli;
@@ -104,18 +98,13 @@ static void proxy_msg_recv(struct bt_mesh_proxy_role *role)
static bool service_registered; static bool service_registered;
static int gatt_recv(uint16_t conn_handle, uint16_t attr_handle, static int gatt_recv_proxy(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg) struct ble_gatt_access_ctxt *ctxt, void *arg)
{ {
const uint8_t *data = ctxt->om->om_data; const uint8_t *data = ctxt->om->om_data;
uint16_t len = ctxt->om->om_len; uint16_t len = ctxt->om->om_len;
struct bt_mesh_proxy_client *client = find_client(conn_handle); struct bt_mesh_proxy_client *client = find_client(conn_handle);
if (conn_handle != cli->conn_handle) {
return -ENOTCONN;
}
if (len < 1) { if (len < 1) {
BT_WARN("Too small Proxy PDU"); BT_WARN("Too small Proxy PDU");
return -EINVAL; return -EINVAL;
@@ -129,6 +118,30 @@ static int gatt_recv(uint16_t conn_handle, uint16_t attr_handle,
return bt_mesh_proxy_msg_recv(client->cli, data, len); return bt_mesh_proxy_msg_recv(client->cli, data, len);
} }
static int gatt_recv_prov(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
const uint8_t *data = ctxt->om->om_data;
uint16_t len = ctxt->om->om_len;
if (conn_handle != cli->conn_handle) {
BT_WARN("conn_handle != cli->conn_handle");
return -ENOTCONN;
}
if (len < 1) {
BT_WARN("Too small Proxy PDU");
return -EINVAL;
}
if (PDU_TYPE(data) != BT_MESH_PROXY_PROV) {
BT_WARN("Proxy PDU type doesn't match GATT service");
return -EINVAL;
}
return bt_mesh_proxy_msg_recv(cli, data, len);
}
void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err) void gatt_connected_pb_gatt(uint16_t conn_handle, uint8_t err)
{ {
struct ble_gap_conn_desc info; struct ble_gap_conn_desc info;
@@ -180,7 +193,7 @@ int prov_ccc_write(uint16_t conn_handle, uint8_t type)
return -ENOTCONN; return -ENOTCONN;
} }
if (type != BLE_GAP_EVENT_NOTIFY_RX) { if (type != BLE_GAP_EVENT_SUBSCRIBE) {
BT_WARN("Client wrote instead enabling notify"); BT_WARN("Client wrote instead enabling notify");
return BT_GATT_ERR(EINVAL); return BT_GATT_ERR(EINVAL);
} }
@@ -211,7 +224,7 @@ static const struct ble_gatt_svc_def svc_defs [] = {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL), .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_VAL),
.characteristics = (struct ble_gatt_chr_def[]) { { .characteristics = (struct ble_gatt_chr_def[]) { {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL), .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_IN_VAL),
.access_cb = gatt_recv, .access_cb = gatt_recv_proxy,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP, .flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
}, { }, {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL), .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROXY_DATA_OUT_VAL),
@@ -225,7 +238,7 @@ static const struct ble_gatt_svc_def svc_defs [] = {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL), .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_VAL),
.characteristics = (struct ble_gatt_chr_def[]) { { .characteristics = (struct ble_gatt_chr_def[]) { {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL), .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_IN_VAL),
.access_cb = gatt_recv, .access_cb = gatt_recv_prov,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP, .flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
}, { }, {
.uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL), .uuid = BLE_UUID16_DECLARE(BT_UUID_MESH_PROV_DATA_OUT_VAL),
@@ -351,15 +364,14 @@ static const struct bt_data prov_ad[] = {
BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)), BT_DATA(BT_DATA_SVC_DATA16, prov_svc_data, sizeof(prov_svc_data)),
}; };
int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf)
void (*end)(uint16_t, void *), void *user_data)
{ {
if (!cli || cli->conn_handle != conn_handle) { if (!cli || cli->conn_handle != conn_handle) {
BT_ERR("No PB-GATT Client found"); BT_ERR("No PB-GATT Client found");
return -ENOTCONN; return -ENOTCONN;
} }
return bt_mesh_proxy_msg_send(cli, BT_MESH_PROXY_PROV, buf, end, user_data); return bt_mesh_proxy_msg_send(cli, BT_MESH_PROXY_PROV, buf);
} }
static size_t gatt_prov_adv_create(struct bt_data prov_sd[1]) static size_t gatt_prov_adv_create(struct bt_data prov_sd[1])
@@ -389,8 +401,7 @@ static size_t gatt_prov_adv_create(struct bt_data prov_sd[1])
} }
static int gatt_send(uint16_t conn_handle, static int gatt_send(uint16_t conn_handle,
const void *data, uint16_t len, const void *data, uint16_t len)
void (*end)(uint16_t, void *), void *user_data)
{ {
struct os_mbuf *om; struct os_mbuf *om;
int err = 0; int err = 0;
@@ -399,9 +410,11 @@ static int gatt_send(uint16_t conn_handle,
om = ble_hs_mbuf_from_flat(data, len); om = ble_hs_mbuf_from_flat(data, len);
assert(om); assert(om);
err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om); err = ble_gattc_notify_custom(conn_handle, svc_handles.prov_data_out_h, om);
/* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ notify_complete();
end(conn_handle, user_data); if (!err) {
atomic_inc(&pending_notifications);
}
return err; return err;
} }
+9 -2
View File
@@ -8,8 +8,7 @@
#ifndef __PB_GATT_SRV_H__ #ifndef __PB_GATT_SRV_H__
#define __PB_GATT_SRV_H__ #define __PB_GATT_SRV_H__
int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf, int bt_mesh_pb_gatt_send(uint16_t conn_handle, struct os_mbuf *buf);
void (*end)(uint16_t, void *), void *user_data);
int bt_mesh_pb_gatt_enable(void); int bt_mesh_pb_gatt_enable(void);
int bt_mesh_pb_gatt_disable(void); int bt_mesh_pb_gatt_disable(void);
@@ -21,4 +20,12 @@ void resolve_svc_handles(void);
int bt_mesh_pb_gatt_adv_start(void); int bt_mesh_pb_gatt_adv_start(void);
extern struct svc_handles {
uint16_t proxy_h;
uint16_t proxy_data_out_h;
uint16_t prov_h;
uint16_t prov_data_in_h;
uint16_t prov_data_out_h;
} svc_handles;
#endif /* __PB_GATT_SRV_H__ */ #endif /* __PB_GATT_SRV_H__ */
+9
View File
@@ -9,6 +9,8 @@
#ifndef __PROXY_H__ #ifndef __PROXY_H__
#define __PROXY_H__ #define __PROXY_H__
#include "mesh/slist.h"
#if CONFIG_BT_MESH_DEBUG_USE_ID_ADDR #if CONFIG_BT_MESH_DEBUG_USE_ID_ADDR
#define ADV_OPT_USE_IDENTITY BT_LE_ADV_OPT_USE_IDENTITY #define ADV_OPT_USE_IDENTITY BT_LE_ADV_OPT_USE_IDENTITY
#else #else
@@ -23,6 +25,12 @@
.itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \ .itvl_min = BT_GAP_ADV_FAST_INT_MIN_2, \
.itvl_max = BT_GAP_ADV_FAST_INT_MAX_2, .itvl_max = BT_GAP_ADV_FAST_INT_MAX_2,
struct bt_mesh_proxy_idle_cb {
sys_snode_t n;
void (*cb)(void);
};
void notify_complete(void);
int bt_mesh_proxy_gatt_enable(void); int bt_mesh_proxy_gatt_enable(void);
int bt_mesh_proxy_gatt_disable(void); int bt_mesh_proxy_gatt_disable(void);
void bt_mesh_proxy_gatt_disconnect(void); void bt_mesh_proxy_gatt_disconnect(void);
@@ -38,5 +46,6 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst);
void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr); void bt_mesh_proxy_addr_add(struct os_mbuf *buf, uint16_t addr);
int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg);
int bt_mesh_proxy_init(void);
#endif /* __PROXY_H__ */ #endif /* __PROXY_H__ */
+26 -7
View File
@@ -50,6 +50,22 @@ static uint8_t bufs[CONFIG_BT_MAX_CONN * CONFIG_BT_MESH_PROXY_MSG_LEN];
static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN]; static struct bt_mesh_proxy_role roles[CONFIG_BT_MAX_CONN];
static void proxy_sar_timeout(struct ble_npl_event *work)
{
struct bt_mesh_proxy_role *role;
int rc;
role = ble_npl_event_get_arg(work);
BT_WARN("Proxy SAR timeout");
if (role->conn_handle) {
rc = ble_gap_terminate(role->conn_handle,
BLE_ERR_REM_USER_CONN_TERM);
assert(rc == 0);
}
}
int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role,
const void *buf, uint16_t len) const void *buf, uint16_t len)
{ {
@@ -119,8 +135,7 @@ int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role,
} }
int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type,
struct os_mbuf *msg, struct os_mbuf *msg)
void (*end)(uint16_t, void *), void *user_data)
{ {
int err; int err;
uint16_t mtu; uint16_t mtu;
@@ -133,11 +148,11 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type,
mtu = ble_att_mtu(conn_handle) - 3; mtu = ble_att_mtu(conn_handle) - 3;
if (mtu > msg->om_len) { if (mtu > msg->om_len) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type)); net_buf_simple_push_u8(msg, PDU_HDR(SAR_COMPLETE, type));
return role->cb.send(conn_handle, msg->om_data, msg->om_len, end, user_data); return role->cb.send(conn_handle, msg->om_data, msg->om_len);
} }
net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type)); net_buf_simple_push_u8(msg, PDU_HDR(SAR_FIRST, type));
err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); err = role->cb.send(conn_handle, msg->om_data, mtu);
if (err) { if (err) {
return err; return err;
} }
@@ -146,7 +161,7 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type,
while (msg->om_len) { while (msg->om_len) {
if (msg->om_len + 1 < mtu) { if (msg->om_len + 1 < mtu) {
net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type)); net_buf_simple_push_u8(msg, PDU_HDR(SAR_LAST, type));
err = role->cb.send(conn_handle, msg->om_data, msg->om_len, end, user_data); err = role->cb.send(conn_handle, msg->om_data, msg->om_len);
if (err) { if (err) {
return err; return err;
} }
@@ -154,7 +169,7 @@ int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type,
} }
net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type)); net_buf_simple_push_u8(msg, PDU_HDR(SAR_CONT, type));
err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); err = role->cb.send(conn_handle, msg->om_data, mtu);
if (err) { if (err) {
return err; return err;
} }
@@ -170,17 +185,21 @@ static void proxy_msg_init(struct bt_mesh_proxy_role *role)
/* Check if buf has been allocated, in this way, we no longer need /* Check if buf has been allocated, in this way, we no longer need
* to repeat the operation. * to repeat the operation.
*/ */
if (role->buf->om_data) { if (role->buf != NULL) {
net_buf_simple_reset(role->buf); net_buf_simple_reset(role->buf);
return; return;
} }
role->buf = NET_BUF_SIMPLE(CONFIG_BT_MESH_PROXY_MSG_LEN);
net_buf_simple_init_with_data(role->buf, net_buf_simple_init_with_data(role->buf,
&bufs[role->conn_handle * &bufs[role->conn_handle *
CONFIG_BT_MESH_PROXY_MSG_LEN], CONFIG_BT_MESH_PROXY_MSG_LEN],
CONFIG_BT_MESH_PROXY_MSG_LEN); CONFIG_BT_MESH_PROXY_MSG_LEN);
net_buf_simple_reset(role->buf); net_buf_simple_reset(role->buf);
k_work_init_delayable(&role->sar_timer, proxy_sar_timeout);
k_work_add_arg_delayable(&role->sar_timer, role);
} }
struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle,
+2 -4
View File
@@ -26,8 +26,7 @@
struct bt_mesh_proxy_role; struct bt_mesh_proxy_role;
typedef int (*proxy_send_cb_t)(uint16_t conn_handle, typedef int (*proxy_send_cb_t)(uint16_t conn_handle,
const void *data, uint16_t len, const void *data, uint16_t len);
void (*end)(uint16_t, void *), void *user_data);
typedef void (*proxy_recv_cb_t)(struct bt_mesh_proxy_role *role); typedef void (*proxy_recv_cb_t)(struct bt_mesh_proxy_role *role);
@@ -57,8 +56,7 @@ struct bt_mesh_proxy_client {
int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role, int bt_mesh_proxy_msg_recv(struct bt_mesh_proxy_role *role,
const void *buf, uint16_t len); const void *buf, uint16_t len);
int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, struct os_mbuf *msg);
struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data);
void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role); void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role);
void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role); void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role);
struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle, struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle,
+35 -51
View File
@@ -9,6 +9,8 @@
#define MESH_LOG_MODULE BLE_MESH_PROXY_LOG #define MESH_LOG_MODULE BLE_MESH_PROXY_LOG
#include "mesh/slist.h"
#include "mesh/mesh.h"
#include "../../host/src/ble_hs_priv.h" #include "../../host/src/ble_hs_priv.h"
#include "services/gatt/ble_svc_gatt.h" #include "services/gatt/ble_svc_gatt.h"
@@ -43,19 +45,13 @@
(((w16) >> 0) & 0xFF), \ (((w16) >> 0) & 0xFF), \
(((w16) >> 8) & 0xFF) (((w16) >> 8) & 0xFF)
static struct { static sys_slist_t idle_waiters;
uint16_t proxy_h; static atomic_t pending_notifications;
uint16_t proxy_data_out_h;
uint16_t prov_h;
uint16_t prov_data_in_h;
uint16_t prov_data_out_h;
} svc_handles;
static void proxy_send_beacons(struct ble_npl_event *work); static void proxy_send_beacons(struct ble_npl_event *work);
static int proxy_send(uint16_t conn_handle, static int proxy_send(uint16_t conn_handle,
const void *data, uint16_t len, const void *data, uint16_t len);
void (*end)(uint16_t, void *), void *user_data);
static struct bt_mesh_proxy_client clients[CONFIG_BT_MAX_CONN]; static struct bt_mesh_proxy_client clients[CONFIG_BT_MAX_CONN];
@@ -185,8 +181,7 @@ static void send_filter_status(struct bt_mesh_proxy_client *client,
return; return;
} }
err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_CONFIG, err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_CONFIG, buf);
buf, NULL, NULL);
if (err) { if (err) {
BT_ERR("Failed to send proxy cfg message (err %d)", err); BT_ERR("Failed to send proxy cfg message (err %d)", err);
} }
@@ -262,7 +257,7 @@ static void proxy_cfg(struct bt_mesh_proxy_role *role)
} }
proxy_filter_recv(role->conn_handle, &rx, buf); proxy_filter_recv(role->conn_handle, &rx, buf);
} }
static void proxy_msg_recv(struct bt_mesh_proxy_role *role) static void proxy_msg_recv(struct bt_mesh_proxy_role *role)
{ {
@@ -293,8 +288,7 @@ static int beacon_send(struct bt_mesh_proxy_client *client, struct bt_mesh_subne
net_buf_simple_init(buf, 1); net_buf_simple_init(buf, 1);
bt_mesh_beacon_create(sub, buf); bt_mesh_beacon_create(sub, buf);
rc = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_BEACON, buf, rc = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_BEACON, buf);
NULL, NULL);
os_mbuf_free_chain(buf); os_mbuf_free_chain(buf);
return rc; return rc;
} }
@@ -434,7 +428,7 @@ static int node_id_adv(struct bt_mesh_subnet *sub, int32_t duration)
memcpy(proxy_svc_data + 3, tmp + 8, 8); memcpy(proxy_svc_data + 3, tmp + 8, 8);
err = bt_le_adv_start(&fast_adv_param, duration, node_id_ad, err = bt_mesh_adv_start(&fast_adv_param, duration, node_id_ad,
ARRAY_SIZE(node_id_ad), sd, 0); ARRAY_SIZE(node_id_ad), sd, 0);
if (err) { if (err) {
BT_WARN("Failed to advertise using Node ID (err %d)", err); BT_WARN("Failed to advertise using Node ID (err %d)", err);
@@ -472,7 +466,7 @@ static int net_id_adv(struct bt_mesh_subnet *sub, int32_t duration)
memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8); memcpy(proxy_svc_data + 3, sub->keys[SUBNET_KEY_TX_IDX(sub)].net_id, 8);
err = bt_le_adv_start(&slow_adv_param, duration, net_id_ad, err = bt_mesh_adv_start(&slow_adv_param, duration, net_id_ad,
ARRAY_SIZE(net_id_ad), sd, 0); ARRAY_SIZE(net_id_ad), sd, 0);
if (err) { if (err) {
BT_WARN("Failed to advertise using Network ID (err %d)", err); BT_WARN("Failed to advertise using Network ID (err %d)", err);
@@ -635,7 +629,7 @@ int bt_mesh_proxy_gatt_enable(void)
BT_DBG(""); BT_DBG("");
if (bt_mesh_is_provisioned()) { if (!bt_mesh_is_provisioned()) {
return -ENOTSUP; return -ENOTSUP;
} }
@@ -751,13 +745,6 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client,
return false; return false;
} }
static void buf_send_end(uint16_t conn_handle, void *user_data)
{
struct os_mbuf *buf = user_data;
net_buf_unref(buf);
}
bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst)
{ {
const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb; const struct bt_mesh_send_cb *cb = BT_MESH_ADV(buf)->cb;
@@ -787,7 +774,7 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst)
net_buf_simple_add_mem(msg, buf->om_data, buf->om_len); net_buf_simple_add_mem(msg, buf->om_data, buf->om_len);
err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_NET_PDU, err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_NET_PDU,
msg, buf_send_end, net_buf_ref(buf)); msg);
adv_send_start(0, err, cb, cb_data); adv_send_start(0, err, cb, cb_data);
if (err) { if (err) {
@@ -808,23 +795,6 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst)
return relayed; return relayed;
} }
static void proxy_sar_timeout(struct ble_npl_event *work)
{
struct bt_mesh_proxy_role *role;
int rc;
role = ble_npl_event_get_arg(work);
BT_WARN("Proxy SAR timeout");
if (role->conn_handle) {
rc = ble_gap_terminate(role->conn_handle,
BLE_ERR_REM_USER_CONN_TERM);
assert(rc == 0);
}
}
static void gatt_connected(uint16_t conn_handle) static void gatt_connected(uint16_t conn_handle)
{ {
struct bt_mesh_proxy_client *client; struct bt_mesh_proxy_client *client;
@@ -880,9 +850,23 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason)
} }
} }
void notify_complete(void)
{
sys_snode_t *n;
if (atomic_dec(&pending_notifications) > 1) {
return;
}
BT_DBG("");
while ((n = sys_slist_get(&idle_waiters))) {
CONTAINER_OF(n, struct bt_mesh_proxy_idle_cb, n)->cb();
}
}
static int proxy_send(uint16_t conn_handle, static int proxy_send(uint16_t conn_handle,
const void *data, uint16_t len, const void *data, uint16_t len)
void (*end)(uint16_t, void *), void *user_data)
{ {
struct os_mbuf *om; struct os_mbuf *om;
int err = 0; int err = 0;
@@ -892,9 +876,12 @@ static int proxy_send(uint16_t conn_handle,
om = ble_hs_mbuf_from_flat(data, len); om = ble_hs_mbuf_from_flat(data, len);
assert(om); assert(om);
err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om); err = ble_gattc_notify_custom(conn_handle, svc_handles.proxy_data_out_h, om);
/* We do not pass cb into ble_gattc_notify_custom - execute it at the end */ notify_complete();
if (!err) {
atomic_inc(&pending_notifications);
}
end(conn_handle, user_data);
return err; return err;
} }
@@ -948,7 +935,7 @@ static void ble_mesh_handle_connect(struct ble_gap_event *event, void *arg)
int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg) int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg)
{ {
if ((event->type == BLE_GAP_EVENT_CONNECT) || if ((event->type == BLE_GAP_EVENT_CONNECT) ||
(event->type == BLE_GAP_EVENT_ADV_COMPLETE)) { (event->type == BLE_GAP_EVENT_ADV_COMPLETE)) {
ble_mesh_handle_connect(event, arg); ble_mesh_handle_connect(event, arg);
} else if (event->type == BLE_GAP_EVENT_DISCONNECT) { } else if (event->type == BLE_GAP_EVENT_DISCONNECT) {
gatt_disconnected(event->disconnect.conn.conn_handle, gatt_disconnected(event->disconnect.conn.conn_handle,
@@ -963,7 +950,7 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg)
proxy_ccc_write(event->subscribe.conn_handle); proxy_ccc_write(event->subscribe.conn_handle);
#endif #endif
} else if (event->subscribe.attr_handle == } else if (event->subscribe.attr_handle ==
svc_handles.prov_data_out_h) { svc_handles.prov_data_out_h) {
#if (MYNEWT_VAL(BLE_MESH_PB_GATT)) #if (MYNEWT_VAL(BLE_MESH_PB_GATT))
prov_ccc_write(event->subscribe.conn_handle, event->type); prov_ccc_write(event->subscribe.conn_handle, event->type);
#endif #endif
@@ -987,9 +974,6 @@ int bt_mesh_proxy_init(void)
#if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY))
k_work_init(&clients[i].send_beacons, proxy_send_beacons); k_work_init(&clients[i].send_beacons, proxy_send_beacons);
#endif #endif
k_work_init_delayable(&clients[i].cli->sar_timer, proxy_sar_timeout);
k_work_add_arg_delayable(&clients[i].cli->sar_timer, &clients[i]);
} }
resolve_svc_handles(); resolve_svc_handles();