Online Check: Change default connection policy
[platform/upstream/connman.git] / src / service.c
old mode 100755 (executable)
new mode 100644 (file)
index c3bdc0e..bc08157
@@ -298,6 +298,10 @@ const char *__connman_service_type2string(enum connman_service_type type)
                return "gadget";
        case CONNMAN_SERVICE_TYPE_P2P:
                return "p2p";
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+               return "mesh";
+#endif
        }
 
        return NULL;
@@ -596,6 +600,9 @@ int __connman_service_load_modifiable(struct connman_service *service)
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                break;
        case CONNMAN_SERVICE_TYPE_VPN:
                set_split_routing(service, g_key_file_get_boolean(keyfile,
@@ -671,6 +678,9 @@ static int service_load(struct connman_service *service)
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                break;
        case CONNMAN_SERVICE_TYPE_VPN:
                set_split_routing(service, g_key_file_get_boolean(keyfile,
@@ -786,11 +796,17 @@ static int service_load(struct connman_service *service)
 
        dns_method = g_key_file_get_string(keyfile, service->identifier,
                        "Nameservers.IPv4method", NULL);
-       service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method);
+       if (dns_method) {
+               service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method);
+               g_free(dns_method);
+       }
 
        dns_method = g_key_file_get_string(keyfile, service->identifier,
                        "Nameservers.IPv6method", NULL);
-       service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method);
+       if (dns_method) {
+               service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method);
+               g_free(dns_method);
+       }
 #endif
 
        service->timeservers_config = g_key_file_get_string_list(keyfile,
@@ -927,6 +943,9 @@ static int service_save(struct connman_service *service)
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                break;
        case CONNMAN_SERVICE_TYPE_VPN:
                g_key_file_set_boolean(keyfile, service->identifier,
@@ -2156,8 +2175,13 @@ struct connman_service *connman_service_get_default_connection(void)
                                state2string(service->state),
                                __connman_service_type2string(service->type));
 
+#if defined TIZEN_MAINTAIN_ONLINE
+               if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+                               service->state == CONNMAN_SERVICE_STATE_ONLINE) {
+#else
                if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
                                is_connected(service->state) == TRUE) {
+#endif
                        return service;
                } else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
                                __connman_service_is_internet_profile(service) == TRUE) {
@@ -2183,6 +2207,9 @@ struct connman_service *connman_service_get_default_connection(void)
 
 struct connman_service *__connman_service_get_default(void)
 {
+#if defined TIZEN_MAINTAIN_ONLINE
+       return connman_service_get_default_connection();
+#else
        struct connman_service *service;
 
        if (!service_list)
@@ -2194,6 +2221,7 @@ struct connman_service *__connman_service_get_default(void)
                return NULL;
 
        return service;
+#endif
 }
 
 bool __connman_service_index_is_default(int index)
@@ -3230,6 +3258,9 @@ static void append_wifi_ext_info(DBusMessageIter *dict,
        const char *enc_mode;
        const char *str;
        gboolean passpoint;
+       char country_code_buff[WIFI_COUNTRY_CODE_LEN + 1] = {0,};
+       char *country_code_str = country_code_buff;
+       unsigned char *country_code;
 
        ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
        bssid = connman_network_get_bssid(network);
@@ -3238,11 +3269,16 @@ static void append_wifi_ext_info(DBusMessageIter *dict,
        enc_mode = connman_network_get_enc_mode(network);
        passpoint = connman_network_get_bool(network, "WiFi.HS20AP");
        keymgmt = connman_network_get_keymgmt(network);
+       country_code = connman_network_get_countrycode(network);
 
        snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
                                bssid[0], bssid[1], bssid[2],
                                bssid[3], bssid[4], bssid[5]);
 
+       snprintf(country_code_str, (WIFI_COUNTRY_CODE_LEN + 1), "%c%c",
+                country_code[0], country_code[1]);
+
+
        connman_dbus_dict_append_fixed_array(dict, "SSID",
                                        DBUS_TYPE_BYTE, &ssid, ssid_len);
        connman_dbus_dict_append_basic(dict, "BSSID",
@@ -3257,6 +3293,8 @@ static void append_wifi_ext_info(DBusMessageIter *dict,
                                        DBUS_TYPE_BOOLEAN, &passpoint);
        connman_dbus_dict_append_basic(dict, "Keymgmt",
                                        DBUS_TYPE_UINT32, &keymgmt);
+       connman_dbus_dict_append_basic(dict, "Country", DBUS_TYPE_STRING,
+                                      &country_code_str);
 
        str = connman_network_get_string(network, "WiFi.Security");
        if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) {
@@ -3293,6 +3331,33 @@ static void append_wifi_ext_info(DBusMessageIter *dict,
                                        DBUS_TYPE_STRING, &str);
        }
 }
+
+static void append_bssid_info(DBusMessageIter *iter, void *user_data)
+{
+        GSList *bssid_list = NULL;
+       struct connman_network *network = user_data;
+        struct connman_bssids *bssids;
+        char bssid_buf[18] = {0,};
+        char *bssid_str = bssid_buf;
+
+        bssid_list = (GSList *)connman_network_get_bssid_list(network);
+        if(bssid_list) {
+                GSList *list;
+                for (list = bssid_list; list; list = list->next) {
+                        bssids = (struct connman_bssids *)list->data;
+                        memcpy(bssid_str, bssids->bssid, 18);
+
+                       connman_dbus_dict_append_basic(iter, "BSSID",
+                                        DBUS_TYPE_STRING, &bssid_str);
+
+                        connman_dbus_dict_append_basic(iter, "Strength",
+                                        DBUS_TYPE_UINT16, &bssids->strength);
+
+                        connman_dbus_dict_append_basic(iter, "Frequency",
+                                        DBUS_TYPE_UINT16, &bssids->frequency);
+                }
+        }
+}
 #endif
 
 static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
@@ -3318,7 +3383,6 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
                vsie_list = (GSList *)connman_network_get_vsie_list(service->network);
 
        if (vsie_list) {
-               DBG("ConnMan, service->path=%s No.of elements in list: %d", service->path, g_slist_length(vsie_list));
                GSList *list;
                for (list = vsie_list; list; list = list->next) {
                        wifi_vsie = (unsigned char *)list->data;
@@ -3385,6 +3449,9 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_VPN:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                break;
        case CONNMAN_SERVICE_TYPE_CELLULAR:
                val = service->roaming;
@@ -3396,8 +3463,11 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
                break;
        case CONNMAN_SERVICE_TYPE_WIFI:
 #if defined TIZEN_EXT
-               if (service->network != NULL)
+               if (service->network != NULL) {
                        append_wifi_ext_info(dict, service->network);
+                       connman_dbus_dict_append_dict(dict, "BSSID.List",
+                                       append_bssid_info, service->network);
+               }
 
                connman_dbus_dict_append_dict(dict, "Ethernet",
                                                append_ethernet, service);
@@ -4808,6 +4878,19 @@ static DBusMessage *set_property(DBusConnection *conn,
                }
 
                service_save(service);
+#if defined TIZEN_EXT
+               /* When AP is connected using WPS without SSID then its password needs
+                * to be saved for autoconnection */
+       } else if (g_str_equal(name, "Passphrase")) {
+               char *passphrase;
+
+               if (type != DBUS_TYPE_STRING)
+                       return __connman_error_invalid_arguments(msg);
+
+               dbus_message_iter_get_basic(&value, &passphrase);
+
+               __connman_service_set_passphrase(service, passphrase);
+#endif
        } else
                return __connman_error_invalid_property(msg);
 
@@ -4988,6 +5071,9 @@ void __connman_service_set_active_session(bool enable, GSList *list)
                case CONNMAN_SERVICE_TYPE_GPS:
                case CONNMAN_SERVICE_TYPE_VPN:
                case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+               case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                        break;
                }
 
@@ -5123,6 +5209,12 @@ static bool auto_connect_service(GList *services,
 
        ignore[CONNMAN_SERVICE_TYPE_VPN] = true;
 
+#if defined TIZEN_EXT_WIFI_MESH
+       /* Don't auto connect wifi if mesh interface is created */
+       if (connman_mesh_is_interface_created())
+               ignore[CONNMAN_SERVICE_TYPE_WIFI] = true;
+#endif
+
        for (list = services; list; list = list->next) {
                service = list->data;
 
@@ -5605,6 +5697,7 @@ static void __connman_service_cleanup_network_8021x(struct connman_service *serv
        connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL);
        connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL);
        connman_network_set_string(service->network, "WiFi.Phase2", NULL);
+       connman_network_set_string(service->network, "WiFi.AnonymousIdentity", NULL);
 }
 #endif
 
@@ -5969,6 +6062,19 @@ static DBusMessage *get_user_favorite(DBusConnection *conn,
        return reply;
 }
 
+#if defined TIZEN_MAINTAIN_ONLINE
+static DBusMessage *downgrade_service(DBusConnection *conn,
+                                       DBusMessage *msg, void *user_data)
+{
+       struct connman_service *service = user_data;
+
+       downgrade_state(service);
+       __connman_connection_update_gateway();
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+#endif
+
 static struct _services_notify {
        int id;
        GHashTable *add;
@@ -6121,6 +6227,9 @@ static const GDBusMethodTable service_methods[] = {
        { GDBUS_METHOD("GetUserFavorite",
                        NULL, GDBUS_ARGS({ "value", "v" }),
                        get_user_favorite) },
+#if defined TIZEN_MAINTAIN_ONLINE
+       { GDBUS_METHOD("Downgrade", NULL, NULL, downgrade_service) },
+#endif
        { },
 };
 
@@ -7078,7 +7187,12 @@ static void __connman_service_disconnect_default(struct connman_service *service
                default_connecting_device = NULL;
 }
 
+#if defined TIZEN_MAINTAIN_ONLINE
+static void __connman_service_connect_default(struct connman_service *current,
+                                                                 enum connman_service_state old_state)
+#else
 static void __connman_service_connect_default(struct connman_service *current)
+#endif
 {
        int err;
        GList *list;
@@ -7115,6 +7229,11 @@ static void __connman_service_connect_default(struct connman_service *current)
                }
 
                return;
+#if defined TIZEN_MAINTAIN_ONLINE
+       } else if (current->state == CONNMAN_SERVICE_STATE_READY &&
+                          old_state == CONNMAN_SERVICE_STATE_ONLINE) {
+               DBG("Device is downgraded: online --> ready");
+#endif
        } else if (is_connected(current->state) == TRUE || is_connecting(current->state) == TRUE)
                return;
 
@@ -7218,7 +7337,19 @@ static void set_priority_connected_service(void)
                if (is_connected(service->state) == FALSE)
                        service->order = 5;
                else
+#if defined TIZEN_MAINTAIN_ONLINE
+               {
+                       if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+                               service->state == CONNMAN_SERVICE_STATE_ONLINE)
+                               service->order = 6;
+                       else if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
+                               service->order = 6;
+                       else
+                               service->order = 5;
+               }
+#else
                        service->order = 6;
+#endif
        }
 }
 #endif
