Add some new API for connected peers
authorJiwan Kim <ji-wan.kim@samsung.com>
Fri, 2 Jun 2017 07:02:03 +0000 (16:02 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 17 Jul 2017 02:09:10 +0000 (11:09 +0900)
- mesh_foreach_connected_peers() added.
- mesh_peer_get_address() added.
- Update mesh_get_joined_network() to return MESH_ERROR_NONE
  if no joined network exists.

include/mesh.h
include/mesh_dbus.h
include/mesh_private.h
src/mesh.c
src/mesh_dbus.c
test/mesh_network.c

index 8b34e28a9d70a0c5a1ce911f9780c252b306d014..28df4d9bf6a8a4304c2a7ea334196394b89c2e7d 100644 (file)
@@ -160,6 +160,12 @@ typedef struct {
 */
 typedef void* mesh_network_h;
 
+/**
+ * @brief The mesh network peer handle.
+ * @since_tizen 4.0
+*/
+typedef void* mesh_peer_h;
+
 /**
  * @brief The mesh station information handle.
  * @since_tizen 4.0
@@ -267,13 +273,16 @@ void mesh_network_destroy(mesh_network_h network);
 /**
  * @brief Gets network mesh network id.
  * @details This function is to return mesh network id
+ * @remark The returned string should be freed when no longer needed.
  *
  * @since_tizen 4.0
  *
  * @param[in] network The mesh network information handle.
  * @param[out] meshid The mesh network id.
  *
- * @return None
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESH_ERROR_NONE Successful
+ * @retval #MESH_ERROR_INVALID_PARAMETER Invalid parameter
  *
  * @see mesh_network_set_meshid()
  *
@@ -301,6 +310,7 @@ int mesh_network_set_meshid(mesh_network_h network, const char *meshid);
 /**
  * @brief Gets BSSID.
  * @details This function is to get basic service set id
+ * @remark The returned string should be freed when no longer needed.
  *
  * @since_tizen 4.0
  *
@@ -442,6 +452,23 @@ int mesh_network_get_data_rate(mesh_network_h network, int *data_rate);
  */
 int mesh_network_set_data_rate(mesh_network_h network, int data_rate);
 
+/**
+ * @brief Gets address from mesh peer.
+ * @details This function is to return mesh network id
+ * @remark The returned string should be freed when no longer needed.
+ *
+ * @since_tizen 4.0
+ *
+ * @param[in] peer The mesh peer information handle.
+ * @param[out] address The address of mesh peer.
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESH_ERROR_NONE Successful
+ * @retval #MESH_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ */
+int mesh_peer_get_address(mesh_peer_h peer, char **address);
+
 /**
  * @brief Initializes Mesh network.
  * @since_tizen 4.0
@@ -666,6 +693,44 @@ typedef void (*mesh_found_mesh_network_cb)(mesh_network_h network, void* user_da
 int mesh_foreach_found_mesh_network(mesh_h handle,
        mesh_found_mesh_network_cb cb, void *user_data);
 
+/**
+ * @brief Called after mesh_foreach_connected_peers()
+ * @details This function can receive connected peers on mesh network.
+ *
+ * @since_tizen 4.0
+ *
+ * @param[out] network The mesh peer information handle
+ * @param[out] user_data user data pointer
+ *
+ * @pre The callback must be registered with mesh_foreach_connected_peers()
+ *
+ * @see mesh_foreach_connected_peers()
+ */
+typedef void (*mesh_connected_peer_cb)(mesh_peer_h peer, void* user_data);
+
+/**
+ * @brief Gets found mesh network peer information
+ * @details This function returns network information found through mesh_connected_peer_cb.
+ *
+ * @since_tizen 4.0
+ *
+ * @param[in] handle The mesh handle
+ * @param[in] cb callback function pointer to inform peer information
+ * @param[in] user_data user data pointer
+ *
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MESH_ERROR_NONE Successful
+ * @retval #MESH_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MESH_ERROR_IO_ERROR Unexpected d-bus error
+ *
+ * @see mesh_find_peers()
+ * @see mesh_connected_peer_cb()
+ *
+ */
+int mesh_foreach_connected_peers(mesh_h handle,
+       mesh_connected_peer_cb cb, void *user_data);
+
 /**
  * @brief Enables the mesh network.
  * @details This function is to join or create mesh network using saved mesh network configuration
index 86e34511d37ede40d8e3a5498ca2a832614b7f2e..b75e70487eb03fb7e82fa6a31b99d0c72d597f0a 100644 (file)
@@ -45,6 +45,9 @@ int _mesh_cancel_scan(mesh_h handle);
 int _mesh_get_scan_result(mesh_h handle);
 int _mesh_foreach_found_mesh_network(mesh_h handle,
        mesh_found_mesh_network_cb cb, void *user_data);
+int _mesh_find_peers(mesh_h handle);
+int _mesh_foreach_connected_peers(mesh_h handle,
+       mesh_connected_peer_cb cb, void *user_data);
 int _mesh_enable_mesh(mesh_h handle);
 int _mesh_disable_mesh(mesh_h handle);
 int _mesh_is_joined(mesh_h handle, int* is_joined);
index 73e10d3345784fa3d3757d762c157afb1728add5..09b82e2ed354acf3cd9177cbbb96a3698ec7a3a9 100644 (file)
@@ -68,6 +68,9 @@ typedef struct mesh_handle {
 #endif
 } mesh_handle_s;
 
+struct mesh_peer_s {
+       char address[MAX_BSSID_LEN]; /**< Peer address */
+};
 
 struct mesh_network_s {
        char meshid[MAX_MESHID_LEN]; /**< Mesh ID */
index 593b09f1aba2c2b6f6da4c11dda35a85396a762d..a96ad6dd71cf7fafdde34330d4d682a08cc0b0cb 100644 (file)
@@ -120,8 +120,7 @@ EXPORT_API int mesh_network_get_meshid(mesh_network_h network, char **meshid)
                return MESH_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
        }
 
-       LOGE("net->meshid = %s", net->meshid);
-       *meshid = net->meshid;
+       *meshid = strdup(net->meshid);
 
        return MESH_ERROR_NONE;
 }
