5 * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
38 #include "technology.h"
39 #include "data_manager.h"
41 #include "dbus_helpers.h"
45 #define MANDATORY_ARGS 3
47 static DBusConnection *connection;
49 static char *ipv4[] = {
57 static char *ipv6[] = {
66 static char *proxy_simple[] = {
72 static int cmd_help(char *args[], int num, struct option *options);
74 static int parse_args(char *arg, struct option *options)
81 for (i = 0; options[i].name != NULL; i++) {
82 if (strcmp(options[i].name, arg) == 0 ||
83 (strncmp(arg, "--", 2) == 0 &&
84 strcmp(&arg[2], options[i].name) == 0))
85 return options[i].val;
91 static int cmd_enable(char *args[], int num, struct option *options)
102 if (strcmp(args[1], "offlinemode") == 0) {
103 err = set_manager(connection, "OfflineMode", TRUE);
105 printf("OfflineMode enabled\n");
110 message = get_message(connection, "GetTechnologies");
114 set_technology(connection, message, "Powered", args[1], TRUE);
119 static int cmd_disable(char *args[], int num, struct option *options)
121 DBusMessage *message;
130 if (strcmp(args[1], "offlinemode") == 0) {
131 err = set_manager(connection, "OfflineMode", FALSE);
133 printf("OfflineMode enabled\n");
138 message = get_message(connection, "GetTechnologies");
142 set_technology(connection, message, "Powered", args[1], FALSE);
147 static void state_print(DBusMessageIter *iter, const char *error,
150 DBusMessageIter entry;
153 fprintf(stderr, "Error: %s", error);
157 dbus_message_iter_recurse(iter, &entry);
158 __connmanctl_dbus_print(&entry, " ", " = ", "\n");
159 fprintf(stdout, "\n");
162 static int cmd_state(char *args[], int num, struct option *options)
167 return __connmanctl_dbus_method_call(connection, "/",
168 "net.connman.Manager", "GetProperties",
169 state_print, NULL, DBUS_TYPE_INVALID);
172 static int cmd_services(char *args[], int num, struct option *options)
174 char *service_name = NULL;
177 DBusMessage *message;
182 c = parse_args(args[1], options);
189 service_name = args[2];
194 service_name = args[1];
198 message = get_message(connection, "GetServices");
202 err = list_properties(connection, "GetServices", service_name);
203 dbus_message_unref(message);
208 static void technology_print(DBusMessageIter *iter, const char *error,
211 DBusMessageIter array;
214 fprintf(stderr, "Error: %s\n", error);
218 dbus_message_iter_recurse(iter, &array);
219 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
220 DBusMessageIter entry, dict;
223 dbus_message_iter_recurse(&array, &entry);
224 dbus_message_iter_get_basic(&entry, &path);
225 fprintf(stdout, "%s\n", path);
227 dbus_message_iter_next(&entry);
229 dbus_message_iter_recurse(&entry, &dict);
230 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
231 fprintf(stdout, "\n");
233 dbus_message_iter_next(&array);
237 static int cmd_technologies(char *args[], int num, struct option *options)
242 return __connmanctl_dbus_method_call(connection, "/",
243 "net.connman.Manager", "GetTechnologies",
244 technology_print, NULL, DBUS_TYPE_INVALID);
247 static void scan_return(DBusMessageIter *iter, const char *error,
250 char *path = user_data;
253 char *str = strrchr(path, '/');
255 fprintf(stdout, "Scan completed for %s\n", str);
257 fprintf(stderr, "Error %s: %s", path, error);
262 static int cmd_scan(char *args[], int num, struct option *options)
272 path = g_strdup_printf("/net/connman/technology/%s", args[1]);
273 return __connmanctl_dbus_method_call(connection, path,
274 "net.connman.Technology", "Scan",
275 scan_return, path, DBUS_TYPE_INVALID);
278 static void connect_return(DBusMessageIter *iter, const char *error,
281 char *path = user_data;
284 char *str = strrchr(path, '/');
286 fprintf(stdout, "Connected %s\n", str);
288 fprintf(stderr, "Error %s: %s\n", path, error);
293 static int cmd_connect(char *args[], int num, struct option *options)
303 path = g_strdup_printf("/net/connman/service/%s", args[1]);
304 return __connmanctl_dbus_method_call(connection, path,
305 "net.connman.Service", "Connect",
306 connect_return, path, DBUS_TYPE_INVALID);
309 static void disconnect_return(DBusMessageIter *iter, const char *error,
312 char *path = user_data;
315 char *str = strrchr(path, '/');
317 fprintf(stdout, "Disconnected %s\n", str);
319 fprintf(stderr, "Error %s: %s\n", path, error);
324 static int cmd_disconnect(char *args[], int num, struct option *options)
334 path = g_strdup_printf("/net/connman/service/%s", args[1]);
335 return __connmanctl_dbus_method_call(connection, path,
336 "net.connman.Service", "Disconnect",
337 disconnect_return, path, DBUS_TYPE_INVALID);
342 static int cmd_config(char *args[], int num, struct option *options)
344 int res = 0, index = 2, oldindex = 0;
347 DBusMessage *message;
351 service_name = args[1];
352 if (service_name == NULL)
355 while (index < num && args[index] != NULL) {
356 c = parse_args(args[index], options);
357 opt_start = &args[index + 1];
360 message = get_message(connection, "GetServices");
368 switch (parse_boolean(*opt_start)) {
380 res = set_service_property(connection, message,
381 service_name, "AutoConnect",
385 res = set_service_property(connection, message,
386 service_name, "IPv4.Configuration",
392 res = set_service_property(connection, message,
393 service_name, "IPv6.Configuration",
399 res = set_service_property(connection, message,
401 "Nameservers.Configuration",
405 res = set_service_property(connection, message,
407 "Timeservers.Configuration",
411 res = set_service_property(connection, message,
413 "Domains.Configuration",
417 if (*opt_start == NULL) {
422 if (strcmp(*opt_start, "direct") == 0) {
423 res = set_service_property(connection, message,
425 "Proxy.Configuration",
426 proxy_simple, opt_start, 1);
430 if (strcmp(*opt_start, "auto") == 0) {
431 res = set_service_property(connection, message,
433 "Proxy.Configuration",
434 proxy_simple, opt_start, 1);
438 if (strcmp(*opt_start, "manual") == 0) {
439 char **url_start = &args[index + 2];
441 if (*url_start != NULL &&
444 url_start = &args[index + 3];
447 res = store_proxy_input(connection,
448 message, service_name,
454 res = remove_service(connection, message, service_name);
461 dbus_message_unref(message);
464 printf("Error '%s': %s\n", args[oldindex],
475 static DBusHandlerResult monitor_changed(DBusConnection *connection,
476 DBusMessage *message, void *user_data)
478 DBusMessageIter iter;
479 const char *interface, *path;
481 interface = dbus_message_get_interface(message);
482 if (strncmp(interface, "net.connman.", 12) != 0)
483 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
485 interface = strrchr(interface, '.');
486 if (interface != NULL && *interface != '\0')
489 path = strrchr(dbus_message_get_path(message), '/');
490 if (path != NULL && *path != '\0')
493 __connmanctl_save_rl();
495 if (dbus_message_is_signal(message, "net.connman.Manager",
496 "ServicesChanged") == TRUE) {
498 fprintf(stdout, "%-12s %-20s = {\n", interface,
500 dbus_message_iter_init(message, &iter);
501 __connmanctl_services_list(&iter);
502 fprintf(stdout, "\n}\n");
504 __connmanctl_redraw_rl();
506 return DBUS_HANDLER_RESULT_HANDLED;
509 if (dbus_message_is_signal(message, "net.connman.Manager",
510 "TechnologyAdded") == TRUE)
511 path = "TechnologyAdded";
513 if (dbus_message_is_signal(message, "net.connman.Manager",
514 "TechnologyRemoved") == TRUE)
515 path = "TechnologyRemoved";
517 fprintf(stdout, "%-12s %-20s ", interface, path);
518 dbus_message_iter_init(message, &iter);
520 __connmanctl_dbus_print(&iter, "", " = ", " = ");
521 fprintf(stdout, "\n");
523 __connmanctl_redraw_rl();
525 return DBUS_HANDLER_RESULT_HANDLED;
528 static bool monitor_s = false;
529 static bool monitor_t = false;
530 static bool monitor_m = false;
532 static void monitor_add(char *interface)
537 if (monitor_s == false && monitor_t == false && monitor_m == false)
538 dbus_connection_add_filter(connection, monitor_changed,
541 if (g_strcmp0(interface, "Service") == 0) {
542 if (monitor_s == true)
545 } else if (g_strcmp0(interface, "Technology") == 0) {
546 if (monitor_t == true)
549 } else if (g_strcmp0(interface, "Manager") == 0) {
550 if (monitor_m == true)
556 dbus_error_init(&err);
557 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
559 dbus_bus_add_match(connection, rule, &err);
562 if (dbus_error_is_set(&err))
563 fprintf(stderr, "Error: %s\n", err.message);
566 static void monitor_del(char *interface)
570 if (g_strcmp0(interface, "Service") == 0) {
571 if (monitor_s == false)
574 } else if (g_strcmp0(interface, "Technology") == 0) {
575 if (monitor_t == false)
578 } else if (g_strcmp0(interface, "Manager") == 0) {
579 if (monitor_m == false)
585 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
587 dbus_bus_remove_match(connection, rule, NULL);
590 if (monitor_s == false && monitor_t == false && monitor_m == false)
591 dbus_connection_remove_filter(connection, monitor_changed,
595 static int cmd_monitor(char *args[], int num, struct option *options)
604 switch (parse_boolean(args[2])) {
614 c = parse_args(args[1], options);
617 monitor_add("Service");
618 monitor_add("Technology");
619 monitor_add("Manager");
624 monitor_add("Service");
626 monitor_del("Service");
631 monitor_add("Technology");
633 monitor_del("Technology");
638 monitor_add("Manager");
640 monitor_del("Manager");
644 switch(parse_boolean(args[1])) {
646 monitor_del("Service");
647 monitor_del("Technology");
648 monitor_del("Manager");
652 monitor_add("Service");
653 monitor_add("Technology");
654 monitor_add("Manager");
668 static int cmd_exit(char *args[], int num, struct option *options)
673 static struct option service_options[] = {
674 {"properties", required_argument, 0, 'p'},
678 static const char *service_desc[] = {
679 "[<service>] (obsolete)",
683 static struct option config_options[] = {
684 {"nameservers", required_argument, 0, 'n'},
685 {"timeservers", required_argument, 0, 't'},
686 {"domains", required_argument, 0, 'd'},
687 {"ipv6", required_argument, 0, 'v'},
688 {"proxy", required_argument, 0, 'x'},
689 {"autoconnect", required_argument, 0, 'a'},
690 {"ipv4", required_argument, 0, 'i'},
691 {"remove", 0, 0, 'r'},
695 static const char *config_desc[] = {
696 "<dns1> [<dns2>] [<dns3>]",
697 "<ntp1> [<ntp2>] [...]",
698 "<domain1> [<domain2>] [...]",
699 "off|auto|manual <address> <prefixlength> <gateway> <privacy>",
700 "direct|auto <URL>|manual <URL1> [<URL2>] [...]\n"
701 " [exclude <exclude1> [<exclude2>] [...]]",
703 "off|dhcp|manual <address> <prefixlength> <gateway>",
708 static struct option monitor_options[] = {
709 {"services", no_argument, 0, 's'},
710 {"tech", no_argument, 0, 'c'},
711 {"manager", no_argument, 0, 'm'},
715 static const char *monitor_desc[] = {
716 "[off] Monitor only services",
717 "[off] Monitor only technologies",
718 "[off] Monitor only manager interface",
722 static const struct {
724 const char *argument;
725 struct option *options;
726 const char **options_desc;
727 int (*func) (char *args[], int num, struct option *options);
730 { "enable", "<technology>|offline", NULL, NULL,
731 cmd_enable, "Enables given technology or offline mode" },
732 { "disable", "<technology>|offline", NULL, NULL,
733 cmd_disable, "Disables given technology or offline mode"},
734 { "state", NULL, NULL, NULL,
735 cmd_state, "Shows if the system is online or offline" },
736 { "services", "[<service>]", service_options, &service_desc[0],
737 cmd_services, "Display services" },
738 { "technologies", NULL, NULL, NULL,
739 cmd_technologies, "Display technologies" },
740 { "scan", "<technology>", NULL, NULL,
741 cmd_scan, "Scans for new services for given technology" },
742 { "connect", "<service>", NULL, NULL,
743 cmd_connect, "Connect a given service" },
744 { "disconnect", "<service>", NULL, NULL,
745 cmd_disconnect, "Disconnect a given service" },
746 { "config", "<service>", config_options, &config_desc[0],
747 cmd_config, "Set service configuration options" },
748 { "monitor", "[off]", monitor_options, &monitor_desc[0],
749 cmd_monitor, "Monitor signals from interfaces" },
750 { "help", NULL, NULL, NULL,
751 cmd_help, "Show help" },
752 { "exit", NULL, NULL, NULL,
754 { "quit", NULL, NULL, NULL,
759 static int cmd_help(char *args[], int num, struct option *options)
761 bool interactive = __connmanctl_is_interactive();
764 if (interactive == false)
765 fprintf(stdout, "Usage: connmanctl [[command] [args]]\n");
767 for (i = 0; cmd_table[i].cmd != NULL; i++) {
768 const char *cmd = cmd_table[i].cmd;
769 const char *argument = cmd_table[i].argument;
770 const char *desc = cmd_table[i].desc;
772 printf("%-12s%-22s%s\n", cmd != NULL? cmd: "",
773 argument != NULL? argument: "",
774 desc != NULL? desc: "");
776 if (cmd_table[i].options != NULL) {
777 for (j = 0; cmd_table[i].options[j].name != NULL;
779 const char *options_desc =
780 cmd_table[i].options_desc != NULL ?
781 cmd_table[i].options_desc[j]: "";
783 printf(" --%-12s%s\n",
784 cmd_table[i].options[j].name,
790 if (interactive == false)
791 fprintf(stdout, "\nNote: arguments and output are considered "
792 "EXPERIMENTAL for now.\n");
797 int commands(DBusConnection *dbus_conn, char *argv[], int argc)
801 connection = dbus_conn;
803 for (i = 0; cmd_table[i].cmd != NULL; i++) {
804 if (g_strcmp0(cmd_table[i].cmd, argv[0]) == 0 &&
805 cmd_table[i].func != NULL) {
806 result = cmd_table[i].func(argv, argc,
807 cmd_table[i].options);
808 if (result < 0 && result != -EINPROGRESS)
809 fprintf(stderr, "Error '%s': %s\n", argv[0],
815 fprintf(stderr, "Error '%s': Unknown command\n", argv[0]);