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);
270 if (device->type == CONNMAN_DEVICE_TYPE_WIFI) {
271 device->driver->set_mac_policy(device, device->mac_policy);
272 device->driver->set_preassoc_mac_policy(device, device->preassoc_mac_policy);
273 device->driver->set_random_mac_lifetime(device, device->random_mac_lifetime);
275 #endif /* TIZEN_EXT */
279 * if err == -EINPROGRESS, then the DBus call to the respective daemon
280 * was successful. We set a 10 sec timeout so if the daemon never
281 * returns a reply, we would reset the pending request.
283 if (err == -EINPROGRESS)
284 device->pending_timeout = g_timeout_add_seconds(10,
285 device_pending_reset, device);
290 int __connman_device_disable(struct connman_device *device)
294 DBG("device %p", device);
296 /* Ongoing power enable request */
297 if (device->powered_pending == PENDING_ENABLE)
300 if (device->powered_pending == PENDING_DISABLE)
303 if (device->powered_pending == PENDING_NONE && !device->powered)
306 device->powered_pending = PENDING_DISABLE;
308 if (device->network) {
309 struct connman_service *service =
310 connman_service_lookup_from_network(device->network);
313 __connman_service_disconnect(service);
315 connman_network_set_connected(device->network, false);
318 if (!device->driver || !device->driver->disable)
321 err = device->driver->disable(device);
322 if (err == 0 || err == -EALREADY) {
323 connman_device_set_powered(device, false);
327 if (err == -EINPROGRESS)
328 device->pending_timeout = g_timeout_add_seconds(4,
329 device_pending_reset, device);
334 static void probe_driver(struct connman_device_driver *driver)
338 DBG("driver %p name %s", driver, driver->name);
340 for (list = device_list; list; list = list->next) {
341 struct connman_device *device = list->data;
346 if (driver->type != device->type)
349 if (driver->probe(device) < 0)
352 device->driver = driver;
354 __connman_technology_add_device(device);
358 static void remove_device(struct connman_device *device)
360 DBG("device %p", device);
362 __connman_device_disable(device);
364 __connman_technology_remove_device(device);
366 if (device->driver->remove)
367 device->driver->remove(device);
369 device->driver = NULL;
372 static void remove_driver(struct connman_device_driver *driver)
376 DBG("driver %p name %s", driver, driver->name);
378 for (list = device_list; list; list = list->next) {
379 struct connman_device *device = list->data;
381 if (device->driver == driver)
382 remove_device(device);
386 bool __connman_device_has_driver(struct connman_device *device)
388 if (!device || !device->driver)
394 static GSList *driver_list = NULL;
396 static gint compare_priority(gconstpointer a, gconstpointer b)
398 const struct connman_device_driver *driver1 = a;
399 const struct connman_device_driver *driver2 = b;
401 return driver2->priority - driver1->priority;
405 * connman_device_driver_register:
406 * @driver: device driver definition
408 * Register a new device driver
410 * Returns: %0 on success
412 int connman_device_driver_register(struct connman_device_driver *driver)
414 DBG("driver %p name %s", driver, driver->name);
416 driver_list = g_slist_insert_sorted(driver_list, driver,
418 probe_driver(driver);
424 * connman_device_driver_unregister:
425 * @driver: device driver definition
427 * Remove a previously registered device driver
429 void connman_device_driver_unregister(struct connman_device_driver *driver)
431 DBG("driver %p name %s", driver, driver->name);
433 driver_list = g_slist_remove(driver_list, driver);
435 remove_driver(driver);
438 static void free_network(gpointer data)
440 struct connman_network *network = data;
442 DBG("network %p", network);
444 __connman_network_set_device(network, NULL);
446 connman_network_unref(network);
449 static void device_destruct(struct connman_device *device)
451 DBG("device %p name %s", device, device->name);
453 clear_pending_trigger(device);
455 g_hash_table_destroy(device->networks);
456 device->networks = NULL;
458 g_free(device->ident);
459 g_free(device->node);
460 g_free(device->name);
461 g_free(device->address);
462 g_free(device->interface);
463 g_free(device->path);
465 g_free(device->last_network);
467 #if defined TIZEN_EXT
468 g_free(device->last_user_selection_ident);
469 g_free(device->last_connected_ident);
475 #if defined TIZEN_EXT
476 static void device_send_changed(const char *ifname, enum connman_service_type type,
477 const char *key, bool state)
480 DBusMessageIter iter, dict;
481 dbus_bool_t value = state;
482 const char *tech_path = connman_techonology_get_path(type);
484 if (!tech_path || !ifname)
487 DBG("%s %s %s", ifname, key, state ? "TRUE" : "FALSE");
489 signal = dbus_message_new_signal(tech_path,
490 CONNMAN_TECHNOLOGY_INTERFACE, "DeviceChanged");
494 dbus_message_iter_init_append(signal, &iter);
496 connman_dbus_dict_open(&iter, &dict);
497 connman_dbus_dict_append_basic(&dict, "Ifname",
500 connman_dbus_dict_append_basic(&dict, key,
503 connman_dbus_dict_close(&iter, &dict);
505 dbus_connection_send(connection, signal, NULL);
506 dbus_message_unref(signal);
509 static void device_send_reply(struct connman_device *device)
511 if (device->pending_reply) {
512 g_dbus_send_reply(connection,
513 device->pending_reply, DBUS_TYPE_INVALID);
514 dbus_message_unref(device->pending_reply);
515 device->pending_reply = NULL;
521 * connman_device_create:
522 * @node: device node name (for example an address)
525 * Allocate a new device of given #type and assign the #node name to it.
527 * Returns: a newly-allocated #connman_device structure
529 struct connman_device *connman_device_create(const char *node,
530 enum connman_device_type type)
532 struct connman_device *device;
534 DBG("node %s type %d", node, type);
536 device = g_try_new0(struct connman_device, 1);
540 DBG("device %p", device);
542 device->refcount = 1;
545 device->name = g_strdup(type2description(device->type));
547 device->networks = g_hash_table_new_full(g_str_hash, g_str_equal,
548 g_free, free_network);
550 device_list = g_slist_prepend(device_list, device);
556 * connman_device_ref:
557 * @device: device structure
559 * Increase reference counter of device
561 struct connman_device *connman_device_ref_debug(struct connman_device *device,
562 const char *file, int line, const char *caller)
564 DBG("%p ref %d by %s:%d:%s()", device, device->refcount + 1,
567 __sync_fetch_and_add(&device->refcount, 1);
573 * connman_device_unref:
574 * @device: device structure
576 * Decrease reference counter of device
578 void connman_device_unref_debug(struct connman_device *device,
579 const char *file, int line, const char *caller)
581 DBG("%p ref %d by %s:%d:%s()", device, device->refcount - 1,
584 if (__sync_fetch_and_sub(&device->refcount, 1) != 1)
587 if (device->driver) {
588 device->driver->remove(device);
589 device->driver = NULL;
592 device_list = g_slist_remove(device_list, device);
594 device_destruct(device);
597 const char *__connman_device_get_type(struct connman_device *device)
599 return type2string(device->type);
603 * connman_device_get_type:
604 * @device: device structure
608 enum connman_device_type connman_device_get_type(struct connman_device *device)
614 * connman_device_set_index:
615 * @device: device structure
616 * @index: index number
618 * Set index number of device
620 void connman_device_set_index(struct connman_device *device, int index)
622 device->index = index;
626 * connman_device_get_index:
627 * @device: device structure
629 * Get index number of device
631 int connman_device_get_index(struct connman_device *device)
633 return device->index;
637 * connman_device_set_interface:
638 * @device: device structure
639 * @interface: interface name
641 * Set interface name of device
643 void connman_device_set_interface(struct connman_device *device,
644 const char *interface)
646 g_free(device->interface);
647 device->interface = g_strdup(interface);
650 const char *str = type2description(device->type);
651 if (str && device->interface)
652 device->name = g_strdup_printf("%s (%s)", str,
658 * connman_device_set_ident:
659 * @device: device structure
660 * @ident: unique identifier
662 * Set unique identifier of device
664 void connman_device_set_ident(struct connman_device *device,
672 g_free(device->ident);
673 device->ident = g_strdup(ident);
676 const char *connman_device_get_ident(struct connman_device *device)
678 return device->ident;
682 * connman_device_set_powered:
683 * @device: device structure
684 * @powered: powered state
686 * Change power state of device
688 int connman_device_set_powered(struct connman_device *device,
691 struct connman_device_scan_params params;
692 enum connman_service_type type;
695 DBG("device %p powered %d", device, powered);
697 if (device->powered == powered)
700 #if defined TIZEN_EXT
701 device_send_reply(device);
704 clear_pending_trigger(device);
706 device->powered_pending = PENDING_NONE;
708 device->powered = powered;
710 type = __connman_device_get_service_type(device);
712 #if defined TIZEN_EXT
713 device_send_changed(device->interface, type, "Powered", powered);
714 technology_save_device(device);
717 if (!device->powered) {
718 __connman_technology_disabled(type);
722 __connman_technology_enabled(type);
724 for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
725 device->scanning[i] = false;
727 if (device->driver && device->driver->scan) {
728 memset(¶ms, 0, sizeof(params));
729 params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
731 device->driver->scan(device, ¶ms);
737 bool connman_device_get_powered(struct connman_device *device)
739 return device->powered;
742 static int device_scan(enum connman_service_type type,
743 struct connman_device *device,
744 bool force_full_scan)
746 struct connman_device_scan_params params;
748 if (!device->driver || !device->driver->scan)
751 if (!device->powered)
754 memset(¶ms, 0, sizeof(params));
756 params.force_full_scan = force_full_scan;
758 return device->driver->scan(device, ¶ms);
761 int __connman_device_disconnect(struct connman_device *device)
766 DBG("device %p", device);
768 g_hash_table_iter_init(&iter, device->networks);
770 while (g_hash_table_iter_next(&iter, &key, &value)) {
771 struct connman_network *network = value;
773 if (connman_network_get_connecting(network)) {
775 * Skip network in the process of connecting.
776 * This is a workaround for WiFi networks serviced
777 * by the supplicant plugin that hold a reference
778 * to the network. If we disconnect the network
779 * here then the referenced object will not be
780 * registered and usage (like launching DHCP client)
781 * will fail. There is nothing to be gained by
782 * removing the network here anyway.
784 connman_warn("Skipping disconnect of %s, network is connecting.",
785 connman_network_get_identifier(network));
789 __connman_network_disconnect(network);
795 int connman_device_reconnect_service(struct connman_device *device)
797 DBG("device %p", device);
799 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
804 #if defined TIZEN_EXT
805 bool connman_device_set_last_user_selection_time(struct connman_device *device,
808 if (device->last_user_selection_time != time) {
809 device->last_user_selection_time = time;
816 time_t connman_device_get_last_user_selection_time(struct connman_device *device)
818 return device->last_user_selection_time;
821 bool connman_device_set_last_user_selection_ident(struct connman_device *device,
824 if (g_strcmp0(device->last_user_selection_ident, ident) != 0) {
825 g_free(device->last_user_selection_ident);
826 device->last_user_selection_ident = g_strdup(ident);
834 const char *connman_device_get_last_user_selection_ident(struct connman_device *device)
836 return device->last_user_selection_ident;
839 bool connman_device_set_last_connected_ident(struct connman_device *device,
842 if (g_strcmp0(device->last_connected_ident, ident) != 0) {
843 g_free(device->last_connected_ident);
844 device->last_connected_ident = g_strdup(ident);
852 const char *connman_device_get_last_connected_ident(struct connman_device *device)
854 return device->last_connected_ident;
857 void connman_device_save_last_user_selection(struct connman_device *device)
861 gchar *selection_str;
863 keyfile = __connman_storage_load_ins();
865 selection_str = g_strdup_printf("%s:%ld",
866 device->last_user_selection_ident, device->last_user_selection_time);
869 keyfile = g_key_file_new();
871 g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str);
872 DBG("%s", selection_str);
873 __connman_storage_save_ins(keyfile);
876 get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL);
877 if (!get_str || g_strcmp0(get_str, selection_str) != 0) {
878 g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str);
879 DBG("%s -> %s", get_str, selection_str);
880 __connman_storage_save_ins(keyfile);
886 g_free(selection_str);
887 g_key_file_free(keyfile);
890 void connman_device_load_last_user_selection(struct connman_device *device)
894 char **selection_str;
896 keyfile = __connman_storage_load_ins();
900 get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL);
902 selection_str = g_strsplit(get_str, ":", 0);
906 time_t last_user_selection_time;
908 /* Only events that occur within 8 hours are counted. */
909 ref_time = time(NULL);
910 timeinfo = localtime(&ref_time);
911 timeinfo->tm_hour -= 8;
912 ref_time = mktime(timeinfo);
914 last_user_selection_time = strtol(selection_str[1], NULL, 10);
916 if (last_user_selection_time > ref_time) {
917 if (g_strcmp0(selection_str[0], device->last_user_selection_ident) != 0) {
918 g_free(device->last_user_selection_ident);
919 device->last_user_selection_ident = g_strdup(selection_str[0]);
922 device->last_user_selection_time = last_user_selection_time;
924 DBG("%s %ld", device->last_user_selection_ident, device->last_user_selection_time);
927 g_strfreev(selection_str);
933 g_key_file_free(keyfile);
936 void connman_device_save_last_connected(struct connman_device *device)
941 if (!device->last_connected_ident)
944 keyfile = __connman_storage_load_ins();
947 keyfile = g_key_file_new();
949 g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident);
950 DBG("%s", device->last_connected_ident);
951 __connman_storage_save_ins(keyfile);
954 get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL);
955 if (!get_str || g_strcmp0(get_str, device->last_connected_ident) != 0) {
956 g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident);
957 DBG("%s -> %s", get_str, device->last_connected_ident);
958 __connman_storage_save_ins(keyfile);
964 g_key_file_free(keyfile);
967 void connman_device_load_last_connected(struct connman_device *device)
972 keyfile = __connman_storage_load_ins();
976 get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL);
978 if (g_strcmp0(get_str, device->last_connected_ident) != 0) {
979 g_free(device->last_connected_ident);
980 device->last_connected_ident = g_strdup(get_str);
983 DBG("%s", device->last_connected_ident);
988 g_key_file_free(keyfile);
992 static void mark_network_available(gpointer key, gpointer value,
995 struct connman_network *network = value;
997 connman_network_set_available(network, true);
1000 static void mark_network_unavailable(gpointer key, gpointer value,
1003 struct connman_network *network = value;
1005 if (connman_network_get_connected(network) ||
1006 connman_network_get_connecting(network))
1009 connman_network_set_available(network, false);
1012 static gboolean remove_unavailable_network(gpointer key, gpointer value,
1015 struct connman_network *network = value;
1017 if (connman_network_get_connected(network) ||
1018 connman_network_get_connecting(network))
1021 if (connman_network_get_available(network))
1027 void __connman_device_cleanup_networks(struct connman_device *device)
1029 g_hash_table_foreach_remove(device->networks,
1030 remove_unavailable_network, NULL);
1033 bool connman_device_get_scanning(struct connman_device *device,
1034 enum connman_service_type type)
1038 if (type != CONNMAN_SERVICE_TYPE_UNKNOWN)
1039 return device->scanning[type];
1041 for (i = 0; i < MAX_CONNMAN_SERVICE_TYPES; i++)
1042 if (device->scanning[i])
1048 void connman_device_reset_scanning(struct connman_device *device)
1050 g_hash_table_foreach(device->networks,
1051 mark_network_available, NULL);
1055 * connman_device_set_scanning:
1056 * @device: device structure
1057 * @scanning: scanning state
1059 * Change scanning state of device
1061 int connman_device_set_scanning(struct connman_device *device,
1062 enum connman_service_type type, bool scanning)
1064 DBG("device %p scanning %d", device, scanning);
1066 if (!device->driver || !device->driver->scan)
1069 if (type == CONNMAN_SERVICE_TYPE_UNKNOWN)
1072 if (device->scanning[type] == scanning)
1075 device->scanning[type] = scanning;
1078 __connman_technology_scan_started(device);
1080 g_hash_table_foreach(device->networks,
1081 mark_network_unavailable, NULL);
1086 __connman_device_cleanup_networks(device);
1088 __connman_technology_scan_stopped(device, type);
1090 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
1092 #if defined TIZEN_EXT_WIFI_MESH
1093 if (type == CONNMAN_SERVICE_TYPE_MESH)
1094 __connman_mesh_auto_connect();
1101 * connman_device_set_string:
1102 * @device: device structure
1103 * @key: unique identifier
1104 * @value: string value
1106 * Set string value for specific key
1108 int connman_device_set_string(struct connman_device *device,
1109 const char *key, const char *value)
1111 DBG("device %p key %s value %s", device, key, value);
1113 if (g_str_equal(key, "Address")) {
1115 if (device->address)
1119 g_free(device->address);
1120 device->address = g_strdup(value);
1121 } else if (g_str_equal(key, "Name")) {
1122 g_free(device->name);
1123 device->name = g_strdup(value);
1124 } else if (g_str_equal(key, "Node")) {
1125 g_free(device->node);
1126 device->node = g_strdup(value);
1127 } else if (g_str_equal(key, "Path")) {
1128 g_free(device->path);
1129 device->path = g_strdup(value);
1138 * connman_device_get_string:
1139 * @device: device structure
1140 * @key: unique identifier
1142 * Get string value for specific key
1144 const char *connman_device_get_string(struct connman_device *device,
1147 #if defined TIZEN_EXT
1148 if (!simplified_log)
1150 DBG("device %p key %s", device, key);
1152 if (g_str_equal(key, "Address"))
1153 return device->address;
1154 else if (g_str_equal(key, "Name"))
1155 return device->name;
1156 else if (g_str_equal(key, "Node"))
1157 return device->node;
1158 else if (g_str_equal(key, "Interface"))
1159 return device->interface;
1160 else if (g_str_equal(key, "Path"))
1161 return device->path;
1167 * connman_device_add_network:
1168 * @device: device structure
1169 * @network: network structure
1171 * Add new network to the device
1173 int connman_device_add_network(struct connman_device *device,
1174 struct connman_network *network)
1176 const char *identifier = connman_network_get_identifier(network);
1177 #if defined TIZEN_EXT
1178 if (!simplified_log)
1180 DBG("device %p network %p", device, network);
1185 connman_network_ref(network);
1187 __connman_network_set_device(network, device);
1189 g_hash_table_replace(device->networks, g_strdup(identifier),
1196 * connman_device_get_network:
1197 * @device: device structure
1198 * @identifier: network identifier
1200 * Get network for given identifier
1202 struct connman_network *connman_device_get_network(struct connman_device *device,
1203 const char *identifier)
1205 #if defined TIZEN_EXT
1206 if (!simplified_log)
1208 DBG("device %p identifier %s", device, identifier);
1210 return g_hash_table_lookup(device->networks, identifier);
1213 #if defined TIZEN_EXT
1214 struct connman_network *connman_device_get_default_network(
1215 struct connman_device *device)
1217 return device->network;
1220 void connman_device_set_pending_reply(struct connman_device *device,
1223 device->pending_reply = dbus_message_ref(msg);
1226 void connman_device_send_connected_signal(struct connman_device *device,
1229 enum connman_service_type type;
1234 type = __connman_device_get_service_type(device);
1235 device_send_changed(device->interface, type, "Connected", connected);
1238 void connman_device_set_max_scan_ssids(struct connman_device *device,
1241 device->max_scan_ssids = max_scan_ssids;
1244 int connman_device_get_max_scan_ssids(struct connman_device *device)
1246 return device->max_scan_ssids;
1249 void connman_device_set_wifi_5ghz_supported(struct connman_device *device,
1250 bool is_5_0_ghz_supported)
1252 device->is_5_0_ghz_supported = is_5_0_ghz_supported;
1255 bool connman_device_get_wifi_5ghz_supported(struct connman_device *device)
1257 return device->is_5_0_ghz_supported;
1262 * connman_device_remove_network:
1263 * @device: device structure
1264 * @identifier: network identifier
1266 * Remove network for given identifier
1268 int connman_device_remove_network(struct connman_device *device,
1269 struct connman_network *network)
1271 const char *identifier;
1273 DBG("device %p network %p", device, network);
1278 identifier = connman_network_get_identifier(network);
1279 g_hash_table_remove(device->networks, identifier);
1284 void __connman_device_set_network(struct connman_device *device,
1285 struct connman_network *network)
1292 if (device->network == network)
1296 name = connman_network_get_string(network, "Name");
1297 g_free(device->last_network);
1298 device->last_network = g_strdup(name);
1300 device->network = network;
1302 g_free(device->last_network);
1303 device->last_network = NULL;
1305 device->network = NULL;
1309 static bool match_driver(struct connman_device *device,
1310 struct connman_device_driver *driver)
1312 if (device->type == driver->type ||
1313 driver->type == CONNMAN_DEVICE_TYPE_UNKNOWN)
1320 * connman_device_register:
1321 * @device: device structure
1323 * Register device with the system
1325 int connman_device_register(struct connman_device *device)
1329 DBG("device %p name %s", device, device->name);
1334 for (list = driver_list; list; list = list->next) {
1335 struct connman_device_driver *driver = list->data;
1337 if (!match_driver(device, driver))
1340 DBG("driver %p name %s", driver, driver->name);
1342 if (driver->probe(device) == 0) {
1343 device->driver = driver;
1348 if (!device->driver)
1351 return __connman_technology_add_device(device);
1355 * connman_device_unregister:
1356 * @device: device structure
1358 * Unregister device with the system
1360 void connman_device_unregister(struct connman_device *device)
1362 DBG("device %p name %s", device, device->name);
1364 if (!device->driver)
1367 remove_device(device);
1371 * connman_device_get_data:
1372 * @device: device structure
1374 * Get private device data pointer
1376 void *connman_device_get_data(struct connman_device *device)
1378 return device->driver_data;
1382 * connman_device_set_data:
1383 * @device: device structure
1384 * @data: data pointer
1386 * Set private device data pointer
1388 void connman_device_set_data(struct connman_device *device, void *data)
1390 device->driver_data = data;
1393 struct connman_device *__connman_device_find_device(
1394 enum connman_service_type type)
1398 for (list = device_list; list; list = list->next) {
1399 struct connman_device *device = list->data;
1400 enum connman_service_type service_type =
1401 __connman_device_get_service_type(device);
1403 if (service_type != type)
1412 struct connman_device *connman_device_find_by_index(int index)
1416 for (list = device_list; list; list = list->next) {
1417 struct connman_device *device = list->data;
1418 if (device->index == index)
1426 * connman_device_set_regdom
1427 * @device: device structure
1428 * @alpha2: string representing regulatory domain
1430 * Set regulatory domain on device basis
1432 int connman_device_set_regdom(struct connman_device *device,
1435 if (!device->driver || !device->driver->set_regdom)
1438 if (!device->powered)
1441 return device->driver->set_regdom(device, alpha2);
1445 * connman_device_regdom_notify
1446 * @device: device structure
1447 * @alpha2: string representing regulatory domain
1449 * Notify on setting regulatory domain on device basis
1451 void connman_device_regdom_notify(struct connman_device *device,
1452 int result, const char *alpha2)
1454 __connman_technology_notify_regdom_by_device(device, result, alpha2);
1457 #if defined TIZEN_EXT
1458 static int device_specific_scan(enum connman_service_type type,
1459 struct connman_device *device,
1460 int scan_type, GSList *specific_scan_list)
1462 if (!device->driver || !device->driver->specific_scan)
1465 if (!device->powered)
1468 return device->driver->specific_scan(type, device, scan_type,
1469 specific_scan_list, NULL);
1472 int __connman_device_request_specific_scan(enum connman_service_type type,
1473 const char *ifname, int scan_type, GSList *specific_scan_list)
1475 bool success = false;
1476 int last_err = -ENOSYS;
1481 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1482 case CONNMAN_SERVICE_TYPE_SYSTEM:
1483 case CONNMAN_SERVICE_TYPE_ETHERNET:
1484 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1485 case CONNMAN_SERVICE_TYPE_CELLULAR:
1486 case CONNMAN_SERVICE_TYPE_GPS:
1487 case CONNMAN_SERVICE_TYPE_VPN:
1488 case CONNMAN_SERVICE_TYPE_GADGET:
1490 case CONNMAN_SERVICE_TYPE_WIFI:
1491 case CONNMAN_SERVICE_TYPE_P2P:
1492 #if defined TIZEN_EXT_WIFI_MESH
1493 case CONNMAN_SERVICE_TYPE_MESH:
1498 for (list = device_list; list; list = list->next) {
1499 struct connman_device *device = list->data;
1500 enum connman_service_type service_type =
1501 __connman_device_get_service_type(device);
1503 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
1504 if (type == CONNMAN_SERVICE_TYPE_P2P) {
1505 if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
1507 } else if (service_type != type)
1511 if (ifname && g_strcmp0(device->interface, ifname) != 0)
1514 err = device_specific_scan(type, device, scan_type, specific_scan_list);
1515 if (err == 0 || err == -EINPROGRESS) {
1519 DBG("device %p err %d", device, err);
1529 int connman_device_request_device_scan(enum connman_service_type type,
1530 const char * ifname, bool force_full_scan)
1532 bool success = false;
1533 int last_err = -ENOSYS;
1538 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1539 case CONNMAN_SERVICE_TYPE_SYSTEM:
1540 case CONNMAN_SERVICE_TYPE_ETHERNET:
1541 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1542 case CONNMAN_SERVICE_TYPE_CELLULAR:
1543 case CONNMAN_SERVICE_TYPE_GPS:
1544 case CONNMAN_SERVICE_TYPE_VPN:
1545 case CONNMAN_SERVICE_TYPE_GADGET:
1547 case CONNMAN_SERVICE_TYPE_WIFI:
1548 case CONNMAN_SERVICE_TYPE_P2P:
1549 #if defined TIZEN_EXT_WIFI_MESH
1550 case CONNMAN_SERVICE_TYPE_MESH:
1555 for (list = device_list; list; list = list->next) {
1556 struct connman_device *device = list->data;
1558 if (!device_has_service_type(device, type))
1561 if (g_strcmp0(device->interface, ifname) != 0)
1564 err = device_scan(type, device, force_full_scan);
1566 if (err == 0 || err == -EINPROGRESS) {
1570 DBG("device %p err %d", device, err);
1581 #if defined TIZEN_EXT_WIFI_MESH
1582 static int device_abort_scan(enum connman_service_type type,
1583 struct connman_device *device)
1585 if (!device->driver || !device->driver->scan)
1588 if (!device->powered)
1591 return device->driver->abort_scan(type, device);
1594 int __connman_device_abort_scan(enum connman_service_type type)
1599 if (type != CONNMAN_SERVICE_TYPE_MESH)
1602 for (list = device_list; list; list = list->next) {
1603 struct connman_device *device = list->data;
1604 enum connman_service_type service_type =
1605 __connman_device_get_service_type(device);
1607 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
1608 if (type == CONNMAN_SERVICE_TYPE_MESH)
1609 if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
1612 if (!device->scanning) {
1617 err = device_abort_scan(type, device);
1623 static int device_mesh_specific_scan(enum connman_service_type type,
1624 struct connman_device *device, const char *name,
1627 if (!device->driver || !device->driver->mesh_specific_scan)
1630 if (!device->powered)
1633 return device->driver->mesh_specific_scan(type, device, name, freq, NULL);
1636 int __connman_device_request_mesh_specific_scan(enum connman_service_type type,
1640 bool success = false;
1641 int last_err = -ENOSYS;
1645 if (type != CONNMAN_SERVICE_TYPE_MESH)
1648 for (list = device_list; list; list = list->next) {
1649 struct connman_device *device = list->data;
1650 enum connman_service_type service_type =
1651 __connman_device_get_service_type(device);
1653 if (service_type != CONNMAN_SERVICE_TYPE_UNKNOWN) {
1654 if (type == CONNMAN_SERVICE_TYPE_MESH)
1655 if (service_type != CONNMAN_SERVICE_TYPE_WIFI)
1659 err = device_mesh_specific_scan(type, device, name, freq);
1660 if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
1664 DBG("device %p err %d", device, err);
1673 #endif /* TIZEN_EXT_WIFI_MESH */
1676 static int connman_device_request_scan(enum connman_service_type type,
1677 bool force_full_scan)
1679 bool success = false;
1680 int last_err = -ENOSYS;
1685 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1686 case CONNMAN_SERVICE_TYPE_SYSTEM:
1687 case CONNMAN_SERVICE_TYPE_ETHERNET:
1688 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1689 case CONNMAN_SERVICE_TYPE_CELLULAR:
1690 case CONNMAN_SERVICE_TYPE_GPS:
1691 case CONNMAN_SERVICE_TYPE_VPN:
1692 case CONNMAN_SERVICE_TYPE_GADGET:
1694 case CONNMAN_SERVICE_TYPE_WIFI:
1695 case CONNMAN_SERVICE_TYPE_P2P:
1696 #if defined TIZEN_EXT_WIFI_MESH
1697 case CONNMAN_SERVICE_TYPE_MESH:
1702 for (list = device_list; list; list = list->next) {
1703 struct connman_device *device = list->data;
1705 if (!device_has_service_type(device, type))
1708 err = device_scan(type, device, force_full_scan);
1709 #if defined TIZEN_EXT
1710 /* When Scan is already in progress then return Error so that
1711 * wifi-manager can block the scan-done signal to be sent to
1712 * application and start requested scan after scan already in progress
1713 * is completed then notify to application about the scan event */
1714 if (err == 0 || err == -EINPROGRESS) {
1716 if (err == 0 || err == -EALREADY || err == -EINPROGRESS) {
1721 DBG("device %p err %d", device, err);
1731 int __connman_device_request_scan(enum connman_service_type type)
1733 return connman_device_request_scan(type, false);
1736 int __connman_device_request_scan_full(enum connman_service_type type)
1738 return connman_device_request_scan(type, true);
1741 int __connman_device_request_hidden_scan(struct connman_device *device,
1742 const char *ssid, unsigned int ssid_len,
1743 const char *identity, const char *passphrase,
1744 const char *security, void *user_data)
1746 struct connman_device_scan_params params;
1748 DBG("device %p", device);
1750 if (!device || !device->driver ||
1751 !device->driver->scan)
1754 params.type = CONNMAN_SERVICE_TYPE_UNKNOWN;
1756 params.ssid_len = ssid_len;
1757 params.identity = identity;
1758 params.passphrase = passphrase;
1759 params.security = security;
1760 params.user_data = user_data;
1762 return device->driver->scan(device, ¶ms);
1765 void __connman_device_stop_scan(enum connman_service_type type)
1769 for (list = device_list; list; list = list->next) {
1770 struct connman_device *device = list->data;
1772 if (!device_has_service_type(device, type))
1775 if (device->driver && device->driver->stop_scan)
1776 device->driver->stop_scan(type, device);
1780 #if defined TIZEN_EXT
1781 #define WIFI_MAC "/opt/etc/.mac.info"
1782 #define MAC_ADDR_LEN 18
1784 char *_get_wifi_addr(void)
1788 char wifi_mac[MAC_ADDR_LEN + 1];
1791 fp = fopen(WIFI_MAC, "r");
1793 connman_error("[%s] not present", WIFI_MAC);
1797 rv = fgets(wifi_mac, MAC_ADDR_LEN, fp);
1799 connman_error("Failed to get wifi mac address");
1804 str = g_try_malloc0(MAC_ADDR_LEN);
1806 connman_error("memory allocation failed");
1811 snprintf(str, MAC_ADDR_LEN, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
1812 g_ascii_tolower(wifi_mac[0]), g_ascii_tolower(wifi_mac[1]),
1813 g_ascii_tolower(wifi_mac[3]), g_ascii_tolower(wifi_mac[4]),
1814 g_ascii_tolower(wifi_mac[6]), g_ascii_tolower(wifi_mac[7]),
1815 g_ascii_tolower(wifi_mac[9]), g_ascii_tolower(wifi_mac[10]),
1816 g_ascii_tolower(wifi_mac[12]), g_ascii_tolower(wifi_mac[13]),
1817 g_ascii_tolower(wifi_mac[15]), g_ascii_tolower(wifi_mac[16]));
1822 char *_get_wifi_ident(void)
1826 char wifi_mac[MAC_ADDR_LEN + 1];
1829 fp = fopen(WIFI_MAC, "r");
1831 connman_error("[%s] not present", WIFI_MAC);
1835 rv = fgets(wifi_mac, MAC_ADDR_LEN, fp);
1837 connman_error("Failed to get wifi mac address");
1842 str = g_try_malloc0(MAC_ADDR_LEN);
1844 connman_error("memory allocation failed");
1849 snprintf(str, MAC_ADDR_LEN, "%c%c%c%c%c%c%c%c%c%c%c%c",
1850 g_ascii_tolower(wifi_mac[0]), g_ascii_tolower(wifi_mac[1]),
1851 g_ascii_tolower(wifi_mac[3]), g_ascii_tolower(wifi_mac[4]),
1852 g_ascii_tolower(wifi_mac[6]), g_ascii_tolower(wifi_mac[7]),
1853 g_ascii_tolower(wifi_mac[9]), g_ascii_tolower(wifi_mac[10]),
1854 g_ascii_tolower(wifi_mac[12]), g_ascii_tolower(wifi_mac[13]),
1855 g_ascii_tolower(wifi_mac[15]), g_ascii_tolower(wifi_mac[16]));
1861 #if defined TIZEN_EXT
1862 char *index2ident(int index, const char *prefix)
1864 static char *index2ident(int index, const char *prefix)
1868 struct ether_addr eth;
1875 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1879 memset(&ifr, 0, sizeof(ifr));
1880 ifr.ifr_ifindex = index;
1882 err = ioctl(sk, SIOCGIFNAME, &ifr);
1885 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1892 len = prefix ? strlen(prefix) + 18 : 18;
1894 str = g_malloc(len);
1898 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1899 snprintf(str, len, "%s%02x%02x%02x%02x%02x%02x",
1900 prefix ? prefix : "",
1901 eth.ether_addr_octet[0],
1902 eth.ether_addr_octet[1],
1903 eth.ether_addr_octet[2],
1904 eth.ether_addr_octet[3],
1905 eth.ether_addr_octet[4],
1906 eth.ether_addr_octet[5]);
1911 #if defined TIZEN_EXT
1912 char *index2addr(int index)
1914 static char *index2addr(int index)
1918 struct ether_addr eth;
1925 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1929 memset(&ifr, 0, sizeof(ifr));
1930 ifr.ifr_ifindex = index;
1932 err = ioctl(sk, SIOCGIFNAME, &ifr);
1935 err = ioctl(sk, SIOCGIFHWADDR, &ifr);
1946 memcpy(ð, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
1947 snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
1948 eth.ether_addr_octet[0],
1949 eth.ether_addr_octet[1],
1950 eth.ether_addr_octet[2],
1951 eth.ether_addr_octet[3],
1952 eth.ether_addr_octet[4],
1953 eth.ether_addr_octet[5]);
1958 struct connman_device *connman_device_create_from_index(int index)
1960 enum connman_device_type type;
1961 struct connman_device *device;
1962 char *devname, *ident = NULL;
1963 char *addr = NULL, *name = NULL;
1968 devname = connman_inet_ifname(index);
1972 if (__connman_device_isfiltered(devname)) {
1973 connman_info("Ignoring interface %s (filtered)", devname);
1978 type = __connman_rtnl_get_device_type(index);
1981 case CONNMAN_DEVICE_TYPE_UNKNOWN:
1982 connman_info("Ignoring interface %s (type unknown)", devname);
1985 case CONNMAN_DEVICE_TYPE_ETHERNET:
1986 case CONNMAN_DEVICE_TYPE_GADGET:
1987 case CONNMAN_DEVICE_TYPE_WIFI:
1988 #if defined TIZEN_EXT
1989 if (type == CONNMAN_DEVICE_TYPE_WIFI)
1990 name = _get_wifi_ident();
1993 name = index2ident(index, "");
1994 #if defined TIZEN_EXT
1995 if (type == CONNMAN_DEVICE_TYPE_WIFI)
1996 addr = _get_wifi_addr();
1999 addr = index2addr(index);
2001 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
2002 case CONNMAN_DEVICE_TYPE_CELLULAR:
2003 case CONNMAN_DEVICE_TYPE_GPS:
2004 case CONNMAN_DEVICE_TYPE_VENDOR:
2005 name = g_strdup(devname);
2009 device = connman_device_create(name, type);
2014 case CONNMAN_DEVICE_TYPE_UNKNOWN:
2015 case CONNMAN_DEVICE_TYPE_VENDOR:
2016 case CONNMAN_DEVICE_TYPE_GPS:
2018 case CONNMAN_DEVICE_TYPE_ETHERNET:
2019 case CONNMAN_DEVICE_TYPE_GADGET:
2020 ident = index2ident(index, NULL);
2022 case CONNMAN_DEVICE_TYPE_WIFI:
2023 #if defined TIZEN_EXT
2024 ident = _get_wifi_ident();
2027 ident = index2ident(index, NULL);
2029 case CONNMAN_DEVICE_TYPE_BLUETOOTH:
2031 case CONNMAN_DEVICE_TYPE_CELLULAR:
2032 ident = index2ident(index, NULL);
2036 connman_device_set_index(device, index);
2037 connman_device_set_interface(device, devname);
2038 #if defined TIZEN_EXT
2039 connman_device_load_last_connected(device);
2040 connman_device_load_last_user_selection(device);
2044 connman_device_set_ident(device, ident);
2048 connman_device_set_string(device, "Address", addr);
2058 bool __connman_device_isfiltered(const char *devname)
2061 char **blacklisted_interfaces;
2067 for (pattern = device_filter, match = false; *pattern; pattern++) {
2068 if (g_pattern_match_simple(*pattern, devname)) {
2075 DBG("ignoring device %s (match)", devname);
2080 if (g_pattern_match_simple("dummy*", devname)) {
2081 DBG("ignoring dummy networking devices");
2085 if (!nodevice_filter)
2088 for (pattern = nodevice_filter; *pattern; pattern++) {
2089 if (g_pattern_match_simple(*pattern, devname)) {
2090 DBG("ignoring device %s (no match)", devname);
2096 if (__connman_inet_isrootnfs_device(devname)) {
2097 DBG("ignoring device %s (rootnfs)", devname);
2101 blacklisted_interfaces =
2102 connman_setting_get_string_list("NetworkInterfaceBlacklist");
2103 if (!blacklisted_interfaces)
2106 for (pattern = blacklisted_interfaces; *pattern; pattern++) {
2107 if (g_str_has_prefix(devname, *pattern)) {
2108 DBG("ignoring device %s (blacklist)", devname);
2116 static void cleanup_devices(void)
2119 * Check what interfaces are currently up and if connman is
2120 * suppose to handle the interface, then cleanup the mess
2121 * related to that interface. There might be weird routes etc
2122 * that are related to that interface and that might confuse
2123 * connmand. So in this case we just turn the interface down
2124 * so that kernel removes routes/addresses automatically and
2125 * then proceed the startup.
2127 * Note that this cleanup must be done before rtnl/detect code
2128 * has activated interface watches.
2134 interfaces = __connman_inet_get_running_interfaces();
2139 for (i = 0; interfaces[i]; i++) {
2142 struct sockaddr_in sin_addr, sin_mask;
2144 filtered = __connman_device_isfiltered(interfaces[i]);
2148 index = connman_inet_ifindex(interfaces[i]);
2152 if (!__connman_inet_get_address_netmask(index, &sin_addr,
2154 char *address = g_strdup(inet_ntoa(sin_addr.sin_addr));
2155 char *netmask = g_strdup(inet_ntoa(sin_mask.sin_addr));
2157 if (__connman_config_address_provisioned(address,
2159 DBG("Skip %s which is already provisioned "
2160 "with %s/%s", interfaces[i], address,
2171 DBG("cleaning up %s index %d", interfaces[i], index);
2173 #if defined TIZEN_EXT
2174 if (strcmp(interfaces[i], "wlan0") != 0)
2176 connman_inet_ifdown(index);
2179 * ConnMan will turn the interface UP automatically so
2180 * no need to do it here.
2184 g_strfreev(interfaces);
2187 int __connman_device_init(const char *device, const char *nodevice)
2191 #if defined TIZEN_EXT
2192 connection = connman_dbus_get_connection();
2196 device_filter = g_strsplit(device, ",", -1);
2199 nodevice_filter = g_strsplit(nodevice, ",", -1);
2206 void __connman_device_cleanup(void)
2210 g_strfreev(nodevice_filter);
2211 g_strfreev(device_filter);
2213 #if defined TIZEN_EXT
2214 dbus_connection_unref(connection);
2219 void connman_device_mac_policy_notify(struct connman_device *device,
2220 int result, unsigned int policy)
2222 device->mac_policy = policy;
2223 __connman_technology_notify_mac_policy_by_device(device, result, policy);
2226 int connman_device_set_mac_policy(struct connman_device *device,
2227 unsigned int policy)
2231 if (!device || !device->driver || !device->driver->set_mac_policy)
2234 device->mac_policy = policy;
2235 err = device->driver->set_mac_policy(device, policy);
2239 unsigned int connman_device_get_mac_policy(struct connman_device *device)
2241 return device->mac_policy;
2244 void connman_device_preassoc_mac_policy_notify(struct connman_device *device,
2245 int result, unsigned int policy)
2247 device->preassoc_mac_policy = policy;
2248 __connman_technology_notify_preassoc_mac_policy_by_device(device, result, policy);
2251 int connman_device_set_preassoc_mac_policy(struct connman_device *device,
2252 unsigned int policy)
2256 if (!device || !device->driver || !device->driver->set_preassoc_mac_policy)
2259 device->preassoc_mac_policy = policy;
2260 err = device->driver->set_preassoc_mac_policy(device, policy);
2264 unsigned int connman_device_get_preassoc_mac_policy(struct connman_device *device)
2266 return device->preassoc_mac_policy;
2269 void connman_device_random_mac_lifetime_notify(struct connman_device *device,
2270 int result, unsigned int lifetime)
2272 device->random_mac_lifetime = lifetime;
2273 __connman_technology_notify_random_mac_lifetime_by_device(device, result, lifetime);
2276 int connman_device_set_random_mac_lifetime(struct connman_device *device,
2277 unsigned int lifetime)
2281 if (!device || !device->driver || !device->driver->set_random_mac_lifetime)
2284 device->random_mac_lifetime = lifetime;
2285 err = device->driver->set_random_mac_lifetime(device, lifetime);
2289 unsigned int connman_device_get_random_mac_lifetime(struct connman_device *device)
2291 return device->random_mac_lifetime;