client: Add printout about connmanctl experimental status
[platform/upstream/connman.git] / client / commands.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2012  Intel Corporation. All rights reserved.
6  *  it under the terms of the GNU General Public License version 2 as
7  *  published by the Free Software Foundation.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <getopt.h>
25
26 #include <glib.h>
27 #include <gdbus.h>
28
29 #include "client/services.h"
30 #include "client/technology.h"
31 #include "client/data_manager.h"
32 #include "client/monitor.h"
33 #include "client/interactive.h"
34 #include "gdbus/gdbus.h"
35
36 #define MANDATORY_ARGS 3
37
38 static char *ipv4[] = {
39         "Method",
40         "Address",
41         "Netmask",
42         "Gateway",
43         NULL
44 };
45
46 static char *ipv6[] = {
47         "Method",
48         "Address",
49         "PrefixLength",
50         "Gateway",
51         "Privacy",
52         NULL
53 };
54
55 static char *proxy_simple[] = {
56         "Method",
57         "URL",
58         NULL
59 };
60
61 void show_help(void)
62 {
63         printf("Usage: connmanctl <command> [args]\n"
64         "  enable                             Enables given technology\n"
65         "        <technology>\n"
66         "        offlinemode                  Enables OfflineMode\n"
67         "  disable                            Disables given technology\n"
68         "        <technology>\n"
69         "        offlinemode                  Disables OfflineMode\n"
70         "  state                              Shows if the system is online or offline\n"
71         "  services                           Display list of all services\n"
72         "        --properties <service name>  Show properties of service\n"
73         "  technologies                       Current technology on the system\n"
74         "  scan <technology>                  Scans for new services on the given technology\n"
75         "  connect <service>                  Connect to a given service\n"
76         "  disconnect <service>               Disconnect from service\n"
77         "  config <service> [arg]             Set certain config options\n"
78         "        --autoconnect=y/n            Set autoconnect to service\n"
79         "        --nameservers <names>        Set manual name servers\n"
80         "        --timeservers <names>        Set manual time servers\n"
81         "        --domains <domains>          Set manual domains\n"
82         "        --ipv4                       Set ipv4 configuration\n"
83         "          [METHOD|DHCP|AUTO|MANUAL] [IP] [NETMASK] [GATEWAY]\n"
84         "        --ipv6                       Set ipv6 configuration\n"
85         "          [METHOD|AUTO|MANUAL|OFF] [IP] [PREFIXLENGTH] [GATEWAY]\n"
86         "          [PRIVACY|DISABLED|ENABLED|PREFERED]\n"
87         "        --proxy                      Set proxy configuration\n"
88         "          [METHOD|URL|SERVERS|EXCLUDES]\n"
89         "          if METHOD = manual, enter 'servers' then the list of servers\n"
90         "                         then enter 'excludes' then the list of excludes\n"
91         "  monitor                            Monitor signals from all Connman interfaces\n"
92         "        --services                   Monitor signals from the Service interface\n"
93         "        --tech                       Monitor signals from the Technology interface\n"
94         "        --manager                    Monitor signals from the Manager interface\n"
95         "  help, --help, (no arguments)       Show this dialogue\n"
96         "  interactive                        Drop into the interactive shell\n"
97         "  exit, quit, q                      Quit interactive mode\n"
98         "\nNote: arguments and output are considered EXPERIMENTAL for now.\n\n");
99 }
100
101 int service_switch(int argc, char *argv[], int c, DBusConnection *conn,
102                                                 struct service_data *service)
103 {
104         const char *name;
105         DBusMessage *message;
106         int error;
107
108         message = get_message(conn, "GetServices");
109
110         switch (c) {
111         case 'p':
112                 name = find_service(conn, message, argv[2], service);
113                 if (name == NULL)
114                         return -ENXIO;
115                 error = list_properties(conn, "GetServices", (char *) name);
116                 if (error != 0)
117                         return error;
118                 break;
119         default:
120                 fprintf(stderr, "Command not recognized, please check help\n");
121                 return -EINVAL;
122                 break;
123         }
124         return 0;
125 }
126
127 int config_switch(int argc, char *argv[], int c, DBusConnection *conn)
128 {
129         DBusMessage *message;
130         int num_args = argc - MANDATORY_ARGS;
131         int error;
132         dbus_bool_t val;
133
134         message = get_message(conn, "GetServices");
135
136         switch (c) {
137         case 'a':
138                 if (*optarg != 'y' || *optarg != 'n' || *optarg != '1' ||
139                                         *optarg != '0' || *optarg != 't' ||
140                                                         *optarg != 'f')
141                         return -EINVAL;
142                 if (*optarg == 'y' || *optarg == '1' ||
143                                                 *optarg == 't')
144                         val = TRUE;
145                 else if (*optarg == 'n' || *optarg == '0' ||
146                                                 *optarg == 'f')
147                         val = FALSE;
148                 error = set_service_property(conn, message, argv[1],
149                                                 "AutoConnect", NULL,
150                                                 &val, 0);
151                 if (error != 0)
152                         return error;
153                 break;
154         case 'i':
155                 error = set_service_property(conn, message, argv[1],
156                                         "IPv4.Configuration", ipv4,
157                                         argv + MANDATORY_ARGS, num_args);
158                 if (error != 0)
159                         return error;
160                 break;
161         case 'v':
162                 error = set_service_property(conn, message, argv[1],
163                                         "IPv6.Configuration", ipv6,
164                                         argv + MANDATORY_ARGS, num_args);
165                 if (error != 0)
166                         return error;
167                 break;
168         case 'n':
169                 error = set_service_property(conn, message, argv[1],
170                                         "Nameservers.Configuration", NULL,
171                                         argv + MANDATORY_ARGS, num_args);
172                 if (error != 0)
173                         return error;
174                 break;
175         case 't':
176                 error = set_service_property(conn, message, argv[1],
177                                         "Timeservers.Configuration", NULL,
178                                         argv + MANDATORY_ARGS, num_args);
179                 if (error != 0)
180                         return error;
181                 break;
182         case 'd':
183                 error = set_service_property(conn, message, argv[1],
184                                         "Domains.Configuration", NULL,
185                                         argv + MANDATORY_ARGS, num_args);
186                 if (error != 0)
187                         return error;
188                 break;
189         case 'x':
190                 if ((strcmp(argv[3], "direct") == 0 && argc < 5) ||
191                         (strcmp(argv[3], "auto") == 0 && argc < 6)) {
192                         error = set_service_property(conn, message, argv[1],
193                                         "Proxy.Configuration", proxy_simple,
194                                         argv + MANDATORY_ARGS, num_args);
195                         if (error != 0)
196                                 return error;
197                 } else if (strcmp(argv[3], "manual") == 0
198                                   && strcmp(argv[4], "servers") == 0
199                                   && argc > 5) {
200                         argc -= 5;
201                         error = store_proxy_input(conn, message, argv[1],
202                                                                 argc, &argv[5]);
203                         if (error != 0)
204                                 return error;
205                 } else {
206                         fprintf(stderr, "Incorrect arguments\n");
207                         return -EINVAL;
208                 }
209                 break;
210         default:
211                 fprintf(stderr, "Command not recognized, please check help\n");
212                 return -EINVAL;
213                 break;
214         }
215         return 0;
216 }
217
218 int monitor_switch(int argc, char *argv[], int c, DBusConnection *conn)
219 {
220         int error;
221
222         switch (c) {
223         case 's':
224                 error = monitor_connman(conn, "Service", "PropertyChanged");
225                 if (error != 0)
226                         return error;
227                 if (dbus_connection_add_filter(conn, service_property_changed,
228                                                         NULL, NULL) == FALSE)
229                         return -ENOMEM;
230                 printf("Now monitoring the service interface.\n");
231                 break;
232         case 'c':
233                 error = monitor_connman(conn, "Technology", "PropertyChanged");
234                 if (error != 0)
235                         return error;
236                 if (dbus_connection_add_filter(conn, tech_property_changed,
237                                                         NULL, NULL) == FALSE)
238                         return -ENOMEM;
239                 printf("Now monitoring the technology interface.\n");
240                 break;
241         case 'm':
242                 error = monitor_connman(conn, "Manager", "PropertyChanged");
243                 if (error != 0)
244                         return error;
245                 error = monitor_connman(conn, "Manager", "TechnologyAdded");
246                 if (error != 0)
247                         return error;
248                 error = monitor_connman(conn, "Manager", "TechnologyRemoved");
249                 if (error != 0)
250                         return error;
251                 error = monitor_connman(conn, "Manager", "ServicesChanged");
252                 if (error != 0)
253                         return error;
254                 if (dbus_connection_add_filter(conn, manager_property_changed,
255                                                         NULL, NULL) == FALSE)
256                         return -ENOMEM;
257                 if (dbus_connection_add_filter(conn, tech_added_removed,
258                                                         NULL, NULL) == FALSE)
259                         return -ENOMEM;
260                 if (dbus_connection_add_filter(conn, manager_services_changed,
261                                                         NULL, NULL) == FALSE)
262                         return -ENOMEM;
263                 printf("Now monitoring the manager interface.\n");
264                 break;
265         default:
266                 fprintf(stderr, "Command not recognized, please check help\n");
267                 return -EINVAL;
268                 break;
269         }
270         return 0;
271 }
272
273 int commands_no_options(DBusConnection *connection, char *argv[], int argc)
274 {
275         int error;
276         DBusMessage *message;
277
278
279         if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "help") == 0  ||
280                                                 strcmp(argv[0], "h") == 0) {
281                 show_help();
282         } else if (strcmp(argv[0], "state") == 0) {
283                 if (argc != 1) {
284                         fprintf(stderr, "State cannot accept an argument, "
285                                                                 "see help\n");
286                         return -EINVAL;
287                 }
288                 error = list_properties(connection, "GetProperties", NULL);
289                 if (error != 0)
290                         return error;
291         } else if (strcmp(argv[0], "technologies") == 0) {
292                 if (argc != 1) {
293                         fprintf(stderr, "Tech cannot accept an argument, "
294                                                                 "see help\n");
295                         return -EINVAL;
296                 }
297                 error = list_properties(connection, "GetTechnologies", NULL);
298                 if (error != 0)
299                         return error;
300         } else if (strcmp(argv[0], "connect") == 0) {
301                 if (argc != 2) {
302                         fprintf(stderr, "Connect requires a service name or "
303                                                         "path, see help\n");
304                         return -EINVAL;
305                 }
306                 error = connect_service(connection, strip_service_path(argv[1]));
307                 if (error != 0)
308                         return error;
309                 printf("Connected to: %s\n", strip_service_path(argv[1]));
310         } else if (strcmp(argv[0], "disconnect") == 0) {
311                 if (argc != 2) {
312                         fprintf(stderr, "Disconnect requires a service name or "
313                                                         "path, see help\n");
314                         return -EINVAL;
315                 }
316                 error = disconnect_service(connection, strip_service_path(argv[1]));
317                 if (error != 0)
318                         return error;
319                 printf("Disconnected from: %s\n", strip_service_path(argv[1]));
320         } else if (strcmp(argv[0], "scan") == 0) {
321                 if (argc != 2) {
322                         fprintf(stderr, "Scan requires a service name or path, "
323                                                                 "see help\n");
324                         return -EINVAL;
325                 }
326                 message = get_message(connection, "GetTechnologies");
327                 error = scan_technology(connection, message, argv[1]);
328                 if (error != 0)
329                         return error;
330                 dbus_message_unref(message);
331         } else if (strcmp(argv[0], "enable") == 0) {
332                 if (argc != 2) {
333                         fprintf(stderr, "Enable requires a technology name or "
334                                 "the argument 'offlinemode', see help\n");
335                         return -EINVAL;
336                 }
337                 if (strcmp(argv[1], "offlinemode") == 0) {
338                         error = set_manager(connection, "OfflineMode", TRUE);
339                         if (error != 0)
340                                 return error;
341                         printf("OfflineMode is now enabled\n");
342                 } else {
343                         message = get_message(connection, "GetTechnologies");
344                         error = set_technology(connection, message, "Powered",
345                                                         argv[1], TRUE);
346                         if (error != 0)
347                                 return error;
348                         printf("Enabled %s technology\n", argv[1]);
349                         dbus_message_unref(message);
350                 }
351         } else if (strcmp(argv[0], "disable") == 0) {
352                 if (argc != 2) {
353                         fprintf(stderr, "Disable requires a technology name or "
354                                 "the argument 'offlinemode' see help\n");
355                         return -EINVAL;
356                 }
357                 if (strcmp(argv[1], "offlinemode") == 0) {
358                         error = set_manager(connection, "OfflineMode", FALSE);
359                         if (error != 0)
360                                 return error;
361                         printf("OfflineMode is now disabled\n");
362                 } else {
363                         message = get_message(connection, "GetTechnologies");
364                         error = set_technology(connection, message, "Powered",
365                                                         argv[1], FALSE);
366                         if (error != 0)
367                                 return error;
368                         printf("Disabled %s technology\n", argv[1]);
369                         dbus_message_unref(message);
370                 }
371         } else
372                 return -1;
373         return 0;
374 }
375
376 int commands_options(DBusConnection *connection, char *argv[], int argc)
377 {
378         int error, c;
379         int option_index = 0;
380         struct service_data service;
381
382         static struct option service_options[] = {
383                 {"properties", required_argument, 0, 'p'},
384                 {0, 0, 0, 0}
385         };
386
387         static struct option config_options[] = {
388                 {"nameservers", required_argument, 0, 'n'},
389                 {"timeservers", required_argument, 0, 't'},
390                 {"domains", required_argument, 0, 'd'},
391                 {"ipv6", required_argument, 0, 'v'},
392                 {"proxy", required_argument, 0, 'x'},
393                 {"autoconnect", required_argument, 0, 'a'},
394                 {"ipv4", required_argument, 0, 'i'},
395                 {0, 0, 0, 0}
396         };
397
398         static struct option monitor_options[] = {
399                 {"services", no_argument, 0, 's'},
400                 {"tech", no_argument, 0, 'c'},
401                 {"manager", no_argument, 0, 'm'},
402                 {0, 0, 0, 0}
403         };
404
405         if (strcmp(argv[0], "services") == 0) {
406                 if (argc > 3) {
407                         fprintf(stderr, "Too many arguments for services, "
408                                                                 "see help\n");
409                         return -EINVAL;
410                 }
411                 if (argc < 2) {
412                         printf("List of all services:\n");
413                         error = list_properties(connection, "GetServices", NULL);
414                         if (error != 0)
415                                 return error;
416                 } else {
417                         while ((c = getopt_long(argc, argv, "", service_options,
418                                                 &option_index))) {
419                                 if (c == -1) {
420                                         if (option_index == 0) {
421                                                 printf("Services takes an "
422                                                         "option, see help.\n");
423                                                 return -EINVAL;
424                                         }
425                                         break;
426                                 }
427                                 error = service_switch(argc, argv, c,
428                                                                 connection,
429                                                                 &service);
430                                 if (error != 0)
431                                         return error;
432                                 option_index++;
433                         }
434                 }
435         } else if (strcmp(argv[0], "config") == 0) {
436                 if (argc < 3) {
437                         fprintf(stderr, "Config requires an option, "
438                                                                 "see help\n");
439                         return -EINVAL;
440                 }
441                 while ((c = getopt_long(argc, argv, "", config_options,
442                                                         &option_index))) {
443                         if (c == -1) {
444                                 if (option_index == 0) {
445                                         printf("Config requires an option, "
446                                                         "see help\n");
447                                         return -EINVAL;
448                                 }
449                                 break;
450                         }
451                         error = config_switch(argc, argv, c, connection);
452                         if (error != 0)
453                                 return error;
454                         option_index++;
455                 }
456         } else if (strcmp(argv[0], "monitor") == 0) {
457                 if (argc > 2) {
458                         fprintf(stderr, "Too many arguments for monitor, "
459                                                                 "see help\n");
460                         return -EINVAL;
461                 }
462                 if (argc < 2) {
463                         error = monitor_connman(connection, "Service",
464                                                         "PropertyChanged");
465                         if (error != 0)
466                                 return error;
467                         error = monitor_connman(connection, "Technology",
468                                                         "PropertyChanged");
469                         if (error != 0)
470                                 return error;
471                         error = monitor_connman(connection, "Manager",
472                                                         "PropertyChanged");
473                         if (error != 0)
474                                 return error;
475                         error = monitor_connman(connection, "Manager",
476                                                         "TechnologyAdded");
477                         if (error != 0)
478                                 return error;
479                         error = monitor_connman(connection, "Manager",
480                                                         "TechnologyRemoved");
481                         if (error != 0)
482                                 return error;
483                         error = monitor_connman(connection, "Manager",
484                                                         "ServicesChanged");
485                         if (error != 0)
486                                 return error;
487                         if (dbus_connection_add_filter(connection,
488                                         service_property_changed, NULL, NULL)
489                                                                 == FALSE)
490                                 return -ENOMEM;
491                         if (dbus_connection_add_filter(connection,
492                                         tech_property_changed, NULL, NULL)
493                                                                 == FALSE)
494                                 return -ENOMEM;
495                         if (dbus_connection_add_filter(connection,
496                                         tech_added_removed, NULL, NULL)
497                                                                 == FALSE)
498                                 return -ENOMEM;
499                         if (dbus_connection_add_filter(connection,
500                                         manager_property_changed, NULL, NULL)
501                                                                 == FALSE)
502                                 return -ENOMEM;
503                         if (dbus_connection_add_filter(connection,
504                                         manager_services_changed, NULL, NULL)
505                                                                 == FALSE)
506                                 return -ENOMEM;
507                         printf("Now monitoring all interfaces.\n");
508                 } else
509                         while ((c = getopt_long(argc, argv, "", monitor_options,
510                                                         &option_index))) {
511                                 if (c == -1) {
512                                         if (option_index == 0) {
513                                                 printf("Monitor takes an "
514                                                         "option, see help\n");
515                                                 return -EINVAL;
516                                         }
517                                         break;
518                                 }
519                                 error = monitor_switch(argc, argv, c, connection);
520                                 if (error != 0)
521                                         return error;
522                                 option_index++;
523                         }
524         } else
525                 return -1;
526         return 0;
527 }