client: Add Remove() method support for service
[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         "        --remove                     Remove the service from favorite\n"
92         "  monitor                            Monitor signals from all Connman interfaces\n"
93         "        --services                   Monitor signals from the Service interface\n"
94         "        --tech                       Monitor signals from the Technology interface\n"
95         "        --manager                    Monitor signals from the Manager interface\n"
96         "  help, --help, (no arguments)       Show this dialogue\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 = 0;
107
108         message = get_message(conn, "GetServices");
109         if (message == NULL)
110                 return -ENOMEM;
111
112         switch (c) {
113         case 'p':
114                 name = find_service(conn, message, argv[2], service);
115                 if (name == NULL) {
116                         error = -ENXIO;
117                         break;
118                 }
119
120                 error = list_properties(conn, "GetServices", (char *) name);
121                 break;
122         default:
123                 fprintf(stderr, "Command not recognized, please check help\n");
124                 error = -EINVAL;
125                 break;
126         }
127
128         dbus_message_unref(message);
129
130         return error;
131 }
132
133 int config_switch(int argc, char *argv[], int c, DBusConnection *conn)
134 {
135         DBusMessage *message;
136         int num_args = argc - MANDATORY_ARGS;
137         int error = 0;
138         dbus_bool_t val;
139
140         message = get_message(conn, "GetServices");
141         if (message == NULL)
142                 return -ENOMEM;
143
144         switch (c) {
145         case 'a':
146                 switch (*optarg) {
147                 case 'y':
148                 case '1':
149                 case 't':
150                         val = TRUE;
151                         break;
152                 case 'n':
153                 case '0':
154                 case 'f':
155                         val = FALSE;
156                         break;
157                 default:
158                         return -EINVAL;
159                 }
160                 error = set_service_property(conn, message, argv[1],
161                                                 "AutoConnect", NULL,
162                                                 &val, 0);
163                 break;
164         case 'i':
165                 error = set_service_property(conn, message, argv[1],
166                                         "IPv4.Configuration", ipv4,
167                                         argv + MANDATORY_ARGS, num_args);
168                 break;
169         case 'v':
170                 error = set_service_property(conn, message, argv[1],
171                                         "IPv6.Configuration", ipv6,
172                                         argv + MANDATORY_ARGS, num_args);
173                 break;
174         case 'n':
175                 error = set_service_property(conn, message, argv[1],
176                                         "Nameservers.Configuration", NULL,
177                                         argv + MANDATORY_ARGS, num_args);
178                 break;
179         case 't':
180                 error = set_service_property(conn, message, argv[1],
181                                         "Timeservers.Configuration", NULL,
182                                         argv + MANDATORY_ARGS, num_args);
183                 break;
184         case 'd':
185                 error = set_service_property(conn, message, argv[1],
186                                         "Domains.Configuration", NULL,
187                                         argv + MANDATORY_ARGS, num_args);
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                 } else if (strcmp(argv[3], "manual") == 0
196                                   && strcmp(argv[4], "servers") == 0
197                                   && argc > 5) {
198                         argc -= 5;
199                         error = store_proxy_input(conn, message, argv[1],
200                                                                 argc, &argv[5]);
201                 } else {
202                         fprintf(stderr, "Incorrect arguments\n");
203                         error = -EINVAL;
204                 }
205                 break;
206         case 'r':
207                 error = remove_service(conn, message, argv[1]);
208                 break;
209         default:
210                 fprintf(stderr, "Command not recognized, please check help\n");
211                 error = -EINVAL;
212                 break;
213         }
214
215         dbus_message_unref(message);
216
217         return error;
218 }
219
220 int monitor_switch(int argc, char *argv[], int c, DBusConnection *conn)
221 {
222         int error;
223
224         switch (c) {
225         case 's':
226                 error = monitor_connman(conn, "Service", "PropertyChanged");
227                 if (error != 0)
228                         return error;
229                 if (dbus_connection_add_filter(conn, service_property_changed,
230                                                         NULL, NULL) == FALSE)
231                         return -ENOMEM;
232                 printf("Now monitoring the service interface.\n");
233                 break;
234         case 'c':
235                 error = monitor_connman(conn, "Technology", "PropertyChanged");
236                 if (error != 0)
237                         return error;
238                 if (dbus_connection_add_filter(conn, tech_property_changed,
239                                                         NULL, NULL) == FALSE)
240                         return -ENOMEM;
241                 printf("Now monitoring the technology interface.\n");
242                 break;
243         case 'm':
244                 error = monitor_connman(conn, "Manager", "PropertyChanged");
245                 if (error != 0)
246                         return error;
247                 error = monitor_connman(conn, "Manager", "TechnologyAdded");
248                 if (error != 0)
249                         return error;
250                 error = monitor_connman(conn, "Manager", "TechnologyRemoved");
251                 if (error != 0)
252                         return error;
253                 error = monitor_connman(conn, "Manager", "ServicesChanged");
254                 if (error != 0)
255                         return error;
256                 if (dbus_connection_add_filter(conn, manager_property_changed,
257                                                         NULL, NULL) == FALSE)
258                         return -ENOMEM;
259                 if (dbus_connection_add_filter(conn, tech_added_removed,
260                                                         NULL, NULL) == FALSE)
261                         return -ENOMEM;
262                 if (dbus_connection_add_filter(conn, manager_services_changed,
263                                                         NULL, NULL) == FALSE)
264                         return -ENOMEM;
265                 printf("Now monitoring the manager interface.\n");
266                 break;
267         default:
268                 fprintf(stderr, "Command not recognized, please check help\n");
269                 return -EINVAL;
270                 break;
271         }
272         return 0;
273 }
274
275 int commands_no_options(DBusConnection *connection, char *argv[], int argc)
276 {
277         DBusMessage *message = NULL;
278         int error = 0;
279
280
281         if (strcmp(argv[0], "--help") == 0 || strcmp(argv[0], "help") == 0  ||
282                                                 strcmp(argv[0], "h") == 0) {
283                 show_help();
284         } else if (strcmp(argv[0], "state") == 0) {
285                 if (argc != 1) {
286                         fprintf(stderr, "State cannot accept an argument, "
287                                                                 "see help\n");
288                         error = -EINVAL;
289                 } else
290                         error = list_properties(connection,
291                                                 "GetProperties", NULL);
292         } else if (strcmp(argv[0], "technologies") == 0) {
293                 if (argc != 1) {
294                         fprintf(stderr, "Tech cannot accept an argument, "
295                                                                 "see help\n");
296                         error = -EINVAL;
297                 } else
298                         error = list_properties(connection,
299                                                 "GetTechnologies", NULL);
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                         error = -EINVAL;
305                 } else
306                         error = connect_service(connection,
307                                                 strip_service_path(argv[1]));
308                 if (error == 0)
309                         printf("Connected to: %s\n",
310                                                 strip_service_path(argv[1]));
311         } else if (strcmp(argv[0], "disconnect") == 0) {
312                 if (argc != 2) {
313                         fprintf(stderr, "Disconnect requires a service name or "
314                                                         "path, see help\n");
315                         error = -EINVAL;
316                 } else
317                         error = disconnect_service(connection,
318                                                 strip_service_path(argv[1]));
319                 if (error == 0)
320                         printf("Disconnected from: %s\n",
321                                                 strip_service_path(argv[1]));
322         } else if (strcmp(argv[0], "scan") == 0) {
323                 if (argc != 2) {
324                         fprintf(stderr, "Scan requires a service name or path, "
325                                                                 "see help\n");
326                         error = -EINVAL;
327                 }
328                 message = get_message(connection, "GetTechnologies");
329                 if (message == NULL)
330                         error = -ENOMEM;
331                 else
332                         error = scan_technology(connection, message, argv[1]);
333         } else if (strcmp(argv[0], "enable") == 0) {
334                 if (argc != 2) {
335                         fprintf(stderr, "Enable requires a technology name or "
336                                 "the argument 'offlinemode', see help\n");
337                         error = -EINVAL;
338                 } else if (strcmp(argv[1], "offlinemode") == 0) {
339                         error = set_manager(connection, "OfflineMode", TRUE);
340                         if (error == 0)
341                                 printf("OfflineMode is now enabled\n");
342                 } else {
343                         message = get_message(connection, "GetTechnologies");
344                         if (message == NULL)
345                                 error = -ENOMEM;
346                         else
347                                 error = set_technology(connection, message,
348                                                 "Powered", argv[1], TRUE);
349                         if (error == 0)
350                                 printf("Enabled %s technology\n", argv[1]);
351                 }
352         } else if (strcmp(argv[0], "disable") == 0) {
353                 if (argc != 2) {
354                         fprintf(stderr, "Disable requires a technology name or "
355                                 "the argument 'offlinemode' see help\n");
356                         error = -EINVAL;
357                 } else if (strcmp(argv[1], "offlinemode") == 0) {
358                         error = set_manager(connection, "OfflineMode", FALSE);
359                         if (error == 0)
360                                 printf("OfflineMode is now disabled\n");
361                 } else {
362                         message = get_message(connection, "GetTechnologies");
363                         if (message == NULL)
364                                 error = -ENOMEM;
365                         else
366                                 error = set_technology(connection, message,
367                                                 "Powered", argv[1], FALSE);
368                         if (error == 0)
369                                 printf("Disabled %s technology\n", argv[1]);
370                 }
371         } else
372                 return -1;
373
374         if (message != NULL)
375                 dbus_message_unref(message);
376
377         return error;
378 }
379
380 int commands_options(DBusConnection *connection, char *argv[], int argc)
381 {
382         int error, c;
383         int option_index = 0;
384         struct service_data service;
385
386         static struct option service_options[] = {
387                 {"properties", required_argument, 0, 'p'},
388                 {0, 0, 0, 0}
389         };
390
391         static struct option config_options[] = {
392                 {"nameservers", required_argument, 0, 'n'},
393                 {"timeservers", required_argument, 0, 't'},
394                 {"domains", required_argument, 0, 'd'},
395                 {"ipv6", required_argument, 0, 'v'},
396                 {"proxy", required_argument, 0, 'x'},
397                 {"autoconnect", required_argument, 0, 'a'},
398                 {"ipv4", required_argument, 0, 'i'},
399                 {"remove", 0, 0, 'r'},
400                 {0, 0, 0, 0}
401         };
402
403         static struct option monitor_options[] = {
404                 {"services", no_argument, 0, 's'},
405                 {"tech", no_argument, 0, 'c'},
406                 {"manager", no_argument, 0, 'm'},
407                 {0, 0, 0, 0}
408         };
409
410         if (strcmp(argv[0], "services") == 0) {
411                 if (argc > 3) {
412                         fprintf(stderr, "Too many arguments for services, "
413                                                                 "see help\n");
414                         return -EINVAL;
415                 }
416                 if (argc < 2) {
417                         printf("List of all services:\n");
418                         error = list_properties(connection, "GetServices", NULL);
419                         if (error != 0)
420                                 return error;
421                 } else {
422                         while ((c = getopt_long(argc, argv, "", service_options,
423                                                 &option_index))) {
424                                 if (c == -1) {
425                                         if (option_index == 0) {
426                                                 printf("Services takes an "
427                                                         "option, see help.\n");
428                                                 return -EINVAL;
429                                         }
430                                         break;
431                                 }
432                                 error = service_switch(argc, argv, c,
433                                                                 connection,
434                                                                 &service);
435                                 if (error != 0)
436                                         return error;
437                                 option_index++;
438                         }
439                 }
440         } else if (strcmp(argv[0], "config") == 0) {
441                 if (argc < 3) {
442                         fprintf(stderr, "Config requires an option, "
443                                                                 "see help\n");
444                         return -EINVAL;
445                 }
446                 while ((c = getopt_long(argc, argv, "", config_options,
447                                                         &option_index))) {
448                         if (c == -1) {
449                                 if (option_index == 0) {
450                                         printf("Config requires an option, "
451                                                         "see help\n");
452                                         return -EINVAL;
453                                 }
454                                 break;
455                         }
456                         error = config_switch(argc, argv, c, connection);
457                         if (error != 0)
458                                 return error;
459                         option_index++;
460                 }
461         } else if (strcmp(argv[0], "monitor") == 0) {
462                 if (argc > 2) {
463                         fprintf(stderr, "Too many arguments for monitor, "
464                                                                 "see help\n");
465                         return -EINVAL;
466                 }
467                 if (argc < 2) {
468                         error = monitor_connman(connection, "Service",
469                                                         "PropertyChanged");
470                         if (error != 0)
471                                 return error;
472                         error = monitor_connman(connection, "Technology",
473                                                         "PropertyChanged");
474                         if (error != 0)
475                                 return error;
476                         error = monitor_connman(connection, "Manager",
477                                                         "PropertyChanged");
478                         if (error != 0)
479                                 return error;
480                         error = monitor_connman(connection, "Manager",
481                                                         "TechnologyAdded");
482                         if (error != 0)
483                                 return error;
484                         error = monitor_connman(connection, "Manager",
485                                                         "TechnologyRemoved");
486                         if (error != 0)
487                                 return error;
488                         error = monitor_connman(connection, "Manager",
489                                                         "ServicesChanged");
490                         if (error != 0)
491                                 return error;
492                         if (dbus_connection_add_filter(connection,
493                                         service_property_changed, NULL, NULL)
494                                                                 == FALSE)
495                                 return -ENOMEM;
496                         if (dbus_connection_add_filter(connection,
497                                         tech_property_changed, NULL, NULL)
498                                                                 == FALSE)
499                                 return -ENOMEM;
500                         if (dbus_connection_add_filter(connection,
501                                         tech_added_removed, NULL, NULL)
502                                                                 == FALSE)
503                                 return -ENOMEM;
504                         if (dbus_connection_add_filter(connection,
505                                         manager_property_changed, NULL, NULL)
506                                                                 == FALSE)
507                                 return -ENOMEM;
508                         if (dbus_connection_add_filter(connection,
509                                         manager_services_changed, NULL, NULL)
510                                                                 == FALSE)
511                                 return -ENOMEM;
512                         printf("Now monitoring all interfaces.\n");
513                 } else
514                         while ((c = getopt_long(argc, argv, "", monitor_options,
515                                                         &option_index))) {
516                                 if (c == -1) {
517                                         if (option_index == 0) {
518                                                 printf("Monitor takes an "
519                                                         "option, see help\n");
520                                                 return -EINVAL;
521                                         }
522                                         break;
523                                 }
524                                 error = monitor_switch(argc, argv, c, connection);
525                                 if (error != 0)
526                                         return error;
527                                 option_index++;
528                         }
529         } else
530                 return -1;
531         return 0;
532 }