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"
45 #include "vpnconnections.h"
46 #if defined TIZEN_EXT_WIFI_MESH
50 static DBusConnection *connection;
51 static GHashTable *service_hash;
52 static GHashTable *vpnconnection_hash;
53 static GHashTable *peer_hash;
54 static GHashTable *technology_hash;
55 static char *session_notify_path;
56 static char *session_path;
57 static bool session_connected;
59 struct connman_option {
65 static char *ipv4[] = {
73 static char *ipv6[] = {
81 static int cmd_help(char *args[], int num, struct connman_option *options);
83 static bool check_dbus_name(const char *name)
86 * Valid dbus chars should be [A-Z][a-z][0-9]_
87 * and should not start with number.
91 if (!name || name[0] == '\0')
94 for (i = 0; name[i] != '\0'; i++)
95 if (!((name[i] >= 'A' && name[i] <= 'Z') ||
96 (name[i] >= 'a' && name[i] <= 'z') ||
97 (name[i] >= '0' && name[i] <= '9') ||
104 static int parse_boolean(char *arg)
109 if (strcasecmp(arg, "no") == 0 ||
110 strcasecmp(arg, "false") == 0 ||
111 strcasecmp(arg, "off" ) == 0 ||
112 strcasecmp(arg, "disable" ) == 0 ||
113 strcasecmp(arg, "n") == 0 ||
114 strcasecmp(arg, "f") == 0 ||
115 strcasecmp(arg, "0") == 0)
118 if (strcasecmp(arg, "yes") == 0 ||
119 strcasecmp(arg, "true") == 0 ||
120 strcasecmp(arg, "on") == 0 ||
121 strcasecmp(arg, "enable" ) == 0 ||
122 strcasecmp(arg, "y") == 0 ||
123 strcasecmp(arg, "t") == 0 ||
124 strcasecmp(arg, "1") == 0)
130 static int parse_args(char *arg, struct connman_option *options)
137 for (i = 0; options[i].name; i++) {
138 if (strcmp(options[i].name, arg) == 0 ||
139 (strncmp(arg, "--", 2) == 0 &&
140 strcmp(&arg[2], options[i].name) == 0))
141 return options[i].val;
147 static int enable_return(DBusMessageIter *iter, const char *error,
150 char *tech = user_data;
153 str = strrchr(tech, '/');
160 fprintf(stdout, "Enabled %s\n", str);
162 fprintf(stderr, "Error %s: %s\n", str, error);
169 static int cmd_enable(char *args[], int num, struct connman_option *options)
172 dbus_bool_t b = TRUE;
180 if (check_dbus_name(args[1]) == false)
183 if (strcmp(args[1], "offline") == 0) {
184 tech = g_strdup(args[1]);
185 return __connmanctl_dbus_set_property(connection, "/",
186 "net.connman.Manager", enable_return, tech,
187 "OfflineMode", DBUS_TYPE_BOOLEAN, &b);
190 tech = g_strdup_printf("/net/connman/technology/%s", args[1]);
191 return __connmanctl_dbus_set_property(connection, tech,
192 "net.connman.Technology", enable_return, tech,
193 "Powered", DBUS_TYPE_BOOLEAN, &b);
196 static int disable_return(DBusMessageIter *iter, const char *error,
199 char *tech = user_data;
202 str = strrchr(tech, '/');
209 fprintf(stdout, "Disabled %s\n", str);
211 fprintf(stderr, "Error %s: %s\n", str, error);
218 static int cmd_disable(char *args[], int num, struct connman_option *options)
221 dbus_bool_t b = FALSE;
229 if (check_dbus_name(args[1]) == false)
232 if (strcmp(args[1], "offline") == 0) {
233 tech = g_strdup(args[1]);
234 return __connmanctl_dbus_set_property(connection, "/",
235 "net.connman.Manager", disable_return, tech,
236 "OfflineMode", DBUS_TYPE_BOOLEAN, &b);
239 tech = g_strdup_printf("/net/connman/technology/%s", args[1]);
240 return __connmanctl_dbus_set_property(connection, tech,
241 "net.connman.Technology", disable_return, tech,
242 "Powered", DBUS_TYPE_BOOLEAN, &b);
245 static int state_print(DBusMessageIter *iter, const char *error,
248 DBusMessageIter entry;
251 fprintf(stderr, "Error: %s", error);
255 dbus_message_iter_recurse(iter, &entry);
256 __connmanctl_dbus_print(&entry, " ", " = ", "\n");
257 fprintf(stdout, "\n");
262 static int cmd_state(char *args[], int num, struct connman_option *options)
267 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
268 CONNMAN_PATH, "net.connman.Manager", "GetProperties",
269 state_print, NULL, NULL, NULL);
272 static int clock_print(DBusMessageIter *iter, const char *error,
275 DBusMessageIter entry;
278 fprintf(stderr, "Error: %s", error);
282 dbus_message_iter_recurse(iter, &entry);
283 __connmanctl_dbus_print(&entry, " ", " = ", "\n");
284 fprintf(stdout, "\n");
289 static int cmd_clock(char *args[], int num, struct connman_option *options)
294 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
295 CONNMAN_PATH, "net.connman.Clock", "GetProperties",
296 clock_print, NULL, NULL, NULL);
299 static int services_list(DBusMessageIter *iter, const char *error,
303 __connmanctl_services_list(iter);
304 fprintf(stdout, "\n");
306 fprintf(stderr, "Error: %s\n", error);
312 static int peers_list(DBusMessageIter *iter,
313 const char *error, void *user_data)
316 __connmanctl_peers_list(iter);
317 fprintf(stdout, "\n");
319 fprintf(stderr, "Error: %s\n", error);
324 static int object_properties(DBusMessageIter *iter,
325 const char *error, void *user_data)
327 char *path = user_data;
329 DBusMessageIter dict;
332 fprintf(stdout, "%s\n", path);
334 dbus_message_iter_recurse(iter, &dict);
335 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
337 fprintf(stdout, "\n");
340 str = strrchr(path, '/');
346 fprintf(stderr, "Error %s: %s\n", str, error);
354 static int cmd_services(char *args[], int num, struct connman_option *options)
356 char *service_name = NULL;
363 c = parse_args(args[1], options);
370 service_name = args[2];
375 service_name = args[1];
380 return __connmanctl_dbus_method_call(connection,
381 CONNMAN_SERVICE, CONNMAN_PATH,
382 "net.connman.Manager", "GetServices",
383 services_list, NULL, NULL, NULL);
386 if (check_dbus_name(service_name) == false)
389 path = g_strdup_printf("/net/connman/service/%s", service_name);
390 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
391 "net.connman.Service", "GetProperties",
392 object_properties, path, NULL, NULL);
395 static int cmd_peers(char *args[], int num, struct connman_option *options)
397 char *peer_name = NULL;
407 return __connmanctl_dbus_method_call(connection,
408 CONNMAN_SERVICE, CONNMAN_PATH,
409 "net.connman.Manager", "GetPeers",
410 peers_list, NULL, NULL, NULL);
413 if (check_dbus_name(peer_name) == false)
416 path = g_strdup_printf("/net/connman/peer/%s", peer_name);
417 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
418 path, "net.connman.Peer", "GetProperties",
419 object_properties, path, NULL, NULL);
422 static int technology_print(DBusMessageIter *iter, const char *error,
425 DBusMessageIter array;
428 fprintf(stderr, "Error: %s\n", error);
432 dbus_message_iter_recurse(iter, &array);
433 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
434 DBusMessageIter entry, dict;
437 dbus_message_iter_recurse(&array, &entry);
438 dbus_message_iter_get_basic(&entry, &path);
439 fprintf(stdout, "%s\n", path);
441 dbus_message_iter_next(&entry);
443 dbus_message_iter_recurse(&entry, &dict);
444 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
445 fprintf(stdout, "\n");
447 dbus_message_iter_next(&array);
453 static int cmd_technologies(char *args[], int num,
454 struct connman_option *options)
459 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
460 CONNMAN_PATH, "net.connman.Manager", "GetTechnologies",
461 technology_print, NULL, NULL, NULL);
464 struct tether_enable {
469 static int tether_set_return(DBusMessageIter *iter, const char *error,
472 struct tether_enable *tether = user_data;
475 str = strrchr(tether->path, '/');
482 fprintf(stdout, "%s tethering for %s\n",
483 tether->enable ? "Enabled" : "Disabled",
486 fprintf(stderr, "Error %s %s tethering: %s\n",
488 "enabling" : "disabling", str, error);
490 g_free(tether->path);
496 static int tether_set(char *technology, int set_tethering)
498 struct tether_enable *tether = g_new(struct tether_enable, 1);
500 switch(set_tethering) {
502 tether->enable = TRUE;
505 tether->enable = FALSE;
512 tether->path = g_strdup_printf("/net/connman/technology/%s",
515 return __connmanctl_dbus_set_property(connection, tether->path,
516 "net.connman.Technology", tether_set_return,
517 tether, "Tethering", DBUS_TYPE_BOOLEAN,
521 struct tether_properties {
523 int passphrase_result;
527 static int tether_update(struct tether_properties *tether)
531 if (tether->ssid_result == 0 && tether->passphrase_result == 0) {
532 ret = tether_set("wifi", tether->set_tethering);
537 if (tether->ssid_result != -EINPROGRESS &&
538 tether->passphrase_result != -EINPROGRESS) {
546 static int tether_set_ssid_return(DBusMessageIter *iter, const char *error,
549 struct tether_properties *tether = user_data;
552 fprintf(stdout, "Wifi SSID set\n");
553 tether->ssid_result = 0;
555 fprintf(stderr, "Error setting wifi SSID: %s\n", error);
556 tether->ssid_result = -EINVAL;
559 return tether_update(tether);
562 static int tether_set_passphrase_return(DBusMessageIter *iter,
563 const char *error, void *user_data)
565 struct tether_properties *tether = user_data;
568 fprintf(stdout, "Wifi passphrase set\n");
569 tether->passphrase_result = 0;
571 fprintf(stderr, "Error setting wifi passphrase: %s\n", error);
572 tether->passphrase_result = -EINVAL;
575 return tether_update(tether);
578 static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering)
580 struct tether_properties *tether = g_new(struct tether_properties, 1);
582 tether->set_tethering = set_tethering;
584 tether->ssid_result = __connmanctl_dbus_set_property(connection,
585 "/net/connman/technology/wifi",
586 "net.connman.Technology",
587 tether_set_ssid_return, tether,
588 "TetheringIdentifier", DBUS_TYPE_STRING, &ssid);
590 tether->passphrase_result =__connmanctl_dbus_set_property(connection,
591 "/net/connman/technology/wifi",
592 "net.connman.Technology",
593 tether_set_passphrase_return, tether,
594 "TetheringPassphrase", DBUS_TYPE_STRING, &passphrase);
596 if (tether->ssid_result != -EINPROGRESS &&
597 tether->passphrase_result != -EINPROGRESS) {
605 #if defined TIZEN_EXT_WIFI_MESH
606 struct mesh_if_prop {
612 struct mesh_create_network {
618 struct mesh_specific_scan_params {
623 struct mesh_gate_params {
629 static int mesh_return(DBusMessageIter *iter, const char *error,
632 char *method = user_data;
635 fprintf(stderr, "Error %s: %s\n", method, error);
637 fprintf(stderr, "Success %s\n", method);
644 static void mesh_interface_add_append(DBusMessageIter *iter, void *user_data)
646 struct mesh_if_prop *append = user_data;
648 /* Append Virtual Interface Name */
649 __connmanctl_dbus_append_dict_entry(iter, "Ifname",
650 DBUS_TYPE_STRING, &append->ifname);
652 /* Append Parent WiFi Interface Name */
653 __connmanctl_dbus_append_dict_entry(iter, "ParentIfname",
654 DBUS_TYPE_STRING, &append->parent_ifname);
656 /* Append Bridge Interface Name */
657 if (append->bridge_ifname)
658 __connmanctl_dbus_append_dict_entry(iter, "BridgeIfname",
659 DBUS_TYPE_STRING, &append->bridge_ifname);
662 static void mesh_interface_remove_append(DBusMessageIter *iter, void *user_data)
664 struct mesh_if_prop *append = user_data;
666 /* Append Virtual Interface Name */
667 __connmanctl_dbus_append_dict_entry(iter, "Ifname",
668 DBUS_TYPE_STRING, &append->ifname);
671 static void mesh_create_network_append(DBusMessageIter *iter, void *user_data)
673 struct mesh_create_network *append = user_data;
675 /* Append Mesh Network Name */
676 __connmanctl_dbus_append_dict_entry(iter, "Name",
677 DBUS_TYPE_STRING, &append->name);
679 /* Append Mesh Network Frequency */
680 __connmanctl_dbus_append_dict_entry(iter, "Frequency",
681 DBUS_TYPE_UINT16, &append->freq);
683 /* Append Mesh Network Security Type */
684 __connmanctl_dbus_append_dict_entry(iter, "Security",
685 DBUS_TYPE_STRING, &append->sec_type);
688 static void mesh_specific_scan_append(DBusMessageIter *iter, void *user_data)
690 struct mesh_specific_scan_params *append = user_data;
692 /* Append Mesh Network Name */
693 __connmanctl_dbus_append_dict_entry(iter, "Name",
694 DBUS_TYPE_STRING, &append->name);
696 /* Append Mesh Network Frequency */
697 __connmanctl_dbus_append_dict_entry(iter, "Frequency",
698 DBUS_TYPE_UINT16, &append->freq);
701 static void mesh_set_gate_append(DBusMessageIter *iter, void *user_data)
703 struct mesh_gate_params *append = user_data;
705 /* Append Gate Announce Protocol */
706 __connmanctl_dbus_append_dict_entry(iter, "GateAnnounce",
707 DBUS_TYPE_BOOLEAN, &append->gate_announce);
709 /* Append HWMP Root Mode */
710 __connmanctl_dbus_append_dict_entry(iter, "HWMPRootMode",
711 DBUS_TYPE_UINT16, &append->hwmp_rootmode);
714 __connmanctl_dbus_append_dict_entry(iter, "STP", DBUS_TYPE_UINT16,
718 static void mesh_peer_append(DBusMessageIter *iter, void *user_data)
720 char *peer_addr = user_data;
722 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &peer_addr);
727 static int mesh_peers_list(DBusMessageIter *iter,
728 const char *error, void *user_data)
731 __connmanctl_mesh_peers_list(iter);
732 fprintf(stdout, "\n");
734 fprintf(stderr, "Error: %s\n", error);
739 static int connected_mesh_peers_list(DBusMessageIter *iter,
740 const char *error, void *user_data)
743 __connmanctl_mesh_connected_peers_list(iter);
744 fprintf(stdout, "\n");
746 fprintf(stderr, "Error: %s\n", error);
751 static int disconnected_mesh_peers_list(DBusMessageIter *iter,
752 const char *error, void *user_data)
755 __connmanctl_mesh_disconnected_peers_list(iter);
756 fprintf(stdout, "\n");
758 fprintf(stderr, "Error: %s\n", error);
763 static int mesh_connect_return(DBusMessageIter *iter, const char *error,
766 char *path = user_data;
769 char *str = strrchr(path, '/');
771 fprintf(stdout, "Connected %s\n", str);
773 fprintf(stderr, "Error %s: %s\n", path, error);
780 static int mesh_disconnect_return(DBusMessageIter *iter, const char *error,
783 char *path = user_data;
786 char *str = strrchr(path, '/');
788 fprintf(stdout, "Disconnected %s\n", str);
790 fprintf(stderr, "Error %s: %s\n", path, error);
797 static int mesh_remove_return(DBusMessageIter *iter, const char *error,
800 char *path = user_data;
803 char *str = strrchr(path, '/');
805 fprintf(stdout, "Removed %s\n", str);
807 fprintf(stderr, "Error %s: %s\n", path, error);
814 static int mesh_config_return(DBusMessageIter *iter, const char *error,
817 char *path = user_data;
818 char *str = strrchr(path, '/');
822 fprintf(stderr, "Error %s: %s\n", path, error);
824 fprintf(stdout, "Success SetProperty %s\n", str);
831 static int cmd_mesh(char *args[], int num, struct connman_option *options)
837 char *mesh_peer_name = NULL;
838 char *mesh_peer_path = NULL;
839 char *property = NULL;
841 struct mesh_if_prop *append;
842 struct mesh_create_network *network;
843 struct mesh_specific_scan_params *scan_params;
844 struct mesh_gate_params *gate_params;
845 char *mesh_peer_addr = NULL;
847 c = parse_args(args[1], options);
851 if (num < 4 || num > 5) {
855 path = g_strdup_printf("/net/connman/technology/mesh");
857 append = dbus_malloc0(sizeof(struct mesh_if_prop));
858 append->ifname = g_strdup(args[2]);
859 append->parent_ifname = g_strdup(args[3]);
861 append->bridge_ifname = g_strdup(args[4]);
862 method = g_strdup("MeshInterfaceAdd");
863 result = __connmanctl_dbus_mesh_dict(connection, path,
864 "net.connman.Technology", mesh_return, method,
865 "MeshInterfaceAdd", DBUS_TYPE_STRING,
866 mesh_interface_add_append, append);
867 g_free(append->ifname);
868 g_free(append->parent_ifname);
869 g_free(append->bridge_ifname);
878 path = g_strdup_printf("/net/connman/technology/mesh");
880 append = dbus_malloc0(sizeof(struct mesh_if_prop));
881 append->ifname = g_strdup(args[2]);
882 method = g_strdup("MeshInterfaceRemove");
883 result = __connmanctl_dbus_mesh_dict(connection, path,
884 "net.connman.Technology", mesh_return, method,
885 "MeshInterfaceRemove", DBUS_TYPE_STRING,
886 mesh_interface_remove_append, append);
887 g_free(append->ifname);
898 mesh_peer_name = args[2];
900 if (!mesh_peer_name) {
901 result = __connmanctl_dbus_method_call(connection,
902 CONNMAN_SERVICE, CONNMAN_PATH,
903 "net.connman.Manager", "GetMeshPeers",
904 mesh_peers_list, NULL, NULL, NULL);
908 if (check_dbus_name(mesh_peer_name) == false) {
913 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
915 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
916 mesh_peer_path, "net.connman.Mesh", "GetProperties",
917 object_properties, mesh_peer_path, NULL, NULL);
931 mesh_peer_name = args[2];
933 if (check_dbus_name(mesh_peer_name) == false) {
938 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
940 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
941 mesh_peer_path, "net.connman.Mesh", "Connect",
942 mesh_connect_return, mesh_peer_path, NULL, NULL);
956 mesh_peer_name = args[2];
958 if (check_dbus_name(mesh_peer_name) == false) {
963 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
965 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
966 mesh_peer_path, "net.connman.Mesh", "Disconnect",
967 mesh_disconnect_return, mesh_peer_path, NULL, NULL);
981 mesh_peer_name = args[2];
983 if (check_dbus_name(mesh_peer_name) == false) {
988 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
990 result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
991 mesh_peer_path, "net.connman.Mesh", "Remove",
992 mesh_remove_return, mesh_peer_path, NULL, NULL);
1001 result = __connmanctl_dbus_method_call(connection,
1002 CONNMAN_SERVICE, CONNMAN_PATH,
1003 "net.connman.Manager", "GetConnectedMeshPeers",
1004 connected_mesh_peers_list, NULL, NULL, NULL);
1013 result = __connmanctl_dbus_method_call(connection,
1014 CONNMAN_SERVICE, CONNMAN_PATH,
1015 "net.connman.Manager",
1016 "GetDisconnectedMeshPeers",
1017 disconnected_mesh_peers_list, NULL, NULL, NULL);
1025 path = g_strdup_printf("/net/connman/technology/mesh");
1027 network = dbus_malloc0(sizeof(struct mesh_create_network));
1028 network->name = g_strdup(args[2]);
1029 network->freq = atoi(args[3]);
1030 network->sec_type = g_strdup(args[4]);
1031 method = g_strdup("MeshCreateNetwork");
1032 result = __connmanctl_dbus_mesh_dict(connection, path,
1033 "net.connman.Technology", mesh_return, method,
1034 "MeshCreateNetwork", DBUS_TYPE_STRING,
1035 mesh_create_network_append, network);
1036 g_free(network->name);
1037 g_free(network->sec_type);
1046 path = g_strdup_printf("/net/connman/technology/mesh");
1048 method = g_strdup("AbortScan");
1049 result = __connmanctl_dbus_mesh_dict(connection, path,
1050 "net.connman.Technology", mesh_return, method,
1051 "AbortScan", DBUS_TYPE_STRING,
1060 path = g_strdup_printf("/net/connman/technology/mesh");
1062 scan_params = dbus_malloc0(sizeof(struct mesh_specific_scan_params));
1063 scan_params->name = g_strdup(args[2]);
1064 scan_params->freq = atoi(args[3]);
1065 method = g_strdup("MeshSpecificScan");
1066 result = __connmanctl_dbus_mesh_dict(connection, path,
1067 "net.connman.Technology", mesh_return, method,
1068 "MeshSpecificScan", DBUS_TYPE_STRING,
1069 mesh_specific_scan_append, scan_params);
1070 g_free(scan_params->name);
1071 g_free(scan_params);
1080 mesh_peer_name = args[2];
1084 if (check_dbus_name(mesh_peer_name) == false) {
1089 mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
1092 if (g_strcmp0(property, "Passphrase") == 0) {
1093 result = __connmanctl_dbus_set_property(connection,
1094 mesh_peer_path, "net.connman.Mesh",
1095 mesh_config_return, mesh_peer_path, property,
1096 DBUS_TYPE_STRING, &value);
1098 printf("Invalid property %s\n", property);
1110 path = g_strdup_printf("/net/connman/technology/mesh");
1112 gate_params = dbus_malloc0(sizeof(struct mesh_gate_params));
1113 gate_params->gate_announce = atoi(args[2]);
1114 gate_params->hwmp_rootmode = atoi(args[3]);
1115 gate_params->stp = atoi(args[4]);
1117 method = g_strdup("SetMeshGate");
1119 result = __connmanctl_dbus_mesh_dict(connection, path,
1120 "net.connman.Technology", mesh_return, method,
1121 "SetMeshGate", DBUS_TYPE_STRING,
1122 mesh_set_gate_append, gate_params);
1132 mesh_peer_addr = g_strdup(args[2]);
1133 method = g_strdup("MeshAddPeer");
1135 result = __connmanctl_dbus_method_call(connection,
1136 CONNMAN_SERVICE, CONNMAN_PATH,
1137 "net.connman.Manager", "MeshAddPeer",
1138 mesh_return, method, mesh_peer_append,
1149 mesh_peer_addr = g_strdup(args[2]);
1150 method = g_strdup("MeshRemovePeer");
1152 result = __connmanctl_dbus_method_call(connection,
1153 CONNMAN_SERVICE, CONNMAN_PATH,
1154 "net.connman.Manager", "MeshRemovePeer",
1155 mesh_return, method, mesh_peer_append,
1168 if (result != -EINPROGRESS)
1169 printf("Error '%s': %s\n", args[1], strerror(-result));
1177 static int cmd_tether(char *args[], int num, struct connman_option *options)
1179 char *ssid, *passphrase;
1185 passphrase = args[num - 1];
1186 ssid = args[num - 2];
1188 set_tethering = parse_boolean(args[2]);
1190 if (strcmp(args[1], "wifi") == 0) {
1195 if (num == 5 && set_tethering == -1)
1202 return tether_set_ssid(ssid, passphrase, set_tethering);
1208 if (set_tethering == -1)
1211 if (check_dbus_name(args[1]) == false)
1214 return tether_set(args[1], set_tethering);
1217 static int scan_return(DBusMessageIter *iter, const char *error,
1220 char *path = user_data;
1223 char *str = strrchr(path, '/');
1225 fprintf(stdout, "Scan completed for %s\n", str);
1227 fprintf(stderr, "Error %s: %s\n", path, error);
1234 static int cmd_scan(char *args[], int num, struct connman_option *options)
1244 if (check_dbus_name(args[1]) == false)
1247 path = g_strdup_printf("/net/connman/technology/%s", args[1]);
1248 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
1249 "net.connman.Technology", "Scan",
1250 scan_return, path, NULL, NULL);
1253 static int connect_return(DBusMessageIter *iter, const char *error,
1256 char *path = user_data;
1259 char *str = strrchr(path, '/');
1261 fprintf(stdout, "Connected %s\n", str);
1263 fprintf(stderr, "Error %s: %s\n", path, error);
1270 static int cmd_connect(char *args[], int num, struct connman_option *options)
1272 const char *iface = "net.connman.Service";
1281 if (check_dbus_name(args[1]) == false)
1284 if (g_strstr_len(args[1], 5, "peer_") == args[1]) {
1285 iface = "net.connman.Peer";
1286 path = g_strdup_printf("/net/connman/peer/%s", args[1]);
1288 path = g_strdup_printf("/net/connman/service/%s", args[1]);
1290 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE, path,
1291 iface, "Connect", connect_return, path, NULL, NULL);
1294 static int disconnect_return(DBusMessageIter *iter, const char *error,
1297 char *path = user_data;
1300 char *str = strrchr(path, '/');
1302 fprintf(stdout, "Disconnected %s\n", str);
1304 fprintf(stderr, "Error %s: %s\n", path, error);
1311 static int cmd_disconnect(char *args[], int num, struct connman_option *options)
1313 const char *iface = "net.connman.Service";
1322 if (check_dbus_name(args[1]) == false)
1325 if (g_strstr_len(args[1], 5, "peer_") == args[1]) {
1326 iface = "net.connman.Peer";
1327 path = g_strdup_printf("/net/connman/peer/%s", args[1]);
1329 path = g_strdup_printf("/net/connman/service/%s", args[1]);
1331 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
1332 path, iface, "Disconnect",
1333 disconnect_return, path, NULL, NULL);
1336 struct move_service {
1341 static int move_before_return(DBusMessageIter *iter, const char *error,
1344 struct move_service *services = user_data;
1349 service = strrchr(services->service, '/');
1351 target = strrchr(services->target, '/');
1353 fprintf(stdout, "Moved %s before %s\n", service, target);
1355 fprintf(stderr, "Error %s: %s\n", services->service, error);
1357 g_free(services->service);
1358 g_free(services->target);
1364 static void move_before_append_args(DBusMessageIter *iter, void *user_data)
1366 char *path = user_data;
1368 dbus_message_iter_append_basic(iter,
1369 DBUS_TYPE_OBJECT_PATH, &path);
1374 static int cmd_service_move_before(char *args[], int num,
1375 struct connman_option *options)
1377 const char *iface = "net.connman.Service";
1378 struct move_service *services;
1386 if (check_dbus_name(args[1]) == false)
1389 services = g_new(struct move_service, 1);
1391 services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
1392 services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
1394 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
1395 services->service, iface, "MoveBefore",
1396 move_before_return, services,
1397 move_before_append_args,
1401 static int move_after_return(DBusMessageIter *iter, const char *error,
1404 struct move_service *services = user_data;
1409 service = strrchr(services->service, '/');
1411 target = strrchr(services->target, '/');
1413 fprintf(stdout, "Moved %s after %s\n", service, target);
1415 fprintf(stderr, "Error %s: %s\n", services->service, error);
1417 g_free(services->service);
1418 g_free(services->target);
1424 static void move_after_append_args(DBusMessageIter *iter, void *user_data)
1426 char *path = user_data;
1428 dbus_message_iter_append_basic(iter,
1429 DBUS_TYPE_OBJECT_PATH, &path);
1434 static int cmd_service_move_after(char *args[], int num,
1435 struct connman_option *options)
1437 const char *iface = "net.connman.Service";
1438 struct move_service *services;
1446 if (check_dbus_name(args[1]) == false)
1449 services = g_new(struct move_service, 1);
1451 services->service = g_strdup_printf("/net/connman/service/%s", args[1]);
1452 services->target = g_strdup_printf("/net/connman/service/%s", args[2]);
1454 return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
1455 services->service, iface, "MoveAfter",
1456 move_after_return, services,
1457 move_after_append_args,
1461 static int config_return(DBusMessageIter *iter, const char *error,
1464 char *service_name = user_data;
1467 fprintf(stderr, "Error %s: %s\n", service_name, error);
1474 struct config_append {
1479 static void config_append_ipv4(DBusMessageIter *iter,
1482 struct config_append *append = user_data;
1483 char **opts = append->opts;
1489 while (opts[i] && ipv4[i]) {
1490 __connmanctl_dbus_append_dict_entry(iter, ipv4[i],
1491 DBUS_TYPE_STRING, &opts[i]);
1498 static void config_append_ipv6(DBusMessageIter *iter, void *user_data)
1500 struct config_append *append = user_data;
1501 char **opts = append->opts;
1508 if (g_strcmp0(opts[0], "auto") == 0) {
1511 switch (parse_boolean(opts[1])) {
1516 __connmanctl_dbus_append_dict_entry(iter, "Privacy",
1517 DBUS_TYPE_STRING, &str);
1524 __connmanctl_dbus_append_dict_entry(iter, "Privacy",
1525 DBUS_TYPE_STRING, &str);
1532 if (g_strcmp0(opts[1], "prefered") != 0 &&
1534 "preferred") != 0) {
1535 fprintf(stderr, "Error %s: %s\n",
1542 __connmanctl_dbus_append_dict_entry(iter,
1543 "Privacy", DBUS_TYPE_STRING,
1548 } else if (g_strcmp0(opts[0], "manual") == 0) {
1551 while (opts[i] && ipv6[i]) {
1553 int value = atoi(opts[i]);
1554 __connmanctl_dbus_append_dict_entry(iter,
1555 ipv6[i], DBUS_TYPE_BYTE,
1558 __connmanctl_dbus_append_dict_entry(iter,
1559 ipv6[i], DBUS_TYPE_STRING,
1567 } else if (g_strcmp0(opts[0], "off") != 0) {
1568 fprintf(stderr, "Error %s: %s\n", opts[0], strerror(EINVAL));
1573 __connmanctl_dbus_append_dict_entry(iter, "Method", DBUS_TYPE_STRING,
1577 static void config_append_str(DBusMessageIter *iter, void *user_data)
1579 struct config_append *append = user_data;
1580 char **opts = append->opts;
1587 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1595 static void append_servers(DBusMessageIter *iter, void *user_data)
1597 struct config_append *append = user_data;
1598 char **opts = append->opts;
1604 while (opts[i] && g_strcmp0(opts[i], "--excludes") != 0) {
1605 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1613 static void append_excludes(DBusMessageIter *iter, void *user_data)
1615 struct config_append *append = user_data;
1616 char **opts = append->opts;
1617 int i = append->values;
1619 if (!opts || !opts[i] ||
1620 g_strcmp0(opts[i], "--excludes") != 0)
1625 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1633 static void config_append_proxy(DBusMessageIter *iter, void *user_data)
1635 struct config_append *append = user_data;
1636 char **opts = append->opts;
1641 if (g_strcmp0(opts[0], "manual") == 0) {
1642 __connmanctl_dbus_append_dict_string_array(iter, "Servers",
1643 append_servers, append);
1645 __connmanctl_dbus_append_dict_string_array(iter, "Excludes",
1646 append_excludes, append);
1648 } else if (g_strcmp0(opts[0], "auto") == 0) {
1650 __connmanctl_dbus_append_dict_entry(iter, "URL",
1651 DBUS_TYPE_STRING, &opts[1]);
1655 } else if (g_strcmp0(opts[0], "direct") != 0)
1658 __connmanctl_dbus_append_dict_entry(iter, "Method",DBUS_TYPE_STRING,
1664 static int cmd_config(char *args[], int num, struct connman_option *options)
1666 int result = 0, res = 0, index = 2, oldindex = 0;
1668 char *service_name, *path;
1671 struct config_append append;
1673 service_name = args[1];
1677 if (check_dbus_name(service_name) == false)
1680 while (index < num && args[index]) {
1681 c = parse_args(args[index], options);
1682 opt_start = &args[index + 1];
1683 append.opts = opt_start;
1689 path = g_strdup_printf("/net/connman/service/%s", service_name);
1693 switch (parse_boolean(*opt_start)) {
1708 res = __connmanctl_dbus_set_property(connection,
1709 path, "net.connman.Service",
1711 g_strdup(service_name),
1713 DBUS_TYPE_BOOLEAN, &val);
1717 res = __connmanctl_dbus_set_property_dict(connection,
1718 path, "net.connman.Service",
1719 config_return, g_strdup(service_name),
1720 "IPv4.Configuration", DBUS_TYPE_STRING,
1721 config_append_ipv4, &append);
1722 index += append.values;
1726 res = __connmanctl_dbus_set_property_dict(connection,
1727 path, "net.connman.Service",
1728 config_return, g_strdup(service_name),
1729 "IPv6.Configuration", DBUS_TYPE_STRING,
1730 config_append_ipv6, &append);
1731 index += append.values;
1735 res = __connmanctl_dbus_set_property_array(connection,
1736 path, "net.connman.Service",
1737 config_return, g_strdup(service_name),
1738 "Nameservers.Configuration",
1739 DBUS_TYPE_STRING, config_append_str,
1741 index += append.values;
1745 res = __connmanctl_dbus_set_property_array(connection,
1746 path, "net.connman.Service",
1747 config_return, g_strdup(service_name),
1748 "Timeservers.Configuration",
1749 DBUS_TYPE_STRING, config_append_str,
1751 index += append.values;
1755 res = __connmanctl_dbus_set_property_array(connection,
1756 path, "net.connman.Service",
1757 config_return, g_strdup(service_name),
1758 "Domains.Configuration",
1759 DBUS_TYPE_STRING, config_append_str,
1761 index += append.values;
1765 res = __connmanctl_dbus_set_property_dict(connection,
1766 path, "net.connman.Service",
1767 config_return, g_strdup(service_name),
1768 "Proxy.Configuration",
1769 DBUS_TYPE_STRING, config_append_proxy,
1771 index += append.values;
1774 res = __connmanctl_dbus_method_call(connection,
1775 CONNMAN_SERVICE, path,
1776 "net.connman.Service", "Remove",
1777 config_return, g_strdup(service_name),
1788 if (res == -EINPROGRESS)
1789 result = -EINPROGRESS;
1791 printf("Error '%s': %s\n", args[oldindex],
1802 static DBusHandlerResult monitor_changed(DBusConnection *connection,
1803 DBusMessage *message, void *user_data)
1805 DBusMessageIter iter;
1806 const char *interface, *path;
1808 interface = dbus_message_get_interface(message);
1810 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1812 if (strncmp(interface, "net.connman.", 12) != 0)
1813 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1815 if (!strcmp(interface, "net.connman.Agent") ||
1816 !strcmp(interface, "net.connman.vpn.Agent") ||
1817 !strcmp(interface, "net.connman.Session") ||
1818 !strcmp(interface, "net.connman.Notification"))
1819 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1821 interface = strrchr(interface, '.');
1822 if (interface && *interface != '\0')
1825 path = strrchr(dbus_message_get_path(message), '/');
1826 if (path && *path != '\0')
1829 __connmanctl_save_rl();
1831 if (dbus_message_is_signal(message, "net.connman.Manager",
1832 "ServicesChanged")) {
1834 fprintf(stdout, "%-12s %-20s = {\n", interface,
1836 dbus_message_iter_init(message, &iter);
1837 __connmanctl_services_list(&iter);
1838 fprintf(stdout, "\n}\n");
1840 __connmanctl_redraw_rl();
1842 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1843 } else if (dbus_message_is_signal(message, "net.connman.Manager",
1845 fprintf(stdout, "%-12s %-20s = {\n", interface,
1847 dbus_message_iter_init(message, &iter);
1848 __connmanctl_peers_list(&iter);
1849 fprintf(stdout, "\n}\n");
1851 __connmanctl_redraw_rl();
1853 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1854 } else if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
1855 "ConnectionAdded") ||
1856 dbus_message_is_signal(message,
1857 "net.connman.vpn.Manager",
1858 "ConnectionRemoved")) {
1859 interface = "vpn.Manager";
1860 path = dbus_message_get_member(message);
1862 } else if (dbus_message_is_signal(message, "net.connman.Manager",
1863 "TechnologyAdded") ||
1864 dbus_message_is_signal(message, "net.connman.Manager",
1865 "TechnologyRemoved"))
1866 path = dbus_message_get_member(message);
1868 fprintf(stdout, "%-12s %-20s ", interface, path);
1869 dbus_message_iter_init(message, &iter);
1871 __connmanctl_dbus_print(&iter, "", " = ", " = ");
1872 fprintf(stdout, "\n");
1874 __connmanctl_redraw_rl();
1876 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1883 { "Service", false },
1884 { "Technology", false },
1885 { "Manager", false },
1886 { "vpn.Manager", false },
1887 { "vpn.Connection", false },
1891 static void monitor_add(char *interface)
1893 bool add_filter = true, found = false;
1898 for (i = 0; monitor[i].interface; i++) {
1899 if (monitor[i].enabled == true)
1902 if (g_strcmp0(interface, monitor[i].interface) == 0) {
1903 if (monitor[i].enabled == true)
1906 monitor[i].enabled = true;
1914 if (add_filter == true)
1915 dbus_connection_add_filter(connection, monitor_changed,
1918 dbus_error_init(&err);
1919 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
1921 dbus_bus_add_match(connection, rule, &err);
1924 if (dbus_error_is_set(&err))
1925 fprintf(stderr, "Error: %s\n", err.message);
1928 static void monitor_del(char *interface)
1930 bool del_filter = true, found = false;
1935 for (i = 0; monitor[i].interface; i++) {
1936 if (g_strcmp0(interface, monitor[i].interface) == 0) {
1937 if (monitor[i].enabled == false)
1940 monitor[i].enabled = false;
1944 if (monitor[i].enabled == true)
1951 rule = g_strdup_printf("type='signal',interface='net.connman.%s'",
1953 dbus_bus_remove_match(connection, rule, NULL);
1956 if (del_filter == true)
1957 dbus_connection_remove_filter(connection, monitor_changed,
1961 static int cmd_monitor(char *args[], int num, struct connman_option *options)
1970 switch (parse_boolean(args[2])) {
1980 c = parse_args(args[1], options);
1983 monitor_add("Service");
1984 monitor_add("Technology");
1985 monitor_add("Manager");
1986 monitor_add("vpn.Manager");
1987 monitor_add("vpn.Connection");
1992 monitor_add("Service");
1994 monitor_del("Service");
1999 monitor_add("Technology");
2001 monitor_del("Technology");
2006 monitor_add("Manager");
2008 monitor_del("Manager");
2013 monitor_add("vpn.Manager");
2015 monitor_del("vpn.Manager");
2020 monitor_add("vpn.Connection");
2022 monitor_del("vpn.Connection");
2026 switch(parse_boolean(args[1])) {
2028 monitor_del("Service");
2029 monitor_del("Technology");
2030 monitor_del("Manager");
2031 monitor_del("vpn.Manager");
2032 monitor_del("vpn.Connection");
2036 monitor_add("Service");
2037 monitor_add("Technology");
2038 monitor_add("Manager");
2039 monitor_add("vpn.Manager");
2040 monitor_add("vpn.Connection");
2049 return -EINPROGRESS;
2054 static int cmd_agent(char *args[], int num, struct connman_option *options)
2056 if (!__connmanctl_is_interactive()) {
2057 fprintf(stderr, "Error: Not supported in non-interactive "
2068 switch(parse_boolean(args[1])) {
2070 __connmanctl_agent_unregister(connection);
2074 if (__connmanctl_agent_register(connection) == -EINPROGRESS)
2075 return -EINPROGRESS;
2087 static int vpnconnections_properties(DBusMessageIter *iter, const char *error,
2090 char *path = user_data;
2092 DBusMessageIter dict;
2095 fprintf(stdout, "%s\n", path);
2097 dbus_message_iter_recurse(iter, &dict);
2098 __connmanctl_dbus_print(&dict, " ", " = ", "\n");
2100 fprintf(stdout, "\n");
2103 str = strrchr(path, '/');
2109 fprintf(stderr, "Error %s: %s\n", str, error);
2117 static int vpnconnections_list(DBusMessageIter *iter, const char *error,
2121 __connmanctl_vpnconnections_list(iter);
2123 fprintf(stderr, "Error: %s\n", error);
2128 static int cmd_vpnconnections(char *args[], int num,
2129 struct connman_option *options)
2131 char *vpnconnection_name, *path;
2136 vpnconnection_name = args[1];
2138 if (!vpnconnection_name)
2139 return __connmanctl_dbus_method_call(connection,
2140 VPN_SERVICE, VPN_PATH,
2141 "net.connman.vpn.Manager", "GetConnections",
2142 vpnconnections_list, NULL,
2145 if (check_dbus_name(vpnconnection_name) == false)
2148 path = g_strdup_printf("/net/connman/vpn/connection/%s",
2149 vpnconnection_name);
2150 return __connmanctl_dbus_method_call(connection, VPN_SERVICE, path,
2151 "net.connman.vpn.Connection", "GetProperties",
2152 vpnconnections_properties, path, NULL, NULL);
2156 static int cmd_vpnagent(char *args[], int num, struct connman_option *options)
2158 if (!__connmanctl_is_interactive()) {
2159 fprintf(stderr, "Error: Not supported in non-interactive "
2170 switch(parse_boolean(args[1])) {
2172 __connmanctl_vpn_agent_unregister(connection);
2176 if (__connmanctl_vpn_agent_register(connection) ==
2178 return -EINPROGRESS;
2190 static DBusMessage *session_release(DBusConnection *connection,
2191 DBusMessage *message, void *user_data)
2193 __connmanctl_save_rl();
2195 fprintf(stdout, "Session %s released\n", session_path);
2197 __connmanctl_redraw_rl();
2199 g_free(session_path);
2200 session_path = NULL;
2201 session_connected = false;
2203 return g_dbus_create_reply(message, DBUS_TYPE_INVALID);
2206 static DBusMessage *session_update(DBusConnection *connection,
2207 DBusMessage *message, void *user_data)
2209 DBusMessageIter iter, dict;
2211 __connmanctl_save_rl();
2213 fprintf(stdout, "Session Update = {\n");
2215 dbus_message_iter_init(message, &iter);
2216 dbus_message_iter_recurse(&iter, &dict);
2218 __connmanctl_dbus_print(&dict, "", " = ", "\n");
2219 fprintf(stdout, "\n}\n");
2221 dbus_message_iter_recurse(&iter, &dict);
2223 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
2224 DBusMessageIter entry, variant;
2225 char *field, *state;
2227 dbus_message_iter_recurse(&dict, &entry);
2229 dbus_message_iter_get_basic(&entry, &field);
2231 if (dbus_message_iter_get_arg_type(&entry)
2233 && !strcmp(field, "State")) {
2235 dbus_message_iter_next(&entry);
2236 dbus_message_iter_recurse(&entry, &variant);
2237 if (dbus_message_iter_get_arg_type(&variant)
2238 != DBUS_TYPE_STRING)
2241 dbus_message_iter_get_basic(&variant, &state);
2243 if (!session_connected && (!strcmp(state, "connected")
2244 || !strcmp(state, "online"))) {
2246 fprintf(stdout, "Session %s connected\n",
2248 session_connected = true;
2253 if (!strcmp(state, "disconnected") &&
2254 session_connected) {
2256 fprintf(stdout, "Session %s disconnected\n",
2258 session_connected = false;
2263 dbus_message_iter_next(&dict);
2266 __connmanctl_redraw_rl();
2268 return g_dbus_create_reply(message, DBUS_TYPE_INVALID);
2271 static const GDBusMethodTable notification_methods[] = {
2272 { GDBUS_METHOD("Release", NULL, NULL, session_release) },
2273 { GDBUS_METHOD("Update", GDBUS_ARGS({"settings", "a{sv}"}),
2274 NULL, session_update) },
2278 static int session_notify_add(const char *path)
2280 if (session_notify_path)
2283 if (!g_dbus_register_interface(connection, path,
2284 "net.connman.Notification",
2285 notification_methods, NULL, NULL,
2287 fprintf(stderr, "Error: Failed to register VPN Agent "
2292 session_notify_path = g_strdup(path);
2297 static void session_notify_remove(void)
2299 if (!session_notify_path)
2302 g_dbus_unregister_interface(connection, session_notify_path,
2303 "net.connman.Notification");
2305 g_free(session_notify_path);
2306 session_notify_path = NULL;
2309 static int session_connect_cb(DBusMessageIter *iter, const char *error,
2313 fprintf(stderr, "Error: %s", error);
2317 return -EINPROGRESS;
2321 static int session_connect(void)
2323 return __connmanctl_dbus_method_call(connection, "net.connman",
2324 session_path, "net.connman.Session", "Connect",
2325 session_connect_cb, NULL, NULL, NULL);
2328 static int session_disconnect_cb(DBusMessageIter *iter, const char *error,
2332 fprintf(stderr, "Error: %s", error);
2337 static int session_disconnect(void)
2339 return __connmanctl_dbus_method_call(connection, "net.connman",
2340 session_path, "net.connman.Session", "Disconnect",
2341 session_disconnect_cb, NULL, NULL, NULL);
2344 static int session_create_cb(DBusMessageIter *iter, const char *error,
2347 gboolean connect = GPOINTER_TO_INT(user_data);
2351 fprintf(stderr, "Error creating session: %s", error);
2352 session_notify_remove();
2356 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH) {
2357 fprintf(stderr, "Error creating session: No session path\n");
2361 g_free(session_path);
2363 dbus_message_iter_get_basic(iter, &str);
2364 session_path = g_strdup(str);
2366 fprintf(stdout, "Session %s created\n", session_path);
2369 return session_connect();
2371 return -EINPROGRESS;
2374 static void session_create_append(DBusMessageIter *iter, void *user_data)
2376 const char *notify_path = user_data;
2378 __connmanctl_dbus_append_dict(iter, NULL, NULL);
2380 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
2384 static int session_create(gboolean connect)
2389 notify_path = g_strdup_printf("/net/connman/connmanctl%d", getpid());
2390 session_notify_add(notify_path);
2392 res = __connmanctl_dbus_method_call(connection, "net.connman", "/",
2393 "net.connman.Manager", "CreateSession",
2394 session_create_cb, GINT_TO_POINTER(connect),
2395 session_create_append, notify_path);
2397 g_free(notify_path);
2399 if (res < 0 && res != -EINPROGRESS)
2400 session_notify_remove();
2405 static int session_destroy_cb(DBusMessageIter *iter, const char *error,
2409 fprintf(stderr, "Error destroying session: %s", error);
2413 fprintf(stdout, "Session %s ended\n", session_path);
2415 g_free(session_path);
2416 session_path = NULL;
2417 session_connected = false;
2422 static void session_destroy_append(DBusMessageIter *iter, void *user_data)
2424 const char *path = user_data;
2426 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
2429 static int session_destroy(void)
2431 return __connmanctl_dbus_method_call(connection, "net.connman", "/",
2432 "net.connman.Manager", "DestroySession",
2433 session_destroy_cb, NULL,
2434 session_destroy_append, session_path);
2437 static int session_config_return(DBusMessageIter *iter, const char *error,
2440 char *property_name = user_data;
2443 fprintf(stderr, "Error setting session %s: %s\n",
2444 property_name, error);
2449 static void session_config_append_array(DBusMessageIter *iter,
2452 struct config_append *append = user_data;
2453 char **opts = append->opts;
2459 while (opts[i] && strncmp(opts[i], "--", 2) != 0) {
2460 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
2468 static int session_config(char *args[], int num,
2469 struct connman_option *options)
2471 int index = 0, res = 0;
2472 struct config_append append;
2475 dbus_bool_t source_ip_rule;
2477 while (index < num && args[index]) {
2478 append.opts = &args[index];
2481 c = parse_args(args[index], options);
2485 res = __connmanctl_dbus_session_change_array(connection,
2486 session_path, session_config_return,
2487 "AllowedBearers", "AllowedBearers",
2488 session_config_append_array, &append);
2491 if (!args[index + 1]) {
2496 res = __connmanctl_dbus_session_change(connection,
2497 session_path, session_config_return,
2498 "ConnectionType", "ConnectionType",
2499 DBUS_TYPE_STRING, &args[index + 1]);
2503 if (index + 1 < num)
2504 ifname = args[index + 1];
2508 res = __connmanctl_dbus_session_change(connection,
2509 session_path, session_config_return,
2510 "AllowedInterface", "AllowedInterface",
2511 DBUS_TYPE_STRING, &ifname);
2515 if (!args[index + 1]) {
2519 switch (parse_boolean(args[index + 1])) {
2521 source_ip_rule = TRUE;
2524 source_ip_rule = FALSE;
2531 res = __connmanctl_dbus_session_change(connection,
2532 session_path, session_config_return,
2533 "SourceIPRule", "SourceIPRule",
2534 DBUS_TYPE_BOOLEAN, &source_ip_rule);
2542 if (res < 0 && res != -EINPROGRESS) {
2543 printf("Error '%s': %s\n", args[index],
2548 index += append.values;
2554 static int cmd_session(char *args[], int num, struct connman_option *options)
2563 switch(parse_boolean(command)) {
2567 return session_destroy();
2572 return session_create(FALSE);
2575 if (!strcmp(command, "connect")) {
2577 return session_create(TRUE);
2579 return session_connect();
2581 } else if (!strcmp(command, "disconnect")) {
2583 if (!session_path) {
2584 fprintf(stdout, "Session does not exist\n");
2588 return session_disconnect();
2589 } else if (!strcmp(command, "config")) {
2590 if (!session_path) {
2591 fprintf(stdout, "Session does not exist\n");
2598 return session_config(&args[2], num - 2, options);
2606 static int cmd_exit(char *args[], int num, struct connman_option *options)
2611 static char *lookup_key_from_table(GHashTable *hash, const char *text,
2615 static GHashTableIter iter;
2616 gpointer key, value;
2619 g_hash_table_iter_init(&iter, hash);
2623 while (g_hash_table_iter_next(&iter, &key, &value))
2624 if (strncmp(text, key, len) == 0)
2630 static char *lookup_service_arg(const char *text, int state)
2632 if (__connmanctl_input_calc_level() > 1) {
2633 __connmanctl_input_lookup_end();
2637 return lookup_key_from_table(service_hash, text, state);
2640 static char *lookup_peer(const char *text, int state)
2642 static GHashTableIter iter;
2643 gpointer key, value;
2647 g_hash_table_iter_init(&iter, peer_hash);
2651 while (g_hash_table_iter_next(&iter, &key, &value)) {
2652 const char *peer = key;
2653 if (strncmp(text, peer, len) == 0)
2654 return strdup(peer);
2660 static char *lookup_peer_arg(const char *text, int state)
2662 if (__connmanctl_input_calc_level() > 1) {
2663 __connmanctl_input_lookup_end();
2667 return lookup_peer(text, state);
2670 static char *lookup_technology(const char *text, int state)
2673 static GHashTableIter iter;
2674 gpointer key, value;
2677 g_hash_table_iter_init(&iter, technology_hash);
2681 while (g_hash_table_iter_next(&iter, &key, &value)) {
2682 const char *technology = key;
2683 if (strncmp(text, technology, len) == 0)
2684 return strdup(technology);
2690 static char *lookup_technology_arg(const char *text, int state)
2692 if (__connmanctl_input_calc_level() > 1) {
2693 __connmanctl_input_lookup_end();
2697 return lookup_technology(text, state);
2700 static char *lookup_technology_offline(const char *text, int state)
2703 static bool end = false;
2706 if (__connmanctl_input_calc_level() > 1) {
2707 __connmanctl_input_lookup_end();
2719 str = lookup_technology(text, state);
2725 if (strncmp(text, "offline", len) == 0)
2726 return strdup("offline");
2731 static char *lookup_on_off(const char *text, int state)
2733 char *onoff[] = { "on", "off", NULL };
2744 while (onoff[idx]) {
2748 if (!strncmp(text, str, len))
2755 static char *lookup_tether(const char *text, int state)
2759 level = __connmanctl_input_calc_level();
2761 return lookup_technology(text, state);
2764 return lookup_on_off(text, state);
2766 __connmanctl_input_lookup_end();
2771 static char *lookup_agent(const char *text, int state)
2773 if (__connmanctl_input_calc_level() > 1) {
2774 __connmanctl_input_lookup_end();
2778 return lookup_on_off(text, state);
2781 static char *lookup_vpnconnection_arg(const char *text, int state)
2783 if (__connmanctl_input_calc_level() > 1) {
2784 __connmanctl_input_lookup_end();
2788 return lookup_key_from_table(vpnconnection_hash, text, state);
2791 static struct connman_option service_options[] = {
2792 {"properties", 'p', "[<service>] (obsolete)"},
2796 static struct connman_option config_options[] = {
2797 {"nameservers", 'n', "<dns1> [<dns2>] [<dns3>]"},
2798 {"timeservers", 't', "<ntp1> [<ntp2>] [...]"},
2799 {"domains", 'd', "<domain1> [<domain2>] [...]"},
2800 {"ipv6", 'v', "off|auto [enable|disable|preferred]|\n"
2801 "\t\t\tmanual <address> <prefixlength> <gateway>"},
2802 {"proxy", 'x', "direct|auto <URL>|manual <URL1> [<URL2>] [...]\n"
2803 "\t\t\t[exclude <exclude1> [<exclude2>] [...]]"},
2804 {"autoconnect", 'a', "yes|no"},
2805 {"ipv4", 'i', "off|dhcp|manual <address> <netmask> <gateway>"},
2806 {"remove", 'r', " Remove service"},
2810 static struct connman_option monitor_options[] = {
2811 {"services", 's', "[off] Monitor only services"},
2812 {"tech", 'c', "[off] Monitor only technologies"},
2813 {"manager", 'm', "[off] Monitor only manager interface"},
2814 {"vpnmanager", 'M', "[off] Monitor only VPN manager "
2816 {"vpnconnection", 'C', "[off] Monitor only VPN "
2821 static struct connman_option session_options[] = {
2822 {"bearers", 'b', "<technology1> [<technology2> [...]]"},
2823 {"type", 't', "local|internet|any"},
2824 {"ifname", 'i', "[<interface_name>]"},
2825 {"srciprule", 's', "yes|no"},
2829 #if defined TIZEN_EXT_WIFI_MESH
2830 static struct connman_option mesh_options[] = {
2831 {"ifadd", 'a', "<ifname> <wifi_ifname>\n"
2832 " [bridge_ifname] Add Virtual Mesh "
2834 {"ifrmv", 'r', "<ifname> Remove Virtual Mesh "
2836 {"peers", 'p', "[peer] Display Mesh peer "
2838 {"connect", 'c', "<peer> Connect Mesh Peer"},
2839 {"disconnect", 'd', "<peer> Disconnect Mesh Peer"},
2840 {"remove", 'f', "<peer> Forget Mesh Peer"},
2841 {"connected_peers", 'C', "[] Displays connected"
2842 " Peer informations"},
2843 {"disconnected_peers", 'D', "[] Displays "
2844 "Disconnected Peer informations"},
2845 {"create_network", 'n', "<name> <frequency> <sec_type> Create New Mesh "
2847 {"abort_scan", 'A', " Abort ongoing mesh "
2849 {"specific_scan", 'S', "<name> <frequency> Create New Mesh "
2851 {"config", 'P', "<peer> Set Mesh Network "
2852 "Configurations\n Passphrase <passphrase>"},
2853 {"set_gate", 'G', "<gate_ann> <rootmode> <stp> Set Mesh Gate "
2855 {"add_peer", 'z', "<addr> Add Mesh Peer"},
2856 {"remove_peer", 'y', "<addr> Remove Mesh Peer"},
2861 static char *lookup_options(struct connman_option *options, const char *text,
2873 while (options[idx].name) {
2874 str = options[idx].name;
2877 if (str && strncmp(text, str, len) == 0)
2884 static char *lookup_monitor(const char *text, int state)
2888 level = __connmanctl_input_calc_level();
2891 return lookup_options(monitor_options, text, state);
2894 return lookup_on_off(text, state);
2896 __connmanctl_input_lookup_end();
2900 static char *lookup_config(const char *text, int state)
2902 if (__connmanctl_input_calc_level() < 2)
2903 return lookup_key_from_table(service_hash, text, state);
2905 return lookup_options(config_options, text, state);
2908 static char *lookup_session(const char *text, int state)
2910 return lookup_options(session_options, text, state);
2913 #if defined TIZEN_EXT_WIFI_MESH
2914 static char *lookup_mesh(const char *text, int state)
2916 return lookup_options(mesh_options, text, state);
2920 static int peer_service_cb(DBusMessageIter *iter, const char *error,
2923 bool registration = GPOINTER_TO_INT(user_data);
2926 fprintf(stderr, "Error %s peer service: %s\n",
2927 registration ? "registering" : "unregistering", error);
2929 fprintf(stdout, "Peer service %s\n",
2930 registration ? "registered" : "unregistered");
2935 struct _peer_service {
2936 unsigned char *bjr_query;
2938 unsigned char *bjr_response;
2939 int bjr_response_len;
2940 unsigned char *wfd_ies;
2947 static void append_dict_entry_fixed_array(DBusMessageIter *iter,
2948 const char *property, void *value, int length)
2950 DBusMessageIter dict_entry, variant, array;
2952 dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY,
2954 dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING,
2956 dbus_message_iter_open_container(&dict_entry, DBUS_TYPE_VARIANT,
2957 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING,
2959 dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
2960 DBUS_TYPE_BYTE_AS_STRING, &array);
2961 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
2963 dbus_message_iter_close_container(&variant, &array);
2964 dbus_message_iter_close_container(&dict_entry, &variant);
2965 dbus_message_iter_close_container(iter, &dict_entry);
2968 static void append_peer_service_dict(DBusMessageIter *iter, void *user_data)
2970 struct _peer_service *service = user_data;
2972 if (service->bjr_query && service->bjr_response) {
2973 append_dict_entry_fixed_array(iter, "BonjourQuery",
2974 &service->bjr_query, service->bjr_query_len);
2975 append_dict_entry_fixed_array(iter, "BonjourResponse",
2976 &service->bjr_response, service->bjr_response_len);
2977 } else if (service->upnp_service && service->version) {
2978 __connmanctl_dbus_append_dict_entry(iter, "UpnpVersion",
2979 DBUS_TYPE_INT32, &service->version);
2980 __connmanctl_dbus_append_dict_entry(iter, "UpnpService",
2981 DBUS_TYPE_STRING, &service->upnp_service);
2982 } else if (service->wfd_ies) {
2983 append_dict_entry_fixed_array(iter, "WiFiDisplayIEs",
2984 &service->wfd_ies, service->wfd_ies_len);
2988 static void peer_service_append(DBusMessageIter *iter, void *user_data)
2990 struct _peer_service *service = user_data;
2993 __connmanctl_dbus_append_dict(iter, append_peer_service_dict, service);
2995 if (service->master < 0)
2998 master = service->master == 1 ? TRUE : FALSE;
2999 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &master);
3002 static struct _peer_service *fill_in_peer_service(unsigned char *bjr_query,
3003 int bjr_query_len, unsigned char *bjr_response,
3004 int bjr_response_len, char *upnp_service,
3005 int version, unsigned char *wfd_ies,
3008 struct _peer_service *service;
3010 service = dbus_malloc0(sizeof(*service));
3012 #if defined TIZEN_EXT
3017 if (bjr_query_len && bjr_response_len) {
3018 service->bjr_query = dbus_malloc0(bjr_query_len);
3019 #if defined TIZEN_EXT
3020 if(!service->bjr_query) {
3025 memcpy(service->bjr_query, bjr_query, bjr_query_len);
3026 service->bjr_query_len = bjr_query_len;
3028 service->bjr_response = dbus_malloc0(bjr_response_len);
3029 #if defined TIZEN_EXT
3030 if(!service->bjr_response) {
3031 dbus_free(service->bjr_query);
3036 memcpy(service->bjr_response, bjr_response, bjr_response_len);
3037 service->bjr_response_len = bjr_response_len;
3038 } else if (upnp_service && version) {
3039 service->upnp_service = strdup(upnp_service);
3040 service->version = version;
3041 } else if (wfd_ies && wfd_ies_len) {
3042 service->wfd_ies = dbus_malloc0(wfd_ies_len);
3043 #if defined TIZEN_EXT
3044 if (!service->wfd_ies) {
3049 memcpy(service->wfd_ies, wfd_ies, wfd_ies_len);
3050 service->wfd_ies_len = wfd_ies_len;
3059 static void free_peer_service(struct _peer_service *service)
3061 dbus_free(service->bjr_query);
3062 dbus_free(service->bjr_response);
3063 dbus_free(service->wfd_ies);
3064 free(service->upnp_service);
3068 static int peer_service_register(unsigned char *bjr_query, int bjr_query_len,
3069 unsigned char *bjr_response, int bjr_response_len,
3070 char *upnp_service, int version,
3071 unsigned char *wfd_ies, int wfd_ies_len, int master)
3073 struct _peer_service *service;
3074 bool registration = true;
3077 service = fill_in_peer_service(bjr_query, bjr_query_len, bjr_response,
3078 bjr_response_len, upnp_service, version,
3079 wfd_ies, wfd_ies_len);
3083 service->master = master;
3085 ret = __connmanctl_dbus_method_call(connection, "net.connman", "/",
3086 "net.connman.Manager", "RegisterPeerService",
3087 peer_service_cb, GINT_TO_POINTER(registration),
3088 peer_service_append, service);
3090 free_peer_service(service);
3095 static int peer_service_unregister(unsigned char *bjr_query, int bjr_query_len,
3096 unsigned char *bjr_response, int bjr_response_len,
3097 char *upnp_service, int version,
3098 unsigned char *wfd_ies, int wfd_ies_len)
3100 struct _peer_service *service;
3101 bool registration = false;
3104 service = fill_in_peer_service(bjr_query, bjr_query_len, bjr_response,
3105 bjr_response_len, upnp_service, version,
3106 wfd_ies, wfd_ies_len);
3110 service->master = -1;
3112 ret = __connmanctl_dbus_method_call(connection, "net.connman", "/",
3113 "net.connman.Manager", "UnregisterPeerService",
3114 peer_service_cb, GINT_TO_POINTER(registration),
3115 peer_service_append, service);
3117 free_peer_service(service);
3122 static int parse_spec_array(char *command, unsigned char spec[1024])
3124 int length, pos, end;
3128 end = strlen(command);
3129 for (e = NULL, length = pos = 0; command[pos] != '\0'; length++) {
3133 b[0] = command[pos];
3134 b[1] = command[pos+1];
3136 spec[length] = strtol(b, &e, 16);
3137 if (e && *e != '\0')
3146 static int cmd_peer_service(char *args[], int num,
3147 struct connman_option *options)
3149 unsigned char bjr_query[1024] = {};
3150 unsigned char bjr_response[1024] = {};
3151 unsigned char wfd_ies[1024] = {};
3152 char *upnp_service = NULL;
3153 int bjr_query_len = 0, bjr_response_len = 0;
3154 int version = 0, master = 0, wfd_ies_len = 0;
3160 if (!strcmp(args[2], "wfd_ies")) {
3161 wfd_ies_len = parse_spec_array(args[3], wfd_ies);
3162 if (wfd_ies_len == -EINVAL)
3172 if (!strcmp(args[2], "bjr_query")) {
3173 if (strcmp(args[4], "bjr_response"))
3175 bjr_query_len = parse_spec_array(args[3], bjr_query);
3176 bjr_response_len = parse_spec_array(args[5], bjr_response);
3178 if (bjr_query_len == -EINVAL || bjr_response_len == -EINVAL)
3180 } else if (!strcmp(args[2], "upnp_service")) {
3183 if (strcmp(args[4], "upnp_version"))
3185 upnp_service = args[3];
3186 version = strtol(args[5], &e, 10);
3193 master = parse_boolean(args[6]);
3198 if (!strcmp(args[1], "register")) {
3199 return peer_service_register(bjr_query, bjr_query_len,
3200 bjr_response, bjr_response_len, upnp_service,
3201 version, wfd_ies, wfd_ies_len, master);
3202 } else if (!strcmp(args[1], "unregister")) {
3203 return peer_service_unregister(bjr_query, bjr_query_len,
3204 bjr_response, bjr_response_len, upnp_service,
3205 version, wfd_ies, wfd_ies_len);
3211 static const struct {
3213 const char *argument;
3214 struct connman_option *options;
3215 int (*func) (char *args[], int num, struct connman_option *options);
3217 __connmanctl_lookup_cb cb;
3219 { "state", NULL, NULL, cmd_state,
3220 "Shows if the system is online or offline", NULL },
3221 { "technologies", NULL, NULL, cmd_technologies,
3222 "Display technologies", NULL },
3223 { "clock", NULL, NULL, cmd_clock,
3224 "Get System Clock Properties", NULL },
3225 { "enable", "<technology>|offline", NULL, cmd_enable,
3226 "Enables given technology or offline mode",
3227 lookup_technology_offline },
3228 { "disable", "<technology>|offline", NULL, cmd_disable,
3229 "Disables given technology or offline mode",
3230 lookup_technology_offline },
3231 #if defined TIZEN_EXT_WIFI_MESH
3232 { "mesh", "", mesh_options, cmd_mesh, "Mesh specific commands",
3235 { "tether", "<technology> on|off\n"
3236 " wifi [on|off] <ssid> <passphrase> ",
3238 "Enable, disable tethering, set SSID and passphrase for wifi",
3240 { "services", "[<service>]", service_options, cmd_services,
3241 "Display services", lookup_service_arg },
3242 { "peers", "[peer]", NULL, cmd_peers,
3243 "Display peers", lookup_peer_arg },
3244 { "scan", "<technology>", NULL, cmd_scan,
3245 "Scans for new services for given technology",
3246 lookup_technology_arg },
3247 { "connect", "<service/peer>", NULL, cmd_connect,
3248 "Connect a given service or peer", lookup_service_arg },
3249 { "disconnect", "<service/peer>", NULL, cmd_disconnect,
3250 "Disconnect a given service or peer", lookup_service_arg },
3251 { "move-before", "<service> <target service> ", NULL,
3252 cmd_service_move_before, "Move <service> before <target service>",
3253 lookup_service_arg },
3254 { "move-after", "<service> <target service> ", NULL,
3255 cmd_service_move_after, "Move <service> after <target service>",
3256 lookup_service_arg },
3257 { "config", "<service>", config_options, cmd_config,
3258 "Set service configuration options", lookup_config },
3259 { "monitor", "[off]", monitor_options, cmd_monitor,
3260 "Monitor signals from interfaces", lookup_monitor },
3261 { "agent", "on|off", NULL, cmd_agent,
3262 "Agent mode", lookup_agent },
3263 { "vpnconnections", "[<connection>]", NULL, cmd_vpnconnections,
3264 "Display VPN connections", lookup_vpnconnection_arg },
3265 { "vpnagent", "on|off", NULL, cmd_vpnagent,
3266 "VPN Agent mode", lookup_agent },
3267 { "session", "on|off|connect|disconnect|config", session_options,
3268 cmd_session, "Enable or disable a session", lookup_session },
3269 { "peer_service", "register|unregister <specs> <master>\n"
3270 "Where specs are:\n"
3271 "\tbjr_query <query> bjr_response <response>\n"
3272 "\tupnp_service <service> upnp_version <version>\n"
3273 "\twfd_ies <ies>\n", NULL,
3274 cmd_peer_service, "(Un)Register a Peer Service", NULL },
3275 { "help", NULL, NULL, cmd_help,
3276 "Show help", NULL },
3277 { "exit", NULL, NULL, cmd_exit,
3279 { "quit", NULL, NULL, cmd_exit,
3284 static int cmd_help(char *args[], int num, struct connman_option *options)
3286 bool interactive = __connmanctl_is_interactive();
3289 if (interactive == false)
3290 fprintf(stdout, "Usage: connmanctl [[command] [args]]\n");
3292 for (i = 0; cmd_table[i].cmd; i++) {
3293 const char *cmd = cmd_table[i].cmd;
3294 const char *argument = cmd_table[i].argument;
3295 const char *desc = cmd_table[i].desc;
3297 printf("%-16s%-22s%s\n", cmd? cmd: "",
3298 argument? argument: "",
3301 if (cmd_table[i].options) {
3302 for (j = 0; cmd_table[i].options[j].name;
3304 const char *options_desc =
3305 cmd_table[i].options[j].desc ?
3306 cmd_table[i].options[j].desc: "";
3308 printf(" --%-16s%s\n",
3309 cmd_table[i].options[j].name,
3315 if (interactive == false)
3316 fprintf(stdout, "\nNote: arguments and output are considered "
3317 "EXPERIMENTAL for now.\n");
3322 __connmanctl_lookup_cb __connmanctl_get_lookup_func(const char *text)
3324 int i, cmdlen, textlen;
3329 textlen = strlen(text);
3331 for (i = 0; cmd_table[i].cmd; i++) {
3332 cmdlen = strlen(cmd_table[i].cmd);
3334 if (textlen > cmdlen && text[cmdlen] != ' ')
3337 if (strncmp(cmd_table[i].cmd, text, cmdlen) == 0)
3338 return cmd_table[i].cb;
3344 int __connmanctl_commands(DBusConnection *dbus_conn, char *argv[], int argc)
3348 connection = dbus_conn;
3350 for (i = 0; cmd_table[i].cmd; i++) {
3351 if (g_strcmp0(cmd_table[i].cmd, argv[0]) == 0 &&
3352 cmd_table[i].func) {
3353 result = cmd_table[i].func(argv, argc,
3354 cmd_table[i].options);
3355 if (result < 0 && result != -EINPROGRESS)
3356 fprintf(stderr, "Error '%s': %s\n", argv[0],
3362 fprintf(stderr, "Error '%s': Unknown command\n", argv[0]);
3366 char *__connmanctl_lookup_command(const char *text, int state)
3376 while (cmd_table[i].cmd) {
3377 const char *command = cmd_table[i].cmd;
3381 if (strncmp(text, command, len) == 0)
3382 return strdup(command);
3388 static char *get_path(char *full_path)
3392 path = strrchr(full_path, '/');
3393 if (path && *path != '\0')
3401 static void add_service_id(const char *path)
3403 g_hash_table_replace(service_hash, g_strdup(path),
3404 GINT_TO_POINTER(TRUE));
3407 static void remove_service_id(const char *path)
3409 g_hash_table_remove(service_hash, path);
3412 static void services_added(DBusMessageIter *iter)
3414 DBusMessageIter array;
3417 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
3419 dbus_message_iter_recurse(iter, &array);
3420 if (dbus_message_iter_get_arg_type(&array) !=
3421 DBUS_TYPE_OBJECT_PATH)
3424 dbus_message_iter_get_basic(&array, &path);
3425 add_service_id(get_path(path));
3427 dbus_message_iter_next(iter);
3431 static void update_services(DBusMessageIter *iter)
3433 DBusMessageIter array;
3436 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3439 dbus_message_iter_recurse(iter, &array);
3440 services_added(&array);
3442 dbus_message_iter_next(iter);
3443 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3446 dbus_message_iter_recurse(iter, &array);
3447 while (dbus_message_iter_get_arg_type(&array) ==
3448 DBUS_TYPE_OBJECT_PATH) {
3449 dbus_message_iter_get_basic(&array, &path);
3450 remove_service_id(get_path(path));
3452 dbus_message_iter_next(&array);
3456 static int populate_service_hash(DBusMessageIter *iter, const char *error,
3460 fprintf(stderr, "Error getting services: %s", error);
3464 update_services(iter);
3468 static void add_vpnconnection_id(const char *path)
3470 g_hash_table_replace(vpnconnection_hash, g_strdup(path),
3471 GINT_TO_POINTER(TRUE));
3474 static void remove_vpnconnection_id(const char *path)
3476 g_hash_table_remove(vpnconnection_hash, path);
3479 static void vpnconnection_added(DBusMessageIter *iter)
3483 dbus_message_iter_get_basic(iter, &path);
3484 add_vpnconnection_id(get_path(path));
3487 static void vpnconnection_removed(DBusMessageIter *iter)
3491 dbus_message_iter_get_basic(iter, &path);
3492 remove_vpnconnection_id(get_path(path));
3495 static void add_vpnconnections(DBusMessageIter *iter)
3497 DBusMessageIter array;
3500 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
3502 dbus_message_iter_recurse(iter, &array);
3503 if (dbus_message_iter_get_arg_type(&array) !=
3504 DBUS_TYPE_OBJECT_PATH)
3507 dbus_message_iter_get_basic(&array, &path);
3508 add_vpnconnection_id(get_path(path));
3510 dbus_message_iter_next(iter);
3514 static int populate_vpnconnection_hash(DBusMessageIter *iter, const char *error,
3517 DBusMessageIter array;
3520 fprintf(stderr, "Error getting VPN connections: %s", error);
3524 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3527 dbus_message_iter_recurse(iter, &array);
3529 add_vpnconnections(&array);
3534 static void add_peer_id(const char *path)
3536 g_hash_table_replace(peer_hash, g_strdup(path), GINT_TO_POINTER(TRUE));
3539 static void remove_peer_id(const char *path)
3541 g_hash_table_remove(peer_hash, path);
3544 static void peers_added(DBusMessageIter *iter)
3546 DBusMessageIter array;
3549 while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
3551 dbus_message_iter_recurse(iter, &array);
3552 if (dbus_message_iter_get_arg_type(&array) !=
3553 DBUS_TYPE_OBJECT_PATH)
3556 dbus_message_iter_get_basic(&array, &path);
3557 add_peer_id(get_path(path));
3559 dbus_message_iter_next(iter);
3563 static void update_peers(DBusMessageIter *iter)
3565 DBusMessageIter array;
3568 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3571 dbus_message_iter_recurse(iter, &array);
3572 peers_added(&array);
3574 dbus_message_iter_next(iter);
3575 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3578 dbus_message_iter_recurse(iter, &array);
3579 while (dbus_message_iter_get_arg_type(&array) ==
3580 DBUS_TYPE_OBJECT_PATH) {
3581 dbus_message_iter_get_basic(&array, &path);
3582 remove_peer_id(get_path(path));
3584 dbus_message_iter_next(&array);
3588 static int populate_peer_hash(DBusMessageIter *iter,
3589 const char *error, void *user_data)
3592 fprintf(stderr, "Error getting peers: %s", error);
3600 static void add_technology_id(const char *path)
3602 g_hash_table_replace(technology_hash, g_strdup(path),
3603 GINT_TO_POINTER(TRUE));
3606 static void remove_technology_id(const char *path)
3608 g_hash_table_remove(technology_hash, path);
3611 static void remove_technology(DBusMessageIter *iter)
3615 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH)
3618 dbus_message_iter_get_basic(iter, &path);
3619 remove_technology_id(get_path(path));
3622 static void add_technology(DBusMessageIter *iter)
3626 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH)
3629 dbus_message_iter_get_basic(iter, &path);
3630 add_technology_id(get_path(path));
3633 static void update_technologies(DBusMessageIter *iter)
3635 DBusMessageIter array;
3637 if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
3640 dbus_message_iter_recurse(iter, &array);
3642 while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
3643 DBusMessageIter object_path;
3645 dbus_message_iter_recurse(&array, &object_path);
3647 add_technology(&object_path);
3649 dbus_message_iter_next(&array);
3653 static int populate_technology_hash(DBusMessageIter *iter, const char *error,
3657 fprintf(stderr, "Error getting technologies: %s", error);
3661 update_technologies(iter);
3666 static DBusHandlerResult monitor_completions_changed(
3667 DBusConnection *connection,
3668 DBusMessage *message, void *user_data)
3670 bool *enabled = user_data;
3671 DBusMessageIter iter;
3672 DBusHandlerResult handled;
3675 handled = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3677 handled = DBUS_HANDLER_RESULT_HANDLED;
3679 if (dbus_message_is_signal(message, "net.connman.Manager",
3680 "ServicesChanged")) {
3681 dbus_message_iter_init(message, &iter);
3682 update_services(&iter);
3686 if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
3687 "ConnectionAdded")) {
3688 dbus_message_iter_init(message, &iter);
3689 vpnconnection_added(&iter);
3693 if (dbus_message_is_signal(message, "net.connman.vpn.Manager",
3694 "ConnectionRemoved")) {
3695 dbus_message_iter_init(message, &iter);
3696 vpnconnection_removed(&iter);
3700 if (dbus_message_is_signal(message, "net.connman.Manager",
3702 dbus_message_iter_init(message, &iter);
3703 update_peers(&iter);
3707 if (dbus_message_is_signal(message, "net.connman.Manager",
3708 "TechnologyAdded")) {
3709 dbus_message_iter_init(message, &iter);
3710 add_technology(&iter);
3714 if (dbus_message_is_signal(message, "net.connman.Manager",
3715 "TechnologyRemoved")) {
3716 dbus_message_iter_init(message, &iter);
3717 remove_technology(&iter);
3721 if (!g_strcmp0(dbus_message_get_interface(message),
3722 "net.connman.Manager"))
3725 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3728 void __connmanctl_monitor_completions(DBusConnection *dbus_conn)
3730 bool *manager_enabled = NULL;
3734 for (i = 0; monitor[i].interface; i++) {
3735 if (!strcmp(monitor[i].interface, "Manager")) {
3736 manager_enabled = &monitor[i].enabled;
3742 g_hash_table_destroy(service_hash);
3743 g_hash_table_destroy(vpnconnection_hash);
3744 g_hash_table_destroy(technology_hash);
3746 dbus_bus_remove_match(connection,
3747 "type='signal',interface='net.connman.Manager'", NULL);
3748 dbus_bus_remove_match(connection,
3749 "type='signal',interface='net.connman.vpn.Manager'",
3751 dbus_connection_remove_filter(connection,
3752 monitor_completions_changed,
3757 connection = dbus_conn;
3759 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3762 vpnconnection_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3765 peer_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3768 technology_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
3771 __connmanctl_dbus_method_call(connection,
3772 CONNMAN_SERVICE, CONNMAN_PATH,
3773 "net.connman.Manager", "GetServices",
3774 populate_service_hash, NULL, NULL, NULL);
3776 __connmanctl_dbus_method_call(connection,
3777 VPN_SERVICE, CONNMAN_PATH,
3778 "net.connman.vpn.Manager", "GetConnections",
3779 populate_vpnconnection_hash, NULL, NULL, NULL);
3781 __connmanctl_dbus_method_call(connection,
3782 CONNMAN_SERVICE, CONNMAN_PATH,
3783 "net.connman.Manager", "GetPeers",
3784 populate_peer_hash, NULL, NULL, NULL);
3786 __connmanctl_dbus_method_call(connection,
3787 CONNMAN_SERVICE, CONNMAN_PATH,
3788 "net.connman.Manager", "GetTechnologies",
3789 populate_technology_hash, NULL, NULL, NULL);
3791 dbus_connection_add_filter(connection,
3792 monitor_completions_changed, manager_enabled,
3795 dbus_error_init(&err);
3796 dbus_bus_add_match(connection,
3797 "type='signal',interface='net.connman.Manager'", &err);
3799 if (dbus_error_is_set(&err)) {
3800 fprintf(stderr, "Error: %s\n", err.message);
3804 dbus_bus_add_match(connection,
3805 "type='signal',interface='net.connman.vpn.Manager'",
3808 if (dbus_error_is_set(&err))
3809 fprintf(stderr, "Error: %s\n", err.message);