@@ -153,7 +152,8 @@ EXPORT_API int mesh_network_get_bssid(mesh_network_h network, char **bssid)
                return MESH_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
        }
 
-       *bssid = net->bssid;
+       *bssid = strdup(net->bssid);
+
        return MESH_ERROR_NONE;
 }
 
@@ -269,6 +269,22 @@ EXPORT_API int mesh_network_set_data_rate(mesh_network_h network, int data_rate)
        return MESH_ERROR_NONE;
 }
 
+EXPORT_API int mesh_peer_get_address(mesh_peer_h peer, char **address)
+{
+       struct mesh_peer_s *peer_info = (struct mesh_peer_s *)peer;
+
+       CHECK_FEATURE_SUPPORTED(MESH_FEATURE);
+
+       if (peer == NULL) {
+               LOGE("Invalid parameter"); //LCOV_EXCL_LINE
+               return MESH_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
+       }
+
+       *address = strdup(peer_info->address);
+
+       return MESH_ERROR_NONE;
+}
+
 EXPORT_API int mesh_initialize(mesh_h *mesh)
 {
        int rv;
@@ -404,6 +420,24 @@ EXPORT_API int mesh_foreach_found_mesh_network(mesh_h handle,
        return rv;
 }
 
+EXPORT_API int mesh_foreach_connected_peers(mesh_h handle,
+       mesh_connected_peer_cb cb, void *user_data)
+{
+       int rv = 0;
+       CHECK_FEATURE_SUPPORTED(MESH_FEATURE);
+
+       RETV_IF(NULL == cb, MESH_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == handle, MESH_ERROR_INVALID_PARAMETER);
+
+       rv = _mesh_find_peers(handle);
+       if (MESH_ERROR_NONE != rv) {
+               return rv;
+       }
+
+       rv = _mesh_foreach_connected_peers(handle, cb, user_data);
+       return rv;
+}
+
 EXPORT_API int mesh_enable_mesh(mesh_h handle)
 {
        int rv = 0;
index e9fc5ac0f584a91a2092b8b988e29c42b2b6a81e..ff793261baec54c98467ec2457f1859daf2e5a71 100644 (file)
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <stdlib.h>
+
 #include "mesh.h"
 #include "mesh_log.h"
 #include "mesh_dbus.h"
@@ -124,32 +126,37 @@ static int _mesh_close_gdbus_call(mesh_h handle)
        return MESH_ERROR_NONE;
 }
 
-struct mesh_network_list_s {
-       int count;
-       GList *list;
-};
-struct mesh_network_list_s g_networks;
-
+static GList *g_networks = { 0, };
 static void _mesh_free_network(gpointer data)
 {
        struct mesh_network_s *network = data;
-       if (network) g_free(network);
+       g_free(network);
        network = NULL;
 }
 
+static void _mesh_remove_networks()
+{
+       if (g_networks)
+               g_list_free_full(g_networks, _mesh_free_network);
+       g_networks = NULL;
+}
+
 static void _mesh_append_network(gpointer data)
 {
-       g_networks.list = g_list_append(g_networks.list, data);
-       g_networks.count++;
-       LOGE("%dth item added", g_networks.count);
+       g_networks = g_list_append(g_networks, data);
 }
 
-static void _mesh_remove_networks()
+static GList *g_peers = NULL;
+static void _mesh_remove_peers()
 {
-       if (g_networks.list)
-               g_list_free_full(g_networks.list, _mesh_free_network);
-       g_networks.list = NULL;
-       g_networks.count = 0;
+       if (g_peers)
+               g_list_free(g_peers);
+       g_peers = NULL;
+}
+
+static void _mesh_append_peer(gpointer data)
+{
+       g_peers = g_list_append(g_peers, data);
 }
 
 int _mesh_get_scan_result(mesh_h handle)
@@ -219,6 +226,59 @@ int _mesh_get_scan_result(mesh_h handle)
        return result;
 }
 
