diff --git a/framework/include/bluetooth.h b/framework/include/bluetooth.h index fdd52e3..421700d 100644 --- a/framework/include/bluetooth.h +++ b/framework/include/bluetooth.h @@ -56,6 +56,10 @@ extern "C" { #endif #endif // End of else +#define PRIMARY_ADAPTER 0 + +typedef uint8_t bt_controller_id_t; + typedef enum { BT_IO_CAPABILITY_DISPLAYONLY = 0, BT_IO_CAPABILITY_DISPLAYYESNO, @@ -182,6 +186,11 @@ typedef enum { BT_LE_ADDR_TYPE_UNKNOWN = 0xFF } ble_addr_type_t; +typedef enum { + BT_ADDR_TYPE_BREDR, + BT_ADDR_TYPE_UNKNOWN = 0xFF +} bt_addr_type_t; + /* * BLE PHY type */ typedef enum { BT_LE_1M_PHY, @@ -202,6 +211,11 @@ typedef enum { typedef uint8_t bt_128key_t[16]; +typedef struct { + uint8_t hash[16]; + uint8_t rand[16]; +} bt_oob_data_t; + #define COD_SERVICE_BITS(c) (c & 0xFFE000) /* The major service classes field */ #define COD_DEVICE_MAJOR_BITS(c) (c & 0x001F00) /* The major device classes field */ #define COD_DEVICE_CLASS_BITS(c) (c & 0x001FFC) /* The device classes field, including major and minor */ diff --git a/service/profiles/a2dp/a2dp_state_machine.c b/service/profiles/a2dp/a2dp_state_machine.c index a447cc4..0bc7206 100644 --- a/service/profiles/a2dp/a2dp_state_machine.c +++ b/service/profiles/a2dp/a2dp_state_machine.c @@ -41,9 +41,9 @@ #include "sal_a2dp_sink_interface.h" #include "sal_a2dp_source_interface.h" -#include "sal_adapter_interface.h" #include "sal_avrcp_control_interface.h" #include "sal_avrcp_target_interface.h" +#include "sal_interface.h" #include "a2dp_audio.h" #include "a2dp_control.h" @@ -362,7 +362,7 @@ static bt_status_t a2dp_offload_send_stop_cmd(a2dp_state_machine_t* a2dp_sm, STREAM_TO_UINT16(ocf, payload); flag_set(a2dp_sm, PENDING_OFFLOAD_STOP); - return bt_sal_send_hci_command(ogf, ocf, len, payload, bt_hci_event_callback, a2dp_sm); + return bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, len, payload, bt_hci_event_callback, a2dp_sm); } static bool flag_isset(a2dp_state_machine_t* a2dp_sm, pending_state_t flag) @@ -745,7 +745,7 @@ static bool opened_process_event(state_machine_t* sm, uint32_t event, void* p_da flag_set(a2dp_sm, PENDING_OFFLOAD_START); a2dp_sm->offload_timer = service_loop_timer(A2DP_OFFLOAD_TIMEOUT, 0, a2dp_offload_config_timeout_callback, a2dp_sm); - bt_sal_send_hci_command(ogf, ocf, len, payload, bt_hci_event_callback, + bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, len, payload, bt_hci_event_callback, a2dp_sm); break; } @@ -834,7 +834,7 @@ static bt_status_t a2dp_send_active_link_cmd(a2dp_state_machine_t* a2dp_sm, bool STREAM_TO_UINT16(ocf, payload); size -= sizeof(ogf) + sizeof(ocf); - return bt_sal_send_hci_command(ogf, ocf, size, payload, NULL /* TODO: add callback */, a2dp_sm); + return bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, size, payload, NULL /* TODO: add callback */, a2dp_sm); } static void started_enter(state_machine_t* sm) diff --git a/service/profiles/a2dp/source/a2dp_source_service.c b/service/profiles/a2dp/source/a2dp_source_service.c index 6ac1952..a5a4e41 100644 --- a/service/profiles/a2dp/source/a2dp_source_service.c +++ b/service/profiles/a2dp/source/a2dp_source_service.c @@ -30,7 +30,7 @@ #include "bt_list.h" #include "callbacks_list.h" #include "sal_a2dp_source_interface.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "service_loop.h" #include "service_manager.h" #include "utils/log.h" @@ -117,7 +117,7 @@ static void a2dp_service_prepare_handle(a2dp_state_machine_t* sm, { switch (event->event) { case CONNECTED_EVT: { - set_active_peer(&event->event_data.bd_addr, bt_sal_get_acl_link_handle(&event->event_data.bd_addr, BT_TRANSPORT_BREDR)); + set_active_peer(&event->event_data.bd_addr, bt_sal_get_acl_connection_handle(PRIMARY_ADAPTER, &event->event_data.bd_addr, BT_TRANSPORT_BREDR)); break; } diff --git a/service/profiles/hfp_ag/hfp_ag_state_machine.c b/service/profiles/hfp_ag/hfp_ag_state_machine.c index cd2f216..20a3509 100644 --- a/service/profiles/hfp_ag/hfp_ag_state_machine.c +++ b/service/profiles/hfp_ag/hfp_ag_state_machine.c @@ -34,8 +34,8 @@ #include "hfp_ag_tele_service.h" #include "media_system.h" #include "power_manager.h" -#include "sal_adapter_interface.h" #include "sal_hfp_ag_interface.h" +#include "sal_interface.h" #include "utils/log.h" #define HFP_AG_RETRY_MAX 1 @@ -880,7 +880,7 @@ static bt_status_t ag_offload_send_cmd(ag_state_machine_t* agsm, bool is_start) STREAM_TO_UINT16(ocf, payload); size -= sizeof(ogf) + sizeof(ocf); - return bt_sal_send_hci_command(ogf, ocf, size, payload, bt_hci_event_callback, agsm); + return bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, size, payload, bt_hci_event_callback, agsm); } static bool is_virtual_call_allowed(state_machine_t* sm) @@ -940,7 +940,7 @@ static bool connected_process_event(state_machine_t* sm, uint32_t event, void* p hsm_transition_to(sm, &audio_connecting_state); break; case AG_STACK_EVENT_AUDIO_REQ: - if (bt_sal_reply_sco_link_request(&agsm->addr, true) != BT_STATUS_SUCCESS) { + if (bt_sal_sco_connection_reply(PRIMARY_ADAPTER, &agsm->addr, true) != BT_STATUS_SUCCESS) { BT_ADDR_LOG("Reply audio request fail:%s", &agsm->addr); return false; } diff --git a/service/profiles/hfp_hf/hfp_hf_state_machine.c b/service/profiles/hfp_hf/hfp_hf_state_machine.c index fc6e70e..dfd39ef 100644 --- a/service/profiles/hfp_hf/hfp_hf_state_machine.c +++ b/service/profiles/hfp_hf/hfp_hf_state_machine.c @@ -31,8 +31,8 @@ #include "hfp_hf_state_machine.h" #include "media_system.h" #include "power_manager.h" -#include "sal_adapter_interface.h" #include "sal_hfp_hf_interface.h" +#include "sal_interface.h" #include "service_loop.h" #include "utils/log.h" @@ -428,7 +428,7 @@ static bt_status_t hf_offload_send_cmd(hf_state_machine_t* hfsm, bool is_start) STREAM_TO_UINT16(ocf, payload); size -= sizeof(ogf) + sizeof(ocf); - return bt_sal_send_hci_command(ogf, ocf, size, payload, bt_hci_event_callback, hfsm); + return bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, size, payload, bt_hci_event_callback, hfsm); } static bool check_hfp_allowed(hf_state_machine_t* hfsm) @@ -1215,7 +1215,7 @@ static bool connected_process_event(state_machine_t* sm, uint32_t event, void* p pending_action_create(hfsm, HFP_ATCMD_CODE_BLDN, NULL); break; case HF_STACK_EVENT_AUDIO_REQ: - status = bt_sal_reply_sco_link_request(&hfsm->addr, true); + status = bt_sal_sco_connection_reply(PRIMARY_ADAPTER, &hfsm->addr, true); if (status != BT_STATUS_SUCCESS) { BT_LOGE("Accept Sco request failed"); } diff --git a/service/profiles/leaudio/client/lea_client_state_machine.c b/service/profiles/leaudio/client/lea_client_state_machine.c index 147605f..f18fba3 100644 --- a/service/profiles/leaudio/client/lea_client_state_machine.c +++ b/service/profiles/leaudio/client/lea_client_state_machine.c @@ -29,7 +29,7 @@ #include "lea_client_service.h" #include "lea_client_state_machine.h" #include "lea_codec.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "sal_lea_client_interface.h" #include "sal_lea_common.h" #include "service_loop.h" @@ -477,7 +477,7 @@ static void lea_client_stop_offload_req(lea_client_state_machine_t* leas_sm, lea STREAM_TO_UINT16(ocf, payload); flag_set(leas_sm, PENDING_OFFLOAD_STOP); - bt_sal_send_hci_command(ogf, ocf, len, payload, bt_hci_event_callback, + bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, len, payload, bt_hci_event_callback, leas_sm); } @@ -539,7 +539,7 @@ static bool started_process_event(state_machine_t* sm, uint32_t event, void* p_d flag_set(leas_sm, PENDING_OFFLOAD_START); leas_sm->offload_timer = service_loop_timer(LEA_SERVER_OFFLOAD_TIMEOUT, 0, lea_offload_config_timeout_callback, leas_sm); - bt_sal_send_hci_command(ogf, ocf, len, payload, bt_hci_event_callback, + bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, len, payload, bt_hci_event_callback, leas_sm); break; } diff --git a/service/profiles/leaudio/server/lea_server_state_machine.c b/service/profiles/leaudio/server/lea_server_state_machine.c index 2a1e6ee..ce4a956 100644 --- a/service/profiles/leaudio/server/lea_server_state_machine.c +++ b/service/profiles/leaudio/server/lea_server_state_machine.c @@ -28,7 +28,7 @@ #include "lea_audio_source.h" #include "lea_server_service.h" #include "lea_server_state_machine.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "sal_lea_server_interface.h" #include "service_loop.h" @@ -410,7 +410,7 @@ static void lea_server_stop_offload_req(lea_server_state_machine_t* leas_sm, lea STREAM_TO_UINT16(ocf, payload); flag_set(leas_sm, PENDING_OFFLOAD_STOP); - bt_sal_send_hci_command(ogf, ocf, len, payload, bt_hci_event_callback, + bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, len, payload, bt_hci_event_callback, leas_sm); } @@ -460,7 +460,7 @@ static bool opened_process_event(state_machine_t* sm, uint32_t event, void* p_da flag_set(leas_sm, PENDING_OFFLOAD_START); leas_sm->offload_timer = service_loop_timer(LEA_SERVER_OFFLOAD_TIMEOUT, 0, lea_offload_config_timeout_callback, leas_sm); - bt_sal_send_hci_command(ogf, ocf, len, payload, bt_hci_event_callback, + bt_sal_send_hci_command(PRIMARY_ADAPTER, ogf, ocf, len, payload, bt_hci_event_callback, leas_sm); break; } diff --git a/service/src/adapter_internel.h b/service/src/adapter_internel.h index cf89866..0002ea7 100644 --- a/service/src/adapter_internel.h +++ b/service/src/adapter_internel.h @@ -51,7 +51,7 @@ enum { typedef struct { bt_address_t addr; // Remote BT address ble_addr_type_t addr_type; // if link type is ble connection type - uint8_t link_type; + uint8_t transport; bt_status_t status; connection_state_t connection_state; uint32_t hci_reason_code; @@ -114,6 +114,7 @@ typedef struct { bt_address_t addr; uint8_t evt_id; union { + uint32_t cod; acl_state_param_t acl_params; struct { bool local_initiate; @@ -128,17 +129,18 @@ typedef struct { uint32_t cod; bt_pair_type_t ssp_type; uint32_t pass_key; - uint8_t link_type; + uint8_t transport; char name[BT_REM_NAME_MAX_LEN + 1]; } ssp_req; struct { bond_state_t state; - uint8_t link_type; + uint8_t transport; + bt_status_t status; bool is_ctkd; } bond_state; struct { bool encrypted; - uint8_t link_type; + uint8_t transport; } enc_state; struct { bt_128key_t key; @@ -222,7 +224,7 @@ void adapter_on_device_found(bt_discovery_result_t* result); void adapter_on_scan_mode_changed(bt_scan_mode_t mode); void adapter_on_discovery_state_changed(bt_discovery_state_t state); void adapter_on_remote_name_recieved(bt_address_t* addr, const char* name); -void adapter_on_connect_request(bt_address_t* addr); +void adapter_on_connect_request(bt_address_t* addr, uint32_t cod); void adapter_on_connection_state_changed(acl_state_param_t* param); void adapter_on_pairing_request(bt_address_t* addr, bool local_initiate, bool is_bondable); void adapter_on_ssp_request(bt_address_t* addr, uint8_t transport, @@ -230,9 +232,9 @@ void adapter_on_ssp_request(bt_address_t* addr, uint8_t transport, uint32_t pass_key, const char* name); void adapter_on_pin_request(bt_address_t* addr, uint32_t cod, bool min_16_digit, const char* name); -void adapter_on_bond_state_changed(bt_address_t* addr, bond_state_t state, uint8_t link_type, bool is_ctkd); +void adapter_on_bond_state_changed(bt_address_t* addr, bond_state_t state, uint8_t transport, bt_status_t status, bool is_ctkd); void adapter_on_service_search_done(bt_address_t* addr, bt_uuid_t* uuids, uint16_t size); -void adapter_on_encryption_state_changed(bt_address_t* addr, bool encrypted, uint8_t link_type); +void adapter_on_encryption_state_changed(bt_address_t* addr, bool encrypted, uint8_t transport); void adapter_on_link_key_update(bt_address_t* addr, bt_128key_t link_key, bt_link_key_type_t type); void adapter_on_link_key_removed(bt_address_t* addr, bt_status_t status); void adapter_on_link_role_changed(bt_address_t* addr, bt_link_role_t role); diff --git a/service/src/adapter_service.c b/service/src/adapter_service.c index a25aa0d..0425682 100644 --- a/service/src/adapter_service.c +++ b/service/src/adapter_service.c @@ -48,7 +48,7 @@ #include "connection_manager.h" #include "device.h" #include "hci_error.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "service_loop.h" #include "service_manager.h" #include "state_machine.h" @@ -262,7 +262,7 @@ static void bonded_device_loaded(void* data, uint16_t length, uint16_t items) BT_LOGD("BONDED DEVICE[%d], Name:[%s] Addr:[%s] LinkKey: [%02X] | [%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X]", i, remote->name, addr_str, remote->link_key_type, lk[0], lk[1], lk[2], lk[3], lk[4], lk[5], lk[6], lk[7], lk[8], lk[9], lk[10], lk[11], lk[12], lk[13], lk[14], lk[15]); - bt_sal_set_bonded_devices(remote); + bt_sal_set_bonded_devices(PRIMARY_ADAPTER, remote, 1); remote++; } } @@ -396,7 +396,7 @@ static void process_pair_request_evt(bt_address_t* addr, bool local_initiate, bo if (!is_bondable) { BT_ADDR_LOG("Pair not allowed for:%s", addr); - bt_sal_reply_pair_request(addr, HCI_ERR_PAIRING_NOT_ALLOWED); + bt_sal_pair_reply(PRIMARY_ADAPTER, addr, HCI_ERR_PAIRING_NOT_ALLOWED); return; } @@ -418,13 +418,19 @@ static void process_pin_request_evt(bt_address_t* addr, uint32_t cod, adapter_lock(); device = adapter_find_create_classic_device(addr); - device_set_device_class(device, cod); if (device_get_bond_state(device) == BOND_STATE_CANCELING) { BT_LOGE("%s, canceling reject", __func__); - bt_sal_pin_reply(addr, false, NULL, 0); + bt_sal_pin_reply(PRIMARY_ADAPTER, addr, false, NULL, 0); adapter_unlock(); return; } + + if (!device_check_flag(device, DFLAG_NAME_SET | DFLAG_GET_RMT_NAME)) { + BT_LOGD("pin requesting, request remote name..."); + bt_sal_get_remote_name(PRIMARY_ADAPTER, addr); + device_set_flags(device, DFLAG_GET_RMT_NAME); + } + if (device_get_bond_state(device) != BOND_STATE_BONDING) device_set_bond_state(device, BOND_STATE_BONDING); adapter_unlock(); @@ -432,21 +438,20 @@ static void process_pin_request_evt(bt_address_t* addr, uint32_t cod, send_pair_display_notification(addr, BT_TRANSPORT_BREDR, PAIR_TYPE_PIN_CODE, 0x0); } -static void process_ssp_request_evt(bt_address_t* addr, uint8_t link_type, +static void process_ssp_request_evt(bt_address_t* addr, uint8_t transport, uint32_t cod, bt_pair_type_t ssp_type, uint32_t pass_key, const char* name) { bt_device_t* device; adapter_lock(); - device = adapter_find_device(addr, link_type); + device = adapter_find_device(addr, transport); - device_set_device_class(device, cod); if (device_get_bond_state(device) == BOND_STATE_CANCELING) { BT_LOGE("%s, canceling reject", __func__); - if (link_type == BT_TRANSPORT_BREDR) { + if (transport == BT_TRANSPORT_BREDR) { #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT - bt_sal_ssp_reply(addr, false, ssp_type, 0x0); + bt_sal_ssp_reply(PRIMARY_ADAPTER, addr, false, ssp_type, 0x0); #endif } else { #ifdef CONFIG_BLUETOOTH_BLE_SUPPORT @@ -458,31 +463,37 @@ static void process_ssp_request_evt(bt_address_t* addr, uint8_t link_type, return; } + if (!device_check_flag(device, DFLAG_NAME_SET | DFLAG_GET_RMT_NAME)) { + BT_LOGD("ssp, request remote name..."); + bt_sal_get_remote_name(PRIMARY_ADAPTER, addr); + device_set_flags(device, DFLAG_GET_RMT_NAME); + } + if (device_get_bond_state(device) != BOND_STATE_BONDING) device_set_bond_state(device, BOND_STATE_BONDING); adapter_unlock(); /* send ssp request notification*/ - send_pair_display_notification(addr, link_type, ssp_type, pass_key); + send_pair_display_notification(addr, transport, ssp_type, pass_key); } static void process_bond_state_change_evt(bt_address_t* addr, bond_state_t state, - uint8_t link_type, bool is_ctkd) + uint8_t transport, bool is_ctkd) { remote_device_properties_t remote; bt_device_t* device; adapter_lock(); - if (link_type == BT_TRANSPORT_BREDR) { + if (transport == BT_TRANSPORT_BREDR) { device = adapter_find_create_classic_device(addr); if (state == BOND_STATE_BONDED) { device_set_bond_state(device, BOND_STATE_BONDED); - bt_sal_get_remote_device_info(addr, &remote); + bt_sal_get_remote_device_info(PRIMARY_ADAPTER, addr, &remote); device_set_device_type(device, remote.device_type); /* update bonded device info */ adapter_update_bonded_device(); // device_set_connection_state(device, CONNECTION_STATE_ENCRYPTED_BREDR); if (device_is_connected(device)) - bt_sal_start_service_discovery(addr, NULL); + bt_sal_start_service_discovery(PRIMARY_ADAPTER, addr, NULL); } } else { #ifdef CONFIG_BLUETOOTH_BLE_SUPPORT @@ -503,7 +514,7 @@ static void process_bond_state_change_evt(bt_address_t* addr, bond_state_t state device_set_bond_state(device, state); adapter_unlock(); /* send bond state change notification */ - CALLBACK_FOREACH(CBLIST, adapter_callbacks_t, on_bond_state_changed, addr, link_type, state, is_ctkd); + CALLBACK_FOREACH(CBLIST, adapter_callbacks_t, on_bond_state_changed, addr, transport, state, is_ctkd); } static void process_service_search_done_evt(bt_address_t* addr, bt_uuid_t* uuids, uint16_t size) @@ -520,20 +531,20 @@ static void process_service_search_done_evt(bt_address_t* addr, bt_uuid_t* uuids } static void process_enc_state_change_evt(bt_address_t* addr, bool encrypted, - uint8_t link_type) + uint8_t transport) { bt_device_t* device; adapter_lock(); - if (link_type == BT_TRANSPORT_BREDR) + if (transport == BT_TRANSPORT_BREDR) device = adapter_find_create_classic_device(addr); - else if (link_type == BT_TRANSPORT_BLE) + else if (transport == BT_TRANSPORT_BLE) device = adapter_find_device(addr, BT_TRANSPORT_BLE); else return; if (encrypted) { - if (link_type == BT_TRANSPORT_BREDR) + if (transport == BT_TRANSPORT_BREDR) device_set_connection_state(device, CONNECTION_STATE_ENCRYPTED_BREDR); else device_set_connection_state(device, CONNECTION_STATE_ENCRYPTED_LE); @@ -552,6 +563,7 @@ static void process_link_key_update_evt(bt_address_t* addr, bt_128key_t link_key device = adapter_find_create_classic_device(addr); device_set_link_key(device, link_key); device_set_link_key_type(device, type); + adapter_update_bonded_device(); bt_addr_ba2str(addr, addr_str); uint8_t* lk = link_key; BT_LOGI("DEVICE[%s] LinkKey: %02X | [%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X]", @@ -588,12 +600,12 @@ static void handle_security_event(void* data) evt->pin_req.name); break; case SSP_REQUEST_EVT: - process_ssp_request_evt(&evt->addr, evt->ssp_req.link_type, evt->ssp_req.cod, + process_ssp_request_evt(&evt->addr, evt->ssp_req.transport, evt->ssp_req.cod, evt->ssp_req.ssp_type, evt->ssp_req.pass_key, evt->ssp_req.name); break; case BOND_STATE_CHANGE_EVT: process_bond_state_change_evt(&evt->addr, evt->bond_state.state, - evt->bond_state.link_type, + evt->bond_state.transport, evt->bond_state.is_ctkd); break; case SDP_SEARCH_DONE_EVT: @@ -601,7 +613,7 @@ static void handle_security_event(void* data) break; case ENC_STATE_CHANGE_EVT: process_enc_state_change_evt(&evt->addr, evt->enc_state.encrypted, - evt->enc_state.link_type); + evt->enc_state.transport); break; case LINK_KEY_UPDATE_EVT: process_link_key_update_evt(&evt->addr, evt->link_key.key, evt->link_key.type); @@ -616,10 +628,9 @@ static void handle_security_event(void* data) free(data); } -static void process_connect_request_evt(bt_address_t* addr) +static void process_connect_request_evt(bt_address_t* addr, uint32_t cod) { adapter_service_t* adapter = &g_adapter_service; - remote_device_properties_t remote; bt_device_t* device; bool reject = false; @@ -627,13 +638,12 @@ static void process_connect_request_evt(bt_address_t* addr) adapter_lock(); device = adapter_find_create_classic_device(addr); - bt_sal_get_remote_device_info(addr, &remote); - device_set_device_class(device, remote.class_of_device); + device_set_device_class(device, cod); if (get_devices_cnt(DFLAG_CONNECTED, BT_TRANSPORT_BREDR) >= adapter->max_acl_connections) { reject = true; BT_LOGW("Reject connect request without available connection"); /* if a2dp source support, accept link with master role ? */ - bt_sal_reply_link_request(addr, false); + bt_sal_acl_connection_reply(PRIMARY_ADAPTER, addr, false); } adapter_unlock(); if (!reject) { @@ -659,17 +669,22 @@ static void process_connection_state_changed_evt(bt_address_t* addr, acl_state_p bt_device_t* device; BT_ADDR_LOG("ACL connection state changed, addr:%s, link:%d, state:%s, status:%d, reason:%" PRIu32 "", addr, - acl_params->link_type, acl_connection_str(acl_params->connection_state), + acl_params->transport, acl_connection_str(acl_params->connection_state), acl_params->status, acl_params->hci_reason_code); adapter_lock(); #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT - if (acl_params->link_type == BT_TRANSPORT_BREDR) + if (acl_params->transport == BT_TRANSPORT_BREDR) { device = adapter_find_create_classic_device(addr); - else + if (device_get_bond_state(device) == BOND_STATE_BONDING && !device_check_flag(device, DFLAG_NAME_SET | DFLAG_GET_RMT_NAME)) { + BT_LOGD("bonding, request remote name..."); + bt_sal_get_remote_name(PRIMARY_ADAPTER, addr); + device_set_flags(device, DFLAG_GET_RMT_NAME); + } + } else #endif #ifdef CONFIG_BLUETOOTH_BLE_SUPPORT - if (acl_params->link_type == BT_TRANSPORT_BLE) + if (acl_params->transport == BT_TRANSPORT_BLE) device = adapter_find_create_le_device(addr, acl_params->addr_type); else #endif @@ -681,11 +696,13 @@ static void process_connection_state_changed_evt(bt_address_t* addr, acl_state_p device_set_connection_state(device, acl_params->connection_state); if (acl_params->connection_state == CONNECTION_STATE_CONNECTED) { - device_set_acl_handle(device, bt_sal_get_acl_link_handle(addr, acl_params->link_type)); + device_set_acl_handle(device, bt_sal_get_acl_connection_handle(PRIMARY_ADAPTER, addr, acl_params->transport)); + // if (acl_params->transport == BT_TRANSPORT_BLE) + // adapter_le_add_whitelist(addr); } adapter_unlock(); - if (acl_params->link_type == BT_TRANSPORT_BREDR) { + if (acl_params->transport == BT_TRANSPORT_BREDR) { switch (acl_params->connection_state) { case CONNECTION_STATE_CONNECTED: bt_pm_remote_device_connected(addr); @@ -699,11 +716,11 @@ static void process_connection_state_changed_evt(bt_address_t* addr, acl_state_p } if (acl_params->connection_state == CONNECTION_STATE_DISCONNECTED) - bt_cm_process_disconnect_event(addr, acl_params->link_type); + bt_cm_process_disconnect_event(addr, acl_params->transport); /* send connection changed notification */ CALLBACK_FOREACH(CBLIST, adapter_callbacks_t, on_connection_state_changed, addr, - acl_params->link_type, acl_params->connection_state); + acl_params->transport, acl_params->connection_state); } static void handle_connection_event(void* data) @@ -712,7 +729,7 @@ static void handle_connection_event(void* data) switch (conn_evt->evt_id) { case CONNECT_REQUEST_EVT: - process_connect_request_evt(&conn_evt->addr); + process_connect_request_evt(&conn_evt->addr, conn_evt->cod); break; case CONNECTION_STATE_CHANGE_EVT: process_connection_state_changed_evt(&conn_evt->addr, &conn_evt->acl_params); @@ -765,6 +782,7 @@ static void process_remote_name_recieved_evt(bt_address_t* addr, const char* nam BT_ADDR_LOG("remote device:%s name:%s", addr, name); notify = device_set_name(device, name); + device_clear_flag(device, DFLAG_GET_RMT_NAME); adapter_unlock(); if (notify) { /* send name changed notification to all observer */ @@ -1087,15 +1105,15 @@ void adapter_on_br_enabled(void) char addrstr[BT_ADDR_STR_LENGTH]; /* set local name */ - bt_sal_set_local_name(props->name); + bt_sal_set_name(PRIMARY_ADAPTER, props->name); /* get local address */ - bt_sal_get_local_address(&props->addr); + bt_sal_get_address(PRIMARY_ADAPTER, &props->addr); /* set io capability, first load stored adapter info, or use Kconfig default */ - bt_sal_set_local_io_capability(props->io_capability); + bt_sal_set_io_capability(PRIMARY_ADAPTER, props->io_capability); /* set scan mode, no discoverable no connectable */ - bt_sal_set_scan_mode(props->scan_mode, props->bondable); + bt_sal_set_scan_mode(PRIMARY_ADAPTER, props->scan_mode, props->bondable); /* set local class of device */ - bt_sal_set_local_device_class(props->class_of_device); + bt_sal_set_device_class(PRIMARY_ADAPTER, props->class_of_device); /* set default inquiry scan parameter */ /* */ /* enable L2CAP service */ @@ -1163,7 +1181,7 @@ static void process_link_role_changed_evt(bt_address_t* addr, bt_link_role_t rol if (disable_policy) { BT_ADDR_LOG("Disable role switch at %s", addr); policy &= ~BT_BR_LINK_POLICY_ENABLE_ROLE_SWITCH; - bt_sal_set_link_policy(addr, policy); + bt_sal_set_link_policy(PRIMARY_ADAPTER, addr, policy); } } @@ -1248,12 +1266,13 @@ void adapter_on_remote_name_recieved(bt_address_t* addr, const char* name) do_in_service_loop(handle_discovery_event, evt); } -void adapter_on_connect_request(bt_address_t* addr) +void adapter_on_connect_request(bt_address_t* addr, uint32_t cod) { adapter_remote_event_t* evt = create_remote_event(addr, CONNECT_REQUEST_EVT); if (!evt) return; + evt->cod = cod; do_in_service_loop(handle_connection_event, evt); } @@ -1287,7 +1306,8 @@ void adapter_on_pin_request(bt_address_t* addr, uint32_t cod, evt->pin_req.cod = cod; evt->pin_req.min_16_digit = min_16_digit; - strncpy(evt->pin_req.name, name, BT_REM_NAME_MAX_LEN); + if (name) + strncpy(evt->pin_req.name, name, BT_REM_NAME_MAX_LEN); do_in_service_loop(handle_security_event, evt); } @@ -1304,21 +1324,23 @@ void adapter_on_ssp_request(bt_address_t* addr, uint8_t transport, evt->ssp_req.cod = cod; evt->ssp_req.ssp_type = ssp_type; evt->ssp_req.pass_key = pass_key; - evt->ssp_req.link_type = transport; - strncpy(evt->ssp_req.name, name, BT_REM_NAME_MAX_LEN); + evt->ssp_req.transport = transport; + if (name) + strncpy(evt->ssp_req.name, name, BT_REM_NAME_MAX_LEN); do_in_service_loop(handle_security_event, evt); } -void adapter_on_bond_state_changed(bt_address_t* addr, bond_state_t state, uint8_t link_type, bool is_ctkd) +void adapter_on_bond_state_changed(bt_address_t* addr, bond_state_t state, uint8_t transport, bt_status_t status, bool is_ctkd) { adapter_remote_event_t* evt = create_remote_event(addr, BOND_STATE_CHANGE_EVT); if (!evt) return; evt->bond_state.state = state; - evt->bond_state.link_type = link_type; + evt->bond_state.transport = transport; evt->bond_state.is_ctkd = is_ctkd; + evt->bond_state.status = status; do_in_service_loop(handle_security_event, evt); } @@ -1338,14 +1360,14 @@ void adapter_on_service_search_done(bt_address_t* addr, bt_uuid_t* uuids, uint16 do_in_service_loop(handle_security_event, evt); } -void adapter_on_encryption_state_changed(bt_address_t* addr, bool encrypted, uint8_t link_type) +void adapter_on_encryption_state_changed(bt_address_t* addr, bool encrypted, uint8_t transport) { adapter_remote_event_t* evt = create_remote_event(addr, ENC_STATE_CHANGE_EVT); if (!evt) return; evt->enc_state.encrypted = encrypted; - evt->enc_state.link_type = link_type; + evt->enc_state.transport = transport; do_in_service_loop(handle_security_event, evt); } @@ -1674,7 +1696,7 @@ bt_status_t adapter_start_discovery(uint32_t timeout) return BT_STATUS_FAIL; } - bt_status_t status = bt_sal_start_discovery(timeout); + bt_status_t status = bt_sal_start_discovery(PRIMARY_ADAPTER, timeout); if (status != BT_STATUS_SUCCESS) { adapter_unlock(); return status; @@ -1700,7 +1722,7 @@ bt_status_t adapter_cancel_discovery(void) return BT_STATUS_FAIL; } - bt_status_t status = bt_sal_stop_discovery(); + bt_status_t status = bt_sal_stop_discovery(PRIMARY_ADAPTER); adapter->is_discovering = false; adapter_unlock(); @@ -1739,7 +1761,7 @@ bt_status_t adapter_set_name(const char* name) if (strncmp(adapter->properties.name, name, BT_LOC_NAME_MAX_LEN) == 0) goto error; - status = bt_sal_set_local_name((char*)name); + status = bt_sal_set_name(PRIMARY_ADAPTER, (char*)name); if (status != BT_STATUS_SUCCESS) goto error; @@ -1778,7 +1800,7 @@ bt_status_t adapter_set_scan_mode(bt_scan_mode_t mode, bool bondable) if (adapter->properties.scan_mode == mode && adapter->properties.bondable == bondable) goto error; - status = bt_sal_set_scan_mode(mode, bondable); + status = bt_sal_set_scan_mode(PRIMARY_ADAPTER, mode, bondable); if (status != BT_STATUS_SUCCESS) goto error; @@ -1812,7 +1834,7 @@ bt_status_t adapter_set_device_class(uint32_t cod) if (adapter->properties.class_of_device == cod) goto error; - status = bt_sal_set_local_device_class(cod); + status = bt_sal_set_device_class(PRIMARY_ADAPTER, cod); if (status != BT_STATUS_SUCCESS) goto error; @@ -1845,7 +1867,7 @@ bt_status_t adapter_set_io_capability(bt_io_capability_t cap) if (adapter->properties.io_capability == cap) goto error; - status = bt_sal_set_local_io_capability(cap); + status = bt_sal_set_io_capability(PRIMARY_ADAPTER, cap); if (status != BT_STATUS_SUCCESS) goto error; @@ -1873,14 +1895,14 @@ bt_status_t adapter_set_inquiry_scan_parameters(bt_scan_type_t type, uint16_t interval, uint16_t window) { - return bt_sal_set_inquiry_scan_parameters(type, interval, window); + return bt_sal_set_inquiry_scan_parameters(PRIMARY_ADAPTER, type, interval, window); } bt_status_t adapter_set_page_scan_parameters(bt_scan_type_t type, uint16_t interval, uint16_t window) { - return bt_sal_set_page_scan_parameters(type, interval, window); + return bt_sal_set_page_scan_parameters(PRIMARY_ADAPTER, type, interval, window); } bt_status_t adapter_get_le_address(bt_address_t* addr, ble_addr_type_t* type) @@ -2339,7 +2361,7 @@ bt_status_t adapter_connect(bt_address_t* addr) adapter_lock(); device = adapter_find_create_classic_device(addr); - if (bt_sal_connect(addr) != BT_STATUS_SUCCESS) { + if (bt_sal_connect(PRIMARY_ADAPTER, addr) != BT_STATUS_SUCCESS) { adapter_unlock(); return BT_STATUS_FAIL; } @@ -2365,7 +2387,9 @@ bt_status_t adapter_disconnect(bt_address_t* addr) return BT_STATUS_BUSY; } - if (bt_sal_disconnect(addr) != BT_STATUS_SUCCESS) { + if (bt_sal_disconnect(PRIMARY_ADAPTER, addr, + HCI_ERR_CONNECTION_TERMINATED_BY_LOCAL_HOST) + != BT_STATUS_SUCCESS) { adapter_unlock(); return BT_STATUS_FAIL; } @@ -2437,7 +2461,7 @@ bt_status_t adapter_connect_request_reply(bt_address_t* addr, bool accept) } adapter_unlock(); bt_status_t status; - status = bt_sal_reply_link_request(addr, accept); + status = bt_sal_acl_connection_reply(PRIMARY_ADAPTER, addr, accept); if (status == BT_STATUS_SUCCESS && accept) { device_set_connection_state(device, CONNECTION_STATE_CONNECTING); } @@ -2547,7 +2571,7 @@ bt_status_t adapter_create_bond(bt_address_t* addr, bt_transport_t transport) } if (adapter->is_discovering) - bt_sal_stop_discovery(); + bt_sal_stop_discovery(PRIMARY_ADAPTER); #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT if (transport == BT_TRANSPORT_BREDR) @@ -2576,7 +2600,7 @@ bt_status_t adapter_create_bond(bt_address_t* addr, bt_transport_t transport) adapter_unlock(); #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT if (transport == BT_TRANSPORT_BREDR) - return bt_sal_create_bond(addr); + return bt_sal_create_bond(PRIMARY_ADAPTER, addr, transport, device_get_address_type(device)); else #endif #ifdef CONFIG_BLUETOOTH_BLE_SUPPORT @@ -2600,7 +2624,7 @@ bt_status_t adapter_remove_bond(bt_address_t* addr, uint8_t transport) #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT if (transport == BT_TRANSPORT_BREDR) { device_delete_link_key(device); - bt_sal_remove_bond(addr); + bt_sal_remove_bond(PRIMARY_ADAPTER, addr, transport); /* remove bond device form storage */ adapter_update_bonded_device(); } else @@ -2624,7 +2648,7 @@ bt_status_t adapter_cancel_bond(bt_address_t* addr) return BT_STATUS_FAIL; } - bt_status_t status = bt_sal_cancel_bond(addr); + bt_status_t status = bt_sal_cancel_bond(PRIMARY_ADAPTER, addr, BT_TRANSPORT_BREDR); if (status == BT_STATUS_SUCCESS) device_set_bond_state(device, BOND_STATE_CANCELING); adapter_unlock(); @@ -2642,7 +2666,7 @@ bt_status_t adapter_pair_request_reply(bt_address_t* addr, bool accept) } adapter_unlock(); bt_status_t status; - status = bt_sal_reply_pair_request(addr, accept ? 0 : HCI_ERR_PAIRING_NOT_ALLOWED); + status = bt_sal_pair_reply(PRIMARY_ADAPTER, addr, accept ? 0 : HCI_ERR_PAIRING_NOT_ALLOWED); if (status == BT_STATUS_SUCCESS && accept) { /* callback bonding */ CALLBACK_FOREACH(CBLIST, adapter_callbacks_t, on_bond_state_changed, @@ -2663,7 +2687,7 @@ bt_status_t adapter_set_pin_code(bt_address_t* addr, bool accept, } adapter_unlock(); - return bt_sal_pin_reply(addr, accept, pincode, len); + return bt_sal_pin_reply(PRIMARY_ADAPTER, addr, accept, pincode, len); } bt_status_t adapter_set_pairing_confirmation(bt_address_t* addr, uint8_t transport, bool accept) @@ -2678,7 +2702,7 @@ bt_status_t adapter_set_pairing_confirmation(bt_address_t* addr, uint8_t transpo adapter_unlock(); #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT if (transport == BT_TRANSPORT_BREDR) - return bt_sal_ssp_reply(addr, accept, PAIR_TYPE_PASSKEY_CONFIRMATION, 0); + return bt_sal_ssp_reply(PRIMARY_ADAPTER, addr, accept, PAIR_TYPE_PASSKEY_CONFIRMATION, 0); else #endif #ifdef CONFIG_BLUETOOTH_BLE_SUPPORT @@ -2701,7 +2725,7 @@ bt_status_t adapter_set_pass_key(bt_address_t* addr, uint8_t transport, bool acc adapter_unlock(); #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT if (transport == BT_TRANSPORT_BREDR) - return bt_sal_ssp_reply(addr, accept, PAIR_TYPE_PASSKEY_ENTRY, passkey); + return bt_sal_ssp_reply(PRIMARY_ADAPTER, addr, accept, PAIR_TYPE_PASSKEY_ENTRY, passkey); else #endif #ifdef CONFIG_BLUETOOTH_BLE_SUPPORT @@ -2782,7 +2806,7 @@ bt_status_t adapter_switch_role(bt_address_t* addr, bt_link_role_t role) adapter_unlock(); if (prev_role != role) - return bt_sal_set_link_role(addr, role); + return bt_sal_set_link_role(PRIMARY_ADAPTER, addr, role); return BT_STATUS_SUCCESS; } @@ -2791,7 +2815,7 @@ bt_status_t adapter_set_afh_channel_classification(uint16_t central_frequency, uint16_t band_width, uint16_t number) { - return bt_sal_set_afh_channel_classification(central_frequency, band_width, number); + return bt_sal_set_afh_channel_classification(PRIMARY_ADAPTER, central_frequency, band_width, number); } void adapter_get_support_profiles(void) { } diff --git a/service/src/adapter_state.c b/service/src/adapter_state.c index 0f291ec..3599d51 100644 --- a/service/src/adapter_state.c +++ b/service/src/adapter_state.c @@ -25,7 +25,7 @@ #include "bt_adapter.h" #include "btservice.h" #include "media_system.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "service_manager.h" #include "state_machine.h" @@ -336,7 +336,7 @@ static bool ble_on_process_event(state_machine_t* sm, uint32_t event, void* p_da static void turning_on_enter(state_machine_t* sm) { ADAPTER_DBG_ENTER(sm); - bt_status_t status = bt_sal_enable(); + bt_status_t status = bt_sal_enable(PRIMARY_ADAPTER); if (status == BT_STATUS_SUCCESS) { const state_t* prev = hsm_get_previous_state(sm); adapter_notify_state_change(hsm_get_state_value(prev), BT_ADAPTER_STATE_TURNING_ON); @@ -425,7 +425,7 @@ static bool turning_off_process_event(state_machine_t* sm, uint32_t event, void* switch (event) { case BREDR_PROFILE_DISABLED: - bt_sal_disable(); + bt_sal_disable(PRIMARY_ADAPTER); break; case BREDR_DISABLED: if (adapter_is_support_le()) { diff --git a/service/src/advertising.c b/service/src/advertising.c index 0cd354f..5ba8349 100644 --- a/service/src/advertising.c +++ b/service/src/advertising.c @@ -23,7 +23,7 @@ #include "bluetooth.h" #include "bt_list.h" #include "index_allocator.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "service_loop.h" #include "utils/log.h" diff --git a/service/src/device.c b/service/src/device.c index 141745c..721db8a 100644 --- a/service/src/device.c +++ b/service/src/device.c @@ -173,6 +173,8 @@ bool device_set_name(bt_device_t* device, const char* name) if (!strncmp(device->remote.alias, "", BT_REM_NAME_MAX_LEN)) strlcpy((char*)device->remote.alias, name, sizeof(device->remote.alias)); + device_set_flags(device, DFLAG_NAME_SET); + return true; } diff --git a/service/src/device.h b/service/src/device.h index 4fb6318..7bc79f1 100644 --- a/service/src/device.h +++ b/service/src/device.h @@ -19,15 +19,14 @@ #include "bluetooth_define.h" #include "bt_list.h" -enum device_flags { - DFLAG_NAME_SET = 0x00000001, - DFLAG_ALIAS_SET = 0x00000002, - DFLAG_LINKKEY_SET = 0x00000004, - DFLAG_WHITELIST_ADDED = 0x00000008, - DFLAG_CONNECTED = 0x00000016, - DFLAG_BONDED = 0x00000032, - DFLAG_LE_KEY_SET = 0x00000064, -}; +#define DFLAG_NAME_SET (1 << 0) +#define DFLAG_GET_RMT_NAME (1 << 1) +#define DFLAG_ALIAS_SET (1 << 2) +#define DFLAG_LINKKEY_SET (1 << 3) +#define DFLAG_WHITELIST_ADDED (1 << 4) +#define DFLAG_CONNECTED (1 << 5) +#define DFLAG_BONDED (1 << 6) +#define DFLAG_LE_KEY_SET (1 << 7) typedef struct bt_device bt_device_t; diff --git a/service/src/power_manager.c b/service/src/power_manager.c index d67a9c8..79092b1 100644 --- a/service/src/power_manager.c +++ b/service/src/power_manager.c @@ -22,7 +22,7 @@ #include "bt_list.h" #include "bt_profile.h" #include "power_manager.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "service_loop.h" #include "utils/log.h" @@ -391,7 +391,7 @@ static bt_status_t pm_request_sniff(bt_address_t* peer_addr, bt_pm_mode_index_t } BT_LOGD("%s, peer_addr:%s, max:%d, min:%d, attempt:%d, timeout:%d", __func__, bt_addr_str(peer_addr), mode.max, mode.min, mode.attempt, mode.timeout); - ret = bt_sal_set_power_mode(peer_addr, &mode); + ret = bt_sal_set_power_mode(PRIMARY_ADAPTER, peer_addr, &mode); if (ret != BT_STATUS_SUCCESS) { BT_LOGE("%s, fail to set power mode, ret:%d", __func__, ret); return ret; @@ -419,7 +419,7 @@ static bt_status_t pm_request_active(bt_address_t* peer_addr) } BT_LOGD("%s, peer_addr:%s", __func__, bt_addr_str(peer_addr)); - ret = bt_sal_set_power_mode(peer_addr, &mode); + ret = bt_sal_set_power_mode(PRIMARY_ADAPTER, peer_addr, &mode); if (ret != BT_STATUS_SUCCESS) { BT_LOGE("%s, fail to set power mode, ret:%d", __func__, ret); return ret; diff --git a/service/src/scan_manager.c b/service/src/scan_manager.c index a57d3a7..4ea7567 100644 --- a/service/src/scan_manager.c +++ b/service/src/scan_manager.c @@ -25,7 +25,7 @@ #include "bt_le_scan.h" #include "bt_list.h" #include "bt_time.h" -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "scan_filter.h" #include "scan_manager.h" #include "scan_record.h" diff --git a/service/stacks/include/sal_adapter_classic_interface.h b/service/stacks/include/sal_adapter_classic_interface.h new file mode 100644 index 0000000..534712e --- /dev/null +++ b/service/stacks/include/sal_adapter_classic_interface.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * Copyright (C) 2024 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +#ifndef __SAL_ADAPTER_CLASSIC_INTERFACE_H_ +#define __SAL_ADAPTER_CLASSIC_INTERFACE_H_ + +#include + +#include "bluetooth.h" +#include "bt_addr.h" +#include "bt_device.h" +#include "bt_status.h" +#include "bt_vhal.h" + +#include "bluetooth_define.h" +#include "power_manager.h" + +/* service adapter layer for BREDR */ +// #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT +bt_status_t bt_sal_init(const bt_vhal_interface* vhal); +void bt_sal_cleanup(void); + +/* Adapter power */ +bt_status_t bt_sal_enable(bt_controller_id_t id); +bt_status_t bt_sal_disable(bt_controller_id_t id); +bool bt_sal_is_enabled(bt_controller_id_t id); + +/* Adapter properties */ +bt_status_t bt_sal_set_name(bt_controller_id_t id, char* name); +const char* bt_sal_get_name(bt_controller_id_t id); +bt_status_t bt_sal_get_address(bt_controller_id_t id, bt_address_t* addr); +bt_status_t bt_sal_set_io_capability(bt_controller_id_t id, bt_io_capability_t cap); +bt_io_capability_t bt_sal_get_io_capability(bt_controller_id_t id); +bt_status_t bt_sal_set_device_class(bt_controller_id_t id, uint32_t cod); +uint32_t bt_sal_get_device_class(bt_controller_id_t id); +bt_status_t bt_sal_set_scan_mode(bt_controller_id_t id, bt_scan_mode_t scan_mode, bool bondable); +bt_scan_mode_t bt_sal_get_scan_mode(bt_controller_id_t id); +bool bt_sal_get_bondable(bt_controller_id_t id); + +/* Inquiry/page and inquiry/page scan */ +bt_status_t bt_sal_start_discovery(bt_controller_id_t id, uint32_t timeout); +bt_status_t bt_sal_stop_discovery(bt_controller_id_t id); +bt_status_t bt_sal_set_page_scan_parameters(bt_controller_id_t id, bt_scan_type_t type, + uint16_t interval, uint16_t window); +bt_status_t bt_sal_set_inquiry_scan_parameters(bt_controller_id_t id, bt_scan_type_t type, + uint16_t interval, uint16_t window); + +/* Remote device RNR/connection/bond/properties */ +bt_status_t bt_sal_get_remote_name(bt_controller_id_t id, bt_address_t* addr); +bt_status_t bt_sal_auto_accept_connection(bt_controller_id_t id, bool enable); +bt_status_t bt_sal_sco_connection_reply(bt_controller_id_t id, bt_address_t* addr, bool accept); +bt_status_t bt_sal_acl_connection_reply(bt_controller_id_t id, bt_address_t* addr, bool accept); +bt_status_t bt_sal_pair_reply(bt_controller_id_t id, bt_address_t* addr, uint8_t reason); +bt_status_t bt_sal_ssp_reply(bt_controller_id_t id, bt_address_t* addr, + bool accept, bt_pair_type_t type, uint32_t passkey); +bt_status_t bt_sal_pin_reply(bt_controller_id_t id, bt_address_t* addr, + bool accept, char* pincode, int len); +connection_state_t bt_sal_get_connection_state(bt_controller_id_t id, bt_address_t* addr); +uint16_t bt_sal_get_acl_connection_handle(bt_controller_id_t id, bt_address_t* addr, bt_transport_t trasnport); +uint16_t bt_sal_get_sco_connection_handle(bt_controller_id_t id, bt_address_t* addr); +bt_status_t bt_sal_connect(bt_controller_id_t id, bt_address_t* addr); +bt_status_t bt_sal_disconnect(bt_controller_id_t id, bt_address_t* addr, uint8_t reason); +bt_status_t bt_sal_create_bond(bt_controller_id_t id, bt_address_t* addr, bt_transport_t transport, bt_addr_type_t type); +bt_status_t bt_sal_cancel_bond(bt_controller_id_t id, bt_address_t* addr, bt_transport_t transport); +bt_status_t bt_sal_remove_bond(bt_controller_id_t id, bt_address_t* addr, bt_transport_t transport); +bt_status_t bt_sal_set_remote_oob_data(bt_controller_id_t id, bt_address_t* addr, + bt_oob_data_t* p192_val, bt_oob_data_t* p256_val); +bt_status_t bt_sal_remove_remote_oob_data(bt_controller_id_t id, bt_address_t* addr); +bt_status_t bt_sal_get_local_oob_data(bt_controller_id_t id); +bt_status_t bt_sal_get_remote_device_info(bt_controller_id_t id, bt_address_t* addr, remote_device_properties_t* properties); +bt_status_t bt_sal_set_bonded_devices(bt_controller_id_t id, remote_device_properties_t* props, int cnt); +bt_status_t bt_sal_get_bonded_devices(bt_controller_id_t id, remote_device_properties_t* props, int* cnt); +bt_status_t bt_sal_get_connected_devices(bt_controller_id_t id, remote_device_properties_t* props, int* cnt); + +/* Service discovery */ +bt_status_t bt_sal_start_service_discovery(bt_controller_id_t id, bt_address_t* addr, bt_uuid_t* uuid); +bt_status_t bt_sal_stop_service_discovery(bt_controller_id_t id, bt_address_t* addr); + +/* Link policy */ +bt_status_t bt_sal_set_power_mode(bt_controller_id_t id, bt_address_t* addr, bt_pm_mode_t* mode); +bt_status_t bt_sal_set_link_role(bt_controller_id_t id, bt_address_t* addr, bt_link_role_t role); +bt_status_t bt_sal_set_link_policy(bt_controller_id_t id, bt_address_t* addr, bt_link_policy_t policy); +bt_status_t bt_sal_set_afh_channel_classification(bt_controller_id_t id, uint16_t central_frequency, + uint16_t band_width, uint16_t number); +bt_status_t bt_sal_set_afh_channel_classification_1(bt_controller_id_t id, uint8_t* map); + +/* VSC */ +bt_status_t bt_sal_send_hci_command(bt_controller_id_t id, uint8_t ogf, uint16_t ocf, uint8_t length, uint8_t* buf, + bt_hci_event_callback_t cb, void* context); +// #endif +#endif /* __SAL_ADAPTER_CLASSIC_INTERFACE_V2_H_ */ diff --git a/service/stacks/include/sal_debug_interface.h b/service/stacks/include/sal_debug_interface.h new file mode 100644 index 0000000..7a72d59 --- /dev/null +++ b/service/stacks/include/sal_debug_interface.h @@ -0,0 +1,34 @@ +/**************************************************************************** + * Copyright (C) 2024 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +#ifndef __SAL_DEBUG_INTERFACE_H_ +#define __SAL_DEBUG_INTERFACE_H_ + +#include + +#include "bluetooth.h" +#include "bt_addr.h" + +void bt_sal_debug_init(void); +void bt_sal_debug_cleanup(void); +bt_status_t bt_sal_debug_enable(void); +bt_status_t bt_sal_debug_disable(void); +bt_status_t bt_sal_debug_set_log_level(uint32_t level); +bool bt_sal_debug_is_type_support(bt_debug_type_t type); +bt_status_t bt_sal_debug_set_log_enable(bt_debug_type_t type, bool enable); +bt_status_t bt_sal_debug_update_log_mask(int mask); + +// #endif +#endif /* __SAL_DEBUG_INTERFACE_V2_H_ */ diff --git a/service/stacks/include/sal_interface.h b/service/stacks/include/sal_interface.h new file mode 100644 index 0000000..4fa394e --- /dev/null +++ b/service/stacks/include/sal_interface.h @@ -0,0 +1,75 @@ +/**************************************************************************** + * Copyright (C) 2024 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +#ifndef __SAL_ADAPTER_H_ +#define __SAL_ADAPTER_H_ + +#include "bluetooth_define.h" + +#include "sal_adapter_classic_interface.h" +#include "sal_debug_interface.h" + +#if defined(CONFIG_BLUETOOTH_STACK_BREDR_BLUELET) || defined(CONFIG_BLUETOOTH_STACK_LE_BLUELET) +#include "sal_adapter_interface.h" +#include "sal_bluelet.h" +#endif + +typedef struct bt_stack_info { + char name[32]; + uint8_t stack_ver_major; + uint8_t stack_ver_minor; + uint8_t sal_ver; + /* data */ +} bt_stack_info_t; + +#define SAL_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define SAL_CHECK(cond, expect) \ + { \ + int __ret = cond; \ + if (__ret != expect) { \ + BT_LOGE("[%s] return:%d", __func__, __ret); \ + } \ + } + +#define SAL_NOT_SUPPORT \ + { \ + BT_LOGW("interface [%s] not supported", __func__); \ + return BT_STATUS_NOT_SUPPORTED; \ + } + +#define SAL_CHECK_PARAM(cond) \ + { \ + if (!(cond)) \ + return BT_STATUS_PARM_INVALID; \ + } + +#define SAL_CHECK_RET(cond, expect) \ + { \ + int __ret = cond; \ + if (__ret != expect) { \ + BT_LOGE("[%s] return:%d", __func__, __ret); \ + return BT_STATUS_FAIL; \ + } \ + } + +#define SAL_ASSERT(cond) \ + { \ + assert(cond); \ + } + +void bt_sal_get_stack_info(bt_stack_info_t* info); + +#endif /* __SAL_ADAPTER_V2_H_ */ diff --git a/service/stacks/stack_manager.c b/service/stacks/stack_manager.c index 6f31df0..b5c5941 100644 --- a/service/stacks/stack_manager.c +++ b/service/stacks/stack_manager.c @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -#include "sal_adapter_interface.h" +#include "sal_interface.h" #include "service_loop.h" #define LOG_TAG "stack_manager" @@ -24,8 +24,13 @@ bt_status_t stack_manager_init(void) { bt_status_t ret; const bt_vhal_interface* vhal; + bt_stack_info_t info; vhal = get_bt_vhal_interface(); + + bt_sal_get_stack_info(&info); + BT_LOGI("Stack Info: %s Ver:%d.%d Sal:%d", info.name, + info.stack_ver_major, info.stack_ver_minor, info.sal_ver); #ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT ret = bt_sal_init(vhal); if (ret != BT_STATUS_SUCCESS) diff --git a/service/stacks/zephyr/sal_adapter_classic_interface.c b/service/stacks/zephyr/sal_adapter_classic_interface.c new file mode 100644 index 0000000..91d43fd --- /dev/null +++ b/service/stacks/zephyr/sal_adapter_classic_interface.c @@ -0,0 +1,1461 @@ +/**************************************************************************** + * Copyright (C) 2024 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +#define LOG_TAG "sal_adapter" +#include + +#include "bluetooth.h" +#include "bt_adapter.h" + +#include "bt_addr.h" +#include "bt_device.h" +#include "bt_status.h" + +#include "adapter_internel.h" +#include "bluetooth_define.h" +#include "power_manager.h" +#include "service_loop.h" + +#include +#include +#include +#include + +#include + +#include "sal_interface.h" + +#include "utils/log.h" + +#define STACK_CALL(func) zblue_##func + +typedef void (*sal_func_t)(void* args); + +typedef union { + char name[BT_LOC_NAME_MAX_LEN]; + bt_io_capability_t cap; + uint32_t cod; + struct { + bt_scan_mode_t scan_mode; + bool bondable; + } scanmode; + uint32_t timeout; + struct { + bool inquiry; + bt_scan_type_t type; + uint16_t interval; + uint16_t window; + } sp; + bool accept; + uint8_t reason; + struct { + bool accept; + bt_pair_type_t type; + uint32_t passkey; + } ssp; + struct { + bool accept; + char* pincode; + int len; + } pin; + struct { + bt_transport_t transport; + bt_addr_type_t type; + } bond; + bt_pm_mode_t mode; + bt_link_role_t role; + bt_link_policy_t policy; + struct { + uint16_t central_frequency; + uint16_t band_width; + uint16_t number; + } afh; + uint8_t map[10]; +} sal_adapter_args_t; + +typedef struct { + bt_controller_id_t id; + bt_address_t addr; + sal_func_t func; + sal_adapter_args_t adpt; +} sal_adapter_req_t; + +struct device_context { + remote_device_properties_t* props; + int got; + int cnt; +}; + +extern int zblue_main(void); +static void zblue_on_connect_req(struct bt_conn* conn, uint8_t link_type, uint8_t* cod); +static void zblue_on_connected(struct bt_conn* conn, uint8_t err); +static void zblue_on_disconnected(struct bt_conn* conn, uint8_t reason); +static void zblue_on_security_changed(struct bt_conn* conn, bt_security_t level, + enum bt_security_err err); +#ifdef CONFIG_BT_REMOTE_INFO +static void zblue_on_remote_info_available(struct bt_conn* conn, + struct bt_conn_remote_info* remote_info); +#endif +static void zblue_on_link_mode_changed(struct bt_conn* conn, uint8_t mode, uint16_t interval); +static void zblue_on_role_changed(struct bt_conn* conn, uint8_t role); +static void zblue_on_pairing_request(struct bt_conn* conn); +static void zblue_on_passkey_display(struct bt_conn* conn, unsigned int passkey); +static void zblue_on_passkey_entry(struct bt_conn* conn); +static void zblue_on_passkey_confirm(struct bt_conn* conn, unsigned int passkey); +static void zblue_on_cancel(struct bt_conn* conn); +static void zblue_on_pairing_confirm(struct bt_conn* conn); +static void zblue_on_pincode_entry(struct bt_conn* conn, bool highsec); +static void zblue_on_link_key_notify(struct bt_conn* conn, uint8_t* key, uint8_t key_type); +static void zblue_on_pairing_complete(struct bt_conn* conn, bool bonded); +static void zblue_on_pairing_failed(struct bt_conn* conn, enum bt_security_err reason); +static void zblue_on_bond_deleted(uint8_t id, const bt_addr_le_t* peer); + +static struct bt_conn_cb g_conn_cbs = { + .connect_req = zblue_on_connect_req, + .connected = zblue_on_connected, + .disconnected = zblue_on_disconnected, + .security_changed = zblue_on_security_changed, +#ifdef CONFIG_BT_REMOTE_INFO + .remote_info_available = zblue_on_remote_info_available, +#endif + .link_mode_changed = zblue_on_link_mode_changed, + .role_changed = zblue_on_role_changed, +}; + +static struct bt_conn_auth_info_cb g_conn_auth_info_cbs = { + .link_key_notify = zblue_on_link_key_notify, + .pairing_complete = zblue_on_pairing_complete, + .pairing_failed = zblue_on_pairing_failed, + .bond_deleted = zblue_on_bond_deleted, +}; + +static struct bt_conn_auth_cb g_conn_auth_cbs = { + .pairing_request = zblue_on_pairing_request, + .cancel = zblue_on_cancel, + .pairing_confirm = zblue_on_pairing_confirm, + .pincode_entry = zblue_on_pincode_entry +}; + +static sal_adapter_req_t* sal_adapter_req(bt_controller_id_t id, bt_address_t* addr, sal_func_t func) +{ + sal_adapter_req_t* req = calloc(sizeof(sal_adapter_req_t), 1); + + if (req) { + req->id = id; + req->func = func; + if (addr) + memcpy(&req->addr, addr, sizeof(bt_address_t)); + } + + return req; +} + +static void sal_invoke_async(service_work_t* work, void* userdata) +{ + sal_adapter_req_t* req = userdata; + + SAL_ASSERT(req); + req->func(req); + free(userdata); +} + +static bt_status_t sal_send_req(sal_adapter_req_t* req) +{ + if (!req) + return BT_STATUS_PARM_INVALID; + + if (!service_loop_work((void*)req, sal_invoke_async, NULL)) + return BT_STATUS_FAIL; + + return BT_STATUS_SUCCESS; +} + +static void zblue_conn_get_addr(struct bt_conn* conn, bt_address_t* addr) +{ + struct bt_conn_info info; + + bt_conn_get_info(conn, &info); + bt_addr_set(addr, info.br.dst->val); +} + +static void zblue_on_connect_req(struct bt_conn* conn, uint8_t link_type, uint8_t* cod) +{ + if (link_type == BT_HCI_ACL) { + acl_state_param_t state = { + .transport = BT_TRANSPORT_BREDR, + .connection_state = CONNECTION_STATE_CONNECTING + }; + uint32_t class = ((uint32_t)cod[2] << 16) | ((uint32_t)cod[1] << 8) | (uint32_t)cod[0]; + + zblue_conn_get_addr(conn, &state.addr); + adapter_on_connect_request(&state.addr, class); + adapter_on_connection_state_changed(&state); + } else { + // Ignore + } +} + +static void zblue_on_connected(struct bt_conn* conn, uint8_t err) +{ + acl_state_param_t state = { + .transport = BT_TRANSPORT_BREDR, + .connection_state = CONNECTION_STATE_CONNECTED + }; + + zblue_conn_get_addr(conn, &state.addr); + adapter_on_connection_state_changed(&state); +} + +static void zblue_on_disconnected(struct bt_conn* conn, uint8_t reason) +{ + acl_state_param_t state = { + .transport = BT_TRANSPORT_BREDR, + .connection_state = CONNECTION_STATE_DISCONNECTED + }; + + zblue_conn_get_addr(conn, &state.addr); + adapter_on_connection_state_changed(&state); +} + +static void zblue_on_security_changed(struct bt_conn* conn, bt_security_t level, + enum bt_security_err err) +{ + bt_address_t addr; + bool encrypted = false; + + zblue_conn_get_addr(conn, &addr); + + if (err) { + adapter_on_bond_state_changed(&addr, BOND_STATE_NONE, BT_TRANSPORT_BREDR, BT_STATUS_FAIL, false); + } + + if (level >= BT_SECURITY_L2 && err == BT_SECURITY_ERR_SUCCESS) { + encrypted = true; + } + + adapter_on_encryption_state_changed(&addr, encrypted, BT_TRANSPORT_BREDR); +} + +#ifdef CONFIG_BT_REMOTE_INFO +static void zblue_on_remote_info_available(struct bt_conn* conn, + struct bt_conn_remote_info* remote_info) +{ +} +#endif + +static void zblue_on_link_mode_changed(struct bt_conn* conn, uint8_t mode, uint16_t interval) +{ + bt_link_mode_t linkmode; + bt_address_t addr; + + if (mode == BT_ACTIVE_MODE) { + linkmode = BT_LINK_MODE_ACTIVE; + } else { + linkmode = BT_LINK_MODE_SNIFF; + } + + zblue_conn_get_addr(conn, &addr); + adapter_on_link_mode_changed(&addr, linkmode, interval); +} + +static void zblue_on_role_changed(struct bt_conn* conn, uint8_t role) +{ + bt_link_role_t linkrole; + bt_address_t addr; + + if (role == BT_CONN_ROLE_PERIPHERAL) { + linkrole = BT_LINK_ROLE_SLAVE; + } else { + linkrole = BT_LINK_ROLE_MASTER; + } + + zblue_conn_get_addr(conn, &addr); + adapter_on_link_role_changed(&addr, linkrole); +} + +static void zblue_on_pairing_request(struct bt_conn* conn) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + adapter_on_pairing_request(&addr, false, true); +} + +static void zblue_on_passkey_display(struct bt_conn* conn, unsigned int passkey) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + adapter_on_ssp_request(&addr, BT_TRANSPORT_BREDR, 0, PAIR_TYPE_PASSKEY_NOTIFICATION, passkey, NULL); +} + +static void zblue_on_passkey_entry(struct bt_conn* conn) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + adapter_on_ssp_request(&addr, BT_TRANSPORT_BREDR, 0, PAIR_TYPE_PASSKEY_ENTRY, 0, NULL); +} + +static void zblue_on_passkey_confirm(struct bt_conn* conn, unsigned int passkey) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + adapter_on_ssp_request(&addr, BT_TRANSPORT_BREDR, 0, PAIR_TYPE_PASSKEY_CONFIRMATION, passkey, NULL); +} + +static void zblue_on_cancel(struct bt_conn* conn) +{ +} + +static void zblue_on_pairing_confirm(struct bt_conn* conn) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + /* it's justworks */ + adapter_on_ssp_request(&addr, BT_TRANSPORT_BREDR, 0, PAIR_TYPE_CONSENT, 0, NULL); +} + +static void zblue_on_pincode_entry(struct bt_conn* conn, bool highsec) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + adapter_on_pin_request(&addr, 0, true, NULL); +} + +static void zblue_on_link_key_notify(struct bt_conn* conn, uint8_t* key, uint8_t key_type) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + adapter_on_link_key_update(&addr, key, key_type); + adapter_on_bond_state_changed(&addr, BOND_STATE_BONDED, BT_TRANSPORT_BREDR, BT_STATUS_SUCCESS, false); +} + +static void zblue_on_pairing_complete(struct bt_conn* conn, bool bonded) +{ + bt_address_t addr; + bond_state_t state; + + if (bonded) { + state = BOND_STATE_BONDED; + /* Start timer, waiting for linkkey notify */ + } else { + state = BOND_STATE_NONE; + zblue_conn_get_addr(conn, &addr); + adapter_on_bond_state_changed(&addr, state, BT_TRANSPORT_BREDR, BT_STATUS_AUTH_FAILURE, false); + } +} + +static void zblue_on_pairing_failed(struct bt_conn* conn, enum bt_security_err reason) +{ + bt_address_t addr; + + zblue_conn_get_addr(conn, &addr); + adapter_on_bond_state_changed(&addr, BOND_STATE_NONE, BT_TRANSPORT_BREDR, BT_STATUS_AUTH_FAILURE, false); + bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL); +} + +static void zblue_on_bond_deleted(uint8_t id, const bt_addr_le_t* peer) +{ + bt_address_t addr; + + if (id == 0 && peer->type == BT_ADDR_LE_PUBLIC) { + bt_addr_set(&addr, peer->a.val); + adapter_on_link_key_removed(&addr, BT_STATUS_SUCCESS); + } /* else: Ignore it*/ +} + +static void zblue_on_ready_cb(int err) +{ + uint8_t state = BT_BREDR_STACK_STATE_OFF; + + if (IS_ENABLED(CONFIG_SETTINGS)) { + settings_load(); + } + + if (err) { + BT_LOGD("zblue init failed (err %d)\n", err); + adapter_on_adapter_state_changed(BT_BREDR_STACK_STATE_OFF); + return; + } + + bt_conn_set_auto(false); + +#if defined(CONFIG_BLUETOOTH_STACK_BREDR_ZBLUE) && !defined(CONFIG_BLUETOOTH_STACK_LE_ZBLUE) + state = BT_BREDR_STACK_STATE_ON; +#else + switch (adapter_get_state()) { + case BT_ADAPTER_STATE_BLE_TURNING_ON: + state = BLE_STACK_STATE_ON; + break; + case BT_ADAPTER_STATE_TURNING_ON: + state = BT_BREDR_STACK_STATE_ON; + break; + default: + break; + } +#endif + adapter_on_adapter_state_changed(state); +} + +/* service adapter layer for BREDR */ +bt_status_t bt_sal_init(const bt_vhal_interface* vhal) +{ + zblue_main(); + + bt_conn_cb_register(&g_conn_cbs); + bt_conn_auth_cb_register(&g_conn_auth_cbs); + bt_conn_auth_info_cb_register(&g_conn_auth_info_cbs); + + return BT_STATUS_SUCCESS; +} + +void bt_sal_cleanup(void) +{ + bt_conn_auth_cb_register(NULL); + bt_conn_auth_info_cb_unregister(&g_conn_auth_info_cbs); +} + +/* Adapter power */ +bt_status_t bt_sal_enable(bt_controller_id_t id) +{ + UNUSED(id); + +#ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT + if (bt_is_ready()) { + adapter_on_adapter_state_changed(BT_BREDR_STACK_STATE_ON); + return BT_STATUS_SUCCESS; + } + + SAL_CHECK_RET(bt_enable(zblue_on_ready_cb), 0); + + return BT_STATUS_SUCCESS; +#else + return BT_STATUS_NOT_SUPPORTED; +#endif +} + +bt_status_t bt_sal_disable(bt_controller_id_t id) +{ + UNUSED(id); + +#ifdef CONFIG_BLUETOOTH_BREDR_SUPPORT + if (!bt_is_ready()) { + adapter_on_adapter_state_changed(BT_BREDR_STACK_STATE_OFF); + return BT_STATUS_SUCCESS; + } + + SAL_CHECK_RET(bt_disable(), 0); + adapter_on_adapter_state_changed(BT_BREDR_STACK_STATE_OFF); + + return BT_STATUS_SUCCESS; +#else + return BT_STATUS_NOT_SUPPORTED; +#endif +} + +bool bt_sal_is_enabled(bt_controller_id_t id) +{ + UNUSED(id); + + return bt_is_ready(); +} + +static void STACK_CALL(set_name)(void* args) +{ + sal_adapter_req_t* req = args; + + BT_LOGD("%s: %s", __func__, req->adpt.name); + SAL_CHECK(bt_set_name(req->adpt.name), 0); +} + +bt_status_t bt_sal_set_name(bt_controller_id_t id, char* name) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, NULL, STACK_CALL(set_name)); + if (!req) + return BT_STATUS_NOMEM; + + strlcpy(req->adpt.name, name, BT_LOC_NAME_MAX_LEN); + + return sal_send_req(req); +} + +const char* bt_sal_get_name(bt_controller_id_t id) +{ + UNUSED(id); + + return bt_get_name(); +} + +bt_status_t bt_sal_get_address(bt_controller_id_t id, bt_address_t* addr) +{ + UNUSED(id); + bt_addr_le_t got = { 0 }; + size_t count = 1; + + SAL_CHECK_PARAM(addr); + + bt_id_get(&got, &count); + bt_addr_set(addr, (uint8_t*)&got.a); + + SAL_ASSERT(got.type == BT_ADDR_LE_PUBLIC); + return BT_STATUS_SUCCESS; +} + +bt_status_t bt_sal_set_io_capability(bt_controller_id_t id, bt_io_capability_t cap) +{ + UNUSED(id); + + switch (cap) { + case BT_IO_CAPABILITY_DISPLAYONLY: + g_conn_auth_cbs.passkey_display = zblue_on_passkey_display; + g_conn_auth_cbs.passkey_entry = NULL; + g_conn_auth_cbs.passkey_confirm = NULL; + break; + case BT_IO_CAPABILITY_DISPLAYYESNO: + g_conn_auth_cbs.passkey_display = zblue_on_passkey_display; + g_conn_auth_cbs.passkey_entry = NULL; + g_conn_auth_cbs.passkey_confirm = zblue_on_passkey_confirm; + break; + case BT_IO_CAPABILITY_KEYBOARDONLY: + g_conn_auth_cbs.passkey_display = NULL; + g_conn_auth_cbs.passkey_entry = zblue_on_passkey_entry; + g_conn_auth_cbs.passkey_confirm = NULL; + break; + case BT_IO_CAPABILITY_KEYBOARDDISPLAY: + g_conn_auth_cbs.passkey_display = zblue_on_passkey_display; + g_conn_auth_cbs.passkey_entry = zblue_on_passkey_entry; + g_conn_auth_cbs.passkey_confirm = zblue_on_passkey_confirm; + break; + case BT_IO_CAPABILITY_NOINPUTNOOUTPUT: + default: + g_conn_auth_cbs.passkey_display = NULL; + g_conn_auth_cbs.passkey_entry = NULL; + g_conn_auth_cbs.passkey_confirm = NULL; + break; + } + + bt_conn_auth_cb_register(NULL); + bt_conn_auth_cb_register(&g_conn_auth_cbs); + + return BT_STATUS_SUCCESS; +} + +bt_io_capability_t bt_sal_get_io_capability(bt_controller_id_t id) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +static void STACK_CALL(set_device_class)(void* args) +{ + sal_adapter_req_t* req = args; + + BT_LOGD("%s: %d", __func__, req->adpt.cod); + SAL_CHECK(bt_set_class_of_device(req->adpt.cod), 0); +} + +bt_status_t bt_sal_set_device_class(bt_controller_id_t id, uint32_t cod) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, NULL, STACK_CALL(set_device_class)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.cod = cod; + + return sal_send_req(req); +} + +uint32_t bt_sal_get_device_class(bt_controller_id_t id) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +/* +test 0->1 +test 0->2 +test 0->0 +test 1->2 +test 1->0 +test 1->1 +test 2->1 +test 2->0 +test 2->2 +*/ +static void STACK_CALL(set_scan_mode)(void* args) +{ + sal_adapter_req_t* req = args; + bool iscan = false; + bool pscan = false; + + switch (req->adpt.scanmode.scan_mode) { + case BT_SCAN_MODE_NONE: + break; + case BT_SCAN_MODE_CONNECTABLE: { + pscan = true; + break; + } + case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: { + iscan = true; + pscan = true; + break; + } + default: + break; + } + + int ret = bt_br_set_connectable(pscan); + if (ret != 0 && ret != -EALREADY) { + BT_LOGE("%s set connectable failed:%d", __func__, ret); + return; + } + + if (iscan) { + ret = bt_br_set_discoverable(iscan); + if (ret != 0 && ret != -EALREADY) { + BT_LOGE("%s set discoverable failed:%d", __func__, ret); + return; + } + } + + if (ret == 0) + adapter_on_scan_mode_changed(req->adpt.scanmode.scan_mode); +} + +bt_status_t bt_sal_set_scan_mode(bt_controller_id_t id, bt_scan_mode_t scan_mode, bool bondable) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, NULL, STACK_CALL(set_scan_mode)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.scanmode.scan_mode = scan_mode; + req->adpt.scanmode.bondable = bondable; + + return sal_send_req(req); +} + +bt_scan_mode_t bt_sal_get_scan_mode(bt_controller_id_t id) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +bool bt_sal_get_bondable(bt_controller_id_t id) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +/* Inquiry/page and inquiry/page scan */ + +static bool zblue_inquiry_eir_name(uint8_t* eir, int len, char* name) +{ + while (len) { + if (len < 2) { + false; + } + + /* Look for early termination */ + if (!eir[0]) { + false; + } + + /* Check if field length is correct */ + if (eir[0] > len - 1) { + false; + } + + switch (eir[1]) { + case BT_DATA_NAME_SHORTENED: + case BT_DATA_NAME_COMPLETE: + memset(name, 0, BT_REM_NAME_MAX_LEN); + if (eir[0] > BT_REM_NAME_MAX_LEN - 1) { + memcpy(name, &eir[2], BT_REM_NAME_MAX_LEN - 1); + } else { + memcpy(name, &eir[2], eir[0] - 1); + } + return true; + default: + break; + } + + /* Parse next AD Structure */ + len -= eir[0] + 1; + eir += eir[0] + 1; + } + + return false; +} + +static void zblue_on_discovery_complete_cb(struct bt_br_discovery_result* results, + size_t count) +{ + bt_discovery_result_t device; + + if (results == NULL || count == 0) { + adapter_on_discovery_state_changed(BT_DISCOVERY_STOPPED); + return; + } + + for (size_t i = 0; i < count; i++) { + memcpy(device.addr.addr, &results[i].addr, 6); + device.rssi = results[i].rssi; + device.cod = (results[i].cod[2] << 16) | (results[i].cod[1] << 8) | results[i].cod[0]; + zblue_inquiry_eir_name(results[i].eir, sizeof(results[i].eir), device.name); + + /* report discovery result to service */ + adapter_on_device_found(&device); + } +} + +static void STACK_CALL(start_discovery)(void* args) +{ +#define DISCOVERY_DEVICE_MAX 30 + sal_adapter_req_t* req = args; + struct bt_br_discovery_param param; + static struct bt_br_discovery_result g_discovery_results[DISCOVERY_DEVICE_MAX]; + + /* unlimited number of responses. */ + param.limited = false; + param.length = req->adpt.timeout; + + if (bt_br_discovery_start(¶m, g_discovery_results, + SAL_ARRAY_SIZE(g_discovery_results), zblue_on_discovery_complete_cb) + == 0) + adapter_on_discovery_state_changed(BT_DISCOVERY_STARTED); +} + +bt_status_t bt_sal_start_discovery(bt_controller_id_t id, uint32_t timeout) +{ + UNUSED(id); + sal_adapter_req_t* req; + + /* Range(timeout * 1.28s) --> 1.28 to 61.44 s */ + if (!timeout || timeout > 0x30) + return BT_STATUS_PARM_INVALID; + + req = sal_adapter_req(id, NULL, STACK_CALL(start_discovery)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.timeout = timeout; + + return sal_send_req(req); +} + +static void STACK_CALL(stop_discovery)(void* args) +{ + SAL_CHECK(bt_br_discovery_stop(), 0); + adapter_on_discovery_state_changed(BT_DISCOVERY_STOPPED); +} + +bt_status_t bt_sal_stop_discovery(bt_controller_id_t id) +{ + UNUSED(id); + + return sal_send_req(sal_adapter_req(id, NULL, STACK_CALL(stop_discovery))); +} + +static void STACK_CALL(set_scan_parameters)(void* args) +{ + sal_adapter_req_t* req = args; + + if (req->adpt.sp.type == BT_BR_SCAN_TYPE_STANDARD || req->adpt.sp.type == BT_BR_SCAN_TYPE_INTERLACED) { + if (req->adpt.sp.inquiry) { + SAL_CHECK(bt_br_write_inquiry_scan_type(req->adpt.sp.type), 0); + } else { + SAL_CHECK(bt_br_write_page_scan_type(req->adpt.sp.type), 0); + } + } + + if (req->adpt.sp.window <= 0x1000 && req->adpt.sp.interval >= 0x11 && (req->adpt.sp.interval > req->adpt.sp.window)) { + if (req->adpt.sp.inquiry) { + SAL_CHECK(bt_br_write_inquiry_scan_activity(req->adpt.sp.interval, req->adpt.sp.window), 0); + } else { + SAL_CHECK(bt_br_write_page_scan_activity(req->adpt.sp.interval, req->adpt.sp.window), 0); + } + } +} + +bt_status_t bt_sal_set_page_scan_parameters(bt_controller_id_t id, bt_scan_type_t type, + uint16_t interval, uint16_t window) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, NULL, STACK_CALL(set_scan_parameters)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.sp.inquiry = false; + req->adpt.sp.type = type; + req->adpt.sp.interval = interval; + req->adpt.sp.window = window; + + return sal_send_req(req); +} + +bt_status_t bt_sal_set_inquiry_scan_parameters(bt_controller_id_t id, bt_scan_type_t type, + uint16_t interval, uint16_t window) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, NULL, STACK_CALL(set_scan_parameters)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.sp.inquiry = true; + req->adpt.sp.type = type; + req->adpt.sp.interval = interval; + req->adpt.sp.window = window; + + return sal_send_req(req); +} + +/* Remote device RNR/connection/bond/properties */ +static void zblue_on_remote_name_req_cb(const bt_addr_t* bdaddr, const char* name, uint8_t status) +{ + if (status == BT_HCI_ERR_SUCCESS) { + adapter_on_remote_name_recieved((bt_address_t*)bdaddr, name); + } else { + BT_LOGE("%s error: %02" PRIu8, __func__, status); + } +} + +static void STACK_CALL(get_remote_name)(void* args) +{ + sal_adapter_req_t* req = args; + + SAL_CHECK(bt_br_remote_name_request((bt_addr_t*)&req->addr, zblue_on_remote_name_req_cb), 0); +} + +bt_status_t bt_sal_get_remote_name(bt_controller_id_t id, bt_address_t* addr) +{ + UNUSED(id); + + return sal_send_req(sal_adapter_req(id, addr, STACK_CALL(get_remote_name))); +} + +bt_status_t bt_sal_auto_accept_connection(bt_controller_id_t id, bool enable) +{ + bt_conn_set_auto(enable); + + return BT_STATUS_SUCCESS; +} + +static void STACK_CALL(sco_connection_reply)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_sco((bt_addr_t*)&req->addr); + + if (req->adpt.accept) { + SAL_CHECK(bt_conn_accept_sco_conn(conn), 0); + } else { + SAL_CHECK(bt_conn_reject_sco_conn(conn, BT_HCI_ERR_INSUFFICIENT_RESOURCES), 0); + } + + bt_conn_unref(conn); +} + +bt_status_t bt_sal_sco_connection_reply(bt_controller_id_t id, bt_address_t* addr, bool accept) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(sco_connection_reply)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.accept = accept; + + return sal_send_req(req); +} + +static void STACK_CALL(acl_connection_reply)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + if (req->adpt.accept) { + SAL_CHECK(bt_conn_accept_acl_conn(conn), 0); + } else { + SAL_CHECK(bt_conn_reject_acl_conn(conn, BT_HCI_ERR_INSUFFICIENT_RESOURCES), 0); + } + + bt_conn_unref(conn); +} + +bt_status_t bt_sal_acl_connection_reply(bt_controller_id_t id, bt_address_t* addr, bool accept) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(acl_connection_reply)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.accept = accept; + + return sal_send_req(req); +} + +static void STACK_CALL(pair_reply)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + if (req->adpt.reason == BT_HCI_ERR_SUCCESS) { + SAL_CHECK(bt_conn_auth_pairing_accept(conn), 0); + } else { + SAL_CHECK(bt_conn_auth_pairing_reject(conn, req->adpt.reason), 0); + } +} + +bt_status_t bt_sal_pair_reply(bt_controller_id_t id, bt_address_t* addr, uint8_t reason) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(pair_reply)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.reason = reason; + + return sal_send_req(req); +} + +static void STACK_CALL(ssp_reply)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + if (req->adpt.ssp.accept) { + switch (req->adpt.ssp.type) { + case PAIR_TYPE_PASSKEY_CONFIRMATION: + case PAIR_TYPE_CONSENT: + SAL_CHECK(bt_conn_auth_passkey_confirm(conn), 0); + break; + case PAIR_TYPE_PASSKEY_ENTRY: + SAL_CHECK(bt_conn_auth_passkey_entry(conn, req->adpt.ssp.passkey), 0); + break; + default: + break; + } + } else { + SAL_CHECK(bt_conn_auth_cancel(conn), 0); + } + + bt_conn_unref(conn); +} + +bt_status_t bt_sal_ssp_reply(bt_controller_id_t id, bt_address_t* addr, bool accept, + bt_pair_type_t type, uint32_t passkey) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(ssp_reply)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.ssp.accept = accept; + req->adpt.ssp.type = type; + req->adpt.ssp.passkey = passkey; + + return sal_send_req(req); +} + +static void STACK_CALL(pin_reply)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + if (req->adpt.pin.accept) { + SAL_CHECK(bt_conn_auth_pincode_entry(conn, req->adpt.pin.pincode), 0); + } else { + SAL_CHECK(bt_conn_auth_cancel(conn), 0); + } + + bt_conn_unref(conn); +} + +bt_status_t bt_sal_pin_reply(bt_controller_id_t id, bt_address_t* addr, + bool accept, char* pincode, int len) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(pin_reply)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.pin.accept = accept; + req->adpt.pin.pincode = malloc(len + 1); + memcpy(req->adpt.pin.pincode, pincode, len); + req->adpt.pin.pincode[len] = '\0'; + req->adpt.pin.len = len; + + return sal_send_req(req); +} + +connection_state_t bt_sal_get_connection_state(bt_controller_id_t id, bt_address_t* addr) +{ + UNUSED(id); + struct bt_conn_info info; + connection_state_t state = CONNECTION_STATE_DISCONNECTED; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)addr); + + bt_conn_get_info(conn, &info); + switch (info.state) { + case BT_CONN_STATE_DISCONNECTED: { + state = CONNECTION_STATE_DISCONNECTED; + break; + } + case BT_CONN_STATE_CONNECTING: { + state = CONNECTION_STATE_CONNECTING; + break; + } + case BT_CONN_STATE_CONNECTED: { + state = CONNECTION_STATE_CONNECTED; + break; + } + case BT_CONN_STATE_DISCONNECTING: { + state = CONNECTION_STATE_DISCONNECTING; + break; + } + default: + break; + } + + bt_conn_unref(conn); + return state; +} + +uint16_t bt_sal_get_acl_connection_handle(bt_controller_id_t id, bt_address_t* addr, bt_transport_t trasnport) +{ + UNUSED(id); + struct bt_conn_info info; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)addr); + + bt_conn_get_info(conn, &info); + bt_conn_unref(conn); + + return info.handle; +} + +uint16_t bt_sal_get_sco_connection_handle(bt_controller_id_t id, bt_address_t* addr) +{ + UNUSED(id); + struct bt_conn_info info; + struct bt_conn* conn = bt_conn_lookup_addr_sco((bt_addr_t*)addr); + + bt_conn_get_info(conn, &info); + bt_conn_unref(conn); + + return info.handle; +} + +static void STACK_CALL(connect)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn; + + conn = bt_conn_create_br((const bt_addr_t*)&req->addr, BT_BR_CONN_PARAM_DEFAULT); + if (!conn) { + BT_LOGW("bt_conn_create_br Connection failed"); + return; + } + + bt_conn_unref(conn); +} + +bt_status_t bt_sal_connect(bt_controller_id_t id, bt_address_t* addr) +{ + UNUSED(id); + + return sal_send_req(sal_adapter_req(id, addr, STACK_CALL(connect))); +} + +static void STACK_CALL(disconnect)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + SAL_CHECK(bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN), 0); + bt_conn_unref(conn); +} + +bt_status_t bt_sal_disconnect(bt_controller_id_t id, bt_address_t* addr, uint8_t reason) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(disconnect)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.reason = reason; + + return sal_send_req(req); +} + +static void STACK_CALL(create_bond)(void* args) +{ + sal_adapter_req_t* req = args; + bond_state_t state = BOND_STATE_NONE; + struct bt_conn* conn; + + conn = bt_conn_pair((bt_addr_t*)&req->addr, BT_SECURITY_L3); + if (conn) { + state = BOND_STATE_BONDING; + bt_conn_unref(conn); + } + + adapter_on_bond_state_changed(&req->addr, state, BT_TRANSPORT_BREDR, BT_STATUS_SUCCESS, false); +} + +bt_status_t bt_sal_create_bond(bt_controller_id_t id, bt_address_t* addr, bt_transport_t transport, bt_addr_type_t type) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(create_bond)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.bond.transport = transport; + req->adpt.bond.type = type; + + return sal_send_req(req); +} + +static void STACK_CALL(cancel_bond)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + SAL_CHECK(bt_conn_auth_cancel(conn), 0); + SAL_CHECK(bt_br_unpair((bt_addr_t*)&req->addr), 0); +} + +bt_status_t bt_sal_cancel_bond(bt_controller_id_t id, bt_address_t* addr, bt_transport_t transport) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(cancel_bond)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.bond.transport = transport; + + return sal_send_req(req); +} + +static void STACK_CALL(remove_bond)(void* args) +{ + sal_adapter_req_t* req = args; + + SAL_CHECK(bt_br_unpair((bt_addr_t*)&req->addr), 0); +} + +bt_status_t bt_sal_remove_bond(bt_controller_id_t id, bt_address_t* addr, bt_transport_t transport) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(remove_bond)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.bond.transport = transport; + + return sal_send_req(req); +} + +bt_status_t bt_sal_set_remote_oob_data(bt_controller_id_t id, bt_address_t* addr, + bt_oob_data_t* p192_val, bt_oob_data_t* p256_val) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +bt_status_t bt_sal_remove_remote_oob_data(bt_controller_id_t id, bt_address_t* addr) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +bt_status_t bt_sal_get_local_oob_data(bt_controller_id_t id) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +bt_status_t bt_sal_get_remote_device_info(bt_controller_id_t id, bt_address_t* addr, remote_device_properties_t* properties) +{ + UNUSED(id); + return BT_STATUS_SUCCESS; +} + +bt_status_t bt_sal_set_bonded_devices(bt_controller_id_t id, remote_device_properties_t* props, int cnt) +{ + UNUSED(id); + struct bt_bond_info_br bondinfo; + + for (int i = 0; i < cnt; i++) { + memcpy(&bondinfo.addr, &props->addr, 6); + memcpy(&bondinfo.key, &props->link_key, 16); + bondinfo.key_type = props->link_key_type; + if (bt_br_set_bond_info(&bondinfo)) + break; + } + + return BT_STATUS_SUCCESS; +} + +static void get_bonded_devices(const struct bt_bond_info_br* info, + void* user_data) +{ + struct device_context* ctx = user_data; + + if (ctx->got < ctx->cnt) { + memcpy(&ctx->props->addr, &info->addr, 6); + memcpy(&ctx->props->link_key, &info->key, 16); + ctx->props->link_key_type = info->key_type; + ctx->props++; + ctx->got++; + } +} + +bt_status_t bt_sal_get_bonded_devices(bt_controller_id_t id, remote_device_properties_t* props, int* cnt) +{ + UNUSED(id); + struct device_context ctx; + + ctx.props = props; + ctx.cnt = *cnt; + ctx.got = 0; + + bt_br_foreach_bond(get_bonded_devices, &ctx); + *cnt = ctx.got; + + return BT_STATUS_SUCCESS; +} + +static void get_connected_devices(struct bt_conn* conn, void* data) +{ + struct device_context* ctx = data; + struct bt_conn_info info; + + if (ctx->got < ctx->cnt) { + bt_conn_get_info(conn, &info); + memcpy(&ctx->props->addr, info.br.dst->val, 6); + ctx->props++; + ctx->got++; + } +} + +bt_status_t bt_sal_get_connected_devices(bt_controller_id_t id, remote_device_properties_t* props, int* cnt) +{ + UNUSED(id); + struct device_context ctx; + + ctx.props = props; + ctx.cnt = *cnt; + ctx.got = 0; + + bt_conn_foreach(BT_CONN_TYPE_BR, get_connected_devices, &ctx); + *cnt = ctx.got; + + return BT_STATUS_SUCCESS; +} + +/* Service discovery */ +bt_status_t bt_sal_start_service_discovery(bt_controller_id_t id, bt_address_t* addr, bt_uuid_t* uuid) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} + +static void STACK_CALL(stop_service_discovery)(void* args) +{ +} + +bt_status_t bt_sal_stop_service_discovery(bt_controller_id_t id, bt_address_t* addr) +{ + UNUSED(id); + + return sal_send_req(sal_adapter_req(id, addr, STACK_CALL(stop_service_discovery))); +} + +/* Link policy */ +static void STACK_CALL(set_power_mode)(void* args) +{ + sal_adapter_req_t* req = args; + bt_pm_mode_t* pm = &req->adpt.mode; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + if (pm->mode == BT_LINK_MODE_ACTIVE) { + SAL_CHECK(bt_conn_check_exit_sniff(conn), 0); + } else { + SAL_CHECK(bt_conn_check_enter_sniff(conn, pm->min, pm->max, pm->attempt, pm->timeout), 0); + } + + bt_conn_unref(conn); +} + +bt_status_t bt_sal_set_power_mode(bt_controller_id_t id, bt_address_t* addr, bt_pm_mode_t* mode) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(set_power_mode)); + if (!req) + return BT_STATUS_NOMEM; + + memcpy(&req->adpt.mode, mode, sizeof(*mode)); + + return sal_send_req(req); +} + +static void STACK_CALL(set_link_role)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + + SAL_CHECK(bt_conn_switch_role(conn, req->adpt.role), 0); + bt_conn_unref(conn); +} + +bt_status_t bt_sal_set_link_role(bt_controller_id_t id, bt_address_t* addr, bt_link_role_t role) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(set_link_role)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.role = role; + + return sal_send_req(req); +} + +static void STACK_CALL(set_link_policy)(void* args) +{ + sal_adapter_req_t* req = args; + struct bt_conn* conn = bt_conn_lookup_addr_br((bt_addr_t*)&req->addr); + uint16_t policy = 0; + + switch (req->adpt.policy) { + case BT_BR_LINK_POLICY_DISABLE_ALL: + break; + case BT_BR_LINK_POLICY_ENABLE_ROLE_SWITCH: + policy = 1 << BT_HCI_POLICY_ROLE_SWITCH; + break; + case BT_BR_LINK_POLICY_ENABLE_SNIFF: + policy = 1 << BT_HCI_POLICY_SNIFF_MODE; + break; + case BT_BR_LINK_POLICY_ENABLE_ROLE_SWITCH_AND_SNIFF: + policy = (1 << BT_HCI_POLICY_ROLE_SWITCH) | (1 << BT_HCI_POLICY_SNIFF_MODE); + break; + default: + break; + } + + if (!bt_conn_set_link_policy_settings(conn, policy)) { + adapter_on_link_policy_changed(&req->addr, req->adpt.policy); + } + + bt_conn_unref(conn); +} + +bt_status_t bt_sal_set_link_policy(bt_controller_id_t id, bt_address_t* addr, bt_link_policy_t policy) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, addr, STACK_CALL(set_link_policy)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.policy = policy; + + return sal_send_req(req); +} + +static void STACK_CALL(set_afh_channel_classification)(void* args) +{ +} + +bt_status_t bt_sal_set_afh_channel_classification(bt_controller_id_t id, uint16_t central_frequency, + uint16_t band_width, uint16_t number) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, NULL, STACK_CALL(set_afh_channel_classification)); + if (!req) + return BT_STATUS_NOMEM; + + req->adpt.afh.central_frequency = central_frequency; + req->adpt.afh.band_width = band_width; + req->adpt.afh.number = number; + + return sal_send_req(req); +} + +static void STACK_CALL(set_afh_channel_classification_1)(void* args) +{ +} + +bt_status_t bt_sal_set_afh_channel_classification_1(bt_controller_id_t id, uint8_t* map) +{ + UNUSED(id); + sal_adapter_req_t* req; + + req = sal_adapter_req(id, NULL, STACK_CALL(set_afh_channel_classification_1)); + if (!req) + return BT_STATUS_NOMEM; + + memcpy(req->adpt.map, map, 10); + + return sal_send_req(req); +} + +/* VSC */ +bt_status_t bt_sal_send_hci_command(bt_controller_id_t id, uint8_t ogf, uint16_t ocf, uint8_t length, uint8_t* buf, + bt_hci_event_callback_t cb, void* context) +{ + UNUSED(id); + SAL_NOT_SUPPORT; +} diff --git a/service/stacks/zephyr/sal_debug_interface.c b/service/stacks/zephyr/sal_debug_interface.c new file mode 100644 index 0000000..d8280f2 --- /dev/null +++ b/service/stacks/zephyr/sal_debug_interface.c @@ -0,0 +1,29 @@ +/**************************************************************************** + * Copyright (C) 2024 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +#include + +#include "bluetooth_define.h" + +#include "utils/log.h" + +void bt_sal_debug_init(void) { } +void bt_sal_debug_cleanup(void) { } +bt_status_t bt_sal_debug_enable(void) { return BT_STATUS_NOT_SUPPORTED; } +bt_status_t bt_sal_debug_disable(void) { return BT_STATUS_NOT_SUPPORTED; } +bt_status_t bt_sal_debug_set_log_level(uint32_t level) { return BT_STATUS_NOT_SUPPORTED; } +bool bt_sal_debug_is_type_support(bt_debug_type_t type) { return false; } +bt_status_t bt_sal_debug_set_log_enable(bt_debug_type_t type, bool enable) { return BT_STATUS_NOT_SUPPORTED; } +bt_status_t bt_sal_debug_update_log_mask(int mask) { return BT_STATUS_NOT_SUPPORTED; } \ No newline at end of file diff --git a/service/stacks/zephyr/sal_zblue.c b/service/stacks/zephyr/sal_zblue.c new file mode 100644 index 0000000..f95028c --- /dev/null +++ b/service/stacks/zephyr/sal_zblue.c @@ -0,0 +1,24 @@ +/**************************************************************************** + * Copyright (C) 2024 Xiaomi Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +#include "sal_interface.h" + +void bt_sal_get_stack_info(bt_stack_info_t* info) +{ + snprintf(info->name, 32, "Zblue"); + info->stack_ver_major = 5; + info->stack_ver_minor = 4; + info->sal_ver = 2; +} \ No newline at end of file diff --git a/service/stacks/zephyr/zblue.h b/service/stacks/zephyr/zblue.h deleted file mode 100644 index e69de29..0000000 diff --git a/service/utils/log_server.c b/service/utils/log_server.c index bf0fdbc..c1f45aa 100644 --- a/service/utils/log_server.c +++ b/service/utils/log_server.c @@ -26,7 +26,7 @@ #include "bt_status.h" #include "btsnoop_log.h" #include "log.h" -#include "sal.h" +#include "sal_interface.h" #include "service_loop.h" enum {