Skip to content

gattc: add connect_bear support for ATT over BR/EDR#537

Open
liuX10 wants to merge 896 commits into
open-vela:devfrom
liuX10:gattc-connect-bear
Open

gattc: add connect_bear support for ATT over BR/EDR#537
liuX10 wants to merge 896 commits into
open-vela:devfrom
liuX10:gattc-connect-bear

Conversation

@liuX10
Copy link
Copy Markdown
Contributor

@liuX10 liuX10 commented Mar 23, 2026

Summary

Add bt_gattc_connect_bear API to support specifying the ATT bearer type (LE ATT or BR/EDR ATT) when initiating a GATT client connection.

Changes across all layers:

  • framework/include: add bt_gattc_connect_bear declaration
  • framework/api: add API routing to profile interface
  • framework/socket: add IPC message marshalling
  • framework/binder: add binder proxy call
  • service/ipc: add BT_GATT_CLIENT_CONNECT_BEAR IPC code and message struct
  • service/ipc/socket: add message dispatch handler
  • service/profiles: add connect_bear to gattc_interface_t and implementation
  • service/stacks/sal: add bt_sal_gatt_client_connect_bear with BR/EDR profile connect support
  • service/stacks/sal_gatt_server: fix undefined role variable in BR/EDR ATT callbacks
  • tools/gatt_client: add connect_bear command

Impact

Adds new API for BR/EDR ATT bearer connection. No breaking changes to existing APIs.

Testing

Build and functional test on target device with BR/EDR ATT connection scenarios.

expliyh and others added 30 commits December 23, 2025 23:48
bug: v/81504
Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
bug: v/80268

Rootcause: Not unregister callbacks when cleanup.
Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
bug: v/81522

When event_id == BT_AVRCP_EVT_VOLUME_CHANGED, flag = true is set only if both CONFIG_BLUETOOTH_AVRCP_ABSOLUTE_VOLUME and CONFIG_BLUETOOTH_AVRCP_CONTROL are enabled.
Otherwise in the else branch, flag = true is set only if CONFIG_BLUETOOTH_AVRCP_TARGET is enabled. All configurations are enabled, treating flag as always true, making the if (!flag) condition unreachable.

Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
bug: v/81702

Fixed memory leak caused by premature return.

Signed-off-by: liuxiang18 <liuxiang18@xiaomi.com>
bug: v/80258

Rootcause: attributes in bt_sdp_discover_params may be modified by ZBlue SDP. Using const could cause a crash in some cases
Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
bug: v/81752

Rootcause: audio_connect should not be called in bluetoothd task
Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
bug: v/81968

Rootcause: disconnected_callback not called caused connect info not cleared in connection manager module

Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
… an asynchronous API.

bug: v/81682

When priv dynamically allocates memory successfully but fails later due to other reasons before reaching the assignment ins->priv = priv;, the memory allocated to priv cannot be freed in bt_socket_async_client_deinit, leading to a resource leak.

Signed-off-by: jialu <jialu@xiaomi.com>
…se functions

bug: v/80811

Rootcause: In certain scenarios, users of `euv_pipe` must ensure all UV requests have completed execution before releasing resources. Consequently, it is necessary to notify users that `euv_pipe` has been fully released after its close operation is completed, thereby permitting subsequent operational procedures to proceed. Support for the close callback has therefore been added.

Signed-off-by: chejinxian1 <chejinxian1@xiaomi.com>
…e callback

bug: v/80808

Rootcause: In high-throughput reception scenarios, situations may arise where the `write_cb` for SPP data transmission to the application has not yet completed, yet the SPP device is released due to an abrupt disconnection, thereby preventing notification to the protocol stack that data reception has concluded.

To circumvent this issue, it is imperative to ensure all write operations are finalised before releasing the SPP device. Consequently, an `euv_pipe` close callback implementation has been introduced to guarantee that all `write_cb` operations execute successfully prior to severing the data pathway.

Signed-off-by: chejinxian1 <chejinxian1@xiaomi.com>
bug: v/74709

only open CONFIG_BLUETOOTH_AVRCP_CONTROL or CONFIG_BLUETOOTH_AVRCP_ABSOLUTE_VOLUME can build in bt_avrcp_control_notification_cb.

error: 'bt_avrcp_info_find_by_ct' undeclared (first use in this function); did you mean 'bt_avrcp_info_find_by_tg'?
 1501 |     avrcp_info = bt_list_find(bt_avrcp_conn, bt_avrcp_info_find_by_ct, ct);
      |                                              ^~~~~~~~~~~~~~~~~~~~~~~~
      |                                              bt_avrcp_info_find_by_tg

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/82095

