diff --git a/nimble/host/mesh/src/adv_legacy.c b/nimble/host/mesh/src/adv_legacy.c index afbfc2fcd..94065bc9b 100644 --- a/nimble/host/mesh/src/adv_legacy.c +++ b/nimble/host/mesh/src/adv_legacy.c @@ -105,6 +105,8 @@ static inline void adv_send(struct os_mbuf *buf) param.itvl_max = param.itvl_min; param.conn_mode = BLE_GAP_CONN_MODE_NON; + int64_t time = k_uptime_get(); + err = bt_le_adv_start(¶m, duration, &ad, 1, NULL, 0); @@ -124,7 +126,7 @@ static inline void adv_send(struct os_mbuf *buf) return; } - BT_DBG("Advertising stopped"); + BT_DBG("Advertising stopped (%u ms)", (uint32_t) k_uptime_delta(&time)); } void @@ -136,30 +138,29 @@ mesh_adv_thread(void *args) BT_DBG("started"); while (1) { -#if (MYNEWT_VAL(BLE_MESH_PROXY)) - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0); - while (!ev) { - /* Adv timeout may be set by a call from proxy - * to bt_mesh_adv_start: - */ - adv_timeout = K_FOREVER; - if (bt_mesh_is_provisioned()) { - if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { - (void)bt_mesh_proxy_adv_start(); - BT_DBG("Proxy Advertising up to %d ms", (int) adv_timeout); + if (MYNEWT_VAL(BLE_MESH_GATT_SERVER)) { + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, 0); + while (!ev) { + /* Adv timeout may be set by a call from proxy + * to bt_mesh_adv_start: + */ + adv_timeout = K_FOREVER; + if (bt_mesh_is_provisioned()) { + if (IS_ENABLED(CONFIG_BT_MESH_GATT_PROXY)) { + bt_mesh_proxy_adv_start(); + 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(); - BT_DBG("PB-GATT Advertising up to %d ms", (int) adv_timeout); + + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout); + bt_le_adv_stop(); } - - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, adv_timeout); - bt_le_adv_stop(); + } else { + ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER); } -#else - ev = ble_npl_eventq_get(&bt_mesh_adv_queue, BLE_NPL_TIME_FOREVER); -#endif - if (!ev || !ble_npl_event_get_arg(ev)) { continue; } diff --git a/nimble/host/mesh/src/friend.c b/nimble/host/mesh/src/friend.c index 475fbd54e..c7603a8d9 100644 --- a/nimble/host/mesh/src/friend.c +++ b/nimble/host/mesh/src/friend.c @@ -60,15 +60,16 @@ struct friend_pdu_info { }; static struct friend_adv { + struct bt_mesh_adv adv; uint16_t app_idx; } 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; - return &adv_pool[id]; + return &adv_pool[id].adv; } 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; - 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) { 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 */ 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.dst = frnd->lpn; - info.ctl = 1; - info.ttl = 0; + info.ctl = 1U; + info.ttl = 0U; memset(info.seq, 0, sizeof(info.seq)); diff --git a/nimble/host/mesh/src/glue.c b/nimble/host/mesh/src/glue.c index c7b2cc16f..7a811210f 100644 --- a/nimble/host/mesh/src/glue.c +++ b/nimble/host/mesh/src/glue.c @@ -105,6 +105,10 @@ net_buf_unref(struct os_mbuf *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) { return; } @@ -154,13 +158,13 @@ net_buf_simple_pull_le16(struct os_mbuf *om) uint32_t net_buf_simple_pull_le24(struct os_mbuf *om) { - uint16_t val; + uint32_t val; struct os_mbuf *old = om; - om = os_mbuf_pullup(om, sizeof(val)); + om = os_mbuf_pullup(om, 3); assert(om == old); val = get_le24(om->om_data); - os_mbuf_adj(om, sizeof(val)); + os_mbuf_adj(om, 3); return val; } @@ -445,7 +449,7 @@ k_work_cancel_delayable(struct k_work_delayable *w) void k_work_schedule(struct k_work_delayable *w, uint32_t ms) - { +{ uint32_t ticks; 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 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) { - assert(0); - } - if (ms == 0) { - ble_npl_callout_stop(&w->work); - } - ble_npl_callout_reset(&w->work, ticks); + if (ble_npl_time_ms_to_ticks(ms, &ticks) != 0) { + assert(0); + } + ble_npl_callout_reset(&w->work, ticks); } 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); if (err) { BT_ERR("Advertising failed: err %d", err); diff --git a/nimble/host/mesh/src/mesh.c b/nimble/host/mesh/src/mesh.c index ccdfed37f..6ab71e8b1 100644 --- a/nimble/host/mesh/src/mesh.c +++ b/nimble/host/mesh/src/mesh.c @@ -316,6 +316,10 @@ int bt_mesh_init(uint8_t own_addr_type, const struct bt_mesh_prov *prov, return err; } +#if (MYNEWT_VAL(BLE_MESH_PROXY)) + bt_mesh_proxy_init(); +#endif + #if (MYNEWT_VAL(BLE_MESH_PROV)) err = bt_mesh_prov_init(prov); if (err) { diff --git a/nimble/host/mesh/src/pb_gatt.c b/nimble/host/mesh/src/pb_gatt.c index 6a215e1d3..906abd2fc 100644 --- a/nimble/host/mesh/src/pb_gatt.c +++ b/nimble/host/mesh/src/pb_gatt.c @@ -137,13 +137,6 @@ static int link_accept(const struct prov_bearer_cb *cb, void *cb_data) 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, 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); - 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) diff --git a/nimble/host/mesh/src/pb_gatt_srv.c b/nimble/host/mesh/src/pb_gatt_srv.c index 94dcd174a..61fadb6fc 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.c +++ b/nimble/host/mesh/src/pb_gatt_srv.c @@ -75,17 +75,11 @@ ble_uuid16_t BT_UUID_MESH_PROXY_DATA_OUT = BLE_UUID16_INIT(0x2ade); static bool prov_fast_adv; -static struct { - 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; +struct svc_handles svc_handles; +static atomic_t pending_notifications; static int gatt_send(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data); + const void *data, uint16_t len); 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 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) { const uint8_t *data = ctxt->om->om_data; uint16_t len = ctxt->om->om_len; struct bt_mesh_proxy_client *client = find_client(conn_handle); - - if (conn_handle != cli->conn_handle) { - return -ENOTCONN; - } - if (len < 1) { BT_WARN("Too small Proxy PDU"); 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); } +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) { struct ble_gap_conn_desc info; @@ -180,7 +193,7 @@ int prov_ccc_write(uint16_t conn_handle, uint8_t type) return -ENOTCONN; } - if (type != BLE_GAP_EVENT_NOTIFY_RX) { + if (type != BLE_GAP_EVENT_SUBSCRIBE) { BT_WARN("Client wrote instead enabling notify"); 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), .characteristics = (struct ble_gatt_chr_def[]) { { .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, }, { .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), .characteristics = (struct ble_gatt_chr_def[]) { { .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, }, { .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)), }; -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_send(uint16_t conn_handle, struct os_mbuf *buf) { if (!cli || cli->conn_handle != conn_handle) { BT_ERR("No PB-GATT Client found"); 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]) @@ -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, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data) + const void *data, uint16_t len) { struct os_mbuf *om; int err = 0; @@ -399,9 +410,11 @@ static int gatt_send(uint16_t conn_handle, om = ble_hs_mbuf_from_flat(data, len); assert(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; } diff --git a/nimble/host/mesh/src/pb_gatt_srv.h b/nimble/host/mesh/src/pb_gatt_srv.h index 364f53553..816089477 100644 --- a/nimble/host/mesh/src/pb_gatt_srv.h +++ b/nimble/host/mesh/src/pb_gatt_srv.h @@ -8,8 +8,7 @@ #ifndef __PB_GATT_SRV_H__ #define __PB_GATT_SRV_H__ -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_send(uint16_t conn_handle, struct os_mbuf *buf); int bt_mesh_pb_gatt_enable(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); +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__ */ \ No newline at end of file diff --git a/nimble/host/mesh/src/proxy.h b/nimble/host/mesh/src/proxy.h index f84fa424f..42530293e 100644 --- a/nimble/host/mesh/src/proxy.h +++ b/nimble/host/mesh/src/proxy.h @@ -9,6 +9,8 @@ #ifndef __PROXY_H__ #define __PROXY_H__ +#include "mesh/slist.h" + #if CONFIG_BT_MESH_DEBUG_USE_ID_ADDR #define ADV_OPT_USE_IDENTITY BT_LE_ADV_OPT_USE_IDENTITY #else @@ -23,6 +25,12 @@ .itvl_min = BT_GAP_ADV_FAST_INT_MIN_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_disable(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); int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg); +int bt_mesh_proxy_init(void); #endif /* __PROXY_H__ */ diff --git a/nimble/host/mesh/src/proxy_msg.c b/nimble/host/mesh/src/proxy_msg.c index 1ed3acdc5..44613af16 100644 --- a/nimble/host/mesh/src/proxy_msg.c +++ b/nimble/host/mesh/src/proxy_msg.c @@ -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 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, 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, - struct os_mbuf *msg, - void (*end)(uint16_t, void *), void *user_data) + struct os_mbuf *msg) { int err; 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; if (mtu > msg->om_len) { 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)); - err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); + err = role->cb.send(conn_handle, msg->om_data, mtu); if (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) { if (msg->om_len + 1 < mtu) { 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) { 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)); - err = role->cb.send(conn_handle, msg->om_data, mtu, NULL, NULL); + err = role->cb.send(conn_handle, msg->om_data, mtu); if (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 * to repeat the operation. */ - if (role->buf->om_data) { + if (role->buf != NULL) { net_buf_simple_reset(role->buf); return; } + role->buf = NET_BUF_SIMPLE(CONFIG_BT_MESH_PROXY_MSG_LEN); net_buf_simple_init_with_data(role->buf, &bufs[role->conn_handle * CONFIG_BT_MESH_PROXY_MSG_LEN], CONFIG_BT_MESH_PROXY_MSG_LEN); 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, diff --git a/nimble/host/mesh/src/proxy_msg.h b/nimble/host/mesh/src/proxy_msg.h index 0e06c5cae..349ebcdf4 100644 --- a/nimble/host/mesh/src/proxy_msg.h +++ b/nimble/host/mesh/src/proxy_msg.h @@ -26,8 +26,7 @@ struct bt_mesh_proxy_role; typedef int (*proxy_send_cb_t)(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data); + const void *data, uint16_t len); 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, const void *buf, uint16_t len); -int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, - struct os_mbuf *msg, void (*end)(uint16_t, void *), void *user_data); +int bt_mesh_proxy_msg_send(struct bt_mesh_proxy_role *role, uint8_t type, struct os_mbuf *msg); void bt_mesh_proxy_msg_init(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, diff --git a/nimble/host/mesh/src/proxy_srv.c b/nimble/host/mesh/src/proxy_srv.c index 7fa297fa7..f634f400e 100644 --- a/nimble/host/mesh/src/proxy_srv.c +++ b/nimble/host/mesh/src/proxy_srv.c @@ -9,6 +9,8 @@ #define MESH_LOG_MODULE BLE_MESH_PROXY_LOG +#include "mesh/slist.h" +#include "mesh/mesh.h" #include "../../host/src/ble_hs_priv.h" #include "services/gatt/ble_svc_gatt.h" @@ -43,19 +45,13 @@ (((w16) >> 0) & 0xFF), \ (((w16) >> 8) & 0xFF) -static struct { - 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; +static sys_slist_t idle_waiters; +static atomic_t pending_notifications; static void proxy_send_beacons(struct ble_npl_event *work); static int proxy_send(uint16_t conn_handle, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data); + const void *data, uint16_t len); 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; } - err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_CONFIG, - buf, NULL, NULL); + err = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_CONFIG, buf); if (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); - } +} 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); bt_mesh_beacon_create(sub, buf); - rc = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_BEACON, buf, - NULL, NULL); + rc = bt_mesh_proxy_msg_send(client->cli, BT_MESH_PROXY_BEACON, buf); os_mbuf_free_chain(buf); 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); - 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); if (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); - 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); if (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(""); - if (bt_mesh_is_provisioned()) { + if (!bt_mesh_is_provisioned()) { return -ENOTSUP; } @@ -751,13 +745,6 @@ static bool client_filter_match(struct bt_mesh_proxy_client *client, 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) { 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); 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); if (err) { @@ -808,23 +795,6 @@ bool bt_mesh_proxy_relay(struct os_mbuf *buf, uint16_t dst) 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) { 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, - const void *data, uint16_t len, - void (*end)(uint16_t, void *), void *user_data) + const void *data, uint16_t len) { struct os_mbuf *om; int err = 0; @@ -892,9 +876,12 @@ static int proxy_send(uint16_t conn_handle, om = ble_hs_mbuf_from_flat(data, len); assert(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; } @@ -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) { 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); } else if (event->type == BLE_GAP_EVENT_DISCONNECT) { 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); #endif } 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)) prov_ccc_write(event->subscribe.conn_handle, event->type); #endif @@ -987,9 +974,6 @@ int bt_mesh_proxy_init(void) #if (MYNEWT_VAL(BLE_MESH_GATT_PROXY)) k_work_init(&clients[i].send_beacons, proxy_send_beacons); #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();