+int _mesh_find_peers(mesh_h handle)
+{
+       GVariant *variant = NULL;
+       int result = MESH_ERROR_NONE;
+       GError *error = NULL;
+       struct mesh_handle *h = handle;
+
+       GVariantIter *iter = NULL;
+       GVariantIter *iter_row = NULL;
+
+       gchar *key;
+       GVariant *val;
+       gsize len = 0;
+
+       /* Clear previous peer list */
+       _mesh_remove_peers();
+
+       RETV_IF(NULL == h->dbus_connection, MESH_ERROR_IO_ERROR);
+       RETV_IF(NULL == _gproxy_mesh_service, MESH_ERROR_IO_ERROR);
+
+       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "get_connected_peers",
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL, &error);
+       if (variant) {
+               g_variant_get(variant, "(aa{sv}i)", &iter, &result);
+               result = __convert_service_error_type(result);
+               while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
+                       struct mesh_peer_s *peer_info =
+                               g_malloc0(sizeof(struct mesh_peer_s));
+                       while (g_variant_iter_loop(iter_row, "{sv}", &key, &val)) {
+                               if (strcasecmp(key, "Address") == 0)  {
+                                       const char *buf = g_variant_get_string(val, &len);
+                                       memcpy(peer_info->address, buf, len);
+                                       LOGD("  Address [%s]", peer_info->address);
+                               }
+                       }
+                       /* Last element */
+                       _mesh_append_peer(peer_info);
+                       g_variant_iter_free(iter_row);
+               }
+               g_variant_iter_free(iter);
+
+       } else if (error) {
+               LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESH_ERROR_IO_ERROR;
+       }
+
+       return result;
+}
+
 static void _mesh_signal_handler(GDBusConnection *connection,
                const gchar *sender_name, const gchar *object_path, const gchar *interface_name,
                const gchar *signal_name, GVariant *parameters, gpointer user_data)
@@ -459,6 +519,7 @@ int _mesh_disable(mesh_h handle)
        GError *error = NULL;
        struct mesh_handle *h = handle;
 
