Skip to content

Commit 343870e

Browse files
committed
refactor(split): Clean up split GATT discovery.
* Use Zephyr auto CCC discovery instead of doing it ourselves. * Split service versus characteristic discovery into dedicated steps in the flow. * Fix for not searching properly when connecting to a peripheral a second time.
1 parent f55c2c1 commit 343870e

File tree

2 files changed

+58
-48
lines changed

2 files changed

+58
-48
lines changed

app/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ menuconfig ZMK_SPLIT_BLE_ROLE_CENTRAL
114114
bool "Central"
115115
select BT_CENTRAL
116116
select BT_GATT_CLIENT
117+
select BT_GATT_AUTO_DISCOVER_CCC
117118

118119
if ZMK_SPLIT_BLE_ROLE_CENTRAL
119120

app/src/split/bluetooth/central.c

+57-48
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ static int start_scan(void);
3131

3232
static struct bt_conn *default_conn;
3333

34-
static struct bt_uuid_128 uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID);
34+
static struct bt_uuid_128 split_service_uuid = BT_UUID_INIT_128(ZMK_SPLIT_BT_SERVICE_UUID);
3535
static struct bt_gatt_discover_params discover_params;
3636
static struct bt_gatt_subscribe_params subscribe_params;
37+
static struct bt_gatt_discover_params sub_discover_params;
3738
static uint16_t run_behavior_handle;
3839

3940
K_MSGQ_DEFINE(peripheral_event_msgq, sizeof(struct zmk_position_state_changed),
@@ -88,81 +89,85 @@ static uint8_t split_central_notify_func(struct bt_conn *conn,
8889
return BT_GATT_ITER_CONTINUE;
8990
}
9091

91-
static int split_central_subscribe(struct bt_conn *conn) {
92+
static void split_central_subscribe(struct bt_conn *conn) {
9293
int err = bt_gatt_subscribe(conn, &subscribe_params);
9394
switch (err) {
9495
case -EALREADY:
9596
LOG_DBG("[ALREADY SUBSCRIBED]");
9697
break;
97-
// break;
98-
// bt_gatt_unsubscribe(conn, &subscribe_params);
99-
// return split_central_subscribe(conn);
10098
case 0:
10199
LOG_DBG("[SUBSCRIBED]");
102100
break;
103101
default:
104102
LOG_ERR("Subscribe failed (err %d)", err);
105103
break;
106104
}
107-
108-
return 0;
109105
}
110106

111-
static uint8_t split_central_discovery_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
112-
struct bt_gatt_discover_params *params) {
113-
int err;
114-
107+
static uint8_t split_central_chrc_discovery_func(struct bt_conn *conn,
108+
const struct bt_gatt_attr *attr,
109+
struct bt_gatt_discover_params *params) {
115110
if (!attr) {
116111
LOG_DBG("Discover complete");
117-
(void)memset(params, 0, sizeof(*params));
118112
return BT_GATT_ITER_STOP;
119113
}
120114

121115
LOG_DBG("[ATTRIBUTE] handle %u", attr->handle);
122116

123-
if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID))) {
124-
memcpy(&uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID), sizeof(uuid));
125-
discover_params.uuid = &uuid.uuid;
126-
discover_params.start_handle = attr->handle + 1;
117+
if (attr->user_data &&
118+
!bt_uuid_cmp(((struct bt_gatt_chrc *)attr->user_data)->uuid,
119+
BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID))) {
120+
LOG_DBG("Found position state characteristic");
121+
discover_params.uuid = NULL;
122+
discover_params.start_handle = attr->handle + 2;
127123
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
128124

129-
err = bt_gatt_discover(conn, &discover_params);
130-
if (err) {
131-
LOG_ERR("Discover failed (err %d)", err);
132-
}
133-
} else if (!bt_uuid_cmp(discover_params.uuid,
134-
BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_POSITION_STATE_UUID))) {
135-
memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
136-
discover_params.uuid = &uuid.uuid;
137-
discover_params.start_handle = attr->handle + 2;
138-
discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
125+
subscribe_params.disc_params = &sub_discover_params;
126+
subscribe_params.end_handle = discover_params.end_handle;
139127
subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
140-
141-
err = bt_gatt_discover(conn, &discover_params);
142-
if (err) {
143-
LOG_ERR("Discover failed (err %d)", err);
144-
}
145-
} else if (!bt_uuid_cmp(discover_params.uuid,
146-
BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_RUN_BEHAVIOR_UUID))) {
147-
run_behavior_handle = bt_gatt_attr_value_handle(attr);
148-
} else {
149128
subscribe_params.notify = split_central_notify_func;
150129
subscribe_params.value = BT_GATT_CCC_NOTIFY;
151-
subscribe_params.ccc_handle = attr->handle;
152-
153130
split_central_subscribe(conn);
131+
} else if (attr->user_data &&
132+
!bt_uuid_cmp(((struct bt_gatt_chrc *)attr->user_data)->uuid,
133+
BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_RUN_BEHAVIOR_UUID))) {
134+
LOG_DBG("Found run behavior handle");
135+
run_behavior_handle = bt_gatt_attr_value_handle(attr);
136+
}
154137

