Add interface to get mesh connected peers
authorJiwan Kim <ji-wan.kim@samsung.com>
Fri, 2 Jun 2017 07:19:53 +0000 (16:19 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 17 Jul 2017 02:35:36 +0000 (11:35 +0900)
- get_connected_peers added.

include/mesh-gdbus.h
include/mesh.h
introspection/mesh.xml
src/mesh-gdbus.c
src/mesh-service-interface.c

index 7207086..30ab605 100644 (file)
@@ -46,6 +46,7 @@ int mesh_ipc_mesh_specific_scan(mesh_service *service, gchar *mesh_id,
         gint channel);
 int mesh_ipc_mesh_cancel_scan(mesh_service *service);
 int mesh_ipc_get_mesh_peers(mesh_service *service);
+int mesh_ipc_get_connected_peers(mesh_service *service);
 int mesh_ipc_get_joined_mesh_network(mesh_service *service);
 
 int mesh_ipc_create_network(mesh_service *service, gchar *mesh_id, gint channel,
index 4dde086..ce9ee33 100644 (file)
@@ -66,6 +66,11 @@ typedef struct {
        gint data_rate; /**< Data rate */
 } mesh_scan_result_s;
 
+/**< Mesh peer structure */
+typedef struct {
+       gchar *address; /**< MAC address of connected peer */
+} mesh_peer_info_s;
+
 /**< Connected mesh network station */
 typedef struct {
        gchar *bssid; /* station bssid ex) 7c:dd:90:62:37:cf */
@@ -136,6 +141,7 @@ typedef struct _mesh_service {
        gboolean mesh_activated; /**< Stored if mesh network is activated */
        GList *saved_mesh_network; /**< Saved mesh network list */
        GList *scanned_mesh_network; /**< Scanned mesh network list */
+       GList *connected_mesh_peers; /**< Connected mesh peer list */
        mesh_network_info_s *joined_network; /**< Joined network info */
 
        GList *station_list; /**< Mesh station list */
index d06d4ed..d0a65db 100644 (file)
                        <arg type="aa{sv}" name="network" direction="out"/>\r
                        <arg type="i" name="result" direction="out"/>\r
                </method>\r
+               <method name="get_connected_peers">\r
+                       <arg type="aa{sv}" name="network" direction="out"/>\r
+                       <arg type="i" name="result" direction="out"/>\r
+               </method>\r
                <method name="enable_mesh">\r
                        <arg type="i" name="result" direction="out"/>\r
                </method>\r
index 1e6b217..d55f866 100644 (file)
@@ -462,6 +462,13 @@ static void _on_scan_result_destroy(gpointer data)
        }
 }
 
+static void _on_peer_info_destroy(gpointer data)
+{
+       mesh_peer_info_s *peer = (mesh_peer_info_s *)data;
+       if (peer)
+               g_free(peer->address);
+}
+
 static void _get_joined_network(mesh_service *service, GVariant *variant)
 {
        GVariantIter *peer = NULL;
@@ -608,6 +615,42 @@ static void _get_mesh_peers(mesh_service *service, GVariant *variant)
        g_variant_iter_free(peer);
 }
 
+static void _get_connected_mesh_peers(mesh_service *service, GVariant *variant)
+{
+       GVariantIter *peer = NULL;
+       GVariantIter *property = NULL;
+       gchar *key = NULL;
+       GVariant *val = NULL;
+       gsize len = 0;
+       GVariant *child;
+
+       g_variant_get(variant, "(a(a{sv}))", &peer);
+       while ((child = g_variant_iter_next_value(peer))) {
+               mesh_peer_info_s *peer_info = NULL;
+
+               peer_info = g_try_new0(mesh_peer_info_s, 1);
+               if (NULL == peer_info) {
+                       MESH_LOGE("Failed to allocate !");
+                       return;
+               }
+
+               g_variant_get(child, "(a{sv})", &property);
+               while (g_variant_iter_loop(property, "{sv}", &key, &val)) {
+                       if (strcasecmp(key, "PeerAddress") == 0)  {
+                               const char *buf = g_variant_get_string(val, &len);
+                               peer_info->address = g_strdup(buf);
+                               MESH_LOGD("    Address : %s", peer_info->address);
+                       }
+               }
+               /* Last element */
+               service->connected_mesh_peers =
+                       g_list_prepend(service->connected_mesh_peers, peer_info);
+
+               g_variant_iter_free(property);
+       }
+       g_variant_iter_free(peer);
+}
+
 int mesh_ipc_get_mesh_peers(mesh_service *service)
 {
        GVariant *variant = NULL;
@@ -645,6 +688,43 @@ int mesh_ipc_get_mesh_peers(mesh_service *service)
        return MESHD_ERROR_NONE;
 }
 
+int mesh_ipc_get_connected_peers(mesh_service *service)
+{
+       GVariant *variant = NULL;
+       GError *error = NULL;
+
+       meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
+       meshd_check_null_ret_error("connection", service->connection,
+                       MESHD_ERROR_INVALID_PARAMETER);
+       meshd_check_null_ret_error("_gproxy_connman",
+                       _gproxy_connman, MESHD_ERROR_IO_ERROR);
+
+       variant = g_dbus_proxy_call_sync(_gproxy_connman, "GetConnectedMeshPeers",
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+       if (variant) {
+               MESH_LOGD("Successfully requested. [GetConnectedMeshPeers]");
+
+               if (service->connected_mesh_peers) {
+                       g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy);
+                       service->connected_mesh_peers = NULL;
+               }
+
+               _get_connected_mesh_peers(service, variant);
+
+               /* List item is saved with reversed order for efficiency. */
+               service->connected_mesh_peers =
+                               g_list_reverse(service->connected_mesh_peers);
+       } else if (error) {
+               MESH_LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESHD_ERROR_IO_ERROR;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
 int mesh_ipc_get_joined_mesh_network(mesh_service *service)
 {
        GVariant *variant = NULL;
index d10704d..52a1e25 100644 (file)
@@ -547,6 +547,44 @@ static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object,
        return TRUE;
 }
 
+static gboolean _meshd_dbus_handle_get_connected_peers(NetMesh *object,
+               GDBusMethodInvocation *invocation,
+               gpointer user_data)
+{
+       int ret = MESHD_ERROR_NONE;
+       mesh_service *service = (mesh_service *)user_data;
+
+       GVariantBuilder builder;
+       GVariant* peer_list;
+       GList *iter = NULL;
+       mesh_peer_info_s *peer = NULL;
+
+       MESH_LOGD("Request to get connected peers");
+
+       ret = mesh_ipc_get_connected_peers(service);
+       if (MESHD_ERROR_NONE != ret)
+               MESH_LOGE("Failed to mesh_ipc_get_connected_peers");
+       g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
+
+       iter = service->connected_mesh_peers;
+       while (iter != NULL) {
+               peer = (mesh_peer_info_s*)iter->data;
+
+               g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
+               g_variant_builder_add(&builder, "{sv}", "Address",
+                               g_variant_new_string(peer->address));
+               g_variant_builder_close(&builder);
+
+               iter = g_list_next(iter);
+       }
+
+       peer_list = g_variant_builder_end(&builder);
+
+       net_mesh_complete_get_connected_peers(object, invocation, peer_list, ret);
+
+       return TRUE;
+}
+
 static gboolean _meshd_dbus_handle_set_gate(NetMesh *object,
                GDBusMethodInvocation *invocation, gboolean stp, gboolean gate_announce,
                gpointer user_data)
@@ -1105,6 +1143,8 @@ static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name
                        G_CALLBACK(_meshd_dbus_handle_disable_mesh), service);
        g_signal_connect(meshd_dbus_object, "handle-get-joined-mesh-network",
                        G_CALLBACK(_meshd_dbus_handle_get_joined_mesh_network), service);
+       g_signal_connect(meshd_dbus_object, "handle-get-connected-peers",
+                       G_CALLBACK(_meshd_dbus_handle_get_connected_peers), service);
        g_signal_connect(meshd_dbus_object, "handle-set-gate",
                        G_CALLBACK(_meshd_dbus_handle_set_gate), service);
        g_signal_connect(meshd_dbus_object, "handle-unset-gate",