The spp_connect_handler was attempting to look up the SPP connection
by rfcomm_dlc before it was added to the connection list, causing
"SPP connection not found for rfcomm_dlc" error.

Root Cause:
The connection object wasn't in the global connection list at the
time of lookup, making spp_find_connection_by_dlc() always fail.

Fix:
Pass the spp_conn pointer directly as user_data to avoid the lookup,
and add it to the connection list after successful initialization.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/81925

Add a generic descriptor allocation path, matching alloc_characteristic() style.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/81958

Some services are marked with GATT_PROP_EXPOSED_OVER_BREDR, but current
not implement gatt over bredr. As a temporary workaround, clear
this flag when calling add_service() so the service is exposed over BLE.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/82081

`bt_le_scan.h` is a globally exposed header file. Then, Zephyr's `#include <zephyr/bluetooth/bluetooth.h>` is declared as a private inclusion of Zephyr in CMake. However, the problem is that when third-party apps use my global `bt_le_scan.h`, the CMake system doesn't know where `zephyr/bluetooth/bluetooth.h` is and throws an error. One solution is for the third-party app to also declare a private inclusion of Zephyr in CMake, but this doesn't conform to design principles. The app only needs to be concerned with my framework layer. If the app also needs to include Zephyr's header files, then the framework layer is not properly configured. Therefore, `zephyr/bluetooth/bluetooth.h` must not be explicitly included in `bt_le_scan`.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/82104

The number of gatts sal DB attributes was insufficient for miwear's needs, so it was increased to a margin of 60. Future memory optimization projects will no longer maintain static arrays.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/81701

Rootcause: dereference null.
Signed-off-by: Yuheng Li <liyuheng@xiaomi.com>
bug: v/81701

Rootcause: unnecessary malloc
Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
bug: v/81924

By default, just working (no I/O) should automatically accept user confirmation, but for compatibility with the watch app, app confirmation is required.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/59050

Rootcause:When reconnect to the headset during a call, the headset will obtain the call status through the cind command. Since Vela does not have modem, the status will be error. So, get cind from Android.

Signed-off-by: zhangyuan20 <zhangyuan20@xiaomi.com>
bug: v/61170

Signed-off-by: zhangyuan20 <zhangyuan20@xiaomi.com>
bug: v/81520

In `spp_find_connection_by_sdp_param` and `spp_connect_with_uuid`, the pointer `spp_conn` was dereferenced before the NULL check. This patch ensures the pointer is validated before access to avoid potential crashes.

Signed-off-by: v-yichenxi <v-yichenxi@xiaomi.com>
bug: v/82928

Remove the redundant stack variable bd_addr, which already exists in sal_conn.

Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
bug: v/82928

Rootcause: bt_sal_get_remote_address may fail

Signed-off-by: YuhengLi <liyuheng@xiaomi.com>
Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
support.

bug: v/65087

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
…global database hash.

bug :v/65095

The logic is implemented in gatts_service.c to trigger hash calculation
and return the result via a registered callback, for trusted device sync and DB change tracking.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
…h from adapter to profile.

bug: v/65126

Root cause:
Adapter had no generic message path to deliver events to profile services.
GATTS could not receive a request to fetch the server database hash.
Add adapter handler to forward profile_msg_t to service_manager.
Add PROFILE_EVT_GATTS_REQUEST_DB_HASH and handle it in gatts_service via process_msg.
Wire bt_sal_gatt_server_get_database_hash() call when the event is received.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/65129

Root cause:
The stack did not compute and store the server GATT database hash on initial bonding.
Peers could keep a stale GATT cache because no hash update was triggered.
When a bonded LE device is connected, send PROFILE_EVT_GATTS_REQUEST_DB_HASH.
Force hash update to start cache sync for the new bond.

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
bug: v/65131

There was no persistent storage for the server GATT database hash.
The system could not compare hashes after reboot and peers could keep a stale GATT cache.
Add remote_device_gatt_properties_t with 16-byte hash field.
Add save/load APIs for GATT hash cache using the uv_db backend (BT_KEY_BLEGATTHASH).

Signed-off-by: zhongzhijie1 <zhongzhijie1@xiaomi.com>
expliyh added 4 commits April 15, 2026 15:51
bug: v/87673

Rootcause: Multiple bt_sal_hfp_ag_* functions directly call zblue
Z_API() in the caller's context, which can cause concurrent access
issues similar to the set_volume deadlock. Move all remaining AG
interfaces (voice_recognition, cind_response, dial_response,
cops_response, notify_device_status_changed, set_inband_ring_enable,
send_at_cmd, error_response) into service_loop_work to serialize
execution in the service loop.

