5 * Copyright (C) 2007-2014 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <sys/ioctl.h>
32 #include <net/ethernet.h>
37 static GSList *device_list = NULL;
38 static gchar **device_filter = NULL;
39 static gchar **nodevice_filter = NULL;
42 static DBusConnection *connection;
45 enum connman_pending_type {
51 struct connman_device {
53 enum connman_device_type type;
54 enum connman_pending_type powered_pending; /* Indicates a pending
59 bool scanning[MAX_CONNMAN_SERVICE_TYPES];
67 guint pending_timeout;
69 struct connman_device_driver *driver;
73 struct connman_network *network;
76 time_t last_user_selection_time;
77 char *last_user_selection_ident;
78 char *last_connected_ident;
79 DBusMessage *pending_reply;
81 bool is_5_0_ghz_supported;
82 unsigned int mac_policy;
83 unsigned int preassoc_mac_policy;
84 unsigned int random_mac_lifetime;
88 static void clear_pending_trigger(struct connman_device *device)
91 if (device->pending_reply) {
92 dbus_message_unref(device->pending_reply);
93 device->pending_reply = NULL;
96 if (device->pending_timeout > 0) {
97 g_source_remove(device->pending_timeout);
98 device->pending_timeout = 0;
102 static const char *type2description(enum connman_device_type type)
105 case CONNMAN_DEVICE_TYPE_UNKNOWN:
106 case CONNMAN_DEVICE_TYPE_VENDOR:
108 case CONNMAN_DEVICE_TYPE_ETHERNET:
110 case CONNMAN_DEVICE_TYPE_WIFI:
112 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
114 case CONNMAN_DEVICE_TYPE_GPS:
116 case CONNMAN_DEVICE_TYPE_CELLULAR:
118 case CONNMAN_DEVICE_TYPE_GADGET:
126 static const char *type2string(enum connman_device_type type)
129 case CONNMAN_DEVICE_TYPE_UNKNOWN:
130 case CONNMAN_DEVICE_TYPE_VENDOR:
132 case CONNMAN_DEVICE_TYPE_ETHERNET:
134 case CONNMAN_DEVICE_TYPE_WIFI:
136 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
138 case CONNMAN_DEVICE_TYPE_GPS:
140 case CONNMAN_DEVICE_TYPE_CELLULAR:
142 case CONNMAN_DEVICE_TYPE_GADGET:
150 enum connman_service_type __connman_device_get_service_type(
151 struct connman_device *device)
153 enum connman_device_type type = connman_device_get_type(device);
156 case CONNMAN_DEVICE_TYPE_UNKNOWN:
157 case CONNMAN_DEVICE_TYPE_VENDOR:
158 case CONNMAN_DEVICE_TYPE_GPS:
160 case CONNMAN_DEVICE_TYPE_ETHERNET:
161 return CONNMAN_SERVICE_TYPE_ETHERNET;
162 case CONNMAN_DEVICE_TYPE_WIFI:
163 return CONNMAN_SERVICE_TYPE_WIFI;
164 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
165 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
166 case CONNMAN_DEVICE_TYPE_CELLULAR:
167 return CONNMAN_SERVICE_TYPE_CELLULAR;
168 case CONNMAN_DEVICE_TYPE_GADGET:
169 return CONNMAN_SERVICE_TYPE_GADGET;
173 return CONNMAN_SERVICE_TYPE_UNKNOWN;
176 static bool device_has_service_type(struct connman_device *device,
177 enum connman_service_type service_type)
179 enum connman_service_type device_service_type =
180 __connman_device_get_service_type(device);
183 * For devices whose device_service_type is unknown we should
184 * allow to decide whether they support specific service_type
187 if (device_service_type == CONNMAN_SERVICE_TYPE_UNKNOWN)
190 #if defined TIZEN_EXT_WIFI_MESH
191 if (device_service_type == CONNMAN_SERVICE_TYPE_MESH)
192 return service_type != CONNMAN_SERVICE_TYPE_MESH;
195 if (device_service_type == CONNMAN_SERVICE_TYPE_WIFI) {
196 return service_type == CONNMAN_SERVICE_TYPE_WIFI ||
197 service_type == CONNMAN_SERVICE_TYPE_P2P;
200 return service_type == device_service_type;
203 static gboolean device_pending_reset(gpointer user_data)
205 struct connman_device *device = user_data;
207 DBG("device %p", device);
209 #if defined TIZEN_EXT
212 /* Power request timed out, send ETIMEDOUT. */
213 if (device->pending_reply) {
214 reply = __connman_error_failed(device->pending_reply, ETIMEDOUT);
216 g_dbus_send_message(connection, reply);
218 dbus_message_unref(device->pending_reply);
219 device->pending_reply = NULL;
222 /* Power request timedout, reset power pending state. */
223 device->pending_timeout = 0;
224 device->powered_pending = PENDING_NONE;
229 int __connman_device_enable(struct connman_device *device)
233 DBG("device %p", device);
235 if (!device->driver || !device->driver->enable)
238 /* There is an ongoing power disable request. */
239 if (device->powered_pending == PENDING_DISABLE)
242 if (device->powered_pending == PENDING_ENABLE)
245 if (device->powered_pending == PENDING_NONE && device->powered)
248 if (device->index > 0) {
249 err = connman_inet_ifup(device->index);
250 if (err < 0 && err != -EALREADY)
254 device->powered_pending = PENDING_ENABLE;
256 err = device->driver->enable(device);
258 * device gets enabled right away.
259 * Invoke the callback
262 connman_device_set_powered(device, true);
266 if (err == -EALREADY) {
267 /* If device is already powered, but connman is not updated */
268 connman_device_set_powered(device, true);
272 * if err == -EINPROGRESS, then the DBus call to the respective daemon
273 * was successful. We set a 4 sec timeout so if the daemon never
274 * returns a reply, we would reset the pending request.
276 if (err == -EINPROGRESS)
277 device->pending_timeout = g_timeout_add_seconds(4,
278 device_pending_reset, device);
283 int __connman_device_disable(struct connman_device *device)
287 DBG("device %p", device);
289 /* Ongoing power enable request */
290 if (device->powered_pending == PENDING_ENABLE)
293 if (device->powered_pending == PENDING_DISABLE)
296 if (device->powered_pending == PENDING_NONE && !device->powered)
299 device->powered_pending = PENDING_DISABLE;
301 if (device->network) {
302 struct connman_service *service =
303 connman_service_lookup_from_network(device->network);
306 __connman_service_disconnect(service);
308 connman_network_set_connected(device->network, false);
311 if (!device->driver || !device->driver->disable)
314 err = device->driver->disable(device);
315 if (err == 0 || err == -EALREADY) {
316 connman_device_set_powered(device, false);
320 if (err == -EINPROGRESS)
321 device->pending_timeout = g_timeout_add_seconds(4,
322 device_pending_reset, device);
327 static void probe_driver(struct connman_device_driver *driver)
331 DBG("driver %p name %s", driver, driver->name);
333 for (list = device_list; list; list = list->next) {
334 struct connman_device *device = list->data;
339 if (driver->type != device->type)
342 if (driver->probe(device) < 0)
345 device->driver = driver;
347 __connman_technology_add_device(device);
351 static void remove_device(struct connman_device *device)
353 DBG("device %p", device);
355 __connman_device_disable(device);
357 __connman_technology_remove_device(device);
359 if (device->driver->remove)
360 device->driver->remove(device);
362 device->driver = NULL;
365 static void remove_driver(struct connman_device_driver *driver)
369 DBG("driver %p name %s", driver, driver->name);
371 for (list = device_list; list; list = list->next) {
372 struct connman_device *device = list->data;
374 if (device->driver == driver)
375 remove_device(device);
379 bool __connman_device_has_driver(struct connman_device *device)
381 if (!device || !device->driver)
387 static GSList *driver_list = NULL;
389 static gint compare_priority(gconstpointer a, gconstpointer b)
391 const struct connman_device_driver *driver1 = a;
392 const struct connman_device_driver *driver2 = b;
394 return driver2->priority - driver1->priority;
398 * connman_device_driver_register:
399 * @driver: device driver definition
401 * Register a new device driver
403 * Returns: %0 on success
405 int connman_device_driver_register(struct connman_device_driver *driver)
407 DBG("driver %p name %s", driver, driver->name);
409 driver_list = g_slist_insert_sorted(driver_list, driver,
411 probe_driver(driver);
417 * connman_device_driver_unregister:
418 * @driver: device driver definition
420 * Remove a previously registered device driver
422 void connman_device_driver_unregister(struct connman_device_driver *driver)
424 DBG("driver %p name %s", driver, driver->name);
426 driver_list = g_slist_remove(driver_list, driver);
428 remove_driver(driver);
431 static void free_network(gpointer data)
433 struct connman_network *network = data;
435 DBG("network %p", network);
437 __connman_network_set_device(network, NULL);
439 connman_network_unref(network);
442 static void device_destruct(struct connman_device *device)
444 DBG("device %p name %s", device, device->name);
446 clear_pending_trigger(device);
448 g_hash_table_destroy(device->networks);
449 device->networks = NULL;
451 g_free(device->ident);
452 g_free(device->node);
453 g_free(device->name);
454 g_free(device->address);
455 g_free(device->interface);
456 g_free(device->path);
458 g_free(device->last_network);
460 #if defined TIZEN_EXT
461 g_free(device->last_user_selection_ident);
462 g_free(device->last_connected_ident);
468 #if defined TIZEN_EXT
469 static void device_send_changed(const char *ifname, enum connman_service_type type,
470 const char *key, bool state)
473 DBusMessageIter iter, dict;
474 dbus_bool_t value = state;
475 const char *tech_path = connman_techonology_get_path(type);
477 if (!tech_path || !ifname)
480 DBG("%s %s %s", ifname, key, state ? "TRUE" : "FALSE");
482 signal = dbus_message_new_signal(tech_path,
483 CONNMAN_TECHNOLOGY_INTERFACE, "DeviceChanged");
487 dbus_message_iter_init_append(signal, &iter);
489 connman_dbus_dict_open(&iter, &dict);
490 connman_dbus_dict_append_basic(&dict, "Ifname",
493 connman_dbus_dict_append_basic(&dict, key,
496 connman_dbus_dict_close(&iter, &dict);
498 dbus_connection_send(connection, signal, NULL);
499 dbus_message_unref(signal);
502 static void device_send_reply(struct connman_device *device)
504 if (device->pending_reply) {
505 g_dbus_send_reply(connection,
506 device->pending_reply, DBUS_TYPE_INVALID);
507 dbus_message_unref(device->pending_reply);
508 device->pending_reply = NULL;
514 * connman_device_create:
515 * @node: device node name (for example an address)
518 * Allocate a new device of given #type and assign the #node name to it.
520 * Returns: a newly-allocated #connman_device structure
522 struct connman_device *connman_device_create(const char *node,
523 enum connman_device_type type)
525 struct connman_device *device;
527 DBG("node %s type %d", node, type);
529 device = g_try_new0(struct connman_device, 1);
533 DBG("device %p", device);
535 device->refcount = 1;
538 device->name = g_strdup(type2description(device->type));
540 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
541 g_free, free_network);
543 device_list = g_slist_prepend(device_list, device);
549 * connman_device_ref:
550 * @device: device structure
552 * Increase reference counter of device
554 struct connman_device *connman_device_ref_debug(struct connman_device *device,
555 const char *file, int line, const char *caller)
557 DBG("%p ref %d by %s:%d:%s()", device, device->refcount + 1,
560 __sync_fetch_and_add(&device->refcount, 1);
566 * connman_device_unref:
567 * @device: device structure
569 * Decrease reference counter of device
571 void connman_device_unref_debug(struct connman_device *device,
572 const char *file, int line, const char *caller)
574 DBG("%p ref %d by %s:%d:%s()", device, device->refcount - 1,
577 if (__sync_fetch_and_sub(&device->refcount, 1) != 1)
580 if (device->driver) {
581 device->driver->remove(device);
582 device->driver = NULL;
585 device_list = g_slist_remove(device_list, device);
587 device_destruct(device);
590 const char *__connman_device_get_type(struct connman_device *device)
592 return type2string(device->type);
596 * connman_device_get_type:
597 * @device: device structure
601 enum connman_device_type connman_device_get_type(struct connman_device *device)
607 * connman_device_set_index:
608 * @device: device structure
609 * @index: index number
611 * Set index number of device
613 void connman_device_set_index(struct connman_device *device, int index)
615 device->index = index;
619 * connman_device_get_index:
620 * @device: device structure
622 * Get index number of device
624 int connman_device_get_index(struct connman_device *device)
626 return device->index;
630 * connman_device_set_interface:
631 * @device: device structure
632 * @interface: interface name
634 * Set interface name of device
636 void connman_device_set_interface(struct connman_device *device,
637 const char *interface)
639 g_free(device->interface);
640 device->interface = g_strdup(interface);
643 const char *str = type2description(device->type);
644 if (str && device->interface)
645 device->name = g_strdup_printf("%s (%s)", str,
651 * connman_device_set_ident:
652 * @device: device structure
653 * @ident: unique identifier
655 * Set unique identifier of device
657 void connman_device_set_ident(struct connman_device *device,
665 g_free(device->ident);
666 device->ident = g_strdup(ident);
669 const char *connman_device_get_ident(struct connman_device *device)
671 return device->ident;
675 * connman_device_set_powered:
676 * @device: device structure
677 * @powered: powered state
679 * Change power state of device
681 int connman_device_set_powered(struct connman_device *device,
684 struct connman_device_scan_params params;
685 enum connman_service_type type;
688 DBG("device %p powered %d", device, powered);
690 if (device->powered == powered)
693 #if defined TIZEN_EXT
694 device_send_reply(device);
697 clear_pending_trigger(device);
699 device->powered_pending = PENDING_NONE;
701 device->powered = powered;
703 type = __connman_device_get_service_type(device);
705 #if defined TIZEN_EXT
706 device_send_changed(device->interface, type, "Powered", powered);
707 technology_save_device(device);
710 if (!device->powered) {
711 __connman_technology_disabled(type);
715 __connman_technology_enabled(type);
717 for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
718 device->scanning[i] = false;
720 if (device->driver && device->driver->scan) {
721 memset(¶ms, 0, sizeof(params));
722 params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
724 device->driver->scan(device, ¶ms);
730 bool connman_device_get_powered(struct connman_device *device)
732 return device->powered;
735 static int device_scan(enum connman_service_type type,
736 struct connman_device *device,
737 bool force_full_scan)
739 struct connman_device_scan_params params;
741 if (!device->driver || !device->driver->scan)
744 if (!device->powered)
747 memset(¶ms, 0, sizeof(params));
749 params.force_full_scan = force_full_scan;
751 return device->driver->scan(device, ¶ms);
754 int __connman_device_disconnect(struct connman_device *device)
759 DBG("device %p", device);
761 g_hash_table_iter_init(&iter, device->networks);
763 while (g_hash_table_iter_next(&iter, &key, &value)) {
764 struct connman_network *network = value;
766 if (connman_network_get_connecting(network)) {
768 * Skip network in the process of connecting.
769 * This is a workaround for WiFi networks serviced
770 * by the supplicant plugin that hold a reference
771 * to the network. If we disconnect the network
772 * here then the referenced object will not be
773 * registered and usage (like launching DHCP client)
774 * will fail. There is nothing to be gained by
775 * removing the network here anyway.
777 connman_warn("Skipping disconnect of %s, network is connecting.",
778 connman_network_get_identifier(network));
782 __connman_network_disconnect(network);
788 int connman_device_reconnect_service(struct connman_device *device)
790 DBG("device %p", device);
792 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
797 #if defined TIZEN_EXT
798 bool connman_device_set_last_user_selection_time(struct connman_device *device,
801 if (device->last_user_selection_time != time) {
802 device->last_user_selection_time = time;
809 time_t connman_device_get_last_user_selection_time(struct connman_device *device)
811 return device->last_user_selection_time;
814 bool connman_device_set_last_user_selection_ident(struct connman_device *device,
817 if (g_strcmp0(device->last_user_selection_ident, ident) != 0) {
818 g_free(device->last_user_selection_ident);
819 device->last_user_selection_ident = g_strdup(ident);
827 const char *connman_device_get_last_user_selection_ident(struct connman_device *device)
829 return device->last_user_selection_ident;
832 bool connman_device_set_last_connected_ident(struct connman_device *device,
835 if (g_strcmp0(device->last_connected_ident, ident) != 0) {
836 g_free(device->last_connected_ident);
837 device->last_connected_ident = g_strdup(ident);
845 const char *connman_device_get_last_connected_ident(struct connman_device *device)
847 return device->last_connected_ident;
850 void connman_device_save_last_user_selection(struct connman_device *device)
854 gchar *selection_str;
856 keyfile = __connman_storage_load_ins();
858 selection_str = g_strdup_printf("%s:%ld",
859 device->last_user_selection_ident, device->last_user_selection_time);
862 keyfile = g_key_file_new();
864 g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str);
865 DBG("%s", selection_str);
866 __connman_storage_save_ins(keyfile);
869 get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL);
870 if (!get_str || g_strcmp0(get_str, selection_str) != 0) {
871 g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str);
872 DBG("%s -> %s", get_str, selection_str);
873 __connman_storage_save_ins(keyfile);
879 g_free(selection_str);
880 g_key_file_free(keyfile);
883 void connman_device_load_last_user_selection(struct connman_device *device)
887 char **selection_str;
889 keyfile = __connman_storage_load_ins();
893 get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL);
895 selection_str = g_strsplit(get_str, ":", 0);
899 time_t last_user_selection_time;
901 /* Only events that occur within 8 hours are counted. */
902 ref_time = time(NULL);
903 timeinfo = localtime(&ref_time);
904 timeinfo->tm_hour -= 8;
905 ref_time = mktime(timeinfo);
907 last_user_selection_time = strtol(selection_str[1], NULL, 10);
909 if (last_user_selection_time > ref_time) {
910 if (g_strcmp0(selection_str[0], device->last_user_selection_ident) != 0) {
911 g_free(device->last_user_selection_ident);
912 device->last_user_selection_ident = g_strdup(selection_str[0]);
915 device->last_user_selection_time = last_user_selection_time;
917 DBG("%s %ld", device->last_user_selection_ident, device->last_user_selection_time);
920 g_strfreev(selection_str);
926 g_key_file_free(keyfile);
929 void connman_device_save_last_connected(struct connman_device *device)
934 if (!device->last_connected_ident)
937 keyfile = __connman_storage_load_ins();
940 keyfile = g_key_file_new();
942 g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident);
943 DBG("%s", device->last_connected_ident);
944 __connman_storage_save_ins(keyfile);
947 get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL);
948 if (!get_str || g_strcmp0(get_str, device->last_connected_ident) != 0) {
949 g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident);
950 DBG("%s -> %s", get_str, device->last_connected_ident);
951 __connman_storage_save_ins(keyfile);
957 g_key_file_free(keyfile);
960 void connman_device_load_last_connected(struct connman_device *device)
965 keyfile = __connman_storage_load_ins();
969 get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL);
971 if (g_strcmp0(get_str, device->last_connected_ident) != 0) {
972 g_free(device->last_connected_ident);
973 device->last_connected_ident = g_strdup(get_str);
976 DBG("%s", device->last_connected_ident);
981 g_key_file_free(keyfile);
985 static void mark_network_available(gpointer key, gpointer value,
988 struct connman_network *network = value;
990 connman_network_set_available(network, true);
993 static void mark_network_unavailable(gpointer key, gpointer value,
996 struct connman_network *network = value;
998 if (connman_network_get_connected(network) ||
999 connman_network_get_connecting(network))
1002 connman_network_set_available(network, false);
1005 static gboolean remove_unavailable_network(gpointer key, gpointer value,
1008 struct connman_network *network = value;
1010 if (connman_network_get_connected(network) ||
1011 connman_network_get_connecting(network))
1014 if (connman_network_get_available(network))
1020 void __connman_device_cleanup_networks(struct connman_device *device)
1022 g_hash_table_foreach_remove(device->networks,
1023 remove_unavailable_network, NULL);
1026 bool connman_device_get_scanning(struct connman_device *device,
1027 enum connman_service_type type)
1031 if (type != CONNMAN_SERVICE_TYPE_UNKNOWN)
1032 return device->scanning[type];
1034 for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
1035 if (device->scanning[i])
1041 void connman_device_reset_scanning(struct connman_device *device)
1043 g_hash_table_foreach(device->networks,
1044 mark_network_available, NULL);
1048 * connman_device_set_scanning:
1049 * @device: device structure
1050 * @scanning: scanning state
1052 * Change scanning state of device
1054 int connman_device_set_scanning(struct connman_device *device,
1055 enum connman_service_type type, bool scanning)
1057 DBG("device %p scanning %d", device, scanning);
1059 if (!device->driver || !device->driver->scan)
1062 if (type == CONNMAN_SERVICE_TYPE_UNKNOWN)
1065 if (device->scanning[type] == scanning)
1068 device->scanning[type] = scanning;
1071 __connman_technology_scan_started(device);
1073 g_hash_table_foreach(device->networks,
1074 mark_network_unavailable, NULL);
1079 __connman_device_cleanup_networks(device);
1081 __connman_technology_scan_stopped(device, type);
1083 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
1085 #if defined TIZEN_EXT_WIFI_MESH
1086 if (type == CONNMAN_SERVICE_TYPE_MESH)
1087 __connman_mesh_auto_connect();
1094 * connman_device_set_string:
1095 * @device: device structure
1096 * @key: unique identifier
1097 * @value: string value
1099 * Set string value for specific key
1101 int connman_device_set_string(struct connman_device *device,
1102 const char *key, const char *value)
1104 DBG("device %p key %s value %s", device, key, value);
1106 if (g_str_equal(key, "Address")) {
1108 if (device->address)
1112 g_free(device->address);
1113 device->address = g_strdup(value);
1114 } else if (g_str_equal(key, "Name")) {
1115 g_free(device->name);
1116 device->name = g_strdup(value);
1117 } else if (g_str_equal(key, "Node")) {
1118 g_free(device->node);
1119 device->node = g_strdup(value);
1120 } else if (g_str_equal(key, "Path")) {
1121 g_free(device->path);
1122 device->path = g_strdup(value);
1131 * connman_device_get_string:
1132 * @device: device structure
1133 * @key: unique identifier
1135 * Get string value for specific key
1137 const char *connman_device_get_string(struct connman_device *device,
1140 #if defined TIZEN_EXT
1141 if (!simplified_log)
1143 DBG("device %p key %s", device, key);
1145 if (g_str_equal(key, "Address"))
1146 return device->address;
1147 else if (g_str_equal(key, "Name"))
1148 return device->name;
1149 else if (g_str_equal(key, "Node"))
1150 return device->node;
1151 else if (g_str_equal(key, "Interface"))
1152 return device->interface;
1153 else if (g_str_equal(key, "Path"))
1154 return device->path;
1160 * connman_device_add_network:
1161 * @device: device structure
1162 * @network: network structure
1164 * Add new network to the device
1166 int connman_device_add_network(struct connman_device *device,
1167 struct connman_network *network)
1169 const char *identifier = connman_network_get_identifier(network);
1170 #if defined TIZEN_EXT
1171 if (!simplified_log)
1173 DBG("device %p network %p", device, network);
1178 connman_network_ref(network);
1180 __connman_network_set_device(network, device);
1182 g_hash_table_replace(device->networks, g_strdup(identifier),
1189 * connman_device_get_network:
1190 * @device: device structure
1191 * @identifier: network identifier
1193 * Get network for given identifier
1195 struct connman_network *connman_device_get_network(struct connman_device *device,
1196 const char *identifier)
1198 #if defined TIZEN_EXT
1199 if (!simplified_log)
1201 DBG("device %p identifier %s", device, identifier);
1203 return g_hash_table_lookup(device->networks, identifier);
1206 #if defined TIZEN_EXT
1207 struct connman_network *connman_device_get_default_network(
1208 struct connman_device *device)
1210 return device->network;
1213 void connman_device_set_pending_reply(struct connman_device *device,
1216 device->pending_reply = dbus_message_ref(msg);
1219 void connman_device_send_connected_signal(struct connman_device *device,
1222 enum connman_service_type type;
1227 type = __connman_device_get_service_type(device);
1228 device_send_changed(device->interface, type, "Connected", connected);
1231 void connman_device_set_max_scan_ssids(struct connman_device *device,
1234 device->max_scan_ssids = max_scan_ssids;
1237 int connman_device_get_max_scan_ssids(struct connman_device *device)
1239 return device->max_scan_ssids;
1242 void connman_device_set_wifi_5ghz_supported(struct connman_device *device,
1243 bool is_5_0_ghz_supported)
1245 device->is_5_0_ghz_supported = is_5_0_ghz_supported;
1248 bool connman_device_get_wifi_5ghz_supported(struct connman_device *device)
1250 return device->is_5_0_ghz_supported;
1255 * connman_device_remove_network:
1256 * @device: device structure
1257 * @identifier: network identifier
1259 * Remove network for given identifier
1261 int connman_device_remove_network(struct connman_device *device,
1262 struct connman_network *network)
1264 const char *identifier;
1266 DBG("device %p network %p", device, network);
1271 identifier = connman_network_get_identifier(network);
1272 g_hash_table_remove(device->networks, identifier);
1277 void __connman_device_set_network(struct connman_device *device,
1278 struct connman_network *network)
1285 if (device->network == network)
1289 name = connman_network_get_string(network, "Name");
1290 g_free(device->last_network);
1291 device->last_network = g_strdup(name);
1293 device->network = network;
1295 g_free(device->last_network);
1296 device->last_network = NULL;
1298 device->network = NULL;
1302 static bool match_driver(struct connman_device *device,
1303 struct connman_device_driver *driver)
1305 if (device->type == driver->type ||
1306 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1313 * connman_device_register:
1314 * @device: device structure
1316 * Register device with the system
1318 int connman_device_register(struct connman_device *device)
1322 DBG("device %p name %s", device, device->name);
1327 for (list = driver_list; list; list = list->next) {
1328 struct connman_device_driver *driver = list->data;
1330 if (!match_driver(device, driver))
1333 DBG("driver %p name %s", driver, driver->name);
1335 if (driver->probe(device) == 0) {
1336 device->driver = driver;
1341 if (!device->driver)
1344 return __connman_technology_add_device(device);
1348 * connman_device_unregister:
1349 * @device: device structure
1351 * Unregister device with the system
1353 void connman_device_unregister(struct connman_device *device)
1355 DBG("device %p name %s", device, device->name);
1357 if (!device->driver)
1360 remove_device(device);
1364 * connman_device_get_data:
1365 * @device: device structure
1367 * Get private device data pointer
1369 void *connman_device_get_data(struct connman_device *device)
1371 return device->driver_data;
1375 * connman_device_set_data:
1376 * @device: device structure
1377 * @data: data pointer
1379 * Set private device data pointer
1381 void connman_device_set_data(struct connman_device *device, void *data)
1383 device->driver_data = data;
1386 struct connman_device *__connman_device_find_device(
1387 enum connman_service_type type)
1391 for (list = device_list; list; list = list->next) {
1392 struct connman_device *device = list->data;
1393 enum connman_service_type service_type =
1394 __connman_device_get_service_type(device);
1396 if (service_type != type)
1405 struct connman_device *connman_device_find_by_index(int index)
1409 for (list = device_list; list; list = list->next) {
1410 struct connman_device *device = list->data;
1411 if (device->index == index)
1419 * connman_device_set_regdom
1420 * @device: device structure
1421 * @alpha2: string representing regulatory domain
1423 * Set regulatory domain on device basis
1425 int connman_device_set_regdom(struct connman_device *device,
1428 if (!device->driver || !device->driver->set_regdom)
1431 if (!device->powered)
1434 return device->driver->set_regdom(device, alpha2);
1438 * connman_device_regdom_notify
1439 * @device: device structure
1440 * @alpha2: string representing regulatory domain
1442 * Notify on setting regulatory domain on device basis
1444 void connman_device_regdom_notify(struct connman_device *device,
1445 int result, const char *alpha2)
1447 __connman_technology_notify_regdom_by_device(device, result, alpha2);
1450 #if defined TIZEN_EXT
1451 static int device_specific_scan(enum connman_service_type type,
1452 struct connman_device *device,
1453 int scan_type, GSList *specific_scan_list)
1455 if (!device->driver || !device->driver->specific_scan)
1458 if (!device->powered)
1461 return device->driver->specific_scan(type, device, scan_type,
1462 specific_scan_list, NULL);
1465 int __connman_device_request_specific_scan(enum connman_service_type type,
1466 const char *ifname, int scan_type, GSList *specific_scan_list)
1468 bool success = false;
1469 int last_err = -ENOSYS;
1474 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1475 case CONNMAN_SERVICE_TYPE_SYSTEM:
1476 case CONNMAN_SERVICE_TYPE_ETHERNET:
1477 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1478 case CONNMAN_SERVICE_TYPE_CELLULAR:
1479 case CONNMAN_SERVICE_TYPE_GPS:
1480 case CONNMAN_SERVICE_TYPE_VPN:
1481 case CONNMAN_SERVICE_TYPE_GADGET:
1483 case CONNMAN_SERVICE_TYPE_WIFI:
1484 case CONNMAN_SERVICE_TYPE_P2P:
1485 #if defined TIZEN_EXT_WIFI_MESH
1486 case CONNMAN_SERVICE_TYPE_MESH:
1491 for (list = device_list; list; list = list->next) {
1492 struct connman_device *device = list->data;
1493 enum connman_service_type service_type =
1494 __connman_device_get_service_type(device);
1496 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
1497 if (type == CONNMAN_SERVICE_TYPE_P2P) {
1498 if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
1500 } else if (service_type != type)
1504 if (ifname && g_strcmp0(device->interface, ifname) != 0)
1507 err = device_specific_scan(type, device, scan_type, specific_scan_list);
1508 if (err == 0 || err == -EINPROGRESS) {
1512 DBG("device %p err %d", device, err);
1522 int connman_device_request_device_scan(enum connman_service_type type,
1523 const char * ifname, bool force_full_scan)
1525 bool success = false;
1526 int last_err = -ENOSYS;
1531 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1532 case CONNMAN_SERVICE_TYPE_SYSTEM:
1533 case CONNMAN_SERVICE_TYPE_ETHERNET:
1534 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1535 case CONNMAN_SERVICE_TYPE_CELLULAR:
1536 case CONNMAN_SERVICE_TYPE_GPS:
1537 case CONNMAN_SERVICE_TYPE_VPN:
1538 case CONNMAN_SERVICE_TYPE_GADGET:
1540 case CONNMAN_SERVICE_TYPE_WIFI:
1541 case CONNMAN_SERVICE_TYPE_P2P:
1542 #if defined TIZEN_EXT_WIFI_MESH
1543 case CONNMAN_SERVICE_TYPE_MESH:
1548 for (list = device_list; list; list = list->next) {
1549 struct connman_device *device = list->data;
1551 if (!device_has_service_type(device, type))
1554 if (g_strcmp0(device->interface, ifname) != 0)
1557 err = device_scan(type, device, force_full_scan);
1559 if (err == 0 || err == -EINPROGRESS) {
1563 DBG("device %p err %d", device, err);
1574 #if defined TIZEN_EXT_WIFI_MESH
1575 static int device_abort_scan(enum connman_service_type type,
1576 struct connman_device *device)
1578 if (!device->driver || !device->driver->scan)
1581 if (!device->powered)
1584 return device->driver->abort_scan(type, device);
1587 int __connman_device_abort_scan(enum connman_service_type type)
1592 if (type != CONNMAN_SERVICE_TYPE_MESH)
1595 for (list = device_list; list; list = list->next) {
1596 struct connman_device *device = list->data;
1597 enum connman_service_type service_type =
1598 __connman_device_get_service_type(device);
1600 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
1601 if (type == CONNMAN_SERVICE_TYPE_MESH)
1602 if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
1605 if (!device->scanning) {
1610 err = device_abort_scan(type, device);
1616 static int device_mesh_specific_scan(enum connman_service_type type,
1617 struct connman_device *device, const char *name,
1620 if (!device->driver || !device->driver->mesh_specific_scan)
1623 if (!device->powered)
1626 return device->driver->mesh_specific_scan(type, device, name, freq, NULL);
1629 int __connman_device_request_mesh_specific_scan(enum connman_service_type type,
1633 bool success = false;
1634 int last_err = -ENOSYS;
1638 if (type != CONNMAN_SERVICE_TYPE_MESH)
1641 for (list = device_list; list; list = list->next) {
1642 struct connman_device *device = list->data;
1643 enum connman_service_type service_type =
1644 __connman_device_get_service_type(device);
1646 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
1647 if (type == CONNMAN_SERVICE_TYPE_MESH)
1648 if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
1652 err = device_mesh_specific_scan(type, device, name, freq);
1653 if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
1657 DBG("device %p err %d", device, err);
1666 #endif /* TIZEN_EXT_WIFI_MESH */
1669 static int connman_device_request_scan(enum connman_service_type type,
1670 bool force_full_scan)
1672 bool success = false;
1673 int last_err = -ENOSYS;
1678 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1679 case CONNMAN_SERVICE_TYPE_SYSTEM:
1680 case CONNMAN_SERVICE_TYPE_ETHERNET:
1681 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1682 case CONNMAN_SERVICE_TYPE_CELLULAR:
1683 case CONNMAN_SERVICE_TYPE_GPS:
1684 case CONNMAN_SERVICE_TYPE_VPN:
1685 case CONNMAN_SERVICE_TYPE_GADGET:
1687 case CONNMAN_SERVICE_TYPE_WIFI:
1688 case CONNMAN_SERVICE_TYPE_P2P:
1689 #if defined TIZEN_EXT_WIFI_MESH
1690 case CONNMAN_SERVICE_TYPE_MESH:
1695 for (list = device_list; list; list = list->next) {
1696 struct connman_device *device = list->data;
1698 if (!device_has_service_type(device, type))
1701 err = device_scan(type, device, force_full_scan);
1702 #if defined TIZEN_EXT
1703 /* When Scan is already in progress then return Error so that
1704 * wifi-manager can block the scan-done signal to be sent to
1705 * application and start requested scan after scan already in progress
1706 * is completed then notify to application about the scan event */
1707 if (err == 0 || err == -EINPROGRESS) {
1709 if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
1714 DBG("device %p err %d", device, err);
1724 int __connman_device_request_scan(enum connman_service_type type)
1726 return connman_device_request_scan(type, false);
1729 int __connman_device_request_scan_full(enum connman_service_type type)
1731 return connman_device_request_scan(type, true);
1734 int __connman_device_request_hidden_scan(struct connman_device *device,
1735 const char *ssid, unsigned int ssid_len,
1736 const char *identity, const char *passphrase,
1737 const char *security, void *user_data)
1739 struct connman_device_scan_params params;
1741 DBG("device %p", device);
1743 if (!device || !device->driver ||
1744 !device->driver->scan)
1747 params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
1749 params.ssid_len = ssid_len;
1750 params.identity = identity;
1751 params.passphrase = passphrase;
1752 params.security = security;
1753 params.user_data = user_data;
1755 return device->driver->scan(device, ¶ms);
1758 void __connman_device_stop_scan(enum connman_service_type type)
1762 for (list = device_list; list; list = list->next) {
1763 struct connman_device *device = list->data;
1765 if (!device_has_service_type(device, type))
1768 if (device->driver && device->driver->stop_scan)
1769 device->driver->stop_scan(type, device);
1773 #if defined TIZEN_EXT
1774 #define WIFI_MAC "/opt/etc/.mac.info"
1775 #define MAC_ADDR_LEN 18
1777 char *_get_wifi_addr(void)
1781 char wifi_mac[MAC_ADDR_LEN + 1];
1784 fp = fopen(WIFI_MAC, "r");
1786 connman_error("[%s] not present", WIFI_MAC);
1790 rv = fgets(wifi_mac, MAC_ADDR_LEN, fp);
1792 connman_error("Failed to get wifi mac address");
1797 str = g_try_malloc0(MAC_ADDR_LEN);
1799 connman_error("memory allocation failed");
1804 snprintf(str, MAC_ADDR_LEN, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
1805 g_ascii_tolower(wifi_mac[0]), g_ascii_tolower(wifi_mac[1]),
1806 g_ascii_tolower(wifi_mac[3]), g_ascii_tolower(wifi_mac[4]),
1807 g_ascii_tolower(wifi_mac[6]), g_ascii_tolower(wifi_mac[7]),
1808 g_ascii_tolower(wifi_mac[9]), g_ascii_tolower(wifi_mac[10]),
1809 g_ascii_tolower(wifi_mac[12]), g_ascii_tolower(wifi_mac[13]),
1810 g_ascii_tolower(wifi_mac[15]), g_ascii_tolower(wifi_mac[16]));
1815 char *_get_wifi_ident(void)
1819 char wifi_mac[MAC_ADDR_LEN + 1];
1822 fp = fopen(WIFI_MAC, "r");
1824 connman_error("[%s] not present", WIFI_MAC);
1828 rv = fgets(wifi_mac, MAC_ADDR_LEN, fp);
1830 connman_error("Failed to get wifi mac address");
1835 str = g_try_malloc0(MAC_ADDR_LEN);
1837 connman_error("memory allocation failed");
1842 snprintf(str, MAC_ADDR_LEN, "%c%c%c%c%c%c%c%c%c%c%c%c",
1843 g_ascii_tolower(wifi_mac[0]), g_ascii_tolower(wifi_mac[1]),
1844 g_ascii_tolower(wifi_mac[3]), g_ascii_tolower(wifi_mac[4]),
1845 g_ascii_tolower(wifi_mac[6]), g_ascii_tolower(wifi_mac[7]),
1846 g_ascii_tolower(wifi_mac[9]), g_ascii_tolower(wifi_mac[10]),
1847 g_ascii_tolower(wifi_mac[12]), g_ascii_tolower(wifi_mac[13]),
1848 g_ascii_tolower(wifi_mac[15]), g_ascii_tolower(wifi_mac[16]));
1854 #if defined TIZEN_EXT
1855 char *index2ident(int index, const char *prefix)
1857 static char *index2ident(int index, const char *prefix)
1861 struct ether_addr eth;
1868 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1872 memset(&ifr, 0, sizeof(ifr));
1873 ifr.ifr_ifindex = index;
1875 err = ioctl(sk, SIOCGIFNAME, &ifr);
1878 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1885 len = prefix ? strlen(prefix) + 18 : 18;
1887 str = g_malloc(len);
1891 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1892 snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
1893 prefix ? prefix : "",
1894 eth.ether_addr_octet[0],
1895 eth.ether_addr_octet[1],
1896 eth.ether_addr_octet[2],
1897 eth.ether_addr_octet[3],
1898 eth.ether_addr_octet[4],
1899 eth.ether_addr_octet[5]);
1904 #if defined TIZEN_EXT
1905 char *index2addr(int index)
1907 static char *index2addr(int index)
1911 struct ether_addr eth;
1918 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1922 memset(&ifr, 0, sizeof(ifr));
1923 ifr.ifr_ifindex = index;
1925 err = ioctl(sk, SIOCGIFNAME, &ifr);
1928 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1939 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1940 snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1941 eth.ether_addr_octet[0],
1942 eth.ether_addr_octet[1],
1943 eth.ether_addr_octet[2],
1944 eth.ether_addr_octet[3],
1945 eth.ether_addr_octet[4],
1946 eth.ether_addr_octet[5]);
1951 struct connman_device *connman_device_create_from_index(int index)
1953 enum connman_device_type type;
1954 struct connman_device *device;
1955 char *devname, *ident = NULL;
1956 char *addr = NULL, *name = NULL;
1961 devname = connman_inet_ifname(index);
1965 if (__connman_device_isfiltered(devname)) {
1966 connman_info("Ignoring interface %s (filtered)", devname);
1971 type = __connman_rtnl_get_device_type(index);
1974 case CONNMAN_DEVICE_TYPE_UNKNOWN:
1975 connman_info("Ignoring interface %s (type unknown)", devname);
1978 case CONNMAN_DEVICE_TYPE_ETHERNET:
1979 case CONNMAN_DEVICE_TYPE_GADGET:
1980 case CONNMAN_DEVICE_TYPE_WIFI:
1981 #if defined TIZEN_EXT
1982 if (type == CONNMAN_DEVICE_TYPE_WIFI)
1983 name = _get_wifi_ident();
1986 name = index2ident(index, "");
1987 #if defined TIZEN_EXT
1988 if (type == CONNMAN_DEVICE_TYPE_WIFI)
1989 addr = _get_wifi_addr();
1992 addr = index2addr(index);
1994 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
1995 case CONNMAN_DEVICE_TYPE_CELLULAR:
1996 case CONNMAN_DEVICE_TYPE_GPS:
1997 case CONNMAN_DEVICE_TYPE_VENDOR:
1998 name = g_strdup(devname);
2002 device = connman_device_create(name, type);
2007 case CONNMAN_DEVICE_TYPE_UNKNOWN:
2008 case CONNMAN_DEVICE_TYPE_VENDOR:
2009 case CONNMAN_DEVICE_TYPE_GPS:
2011 case CONNMAN_DEVICE_TYPE_ETHERNET:
2012 case CONNMAN_DEVICE_TYPE_GADGET:
2013 ident = index2ident(index, NULL);
2015 case CONNMAN_DEVICE_TYPE_WIFI:
2016 #if defined TIZEN_EXT
2017 ident = _get_wifi_ident();
2020 ident = index2ident(index, NULL);
2022 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
2024 case CONNMAN_DEVICE_TYPE_CELLULAR:
2025 ident = index2ident(index, NULL);
2029 connman_device_set_index(device, index);
2030 connman_device_set_interface(device, devname);
2031 #if defined TIZEN_EXT
2032 connman_device_load_last_connected(device);
2033 connman_device_load_last_user_selection(device);
2037 connman_device_set_ident(device, ident);
2041 connman_device_set_string(device, "Address", addr);
2051 bool __connman_device_isfiltered(const char *devname)
2054 char **blacklisted_interfaces;
2060 for (pattern = device_filter, match = false; *pattern; pattern++) {
2061 if (g_pattern_match_simple(*pattern, devname)) {
2068 DBG("ignoring device %s (match)", devname);
2073 if (g_pattern_match_simple("dummy*", devname)) {
2074 DBG("ignoring dummy networking devices");
2078 if (!nodevice_filter)
2081 for (pattern = nodevice_filter; *pattern; pattern++) {
2082 if (g_pattern_match_simple(*pattern, devname)) {
2083 DBG("ignoring device %s (no match)", devname);
2089 if (__connman_inet_isrootnfs_device(devname)) {
2090 DBG("ignoring device %s (rootnfs)", devname);
2094 blacklisted_interfaces =
2095 connman_setting_get_string_list("NetworkInterfaceBlacklist");
2096 if (!blacklisted_interfaces)
2099 for (pattern = blacklisted_interfaces; *pattern; pattern++) {
2100 if (g_str_has_prefix(devname, *pattern)) {
2101 DBG("ignoring device %s (blacklist)", devname);
2109 static void cleanup_devices(void)
2112 * Check what interfaces are currently up and if connman is
2113 * suppose to handle the interface, then cleanup the mess
2114 * related to that interface. There might be weird routes etc
2115 * that are related to that interface and that might confuse
2116 * connmand. So in this case we just turn the interface down
2117 * so that kernel removes routes/addresses automatically and
2118 * then proceed the startup.
2120 * Note that this cleanup must be done before rtnl/detect code
2121 * has activated interface watches.
2127 interfaces = __connman_inet_get_running_interfaces();
2132 for (i = 0; interfaces[i]; i++) {
2135 struct sockaddr_in sin_addr, sin_mask;
2137 filtered = __connman_device_isfiltered(interfaces[i]);
2141 index = connman_inet_ifindex(interfaces[i]);
2145 if (!__connman_inet_get_address_netmask(index, &sin_addr,
2147 char *address = g_strdup(inet_ntoa(sin_addr.sin_addr));
2148 char *netmask = g_strdup(inet_ntoa(sin_mask.sin_addr));
2150 if (__connman_config_address_provisioned(address,
2152 DBG("Skip %s which is already provisioned "
2153 "with %s/%s", interfaces[i], address,
2164 DBG("cleaning up %s index %d", interfaces[i], index);
2166 #if defined TIZEN_EXT
2167 if (strcmp(interfaces[i], "wlan0") != 0)
2169 connman_inet_ifdown(index);
2172 * ConnMan will turn the interface UP automatically so
2173 * no need to do it here.
2177 g_strfreev(interfaces);
2180 int __connman_device_init(const char *device, const char *nodevice)
2184 #if defined TIZEN_EXT
2185 connection = connman_dbus_get_connection();
2189 device_filter = g_strsplit(device, ",", -1);
2192 nodevice_filter = g_strsplit(nodevice, ",", -1);
2199 void __connman_device_cleanup(void)
2203 g_strfreev(nodevice_filter);
2204 g_strfreev(device_filter);
2206 #if defined TIZEN_EXT
2207 dbus_connection_unref(connection);
2212 void connman_device_mac_policy_notify(struct connman_device *device,
2213 int result, unsigned int policy)
2215 device->mac_policy = policy;
2216 __connman_technology_notify_mac_policy_by_device(device, result, policy);
2219 int connman_device_set_mac_policy(struct connman_device *device,
2220 unsigned int policy)
2224 if (!device || !device->driver || !device->driver->set_mac_policy)
2227 device->mac_policy = policy;
2228 err = device->driver->set_mac_policy(device, policy);
2232 unsigned int connman_device_get_mac_policy(struct connman_device *device)
2234 return device->mac_policy;
2237 void connman_device_preassoc_mac_policy_notify(struct connman_device *device,
2238 int result, unsigned int policy)
2240 device->preassoc_mac_policy = policy;
2241 __connman_technology_notify_preassoc_mac_policy_by_device(device, result, policy);
2244 int connman_device_set_preassoc_mac_policy(struct connman_device *device,
2245 unsigned int policy)
2249 if (!device || !device->driver || !device->driver->set_preassoc_mac_policy)
2252 device->preassoc_mac_policy = policy;
2253 err = device->driver->set_preassoc_mac_policy(device, policy);
2257 unsigned int connman_device_get_preassoc_mac_policy(struct connman_device *device)
2259 return device->preassoc_mac_policy;
2262 void connman_device_random_mac_lifetime_notify(struct connman_device *device,
2263 int result, unsigned int lifetime)
2265 device->random_mac_lifetime = lifetime;
2266 __connman_technology_notify_random_mac_lifetime_by_device(device, result, lifetime);
2269 int connman_device_set_random_mac_lifetime(struct connman_device *device,
2270 unsigned int lifetime)
2274 if (!device || !device->driver || !device->driver->set_random_mac_lifetime)
2277 device->random_mac_lifetime = lifetime;
2278 err = device->driver->set_random_mac_lifetime(device, lifetime);
2282 unsigned int connman_device_get_random_mac_lifetime(struct connman_device *device)
2284 return device->random_mac_lifetime;