summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorNishant Chaprana <n.chaprana@samsung.com>2018-08-10 16:41:37 +0530
committerNishant Chaprana <n.chaprana@samsung.com>2018-08-24 10:20:11 +0530
commitd04bfa0350781ebfb8cbb2e64fabdfb2f36cd302 (patch)
tree750ce9bb53579e1ee54d91aa3a6c976e55f1a8db /client
parent037a4a5e75f3fc0845a924bb94addc2549550e63 (diff)
downloadconnman-d04bfa0350781ebfb8cbb2e64fabdfb2f36cd302.tar.gz
connman-d04bfa0350781ebfb8cbb2e64fabdfb2f36cd302.tar.bz2
connman-d04bfa0350781ebfb8cbb2e64fabdfb2f36cd302.zip
[connman] Added Tizen Wi-Fi Meshsubmit/tizen/20180824.072908
Change-Id: Iec2ec99fb7d4fc6d9c0539e5a9e7c903e1969580 Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
Diffstat (limited to 'client')
-rw-r--r--[-rwxr-xr-x]client/commands.c618
-rw-r--r--[-rwxr-xr-x]client/dbus_helpers.c49
-rw-r--r--[-rwxr-xr-x]client/dbus_helpers.h9
-rw-r--r--client/mesh.c166
-rw-r--r--client/mesh.h40
5 files changed, 882 insertions, 0 deletions
diff --git a/client/commands.c b/client/commands.c
index 746e1589..ce827919 100755..100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -43,6 +43,9 @@
#include "commands.h"
#include "agent.h"
#include "vpnconnections.h"
+#if defined TIZEN_EXT_WIFI_MESH
+#include "mesh.h"
+#endif
static DBusConnection *connection;
static GHashTable *service_hash;
@@ -599,6 +602,578 @@ static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering)
return -EINPROGRESS;
}
+#if defined TIZEN_EXT_WIFI_MESH
+struct mesh_if_prop {
+ char *ifname;
+ char *parent_ifname;
+ char *bridge_ifname;
+};
+
+struct mesh_create_network {
+ char *name;
+ unsigned int freq;
+ char *sec_type;
+};
+
+struct mesh_specific_scan_params {
+ char *name;
+ unsigned int freq;
+};
+
+struct mesh_gate_params {
+ bool gate_announce;
+ int hwmp_rootmode;
+ int stp;
+};
+
+static int mesh_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ char *method = user_data;
+
+ if (error)
+ fprintf(stderr, "Error %s: %s\n", method, error);
+ else
+ fprintf(stderr, "Success %s\n", method);
+
+ g_free(method);
+
+ return 0;
+}
+
+static void mesh_interface_add_append(DBusMessageIter *iter, void *user_data)
+{
+ struct mesh_if_prop *append = user_data;
+
+ /* Append Virtual Interface Name */
+ __connmanctl_dbus_append_dict_entry(iter, "Ifname",
+ DBUS_TYPE_STRING, &append->ifname);
+
+ /* Append Parent WiFi Interface Name */
+ __connmanctl_dbus_append_dict_entry(iter, "ParentIfname",
+ DBUS_TYPE_STRING, &append->parent_ifname);
+
+ /* Append Bridge Interface Name */
+ if (append->bridge_ifname)
+ __connmanctl_dbus_append_dict_entry(iter, "BridgeIfname",
+ DBUS_TYPE_STRING, &append->bridge_ifname);
+}
+
+static void mesh_interface_remove_append(DBusMessageIter *iter, void *user_data)
+{
+ struct mesh_if_prop *append = user_data;
+
+ /* Append Virtual Interface Name */
+ __connmanctl_dbus_append_dict_entry(iter, "Ifname",
+ DBUS_TYPE_STRING, &append->ifname);
+}
+
+static void mesh_create_network_append(DBusMessageIter *iter, void *user_data)
+{
+ struct mesh_create_network *append = user_data;
+
+ /* Append Mesh Network Name */
+ __connmanctl_dbus_append_dict_entry(iter, "Name",
+ DBUS_TYPE_STRING, &append->name);
+
+ /* Append Mesh Network Frequency */
+ __connmanctl_dbus_append_dict_entry(iter, "Frequency",
+ DBUS_TYPE_UINT16, &append->freq);
+
+ /* Append Mesh Network Security Type */
+ __connmanctl_dbus_append_dict_entry(iter, "Security",
+ DBUS_TYPE_STRING, &append->sec_type);
+}
+
+static void mesh_specific_scan_append(DBusMessageIter *iter, void *user_data)
+{
+ struct mesh_specific_scan_params *append = user_data;
+
+ /* Append Mesh Network Name */
+ __connmanctl_dbus_append_dict_entry(iter, "Name",
+ DBUS_TYPE_STRING, &append->name);
+
+ /* Append Mesh Network Frequency */
+ __connmanctl_dbus_append_dict_entry(iter, "Frequency",
+ DBUS_TYPE_UINT16, &append->freq);
+}
+
+static void mesh_set_gate_append(DBusMessageIter *iter, void *user_data)
+{
+ struct mesh_gate_params *append = user_data;
+
+ /* Append Gate Announce Protocol */
+ __connmanctl_dbus_append_dict_entry(iter, "GateAnnounce",
+ DBUS_TYPE_BOOLEAN, &append->gate_announce);
+
+ /* Append HWMP Root Mode */
+ __connmanctl_dbus_append_dict_entry(iter, "HWMPRootMode",
+ DBUS_TYPE_UINT16, &append->hwmp_rootmode);
+
+ /* Append STP */
+ __connmanctl_dbus_append_dict_entry(iter, "STP", DBUS_TYPE_UINT16,
+ &append->stp);
+}
+
+static void mesh_peer_append(DBusMessageIter *iter, void *user_data)
+{
+ char *peer_addr = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &peer_addr);
+
+ g_free(peer_addr);
+}
+
+static int mesh_peers_list(DBusMessageIter *iter,
+ const char *error, void *user_data)
+{
+ if (!error) {
+ __connmanctl_mesh_peers_list(iter);
+ fprintf(stdout, "\n");
+ } else
+ fprintf(stderr, "Error: %s\n", error);
+
+ return 0;
+}
+
+static int connected_mesh_peers_list(DBusMessageIter *iter,
+ const char *error, void *user_data)
+{
+ if (!error) {
+ __connmanctl_mesh_connected_peers_list(iter);
+ fprintf(stdout, "\n");
+ } else
+ fprintf(stderr, "Error: %s\n", error);
+
+ return 0;
+}
+
+static int disconnected_mesh_peers_list(DBusMessageIter *iter,
+ const char *error, void *user_data)
+{
+ if (!error) {
+ __connmanctl_mesh_disconnected_peers_list(iter);
+ fprintf(stdout, "\n");
+ } else
+ fprintf(stderr, "Error: %s\n", error);
+
+ return 0;
+}
+
+static int mesh_connect_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ char *path = user_data;
+
+ if (!error) {
+ char *str = strrchr(path, '/');
+ str++;
+ fprintf(stdout, "Connected %s\n", str);
+ } else
+ fprintf(stderr, "Error %s: %s\n", path, error);
+
+ g_free(user_data);
+
+ return 0;
+}
+
+static int mesh_disconnect_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ char *path = user_data;
+
+ if (!error) {
+ char *str = strrchr(path, '/');
+ str++;
+ fprintf(stdout, "Disconnected %s\n", str);
+ } else
+ fprintf(stderr, "Error %s: %s\n", path, error);
+
+ g_free(user_data);
+
+ return 0;
+}
+
+static int mesh_remove_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ char *path = user_data;
+
+ if (!error) {
+ char *str = strrchr(path, '/');
+ str++;
+ fprintf(stdout, "Removed %s\n", str);
+ } else
+ fprintf(stderr, "Error %s: %s\n", path, error);
+
+ g_free(user_data);
+
+ return 0;
+}
+
+static int mesh_config_return(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ char *path = user_data;
+ char *str = strrchr(path, '/');
+ str++;
+
+ if (error)
+ fprintf(stderr, "Error %s: %s\n", path, error);
+ else
+ fprintf(stdout, "Success SetProperty %s\n", str);
+
+ g_free(user_data);
+
+ return 0;
+}
+
+static int cmd_mesh(char *args[], int num, struct connman_option *options)
+{
+ int result = 0;
+ int c;
+ char *path = NULL;
+ char *method = NULL;
+ char *mesh_peer_name = NULL;
+ char *mesh_peer_path = NULL;
+ char *property = NULL;
+ char *value = NULL;
+ struct mesh_if_prop *append;
+ struct mesh_create_network *network;
+ struct mesh_specific_scan_params *scan_params;
+ struct mesh_gate_params *gate_params;
+ char *mesh_peer_addr = NULL;
+
+ c = parse_args(args[1], options);
+
+ switch (c) {
+ case 'a':
+ if (num < 4 || num > 5) {
+ result = -EINVAL;
+ break;
+ }
+ path = g_strdup_printf("/net/connman/technology/mesh");
+
+ append = dbus_malloc0(sizeof(struct mesh_if_prop));
+ append->ifname = g_strdup(args[2]);
+ append->parent_ifname = g_strdup(args[3]);
+ if (num == 5)
+ append->bridge_ifname = g_strdup(args[4]);
+ method = g_strdup("MeshInterfaceAdd");
+ result = __connmanctl_dbus_mesh_dict(connection, path,
+ "net.connman.Technology", mesh_return, method,
+ "MeshInterfaceAdd", DBUS_TYPE_STRING,
+ mesh_interface_add_append, append);
+ g_free(append->ifname);
+ g_free(append->parent_ifname);
+ g_free(append->bridge_ifname);
+ g_free(append);
+ break;
+
+ case 'r':
+ if (num != 3) {
+ result = -EINVAL;
+ break;
+ }
+ path = g_strdup_printf("/net/connman/technology/mesh");
+
+ append = dbus_malloc0(sizeof(struct mesh_if_prop));
+ append->ifname = g_strdup(args[2]);
+ method = g_strdup("MeshInterfaceRemove");
+ result = __connmanctl_dbus_mesh_dict(connection, path,
+ "net.connman.Technology", mesh_return, method,
+ "MeshInterfaceRemove", DBUS_TYPE_STRING,
+ mesh_interface_remove_append, append);
+ g_free(append->ifname);
+ g_free(append);
+ break;
+
+ case 'p':
+ if (num > 3) {
+ result = -E2BIG;
+ break;
+ }
+
+ if (num == 3)
+ mesh_peer_name = args[2];
+
+ if (!mesh_peer_name) {
+ result = __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "GetMeshPeers",
+ mesh_peers_list, NULL, NULL, NULL);
+ break;
+ }
+
+ if (check_dbus_name(mesh_peer_name) == false) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
+ mesh_peer_name);
+ result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ mesh_peer_path, "net.connman.Mesh", "GetProperties",
+ object_properties, mesh_peer_path, NULL, NULL);
+ break;
+
+ case 'c':
+ if (num < 3) {
+ result = -EINVAL;
+ break;
+ }
+
+ if (num > 3) {
+ result = -E2BIG;
+ break;
+ }
+
+ mesh_peer_name = args[2];
+
+ if (check_dbus_name(mesh_peer_name) == false) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
+ mesh_peer_name);
+ result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ mesh_peer_path, "net.connman.Mesh", "Connect",
+ mesh_connect_return, mesh_peer_path, NULL, NULL);
+ break;
+
+ case 'd':
+ if (num < 3) {
+ result = -EINVAL;
+ break;
+ }
+
+ if (num > 3) {
+ result = -E2BIG;
+ break;
+ }
+
+ mesh_peer_name = args[2];
+
+ if (check_dbus_name(mesh_peer_name) == false) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
+ mesh_peer_name);
+ result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ mesh_peer_path, "net.connman.Mesh", "Disconnect",
+ mesh_disconnect_return, mesh_peer_path, NULL, NULL);
+ break;
+
+ case 'f':
+ if (num < 3) {
+ result = -EINVAL;
+ break;
+ }
+
+ if (num > 3) {
+ result = -E2BIG;
+ break;
+ }
+
+ mesh_peer_name = args[2];
+
+ if (check_dbus_name(mesh_peer_name) == false) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
+ mesh_peer_name);
+ result = __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ mesh_peer_path, "net.connman.Mesh", "Remove",
+ mesh_remove_return, mesh_peer_path, NULL, NULL);
+ break;
+
+ case 'C':
+ if (num > 2) {
+ result = -E2BIG;
+ break;
+ }
+
+ result = __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "GetConnectedMeshPeers",
+ connected_mesh_peers_list, NULL, NULL, NULL);
+ break;
+
+ case 'D':
+ if (num > 2) {
+ result = -E2BIG;
+ break;
+ }
+
+ result = __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager",
+ "GetDisconnectedMeshPeers",
+ disconnected_mesh_peers_list, NULL, NULL, NULL);
+ break;
+
+ case 'n':
+ if (num != 5) {
+ result = -EINVAL;
+ break;
+ }
+ path = g_strdup_printf("/net/connman/technology/mesh");
+
+ network = dbus_malloc0(sizeof(struct mesh_create_network));
+ network->name = g_strdup(args[2]);
+ network->freq = atoi(args[3]);
+ network->sec_type = g_strdup(args[4]);
+ method = g_strdup("MeshCreateNetwork");
+ result = __connmanctl_dbus_mesh_dict(connection, path,
+ "net.connman.Technology", mesh_return, method,
+ "MeshCreateNetwork", DBUS_TYPE_STRING,
+ mesh_create_network_append, network);
+ g_free(network->name);
+ g_free(network->sec_type);
+ g_free(network);
+ break;
+
+ case 'A':
+ if (num != 2) {
+ result = -EINVAL;
+ break;
+ }
+ path = g_strdup_printf("/net/connman/technology/mesh");
+
+ method = g_strdup("AbortScan");
+ result = __connmanctl_dbus_mesh_dict(connection, path,
+ "net.connman.Technology", mesh_return, method,
+ "AbortScan", DBUS_TYPE_STRING,
+ NULL, NULL);
+ break;
+
+ case 'S':
+ if (num != 4) {
+ result = -EINVAL;
+ break;
+ }
+ path = g_strdup_printf("/net/connman/technology/mesh");
+
+ scan_params = dbus_malloc0(sizeof(struct mesh_specific_scan_params));
+ scan_params->name = g_strdup(args[2]);
+ scan_params->freq = atoi(args[3]);
+ method = g_strdup("MeshSpecificScan");
+ result = __connmanctl_dbus_mesh_dict(connection, path,
+ "net.connman.Technology", mesh_return, method,
+ "MeshSpecificScan", DBUS_TYPE_STRING,
+ mesh_specific_scan_append, scan_params);
+ g_free(scan_params->name);
+ g_free(scan_params);
+ break;
+
+ case 'P':
+ if (num != 5) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_name = args[2];
+ property = args[3];
+ value = args[4];
+
+ if (check_dbus_name(mesh_peer_name) == false) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_path = g_strdup_printf("/net/connman/mesh/%s",
+ mesh_peer_name);
+
+ if (g_strcmp0(property, "Passphrase") == 0) {
+ result = __connmanctl_dbus_set_property(connection,
+ mesh_peer_path, "net.connman.Mesh",
+ mesh_config_return, mesh_peer_path, property,
+ DBUS_TYPE_STRING, &value);
+ } else {
+ printf("Invalid property %s\n", property);
+ result = -EINVAL;
+ }
+
+ break;
+
+ case 'G':
+ if (num != 5) {
+ result = -EINVAL;
+ break;
+ }
+
+ path = g_strdup_printf("/net/connman/technology/mesh");
+
+ gate_params = dbus_malloc0(sizeof(struct mesh_gate_params));
+ gate_params->gate_announce = atoi(args[2]);
+ gate_params->hwmp_rootmode = atoi(args[3]);
+ gate_params->stp = atoi(args[4]);
+
+ method = g_strdup("SetMeshGate");
+
+ result = __connmanctl_dbus_mesh_dict(connection, path,
+ "net.connman.Technology", mesh_return, method,
+ "SetMeshGate", DBUS_TYPE_STRING,
+ mesh_set_gate_append, gate_params);
+
+ break;
+
+ case 'z':
+ if (num != 3) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_addr = g_strdup(args[2]);
+ method = g_strdup("MeshAddPeer");
+
+ result = __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "MeshAddPeer",
+ mesh_return, method, mesh_peer_append,
+ mesh_peer_addr);
+
+ break;
+
+ case 'y':
+ if (num != 3) {
+ result = -EINVAL;
+ break;
+ }
+
+ mesh_peer_addr = g_strdup(args[2]);
+ method = g_strdup("MeshRemovePeer");
+
+ result = __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "MeshRemovePeer",
+ mesh_return, method, mesh_peer_append,
+ mesh_peer_addr);
+
+ break;
+
+ default:
+ result = -EINVAL;
+ break;
+ }
+
+ g_free(path);
+
+ if (result < 0) {
+ if (result != -EINPROGRESS)
+ printf("Error '%s': %s\n", args[1], strerror(-result));
+ }
+
+
+ return result;
+}
+#endif
+
static int cmd_tether(char *args[], int num, struct connman_option *options)
{
char *ssid, *passphrase;
@@ -2251,6 +2826,38 @@ static struct connman_option session_options[] = {
{ NULL, }
};
+#if defined TIZEN_EXT_WIFI_MESH
+static struct connman_option mesh_options[] = {
+ {"ifadd", 'a', "<ifname> <wifi_ifname>\n"
+ " [bridge_ifname] Add Virtual Mesh "
+ "interface"},
+ {"ifrmv", 'r', "<ifname> Remove Virtual Mesh "
+ "interface"},
+ {"peers", 'p', "[peer] Display Mesh peer "
+ "informations"},
+ {"connect", 'c', "<peer> Connect Mesh Peer"},
+ {"disconnect", 'd', "<peer> Disconnect Mesh Peer"},
+ {"remove", 'f', "<peer> Forget Mesh Peer"},
+ {"connected_peers", 'C', "[] Displays connected"
+ " Peer informations"},
+ {"disconnected_peers", 'D', "[] Displays "
+ "Disconnected Peer informations"},
+ {"create_network", 'n', "<name> <frequency> <sec_type> Create New Mesh "
+ "Network"},
+ {"abort_scan", 'A', " Abort ongoing mesh "
+ "scan"},
+ {"specific_scan", 'S', "<name> <frequency> Create New Mesh "
+ "Network"},
+ {"config", 'P', "<peer> Set Mesh Network "
+ "Configurations\n Passphrase <passphrase>"},
+ {"set_gate", 'G', "<gate_ann> <rootmode> <stp> Set Mesh Gate "
+ "Option"},
+ {"add_peer", 'z', "<addr> Add Mesh Peer"},
+ {"remove_peer", 'y', "<addr> Remove Mesh Peer"},
+ { NULL, }
+};
+#endif
+
static char *lookup_options(struct connman_option *options, const char *text,
int state)
{
@@ -2303,6 +2910,13 @@ static char *lookup_session(const char *text, int state)
return lookup_options(session_options, text, state);
}
+#if defined TIZEN_EXT_WIFI_MESH
+static char *lookup_mesh(const char *text, int state)
+{
+ return lookup_options(mesh_options, text, state);
+}
+#endif
+
static int peer_service_cb(DBusMessageIter *iter, const char *error,
void *user_data)
{
@@ -2614,6 +3228,10 @@ static const struct {
{ "disable", "<technology>|offline", NULL, cmd_disable,
"Disables given technology or offline mode",
lookup_technology_offline },
+#if defined TIZEN_EXT_WIFI_MESH
+ { "mesh", "", mesh_options, cmd_mesh, "Mesh specific commands",
+ lookup_mesh },
+#endif
{ "tether", "<technology> on|off\n"
" wifi [on|off] <ssid> <passphrase> ",
NULL, cmd_tether,
diff --git a/client/dbus_helpers.c b/client/dbus_helpers.c
index 6ca407d4..8c6bdbb3 100755..100644
--- a/client/dbus_helpers.c
+++ b/client/dbus_helpers.c
@@ -224,6 +224,11 @@ static int append_variant(DBusMessageIter *iter, const char *property,
case DBUS_TYPE_INT32:
type_str = DBUS_TYPE_INT32_AS_STRING;
break;
+#if defined TIZEN_EXT_WIFI_MESH
+ case DBUS_TYPE_UINT16:
+ type_str = DBUS_TYPE_UINT16_AS_STRING;
+ break;
+#endif
default:
return -EOPNOTSUPP;
}
@@ -354,6 +359,50 @@ int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
return send_method_call(connection, message, cb, user_data);
}
+#if defined TIZEN_EXT_WIFI_MESH
+int __connmanctl_dbus_mesh_dict(DBusConnection *connection,
+ const char *path, const char *interface,
+ connmanctl_dbus_method_return_func_t cb, void *user_data,
+ const char *property, int type,
+ connmanctl_dbus_append_func_t append_fn,
+ void *append_user_data)
+{
+ DBusMessage *message;
+ DBusMessageIter iter, variant, dict;
+
+ message = dbus_message_new_method_call(CONNMAN_SERVICE, path,
+ interface, "MeshCommands");
+
+ if (!message)
+ return -ENOMEM;
+
+ dbus_message_iter_init_append(message, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &property);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+ DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &variant);
+
+ dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+ &dict);
+
+ if (append_fn)
+ append_fn(&dict, append_user_data);
+
+ dbus_message_iter_close_container(&variant, &dict);
+ dbus_message_iter_close_container(&iter, &variant);
+
+ return send_method_call(connection, message, cb, user_data);
+}
+#endif
+
static void append_variant_array(DBusMessageIter *iter, const char *property,
connmanctl_dbus_append_func_t append_fn,
void *append_user_data)
diff --git a/client/dbus_helpers.h b/client/dbus_helpers.h
index 395808ac..69458395 100755..100644
--- a/client/dbus_helpers.h
+++ b/client/dbus_helpers.h
@@ -67,6 +67,15 @@ int __connmanctl_dbus_set_property_dict(DBusConnection *connection,
connmanctl_dbus_append_func_t append_fn,
void *append_user_data);
+#if defined TIZEN_EXT_WIFI_MESH
+int __connmanctl_dbus_mesh_dict(DBusConnection *connection,
+ const char *path, const char *interface,
+ connmanctl_dbus_method_return_func_t cb, void *user_data,
+ const char *property, int type,
+ connmanctl_dbus_append_func_t append_fn,
+ void *append_user_data);
+#endif
+
void __connmanctl_dbus_append_dict_string_array(DBusMessageIter *iter,
const char *property, connmanctl_dbus_append_func_t append_fn,
void *append_user_data);
diff --git a/client/mesh.c b/client/mesh.c
new file mode 100644
index 00000000..6e577934
--- /dev/null
+++ b/client/mesh.c
@@ -0,0 +1,166 @@
+/*
+ *
+ * Connection Manager
+ *
+ *
+ * Copyright (C) 2017 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "mesh.h"
+#include "dbus_helpers.h"
+
+static void print_mesh_peer(char *path, DBusMessageIter *iter)
+{
+ char *name = "";
+ char state = ' ';
+ char *str, *property;
+ DBusMessageIter entry, val;
+ int count = 0, favorite = 0;
+
+ while (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
+ dbus_message_iter_recurse(iter, &entry);
+ dbus_message_iter_get_basic(&entry, &property);
+
+ if (strcmp(property, "Name") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &name);
+ } else if (strcmp(property, "State") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &str);
+
+ if (str) {
+ if (strcmp(str, "online") == 0)
+ state = 'O';
+ else if (strcmp(str, "ready") == 0)
+ state = 'R';
+ else if (!strcmp(str, "association"))
+ state = 'a';
+ else if (!strcmp(str, "configuration"))
+ state = 'c';
+ else if (!strcmp(str, "disconnect"))
+ state = 'd';
+ }
+ } else if (strcmp(property, "Favorite") == 0) {
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &val);
+ dbus_message_iter_get_basic(&val, &favorite);
+ }
+
+ dbus_message_iter_next(iter);
+ count++;
+ }
+
+ str = strrchr(path, '/');
+ if (str)
+ str++;
+ else
+ str = path;
+
+ if (count > 0)
+ fprintf(stdout, "%c%c %-20s %s", favorite != 0 ? 'A' : ' ',
+ state, name, str);
+ else
+ fprintf(stdout, "%s %s", "unchanged", str);
+}
+
+static void list_mesh_peer_array(DBusMessageIter *iter)
+{
+ DBusMessageIter array, dict;
+ char *path = NULL;
+
+ while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRUCT) {
+ dbus_message_iter_recurse(iter, &array);
+ if (dbus_message_iter_get_arg_type(&array)
+ != DBUS_TYPE_OBJECT_PATH)
+ return;
+
+ dbus_message_iter_get_basic(&array, &path);
+
+ dbus_message_iter_next(&array);
+ if (dbus_message_iter_get_arg_type(&array)
+ == DBUS_TYPE_ARRAY) {
+ dbus_message_iter_recurse(&array, &dict);
+ print_mesh_peer(path, &dict);
+ }
+
+ if (dbus_message_iter_has_next(iter))
+ fprintf(stdout, "\n");
+
+ dbus_message_iter_next(iter);
+ }
+}
+
+void __connmanctl_mesh_peers_list(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+ char *path;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ list_mesh_peer_array(&array);
+
+ dbus_message_iter_next(iter);
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ fprintf(stdout, "\n}, {");
+
+ dbus_message_iter_recurse(iter, &array);
+ while (dbus_message_iter_get_arg_type(&array)
+ == DBUS_TYPE_OBJECT_PATH) {
+ dbus_message_iter_get_basic(&array, &path);
+ fprintf(stdout, "\n%s %s", "removed", path);
+
+ dbus_message_iter_next(&array);
+ }
+
+}
+
+void __connmanctl_mesh_connected_peers_list(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ __connmanctl_dbus_print(&array, " ", " = ", "\n");
+ fprintf(stdout, "\n");
+}
+
+void __connmanctl_mesh_disconnected_peers_list(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ __connmanctl_dbus_print(&array, " ", " = ", "\n");
+ fprintf(stdout, "\n");
+}
diff --git a/client/mesh.h b/client/mesh.h
new file mode 100644
index 00000000..8dd413d0
--- /dev/null
+++ b/client/mesh.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Connection Manager
+ *
+ *
+ * Copyright (C) 2017 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __CONNMANCTL_MESH_H
+#define __CONNMANCTL_MESH_H
+
+#include <dbus/dbus.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __connmanctl_mesh_peers_list(DBusMessageIter *iter);
+void __connmanctl_mesh_connected_peers_list(DBusMessageIter *iter);
+void __connmanctl_mesh_disconnected_peers_list(DBusMessageIter *iter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONNMANCTL_MESH_H */