155-
memcpy(&uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_CHAR_RUN_BEHAVIOR_UUID), sizeof(uuid));
156-
discover_params.uuid = &uuid.uuid;
157-
discover_params.start_handle = attr->handle + 1;
158-
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
138+
bool subscribed = (run_behavior_handle && subscribe_params.value_handle);
159139

160-
err = bt_gatt_discover(conn, &discover_params);
161-
if (err) {
162-
LOG_ERR("Discover failed (err %d)", err);
163-
}
140+
return subscribed ? BT_GATT_ITER_STOP : BT_GATT_ITER_CONTINUE;
141+
}
142+
143+
static uint8_t split_central_service_discovery_func(struct bt_conn *conn,
144+
const struct bt_gatt_attr *attr,
145+
struct bt_gatt_discover_params *params) {
146+
int err;
147+
148+
if (!attr) {
149+
LOG_DBG("Discover complete");
150+
(void)memset(params, 0, sizeof(*params));
151+
return BT_GATT_ITER_STOP;
152+
}
153+
154+
LOG_DBG("[ATTRIBUTE] handle %u", attr->handle);
155+
156+
if (bt_uuid_cmp(discover_params.uuid, BT_UUID_DECLARE_128(ZMK_SPLIT_BT_SERVICE_UUID))) {
157+
LOG_DBG("Found other service");
158+
return BT_GATT_ITER_CONTINUE;
164159
}
165160

161+
LOG_DBG("Found split service");
162+
discover_params.uuid = NULL;
163+
discover_params.func = split_central_chrc_discovery_func;
164+
discover_params.start_handle = attr->handle + 1;
165+
discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
166+
167+
err = bt_gatt_discover(conn, &discover_params);
168+
if (err) {
169+
LOG_ERR("Failed to start discovering split service characteristics (err %d)", err);
170+
}
166171
return BT_GATT_ITER_STOP;
167172
}
168173

@@ -177,9 +182,9 @@ static void split_central_process_connection(struct bt_conn *conn) {
177182
return;
178183
}
179184

180-
if (conn == default_conn && !subscribe_params.value) {
181-
discover_params.uuid = &uuid.uuid;
182-
discover_params.func = split_central_discovery_func;
185+
if (conn == default_conn && !subscribe_params.value_handle) {
186+
discover_params.uuid = &split_service_uuid.uuid;
187+
discover_params.func = split_central_service_discovery_func;
183188
discover_params.start_handle = 0x0001;
184189
discover_params.end_handle = 0xffff;
185190
discover_params.type = BT_GATT_DISCOVER_PRIMARY;
@@ -334,6 +339,10 @@ static void split_central_disconnected(struct bt_conn *conn, uint8_t reason) {
334339
bt_conn_unref(default_conn);
335340
default_conn = NULL;
336341

342+
// Clean up previously discovered handles;
343+
subscribe_params.value_handle = 0;
344+
run_behavior_handle = 0;
345+
337346
start_scan();
338347
}
339348

0 commit comments

Comments
 (0)