uint8_t mode);
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
static bool set_privacy(struct btd_adapter *adapter, bool privacy);
+static bool set_irk(struct btd_adapter *adapter, bool set);
#endif
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
if (adapter->le_privacy_enabled &&
(adapter->supported_settings & MGMT_SETTING_PRIVACY))
set_privacy(adapter, true);
- else
+ else {
+ /*
+ * Some Android devices don't consider the device as LE one,
+ * if the device doesn't distribute IRK when pairing.
+ * Because of this compatibility issue, set IRK
+ * even though privacy feature is disabled.
+ */
DBG("LE privacy feature not configured or supported");
+ set_irk(adapter, true);
+ }
#endif
/* retrieve the active connections: address the scenario where
}
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static uint8_t *generate_irk(void)
+{
+ int fd;
+ uint8_t *irk;
+
+ DBG("Generate IRK");
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0)
+ return NULL;
+
+ irk = g_malloc0(MGMT_IRK_SIZE);
+ if (read(fd, irk, MGMT_IRK_SIZE) != MGMT_IRK_SIZE) {
+ error("Cannot read random bytes");
+ g_free(irk);
+ close(fd);
+ return NULL;
+ }
+ close(fd);
+
+ return irk;
+}
+
static void set_privacy_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
memset(&cp, 0, sizeof(cp));
- if (privacy && !adapter->local_irk) {
- int fd;
-
- DBG("Generate local irk");
-
- fd = open("/dev/urandom", O_RDONLY);
- if (fd < 0)
- goto fail;
-
- adapter->local_irk = g_malloc0(MGMT_IRK_SIZE);
- if (read(fd, adapter->local_irk, MGMT_IRK_SIZE) !=
- MGMT_IRK_SIZE) {
- error("Cannot read local irk");
- close(fd);
- goto fail;
+ if (privacy) {
+ if (adapter->local_irk == NULL) {
+ adapter->local_irk = generate_irk();
+ if (adapter->local_irk == NULL)
+ goto fail;
}
- close(fd);
store_adapter_info(adapter);
- }
- if (privacy) {
cp.privacy = 0x01;
memcpy(cp.irk, adapter->local_irk, MGMT_IRK_SIZE);
}
return false;
}
+static void set_irk_complete(uint8_t status, uint16_t length,
+ const void *param, void *user_data)
+{
+ struct btd_adapter *adapter = user_data;
+
+ if (status != MGMT_STATUS_SUCCESS)
+ error("Setting IRK is failed for hci%u: %s (0x%02x)",
+ adapter->dev_id, mgmt_errstr(status), status);
+ else
+ DBG("Setting IRK is succeed for hci%u", adapter->dev_id);
+}
+
+static bool set_irk(struct btd_adapter *adapter, bool set)
+{
+ struct mgmt_cp_set_irk cp;
+
+ memset(&cp, 0, sizeof(cp));
+
+ if (set) {
+ if (adapter->local_irk == NULL) {
+ adapter->local_irk = generate_irk();
+ if (adapter->local_irk == NULL)
+ goto fail;
+ }
+
+ store_adapter_info(adapter);
+ memcpy(cp.irk, adapter->local_irk, MGMT_IRK_SIZE);
+ }
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_SET_IRK,
+ adapter->dev_id, sizeof(cp), &cp,
+ set_irk_complete, adapter, NULL) > 0)
+ return true;
+
+fail:
+ error("Failed to set irk %u", adapter->dev_id);
+ return false;
+}
int btd_adapter_connect_ipsp(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,