technology: Return technology name Cellular instead 3G
[framework/connectivity/connman.git] / src / technology.c
index 3b24917..de0fab8 100644 (file)
@@ -51,13 +51,13 @@ enum connman_technology_state {
 };
 
 struct connman_technology {
-       gint refcount;
+       int refcount;
        enum connman_service_type type;
        enum connman_technology_state state;
        char *path;
        GHashTable *rfkill_list;
        GSList *device_list;
-       gint enabled;
+       int enabled;
        char *regdom;
 
        connman_bool_t tethering;
@@ -154,6 +154,8 @@ static void tethering_changed(struct connman_technology *technology)
 void connman_technology_tethering_notify(struct connman_technology *technology,
                                                        connman_bool_t enabled)
 {
+       GSList *list;
+
        DBG("technology %p enabled %u", technology, enabled);
 
        if (technology->tethering == enabled)
@@ -165,8 +167,15 @@ void connman_technology_tethering_notify(struct connman_technology *technology,
 
        if (enabled == TRUE)
                __connman_tethering_set_enabled();
-       else
-               __connman_tethering_set_disabled();
+       else {
+               for (list = technology_list; list; list = list->next) {
+                       struct connman_technology *other_tech = list->data;
+                       if (other_tech->tethering == TRUE)
+                               break;
+               }
+               if (list == NULL)
+                       __connman_tethering_set_disabled();
+       }
 }
 
 static int set_tethering(struct connman_technology *technology,
@@ -300,7 +309,7 @@ static const char *get_name(enum connman_service_type type)
        case CONNMAN_SERVICE_TYPE_BLUETOOTH:
                return "Bluetooth";
        case CONNMAN_SERVICE_TYPE_CELLULAR:
-               return "3G";
+               return "Cellular";
        }
 
        return NULL;
@@ -566,7 +575,7 @@ static struct connman_technology *technology_get(enum connman_service_type type)
 
        technology = technology_find(type);
        if (technology != NULL) {
-               g_atomic_int_inc(&technology->refcount);
+               __sync_fetch_and_add(&technology->refcount, 1);
                goto done;
        }
 
@@ -633,7 +642,7 @@ static void technology_put(struct connman_technology *technology)
 {
        DBG("technology %p", technology);
 
-       if (g_atomic_int_dec_and_test(&technology->refcount) == FALSE)
+       if (__sync_fetch_and_sub(&technology->refcount, 1) != 1)
                return;
 
        if (technology->driver) {
@@ -800,7 +809,7 @@ int __connman_technology_enabled(enum connman_service_type type)
        if (technology == NULL)
                return -ENXIO;
 
-       if (g_atomic_int_exchange_and_add(&technology->enabled, 1) == 0) {
+       if (__sync_fetch_and_add(&technology->enabled, 1) == 0) {
                __connman_notifier_enable(type);
                technology->state = CONNMAN_TECHNOLOGY_STATE_ENABLED;
                state_changed(technology);
@@ -809,6 +818,7 @@ int __connman_technology_enabled(enum connman_service_type type)
        if (technology->pending_reply != NULL) {
                g_dbus_send_reply(connection, technology->pending_reply, DBUS_TYPE_INVALID);
                dbus_message_unref(technology->pending_reply);
+               g_source_remove(technology->pending_timeout);
                technology->pending_reply = NULL;
                technology->pending_timeout = 0;
        }
@@ -838,7 +848,6 @@ int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg
        }
 
        if (msg != NULL) {
-               technology->pending_reply = dbus_message_ref(msg);
                /*
                 * This is a bit of a trick. When msg is not NULL it means
                 * thats technology_enable was invoked from the manager API. Hence we save
@@ -850,6 +859,13 @@ int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg
 
        __connman_rfkill_block(technology->type, FALSE);
 
+       /*
+        * An empty device list means that devices in the technology
+        * were rfkill blocked. The unblock above will enable the devs.
+        */
+       if (technology->device_list == NULL)
+               return 0;
+
        for (list = technology->device_list; list; list = list->next) {
                struct connman_device *device = list->data;
 
@@ -864,14 +880,18 @@ int __connman_technology_enable(enum connman_service_type type, DBusMessage *msg
        }
 
 done:
-       if (ret == 0)
+       if (ret == 0) {
+               if (msg != NULL)
+                       g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
                return ret;
+       }
 
        if (msg != NULL) {
-               if (err == -EINPROGRESS)
+               if (err == -EINPROGRESS) {
+                       technology->pending_reply = dbus_message_ref(msg);
                        technology->pending_timeout = g_timeout_add_seconds(10,
                                        technology_pending_reply, technology);
-               else {
+               else {
                        reply = __connman_error_failed(msg, -err);
                        if (reply != NULL)
                                g_dbus_send_message(connection, reply);
@@ -892,14 +912,17 @@ int __connman_technology_disabled(enum connman_service_type type)
        if (technology->pending_reply != NULL) {
                g_dbus_send_reply(connection, technology->pending_reply, DBUS_TYPE_INVALID);
                dbus_message_unref(technology->pending_reply);
+               g_source_remove(technology->pending_timeout);
                technology->pending_reply = NULL;
+               technology->pending_timeout = 0;
        }
 
-       if (g_atomic_int_dec_and_test(&technology->enabled) == TRUE) {
-               __connman_notifier_disable(type);
-               technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
-               state_changed(technology);
-       }
+       if (__sync_fetch_and_sub(&technology->enabled, 1) != 1)
+               return 0;
+
+       __connman_notifier_disable(type);
+       technology->state = CONNMAN_TECHNOLOGY_STATE_OFFLINE;
+       state_changed(technology);
 
        return 0;
 }
@@ -925,8 +948,10 @@ int __connman_technology_disable(enum connman_service_type type, DBusMessage *ms
                goto done;
        }
 
+       if (technology->tethering == TRUE)
+               set_tethering(technology, FALSE);
+
        if (msg != NULL) {
-               technology->pending_reply = dbus_message_ref(msg);
                technology->enable_persistent = FALSE;
                save_state(technology);
        }
@@ -942,14 +967,18 @@ int __connman_technology_disable(enum connman_service_type type, DBusMessage *ms
        }
 
 done:
-       if (ret == 0)
+       if (ret == 0) {
+               if (msg != NULL)
+                       g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
                return ret;
+       }
 
        if (msg != NULL) {
-               if (err == -EINPROGRESS)
+               if (err == -EINPROGRESS) {
+                       technology->pending_reply = dbus_message_ref(msg);
                        technology->pending_timeout = g_timeout_add_seconds(10,
                                        technology_pending_reply, technology);
-               else {
+               else {
                        reply = __connman_error_failed(msg, -err);
                        if (reply != NULL)
                                g_dbus_send_message(connection, reply);
@@ -1019,6 +1048,8 @@ int __connman_technology_add_rfkill(unsigned int index,
        if (rfkill == NULL)
                return -ENOMEM;
 
+       __connman_notifier_register(type);
+
        rfkill->index = index;
        rfkill->type = type;
        rfkill->softblock = softblock;