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.conn_mode = BLE_GAP_CONN_MODE_NON;
int64_t time = k_uptime_get();
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;
}
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;
}
+9 -8
View File
@@ -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));
+14 -13
View File
@@ -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);
+4
View File
@@ -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) {
+1 -8
View File
@@ -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)
+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 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;
}
+9 -2
View File
@@ -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__ */
+9
View File
@@ -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__ */
+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 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,
+2 -4
View File
@@ -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,
+35 -51
View File
@@ -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();