char *current_alias; /* current adapter name alias */
char *stored_alias; /* stored adapter name alias */
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
- bool le_privacy_enabled; /* whether LE Privacy feature enabled */
uint8_t *local_irk; /* adapter local IRK */
uint8_t disc_type;
bool ipsp_intialized; /* Ipsp Initialization state */
if (adapter->stored_alias)
g_key_file_set_string(key_file, "General", "Alias",
adapter->stored_alias);
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
- 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
-
ba2str(&adapter->bdaddr, address);
snprintf(filename, PATH_MAX, STORAGEDIR "/%s/settings", address);
static bool set_mode(struct btd_adapter *adapter, uint16_t opcode,
uint8_t mode);
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static bool load_local_irk(struct btd_adapter *adapter);
+static bool set_local_irk(struct btd_adapter *adapter);
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
adapter->advertising = adapter->current_settings & MGMT_SETTING_ADVERTISING;
advertising_state_changed(adapter, 0, adapter->advertising);
}
+
+ if ((changed_mask & MGMT_SETTING_PRIVACY) &&
+ !(adapter->current_settings & MGMT_SETTING_PRIVACY)) {
+ DBG("LE Privacy feature is disabled");
+
+ /*
+ * 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.
+ */
+ set_local_irk(adapter);
+ }
#endif
}
char address[18];
struct stat st;
GError *gerr = NULL;
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
- char *str;
-#endif
ba2str(&adapter->bdaddr, address);
gerr = NULL;
}
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
- /* Get Local IRK */
- str = g_key_file_get_string(key_file, "General", "LocalIrk", &gerr);
- if (gerr || !str || strlen(str) != 34) {
- g_error_free(gerr);
- gerr = NULL;
-
- g_free(adapter->local_irk);
- adapter->local_irk = NULL;
- } else {
- if (!adapter->local_irk)
- adapter->local_irk = g_malloc0(MGMT_IRK_SIZE);
-
- str2buf(&str[2], adapter->local_irk, MGMT_IRK_SIZE);
- }
-#endif
-
g_key_file_free(key_file);
}
DBG("Modalias: %s", adapter->modalias);
DBG("Discoverable timeout: %u seconds", adapter->discoverable_timeout);
DBG("Pairable timeout: %u seconds", adapter->pairable_timeout);
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
- if (main_opts.le_privacy)
- DBG("LE Privacy is enabled.");
- else
- DBG("LE Privacy is disabled.");
-#endif
adapter->auths = g_queue_new();
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
adapter_print_devices(adapter);
- if (adapter->le_privacy_enabled &&
- (adapter->supported_settings & MGMT_SETTING_PRIVACY))
- set_privacy(adapter, true);
- else {
+ if (load_local_irk(adapter)) {
+ if (!(adapter->supported_settings & MGMT_SETTING_PRIVACY))
+ main_opts.le_privacy = false;
+
/*
* 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);
+ set_local_irk(adapter);
+
+ if (main_opts.le_privacy) {
+ DBG("Enable LE Privacy feature");
+ set_privacy(adapter, true);
+ } else {
+ DBG("Disable LE Privacy feature");
+ }
}
#endif
return irk;
}
+#define LOCAL_IRK_DIRNAME "/csa/bluetooth"
+#define LOCAL_IRK_FILENAME ".local_irk"
+
+static bool store_local_irk(struct btd_adapter *adapter)
+{
+ int fd;
+ int ret;
+
+ if (adapter->local_irk == NULL) {
+ error("Local IRK is not proper");
+ return false;
+ }
+
+ if (access(LOCAL_IRK_DIRNAME, F_OK) < 0) {
+ if (mkdir(LOCAL_IRK_DIRNAME, 0755) < 0) {
+ error("Cannot create a directory for local IRK : %s",
+ strerror(errno));
+ return false;
+ }
+ }
+
+ fd = open(LOCAL_IRK_DIRNAME"/"LOCAL_IRK_FILENAME,
+ O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd < 0) {
+ error("Cannot open a file for local IRK : %s", strerror(errno));
+ return false;
+ }
+
+ ret = write(fd, adapter->local_irk, MGMT_IRK_SIZE);
+ if (ret != MGMT_IRK_SIZE) {
+ error("Cannot write local IRK [%d] : %s", ret, strerror(errno));
+
+ close(fd);
+ unlink(LOCAL_IRK_DIRNAME"/"LOCAL_IRK_FILENAME);
+ return false;
+ }
+
+ ret = fdatasync(fd);
+ if (ret < 0)
+ error("sync failed : %s", strerror(errno));
+
+ close(fd);
+ return true;
+}
+
+static bool load_local_irk(struct btd_adapter *adapter)
+{
+ int fd;
+ int ret;
+
+ if (access(LOCAL_IRK_DIRNAME"/"LOCAL_IRK_FILENAME, F_OK) < 0) {
+ adapter->local_irk = generate_irk();
+ if (store_local_irk(adapter) < 0) {
+ error("Cannot store Local IRK");
+ g_free(adapter->local_irk);
+ return false;
+ }
+
+ return true;
+ }
+
+ if (adapter->local_irk) {
+ DBG("Local IRK is already loaded");
+ return true;
+ }
+
+ fd = open(LOCAL_IRK_DIRNAME"/"LOCAL_IRK_FILENAME, O_RDONLY);
+ if (fd < 0) {
+ error("Cannot open local IRK file : %s", strerror(errno));
+ return false;
+ }
+
+ adapter->local_irk = g_malloc0(MGMT_IRK_SIZE);
+
+ ret = read(fd, adapter->local_irk, MGMT_IRK_SIZE);
+ if (ret != MGMT_IRK_SIZE) {
+ error("Cannot read local IRK [%d] : %s", ret, strerror(errno));
+ g_free(adapter->local_irk);
+ close(fd);
+ return false;
+ }
+
+ close(fd);
+ return true;
+}
+
static void set_privacy_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
{
struct mgmt_cp_set_privacy cp;
- memset(&cp, 0, sizeof(cp));
-
- if (privacy) {
- if (adapter->local_irk == NULL) {
- adapter->local_irk = generate_irk();
- if (adapter->local_irk == NULL)
- goto fail;
- }
+ if (!adapter->local_irk) {
+ error("Local IRK is not available");
+ return false;
+ }
- store_adapter_info(adapter);
+ memset(&cp, 0, sizeof(cp));
+ memcpy(cp.irk, adapter->local_irk, MGMT_IRK_SIZE);
+ if (privacy)
cp.privacy = 0x01;
- memcpy(cp.irk, adapter->local_irk, MGMT_IRK_SIZE);
- }
if (mgmt_send(adapter->mgmt, MGMT_OP_SET_PRIVACY,
adapter->dev_id, sizeof(cp), &cp,
set_privacy_complete, adapter, NULL) > 0)
return true;
-fail:
error("Failed to set privacy and load local irk for index %u",
adapter->dev_id);
return false;
DBG("Setting IRK is succeed for hci%u", adapter->dev_id);
}
-static bool set_irk(struct btd_adapter *adapter, bool set)
+static bool set_local_irk(struct btd_adapter *adapter)
{
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 (!adapter->local_irk) {
+ error("Local IRK is not available");
+ return false;
}
+ 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;
}
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
/* Set the RPA resolution value to '1' if privacy is supported */
- if (adapter->le_privacy_enabled &&
+ if (main_opts.le_privacy &&
adapter->supported_settings & MGMT_SETTING_PRIVACY)
adapter->central_rpa_res_support = 0x01;
#endif