Imported Upstream version 1.24
[platform/upstream/connman.git] / client / services.c
index 139637b..0c18669 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  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 <unistd.h>
 #include <errno.h>
 
-#include "client/services.h"
-#include "src/connman.h"
+#include <glib.h>
 
-static void append_property_array(DBusMessageIter *iter, char *property,
-                                               char **data, int num_args)
-{
-       DBusMessageIter value, array;
-       int i;
-
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &property);
-
-       connman_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);
-}
+#include "services.h"
 
-static void append_property_dict(DBusMessageIter *iter, char *property,
-                                       char **keys, char **data, int num_args)
+static void print_service(char *path, DBusMessageIter *iter)
 {
-       DBusMessageIter value, dict, entry, dict_key;
-       int i;
-       unsigned char prefix;
+       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) {
 
-       /* Top most level is a{sv} */
-       connman_dbus_dict_open_variant(iter, &value);
-
-       connman_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]);
+               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);
 
-               if (strcmp(property, "IPv6.Configuration") == 0 &&
-                                          g_strcmp0(keys[i], "PrefixLength")) {
-                       if (data[i] == NULL) {
-                               fprintf(stderr, "No values entered!\n");
-                               exit(EXIT_FAILURE);
+               } 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';
                        }
-                       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} */
-       connman_dbus_dict_close(&value, &dict);
-       connman_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;
 
-       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);
-                       }
-                       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;
-
-               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;
-               }
-               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);
+               } else if (strcmp(property, "AutoConnect") == 0) {
+                       dbus_message_iter_next(&entry);
+                       dbus_message_iter_recurse(&entry, &val);
+                       dbus_message_iter_get_basic(&val, &autoconn);
 
-               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;
+               } 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(&array);
-       }
-}
-
-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);
+               count++;
+               dbus_message_iter_next(iter);
        }
-}
-
-/* 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);
-       connman_dbus_dict_open_variant(&iter, &value);
-       connman_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)
-               connman_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;
 }