From 2bd325428feab81382b17b062d4e3b49ede180e4 Mon Sep 17 00:00:00 2001 From: Nishant Chaprana Date: Thu, 18 Mar 2021 11:38:16 +0530 Subject: [PATCH] Add setter/getter for handling MAC randomization policy Change-Id: I978ab95f02d04574efc7c3455b71f72841956c36 Signed-off-by: Nishant Chaprana --- gsupplicant/gsupplicant.h | 17 +++ gsupplicant/supplicant.c | 191 ++++++++++++++++++++++++++++++ include/device.h | 19 +++ packaging/connman.spec | 2 +- plugins/wifi.c | 113 ++++++++++++++++++ src/connman.conf | 3 + src/device.c | 91 +++++++++++++++ src/technology.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 726 insertions(+), 1 deletion(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 7e94e97..991554b 100755 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -378,6 +378,23 @@ void *g_supplicant_interface_get_data(GSupplicantInterface *interface); const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface); #if defined TIZEN_EXT bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *interface); + +typedef void (*GSupplicantMacPolicyCallback) (int result, unsigned int policy, void *user_data); +int g_supplicant_interface_set_mac_policy(GSupplicantInterface *interface, + GSupplicantMacPolicyCallback callback, + unsigned int policy, + void *user_data); + +int g_supplicant_interface_set_preassoc_mac_policy(GSupplicantInterface *interface, + GSupplicantMacPolicyCallback callback, + unsigned int policy, + void *user_data); + +typedef void (*GSupplicantRandomMaclifetimeCallback) (int result, unsigned int lifetime, void *user_data); +int g_supplicant_interface_set_random_mac_lifetime(GSupplicantInterface *interface, + GSupplicantRandomMaclifetimeCallback callback, + unsigned int lifetime, + void *user_data); #endif const char *g_supplicant_interface_get_driver(GSupplicantInterface *interface); GSupplicantState g_supplicant_interface_get_state(GSupplicantInterface *interface); diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index f57ef78..bb1bfa7 100755 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -398,6 +398,11 @@ struct interface_create_data { char *ifname; char *driver; char *bridge; +#if defined TIZEN_EXT + unsigned int mac_addr; + unsigned int preassoc_mac_addr; + unsigned int random_mac_lifetime; +#endif /* TIZEN_EXT */ #if defined TIZEN_EXT_WIFI_MESH char *parent_ifname; bool is_mesh_interface; @@ -5686,6 +5691,19 @@ static void interface_create_params(DBusMessageIter *iter, void *user_data) DBUS_TYPE_STRING, &config_file); } +#ifdef TIZEN_EXT + if (!g_strcmp0(data->driver, "wifi")) { + supplicant_dbus_dict_append_basic(&dict, "MacAddr", + DBUS_TYPE_UINT32, &data->mac_addr); + + supplicant_dbus_dict_append_basic(&dict, "PreassocMacAddr", + DBUS_TYPE_UINT32, &data->preassoc_mac_addr); + + supplicant_dbus_dict_append_basic(&dict, "RandAddrLifetime", + DBUS_TYPE_UINT32, &data->random_mac_lifetime); + } +#endif /* TIZEN_EXT */ + #if defined TIZEN_EXT_WIFI_MESH if (data->is_mesh_interface) { if (data->parent_ifname) @@ -8680,3 +8698,176 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks) callbacks_pointer = NULL; eap_methods = 0; } + +#ifdef TIZEN_EXT +struct supplicant_mac_policy { + GSupplicantMacPolicyCallback callback; + dbus_uint32_t policy; + const void *user_data; +}; + +static void mac_policy_result(const char *error, + DBusMessageIter *iter, void *user_data) +{ + struct supplicant_mac_policy *data = user_data; + int result = 0; + + if (!user_data) + return; + + if (error) { + SUPPLICANT_DBG("Mac policy setting failure %s", error); + result = -EINVAL; + } + + if (data->callback) + data->callback(result, data->policy, + (void *) data->user_data); + + dbus_free(data); +} + +static void mac_policy_params(DBusMessageIter *iter, void *user_data) +{ + struct supplicant_mac_policy *data = user_data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &(data->policy)); +} + +int g_supplicant_interface_set_mac_policy(GSupplicantInterface *interface, + GSupplicantMacPolicyCallback callback, + unsigned int policy, + void *user_data) +{ + struct supplicant_mac_policy *data = NULL; + int ret; + + if (!system_available) + return -EFAULT; + + if (!interface) + return -EINVAL; + + data = dbus_malloc0(sizeof(*data)); + if (!data) + return -ENOMEM; + + data->callback = callback; + data->policy = policy; + data->user_data = user_data; + + ret = supplicant_dbus_property_set(interface->path, + SUPPLICANT_INTERFACE ".Interface", + "MacAddr", DBUS_TYPE_INT32_AS_STRING, + mac_policy_params, mac_policy_result, data, NULL); + if (ret < 0) { + SUPPLICANT_DBG("Unable to set MacAddr configuration"); + dbus_free(data); + } + + return ret; +} + +int g_supplicant_interface_set_preassoc_mac_policy(GSupplicantInterface *interface, + GSupplicantMacPolicyCallback callback, + unsigned int policy, + void *user_data) +{ + struct supplicant_mac_policy *data; + int ret; + + if (!system_available) + return -EFAULT; + + if (!interface) + return -EINVAL; + + data = dbus_malloc0(sizeof(*data)); + if (!data) + return -ENOMEM; + + data->callback = callback; + data->policy = policy; + data->user_data = user_data; + + ret = supplicant_dbus_property_set(interface->path, + SUPPLICANT_INTERFACE ".Interface", + "PreassocMacAddr", DBUS_TYPE_INT32_AS_STRING, + mac_policy_params, mac_policy_result, data, NULL); + if (ret < 0) { + SUPPLICANT_DBG("Unable to set PreassocMacAddr configuration"); + dbus_free(data); + } + + return ret; +} + +struct supplicant_random_mac_lifetime { + GSupplicantRandomMaclifetimeCallback callback; + dbus_uint32_t lifetime; + const void *user_data; +}; + +static void random_mac_lifetime_result(const char *error, + DBusMessageIter *iter, void *user_data) +{ + struct supplicant_random_mac_lifetime *data = user_data; + int result = 0; + + if (!user_data) + return; + + if (error) { + SUPPLICANT_DBG("Random Mac lifetime setting failure %s", error); + result = -EINVAL; + } + + if (data->callback) + data->callback(result, data->lifetime, + (void *) data->user_data); + + dbus_free(data); +} + +static void random_mac_lifetime_params(DBusMessageIter *iter, void *user_data) +{ + struct supplicant_random_mac_lifetime *data = user_data; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &(data->lifetime)); +} + +int g_supplicant_interface_set_random_mac_lifetime(GSupplicantInterface *interface, + GSupplicantRandomMaclifetimeCallback callback, + unsigned int lifetime, + void *user_data) +{ + struct supplicant_random_mac_lifetime *data; + int ret; + + if (!system_available) + return -EFAULT; + + if (!interface) + return -EINVAL; + + data = dbus_malloc0(sizeof(*data)); + if (!data) + return -ENOMEM; + + data->callback = callback; + data->lifetime = lifetime; + data->user_data = user_data; + + ret = supplicant_dbus_property_set(interface->path, + SUPPLICANT_INTERFACE ".Interface", + "RandAddrLifetime", DBUS_TYPE_UINT32_AS_STRING, + random_mac_lifetime_params, random_mac_lifetime_result, + data, NULL); + if (ret < 0) { + SUPPLICANT_DBG("Unable to set RandAddrLifetime configuration"); + dbus_free(data); + } + + return ret; +} +#endif diff --git a/include/device.h b/include/device.h index 67d7928..8cc8cce 100755 --- a/include/device.h +++ b/include/device.h @@ -151,6 +151,22 @@ void connman_device_save_last_user_selection(struct connman_device *device); void connman_device_load_last_user_selection(struct connman_device *device); void connman_device_save_last_connected(struct connman_device *device); void connman_device_load_last_connected(struct connman_device *device); + +void connman_device_mac_policy_notify(struct connman_device *device, + int result, unsigned int policy); +int connman_device_set_mac_policy(struct connman_device *device, + unsigned int policy); +unsigned int connman_device_get_mac_policy(struct connman_device *device); +void connman_device_preassoc_mac_policy_notify(struct connman_device *device, + int result, unsigned int policy); +int connman_device_set_preassoc_mac_policy(struct connman_device *device, + unsigned int policy); +unsigned int connman_device_get_preassoc_mac_policy(struct connman_device *device); +void connman_device_random_mac_lifetime_notify(struct connman_device *device, + int result, unsigned int lifetime); +int connman_device_set_random_mac_lifetime(struct connman_device *device, + unsigned int lifetime); +unsigned int connman_device_get_random_mac_lifetime(struct connman_device *device); #endif struct connman_device_driver { @@ -171,6 +187,9 @@ struct connman_device_driver { int (*specific_scan) (enum connman_service_type type, struct connman_device *device, int scan_type, GSList *specific_scan_list, void *user_data); + int (*set_mac_policy) (struct connman_device *device, unsigned int policy); + int (*set_preassoc_mac_policy) (struct connman_device *device, unsigned int policy); + int (*set_random_mac_lifetime) (struct connman_device *device, unsigned int lifetime); #endif #if defined TIZEN_EXT_WIFI_MESH int (*abort_scan) (enum connman_service_type type, diff --git a/packaging/connman.spec b/packaging/connman.spec index 501c10e..ed890d1 100644 --- a/packaging/connman.spec +++ b/packaging/connman.spec @@ -6,7 +6,7 @@ Name: connman Version: 1.38 -Release: 4 +Release: 5 License: GPL-2.0+ Summary: Connection Manager Url: http://connman.net diff --git a/plugins/wifi.c b/plugins/wifi.c index 2c6d50d..5b4a0aa 100755 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -2435,6 +2435,12 @@ static void setup_autoscan(struct wifi_data *wifi) #endif } +#ifdef TIZEN_EXT +int wifi_set_mac_policy(struct connman_device *device, unsigned int policy); +int wifi_set_preassoc_mac_policy(struct connman_device *device, unsigned int policy); +int wifi_set_random_mac_lifetime(struct connman_device *device, unsigned int lifetime); +#endif /* TIZEN_EXT */ + static void finalize_interface_creation(struct wifi_data *wifi) { DBG("interface is ready wifi %p tethering %d", wifi, wifi->tethering); @@ -2446,6 +2452,17 @@ static void finalize_interface_creation(struct wifi_data *wifi) connman_device_set_powered(wifi->device, true); +#ifdef TIZEN_EXT + wifi_set_mac_policy(wifi->device, + connman_device_get_mac_policy(wifi->device)); + + wifi_set_preassoc_mac_policy(wifi->device, + connman_device_get_preassoc_mac_policy(wifi->device)); + + wifi_set_random_mac_lifetime(wifi->device, + connman_device_get_random_mac_lifetime(wifi->device)); +#endif /* TIZEN_EXT */ + if (wifi->p2p_device) return; @@ -2957,6 +2974,99 @@ static int wifi_specific_scan(enum connman_service_type type, return ret; } + +static void wifi_mac_policy_callback(int result, + unsigned int policy, + void *user_data) +{ + struct connman_device *device = user_data; + + if (result == 0) + connman_device_mac_policy_notify(device, result, policy); + + connman_device_unref(device); +} + +int wifi_set_mac_policy(struct connman_device *device, unsigned int policy) +{ + struct wifi_data *wifi = connman_device_get_data(device); + int ret; + + if (!wifi) + return -EINVAL; + + connman_device_ref(device); + + ret = g_supplicant_interface_set_mac_policy(wifi->interface, + wifi_mac_policy_callback, + policy, device); + if (ret != 0) + connman_device_unref(device); + + return ret; +} + +static void wifi_preassoc_mac_policy_callback(int result, + unsigned int policy, + void *user_data) +{ + struct connman_device *device = user_data; + + if (result == 0) + connman_device_preassoc_mac_policy_notify(device, result, policy); + + connman_device_unref(device); +} + +int wifi_set_preassoc_mac_policy(struct connman_device *device, unsigned int policy) +{ + struct wifi_data *wifi = connman_device_get_data(device); + int ret; + + if (!wifi) + return -EINVAL; + + connman_device_ref(device); + + ret = g_supplicant_interface_set_preassoc_mac_policy(wifi->interface, + wifi_preassoc_mac_policy_callback, + policy, device); + if (ret != 0) + connman_device_unref(device); + + return ret; +} + +static void wifi_random_mac_lifetime_callback(int result, + unsigned int lifetime, + void *user_data) +{ + struct connman_device *device = user_data; + + if (result == 0) + connman_device_random_mac_lifetime_notify(device, result, lifetime); + + connman_device_unref(device); +} + +int wifi_set_random_mac_lifetime(struct connman_device *device, unsigned int lifetime) +{ + struct wifi_data *wifi = connman_device_get_data(device); + int ret; + + if (!wifi) + return -EINVAL; + + connman_device_ref(device); + + ret = g_supplicant_interface_set_random_mac_lifetime(wifi->interface, + wifi_random_mac_lifetime_callback, + lifetime, device); + if (ret != 0) + connman_device_unref(device); + + return ret; +} #endif #if defined TIZEN_EXT_WIFI_MESH @@ -3332,6 +3442,9 @@ static struct connman_device_driver wifi_ng_driver = { .set_regdom = wifi_set_regdom, #if defined TIZEN_EXT .specific_scan = wifi_specific_scan, + .set_mac_policy = wifi_set_mac_policy, + .set_preassoc_mac_policy = wifi_set_preassoc_mac_policy, + .set_random_mac_lifetime = wifi_set_random_mac_lifetime, #endif #if defined TIZEN_EXT_WIFI_MESH .abort_scan = mesh_abort_scan, diff --git a/src/connman.conf b/src/connman.conf index adff8fa..7e33e3e 100644 --- a/src/connman.conf +++ b/src/connman.conf @@ -39,5 +39,8 @@ + + + diff --git a/src/device.c b/src/device.c index 801400f..fa5a001 100755 --- a/src/device.c +++ b/src/device.c @@ -79,6 +79,9 @@ struct connman_device { DBusMessage *pending_reply; int max_scan_ssids; bool is_5_0_ghz_supported; + unsigned int mac_policy; + unsigned int preassoc_mac_policy; + unsigned int random_mac_lifetime; #endif }; @@ -654,6 +657,11 @@ void connman_device_set_interface(struct connman_device *device, void connman_device_set_ident(struct connman_device *device, const char *ident) { +#ifdef TIZEN_EXT + if (device->ident) + return; + else +#endif g_free(device->ident); device->ident = g_strdup(ident); } @@ -1096,6 +1104,11 @@ int connman_device_set_string(struct connman_device *device, DBG("device %p key %s value %s", device, key, value); if (g_str_equal(key, "Address")) { +#ifdef TIZEN_EXT + if (device->address) + return 0; + else +#endif g_free(device->address); device->address = g_strdup(value); } else if (g_str_equal(key, "Name")) { @@ -2099,3 +2112,81 @@ void __connman_device_cleanup(void) dbus_connection_unref(connection); #endif } + +#ifdef TIZEN_EXT +void connman_device_mac_policy_notify(struct connman_device *device, + int result, unsigned int policy) +{ + device->mac_policy = policy; + __connman_technology_notify_mac_policy_by_device(device, result, policy); +} + +int connman_device_set_mac_policy(struct connman_device *device, + unsigned int policy) +{ + int err = 0; + + if (!device || !device->driver || !device->driver->set_mac_policy) + return -EOPNOTSUPP; + + device->mac_policy = policy; + err = device->driver->set_mac_policy(device, policy); + return err; +} + +unsigned int connman_device_get_mac_policy(struct connman_device *device) +{ + return device->mac_policy; +} + +void connman_device_preassoc_mac_policy_notify(struct connman_device *device, + int result, unsigned int policy) +{ + device->preassoc_mac_policy = policy; + __connman_technology_notify_preassoc_mac_policy_by_device(device, result, policy); +} + +int connman_device_set_preassoc_mac_policy(struct connman_device *device, + unsigned int policy) +{ + int err = 0; + + if (!device || !device->driver || !device->driver->set_preassoc_mac_policy) + return -EOPNOTSUPP; + + device->preassoc_mac_policy = policy; + err = device->driver->set_preassoc_mac_policy(device, policy); + return err; +} + +unsigned int connman_device_get_preassoc_mac_policy(struct connman_device *device) +{ + return device->preassoc_mac_policy; +} + +void connman_device_random_mac_lifetime_notify(struct connman_device *device, + int result, unsigned int lifetime) +{ + device->random_mac_lifetime = lifetime; + __connman_technology_notify_random_mac_lifetime_by_device(device, result, lifetime); +} + +int connman_device_set_random_mac_lifetime(struct connman_device *device, + unsigned int lifetime) +{ + int err = 0; + + if (!device || !device->driver || !device->driver->set_random_mac_lifetime) + return -EOPNOTSUPP; + + device->random_mac_lifetime = lifetime; + err = device->driver->set_random_mac_lifetime(device, lifetime); + return err; +} + +unsigned int connman_device_get_random_mac_lifetime(struct connman_device *device) +{ + return device->random_mac_lifetime; +} + +#endif diff --git a/src/technology.c b/src/technology.c index 440d7eb..c476b3e 100644 --- a/src/technology.c +++ b/src/technology.c @@ -100,6 +100,9 @@ struct connman_technology { bool dbus_registered; #if defined TIZEN_EXT char **enabled_devices; + unsigned int mac_policy; + unsigned int preassoc_mac_policy; + unsigned int random_mac_lifetime; #endif #if defined TIZEN_EXT_WIFI_MESH DBusMessage *mesh_dbus_msg; @@ -218,6 +221,19 @@ static void technology_save(struct connman_technology *technology) "Tethering.Passphrase", technology->tethering_passphrase); +#ifdef TIZEN_EXT + if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) { + g_key_file_set_uint64(keyfile, identifier, "MacPolicy", + technology->mac_policy); + + g_key_file_set_uint64(keyfile, identifier, "PreassocMacPolicy", + technology->preassoc_mac_policy); + + g_key_file_set_uint64(keyfile, identifier, "RandomMacLifetime", + technology->random_mac_lifetime); + } +#endif /* TIZEN_EXT */ + done: g_free(identifier); @@ -488,6 +504,34 @@ static void technology_load(struct connman_technology *technology) technology->tethering_passphrase = g_key_file_get_string(keyfile, identifier, "Tethering.Passphrase", NULL); + +#ifdef TIZEN_EXT + if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) { + unsigned int val = 0; + + val = g_key_file_get_uint64(keyfile, + identifier, "MacPolicy", NULL); + if (val <= 2) + technology->mac_policy = val; + else + technology->mac_policy = 0; + + val = g_key_file_get_uint64(keyfile, + identifier, "PreassocMacPolicy", NULL); + if (val <= 2) + technology->preassoc_mac_policy = val; + else + technology->preassoc_mac_policy = 0; + + val = g_key_file_get_uint64(keyfile, + identifier, "RandomMacLifetime", NULL); + if (val > 0) + technology->random_mac_lifetime = val; + else + technology->random_mac_lifetime = 60; + } +#endif /* TIZEN_EXT */ + done: g_free(identifier); @@ -666,6 +710,18 @@ static void append_properties(DBusMessageIter *iter, connman_dbus_dict_append_basic(&dict, "TetheringPassphrase", DBUS_TYPE_STRING, &technology->tethering_passphrase); + + connman_dbus_dict_append_basic(&dict, "MacPolicy", + DBUS_TYPE_UINT32, + &(technology->mac_policy)); + + connman_dbus_dict_append_basic(&dict, "PreassocMacPolicy", + DBUS_TYPE_UINT32, + &(technology->preassoc_mac_policy)); + + connman_dbus_dict_append_basic(&dict, "RandomMacLifetime", + DBUS_TYPE_UINT32, + &(technology->random_mac_lifetime)); #if defined TIZEN_EXT if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) connman_dbus_dict_append_dict(&dict, "Device.List", @@ -1078,6 +1134,190 @@ int set_connman_bssid(enum bssid_type mode, char *bssid, const char *ifname) return bssid_len; } + +void connman_technology_mac_policy_notify(struct connman_technology *technology, + unsigned int policy) +{ + DBG("Mac polict set to %u", policy); + + technology->mac_policy = policy; + technology_save(technology); +} + +void __connman_technology_notify_mac_policy_by_device(struct connman_device *device, + int result, unsigned int policy) +{ + struct connman_technology *technology; + enum connman_service_type type; + + type = __connman_device_get_service_type(device); + technology = technology_find(type); + + if (!technology) + return; + + connman_technology_mac_policy_notify(technology, policy); +} + +static DBusMessage *set_mac_policy(struct connman_technology *technology, + DBusMessage *msg, unsigned int policy) +{ + DBusMessage *reply = NULL; + int err = 0; + unsigned int last_policy = technology->mac_policy; + + if (technology->rfkill_driven && technology->hardblocked) { + err = -EACCES; + goto make_reply; + } + + for (GSList *list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + err = connman_device_set_mac_policy(device, policy); + if (err < 0) + break; + } + +make_reply: + if (err < 0) { + if (err != -EACCES && err != -EOPNOTSUPP) { + for (GSList *list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + connman_device_set_mac_policy(device, last_policy); + } + } + + reply = __connman_error_failed(msg, -err); + } else { + reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + } + + return reply; +} + +void connman_technology_preassoc_mac_policy_notify(struct connman_technology *technology, + unsigned int policy) +{ + DBG("Preassoc mac polict set to %u", policy); + + technology->preassoc_mac_policy = policy; + technology_save(technology); +} + +void __connman_technology_notify_preassoc_mac_policy_by_device(struct connman_device *device, + int result, unsigned int policy) +{ + struct connman_technology *technology; + enum connman_service_type type; + + type = __connman_device_get_service_type(device); + technology = technology_find(type); + + if (!technology) + return; + + connman_technology_preassoc_mac_policy_notify(technology, policy); +} + +static DBusMessage *set_preassoc_mac_policy(struct connman_technology *technology, + DBusMessage *msg, unsigned int policy) +{ + DBusMessage *reply = NULL; + int err = 0; + unsigned int last_policy = technology->preassoc_mac_policy; + + if (technology->rfkill_driven && technology->hardblocked) { + err = -EACCES; + goto make_reply; + } + + for (GSList *list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + err = connman_device_set_preassoc_mac_policy(device, policy); + if (err < 0) + break; + } + +make_reply: + if (err < 0) { + if (err != -EACCES && err != -EOPNOTSUPP) { + for (GSList *list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + connman_device_set_preassoc_mac_policy(device, last_policy); + } + } + + reply = __connman_error_failed(msg, -err); + } else { + reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + } + + return reply; +} + +void connman_technology_random_mac_lifetime_notify(struct connman_technology *technology, + unsigned int lifetime) +{ + DBG("Random mac lifetime set to %u", lifetime); + + technology->random_mac_lifetime = lifetime; + technology_save(technology); +} + +void __connman_technology_notify_random_mac_lifetime_by_device(struct connman_device *device, + int result, unsigned int lifetime) +{ + struct connman_technology *technology; + enum connman_service_type type; + + type = __connman_device_get_service_type(device); + technology = technology_find(type); + + if (!technology) + return; + + connman_technology_random_mac_lifetime_notify(technology, lifetime); +} + +static DBusMessage *set_random_mac_lifetime(struct connman_technology *technology, + DBusMessage *msg, unsigned int lifetime) +{ + DBusMessage *reply = NULL; + int err = 0; + unsigned int last_lifetime = technology->random_mac_lifetime; + + if (technology->rfkill_driven && technology->hardblocked) { + err = -EACCES; + goto make_reply; + } + + for (GSList *list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + err = connman_device_set_random_mac_lifetime(device, lifetime); + } + +make_reply: + if (err < 0) { + if (err != -EACCES && err != -EOPNOTSUPP) { + for (GSList *list = technology->device_list; list; list = list->next) { + struct connman_device *device = list->data; + + connman_device_set_random_mac_lifetime(device, last_lifetime); + } + } + + reply = __connman_error_failed(msg, -err); + } else { + reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + } + + return reply; +} #endif static DBusMessage *set_property(DBusConnection *conn, @@ -1203,6 +1443,53 @@ static DBusMessage *set_property(DBusConnection *conn, dbus_message_iter_get_basic(&value, &key); DBG("BSSID %s", key); set_connman_bssid(SET_BSSID, key, NULL); + } else if (g_str_equal(name, "MacPolicy")) { + dbus_uint32_t mac_policy; + + if (technology->type != CONNMAN_SERVICE_TYPE_WIFI) + return __connman_error_not_supported(msg); + + if (type != DBUS_TYPE_UINT32) + return __connman_error_invalid_arguments(msg); + + dbus_message_iter_get_basic(&value, &mac_policy); + + if (mac_policy <= 2) + return set_mac_policy(technology, msg, mac_policy); + else + return __connman_error_invalid_arguments(msg); + + } else if (g_str_equal(name, "PreassocMacPolicy")) { + dbus_uint32_t preassoc_mac_policy; + + if (technology->type != CONNMAN_SERVICE_TYPE_WIFI) + return __connman_error_not_supported(msg); + + if (type != DBUS_TYPE_UINT32) + return __connman_error_invalid_arguments(msg); + + dbus_message_iter_get_basic(&value, &preassoc_mac_policy); + + if (preassoc_mac_policy <= 2) + return set_preassoc_mac_policy(technology, msg, preassoc_mac_policy); + else + return __connman_error_invalid_arguments(msg); + + } else if (g_str_equal(name, "RandomMacLifetime")) { + dbus_uint32_t random_mac_lifetime; + + if (technology->type != CONNMAN_SERVICE_TYPE_WIFI) + return __connman_error_not_supported(msg); + + if (type != DBUS_TYPE_UINT32) + return __connman_error_invalid_arguments(msg); + + dbus_message_iter_get_basic(&value, &random_mac_lifetime); + + if (random_mac_lifetime > 0) + return set_random_mac_lifetime(technology, msg, random_mac_lifetime); + else + return __connman_error_invalid_arguments(msg); #endif } else return __connman_error_invalid_property(msg); @@ -2960,6 +3247,10 @@ done: #if defined TIZEN_EXT const char *ifname = connman_device_get_string(device, "Interface"); __connman_technology_notify_device_detected(technology, ifname, true); + + connman_device_set_mac_policy(device, technology->mac_policy); + connman_device_set_preassoc_mac_policy(device, technology->preassoc_mac_policy); + connman_device_set_random_mac_lifetime(device, technology->random_mac_lifetime); #endif return 0; } -- 2.7.4