Signed-off-by: liyuheng <liyuheng@xiaomi.com>
bug: v/87673

Rootcause: Multiple bt_sal_hfp_hf_* functions directly call zblue
Z_API() in the caller's context, which can cause concurrent access
issues. Move all remaining HF interfaces (answer_call, reject_call,
hold_call, hangup_call, dial_number, dial_memory, call_control,
get_current_calls, voice_recognition, send_battery_level, send_at_cmd,
send_dtmf, get_subscriber_number) into service_loop_work to serialize
execution in the service loop.

Signed-off-by: liyuheng <liyuheng@xiaomi.com>
bug: v/87935

Rootcause: The global connection list g_sal_ag_conn_list in
sal_hfp_ag_interface.c is accessed by multiple threads (zblue
callback thread, service work thread, upper layer API thread)
without any synchronization, which may cause data race, list
corruption, use-after-free or crash.

Add a pthread recursive mutex (g_sal_ag_conn_lock) with wrapper
functions conn_list_lock()/conn_list_unlock() to protect all
accesses to g_sal_ag_conn_list and calls sub-lists. The mutex
is initialized in bt_sal_hfp_ag_init() and destroyed in
bt_sal_hfp_ag_cleanup(). NULL checks for the list pointer are
moved inside the lock scope to avoid TOCTOU races.

Signed-off-by: liyuheng <liyuheng@xiaomi.com>
bug: v/87935

Rootcause: The global connection list g_sal_hf_conn_list in
sal_hfp_hf_interface.c is accessed by multiple threads (zblue
callback thread, service work thread, upper layer API thread)
without any synchronization, which may cause data race, list
corruption, use-after-free or crash.

Add a pthread recursive mutex (g_sal_hf_conn_lock) with wrapper
functions conn_list_lock()/conn_list_unlock() to protect all
accesses to g_sal_hf_conn_list and calls sub-lists. The mutex
is initialized in bt_sal_hfp_hf_init() and destroyed in
bt_sal_hfp_hf_cleanup(). NULL checks for the list pointer are
moved inside the lock scope to avoid TOCTOU races.

Signed-off-by: liyuheng <liyuheng@xiaomi.com>
jialu522 and others added 6 commits April 21, 2026 11:26
bug: v/88938

When acting as A2DP ACP, if the remote side disconnects ACL right after
Set Configuration (before media channel is established), a2dp_info->stream
is freed in a2dp_info_destroy() while zblue's ep->stream still references
the same memory. The subsequent avdtp_release_work() then accesses freed
memory (use-after-free).

Fix by deferring a2dp_info cleanup in zblue_on_disconnected() when stream
is still alive. The cleanup is completed later in zblue_on_stream_released()
after zblue finishes its release work.

Also guard DISCONNECTED_EVT in zblue_on_stream_released() to only fire
when media channel was actually established, avoiding duplicate events
with zblue_on_disconnected().

Add debug logging to a2dp_info_destroy, zblue_on_stream_configured,
zblue_on_stream_released, and zblue_on_disconnected for easier diagnosis.

Signed-off-by: Lu Jia <jialu@xiaomi.com>
bug: v/90257

Add log privacy as bitmask enum to support multiple privacy types.
Currently supports address privacy (BIT 0), extensible for future
types (e.g., name privacy).

- bt_addr.c/h: bt_addr_set_privacy()/bt_addr_get_privacy() for address masking
- log.h: enum bt_log_privacy_ bitmask, DEFAULT_BT_LOG_PRIVACY macro,
  bt_log_set_privacy() declaration
- log_server.c: privacy_flags in g_logger, bt_log_set_privacy() dispatches
  by changed bits, init/monitor via kvdb
- tools/log.c: bttool log privacy <bit> <0|1>
- Kconfig: BLUETOOTH_LOG_PRIVACY (int, default 0)

Signed-off-by: liuxiang18 <liuxiang18@xiaomi.com>
bug: v/88766

Add CS state machine encryption state, RAP GATTC connection
in connected state, framework API and socket IPC for RAP
operations, build system integration, and bttool le_cs
command updates.

Signed-off-by: huangyulong3 <huangyulong3@xiaomi.com>
bug: v/88762

Add CS RAP (Ranging Application Profile) implementation including
segment reassembly, step data restoration, Mode1 size detection,
RTT and phase-based distance calculation algorithms, and le_rap
command line tool.

Signed-off-by: huangyulong3 <huangyulong3@xiaomi.com>
bug: v/88765