@@ -7361,10 +7492,15 @@ static int service_indicate_state(struct connman_service *service)
                        __connman_ipconfig_disable_ipv6(
                                                service->ipconfig_ipv6);
 
+#if !defined TIZEN_MAINTAIN_ONLINE
                if (connman_setting_get_bool("SingleConnectedTechnology"))
                        single_connected_tech(service);
                else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
                        vpn_auto_connect();
+#else
+               if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+                       vpn_auto_connect();
+#endif
 
 #if defined TIZEN_EXT
                if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
@@ -7374,6 +7510,15 @@ static int service_indicate_state(struct connman_service *service)
                break;
 
        case CONNMAN_SERVICE_STATE_ONLINE:
+#if defined TIZEN_MAINTAIN_ONLINE
+#if defined TIZEN_EXT
+               if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
+                       set_priority_connected_service();
+#endif
+
+               if (connman_setting_get_bool("SingleConnectedTechnology"))
+                       single_connected_tech(service);
+#endif
 
                break;
 
@@ -7443,8 +7588,12 @@ static int service_indicate_state(struct connman_service *service)
        service_list_sort();
 
 #if defined TIZEN_EXT
+#if defined TIZEN_MAINTAIN_ONLINE
+       __connman_service_connect_default(service, old_state);
+#else
        __connman_service_connect_default(service);
 #endif
