Added some logs for debugging
[platform/upstream/connman.git] / src / technology.c
old mode 100644 (file)
new mode 100755 (executable)
index a06efd3..c43fc32
@@ -66,6 +66,7 @@ struct connman_technology {
                                              */
        char *tethering_ident;
        char *tethering_passphrase;
+       bool tethering_hidden;
 
        bool enable_persistent; /* Save the tech state */
 
@@ -84,6 +85,9 @@ struct connman_technology {
 
 static GSList *driver_list = NULL;
 
+static int technology_enabled(struct connman_technology *technology);
+static int technology_disabled(struct connman_technology *technology);
+
 static gint compare_priority(gconstpointer a, gconstpointer b)
 {
        const struct connman_technology_driver *driver1 = a;
@@ -177,6 +181,9 @@ static void technology_save(struct connman_technology *technology)
        g_key_file_set_boolean(keyfile, identifier, "Tethering",
                                technology->tethering_persistent);
 
+       g_key_file_set_boolean(keyfile, identifier, "Hidden",
+                               technology->tethering_hidden);
+
        if (technology->tethering_ident)
                g_key_file_set_string(keyfile, identifier,
                                        "Tethering.Identifier",
@@ -233,9 +240,11 @@ static int set_tethering(struct connman_technology *technology,
        int err;
        const char *ident, *passphrase, *bridge;
        GSList *tech_drivers;
+       bool hidden;
 
        ident = technology->tethering_ident;
        passphrase = technology->tethering_passphrase;
+       hidden = technology->tethering_hidden;
 
        __sync_synchronize();
        if (!technology->enabled)
@@ -245,8 +254,7 @@ static int set_tethering(struct connman_technology *technology,
        if (!bridge)
                return -EOPNOTSUPP;
 
-       if (technology->type == CONNMAN_SERVICE_TYPE_WIFI &&
-           (!ident || !passphrase))
+       if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && (!ident))
                return -EINVAL;
 
        for (tech_drivers = technology->driver_list; tech_drivers;
@@ -257,7 +265,7 @@ static int set_tethering(struct connman_technology *technology,
                        continue;
 
                err = driver->set_tethering(technology, ident, passphrase,
-                               bridge, enabled);
+                               bridge, enabled, hidden);
 
                if (result == -EINPROGRESS)
                        continue;
@@ -524,6 +532,11 @@ static void append_properties(DBusMessageIter *iter,
                                        DBUS_TYPE_STRING,
                                        &technology->tethering_passphrase);
 
+       val = technology->tethering_hidden;
+       connman_dbus_dict_append_basic(&dict, "Hidden",
+                                       DBUS_TYPE_BOOLEAN,
+                                       &val);
+
        connman_dbus_dict_close(iter, &dict);
 }
 
@@ -615,19 +628,27 @@ static gboolean technology_pending_reply(gpointer user_data)
 static int technology_affect_devices(struct connman_technology *technology,
                                                bool enable_device)
 {
+       int err = 0, err_dev;
        GSList *list;
-       int err = -ENXIO;
 
-       if (technology->type == CONNMAN_SERVICE_TYPE_P2P)
+       if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
+               if (enable_device)
+                       __connman_technology_enabled(technology->type);
+               else
+                       __connman_technology_disabled(technology->type);
                return 0;
+       }
 
        for (list = technology->device_list; list; list = list->next) {
                struct connman_device *device = list->data;
 
                if (enable_device)
-                       err = __connman_device_enable(device);
+                       err_dev = __connman_device_enable(device);
                else
-                       err = __connman_device_disable(device);
+                       err_dev = __connman_device_disable(device);
+
+               if (err_dev < 0 && err_dev != -EALREADY)
+                       err = err_dev;
        }
 
        return err;
@@ -652,6 +673,10 @@ static void powered_changed(struct connman_technology *technology)
 
        __sync_synchronize();
        enabled = technology->enabled;
+#if defined TIZEN_EXT
+       DBG("ConnMan, Powered : %s, %s",
+                       enabled ? "TRUE" : "FALSE",technology->path);
+#endif
        connman_dbus_property_changed_basic(technology->path,
                        CONNMAN_TECHNOLOGY_INTERFACE, "Powered",
                        DBUS_TYPE_BOOLEAN, &enabled);
@@ -852,6 +877,21 @@ static DBusMessage *set_property(DBusConnection *conn,
 
        DBG("property %s", name);
 
+       if (technology->type == CONNMAN_SERVICE_TYPE_WIFI && technology->connected) {
+               uid_t uid;
+               if (connman_dbus_get_connection_unix_user_sync(conn,
+                                               dbus_message_get_sender(msg),
+                                               &uid) < 0) {
+                       DBG("Can not get unix user id!");
+                       return __connman_error_permission_denied(msg);
+               }
+
+               if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
+                       DBG("Not allow this user to operate wifi technology now!");
+                       return __connman_error_permission_denied(msg);
+               }
+       }
+
        if (g_str_equal(name, "Tethering")) {
                dbus_bool_t tethering;
                int err;
@@ -912,20 +952,50 @@ static DBusMessage *set_property(DBusConnection *conn,
                if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
                        return __connman_error_not_supported(msg);
 
-               if (strlen(str) < 8 || strlen(str) > 63)
-                       return __connman_error_passphrase_required(msg);
+               if (strlen(str) < 8 || strlen(str) > 63) {
+                       if (g_str_equal(str, "")) {
+                               technology->tethering_passphrase = NULL;
 
-               if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
-                       g_free(technology->tethering_passphrase);
-                       technology->tethering_passphrase = g_strdup(str);
-                       technology_save(technology);
+                               connman_dbus_property_changed_basic(technology->path,
+                                               CONNMAN_TECHNOLOGY_INTERFACE,
+                                               "TetheringPassphrase",
+                                               DBUS_TYPE_STRING,
+                                               &str);
+                       }
+                       else
+                               return __connman_error_passphrase_required(msg);
+               } else {
+                       if (g_strcmp0(technology->tethering_passphrase, str) != 0) {
+                               g_free(technology->tethering_passphrase);
+                               technology->tethering_passphrase = g_strdup(str);
+                               technology_save(technology);
 
-                       connman_dbus_property_changed_basic(technology->path,
-                                       CONNMAN_TECHNOLOGY_INTERFACE,
-                                       "TetheringPassphrase",
-                                       DBUS_TYPE_STRING,
-                                       &technology->tethering_passphrase);
+                               connman_dbus_property_changed_basic(technology->path,
+                                               CONNMAN_TECHNOLOGY_INTERFACE,
+                                               "TetheringPassphrase",
+                                               DBUS_TYPE_STRING,
+                                               &technology->tethering_passphrase);
+                       }
                }
+       } else if (g_str_equal(name, "Hidden")) {
+               dbus_bool_t hidden;
+
+               if (type != DBUS_TYPE_BOOLEAN)
+                       return __connman_error_invalid_arguments(msg);
+
+               dbus_message_iter_get_basic(&value, &hidden);
+
+               if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+                       return __connman_error_not_supported(msg);
+
+               technology->tethering_hidden = hidden;
+               technology_save(technology);
+
+               connman_dbus_property_changed_basic(technology->path,
+                                       CONNMAN_TECHNOLOGY_INTERFACE,
+                                       "Hidden",
+                                       DBUS_TYPE_BOOLEAN,
+                                       &hidden);
        } else if (g_str_equal(name, "Powered")) {
                dbus_bool_t enable;
 
@@ -965,9 +1035,38 @@ static void reply_scan_pending(struct connman_technology *technology, int err)
        }
 }
 
+#if defined TIZEN_EXT
+dbus_bool_t __connman_technology_notify_scan_changed(const char *key, void *val)
+{
+       DBG("key %s", key);
+       DBusMessage *signal;
+       DBusMessageIter iter;
+       dbus_bool_t result = FALSE;
+
+       signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+                       CONNMAN_MANAGER_INTERFACE, "ScanChanged");
+       if (!signal)
+               return result;
+
+       dbus_message_iter_init_append(signal, &iter);
+       connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_BOOLEAN, val);
+
+       result = dbus_connection_send(connection, signal, NULL);
+       dbus_message_unref(signal);
+
+       DBG("Successfuly sent signal");
+
+       return result;
+}
+#endif
+
 void __connman_technology_scan_started(struct connman_device *device)
 {
        DBG("device %p", device);
+#if defined TIZEN_EXT
+       dbus_bool_t status = 1;
+       __connman_technology_notify_scan_changed("scan_started", &status);
+#endif
 }
 
 void __connman_technology_scan_stopped(struct connman_device *device,
@@ -997,8 +1096,25 @@ void __connman_technology_scan_stopped(struct connman_device *device,
                        count += 1;
        }
 
+#if defined TIZEN_EXT
+       if (count == 0) {
+               DBusMessage *signal;
+               dbus_bool_t status = 0;
+               __connman_technology_notify_scan_changed("scan_done", &status);
+
+               signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+                                                                               CONNMAN_MANAGER_INTERFACE, "ScanDone");
+               if (!signal)
+                       return;
+
+               dbus_connection_send(connection, signal, NULL);
+               dbus_message_unref(signal);
+               reply_scan_pending(technology, 0);
+       }
+#else
        if (count == 0)
                reply_scan_pending(technology, 0);
+#endif
 }
 
 void __connman_technology_notify_regdom_by_device(struct connman_device *device,
@@ -1056,6 +1172,42 @@ static DBusMessage *scan(DBusConnection *conn, DBusMessage *msg, void *data)
        return NULL;
 }
 
+#if defined TIZEN_EXT
+static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+       DBusMessage *reply;
+       DBusMessageIter iter, dict;
+       GSList *list;
+       struct connman_technology *technology = data;
+       dbus_bool_t scanning = false;
+
+       DBG("technology %p", technology);
+
+       for (list = technology->device_list; list; list = list->next) {
+               struct connman_device *device = list->data;
+               scanning = connman_device_get_scanning(device);
+               if(scanning)
+                       break;
+       }
+
+       DBG("scanning : %d", scanning);
+       reply = dbus_message_new_method_return(msg);
+       if (!reply)
+               return NULL;
+
+       dbus_message_iter_init_append(reply, &iter);
+
+       connman_dbus_dict_open(&iter, &dict);
+       connman_dbus_dict_append_basic(&dict, "Scanstate",
+                                       DBUS_TYPE_BOOLEAN,
+                                       &scanning);
+
+       connman_dbus_dict_close(&iter, &dict);
+
+       return reply;
+}
+#endif
+
 static const GDBusMethodTable technology_methods[] = {
        { GDBUS_DEPRECATED_METHOD("GetProperties",
                        NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
@@ -1064,6 +1216,10 @@ static const GDBusMethodTable technology_methods[] = {
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
                        NULL, set_property) },
        { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) },
+#if defined TIZEN_EXT
+       { GDBUS_METHOD("GetScanState", NULL, GDBUS_ARGS({ "scan_state", "a{sv}" }),
+                       get_scan_state) },
+#endif
        { },
 };
 
@@ -1194,15 +1350,9 @@ static struct connman_technology *technology_get(enum connman_service_type type)
 
        technology->refcount = 1;
        technology->type = type;
+       technology->tethering_hidden = FALSE;
        technology->path = g_strdup_printf("%s/technology/%s",
                                                        CONNMAN_PATH, str);
-       if (type == CONNMAN_SERVICE_TYPE_P2P) {
-               struct connman_technology *wifi;
-
-               wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
-               if (wifi)
-                       technology->enabled = wifi->enabled;
-       }
 
        technology_load(technology);
        technology_list = g_slist_prepend(technology_list, technology);
@@ -1221,7 +1371,20 @@ static struct connman_technology *technology_get(enum connman_service_type type)
                return NULL;
        }
 
