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
33 static DBusConnection *connection;
35 static GSList *technology_list = NULL;
38 * List of devices with no technology associated with them either because of
39 * no compiled in support or the driver is not yet loaded.
41 static GSList *techless_device_list = NULL;
42 static GHashTable *rfkill_list;
44 static bool global_offlinemode;
48 CONNMAN_SCAN_TYPE_FULL_CHANNEL = 0x00,
49 CONNMAN_SCAN_TYPE_SPECIFIC_AP,
50 CONNMAN_SCAN_TYPE_MULTI_AP,
51 } connman_scan_type_e;
53 static connman_scan_type_e g_scan_type = -1;
56 struct connman_rfkill {
58 enum connman_service_type type;
63 struct connman_technology {
65 enum connman_service_type type;
73 bool tethering_persistent; /* Tells the save status, needed
74 * as offline mode might set
77 char *tethering_ident;
78 char *tethering_passphrase;
79 bool tethering_hidden;
81 bool enable_persistent; /* Save the tech state */
85 DBusMessage *pending_reply;
86 guint pending_timeout;
96 static GSList *driver_list = NULL;
98 static int technology_enabled(struct connman_technology *technology);
99 static int technology_disabled(struct connman_technology *technology);
101 static gint compare_priority(gconstpointer a, gconstpointer b)
103 const struct connman_technology_driver *driver1 = a;
104 const struct connman_technology_driver *driver2 = b;
106 return driver2->priority - driver1->priority;
109 static void rfkill_check(gpointer key, gpointer value, gpointer user_data)
111 struct connman_rfkill *rfkill = value;
112 enum connman_service_type type = GPOINTER_TO_INT(user_data);
114 /* Calling _technology_rfkill_add will update the tech. */
115 if (rfkill->type == type)
116 __connman_technology_add_rfkill(rfkill->index, type,
117 rfkill->softblock, rfkill->hardblock);
121 connman_technology_is_tethering_allowed(enum connman_service_type type)
123 static char *allowed_default[] = { "wifi", "bluetooth", "gadget",
125 const char *type_str = __connman_service_type2string(type);
132 allowed = connman_setting_get_string_list("TetheringTechnologies");
134 allowed = allowed_default;
136 for (i = 0; allowed[i]; i++) {
137 if (g_strcmp0(allowed[i], type_str) == 0)
144 static const char *get_name(enum connman_service_type type)
147 case CONNMAN_SERVICE_TYPE_UNKNOWN:
148 case CONNMAN_SERVICE_TYPE_SYSTEM:
149 case CONNMAN_SERVICE_TYPE_GPS:
150 case CONNMAN_SERVICE_TYPE_VPN:
152 case CONNMAN_SERVICE_TYPE_GADGET:
154 case CONNMAN_SERVICE_TYPE_ETHERNET:
156 case CONNMAN_SERVICE_TYPE_WIFI:
158 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
160 case CONNMAN_SERVICE_TYPE_CELLULAR:
162 case CONNMAN_SERVICE_TYPE_P2P:
169 static void technology_save(struct connman_technology *technology)
173 const char *name = get_name(technology->type);
175 DBG("technology %p type %d name %s", technology, technology->type,
180 keyfile = __connman_storage_load_global();
182 keyfile = g_key_file_new();
184 identifier = g_strdup_printf("%s", name);
188 g_key_file_set_boolean(keyfile, identifier, "Enable",
189 technology->enable_persistent);
191 g_key_file_set_boolean(keyfile, identifier, "Tethering",
192 technology->tethering_persistent);
194 g_key_file_set_boolean(keyfile, identifier, "Hidden",
195 technology->tethering_hidden);
197 if (technology->tethering_ident)
198 g_key_file_set_string(keyfile, identifier,
199 "Tethering.Identifier",
200 technology->tethering_ident);
202 if (technology->tethering_passphrase)
203 g_key_file_set_string(keyfile, identifier,
204 "Tethering.Passphrase",
205 technology->tethering_passphrase);
210 __connman_storage_save_global(keyfile);
212 g_key_file_free(keyfile);
217 static void tethering_changed(struct connman_technology *technology)
219 dbus_bool_t tethering = technology->tethering;
221 connman_dbus_property_changed_basic(technology->path,
222 CONNMAN_TECHNOLOGY_INTERFACE, "Tethering",
223 DBUS_TYPE_BOOLEAN, &tethering);
225 technology_save(technology);
228 int connman_technology_tethering_notify(struct connman_technology *technology,
233 DBG("technology %p enabled %u", technology, enabled);
235 if (technology->tethering == enabled)
239 err = __connman_tethering_set_enabled();
243 __connman_tethering_set_disabled();
245 technology->tethering = enabled;
246 tethering_changed(technology);
251 static int set_tethering(struct connman_technology *technology,
254 int result = -EOPNOTSUPP;
256 const char *ident, *passphrase, *bridge;
257 GSList *tech_drivers;
259 ident = technology->tethering_ident;
260 passphrase = technology->tethering_passphrase;
262 __sync_synchronize();
263 if (!technology->enabled)
266 bridge = __connman_tethering_get_bridge();
270 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && (!ident))
273 for (tech_drivers = technology->driver_list; tech_drivers;
274 tech_drivers = g_slist_next(tech_drivers)) {
275 struct connman_technology_driver *driver = tech_drivers->data;
277 if (!driver || !driver->set_tethering)
280 err = driver->set_tethering(technology, ident, passphrase,
283 if (result == -EINPROGRESS)
286 if (err == -EINPROGRESS || err == 0)
293 void connman_technology_regdom_notify(struct connman_technology *technology,
299 connman_error("Failed to set regulatory domain");
301 DBG("Regulatory domain set to %s", alpha2);
303 g_free(technology->regdom);
304 technology->regdom = g_strdup(alpha2);
307 static int set_regdom_by_device(struct connman_technology *technology,
312 for (list = technology->device_list; list; list = list->next) {
313 struct connman_device *device = list->data;
315 if (connman_device_set_regdom(device, alpha2) != 0)
322 int connman_technology_set_regdom(const char *alpha2)
324 GSList *list, *tech_drivers;
326 for (list = technology_list; list; list = list->next) {
327 struct connman_technology *technology = list->data;
329 if (set_regdom_by_device(technology, alpha2) != 0) {
331 for (tech_drivers = technology->driver_list;
333 tech_drivers = g_slist_next(tech_drivers)) {
335 struct connman_technology_driver *driver =
338 if (driver->set_regdom)
339 driver->set_regdom(technology, alpha2);
347 static struct connman_technology *technology_find(enum connman_service_type type)
351 DBG("type %d", type);
353 for (list = technology_list; list; list = list->next) {
354 struct connman_technology *technology = list->data;
356 if (technology->type == type)
363 bool connman_technology_get_wifi_tethering(const char **ssid,
366 struct connman_technology *technology;
373 technology = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
377 if (!technology->tethering)
380 *ssid = technology->tethering_ident;
381 *psk = technology->tethering_passphrase;
386 static void free_rfkill(gpointer data)
388 struct connman_rfkill *rfkill = data;
393 static void technology_load(struct connman_technology *technology)
397 GError *error = NULL;
398 bool enable, need_saving = false;
400 DBG("technology %p", technology);
402 keyfile = __connman_storage_load_global();
403 /* Fallback on disabling technology if file not found. */
405 if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
406 /* We enable ethernet by default */
407 technology->enable_persistent = true;
409 technology->enable_persistent = false;
413 identifier = g_strdup_printf("%s", get_name(technology->type));
417 enable = g_key_file_get_boolean(keyfile, identifier, "Enable", &error);
419 technology->enable_persistent = enable;
421 if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
422 technology->enable_persistent = true;
424 technology->enable_persistent = false;
427 g_clear_error(&error);
430 enable = g_key_file_get_boolean(keyfile, identifier,
431 "Tethering", &error);
433 technology->tethering_persistent = enable;
436 g_clear_error(&error);
440 technology_save(technology);
442 technology->tethering_ident = g_key_file_get_string(keyfile,
443 identifier, "Tethering.Identifier", NULL);
445 technology->tethering_passphrase = g_key_file_get_string(keyfile,
446 identifier, "Tethering.Passphrase", NULL);
450 g_key_file_free(keyfile);
455 bool __connman_technology_get_offlinemode(void)
457 return global_offlinemode;
460 static void connman_technology_save_offlinemode(void)
463 GError *error = NULL;
466 keyfile = __connman_storage_load_global();
469 keyfile = g_key_file_new();
470 g_key_file_set_boolean(keyfile, "global",
471 "OfflineMode", global_offlinemode);
473 __connman_storage_save_global(keyfile);
476 offlinemode = g_key_file_get_boolean(keyfile, "global",
477 "OfflineMode", &error);
479 if (error || offlinemode != global_offlinemode) {
480 g_key_file_set_boolean(keyfile, "global",
481 "OfflineMode", global_offlinemode);
483 g_clear_error(&error);
485 __connman_storage_save_global(keyfile);
489 g_key_file_free(keyfile);
494 static bool connman_technology_load_offlinemode(void)
497 GError *error = NULL;
500 /* If there is a error, we enable offlinemode */
501 keyfile = __connman_storage_load_global();
505 offlinemode = g_key_file_get_boolean(keyfile, "global",
506 "OfflineMode", &error);
509 g_clear_error(&error);
512 g_key_file_free(keyfile);
517 static void append_properties(DBusMessageIter *iter,
518 struct connman_technology *technology)
520 DBusMessageIter dict;
524 connman_dbus_dict_open(iter, &dict);
526 str = get_name(technology->type);
528 connman_dbus_dict_append_basic(&dict, "Name",
529 DBUS_TYPE_STRING, &str);
531 str = __connman_service_type2string(technology->type);
533 connman_dbus_dict_append_basic(&dict, "Type",
534 DBUS_TYPE_STRING, &str);
536 __sync_synchronize();
537 val = technology->enabled;
538 connman_dbus_dict_append_basic(&dict, "Powered",
542 val = technology->connected;
543 connman_dbus_dict_append_basic(&dict, "Connected",
547 val = technology->tethering;
548 connman_dbus_dict_append_basic(&dict, "Tethering",
552 if (technology->tethering_ident)
553 connman_dbus_dict_append_basic(&dict, "TetheringIdentifier",
555 &technology->tethering_ident);
557 if (technology->tethering_passphrase)
558 connman_dbus_dict_append_basic(&dict, "TetheringPassphrase",
560 &technology->tethering_passphrase);
562 val = technology->tethering_hidden;
563 connman_dbus_dict_append_basic(&dict, "Hidden",
567 connman_dbus_dict_close(iter, &dict);
570 static void technology_added_signal(struct connman_technology *technology)
573 DBusMessageIter iter;
575 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
576 CONNMAN_MANAGER_INTERFACE, "TechnologyAdded");
580 dbus_message_iter_init_append(signal, &iter);
581 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
583 append_properties(&iter, technology);
585 dbus_connection_send(connection, signal, NULL);
586 dbus_message_unref(signal);
589 static void technology_removed_signal(struct connman_technology *technology)
591 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
592 CONNMAN_MANAGER_INTERFACE, "TechnologyRemoved",
593 DBUS_TYPE_OBJECT_PATH, &technology->path,
597 static DBusMessage *get_properties(DBusConnection *conn,
598 DBusMessage *message, void *user_data)
600 struct connman_technology *technology = user_data;
602 DBusMessageIter iter;
604 reply = dbus_message_new_method_return(message);
608 dbus_message_iter_init_append(reply, &iter);
609 append_properties(&iter, technology);
614 void __connman_technology_list_struct(DBusMessageIter *array)
617 DBusMessageIter entry;
619 for (list = technology_list; list; list = list->next) {
620 struct connman_technology *technology = list->data;
622 if (!technology->path ||
623 (technology->rfkill_driven &&
624 technology->hardblocked))
627 dbus_message_iter_open_container(array, DBUS_TYPE_STRUCT,
629 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
631 append_properties(&entry, technology);
632 dbus_message_iter_close_container(array, &entry);
636 static gboolean technology_pending_reply(gpointer user_data)
638 struct connman_technology *technology = user_data;
641 /* Power request timedout, send ETIMEDOUT. */
642 if (technology->pending_reply) {
643 reply = __connman_error_failed(technology->pending_reply, ETIMEDOUT);
645 g_dbus_send_message(connection, reply);
647 dbus_message_unref(technology->pending_reply);
648 technology->pending_reply = NULL;
649 technology->pending_timeout = 0;
655 static int technology_affect_devices(struct connman_technology *technology,
658 int err = 0, err_dev;
661 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
663 __connman_technology_enabled(technology->type);
665 __connman_technology_disabled(technology->type);
669 for (list = technology->device_list; list; list = list->next) {
670 struct connman_device *device = list->data;
673 err_dev = __connman_device_enable(device);
675 err_dev = __connman_device_disable(device);
677 if (err_dev < 0 && err_dev != -EALREADY)
684 static void powered_changed(struct connman_technology *technology)
688 if (!technology->dbus_registered)
691 if (technology->pending_reply) {
692 g_dbus_send_reply(connection,
693 technology->pending_reply, DBUS_TYPE_INVALID);
694 dbus_message_unref(technology->pending_reply);
695 technology->pending_reply = NULL;
697 g_source_remove(technology->pending_timeout);
698 technology->pending_timeout = 0;
701 __sync_synchronize();
702 enabled = technology->enabled;
703 #if defined TIZEN_EXT
704 DBG("ConnMan, Powered : %s, %s",
705 enabled ? "TRUE" : "FALSE",technology->path);
707 connman_dbus_property_changed_basic(technology->path,
708 CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
709 DBUS_TYPE_BOOLEAN, &enabled);
712 static void enable_tethering(struct connman_technology *technology)
716 if (!connman_setting_get_bool("PersistentTetheringMode"))
719 ret = set_tethering(technology, true);
720 if (ret < 0 && ret != -EALREADY)
721 DBG("Cannot enable tethering yet for %s (%d/%s)",
722 get_name(technology->type),
723 -ret, strerror(-ret));
726 static int technology_enabled(struct connman_technology *technology)
728 __sync_synchronize();
729 if (technology->enabled)
732 technology->enabled = true;
734 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
735 struct connman_technology *p2p;
737 p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
738 if (p2p && !p2p->enabled && p2p->enable_persistent)
739 technology_enabled(p2p);
742 if (technology->tethering_persistent)
743 enable_tethering(technology);
745 powered_changed(technology);
750 static int technology_enable(struct connman_technology *technology)
755 DBG("technology %p enable", technology);
757 __sync_synchronize();
759 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
760 struct connman_technology *wifi;
762 wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
763 if (wifi && wifi->enabled)
764 return technology_enabled(technology);
768 if (technology->enabled)
771 if (technology->pending_reply)
774 if (connman_setting_get_bool("PersistentTetheringMode") &&
775 technology->tethering)
776 set_tethering(technology, true);
778 if (technology->rfkill_driven)
779 err = __connman_rfkill_block(technology->type, false);
781 err_dev = technology_affect_devices(technology, true);
783 if (!technology->rfkill_driven)
789 static int technology_disabled(struct connman_technology *technology)
791 __sync_synchronize();
792 if (!technology->enabled)
795 technology->enabled = false;
797 powered_changed(technology);
802 static int technology_disable(struct connman_technology *technology)
806 DBG("technology %p disable", technology);
808 __sync_synchronize();
810 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
811 technology->enable_persistent = false;
812 return technology_disabled(technology);
813 } else if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
814 struct connman_technology *p2p;
816 p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
817 if (p2p && p2p->enabled) {
818 p2p->enable_persistent = true;
819 technology_disabled(p2p);
823 if (!technology->enabled)
826 if (technology->pending_reply)
829 if (technology->tethering)
830 set_tethering(technology, false);
832 err = technology_affect_devices(technology, false);
834 if (technology->rfkill_driven)
835 err = __connman_rfkill_block(technology->type, true);
840 static DBusMessage *set_powered(struct connman_technology *technology,
841 DBusMessage *msg, bool powered)
843 DBusMessage *reply = NULL;
846 if (technology->rfkill_driven && technology->hardblocked) {
852 err = technology_enable(technology);
854 err = technology_disable(technology);
857 technology->enable_persistent = powered;
858 technology_save(technology);
862 if (err == -EINPROGRESS) {
863 technology->pending_reply = dbus_message_ref(msg);
864 technology->pending_timeout = g_timeout_add_seconds(10,
865 technology_pending_reply, technology);
866 } else if (err == -EALREADY) {
868 reply = __connman_error_already_enabled(msg);
870 reply = __connman_error_already_disabled(msg);
872 reply = __connman_error_failed(msg, -err);
874 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
879 static DBusMessage *set_property(DBusConnection *conn,
880 DBusMessage *msg, void *data)
882 struct connman_technology *technology = data;
883 DBusMessageIter iter, value;
887 DBG("conn %p", conn);
889 if (!dbus_message_iter_init(msg, &iter))
890 return __connman_error_invalid_arguments(msg);
892 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
893 return __connman_error_invalid_arguments(msg);
895 dbus_message_iter_get_basic(&iter, &name);
896 dbus_message_iter_next(&iter);
898 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
899 return __connman_error_invalid_arguments(msg);
901 dbus_message_iter_recurse(&iter, &value);
903 type = dbus_message_iter_get_arg_type(&value);
905 DBG("property %s", name);
907 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && technology->connected) {
909 if (connman_dbus_get_connection_unix_user_sync(conn,
910 dbus_message_get_sender(msg),
912 DBG("Can not get unix user id!");
913 return __connman_error_permission_denied(msg);
916 if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
917 DBG("Not allow this user to operate wifi technology now!");
918 return __connman_error_permission_denied(msg);
922 if (g_str_equal(name, "Tethering")) {
923 dbus_bool_t tethering;
926 if (type != DBUS_TYPE_BOOLEAN)
927 return __connman_error_invalid_arguments(msg);
929 if (!connman_technology_is_tethering_allowed(technology->type)) {
930 DBG("%s tethering not allowed by config file",
931 __connman_service_type2string(technology->type));
932 return __connman_error_not_supported(msg);
935 dbus_message_iter_get_basic(&value, &tethering);
937 if (technology->tethering == tethering) {
939 return __connman_error_already_disabled(msg);
941 return __connman_error_already_enabled(msg);
944 err = set_tethering(technology, tethering);
946 return __connman_error_failed(msg, -err);
948 technology->tethering_persistent = tethering;
950 technology_save(technology);
952 } else if (g_str_equal(name, "TetheringIdentifier")) {
955 dbus_message_iter_get_basic(&value, &str);
957 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
958 return __connman_error_not_supported(msg);
960 if (strlen(str) < 1 || strlen(str) > 32)
961 return __connman_error_invalid_arguments(msg);
963 if (g_strcmp0(technology->tethering_ident, str) != 0) {
964 g_free(technology->tethering_ident);
965 technology->tethering_ident = g_strdup(str);
966 technology_save(technology);
968 connman_dbus_property_changed_basic(technology->path,
969 CONNMAN_TECHNOLOGY_INTERFACE,
970 "TetheringIdentifier",
972 &technology->tethering_ident);
974 } else if (g_str_equal(name, "TetheringPassphrase")) {
977 dbus_message_iter_get_basic(&value, &str);
979 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
980 return __connman_error_not_supported(msg);
982 err = __connman_service_check_passphrase(CONNMAN_SERVICE_SECURITY_PSK,
985 return __connman_error_passphrase_required(msg);
987 if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
988 g_free(technology->tethering_passphrase);
989 technology->tethering_passphrase = g_strdup(str);
990 technology_save(technology);
992 connman_dbus_property_changed_basic(technology->path,
993 CONNMAN_TECHNOLOGY_INTERFACE,
994 "TetheringPassphrase",
996 &technology->tethering_passphrase);
998 } else if (g_str_equal(name, "Hidden")) {
1001 if (type != DBUS_TYPE_BOOLEAN)
1002 return __connman_error_invalid_arguments(msg);
1004 dbus_message_iter_get_basic(&value, &hidden);
1006 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1007 return __connman_error_not_supported(msg);
1009 technology->tethering_hidden = hidden;
1010 technology_save(technology);
1012 connman_dbus_property_changed_basic(technology->path,
1013 CONNMAN_TECHNOLOGY_INTERFACE,
1017 } else if (g_str_equal(name, "Powered")) {
1020 if (type != DBUS_TYPE_BOOLEAN)
1021 return __connman_error_invalid_arguments(msg);
1023 dbus_message_iter_get_basic(&value, &enable);
1025 return set_powered(technology, msg, enable);
1027 return __connman_error_invalid_property(msg);
1029 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1032 static void reply_scan_pending(struct connman_technology *technology, int err)
1036 DBG("technology %p err %d", technology, err);
1038 while (technology->scan_pending) {
1039 DBusMessage *msg = technology->scan_pending->data;
1041 DBG("reply to %s", dbus_message_get_sender(msg));
1044 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1046 reply = __connman_error_failed(msg, -err);
1047 g_dbus_send_message(connection, reply);
1048 dbus_message_unref(msg);
1050 technology->scan_pending =
1051 g_slist_delete_link(technology->scan_pending,
1052 technology->scan_pending);
1056 #if defined TIZEN_EXT
1057 dbus_bool_t __connman_technology_notify_scan_changed(const char *key, void *val)
1060 DBusMessage *signal;
1061 DBusMessageIter iter;
1062 dbus_bool_t result = FALSE;
1064 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1065 CONNMAN_MANAGER_INTERFACE, "ScanChanged");
1069 dbus_message_iter_init_append(signal, &iter);
1070 connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_BOOLEAN, val);
1072 result = dbus_connection_send(connection, signal, NULL);
1073 dbus_message_unref(signal);
1075 DBG("Successfuly sent signal");
1081 void __connman_technology_scan_started(struct connman_device *device)
1083 DBG("device %p", device);
1084 #if defined TIZEN_EXT
1085 dbus_bool_t status = 1;
1086 __connman_technology_notify_scan_changed("scan_started", &status);
1090 void __connman_technology_scan_stopped(struct connman_device *device,
1091 enum connman_service_type type)
1094 struct connman_technology *technology;
1097 technology = technology_find(type);
1099 DBG("technology %p device %p", technology, device);
1104 for (list = technology->device_list; list; list = list->next) {
1105 struct connman_device *other_device = list->data;
1107 if (device == other_device)
1110 if (__connman_device_get_service_type(other_device) != type)
1113 if (connman_device_get_scanning(other_device))
1117 #if defined TIZEN_EXT
1119 DBusMessage *signal;
1120 DBusMessageIter iter;
1121 dbus_bool_t status = 0;
1122 __connman_technology_notify_scan_changed("scan_done", &status);
1124 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1125 CONNMAN_MANAGER_INTERFACE, "ScanDone");
1129 dbus_message_iter_init_append(signal, &iter);
1130 connman_dbus_property_append_basic(&iter, "Scantype",
1131 DBUS_TYPE_INT32, &g_scan_type);
1133 dbus_connection_send(connection, signal, NULL);
1134 dbus_message_unref(signal);
1135 reply_scan_pending(technology, 0);
1137 DBG("Successfuly sent ScanDone signal");
1141 reply_scan_pending(technology, 0);
1145 void __connman_technology_notify_regdom_by_device(struct connman_device *device,
1146 int result, const char *alpha2)
1148 bool regdom_set = false;
1149 struct connman_technology *technology;
1150 enum connman_service_type type;
1151 GSList *tech_drivers;
1153 type = __connman_device_get_service_type(device);
1154 technology = technology_find(type);
1161 for (tech_drivers = technology->driver_list;
1163 tech_drivers = g_slist_next(tech_drivers)) {
1164 struct connman_technology_driver *driver =
1167 if (driver->set_regdom) {
1168 driver->set_regdom(technology, alpha2);
1178 connman_technology_regdom_notify(technology, alpha2);
1181 static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
1183 struct connman_technology *technology = data;
1186 DBG("technology %p request from %s", technology,
1187 dbus_message_get_sender(msg));
1189 if (technology->type == CONNMAN_SERVICE_TYPE_P2P &&
1190 !technology->enabled)
1191 return __connman_error_permission_denied(msg);
1193 dbus_message_ref(msg);
1194 #if !defined TIZEN_EXT
1195 technology->scan_pending =
1196 g_slist_prepend(technology->scan_pending, msg);
1199 err = __connman_device_request_scan(technology->type);
1200 #if defined TIZEN_EXT
1202 return __connman_error_failed(msg, -err);
1205 reply_scan_pending(technology, err);
1208 #if defined TIZEN_EXT
1210 g_scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL;
1211 DBG("g_scan_type %d", g_scan_type);
1213 technology->scan_pending =
1214 g_slist_prepend(technology->scan_pending, msg);
1219 #if defined TIZEN_EXT
1220 static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data)
1222 struct connman_technology *technology = data;
1223 GSList *specific_scan_list = NULL;
1225 const char *name = NULL;
1226 unsigned int freq = 0;
1227 DBusMessageIter iter, dict;
1230 DBG("technology %p request from %s", technology,
1231 dbus_message_get_sender(msg));
1233 if (!dbus_message_iter_init(msg, &iter))
1234 return __connman_error_invalid_arguments(msg);
1236 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
1237 return __connman_error_invalid_arguments(msg);
1239 dbus_message_iter_recurse(&iter, &dict);
1240 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
1241 DBusMessageIter entry, value2;
1245 dbus_message_iter_recurse(&dict, &entry);
1246 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
1247 g_slist_free_full(specific_scan_list, g_free);
1248 return __connman_error_invalid_arguments(msg);
1251 dbus_message_iter_get_basic(&entry, &key);
1252 dbus_message_iter_next(&entry);
1254 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) {
1255 g_slist_free_full(specific_scan_list, g_free);
1256 return __connman_error_invalid_arguments(msg);
1259 dbus_message_iter_recurse(&entry, &value2);
1260 type = dbus_message_iter_get_arg_type(&value2);
1261 if (g_str_equal(key, "SSID")) {
1262 if (type != DBUS_TYPE_STRING) {
1263 g_slist_free_full(specific_scan_list, g_free);
1264 return __connman_error_invalid_arguments(msg);
1267 scan_type = 1; /* SSID based scan */
1268 dbus_message_iter_get_basic(&value2, &name);
1269 DBG("name %s", name);
1270 specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name));
1271 } else if (g_str_equal(key, "Frequency")) {
1272 if (type != DBUS_TYPE_UINT16) {
1273 g_slist_free_full(specific_scan_list, g_free);
1274 return __connman_error_invalid_arguments(msg);
1277 scan_type = 2; /* Frequency based scan */
1278 dbus_message_iter_get_basic(&value2, &freq);
1279 DBG("freq %d", freq);
1280 specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(freq));
1282 dbus_message_iter_next(&dict);
1285 dbus_message_ref(msg);
1287 err = __connman_device_request_specific_scan(technology->type, scan_type, specific_scan_list);
1289 return __connman_error_failed(msg, -err);
1292 guint list_size = g_slist_length(specific_scan_list);
1294 g_scan_type = CONNMAN_SCAN_TYPE_SPECIFIC_AP;
1296 g_scan_type = CONNMAN_SCAN_TYPE_MULTI_AP;
1297 DBG("list_size %u g_scan_type %d", list_size, g_scan_type);
1299 technology->scan_pending =
1300 g_slist_prepend(technology->scan_pending, msg);
1302 if (scan_type == 1) {
1303 g_slist_free_full(specific_scan_list, g_free);
1309 static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
1312 DBusMessageIter iter, dict;
1314 struct connman_technology *technology = data;
1315 dbus_bool_t scanning = false;
1317 DBG("technology %p", technology);
1319 for (list = technology->device_list; list; list = list->next) {
1320 struct connman_device *device = list->data;
1321 scanning = connman_device_get_scanning(device);
1326 DBG("scanning : %d", scanning);
1327 reply = dbus_message_new_method_return(msg);
1331 dbus_message_iter_init_append(reply, &iter);
1333 connman_dbus_dict_open(&iter, &dict);
1334 connman_dbus_dict_append_basic(&dict, "Scanstate",
1338 connman_dbus_dict_close(&iter, &dict);
1344 static const GDBusMethodTable technology_methods[] = {
1345 { GDBUS_DEPRECATED_METHOD("GetProperties",
1346 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
1348 { GDBUS_ASYNC_METHOD("SetProperty",
1349 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
1350 NULL, set_property) },
1351 { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
1352 #if defined TIZEN_EXT
1353 { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }),
1354 NULL, specific_scan) },
1355 { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
1361 static const GDBusSignalTable technology_signals[] = {
1362 { GDBUS_SIGNAL("PropertyChanged",
1363 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
1364 { GDBUS_SIGNAL("DhcpConnected",
1365 GDBUS_ARGS({ "aptype", "s" },
1368 { "hostname", "s" })) },
1369 { GDBUS_SIGNAL("DhcpLeaseDeleted",
1370 GDBUS_ARGS({ "aptype", "s" },
1373 { "hostname", "s" })) },
1377 static bool technology_dbus_register(struct connman_technology *technology)
1379 if (technology->dbus_registered ||
1380 (technology->rfkill_driven &&
1381 technology->hardblocked))
1384 if (!g_dbus_register_interface(connection, technology->path,
1385 CONNMAN_TECHNOLOGY_INTERFACE,
1386 technology_methods, technology_signals,
1387 NULL, technology, NULL)) {
1388 connman_error("Failed to register %s", technology->path);
1392 technology_added_signal(technology);
1393 technology->dbus_registered = true;
1398 static void technology_dbus_unregister(struct connman_technology *technology)
1400 if (!technology->dbus_registered)
1403 technology_removed_signal(technology);
1404 g_dbus_unregister_interface(connection, technology->path,
1405 CONNMAN_TECHNOLOGY_INTERFACE);
1407 technology->dbus_registered = false;
1410 static void technology_put(struct connman_technology *technology)
1412 DBG("technology %p", technology);
1414 if (__sync_sub_and_fetch(&technology->refcount, 1) > 0)
1417 reply_scan_pending(technology, -EINTR);
1419 while (technology->driver_list) {
1420 struct connman_technology_driver *driver;
1422 driver = technology->driver_list->data;
1425 driver->remove(technology);
1427 technology->driver_list =
1428 g_slist_delete_link(technology->driver_list,
1429 technology->driver_list);
1432 technology_list = g_slist_remove(technology_list, technology);
1434 technology_dbus_unregister(technology);
1436 g_slist_free(technology->device_list);
1438 if (technology->pending_reply) {
1439 dbus_message_unref(technology->pending_reply);
1440 technology->pending_reply = NULL;
1441 g_source_remove(technology->pending_timeout);
1442 technology->pending_timeout = 0;
1445 g_free(technology->path);
1446 g_free(technology->regdom);
1447 g_free(technology->tethering_ident);
1448 g_free(technology->tethering_passphrase);
1452 static struct connman_technology *technology_get(enum connman_service_type type)
1454 GSList *tech_drivers = NULL;
1455 struct connman_technology_driver *driver;
1456 struct connman_technology *technology;
1460 DBG("type %d", type);
1462 str = __connman_service_type2string(type);
1466 technology = technology_find(type);
1468 if (type != CONNMAN_SERVICE_TYPE_P2P)
1469 __sync_fetch_and_add(&technology->refcount, 1);
1473 /* First check if we have a driver for this technology type */
1474 for (list = driver_list; list; list = list->next) {
1475 driver = list->data;
1477 if (driver->type == type) {
1478 DBG("technology %p driver %p", technology, driver);
1479 tech_drivers = g_slist_append(tech_drivers, driver);
1483 if (!tech_drivers) {
1484 DBG("No matching drivers found for %s.",
1485 __connman_service_type2string(type));
1489 technology = g_try_new0(struct connman_technology, 1);
1493 technology->refcount = 1;
1494 technology->type = type;
1495 technology->tethering_hidden = FALSE;
1496 technology->path = g_strdup_printf("%s/technology/%s",
1499 technology_load(technology);
1500 technology_list = g_slist_prepend(technology_list, technology);
1501 technology->driver_list = tech_drivers;
1503 for (list = tech_drivers; list; list = list->next) {
1504 driver = list->data;
1506 if (driver->probe && driver->probe(technology) < 0)
1507 DBG("Driver probe failed for technology %p",
1511 if (!technology_dbus_register(technology)) {
1512 technology_put(technology);
1516 if (type == CONNMAN_SERVICE_TYPE_P2P) {
1517 struct connman_technology *wifi;
1520 enable = technology->enable_persistent;
1522 wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
1524 enable = wifi->enabled;
1526 technology_affect_devices(technology, enable);
1529 DBG("technology %p %s", technology, get_name(technology->type));
1534 int connman_technology_driver_register(struct connman_technology_driver *driver)
1537 struct connman_device *device;
1538 enum connman_service_type type;
1540 for (list = driver_list; list; list = list->next) {
1541 if (list->data == driver)
1545 DBG("Registering %s driver", driver->name);
1547 driver_list = g_slist_insert_sorted(driver_list, driver,
1551 * Check for technology less devices if this driver
1552 * can service any of them.
1554 for (list = techless_device_list; list; list = list->next) {
1555 device = list->data;
1557 type = __connman_device_get_service_type(device);
1558 if (type != driver->type)
1561 techless_device_list = g_slist_remove(techless_device_list,
1564 __connman_technology_add_device(device);
1567 /* Check for orphaned rfkill switches. */
1568 g_hash_table_foreach(rfkill_list, rfkill_check,
1569 GINT_TO_POINTER(driver->type));
1572 if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
1573 if (!technology_get(CONNMAN_SERVICE_TYPE_P2P))
1580 void connman_technology_driver_unregister(struct connman_technology_driver *driver)
1582 GSList *list, *tech_drivers;
1583 struct connman_technology *technology;
1584 struct connman_technology_driver *current;
1586 DBG("Unregistering driver %p name %s", driver, driver->name);
1588 for (list = technology_list; list; list = list->next) {
1589 technology = list->data;
1591 for (tech_drivers = technology->driver_list; tech_drivers;
1592 tech_drivers = g_slist_next(tech_drivers)) {
1593 current = tech_drivers->data;
1594 if (driver != current)
1598 driver->remove(technology);
1600 technology->driver_list =
1601 g_slist_remove(technology->driver_list,
1607 driver_list = g_slist_remove(driver_list, driver);
1609 if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
1610 technology = technology_find(CONNMAN_SERVICE_TYPE_P2P);
1612 technology_put(technology);
1616 void __connman_technology_add_interface(enum connman_service_type type,
1617 int index, const char *ident)
1619 struct connman_technology *technology;
1620 GSList *tech_drivers;
1621 struct connman_technology_driver *driver;
1625 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1626 case CONNMAN_SERVICE_TYPE_SYSTEM:
1628 case CONNMAN_SERVICE_TYPE_ETHERNET:
1629 case CONNMAN_SERVICE_TYPE_WIFI:
1630 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1631 case CONNMAN_SERVICE_TYPE_CELLULAR:
1632 case CONNMAN_SERVICE_TYPE_GPS:
1633 case CONNMAN_SERVICE_TYPE_VPN:
1634 case CONNMAN_SERVICE_TYPE_GADGET:
1635 case CONNMAN_SERVICE_TYPE_P2P:
1639 name = connman_inet_ifname(index);
1640 connman_info("Adding interface %s [ %s ]", name,
1641 __connman_service_type2string(type));
1643 technology = technology_find(type);
1648 for (tech_drivers = technology->driver_list; tech_drivers;
1649 tech_drivers = g_slist_next(tech_drivers)) {
1650 driver = tech_drivers->data;
1652 if (driver->add_interface)
1653 driver->add_interface(technology, index, name, ident);
1657 * At this point we can try to enable tethering automatically as
1658 * now the interfaces are set properly.
1660 if (technology->tethering_persistent)
1661 enable_tethering(technology);
1667 void __connman_technology_remove_interface(enum connman_service_type type,
1668 int index, const char *ident)
1670 struct connman_technology *technology;
1671 GSList *tech_drivers;
1672 struct connman_technology_driver *driver;
1676 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1677 case CONNMAN_SERVICE_TYPE_SYSTEM:
1679 case CONNMAN_SERVICE_TYPE_ETHERNET:
1680 case CONNMAN_SERVICE_TYPE_WIFI:
1681 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1682 case CONNMAN_SERVICE_TYPE_CELLULAR:
1683 case CONNMAN_SERVICE_TYPE_GPS:
1684 case CONNMAN_SERVICE_TYPE_VPN:
1685 case CONNMAN_SERVICE_TYPE_GADGET:
1686 case CONNMAN_SERVICE_TYPE_P2P:
1690 name = connman_inet_ifname(index);
1691 connman_info("Remove interface %s [ %s ]", name,
1692 __connman_service_type2string(type));
1695 technology = technology_find(type);
1700 for (tech_drivers = technology->driver_list; tech_drivers;
1701 tech_drivers = g_slist_next(tech_drivers)) {
1702 driver = tech_drivers->data;
1704 if (driver->remove_interface)
1705 driver->remove_interface(technology, index);
1709 int __connman_technology_add_device(struct connman_device *device)
1711 struct connman_technology *technology;
1712 enum connman_service_type type;
1714 type = __connman_device_get_service_type(device);
1716 DBG("device %p type %s", device, get_name(type));
1718 technology = technology_get(type);
1721 * Since no driver can be found for this device at the moment we
1722 * add it to the techless device list.
1724 techless_device_list = g_slist_prepend(techless_device_list,
1730 __sync_synchronize();
1731 if (technology->rfkill_driven) {
1732 if (technology->enabled)
1733 __connman_device_enable(device);
1735 __connman_device_disable(device);
1740 if (technology->enable_persistent &&
1741 !global_offlinemode) {
1742 int err = __connman_device_enable(device);
1744 * connman_technology_add_device() calls __connman_device_enable()
1745 * but since the device is already enabled, the calls does not
1746 * propagate through to connman_technology_enabled via
1747 * connman_device_set_powered.
1749 if (err == -EALREADY)
1750 __connman_technology_enabled(type);
1752 /* if technology persistent state is offline */
1753 if (!technology->enable_persistent)
1754 __connman_device_disable(device);
1757 technology->device_list = g_slist_prepend(technology->device_list,
1763 int __connman_technology_remove_device(struct connman_device *device)
1765 struct connman_technology *technology;
1766 enum connman_service_type type;
1768 DBG("device %p", device);
1770 type = __connman_device_get_service_type(device);
1772 technology = technology_find(type);
1774 techless_device_list = g_slist_remove(techless_device_list,
1779 technology->device_list = g_slist_remove(technology->device_list,
1782 if (technology->tethering)
1783 set_tethering(technology, false);
1785 technology_put(technology);
1790 int __connman_technology_enabled(enum connman_service_type type)
1792 struct connman_technology *technology;
1794 technology = technology_find(type);
1798 DBG("technology %p type %s rfkill %d enabled %d", technology,
1799 get_name(type), technology->rfkill_driven,
1800 technology->enabled);
1801 #if !defined TIZEN_EXT
1802 if (technology->rfkill_driven) {
1803 if (technology->tethering_persistent)
1804 enable_tethering(technology);
1809 return technology_enabled(technology);
1812 int __connman_technology_disabled(enum connman_service_type type)
1814 struct connman_technology *technology;
1817 technology = technology_find(type);
1820 #if !defined TIZEN_EXT
1821 if (technology->rfkill_driven)
1824 for (list = technology->device_list; list; list = list->next) {
1825 struct connman_device *device = list->data;
1827 if (connman_device_get_powered(device))
1831 return technology_disabled(technology);
1834 int __connman_technology_set_offlinemode(bool offlinemode)
1837 int err = -EINVAL, enabled_tech_count = 0;
1839 if (global_offlinemode == offlinemode)
1842 DBG("offlinemode %s", offlinemode ? "On" : "Off");
1845 * This is a bit tricky. When you set offlinemode, there is no
1846 * way to differentiate between attempting offline mode and
1847 * resuming offlinemode from last saved profile. We need that
1848 * information in rfkill_update, otherwise it falls back on the
1849 * technology's persistent state. Hence we set the offline mode here
1850 * but save it & call the notifier only if its successful.
1853 global_offlinemode = offlinemode;
1855 /* Traverse technology list, enable/disable each technology. */
1856 for (list = technology_list; list; list = list->next) {
1857 struct connman_technology *technology = list->data;
1860 err = technology_disable(technology);
1862 if (technology->hardblocked)
1865 if (technology->enable_persistent) {
1866 err = technology_enable(technology);
1867 enabled_tech_count++;
1872 if (err == 0 || err == -EINPROGRESS || err == -EALREADY ||
1873 (err == -EINVAL && enabled_tech_count == 0)) {
1874 connman_technology_save_offlinemode();
1875 __connman_notifier_offlinemode(offlinemode);
1877 global_offlinemode = connman_technology_load_offlinemode();
1882 void __connman_technology_set_connected(enum connman_service_type type,
1885 struct connman_technology *technology;
1888 technology = technology_find(type);
1892 DBG("technology %p connected %d", technology, connected);
1894 technology->connected = connected;
1897 connman_dbus_property_changed_basic(technology->path,
1898 CONNMAN_TECHNOLOGY_INTERFACE, "Connected",
1899 DBUS_TYPE_BOOLEAN, &val);
1902 static bool technology_apply_rfkill_change(struct connman_technology *technology,
1907 bool hardblock_changed = false;
1909 GList *start, *list;
1911 DBG("technology %p --> %d/%d vs %d/%d",
1912 technology, softblock, hardblock,
1913 technology->softblocked, technology->hardblocked);
1915 if (technology->hardblocked == hardblock)
1916 goto softblock_change;
1918 if (!(new_rfkill && !hardblock)) {
1919 start = g_hash_table_get_values(rfkill_list);
1921 for (list = start; list; list = list->next) {
1922 struct connman_rfkill *rfkill = list->data;
1924 if (rfkill->type != technology->type)
1927 if (rfkill->hardblock != hardblock)
1935 goto softblock_change;
1937 technology->hardblocked = hardblock;
1938 hardblock_changed = true;
1941 if (!apply && technology->softblocked != softblock)
1945 return technology->hardblocked;
1947 technology->softblocked = softblock;
1949 if (technology->hardblocked ||
1950 technology->softblocked) {
1951 if (technology_disabled(technology) != -EALREADY)
1952 technology_affect_devices(technology, false);
1953 } else if (!technology->hardblocked &&
1954 !technology->softblocked) {
1955 if (technology_enabled(technology) != -EALREADY)
1956 technology_affect_devices(technology, true);
1959 if (hardblock_changed) {
1960 if (technology->hardblocked) {
1961 DBG("%s is switched off.", get_name(technology->type));
1962 technology_dbus_unregister(technology);
1964 DBG("%s is switched on.", get_name(technology->type));
1965 technology_dbus_register(technology);
1967 if (global_offlinemode)
1968 __connman_rfkill_block(technology->type, true);
1972 return technology->hardblocked;
1975 int __connman_technology_add_rfkill(unsigned int index,
1976 enum connman_service_type type,
1980 struct connman_technology *technology;
1981 struct connman_rfkill *rfkill;
1983 DBG("index %u type %d soft %u hard %u", index, type,
1984 softblock, hardblock);
1986 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
1990 rfkill = g_try_new0(struct connman_rfkill, 1);
1994 rfkill->index = index;
1995 rfkill->type = type;
1996 rfkill->softblock = softblock;
1997 rfkill->hardblock = hardblock;
1999 g_hash_table_insert(rfkill_list, GINT_TO_POINTER(index), rfkill);
2002 #if defined TIZEN_EXT
2003 /* Fix Svace Issue [WGID: 1348]. */
2006 technology = technology_get(type);
2007 /* If there is no driver for this type, ignore it. */
2011 technology->rfkill_driven = true;
2013 #if !defined TIZEN_EXT
2014 /* If hardblocked, there is no need to handle softblocked state */
2015 if (technology_apply_rfkill_change(technology,
2016 softblock, hardblock, true))
2019 if (global_offlinemode)
2023 * Depending on softblocked state we unblock/block according to
2024 * offlinemode and persistente state.
2026 if (technology->softblocked &&
2027 technology->enable_persistent)
2028 return __connman_rfkill_block(type, false);
2029 else if (!technology->softblocked &&
2030 !technology->enable_persistent)
2031 return __connman_rfkill_block(type, true);
2036 int __connman_technology_update_rfkill(unsigned int index,
2037 enum connman_service_type type,
2041 struct connman_technology *technology;
2042 struct connman_rfkill *rfkill;
2044 DBG("index %u soft %u hard %u", index, softblock, hardblock);
2046 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
2050 if (rfkill->softblock == softblock &&
2051 rfkill->hardblock == hardblock)
2054 rfkill->softblock = softblock;
2055 rfkill->hardblock = hardblock;
2057 technology = technology_find(type);
2058 /* If there is no driver for this type, ignore it. */
2062 technology_apply_rfkill_change(technology, softblock, hardblock,
2065 if (technology->hardblocked)
2066 DBG("%s hardblocked", get_name(technology->type));
2068 DBG("%s is%s softblocked", get_name(technology->type),
2069 technology->softblocked ? "" : " not");
2074 int __connman_technology_remove_rfkill(unsigned int index,
2075 enum connman_service_type type)
2077 struct connman_technology *technology;
2078 struct connman_rfkill *rfkill;
2080 DBG("index %u", index);
2082 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
2086 g_hash_table_remove(rfkill_list, GINT_TO_POINTER(index));
2088 technology = technology_find(type);
2092 technology_apply_rfkill_change(technology,
2093 technology->softblocked, !technology->hardblocked, false);
2095 technology_put(technology);
2100 int __connman_technology_init(void)
2104 connection = connman_dbus_get_connection();
2106 rfkill_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2109 global_offlinemode = connman_technology_load_offlinemode();
2111 /* This will create settings file if it is missing */
2112 connman_technology_save_offlinemode();
2117 void __connman_technology_cleanup(void)
2121 while (technology_list) {
2122 struct connman_technology *technology = technology_list->data;
2123 technology_list = g_slist_remove(technology_list, technology);
2124 technology_put(technology);
2127 g_hash_table_destroy(rfkill_list);
2129 dbus_connection_unref(connection);