Fix incorrect handling in multi-interface environment
[platform/upstream/connman.git] / src / device.c
index fa5a001..5350282 100755 (executable)
@@ -76,7 +76,10 @@ struct connman_device {
        time_t last_user_selection_time;
        char *last_user_selection_ident;
        char *last_connected_ident;
-       DBusMessage *pending_reply;
+       GList *pending_reply_list; /* List of DBusMessage* for async reply to multiple
+                                   * device power dbus calls, which are made before
+                                   * connman_device_set_powered().
+                                   */
        int max_scan_ssids;
        bool is_5_0_ghz_supported;
        unsigned int mac_policy;
@@ -85,12 +88,21 @@ struct connman_device {
 #endif
 };
 
+#if defined TIZEN_EXT
+static void __clear_pending_trigger(gpointer data, gpointer user_data)
+{
+       DBusMessage *msg = (DBusMessage *)data;
+       dbus_message_unref(msg);
+}
+#endif
+
 static void clear_pending_trigger(struct connman_device *device)
 {
 #if defined TIZEN_EXT
-       if (device->pending_reply) {
-               dbus_message_unref(device->pending_reply);
-               device->pending_reply = NULL;
+       if (device->pending_reply_list) {
+               g_list_foreach(device->pending_reply_list, __clear_pending_trigger, NULL);
+               g_list_free(device->pending_reply_list);
+               device->pending_reply_list = NULL;
        }
 #endif
        if (device->pending_timeout > 0) {
@@ -200,6 +212,20 @@ static bool device_has_service_type(struct connman_device *device,
        return service_type == device_service_type;
 }
 
+#if defined TIZEN_EXT
+static void __device_pending_reset(gpointer data, gpointer user_data)
+{
+       DBusMessage *msg = (DBusMessage *)data;
+       DBusMessage *reply;
+
+       reply = __connman_error_failed(msg, ETIMEDOUT);
+       if (reply)
+               g_dbus_send_message(connection, reply);
+
+       dbus_message_unref(msg);
+}
+#endif
+
 static gboolean device_pending_reset(gpointer user_data)
 {
        struct connman_device *device = user_data;
@@ -210,13 +236,10 @@ static gboolean device_pending_reset(gpointer user_data)
        DBusMessage *reply;
 
        /* Power request timed out, send ETIMEDOUT. */
-       if (device->pending_reply) {
-               reply = __connman_error_failed(device->pending_reply, ETIMEDOUT);
-               if (reply)
-                       g_dbus_send_message(connection, reply);
-
-               dbus_message_unref(device->pending_reply);
-               device->pending_reply = NULL;
+       if (device->pending_reply_list) {
+               g_list_foreach(device->pending_reply_list, __device_pending_reset, NULL);
+               g_list_free(device->pending_reply_list);
+               device->pending_reply_list = NULL;
        }
 #endif
        /* Power request timedout, reset power pending state. */
@@ -266,15 +289,22 @@ int __connman_device_enable(struct connman_device *device)
        if (err == -EALREADY) {
                /* If device is already powered, but connman is not updated */
                connman_device_set_powered(device, true);
+#ifdef TIZEN_EXT
+               if (device->type == CONNMAN_DEVICE_TYPE_WIFI) {
+                       device->driver->set_mac_policy(device, device->mac_policy);
+                       device->driver->set_preassoc_mac_policy(device, device->preassoc_mac_policy);
+                       device->driver->set_random_mac_lifetime(device, device->random_mac_lifetime);
+               }
+#endif /* TIZEN_EXT */
                goto done;
        }
        /*
         * if err == -EINPROGRESS, then the DBus call to the respective daemon
-        * was successful. We set a 4 sec timeout so if the daemon never
+        * was successful. We set a 10 sec timeout so if the daemon never
         * returns a reply, we would reset the pending request.
         */
        if (err == -EINPROGRESS)
-               device->pending_timeout = g_timeout_add_seconds(4,
+               device->pending_timeout = g_timeout_add_seconds(10,
                                        device_pending_reset, device);
 done:
        return err;
@@ -499,13 +529,19 @@ static void device_send_changed(const char *ifname, enum connman_service_type ty
        dbus_message_unref(signal);
 }
 
+static void __device_send_reply(gpointer data, gpointer user_data)
+{
+       DBusMessage *msg = (DBusMessage *)data;
+       g_dbus_send_reply(connection, msg, DBUS_TYPE_INVALID);
+       dbus_message_unref(msg);
+}
+
 static void device_send_reply(struct connman_device *device)
 {
-       if (device->pending_reply) {
-               g_dbus_send_reply(connection,
-                               device->pending_reply, DBUS_TYPE_INVALID);
-               dbus_message_unref(device->pending_reply);
-               device->pending_reply = NULL;
+       if (device->pending_reply_list) {
+               g_list_foreach(device->pending_reply_list, __device_send_reply, NULL);
+               g_list_free(device->pending_reply_list);
+               device->pending_reply_list = NULL;
        }
 }
 #endif
@@ -658,7 +694,7 @@ void connman_device_set_ident(struct connman_device *device,
                                                        const char *ident)
 {
 #ifdef TIZEN_EXT
-       if (device->ident)
+       if (device->ident && device->powered)
                return;
        else
 #endif
@@ -704,7 +740,6 @@ int connman_device_set_powered(struct connman_device *device,
 
 #if defined TIZEN_EXT
        device_send_changed(device->interface, type, "Powered", powered);
-       technology_save_device(device);
 #endif
 
        if (!device->powered) {
@@ -1105,7 +1140,7 @@ int connman_device_set_string(struct connman_device *device,
 
        if (g_str_equal(key, "Address")) {
 #ifdef TIZEN_EXT
-               if (device->address)
+               if (device->address && device->powered)
                        return 0;
                else
 #endif
@@ -1213,7 +1248,7 @@ struct connman_network *connman_device_get_default_network(
 void connman_device_set_pending_reply(struct connman_device *device,
                                                        DBusMessage *msg)
 {
-       device->pending_reply = dbus_message_ref(msg);
+       device->pending_reply_list = g_list_prepend(device->pending_reply_list, dbus_message_ref(msg));
 }
 
 void connman_device_send_connected_signal(struct connman_device *device,
@@ -1771,6 +1806,87 @@ void __connman_device_stop_scan(enum connman_service_type type)
 }
 
 #if defined TIZEN_EXT
+#define WIFI_MAC "/opt/etc/.mac.info"
+#define MAC_ADDR_LEN 18
+
+char *_get_wifi_addr(void)
+{
+       FILE *fp = NULL;
+       char* rv = 0;
+       char wifi_mac[MAC_ADDR_LEN + 1];
+       char *str;
+
+       fp = fopen(WIFI_MAC, "r");
+       if (!fp){
+               connman_error("[%s] not present", WIFI_MAC);
+               return NULL;
+       }
+
+       rv = fgets(wifi_mac, MAC_ADDR_LEN, fp);
+       if (!rv) {
+               connman_error("Failed to get wifi mac address");
+               fclose(fp);
+               return NULL;
+       }
+
+       str = g_try_malloc0(MAC_ADDR_LEN);
+       if (!str) {
+               connman_error("memory allocation failed");
+               fclose(fp);
+               return NULL;
+       }
+
+       snprintf(str, MAC_ADDR_LEN, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",
+                       g_ascii_tolower(wifi_mac[0]), g_ascii_tolower(wifi_mac[1]),
+                       g_ascii_tolower(wifi_mac[3]), g_ascii_tolower(wifi_mac[4]),
+                       g_ascii_tolower(wifi_mac[6]), g_ascii_tolower(wifi_mac[7]),
+                       g_ascii_tolower(wifi_mac[9]), g_ascii_tolower(wifi_mac[10]),
+                       g_ascii_tolower(wifi_mac[12]), g_ascii_tolower(wifi_mac[13]),
+                       g_ascii_tolower(wifi_mac[15]), g_ascii_tolower(wifi_mac[16]));
+       fclose(fp);
+       return str;
+}
+
+char *_get_wifi_ident(void)
+{
+       FILE *fp = NULL;
+       char* rv = 0;
+       char wifi_mac[MAC_ADDR_LEN + 1];
+       char *str;
+
+       fp = fopen(WIFI_MAC, "r");
+       if (!fp){
+               connman_error("[%s] not present", WIFI_MAC);
+               return NULL;
+       }
+
+       rv = fgets(wifi_mac, MAC_ADDR_LEN, fp);
+       if (!rv) {
+               connman_error("Failed to get wifi mac address");
+               fclose(fp);
+               return NULL;
+       }
+
+       str = g_try_malloc0(MAC_ADDR_LEN);
+       if (!str) {
+               connman_error("memory allocation failed");
+               fclose(fp);
+               return NULL;
+       }
+
+       snprintf(str, MAC_ADDR_LEN, "%c%c%c%c%c%c%c%c%c%c%c%c",
+                       g_ascii_tolower(wifi_mac[0]), g_ascii_tolower(wifi_mac[1]),
+                       g_ascii_tolower(wifi_mac[3]), g_ascii_tolower(wifi_mac[4]),
+                       g_ascii_tolower(wifi_mac[6]), g_ascii_tolower(wifi_mac[7]),
+                       g_ascii_tolower(wifi_mac[9]), g_ascii_tolower(wifi_mac[10]),
+                       g_ascii_tolower(wifi_mac[12]), g_ascii_tolower(wifi_mac[13]),
+                       g_ascii_tolower(wifi_mac[15]), g_ascii_tolower(wifi_mac[16]));
+       fclose(fp);
+       return str;
+}
+#endif
+
+#if defined TIZEN_EXT
 char *index2ident(int index, const char *prefix)
 #else
 static char *index2ident(int index, const char *prefix)