5 * Copyright (C) 2012-2014 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
32 #include <sys/types.h>
39 #include "dbus_helpers.h"
42 #include "tethering.h"
46 #include "vpnconnections.h"
47 #if defined TIZEN_EXT_WIFI_MESH
51 static DBusConnection *connection;
52 static GHashTable *service_hash;
53 static GHashTable *vpnconnection_hash;
54 static GHashTable *peer_hash;
55 static GHashTable *technology_hash;
56 static char *session_notify_path;
57 static char *session_path;
58 static bool session_connected;
60 struct connman_option {
66 static char *ipv4[] = {
74 static char *ipv6[] = {
82 static int cmd_help(char *args[], int num, struct connman_option *options);
84 static bool check_dbus_name(const char *name)
87 * Valid dbus chars should be [A-Z][a-z][0-9]_
88 * and should not start with number.
92 if (!name || name[0] == '\0')
95 for (i = 0; name[i] != '\0'; i++)
96 if (!((name[i] >= 'A' && name[i] <= 'Z') ||
97 (name[i] >= 'a' && name[i] <= 'z') ||
98 (name[i] >= '0' && name[i] <= '9') ||
105 static int parse_boolean(char *arg)
110 if (strcasecmp(arg, "no") == 0 ||
111 strcasecmp(arg, "false") == 0 ||
112 strcasecmp(arg, "off" ) == 0 ||
113 strcasecmp(arg, "disable" ) == 0 ||
114 strcasecmp(arg, "n") == 0 ||
115 strcasecmp(arg, "f") == 0 ||
116 strcasecmp(arg, "0") == 0)
119 if (strcasecmp(arg, "yes") == 0 ||
120 strcasecmp(arg, "true") == 0 ||
121 strcasecmp(arg, "on") == 0 ||
122 strcasecmp(arg, "enable" ) == 0 ||
123 strcasecmp(arg, "y") == 0 ||
124 strcasecmp(arg, "t") == 0 ||
125 strcasecmp(arg, "1") == 0)
131 static int parse_args(char *arg, struct connman_option *options)
138 for (i = 0; options[i].name; i++) {
139 if (strcmp(options[i].name, arg) == 0 ||
140 (strncmp(arg, "--", 2) == 0 &&
141 strcmp(&arg[2], options[i].name) == 0))
142 return options[i].val;
148 static int enable_return(DBusMessageIter *iter, const char *error,
151 char *tech = user_data;
154 str = strrchr(tech, '/');
161 fprintf(stdout, "Enabled %s\n", str);
163 fprintf(stderr, "Error %s: %s\n", str, error);
170 static int cmd_enable(char *args[], int num, struct connman_option *options)
173 dbus_bool_t b = TRUE;
181 if (check_dbus_name(args[1]) == false)
184 if (strcmp(args[1], "offline") == 0) {
185 tech = g_strdup(args[1]);
186 return __connmanctl_dbus_set_property(connection, "/",
187 "net.connman.Manager", enable_return, tech,
188 "OfflineMode", DBUS_TYPE_BOOLEAN, &b);
191 tech = g_strdup_printf("/net/connman/technology/%s", args[1]);
192 return __connmanctl_dbus_set_property(connection, tech,
193 "net.connman.Technology", enable_return, tech,
194 "Powered", DBUS_TYPE_BOOLEAN, &b);
197 static int disable_return(DBusMessageIter *iter, const char *error,
200 char *tech = user_data;
203 str = strrchr(tech, '/');
210 fprintf(stdout, "Disabled %s\n", str);
212 fprintf(stderr, "Error %s: %s\n", str, error);
219 static int cmd_disable(char *args[], int num, struct connman_option *options)
222 dbus_bool_t b = FALSE;
230 if (check_dbus_name(args[1]) == false)
233 if (strcmp(args[1], "offline") == 0) {
234 tech = g_strdup(args[1]);
235 return __connmanctl_dbus_set_property(connection, "/",
236 "net.connman.Manager", disable_return, tech,
237 "OfflineMode", DBUS_TYPE_BOOLEAN, &b);
240 tech = g_strdup_printf("/net/connman/technology/%s", args[1]);
241 return __connmanctl_dbus_set_property(connection, tech,
242 "net.connman.Technology", disable_return, tech,
243 "Powered", DBUS_TYPE_BOOLEAN, &b);
246 static int state_print(DBusMessageIter *iter, const char *error,
249 DBusMessageIter entry;
252 fprintf(stderr, "Error: %s\n", error);
256 dbus_message_iter_recurse(iter, &entry);
257 __connmanctl_dbus_print(&entry, " ", " = ", "\n");
258 fprintf(stdout, "\n");
263 static int cmd_state(char *args[], int num, struct connman_option *options)
268 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
269 CONNMAN_PATH, "net.connman.Manager", "GetProperties",
270 state_print, NULL, NULL, NULL);
273 static int clock_print(DBusMessageIter *iter, const char *error,
276 DBusMessageIter entry;
279 fprintf(stderr, "Error: %s\n", error);
283 dbus_message_iter_recurse(iter, &entry);
284 __connmanctl_dbus_print(&entry, " ", " = ", "\n");
285 fprintf(stdout, "\n");
290 static int cmd_clock(char *args[], int num, struct connman_option *options)
295 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
296 CONNMAN_PATH, "net.connman.Clock", "GetProperties",
297 clock_print, NULL, NULL, NULL);
300 static int services_list(DBusMessageIter *iter, const char *error,
304 __connmanctl_services_list(iter);
305 fprintf(stdout, "\n");
307 fprintf(stderr, "Error: %s\n", error);
313 static int peers_list(DBusMessageIter *iter,
314 const char *error, void *user_data)
317 __connmanctl_peers_list(iter);
318 fprintf(stdout, "\n");
320 fprintf(stderr, "Error: %s\n", error);
325 static int tethering_clients_list(DBusMessageIter *iter,
326 const char *error, void *user_data)
329 __connmanctl_tethering_clients_list(iter);
330 fprintf(stdout, "\n");
332 fprintf(stderr, "Error: %s\n", error);
337 static int object_properties(DBusMessageIter *iter,
338 const char *error, void *user_data)
340 char *path = user_data;
342 DBusMessageIter dict;
345 fprintf(stdout, "%s\n", path);
347 dbus_message_iter_recurse(iter, &dict);
348 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
350 fprintf(stdout, "\n");
353 str = strrchr(path, '/');
359 fprintf(stderr, "Error %s: %s\n", str, error);
367 static int cmd_services(char *args[], int num, struct connman_option *options)
369 char *service_name = NULL;
376 c = parse_args(args[1], options);
383 service_name = args[2];
388 service_name = args[1];
393 return __connmanctl_dbus_method_call(connection,
394 CONNMAN_SERVICE, CONNMAN_PATH,
395 "net.connman.Manager", "GetServices",
396 services_list, NULL, NULL, NULL);
399 if (check_dbus_name(service_name) == false)
402 path = g_strdup_printf("/net/connman/service/%s", service_name);
403 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
404 "net.connman.Service", "GetProperties",
405 object_properties, path, NULL, NULL);
408 static int cmd_peers(char *args[], int num, struct connman_option *options)
410 char *peer_name = NULL;
420 return __connmanctl_dbus_method_call(connection,
421 CONNMAN_SERVICE, CONNMAN_PATH,
422 "net.connman.Manager", "GetPeers",
423 peers_list, NULL, NULL, NULL);
426 if (check_dbus_name(peer_name) == false)
429 path = g_strdup_printf("/net/connman/peer/%s", peer_name);
430 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
431 path, "net.connman.Peer", "GetProperties",
432 object_properties, path, NULL, NULL);
435 static int technology_print(DBusMessageIter *iter, const char *error,
438 DBusMessageIter array;
441 fprintf(stderr, "Error: %s\n", error);
445 dbus_message_iter_recurse(iter, &array);
446 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
447 DBusMessageIter entry, dict;
450 dbus_message_iter_recurse(&array, &entry);
451 dbus_message_iter_get_basic(&entry, &path);
452 fprintf(stdout, "%s\n", path);
454 dbus_message_iter_next(&entry);
456 dbus_message_iter_recurse(&entry, &dict);
457 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
458 fprintf(stdout, "\n");
460 dbus_message_iter_next(&array);
466 static int cmd_technologies(char *args[], int num,
467 struct connman_option *options)
472 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
473 CONNMAN_PATH, "net.connman.Manager", "GetTechnologies",
474 technology_print, NULL, NULL, NULL);
477 struct tether_enable {
482 static int tether_set_return(DBusMessageIter *iter, const char *error,
485 struct tether_enable *tether = user_data;
488 str = strrchr(tether->path, '/');
495 fprintf(stdout, "%s tethering for %s\n",
496 tether->enable ? "Enabled" : "Disabled",
499 fprintf(stderr, "Error %s %s tethering: %s\n",
501 "enabling" : "disabling", str, error);
503 g_free(tether->path);
509 static int tether_set(char *technology, int set_tethering)
511 struct tether_enable *tether = g_new(struct tether_enable, 1);
513 switch(set_tethering) {
515 tether->enable = TRUE;
518 tether->enable = FALSE;
525 tether->path = g_strdup_printf("/net/connman/technology/%s",
528 return __connmanctl_dbus_set_property(connection, tether->path,
529 "net.connman.Technology", tether_set_return,
530 tether, "Tethering", DBUS_TYPE_BOOLEAN,
534 struct tether_properties {
536 int passphrase_result;
540 static int tether_update(struct tether_properties *tether)
544 if (tether->ssid_result == 0 && tether->passphrase_result == 0) {
545 ret = tether_set("wifi", tether->set_tethering);
550 if (tether->ssid_result != -EINPROGRESS &&
551 tether->passphrase_result != -EINPROGRESS) {
559 static int tether_set_ssid_return(DBusMessageIter *iter, const char *error,
562 struct tether_properties *tether = user_data;
565 fprintf(stdout, "Wifi SSID set\n");
566 tether->ssid_result = 0;
568 fprintf(stderr, "Error setting wifi SSID: %s\n", error);
569 tether->ssid_result = -EINVAL;
572 return tether_update(tether);
575 static int tether_set_passphrase_return(DBusMessageIter *iter,
576 const char *error, void *user_data)
578 struct tether_properties *tether = user_data;
581 fprintf(stdout, "Wifi passphrase set\n");
582 tether->passphrase_result = 0;
584 fprintf(stderr, "Error setting wifi passphrase: %s\n", error);
585 tether->passphrase_result = -EINVAL;
588 return tether_update(tether);
591 static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering)
593 struct tether_properties *tether = g_new(struct tether_properties, 1);
595 tether->set_tethering = set_tethering;
597 tether->ssid_result = __connmanctl_dbus_set_property(connection,
598 "/net/connman/technology/wifi",
599 "net.connman.Technology",
600 tether_set_ssid_return, tether,
601 "TetheringIdentifier", DBUS_TYPE_STRING, &ssid);
603 tether->passphrase_result =__connmanctl_dbus_set_property(connection,
604 "/net/connman/technology/wifi",
605 "net.connman.Technology",
606 tether_set_passphrase_return, tether,
607 "TetheringPassphrase", DBUS_TYPE_STRING, &passphrase);
609 if (tether->ssid_result != -EINPROGRESS &&
610 tether->passphrase_result != -EINPROGRESS) {
618 #if defined TIZEN_EXT_WIFI_MESH
619 struct mesh_if_prop {
625 struct mesh_create_network {
631 struct mesh_specific_scan_params {
636 struct mesh_gate_params {
642 static int mesh_return(DBusMessageIter *iter, const char *error,
645 char *method = user_data;
648 fprintf(stderr, "Error %s: %s\n", method, error);
650 fprintf(stderr, "Success %s\n", method);
657 static void mesh_interface_add_append(DBusMessageIter *iter, void *user_data)
659 struct mesh_if_prop *append = user_data;
661 /* Append Virtual Interface Name */
662 __connmanctl_dbus_append_dict_entry(iter, "Ifname",
663 DBUS_TYPE_STRING, &append->ifname);
665 /* Append Parent WiFi Interface Name */
666 __connmanctl_dbus_append_dict_entry(iter, "ParentIfname",
667 DBUS_TYPE_STRING, &append->parent_ifname);
669 /* Append Bridge Interface Name */
670 if (append->bridge_ifname)
671 __connmanctl_dbus_append_dict_entry(iter, "BridgeIfname",
672 DBUS_TYPE_STRING, &append->bridge_ifname);
675 static void mesh_interface_remove_append(DBusMessageIter *iter, void *user_data)
677 struct mesh_if_prop *append = user_data;
679 /* Append Virtual Interface Name */
680 __connmanctl_dbus_append_dict_entry(iter, "Ifname",
681 DBUS_TYPE_STRING, &append->ifname);
684 static void mesh_create_network_append(DBusMessageIter *iter, void *user_data)
686 struct mesh_create_network *append = user_data;
688 /* Append Mesh Network Name */
689 __connmanctl_dbus_append_dict_entry(iter, "Name",
690 DBUS_TYPE_STRING, &append->name);
692 /* Append Mesh Network Frequency */
693 __connmanctl_dbus_append_dict_entry(iter, "Frequency",
694 DBUS_TYPE_UINT16, &append->freq);
696 /* Append Mesh Network Security Type */
697 __connmanctl_dbus_append_dict_entry(iter, "Security",
698 DBUS_TYPE_STRING, &append->sec_type);
701 static void mesh_specific_scan_append(DBusMessageIter *iter, void *user_data)
703 struct mesh_specific_scan_params *append = user_data;
705 /* Append Mesh Network Name */
706 __connmanctl_dbus_append_dict_entry(iter, "Name",
707 DBUS_TYPE_STRING, &append->name);
709 /* Append Mesh Network Frequency */
710 __connmanctl_dbus_append_dict_entry(iter, "Frequency",
711 DBUS_TYPE_UINT16, &append->freq);
714 static void mesh_set_gate_append(DBusMessageIter *iter, void *user_data)
716 struct mesh_gate_params *append = user_data;
718 /* Append Gate Announce Protocol */
719 __connmanctl_dbus_append_dict_entry(iter, "GateAnnounce",
720 DBUS_TYPE_BOOLEAN, &append->gate_announce);
722 /* Append HWMP Root Mode */
723 __connmanctl_dbus_append_dict_entry(iter, "HWMPRootMode",
724 DBUS_TYPE_UINT16, &append->hwmp_rootmode);
727 __connmanctl_dbus_append_dict_entry(iter, "STP", DBUS_TYPE_UINT16,
731 static void mesh_peer_append(DBusMessageIter *iter, void *user_data)
733 char *peer_addr = user_data;
735 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &peer_addr);
740 static int mesh_peers_list(DBusMessageIter *iter,
741 const char *error, void *user_data)
744 __connmanctl_mesh_peers_list(iter);
745 fprintf(stdout, "\n");
747 fprintf(stderr, "Error: %s\n", error);
752 static int connected_mesh_peers_list(DBusMessageIter *iter,
753 const char *error, void *user_data)
756 __connmanctl_mesh_connected_peers_list(iter);
757 fprintf(stdout, "\n");
759 fprintf(stderr, "Error: %s\n", error);
764 static int disconnected_mesh_peers_list(DBusMessageIter *iter,
765 const char *error, void *user_data)
768 __connmanctl_mesh_disconnected_peers_list(iter);
769 fprintf(stdout, "\n");
771 fprintf(stderr, "Error: %s\n", error);
776 static int mesh_connect_return(DBusMessageIter *iter, const char *error,
779 char *path = user_data;
782 char *str = strrchr(path, '/');
784 fprintf(stdout, "Connected %s\n", str);
786 fprintf(stderr, "Error %s: %s\n", path, error);
793 static int mesh_disconnect_return(DBusMessageIter *iter, const char *error,
796 char *path = user_data;
799 char *str = strrchr(path, '/');
801 fprintf(stdout, "Disconnected %s\n", str);
803 fprintf(stderr, "Error %s: %s\n", path, error);
810 static int mesh_remove_return(DBusMessageIter *iter, const char *error,
813 char *path = user_data;
816 char *str = strrchr(path, '/');
818 fprintf(stdout, "Removed %s\n", str);
820 fprintf(stderr, "Error %s: %s\n", path, error);
827 static int mesh_config_return(DBusMessageIter *iter, const char *error,
830 char *path = user_data;
831 char *str = strrchr(path, '/');
835 fprintf(stderr, "Error %s: %s\n", path, error);
837 fprintf(stdout, "Success SetProperty %s\n", str);
844 static int cmd_mesh(char *args[], int num, struct connman_option *options)
850 char *mesh_peer_name = NULL;
851 char *mesh_peer_path = NULL;
852 char *property = NULL;
854 struct mesh_if_prop *append;
855 struct mesh_create_network *network;
856 struct mesh_specific_scan_params *scan_params;
857 struct mesh_gate_params *gate_params;
858 char *mesh_peer_addr = NULL;
860 c = parse_args(args[1], options);
864 if (num < 4 || num > 5) {
868 path = g_strdup_printf("/net/connman/technology/mesh");
870 append = dbus_malloc0(sizeof(struct mesh_if_prop));
871 append->ifname = g_strdup(args[2]);
872 append->parent_ifname = g_strdup(args[3]);
874 append->bridge_ifname = g_strdup(args[4]);
875 method = g_strdup("MeshInterfaceAdd");
876 result = __connmanctl_dbus_mesh_dict(connection, path,
877 "net.connman.Technology", mesh_return, method,
878 "MeshInterfaceAdd", DBUS_TYPE_STRING,
879 mesh_interface_add_append, append);
880 g_free(append->ifname);
881 g_free(append->parent_ifname);
882 g_free(append->bridge_ifname);
891 path = g_strdup_printf("/net/connman/technology/mesh");
893 append = dbus_malloc0(sizeof(struct mesh_if_prop));
894 append->ifname = g_strdup(args[2]);
895 method = g_strdup("MeshInterfaceRemove");
896 result = __connmanctl_dbus_mesh_dict(connection, path,
897 "net.connman.Technology", mesh_return, method,
898 "MeshInterfaceRemove", DBUS_TYPE_STRING,
899 mesh_interface_remove_append, append);
900 g_free(append->ifname);
911 mesh_peer_name = args[2];
913 if (!mesh_peer_name) {
914 result = __connmanctl_dbus_method_call(connection,
915 CONNMAN_SERVICE, CONNMAN_PATH,
916 "net.connman.Manager", "GetMeshPeers",
917 mesh_peers_list, NULL, NULL, NULL);
921 if (check_dbus_name(mesh_peer_name) == false) {
926 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
928 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
929 mesh_peer_path, "net.connman.Mesh", "GetProperties",
930 object_properties, mesh_peer_path, NULL, NULL);
944 mesh_peer_name = args[2];
946 if (check_dbus_name(mesh_peer_name) == false) {
951 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
953 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
954 mesh_peer_path, "net.connman.Mesh", "Connect",
955 mesh_connect_return, mesh_peer_path, NULL, NULL);
969 mesh_peer_name = args[2];
971 if (check_dbus_name(mesh_peer_name) == false) {
976 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
978 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
979 mesh_peer_path, "net.connman.Mesh", "Disconnect",
980 mesh_disconnect_return, mesh_peer_path, NULL, NULL);
994 mesh_peer_name = args[2];
996 if (check_dbus_name(mesh_peer_name) == false) {
1001 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
1003 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
1004 mesh_peer_path, "net.connman.Mesh", "Remove",
1005 mesh_remove_return, mesh_peer_path, NULL, NULL);
1014 result = __connmanctl_dbus_method_call(connection,
1015 CONNMAN_SERVICE, CONNMAN_PATH,
1016 "net.connman.Manager", "GetConnectedMeshPeers",
1017 connected_mesh_peers_list, NULL, NULL, NULL);
1026 result = __connmanctl_dbus_method_call(connection,
1027 CONNMAN_SERVICE, CONNMAN_PATH,
1028 "net.connman.Manager",
1029 "GetDisconnectedMeshPeers",
1030 disconnected_mesh_peers_list, NULL, NULL, NULL);
1038 path = g_strdup_printf("/net/connman/technology/mesh");
1040 network = dbus_malloc0(sizeof(struct mesh_create_network));
1041 network->name = g_strdup(args[2]);
1042 network->freq = atoi(args[3]);
1043 network->sec_type = g_strdup(args[4]);
1044 method = g_strdup("MeshCreateNetwork");
1045 result = __connmanctl_dbus_mesh_dict(connection, path,
1046 "net.connman.Technology", mesh_return, method,
1047 "MeshCreateNetwork", DBUS_TYPE_STRING,
1048 mesh_create_network_append, network);
1049 g_free(network->name);
1050 g_free(network->sec_type);
1059 path = g_strdup_printf("/net/connman/technology/mesh");
1061 method = g_strdup("AbortScan");
1062 result = __connmanctl_dbus_mesh_dict(connection, path,
1063 "net.connman.Technology", mesh_return, method,
1064 "AbortScan", DBUS_TYPE_STRING,
1073 path = g_strdup_printf("/net/connman/technology/mesh");
1075 scan_params = dbus_malloc0(sizeof(struct mesh_specific_scan_params));
1076 scan_params->name = g_strdup(args[2]);
1077 scan_params->freq = atoi(args[3]);
1078 method = g_strdup("MeshSpecificScan");
1079 result = __connmanctl_dbus_mesh_dict(connection, path,
1080 "net.connman.Technology", mesh_return, method,
1081 "MeshSpecificScan", DBUS_TYPE_STRING,
1082 mesh_specific_scan_append, scan_params);
1083 g_free(scan_params->name);
1084 g_free(scan_params);
1093 mesh_peer_name = args[2];
1097 if (check_dbus_name(mesh_peer_name) == false) {
1102 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
1105 if (g_strcmp0(property, "Passphrase") == 0) {
1106 result = __connmanctl_dbus_set_property(connection,
1107 mesh_peer_path, "net.connman.Mesh",
1108 mesh_config_return, mesh_peer_path, property,
1109 DBUS_TYPE_STRING, &value);
1111 printf("Invalid property %s\n", property);
1123 path = g_strdup_printf("/net/connman/technology/mesh");
1125 gate_params = dbus_malloc0(sizeof(struct mesh_gate_params));
1126 gate_params->gate_announce = atoi(args[2]);
1127 gate_params->hwmp_rootmode = atoi(args[3]);
1128 gate_params->stp = atoi(args[4]);
1130 method = g_strdup("SetMeshGate");
1132 result = __connmanctl_dbus_mesh_dict(connection, path,
1133 "net.connman.Technology", mesh_return, method,
1134 "SetMeshGate", DBUS_TYPE_STRING,
1135 mesh_set_gate_append, gate_params);
1145 mesh_peer_addr = g_strdup(args[2]);
1146 method = g_strdup("MeshAddPeer");
1148 result = __connmanctl_dbus_method_call(connection,
1149 CONNMAN_SERVICE, CONNMAN_PATH,
1150 "net.connman.Manager", "MeshAddPeer",
1151 mesh_return, method, mesh_peer_append,
1162 mesh_peer_addr = g_strdup(args[2]);
1163 method = g_strdup("MeshRemovePeer");
1165 result = __connmanctl_dbus_method_call(connection,
1166 CONNMAN_SERVICE, CONNMAN_PATH,
1167 "net.connman.Manager", "MeshRemovePeer",
1168 mesh_return, method, mesh_peer_append,
1181 if (result != -EINPROGRESS)
1182 printf("Error '%s': %s\n", args[1], strerror(-result));
1190 static int cmd_tether(char *args[], int num, struct connman_option *options)
1192 char *ssid, *passphrase;
1198 passphrase = args[num - 1];
1199 ssid = args[num - 2];
1201 set_tethering = parse_boolean(args[2]);
1203 if (strcmp(args[1], "wifi") == 0) {
1208 if (num == 5 && set_tethering == -1)
1215 return tether_set_ssid(ssid, passphrase, set_tethering);
1221 if (set_tethering == -1)
1224 if (check_dbus_name(args[1]) == false)
1227 return tether_set(args[1], set_tethering);
1230 static int cmd_tethering_clients(char *args[], int num, struct connman_option *options)
1235 return __connmanctl_dbus_method_call(connection,
1236 CONNMAN_SERVICE, CONNMAN_PATH,
1237 "net.connman.Manager", "GetTetheringClients",
1238 tethering_clients_list, NULL, NULL, NULL);
1241 static int scan_return(DBusMessageIter *iter, const char *error,
1244 char *path = user_data;
1247 char *str = strrchr(path, '/');
1249 fprintf(stdout, "Scan completed for %s\n", str);
1251 fprintf(stderr, "Error %s: %s\n", path, error);
1258 static int cmd_scan(char *args[], int num, struct connman_option *options)
1268 if (check_dbus_name(args[1]) == false)
1271 path = g_strdup_printf("/net/connman/technology/%s", args[1]);
1272 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
1273 "net.connman.Technology", "Scan",
1274 scan_return, path, NULL, NULL);
1277 static int connect_return(DBusMessageIter *iter, const char *error,
1280 char *path = user_data;
1283 char *str = strrchr(path, '/');
1285 fprintf(stdout, "Connected %s\n", str);
1287 fprintf(stderr, "Error %s: %s\n", path, error);
1294 static int cmd_connect(char *args[], int num, struct connman_option *options)
1296 const char *iface = "net.connman.Service";
1305 if (check_dbus_name(args[1]) == false)
1308 if (g_strstr_len(args[1], 5, "peer_") == args[1]) {
1309 iface = "net.connman.Peer";
1310 path = g_strdup_printf("/net/connman/peer/%s", args[1]);
1312 path = g_strdup_printf("/net/connman/service/%s", args[1]);
1314 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
1315 iface, "Connect", connect_return, path, NULL, NULL);
1318 static int disconnect_return(DBusMessageIter *iter, const char *error,
1321 char *path = user_data;
1324 char *str = strrchr(path, '/');
1326 fprintf(stdout, "Disconnected %s\n", str);
1328 fprintf(stderr, "Error %s: %s\n", path, error);
1335 static int cmd_disconnect(char *args[], int num, struct connman_option *options)
1337 const char *iface = "net.connman.Service";
1346 if (check_dbus_name(args[1]) == false)
1349 if (g_strstr_len(args[1], 5, "peer_") == args[1]) {
1350 iface = "net.connman.Peer";
1351 path = g_strdup_printf("/net/connman/peer/%s", args[1]);
1353 path = g_strdup_printf("/net/connman/service/%s", args[1]);
1355 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
1356 path, iface, "Disconnect",
1357 disconnect_return, path, NULL, NULL);
1360 struct move_service {
1365 static int move_before_return(DBusMessageIter *iter, const char *error,
1368 struct move_service *services = user_data;
1373 service = strrchr(services->service, '/');
1375 target = strrchr(services->target, '/');
1377 fprintf(stdout, "Moved %s before %s\n", service, target);
1379 fprintf(stderr, "Error %s: %s\n", services->service, error);
1381 g_free(services->service);
1382 g_free(services->target);
1388 static void move_before_append_args(DBusMessageIter *iter, void *user_data)
1390 char *path = user_data;
1392 dbus_message_iter_append_basic(iter,
1393 DBUS_TYPE_OBJECT_PATH, &path);
1396 static int cmd_service_move_before(char *args[], int num,
1397 struct connman_option *options)
1399 const char *iface = "net.connman.Service";
1400 struct move_service *services;
1408 if (check_dbus_name(args[1]) == false)
1411 services = g_new(struct move_service, 1);
1413 services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
1414 services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
1416 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
1417 services->service, iface, "MoveBefore",
1418 move_before_return, services,
1419 move_before_append_args,
1423 static int move_after_return(DBusMessageIter *iter, const char *error,
1426 struct move_service *services = user_data;
1431 service = strrchr(services->service, '/');
1433 target = strrchr(services->target, '/');
1435 fprintf(stdout, "Moved %s after %s\n", service, target);
1437 fprintf(stderr, "Error %s: %s\n", services->service, error);
1439 g_free(services->service);
1440 g_free(services->target);
1446 static void move_after_append_args(DBusMessageIter *iter, void *user_data)
1448 char *path = user_data;
1450 dbus_message_iter_append_basic(iter,
1451 DBUS_TYPE_OBJECT_PATH, &path);
1454 static int cmd_service_move_after(char *args[], int num,
1455 struct connman_option *options)
1457 const char *iface = "net.connman.Service";
1458 struct move_service *services;
1466 if (check_dbus_name(args[1]) == false)
1469 services = g_new(struct move_service, 1);
1471 services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
1472 services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
1474 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
1475 services->service, iface, "MoveAfter",
1476 move_after_return, services,
1477 move_after_append_args,
1481 static int config_return(DBusMessageIter *iter, const char *error,
1484 char *service_name = user_data;
1487 fprintf(stderr, "Error %s: %s\n", service_name, error);
1494 struct config_append {
1499 struct session_options {
1503 struct connman_option *options;
1506 static void config_append_ipv4(DBusMessageIter *iter,
1509 struct config_append *append = user_data;
1510 char **opts = append->opts;
1516 while (opts[i] && ipv4[i]) {
1517 __connmanctl_dbus_append_dict_entry(iter, ipv4[i],
1518 DBUS_TYPE_STRING, &opts[i]);
1525 static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
1527 struct config_append *append = user_data;
1528 char **opts = append->opts;
1535 if (g_strcmp0(opts[0], "auto") == 0) {
1538 switch (parse_boolean(opts[1])) {
1543 __connmanctl_dbus_append_dict_entry(iter, "Privacy",
1544 DBUS_TYPE_STRING, &str);
1551 __connmanctl_dbus_append_dict_entry(iter, "Privacy",
1552 DBUS_TYPE_STRING, &str);
1559 if (g_strcmp0(opts[1], "prefered") != 0 &&
1561 "preferred") != 0) {
1562 fprintf(stderr, "Error %s: %s\n",
1569 __connmanctl_dbus_append_dict_entry(iter,
1570 "Privacy", DBUS_TYPE_STRING,
1575 } else if (g_strcmp0(opts[0], "manual") == 0) {
1578 while (opts[i] && ipv6[i]) {
1580 int value = atoi(opts[i]);
1581 __connmanctl_dbus_append_dict_entry(iter,
1582 ipv6[i], DBUS_TYPE_BYTE,
1585 __connmanctl_dbus_append_dict_entry(iter,
1586 ipv6[i], DBUS_TYPE_STRING,
1594 } else if (g_strcmp0(opts[0], "off") != 0) {
1595 fprintf(stderr, "Error %s: %s\n", opts[0], strerror(EINVAL));
1600 __connmanctl_dbus_append_dict_entry(iter, "Method", DBUS_TYPE_STRING,
1604 static void config_append_str(DBusMessageIter *iter, void *user_data)
1606 struct config_append *append = user_data;
1607 char **opts = append->opts;
1614 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1622 static void append_servers(DBusMessageIter *iter, void *user_data)
1624 struct config_append *append = user_data;
1625 char **opts = append->opts;
1631 while (opts[i] && g_strcmp0(opts[i], "--excludes") != 0) {
1632 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1640 static void append_excludes(DBusMessageIter *iter, void *user_data)
1642 struct config_append *append = user_data;
1643 char **opts = append->opts;
1644 int i = append->values;
1646 if (!opts || !opts[i] ||
1647 g_strcmp0(opts[i], "--excludes") != 0)
1652 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1660 static void config_append_proxy(DBusMessageIter *iter, void *user_data)
1662 struct config_append *append = user_data;
1663 char **opts = append->opts;
1668 if (g_strcmp0(opts[0], "manual") == 0) {
1669 __connmanctl_dbus_append_dict_string_array(iter, "Servers",
1670 append_servers, append);
1672 __connmanctl_dbus_append_dict_string_array(iter, "Excludes",
1673 append_excludes, append);
1675 } else if (g_strcmp0(opts[0], "auto") == 0) {
1677 __connmanctl_dbus_append_dict_entry(iter, "URL",
1678 DBUS_TYPE_STRING, &opts[1]);
1682 } else if (g_strcmp0(opts[0], "direct") != 0)
1685 __connmanctl_dbus_append_dict_entry(iter, "Method",DBUS_TYPE_STRING,
1691 static int cmd_config(char *args[], int num, struct connman_option *options)
1693 int result = 0, res = 0, index = 2, oldindex = 0;
1695 char *service_name, *path;
1698 struct config_append append;
1700 service_name = args[1];
1704 if (check_dbus_name(service_name) == false)
1707 while (index < num && args[index]) {
1708 c = parse_args(args[index], options);
1709 opt_start = &args[index + 1];
1710 append.opts = opt_start;
1716 path = g_strdup_printf("/net/connman/service/%s", service_name);
1720 switch (parse_boolean(*opt_start)) {
1735 res = __connmanctl_dbus_set_property(connection,
1736 path, "net.connman.Service",
1738 g_strdup(service_name),
1740 DBUS_TYPE_BOOLEAN, &val);
1744 res = __connmanctl_dbus_set_property_dict(connection,
1745 path, "net.connman.Service",
1746 config_return, g_strdup(service_name),
1747 "IPv4.Configuration", DBUS_TYPE_STRING,
1748 config_append_ipv4, &append);
1749 index += append.values;
1753 res = __connmanctl_dbus_set_property_dict(connection,
1754 path, "net.connman.Service",
1755 config_return, g_strdup(service_name),
1756 "IPv6.Configuration", DBUS_TYPE_STRING,
1757 config_append_ipv6, &append);
1758 index += append.values;
1762 res = __connmanctl_dbus_set_property_array(connection,
1763 path, "net.connman.Service",
1764 config_return, g_strdup(service_name),
1765 "Nameservers.Configuration",
1766 DBUS_TYPE_STRING, config_append_str,
1768 index += append.values;
1772 res = __connmanctl_dbus_set_property_array(connection,
1773 path, "net.connman.Service",
1774 config_return, g_strdup(service_name),
1775 "Timeservers.Configuration",
1776 DBUS_TYPE_STRING, config_append_str,
1778 index += append.values;
1782 res = __connmanctl_dbus_set_property_array(connection,
1783 path, "net.connman.Service",
1784 config_return, g_strdup(service_name),
1785 "Domains.Configuration",
1786 DBUS_TYPE_STRING, config_append_str,
1788 index += append.values;
1792 res = __connmanctl_dbus_set_property_dict(connection,
1793 path, "net.connman.Service",
1794 config_return, g_strdup(service_name),
1795 "Proxy.Configuration",
1796 DBUS_TYPE_STRING, config_append_proxy,
1798 index += append.values;
1801 res = __connmanctl_dbus_method_call(connection,
1802 CONNMAN_SERVICE, path,
1803 "net.connman.Service", "Remove",
1804 config_return, g_strdup(service_name),
1809 switch (parse_boolean(*opt_start)) {
1821 res = __connmanctl_dbus_set_property(connection,
1822 path, "net.connman.Service",
1824 g_strdup(service_name),
1825 "mDNS.Configuration",
1826 DBUS_TYPE_BOOLEAN, &val);
1839 if (res == -EINPROGRESS)
1840 result = -EINPROGRESS;
1842 printf("Error '%s': %s\n", args[oldindex],
1853 static DBusHandlerResult monitor_changed(DBusConnection *connection,
1854 DBusMessage *message, void *user_data)
1856 DBusMessageIter iter;
1857 const char *interface, *path;
1859 interface = dbus_message_get_interface(message);
1861 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1863 if (strncmp(interface, "net.connman.", 12) != 0)
1864 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1866 if (!strcmp(interface, "net.connman.Agent") ||
1867 !strcmp(interface, "net.connman.vpn.Agent") ||
1868 !strcmp(interface, "net.connman.Session") ||
1869 !strcmp(interface, "net.connman.Notification"))
1870 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1872 interface = strrchr(interface, '.');
1873 if (interface && *interface != '\0')
1876 path = strrchr(dbus_message_get_path(message), '/');
1877 if (path && *path != '\0')
1880 __connmanctl_save_rl();
1882 if (dbus_message_is_signal(message, "net.connman.Manager",
1883 "ServicesChanged")) {
1885 fprintf(stdout, "%-12s %-20s = {\n", interface,
1887 dbus_message_iter_init(message, &iter);
1888 __connmanctl_services_list(&iter);
1889 fprintf(stdout, "\n}\n");
1891 __connmanctl_redraw_rl();
1893 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1894 } else if (dbus_message_is_signal(message, "net.connman.Manager",
1896 fprintf(stdout, "%-12s %-20s = {\n", interface,
1898 dbus_message_iter_init(message, &iter);
1899 __connmanctl_peers_list(&iter);
1900 fprintf(stdout, "\n}\n");
1902 __connmanctl_redraw_rl();
1904 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1905 } else if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
1906 "ConnectionAdded") ||
1907 dbus_message_is_signal(message,
1908 "net.connman.vpn.Manager",
1909 "ConnectionRemoved")) {
1910 interface = "vpn.Manager";
1911 path = dbus_message_get_member(message);
1913 } else if (dbus_message_is_signal(message, "net.connman.Manager",
1914 "TechnologyAdded") ||
1915 dbus_message_is_signal(message, "net.connman.Manager",
1916 "TechnologyRemoved"))
1917 path = dbus_message_get_member(message);
1919 fprintf(stdout, "%-12s %-20s ", interface, path);
1920 dbus_message_iter_init(message, &iter);
1922 __connmanctl_dbus_print(&iter, "", " = ", " = ");
1923 fprintf(stdout, "\n");
1925 __connmanctl_redraw_rl();
1927 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1934 { "Service", false },
1935 { "Technology", false },
1936 { "Manager", false },
1937 { "vpn.Manager", false },
1938 { "vpn.Connection", false },
1942 static void monitor_add(char *interface)
1944 bool add_filter = true, found = false;
1949 for (i = 0; monitor[i].interface; i++) {
1950 if (monitor[i].enabled == true)
1953 if (g_strcmp0(interface, monitor[i].interface) == 0) {
1954 if (monitor[i].enabled == true)
1957 monitor[i].enabled = true;
1965 if (add_filter == true)
1966 dbus_connection_add_filter(connection, monitor_changed,
1969 dbus_error_init(&err);
1970 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
1972 dbus_bus_add_match(connection, rule, &err);
1975 if (dbus_error_is_set(&err))
1976 fprintf(stderr, "Error: %s\n", err.message);
1979 static void monitor_del(char *interface)
1981 bool del_filter = true, found = false;
1986 for (i = 0; monitor[i].interface; i++) {
1987 if (g_strcmp0(interface, monitor[i].interface) == 0) {
1988 if (monitor[i].enabled == false)
1991 monitor[i].enabled = false;
1995 if (monitor[i].enabled == true)
2002 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
2004 dbus_bus_remove_match(connection, rule, NULL);
2007 if (del_filter == true)
2008 dbus_connection_remove_filter(connection, monitor_changed,
2012 static int cmd_monitor(char *args[], int num, struct connman_option *options)
2021 switch (parse_boolean(args[2])) {
2031 c = parse_args(args[1], options);
2034 monitor_add("Service");
2035 monitor_add("Technology");
2036 monitor_add("Manager");
2037 monitor_add("vpn.Manager");
2038 monitor_add("vpn.Connection");
2043 monitor_add("Service");
2045 monitor_del("Service");
2050 monitor_add("Technology");
2052 monitor_del("Technology");
2057 monitor_add("Manager");
2059 monitor_del("Manager");
2064 monitor_add("vpn.Manager");
2066 monitor_del("vpn.Manager");
2071 monitor_add("vpn.Connection");
2073 monitor_del("vpn.Connection");
2077 switch(parse_boolean(args[1])) {
2079 monitor_del("Service");
2080 monitor_del("Technology");
2081 monitor_del("Manager");
2082 monitor_del("vpn.Manager");
2083 monitor_del("vpn.Connection");
2087 monitor_add("Service");
2088 monitor_add("Technology");
2089 monitor_add("Manager");
2090 monitor_add("vpn.Manager");
2091 monitor_add("vpn.Connection");
2100 return -EINPROGRESS;
2105 static int cmd_agent(char *args[], int num, struct connman_option *options)
2107 if (!__connmanctl_is_interactive()) {
2108 fprintf(stderr, "Error: Not supported in non-interactive "
2119 switch(parse_boolean(args[1])) {
2121 __connmanctl_agent_unregister(connection);
2125 if (__connmanctl_agent_register(connection) == -EINPROGRESS)
2126 return -EINPROGRESS;
2138 static int vpnconnections_properties(DBusMessageIter *iter, const char *error,
2141 char *path = user_data;
2143 DBusMessageIter dict;
2146 fprintf(stdout, "%s\n", path);
2148 dbus_message_iter_recurse(iter, &dict);
2149 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
2151 fprintf(stdout, "\n");
2154 str = strrchr(path, '/');
2160 fprintf(stderr, "Error %s: %s\n", str, error);
2168 static int vpnconnections_list(DBusMessageIter *iter, const char *error,
2172 __connmanctl_vpnconnections_list(iter);
2174 fprintf(stderr, "Error: %s\n", error);
2179 static int cmd_vpnconnections(char *args[], int num,
2180 struct connman_option *options)
2182 char *vpnconnection_name, *path;
2187 vpnconnection_name = args[1];
2189 if (!vpnconnection_name)
2190 return __connmanctl_dbus_method_call(connection,
2191 VPN_SERVICE, VPN_PATH,
2192 "net.connman.vpn.Manager", "GetConnections",
2193 vpnconnections_list, NULL,
2196 if (check_dbus_name(vpnconnection_name) == false)
2199 path = g_strdup_printf("/net/connman/vpn/connection/%s",
2200 vpnconnection_name);
2201 return __connmanctl_dbus_method_call(connection, VPN_SERVICE, path,
2202 "net.connman.vpn.Connection", "GetProperties",
2203 vpnconnections_properties, path, NULL, NULL);
2207 static int cmd_vpnagent(char *args[], int num, struct connman_option *options)
2209 if (!__connmanctl_is_interactive()) {
2210 fprintf(stderr, "Error: Not supported in non-interactive "
2221 switch(parse_boolean(args[1])) {
2223 __connmanctl_vpn_agent_unregister(connection);
2227 if (__connmanctl_vpn_agent_register(connection) ==
2229 return -EINPROGRESS;
2241 static DBusMessage *session_release(DBusConnection *connection,
2242 DBusMessage *message, void *user_data)
2244 __connmanctl_save_rl();
2246 fprintf(stdout, "Session %s released\n", session_path);
2248 __connmanctl_redraw_rl();
2250 g_free(session_path);
2251 session_path = NULL;
2252 session_connected = false;
2254 return g_dbus_create_reply(message, DBUS_TYPE_INVALID);
2257 static DBusMessage *session_update(DBusConnection *connection,
2258 DBusMessage *message, void *user_data)
2260 DBusMessageIter iter, dict;
2262 __connmanctl_save_rl();
2264 fprintf(stdout, "Session Update = {\n");
2266 dbus_message_iter_init(message, &iter);
2267 dbus_message_iter_recurse(&iter, &dict);
2269 __connmanctl_dbus_print(&dict, "", " = ", "\n");
2270 fprintf(stdout, "\n}\n");
2272 dbus_message_iter_recurse(&iter, &dict);
2274 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2275 DBusMessageIter entry, variant;
2276 char *field, *state;
2278 dbus_message_iter_recurse(&dict, &entry);
2280 dbus_message_iter_get_basic(&entry, &field);
2282 if (dbus_message_iter_get_arg_type(&entry)
2284 && !strcmp(field, "State")) {
2286 dbus_message_iter_next(&entry);
2287 dbus_message_iter_recurse(&entry, &variant);
2288 if (dbus_message_iter_get_arg_type(&variant)
2289 != DBUS_TYPE_STRING)
2292 dbus_message_iter_get_basic(&variant, &state);
2294 if (!session_connected && (!strcmp(state, "connected")
2295 || !strcmp(state, "online"))) {
2297 fprintf(stdout, "Session %s connected\n",
2299 session_connected = true;
2304 if (!strcmp(state, "disconnected") &&
2305 session_connected) {
2307 fprintf(stdout, "Session %s disconnected\n",
2309 session_connected = false;
2314 dbus_message_iter_next(&dict);
2317 __connmanctl_redraw_rl();
2319 return g_dbus_create_reply(message, DBUS_TYPE_INVALID);
2322 static const GDBusMethodTable notification_methods[] = {
2323 { GDBUS_METHOD("Release", NULL, NULL, session_release) },
2324 { GDBUS_METHOD("Update", GDBUS_ARGS({"settings", "a{sv}"}),
2325 NULL, session_update) },
2329 static int session_notify_add(const char *path)
2331 if (session_notify_path)
2334 if (!g_dbus_register_interface(connection, path,
2335 "net.connman.Notification",
2336 notification_methods, NULL, NULL,
2338 fprintf(stderr, "Error: Failed to register VPN Agent "
2343 session_notify_path = g_strdup(path);
2348 static void session_notify_remove(void)
2350 if (!session_notify_path)
2353 g_dbus_unregister_interface(connection, session_notify_path,
2354 "net.connman.Notification");
2356 g_free(session_notify_path);
2357 session_notify_path = NULL;
2360 static int session_connect_cb(DBusMessageIter *iter, const char *error,
2364 fprintf(stderr, "Error: %s\n", error);
2368 return -EINPROGRESS;
2372 static int session_connect(void)
2374 return __connmanctl_dbus_method_call(connection, "net.connman",
2375 session_path, "net.connman.Session", "Connect",
2376 session_connect_cb, NULL, NULL, NULL);
2379 static int session_disconnect_cb(DBusMessageIter *iter, const char *error,
2383 fprintf(stderr, "Error: %s\n", error);
2388 static int session_disconnect(void)
2390 return __connmanctl_dbus_method_call(connection, "net.connman",
2391 session_path, "net.connman.Session", "Disconnect",
2392 session_disconnect_cb, NULL, NULL, NULL);
2395 static int session_create_cb(DBusMessageIter *iter, const char *error,
2398 gboolean connect = GPOINTER_TO_INT(user_data);
2402 fprintf(stderr, "Error creating session: %s", error);
2403 session_notify_remove();
2407 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH) {
2408 fprintf(stderr, "Error creating session: No session path\n");
2412 g_free(session_path);
2414 dbus_message_iter_get_basic(iter, &str);
2415 session_path = g_strdup(str);
2417 fprintf(stdout, "Session %s created\n", session_path);
2420 return session_connect();
2422 return -EINPROGRESS;
2425 static void session_config_append_array(DBusMessageIter *iter,
2428 struct config_append *append = user_data;
2429 char **opts = append->opts;
2435 while (opts[i] && strncmp(opts[i], "--", 2) != 0) {
2436 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
2444 static void session_create_append_dict(DBusMessageIter *iter, void *user_data)
2446 struct session_options *args_struct = user_data;
2447 int index = 0, res = 0;
2448 struct config_append append;
2451 dbus_bool_t source_ip_rule;
2453 while (index < args_struct->num && args_struct->args[index]) {
2454 append.opts = &args_struct->args[index];
2457 c = parse_args(args_struct->args[index], args_struct->options);
2461 __connmanctl_dbus_append_dict_string_array(iter, "AllowedBearers",
2462 session_config_append_array,
2466 if (! args_struct->args[index + 1]) {
2470 __connmanctl_dbus_append_dict_entry(iter, "ConnectionType",
2472 &args_struct->args[index + 1]);
2476 if (index + 1 < args_struct->num)
2477 ifname = args_struct->args[index + 1];
2480 __connmanctl_dbus_append_dict_entry(iter, "AllowedInterface",
2486 if (! args_struct->args[index + 1]) {
2490 switch (parse_boolean( args_struct->args[index + 1])) {
2492 source_ip_rule = TRUE;
2495 source_ip_rule = FALSE;
2501 __connmanctl_dbus_append_dict_entry(iter, "SourceIPRule",
2507 if (!args_struct->args[index + 1]) {
2511 __connmanctl_dbus_append_dict_entry(iter, "ContextIdentifier",
2513 &args_struct->args[index + 1]);
2520 if (res < 0 && res != -EINPROGRESS) {
2521 printf("Error '%s': %s\n", args_struct->args[index],
2526 index += append.values;
2530 static void session_create_append(DBusMessageIter *iter, void *user_data)
2532 struct session_options *args_struct = user_data;
2534 __connmanctl_dbus_append_dict(iter, session_create_append_dict,
2537 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
2538 &args_struct->notify_path);
2541 static int session_create(gboolean connect, char *args[], int num,
2542 struct connman_option *options)
2546 struct session_options args_struct;
2547 args_struct.args = args;
2548 args_struct.num = num;
2549 args_struct.options = options;
2551 notify_path = g_strdup_printf("/net/connman/connmanctl%d", getpid());
2552 session_notify_add(notify_path);
2553 args_struct.notify_path = notify_path;
2555 res = __connmanctl_dbus_method_call(connection, "net.connman", "/",
2556 "net.connman.Manager", "CreateSession",
2557 session_create_cb, GINT_TO_POINTER(connect),
2558 session_create_append, &args_struct);
2560 g_free(notify_path);
2562 if (res < 0 && res != -EINPROGRESS)
2563 session_notify_remove();
2568 static int session_destroy_cb(DBusMessageIter *iter, const char *error,
2572 fprintf(stderr, "Error destroying session: %s", error);
2576 fprintf(stdout, "Session %s ended\n", session_path);
2578 g_free(session_path);
2579 session_path = NULL;
2580 session_connected = false;
2585 static void session_destroy_append(DBusMessageIter *iter, void *user_data)
2587 const char *path = user_data;
2589 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
2592 static int session_destroy(void)
2594 return __connmanctl_dbus_method_call(connection, "net.connman", "/",
2595 "net.connman.Manager", "DestroySession",
2596 session_destroy_cb, NULL,
2597 session_destroy_append, session_path);
2600 static int session_config_return(DBusMessageIter *iter, const char *error,
2603 char *property_name = user_data;
2606 fprintf(stderr, "Error setting session %s: %s\n",
2607 property_name, error);
2612 static int session_config(char *args[], int num,
2613 struct connman_option *options)
2615 int index = 0, res = 0;
2616 struct config_append append;
2619 dbus_bool_t source_ip_rule;
2621 while (index < num && args[index]) {
2622 append.opts = &args[index];
2625 c = parse_args(args[index], options);
2629 res = __connmanctl_dbus_session_change_array(connection,
2630 session_path, session_config_return,
2631 "AllowedBearers", "AllowedBearers",
2632 session_config_append_array, &append);
2635 if (!args[index + 1]) {
2640 res = __connmanctl_dbus_session_change(connection,
2641 session_path, session_config_return,
2642 "ConnectionType", "ConnectionType",
2643 DBUS_TYPE_STRING, &args[index + 1]);
2647 if (index + 1 < num)
2648 ifname = args[index + 1];
2652 res = __connmanctl_dbus_session_change(connection,
2653 session_path, session_config_return,
2654 "AllowedInterface", "AllowedInterface",
2655 DBUS_TYPE_STRING, &ifname);
2659 if (!args[index + 1]) {
2663 switch (parse_boolean(args[index + 1])) {
2665 source_ip_rule = TRUE;
2668 source_ip_rule = FALSE;
2675 res = __connmanctl_dbus_session_change(connection,
2676 session_path, session_config_return,
2677 "SourceIPRule", "SourceIPRule",
2678 DBUS_TYPE_BOOLEAN, &source_ip_rule);
2682 if (!args[index + 1]) {
2687 res = __connmanctl_dbus_session_change(connection,
2688 session_path, session_config_return,
2689 "ctxid", "ctxid", DBUS_TYPE_STRING,
2698 if (res < 0 && res != -EINPROGRESS) {
2699 printf("Error '%s': %s\n", args[index],
2704 index += append.values;
2710 static int cmd_session(char *args[], int num, struct connman_option *options)
2719 switch(parse_boolean(command)) {
2723 return session_destroy();
2728 return session_create(FALSE, &args[2], num - 2, options);
2731 if (!strcmp(command, "connect")) {
2733 return session_create(TRUE, &args[2], num - 2,
2736 return session_connect();
2738 } else if (!strcmp(command, "disconnect")) {
2740 if (!session_path) {
2741 fprintf(stdout, "Session does not exist\n");
2745 return session_disconnect();
2746 } else if (!strcmp(command, "config")) {
2747 if (!session_path) {
2748 fprintf(stdout, "Session does not exist\n");
2755 return session_config(&args[2], num - 2, options);
2763 static int cmd_exit(char *args[], int num, struct connman_option *options)
2768 static char *lookup_key_from_table(GHashTable *hash, const char *text,
2772 static GHashTableIter iter;
2773 gpointer key, value;
2776 g_hash_table_iter_init(&iter, hash);
2780 while (g_hash_table_iter_next(&iter, &key, &value))
2781 if (strncmp(text, key, len) == 0)
2787 static char *lookup_service_arg(const char *text, int state)
2789 if (__connmanctl_input_calc_level() > 1) {
2790 __connmanctl_input_lookup_end();
2794 return lookup_key_from_table(service_hash, text, state);
2797 static char *lookup_peer(const char *text, int state)
2799 static GHashTableIter iter;
2800 gpointer key, value;
2804 g_hash_table_iter_init(&iter, peer_hash);
2808 while (g_hash_table_iter_next(&iter, &key, &value)) {
2809 const char *peer = key;
2810 if (strncmp(text, peer, len) == 0)
2811 return strdup(peer);
2817 static char *lookup_peer_arg(const char *text, int state)
2819 if (__connmanctl_input_calc_level() > 1) {
2820 __connmanctl_input_lookup_end();
2824 return lookup_peer(text, state);
2827 static char *lookup_technology(const char *text, int state)
2830 static GHashTableIter iter;
2831 gpointer key, value;
2834 g_hash_table_iter_init(&iter, technology_hash);
2838 while (g_hash_table_iter_next(&iter, &key, &value)) {
2839 const char *technology = key;
2840 if (strncmp(text, technology, len) == 0)
2841 return strdup(technology);
2847 static char *lookup_technology_arg(const char *text, int state)
2849 if (__connmanctl_input_calc_level() > 1) {
2850 __connmanctl_input_lookup_end();
2854 return lookup_technology(text, state);
2857 static char *lookup_technology_offline(const char *text, int state)
2860 static bool end = false;
2863 if (__connmanctl_input_calc_level() > 1) {
2864 __connmanctl_input_lookup_end();
2876 str = lookup_technology(text, state);
2882 if (strncmp(text, "offline", len) == 0)
2883 return strdup("offline");
2888 static char *lookup_on_off(const char *text, int state)
2890 char *onoff[] = { "on", "off", NULL };
2901 while (onoff[idx]) {
2905 if (!strncmp(text, str, len))
2912 static char *lookup_tether(const char *text, int state)
2916 level = __connmanctl_input_calc_level();
2918 return lookup_technology(text, state);
2921 return lookup_on_off(text, state);
2923 __connmanctl_input_lookup_end();
2928 static char *lookup_agent(const char *text, int state)
2930 if (__connmanctl_input_calc_level() > 1) {
2931 __connmanctl_input_lookup_end();
2935 return lookup_on_off(text, state);
2938 static char *lookup_vpnconnection_arg(const char *text, int state)
2940 if (__connmanctl_input_calc_level() > 1) {
2941 __connmanctl_input_lookup_end();
2945 return lookup_key_from_table(vpnconnection_hash, text, state);
2948 static struct connman_option service_options[] = {
2949 {"properties", 'p', "[<service>] (obsolete)"},
2953 static struct connman_option config_options[] = {
2954 {"nameservers", 'n', "<dns1> [<dns2>] [<dns3>]"},
2955 {"timeservers", 't', "<ntp1> [<ntp2>] [...]"},
2956 {"domains", 'd', "<domain1> [<domain2>] [...]"},
2957 {"mdns", 'm', "yes|no"},
2958 {"ipv6", 'v', "off|auto [enable|disable|preferred]|\n"
2959 "\t\t\tmanual <address> <prefixlength> <gateway>"},
2960 {"proxy", 'x', "direct|auto <URL>|manual <URL1> [<URL2>] [...]\n"
2961 "\t\t\t[exclude <exclude1> [<exclude2>] [...]]"},
2962 {"autoconnect", 'a', "yes|no"},
2963 {"ipv4", 'i', "off|dhcp|manual <address> <netmask> <gateway>"},
2964 {"remove", 'r', " Remove service"},
2968 static struct connman_option monitor_options[] = {
2969 {"services", 's', "[off] Monitor only services"},
2970 {"tech", 'c', "[off] Monitor only technologies"},
2971 {"manager", 'm', "[off] Monitor only manager interface"},
2972 {"vpnmanager", 'M', "[off] Monitor only VPN manager "
2974 {"vpnconnection", 'C', "[off] Monitor only VPN "
2979 static struct connman_option session_options[] = {
2980 {"bearers", 'b', "<technology1> [<technology2> [...]]"},
2981 {"type", 't', "local|internet|any"},
2982 {"ifname", 'i', "[<interface_name>]"},
2983 {"srciprule", 's', "yes|no"},
2984 {"ctxid", 'c', "<context_identifier>"},
2988 #if defined TIZEN_EXT_WIFI_MESH
2989 static struct connman_option mesh_options[] = {
2990 {"ifadd", 'a', "<ifname> <wifi_ifname>\n"
2991 " [bridge_ifname] Add Virtual Mesh "
2993 {"ifrmv", 'r', "<ifname> Remove Virtual Mesh "
2995 {"peers", 'p', "[peer] Display Mesh peer "
2997 {"connect", 'c', "<peer> Connect Mesh Peer"},
2998 {"disconnect", 'd', "<peer> Disconnect Mesh Peer"},
2999 {"remove", 'f', "<peer> Forget Mesh Peer"},
3000 {"connected_peers", 'C', "[] Displays connected"
3001 " Peer informations"},
3002 {"disconnected_peers", 'D', "[] Displays "
3003 "Disconnected Peer informations"},
3004 {"create_network", 'n', "<name> <frequency> <sec_type> Create New Mesh "
3006 {"abort_scan", 'A', " Abort ongoing mesh "
3008 {"specific_scan", 'S', "<name> <frequency> Create New Mesh "
3010 {"config", 'P', "<peer> Set Mesh Network "
3011 "Configurations\n Passphrase <passphrase>"},
3012 {"set_gate", 'G', "<gate_ann> <rootmode> <stp> Set Mesh Gate "
3014 {"add_peer", 'z', "<addr> Add Mesh Peer"},
3015 {"remove_peer", 'y', "<addr> Remove Mesh Peer"},
3020 static char *lookup_options(struct connman_option *options, const char *text,
3032 while (options[idx].name) {
3033 str = options[idx].name;
3036 if (str && strncmp(text, str, len) == 0)
3043 static char *lookup_monitor(const char *text, int state)
3047 level = __connmanctl_input_calc_level();
3050 return lookup_options(monitor_options, text, state);
3053 return lookup_on_off(text, state);
3055 __connmanctl_input_lookup_end();
3059 static char *lookup_config(const char *text, int state)
3061 if (__connmanctl_input_calc_level() < 2)
3062 return lookup_key_from_table(service_hash, text, state);
3064 return lookup_options(config_options, text, state);
3067 static char *lookup_session(const char *text, int state)
3069 return lookup_options(session_options, text, state);
3072 #if defined TIZEN_EXT_WIFI_MESH
3073 static char *lookup_mesh(const char *text, int state)
3075 return lookup_options(mesh_options, text, state);
3079 static int peer_service_cb(DBusMessageIter *iter, const char *error,
3082 bool registration = GPOINTER_TO_INT(user_data);
3085 fprintf(stderr, "Error %s peer service: %s\n",
3086 registration ? "registering" : "unregistering", error);
3088 fprintf(stdout, "Peer service %s\n",
3089 registration ? "registered" : "unregistered");
3094 struct _peer_service {
3095 unsigned char *bjr_query;
3097 unsigned char *bjr_response;
3098 int bjr_response_len;
3099 unsigned char *wfd_ies;
3106 static void append_dict_entry_fixed_array(DBusMessageIter *iter,
3107 const char *property, void *value, int length)
3109 DBusMessageIter dict_entry, variant, array;
3111 dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
3113 dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING,
3115 dbus_message_iter_open_container(&dict_entry, DBUS_TYPE_VARIANT,
3116 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
3118 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
3119 DBUS_TYPE_BYTE_AS_STRING, &array);
3120 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
3122 dbus_message_iter_close_container(&variant, &array);
3123 dbus_message_iter_close_container(&dict_entry, &variant);
3124 dbus_message_iter_close_container(iter, &dict_entry);
3127 static void append_peer_service_dict(DBusMessageIter *iter, void *user_data)
3129 struct _peer_service *service = user_data;
3131 if (service->bjr_query && service->bjr_response) {
3132 append_dict_entry_fixed_array(iter, "BonjourQuery",
3133 &service->bjr_query, service->bjr_query_len);
3134 append_dict_entry_fixed_array(iter, "BonjourResponse",
3135 &service->bjr_response, service->bjr_response_len);
3136 } else if (service->upnp_service && service->version) {
3137 __connmanctl_dbus_append_dict_entry(iter, "UpnpVersion",
3138 DBUS_TYPE_INT32, &service->version);
3139 __connmanctl_dbus_append_dict_entry(iter, "UpnpService",
3140 DBUS_TYPE_STRING, &service->upnp_service);
3141 } else if (service->wfd_ies) {
3142 append_dict_entry_fixed_array(iter, "WiFiDisplayIEs",
3143 &service->wfd_ies, service->wfd_ies_len);
3147 static void peer_service_append(DBusMessageIter *iter, void *user_data)
3149 struct _peer_service *service = user_data;
3152 __connmanctl_dbus_append_dict(iter, append_peer_service_dict, service);
3154 if (service->master < 0)
3157 master = service->master == 1 ? TRUE : FALSE;
3158 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &master);
3161 static struct _peer_service *fill_in_peer_service(unsigned char *bjr_query,
3162 int bjr_query_len, unsigned char *bjr_response,
3163 int bjr_response_len, char *upnp_service,
3164 int version, unsigned char *wfd_ies,
3167 struct _peer_service *service;
3169 service = dbus_malloc0(sizeof(*service));
3171 #if defined TIZEN_EXT
3176 if (bjr_query_len && bjr_response_len) {
3177 service->bjr_query = dbus_malloc0(bjr_query_len);
3178 #if defined TIZEN_EXT
3179 if(!service->bjr_query) {
3184 memcpy(service->bjr_query, bjr_query, bjr_query_len);
3185 service->bjr_query_len = bjr_query_len;
3187 service->bjr_response = dbus_malloc0(bjr_response_len);
3188 #if defined TIZEN_EXT
3189 if(!service->bjr_response) {
3190 dbus_free(service->bjr_query);
3195 memcpy(service->bjr_response, bjr_response, bjr_response_len);
3196 service->bjr_response_len = bjr_response_len;
3197 } else if (upnp_service && version) {
3198 service->upnp_service = strdup(upnp_service);
3199 service->version = version;
3200 } else if (wfd_ies && wfd_ies_len) {
3201 service->wfd_ies = dbus_malloc0(wfd_ies_len);
3202 #if defined TIZEN_EXT
3203 if (!service->wfd_ies) {
3208 memcpy(service->wfd_ies, wfd_ies, wfd_ies_len);
3209 service->wfd_ies_len = wfd_ies_len;
3218 static void free_peer_service(struct _peer_service *service)
3220 dbus_free(service->bjr_query);
3221 dbus_free(service->bjr_response);
3222 dbus_free(service->wfd_ies);
3223 free(service->upnp_service);
3227 static int peer_service_register(unsigned char *bjr_query, int bjr_query_len,
3228 unsigned char *bjr_response, int bjr_response_len,
3229 char *upnp_service, int version,
3230 unsigned char *wfd_ies, int wfd_ies_len, int master)
3232 struct _peer_service *service;
3233 bool registration = true;
3236 service = fill_in_peer_service(bjr_query, bjr_query_len, bjr_response,
3237 bjr_response_len, upnp_service, version,
3238 wfd_ies, wfd_ies_len);
3242 service->master = master;
3244 ret = __connmanctl_dbus_method_call(connection, "net.connman", "/",
3245 "net.connman.Manager", "RegisterPeerService",
3246 peer_service_cb, GINT_TO_POINTER(registration),
3247 peer_service_append, service);
3249 free_peer_service(service);
3254 static int peer_service_unregister(unsigned char *bjr_query, int bjr_query_len,
3255 unsigned char *bjr_response, int bjr_response_len,
3256 char *upnp_service, int version,
3257 unsigned char *wfd_ies, int wfd_ies_len)
3259 struct _peer_service *service;
3260 bool registration = false;
3263 service = fill_in_peer_service(bjr_query, bjr_query_len, bjr_response,
3264 bjr_response_len, upnp_service, version,
3265 wfd_ies, wfd_ies_len);
3269 service->master = -1;
3271 ret = __connmanctl_dbus_method_call(connection, "net.connman", "/",
3272 "net.connman.Manager", "UnregisterPeerService",
3273 peer_service_cb, GINT_TO_POINTER(registration),
3274 peer_service_append, service);
3276 free_peer_service(service);
3281 static int parse_spec_array(char *command, unsigned char spec[1024])
3283 int length, pos, end;
3287 end = strlen(command);
3288 for (e = NULL, length = pos = 0; command[pos] != '\0'; length++) {
3292 b[0] = command[pos];
3293 b[1] = command[pos+1];
3295 spec[length] = strtol(b, &e, 16);
3296 if (e && *e != '\0')
3305 static int cmd_peer_service(char *args[], int num,
3306 struct connman_option *options)
3308 unsigned char bjr_query[1024] = {};
3309 unsigned char bjr_response[1024] = {};
3310 unsigned char wfd_ies[1024] = {};
3311 char *upnp_service = NULL;
3312 int bjr_query_len = 0, bjr_response_len = 0;
3313 int version = 0, master = 0, wfd_ies_len = 0;
3319 if (!strcmp(args[2], "wfd_ies")) {
3320 wfd_ies_len = parse_spec_array(args[3], wfd_ies);
3321 if (wfd_ies_len == -EINVAL)
3331 if (!strcmp(args[2], "bjr_query")) {
3332 if (strcmp(args[4], "bjr_response"))
3334 bjr_query_len = parse_spec_array(args[3], bjr_query);
3335 bjr_response_len = parse_spec_array(args[5], bjr_response);
3337 if (bjr_query_len == -EINVAL || bjr_response_len == -EINVAL)
3339 } else if (!strcmp(args[2], "upnp_service")) {
3342 if (strcmp(args[4], "upnp_version"))
3344 upnp_service = args[3];
3345 version = strtol(args[5], &e, 10);
3352 master = parse_boolean(args[6]);
3357 if (!strcmp(args[1], "register")) {
3358 return peer_service_register(bjr_query, bjr_query_len,
3359 bjr_response, bjr_response_len, upnp_service,
3360 version, wfd_ies, wfd_ies_len, master);
3361 } else if (!strcmp(args[1], "unregister")) {
3362 return peer_service_unregister(bjr_query, bjr_query_len,
3363 bjr_response, bjr_response_len, upnp_service,
3364 version, wfd_ies, wfd_ies_len);
3370 static const struct {
3372 const char *argument;
3373 struct connman_option *options;
3374 int (*func) (char *args[], int num, struct connman_option *options);
3376 __connmanctl_lookup_cb cb;
3378 { "state", NULL, NULL, cmd_state,
3379 "Shows if the system is online or offline", NULL },
3380 { "technologies", NULL, NULL, cmd_technologies,
3381 "Display technologies", NULL },
3382 { "clock", NULL, NULL, cmd_clock,
3383 "Get System Clock Properties", NULL },
3384 { "enable", "<technology>|offline", NULL, cmd_enable,
3385 "Enables given technology or offline mode",
3386 lookup_technology_offline },
3387 { "disable", "<technology>|offline", NULL, cmd_disable,
3388 "Disables given technology or offline mode",
3389 lookup_technology_offline },
3390 #if defined TIZEN_EXT_WIFI_MESH
3391 { "mesh", "", mesh_options, cmd_mesh, "Mesh specific commands",
3394 { "tether", "<technology> on|off\n"
3395 " wifi [on|off] <ssid> <passphrase> ",
3397 "Enable, disable tethering, set SSID and passphrase for wifi",
3399 { "tethering_clients", NULL, NULL, cmd_tethering_clients,
3400 "Display tethering clients", NULL },
3401 { "services", "[<service>]", service_options, cmd_services,
3402 "Display services", lookup_service_arg },
3403 { "peers", "[peer]", NULL, cmd_peers,
3404 "Display peers", lookup_peer_arg },
3405 { "scan", "<technology>", NULL, cmd_scan,
3406 "Scans for new services for given technology",
3407 lookup_technology_arg },
3408 { "connect", "<service/peer>", NULL, cmd_connect,
3409 "Connect a given service or peer", lookup_service_arg },
3410 { "disconnect", "<service/peer>", NULL, cmd_disconnect,
3411 "Disconnect a given service or peer", lookup_service_arg },
3412 { "move-before", "<service> <target service> ", NULL,
3413 cmd_service_move_before, "Move <service> before <target service>",
3414 lookup_service_arg },
3415 { "move-after", "<service> <target service> ", NULL,
3416 cmd_service_move_after, "Move <service> after <target service>",
3417 lookup_service_arg },
3418 { "config", "<service>", config_options, cmd_config,
3419 "Set service configuration options", lookup_config },
3420 { "monitor", "[off]", monitor_options, cmd_monitor,
3421 "Monitor signals from interfaces", lookup_monitor },
3422 { "agent", "on|off", NULL, cmd_agent,
3423 "Agent mode", lookup_agent },
3424 { "vpnconnections", "[<connection>]", NULL, cmd_vpnconnections,
3425 "Display VPN connections", lookup_vpnconnection_arg },
3426 { "vpnagent", "on|off", NULL, cmd_vpnagent,
3427 "VPN Agent mode", lookup_agent },
3428 { "session", "on|off|connect|disconnect|config", session_options,
3429 cmd_session, "Enable or disable a session", lookup_session },
3430 { "peer_service", "register|unregister <specs> <master>\n"
3431 "Where specs are:\n"
3432 "\tbjr_query <query> bjr_response <response>\n"
3433 "\tupnp_service <service> upnp_version <version>\n"
3434 "\twfd_ies <ies>\n", NULL,
3435 cmd_peer_service, "(Un)Register a Peer Service", NULL },
3436 { "help", NULL, NULL, cmd_help,
3437 "Show help", NULL },
3438 { "exit", NULL, NULL, cmd_exit,
3440 { "quit", NULL, NULL, cmd_exit,
3445 static int cmd_help(char *args[], int num, struct connman_option *options)
3447 bool interactive = __connmanctl_is_interactive();
3450 if (interactive == false)
3451 fprintf(stdout, "Usage: connmanctl [[command] [args]]\n");
3453 for (i = 0; cmd_table[i].cmd; i++) {
3454 const char *cmd = cmd_table[i].cmd;
3455 const char *argument = cmd_table[i].argument;
3456 const char *desc = cmd_table[i].desc;
3458 printf("%-16s%-22s%s\n", cmd? cmd: "",
3459 argument? argument: "",
3462 if (cmd_table[i].options) {
3463 for (j = 0; cmd_table[i].options[j].name;
3465 const char *options_desc =
3466 cmd_table[i].options[j].desc ?
3467 cmd_table[i].options[j].desc: "";
3469 printf(" --%-16s%s\n",
3470 cmd_table[i].options[j].name,
3476 if (interactive == false)
3477 fprintf(stdout, "\nNote: arguments and output are considered "
3478 "EXPERIMENTAL for now.\n");
3483 __connmanctl_lookup_cb __connmanctl_get_lookup_func(const char *text)
3485 int i, cmdlen, textlen;
3490 textlen = strlen(text);
3492 for (i = 0; cmd_table[i].cmd; i++) {
3493 cmdlen = strlen(cmd_table[i].cmd);
3495 if (textlen > cmdlen && text[cmdlen] != ' ')
3498 if (strncmp(cmd_table[i].cmd, text, cmdlen) == 0)
3499 return cmd_table[i].cb;
3505 int __connmanctl_commands(DBusConnection *dbus_conn, char *argv[], int argc)
3509 connection = dbus_conn;
3511 for (i = 0; cmd_table[i].cmd; i++) {
3512 if (g_strcmp0(cmd_table[i].cmd, argv[0]) == 0 &&
3513 cmd_table[i].func) {
3514 result = cmd_table[i].func(argv, argc,
3515 cmd_table[i].options);
3516 if (result < 0 && result != -EINPROGRESS)
3517 fprintf(stderr, "Error '%s': %s\n", argv[0],
3523 fprintf(stderr, "Error '%s': Unknown command\n", argv[0]);
3527 char *__connmanctl_lookup_command(const char *text, int state)
3537 while (cmd_table[i].cmd) {
3538 const char *command = cmd_table[i].cmd;
3542 if (strncmp(text, command, len) == 0)
3543 return strdup(command);
3549 static char *get_path(char *full_path)
3553 path = strrchr(full_path, '/');
3554 if (path && *path != '\0')
3562 static void add_service_id(const char *path)
3564 g_hash_table_replace(service_hash, g_strdup(path),
3565 GINT_TO_POINTER(TRUE));
3568 static void remove_service_id(const char *path)
3570 g_hash_table_remove(service_hash, path);
3573 static void services_added(DBusMessageIter *iter)
3575 DBusMessageIter array;
3578 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
3580 dbus_message_iter_recurse(iter, &array);
3581 if (dbus_message_iter_get_arg_type(&array) !=
3582 DBUS_TYPE_OBJECT_PATH)
3585 dbus_message_iter_get_basic(&array, &path);
3586 add_service_id(get_path(path));
3588 dbus_message_iter_next(iter);
3592 static void update_services(DBusMessageIter *iter)
3594 DBusMessageIter array;
3597 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3600 dbus_message_iter_recurse(iter, &array);
3601 services_added(&array);
3603 dbus_message_iter_next(iter);
3604 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3607 dbus_message_iter_recurse(iter, &array);
3608 while (dbus_message_iter_get_arg_type(&array) ==
3609 DBUS_TYPE_OBJECT_PATH) {
3610 dbus_message_iter_get_basic(&array, &path);
3611 remove_service_id(get_path(path));
3613 dbus_message_iter_next(&array);
3617 static int populate_service_hash(DBusMessageIter *iter, const char *error,
3621 fprintf(stderr, "Error getting services: %s", error);
3625 update_services(iter);
3629 static void add_vpnconnection_id(const char *path)
3631 g_hash_table_replace(vpnconnection_hash, g_strdup(path),
3632 GINT_TO_POINTER(TRUE));
3635 static void remove_vpnconnection_id(const char *path)
3637 g_hash_table_remove(vpnconnection_hash, path);
3640 static void vpnconnection_added(DBusMessageIter *iter)
3644 dbus_message_iter_get_basic(iter, &path);
3645 add_vpnconnection_id(get_path(path));
3648 static void vpnconnection_removed(DBusMessageIter *iter)
3652 dbus_message_iter_get_basic(iter, &path);
3653 remove_vpnconnection_id(get_path(path));
3656 static void add_vpnconnections(DBusMessageIter *iter)
3658 DBusMessageIter array;
3661 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
3663 dbus_message_iter_recurse(iter, &array);
3664 if (dbus_message_iter_get_arg_type(&array) !=
3665 DBUS_TYPE_OBJECT_PATH)
3668 dbus_message_iter_get_basic(&array, &path);
3669 add_vpnconnection_id(get_path(path));
3671 dbus_message_iter_next(iter);
3675 static int populate_vpnconnection_hash(DBusMessageIter *iter, const char *error,
3678 DBusMessageIter array;
3681 fprintf(stderr, "Error getting VPN connections: %s", error);
3685 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3688 dbus_message_iter_recurse(iter, &array);
3690 add_vpnconnections(&array);
3695 static void add_peer_id(const char *path)
3697 g_hash_table_replace(peer_hash, g_strdup(path), GINT_TO_POINTER(TRUE));
3700 static void remove_peer_id(const char *path)
3702 g_hash_table_remove(peer_hash, path);
3705 static void peers_added(DBusMessageIter *iter)
3707 DBusMessageIter array;
3710 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
3712 dbus_message_iter_recurse(iter, &array);
3713 if (dbus_message_iter_get_arg_type(&array) !=
3714 DBUS_TYPE_OBJECT_PATH)
3717 dbus_message_iter_get_basic(&array, &path);
3718 add_peer_id(get_path(path));
3720 dbus_message_iter_next(iter);
3724 static void update_peers(DBusMessageIter *iter)
3726 DBusMessageIter array;
3729 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3732 dbus_message_iter_recurse(iter, &array);
3733 peers_added(&array);
3735 dbus_message_iter_next(iter);
3736 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3739 dbus_message_iter_recurse(iter, &array);
3740 while (dbus_message_iter_get_arg_type(&array) ==
3741 DBUS_TYPE_OBJECT_PATH) {
3742 dbus_message_iter_get_basic(&array, &path);
3743 remove_peer_id(get_path(path));
3745 dbus_message_iter_next(&array);
3749 static int populate_peer_hash(DBusMessageIter *iter,
3750 const char *error, void *user_data)
3753 fprintf(stderr, "Error getting peers: %s", error);
3761 static void add_technology_id(const char *path)
3763 g_hash_table_replace(technology_hash, g_strdup(path),
3764 GINT_TO_POINTER(TRUE));
3767 static void remove_technology_id(const char *path)
3769 g_hash_table_remove(technology_hash, path);
3772 static void remove_technology(DBusMessageIter *iter)
3776 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH)
3779 dbus_message_iter_get_basic(iter, &path);
3780 remove_technology_id(get_path(path));
3783 static void add_technology(DBusMessageIter *iter)
3787 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH)
3790 dbus_message_iter_get_basic(iter, &path);
3791 add_technology_id(get_path(path));
3794 static void update_technologies(DBusMessageIter *iter)
3796 DBusMessageIter array;
3798 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3801 dbus_message_iter_recurse(iter, &array);
3803 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
3804 DBusMessageIter object_path;
3806 dbus_message_iter_recurse(&array, &object_path);
3808 add_technology(&object_path);
3810 dbus_message_iter_next(&array);
3814 static int populate_technology_hash(DBusMessageIter *iter, const char *error,
3818 fprintf(stderr, "Error getting technologies: %s\n", error);
3822 update_technologies(iter);
3827 static DBusHandlerResult monitor_completions_changed(
3828 DBusConnection *connection,
3829 DBusMessage *message, void *user_data)
3831 bool *enabled = user_data;
3832 DBusMessageIter iter;
3833 DBusHandlerResult handled;
3836 handled = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3838 handled = DBUS_HANDLER_RESULT_HANDLED;
3840 if (dbus_message_is_signal(message, "net.connman.Manager",
3841 "ServicesChanged")) {
3842 dbus_message_iter_init(message, &iter);
3843 update_services(&iter);
3847 if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
3848 "ConnectionAdded")) {
3849 dbus_message_iter_init(message, &iter);
3850 vpnconnection_added(&iter);
3854 if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
3855 "ConnectionRemoved")) {
3856 dbus_message_iter_init(message, &iter);
3857 vpnconnection_removed(&iter);
3861 if (dbus_message_is_signal(message, "net.connman.Manager",
3863 dbus_message_iter_init(message, &iter);
3864 update_peers(&iter);
3868 if (dbus_message_is_signal(message, "net.connman.Manager",
3869 "TechnologyAdded")) {
3870 dbus_message_iter_init(message, &iter);
3871 add_technology(&iter);
3875 if (dbus_message_is_signal(message, "net.connman.Manager",
3876 "TechnologyRemoved")) {
3877 dbus_message_iter_init(message, &iter);
3878 remove_technology(&iter);
3882 if (!g_strcmp0(dbus_message_get_interface(message),
3883 "net.connman.Manager"))
3886 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3889 void __connmanctl_monitor_completions(DBusConnection *dbus_conn)
3891 bool *manager_enabled = NULL;
3895 for (i = 0; monitor[i].interface; i++) {
3896 if (!strcmp(monitor[i].interface, "Manager")) {
3897 manager_enabled = &monitor[i].enabled;
3903 g_hash_table_destroy(service_hash);
3904 g_hash_table_destroy(vpnconnection_hash);
3905 g_hash_table_destroy(technology_hash);
3907 dbus_bus_remove_match(connection,
3908 "type='signal',interface='net.connman.Manager'", NULL);
3909 dbus_bus_remove_match(connection,
3910 "type='signal',interface='net.connman.vpn.Manager'",
3912 dbus_connection_remove_filter(connection,
3913 monitor_completions_changed,
3918 connection = dbus_conn;
3920 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3923 vpnconnection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3926 peer_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3929 technology_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3932 __connmanctl_dbus_method_call(connection,
3933 CONNMAN_SERVICE, CONNMAN_PATH,
3934 "net.connman.Manager", "GetServices",
3935 populate_service_hash, NULL, NULL, NULL);
3937 __connmanctl_dbus_method_call(connection,
3938 VPN_SERVICE, CONNMAN_PATH,
3939 "net.connman.vpn.Manager", "GetConnections",
3940 populate_vpnconnection_hash, NULL, NULL, NULL);
3942 __connmanctl_dbus_method_call(connection,
3943 CONNMAN_SERVICE, CONNMAN_PATH,
3944 "net.connman.Manager", "GetPeers",
3945 populate_peer_hash, NULL, NULL, NULL);
3947 __connmanctl_dbus_method_call(connection,
3948 CONNMAN_SERVICE, CONNMAN_PATH,
3949 "net.connman.Manager", "GetTechnologies",
3950 populate_technology_hash, NULL, NULL, NULL);
3952 dbus_connection_add_filter(connection,
3953 monitor_completions_changed, manager_enabled,
3956 dbus_error_init(&err);
3957 dbus_bus_add_match(connection,
3958 "type='signal',interface='net.connman.Manager'", &err);
3960 if (dbus_error_is_set(&err)) {
3961 fprintf(stderr, "Error: %s\n", err.message);
3965 dbus_bus_add_match(connection,
3966 "type='signal',interface='net.connman.vpn.Manager'",
3969 if (dbus_error_is_set(&err))
3970 fprintf(stderr, "Error: %s\n", err.message);