#include "connman.h"
-#define MAX_CONNECT_RETRIES 2
+#define CONNECT_TIMEOUT 120
static DBusConnection *connection = NULL;
connman_bool_t userconnect;
GTimeVal modified;
unsigned int order;
- unsigned int failcounter;
char *name;
char *passphrase;
char *profile;
char *mnc;
connman_bool_t roaming;
struct connman_ipconfig *ipconfig;
- struct connman_device *device;
struct connman_network *network;
DBusMessage *pending;
guint timeout;
&service->path);
}
-void __connman_service_list(DBusMessageIter *iter)
+void __connman_service_list(DBusMessageIter *iter, void *user_data)
{
- DBG("");
-
g_sequence_foreach(service_list, append_path, iter);
}
return data.service;
}
-static const char *type2string(enum connman_service_type type)
+const char *__connman_service_type2string(enum connman_service_type type)
{
switch (type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
break;
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ return "system";
case CONNMAN_SERVICE_TYPE_ETHERNET:
return "ethernet";
case CONNMAN_SERVICE_TYPE_WIFI:
return "bluetooth";
case CONNMAN_SERVICE_TYPE_CELLULAR:
return "cellular";
+ case CONNMAN_SERVICE_TYPE_VPN:
+ return "vpn";
}
return NULL;
return "managed";
case CONNMAN_SERVICE_MODE_ADHOC:
return "adhoc";
+ case CONNMAN_SERVICE_MODE_GPRS:
+ return "gprs";
+ case CONNMAN_SERVICE_MODE_EDGE:
+ return "edge";
+ case CONNMAN_SERVICE_MODE_UMTS:
+ return "umts";
}
return NULL;
return "none";
case CONNMAN_SERVICE_SECURITY_WEP:
return "wep";
+ case CONNMAN_SERVICE_SECURITY_PSK:
+ return "psk";
+ case CONNMAN_SERVICE_SECURITY_8021X:
+ return "ieee8021x";
case CONNMAN_SERVICE_SECURITY_WPA:
return "wpa";
case CONNMAN_SERVICE_SECURITY_RSN:
break;
case CONNMAN_SERVICE_STATE_IDLE:
return "idle";
- case CONNMAN_SERVICE_STATE_CARRIER:
- return "carrier";
case CONNMAN_SERVICE_STATE_ASSOCIATION:
return "association";
case CONNMAN_SERVICE_STATE_CONFIGURATION:
return CONNMAN_SERVICE_ERROR_UNKNOWN;
}
-const char *__connman_service_default(void)
+static struct connman_service *get_default(void)
{
struct connman_service *service;
GSequenceIter *iter;
iter = g_sequence_get_begin_iter(service_list);
if (g_sequence_iter_is_end(iter) == TRUE)
- return "";
+ return NULL;
service = g_sequence_get(iter);
- if (service == NULL)
- return "";
if (service->state != CONNMAN_SERVICE_STATE_READY)
- return "";
+ return NULL;
- return type2string(service->type);
+ return service;
}
-static void state_changed(struct connman_service *service)
+static void default_changed(void)
{
- DBusMessage *signal;
- DBusMessageIter entry, value;
- const char *str, *key = "State";
+ struct connman_service *service = get_default();
- if (service->path == NULL)
- return;
+ __connman_notifier_default_changed(service);
+}
- str = state2string(service->state);
- if (str == NULL)
- return;
+const char *__connman_service_default(void)
+{
+ struct connman_service *service;
- signal = dbus_message_new_signal(service->path,
- CONNMAN_SERVICE_INTERFACE, "PropertyChanged");
- if (signal == NULL)
- return;
+ service = get_default();
+ if (service == NULL)
+ return "";
- dbus_message_iter_init_append(signal, &entry);
+ return __connman_service_type2string(service->type);
+}
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+static void mode_changed(struct connman_service *service)
+{
+ const char *str;
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_STRING_AS_STRING, &value);
- dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &str);
- dbus_message_iter_close_container(&entry, &value);
+ str = mode2string(service->mode);
+ if (str == NULL)
+ return;
- g_dbus_send_message(connection, signal);
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "Mode",
+ DBUS_TYPE_STRING, &str);
}
-static void strength_changed(struct connman_service *service)
+static void state_changed(struct connman_service *service)
{
- DBusMessage *signal;
- DBusMessageIter entry, value;
- const char *key = "Strength";
+ const char *str;
- if (service->path == NULL)
+ str = state2string(service->state);
+ if (str == NULL)
return;
- if (service->strength == 0)
- return;
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "State",
+ DBUS_TYPE_STRING, &str);
+}
- signal = dbus_message_new_signal(service->path,
- CONNMAN_SERVICE_INTERFACE, "PropertyChanged");
- if (signal == NULL)
+static void strength_changed(struct connman_service *service)
+{
+ if (service->strength == 0)
return;
- dbus_message_iter_init_append(signal, &entry);
-
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "Strength",
+ DBUS_TYPE_BYTE, &service->strength);
+}
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_BYTE_AS_STRING, &value);
- dbus_message_iter_append_basic(&value, DBUS_TYPE_BYTE,
- &service->strength);
- dbus_message_iter_close_container(&entry, &value);
+static void favorite_changed(struct connman_service *service)
+{
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "Favorite",
+ DBUS_TYPE_BOOLEAN, &service->favorite);
+}
- g_dbus_send_message(connection, signal);
+static void roaming_changed(struct connman_service *service)
+{
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "Roaming",
+ DBUS_TYPE_BOOLEAN, &service->roaming);
}
static void autoconnect_changed(struct connman_service *service)
{
- DBusMessage *signal;
- DBusMessageIter entry, value;
- const char *key = "AutoConnect";
-
- if (service->path == NULL)
- return;
-
- signal = dbus_message_new_signal(service->path,
- CONNMAN_SERVICE_INTERFACE, "PropertyChanged");
- if (signal == NULL)
- return;
-
- dbus_message_iter_init_append(signal, &entry);
-
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
-
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_BOOLEAN_AS_STRING, &value);
- dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN,
- &service->autoconnect);
- dbus_message_iter_close_container(&entry, &value);
-
- g_dbus_send_message(connection, signal);
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "AutoConnect",
+ DBUS_TYPE_BOOLEAN, &service->autoconnect);
}
static void passphrase_changed(struct connman_service *service)
{
- DBusMessage *signal;
- DBusMessageIter entry, value;
dbus_bool_t required;
- const char *key = "PassphraseRequired";
-
- if (service->path == NULL)
- return;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_VPN:
return;
case CONNMAN_SERVICE_TYPE_WIFI:
required = FALSE;
switch (service->security) {
case CONNMAN_SERVICE_SECURITY_UNKNOWN:
case CONNMAN_SERVICE_SECURITY_NONE:
+ case CONNMAN_SERVICE_SECURITY_8021X:
break;
case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_PSK:
case CONNMAN_SERVICE_SECURITY_WPA:
case CONNMAN_SERVICE_SECURITY_RSN:
if (service->passphrase == NULL)
break;
}
- signal = dbus_message_new_signal(service->path,
- CONNMAN_SERVICE_INTERFACE, "PropertyChanged");
- if (signal == NULL)
- return;
-
- dbus_message_iter_init_append(signal, &entry);
-
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
-
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_BOOLEAN_AS_STRING, &value);
- dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &required);
- dbus_message_iter_close_container(&entry, &value);
-
- g_dbus_send_message(connection, signal);
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "PassphraseRequired",
+ DBUS_TYPE_BOOLEAN, &required);
}
static void apn_changed(struct connman_service *service)
{
- DBusMessage *signal;
- DBusMessageIter entry, value;
dbus_bool_t required;
- const char *key = "SetupRequired";
-
- if (service->path == NULL)
- return;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_VPN:
return;
case CONNMAN_SERVICE_TYPE_CELLULAR:
break;
required = (service->apn == NULL) ? TRUE : FALSE;
- signal = dbus_message_new_signal(service->path,
- CONNMAN_SERVICE_INTERFACE, "PropertyChanged");
- if (signal == NULL)
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "SetupRequired",
+ DBUS_TYPE_BOOLEAN, &required);
+}
+
+static void append_ethernet(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
+
+ switch (service->state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
return;
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_READY:
+ break;
+ }
- dbus_message_iter_init_append(signal, &entry);
+ if (service->ipconfig != NULL)
+ __connman_ipconfig_append_ethernet(service->ipconfig, iter);
+}
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+static void append_ipv4(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_BOOLEAN_AS_STRING, &value);
- dbus_message_iter_append_basic(&value, DBUS_TYPE_BOOLEAN, &required);
- dbus_message_iter_close_container(&entry, &value);
+ switch (service->state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ return;
+ case CONNMAN_SERVICE_STATE_READY:
+ break;
+ }
+
+ if (service->ipconfig != NULL)
+ __connman_ipconfig_append_ipv4(service->ipconfig, iter);
+}
- g_dbus_send_message(connection, signal);
+static void settings_changed(struct connman_service *service)
+{
+ connman_dbus_property_changed_dict(service->path,
+ CONNMAN_SERVICE_INTERFACE, "IPv4",
+ append_ipv4, service);
}
static DBusMessage *get_properties(DBusConnection *conn,
dbus_message_iter_init_append(reply, &array);
- dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+ connman_dbus_dict_open(&array, &dict);
- str = type2string(service->type);
+ str = __connman_service_type2string(service->type);
if (str != NULL)
- connman_dbus_dict_append_variant(&dict, "Type",
+ connman_dbus_dict_append_basic(&dict, "Type",
DBUS_TYPE_STRING, &str);
str = mode2string(service->mode);
if (str != NULL)
- connman_dbus_dict_append_variant(&dict, "Mode",
+ connman_dbus_dict_append_basic(&dict, "Mode",
DBUS_TYPE_STRING, &str);
str = security2string(service->security);
if (str != NULL)
- connman_dbus_dict_append_variant(&dict, "Security",
+ connman_dbus_dict_append_basic(&dict, "Security",
DBUS_TYPE_STRING, &str);
str = state2string(service->state);
if (str != NULL)
- connman_dbus_dict_append_variant(&dict, "State",
+ connman_dbus_dict_append_basic(&dict, "State",
DBUS_TYPE_STRING, &str);
str = error2string(service->error);
if (str != NULL)
- connman_dbus_dict_append_variant(&dict, "Error",
+ connman_dbus_dict_append_basic(&dict, "Error",
DBUS_TYPE_STRING, &str);
if (service->strength > 0)
- connman_dbus_dict_append_variant(&dict, "Strength",
+ connman_dbus_dict_append_basic(&dict, "Strength",
DBUS_TYPE_BYTE, &service->strength);
- connman_dbus_dict_append_variant(&dict, "Favorite",
+ connman_dbus_dict_append_basic(&dict, "Favorite",
DBUS_TYPE_BOOLEAN, &service->favorite);
if (service->favorite == TRUE)
- connman_dbus_dict_append_variant(&dict, "AutoConnect",
+ connman_dbus_dict_append_basic(&dict, "AutoConnect",
DBUS_TYPE_BOOLEAN, &service->autoconnect);
else
- connman_dbus_dict_append_variant(&dict, "AutoConnect",
+ connman_dbus_dict_append_basic(&dict, "AutoConnect",
DBUS_TYPE_BOOLEAN, &service->favorite);
if (service->name != NULL)
- connman_dbus_dict_append_variant(&dict, "Name",
+ connman_dbus_dict_append_basic(&dict, "Name",
DBUS_TYPE_STRING, &service->name);
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
- case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_VPN:
break;
case CONNMAN_SERVICE_TYPE_CELLULAR:
- connman_dbus_dict_append_variant(&dict, "Roaming",
+ connman_dbus_dict_append_basic(&dict, "Roaming",
DBUS_TYPE_BOOLEAN, &service->roaming);
if (service->mcc != NULL && service->mnc != NULL) {
- connman_dbus_dict_append_variant(&dict, "MCC",
+ connman_dbus_dict_append_basic(&dict, "MCC",
DBUS_TYPE_STRING, &service->mcc);
- connman_dbus_dict_append_variant(&dict, "MNC",
+ connman_dbus_dict_append_basic(&dict, "MNC",
DBUS_TYPE_STRING, &service->mnc);
}
if (service->apn != NULL) {
- connman_dbus_dict_append_variant(&dict, "APN",
+ connman_dbus_dict_append_basic(&dict, "APN",
DBUS_TYPE_STRING, &service->apn);
if (service->username != NULL)
- connman_dbus_dict_append_variant(&dict,
+ connman_dbus_dict_append_basic(&dict,
"Username", DBUS_TYPE_STRING,
&service->username);
if (service->password != NULL)
- connman_dbus_dict_append_variant(&dict,
+ connman_dbus_dict_append_basic(&dict,
"Password", DBUS_TYPE_STRING,
&service->password);
} else
required = TRUE;
- connman_dbus_dict_append_variant(&dict, "SetupRequired",
+ connman_dbus_dict_append_basic(&dict, "SetupRequired",
DBUS_TYPE_BOOLEAN, &required);
break;
case CONNMAN_SERVICE_TYPE_WIFI:
if (service->passphrase != NULL &&
__connman_security_check_privilege(msg,
CONNMAN_SECURITY_PRIVILEGE_SECRET) == 0)
- connman_dbus_dict_append_variant(&dict, "Passphrase",
+ connman_dbus_dict_append_basic(&dict, "Passphrase",
DBUS_TYPE_STRING, &service->passphrase);
required = FALSE;
switch (service->security) {
case CONNMAN_SERVICE_SECURITY_UNKNOWN:
case CONNMAN_SERVICE_SECURITY_NONE:
+ case CONNMAN_SERVICE_SECURITY_8021X:
break;
case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_PSK:
case CONNMAN_SERVICE_SECURITY_WPA:
case CONNMAN_SERVICE_SECURITY_RSN:
if (service->passphrase == NULL)
break;
}
- connman_dbus_dict_append_variant(&dict, "PassphraseRequired",
+ connman_dbus_dict_append_basic(&dict, "PassphraseRequired",
DBUS_TYPE_BOOLEAN, &required);
+ /* fall through */
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ connman_dbus_dict_append_dict(&dict, "Ethernet",
+ append_ethernet, service);
break;
}
- if (service->ipconfig != NULL)
- __connman_ipconfig_append_ipv4(service->ipconfig,
- &dict, "IPv4.");
+ connman_dbus_dict_append_dict(&dict, "IPv4", append_ipv4, service);
- dbus_message_iter_close_container(&array, &dict);
+ connman_dbus_dict_close(&array, &dict);
return reply;
}
"Cellular.Password", service->password);
__connman_storage_save_service(service);
- } else if (g_str_has_prefix(name, "IPv4.") == TRUE) {
- int err;
-
- if (service->ipconfig == NULL)
- return __connman_error_invalid_property(msg);
-
- err = __connman_ipconfig_set_ipv4(service->ipconfig,
- name + 5, &value);
- if (err < 0)
- return __connman_error_failed(msg, -err);
} else
return __connman_error_invalid_property(msg);
switch (service->state) {
case CONNMAN_SERVICE_STATE_UNKNOWN:
case CONNMAN_SERVICE_STATE_IDLE:
- case CONNMAN_SERVICE_STATE_CARRIER:
case CONNMAN_SERVICE_STATE_FAILURE:
case CONNMAN_SERVICE_STATE_DISCONNECT:
case CONNMAN_SERVICE_STATE_READY:
if (service->autoconnect == FALSE)
return TRUE;
+ if (service->roaming == TRUE)
+ return TRUE;
+
if (service->ignore == TRUE)
return TRUE;
}
}
-static void reply_pending(struct connman_service *service, int error)
+static void remove_timeout(struct connman_service *service)
{
if (service->timeout > 0) {
g_source_remove(service->timeout);
service->timeout = 0;
}
+}
+
+static void reply_pending(struct connman_service *service, int error)
+{
+ remove_timeout(service);
if (service->pending != NULL) {
if (error > 0) {
if (service->network != NULL)
__connman_network_disconnect(service->network);
- else if (service->device != NULL)
- __connman_device_disconnect(service->device);
__connman_ipconfig_disable(service->ipconfig);
return FALSE;
}
+static void set_reconnect_state(struct connman_service *service,
+ connman_bool_t reconnect)
+{
+ struct connman_device *device;
+
+ if (service->network == NULL)
+ return;
+
+ device = connman_network_get_device(service->network);
+ if (device == NULL)
+ return;
+
+ __connman_device_set_reconnect(device, reconnect);
+}
+
+static connman_bool_t get_reconnect_state(struct connman_service *service)
+{
+ struct connman_device *device;
+
+ if (service->network == NULL)
+ return FALSE;
+
+ device = connman_network_get_device(service->network);
+ if (device == NULL)
+ return FALSE;
+
+ return __connman_device_get_reconnect(device);
+}
+
static DBusMessage *connect_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
service->ignore = FALSE;
service->userconnect = TRUE;
- service->failcounter = 0;
service->pending = dbus_message_ref(msg);
+ set_reconnect_state(service, FALSE);
+
err = __connman_service_connect(service);
if (err < 0) {
if (err == -ENOKEY) {
service->ignore = TRUE;
+ set_reconnect_state(service, FALSE);
+
err = __connman_service_disconnect(service);
if (err < 0) {
if (err != -EINPROGRESS)
if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
return __connman_error_not_supported(msg);
- if (service->favorite == FALSE)
+ if (service->favorite == FALSE &&
+ service->state != CONNMAN_SERVICE_STATE_FAILURE)
return __connman_error_not_supported(msg);
- if (service->network != NULL)
+ if (service->network != NULL) {
+ set_reconnect_state(service, FALSE);
+
__connman_network_disconnect(service->network);
+ }
g_free(service->passphrase);
service->passphrase = NULL;
apn_changed(service);
+ set_idle(service);
+
connman_service_set_favorite(service, FALSE);
__connman_storage_save_service(service);
if (service_a->type != service_b->type) {
switch (service_a->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_VPN:
break;
case CONNMAN_SERVICE_TYPE_WIFI:
return 1;
}
/**
+ * connman_service_get_type:
+ * @service: service structure
+ *
+ * Get the type of service
+ */
+enum connman_service_type connman_service_get_type(struct connman_service *service)
+{
+ if (service == NULL)
+ return CONNMAN_SERVICE_TYPE_UNKNOWN;
+
+ return service->type;
+}
+
+/**
+ * connman_service_get_interface:
+ * @service: service structure
+ *
+ * Get network interface of service
+ */
+char *connman_service_get_interface(struct connman_service *service)
+{
+ int index;
+
+ if (service == NULL)
+ return NULL;
+
+ if (service->network == NULL)
+ return NULL;
+
+ index = connman_network_get_index(service->network);
+
+ return connman_inet_ifname(index);
+}
+
+/**
* connman_service_set_favorite:
* @service: service structure
* @favorite: favorite value
service->favorite = favorite;
+ favorite_changed(service);
+
g_sequence_sort_changed(iter, service_compare, NULL);
__connman_profile_changed(FALSE);
return 0;
}
-static void default_changed(void)
-{
- DBusMessage *signal;
- DBusMessageIter entry, value;
- const char *key = "DefaultTechnology";
- const char *str = __connman_service_default();
-
- signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
- CONNMAN_MANAGER_INTERFACE, "PropertyChanged");
- if (signal == NULL)
- return;
-
- dbus_message_iter_init_append(signal, &entry);
-
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
-
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_STRING_AS_STRING, &value);
- dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &str);
- dbus_message_iter_close_container(&entry, &value);
-
- g_dbus_send_message(connection, signal);
-}
-
int __connman_service_indicate_state(struct connman_service *service,
enum connman_service_state state)
{
service->state = state;
state_changed(service);
+ if (state == CONNMAN_SERVICE_STATE_IDLE) {
+ connman_bool_t reconnect;
+
+ reconnect = get_reconnect_state(service);
+ if (reconnect == TRUE)
+ __connman_service_auto_connect();
+ }
+
if (state == CONNMAN_SERVICE_STATE_READY) {
+ set_reconnect_state(service, TRUE);
+
connman_service_set_favorite(service, TRUE);
reply_pending(service, 0);
service->userconnect = FALSE;
- service->failcounter = 0;
g_get_current_time(&service->modified);
__connman_storage_save_service(service);
+ settings_changed(service);
+
__connman_notifier_connect(service->type);
default_changed();
}
if (state == CONNMAN_SERVICE_STATE_FAILURE) {
- if (service->failcounter++ < MAX_CONNECT_RETRIES) {
- connman_warn("Connecting again (try %d)",
- service->failcounter);
- __connman_service_disconnect(service);
- __connman_service_connect(service);
- return 0;
- }
-
reply_pending(service, EIO);
if (service->userconnect == FALSE)
connman_network_set_string(service->network,
"WiFi.Passphrase", service->passphrase);
break;
+ case CONNMAN_NETWORK_TYPE_ETHERNET:
case CONNMAN_NETWORK_TYPE_WIMAX:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
+ case CONNMAN_NETWORK_TYPE_CELLULAR:
break;
case CONNMAN_NETWORK_TYPE_MBM:
case CONNMAN_NETWORK_TYPE_HSO:
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_VPN:
return -EINVAL;
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_WIMAX:
switch (service->security) {
case CONNMAN_SERVICE_SECURITY_UNKNOWN:
case CONNMAN_SERVICE_SECURITY_NONE:
+ case CONNMAN_SERVICE_SECURITY_8021X:
break;
case CONNMAN_SERVICE_SECURITY_WEP:
+ case CONNMAN_SERVICE_SECURITY_PSK:
case CONNMAN_SERVICE_SECURITY_WPA:
case CONNMAN_SERVICE_SECURITY_RSN:
if (service->passphrase == NULL)
__connman_ipconfig_enable(service->ipconfig);
err = __connman_network_connect(service->network);
- } else if (service->device != NULL) {
- if (service->favorite == FALSE)
- return -ENOLINK;
-
- __connman_ipconfig_enable(service->ipconfig);
-
- err = __connman_device_connect(service->device);
} else
return -EOPNOTSUPP;
return err;
}
- service->timeout = g_timeout_add_seconds(45,
+ service->timeout = g_timeout_add_seconds(CONNECT_TIMEOUT,
connect_timeout, service);
return -EINPROGRESS;
if (service->network != NULL) {
err = __connman_network_disconnect(service->network);
- } else if (service->device != NULL) {
- if (service->favorite == FALSE)
- return -ENOLINK;
- err = __connman_device_disconnect(service->device);
} else
return -EOPNOTSUPP;
return -EINVAL;
if (g_strcmp0(security, "none") != 0 &&
- g_strcmp0(security, "wep") != 0 &&
+ g_strcmp0(security, "wep") != 0 &&
+ g_strcmp0(security, "psk") != 0 &&
g_strcmp0(security, "wpa") != 0 &&
- g_strcmp0(security, "rsn") != 0)
+ g_strcmp0(security, "rsn") != 0)
return -EINVAL;
- device = __connman_element_find_device(CONNMAN_SERVICE_TYPE_WIFI);
+ device = __connman_element_find_device(CONNMAN_DEVICE_TYPE_WIFI);
if (device == NULL)
return -EOPNOTSUPP;
goto failed;
}
+ set_reconnect_state(service, FALSE);
+
__connman_device_disconnect(device);
if (passphrase != NULL) {
}
/**
- * __connman_service_lookup_from_device:
- * @device: device structure
- *
- * Look up a service by device (reference count will not be increased)
- */
-struct connman_service *__connman_service_lookup_from_device(struct connman_device *device)
-{
- struct connman_service *service;
- const char *ident;
- char *name;
-
- ident = __connman_device_get_ident(device);
- if (ident == NULL)
- return NULL;
-
- name = g_strdup_printf("%s_%s",
- __connman_device_get_type(device), ident);
- service = __connman_service_lookup(name);
- g_free(name);
-
- return service;
-}
-
-/**
- * __connman_service_create_from_device:
- * @device: device structure
- *
- * Look up service by device and if not found, create one
- */
-struct connman_service *__connman_service_create_from_device(struct connman_device *device)
-{
- struct connman_service *service;
- const char *ident;
- char *name;
-
- ident = __connman_device_get_ident(device);
- if (ident == NULL)
- return NULL;
-
- name = g_strdup_printf("%s_%s",
- __connman_device_get_type(device), ident);
- service = __connman_service_get(name);
- g_free(name);
-
- if (service == NULL)
- return NULL;
-
- if (service->path != NULL) {
- __connman_profile_changed(TRUE);
- return service;
- }
-
- service->type = __connman_device_get_service_type(device);
-
- service->autoconnect = FALSE;
-
- service->device = device;
-
- setup_ipconfig(service, connman_device_get_index(device));
-
- service_register(service);
-
- __connman_profile_changed(TRUE);
-
- if (service->favorite == TRUE)
- __connman_service_auto_connect();
-
- return service;
-}
-
-void __connman_service_remove_from_device(struct connman_device *device)
-{
- struct connman_service *service;
- enum connman_service_type type;
-
- service = __connman_service_lookup_from_device(device);
- if (service == NULL)
- return;
-
- type = service->type;
-
- __connman_service_put(service);
-
- default_changed();
-
- __connman_notifier_disconnect(type);
-
- __connman_service_auto_connect();
-}
-
-/**
* __connman_service_lookup_from_network:
* @network: network structure
*
const char *ident, *group;
char *name;
+ DBG("network %p", network);
+
ident = __connman_network_get_ident(network);
if (ident == NULL)
return NULL;
case CONNMAN_NETWORK_TYPE_UNKNOWN:
case CONNMAN_NETWORK_TYPE_VENDOR:
break;
+ case CONNMAN_NETWORK_TYPE_ETHERNET:
+ return CONNMAN_SERVICE_TYPE_ETHERNET;
case CONNMAN_NETWORK_TYPE_WIFI:
return CONNMAN_SERVICE_TYPE_WIFI;
case CONNMAN_NETWORK_TYPE_WIMAX:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
return CONNMAN_SERVICE_TYPE_BLUETOOTH;
+ case CONNMAN_NETWORK_TYPE_CELLULAR:
case CONNMAN_NETWORK_TYPE_MBM:
case CONNMAN_NETWORK_TYPE_HSO:
return CONNMAN_SERVICE_TYPE_CELLULAR;
return CONNMAN_SERVICE_MODE_UNKNOWN;
}
-static enum connman_service_mode convert_wifi_security(const char *security)
+static enum connman_service_security convert_wifi_security(const char *security)
{
if (security == NULL)
return CONNMAN_SERVICE_SECURITY_UNKNOWN;
return CONNMAN_SERVICE_SECURITY_NONE;
else if (g_str_equal(security, "wep") == TRUE)
return CONNMAN_SERVICE_SECURITY_WEP;
+ else if (g_str_equal(security, "wep") == TRUE)
+ return CONNMAN_SERVICE_SECURITY_PSK;
+ else if (g_str_equal(security, "ieee8021x") == TRUE)
+ return CONNMAN_SERVICE_SECURITY_8021X;
else if (g_str_equal(security, "wpa") == TRUE)
return CONNMAN_SERVICE_SECURITY_WPA;
else if (g_str_equal(security, "rsn") == TRUE)
return CONNMAN_SERVICE_SECURITY_UNKNOWN;
}
+static enum connman_service_mode convert_cellular_mode(connman_uint8_t mode)
+{
+ switch (mode) {
+ case 0:
+ case 1:
+ return CONNMAN_SERVICE_MODE_GPRS;
+ case 3:
+ return CONNMAN_SERVICE_MODE_EDGE;
+ case 2:
+ case 4:
+ case 5:
+ case 6:
+ return CONNMAN_SERVICE_MODE_UMTS;
+ }
+
+ return CONNMAN_SERVICE_MODE_UNKNOWN;
+}
+
static void update_from_network(struct connman_service *service,
struct connman_network *network)
{
GSequenceIter *iter;
const char *str;
+ DBG("service %p network %p", service, network);
+
if (service->state == CONNMAN_SERVICE_STATE_READY)
return;
}
service->strength = connman_network_get_uint8(network, "Strength");
+ service->roaming = connman_network_get_bool(network, "Roaming");
+
+ if (service->strength == 0) {
+ /*
+ * Filter out 0-values; it's unclear what they mean
+ * and they cause anomalous sorting of the priority list.
+ */
+ service->strength = strength;
+ }
str = connman_network_get_string(network, "WiFi.Mode");
service->mode = convert_wifi_mode(str);
g_free(service->mnc);
service->mnc = g_strdup(str);
+ if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
+ connman_uint8_t value = connman_network_get_uint8(network,
+ "Cellular.Mode");
+
+ service->mode = convert_cellular_mode(value);
+ }
+
if (service->strength > strength && service->network != NULL) {
connman_network_unref(service->network);
service->network = connman_network_ref(network);
const char *ident, *group;
char *name;
+ DBG("network %p", network);
+
ident = __connman_network_get_ident(network);
if (ident == NULL)
return NULL;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
- case CONNMAN_SERVICE_TYPE_CELLULAR:
+ case CONNMAN_SERVICE_TYPE_VPN:
service->autoconnect = FALSE;
break;
case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
service->autoconnect = TRUE;
break;
}
void __connman_service_update_from_network(struct connman_network *network)
{
struct connman_service *service;
- connman_uint8_t strength;
+ enum connman_service_mode mode;
+ connman_uint8_t strength, value;
+ connman_bool_t roaming;
+ GSequenceIter *iter;
+
+ DBG("network %p", network);
service = __connman_service_lookup_from_network(network);
if (service == NULL)
strength = connman_network_get_uint8(service->network, "Strength");
if (strength == service->strength)
- return;
+ goto roaming;
service->strength = strength;
strength_changed(service);
+
+roaming:
+ roaming = connman_network_get_bool(service->network, "Roaming");
+ if (roaming == service->roaming)
+ goto done;
+
+ service->roaming = roaming;
+
+ roaming_changed(service);
+
+ iter = g_hash_table_lookup(service_hash, service->identifier);
+ if (iter != NULL)
+ g_sequence_sort_changed(iter, service_compare, NULL);
+
+done:
+ if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
+ return;
+
+ value = connman_network_get_uint8(service->network, "Cellular.Mode");
+ mode = convert_cellular_mode(value);
+
+ if (mode == service->mode)
+ return;
+
+ service->mode = mode;
+
+ mode_changed(service);
}
void __connman_service_remove_from_network(struct connman_network *network)
{
struct connman_service *service;
+ DBG("network %p", network);
+
service = __connman_service_lookup_from_network(network);
if (service == NULL)
return;
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_VPN:
break;
case CONNMAN_SERVICE_TYPE_WIFI:
if (service->name == NULL) {
switch (service->type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
case CONNMAN_SERVICE_TYPE_ETHERNET:
+ case CONNMAN_SERVICE_TYPE_VPN:
break;
case CONNMAN_SERVICE_TYPE_WIFI:
if (service->network) {