+       _mesh_remove_peers();
        _mesh_remove_networks();
        _mesh_remove_mpath();
 
@@ -582,14 +643,48 @@ int _mesh_foreach_found_mesh_network(mesh_h handle,
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ERROR_IO_ERROR);
        RETV_IF(NULL == cb, MESH_ERROR_INVALID_PARAMETER);
 
-       if (0 >= g_list_length(g_networks.list)) {
+       if (0 >= g_list_length(g_networks)) {
                LOGD("No scan result");
                return MESH_ERROR_NONE;
        }
 
        /* Get a first item */
        i = 0;
-       iter = g_list_first(g_networks.list);
+       iter = g_list_first(g_networks);
+
+       while (NULL != iter) {
+               data = iter->data;
+               if (data)
+                       LOGE("data is null");
+               cb(data, user_data);
+               /* Next item */
+               iter = g_list_next(iter);
+               i++;
+       }
+
+       return MESH_ERROR_NONE;
+}
+
+int _mesh_foreach_connected_peers(mesh_h handle,
+       mesh_connected_peer_cb cb, void *user_data)
+{
+       int i;
+       GList *iter = NULL;
+       struct mesh_network_s *data = NULL;
+       struct mesh_handle *h = handle;
+
+       RETV_IF(NULL == h->dbus_connection, MESH_ERROR_IO_ERROR);
+       RETV_IF(NULL == _gproxy_mesh_service, MESH_ERROR_IO_ERROR);
+       RETV_IF(NULL == cb, MESH_ERROR_INVALID_PARAMETER);
+
+       if (0 >= g_list_length(g_peers)) {
+               LOGD("No peer data");
+               return MESH_ERROR_NONE;
+       }
+
+       /* Get a first item */
+       i = 0;
+       iter = g_list_first(g_peers);
 
        while (NULL != iter) {
                data = iter->data;
@@ -711,26 +806,40 @@ int _mesh_get_joined_mesh_network(mesh_h handle, mesh_network_h* _network)
                char *meshid = NULL;
                char *bssid = NULL;
                int channel = -1;
+               int svc_result = 0;
 
-               g_variant_get(variant, "(ssii)", &meshid, &bssid, &channel, &result);
-               LOGD("get_joined_mesh_network status 0x%x", result);
-               result = __convert_service_error_type(result);
+               g_variant_get(variant, "(ssii)", &meshid, &bssid, &channel, &svc_result);
+               LOGD("get_joined_mesh_network status 0x%x", svc_result);
+               result = __convert_service_error_type(svc_result);
+
+               /* Clear previous information */
+               memset(g_joined_network.meshid, 0, MAX_MESHID_LEN);
+               memset(g_joined_network.bssid, 0, MAX_BSSID_LEN);
+               g_joined_network.channel = 0;
+               g_joined_network.rssi = -1;
+               g_joined_network.data_rate = 0;
+               g_joined_network.security = 0;
+
+               if (SERVICE_ERROR_NO_DATA == svc_result) {
+                       *_network = NULL;
+                       return MESH_ERROR_NONE;
+               }
 
                if (MESH_ERROR_NONE != result)
                        return result;
 
                if (meshid) {
                        LOGE("  Mesh ID : %s", meshid);
-                       memcpy(g_joined_network.meshid, meshid, MAX_MESHID_LEN);
+                       g_snprintf(g_joined_network.meshid, MAX_MESHID_LEN, "%s", meshid);
                }
                if (bssid) {
                        LOGE("  BSSID   : %s", bssid);
-                       memcpy(g_joined_network.bssid, bssid, MAX_BSSID_LEN);
+                       g_snprintf(g_joined_network.bssid, MAX_BSSID_LEN, "%s", bssid);
                }
                g_joined_network.channel = channel;
                g_joined_network.rssi = -1;
 
-               *_network= &g_joined_network;
+               *_network = &g_joined_network;
        } else if (error) {
                LOGE("Failed DBus call [%s]", error->message);
                g_error_free(error);
index e14bcc3164ac9233e8a34f9da30e29d74fd31481..1cc76ecaa524f06c5906e15fcf3c86f781788f8b 100644 (file)
@@ -49,7 +49,7 @@ static char network_idx[MENU_DATA_SIZE + 1] = "1";
 static int g_scan_net_idx = 0;
 GList *g_found_network_list = NULL;
 
-void found_mesh_network_cb(mesh_network_h network, void* user_data)
+static void found_mesh_network_cb(mesh_network_h network, void* user_data)
 {
        int ret;
        mesh_network_h net = NULL;
@@ -71,6 +71,20 @@ void found_mesh_network_cb(mesh_network_h network, void* user_data)
        msgb("  [%02d] Mesh ID[%-10s] BSSID[%s] Channel[%d]", g_scan_net_idx, meshid, bssid, channel);
 
        g_scan_net_idx++;
+
+       if (meshid) free(meshid);
+       if (bssid) free(bssid);
+}
+
+static void connected_peer_cb(mesh_peer_h peer, void* user_data)
+{
+       char *address = NULL;
+
+       mesh_peer_get_address(peer, &address);
+       msgb("  Peer Address [%s]", address);
+
+       if (address)
+               free(address);
 }
 
 static void found_station_cb(mesh_station_info_h station, void* user_data)
@@ -103,6 +117,9 @@ static int run_show_found_network(MManager *mm, struct menu_data *menu)
                mesh_network_get_meshid(_net, &_meshid);
                mesh_network_get_channel(_net, &_channel);
                msgb("  [%02d] Mesh ID[%-10s] Channel[%d]", i++, _meshid, _channel);
+
+               if (_meshid) free(_meshid);
+
                iter = g_list_next(iter);
        }
 
@@ -227,7 +244,7 @@ static int run_get_joined_mesh_network(MManager *mm, struct menu_data *menu)
 
        ret = mesh_get_joined_network(mesh, &network);
        if (MESH_ERROR_NONE != ret) {
-               msgr("Failed to enable mesh network: [%s(0x%X)]",
+               msgr("Failed to get joined mesh network: [%s(0x%X)]",
                        mesh_error_to_string(ret), ret);
                return RET_FAILURE;
        }
@@ -242,7 +259,27 @@ static int run_get_joined_mesh_network(MManager *mm, struct menu_data *menu)
                msgp("  BSSID   = %s", _bssid);
                mesh_network_get_channel(network, &_channel);
                msgp("  Channel = %d", _channel);
+
+               if (_meshid) free(_meshid);
+               if (_bssid) free(_bssid);
+       }
+       return RET_SUCCESS;
+}
+
+static int run_get_connected_peers(MManager *mm, struct menu_data *menu)
+{
+       int ret;
+       msg("Get Connected Mesh Peers");
+
+       ret = mesh_foreach_connected_peers(mesh, connected_peer_cb, NULL);
+       if (MESH_ERROR_NONE != ret) {
+               msgr("Failed to mesh_foreach_connected_peers: [%s(0x%X)]",
+                               mesh_error_to_string(ret), ret);
+               return RET_FAILURE;
        }
+       msg(" - mesh_foreach_connected_peers() ret: [0x%X] [%s]",
+                       ret, mesh_error_to_string(ret));
+
        return RET_SUCCESS;
 }
 
@@ -587,7 +624,8 @@ struct menu_data menu_mesh_network[] = {
        { "14", "Connect network", menu_connect_network, NULL, NULL },
        { "15", "Disconnect network", menu_disconnect_network, NULL, NULL },
        { "16", "Forget network", menu_forget_network, NULL, NULL },
-       { "17", "Get mesh station information", NULL, run_get_station_information, NULL },
-       { "18", "Get mesh path information", NULL, run_get_mpath_information, NULL },
+       { "17", "Get connected mesh peers", NULL, run_get_connected_peers, NULL },
+       { "18", "Get mesh station information", NULL, run_get_station_information, NULL },
+       { "19", "Get mesh path information", NULL, run_get_mpath_information, NULL },
        { NULL, NULL, },
 };