#include <config.h>
#endif
+#include <stdio.h>
+#include <string.h>
#include <gdbus.h>
#include "connman.h"
connman_uint8_t strength;
connman_bool_t favorite;
connman_bool_t hidden;
+ connman_bool_t ignore;
GTimeVal modified;
unsigned int order;
char *name;
switch (error) {
case CONNMAN_SERVICE_ERROR_UNKNOWN:
break;
- case CONNMAN_SERVICE_ERROR_DHCP_FAILED:
- return "dhcp-failed";
case CONNMAN_SERVICE_ERROR_PIN_MISSING:
return "pin-missing";
+ case CONNMAN_SERVICE_ERROR_DHCP_FAILED:
+ return "dhcp-failed";
+ case CONNMAN_SERVICE_ERROR_CONNECT_FAILED:
+ return "connect-failed";
}
return NULL;
return NULL;
}
+static connman_bool_t is_ignore(struct connman_service *service)
+{
+ if (service->ignore == TRUE)
+ return TRUE;
+
+ if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
+ return TRUE;
+
+ return FALSE;
+}
+
static void __connman_service_auto_connect(void)
{
struct connman_service *service;
service = g_sequence_get(iter);
- while (service->state == CONNMAN_SERVICE_STATE_FAILURE) {
+ while (is_ignore(service) == TRUE) {
iter = g_sequence_iter_next(iter);
if (g_sequence_iter_is_end(iter))
return;
if (service->pending != NULL)
return __connman_error_in_progress(msg);
+ service->ignore = FALSE;
+
service->pending = dbus_message_ref(msg);
err = __connman_service_connect(service);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+ service->ignore = TRUE;
+
err = __connman_service_disconnect(service);
if (err < 0) {
if (err != -EINPROGRESS)
g_sequence_move(src, dst);
- __connman_profile_changed();
+ __connman_profile_changed(FALSE);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
service->path = NULL;
if (path != NULL) {
- __connman_profile_changed();
+ __connman_profile_changed(TRUE);
g_dbus_unregister_interface(connection, path,
CONNMAN_SERVICE_INTERFACE);
service->favorite = FALSE;
service->hidden = FALSE;
+ service->ignore = FALSE;
+
service->order = 0;
}
g_sequence_sort_changed(iter, service_compare, NULL);
- __connman_profile_changed();
+ __connman_profile_changed(FALSE);
return 0;
}
if (service->state == state)
return -EALREADY;
+ if (service->state == CONNMAN_SERVICE_STATE_FAILURE &&
+ state == CONNMAN_SERVICE_STATE_IDLE)
+ return -EINVAL;
+
if (service->state == CONNMAN_SERVICE_STATE_IDLE &&
state == CONNMAN_SERVICE_STATE_DISCONNECT)
return -EINVAL;
if (iter != NULL)
g_sequence_sort_changed(iter, service_compare, NULL);
- __connman_profile_changed();
+ __connman_profile_changed(FALSE);
return 0;
}
if (service->state == CONNMAN_SERVICE_STATE_READY)
return -EISCONN;
+ if (is_connecting(service) == TRUE)
+ return -EALREADY;
+
if (service->network != NULL) {
- if (service->hidden == TRUE)
+ unsigned int ssid_len;
+
+ if (connman_network_get_blob(service->network, "WiFi.SSID",
+ &ssid_len) == NULL)
return -EINVAL;
connman_network_set_string(service->network,
return NULL;
}
+int __connman_service_create_and_connect(DBusMessage *msg)
+{
+ struct connman_service *service;
+ struct connman_device *device;
+ DBusMessageIter iter, array;
+ const char *mode = "managed", *security = "none";
+ const char *type = NULL, *ssid = NULL, *passphrase = NULL;
+ const char *ident;
+ char *name, *group;
+ int err;
+
+ dbus_message_iter_init(msg, &iter);
+ dbus_message_iter_recurse(&iter, &array);
+
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *key;
+
+ dbus_message_iter_recurse(&array, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ switch (dbus_message_iter_get_arg_type(&value)) {
+ case DBUS_TYPE_STRING:
+ if (g_str_equal(key, "Type") == TRUE)
+ dbus_message_iter_get_basic(&value, &type);
+ else if (g_str_equal(key, "WiFi.Mode") == TRUE ||
+ g_str_equal(key, "Mode") == TRUE)
+ dbus_message_iter_get_basic(&value, &mode);
+ else if (g_str_equal(key, "WiFi.Security") == TRUE ||
+ g_str_equal(key, "Security") == TRUE)
+ dbus_message_iter_get_basic(&value, &security);
+ else if (g_str_equal(key, "WiFi.Passphrase") == TRUE ||
+ g_str_equal(key, "Passphrase") == TRUE)
+ dbus_message_iter_get_basic(&value, &passphrase);
+ else if (g_str_equal(key, "WiFi.SSID") == TRUE ||
+ g_str_equal(key, "SSID") == TRUE)
+ dbus_message_iter_get_basic(&value, &ssid);
+ }
+
+ dbus_message_iter_next(&array);
+ }
+
+ if (type == NULL)
+ return -EINVAL;
+
+ if (g_strcmp0(type, "wifi") != 0 || g_strcmp0(mode, "managed") != 0)
+ return -EOPNOTSUPP;
+
+ if (ssid == NULL)
+ return -EINVAL;
+
+ device = __connman_element_find_device(CONNMAN_DEVICE_TYPE_WIFI);
+ if (device == NULL)
+ return -EOPNOTSUPP;
+
+ ident = __connman_device_get_ident(device);
+ if (ident == NULL)
+ return -EOPNOTSUPP;
+
+ group = connman_wifi_build_group_name((unsigned char *) ssid,
+ strlen(ssid), mode, security);
+ if (group == NULL)
+ return -EINVAL;
+
+ name = g_strdup_printf("%s_%s_%s", type, ident, group);
+
+ g_free(group);
+
+ service = __connman_service_lookup(name);
+
+ g_free(name);
+
+ if (service != NULL) {
+ if (passphrase != NULL) {
+ g_free(service->passphrase);
+ service->passphrase = g_strdup(passphrase);
+ }
+
+ err = __connman_service_connect(service);
+ if (err < 0 && err != -EINPROGRESS)
+ return err;
+
+ g_dbus_send_reply(connection, msg,
+ DBUS_TYPE_OBJECT_PATH, &service->path,
+ DBUS_TYPE_INVALID);
+
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+
/**
* __connman_service_get:
* @identifier: service identifier
if (iter != NULL)
g_sequence_sort_changed(iter, service_compare, NULL);
- __connman_profile_changed();
+ __connman_profile_changed(TRUE);
return 0;
}
if (ident == NULL)
return NULL;
- group = __connman_network_get_group(network);
+ group = connman_network_get_group(network);
if (group == NULL)
return NULL;
unsigned int __connman_service_get_order(struct connman_service *service)
{
+ GSequenceIter *iter;
+
if (service == NULL)
return 0;
+ if (service->favorite == FALSE)
+ return 0;
+
+ iter = g_hash_table_lookup(service_hash, service->identifier);
+ if (iter != NULL) {
+ if (g_sequence_iter_get_position(iter) == 0)
+ return 1;
+ }
+
return service->order;
}
case CONNMAN_NETWORK_TYPE_VENDOR:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
- case CONNMAN_NETWORK_TYPE_HSO:
break;
+ case CONNMAN_NETWORK_TYPE_MBM:
+ case CONNMAN_NETWORK_TYPE_HSO:
+ return CONNMAN_SERVICE_TYPE_CELLULAR;
case CONNMAN_NETWORK_TYPE_WIFI:
return CONNMAN_SERVICE_TYPE_WIFI;
case CONNMAN_NETWORK_TYPE_WIMAX:
if (ident == NULL)
return NULL;
- group = __connman_network_get_group(network);
+ group = connman_network_get_group(network);
if (group == NULL)
return NULL;
if (service->path != NULL) {
update_from_network(service, network);
- __connman_profile_changed();
+ __connman_profile_changed(TRUE);
__connman_service_put(service);
service = NULL;
gchar *pathname, *data = NULL;
gsize length;
gchar *str;
+ unsigned int ssid_len;
+ int err = 0;
DBG("service %p", service);
case CONNMAN_SERVICE_TYPE_ETHERNET:
break;
case CONNMAN_SERVICE_TYPE_WIFI:
+ if (service->name == NULL) {
+ gchar *name;
+
+ name = g_key_file_get_string(keyfile,
+ service->identifier, "Name", NULL);
+ if (name != NULL) {
+ g_free(service->name);
+ service->name = name;
+ }
+
+ if (service->network != NULL)
+ connman_network_set_name(service->network,
+ name);
+ }
+
+ if (service->network &&
+ connman_network_get_blob(service->network,
+ "WiFi.SSID", &ssid_len) == NULL) {
+ gchar *hex_ssid;
+
+ hex_ssid = g_key_file_get_string(keyfile,
+ service->identifier,
+ "SSID", NULL);
+
+ if (hex_ssid != NULL) {
+ gchar *ssid;
+ unsigned int i, j = 0, hex;
+ size_t hex_ssid_len = strlen(hex_ssid);
+
+ ssid = g_try_malloc0(hex_ssid_len / 2);
+ if (ssid == NULL) {
+ g_free(hex_ssid);
+ err = -ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < hex_ssid_len; i += 2) {
+ sscanf(hex_ssid + i, "%02x", &hex);
+ ssid[j++] = hex;
+ }
+
+ connman_network_set_blob(service->network,
+ "WiFi.SSID", ssid, hex_ssid_len / 2);
+ }
+
+ g_free(hex_ssid);
+ }
+ /* fall through */
+
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
__connman_ipconfig_load(service->ipconfig, keyfile,
service->identifier, "IPv4.");
+done:
g_key_file_free(keyfile);
- return 0;
+ return err;
}
static int service_save(struct connman_service *service)
gchar *pathname, *data = NULL;
gsize length;
gchar *str;
+ int err = 0;
DBG("service %p", service);
case CONNMAN_SERVICE_TYPE_ETHERNET:
break;
case CONNMAN_SERVICE_TYPE_WIFI:
+ if (service->network) {
+ const unsigned char *ssid;
+ unsigned int ssid_len = 0;
+
+ ssid = connman_network_get_blob(service->network,
+ "WiFi.SSID", &ssid_len);
+
+ if (ssid != NULL && ssid_len > 0 && ssid[0] != '\0') {
+ char *identifier = service->identifier;
+ GString *str;
+ unsigned int i;
+
+ str = g_string_sized_new(ssid_len * 2);
+ if (str == NULL) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < ssid_len; i++)
+ g_string_append_printf(str,
+ "%02x", ssid[i]);
+
+ g_key_file_set_string(keyfile, identifier,
+ "SSID", str->str);
+
+ g_string_free(str, TRUE);
+ }
+ }
+ /* fall through */
+
case CONNMAN_SERVICE_TYPE_WIMAX:
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_CELLULAR:
g_free(pathname);
- return 0;
+ return err;
}
static struct connman_storage service_storage = {