From: Jiwan Kim Date: Fri, 2 Jun 2017 07:02:03 +0000 (+0900) Subject: Add some new API for connected peers X-Git-Tag: submit/tizen/20170828.225740~37 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=350d81697a2d6a5065a1bc7af87178d1666e6dbc;p=platform%2Fcore%2Fapi%2Fwifi-mesh.git Add some new API for connected peers - 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. --- diff --git a/include/mesh.h b/include/mesh.h index 8b34e28..28df4d9 100644 --- a/include/mesh.h +++ b/include/mesh.h @@ -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 diff --git a/include/mesh_dbus.h b/include/mesh_dbus.h index 86e3451..b75e704 100644 --- a/include/mesh_dbus.h +++ b/include/mesh_dbus.h @@ -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); diff --git a/include/mesh_private.h b/include/mesh_private.h index 73e10d3..09b82e2 100644 --- a/include/mesh_private.h +++ b/include/mesh_private.h @@ -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 */ diff --git a/src/mesh.c b/src/mesh.c index 593b09f..a96ad6d 100644 --- a/src/mesh.c +++ b/src/mesh.c @@ -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; diff --git a/src/mesh_dbus.c b/src/mesh_dbus.c index e9fc5ac..ff79326 100644 --- a/src/mesh_dbus.c +++ b/src/mesh_dbus.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + #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); diff --git a/test/mesh_network.c b/test/mesh_network.c index e14bcc3..1cc76ec 100644 --- a/test/mesh_network.c +++ b/test/mesh_network.c @@ -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, }, };