Add cs_rap_gattc module for RAP GATT Client operations including
RAS service discovery, feature read, real-time and on-demand data
subscription, control point write, and lost segment retrieval.

Signed-off-by: huangyulong3 <huangyulong3@xiaomi.com>
bug: v/88240

Add null pointer and length check before memcpy in
if_gattc_on_element_read to prevent crash when stack
reports a read result with null value pointer.

Signed-off-by: liuxiang18 <liuxiang18@xiaomi.com>
@liuX10 liuX10 force-pushed the gattc-connect-bear branch 3 times, most recently from 1157e96 to 3dadcfb Compare May 8, 2026 06:12
Comment thread framework/binder/bt_gattc.c Outdated
return BpBtGattClient_connect(cbks->proxy, cbks->cookie, addr, addr_type);
}

bt_status_t bt_gattc_connect_bear(gattc_handle_t conn_handle, bt_address_t* addr, ble_addr_type_t addr_type, uint8_t bear_type)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove? we do not support binder

Comment thread framework/socket/bt_gattc.c Outdated
Copy link
Copy Markdown
Contributor

@chengkai15 chengkai15 May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we reuse bt_gattc_connect_bear?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we only have bt_gatts_connect_bear, To comply with the current coding guidelines, it is not recommended to use the GATTs API within GATTc.

uint8_t addr_type; /* ble_addr_type_t */
} _bt_gattc_connect;

struct {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest expand _bt_gattc_connect struct

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reference gatts

struct {
            uint64_t handle; /* gatts_handle_t */
            bt_address_t addr;
            uint8_t addr_type; /* ble_addr_type_t */
        } _bt_gatts_connect;

        struct {
            uint64_t handle; /* gatts_handle_t */
            bt_address_t addr;
            uint8_t addr_type; /* ble_addr_type_t */
            uint8_t bear_type; /* ble_bear_type_t */
        } _bt_gatts_connect_bear;

shall we edit with gatts?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

save. shall we edit gatts too.

Comment thread service/profiles/gatt/gattc_service.c Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove if_gattc_connect wirh if_gattc_connect_bear?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

default:
BT_LOGE("%s, invalid type:%d", __func__, addr_type);
assert(0);
free(req);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove static assert(0); check ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit with your previous comments and @zhongzhijie1 's comments

break;
default:
BT_LOGE("%s, invalid type:%d", __func__, addr_type);
free(req);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest warp these dup codes to a common func

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dito

liuX10 added 2 commits May 8, 2026 15:06
bug: v/88246

- Add helper to find the service declaration element from any
  characteristic or descriptor element within the same service table
- Add PTS mode check in read_value to reject cross-transport access:
  BR conn to LE-only service or LE conn to BR-only service returns 0x80

Signed-off-by: liuxiang18 <liuxiang18@xiaomi.com>
bug: v/87180

bt_sal_gatt_server_disable() only unregistered callbacks without
cleaning up server_db[] and server_svcs[] static arrays. Each
disable/enable cycle left stale attributes occupying slots, causing
attr_count to eventually reach CONFIG_GATT_SERVER_MAX_ATTRIBUTES.

- Add full resource cleanup in bt_sal_gatt_server_disable(): unregister
  all GATT services from zephyr, free SDP records, release all
  attribute user_data/uuid memory, and reset server_db/server_svcs/
  attr_count/svc_attr_count.
- Reorder if_gatts_shutdown() to call disable before freeing the
  upper-layer service list, ensuring zephyr unregister completes first.

Signed-off-by: liuxiang18 <liuxiang18@xiaomi.com>
@liuX10 liuX10 force-pushed the gattc-connect-bear branch from 3dadcfb to c1ddd69 Compare May 8, 2026 09:09
bug: v/88239

Add bt_gattc_connect_bear API to support specifying the ATT bearer
type (LE ATT or BR/EDR ATT) when initiating a GATT client connection.

Changes across all layers:
- framework/include: add bt_gattc_connect_bear declaration
- framework/api: add API routing to profile interface
- framework/socket: add IPC message marshalling
- framework/binder: add binder proxy call
- service/ipc: add BT_GATT_CLIENT_CONNECT_BEAR IPC code and message struct
- service/ipc/socket: add message dispatch handler
- service/profiles: add connect_bear to gattc_interface_t and implementation
- service/stacks/sal: add bt_sal_gatt_client_connect_bear with BR/EDR support
- service/stacks/sal_gatt_server: fix undefined role variable in BR/EDR ATT callbacks
- tools/gatt_client: add connect_bear command

Signed-off-by: liuxiang18 <liuxiang18@xiaomi.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.