Loading system/bta/hh/bta_hh_act.cc +147 −62 Original line number Diff line number Diff line Loading @@ -33,13 +33,16 @@ #include "bta/include/bta_hh_api.h" #include "bta/include/bta_hh_co.h" #include "bta/sys/bta_sys.h" #include "btif/include/btif_storage.h" #include "main/shim/dumpsys.h" #include "osi/include/allocator.h" #include "osi/include/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/acl_api.h" #include "stack/include/bt_hdr.h" #include "stack/include/hiddefs.h" #include "stack/include/hidh_api.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" /***************************************************************************** Loading Loading @@ -315,77 +318,38 @@ static void bta_hh_di_sdp_cback(tSDP_RESULT result) { * Returns void * ******************************************************************************/ void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { tBTA_HH_STATUS status = BTA_HH_ERR_SDP; uint8_t hdl; p_cb->mode = p_data->api_conn.mode; bta_hh_cb.p_cur = p_cb; if (BTM_UseLeLink(p_data->api_conn.bd_addr)) { p_cb->is_le_device = true; bta_hh_le_open_conn(p_cb, p_data->api_conn.bd_addr); return; } /* if previously virtually cabled device, skip SDP */ if (p_cb->app_id) { status = BTA_HH_OK; APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__); if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) { /* update device CB with newly register device handle */ bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL, p_cb->sub_class, p_cb->dscp_info.ssr_max_latency, p_cb->dscp_info.ssr_min_tout, p_cb->app_id); /* update cb_index[] map */ bta_hh_cb.cb_index[hdl] = p_cb->index; } else status = BTA_HH_ERR_NO_RES; } tBTA_HH_DATA bta_hh_data; bta_hh_data.status = status; bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); return; } /* GetSDPRecord. at one time only one SDP precedure can be active */ else if (!bta_hh_cb.p_disc_db) { static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { if (!bta_hh_cb.p_disc_db) { bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size); bta_hh_cb.p_cur = p_cb; /* do DI discovery first */ /* Do DI discovery first */ if (SDP_DiDiscover(p_data->api_conn.bd_addr, bta_hh_cb.p_disc_db, p_bta_hh_cfg->sdp_db_size, bta_hh_di_sdp_cback) != SDP_SUCCESS) { APPL_TRACE_DEBUG("%s: SDP_DiDiscover failed: Status 0x%2X", __func__, status); status = BTA_HH_ERR_SDP; osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); bta_hh_di_sdp_cback) == SDP_SUCCESS) { /* SDP search started successfully * Connection will be triggered at the end of successful SDP search */ } else { status = BTA_HH_OK; LOG_ERROR("SDP_DiDiscover failed"); osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); tBTA_HH_DATA bta_hh_data; bta_hh_data.status = BTA_HH_ERR_SDP; bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); } } else if (bta_hh_cb.p_disc_db) { /* It is possible that there is incoming/outgoing collision case. DUT * initiated * HID connection at same time remote has connected L2CAP for HID control, * so SDP would be in progress, when this flow reaches here. Just do nothing * when the code reaches here, and ongoing SDP completion or failure will * handle this case. /* Incoming/outgoing collision case. DUT initiated HID connection at the * same time as the remote connected HID control channel. * When flow reaches here due to remote initiated connection, DUT may be * doing SDP. In such case, just do nothing and the ongoing SDP completion * or failure will handle this case. */ APPL_TRACE_DEBUG("%s: ignoring as SDP already in progress", __func__); return; LOG_WARN("Ignoring as SDP already in progress"); } if (status != BTA_HH_OK) { tBTA_HH_DATA bta_hh_data; bta_hh_data.status = status; bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); } return; } /******************************************************************************* * * Function bta_hh_sdp_cmpl Loading Loading @@ -470,6 +434,126 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { return; } /******************************************************************************* * * Function bta_hh_bredr_conn * * Description Initiate BR/EDR HID connection. This may be triggered by * the local application or as a result of remote initiated * HID connection. * * Returns void * ******************************************************************************/ static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { bta_hh_cb.p_cur = p_cb; /* If previously virtually cabled device */ if (p_cb->app_id) { tBTA_HH_DATA bta_hh_data; bta_hh_data.status = BTA_HH_OK; APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__); if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { uint8_t hdl; if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) { /* update device CB with newly register device handle */ bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL, p_cb->sub_class, p_cb->dscp_info.ssr_max_latency, p_cb->dscp_info.ssr_min_tout, p_cb->app_id); /* update cb_index[] map */ bta_hh_cb.cb_index[hdl] = p_cb->index; } else { bta_hh_data.status = BTA_HH_ERR_NO_RES; } } bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); } else { /* First time connection, start SDP */ bta_hh_start_sdp(p_cb, p_data); } } /******************************************************************************* * * Function bta_hh_connect * * Description Start HID host connection. * * Returns void * ******************************************************************************/ void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { bool hid_available = false; bool hogp_available = false; bluetooth::Uuid remote_uuids[BT_MAX_NUM_UUIDS] = {}; bt_property_t remote_properties = {BT_PROPERTY_UUIDS, sizeof(remote_uuids), &remote_uuids}; const RawAddress& bd_addr = p_data->api_conn.bd_addr; // Find the device type tBT_DEVICE_TYPE dev_type; tBLE_ADDR_TYPE addr_type; BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type); // Find which transports are already connected bool bredr = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR); bool le_acl = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE); // Find which services known to be available if (btif_storage_get_remote_device_property(&bd_addr, &remote_properties) == BT_STATUS_SUCCESS) { int count = remote_properties.len / sizeof(remote_uuids[0]); for (int i = 0; i < count; i++) { if (remote_uuids[i].Is16Bit()) { if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_HUMAN_INTERFACE) { hid_available = true; } else if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_LE_HID) { hogp_available = true; } } if (hid_available && hogp_available) { break; } } } /* Decide whether to connect HID or HOGP */ if (bredr && hid_available) { p_cb->is_le_device = false; } else if (le_acl && hogp_available) { p_cb->is_le_device = true; } else if (hid_available) { p_cb->is_le_device = false; } else if (hogp_available) { p_cb->is_le_device = true; } else if (bredr) { p_cb->is_le_device = false; } else if (le_acl || dev_type == BT_DEVICE_TYPE_BLE) { p_cb->is_le_device = true; } else { p_cb->is_le_device = false; } LOG_DEBUG("bd_addr:%s, bredr:%d, hid_available:%d, le_acl:%d, hogp_available:%d, " "dev_type:%d, is_le_device:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bredr, hid_available, le_acl, hogp_available, dev_type, p_cb->is_le_device); p_cb->mode = p_data->api_conn.mode; bta_hh_cb.p_cur = p_cb; // Initiate HID host connection if (p_cb->is_le_device) { bta_hh_le_open_conn(p_cb, bd_addr); } else { bta_hh_bredr_conn(p_cb, p_data); } } /******************************************************************************* * * Function bta_hh_api_disc_act Loading Loading @@ -603,7 +687,8 @@ void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN)); conn_data.bd_addr = p_cb->addr; bta_hh_start_sdp(p_cb, (tBTA_HH_DATA*)&conn_data); bta_hh_cb.p_cur = p_cb; bta_hh_bredr_conn(p_cb, (tBTA_HH_DATA*)&conn_data); } return; Loading system/bta/hh/bta_hh_int.h +1 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,7 @@ extern void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_data_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); Loading system/bta/hh/bta_hh_main.cc +1 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event, switch (event) { case BTA_HH_API_OPEN_EVT: p_cb->state = BTA_HH_W4_CONN_ST; bta_hh_start_sdp(p_cb, p_data); bta_hh_connect(p_cb, p_data); break; case BTA_HH_INT_OPEN_EVT: p_cb->state = BTA_HH_W4_CONN_ST; Loading Loading
system/bta/hh/bta_hh_act.cc +147 −62 Original line number Diff line number Diff line Loading @@ -33,13 +33,16 @@ #include "bta/include/bta_hh_api.h" #include "bta/include/bta_hh_co.h" #include "bta/sys/bta_sys.h" #include "btif/include/btif_storage.h" #include "main/shim/dumpsys.h" #include "osi/include/allocator.h" #include "osi/include/log.h" #include "osi/include/osi.h" // UNUSED_ATTR #include "stack/include/acl_api.h" #include "stack/include/bt_hdr.h" #include "stack/include/hiddefs.h" #include "stack/include/hidh_api.h" #include "types/bluetooth/uuid.h" #include "types/raw_address.h" /***************************************************************************** Loading Loading @@ -315,77 +318,38 @@ static void bta_hh_di_sdp_cback(tSDP_RESULT result) { * Returns void * ******************************************************************************/ void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { tBTA_HH_STATUS status = BTA_HH_ERR_SDP; uint8_t hdl; p_cb->mode = p_data->api_conn.mode; bta_hh_cb.p_cur = p_cb; if (BTM_UseLeLink(p_data->api_conn.bd_addr)) { p_cb->is_le_device = true; bta_hh_le_open_conn(p_cb, p_data->api_conn.bd_addr); return; } /* if previously virtually cabled device, skip SDP */ if (p_cb->app_id) { status = BTA_HH_OK; APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__); if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) { /* update device CB with newly register device handle */ bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL, p_cb->sub_class, p_cb->dscp_info.ssr_max_latency, p_cb->dscp_info.ssr_min_tout, p_cb->app_id); /* update cb_index[] map */ bta_hh_cb.cb_index[hdl] = p_cb->index; } else status = BTA_HH_ERR_NO_RES; } tBTA_HH_DATA bta_hh_data; bta_hh_data.status = status; bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); return; } /* GetSDPRecord. at one time only one SDP precedure can be active */ else if (!bta_hh_cb.p_disc_db) { static void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { if (!bta_hh_cb.p_disc_db) { bta_hh_cb.p_disc_db = (tSDP_DISCOVERY_DB*)osi_malloc(p_bta_hh_cfg->sdp_db_size); bta_hh_cb.p_cur = p_cb; /* do DI discovery first */ /* Do DI discovery first */ if (SDP_DiDiscover(p_data->api_conn.bd_addr, bta_hh_cb.p_disc_db, p_bta_hh_cfg->sdp_db_size, bta_hh_di_sdp_cback) != SDP_SUCCESS) { APPL_TRACE_DEBUG("%s: SDP_DiDiscover failed: Status 0x%2X", __func__, status); status = BTA_HH_ERR_SDP; osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); bta_hh_di_sdp_cback) == SDP_SUCCESS) { /* SDP search started successfully * Connection will be triggered at the end of successful SDP search */ } else { status = BTA_HH_OK; LOG_ERROR("SDP_DiDiscover failed"); osi_free_and_reset((void**)&bta_hh_cb.p_disc_db); tBTA_HH_DATA bta_hh_data; bta_hh_data.status = BTA_HH_ERR_SDP; bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); } } else if (bta_hh_cb.p_disc_db) { /* It is possible that there is incoming/outgoing collision case. DUT * initiated * HID connection at same time remote has connected L2CAP for HID control, * so SDP would be in progress, when this flow reaches here. Just do nothing * when the code reaches here, and ongoing SDP completion or failure will * handle this case. /* Incoming/outgoing collision case. DUT initiated HID connection at the * same time as the remote connected HID control channel. * When flow reaches here due to remote initiated connection, DUT may be * doing SDP. In such case, just do nothing and the ongoing SDP completion * or failure will handle this case. */ APPL_TRACE_DEBUG("%s: ignoring as SDP already in progress", __func__); return; LOG_WARN("Ignoring as SDP already in progress"); } if (status != BTA_HH_OK) { tBTA_HH_DATA bta_hh_data; bta_hh_data.status = status; bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); } return; } /******************************************************************************* * * Function bta_hh_sdp_cmpl Loading Loading @@ -470,6 +434,126 @@ void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { return; } /******************************************************************************* * * Function bta_hh_bredr_conn * * Description Initiate BR/EDR HID connection. This may be triggered by * the local application or as a result of remote initiated * HID connection. * * Returns void * ******************************************************************************/ static void bta_hh_bredr_conn(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { bta_hh_cb.p_cur = p_cb; /* If previously virtually cabled device */ if (p_cb->app_id) { tBTA_HH_DATA bta_hh_data; bta_hh_data.status = BTA_HH_OK; APPL_TRACE_DEBUG("%s: skip SDP for known devices", __func__); if (p_cb->hid_handle == BTA_HH_INVALID_HANDLE) { uint8_t hdl; if (HID_HostAddDev(p_cb->addr, p_cb->attr_mask, &hdl) == HID_SUCCESS) { /* update device CB with newly register device handle */ bta_hh_add_device_to_list(p_cb, hdl, p_cb->attr_mask, NULL, p_cb->sub_class, p_cb->dscp_info.ssr_max_latency, p_cb->dscp_info.ssr_min_tout, p_cb->app_id); /* update cb_index[] map */ bta_hh_cb.cb_index[hdl] = p_cb->index; } else { bta_hh_data.status = BTA_HH_ERR_NO_RES; } } bta_hh_sm_execute(p_cb, BTA_HH_SDP_CMPL_EVT, &bta_hh_data); } else { /* First time connection, start SDP */ bta_hh_start_sdp(p_cb, p_data); } } /******************************************************************************* * * Function bta_hh_connect * * Description Start HID host connection. * * Returns void * ******************************************************************************/ void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { bool hid_available = false; bool hogp_available = false; bluetooth::Uuid remote_uuids[BT_MAX_NUM_UUIDS] = {}; bt_property_t remote_properties = {BT_PROPERTY_UUIDS, sizeof(remote_uuids), &remote_uuids}; const RawAddress& bd_addr = p_data->api_conn.bd_addr; // Find the device type tBT_DEVICE_TYPE dev_type; tBLE_ADDR_TYPE addr_type; BTM_ReadDevInfo(bd_addr, &dev_type, &addr_type); // Find which transports are already connected bool bredr = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_BR_EDR); bool le_acl = BTM_IsAclConnectionUp(bd_addr, BT_TRANSPORT_LE); // Find which services known to be available if (btif_storage_get_remote_device_property(&bd_addr, &remote_properties) == BT_STATUS_SUCCESS) { int count = remote_properties.len / sizeof(remote_uuids[0]); for (int i = 0; i < count; i++) { if (remote_uuids[i].Is16Bit()) { if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_HUMAN_INTERFACE) { hid_available = true; } else if (remote_uuids[i].As16Bit() == UUID_SERVCLASS_LE_HID) { hogp_available = true; } } if (hid_available && hogp_available) { break; } } } /* Decide whether to connect HID or HOGP */ if (bredr && hid_available) { p_cb->is_le_device = false; } else if (le_acl && hogp_available) { p_cb->is_le_device = true; } else if (hid_available) { p_cb->is_le_device = false; } else if (hogp_available) { p_cb->is_le_device = true; } else if (bredr) { p_cb->is_le_device = false; } else if (le_acl || dev_type == BT_DEVICE_TYPE_BLE) { p_cb->is_le_device = true; } else { p_cb->is_le_device = false; } LOG_DEBUG("bd_addr:%s, bredr:%d, hid_available:%d, le_acl:%d, hogp_available:%d, " "dev_type:%d, is_le_device:%d", ADDRESS_TO_LOGGABLE_CSTR(bd_addr), bredr, hid_available, le_acl, hogp_available, dev_type, p_cb->is_le_device); p_cb->mode = p_data->api_conn.mode; bta_hh_cb.p_cur = p_cb; // Initiate HID host connection if (p_cb->is_le_device) { bta_hh_le_open_conn(p_cb, bd_addr); } else { bta_hh_bredr_conn(p_cb, p_data); } } /******************************************************************************* * * Function bta_hh_api_disc_act Loading Loading @@ -603,7 +687,8 @@ void bta_hh_open_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data) { memset(&conn_data, 0, sizeof(tBTA_HH_API_CONN)); conn_data.bd_addr = p_cb->addr; bta_hh_start_sdp(p_cb, (tBTA_HH_DATA*)&conn_data); bta_hh_cb.p_cur = p_cb; bta_hh_bredr_conn(p_cb, (tBTA_HH_DATA*)&conn_data); } return; Loading
system/bta/hh/bta_hh_int.h +1 −1 Original line number Diff line number Diff line Loading @@ -253,7 +253,7 @@ extern void bta_hh_close_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_data_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_start_sdp(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_connect(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); extern void bta_hh_write_dev_act(tBTA_HH_DEV_CB* p_cb, const tBTA_HH_DATA* p_data); Loading
system/bta/hh/bta_hh_main.cc +1 −1 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ static void bta_hh_better_state_machine(tBTA_HH_DEV_CB* p_cb, uint16_t event, switch (event) { case BTA_HH_API_OPEN_EVT: p_cb->state = BTA_HH_W4_CONN_ST; bta_hh_start_sdp(p_cb, p_data); bta_hh_connect(p_cb, p_data); break; case BTA_HH_INT_OPEN_EVT: p_cb->state = BTA_HH_W4_CONN_ST; Loading