+#endif
 
        __connman_connection_update_gateway();
 
@@ -7687,12 +7836,35 @@ static gboolean redo_wispr(gpointer user_data)
        return FALSE;
 }
 
+#if defined TIZEN_MAINTAIN_ONLINE
+static gboolean redo_wispr_ipv4(gpointer user_data)
+{
+       struct connman_service *service = user_data;
+
+       DBG("");
+
+       __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
+
+       return FALSE;
+}
+#endif
+
 int __connman_service_online_check_failed(struct connman_service *service,
                                        enum connman_ipconfig_type type)
 {
        DBG("service %p type %d count %d", service, type,
                                                service->online_check_count);
 
+#if defined TIZEN_MAINTAIN_ONLINE
+       /* Retry IPv4 stuff also */
+       if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
+               connman_warn("Online check failed for %p %s", service,
+                                       service->name);
+
+               g_timeout_add_seconds(1, redo_wispr_ipv4, service);
+               return 0;
+       }
+#else
        /* currently we only retry IPv6 stuff */
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4 ||
                        service->online_check_count != 1) {
@@ -7700,6 +7872,7 @@ int __connman_service_online_check_failed(struct connman_service *service,
                        service->name);
                return 0;
        }
+#endif
 
        service->online_check_count = 0;
 
