host/mesh: Fix crash on disconnect

bt_mesh_proxy_role_setup() is called conditionally when peer is
connected and gatt_disconnected() is always called. This leads
to unbalance in role->conn reference count and crash.

Instead of hot-fixing this in gatt_disconnected(), this commit adds
proper bt_mesh_proxy_role_cleanup() API that is called by roles
implementations if cleanup is needed.

This is port of 088fac76ed65a6cb8c367a89fae53d0e4bea2763
This commit is contained in:
Krzysztof Kopyściński
2021-11-10 06:24:00 +01:00
committed by Krzysztof Kopyściński
parent 267eed3ca7
commit f757df8e70
4 changed files with 10 additions and 13 deletions
+4 -1
View File
@@ -159,7 +159,10 @@ void gatt_disconnected_pb_gatt(uint16_t conn_handle, uint8_t reason)
return;
}
cli = NULL;
if (cli) {
bt_mesh_proxy_role_cleanup(cli);
cli = NULL;
}
BT_DBG("conn %p reason 0x%02x", (void *)conn, reason);
+1 -6
View File
@@ -200,13 +200,8 @@ struct bt_mesh_proxy_role *bt_mesh_proxy_role_setup(uint16_t conn_handle,
return role;
}
void gatt_disconnected_proxy_msg(uint16_t conn_handle, uint8_t reason)
void bt_mesh_proxy_role_cleanup(struct bt_mesh_proxy_role *role)
{
struct bt_mesh_proxy_role *role;
BT_DBG("conn_handle %d reason 0x%02x", conn_handle, reason);
role = &roles[conn_handle];
/* If this fails, the work handler exits early, as
* there's no active connection.
+1 -1
View File
@@ -60,7 +60,7 @@ ssize_t 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);
void bt_mesh_proxy_msg_init(struct bt_mesh_proxy_role *role);
void gatt_disconnected_proxy_msg(uint16_t conn_handle, uint8_t reason);
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,
proxy_send_cb_t send,
proxy_recv_cb_t recv);
+4 -5
View File
@@ -874,7 +874,10 @@ static void gatt_disconnected(uint16_t conn_handle, uint8_t reason)
conn_count--;
client = find_client(conn_handle);
client->cli = NULL;
if (client->cli) {
bt_mesh_proxy_role_cleanup(client->cli);
client->cli = NULL;
}
}
static int proxy_send(uint16_t conn_handle,
@@ -953,10 +956,6 @@ int ble_mesh_proxy_gap_event(struct ble_gap_event *event, void *arg)
#if MYNEWT_VAL(BLE_MESH_PB_GATT)
gatt_disconnected_pb_gatt(event->disconnect.conn.conn_handle,
event->disconnect.reason);
#endif
#if MYNEWT_VAL(BLE_MESH_PROXY)
gatt_disconnected_proxy_msg(event->disconnect.conn.conn_handle,
event->disconnect.reason);
#endif
} else if (event->type == BLE_GAP_EVENT_SUBSCRIBE) {
if (event->subscribe.attr_handle == svc_handles.proxy_data_out_h) {