From 4d0dab12010e43d89af12b9d987720d42e77044f Mon Sep 17 00:00:00 2001 From: Seungyoun Ju Date: Thu, 18 Aug 2016 14:38:01 +0900 Subject: [PATCH] Create RPA device structure separately from others [Model] COMMON [BinType] AP [Customer] OPEN [Issue#] N/A [Request] Internal [Occurrence Version] N/A [Problem] Paired remote device's address is changed after BR/EDR pairing -> LE pairing when it uses RPA address for LE [Cause & Measure] When LE is paired, BR/EDR device structure is merged to LE RPA device structure. It causes address change of BR/EDR device and applications cannot track that device. [Checking Method] BR/EDR Pairing -> LE Pairing with M OS Android device [Team] Basic connection [Developer] Seungyoun Ju [Solution company] Samsung [Change Type] Specification change Change-Id: Ia7afff8151c1f10024bae8826c0ecaf1ee25a26d Signed-off-by: DoHyun Pyun --- src/adapter.c | 477 ++++++++++++++++++++++++++++------------------------------ src/device.c | 248 +++++++++++++++++++----------- src/device.h | 6 + 3 files changed, 399 insertions(+), 332 deletions(-) diff --git a/src/adapter.c b/src/adapter.c index d27fa59..c18f6c2 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -510,11 +510,6 @@ static void store_adapter_info(struct btd_adapter *adapter) char *str; gsize length = 0; gboolean discoverable; -#ifdef __TIZEN_PATCH__ - char key_str[35]; - static const char testblock[MGMT_IRK_SIZE]; - int i; -#endif key_file = g_key_file_new(); @@ -540,14 +535,18 @@ static void store_adapter_info(struct btd_adapter *adapter) g_key_file_set_string(key_file, "General", "Alias", adapter->stored_alias); #ifdef __TIZEN_PATCH__ - if (memcmp(adapter->local_irk, testblock , MGMT_IRK_SIZE)) { - key_str[0] = '0'; - key_str[1] = 'x'; - for (i = 0; i < MGMT_IRK_SIZE; i++) - sprintf(key_str + 2 + (i * 2), "%2.2X", - adapter->local_irk[i]); - g_key_file_set_string(key_file, "General", - "LocalIrk", key_str); + if (adapter->local_irk) { + int i; + char key_str[35]; + char *ptr = key_str; + + ptr[0] = '0'; + ptr[1] = 'x'; + ptr += 2; + for (i = 0; i < MGMT_IRK_SIZE; i++, ptr += 2) + snprintf(ptr, 3, "%2.2X", adapter->local_irk[i]); + + g_key_file_set_string(key_file, "General", "LocalIrk", key_str); } #endif @@ -1110,6 +1109,10 @@ struct btd_device *btd_adapter_find_device(struct btd_adapter *adapter, struct device_addr_type addr; struct btd_device *device; GSList *list; +#ifdef __TIZEN_PATCH__ + bool exact_match = false; +#endif + char addr_str[18]; if (!adapter) return NULL; @@ -1117,46 +1120,38 @@ struct btd_device *btd_adapter_find_device(struct btd_adapter *adapter, bacpy(&addr.bdaddr, dst); addr.bdaddr_type = bdaddr_type; - list = g_slist_find_custom(adapter->devices, &addr, - device_addr_type_cmp); + ba2str(dst, addr_str); + DBG("find device %s %d", addr_str, bdaddr_type); -/* Find the device based on RPA */ #ifdef __TIZEN_PATCH__ - if (!list) { - uint8_t msb = 0x00; - char address[18]; - - ba2str(&addr.bdaddr, address); - - msb = addr.bdaddr.b[5] >> 6; - - /* Check whether address is RPA */ - if (msb == 0x00 || msb == 0x01) { - list = g_slist_find_custom(adapter->devices, - address, (GCompareFunc) device_rpa_cmp); - } - } else { + list = g_slist_find_custom(adapter->devices, &addr, + device_addr_type_strict_cmp); + if (list) { device = list->data; - - if (device_get_rpa_exist(device) == true) { - GSList *rpa_list; - - rpa_list = g_slist_find_custom(adapter->devices, - device_get_address(device), - device_addr_cmp); - if (rpa_list) { - list = rpa_list; - bdaddr_type = BDADDR_LE_RANDOM; - } + DBG("Exact matched"); + device_print_addr(device); + exact_match = true; + } else { +#endif + list = g_slist_find_custom(adapter->devices, &addr, + device_addr_type_cmp); + if (list) { + device = list->data; + DBG("Soft matched"); + device_print_addr(device); } } -#endif if (!list) return NULL; device = list->data; +#ifdef __TIZEN_PATCH__ + if (exact_match) + return device; +#endif + /* * If we're looking up based on public address and the address * was not previously used over this bearer we may need to @@ -1473,6 +1468,18 @@ void adapter_service_remove(struct btd_adapter *adapter, uint32_t handle) remove_record_from_server(rec->handle); } +#ifdef __TIZEN_PATCH__ +static void adapter_print_devices(struct btd_adapter *adapter) +{ + GSList *dev; + + dev = adapter->devices; + for (; dev; dev = dev->next) { + device_print_addr(dev->data); + } +} +#endif + static struct btd_device *adapter_create_device(struct btd_adapter *adapter, const bdaddr_t *bdaddr, uint8_t bdaddr_type) @@ -1485,6 +1492,10 @@ static struct btd_device *adapter_create_device(struct btd_adapter *adapter, adapter->devices = g_slist_append(adapter->devices, device); +#ifdef __TIZEN_PATCH__ + adapter_print_devices(adapter); +#endif + return device; } @@ -3286,12 +3297,12 @@ static DBusMessage *adapter_le_scan_filter_param_setup(DBusConnection *conn, DBusMessage *msg, void *data) { struct btd_adapter *adapter = data; - dbus_bool_t err; dbus_int32_t client_if, action, filt_index; dbus_int32_t feat_seln, list_logic_type, filt_logic_type; dbus_int32_t rssi_high_thres, rssi_low_thres, dely_mode; dbus_int32_t found_timeout, lost_timeout, found_timeout_cnt; adapter_le_scan_filter_param_t params; + gboolean err; DBG("adapter_le_scan_filter_param_setup"); @@ -3345,16 +3356,17 @@ static DBusMessage *adapter_le_scan_filter_add_remove(DBusConnection *conn, DBusMessage *msg, void *data) { struct btd_adapter *adapter = data; - struct btd_device *dev; - bdaddr_t bdaddr; - dbus_bool_t err; + struct btd_device *dev = NULL; dbus_int32_t client_if, action, filt_type, filt_index; dbus_int32_t company_id, company_id_mask; - gchar *string; + gchar *address = NULL; + dbus_uint32_t address_type = 0; + uint8_t addr_type; + GSList *list; char ida_string[18]; - dbus_uint32_t address_type; uint8_t *p_uuid, *p_uuid_mask, *p_data, *p_mask; int32_t uuid_len = 0, uuid_mask_len = 0, data_len = 0, mask_len = 0; + gboolean err; DBG("adapter_le_scan_filter_add_remove"); @@ -3372,32 +3384,36 @@ static DBusMessage *adapter_le_scan_filter_add_remove(DBusConnection *conn, DBUS_TYPE_INT32, &company_id_mask, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &p_uuid, &uuid_len, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &p_uuid_mask, &uuid_mask_len, - DBUS_TYPE_STRING, &string, + DBUS_TYPE_STRING, &address, DBUS_TYPE_UINT32, &address_type, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &p_data, &data_len, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &p_mask, &mask_len, DBUS_TYPE_INVALID)) return btd_error_invalid_args(msg); - DBG("addr %s, type %d", string, address_type); - - str2ba(string, &bdaddr); - - dev = btd_adapter_find_device(adapter, &bdaddr, address_type); + list = g_slist_find_custom(adapter->devices, address, device_rpa_cmp); + if (!list) + list = g_slist_find_custom(adapter->devices, address, + device_address_cmp); + if (list) + dev = list->data; if (dev && device_get_rpa_exist(dev) == true) { ba2str(device_get_address(dev), ida_string); if (btd_device_get_bdaddr_type(dev) == BDADDR_LE_PUBLIC) - address_type = 0x0; + addr_type = 0x00; else - address_type = 0x1; + addr_type = 0x01; } else { - memcpy(ida_string, string, sizeof(ida_string)); + memcpy(ida_string, address, sizeof(ida_string)); + addr_type = 0x00; } + DBG("addr %s, type %d", ida_string, addr_type); + err = adapter_le_set_scan_filter_data(client_if, action, filt_type, filt_index, company_id, company_id_mask, uuid_len, p_uuid, uuid_mask_len, p_uuid_mask, - ida_string, address_type, data_len, p_data, mask_len, p_mask); + ida_string, addr_type, data_len, p_data, mask_len, p_mask); if (!err) return btd_error_failed(msg, "Failed to add/remove filter"); @@ -3409,9 +3425,9 @@ static DBusMessage *adapter_le_scan_filter_clear(DBusConnection *conn, DBusMessage *msg, void *data) { struct btd_adapter *adapter = data; - dbus_bool_t err; - dbus_int32_t client_if; - dbus_int32_t filt_index; + dbus_int32_t client_if = 0; + dbus_int32_t filt_index = 0; + gboolean err; DBG("adapter_le_scan_filter_clear"); @@ -3439,9 +3455,9 @@ static DBusMessage *adapter_le_scan_filter_enable(DBusConnection *conn, DBusMessage *msg, void *data) { struct btd_adapter *adapter = data; - dbus_bool_t err; dbus_bool_t enable = FALSE; - dbus_int32_t client_if; + dbus_int32_t client_if = 0; + gboolean err; DBG("adapter_le_scan_filter_enable"); @@ -3575,6 +3591,7 @@ static DBusMessage *adapter_add_device_white_list(DBusConnection *conn, const gchar *address; bdaddr_t bdaddr; dbus_uint32_t address_type; + uint8_t addr_type; struct btd_device *dev; DBG("Add device whie list"); @@ -3590,11 +3607,15 @@ static DBusMessage *adapter_add_device_white_list(DBusConnection *conn, if (!(adapter->current_settings & MGMT_SETTING_POWERED)) return btd_error_not_ready(msg); + if (address_type == 0) + addr_type = BDADDR_LE_PUBLIC; + else + addr_type = BDADDR_LE_RANDOM; - DBG("addr %s, type %d", address, address_type); + DBG("addr %s, type %d", address, addr_type); str2ba(address, &bdaddr); - dev = btd_adapter_find_device(adapter, &bdaddr, address_type); + dev = btd_adapter_find_device(adapter, &bdaddr, addr_type); if (dev && device_get_rpa_exist(dev) == true) { if (adapter_le_is_supported_offloading() == FALSE) { error("Spec based command is not supported yet"); @@ -3603,8 +3624,8 @@ static DBusMessage *adapter_add_device_white_list(DBusConnection *conn, /* Add IRK value to list */ if (adapter_le_add_irk_to_list(device_get_irk_value(dev), - device_get_address(dev), - btd_device_get_bdaddr_type(dev))) { + device_get_address(dev), + btd_device_get_bdaddr_type(dev))) { return dbus_message_new_method_return(msg); } else { return btd_error_failed(msg, "Add LE IRK to list failed"); @@ -3613,7 +3634,7 @@ static DBusMessage *adapter_add_device_white_list(DBusConnection *conn, memset(&cp, 0, sizeof(cp)); - cp.bdaddr_type = address_type; + cp.bdaddr_type = addr_type; memcpy(&cp.bdaddr, &bdaddr, sizeof(bdaddr_t)); if (mgmt_send(adapter->mgmt, MGMT_OP_ADD_DEV_WHITE_LIST, @@ -3632,6 +3653,7 @@ static DBusMessage *adapter_remove_device_white_list(DBusConnection *conn, const gchar *address; bdaddr_t bdaddr; dbus_uint32_t address_type; + uint8_t addr_type; struct btd_device *dev; DBG("Remove device whie list"); @@ -3648,10 +3670,15 @@ static DBusMessage *adapter_remove_device_white_list(DBusConnection *conn, if (check_address(address) < 0) return btd_error_invalid_args(msg); - DBG("addr %s, type %d", address, address_type); + if (address_type == 0) + addr_type = BDADDR_LE_PUBLIC; + else + addr_type = BDADDR_LE_RANDOM; + + DBG("addr %s, type %d", address, addr_type); str2ba(address, &bdaddr); - dev = btd_adapter_find_device(adapter, &bdaddr, address_type); + dev = btd_adapter_find_device(adapter, &bdaddr, addr_type); if (dev && device_get_rpa_exist(dev) == true) { if (adapter_le_is_supported_offloading() == FALSE) { error("Spec based command is not supported yet"); @@ -3660,16 +3687,16 @@ static DBusMessage *adapter_remove_device_white_list(DBusConnection *conn, /* Remove IRK value to list */ if (adapter_le_remove_irk_to_list(device_get_address(dev), - btd_device_get_bdaddr_type(dev))) { + btd_device_get_bdaddr_type(dev))) { return dbus_message_new_method_return(msg); } else { - return btd_error_failed(msg, "Remove LE IRK to list failed"); + return btd_error_failed(msg, "Remove IRK is failed"); } } memset(&cp, 0, sizeof(cp)); - cp.bdaddr_type = address_type; + cp.bdaddr_type = addr_type; memcpy(&cp.bdaddr, &bdaddr, sizeof(bdaddr_t)); if (mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_DEV_FROM_WHITE_LIST, @@ -5540,27 +5567,15 @@ static DBusMessage *find_device(DBusConnection *conn, DBusMessage *msg, const gchar *address; GSList *l; const gchar *dev_path; - bdaddr_t rpa; - uint8_t msb = 0x00; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID)) - return btd_error_invalid_args(msg); - - str2ba(address, &rpa); - - l = g_slist_find_custom(adapter->devices, - address, (GCompareFunc) device_address_cmp); - - if (!l) { - msb = rpa.b[5] >> 6; - - /* Check whether address is RPA */ - if (msb == 0x00 || msb == 0x01) - l = g_slist_find_custom(adapter->devices, - address, (GCompareFunc) device_rpa_cmp); - } + DBUS_TYPE_INVALID)) + return btd_error_invalid_args(msg); + l = g_slist_find_custom(adapter->devices, address, device_rpa_cmp); + if (!l) + l = g_slist_find_custom(adapter->devices, address, + device_address_cmp); if (!l) return btd_error_does_not_exist(msg); @@ -5568,13 +5583,13 @@ static DBusMessage *find_device(DBusConnection *conn, DBusMessage *msg, reply = dbus_message_new_method_return(msg); if (!reply) - return NULL; + return NULL; dev_path = device_get_path(device); dbus_message_append_args(reply, - DBUS_TYPE_OBJECT_PATH, &dev_path, - DBUS_TYPE_INVALID); + DBUS_TYPE_OBJECT_PATH, &dev_path, + DBUS_TYPE_INVALID); return reply; } @@ -6503,6 +6518,47 @@ static uint8_t get_le_addr_type(GKeyFile *keyfile) return addr_type; } +#ifdef __TIZEN_PATCH__ +static uint8_t get_addr_type(GKeyFile *keyfile) +{ + char **techno, **t; + char *str; + uint8_t bdaddr_type = BDADDR_BREDR; + bool le = false; + + /* Load device technology */ + techno = g_key_file_get_string_list(keyfile, "General", + "SupportedTechnologies", NULL, NULL); + if (!techno) + return BDADDR_BREDR; + + for (t = techno; *t; t++) { + if (g_str_equal(*t, "LE")) + le = true; + } + + if (!le) { + bdaddr_type = BDADDR_BREDR; + } else { + str = g_key_file_get_string(keyfile, "General", + "AddressType", NULL); + + if (str && g_str_equal(str, "public")) + bdaddr_type = BDADDR_LE_PUBLIC; + else if (str && g_str_equal(str, "static")) + bdaddr_type = BDADDR_LE_RANDOM; + else + error("Unknown LE device technology"); + + g_free(str); + } + + g_strfreev(techno); + + return bdaddr_type; +} +#endif + static void probe_devices(void *user_data) { struct btd_device *device = user_data; @@ -6541,6 +6597,7 @@ static void load_devices(struct btd_adapter *adapter) #ifdef __TIZEN_PATCH__ struct link_key_info *key_info = NULL; GSList *list, *ltk_info = NULL; + struct device_addr_type addr; #else struct link_key_info *key_info; GSList *list, *ltk_info; @@ -6590,36 +6647,25 @@ static void load_devices(struct btd_adapter *adapter) if (param) params = g_slist_append(params, param); +#ifdef __TIZEN_PATCH__ + str2ba(entry->d_name, &addr.bdaddr); + addr.bdaddr_type = get_addr_type(key_file); + + list = g_slist_find_custom(adapter->devices, &addr, + device_addr_type_strict_cmp); +#else list = g_slist_find_custom(adapter->devices, entry->d_name, device_address_cmp); +#endif if (list) { +#ifdef __TIZEN_PATCH__ + DBG("Skip already loaded device [%s] [%d]", + entry->d_name, addr.bdaddr_type); +#endif device = list->data; goto device_exist; } -#ifdef __TIZEN_PATCH__ -{ - char **techno; - - techno = g_key_file_get_string_list(key_file, "General", - "SupportedTechnologies", NULL, NULL); - - /* KITT: Encryption fail with MIC Failure error - Problem happend when two LTK is stored on both RPA and IDA address folder - Here, if IDA dev info is loaded before RPA info, both RPA dev and IDA dev - are created and problem happend.(If RPA info is loaded first, IDA is not - loaded. (upper device_exist case)) - Fix: skip a loadding info in case of 'no technologies' */ - - if (!techno) { - DBG("No SupportedTechnologies. Skipping"); - goto free; - } - - g_strfreev(techno); -} -#endif - device = device_create_from_storage(adapter, entry->d_name, key_file); if (!device) @@ -6627,31 +6673,36 @@ static void load_devices(struct btd_adapter *adapter) #ifdef __TIZEN_PATCH__ { - char irk_addr[18]; + char idaddr[18]; - /* After load IRK information from file, store it into device->bdaddr - RPA is stored in device->rpa_addr */ - ba2str(device_get_address(device), irk_addr); + /* + * After loading IRK information from file, + * store it into device->bdaddr. + * RPA is stored in device->rpa_addr + */ + ba2str(device_get_address(device), idaddr); - DBG("irk address: %s, rpa_exist %d", irk_addr, device_get_rpa_exist(device)); + DBG("irk address: %s, rpa_exist %d", + idaddr, device_get_rpa_exist(device)); if (device_get_rpa_exist(device) == true) { if (key_info) - str2ba(irk_addr, &key_info->bdaddr); + str2ba(idaddr, &key_info->bdaddr); if (ltk_info) { ltks = g_slist_remove(ltks, ltk_info); - ltk_info = get_ltk_info(key_file, irk_addr, bdaddr_type); + ltk_info = get_ltk_info(key_file, + idaddr, bdaddr_type); ltks = g_slist_concat(ltks, ltk_info); } if (irk_info) { - str2ba(irk_addr, &irk_info->bdaddr); + str2ba(idaddr, &irk_info->bdaddr); device_set_irk_value(device, irk_info->val); } if (param) - str2ba(irk_addr, ¶m->bdaddr); + str2ba(idaddr, ¶m->bdaddr); } } #endif @@ -10382,6 +10433,9 @@ static void dev_disconnected(struct btd_adapter *adapter, { struct btd_device *device; char dst[18]; +#ifdef __TIZEN_PATCH__ + struct device_addr_type t_addr; +#endif ba2str(&addr->bdaddr, dst); @@ -10391,13 +10445,18 @@ static void dev_disconnected(struct btd_adapter *adapter, #ifdef __TIZEN_PATCH__ if (device) { + device_get_tizen_addr(device, &t_addr); device_set_disconnect_reason(device, reason); - adapter_remove_connection(adapter, device, addr->type); + adapter_remove_connection(adapter, device, t_addr.bdaddr_type); disconnect_notify(device, reason); - if (device_is_bonded(device, addr->type)) { - DBG("addr type %d, bonded", addr->type); + if (device_is_bonded(device, t_addr.bdaddr_type)) { + DBG("addr type %d, bonded", t_addr.bdaddr_type); return; } + + bonding_attempt_complete(adapter, &t_addr.bdaddr, + t_addr.bdaddr_type, MGMT_STATUS_DISCONNECTED); + return; } #else if (device) { @@ -10500,11 +10559,6 @@ static void store_link_key(struct btd_adapter *adapter, ba2str(btd_adapter_get_address(adapter), adapter_addr); ba2str(device_get_address(device), device_addr); -#ifdef __TIZEN_PATCH__ - if (device_get_rpa_exist(device) == true) - ba2str(device_get_rpa(device), device_addr); -#endif - snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr, device_addr); key_file = g_key_file_new(); @@ -10527,28 +10581,6 @@ static void store_link_key(struct btd_adapter *adapter, g_key_file_free(key_file); } -#ifdef __TIZEN_PATCH__ -static struct link_key_info *load_link_key(struct btd_adapter *adapter, - const char *peer) -{ - struct link_key_info *key_info; - GKeyFile *key_file; - char filename[PATH_MAX]; - char srcaddr[18]; - - ba2str(&adapter->bdaddr, srcaddr); - - snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", srcaddr, peer); - - key_file = g_key_file_new(); - g_key_file_load_from_file(key_file, filename, 0, NULL); - - key_info = get_key_info(key_file, peer); - - return key_info; -} -#endif - static void new_link_key_callback(uint16_t index, uint16_t length, const void *param, void *user_data) { @@ -10599,29 +10631,6 @@ static void new_link_key_callback(uint16_t index, uint16_t length, } #endif - /* If BR/EDR linkkey exists in previous, update the linkkey into RPA based folder info */ -#ifdef __TIZEN_PATCH__ - if (device_get_rpa_exist(device) == true) { - struct link_key_info *key_info; - - key_info = load_link_key(adapter, dst); - if (key_info && key_info->type == 0x05) { - DBG("Replace linkkey!"); - - /* #define HCI_LK_AUTH_COMBINATION_P192 0x05 - Replace the linkkey as the orginal one - */ - store_link_key(adapter, device, key_info->key, - key_info->type, key_info->pin_len); - - /* Delete irk based folder */ - device_remove_stored_folder(device); - } else { - DBG("There is no original linkkey or type is not 0x05"); - } - } -#endif - bonding_complete(adapter, &addr->bdaddr, addr->type, 0); } @@ -10687,6 +10696,9 @@ static void new_long_term_key_callback(uint16_t index, uint16_t length, struct btd_device *device; bool persistent; char dst[18]; +#ifdef __TIZEN_PATCH__ + struct device_addr_type t_addr; +#endif if (length < sizeof(*ev)) { btd_error(adapter->dev_id, "Too small long term key event"); @@ -10732,15 +10744,10 @@ static void new_long_term_key_callback(uint16_t index, uint16_t length, rand = le64_to_cpu(key->rand); #ifdef __TIZEN_PATCH__ - if (device_get_rpa_exist(device) == true) { - store_longtermkey(bdaddr, device_get_rpa(device), - key->addr.type, key->val, key->master, - key->type, key->enc_size, ediv, rand); - } else { - store_longtermkey(bdaddr, &key->addr.bdaddr, - key->addr.type, key->val, key->master, - key->type, key->enc_size, ediv, rand); - } + device_get_tizen_addr(device, &t_addr); + store_longtermkey(bdaddr, &t_addr.bdaddr, t_addr.bdaddr_type, + key->val, key->master, key->type, + key->enc_size, ediv, rand); #else store_longtermkey(bdaddr, &key->addr.bdaddr, key->addr.type, key->val, key->master, @@ -10825,6 +10832,9 @@ static void new_csrk_callback(uint16_t index, uint16_t length, const bdaddr_t *bdaddr = btd_adapter_get_address(adapter); struct btd_device *device; char dst[18]; +#ifdef __TIZEN_PATCH__ + struct device_addr_type t_addr; +#endif if (length < sizeof(*ev)) { btd_error(adapter->dev_id, "Too small CSRK event"); @@ -10846,8 +10856,14 @@ static void new_csrk_callback(uint16_t index, uint16_t length, if (!ev->store_hint) return; +#ifdef __TIZEN_PATCH__ + device_get_tizen_addr(device, &t_addr); + store_csrk(bdaddr, &t_addr.bdaddr, t_addr.bdaddr_type, key->val, 0, + key->type); +#else store_csrk(bdaddr, &key->addr.bdaddr, key->addr.type, key->val, 0, key->type); +#endif btd_device_set_temporary(device, false); } @@ -10896,6 +10912,9 @@ static void new_irk_callback(uint16_t index, uint16_t length, struct btd_device *device, *duplicate; bool persistent; char dst[18], rpa[18]; +#ifdef __TIZEN_PATCH__ + struct device_addr_type t_addr; +#endif if (length < sizeof(*ev)) { btd_error(adapter->dev_id, "Too small New IRK event"); @@ -10908,31 +10927,17 @@ static void new_irk_callback(uint16_t index, uint16_t length, DBG("hci%u new IRK for %s RPA %s", adapter->dev_id, dst, rpa); if (bacmp(&ev->rpa, BDADDR_ANY)) { -#ifdef __TIZEN_PATCH__ - /* - * With new RPA, existing device can be found only when bonding is - * initiated from local side using remote RPA; so first find the device - * with RPA. If device is not found then find the device with IDA. - */ - - device = btd_adapter_find_device(adapter, &ev->rpa, - BDADDR_LE_RANDOM); - if (device == NULL) - device = btd_adapter_find_device(adapter, &addr->bdaddr, - addr->type); - if (device == NULL) - device = btd_adapter_get_device(adapter, &ev->rpa, - BDADDR_LE_RANDOM); -#else - device = btd_adapter_get_device(adapter, &ev->rpa, BDADDR_LE_RANDOM); -#endif - +#ifndef __TIZEN_PATCH__ duplicate = btd_adapter_find_device(adapter, &addr->bdaddr, addr->type); if (duplicate == device) duplicate = NULL; +#else + device_set_rpa(device, &ev->rpa); + duplicate = NULL; +#endif } else { device = btd_adapter_get_device(adapter, &addr->bdaddr, addr->type); @@ -10945,44 +10950,13 @@ static void new_irk_callback(uint16_t index, uint16_t length, return; } -#ifdef __TIZEN_PATCH__ - if (bacmp(&ev->rpa, BDADDR_ANY) != 0) { - device_set_rpa(device, &ev->rpa); - - if (duplicate) - device_set_rpa(duplicate, &ev->rpa); - } -#endif - device_update_addr(device, &addr->bdaddr, addr->type); -#ifdef __TIZEN_PATCH__ - if (duplicate) { - device_merge_duplicate(device, duplicate); - device_set_irk_value(duplicate, irk->val); - - /* If BR/EDR linkkey exists in previous, update the linkkey into RPA based folder info */ - if (device_get_rpa_exist(device) == true) { - struct link_key_info *key_info; - - key_info = load_link_key(adapter, dst); - if (key_info && key_info->type == 0x05) { - DBG("Add linkkey of BR/EDR"); - - /* #define HCI_LK_AUTH_COMBINATION_P192 0x05 */ - store_link_key(adapter, device, key_info->key, - key_info->type, key_info->pin_len); - - /* Delete IDA based folder */ - device_remove_stored_folder(duplicate); - } else { - DBG("There is no original linkkey or type is not 0x05"); - } - } - } -#else if (duplicate) device_merge_duplicate(device, duplicate); + +#ifdef __TIZEN_PATCH__ + device_set_irk_value(device, irk->val); #endif persistent = !!ev->store_hint; @@ -10990,12 +10964,8 @@ static void new_irk_callback(uint16_t index, uint16_t length, return; #ifdef __TIZEN_PATCH__ - if (bacmp(&ev->rpa, BDADDR_ANY) != 0) - store_irk(adapter, device_get_rpa(device), addr->type, irk->val); - else - store_irk(adapter, &addr->bdaddr, addr->type, irk->val); - - device_set_irk_value(device, irk->val); + device_get_tizen_addr(device, &t_addr); + store_irk(adapter, &t_addr.bdaddr, t_addr.bdaddr_type, irk->val); #else store_irk(adapter, &addr->bdaddr, addr->type, irk->val); #endif @@ -11051,7 +11021,9 @@ static void new_conn_param(uint16_t index, uint16_t length, uint16_t min, max, latency, timeout; struct btd_device *dev; char dst[18]; - +#ifdef __TIZEN_PATCH__ + struct device_addr_type t_addr; +#endif if (length < sizeof(*ev)) { btd_error(adapter->dev_id, @@ -11079,9 +11051,16 @@ static void new_conn_param(uint16_t index, uint16_t length, if (!ev->store_hint) return; +#ifdef __TIZEN_PATCH__ + device_get_tizen_addr(dev, &t_addr); + store_conn_param(adapter, &t_addr.bdaddr, t_addr.bdaddr_type, + ev->min_interval, ev->max_interval, + ev->latency, ev->timeout); +#else store_conn_param(adapter, &ev->addr.bdaddr, ev->addr.type, ev->min_interval, ev->max_interval, ev->latency, ev->timeout); +#endif } int adapter_set_io_capability(struct btd_adapter *adapter, uint8_t io_cap) @@ -11436,6 +11415,8 @@ static int adapter_register(struct btd_adapter *adapter) load_devices(adapter); #ifdef __TIZEN_PATCH__ + adapter_print_devices(adapter); + if (adapter->le_privacy_enabled && (adapter->supported_settings & MGMT_SETTING_PRIVACY)) set_privacy(adapter, true); diff --git a/src/device.c b/src/device.c index 6feb69d..79637f2 100644 --- a/src/device.c +++ b/src/device.c @@ -333,13 +333,11 @@ struct btd_device { gboolean ipsp_connected; /* IPSP Connection state */ char if_name[16 + 1]; /* BT interface UP after IPSP connection */ uint8_t rpa_res_support; /* RPA Resolution capability of device */ - uint16_t max_tx_octets; - uint16_t max_tx_time; - uint16_t max_rx_octets; - uint16_t max_rx_time; - bdaddr_t rpa; - bool rpa_exist; - bool duplicate; + uint16_t max_tx_octets; + uint16_t max_tx_time; + uint16_t max_rx_octets; + uint16_t max_rx_time; + bdaddr_t *rpa; DBusMessage *req_att_mtu; /* Attribute MTU request message */ uint8_t irk_val[16]; bool pending_conn_update; @@ -518,8 +516,8 @@ static gboolean store_device_info_cb(gpointer user_data) ba2str(&device->bdaddr, device_addr); #ifdef __TIZEN_PATCH__ - if (device->rpa_exist) - ba2str(&device->rpa, device_addr); + if (device->rpa) + ba2str(device->rpa, device_addr); #endif snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr, device_addr); @@ -612,7 +610,7 @@ static gboolean store_device_info_cb(gpointer user_data) "ManufacturerDataLen", NULL); } - if (device->rpa_exist) { + if (device->rpa) { char irk_addr[18]; ba2str(&device->bdaddr, irk_addr); @@ -707,8 +705,8 @@ void device_store_cached_name(struct btd_device *dev, const char *name) ba2str(&dev->bdaddr, d_addr); #ifdef __TIZEN_PATCH__ - if (dev->rpa_exist) - ba2str(&dev->rpa, d_addr); + if (dev->rpa) + ba2str(dev->rpa, d_addr); #endif snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", s_addr, d_addr); @@ -868,6 +866,9 @@ static void device_free(gpointer user_data) if (device->eir_uuids) g_slist_free_full(device->eir_uuids, g_free); +#ifdef __TIZEN_PATCH__ + g_free(device->rpa); +#endif g_free(device->local_csrk); g_free(device->remote_csrk); g_free(device->path); @@ -951,7 +952,12 @@ static gboolean dev_property_get_address(const GDBusPropertyTable *property, char dstaddr[18]; const char *ptr = dstaddr; - ba2str(&device->bdaddr, dstaddr); +#ifdef __TIZEN_PATCH__ + if (device->rpa) + ba2str(device->rpa, dstaddr); + else +#endif + ba2str(&device->bdaddr, dstaddr); dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr); return TRUE; @@ -2460,8 +2466,8 @@ static void store_services(struct btd_device *device) ba2str(&device->bdaddr, dst_addr); #ifdef __TIZEN_PATCH__ - if (device->rpa_exist) - ba2str(&device->rpa, dst_addr); + if (device->rpa) + ba2str(device->rpa, dst_addr); #endif snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", src_addr, @@ -3657,40 +3663,28 @@ static DBusMessage *device_get_ida(DBusConnection *conn, DBusMessage *msg, struct btd_device *device = user_data; char device_idaddr[18] = { 0 }; DBusMessage *reply; - const gchar *id_address; + const gchar *id_address = device_idaddr; DBG(""); - if (device == NULL) { - error("device is NULL"); + if (device == NULL) return btd_error_invalid_args(msg); - } - if (!device->le) { - error("le is not supported"); + if (!device->le) return btd_error_not_supported(msg); - } - DBG("bdaddr_type %d", device->bdaddr_type); - - /* Device will have its IDA only if device has RPA */ - if (device->rpa_exist) { - DBG("device->rpa_exist"); + if (device->rpa) ba2str(&device->bdaddr, device_idaddr); - } - else { - DBG("device->rpa_exist does not exist"); + else return btd_error_does_not_exist(msg); - } reply = dbus_message_new_method_return(msg); if (!reply) - return NULL; - - id_address = g_strdup(device_idaddr); + return NULL; dbus_message_append_args(reply, DBUS_TYPE_STRING, &id_address, - DBUS_TYPE_INVALID); + DBUS_TYPE_INVALID); + return reply; } @@ -4111,11 +4105,11 @@ static void load_info(struct btd_device *device, const char *local, str = g_key_file_get_string(key_file, "General", "IdentityAddress", NULL); - /* Folder name is RPA(Resolvable Private Address), So we need to swap it */ if (str) { - memcpy(&device->rpa, &device->bdaddr, sizeof(bdaddr_t)); + device->rpa = g_malloc0(sizeof(bdaddr_t)); + bacpy(device->rpa, &device->bdaddr); str2ba(str, &device->bdaddr); - device->rpa_exist = true; + g_free(str); } #endif @@ -4942,6 +4936,35 @@ static struct btd_device *device_new(struct btd_adapter *adapter, return btd_device_ref(device); } +#ifdef __TIZEN_PATCH__ +void device_print_addr(struct btd_device *dev) +{ + char addr[18]; + + ba2str(&dev->bdaddr, addr); + DBG("IDA : %s %d", addr, dev->bdaddr_type); + + if (dev->rpa) { + ba2str(dev->rpa, addr); + DBG("RPA : %s", addr); + } else { + DBG("No RPA"); + } + + if (dev->bredr) + DBG("BREDR Support"); + else + DBG("BREDR Not Support"); + + if (dev->le) + DBG("LE Support"); + else + DBG("LE Not Support"); + + DBG("***"); +} +#endif + struct btd_device *device_create_from_storage(struct btd_adapter *adapter, const char *address, GKeyFile *key_file) { @@ -4986,11 +5009,6 @@ struct btd_device *device_create(struct btd_adapter *adapter, else device->le = true; -#ifdef __TIZEN_PATCH__ - if (bdaddr_type == BDADDR_LE_RANDOM) - bacpy(&device->rpa, bdaddr); -#endif - sba = btd_adapter_get_address(adapter); ba2str(sba, src); @@ -5018,8 +5036,8 @@ char *btd_device_get_storage_path(struct btd_device *device, ba2str(&device->bdaddr, dstaddr); #ifdef __TIZEN_PATCH__ - if (device->rpa_exist) - ba2str(&device->rpa, dstaddr); + if (device->rpa) + ba2str(device->rpa, dstaddr); #endif if (!filename) @@ -5103,6 +5121,23 @@ void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr, void device_set_bredr_support(struct btd_device *device) { +#ifdef __TIZEN_PATCH__ + char addr_str[18]; + + if (device->rpa) { + ba2str(device->rpa, addr_str); + error("Cannot set bredr support to RPA device [%s]", addr_str); + return; + } + + if (device->bdaddr_type == BDADDR_LE_RANDOM) { + ba2str(&device->bdaddr, addr_str); + error("Cannot set bredr support to LE random device [%s]", + addr_str); + return; + } +#endif + if (device->bredr) return; @@ -5113,13 +5148,11 @@ void device_set_bredr_support(struct btd_device *device) #ifdef __TIZEN_PATCH__ void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa) { - DBG("rpa exist: %d", device->rpa_exist); - - if (device->rpa_exist == false) { - /* Only use first RPA value even if the device was re-paired */ - bacpy(&device->rpa, rpa); - device->rpa_exist = true; - } + if (device->rpa == NULL) { + device->rpa = g_malloc0(sizeof(bdaddr_t)); + bacpy(device->rpa, rpa); + } else + error("RPA is already set"); } void device_set_irk_value(struct btd_device *device, const uint8_t *val) @@ -5180,15 +5213,6 @@ void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup) dev->vendor = dup->vendor; dev->product = dup->product; dev->version = dup->version; - -#ifdef __TIZEN_PATCH__ - for (l = dup->services; l; l = g_slist_next(l)) { - struct btd_service *svc = l->data; - dev->services = g_slist_append(dev->services, btd_service_ref(svc)); - } - - dup->duplicate = true; -#endif } uint32_t btd_device_get_class(struct btd_device *device) @@ -5278,8 +5302,8 @@ static void device_remove_stored(struct btd_device *device) ba2str(&device->bdaddr, device_addr); #ifdef __TIZEN_PATCH__ - if (device->rpa_exist) - ba2str(&device->rpa, device_addr); + if (device->rpa) + ba2str(device->rpa, device_addr); #endif snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr, @@ -5350,12 +5374,12 @@ void device_unpair(struct btd_device *device, gboolean remove_stored) gatt_db_clear(device->db); - if (device->rpa_exist) { - bacpy(&device->bdaddr, &device->rpa); + if (device->rpa) { + bacpy(&device->bdaddr, device->rpa); device->bdaddr_type = BDADDR_LE_RANDOM; - bacpy(&device->rpa, BDADDR_ANY); - device->rpa_exist = false; + g_free(device->rpa); + device->rpa = NULL; } device->bredr_state.paired = 0; @@ -5451,7 +5475,11 @@ int device_rpa_cmp(gconstpointer a, gconstpointer b) const char *address = b; char addr[18]; - ba2str(&device->rpa, addr); + if (!device->rpa) + return -1; + + ba2str(device->rpa, addr); + return strcasecmp(addr, address); } @@ -5460,9 +5488,6 @@ int device_addr_cmp(gconstpointer a, gconstpointer b) const struct btd_device *device = a; const bdaddr_t *bdaddr = b; - if (device->duplicate) - return -1; - return bacmp(&device->bdaddr, bdaddr); } #endif @@ -5493,6 +5518,36 @@ static bool addr_is_public(uint8_t addr_type) return false; } +#ifdef __TIZEN_PATCH__ +int device_addr_type_strict_cmp(gconstpointer a, gconstpointer b) +{ + const struct btd_device *dev = a; + const struct device_addr_type *addr = b; + int cmp; + + cmp = bacmp(&dev->bdaddr, &addr->bdaddr); + + if (addr->bdaddr_type == BDADDR_BREDR) { + if (!dev->bredr) + return -1; + + return cmp; + } + + if (!dev->le) + return -1; + + if (cmp && dev->rpa && addr->bdaddr_type == BDADDR_LE_RANDOM && + (addr->bdaddr.b[5] >> 6) == 0x01) + return bacmp(dev->rpa, &addr->bdaddr); + + if (addr->bdaddr_type != dev->bdaddr_type) + return -1; + + return cmp; +} +#endif + int device_addr_type_cmp(gconstpointer a, gconstpointer b) { const struct btd_device *dev = a; @@ -5508,7 +5563,20 @@ int device_addr_type_cmp(gconstpointer a, gconstpointer b) */ if (!cmp && addr_is_public(addr->bdaddr_type) && addr_is_public(dev->bdaddr_type)) +#ifdef __TIZEN_PATCH__ + { + if (dev->rpa && addr->bdaddr_type == BDADDR_BREDR) { + char addr_str[18]; + + ba2str(&dev->bdaddr, addr_str); + DBG("Don't match. LE Only device [%s]", addr_str); + return -1; + } + return 0; + } +#else return 0; +#endif if (addr->bdaddr_type == BDADDR_BREDR) { if (!dev->bredr) @@ -5842,11 +5910,6 @@ static void update_bredr_services(struct browse_req *req, sdp_list_t *recs) ba2str(btd_adapter_get_address(device->adapter), srcaddr); ba2str(&device->bdaddr, dstaddr); -#ifdef __TIZEN_PATCH__ - if (device->rpa_exist) - ba2str(&device->rpa, dstaddr); -#endif - snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr, dstaddr); @@ -6830,7 +6893,7 @@ void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_oc const bdaddr_t *device_get_rpa(struct btd_device *device) { - return &device->rpa; + return device->rpa; } const uint8_t *device_get_irk_value(struct btd_device *device) @@ -6840,7 +6903,7 @@ const uint8_t *device_get_irk_value(struct btd_device *device) bool device_get_rpa_exist(struct btd_device *device) { - return device->rpa_exist; + return device->rpa ? true : false; } void device_set_auth_addr_type(struct btd_device *device, uint8_t type) @@ -6852,6 +6915,22 @@ void device_set_auth_addr_type(struct btd_device *device, uint8_t type) device->auth_bdaddr_type = type; } + +void device_get_tizen_addr(struct btd_device *device, + struct device_addr_type *addr) +{ + if (!device || !addr) + return; + + if (device->rpa) { + bacpy(&addr->bdaddr, device->rpa); + addr->bdaddr_type = BDADDR_LE_RANDOM; + return; + } + + bacpy(&addr->bdaddr, &device->bdaddr); + addr->bdaddr_type = device->bdaddr_type; +} #endif int device_discover_services(struct btd_device *device) @@ -7184,9 +7263,10 @@ void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type, #ifdef TIZEN_WEARABLE if (bdaddr_type == BDADDR_BREDR && state->svc_resolved) { DBG("Link key has been changed. Report it"); - if (device->rpa_exist == false) - g_dbus_emit_property_changed(dbus_conn, device->path, - DEVICE_INTERFACE, "Paired"); + if (!device->rpa) + g_dbus_emit_property_changed(dbus_conn, + device->path, DEVICE_INTERFACE, + "Paired"); else DBG("Just overwrite Link key"); } else if (bdaddr_type == BDADDR_LE_RANDOM || @@ -7814,8 +7894,8 @@ static sdp_list_t *read_device_records(struct btd_device *device) ba2str(&device->bdaddr, peer); #ifdef __TIZEN_PATCH__ - if (device->rpa_exist) - ba2str(&device->rpa, peer); + if (device->rpa) + ba2str(device->rpa, peer); #endif snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer); @@ -7960,7 +8040,7 @@ void device_set_adv_report_info(struct btd_device *device, void *data, uint8_t d ba2str(&device->bdaddr, peer_addr); /* Replace address type for paired RPA device since IDA passed from controller */ - if(device_get_rpa_exist(device) == true) + if (device->rpa) addr_type = BDADDR_LE_RANDOM; else addr_type = device->bdaddr_type; diff --git a/src/device.h b/src/device.h index 0a18596..8c73d13 100644 --- a/src/device.h +++ b/src/device.h @@ -66,6 +66,9 @@ struct device_addr_type { uint8_t bdaddr_type; }; +#ifdef __TIZEN_PATCH__ +int device_addr_type_strict_cmp(gconstpointer a, gconstpointer b); +#endif int device_addr_type_cmp(gconstpointer a, gconstpointer b); GSList *btd_device_get_uuids(struct btd_device *device); void device_probe_profiles(struct btd_device *device, GSList *profiles); @@ -181,6 +184,8 @@ void device_set_rpa_res_char_value(struct btd_device *device, uint8_t value); void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets, uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time); +void device_get_tizen_addr(struct btd_device *device, + struct device_addr_type *addr); #endif struct btd_device *btd_device_ref(struct btd_device *device); @@ -207,6 +212,7 @@ struct btd_service *btd_device_get_service(struct btd_device *dev, const char *remote_uuid); #ifdef __TIZEN_PATCH__ +void device_print_addr(struct btd_device *dev); gboolean device_is_profile_trusted(struct btd_device *device, const char *uuid); gboolean device_is_profile_blocked(struct btd_device *device, -- 2.7.4