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
36 static DBusConnection *connection;
38 static GSList *technology_list = NULL;
41 * List of devices with no technology associated with them either because of
42 * no compiled in support or the driver is not yet loaded.
44 static GSList *techless_device_list = NULL;
45 static GHashTable *rfkill_list;
47 static bool global_offlinemode;
51 CONNMAN_SCAN_TYPE_FULL_CHANNEL = 0x00,
52 CONNMAN_SCAN_TYPE_SPECIFIC_AP,
53 CONNMAN_SCAN_TYPE_MULTI_AP,
54 } connman_scan_type_e;
56 static connman_scan_type_e g_scan_type = -1;
59 struct connman_rfkill {
61 enum connman_service_type type;
66 struct connman_technology {
68 enum connman_service_type type;
76 bool tethering_persistent; /* Tells the save status, needed
77 * as offline mode might set
80 char *tethering_ident;
81 char *tethering_passphrase;
82 bool tethering_hidden;
84 bool enable_persistent; /* Save the tech state */
88 DBusMessage *pending_reply;
89 guint pending_timeout;
99 static GSList *driver_list = NULL;
101 static int technology_enabled(struct connman_technology *technology);
102 static int technology_disabled(struct connman_technology *technology);
104 static gint compare_priority(gconstpointer a, gconstpointer b)
106 const struct connman_technology_driver *driver1 = a;
107 const struct connman_technology_driver *driver2 = b;
109 return driver2->priority - driver1->priority;
112 static void rfkill_check(gpointer key, gpointer value, gpointer user_data)
114 struct connman_rfkill *rfkill = value;
115 enum connman_service_type type = GPOINTER_TO_INT(user_data);
117 /* Calling _technology_rfkill_add will update the tech. */
118 if (rfkill->type == type)
119 __connman_technology_add_rfkill(rfkill->index, type,
120 rfkill->softblock, rfkill->hardblock);
124 connman_technology_is_tethering_allowed(enum connman_service_type type)
126 static char *allowed_default[] = { "wifi", "bluetooth", "gadget",
128 const char *type_str = __connman_service_type2string(type);
135 allowed = connman_setting_get_string_list("TetheringTechnologies");
137 allowed = allowed_default;
139 for (i = 0; allowed[i]; i++) {
140 if (g_strcmp0(allowed[i], type_str) == 0)
147 static const char *get_name(enum connman_service_type type)
150 case CONNMAN_SERVICE_TYPE_UNKNOWN:
151 case CONNMAN_SERVICE_TYPE_SYSTEM:
152 case CONNMAN_SERVICE_TYPE_GPS:
153 case CONNMAN_SERVICE_TYPE_VPN:
155 case CONNMAN_SERVICE_TYPE_GADGET:
157 case CONNMAN_SERVICE_TYPE_ETHERNET:
159 case CONNMAN_SERVICE_TYPE_WIFI:
161 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
163 case CONNMAN_SERVICE_TYPE_CELLULAR:
165 case CONNMAN_SERVICE_TYPE_P2P:
172 static void technology_save(struct connman_technology *technology)
176 const char *name = get_name(technology->type);
178 DBG("technology %p type %d name %s", technology, technology->type,
183 keyfile = __connman_storage_load_global();
185 keyfile = g_key_file_new();
187 identifier = g_strdup_printf("%s", name);
191 g_key_file_set_boolean(keyfile, identifier, "Enable",
192 technology->enable_persistent);
194 g_key_file_set_boolean(keyfile, identifier, "Tethering",
195 technology->tethering_persistent);
197 g_key_file_set_boolean(keyfile, identifier, "Hidden",
198 technology->tethering_hidden);
200 if (technology->tethering_ident)
201 g_key_file_set_string(keyfile, identifier,
202 "Tethering.Identifier",
203 technology->tethering_ident);
205 if (technology->tethering_passphrase)
206 g_key_file_set_string(keyfile, identifier,
207 "Tethering.Passphrase",
208 technology->tethering_passphrase);
213 __connman_storage_save_global(keyfile);
215 g_key_file_free(keyfile);
220 static void tethering_changed(struct connman_technology *technology)
222 dbus_bool_t tethering = technology->tethering;
224 connman_dbus_property_changed_basic(technology->path,
225 CONNMAN_TECHNOLOGY_INTERFACE, "Tethering",
226 DBUS_TYPE_BOOLEAN, &tethering);
228 technology_save(technology);
231 int connman_technology_tethering_notify(struct connman_technology *technology,
236 DBG("technology %p enabled %u", technology, enabled);
238 if (technology->tethering == enabled)
242 err = __connman_tethering_set_enabled();
246 __connman_tethering_set_disabled();
248 technology->tethering = enabled;
249 tethering_changed(technology);
254 static int set_tethering(struct connman_technology *technology,
257 int result = -EOPNOTSUPP;
259 const char *ident, *passphrase, *bridge;
260 GSList *tech_drivers;
262 ident = technology->tethering_ident;
263 passphrase = technology->tethering_passphrase;
265 __sync_synchronize();
266 if (!technology->enabled)
269 bridge = __connman_tethering_get_bridge();
273 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && (!ident))
276 for (tech_drivers = technology->driver_list; tech_drivers;
277 tech_drivers = g_slist_next(tech_drivers)) {
278 struct connman_technology_driver *driver = tech_drivers->data;
280 if (!driver || !driver->set_tethering)
283 err = driver->set_tethering(technology, ident, passphrase,
286 if (result == -EINPROGRESS)
289 if (err == -EINPROGRESS || err == 0)
296 void connman_technology_regdom_notify(struct connman_technology *technology,
302 connman_error("Failed to set regulatory domain");
304 DBG("Regulatory domain set to %s", alpha2);
306 g_free(technology->regdom);
307 technology->regdom = g_strdup(alpha2);
310 static int set_regdom_by_device(struct connman_technology *technology,
315 for (list = technology->device_list; list; list = list->next) {
316 struct connman_device *device = list->data;
318 if (connman_device_set_regdom(device, alpha2) != 0)
325 int connman_technology_set_regdom(const char *alpha2)
327 GSList *list, *tech_drivers;
329 for (list = technology_list; list; list = list->next) {
330 struct connman_technology *technology = list->data;
332 if (set_regdom_by_device(technology, alpha2) != 0) {
334 for (tech_drivers = technology->driver_list;
336 tech_drivers = g_slist_next(tech_drivers)) {
338 struct connman_technology_driver *driver =
341 if (driver->set_regdom)
342 driver->set_regdom(technology, alpha2);
350 static struct connman_technology *technology_find(enum connman_service_type type)
354 DBG("type %d", type);
356 for (list = technology_list; list; list = list->next) {
357 struct connman_technology *technology = list->data;
359 if (technology->type == type)
366 bool connman_technology_get_wifi_tethering(const char **ssid,
369 struct connman_technology *technology;
376 technology = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
380 if (!technology->tethering)
383 *ssid = technology->tethering_ident;
384 *psk = technology->tethering_passphrase;
389 static void free_rfkill(gpointer data)
391 struct connman_rfkill *rfkill = data;
396 static void technology_load(struct connman_technology *technology)
400 GError *error = NULL;
401 bool enable, need_saving = false;
403 DBG("technology %p", technology);
405 keyfile = __connman_storage_load_global();
406 /* Fallback on disabling technology if file not found. */
408 if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
409 /* We enable ethernet by default */
410 technology->enable_persistent = true;
412 technology->enable_persistent = false;
416 identifier = g_strdup_printf("%s", get_name(technology->type));
420 enable = g_key_file_get_boolean(keyfile, identifier, "Enable", &error);
422 technology->enable_persistent = enable;
424 if (technology->type == CONNMAN_SERVICE_TYPE_ETHERNET)
425 technology->enable_persistent = true;
427 technology->enable_persistent = false;
430 g_clear_error(&error);
433 enable = g_key_file_get_boolean(keyfile, identifier,
434 "Tethering", &error);
436 technology->tethering_persistent = enable;
439 g_clear_error(&error);
443 technology_save(technology);
445 technology->tethering_ident = g_key_file_get_string(keyfile,
446 identifier, "Tethering.Identifier", NULL);
448 technology->tethering_passphrase = g_key_file_get_string(keyfile,
449 identifier, "Tethering.Passphrase", NULL);
453 g_key_file_free(keyfile);
458 bool __connman_technology_get_offlinemode(void)
460 return global_offlinemode;
463 static void connman_technology_save_offlinemode(void)
466 GError *error = NULL;
469 keyfile = __connman_storage_load_global();
472 keyfile = g_key_file_new();
473 g_key_file_set_boolean(keyfile, "global",
474 "OfflineMode", global_offlinemode);
476 __connman_storage_save_global(keyfile);
479 offlinemode = g_key_file_get_boolean(keyfile, "global",
480 "OfflineMode", &error);
482 if (error || offlinemode != global_offlinemode) {
483 g_key_file_set_boolean(keyfile, "global",
484 "OfflineMode", global_offlinemode);
486 g_clear_error(&error);
488 __connman_storage_save_global(keyfile);
492 g_key_file_free(keyfile);
497 static bool connman_technology_load_offlinemode(void)
500 GError *error = NULL;
503 /* If there is a error, we enable offlinemode */
504 keyfile = __connman_storage_load_global();
508 offlinemode = g_key_file_get_boolean(keyfile, "global",
509 "OfflineMode", &error);
512 g_clear_error(&error);
515 g_key_file_free(keyfile);
520 static void append_properties(DBusMessageIter *iter,
521 struct connman_technology *technology)
523 DBusMessageIter dict;
527 connman_dbus_dict_open(iter, &dict);
529 str = get_name(technology->type);
531 connman_dbus_dict_append_basic(&dict, "Name",
532 DBUS_TYPE_STRING, &str);
534 str = __connman_service_type2string(technology->type);
536 connman_dbus_dict_append_basic(&dict, "Type",
537 DBUS_TYPE_STRING, &str);
539 __sync_synchronize();
540 val = technology->enabled;
541 connman_dbus_dict_append_basic(&dict, "Powered",
545 val = technology->connected;
546 connman_dbus_dict_append_basic(&dict, "Connected",
550 val = technology->tethering;
551 connman_dbus_dict_append_basic(&dict, "Tethering",
555 if (technology->tethering_ident)
556 connman_dbus_dict_append_basic(&dict, "TetheringIdentifier",
558 &technology->tethering_ident);
560 if (technology->tethering_passphrase)
561 connman_dbus_dict_append_basic(&dict, "TetheringPassphrase",
563 &technology->tethering_passphrase);
565 val = technology->tethering_hidden;
566 connman_dbus_dict_append_basic(&dict, "Hidden",
570 connman_dbus_dict_close(iter, &dict);
573 static void technology_added_signal(struct connman_technology *technology)
576 DBusMessageIter iter;
578 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
579 CONNMAN_MANAGER_INTERFACE, "TechnologyAdded");
583 dbus_message_iter_init_append(signal, &iter);
584 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
586 append_properties(&iter, technology);
588 dbus_connection_send(connection, signal, NULL);
589 dbus_message_unref(signal);
592 static void technology_removed_signal(struct connman_technology *technology)
594 g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
595 CONNMAN_MANAGER_INTERFACE, "TechnologyRemoved",
596 DBUS_TYPE_OBJECT_PATH, &technology->path,
600 static DBusMessage *get_properties(DBusConnection *conn,
601 DBusMessage *message, void *user_data)
603 struct connman_technology *technology = user_data;
605 DBusMessageIter iter;
607 reply = dbus_message_new_method_return(message);
611 dbus_message_iter_init_append(reply, &iter);
612 append_properties(&iter, technology);
617 void __connman_technology_list_struct(DBusMessageIter *array)
620 DBusMessageIter entry;
622 for (list = technology_list; list; list = list->next) {
623 struct connman_technology *technology = list->data;
625 if (!technology->path ||
626 (technology->rfkill_driven &&
627 technology->hardblocked))
630 dbus_message_iter_open_container(array, DBUS_TYPE_STRUCT,
632 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
634 append_properties(&entry, technology);
635 dbus_message_iter_close_container(array, &entry);
639 static gboolean technology_pending_reply(gpointer user_data)
641 struct connman_technology *technology = user_data;
644 /* Power request timedout, send ETIMEDOUT. */
645 if (technology->pending_reply) {
646 reply = __connman_error_failed(technology->pending_reply, ETIMEDOUT);
648 g_dbus_send_message(connection, reply);
650 dbus_message_unref(technology->pending_reply);
651 technology->pending_reply = NULL;
652 technology->pending_timeout = 0;
658 static int technology_affect_devices(struct connman_technology *technology,
661 int err = 0, err_dev;
664 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
666 __connman_technology_enabled(technology->type);
668 __connman_technology_disabled(technology->type);
672 for (list = technology->device_list; list; list = list->next) {
673 struct connman_device *device = list->data;
676 err_dev = __connman_device_enable(device);
678 err_dev = __connman_device_disable(device);
680 if (err_dev < 0 && err_dev != -EALREADY)
687 static void powered_changed(struct connman_technology *technology)
691 if (!technology->dbus_registered)
694 if (technology->pending_reply) {
695 g_dbus_send_reply(connection,
696 technology->pending_reply, DBUS_TYPE_INVALID);
697 dbus_message_unref(technology->pending_reply);
698 technology->pending_reply = NULL;
700 g_source_remove(technology->pending_timeout);
701 technology->pending_timeout = 0;
704 __sync_synchronize();
705 enabled = technology->enabled;
706 #if defined TIZEN_EXT
707 DBG("ConnMan, Powered : %s, %s",
708 enabled ? "TRUE" : "FALSE",technology->path);
710 connman_dbus_property_changed_basic(technology->path,
711 CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
712 DBUS_TYPE_BOOLEAN, &enabled);
715 static void enable_tethering(struct connman_technology *technology)
719 if (!connman_setting_get_bool("PersistentTetheringMode"))
722 ret = set_tethering(technology, true);
723 if (ret < 0 && ret != -EALREADY)
724 DBG("Cannot enable tethering yet for %s (%d/%s)",
725 get_name(technology->type),
726 -ret, strerror(-ret));
729 static int technology_enabled(struct connman_technology *technology)
731 __sync_synchronize();
732 if (technology->enabled)
735 technology->enabled = true;
737 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
738 struct connman_technology *p2p;
740 p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
741 if (p2p && !p2p->enabled && p2p->enable_persistent)
742 technology_enabled(p2p);
745 if (technology->tethering_persistent)
746 enable_tethering(technology);
748 powered_changed(technology);
753 static int technology_enable(struct connman_technology *technology)
758 DBG("technology %p enable", technology);
760 __sync_synchronize();
762 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
763 struct connman_technology *wifi;
765 wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
766 if (wifi && wifi->enabled)
767 return technology_enabled(technology);
771 if (technology->enabled)
774 if (technology->pending_reply)
777 if (connman_setting_get_bool("PersistentTetheringMode") &&
778 technology->tethering)
779 set_tethering(technology, true);
781 if (technology->rfkill_driven)
782 err = __connman_rfkill_block(technology->type, false);
784 err_dev = technology_affect_devices(technology, true);
786 if (!technology->rfkill_driven)
792 static int technology_disabled(struct connman_technology *technology)
794 __sync_synchronize();
795 if (!technology->enabled)
798 technology->enabled = false;
800 powered_changed(technology);
805 static int technology_disable(struct connman_technology *technology)
809 DBG("technology %p disable", technology);
811 __sync_synchronize();
813 if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
814 technology->enable_persistent = false;
815 return technology_disabled(technology);
816 } else if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
817 struct connman_technology *p2p;
819 p2p = technology_find(CONNMAN_SERVICE_TYPE_P2P);
820 if (p2p && p2p->enabled) {
821 p2p->enable_persistent = true;
822 technology_disabled(p2p);
826 if (!technology->enabled)
829 if (technology->pending_reply)
832 if (technology->tethering)
833 set_tethering(technology, false);
835 err = technology_affect_devices(technology, false);
837 if (technology->rfkill_driven)
838 err = __connman_rfkill_block(technology->type, true);
843 static DBusMessage *set_powered(struct connman_technology *technology,
844 DBusMessage *msg, bool powered)
846 DBusMessage *reply = NULL;
849 if (technology->rfkill_driven && technology->hardblocked) {
855 err = technology_enable(technology);
857 err = technology_disable(technology);
860 technology->enable_persistent = powered;
861 technology_save(technology);
865 if (err == -EINPROGRESS) {
866 technology->pending_reply = dbus_message_ref(msg);
867 technology->pending_timeout = g_timeout_add_seconds(10,
868 technology_pending_reply, technology);
869 } else if (err == -EALREADY) {
871 reply = __connman_error_already_enabled(msg);
873 reply = __connman_error_already_disabled(msg);
875 reply = __connman_error_failed(msg, -err);
877 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
882 #if defined TIZEN_EXT
883 int set_connman_bssid(enum bssid_type mode, char *bssid)
885 static unsigned char bssid_for_connect[6];
886 static int bssid_len;
888 DBG("mode : %d", mode);
890 if (mode == CHECK_BSSID) {
894 if (mode == GET_BSSID && bssid) {
895 memcpy(bssid, bssid_for_connect, 6);
899 if (mode == RESET_BSSID) {
904 if (mode != SET_BSSID || !bssid) {
905 DBG("Invalid parameter");
909 bssid_len = sscanf(bssid, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
910 &bssid_for_connect[0], &bssid_for_connect[1], &bssid_for_connect[2],
911 &bssid_for_connect[3], &bssid_for_connect[4], &bssid_for_connect[5]);
912 if (bssid_len != 6) {
913 DBG("Incorrect BSSID format. bssid_len = %d", bssid_len);
917 DBG("SET BSSID len : %d, BSSID : %02x:%02x:%02x:%02x:%02x:%02x", bssid_len,
918 bssid_for_connect[0], bssid_for_connect[1], bssid_for_connect[2],
919 bssid_for_connect[3], bssid_for_connect[4], bssid_for_connect[5]);
925 static DBusMessage *set_property(DBusConnection *conn,
926 DBusMessage *msg, void *data)
928 struct connman_technology *technology = data;
929 DBusMessageIter iter, value;
933 DBG("conn %p", conn);
935 if (!dbus_message_iter_init(msg, &iter))
936 return __connman_error_invalid_arguments(msg);
938 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
939 return __connman_error_invalid_arguments(msg);
941 dbus_message_iter_get_basic(&iter, &name);
942 dbus_message_iter_next(&iter);
944 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
945 return __connman_error_invalid_arguments(msg);
947 dbus_message_iter_recurse(&iter, &value);
949 type = dbus_message_iter_get_arg_type(&value);
951 DBG("property %s", name);
953 if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && technology->connected) {
955 if (connman_dbus_get_connection_unix_user_sync(conn,
956 dbus_message_get_sender(msg),
958 DBG("Can not get unix user id!");
959 return __connman_error_permission_denied(msg);
962 if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
963 DBG("Not allow this user to operate wifi technology now!");
964 return __connman_error_permission_denied(msg);
968 if (g_str_equal(name, "Tethering")) {
969 dbus_bool_t tethering;
972 if (type != DBUS_TYPE_BOOLEAN)
973 return __connman_error_invalid_arguments(msg);
975 if (!connman_technology_is_tethering_allowed(technology->type)) {
976 DBG("%s tethering not allowed by config file",
977 __connman_service_type2string(technology->type));
978 return __connman_error_not_supported(msg);
981 dbus_message_iter_get_basic(&value, &tethering);
983 if (technology->tethering == tethering) {
985 return __connman_error_already_disabled(msg);
987 return __connman_error_already_enabled(msg);
990 err = set_tethering(technology, tethering);
992 return __connman_error_failed(msg, -err);
994 technology->tethering_persistent = tethering;
996 technology_save(technology);
998 } else if (g_str_equal(name, "TetheringIdentifier")) {
1001 dbus_message_iter_get_basic(&value, &str);
1003 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1004 return __connman_error_not_supported(msg);
1006 if (strlen(str) < 1 || strlen(str) > 32)
1007 return __connman_error_invalid_arguments(msg);
1009 if (g_strcmp0(technology->tethering_ident, str) != 0) {
1010 g_free(technology->tethering_ident);
1011 technology->tethering_ident = g_strdup(str);
1012 technology_save(technology);
1014 connman_dbus_property_changed_basic(technology->path,
1015 CONNMAN_TECHNOLOGY_INTERFACE,
1016 "TetheringIdentifier",
1018 &technology->tethering_ident);
1020 } else if (g_str_equal(name, "TetheringPassphrase")) {
1023 dbus_message_iter_get_basic(&value, &str);
1025 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1026 return __connman_error_not_supported(msg);
1028 err = __connman_service_check_passphrase(CONNMAN_SERVICE_SECURITY_PSK,
1031 return __connman_error_passphrase_required(msg);
1033 if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
1034 g_free(technology->tethering_passphrase);
1035 technology->tethering_passphrase = g_strdup(str);
1036 technology_save(technology);
1038 connman_dbus_property_changed_basic(technology->path,
1039 CONNMAN_TECHNOLOGY_INTERFACE,
1040 "TetheringPassphrase",
1042 &technology->tethering_passphrase);
1044 } else if (g_str_equal(name, "Hidden")) {
1047 if (type != DBUS_TYPE_BOOLEAN)
1048 return __connman_error_invalid_arguments(msg);
1050 dbus_message_iter_get_basic(&value, &hidden);
1052 if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
1053 return __connman_error_not_supported(msg);
1055 technology->tethering_hidden = hidden;
1056 technology_save(technology);
1058 connman_dbus_property_changed_basic(technology->path,
1059 CONNMAN_TECHNOLOGY_INTERFACE,
1063 } else if (g_str_equal(name, "Powered")) {
1066 if (type != DBUS_TYPE_BOOLEAN)
1067 return __connman_error_invalid_arguments(msg);
1069 dbus_message_iter_get_basic(&value, &enable);
1071 return set_powered(technology, msg, enable);
1072 #if defined TIZEN_EXT
1073 } else if (g_str_equal(name, "SetBSSID")) {
1076 if (type != DBUS_TYPE_STRING)
1077 return __connman_error_invalid_arguments(msg);
1079 dbus_message_iter_get_basic(&value, &key);
1080 DBG("BSSID %s", key);
1081 set_connman_bssid(SET_BSSID, key);
1084 return __connman_error_invalid_property(msg);
1086 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1089 static void reply_scan_pending(struct connman_technology *technology, int err)
1093 DBG("technology %p err %d", technology, err);
1095 while (technology->scan_pending) {
1096 DBusMessage *msg = technology->scan_pending->data;
1098 DBG("reply to %s", dbus_message_get_sender(msg));
1101 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
1103 reply = __connman_error_failed(msg, -err);
1104 g_dbus_send_message(connection, reply);
1105 dbus_message_unref(msg);
1107 technology->scan_pending =
1108 g_slist_delete_link(technology->scan_pending,
1109 technology->scan_pending);
1113 #if defined TIZEN_EXT
1114 dbus_bool_t __connman_technology_notify_scan_changed(const char *key, void *val)
1117 DBusMessage *signal;
1118 DBusMessageIter iter;
1119 dbus_bool_t result = FALSE;
1121 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1122 CONNMAN_MANAGER_INTERFACE, "ScanChanged");
1126 dbus_message_iter_init_append(signal, &iter);
1127 connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_BOOLEAN, val);
1129 result = dbus_connection_send(connection, signal, NULL);
1130 dbus_message_unref(signal);
1132 DBG("Successfuly sent signal");
1138 void __connman_technology_scan_started(struct connman_device *device)
1140 DBG("device %p", device);
1141 #if defined TIZEN_EXT
1142 dbus_bool_t status = 1;
1143 __connman_technology_notify_scan_changed("scan_started", &status);
1147 void __connman_technology_scan_stopped(struct connman_device *device,
1148 enum connman_service_type type)
1151 struct connman_technology *technology;
1154 technology = technology_find(type);
1156 DBG("technology %p device %p", technology, device);
1161 for (list = technology->device_list; list; list = list->next) {
1162 struct connman_device *other_device = list->data;
1164 if (device == other_device)
1167 if (__connman_device_get_service_type(other_device) != type)
1170 if (connman_device_get_scanning(other_device))
1174 #if defined TIZEN_EXT
1176 DBusMessage *signal;
1177 DBusMessageIter iter;
1178 dbus_bool_t status = 0;
1179 __connman_technology_notify_scan_changed("scan_done", &status);
1181 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
1182 CONNMAN_MANAGER_INTERFACE, "ScanDone");
1186 dbus_message_iter_init_append(signal, &iter);
1187 connman_dbus_property_append_basic(&iter, "Scantype",
1188 DBUS_TYPE_INT32, &g_scan_type);
1190 dbus_connection_send(connection, signal, NULL);
1191 dbus_message_unref(signal);
1192 reply_scan_pending(technology, 0);
1194 DBG("Successfuly sent ScanDone signal");
1198 reply_scan_pending(technology, 0);
1202 void __connman_technology_notify_regdom_by_device(struct connman_device *device,
1203 int result, const char *alpha2)
1205 bool regdom_set = false;
1206 struct connman_technology *technology;
1207 enum connman_service_type type;
1208 GSList *tech_drivers;
1210 type = __connman_device_get_service_type(device);
1211 technology = technology_find(type);
1218 for (tech_drivers = technology->driver_list;
1220 tech_drivers = g_slist_next(tech_drivers)) {
1221 struct connman_technology_driver *driver =
1224 if (driver->set_regdom) {
1225 driver->set_regdom(technology, alpha2);
1235 connman_technology_regdom_notify(technology, alpha2);
1238 static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
1240 struct connman_technology *technology = data;
1243 DBG("technology %p request from %s", technology,
1244 dbus_message_get_sender(msg));
1246 if (technology->type == CONNMAN_SERVICE_TYPE_P2P &&
1247 !technology->enabled)
1248 return __connman_error_permission_denied(msg);
1250 dbus_message_ref(msg);
1251 #if !defined TIZEN_EXT
1252 technology->scan_pending =
1253 g_slist_prepend(technology->scan_pending, msg);
1256 err = __connman_device_request_scan(technology->type);
1257 #if defined TIZEN_EXT
1259 return __connman_error_failed(msg, -err);
1262 reply_scan_pending(technology, err);
1265 #if defined TIZEN_EXT
1267 g_scan_type = CONNMAN_SCAN_TYPE_FULL_CHANNEL;
1268 DBG("g_scan_type %d", g_scan_type);
1270 technology->scan_pending =
1271 g_slist_prepend(technology->scan_pending, msg);
1276 #if defined TIZEN_EXT
1277 static DBusMessage *specific_scan(DBusConnection *conn, DBusMessage *msg, void *data)
1279 struct connman_technology *technology = data;
1280 GSList *specific_scan_list = NULL;
1282 const char *name = NULL;
1283 unsigned int freq = 0;
1284 DBusMessageIter iter, dict;
1287 DBG("technology %p request from %s", technology,
1288 dbus_message_get_sender(msg));
1290 if (!dbus_message_iter_init(msg, &iter))
1291 return __connman_error_invalid_arguments(msg);
1293 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
1294 return __connman_error_invalid_arguments(msg);
1296 dbus_message_iter_recurse(&iter, &dict);
1297 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
1298 DBusMessageIter entry, value2;
1302 dbus_message_iter_recurse(&dict, &entry);
1303 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) {
1304 g_slist_free_full(specific_scan_list, g_free);
1305 return __connman_error_invalid_arguments(msg);
1308 dbus_message_iter_get_basic(&entry, &key);
1309 dbus_message_iter_next(&entry);
1311 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) {
1312 g_slist_free_full(specific_scan_list, g_free);
1313 return __connman_error_invalid_arguments(msg);
1316 dbus_message_iter_recurse(&entry, &value2);
1317 type = dbus_message_iter_get_arg_type(&value2);
1318 if (g_str_equal(key, "SSID")) {
1319 if (type != DBUS_TYPE_STRING) {
1320 g_slist_free_full(specific_scan_list, g_free);
1321 return __connman_error_invalid_arguments(msg);
1324 scan_type = 1; /* SSID based scan */
1325 dbus_message_iter_get_basic(&value2, &name);
1326 DBG("name %s", name);
1327 specific_scan_list = g_slist_append(specific_scan_list, g_strdup(name));
1328 } else if (g_str_equal(key, "Frequency")) {
1329 if (type != DBUS_TYPE_UINT16) {
1330 g_slist_free_full(specific_scan_list, g_free);
1331 return __connman_error_invalid_arguments(msg);
1334 scan_type = 2; /* Frequency based scan */
1335 dbus_message_iter_get_basic(&value2, &freq);
1336 DBG("freq %d", freq);
1337 specific_scan_list = g_slist_append(specific_scan_list, GINT_TO_POINTER(freq));
1339 dbus_message_iter_next(&dict);
1342 dbus_message_ref(msg);
1344 err = __connman_device_request_specific_scan(technology->type, scan_type, specific_scan_list);
1346 return __connman_error_failed(msg, -err);
1349 guint list_size = g_slist_length(specific_scan_list);
1351 g_scan_type = CONNMAN_SCAN_TYPE_SPECIFIC_AP;
1353 g_scan_type = CONNMAN_SCAN_TYPE_MULTI_AP;
1354 DBG("list_size %u g_scan_type %d", list_size, g_scan_type);
1356 technology->scan_pending =
1357 g_slist_prepend(technology->scan_pending, msg);
1359 if (scan_type == 1) {
1360 g_slist_free_full(specific_scan_list, g_free);
1366 static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
1369 DBusMessageIter iter, dict;
1371 struct connman_technology *technology = data;
1372 dbus_bool_t scanning = false;
1374 DBG("technology %p", technology);
1376 for (list = technology->device_list; list; list = list->next) {
1377 struct connman_device *device = list->data;
1378 scanning = connman_device_get_scanning(device);
1383 DBG("scanning : %d", scanning);
1384 reply = dbus_message_new_method_return(msg);
1388 dbus_message_iter_init_append(reply, &iter);
1390 connman_dbus_dict_open(&iter, &dict);
1391 connman_dbus_dict_append_basic(&dict, "Scanstate",
1395 connman_dbus_dict_close(&iter, &dict);
1401 static const GDBusMethodTable technology_methods[] = {
1402 { GDBUS_DEPRECATED_METHOD("GetProperties",
1403 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
1405 { GDBUS_ASYNC_METHOD("SetProperty",
1406 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
1407 NULL, set_property) },
1408 { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
1409 #if defined TIZEN_EXT
1410 { GDBUS_ASYNC_METHOD("SpecificScan", GDBUS_ARGS({ "specificscan", "a{sv}" }),
1411 NULL, specific_scan) },
1412 { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
1418 static const GDBusSignalTable technology_signals[] = {
1419 { GDBUS_SIGNAL("PropertyChanged",
1420 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
1421 { GDBUS_SIGNAL("DhcpConnected",
1422 GDBUS_ARGS({ "aptype", "s" },
1425 { "hostname", "s" })) },
1426 { GDBUS_SIGNAL("DhcpLeaseDeleted",
1427 GDBUS_ARGS({ "aptype", "s" },
1430 { "hostname", "s" })) },
1434 static bool technology_dbus_register(struct connman_technology *technology)
1436 if (technology->dbus_registered ||
1437 (technology->rfkill_driven &&
1438 technology->hardblocked))
1441 if (!g_dbus_register_interface(connection, technology->path,
1442 CONNMAN_TECHNOLOGY_INTERFACE,
1443 technology_methods, technology_signals,
1444 NULL, technology, NULL)) {
1445 connman_error("Failed to register %s", technology->path);
1449 technology_added_signal(technology);
1450 technology->dbus_registered = true;
1455 static void technology_dbus_unregister(struct connman_technology *technology)
1457 if (!technology->dbus_registered)
1460 technology_removed_signal(technology);
1461 g_dbus_unregister_interface(connection, technology->path,
1462 CONNMAN_TECHNOLOGY_INTERFACE);
1464 technology->dbus_registered = false;
1467 static void technology_put(struct connman_technology *technology)
1469 DBG("technology %p", technology);
1471 if (__sync_sub_and_fetch(&technology->refcount, 1) > 0)
1474 reply_scan_pending(technology, -EINTR);
1476 while (technology->driver_list) {
1477 struct connman_technology_driver *driver;
1479 driver = technology->driver_list->data;
1482 driver->remove(technology);
1484 technology->driver_list =
1485 g_slist_delete_link(technology->driver_list,
1486 technology->driver_list);
1489 technology_list = g_slist_remove(technology_list, technology);
1491 technology_dbus_unregister(technology);
1493 g_slist_free(technology->device_list);
1495 if (technology->pending_reply) {
1496 dbus_message_unref(technology->pending_reply);
1497 technology->pending_reply = NULL;
1498 g_source_remove(technology->pending_timeout);
1499 technology->pending_timeout = 0;
1502 g_free(technology->path);
1503 g_free(technology->regdom);
1504 g_free(technology->tethering_ident);
1505 g_free(technology->tethering_passphrase);
1509 static struct connman_technology *technology_get(enum connman_service_type type)
1511 GSList *tech_drivers = NULL;
1512 struct connman_technology_driver *driver;
1513 struct connman_technology *technology;
1517 DBG("type %d", type);
1519 str = __connman_service_type2string(type);
1523 technology = technology_find(type);
1525 if (type != CONNMAN_SERVICE_TYPE_P2P)
1526 __sync_fetch_and_add(&technology->refcount, 1);
1530 /* First check if we have a driver for this technology type */
1531 for (list = driver_list; list; list = list->next) {
1532 driver = list->data;
1534 if (driver->type == type) {
1535 DBG("technology %p driver %p", technology, driver);
1536 tech_drivers = g_slist_append(tech_drivers, driver);
1540 if (!tech_drivers) {
1541 DBG("No matching drivers found for %s.",
1542 __connman_service_type2string(type));
1546 technology = g_try_new0(struct connman_technology, 1);
1550 technology->refcount = 1;
1551 technology->type = type;
1552 technology->tethering_hidden = FALSE;
1553 technology->path = g_strdup_printf("%s/technology/%s",
1556 technology_load(technology);
1557 technology_list = g_slist_prepend(technology_list, technology);
1558 technology->driver_list = tech_drivers;
1560 for (list = tech_drivers; list; list = list->next) {
1561 driver = list->data;
1563 if (driver->probe && driver->probe(technology) < 0)
1564 DBG("Driver probe failed for technology %p",
1568 if (!technology_dbus_register(technology)) {
1569 technology_put(technology);
1573 if (type == CONNMAN_SERVICE_TYPE_P2P) {
1574 struct connman_technology *wifi;
1577 enable = technology->enable_persistent;
1579 wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
1581 enable = wifi->enabled;
1583 technology_affect_devices(technology, enable);
1586 DBG("technology %p %s", technology, get_name(technology->type));
1591 int connman_technology_driver_register(struct connman_technology_driver *driver)
1594 struct connman_device *device;
1595 enum connman_service_type type;
1597 for (list = driver_list; list; list = list->next) {
1598 if (list->data == driver)
1602 DBG("Registering %s driver", driver->name);
1604 driver_list = g_slist_insert_sorted(driver_list, driver,
1608 * Check for technology less devices if this driver
1609 * can service any of them.
1611 for (list = techless_device_list; list; list = list->next) {
1612 device = list->data;
1614 type = __connman_device_get_service_type(device);
1615 if (type != driver->type)
1618 techless_device_list = g_slist_remove(techless_device_list,
1621 __connman_technology_add_device(device);
1624 /* Check for orphaned rfkill switches. */
1625 g_hash_table_foreach(rfkill_list, rfkill_check,
1626 GINT_TO_POINTER(driver->type));
1629 if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
1630 if (!technology_get(CONNMAN_SERVICE_TYPE_P2P))
1637 void connman_technology_driver_unregister(struct connman_technology_driver *driver)
1639 GSList *list, *tech_drivers;
1640 struct connman_technology *technology;
1641 struct connman_technology_driver *current;
1643 DBG("Unregistering driver %p name %s", driver, driver->name);
1645 for (list = technology_list; list; list = list->next) {
1646 technology = list->data;
1648 for (tech_drivers = technology->driver_list; tech_drivers;
1649 tech_drivers = g_slist_next(tech_drivers)) {
1650 current = tech_drivers->data;
1651 if (driver != current)
1655 driver->remove(technology);
1657 technology->driver_list =
1658 g_slist_remove(technology->driver_list,
1664 driver_list = g_slist_remove(driver_list, driver);
1666 if (driver->type == CONNMAN_SERVICE_TYPE_P2P) {
1667 technology = technology_find(CONNMAN_SERVICE_TYPE_P2P);
1669 technology_put(technology);
1673 void __connman_technology_add_interface(enum connman_service_type type,
1674 int index, const char *ident)
1676 struct connman_technology *technology;
1677 GSList *tech_drivers;
1678 struct connman_technology_driver *driver;
1682 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1683 case CONNMAN_SERVICE_TYPE_SYSTEM:
1685 case CONNMAN_SERVICE_TYPE_ETHERNET:
1686 case CONNMAN_SERVICE_TYPE_WIFI:
1687 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1688 case CONNMAN_SERVICE_TYPE_CELLULAR:
1689 case CONNMAN_SERVICE_TYPE_GPS:
1690 case CONNMAN_SERVICE_TYPE_VPN:
1691 case CONNMAN_SERVICE_TYPE_GADGET:
1692 case CONNMAN_SERVICE_TYPE_P2P:
1696 name = connman_inet_ifname(index);
1697 connman_info("Adding interface %s [ %s ]", name,
1698 __connman_service_type2string(type));
1700 technology = technology_find(type);
1705 for (tech_drivers = technology->driver_list; tech_drivers;
1706 tech_drivers = g_slist_next(tech_drivers)) {
1707 driver = tech_drivers->data;
1709 if (driver->add_interface)
1710 driver->add_interface(technology, index, name, ident);
1714 * At this point we can try to enable tethering automatically as
1715 * now the interfaces are set properly.
1717 if (technology->tethering_persistent)
1718 enable_tethering(technology);
1724 void __connman_technology_remove_interface(enum connman_service_type type,
1725 int index, const char *ident)
1727 struct connman_technology *technology;
1728 GSList *tech_drivers;
1729 struct connman_technology_driver *driver;
1733 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1734 case CONNMAN_SERVICE_TYPE_SYSTEM:
1736 case CONNMAN_SERVICE_TYPE_ETHERNET:
1737 case CONNMAN_SERVICE_TYPE_WIFI:
1738 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1739 case CONNMAN_SERVICE_TYPE_CELLULAR:
1740 case CONNMAN_SERVICE_TYPE_GPS:
1741 case CONNMAN_SERVICE_TYPE_VPN:
1742 case CONNMAN_SERVICE_TYPE_GADGET:
1743 case CONNMAN_SERVICE_TYPE_P2P:
1747 name = connman_inet_ifname(index);
1748 connman_info("Remove interface %s [ %s ]", name,
1749 __connman_service_type2string(type));
1752 technology = technology_find(type);
1757 for (tech_drivers = technology->driver_list; tech_drivers;
1758 tech_drivers = g_slist_next(tech_drivers)) {
1759 driver = tech_drivers->data;
1761 if (driver->remove_interface)
1762 driver->remove_interface(technology, index);
1766 int __connman_technology_add_device(struct connman_device *device)
1768 struct connman_technology *technology;
1769 enum connman_service_type type;
1771 type = __connman_device_get_service_type(device);
1773 DBG("device %p type %s", device, get_name(type));
1775 technology = technology_get(type);
1778 * Since no driver can be found for this device at the moment we
1779 * add it to the techless device list.
1781 techless_device_list = g_slist_prepend(techless_device_list,
1787 __sync_synchronize();
1788 if (technology->rfkill_driven) {
1789 if (technology->enabled)
1790 __connman_device_enable(device);
1792 __connman_device_disable(device);
1797 if (technology->enable_persistent &&
1798 !global_offlinemode) {
1799 int err = __connman_device_enable(device);
1801 * connman_technology_add_device() calls __connman_device_enable()
1802 * but since the device is already enabled, the calls does not
1803 * propagate through to connman_technology_enabled via
1804 * connman_device_set_powered.
1806 if (err == -EALREADY)
1807 __connman_technology_enabled(type);
1809 /* if technology persistent state is offline */
1810 if (!technology->enable_persistent)
1811 __connman_device_disable(device);
1814 technology->device_list = g_slist_prepend(technology->device_list,
1820 int __connman_technology_remove_device(struct connman_device *device)
1822 struct connman_technology *technology;
1823 enum connman_service_type type;
1825 DBG("device %p", device);
1827 type = __connman_device_get_service_type(device);
1829 technology = technology_find(type);
1831 techless_device_list = g_slist_remove(techless_device_list,
1836 technology->device_list = g_slist_remove(technology->device_list,
1839 if (technology->tethering)
1840 set_tethering(technology, false);
1842 technology_put(technology);
1847 int __connman_technology_enabled(enum connman_service_type type)
1849 struct connman_technology *technology;
1851 technology = technology_find(type);
1855 DBG("technology %p type %s rfkill %d enabled %d", technology,
1856 get_name(type), technology->rfkill_driven,
1857 technology->enabled);
1858 #if !defined TIZEN_EXT
1859 if (technology->rfkill_driven) {
1860 if (technology->tethering_persistent)
1861 enable_tethering(technology);
1866 return technology_enabled(technology);
1869 int __connman_technology_disabled(enum connman_service_type type)
1871 struct connman_technology *technology;
1874 technology = technology_find(type);
1877 #if !defined TIZEN_EXT
1878 if (technology->rfkill_driven)
1881 for (list = technology->device_list; list; list = list->next) {
1882 struct connman_device *device = list->data;
1884 if (connman_device_get_powered(device))
1888 return technology_disabled(technology);
1891 int __connman_technology_set_offlinemode(bool offlinemode)
1894 int err = -EINVAL, enabled_tech_count = 0;
1896 if (global_offlinemode == offlinemode)
1899 DBG("offlinemode %s", offlinemode ? "On" : "Off");
1902 * This is a bit tricky. When you set offlinemode, there is no
1903 * way to differentiate between attempting offline mode and
1904 * resuming offlinemode from last saved profile. We need that
1905 * information in rfkill_update, otherwise it falls back on the
1906 * technology's persistent state. Hence we set the offline mode here
1907 * but save it & call the notifier only if its successful.
1910 global_offlinemode = offlinemode;
1912 /* Traverse technology list, enable/disable each technology. */
1913 for (list = technology_list; list; list = list->next) {
1914 struct connman_technology *technology = list->data;
1917 err = technology_disable(technology);
1919 if (technology->hardblocked)
1922 if (technology->enable_persistent) {
1923 err = technology_enable(technology);
1924 enabled_tech_count++;
1929 if (err == 0 || err == -EINPROGRESS || err == -EALREADY ||
1930 (err == -EINVAL && enabled_tech_count == 0)) {
1931 connman_technology_save_offlinemode();
1932 __connman_notifier_offlinemode(offlinemode);
1934 global_offlinemode = connman_technology_load_offlinemode();
1939 void __connman_technology_set_connected(enum connman_service_type type,
1942 struct connman_technology *technology;
1945 technology = technology_find(type);
1949 DBG("technology %p connected %d", technology, connected);
1951 technology->connected = connected;
1954 connman_dbus_property_changed_basic(technology->path,
1955 CONNMAN_TECHNOLOGY_INTERFACE, "Connected",
1956 DBUS_TYPE_BOOLEAN, &val);
1959 static bool technology_apply_rfkill_change(struct connman_technology *technology,
1964 bool hardblock_changed = false;
1966 GList *start, *list;
1968 DBG("technology %p --> %d/%d vs %d/%d",
1969 technology, softblock, hardblock,
1970 technology->softblocked, technology->hardblocked);
1972 if (technology->hardblocked == hardblock)
1973 goto softblock_change;
1975 if (!(new_rfkill && !hardblock)) {
1976 start = g_hash_table_get_values(rfkill_list);
1978 for (list = start; list; list = list->next) {
1979 struct connman_rfkill *rfkill = list->data;
1981 if (rfkill->type != technology->type)
1984 if (rfkill->hardblock != hardblock)
1992 goto softblock_change;
1994 technology->hardblocked = hardblock;
1995 hardblock_changed = true;
1998 if (!apply && technology->softblocked != softblock)
2002 return technology->hardblocked;
2004 technology->softblocked = softblock;
2006 if (technology->hardblocked ||
2007 technology->softblocked) {
2008 if (technology_disabled(technology) != -EALREADY)
2009 technology_affect_devices(technology, false);
2010 } else if (!technology->hardblocked &&
2011 !technology->softblocked) {
2012 if (technology_enabled(technology) != -EALREADY)
2013 technology_affect_devices(technology, true);
2016 if (hardblock_changed) {
2017 if (technology->hardblocked) {
2018 DBG("%s is switched off.", get_name(technology->type));
2019 technology_dbus_unregister(technology);
2021 DBG("%s is switched on.", get_name(technology->type));
2022 technology_dbus_register(technology);
2024 if (global_offlinemode)
2025 __connman_rfkill_block(technology->type, true);
2029 return technology->hardblocked;
2032 int __connman_technology_add_rfkill(unsigned int index,
2033 enum connman_service_type type,
2037 struct connman_technology *technology;
2038 struct connman_rfkill *rfkill;
2040 DBG("index %u type %d soft %u hard %u", index, type,
2041 softblock, hardblock);
2043 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
2047 rfkill = g_try_new0(struct connman_rfkill, 1);
2051 rfkill->index = index;
2052 rfkill->type = type;
2053 rfkill->softblock = softblock;
2054 rfkill->hardblock = hardblock;
2056 g_hash_table_insert(rfkill_list, GINT_TO_POINTER(index), rfkill);
2059 #if defined TIZEN_EXT
2060 /* Fix Svace Issue [WGID: 1348]. */
2063 technology = technology_get(type);
2064 /* If there is no driver for this type, ignore it. */
2068 technology->rfkill_driven = true;
2070 #if !defined TIZEN_EXT
2071 /* If hardblocked, there is no need to handle softblocked state */
2072 if (technology_apply_rfkill_change(technology,
2073 softblock, hardblock, true))
2076 if (global_offlinemode)
2080 * Depending on softblocked state we unblock/block according to
2081 * offlinemode and persistente state.
2083 if (technology->softblocked &&
2084 technology->enable_persistent)
2085 return __connman_rfkill_block(type, false);
2086 else if (!technology->softblocked &&
2087 !technology->enable_persistent)
2088 return __connman_rfkill_block(type, true);
2093 int __connman_technology_update_rfkill(unsigned int index,
2094 enum connman_service_type type,
2098 struct connman_technology *technology;
2099 struct connman_rfkill *rfkill;
2101 DBG("index %u soft %u hard %u", index, softblock, hardblock);
2103 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
2107 if (rfkill->softblock == softblock &&
2108 rfkill->hardblock == hardblock)
2111 rfkill->softblock = softblock;
2112 rfkill->hardblock = hardblock;
2114 technology = technology_find(type);
2115 /* If there is no driver for this type, ignore it. */
2119 technology_apply_rfkill_change(technology, softblock, hardblock,
2122 if (technology->hardblocked)
2123 DBG("%s hardblocked", get_name(technology->type));
2125 DBG("%s is%s softblocked", get_name(technology->type),
2126 technology->softblocked ? "" : " not");
2131 int __connman_technology_remove_rfkill(unsigned int index,
2132 enum connman_service_type type)
2134 struct connman_technology *technology;
2135 struct connman_rfkill *rfkill;
2137 DBG("index %u", index);
2139 rfkill = g_hash_table_lookup(rfkill_list, GINT_TO_POINTER(index));
2143 g_hash_table_remove(rfkill_list, GINT_TO_POINTER(index));
2145 technology = technology_find(type);
2149 technology_apply_rfkill_change(technology,
2150 technology->softblocked, !technology->hardblocked, false);
2152 technology_put(technology);
2157 int __connman_technology_init(void)
2161 connection = connman_dbus_get_connection();
2163 rfkill_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
2166 global_offlinemode = connman_technology_load_offlinemode();
2168 /* This will create settings file if it is missing */
2169 connman_technology_save_offlinemode();
2174 void __connman_technology_cleanup(void)
2178 while (technology_list) {
2179 struct connman_technology *technology = technology_list->data;
2180 technology_list = g_slist_remove(technology_list, technology);
2181 technology_put(technology);
2184 g_hash_table_destroy(rfkill_list);
2186 dbus_connection_unref(connection);