@@ -7808,6 +7981,10 @@ int __connman_service_ipconfig_indicate_state(struct connman_service *service,
 #if !defined TIZEN_EXT
                                check_proxy_setup(service);
 #endif
+#if defined TIZEN_MAINTAIN_ONLINE
+/*             if (old_state == CONNMAN_SERVICE_STATE_ONLINE) */
+                       check_proxy_setup(service);
+#endif
                        } else {
                                service->online_check_count = 1;
                                __connman_wispr_start(service, type);
@@ -8001,6 +8178,9 @@ static int service_connect(struct connman_service *service)
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                return -EINVAL;
        case CONNMAN_SERVICE_TYPE_ETHERNET:
        case CONNMAN_SERVICE_TYPE_GADGET:
@@ -8144,6 +8324,9 @@ int __connman_service_connect(struct connman_service *service,
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                return -EINVAL;
 
        case CONNMAN_SERVICE_TYPE_ETHERNET:
@@ -8748,8 +8931,15 @@ unsigned int __connman_service_get_order(struct connman_service *service)
                        service->do_split_routing == FALSE)
                order = 10;
        else if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+#if defined TIZEN_MAINTAIN_ONLINE
+               if (service->state != CONNMAN_SERVICE_STATE_ONLINE)
+                       service->order = 0;
+               else if (service->order < 5)
+                       service->order = 5;
+#else
                if (service->order < 5)
                        order = 5;
+#endif
        } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
                order = 4;
        else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
@@ -8966,6 +9156,9 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
        case CONNMAN_SERVICE_TYPE_WIFI:
        case CONNMAN_SERVICE_TYPE_CELLULAR:
        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                break;
        case CONNMAN_SERVICE_TYPE_ETHERNET:
                service->favorite = true;
@@ -8997,6 +9190,9 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
                        case CONNMAN_SERVICE_TYPE_UNKNOWN:
                        case CONNMAN_SERVICE_TYPE_SYSTEM:
                        case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+                       case CONNMAN_SERVICE_TYPE_MESH:
+#endif
                                break;
 
                        case CONNMAN_SERVICE_TYPE_GADGET: