Only exposing ATT services/characteristics to bonded devices?

15 views
Skip to first unread message

Joe Bibben

unread,
Jul 28, 2025, 1:31:58 AMJul 28
to btstack-dev
Hi,

Is there a way to configure BTstack to only expose configured ATT services/characteristics to bonded devices? As in unbonded devices should not be able to list them at all.

I've tried setting SM to require bonding, but this doesn't seem to force bonding (or even trigger it when trying to connect).

Thanks,
Joe

Matthias Ringwald

unread,
Jul 28, 2025, 1:42:35 AMJul 28
to btsta...@googlegroups.com
Hi Joe

The structure of GATT Services and Characteristic is generally public (see Bluetooth Core Specification), while read and write to Characteristic can be restricted to paired devices (with or without bonding). This is done by adding security requirements to the individual Characteristics.
Please have a look at example/sm_pairing_peripheral.gatt, which exposes a single Characteristic that requires at least an encrypted connection via "ENCRYPTION_KEY_SIZE_16".
See more in https://bluekitchen-gmbh.com/btstack/#profiles/%23gatt-server

In theory, you could use att_db_util, to dynamically update the ATT DB after a connection gets encrypted, but I would expect all kinds of weird issues with different peer devices.
What's your use case?

Cheers
Matthias
> --
> You received this message because you are subscribed to the Google Groups "btstack-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to btstack-dev...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/btstack-dev/1f8b5b9b-3899-43e7-8156-7575cfedb991n%40googlegroups.com.

Joe Bibben

unread,
Aug 11, 2025, 4:46:44 PMAug 11
to btstack-dev
Hey Matthias,

Thanks for getting back to me.

I've got an ESP32-based device I am trying to emulate, which is why I am looking for this admittedly odd behavior.

From a packet capture with the device in question, I see the following:

No. Time Source Destination Protocol Length VLAN TZSP Info
1 0.000000 controller host HCI_EVT 53 Rcvd LE Meta (LE Extended Advertising Report)
2 0.000868 controller host HCI_EVT 28 Rcvd LE Meta (LE Extended Advertising Report)
3 6.038913 controller host HCI_EVT 53 Rcvd LE Meta (LE Extended Advertising Report)
4 7.048878 controller host HCI_EVT 33 Rcvd LE Meta (LE Enhanced Connection Complete [v1])

5 7.070540 localhost () e2:cc:83:7b:41:da () ATT 11 Sent Exchange MTU Request, Client Rx MTU: 517
6 7.072923 e2:cc:83:7b:41:da () localhost () SMP 10 Rcvd Security Request: AuthReq: Bonding, SecureConnection
7 7.072969 localhost () e2:cc:83:7b:41:da () SMP 15 Sent Pairing Request: AuthReq: Bonding, SecureConnection | Initiator Key(s): LTK, CSRK, Linkkey | Responder Key(s): LTK, IRK, CSRK, Linkkey
8 7.116927 e2:cc:83:7b:41:da () localhost () ATT 11 Rcvd Exchange MTU Response, Server Rx MTU: 252
9 7.117208 localhost () e2:cc:83:7b:41:da () ATT 15 Sent Read By Type Request, Server Supported Features, Handles: 0x0001..0xffff
10 7.250923 e2:cc:83:7b:41:da () localhost () SMP 15 Rcvd Pairing Response: AuthReq: Bonding, SecureConnection | Initiator Key(s): <none> | Responder Key(s): <none>
11 7.250928 e2:cc:83:7b:41:da () localhost () ATT 13 Rcvd Error Response - Attribute Not Found, Handle: 0x0001 (Unknown)
12 7.258361 localhost () e2:cc:83:7b:41:da () SMP 73 Sent Pairing Public Key
13 7.258582 localhost () e2:cc:83:7b:41:da () ATT 15 Sent Read By Type Request, Database Hash, Handles: 0x0001..0xffff
14 7.340928 e2:cc:83:7b:41:da () localhost () HCI_ACL 31 Rcvd  [Reassembled in #16]
15 7.340934 e2:cc:83:7b:41:da () localhost () HCI_ACL 31 Rcvd  [Continuation to #14] [Reassembled in #16]
16 7.340934 e2:cc:83:7b:41:da () localhost () SMP 19 Rcvd Pairing Public Key
17 7.342924 e2:cc:83:7b:41:da () localhost () SMP 25 Rcvd Pairing Confirm
18 7.342927 e2:cc:83:7b:41:da () localhost () ATT 28 Rcvd Read By Type Response, Attribute List Length: 1
19 7.345220 localhost () e2:cc:83:7b:41:da () SMP 25 Sent Pairing Random
20 7.345624 localhost () e2:cc:83:7b:41:da () ATT 15 Sent Read By Type Request, Database Hash, Handles: 0x0009..0xffff
21 7.386914 e2:cc:83:7b:41:da () localhost () SMP 25 Rcvd Pairing Random
22 7.430921 e2:cc:83:7b:41:da () localhost () ATT 13 Rcvd Error Response - Attribute Not Found, Handle: 0x0009 (Unknown)
23 7.443811 localhost () e2:cc:83:7b:41:da () ATT 12 Sent Write Request, Handle: 0x0006 (Unknown)
24 7.520936 e2:cc:83:7b:41:da () localhost () ATT 9 Rcvd Write Response, Handle: 0x0006 (Unknown)
25 7.521270 localhost () e2:cc:83:7b:41:da () ATT 13 Sent Write Request, Handle: 0x0004 (Unknown)
26 7.745914 e2:cc:83:7b:41:da () localhost () ATT 9 Rcvd Write Response, Handle: 0x0004 (Unknown)
27 7.746342 localhost () e2:cc:83:7b:41:da () ATT 11 Sent Read Request, Handle: 0x000b (Unknown)
28 7.836069 e2:cc:83:7b:41:da () localhost () ATT 21 Rcvd Read Response, Handle: 0x000b (Unknown)
29 7.836689 localhost () e2:cc:83:7b:41:da () ATT 11 Sent Read Request, Handle: 0x000d (Unknown)
30 7.925952 e2:cc:83:7b:41:da () localhost () ATT 11 Rcvd Read Response, Handle: 0x000d (Unknown)
31 7.926378 localhost () e2:cc:83:7b:41:da () ATT 11 Sent Read Request, Handle: 0x000f (Unknown)
32 8.015946 e2:cc:83:7b:41:da () localhost () ATT 17 Rcvd Read Response, Handle: 0x000f (Unknown)


Which seems to indicate it won't respond with any attributes until bonded (from the fact it replies with attribute not found for 0x0001 in packet 11, although I could be mistaken). Also, it seems to send a security request immediately upon connection which is interesting. I assume this is something I could do myself inside one of BTstack's callbacks?

Appreciate the help!

Joe

Joe Bibben

unread,
Aug 11, 2025, 5:23:31 PMAug 11
to btstack-dev
Me again!

Worked it out in the end - using the following 2 callbacks works as expected (sm_pairing_peripheral's behaivour was the key! thank you!)

static void hci_packet_callback(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
if (hci_event_packet_get_type(packet) == HCI_EVENT_META_GAP && hci_event_gap_meta_get_subevent_code(packet) == GAP_SUBEVENT_LE_CONNECTION_COMPLETE) {
sm_request_pairing(gap_subevent_le_connection_complete_get_connection_handle(packet));
}
}

static void sm_packet_callback(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) {
if (hci_event_packet_get_type(packet) == SM_EVENT_JUST_WORKS_REQUEST) {
sm_just_works_confirm(sm_event_just_works_request_get_handle(packet));
}
}

Cheers!

Joe

Matthias Ringwald

unread,
Aug 12, 2025, 12:45:34 PMAug 12
to btsta...@googlegroups.com
Hi Joe

Glad you got it working. Did you have to modify the ATT DB at run time in the end, or was it enough to trigger the pairing after connect?

Cheers
Matthias
> To view this discussion visit https://groups.google.com/d/msgid/btstack-dev/ac6592e3-84c6-4768-9175-0d517e75a3aan%40googlegroups.com.


Reply all
Reply to author
Forward
0 new messages