*
* Connection Manager
*
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <glib.h>
#include "services.h"
-#include "dbus.h"
-static void append_property_array(DBusMessageIter *iter, char *property,
- char **data, int num_args)
+static void print_service(char *path, DBusMessageIter *iter)
{
- DBusMessageIter value, array;
- int i;
+ char *name = "", *str = NULL;
+ int autoconn = 0, favorite = 0, count = 0;
+ char *property;
+ char state = ' ';
+ DBusMessageIter entry, val;
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property);
+ while (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
- dbus_array_open(iter, &value);
- dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY,
- DBUS_TYPE_STRING_AS_STRING, &array);
-
- for (i = 0; i < num_args; i++) {
- dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING,
- &data[i]);
- printf("Added: %s\n", data[i]);
- }
- dbus_message_iter_close_container(&value, &array);
- dbus_message_iter_close_container(iter, &value);
-}
-
-static void append_property_dict(DBusMessageIter *iter, char *property,
- char **keys, char **data, int num_args)
-{
- DBusMessageIter value, dict, entry, dict_key;
- int i;
- unsigned char prefix;
-
- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property);
-
- /* Top most level is a{sv} */
- dbus_dict_open_variant(iter, &value);
-
- dbus_dict_open(&value, &dict);
-
- for (i = 0; i < num_args; i++) {
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
- &keys[i]);
-
- if (strcmp(property, "IPv6.Configuration") == 0 &&
- g_strcmp0(keys[i], "PrefixLength")) {
- if (data[i] == NULL) {
- fprintf(stderr, "No values entered!\n");
- exit(EXIT_FAILURE);
- }
- prefix = atoi(data[i]);
-
- dbus_message_iter_open_container(&entry,
- DBUS_TYPE_VARIANT,
- DBUS_TYPE_BYTE_AS_STRING,
- &dict_key);
- dbus_message_iter_append_basic(&dict_key,
- DBUS_TYPE_BYTE, &prefix);
- } else {
- dbus_message_iter_open_container(&entry,
- DBUS_TYPE_VARIANT,
- DBUS_TYPE_STRING_AS_STRING,
- &dict_key);
- dbus_message_iter_append_basic(&dict_key,
- DBUS_TYPE_STRING,
- &data[i]);
- }
- dbus_message_iter_close_container(&entry, &dict_key);
- dbus_message_iter_close_container(&dict, &entry);
- }
- /* Close {sv}, then close a{sv} */
- dbus_dict_close(&value, &dict);
- dbus_dict_close(iter, &value);
-}
-
-void iterate_array(DBusMessageIter *iter)
-{
- DBusMessageIter array_item;
- dbus_bool_t key_bool;
- char *key_str;
-
- dbus_message_iter_recurse(iter, &array_item);
- /* Make sure the entry is not NULL! */
- printf("[ ");
- while (dbus_message_iter_get_arg_type(&array_item) !=
- DBUS_TYPE_INVALID) {
- if (dbus_message_iter_get_arg_type(&array_item) ==
- DBUS_TYPE_STRING) {
- dbus_message_iter_get_basic(&array_item,
- &key_str);
- printf("%s ", key_str);
- } else if (dbus_message_iter_get_arg_type(&array_item) ==
- DBUS_TYPE_BOOLEAN) {
- dbus_message_iter_get_basic(&array_item, &key_bool);
- printf("%s ", key_bool == TRUE ? "True"
- : "False");
- }
- dbus_message_iter_next(&array_item);
- }
- if (dbus_message_iter_get_arg_type(&array_item) ==
- DBUS_TYPE_INVALID)
- printf("] ");
-}
-
-void iterate_dict(DBusMessageIter *dict, char *string, uint16_t key_int)
-{
- DBusMessageIter dict_entry, sub_dict_entry;
+ dbus_message_iter_recurse(iter, &entry);
+ dbus_message_iter_get_basic(&entry, &property);
+ if (strcmp(property, "Name") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &name);
- printf("{ ");
- while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse(dict, &dict_entry);
- dbus_message_iter_get_basic(&dict_entry, &string);
- printf("%s=", string);
- dbus_message_iter_next(&dict_entry);
- while (dbus_message_iter_get_arg_type(&dict_entry)
- != DBUS_TYPE_INVALID) {
- dbus_message_iter_recurse(&dict_entry, &sub_dict_entry);
- if (dbus_message_iter_get_arg_type(&sub_dict_entry)
- == DBUS_TYPE_UINT16) {
- dbus_message_iter_get_basic(&sub_dict_entry,
- &key_int);
- printf("%d ", key_int);
- } else if (dbus_message_iter_get_arg_type(&sub_dict_entry)
- == DBUS_TYPE_STRING) {
- dbus_message_iter_get_basic(&sub_dict_entry,
- &string);
- printf("%s ", string);
- } else if (dbus_message_iter_get_arg_type(&sub_dict_entry)
- == DBUS_TYPE_ARRAY) {
- iterate_array(&sub_dict_entry);
+ } else if (strcmp(property, "State") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &str);
+
+ if (str) {
+ if (strcmp(str, "online") == 0)
+ state = 'O';
+ else if (strcmp(str, "ready") == 0)
+ state = 'R';
+ else if (!strcmp(str, "association"))
+ state = 'a';
+ else if (!strcmp(str, "configuration"))
+ state = 'c';
+ else if (!strcmp(str, "disconnect"))
+ state = 'd';
}
- dbus_message_iter_next(&dict_entry);
- }
- dbus_message_iter_next(dict);
- }
- printf("}");
-}
-
-/* Get dictionary info about the current service and store it */
-static void extract_service_properties(DBusMessageIter *dict,
- struct service_data *service)
-{
- DBusMessageIter entry, value, array_item;
- char *key;
- char *key_str;
- uint16_t key_uint16;
- dbus_bool_t key_bool;
- while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse(dict, &entry);
- dbus_message_iter_get_basic(&entry, &key);
- printf("\n %s = ", key);
- if (strcmp(key, "Name") == 0 && strlen(key) < 5)
- service->name = key;
+ } else if (strcmp(property, "AutoConnect") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &autoconn);
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &value);
- /* Check if entry is a dictionary itself */
- if (strcmp(key, "Ethernet") == 0 ||
- /* if just strcmp, the .Configuration names don't match
- * and they are iterated with iterate_array instead*/
- strncmp(key, "IPv4", 4) == 0 ||
- strncmp(key, "IPv6", 4) == 0 ||
- strncmp(key, "Proxy", 5) == 0 ||
- strcmp(key, "Provider") == 0) {
- dbus_message_iter_recurse(&value, &array_item);
- iterate_dict(&array_item, key_str, key_uint16);
- } else
- switch (dbus_message_iter_get_arg_type(&value)) {
- case DBUS_TYPE_ARRAY:
- iterate_array(&value);
- break;
- case DBUS_TYPE_BOOLEAN:
- dbus_message_iter_get_basic(&value, &key_bool);
- printf("%s", key_bool == TRUE ? "True" : "False");
- break;
- case DBUS_TYPE_BYTE:
- dbus_message_iter_get_basic(&value, &key_uint16);
- printf("%d", key_uint16);
- break;
- case DBUS_TYPE_STRING:
- dbus_message_iter_get_basic(&value, &key_str);
- printf("%s", key_str);
- break;
+ } else if (strcmp(property, "Favorite") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &favorite);
}
- dbus_message_iter_next(dict);
- }
- printf("\n\n");
-}
-
-static void match_service_name(DBusMessage *message, char *service_name,
- struct service_data *service)
-{
- DBusMessageIter iter, array;
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &array);
-
- while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
- DBusMessageIter entry, dict;
- char *path;
-
- dbus_message_iter_recurse(&array, &entry);
- dbus_message_iter_get_basic(&entry, &path);
-
- service->path = strip_service_path(path);
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &dict);
- extract_service_name(&dict, service);
- if (g_strcmp0(service_name, service->name) == 0) {
- printf(" Matched %s with %s\n\n", service->name,
- service->path);
- break;
- }
- dbus_message_iter_next(&array);
+ count++;
+ dbus_message_iter_next(iter);
}
-}
-void extract_service_name(DBusMessageIter *dict, struct service_data *service)
-{
- DBusMessageIter dict_entry, value;
- const char *key;
- const char *state;
-
- while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse(dict, &dict_entry);
- dbus_message_iter_get_basic(&dict_entry, &key);
- if (strcmp(key, "Name") == 0) {
- dbus_message_iter_next(&dict_entry);
- dbus_message_iter_recurse(&dict_entry, &value);
- dbus_message_iter_get_basic(&value, &service->name);
- }
- if (strcmp(key, "AutoConnect") == 0) {
- dbus_message_iter_next(&dict_entry);
- dbus_message_iter_recurse(&dict_entry, &value);
- dbus_message_iter_get_basic(&value, &service->autoconn);
- }
- if (strcmp(key, "State") == 0) {
- dbus_message_iter_next(&dict_entry);
- dbus_message_iter_recurse(&dict_entry, &value);
- dbus_message_iter_get_basic(&value, &state);
- if (strcmp(state, "ready") == 0) {
- service->connected = TRUE;
- service->online = FALSE;
- } else if (strcmp(state, "online") == 0) {
- service->connected = FALSE;
- service->online = TRUE;
- } else {
- service->connected = FALSE;
- service->online = FALSE;
- }
- }
- if (strcmp(key, "Favorite") == 0) {
- dbus_message_iter_next(&dict_entry);
- dbus_message_iter_recurse(&dict_entry, &value);
- dbus_message_iter_get_basic(&value, &service->favorite);
- }
- dbus_message_iter_next(dict);
- }
-}
-
-/* Show detailed information about a service */
-void extract_services(DBusMessage *message, char *service_name)
-{
- DBusMessageIter iter, array;
-
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &array);
-
- while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
- DBusMessageIter entry, dict;
- struct service_data service;
- char *path;
-
- dbus_message_iter_recurse(&array, &entry);
- dbus_message_iter_get_basic(&entry, &path);
-
- service.path = strip_service_path(path);
- if (g_strcmp0(service.path, service_name) == 0) {
- printf("[ %s ]\n", service.path);
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &dict);
- extract_service_properties(&dict, &service);
- }
- dbus_message_iter_next(&array);
- }
-}
+ str = strrchr(path, '/');
+ if (str)
+ str++;
+ else
+ str = path;
-/* Support both string names and path names for connecting to services */
-char *strip_service_path(char *service)
-{
- char *service_name;
- service_name = strrchr(service, '/');
- if (service_name == NULL)
- return service;
+ if (count > 0)
+ fprintf(stdout, "%c%c%c %-20s %s", favorite != 0 ? '*' : ' ',
+ autoconn != 0 ? 'A' : ' ', state, name, str);
else
- return service_name + 1;
+ fprintf(stdout, "%-24s %s", "unchanged", str);
+
}
-/* Show a simple list of service names only */
-void get_services(DBusMessage *message)
+static void list_service_array(DBusMessageIter *iter)
{
- DBusMessageIter iter, array;
+ DBusMessageIter array, dict;
+ char *path = NULL;
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &array);
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
- while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
- DBusMessageIter entry, dict;
- struct service_data service;
- char *path;
+ dbus_message_iter_recurse(iter, &array);
+ if (dbus_message_iter_get_arg_type(&array)
+ != DBUS_TYPE_OBJECT_PATH)
+ return;
- dbus_message_iter_recurse(&array, &entry);
- dbus_message_iter_get_basic(&entry, &path);
+ dbus_message_iter_get_basic(&array, &path);
- service.path = strip_service_path(path);
- dbus_message_iter_next(&entry);
- dbus_message_iter_recurse(&entry, &dict);
- extract_service_name(&dict, &service);
- printf("%-1s%-1s%-1s %-20s { %s }\n",
- service.favorite ? "*" : "",
- service.autoconn ? "A" : "",
- service.online ? "O" : (service.connected ? "R" : ""),
- service.name, service.path);
dbus_message_iter_next(&array);
- }
-}
-
-const char *find_service(DBusConnection *connection, DBusMessage *message,
- char *service_name, struct service_data *service)
-{
- DBusMessageIter iter, array, entry;
- char *path;
-
- service_name = strip_service_path(service_name);
- match_service_name(message, service_name, service);
- /* Service name did not match, so check if entry is a path */
- if (g_strcmp0(service_name, service->name)) {
- dbus_message_iter_init(message, &iter);
- dbus_message_iter_recurse(&iter, &array);
-
- while (dbus_message_iter_get_arg_type(&array) ==
- DBUS_TYPE_STRUCT) {
- dbus_message_iter_recurse(&array, &entry);
- dbus_message_iter_get_basic(&entry, &path);
-
- service->path = strip_service_path(path);
- if (g_strcmp0(service->path, service_name) == 0)
- return service->path;
- dbus_message_iter_next(&array);
+ if (dbus_message_iter_get_arg_type(&array)
+ == DBUS_TYPE_ARRAY) {
+ dbus_message_iter_recurse(&array, &dict);
+ print_service(path, &dict);
}
- fprintf(stderr, "'%s' is not a valid service name or path.\n",
- service_name);
- fprintf(stderr, "Use the 'services' command to find available "
- "services.\n");
- return NULL;
- } else
- return service->path;
-}
-
-int set_proxy_manual(DBusConnection *connection, DBusMessage *message,
- char *name, char **servers, char **excludes,
- int num_servers, int num_excludes)
-{
- DBusMessage *message_send;
- DBusMessageIter iter, value, dict, entry, data;
- struct service_data service;
- char *path;
- const char *path_name;
- char *property = "Proxy.Configuration";
- char *method = "Method";
- char *manual = "manual";
-
- path_name = find_service(connection, message, name, &service);
- if (path_name == NULL)
- return -ENXIO;
- path = g_strdup_printf("/net/connman/service/%s", path_name);
- message_send = dbus_message_new_method_call("net.connman", path,
- "net.connman.Service",
- "SetProperty");
+ if (dbus_message_iter_has_next(iter))
+ fprintf(stdout, "\n");
- if (message_send == NULL) {
- g_free(path);
- return -ENOMEM;
+ dbus_message_iter_next(iter);
}
-
- dbus_message_iter_init_append(message_send, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
- dbus_dict_open_variant(&iter, &value);
- dbus_dict_open(&value, &dict);
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL,
- &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &method);
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_STRING_AS_STRING,
- &data);
- dbus_message_iter_append_basic(&data, DBUS_TYPE_STRING, &manual);
- dbus_message_iter_close_container(&entry, &data);
- dbus_message_iter_close_container(&dict, &entry);
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL,
- &entry);
- append_property_array(&entry, "Servers", servers, num_servers);
- dbus_message_iter_close_container(&dict, &entry);
-
- if (num_excludes != 0) {
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY,
- NULL, &entry);
- append_property_array(&entry, "Excludes", excludes,
- num_excludes);
- dbus_message_iter_close_container(&dict, &entry);
- }
-
- dbus_message_iter_close_container(&value, &dict);
- dbus_message_iter_close_container(&iter, &value);
- dbus_connection_send(connection, message_send, NULL);
- dbus_connection_flush(connection);
- dbus_message_unref(message_send);
-
- g_free(path);
-
- return 0;
}
-int set_service_property(DBusConnection *connection, DBusMessage *message,
- char *name, char *property, char **keys,
- void *data, int num_args)
+void __connmanctl_services_list(DBusMessageIter *iter)
{
- DBusMessage *message_send;
- DBusMessageIter iter;
- struct service_data service;
+ DBusMessageIter array;
char *path;
- const char *path_name;
- path_name = find_service(connection, message, name, &service);
- if (path_name == NULL)
- return -ENXIO;
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
- path = g_strdup_printf("/net/connman/service/%s", path_name);
- message_send = dbus_message_new_method_call("net.connman", path,
- "net.connman.Service",
- "SetProperty");
+ dbus_message_iter_recurse(iter, &array);
+ list_service_array(&array);
- if (message_send == NULL) {
- g_free(path);
- return -ENOMEM;
- }
-
- dbus_message_iter_init_append(message_send, &iter);
-
- if (strcmp(property, "AutoConnect") == 0)
- dbus_property_append_basic(&iter, (const char *) property,
- DBUS_TYPE_BOOLEAN, data);
- else if ((strcmp(property, "Domains.Configuration") == 0)
- || (strcmp(property, "Timeservers.Configuration") == 0)
- || (strcmp(property, "Nameservers.Configuration") == 0))
- append_property_array(&iter, property, data, num_args);
- else if ((strcmp(property, "IPv4.Configuration") == 0)
- || (strcmp(property, "IPv6.Configuration") == 0)
- || (strcmp(property, "Proxy.Configuration") == 0))
- append_property_dict(&iter, property, keys, data, num_args);
+ dbus_message_iter_next(iter);
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
- dbus_connection_send(connection, message_send, NULL);
- dbus_connection_flush(connection);
- dbus_message_unref(message_send);
- g_free(path);
+ fprintf(stdout, "\n}, {");
- return 0;
-}
+ dbus_message_iter_recurse(iter, &array);
+ while (dbus_message_iter_get_arg_type(&array)
+ == DBUS_TYPE_OBJECT_PATH) {
+ dbus_message_iter_get_basic(&array, &path);
+ fprintf(stdout, "\n%-24s %s", "removed", path);
-int remove_service(DBusConnection *connection, DBusMessage *message,
- char *name)
-{
- struct service_data service;
- DBusMessage *message_send;
- const char *path_name;
- char *path;
-
- path_name = find_service(connection, message, name, &service);
- if (path_name == NULL)
- return -ENXIO;
-
- if (service.favorite == FALSE)
- return 0;
-
- path = g_strdup_printf("/net/connman/service/%s", path_name);
- message_send = dbus_message_new_method_call(CONNMAN_SERVICE, path,
- CONNMAN_SERVICE_INTERFACE,
- "Remove");
- if (message_send == NULL) {
- g_free(path);
- return -ENOMEM;
+ dbus_message_iter_next(&array);
}
- dbus_connection_send(connection, message_send, NULL);
- dbus_message_unref(message_send);
- g_free(path);
-
- return 0;
}