5 * Copyright (C) 2007-2013 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
38 static DBusConnection *connection;
40 static GSList *technology_list = NULL;
43 * List of devices with no technology associated with them either because of
44 * no compiled in support or the driver is not yet loaded.
46 static GSList *techless_device_list = NULL;
47 static GHashTable *rfkill_list;
49 static bool global_offlinemode;
52 struct connman_scan_pending {
54 connman_scan_type_e scan_type;
58 struct connman_bssid_pending {
60 unsigned char bssid[6];
64 struct connman_rfkill {
66 enum connman_service_type type;
71 struct connman_technology {
73 enum connman_service_type type;
81 bool tethering_persistent; /* Tells the save status, needed
82 * as offline mode might set
85 char *tethering_ident;
86 char *tethering_passphrase;
88 bool enable_persistent; /* Save the tech state */
92 DBusMessage *pending_reply;
93 guint pending_timeout;
100 bool dbus_registered;
101 #if defined TIZEN_EXT
102 char **enabled_devices;
103 unsigned int mac_policy;
104 unsigned int preassoc_mac_policy;
105 unsigned int random_mac_lifetime;
107 #if defined TIZEN_EXT_WIFI_MESH
108 DBusMessage *mesh_dbus_msg;
112 static GSList *driver_list = NULL;
114 static int technology_enabled(struct connman_technology *technology);
115 static int technology_disabled(struct connman_technology *technology);
117 static gint compare_priority(gconstpointer a, gconstpointer b)
119 const struct connman_technology_driver *driver1 = a;
120 const struct connman_technology_driver *driver2 = b;
122 return driver2->priority - driver1->priority;
125 static void rfkill_check(gpointer key, gpointer value, gpointer user_data)
127 struct connman_rfkill *rfkill = value;
128 enum connman_service_type type = GPOINTER_TO_INT(user_data);
130 /* Calling _technology_add_rfkill will update the tech. */
131 if (rfkill->type == type)
132 __connman_technology_add_rfkill(rfkill->index, type,
133 rfkill->softblock, rfkill->hardblock);
137 connman_technology_is_tethering_allowed(enum connman_service_type type)
139 static char *allowed_default[] = { "wifi", "bluetooth", "gadget",
141 const char *type_str = __connman_service_type2string(type);
148 allowed = connman_setting_get_string_list("TetheringTechnologies");
150 allowed = allowed_default;
152 for (i = 0; allowed[i]; i++) {
153 if (g_strcmp0(allowed[i], type_str) == 0)
160 static const char *get_name(enum connman_service_type type)
163 case CONNMAN_SERVICE_TYPE_UNKNOWN:
164 case CONNMAN_SERVICE_TYPE_SYSTEM:
165 case CONNMAN_SERVICE_TYPE_GPS:
166 case CONNMAN_SERVICE_TYPE_VPN:
168 case CONNMAN_SERVICE_TYPE_GADGET:
170 case CONNMAN_SERVICE_TYPE_ETHERNET:
172 case CONNMAN_SERVICE_TYPE_WIFI:
174 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
176 case CONNMAN_SERVICE_TYPE_CELLULAR:
178 case CONNMAN_SERVICE_TYPE_P2P:
180 #if defined TIZEN_EXT_WIFI_MESH
181 case CONNMAN_SERVICE_TYPE_MESH:
189 static void technology_save(struct connman_technology *technology)
193 const char *name = get_name(technology->type);
195 DBG("technology %p type %d name %s", technology, technology->type,
200 keyfile = __connman_storage_load_global();
202 keyfile = g_key_file_new();
204 identifier = g_strdup_printf("%s", name);
208 g_key_file_set_boolean(keyfile, identifier, "Enable",
209 technology->enable_persistent);
211 g_key_file_set_boolean(keyfile, identifier, "Tethering",
212 technology->tethering_persistent);
214 if (technology->tethering_ident)
215 g_key_file_set_string(keyfile, identifier,
216 "Tethering.Identifier",
217 technology->tethering_ident);
219 if (technology->tethering_passphrase)
220 g_key_file_set_string(keyfile, identifier,
221 "Tethering.Passphrase",
222 technology->tethering_passphrase);
225 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
226 g_key_file_set_uint64(keyfile, identifier, "MacPolicy",
227 technology->mac_policy);
229 g_key_file_set_uint64(keyfile, identifier, "PreassocMacPolicy",
230 technology->preassoc_mac_policy);
232 g_key_file_set_uint64(keyfile, identifier, "RandomMacLifetime",
233 technology->random_mac_lifetime);
235 #endif /* TIZEN_EXT */
240 __connman_storage_save_global(keyfile);
242 g_key_file_free(keyfile);
245 static void tethering_changed(struct connman_technology *technology)
247 dbus_bool_t tethering = technology->tethering;
249 connman_dbus_property_changed_basic(technology->path,
250 CONNMAN_TECHNOLOGY_INTERFACE, "Tethering",
251 DBUS_TYPE_BOOLEAN, &tethering);
253 technology_save(technology);
256 int connman_technology_tethering_notify(struct connman_technology *technology,
261 DBG("technology %p enabled %u", technology, enabled);
263 if (technology->tethering == enabled)
267 err = __connman_tethering_set_enabled();
271 __connman_tethering_set_disabled();
273 technology->tethering = enabled;
274 tethering_changed(technology);
279 static int set_tethering(struct connman_technology *technology,
282 int result = -EOPNOTSUPP;
284 const char *ident, *passphrase, *bridge;
285 GSList *tech_drivers;
287 ident = technology->tethering_ident;
288 passphrase = technology->tethering_passphrase;
290 __sync_synchronize();
291 if (!technology->enabled)
294 bridge = __connman_tethering_get_bridge();
298 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI &&
299 (!ident || !passphrase))
302 for (tech_drivers = technology->driver_list; tech_drivers;
303 tech_drivers = g_slist_next(tech_drivers)) {
304 struct connman_technology_driver *driver = tech_drivers->data;
306 if (!driver || !driver->set_tethering)
309 err = driver->set_tethering(technology, ident, passphrase,
312 if (result == -EINPROGRESS)
315 if (err == -EINPROGRESS || err == 0)
322 void connman_technology_regdom_notify(struct connman_technology *technology,
328 connman_error("Failed to set regulatory domain");
330 DBG("Regulatory domain set to %s", alpha2);
332 g_free(technology->regdom);
333 technology->regdom = g_strdup(alpha2);
336 static int set_regdom_by_device(struct connman_technology *technology,
341 for (list = technology->device_list; list; list = list->next) {
342 struct connman_device *device = list->data;
344 if (connman_device_set_regdom(device, alpha2) != 0)
351 int connman_technology_set_regdom(const char *alpha2)
353 GSList *list, *tech_drivers;
355 for (list = technology_list; list; list = list->next) {
356 struct connman_technology *technology = list->data;
358 if (set_regdom_by_device(technology, alpha2) != 0) {
360 for (tech_drivers = technology->driver_list;
362 tech_drivers = g_slist_next(tech_drivers)) {
364 struct connman_technology_driver *driver =
367 if (driver->set_regdom)
368 driver->set_regdom(technology, alpha2);
376 static struct connman_technology *technology_find(enum connman_service_type type)
380 DBG("type %d", type);
382 for (list = technology_list; list; list = list->next) {
383 struct connman_technology *technology = list->data;
385 if (technology->type == type)
392 enum connman_service_type connman_technology_get_type
393 (struct connman_technology *technology)
396 return CONNMAN_SERVICE_TYPE_UNKNOWN;
398 return technology->type;
401 bool connman_technology_get_wifi_tethering(const char **ssid,
404 struct connman_technology *technology;
411 technology = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
415 if (!technology->tethering)
418 *ssid = technology->tethering_ident;
419 *psk = technology->tethering_passphrase;
424 #if defined TIZEN_EXT
425 const char *connman_techonology_get_path(enum connman_service_type type)
427 struct connman_technology *technology = technology_find(type);
432 return technology->path;
436 static void free_rfkill(gpointer data)
438 struct connman_rfkill *rfkill = data;
443 static void technology_load(struct connman_technology *technology)
447 GError *error = NULL;
448 bool enable, need_saving = false;
450 DBG("technology %p", technology);
452 keyfile = __connman_storage_load_global();
453 /* Fallback on disabling technology if file not found. */
455 if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
456 /* We enable ethernet by default */
457 technology->enable_persistent = true;
459 technology->enable_persistent = false;
463 identifier = g_strdup_printf("%s", get_name(technology->type));
469 technology->enabled_devices = g_key_file_get_string_list(keyfile,
470 identifier, "Enable.Devices", &length, NULL);
471 if (technology->enabled_devices && length == 0) {
472 g_strfreev(technology->enabled_devices);
473 technology->enabled_devices = NULL;
477 enable = g_key_file_get_boolean(keyfile, identifier, "Enable", &error);
479 technology->enable_persistent = enable;
481 if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
482 technology->enable_persistent = true;
484 technology->enable_persistent = false;
487 g_clear_error(&error);
490 enable = g_key_file_get_boolean(keyfile, identifier,
491 "Tethering", &error);
493 technology->tethering_persistent = enable;
496 g_clear_error(&error);
500 technology_save(technology);
502 technology->tethering_ident = g_key_file_get_string(keyfile,
503 identifier, "Tethering.Identifier", NULL);
505 technology->tethering_passphrase = g_key_file_get_string(keyfile,
506 identifier, "Tethering.Passphrase", NULL);
509 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
510 unsigned int val = 0;
512 val = g_key_file_get_uint64(keyfile,
513 identifier, "MacPolicy", NULL);
515 technology->mac_policy = val;
517 technology->mac_policy = 0;
519 val = g_key_file_get_uint64(keyfile,
520 identifier, "PreassocMacPolicy", NULL);
522 technology->preassoc_mac_policy = val;
524 technology->preassoc_mac_policy = 0;
526 val = g_key_file_get_uint64(keyfile,
527 identifier, "RandomMacLifetime", NULL);
529 technology->random_mac_lifetime = val;
531 technology->random_mac_lifetime = 60;
533 #endif /* TIZEN_EXT */
538 g_key_file_free(keyfile);
541 bool __connman_technology_get_offlinemode(void)
543 return global_offlinemode;
546 static void connman_technology_save_offlinemode(void)
549 GError *error = NULL;
552 keyfile = __connman_storage_load_global();
555 keyfile = g_key_file_new();
556 g_key_file_set_boolean(keyfile, "global",
557 "OfflineMode", global_offlinemode);
559 __connman_storage_save_global(keyfile);
562 offlinemode = g_key_file_get_boolean(keyfile, "global",
563 "OfflineMode", &error);
565 if (error || offlinemode != global_offlinemode) {
566 g_key_file_set_boolean(keyfile, "global",
567 "OfflineMode", global_offlinemode);
569 g_clear_error(&error);
571 __connman_storage_save_global(keyfile);
575 g_key_file_free(keyfile);
578 static bool connman_technology_load_offlinemode(void)
581 GError *error = NULL;
584 /* If there is a error, we enable offlinemode */
585 keyfile = __connman_storage_load_global();
589 offlinemode = g_key_file_get_boolean(keyfile, "global",
590 "OfflineMode", &error);
593 g_clear_error(&error);
596 g_key_file_free(keyfile);
601 #if defined TIZEN_EXT
602 static void append_devices(DBusMessageIter *iter, void *user_data)
606 struct connman_technology *technology = user_data;
608 for (list = technology->device_list; list; list = list->next) {
609 struct connman_device *device = list->data;
611 const char *str = connman_device_get_string(device, "Interface");
612 struct connman_network *network = connman_device_get_default_network(device);
613 struct connman_service *service = connman_service_lookup_from_network(network);
615 connman_dbus_dict_append_basic(iter, "Ifname",
616 DBUS_TYPE_STRING, &str);
618 val = connman_device_get_powered(device);
619 connman_dbus_dict_append_basic(iter, "Powered",
620 DBUS_TYPE_BOOLEAN, &val);
622 if (__connman_service_is_connected_state(service, CONNMAN_IPCONFIG_TYPE_IPV4) ||
623 __connman_service_is_connected_state(service, CONNMAN_IPCONFIG_TYPE_IPV6))
628 connman_dbus_dict_append_basic(iter, "Connected",
629 DBUS_TYPE_BOOLEAN, &val);
631 str = connman_device_get_string(device, "Address");
632 connman_dbus_dict_append_basic(iter, "MAC.Address",
633 DBUS_TYPE_STRING, &str);
637 void __connman_technology_append_interfaces(DBusMessageIter *array,
638 enum connman_service_type type, const char *ifname)
641 struct connman_technology *technology = NULL;
643 for (list = technology_list; list; list = list->next) {
644 struct connman_technology *local_tech = list->data;
646 if (local_tech->type != type)
649 technology = local_tech;
656 for (list = technology->device_list; list; list = list->next) {
657 struct connman_device *device = list->data;
658 const char *str = connman_device_get_string(device, "Interface");
660 if (g_strcmp0(ifname, str) == 0)
663 dbus_message_iter_append_basic(array,
664 DBUS_TYPE_STRING, &str);
669 static void append_properties(DBusMessageIter *iter,
670 struct connman_technology *technology)
672 DBusMessageIter dict;
676 connman_dbus_dict_open(iter, &dict);
678 str = get_name(technology->type);
680 connman_dbus_dict_append_basic(&dict, "Name",
681 DBUS_TYPE_STRING, &str);
683 str = __connman_service_type2string(technology->type);
685 connman_dbus_dict_append_basic(&dict, "Type",
686 DBUS_TYPE_STRING, &str);
688 __sync_synchronize();
689 val = technology->enabled;
690 connman_dbus_dict_append_basic(&dict, "Powered",
694 val = technology->connected;
695 connman_dbus_dict_append_basic(&dict, "Connected",
699 val = technology->tethering;
700 connman_dbus_dict_append_basic(&dict, "Tethering",
704 if (technology->tethering_ident)
705 connman_dbus_dict_append_basic(&dict, "TetheringIdentifier",
707 &technology->tethering_ident);
709 if (technology->tethering_passphrase)
710 connman_dbus_dict_append_basic(&dict, "TetheringPassphrase",
712 &technology->tethering_passphrase);
714 #if defined TIZEN_EXT
715 connman_dbus_dict_append_basic(&dict, "MacPolicy",
717 &(technology->mac_policy));
719 connman_dbus_dict_append_basic(&dict, "PreassocMacPolicy",
721 &(technology->preassoc_mac_policy));
723 connman_dbus_dict_append_basic(&dict, "RandomMacLifetime",
725 &(technology->random_mac_lifetime));
727 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI)
728 connman_dbus_dict_append_dict(&dict, "Device.List",
729 append_devices, technology);
730 if (technology->regdom)
731 connman_dbus_dict_append_basic(&dict, "CountryCode",
733 &technology->regdom);
735 connman_dbus_dict_close(iter, &dict);
738 static void technology_added_signal(struct connman_technology *technology)
741 DBusMessageIter iter;
743 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
744 CONNMAN_MANAGER_INTERFACE, "TechnologyAdded");
748 dbus_message_iter_init_append(signal, &iter);
749 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
751 append_properties(&iter, technology);
753 dbus_connection_send(connection, signal, NULL);
754 dbus_message_unref(signal);
757 static void technology_removed_signal(struct connman_technology *technology)
759 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
760 CONNMAN_MANAGER_INTERFACE, "TechnologyRemoved",
761 DBUS_TYPE_OBJECT_PATH, &technology->path,
765 static DBusMessage *get_properties(DBusConnection *conn,
766 DBusMessage *message, void *user_data)
768 struct connman_technology *technology = user_data;
770 DBusMessageIter iter;
772 reply = dbus_message_new_method_return(message);
776 dbus_message_iter_init_append(reply, &iter);
777 append_properties(&iter, technology);
782 void __connman_technology_list_struct(DBusMessageIter *array)
785 DBusMessageIter entry;
787 for (list = technology_list; list; list = list->next) {
788 struct connman_technology *technology = list->data;
790 if (!technology->path ||
791 (technology->rfkill_driven &&
792 technology->hardblocked))
795 dbus_message_iter_open_container(array, DBUS_TYPE_STRUCT,
797 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
799 append_properties(&entry, technology);
800 dbus_message_iter_close_container(array, &entry);
804 static gboolean technology_pending_reply(gpointer user_data)
806 struct connman_technology *technology = user_data;
809 /* Power request timed out, send ETIMEDOUT. */
810 if (technology->pending_reply) {
811 reply = __connman_error_failed(technology->pending_reply, ETIMEDOUT);
813 g_dbus_send_message(connection, reply);
815 dbus_message_unref(technology->pending_reply);
816 technology->pending_reply = NULL;
817 technology->pending_timeout = 0;
823 static int technology_affect_devices(struct connman_technology *technology,
826 int err = 0, err_dev;
829 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
831 __connman_technology_enabled(technology->type);
833 __connman_technology_disabled(technology->type);
837 #if defined TIZEN_EXT_WIFI_MESH
838 if (technology->type == CONNMAN_SERVICE_TYPE_MESH)
842 for (list = technology->device_list; list; list = list->next) {
843 struct connman_device *device = list->data;
846 err_dev = __connman_device_enable(device);
848 err_dev = __connman_device_disable(device);
850 if (err_dev < 0 && err_dev != -EALREADY)
857 static void powered_changed(struct connman_technology *technology)
861 if (!technology->dbus_registered)
864 if (technology->pending_reply) {
865 g_dbus_send_reply(connection,
866 technology->pending_reply, DBUS_TYPE_INVALID);
867 dbus_message_unref(technology->pending_reply);
868 technology->pending_reply = NULL;
870 g_source_remove(technology->pending_timeout);
871 technology->pending_timeout = 0;
874 __sync_synchronize();
875 enabled = technology->enabled;
876 #if defined TIZEN_EXT
877 DBG("ConnMan, Powered : %s, %s",
878 enabled ? "TRUE" : "FALSE",technology->path);
880 connman_dbus_property_changed_basic(technology->path,
881 CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
882 DBUS_TYPE_BOOLEAN, &enabled);
885 static void enable_tethering(struct connman_technology *technology)
889 if (!connman_setting_get_bool("PersistentTetheringMode"))
892 ret = set_tethering(technology, true);
893 if (ret < 0 && ret != -EALREADY)
894 DBG("Cannot enable tethering yet for %s (%d/%s)",
895 get_name(technology->type),
896 -ret, strerror(-ret));
899 static int technology_enabled(struct connman_technology *technology)
901 __sync_synchronize();
902 if (technology->enabled)
905 technology->enabled = true;
907 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
908 struct connman_technology *p2p;
910 p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
911 if (p2p && !p2p->enabled && p2p->enable_persistent)
912 technology_enabled(p2p);
915 if (technology->tethering_persistent)
916 enable_tethering(technology);
918 powered_changed(technology);
923 static int technology_enable(struct connman_technology *technology)
928 DBG("technology %p enable", technology);
930 __sync_synchronize();
932 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
933 struct connman_technology *wifi;
935 wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
936 if (wifi && wifi->enabled)
937 return technology_enabled(technology);
941 if (technology->enabled)
944 if (technology->pending_reply)
947 if (connman_setting_get_bool("PersistentTetheringMode") &&
948 technology->tethering)
949 set_tethering(technology, true);
951 if (technology->rfkill_driven)
952 err = __connman_rfkill_block(technology->type, false);
954 err_dev = technology_affect_devices(technology, true);
956 if (!technology->rfkill_driven)
962 static int technology_disabled(struct connman_technology *technology)
964 __sync_synchronize();
965 if (!technology->enabled)
968 technology->enabled = false;
970 powered_changed(technology);
975 static int technology_disable(struct connman_technology *technology)
979 DBG("technology %p disable", technology);
981 __sync_synchronize();
983 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
984 technology->enable_persistent = false;
985 __connman_device_stop_scan(CONNMAN_SERVICE_TYPE_P2P);
986 __connman_peer_disconnect_all();
987 return technology_disabled(technology);
988 } else if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
989 struct connman_technology *p2p;
991 p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
992 if (p2p && p2p->enabled) {
993 p2p->enable_persistent = true;
994 technology_disabled(p2p);
998 if (!technology->enabled)
1001 if (technology->pending_reply)
1004 if (technology->tethering)
1005 set_tethering(technology, false);
1007 err = technology_affect_devices(technology, false);
1009 if (technology->rfkill_driven)
1010 err = __connman_rfkill_block(technology->type, true);
1015 static DBusMessage *set_powered(struct connman_technology *technology,
1016 DBusMessage *msg, bool powered)
1018 DBusMessage *reply = NULL;
1021 if (technology->rfkill_driven && technology->hardblocked) {
1027 err = technology_enable(technology);
1029 err = technology_disable(technology);
1031 if (err != -EBUSY) {
1032 technology->enable_persistent = powered;
1033 technology_save(technology);
1037 if (err == -EINPROGRESS) {
1038 technology->pending_reply = dbus_message_ref(msg);
1039 technology->pending_timeout = g_timeout_add_seconds(10,
1040 technology_pending_reply, technology);
1041 } else if (err == -EALREADY) {
1043 reply = __connman_error_already_enabled(msg);
1045 reply = __connman_error_already_disabled(msg);
1047 reply = __connman_error_failed(msg, -err);
1049 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1054 #if defined TIZEN_EXT
1055 int set_connman_bssid(enum bssid_type mode, char *bssid, const char *ifname)
1057 static int bssid_len;
1058 static const char *def_ifname = "default";
1059 static GSList *bssid_list = NULL;
1061 const char *local_ifname = ifname;
1063 struct connman_bssid_pending *bssid_info;
1065 DBG("mode: %d, ifname: %s", mode, ifname);
1068 local_ifname = def_ifname;
1070 for (list = bssid_list; list; list = list->next) {
1071 bssid_info = list->data;
1073 if (g_strcmp0(bssid_info->ifname, local_ifname) == 0) {
1079 if (mode == CHECK_BSSID) {
1086 if (mode == GET_BSSID && bssid) {
1088 memcpy(bssid, bssid_info->bssid, 6);
1094 if (mode == RESET_BSSID) {
1096 bssid_list = g_slist_remove(bssid_list, bssid_info);
1097 g_free(bssid_info->ifname);
1103 if (mode != SET_BSSID || !bssid) {
1104 DBG("Invalid parameter");
1109 bssid_list = g_slist_remove(bssid_list, bssid_info);
1110 g_free(bssid_info->ifname);
1114 bssid_info = g_try_malloc0(sizeof(struct connman_bssid_pending));
1116 DBG("Failed to allocate memory");
1120 unsigned char *bssid_data = bssid_info->bssid;
1122 bssid_len = sscanf(bssid, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
1123 &bssid_data[0], &bssid_data[1], &bssid_data[2],
1124 &bssid_data[3], &bssid_data[4], &bssid_data[5]);
1125 if (bssid_len != 6) {
1126 DBG("Incorrect BSSID format. bssid_len = %d", bssid_len);
1131 DBG("SET BSSID len: %d, BSSID: %02x:%02x:%02x:%02x:%02x:%02x ifname: %s",
1133 bssid_data[0], bssid_data[1], bssid_data[2],
1134 bssid_data[3], bssid_data[4], bssid_data[5],
1137 bssid_info->ifname = g_strdup(ifname);
1138 bssid_list = g_slist_prepend(bssid_list, bssid_info);
1143 void connman_technology_mac_policy_notify(struct connman_technology *technology,
1144 unsigned int policy)
1146 DBG("Mac polict set to %u", policy);
1148 technology->mac_policy = policy;
1149 technology_save(technology);
1152 void __connman_technology_notify_mac_policy_by_device(struct connman_device *device,
1153 int result, unsigned int policy)
1155 struct connman_technology *technology;
1156 enum connman_service_type type;
1158 type = __connman_device_get_service_type(device);
1159 technology = technology_find(type);
1164 connman_technology_mac_policy_notify(technology, policy);
1167 static DBusMessage *set_mac_policy(struct connman_technology *technology,
1168 DBusMessage *msg, unsigned int policy)
1170 DBusMessage *reply = NULL;
1172 unsigned int last_policy = technology->mac_policy;
1174 if (technology->rfkill_driven && technology->hardblocked) {
1179 for (GSList *list = technology->device_list; list; list = list->next) {
1180 struct connman_device *device = list->data;
1182 err = connman_device_set_mac_policy(device, policy);
1189 if (err != -EACCES && err != -EOPNOTSUPP) {
1190 for (GSList *list = technology->device_list; list; list = list->next) {
1191 struct connman_device *device = list->data;
1193 connman_device_set_mac_policy(device, last_policy);
1197 reply = __connman_error_failed(msg, -err);
1199 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1205 void connman_technology_preassoc_mac_policy_notify(struct connman_technology *technology,
1206 unsigned int policy)
1208 DBG("Preassoc mac polict set to %u", policy);
1210 technology->preassoc_mac_policy = policy;
1211 technology_save(technology);
1214 void __connman_technology_notify_preassoc_mac_policy_by_device(struct connman_device *device,
1215 int result, unsigned int policy)
1217 struct connman_technology *technology;
1218 enum connman_service_type type;
1220 type = __connman_device_get_service_type(device);
1221 technology = technology_find(type);
1226 connman_technology_preassoc_mac_policy_notify(technology, policy);
1229 static DBusMessage *set_preassoc_mac_policy(struct connman_technology *technology,
1230 DBusMessage *msg, unsigned int policy)
1232 DBusMessage *reply = NULL;
1234 unsigned int last_policy = technology->preassoc_mac_policy;
1236 if (technology->rfkill_driven && technology->hardblocked) {
1241 for (GSList *list = technology->device_list; list; list = list->next) {
1242 struct connman_device *device = list->data;
1244 err = connman_device_set_preassoc_mac_policy(device, policy);
1251 if (err != -EACCES && err != -EOPNOTSUPP) {
1252 for (GSList *list = technology->device_list; list; list = list->next) {
1253 struct connman_device *device = list->data;
1255 connman_device_set_preassoc_mac_policy(device, last_policy);
1259 reply = __connman_error_failed(msg, -err);
1261 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1267 void connman_technology_random_mac_lifetime_notify(struct connman_technology *technology,
1268 unsigned int lifetime)
1270 DBG("Random mac lifetime set to %u", lifetime);
1272 technology->random_mac_lifetime = lifetime;
1273 technology_save(technology);
1276 void __connman_technology_notify_random_mac_lifetime_by_device(struct connman_device *device,
1277 int result, unsigned int lifetime)
1279 struct connman_technology *technology;
1280 enum connman_service_type type;
1282 type = __connman_device_get_service_type(device);
1283 technology = technology_find(type);
1288 connman_technology_random_mac_lifetime_notify(technology, lifetime);
1291 static DBusMessage *set_random_mac_lifetime(struct connman_technology *technology,
1292 DBusMessage *msg, unsigned int lifetime)
1294 DBusMessage *reply = NULL;
1296 unsigned int last_lifetime = technology->random_mac_lifetime;
1298 if (technology->rfkill_driven && technology->hardblocked) {
1303 for (GSList *list = technology->device_list; list; list = list->next) {
1304 struct connman_device *device = list->data;
1306 err = connman_device_set_random_mac_lifetime(device, lifetime);
1311 if (err != -EACCES && err != -EOPNOTSUPP) {
1312 for (GSList *list = technology->device_list; list; list = list->next) {
1313 struct connman_device *device = list->data;
1315 connman_device_set_random_mac_lifetime(device, last_lifetime);
1319 reply = __connman_error_failed(msg, -err);
1321 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1328 static DBusMessage *set_property(DBusConnection *conn,
1329 DBusMessage *msg, void *data)
1331 struct connman_technology *technology = data;
1332 DBusMessageIter iter, value;
1336 DBG("conn %p", conn);
1338 if (!dbus_message_iter_init(msg, &iter))
1339 return __connman_error_invalid_arguments(msg);
1341 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1342 return __connman_error_invalid_arguments(msg);
1344 dbus_message_iter_get_basic(&iter, &name);
1345 dbus_message_iter_next(&iter);
1347 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
1348 return __connman_error_invalid_arguments(msg);
1350 dbus_message_iter_recurse(&iter, &value);
1352 type = dbus_message_iter_get_arg_type(&value);
1354 DBG("property %s", name);
1356 if (g_str_equal(name, "Tethering")) {
1357 dbus_bool_t tethering;
1360 if (type != DBUS_TYPE_BOOLEAN)
1361 return __connman_error_invalid_arguments(msg);
1363 if (!connman_technology_is_tethering_allowed(technology->type)) {
1364 DBG("%s tethering not allowed by config file",
1365 __connman_service_type2string(technology->type));
1366 return __connman_error_not_supported(msg);
1369 dbus_message_iter_get_basic(&value, &tethering);
1371 if (technology->tethering == tethering) {
1373 return __connman_error_already_disabled(msg);
1375 return __connman_error_already_enabled(msg);
1378 err = set_tethering(technology, tethering);
1380 return __connman_error_failed(msg, -err);
1382 technology->tethering_persistent = tethering;
1384 technology_save(technology);
1386 } else if (g_str_equal(name, "TetheringIdentifier")) {
1389 dbus_message_iter_get_basic(&value, &str);
1391 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1392 return __connman_error_not_supported(msg);
1394 if (strlen(str) < 1 || strlen(str) > 32)
1395 return __connman_error_invalid_arguments(msg);
1397 if (g_strcmp0(technology->tethering_ident, str) != 0) {
1398 g_free(technology->tethering_ident);
1399 technology->tethering_ident = g_strdup(str);
1400 technology_save(technology);
1402 connman_dbus_property_changed_basic(technology->path,
1403 CONNMAN_TECHNOLOGY_INTERFACE,
1404 "TetheringIdentifier",
1406 &technology->tethering_ident);
1408 } else if (g_str_equal(name, "TetheringPassphrase")) {
1411 dbus_message_iter_get_basic(&value, &str);
1413 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1414 return __connman_error_not_supported(msg);
1416 err = __connman_service_check_passphrase(CONNMAN_SERVICE_SECURITY_PSK,
1419 return __connman_error_passphrase_required(msg);
1421 if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
1422 g_free(technology->tethering_passphrase);
1423 technology->tethering_passphrase = g_strdup(str);
1424 technology_save(technology);
1426 connman_dbus_property_changed_basic(technology->path,
1427 CONNMAN_TECHNOLOGY_INTERFACE,
1428 "TetheringPassphrase",
1430 &technology->tethering_passphrase);
1432 } else if (g_str_equal(name, "Powered")) {
1435 if (type != DBUS_TYPE_BOOLEAN)
1436 return __connman_error_invalid_arguments(msg);
1438 dbus_message_iter_get_basic(&value, &enable);
1440 return set_powered(technology, msg, enable);
1441 #if defined TIZEN_EXT
1442 } else if (g_str_equal(name, "SetBSSID")) {
1445 if (type != DBUS_TYPE_STRING)
1446 return __connman_error_invalid_arguments(msg);
1448 dbus_message_iter_get_basic(&value, &key);
1449 DBG("BSSID %s", key);
1450 set_connman_bssid(SET_BSSID, key, NULL);
1451 } else if (g_str_equal(name, "MacPolicy")) {
1452 dbus_uint32_t mac_policy;
1454 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1455 return __connman_error_not_supported(msg);
1457 if (type != DBUS_TYPE_UINT32)
1458 return __connman_error_invalid_arguments(msg);
1460 dbus_message_iter_get_basic(&value, &mac_policy);
1462 if (mac_policy <= 2)
1463 return set_mac_policy(technology, msg, mac_policy);
1465 return __connman_error_invalid_arguments(msg);
1467 } else if (g_str_equal(name, "PreassocMacPolicy")) {
1468 dbus_uint32_t preassoc_mac_policy;
1470 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1471 return __connman_error_not_supported(msg);
1473 if (type != DBUS_TYPE_UINT32)
1474 return __connman_error_invalid_arguments(msg);
1476 dbus_message_iter_get_basic(&value, &preassoc_mac_policy);
1478 if (preassoc_mac_policy <= 2)
1479 return set_preassoc_mac_policy(technology, msg, preassoc_mac_policy);
1481 return __connman_error_invalid_arguments(msg);
1483 } else if (g_str_equal(name, "RandomMacLifetime")) {
1484 dbus_uint32_t random_mac_lifetime;
1486 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1487 return __connman_error_not_supported(msg);
1489 if (type != DBUS_TYPE_UINT32)
1490 return __connman_error_invalid_arguments(msg);
1492 dbus_message_iter_get_basic(&value, &random_mac_lifetime);
1494 if (random_mac_lifetime > 0)
1495 return set_random_mac_lifetime(technology, msg, random_mac_lifetime);
1497 return __connman_error_invalid_arguments(msg);
1499 } else if (g_str_equal(name, "CountryCode")) {
1502 dbus_message_iter_get_basic(&value, &str);
1503 DBG("country code %s", str);
1504 connman_technology_set_regdom(str);
1507 return __connman_error_invalid_property(msg);
1509 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1512 static void reply_scan_pending(struct connman_technology *technology, int err)
1516 DBG("technology %p err %d", technology, err);
1518 while (technology->scan_pending) {
1519 #if defined TIZEN_EXT
1520 struct connman_scan_pending *pending_data = technology->scan_pending->data;
1521 DBusMessage *msg = pending_data->msg;
1523 DBusMessage *msg = technology->scan_pending->data;
1525 DBG("reply to %s", dbus_message_get_sender(msg));
1528 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1530 reply = __connman_error_failed(msg, -err);
1531 g_dbus_send_message(connection, reply);
1532 dbus_message_unref(msg);
1534 technology->scan_pending =
1535 g_slist_delete_link(technology->scan_pending,
1536 technology->scan_pending);
1537 #if defined TIZEN_EXT
1538 g_free(pending_data->ifname);
1539 g_free(pending_data);
1544 #if defined TIZEN_EXT
1545 dbus_bool_t __connman_technology_notify_scan_changed(const char *key, void *val)
1548 DBusMessage *signal;
1549 DBusMessageIter iter;
1550 dbus_bool_t result = FALSE;
1552 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1553 CONNMAN_MANAGER_INTERFACE, "ScanChanged");
1557 dbus_message_iter_init_append(signal, &iter);
1559 connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_BOOLEAN, val);
1561 connman_dbus_property_append_basic(&iter, "", DBUS_TYPE_BOOLEAN, val);
1563 result = dbus_connection_send(connection, signal, NULL);
1564 dbus_message_unref(signal);
1566 DBG("Successfuly sent signal");
1571 void __connman_technology_notify_scan_done(const char *ifname, int val)
1574 DBusMessage *signal;
1575 DBusMessageIter iter;
1577 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1578 CONNMAN_MANAGER_INTERFACE, "ScanDone");
1582 dbus_message_iter_init_append(signal, &iter);
1584 connman_dbus_property_append_basic(&iter, ifname,
1585 DBUS_TYPE_INT32, &val);
1587 connman_dbus_property_append_basic(&iter, "",
1588 DBUS_TYPE_INT32, &val);
1590 dbus_connection_send(connection, signal, NULL);
1591 dbus_message_unref(signal);
1593 DBG("Successfuly sent ScanDone signal");
1596 static void reply_scan_pending_device(
1597 struct connman_technology *technology, const char *ifname, int count)
1601 dbus_bool_t status = 0;
1602 connman_scan_type_e scan_type = CONNMAN_SCAN_TYPE_UNKNOWN;
1604 DBG("technology %p ifname %s count %d", technology, ifname, count);
1606 list = technology->scan_pending;
1609 struct connman_scan_pending *pending_data = list->data;
1610 DBusMessage *msg = pending_data->msg;
1613 if (scan_type == CONNMAN_SCAN_TYPE_UNKNOWN)
1614 scan_type = pending_data->scan_type;
1616 if (count != 0 && g_strcmp0(pending_data->ifname, ifname) != 0)
1619 scan_type = pending_data->scan_type;
1621 DBG("reply to %s", dbus_message_get_sender(msg));
1622 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1624 g_dbus_send_message(connection, reply);
1625 dbus_message_unref(msg);
1627 technology->scan_pending =
1628 g_slist_remove(technology->scan_pending, pending_data);
1630 g_free(pending_data->ifname);
1631 g_free(pending_data);
1634 if (scan_type == CONNMAN_SCAN_TYPE_UNKNOWN)
1635 scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL;
1637 __connman_technology_notify_scan_changed(ifname, &status);
1638 __connman_technology_notify_scan_done(ifname, scan_type);
1641 static void __connman_technology_notify_device_detected(
1642 struct connman_technology *technology, const char *ifname, bool val)
1645 DBusMessage *signal;
1646 DBusMessageIter iter;
1647 dbus_bool_t detected = val;
1652 signal = dbus_message_new_signal(technology->path,
1653 CONNMAN_TECHNOLOGY_INTERFACE, "DeviceDetected");
1657 dbus_message_iter_init_append(signal, &iter);
1658 dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ifname);
1659 dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &detected);
1661 dbus_connection_send(connection, signal, NULL);
1662 dbus_message_unref(signal);
1664 DBG("Successfuly sent DeviceDetected signal");
1667 void __connman_technology_notify_roaming_state(const char *ifname,
1668 const char *state, const char *cur_bssid, const char *dst_bssid)
1671 DBusMessage *signal;
1672 DBusMessageIter array, dict;
1674 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1675 CONNMAN_MANAGER_INTERFACE, "RoamingStateChanged");
1679 dbus_message_iter_init_append(signal, &array);
1681 connman_dbus_dict_open(&array, &dict);
1684 connman_dbus_dict_append_basic(&dict, "Interface",
1685 DBUS_TYPE_STRING, &ifname);
1687 connman_dbus_dict_append_basic(&dict, "State",
1688 DBUS_TYPE_STRING, &state);
1690 connman_dbus_dict_append_basic(&dict, "ConnectedBSSID",
1691 DBUS_TYPE_STRING, &cur_bssid);
1693 connman_dbus_dict_append_basic(&dict, "TargetBSSID",
1694 DBUS_TYPE_STRING, &dst_bssid);
1696 connman_dbus_dict_close(&array, &dict);
1698 dbus_connection_send(connection, signal, NULL);
1699 dbus_message_unref(signal);
1701 DBG("Successfully sent Roaming State Changed signal");
1705 void __connman_technology_scan_started(struct connman_device *device)
1707 DBG("device %p", device);
1708 #if defined TIZEN_EXT
1709 dbus_bool_t status = 1;
1710 const char *ifname = connman_device_get_string(device, "Interface");
1712 __connman_technology_notify_scan_changed(ifname, &status);
1716 void __connman_technology_scan_stopped(struct connman_device *device,
1717 enum connman_service_type type)
1720 struct connman_technology *technology;
1723 technology = technology_find(type);
1725 DBG("technology %p device %p", technology, device);
1730 for (list = technology->device_list; list; list = list->next) {
1731 struct connman_device *other_device = list->data;
1733 if (device == other_device)
1736 if (connman_device_get_scanning(other_device, type))
1740 #if defined TIZEN_EXT
1741 const char *ifname = connman_device_get_string(device, "Interface");
1742 reply_scan_pending_device(technology, ifname, count);
1747 reply_scan_pending(technology, 0);
1751 void __connman_technology_notify_regdom_by_device(struct connman_device *device,
1752 int result, const char *alpha2)
1754 bool regdom_set = false;
1755 struct connman_technology *technology;
1756 enum connman_service_type type;
1757 GSList *tech_drivers;
1759 type = __connman_device_get_service_type(device);
1760 technology = technology_find(type);
1767 for (tech_drivers = technology->driver_list;
1769 tech_drivers = g_slist_next(tech_drivers)) {
1770 struct connman_technology_driver *driver =
1773 if (driver->set_regdom) {
1774 driver->set_regdom(technology, alpha2);
1784 connman_technology_regdom_notify(technology, alpha2);
1787 static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
1789 struct connman_technology *technology = data;
1792 DBG("technology %p request from %s", technology,
1793 dbus_message_get_sender(msg));
1795 if (technology->type == CONNMAN_SERVICE_TYPE_P2P &&
1796 !technology->enabled)
1797 return __connman_error_permission_denied(msg);
1799 #if !defined TIZEN_EXT
1800 dbus_message_ref(msg);
1801 technology->scan_pending =
1802 g_slist_prepend(technology->scan_pending, msg);
1805 err = __connman_device_request_scan_full(technology->type);
1807 #if defined TIZEN_EXT
1808 return __connman_error_failed(msg, -err);
1810 reply_scan_pending(technology, err);
1813 #if defined TIZEN_EXT
1814 struct connman_scan_pending *pending_data =
1815 g_try_malloc0(sizeof(struct connman_scan_pending));
1817 return __connman_error_failed(msg, ENOMEM);
1819 pending_data->scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL;
1820 DBG("scan_type %d", pending_data->scan_type);
1822 pending_data->msg = dbus_message_ref(msg);
1824 technology->scan_pending =
1825 g_slist_prepend(technology->scan_pending, pending_data);
1830 #if defined TIZEN_EXT
1831 static DBusMessage *scan_device(DBusConnection *conn, DBusMessage *msg, void *data)
1833 struct connman_technology *technology = data;
1834 DBusMessageIter iter;
1838 DBG("technology %p request from %s", technology,
1839 dbus_message_get_sender(msg));
1841 if (!dbus_message_iter_init(msg, &iter))
1842 return __connman_error_invalid_arguments(msg);
1844 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
1845 return __connman_error_invalid_arguments(msg);
1847 dbus_message_iter_get_basic(&iter, &ifname);
1848 DBG("Interface name %s", ifname);
1850 if (!ifname || strlen(ifname) == 0)
1851 return __connman_error_invalid_arguments(msg);
1853 err = connman_device_request_device_scan(technology->type, ifname, true);
1855 return __connman_error_failed(msg, -err);
1857 struct connman_scan_pending *pending_data =
1858 g_try_malloc0(sizeof(struct connman_scan_pending));
1860 return __connman_error_failed(msg, ENOMEM);
1862 pending_data->ifname = g_strdup(ifname);
1863 if (pending_data->ifname == NULL) {
1864 g_free(pending_data);
1865 return __connman_error_failed(msg, ENOMEM);
1868 pending_data->scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL;
1869 DBG("scan_type %d", pending_data->scan_type);
1871 pending_data->msg = dbus_message_ref(msg);
1873 technology->scan_pending =
1874 g_slist_prepend(technology->scan_pending, pending_data);
1879 static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data)
1881 struct connman_technology *technology = data;
1882 GSList *specific_scan_list = NULL;
1884 const char *name = NULL;
1885 const char *freq = NULL;
1886 const char *ifname = NULL;
1887 DBusMessageIter iter, dict;
1890 DBG("technology %p request from %s", technology,
1891 dbus_message_get_sender(msg));
1893 if (!dbus_message_iter_init(msg, &iter))
1894 return __connman_error_invalid_arguments(msg);
1896 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
1897 return __connman_error_invalid_arguments(msg);
1899 dbus_message_iter_recurse(&iter, &dict);
1900 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
1901 DBusMessageIter entry, value2;
1905 dbus_message_iter_recurse(&dict, &entry);
1906 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
1907 g_slist_free_full(specific_scan_list, g_free);
1908 return __connman_error_invalid_arguments(msg);
1911 dbus_message_iter_get_basic(&entry, &key);
1912 dbus_message_iter_next(&entry);
1914 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) {
1915 g_slist_free_full(specific_scan_list, g_free);
1916 return __connman_error_invalid_arguments(msg);
1919 dbus_message_iter_recurse(&entry, &value2);
1920 type = dbus_message_iter_get_arg_type(&value2);
1921 if (g_str_equal(key, "Ifname") && type == DBUS_TYPE_STRING) {
1923 dbus_message_iter_get_basic(&value2, &ifname);
1924 DBG("ifname %s", ifname);
1925 } else if (g_str_equal(key, "SSID")) {
1926 if (type != DBUS_TYPE_STRING) {
1927 g_slist_free_full(specific_scan_list, g_free);
1928 return __connman_error_invalid_arguments(msg);
1931 scan_type = CONNMAN_MULTI_SCAN_SSID; /* SSID based scan */
1932 dbus_message_iter_get_basic(&value2, &name);
1933 DBG("name %s", name);
1934 specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name));
1935 } else if (g_str_equal(key, "Frequency")) {
1936 if (type != DBUS_TYPE_STRING) {
1937 g_slist_free_full(specific_scan_list, g_free);
1938 return __connman_error_invalid_arguments(msg);
1941 scan_type = CONNMAN_MULTI_SCAN_FREQ; /* Frequency based scan */
1942 dbus_message_iter_get_basic(&value2, &freq);
1943 DBG("freq %s", freq);
1944 specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(atoi(freq)));
1945 } else if (g_str_equal(key, "SSID_Mixed")) {
1946 if (type != DBUS_TYPE_STRING) {
1947 g_slist_free_full(specific_scan_list, g_free);
1948 return __connman_error_invalid_arguments(msg);
1951 scan_type = CONNMAN_MULTI_SCAN_SSID_FREQ; /* SSID & Frequency mixed scan */
1952 dbus_message_iter_get_basic(&value2, &name);
1954 connman_multi_scan_ap_s *ap =
1955 (connman_multi_scan_ap_s*)g_try_malloc0(sizeof(connman_multi_scan_ap_s));
1957 g_strlcpy(ap->str, name, strlen(name) + 1);
1959 specific_scan_list = g_slist_append(specific_scan_list, ap);
1961 DBG("Failed to allocate memory");
1963 } else if (g_str_equal(key, "Frequency_Mixed")) {
1964 if (type != DBUS_TYPE_STRING) {
1965 g_slist_free_full(specific_scan_list, g_free);
1966 return __connman_error_invalid_arguments(msg);
1969 scan_type = CONNMAN_MULTI_SCAN_SSID_FREQ; /* SSID & Frequency mixed scan */
1970 dbus_message_iter_get_basic(&value2, &freq);
1972 connman_multi_scan_ap_s *ap =
1973 (connman_multi_scan_ap_s*)g_try_malloc0(sizeof(connman_multi_scan_ap_s));
1975 g_strlcpy(ap->str, freq, strlen(freq) + 1);
1977 specific_scan_list = g_slist_append(specific_scan_list, ap);
1979 DBG("Failed to allocate memory");
1981 dbus_message_iter_next(&dict);
1984 err = __connman_device_request_specific_scan(technology->type, ifname, scan_type, specific_scan_list);
1986 return __connman_error_failed(msg, -err);
1988 guint list_size = g_slist_length(specific_scan_list);
1990 if (scan_type == CONNMAN_MULTI_SCAN_SSID ||
1991 scan_type == CONNMAN_MULTI_SCAN_SSID_FREQ)
1992 g_slist_free_full(specific_scan_list, g_free);
1994 struct connman_scan_pending *pending_data =
1995 g_try_malloc0(sizeof(struct connman_scan_pending));
1997 return __connman_error_failed(msg, ENOMEM);
2000 pending_data->ifname = g_strdup(ifname);
2001 if (pending_data->ifname == NULL) {
2002 g_free(pending_data);
2003 return __connman_error_failed(msg, ENOMEM);
2008 pending_data->scan_type = CONNMAN_SCAN_TYPE_SPECIFIC_AP;
2010 pending_data->scan_type = CONNMAN_SCAN_TYPE_MULTI_AP;
2011 DBG("list_size %u scan_type %d", list_size, pending_data->scan_type);
2013 pending_data->msg = dbus_message_ref(msg);
2015 technology->scan_pending =
2016 g_slist_prepend(technology->scan_pending, pending_data);
2021 static DBusMessage *get_5ghz_supported(DBusConnection *conn, DBusMessage *msg, void *data)
2024 DBusMessageIter iter, dict;
2026 struct connman_technology *technology = data;
2027 dbus_bool_t supported = false;
2028 const char *ifname = NULL;
2030 DBG("technology %p", technology);
2032 reply = dbus_message_new_method_return(msg);
2036 dbus_message_iter_init_append(reply, &iter);
2037 connman_dbus_dict_open(&iter, &dict);
2039 for (list = technology->device_list; list; list = list->next) {
2040 struct connman_device *device = list->data;
2042 supported = connman_device_get_wifi_5ghz_supported(device);
2043 ifname = connman_device_get_string(device, "Interface");
2045 DBG("ifname %s supported : %d", ifname, supported);
2046 connman_dbus_dict_append_basic(&dict, ifname,
2051 connman_dbus_dict_close(&iter, &dict);
2056 static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
2059 DBusMessageIter iter, dict;
2061 struct connman_technology *technology = data;
2062 dbus_bool_t scanning = false;
2063 const char *ifname = NULL;
2065 DBG("technology %p", technology);
2067 reply = dbus_message_new_method_return(msg);
2071 dbus_message_iter_init_append(reply, &iter);
2072 connman_dbus_dict_open(&iter, &dict);
2074 for (list = technology->device_list; list; list = list->next) {
2075 struct connman_device *device = list->data;
2077 scanning = connman_device_get_scanning(device, technology->type);
2078 ifname = connman_device_get_string(device, "Interface");
2080 DBG("ifname %s scanning : %d", ifname, scanning);
2081 connman_dbus_dict_append_basic(&dict, ifname,
2086 connman_dbus_dict_close(&iter, &dict);
2091 static DBusMessage *get_max_scan_ssid(DBusConnection *conn, DBusMessage *msg, void *data)
2094 DBusMessageIter iter, dict;
2096 struct connman_technology *technology = data;
2097 dbus_int32_t max_scan_ssids = 0;
2098 const char *ifname = NULL;
2100 DBG("technology %p", technology);
2102 reply = dbus_message_new_method_return(msg);
2106 dbus_message_iter_init_append(reply, &iter);
2107 connman_dbus_dict_open(&iter, &dict);
2109 for (list = technology->device_list; list; list = list->next) {
2110 struct connman_device *device = list->data;
2112 max_scan_ssids = connman_device_get_max_scan_ssids(device);
2113 ifname = connman_device_get_string(device, "Interface");
2115 DBG("ifname %s max_scan_ssids : %d", ifname, max_scan_ssids);
2116 connman_dbus_dict_append_basic(&dict, ifname,
2121 connman_dbus_dict_close(&iter, &dict);
2126 static int technology_enable_device(struct connman_technology *technology,
2127 bool enable_device, const char *ifname, struct connman_device **device_out)
2132 for (list = technology->device_list; list; list = list->next) {
2133 struct connman_device *device = list->data;
2134 const char *str = connman_device_get_string(device, "Interface");
2136 if (g_strcmp0(str, ifname) != 0)
2140 err = __connman_device_enable(device);
2142 err = __connman_device_disable(device);
2144 *device_out = device;
2151 static DBusMessage *technology_set_device_powered(struct connman_technology *technology,
2152 DBusMessage *msg, bool powered, const char *ifname)
2154 DBusMessage *reply = NULL;
2155 struct connman_device *device = NULL;
2158 err = technology_enable_device(technology, powered, ifname, &device);
2160 if (err == -EINPROGRESS) {
2162 connman_device_set_pending_reply(device, msg);
2164 } else if (err == -EALREADY) {
2166 reply = __connman_error_already_enabled(msg);
2168 reply = __connman_error_already_disabled(msg);
2170 reply = __connman_error_failed(msg, -err);
2172 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
2177 static DBusMessage *set_device_power(DBusConnection *conn,
2178 DBusMessage *msg, void *data)
2180 struct connman_technology *technology = data;
2181 DBusMessageIter iter;
2186 DBG("conn %p", conn);
2188 if (!dbus_message_iter_init(msg, &iter))
2189 return __connman_error_invalid_arguments(msg);
2191 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
2192 return __connman_error_invalid_arguments(msg);
2194 dbus_message_iter_get_basic(&iter, &name);
2195 dbus_message_iter_next(&iter);
2197 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)
2198 return __connman_error_invalid_arguments(msg);
2200 DBG("interface name %s", name);
2204 if (len + 1 > IFNAMSIZ)
2205 return __connman_error_invalid_arguments(msg);
2207 dbus_message_iter_get_basic(&iter, &enable);
2208 DBG("powered %s", enable ? "TRUE" : "FALSE");
2210 return technology_set_device_powered(technology, msg, enable, name);
2213 static DBusMessage *set_bssid(DBusConnection *conn,
2214 DBusMessage *msg, void *data)
2216 DBusMessageIter iter;
2220 DBG("conn %p", conn);
2222 if (!dbus_message_iter_init(msg, &iter))
2223 return __connman_error_invalid_arguments(msg);
2225 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
2226 return __connman_error_invalid_arguments(msg);
2228 dbus_message_iter_get_basic(&iter, &name);
2229 dbus_message_iter_next(&iter);
2231 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
2232 return __connman_error_invalid_arguments(msg);
2234 dbus_message_iter_get_basic(&iter, &bssid);
2236 DBG("interface name %s bssid %s", name, bssid);
2240 if (len + 1 > IFNAMSIZ)
2241 return __connman_error_invalid_arguments(msg);
2243 set_connman_bssid(SET_BSSID, bssid, name);
2245 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
2247 static struct connman_technology *technology_get(enum connman_service_type type);
2249 void technology_save_device(struct connman_device *device)
2251 struct connman_technology *technology;
2252 enum connman_service_type type;
2254 type = __connman_device_get_service_type(device);
2256 if (type != CONNMAN_SERVICE_TYPE_WIFI)
2259 technology = technology_get(type);
2263 if (!g_slist_find(technology->device_list, device))
2268 const char *name = get_name(technology->type);
2270 DBG("technology %p type %d name %s", technology, technology->type,
2275 keyfile = __connman_storage_load_global();
2277 keyfile = g_key_file_new();
2279 identifier = g_strdup_printf("%s", name);
2283 GSList *list = NULL;
2284 gchar **ifname_list = NULL;
2285 guint dev_count = g_slist_length(technology->device_list);
2287 if (dev_count >= 1) {
2288 GString *ifname_str = g_string_new(NULL);
2291 for (list = technology->device_list; list; list = list->next) {
2292 struct connman_device *device = list->data;
2294 if (connman_device_get_powered(device)) {
2295 const char *ifname = connman_device_get_string(device, "Interface");
2297 if (ifname_str->len > 0)
2298 g_string_append_printf(ifname_str, " %s", ifname);
2300 g_string_append(ifname_str, ifname);
2304 if (ifname_str->len > 0) {
2305 ifname_list = g_strsplit_set(ifname_str->str, " ", 0);
2306 dev_count = g_strv_length(ifname_list);
2307 g_key_file_set_string_list(keyfile, identifier, "Enable.Devices",
2308 (const gchar **) ifname_list, dev_count);
2310 technology->enable_persistent = true;
2312 g_key_file_remove_key(keyfile, identifier, "Enable.Devices", NULL);
2313 technology->enable_persistent = false;
2316 g_strfreev(ifname_list);
2317 g_string_free(ifname_str, TRUE);
2321 g_key_file_set_boolean(keyfile, identifier, "Enable",
2322 technology->enable_persistent);
2324 g_key_file_set_boolean(keyfile, identifier, "Tethering",
2325 technology->tethering_persistent);
2327 if (technology->tethering_ident)
2328 g_key_file_set_string(keyfile, identifier,
2329 "Tethering.Identifier",
2330 technology->tethering_ident);
2332 if (technology->tethering_passphrase)
2333 g_key_file_set_string(keyfile, identifier,
2334 "Tethering.Passphrase",
2335 technology->tethering_passphrase);
2340 __connman_storage_save_global(keyfile);
2342 g_key_file_free(keyfile);
2346 #if defined TIZEN_EXT_WIFI_MESH
2347 bool __connman_technology_get_connected(enum connman_service_type type)
2349 struct connman_technology *technology;
2351 technology = technology_find(type);
2356 return technology->connected;
2359 void __connman_technology_mesh_interface_create_finished(
2360 enum connman_service_type type, bool success,
2364 struct connman_technology *technology;
2366 technology = technology_find(type);
2368 DBG("technology %p success %d", technology, success);
2373 msg = technology->mesh_dbus_msg;
2375 DBG("No pending dbus message");
2380 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
2381 __connman_device_request_scan(technology->type);
2383 reply = g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
2384 ".MeshInterfaceAddFailed", "%s", error);
2385 g_dbus_send_message(connection, reply);
2386 dbus_message_unref(msg);
2387 technology->mesh_dbus_msg = NULL;
2390 void __connman_technology_mesh_interface_remove_finished(
2391 enum connman_service_type type, bool success)
2394 struct connman_technology *technology;
2396 technology = technology_find(type);
2398 DBG("technology %p success %d", technology, success);
2400 if (!technology || !technology->mesh_dbus_msg)
2403 msg = technology->mesh_dbus_msg;
2405 DBG("No pending dbus message");
2410 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
2412 reply = __connman_error_failed(msg, EINVAL);
2413 g_dbus_send_message(connection, reply);
2414 dbus_message_unref(msg);
2415 technology->mesh_dbus_msg = NULL;
2418 void __connman_technology_notify_abort_scan(enum connman_service_type type,
2422 struct connman_technology *technology;
2424 technology = technology_find(type);
2426 DBG("technology %p result %d", technology, result);
2428 if (!technology || !technology->mesh_dbus_msg)
2431 msg = technology->mesh_dbus_msg;
2433 DBG("No pending dbus message");
2438 reply = __connman_error_scan_abort_failed(msg);
2440 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
2442 g_dbus_send_message(connection, reply);
2443 dbus_message_unref(msg);
2444 technology->mesh_dbus_msg = NULL;
2447 static DBusMessage *mesh_commands(DBusConnection *conn,
2448 DBusMessage *msg, void *data)
2450 struct connman_technology *technology = data;
2451 DBusMessageIter iter, value, dict;
2452 const char *cmd = NULL, *ifname = NULL, *parent_ifname = NULL;
2455 DBG("conn %p", conn);
2457 if (technology->type != CONNMAN_SERVICE_TYPE_MESH)
2458 return __connman_error_invalid_arguments(msg);
2460 if (!dbus_message_iter_init(msg, &iter))
2461 return __connman_error_invalid_arguments(msg);
2463 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
2464 return __connman_error_invalid_arguments(msg);
2466 dbus_message_iter_get_basic(&iter, &cmd);
2467 dbus_message_iter_next(&iter);
2469 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
2470 return __connman_error_invalid_arguments(msg);
2472 dbus_message_iter_recurse(&iter, &value);
2474 if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_ARRAY)
2475 return __connman_error_invalid_arguments(msg);
2477 DBG("Mesh Command %s", cmd);
2478 if (g_str_equal(cmd, "MeshInterfaceAdd")) {
2479 dbus_message_iter_recurse(&value, &dict);
2480 const char *bridge_ifname = NULL;
2481 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2482 DBusMessageIter entry, value2;
2486 dbus_message_iter_recurse(&dict, &entry);
2488 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2489 return __connman_error_invalid_arguments(msg);
2491 dbus_message_iter_get_basic(&entry, &key);
2492 dbus_message_iter_next(&entry);
2494 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2495 return __connman_error_invalid_arguments(msg);
2497 dbus_message_iter_recurse(&entry, &value2);
2499 type = dbus_message_iter_get_arg_type(&value2);
2501 if (g_str_equal(key, "Ifname")) {
2502 if (type != DBUS_TYPE_STRING)
2503 return __connman_error_invalid_arguments(msg);
2505 dbus_message_iter_get_basic(&value2, &ifname);
2506 } else if (g_str_equal(key, "ParentIfname")) {
2507 if (type != DBUS_TYPE_STRING)
2508 return __connman_error_invalid_arguments(msg);
2510 dbus_message_iter_get_basic(&value2, &parent_ifname);
2511 } else if (g_str_equal(key, "BridgeIfname")) {
2512 if (type != DBUS_TYPE_STRING)
2513 return __connman_error_invalid_arguments(msg);
2515 dbus_message_iter_get_basic(&value2, &bridge_ifname);
2517 dbus_message_iter_next(&dict);
2519 DBG("Mesh Ifname %s parent %s bridge %s", ifname, parent_ifname,
2520 bridge_ifname ? bridge_ifname : "NULL");
2521 err = __connman_mesh_add_virtual_interface(ifname, parent_ifname,
2525 DBG("Failed to add virtual mesh interface");
2526 return __connman_error_failed(msg, -err);
2529 DBG("Successfully added virtual mesh interface");
2531 dbus_message_ref(msg);
2532 technology->mesh_dbus_msg = msg;
2534 } else if (g_str_equal(cmd, "MeshInterfaceRemove")) {
2535 dbus_message_iter_recurse(&value, &dict);
2536 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2537 DBusMessageIter entry, value2;
2541 dbus_message_iter_recurse(&dict, &entry);
2543 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2544 return __connman_error_invalid_arguments(msg);
2546 dbus_message_iter_get_basic(&entry, &key);
2547 dbus_message_iter_next(&entry);
2549 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2550 return __connman_error_invalid_arguments(msg);
2552 dbus_message_iter_recurse(&entry, &value2);
2554 type = dbus_message_iter_get_arg_type(&value2);
2556 if (g_str_equal(key, "Ifname")) {
2557 if (type != DBUS_TYPE_STRING)
2558 return __connman_error_invalid_arguments(msg);
2560 dbus_message_iter_get_basic(&value2, &ifname);
2562 dbus_message_iter_next(&dict);
2564 DBG("Mesh Ifname %s", ifname);
2565 err = __connman_mesh_remove_virtual_interface(ifname);
2568 DBG("Failed to remove virtual mesh interface");
2569 return __connman_error_failed(msg, -err);
2572 DBG("Successfully removed virtual mesh interface");
2574 dbus_message_ref(msg);
2575 technology->mesh_dbus_msg = msg;
2577 } else if (g_str_equal(cmd, "MeshCreateNetwork")) {
2578 struct connman_mesh *connman_mesh;
2579 const char *name = NULL;
2580 const char *sec_type = NULL;
2581 const char *mesh_ifname = NULL;
2582 char *identifier, *group, *address;
2583 unsigned int freq = 0;
2584 unsigned int ieee80211w = 0;
2587 dbus_message_iter_recurse(&value, &dict);
2588 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2589 DBusMessageIter entry, value2;
2593 dbus_message_iter_recurse(&dict, &entry);
2595 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2596 return __connman_error_invalid_arguments(msg);
2598 dbus_message_iter_get_basic(&entry, &key);
2599 dbus_message_iter_next(&entry);
2601 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2602 return __connman_error_invalid_arguments(msg);
2604 dbus_message_iter_recurse(&entry, &value2);
2606 type = dbus_message_iter_get_arg_type(&value2);
2608 if (g_str_equal(key, "Name")) {
2609 if (type != DBUS_TYPE_STRING)
2610 return __connman_error_invalid_arguments(msg);
2612 dbus_message_iter_get_basic(&value2, &name);
2613 } else if (g_str_equal(key, "Frequency")) {
2614 if (type != DBUS_TYPE_UINT16)
2615 return __connman_error_invalid_arguments(msg);
2617 dbus_message_iter_get_basic(&value2, &freq);
2618 } else if (g_str_equal(key, "Security")) {
2619 if (type != DBUS_TYPE_STRING)
2620 return __connman_error_invalid_arguments(msg);
2622 dbus_message_iter_get_basic(&value2, &sec_type);
2623 } else if (g_str_equal(key, "Pmf")) {
2624 if (type != DBUS_TYPE_UINT16)
2625 return __connman_error_invalid_arguments(msg);
2627 dbus_message_iter_get_basic(&value2, &ieee80211w);
2629 dbus_message_iter_next(&dict);
2632 if (name == NULL || sec_type == NULL || freq == 0)
2633 return __connman_error_invalid_arguments(msg);
2635 DBG("Name %s Frequency %d Security type %s Pmf %u",
2636 name, freq, sec_type, ieee80211w);
2638 if (g_strcmp0(sec_type, "none") != 0 &&
2639 g_strcmp0(sec_type, "sae") != 0) {
2640 DBG("Unsupported security");
2641 return __connman_error_invalid_arguments(msg);
2644 mesh_ifname = connman_mesh_get_interface_name();
2646 if (!connman_mesh_is_interface_created()) {
2647 DBG("Mesh interface doesn't exists");
2648 return __connman_error_invalid_command(msg);
2651 str = g_string_sized_new((strlen(name) * 2) + 24);
2653 for (i = 0; name[i]; i++)
2654 g_string_append_printf(str, "%02x", name[i]);
2656 g_string_append_printf(str, "_mesh");
2658 if (g_strcmp0(sec_type, "none") == 0)
2659 g_string_append_printf(str, "_none");
2660 else if (g_strcmp0(sec_type, "sae") == 0)
2661 g_string_append_printf(str, "_sae");
2663 group = g_string_free(str, FALSE);
2665 identifier = connman_inet_ifaddr(mesh_ifname);
2666 address = connman_inet_ifname2addr(mesh_ifname);
2668 connman_mesh = connman_mesh_create(identifier, group);
2669 connman_mesh_set_name(connman_mesh, name);
2670 connman_mesh_set_address(connman_mesh, address);
2671 connman_mesh_set_security(connman_mesh, sec_type);
2672 connman_mesh_set_frequency(connman_mesh, freq);
2673 connman_mesh_set_index(connman_mesh, connman_inet_ifindex(mesh_ifname));
2674 connman_mesh_set_peer_type(connman_mesh,
2675 CONNMAN_MESH_PEER_TYPE_CREATED);
2676 connman_mesh_set_ieee80211w(connman_mesh, ieee80211w);
2678 connman_mesh_register(connman_mesh);
2682 DBG("Successfully Created Mesh Network");
2683 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
2685 } else if (g_str_equal(cmd, "AbortScan")) {
2686 DBG("Abort Scan method");
2687 err = __connman_device_abort_scan(technology->type);
2689 DBG("Failed to abort scan");
2690 return __connman_error_failed(msg, -err);
2693 DBG("Successfully requested to abort scan");
2694 dbus_message_ref(msg);
2695 technology->mesh_dbus_msg = msg;
2697 } else if (g_str_equal(cmd, "MeshSpecificScan")) {
2698 const char *name = NULL;
2699 unsigned int freq = 0;
2700 dbus_message_iter_recurse(&value, &dict);
2701 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2702 DBusMessageIter entry, value2;
2706 dbus_message_iter_recurse(&dict, &entry);
2708 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2709 return __connman_error_invalid_arguments(msg);
2711 dbus_message_iter_get_basic(&entry, &key);
2712 dbus_message_iter_next(&entry);
2714 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2715 return __connman_error_invalid_arguments(msg);
2717 dbus_message_iter_recurse(&entry, &value2);
2719 type = dbus_message_iter_get_arg_type(&value2);
2721 if (g_str_equal(key, "Name")) {
2722 if (type != DBUS_TYPE_STRING)
2723 return __connman_error_invalid_arguments(msg);
2725 dbus_message_iter_get_basic(&value2, &name);
2726 } else if (g_str_equal(key, "Frequency")) {
2727 if (type != DBUS_TYPE_UINT16)
2728 return __connman_error_invalid_arguments(msg);
2730 dbus_message_iter_get_basic(&value2, &freq);
2732 dbus_message_iter_next(&dict);
2735 DBG("MeshID %s Frequency %d sender %s", name, freq,
2736 dbus_message_get_sender(msg));
2738 struct connman_scan_pending *pending_data =
2739 g_try_malloc0(sizeof(struct connman_scan_pending));
2741 return __connman_error_failed(msg, ENOMEM);
2743 pending_data->msg = dbus_message_ref(msg);
2745 technology->scan_pending =
2746 g_slist_prepend(technology->scan_pending, pending_data);
2748 err = __connman_device_request_mesh_specific_scan(technology->type,
2751 reply_scan_pending(technology, err);
2753 DBG("Successfully requested to scan specific Mesh Network");
2755 } else if (g_str_equal(cmd, "SetMeshGate")) {
2756 unsigned int hwmp_rootmode = 0;
2757 bool gate_announce = false;
2758 unsigned int stp = 0;
2760 dbus_message_iter_recurse(&value, &dict);
2761 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2762 DBusMessageIter entry, value2;
2766 dbus_message_iter_recurse(&dict, &entry);
2768 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
2769 return __connman_error_invalid_arguments(msg);
2771 dbus_message_iter_get_basic(&entry, &key);
2772 dbus_message_iter_next(&entry);
2774 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
2775 return __connman_error_invalid_arguments(msg);
2777 dbus_message_iter_recurse(&entry, &value2);
2779 type = dbus_message_iter_get_arg_type(&value2);
2781 if (g_str_equal(key, "GateAnnounce")) {
2782 if (type != DBUS_TYPE_BOOLEAN)
2783 return __connman_error_invalid_arguments(msg);
2785 dbus_message_iter_get_basic(&value2, &gate_announce);
2786 } else if (g_str_equal(key, "HWMPRootMode")) {
2787 if (type != DBUS_TYPE_UINT16)
2788 return __connman_error_invalid_arguments(msg);
2790 dbus_message_iter_get_basic(&value2, &hwmp_rootmode);
2791 } else if (g_str_equal(key, "STP")) {
2792 if (type != DBUS_TYPE_UINT16)
2793 return __connman_error_invalid_arguments(msg);
2795 dbus_message_iter_get_basic(&value2, &stp);
2797 dbus_message_iter_next(&dict);
2800 DBG("GateAnnounce %d HWMPRootMode %d STP %d sender %s",
2801 gate_announce, hwmp_rootmode, stp, dbus_message_get_sender(msg));
2803 err = __connman_mesh_set_stp_gate_announce(gate_announce,
2808 return __connman_error_failed(msg, -err);
2810 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
2812 return __connman_error_invalid_command(msg);
2817 static const GDBusMethodTable technology_methods[] = {
2818 { GDBUS_DEPRECATED_METHOD("GetProperties",
2819 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
2821 { GDBUS_ASYNC_METHOD("SetProperty",
2822 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
2823 NULL, set_property) },
2824 { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
2825 #if defined TIZEN_EXT
2826 { GDBUS_ASYNC_METHOD("ScanDevice", GDBUS_ARGS({ "interface_name", "s" }),
2827 NULL, scan_device) },
2828 { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }),
2829 NULL, specific_scan) },
2830 { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
2832 { GDBUS_METHOD("Get5GhzSupported", NULL, GDBUS_ARGS({ "supported", "a{sv}" }),
2833 get_5ghz_supported) },
2834 { GDBUS_METHOD("GetMaxScanSsid", NULL, GDBUS_ARGS({ "maxscanssid", "a{sv}" }),
2835 get_max_scan_ssid) },
2836 { GDBUS_ASYNC_METHOD("SetDevicePower",
2837 GDBUS_ARGS({ "ifname", "s" }, { "value", "b" }),
2838 NULL, set_device_power) },
2839 { GDBUS_ASYNC_METHOD("SetBSSID",
2840 GDBUS_ARGS({ "ifname", "s" }, { "bssid", "s" }),
2843 #if defined TIZEN_EXT_WIFI_MESH
2844 { GDBUS_ASYNC_METHOD("MeshCommands",
2845 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
2846 NULL, mesh_commands) },
2851 static const GDBusSignalTable technology_signals[] = {
2852 { GDBUS_SIGNAL("PropertyChanged",
2853 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
2854 #if defined TIZEN_EXT
2855 { GDBUS_SIGNAL("DeviceChanged",
2856 GDBUS_ARGS({ "device_property", "a{sv}" })) },
2857 { GDBUS_SIGNAL("DeviceDetected",
2858 GDBUS_ARGS({ "ifname", "s" }, { "detected", "b" })) },
2863 static bool technology_dbus_register(struct connman_technology *technology)
2865 if (technology->dbus_registered ||
2866 (technology->rfkill_driven &&
2867 technology->hardblocked))
2870 if (!g_dbus_register_interface(connection, technology->path,
2871 CONNMAN_TECHNOLOGY_INTERFACE,
2872 technology_methods, technology_signals,
2873 NULL, technology, NULL)) {
2874 connman_error("Failed to register %s", technology->path);
2878 technology_added_signal(technology);
2879 technology->dbus_registered = true;
2884 static void technology_dbus_unregister(struct connman_technology *technology)
2886 if (!technology->dbus_registered)
2889 technology_removed_signal(technology);
2890 g_dbus_unregister_interface(connection, technology->path,
2891 CONNMAN_TECHNOLOGY_INTERFACE);
2893 technology->dbus_registered = false;
2896 static void technology_put(struct connman_technology *technology)
2898 DBG("technology %p", technology);
2900 if (__sync_sub_and_fetch(&technology->refcount, 1) > 0)
2903 reply_scan_pending(technology, -EINTR);
2905 while (technology->driver_list) {
2906 struct connman_technology_driver *driver;
2908 driver = technology->driver_list->data;
2911 driver->remove(technology);
2913 technology->driver_list =
2914 g_slist_delete_link(technology->driver_list,
2915 technology->driver_list);
2918 technology_list = g_slist_remove(technology_list, technology);
2920 technology_dbus_unregister(technology);
2922 g_slist_free(technology->device_list);
2924 if (technology->pending_reply) {
2925 dbus_message_unref(technology->pending_reply);
2926 technology->pending_reply = NULL;
2927 g_source_remove(technology->pending_timeout);
2928 technology->pending_timeout = 0;
2931 g_strfreev(technology->enabled_devices);
2933 g_free(technology->path);
2934 g_free(technology->regdom);
2935 g_free(technology->tethering_ident);
2936 g_free(technology->tethering_passphrase);
2940 static struct connman_technology *technology_get(enum connman_service_type type)
2942 GSList *tech_drivers = NULL;
2943 struct connman_technology_driver *driver;
2944 struct connman_technology *technology;
2948 DBG("type %d", type);
2950 str = __connman_service_type2string(type);
2954 technology = technology_find(type);
2956 #if defined TIZEN_EXT_WIFI_MESH
2957 if (type != CONNMAN_SERVICE_TYPE_P2P &&
2958 type != CONNMAN_SERVICE_TYPE_MESH)
2960 if (type != CONNMAN_SERVICE_TYPE_P2P)
2962 __sync_fetch_and_add(&technology->refcount, 1);
2966 /* First check if we have a driver for this technology type */
2967 for (list = driver_list; list; list = list->next) {
2968 driver = list->data;
2970 if (driver->type == type) {
2971 DBG("technology %p driver %p", technology, driver);
2972 tech_drivers = g_slist_append(tech_drivers, driver);
2976 if (!tech_drivers) {
2977 DBG("No matching drivers found for %s.",
2978 __connman_service_type2string(type));
2982 technology = g_try_new0(struct connman_technology, 1);
2986 technology->refcount = 1;
2987 technology->type = type;
2988 technology->path = g_strdup_printf("%s/technology/%s",
2991 #if defined TIZEN_EXT_WIFI_MESH
2992 if (type == CONNMAN_SERVICE_TYPE_MESH) {
2993 struct connman_technology *wifi;
2995 wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
2997 technology->enabled = wifi->enabled;
3001 technology_load(technology);
3002 technology_list = g_slist_prepend(technology_list, technology);
3003 technology->driver_list = tech_drivers;
3005 for (list = tech_drivers; list; list = list->next) {
3006 driver = list->data;
3008 if (driver->probe && driver->probe(technology) < 0)
3009 DBG("Driver probe failed for technology %p",
3013 if (!technology_dbus_register(technology)) {
3014 technology_put(technology);
3018 if (type == CONNMAN_SERVICE_TYPE_P2P) {
3019 struct connman_technology *wifi;
3022 enable = technology->enable_persistent;
3024 wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
3026 enable = wifi->enabled;
3028 technology_affect_devices(technology, enable);
3031 DBG("technology %p %s", technology, get_name(technology->type));
3036 int connman_technology_driver_register(struct connman_technology_driver *driver)
3039 struct connman_device *device;
3040 enum connman_service_type type;
3042 for (list = driver_list; list; list = list->next) {
3043 if (list->data == driver)
3047 DBG("Registering %s driver", driver->name);
3049 driver_list = g_slist_insert_sorted(driver_list, driver,
3053 * Check for technology less devices if this driver
3054 * can service any of them.
3056 for (list = techless_device_list; list; list = list->next) {
3057 device = list->data;
3059 type = __connman_device_get_service_type(device);
3060 if (type != driver->type)
3063 techless_device_list = g_slist_remove(techless_device_list,
3066 __connman_technology_add_device(device);
3069 /* Check for orphaned rfkill switches. */
3070 g_hash_table_foreach(rfkill_list, rfkill_check,
3071 GINT_TO_POINTER(driver->type));
3074 if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
3075 if (!technology_get(CONNMAN_SERVICE_TYPE_P2P))
3079 #if defined TIZEN_EXT_WIFI_MESH
3080 if (driver->type == CONNMAN_SERVICE_TYPE_MESH) {
3081 if (!technology_get(CONNMAN_SERVICE_TYPE_MESH))
3089 void connman_technology_driver_unregister(struct connman_technology_driver *driver)
3091 GSList *list, *tech_drivers;
3092 struct connman_technology *technology;
3093 struct connman_technology_driver *current;
3095 DBG("Unregistering driver %p name %s", driver, driver->name);
3097 for (list = technology_list; list; list = list->next) {
3098 technology = list->data;
3100 for (tech_drivers = technology->driver_list; tech_drivers;
3101 tech_drivers = g_slist_next(tech_drivers)) {
3102 current = tech_drivers->data;
3103 if (driver != current)
3107 driver->remove(technology);
3109 technology->driver_list =
3110 g_slist_remove(technology->driver_list,
3116 driver_list = g_slist_remove(driver_list, driver);
3118 if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
3119 technology = technology_find(CONNMAN_SERVICE_TYPE_P2P);
3121 technology_put(technology);
3123 #if defined TIZEN_EXT_WIFI_MESH
3124 if (driver->type == CONNMAN_SERVICE_TYPE_MESH) {
3125 technology = technology_find(CONNMAN_SERVICE_TYPE_MESH);
3127 technology_put(technology);
3132 void __connman_technology_add_interface(enum connman_service_type type,
3133 int index, const char *ident)
3135 struct connman_technology *technology;
3136 GSList *tech_drivers;
3137 struct connman_technology_driver *driver;
3141 case CONNMAN_SERVICE_TYPE_UNKNOWN:
3142 case CONNMAN_SERVICE_TYPE_SYSTEM:
3144 case CONNMAN_SERVICE_TYPE_ETHERNET:
3145 case CONNMAN_SERVICE_TYPE_WIFI:
3146 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
3147 case CONNMAN_SERVICE_TYPE_CELLULAR:
3148 case CONNMAN_SERVICE_TYPE_GPS:
3149 case CONNMAN_SERVICE_TYPE_VPN:
3150 case CONNMAN_SERVICE_TYPE_GADGET:
3151 case CONNMAN_SERVICE_TYPE_P2P:
3152 #if defined TIZEN_EXT_WIFI_MESH
3153 case CONNMAN_SERVICE_TYPE_MESH:
3158 name = connman_inet_ifname(index);
3159 connman_info("Adding interface %s [ %s ]", name,
3160 __connman_service_type2string(type));
3162 technology = technology_find(type);
3167 for (tech_drivers = technology->driver_list; tech_drivers;
3168 tech_drivers = g_slist_next(tech_drivers)) {
3169 driver = tech_drivers->data;
3171 if (driver->add_interface)
3172 driver->add_interface(technology, index, name, ident);
3176 * At this point we can try to enable tethering automatically as
3177 * now the interfaces are set properly.
3179 if (technology->tethering_persistent)
3180 enable_tethering(technology);
3186 void __connman_technology_remove_interface(enum connman_service_type type,
3187 int index, const char *ident)
3189 struct connman_technology *technology;
3190 GSList *tech_drivers;
3191 struct connman_technology_driver *driver;
3195 case CONNMAN_SERVICE_TYPE_UNKNOWN:
3196 case CONNMAN_SERVICE_TYPE_SYSTEM:
3198 case CONNMAN_SERVICE_TYPE_ETHERNET:
3199 case CONNMAN_SERVICE_TYPE_WIFI:
3200 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
3201 case CONNMAN_SERVICE_TYPE_CELLULAR:
3202 case CONNMAN_SERVICE_TYPE_GPS:
3203 case CONNMAN_SERVICE_TYPE_VPN:
3204 case CONNMAN_SERVICE_TYPE_GADGET:
3205 case CONNMAN_SERVICE_TYPE_P2P:
3206 #if defined TIZEN_EXT_WIFI_MESH
3207 case CONNMAN_SERVICE_TYPE_MESH:
3212 name = connman_inet_ifname(index);
3213 connman_info("Remove interface %s [ %s ]", name,
3214 __connman_service_type2string(type));
3217 technology = technology_find(type);
3222 for (tech_drivers = technology->driver_list; tech_drivers;
3223 tech_drivers = g_slist_next(tech_drivers)) {
3224 driver = tech_drivers->data;
3226 if (driver->remove_interface)
3227 driver->remove_interface(technology, index);
3231 int __connman_technology_add_device(struct connman_device *device)
3233 struct connman_technology *technology;
3234 enum connman_service_type type;
3236 type = __connman_device_get_service_type(device);
3238 DBG("device %p type %s", device, get_name(type));
3240 technology = technology_get(type);
3243 * Since no driver can be found for this device at the moment we
3244 * add it to the techless device list.
3246 techless_device_list = g_slist_prepend(techless_device_list,
3252 __sync_synchronize();
3253 if (technology->rfkill_driven) {
3254 if (technology->enabled)
3255 __connman_device_enable(device);
3257 __connman_device_disable(device);
3262 if (technology->enable_persistent &&
3263 !global_offlinemode) {
3264 #if defined TIZEN_EXT
3267 if (technology->enabled_devices && type == CONNMAN_SERVICE_TYPE_WIFI) {
3270 const char *ifname = connman_device_get_string(device, "Interface");
3272 while (technology->enabled_devices[i]) {
3273 if (g_strcmp0(technology->enabled_devices[i], ifname) == 0) {
3282 err = __connman_device_enable(device);
3284 int err = __connman_device_enable(device);
3287 * connman_technology_add_device() calls __connman_device_enable()
3288 * but since the device is already enabled, the call does not
3289 * propagate through to connman_technology_enabled via
3290 * connman_device_set_powered.
3292 if (err == -EALREADY)
3293 __connman_technology_enabled(type);
3295 /* if technology persistent state is offline */
3296 if (!technology->enable_persistent)
3297 __connman_device_disable(device);
3300 technology->device_list = g_slist_prepend(technology->device_list,
3303 #if defined TIZEN_EXT
3304 technology_save_device(device);
3306 const char *ifname = connman_device_get_string(device, "Interface");
3307 __connman_technology_notify_device_detected(technology, ifname, true);
3309 connman_device_set_mac_policy(device, technology->mac_policy);
3310 connman_device_set_preassoc_mac_policy(device, technology->preassoc_mac_policy);
3311 connman_device_set_random_mac_lifetime(device, technology->random_mac_lifetime);
3316 int __connman_technology_remove_device(struct connman_device *device)
3318 struct connman_technology *technology;
3319 enum connman_service_type type;
3321 DBG("device %p", device);
3323 type = __connman_device_get_service_type(device);
3325 technology = technology_find(type);
3327 techless_device_list = g_slist_remove(techless_device_list,
3332 technology->device_list = g_slist_remove(technology->device_list,
3335 #if defined TIZEN_EXT
3336 technology_save_device(device);
3338 const char *ifname = connman_device_get_string(device, "Interface");
3339 __connman_technology_notify_device_detected(technology, ifname, false);
3342 if (technology->tethering)
3343 set_tethering(technology, false);
3345 technology_put(technology);
3350 int __connman_technology_enabled(enum connman_service_type type)
3352 struct connman_technology *technology;
3354 technology = technology_find(type);
3358 DBG("technology %p type %s rfkill %d enabled %d", technology,
3359 get_name(type), technology->rfkill_driven,
3360 technology->enabled);
3362 #if !defined TIZEN_EXT
3363 if (technology->rfkill_driven) {
3364 if (technology->tethering_persistent)
3365 enable_tethering(technology);
3370 return technology_enabled(technology);
3373 int __connman_technology_disabled(enum connman_service_type type)
3375 struct connman_technology *technology;
3378 technology = technology_find(type);
3382 #if !defined TIZEN_EXT
3383 if (technology->rfkill_driven)
3387 for (list = technology->device_list; list; list = list->next) {
3388 struct connman_device *device = list->data;
3390 if (connman_device_get_powered(device))
3394 return technology_disabled(technology);
3397 int __connman_technology_set_offlinemode(bool offlinemode)
3400 int err = -EINVAL, enabled_tech_count = 0;
3402 if (global_offlinemode == offlinemode)
3405 DBG("offlinemode %s", offlinemode ? "On" : "Off");
3408 * This is a bit tricky. When you set offlinemode, there is no
3409 * way to differentiate between attempting offline mode and
3410 * resuming offlinemode from last saved profile. We need that
3411 * information in rfkill_update, otherwise it falls back on the
3412 * technology's persistent state. Hence we set the offline mode here
3413 * but save it & call the notifier only if it is successful.
3416 global_offlinemode = offlinemode;
3418 /* Traverse technology list, enable/disable each technology. */
3419 for (list = technology_list; list; list = list->next) {
3420 struct connman_technology *technology = list->data;
3423 err = technology_disable(technology);
3425 if (technology->hardblocked)
3428 if (technology->enable_persistent) {
3429 err = technology_enable(technology);
3430 enabled_tech_count++;
3435 if (err == 0 || err == -EINPROGRESS || err == -EALREADY ||
3436 (err == -EINVAL && enabled_tech_count == 0)) {
3437 connman_technology_save_offlinemode();
3438 __connman_notifier_offlinemode(offlinemode);
3440 global_offlinemode = connman_technology_load_offlinemode();
3445 #if defined TIZEN_EXT_WIFI_MESH
3446 static gboolean __add_ethernet_to_bridge(gpointer data)
3449 __connman_mesh_add_ethernet_to_bridge();
3454 void __connman_technology_set_connected(enum connman_service_type type,
3457 struct connman_technology *technology;
3460 technology = technology_find(type);
3464 DBG("technology %p connected %d", technology, connected);
3466 technology->connected = connected;
3468 #if defined TIZEN_EXT_WIFI_MESH
3469 if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET && connected)
3470 g_idle_add(__add_ethernet_to_bridge, NULL);
3474 connman_dbus_property_changed_basic(technology->path,
3475 CONNMAN_TECHNOLOGY_INTERFACE, "Connected",
3476 DBUS_TYPE_BOOLEAN, &val);
3479 static bool technology_apply_rfkill_change(struct connman_technology *technology,
3484 bool hardblock_changed = false;
3486 GList *start, *list;
3488 DBG("technology %p --> %d/%d vs %d/%d",
3489 technology, softblock, hardblock,
3490 technology->softblocked, technology->hardblocked);
3492 if (technology->hardblocked == hardblock)
3493 goto softblock_change;
3495 if (!(new_rfkill && !hardblock)) {
3496 start = g_hash_table_get_values(rfkill_list);
3498 for (list = start; list; list = list->next) {
3499 struct connman_rfkill *rfkill = list->data;
3501 if (rfkill->type != technology->type)
3504 if (rfkill->hardblock != hardblock)
3512 goto softblock_change;
3514 technology->hardblocked = hardblock;
3515 hardblock_changed = true;
3518 if (!apply && technology->softblocked != softblock)
3522 return technology->hardblocked;
3524 technology->softblocked = softblock;
3526 if (technology->hardblocked ||
3527 technology->softblocked) {
3528 if (technology_disabled(technology) != -EALREADY)
3529 technology_affect_devices(technology, false);
3530 } else if (!technology->hardblocked &&
3531 !technology->softblocked) {
3532 if (technology_enabled(technology) != -EALREADY)
3533 technology_affect_devices(technology, true);
3536 if (hardblock_changed) {
3537 if (technology->hardblocked) {
3538 DBG("%s is switched off.", get_name(technology->type));
3539 technology_dbus_unregister(technology);
3541 DBG("%s is switched on.", get_name(technology->type));
3542 technology_dbus_register(technology);
3544 if (global_offlinemode)
3545 __connman_rfkill_block(technology->type, true);
3549 return technology->hardblocked;
3552 int __connman_technology_add_rfkill(unsigned int index,
3553 enum connman_service_type type,
3557 struct connman_technology *technology;
3558 struct connman_rfkill *rfkill;
3560 DBG("index %u type %d soft %u hard %u", index, type,
3561 softblock, hardblock);
3563 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
3567 rfkill = g_try_new0(struct connman_rfkill, 1);
3571 rfkill->index = index;
3572 rfkill->type = type;
3573 rfkill->softblock = softblock;
3574 rfkill->hardblock = hardblock;
3576 g_hash_table_insert(rfkill_list, GINT_TO_POINTER(index), rfkill);
3579 #if defined TIZEN_EXT
3580 /* Fix Svace Issue [WGID: 1348]. */
3583 technology = technology_get(type);
3584 /* If there is no driver for this type, ignore it. */
3588 technology->rfkill_driven = true;
3590 #if !defined TIZEN_EXT
3591 /* If hardblocked, there is no need to handle softblocked state */
3592 if (technology_apply_rfkill_change(technology,
3593 softblock, hardblock, true))
3597 if (global_offlinemode)
3601 * Depending on softblocked state we unblock/block according to
3602 * offlinemode and persistente state.
3604 if (technology->softblocked &&
3605 technology->enable_persistent)
3606 return __connman_rfkill_block(type, false);
3607 else if (!technology->softblocked &&
3608 !technology->enable_persistent)
3609 return __connman_rfkill_block(type, true);
3614 int __connman_technology_update_rfkill(unsigned int index,
3615 enum connman_service_type type,
3619 struct connman_technology *technology;
3620 struct connman_rfkill *rfkill;
3622 DBG("index %u soft %u hard %u", index, softblock, hardblock);
3624 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
3628 if (rfkill->softblock == softblock &&
3629 rfkill->hardblock == hardblock)
3632 rfkill->softblock = softblock;
3633 rfkill->hardblock = hardblock;
3635 technology = technology_find(type);
3636 /* If there is no driver for this type, ignore it. */
3640 technology_apply_rfkill_change(technology, softblock, hardblock,
3643 if (technology->hardblocked)
3644 DBG("%s hardblocked", get_name(technology->type));
3646 DBG("%s is%s softblocked", get_name(technology->type),
3647 technology->softblocked ? "" : " not");
3652 int __connman_technology_remove_rfkill(unsigned int index,
3653 enum connman_service_type type)
3655 struct connman_technology *technology;
3656 struct connman_rfkill *rfkill;
3658 DBG("index %u", index);
3660 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
3664 g_hash_table_remove(rfkill_list, GINT_TO_POINTER(index));
3666 technology = technology_find(type);
3670 technology_apply_rfkill_change(technology,
3671 technology->softblocked, !technology->hardblocked, false);
3673 technology_put(technology);
3678 int __connman_technology_init(void)
3682 connection = connman_dbus_get_connection();
3684 rfkill_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
3687 global_offlinemode = connman_technology_load_offlinemode();
3689 /* This will create settings file if it is missing */
3690 connman_technology_save_offlinemode();
3695 void __connman_technology_cleanup(void)
3699 while (technology_list) {
3700 struct connman_technology *technology = technology_list->data;
3701 technology_list = g_slist_remove(technology_list, technology);
3702 technology_put(technology);
3705 g_hash_table_destroy(rfkill_list);
3707 dbus_connection_unref(connection);