-       DBG("technology %p", technology);
+       if (type == CONNMAN_SERVICE_TYPE_P2P) {
+               struct connman_technology *wifi;
+               bool enable;
+
+               enable = technology->enable_persistent;
+
+               wifi = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
+               if (enable && wifi)
+                       enable = wifi->enabled;
+
+               technology_affect_devices(technology, enable);
+       }
+
+       DBG("technology %p %s", technology, get_name(technology->type));
 
        return technology;
 }
@@ -1493,12 +1656,13 @@ int __connman_technology_enabled(enum connman_service_type type)
        DBG("technology %p type %s rfkill %d enabled %d", technology,
                get_name(type), technology->rfkill_driven,
                technology->enabled);
-
+#if !defined TIZEN_EXT
        if (technology->rfkill_driven) {
                if (technology->tethering_persistent)
                        enable_tethering(technology);
                return 0;
        }
+#endif
 
        return technology_enabled(technology);
 }
@@ -1511,10 +1675,10 @@ int __connman_technology_disabled(enum connman_service_type type)
        technology = technology_find(type);
        if (!technology)
                return -ENXIO;
-
+#if !defined TIZEN_EXT
        if (technology->rfkill_driven)
                return 0;
-
+#endif
        for (list = technology->device_list; list; list = list->next) {
                struct connman_device *device = list->data;
 
@@ -1700,11 +1864,12 @@ done:
 
        technology->rfkill_driven = true;
 
+#if !defined TIZEN_EXT
        /* If hardblocked, there is no need to handle softblocked state */
        if (technology_apply_rfkill_change(technology,
                                softblock, hardblock, true))
                return 0;
-
+#endif
        if (global_offlinemode)
                return 0;
 
@@ -1807,6 +1972,12 @@ void __connman_technology_cleanup(void)
 {
        DBG("");
 
+       while (technology_list) {
+               struct connman_technology *technology = technology_list->data;
+               technology_list = g_slist_remove(technology_list, technology);
+               technology_put(technology);
+       }
+
        g_hash_table_destroy(rfkill_list);
 
        dbus_connection_unref(connection);