Skip to content

Commit a7254b8

Browse files
larsgknashif
authored andcommitted
shell: Fix BT verbose scan logging
Fix endianness printout of values. Handle service data output with initial UUID. Signed-off-by: Lars Knudsen <[email protected]>
1 parent 533c198 commit a7254b8

File tree

1 file changed

+94
-23
lines changed
  • subsys/bluetooth/shell

1 file changed

+94
-23
lines changed

subsys/bluetooth/shell/bt.c

Lines changed: 94 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ static struct bt_conn_auth_info_cb auth_info_cb;
6565

6666
#define KEY_STR_LEN 33
6767

68+
#define ADV_DATA_DELIMITER ", "
69+
6870
/*
6971
* Based on the maximum number of parameters for HCI_LE_Generate_DHKey
7072
* See BT Core Spec V5.2 Vol. 4, Part E, section 7.8.37
@@ -193,65 +195,134 @@ static bool data_cb(struct bt_data *data, void *user_data)
193195
}
194196
}
195197

196-
static void print_data_set(uint8_t type, uint8_t set_value_len,
198+
static void print_data_hex(const uint8_t *data, uint8_t len, enum shell_vt100_color color)
199+
{
200+
if (len == 0)
201+
return;
202+
203+
shell_fprintf(ctx_shell, color, "0x");
204+
/* Reverse the byte order when printing as advertising data is LE
205+
* and the MSB should be first in the printed output.
206+
*/
207+
for (int16_t i = len - 1; i >= 0; i--) {
208+
shell_fprintf(ctx_shell, color, "%02x", data[i]);
209+
}
210+
}
211+
212+
static void print_data_set(uint8_t set_value_len,
197213
const uint8_t *scan_data, uint8_t scan_data_len)
198214
{
199-
uint8_t min_value_len = MIN(set_value_len, scan_data_len);
215+
uint8_t idx = 0;
200216

201-
shell_fprintf(ctx_shell, SHELL_INFO, "%*sType 0x%02x: ",
202-
strlen(scan_response_label), "",
203-
type);
204-
for (uint8_t i = 0U; i < (scan_data_len / min_value_len); i++) {
205-
if (i > 0L) {
206-
shell_fprintf(ctx_shell, SHELL_INFO, ", ");
207-
}
217+
if (scan_data_len == 0 || set_value_len > scan_data_len) {
218+
return;
219+
}
208220

209-
shell_fprintf(ctx_shell, SHELL_INFO, "0x");
210-
for (uint8_t j = 0U; j < min_value_len; j++) {
211-
shell_fprintf(ctx_shell, SHELL_INFO, "%02x",
212-
scan_data[i * min_value_len + j]);
221+
do {
222+
if (idx > 0) {
223+
shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
213224
}
214-
}
215225

216-
shell_fprintf(ctx_shell, SHELL_INFO, "\n");
226+
print_data_hex(&scan_data[idx], set_value_len, SHELL_INFO);
227+
idx += set_value_len;
228+
} while (idx + set_value_len <= scan_data_len);
229+
230+
if (idx < scan_data_len) {
231+
shell_fprintf(ctx_shell, SHELL_WARNING, " Excess data: ");
232+
print_data_hex(&scan_data[idx], scan_data_len - idx, SHELL_WARNING);
233+
}
217234
}
218235

219236
static bool data_verbose_cb(struct bt_data *data, void *user_data)
220237
{
238+
shell_fprintf(ctx_shell, SHELL_INFO, "%*sType 0x%02x: ",
239+
strlen(scan_response_label), "", data->type);
240+
221241
switch (data->type) {
222242
case BT_DATA_UUID16_SOME:
223243
case BT_DATA_UUID16_ALL:
224244
case BT_DATA_SOLICIT16:
245+
print_data_set(BT_UUID_SIZE_16, data->data, data->data_len);
246+
break;
225247
case BT_DATA_SVC_DATA16:
226-
print_data_set(data->type, 2, data->data, data->data_len);
248+
/* Data starts with a UUID16 (2 bytes),
249+
* the rest is unknown and printed as single bytes
250+
*/
251+
if (data->data_len < BT_UUID_SIZE_16) {
252+
shell_fprintf(ctx_shell, SHELL_WARNING,
253+
"BT_DATA_SVC_DATA16 data length too short (%u)",
254+
data->data_len);
255+
break;
256+
}
257+
print_data_set(BT_UUID_SIZE_16, data->data, BT_UUID_SIZE_16);
258+
if (data->data_len > BT_UUID_SIZE_16) {
259+
shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
260+
print_data_set(1, data->data + BT_UUID_SIZE_16,
261+
data->data_len - BT_UUID_SIZE_16);
262+
}
227263
break;
228264
case BT_DATA_UUID32_SOME:
229265
case BT_DATA_UUID32_ALL:
266+
print_data_set(BT_UUID_SIZE_32, data->data, data->data_len);
267+
break;
230268
case BT_DATA_SVC_DATA32:
231-
print_data_set(data->type, 4, data->data, data->data_len);
269+
/* Data starts with a UUID32 (4 bytes),
270+
* the rest is unknown and printed as single bytes
271+
*/
272+
if (data->data_len < BT_UUID_SIZE_32) {
273+
shell_fprintf(ctx_shell, SHELL_WARNING,
274+
"BT_DATA_SVC_DATA32 data length too short (%u)",
275+
data->data_len);
276+
break;
277+
}
278+
print_data_set(BT_UUID_SIZE_32, data->data, BT_UUID_SIZE_32);
279+
if (data->data_len > BT_UUID_SIZE_32) {
280+
shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
281+
print_data_set(1, data->data + BT_UUID_SIZE_32,
282+
data->data_len - BT_UUID_SIZE_32);
283+
}
232284
break;
233285
case BT_DATA_UUID128_SOME:
234286
case BT_DATA_UUID128_ALL:
235287
case BT_DATA_SOLICIT128:
288+
print_data_set(BT_UUID_SIZE_128, data->data, data->data_len);
289+
break;
236290
case BT_DATA_SVC_DATA128:
237-
print_data_set(data->type, 16, data->data, data->data_len);
291+
/* Data starts with a UUID128 (16 bytes),
292+
* the rest is unknown and printed as single bytes
293+
*/
294+
if (data->data_len < BT_UUID_SIZE_128) {
295+
shell_fprintf(ctx_shell, SHELL_WARNING,
296+
"BT_DATA_SVC_DATA128 data length too short (%u)",
297+
data->data_len);
298+
break;
299+
}
300+
print_data_set(BT_UUID_SIZE_128, data->data, BT_UUID_SIZE_128);
301+
if (data->data_len > BT_UUID_SIZE_128) {
302+
shell_fprintf(ctx_shell, SHELL_INFO, ADV_DATA_DELIMITER);
303+
print_data_set(1, data->data + BT_UUID_SIZE_128,
304+
data->data_len - BT_UUID_SIZE_128);
305+
}
238306
break;
239307
case BT_DATA_NAME_SHORTENED:
240308
case BT_DATA_NAME_COMPLETE:
241309
case BT_DATA_BROADCAST_NAME:
242-
shell_info(ctx_shell, "%*sType 0x%02x: %.*s",
243-
strlen(scan_response_label), "",
244-
data->type, data->data_len, data->data);
310+
shell_fprintf(ctx_shell, SHELL_INFO, "%.*s", data->data_len, data->data);
245311
break;
246312
case BT_DATA_PUB_TARGET_ADDR:
247313
case BT_DATA_RAND_TARGET_ADDR:
248314
case BT_DATA_LE_BT_DEVICE_ADDRESS:
249-
print_data_set(data->type, BT_ADDR_SIZE, data->data, data->data_len);
315+
print_data_set(BT_ADDR_SIZE, data->data, data->data_len);
316+
break;
317+
case BT_DATA_CSIS_RSI:
318+
print_data_set(3, data->data, data->data_len);
250319
break;
251320
default:
252-
print_data_set(data->type, 1, data->data, data->data_len);
321+
print_data_set(1, data->data, data->data_len);
253322
}
254323

324+
shell_fprintf(ctx_shell, SHELL_INFO, "\n");
325+
255326
return true;
256327
}
257328

0 commit comments

Comments
 (0)