X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fmesh-service-interface.c;h=a37fca0900c96505c54d28f3b63f5964ba7e2ec8;hb=3e7951a874eac322fc5d9eaa8cea047361a77b0b;hp=376f7cc2c92d8b251acaa64847cdc2283f319ed9;hpb=f1c78eb795efc35129ce5ddbf4934bdc88b8182b;p=platform%2Fcore%2Fconnectivity%2Fwifi-mesh-manager.git diff --git a/src/mesh-service-interface.c b/src/mesh-service-interface.c index 376f7cc..a37fca0 100644 --- a/src/mesh-service-interface.c +++ b/src/mesh-service-interface.c @@ -25,6 +25,8 @@ #include "mesh.h" #include "mesh-log.h" #include "mesh-util.h" +#include "mesh-gdbus.h" +#include "mesh-service.h" #include "mesh-service-interface.h" #include "mesh-generated-code.h" @@ -32,6 +34,7 @@ #include "mesh-interface.h" static NetMesh *meshd_dbus_object; +static Manager *meshd_activator_dbus_object; /* global list to care resource handle for each client */ static GList *meshd_dbus_client_list; @@ -142,7 +145,7 @@ static int _meshd_dbus_subscribe_name_owner_changed(GDBusConnection *conn) return MESHD_ERROR_NONE; } -static gboolean _meshd_dbus_handle_enable(NetMesh *object, +static gboolean _meshd_dbus_handle_enable(Manager *object, GDBusMethodInvocation *invocation, gpointer user_data) { @@ -152,16 +155,21 @@ static gboolean _meshd_dbus_handle_enable(NetMesh *object, if (service->mesh_activated) { /* Already activated */ - net_mesh_complete_enable(object, invocation, - MESHD_ERROR_OPERATION_FAILED); - } else { - /* Do API response first */ - net_mesh_complete_enable(object, invocation, ret); - service->mesh_activated = TRUE; + manager_complete_enable(object, invocation, MESHD_ERROR_NONE); + goto FINISH; } + /* Do API response first */ + manager_complete_enable(object, invocation, ret); + service->mesh_activated = TRUE; + meshd_check_null_ret_error("info", info, FALSE); + /* Register event handler first */ + ret = mesh_request_register_event_handler(); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to register mesh event handler !! [%d]", ret); + ret = mesh_interface_initialize(service->interface_info); if (MESHD_ERROR_NONE != ret) { MESH_LOGE("Failed to mesh_interface_initialize [%d]", ret); @@ -169,12 +177,12 @@ static gboolean _meshd_dbus_handle_enable(NetMesh *object, } FINISH: - net_mesh_emit_mesh_enabled(object, ret); + net_mesh_emit_mesh_enabled(meshd_dbus_get_object(), ret); return TRUE; } -static gboolean _meshd_dbus_handle_disable(NetMesh *object, +static gboolean _meshd_dbus_handle_disable(Manager *object, GDBusMethodInvocation *invocation, gpointer user_data) { @@ -184,24 +192,15 @@ static gboolean _meshd_dbus_handle_disable(NetMesh *object, meshd_check_null_ret_error("info", info, FALSE); - if (FALSE == service->mesh_activated) { - MESH_LOGD("Mesh network is not activated yet"); - ret = MESHD_ERROR_OPERATION_FAILED; - goto FINISH; - } + /* Make response first */ + manager_complete_disable(object, invocation, ret); - ret = mesh_request_disable_mesh(info->mesh_interface); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_disable_mesh_gate"); - } + ret = mesh_request_unregister_event_handler(); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to unregister mesh event handler !! [%d]", ret); - ret = mesh_request_remove_bridge(info->bridge_interface); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_remove_bridge"); - } - -FINISH: - net_mesh_complete_disable(object, invocation, ret); + /* Terminate daemon */ + meshd_service_exit(service); return TRUE; } @@ -216,19 +215,9 @@ static gboolean _meshd_dbus_handle_scan(NetMesh *object, meshd_check_null_ret_error("info", info, FALSE); - ret = mesh_request_scan(info->mesh_interface); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_scan on mesh interface[%s] !", - info->mesh_interface); - } - - /* Fall-back */ - if (MESHD_ERROR_IN_PROGRESS != ret) { - ret = mesh_request_scan(info->base_interface); - if (MESHD_ERROR_NONE != ret) - MESH_LOGE("Failed to mesh_request_scan on base interface[%s] !", - info->base_interface); - } + ret = mesh_request_scan(service); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_scan !"); net_mesh_complete_scan(object, invocation, ret); @@ -247,19 +236,9 @@ static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object, meshd_check_null_ret_error("info", info, FALSE); - ret = mesh_request_specific_scan(info->mesh_interface, mesh_id, channel); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_specific_scan on mesh interface[%s]", - info->mesh_interface); - } - - /* Fall-back */ - if (MESHD_ERROR_IN_PROGRESS != ret) { - ret = mesh_request_specific_scan(info->base_interface, mesh_id, channel); - if (MESHD_ERROR_NONE != ret) - MESH_LOGE("Failed to mesh_request_specific_scan on base interface[%s]", - info->base_interface); - } + ret = mesh_request_specific_scan(service, mesh_id, channel); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_specific_scan !"); net_mesh_complete_specific_scan(object, invocation, ret); @@ -272,12 +251,10 @@ static gboolean _meshd_dbus_handle_cancel_scan(NetMesh *object, { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; - mesh_interface_s *info = service->interface_info; - ret = mesh_request_cancel_scan(info->mesh_interface); - if (MESHD_ERROR_NONE != ret) { + ret = mesh_request_cancel_scan(service); + if (MESHD_ERROR_NONE != ret) MESH_LOGE("Failed to mesh_request_cancel_scan"); - } net_mesh_complete_cancel_scan(object, invocation, ret); @@ -291,6 +268,38 @@ static void _on_scan_result_destroy(gpointer data) if (scan_item) { g_free(scan_item->mesh_id); g_free(scan_item->bssid); + g_free(scan_item->object_path); + } + g_free(scan_item); +} + +static void _on_peer_info_destroy(gpointer data) +{ + mesh_peer_info_s *peer = (mesh_peer_info_s *)data; + if (peer) + g_free(peer->address); + g_free(peer); +} + +static void _on_station_list_destroy(gpointer data) +{ + mesh_station_info_s *info = (mesh_station_info_s*)data; + + if (info) { + g_free(info->bssid); + g_free(info); + } +} + +static void _on_mpath_list_destroy(gpointer data) +{ + mesh_mpath_info_s *info = (mesh_mpath_info_s*)data; + + if (info) { + g_free(info->dest_addr); + g_free(info->next_hop); + g_free(info->interface); + g_free(info); } } @@ -300,7 +309,6 @@ static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object, { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; - mesh_interface_s *info = service->interface_info; GVariantBuilder builder; GVariant* networks; @@ -309,24 +317,13 @@ static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object, MESH_LOGD("Request to get scanned mesh network list"); - ret = mesh_request_get_scan_result(info->mesh_interface, &service->scanned_mesh_network); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_get_scan_result"); - - /* Fall-back */ - ret = mesh_request_get_scan_result(info->base_interface, - &service->scanned_mesh_network); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_get_scan_result on base interface[%s]", - info->base_interface); - - g_dbus_method_invocation_return_error(invocation, - G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed"); - } - } + ret = mesh_request_get_networks(service); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_get_networks"); g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + /* scanned_mesh_network would be filled above request */ iter = service->scanned_mesh_network; while (iter != NULL) { scan_item = (mesh_scan_result_s*)iter->data; @@ -337,21 +334,20 @@ static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object, g_variant_builder_add(&builder, "{sv}", "bssid", g_variant_new_string(scan_item->bssid)); g_variant_builder_add(&builder, "{sv}", "rssi", - g_variant_new_uint32(scan_item->rssi)); + g_variant_new_int32(scan_item->rssi)); g_variant_builder_add(&builder, "{sv}", "channel", g_variant_new_uint32(scan_item->channel)); - g_variant_builder_add(&builder, "{sv}", "data_rate", - g_variant_new_uint32(scan_item->data_rate)); + g_variant_builder_add(&builder, "{sv}", "security", + g_variant_new_uint32((int)scan_item->security)); + g_variant_builder_add(&builder, "{sv}", "state", + g_variant_new_uint32(scan_item->state)); g_variant_builder_close(&builder); iter = g_list_next(iter); } - /* Clear scan list */ - g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy); - service->scanned_mesh_network = NULL; - networks = g_variant_builder_end(&builder); + net_mesh_complete_get_found_mesh_networks(object, invocation, networks, ret); return TRUE; @@ -363,53 +359,21 @@ static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object, { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; - mesh_interface_s *info = service->interface_info; - /* TODO: Create or join mesh network and create bridge */ - ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_enable_mesh [%d]", ret); - goto FINISH; - } - - ret = mesh_request_create_bridge(info->bridge_interface, info->mesh_interface); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret); - goto FINISH; - } + /* It handles creating virtual network and bridge */ + ret = mesh_request_enable_network(service); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_enable_network [%d]", ret); - ret = mesh_request_join_mesh(info->mesh_interface, - service->saved_mesh_network, &service->joined_network); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_join_mesh [%d]", ret); - goto FINISH; - } - - /* TODO: Detect external network state (i.e. Ethernet) +#if 0 + /* Detect external network state (i.e. Ethernet) and decide to make gate enabled */ ret = mesh_request_set_mesh_gate(info->bridge_interface, info->mesh_interface, info->external_interface); - if (MESHD_ERROR_NONE != ret) { + if (MESHD_ERROR_NONE != ret) MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret); - } - ret = MESHD_ERROR_NONE; - - /* TODO: Notify bridge status to Connman */ - -#if 0 - ret = mesh_request_specific_scan(info->mesh_interface, - info->mesh_id, info->mesh_channel); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_specific_scan [%d]", ret); - } - - ret = mesh_dhcp_request(info->bridge_interface); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_dhcp_request [%d]", ret); - } #endif -FINISH: net_mesh_complete_enable_mesh(object, invocation, ret); return TRUE; @@ -421,16 +385,22 @@ static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object, { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; + mesh_interface_s *info = service->interface_info; - MESH_LOGD("Not implemented yet !"); + meshd_check_null_ret_error("info", info, FALSE); - /* TODO: Destroy bridge and return from mesh to infra mode */ - if (service->joined_network) { - g_free(service->joined_network->mesh_id); - g_free(service->joined_network); - service->joined_network = NULL; + if (FALSE == service->mesh_activated) { + MESH_LOGD("Mesh network is not activated yet"); + ret = MESHD_ERROR_OPERATION_FAILED; + net_mesh_complete_disable_mesh(object, invocation, ret); + return TRUE; } + ret = mesh_request_disable_network(service); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to disable mesh network !"); + + /* Make response */ net_mesh_complete_disable_mesh(object, invocation, ret); return TRUE; @@ -442,21 +412,63 @@ static gboolean _meshd_dbus_handle_get_joined_mesh_network(NetMesh *object, { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; - mesh_network_info_s *joined = service->joined_network; - - //gchar *meshid = strdup("meshnet"); - //gchar *bssid = strdup("7c:dd:90:d8:2a:64"); - //gint channel = 161; - //gint max_speed = 866; - - if (joined) { - net_mesh_complete_get_joined_mesh_network(object, invocation, - joined->mesh_id, "", joined->channel, 0, ret); + mesh_network_info_s *joined = NULL; + + ret = mesh_request_get_joined_network(service); + if (MESHD_ERROR_NONE == ret) { + joined = service->joined_network; + if (joined) { + net_mesh_complete_get_joined_mesh_network(object, invocation, + joined->mesh_id, joined->bssid, + joined->channel, (int)joined->security, + joined->state, ret); + } else { + net_mesh_complete_get_joined_mesh_network(object, invocation, + "", "", 0, 0, 0, MESHD_ERROR_NO_DATA); + } } else { net_mesh_complete_get_joined_mesh_network(object, invocation, - "", "", 0, 0, MESHD_ERROR_NO_DATA); + "", "", 0, 0, 0, ret); + } + + 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_request_get_connected_peers(service); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_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; } @@ -474,9 +486,8 @@ static gboolean _meshd_dbus_handle_set_gate(NetMesh *object, /* Set STP and gate_announce */ ret = mesh_request_set_mesh_gate(info->bridge_interface, info->mesh_interface, info->external_interface); - if (MESHD_ERROR_NONE != ret) { + if (MESHD_ERROR_NONE != ret) MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret); - } net_mesh_complete_set_gate(object, invocation, ret); @@ -493,30 +504,37 @@ static gboolean _meshd_dbus_handle_unset_gate(NetMesh *object, ret = mesh_request_unset_mesh_gate(info->bridge_interface, info->mesh_interface, info->external_interface); - if (MESHD_ERROR_NONE != ret) { + if (MESHD_ERROR_NONE != ret) MESH_LOGE("Failed to mesh_request_unset_mesh_gate [%d]", ret); - } + net_mesh_complete_unset_gate(object, invocation, ret); return TRUE; } static gboolean _meshd_dbus_handle_set_softap(NetMesh *object, - GDBusMethodInvocation *invocation, gchar *ssid, gchar *key, - gchar *mode, gint channel, gint visibility, gint max_sta, gint security) + GDBusMethodInvocation *invocation, + gchar *ssid, gchar *passphrase, + gchar *mode, gint channel, gint visibility, gint max_sta, + gint security, gpointer user_data) { int ret = MESHD_ERROR_NONE; + mesh_service *service = (mesh_service *)user_data; + mesh_interface_s *info = service->interface_info; - MESH_LOGD("Not implemented yet !"); - MESH_LOGD("ssid = %s", ssid); - MESH_LOGD("key = %s", key); - MESH_LOGD("mode = %s", mode); - MESH_LOGD("channel = %d", channel); - MESH_LOGD("visibility = %d", visibility); - MESH_LOGD("max_sta = %d", max_sta); - MESH_LOGD("security = %d", security); + MESH_LOGD("SSID : %s", ssid); + MESH_LOGD("mode : %s", mode); + MESH_LOGD("channel : %d", channel); + MESH_LOGD("visibility: %d", visibility); + MESH_LOGD("max_sta : %d", max_sta); + MESH_LOGD("security : %d", security); - /* TODO: Save softAP information */ + /* Save softAP information */ + ret = mesh_request_set_softap_config(info->softap_interface, + ssid, mode, channel, visibility, max_sta, + security, passphrase); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_set_softap_config [%d]", ret); net_mesh_complete_set_softap(object, invocation, ret); @@ -524,13 +542,16 @@ static gboolean _meshd_dbus_handle_set_softap(NetMesh *object, } static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object, - GDBusMethodInvocation *invocation) + GDBusMethodInvocation *invocation, gpointer user_data) { int ret = MESHD_ERROR_NONE; + mesh_service *service = (mesh_service *)user_data; + mesh_interface_s *info = service->interface_info; - MESH_LOGD("Not implemented yet !"); - - /* TODO: Check softAP interface and execute it */ + /* Check softAP interface and execute it */ + ret = mesh_request_enable_softap(info->bridge_interface, info->softap_interface); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_enable_softap [%d]", ret); net_mesh_complete_enable_softap(object, invocation, ret); @@ -538,123 +559,140 @@ static gboolean _meshd_dbus_handle_enable_softap(NetMesh *object, } static gboolean _meshd_dbus_handle_disable_softap(NetMesh *object, - GDBusMethodInvocation *invocation) + GDBusMethodInvocation *invocation, gpointer user_data) { int ret = MESHD_ERROR_NONE; + mesh_service *service = (mesh_service *)user_data; + mesh_interface_s *info = service->interface_info; - MESH_LOGD("Not implemented yet !"); - - /* TODO: Destroy softap */ + /* Destroy softAP */ + ret = mesh_request_disable_softap(info->bridge_interface, info->softap_interface); + if (MESHD_ERROR_NONE != ret) + MESH_LOGE("Failed to mesh_request_disable_softap [%d]", ret); net_mesh_complete_disable_softap(object, invocation, ret); return TRUE; } -static gboolean _meshd_dbus_handle_add_mesh_network(NetMesh *object, +static gboolean _meshd_dbus_handle_create_mesh_network(NetMesh *object, GDBusMethodInvocation *invocation, gchar *mesh_id, gint channel, gint security, gpointer user_data) { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; + meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE; - ret = mesh_request_add_mesh_network(&service->saved_mesh_network, - mesh_id, channel, security); + ret = mesh_request_create_mesh_network(service, mesh_id, channel, sec); - net_mesh_complete_add_mesh_network(object, invocation, ret); + net_mesh_complete_create_mesh_network(object, invocation, ret); return TRUE; } -static gboolean _meshd_dbus_handle_get_saved_mesh_network(NetMesh *object, +static gboolean _meshd_dbus_handle_connect_mesh_network(NetMesh *object, GDBusMethodInvocation *invocation, + gchar *mesh_id, gint channel, gint security, gchar *passphrase, gpointer user_data) { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; + meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE; - GVariantBuilder builder; - GVariant* networks; - GList *iter = NULL; + ret = mesh_request_connect_mesh_network(service, mesh_id, channel, sec, passphrase); - ret = mesh_request_get_saved_mesh_network(&service->saved_mesh_network); - if (MESHD_ERROR_NONE != ret) { - MESH_LOGE("Failed to mesh_request_get_saved_mesh_network"); - - g_dbus_method_invocation_return_error(invocation, - G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed"); - } else { - /* TODO: Get station information and make variant data */ - g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); - - iter = service->saved_mesh_network; - while (iter != NULL) { - mesh_network_info_s *item = (mesh_network_info_s*)iter->data; + net_mesh_complete_connect_mesh_network(object, invocation, ret); - g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add(&builder, "{sv}", "mesh_id", - g_variant_new_string(item->mesh_id)); - g_variant_builder_add(&builder, "{sv}", "channel", - g_variant_new_uint32(item->channel)); - g_variant_builder_add(&builder, "{sv}", "security", - g_variant_new_uint32(item->security)); - g_variant_builder_close(&builder); + return TRUE; +} +static gboolean _meshd_dbus_handle_disconnect_mesh_network(NetMesh *object, + GDBusMethodInvocation *invocation, + gchar *mesh_id, gint channel, gint security, + gpointer user_data) +{ + int ret = MESHD_ERROR_NONE; + mesh_service *service = (mesh_service *)user_data; + meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE; - iter = g_list_next(iter); - } + ret = mesh_request_disconnect_mesh_network(service, mesh_id, channel, sec); - networks = g_variant_builder_end(&builder); - net_mesh_complete_get_saved_mesh_network(object, invocation, networks, ret); - } + net_mesh_complete_disconnect_mesh_network(object, invocation, ret); return TRUE; } -static gboolean _meshd_dbus_handle_select_saved_mesh_network(NetMesh *object, +static gboolean _meshd_dbus_handle_forget_mesh_network(NetMesh *object, GDBusMethodInvocation *invocation, gchar *mesh_id, gint channel, gint security, gpointer user_data) { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; + meshd_security_type_e sec = (1 == security) ? MESHD_SECURITY_SAE : MESHD_SECURITY_NONE; - ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network, - mesh_id, channel, security); + ret = mesh_request_remove_mesh_network(service, mesh_id, channel, sec); - net_mesh_complete_select_saved_mesh_network(object, invocation, ret); + net_mesh_complete_forget_mesh_network(object, invocation, ret); return TRUE; } -static gboolean _meshd_dbus_handle_forget_saved_mesh_network(NetMesh *object, +static gboolean _meshd_dbus_handle_set_interfaces(NetMesh *object, GDBusMethodInvocation *invocation, - gchar *mesh_id, gint channel, gint security, + gchar *mesh, gchar *gate, gchar *softap, gpointer user_data) { int ret = MESHD_ERROR_NONE; mesh_service *service = (mesh_service *)user_data; + mesh_interface_s *info = service->interface_info; + + g_free(info->mesh_interface); + info->mesh_interface = g_strdup(mesh); + + g_free(info->external_interface); + info->external_interface = g_strdup(gate); - ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network, - mesh_id, channel, security); + g_free(info->softap_interface); + info->softap_interface = g_strdup(softap); - net_mesh_complete_forget_saved_mesh_network(object, invocation, ret); + MESH_LOGD("Interface configuration for mesh network :"); + MESH_LOGD(" Base : [%s]", info->base_interface); + MESH_LOGD(" Mesh : [%s]", info->mesh_interface); + MESH_LOGD(" Bridge : [%s]", info->bridge_interface); + MESH_LOGD(" SoftAP : [%s]", info->softap_interface); + MESH_LOGD(" External: [%s]", info->external_interface); + + net_mesh_complete_set_interfaces(object, invocation, ret); return TRUE; } static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object, - GDBusMethodInvocation *invocation) + GDBusMethodInvocation *invocation, + gpointer user_data) { int ret = MESHD_ERROR_NONE; GVariantBuilder builder; GVariant* station; + GList *iter = NULL; - MESH_LOGD("Not implemented yet !"); + mesh_service *service = (mesh_service *)user_data; + mesh_interface_s *info = service->interface_info; - /* TODO: Get station infomation and make variant data */ + /* Clear mesh station list */ + g_list_free_full(service->station_list, _on_station_list_destroy); + service->station_list = NULL; + ret = mesh_request_get_station_info( + info->mesh_interface, &service->station_list); + if (MESHD_ERROR_NONE != ret) { + MESH_LOGE("Failed to mesh_request_get_station_info"); + + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed"); + } else { /* * sh-3.2# iw mesh0 station dump * Station 7c:dd:90:62:37:cf (on mesh0) @@ -666,7 +704,7 @@ static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object, * tx retries: 0 * tx failed: 0 * beacon loss: 0 - * signal: -64 dBm + * signal: -64 dBm * signal avg: -63 dBm * tx bitrate: 54.0 MBit/s * rx bitrate: 5.5 MBit/s @@ -688,94 +726,190 @@ static gboolean _meshd_dbus_handle_get_station_info(NetMesh *object, * short slot time:yes * connected time: 256 seconds */ - g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add(&builder, "{sv}", "station", g_variant_new_string("7c:dd:90:62:37:cf")); - g_variant_builder_add(&builder, "{sv}", "inactive_time", g_variant_new_uint32(1685)); - g_variant_builder_add(&builder, "{sv}", "rx_bytes", g_variant_new_uint32(34174)); - g_variant_builder_add(&builder, "{sv}", "rx_packets", g_variant_new_uint32(1181)); - g_variant_builder_add(&builder, "{sv}", "tx_bytes", g_variant_new_uint32(6877)); - g_variant_builder_add(&builder, "{sv}", "tx_packets", g_variant_new_uint32(76)); - g_variant_builder_add(&builder, "{sv}", "tx_retries", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "tx_failed", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "beacon_loss", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "signal", g_variant_new_int32(-64)); - g_variant_builder_add(&builder, "{sv}", "signal_avg", g_variant_new_int32(-63)); - g_variant_builder_add(&builder, "{sv}", "tx_birrate", g_variant_new_uint32(540)); /* 10 times */ - g_variant_builder_add(&builder, "{sv}", "rx_birrate", g_variant_new_uint32(55)); /* 10 times */ - g_variant_builder_add(&builder, "{sv}", "mesh_llid", g_variant_new_uint32(51731)); - g_variant_builder_add(&builder, "{sv}", "mesh_plid", g_variant_new_uint32(35432)); - g_variant_builder_add(&builder, "{sv}", "mesh_plink", g_variant_new_uint32(1)); /* 0 : DISCON, 1 : ESTAB */ - g_variant_builder_add(&builder, "{sv}", "mesh_local_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */ - g_variant_builder_add(&builder, "{sv}", "mesh_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */ - g_variant_builder_add(&builder, "{sv}", "mesh_none_peer_PS_mode", g_variant_new_uint32(1)); /* 0 : INACTIVE, 1 : ACTIVE */ - g_variant_builder_add(&builder, "{sv}", "authroized", g_variant_new_boolean(TRUE)); - g_variant_builder_add(&builder, "{sv}", "associated", g_variant_new_boolean(TRUE)); - g_variant_builder_add(&builder, "{sv}", "preamble",g_variant_new_string("long")); - g_variant_builder_add(&builder, "{sv}", "WMM_WME", g_variant_new_boolean(TRUE)); - g_variant_builder_add(&builder, "{sv}", "MFP", g_variant_new_boolean(FALSE)); - g_variant_builder_add(&builder, "{sv}", "TDLS_peer", g_variant_new_boolean(FALSE)); - g_variant_builder_add(&builder, "{sv}", "DTIM_period", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "beacon_interval", g_variant_new_uint32(1000)); - g_variant_builder_add(&builder, "{sv}", "short_slot_time", g_variant_new_boolean(TRUE)); - g_variant_builder_add(&builder, "{sv}", "connected_time", g_variant_new_uint32(256)); - station = g_variant_builder_end(&builder); - - net_mesh_complete_get_station_info(object, invocation, station, ret); - - g_object_unref(station); + /* Get station information and make variant data */ + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + iter = service->station_list; + while (iter != NULL) { + mesh_station_info_s *item = (mesh_station_info_s*)iter->data; + + g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&builder, "{sv}", "bssid", + g_variant_new_string(item->bssid)); + g_variant_builder_add(&builder, "{sv}", "inactive_time", + g_variant_new_uint32(item->inactive_time)); + g_variant_builder_add(&builder, "{sv}", "rx_bytes", + g_variant_new_uint64(item->rx_bytes)); + g_variant_builder_add(&builder, "{sv}", "rx_packets", + g_variant_new_uint32(item->rx_packets)); + g_variant_builder_add(&builder, "{sv}", "tx_bytes", + g_variant_new_uint64(item->tx_bytes)); + g_variant_builder_add(&builder, "{sv}", "tx_packets", + g_variant_new_uint32(item->tx_packets)); + g_variant_builder_add(&builder, "{sv}", "tx_retries", + g_variant_new_uint32(item->tx_retries)); + g_variant_builder_add(&builder, "{sv}", "tx_failed", + g_variant_new_uint32(item->tx_failed)); + g_variant_builder_add(&builder, "{sv}", "beacon_loss", + g_variant_new_uint32(item->beacon_loss)); + g_variant_builder_add(&builder, "{sv}", "beacon_rx", + g_variant_new_uint64(item->beacon_rx)); + g_variant_builder_add(&builder, "{sv}", "rx_drop_misc", + g_variant_new_uint64(item->rx_drop_misc)); + g_variant_builder_add(&builder, "{sv}", "signal", + g_variant_new_int32(item->rssi)); + g_variant_builder_add(&builder, "{sv}", "signal_avg", + g_variant_new_int32(item->rssi_avg)); + g_variant_builder_add(&builder, "{sv}", "tx_bitrate", + g_variant_new_uint32(item->tx_bitrate)); /* 10 times */ + g_variant_builder_add(&builder, "{sv}", "rx_bitrate", + g_variant_new_uint32(item->rx_bitrate)); /* 10 times */ + g_variant_builder_add(&builder, "{sv}", "mesh_llid", + g_variant_new_uint16(item->llid)); + g_variant_builder_add(&builder, "{sv}", "mesh_plid", + g_variant_new_uint16(item->plid)); + g_variant_builder_add(&builder, "{sv}", "mesh_plink", + g_variant_new_byte(item->mesh_plink)); /* 0 : DISCON, 1 : ESTAB */ + g_variant_builder_add(&builder, "{sv}", "local_ps_mode", + g_variant_new_uint32(item->local_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */ + g_variant_builder_add(&builder, "{sv}", "peer_ps_mode", + g_variant_new_uint32(item->peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */ + g_variant_builder_add(&builder, "{sv}", "non_peer_ps_mode", + g_variant_new_uint32(item->non_peer_ps_mode)); /* 0 : INACTIVE, 1 : ACTIVE */ + g_variant_builder_add(&builder, "{sv}", "authorized", + g_variant_new_boolean(item->authorized)); + g_variant_builder_add(&builder, "{sv}", "associated", + g_variant_new_boolean(item->associated)); + g_variant_builder_add(&builder, "{sv}", "preamble", + g_variant_new_boolean(item->preamble)); + g_variant_builder_add(&builder, "{sv}", "WMM_WME", + g_variant_new_boolean(item->wme)); + g_variant_builder_add(&builder, "{sv}", "MFP", + g_variant_new_boolean(item->mfp)); + g_variant_builder_add(&builder, "{sv}", "TDLS_peer", + g_variant_new_boolean(item->tdls_peer)); + g_variant_builder_add(&builder, "{sv}", "DTIM_period", + g_variant_new_byte(item->dtim_period)); + g_variant_builder_add(&builder, "{sv}", "beacon_interval", + g_variant_new_uint16(item->beacon_interval)); + g_variant_builder_add(&builder, "{sv}", "short_slot_time", + g_variant_new_boolean(item->short_slot_time)); + g_variant_builder_add(&builder, "{sv}", "connected_time", + g_variant_new_uint32(item->connected_time)); + g_variant_builder_close(&builder); + + iter = g_list_next(iter); + } + + station = g_variant_builder_end(&builder); + net_mesh_complete_get_station_info(object, invocation, station, ret); + + g_object_unref(station); + } return TRUE; } static gboolean _meshd_dbus_handle_get_mpath_info(NetMesh *object, - GDBusMethodInvocation *invocation) + GDBusMethodInvocation *invocation, + gpointer user_data) { int ret = MESHD_ERROR_NONE; GVariantBuilder builder; - GVariant* dump_data; + GVariant* mpath_data; + GList *iter = NULL; - MESH_LOGD("Not implemented yet !"); + mesh_service *service = (mesh_service *)user_data; + mesh_interface_s *info = service->interface_info; - /* TODO: Get mesh path infomation and make variant data */ + /* Clear mesh path list */ + g_list_free_full(service->mpath_list, _on_mpath_list_destroy); + service->mpath_list = NULL; - // ret = _meshd_get_mpath_dump(); + ret = mesh_request_get_mpath_info( + info->mesh_interface, &service->mpath_list); + if (MESHD_ERROR_NONE != ret) { + MESH_LOGE("Failed to mesh_request_get_mpath_info"); + g_dbus_method_invocation_return_error(invocation, + G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed"); + } else { /* * Example) sh-3.2# iw mesh0 mpath dump * DEST ADDR NEXT HOP IFACE SN METRIC QLEN EXPTIME DTIM DRET FLAGS * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0 221 152 0 10 100 0 0x5 */ - g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add(&builder, "{sv}", "DEST_ADDR", g_variant_new_string("7c:dd:90:62:37:cf")); - g_variant_builder_add(&builder, "{sv}", "NEXT_HOP", g_variant_new_string("7c:dd:90:62:37:cf")); - g_variant_builder_add(&builder, "{sv}", "IFACE", g_variant_new_string("mesh0")); - g_variant_builder_add(&builder, "{sv}", "SN", g_variant_new_uint32(221)); - g_variant_builder_add(&builder, "{sv}", "METRIC", g_variant_new_uint32(152)); - g_variant_builder_add(&builder, "{sv}", "QLEN", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "EXPTIME", g_variant_new_uint32(10)); - g_variant_builder_add(&builder, "{sv}", "DTIM", g_variant_new_uint32(100)); - g_variant_builder_add(&builder, "{sv}", "DRET", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "FLAGS", g_variant_new_uint32(0x05)); - - g_variant_builder_add(&builder, "{sv}", "DEST_ADDR", g_variant_new_string("7c:dd:90:63:21:34")); - g_variant_builder_add(&builder, "{sv}", "NEXT_HOP", g_variant_new_string("7c:dd:90:62:37:cf")); - g_variant_builder_add(&builder, "{sv}", "IFACE", g_variant_new_string("mesh0")); - g_variant_builder_add(&builder, "{sv}", "SN", g_variant_new_uint32(221)); - g_variant_builder_add(&builder, "{sv}", "METRIC", g_variant_new_uint32(152)); - g_variant_builder_add(&builder, "{sv}", "QLEN", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "EXPTIME", g_variant_new_uint32(10)); - g_variant_builder_add(&builder, "{sv}", "DTIM", g_variant_new_uint32(100)); - g_variant_builder_add(&builder, "{sv}", "DRET", g_variant_new_uint32(0)); - g_variant_builder_add(&builder, "{sv}", "FLAGS", g_variant_new_uint32(0x05)); - dump_data = g_variant_builder_end(&builder); - - net_mesh_complete_get_mpath_info(object, invocation, dump_data, ret); - - g_object_unref(dump_data); + /* Get mesh path information and make variant data */ + g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}")); + + iter = service->mpath_list; + while (iter != NULL) { + mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data; + + g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add(&builder, "{sv}", "DEST_ADDR", + g_variant_new_string(item->dest_addr)); + g_variant_builder_add(&builder, "{sv}", "NEXT_HOP", + g_variant_new_string(item->next_hop)); + g_variant_builder_add(&builder, "{sv}", "IFACE", + g_variant_new_string(item->interface)); + g_variant_builder_add(&builder, "{sv}", "SN", + g_variant_new_uint32(item->sn)); + g_variant_builder_add(&builder, "{sv}", "METRIC", + g_variant_new_uint32(item->metric)); + g_variant_builder_add(&builder, "{sv}", "QLEN", + g_variant_new_uint32(item->qlen)); + g_variant_builder_add(&builder, "{sv}", "EXPTIME", + g_variant_new_uint32(item->exptime)); + g_variant_builder_add(&builder, "{sv}", "DTIM", + g_variant_new_uint32(item->discovery_timeout)); + g_variant_builder_add(&builder, "{sv}", "DRET", + g_variant_new_byte(item->discovery_retries)); + g_variant_builder_add(&builder, "{sv}", "FLAGS", + g_variant_new_byte(item->flags)); + g_variant_builder_close(&builder); + + iter = g_list_next(iter); + } + + mpath_data = g_variant_builder_end(&builder); + net_mesh_complete_get_mpath_info(object, invocation, mpath_data, ret); + + g_object_unref(mpath_data); + } return TRUE; } +static void _meshd_dbus_on_activator_bus_acquired(GDBusConnection *conn, + const gchar *name, gpointer user_data) +{ + gboolean ret; + GError *error = NULL; + mesh_service *service = (mesh_service *)user_data; + + NOTUSED(name); + + meshd_activator_dbus_object = manager_skeleton_new(); + if (NULL == meshd_activator_dbus_object) { + MESH_LOGE("manager_skeleton_new() Fail"); + return; + } + + g_signal_connect(meshd_activator_dbus_object, "handle-enable", + G_CALLBACK(_meshd_dbus_handle_enable), service); + g_signal_connect(meshd_activator_dbus_object, "handle-disable", + G_CALLBACK(_meshd_dbus_handle_disable), service); + + ret = g_dbus_interface_skeleton_export( + G_DBUS_INTERFACE_SKELETON(meshd_activator_dbus_object), + conn, MESH_DBUS_MANAGER_OBJPATH, &error); + if (FALSE == ret) { + MESH_LOGE("g_dbus_interface_skeleton_export() Fail(%s)", error->message); + g_error_free(error); + } +} + static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data) { @@ -791,10 +925,6 @@ static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name return; } - g_signal_connect(meshd_dbus_object, "handle-enable", - G_CALLBACK(_meshd_dbus_handle_enable), service); - g_signal_connect(meshd_dbus_object, "handle-disable", - G_CALLBACK(_meshd_dbus_handle_disable), service); g_signal_connect(meshd_dbus_object, "handle-scan", G_CALLBACK(_meshd_dbus_handle_scan), service); g_signal_connect(meshd_dbus_object, "handle-specific-scan", @@ -809,6 +939,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", @@ -819,14 +951,16 @@ static void _meshd_dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name G_CALLBACK(_meshd_dbus_handle_enable_softap), service); g_signal_connect(meshd_dbus_object, "handle-disable-softap", G_CALLBACK(_meshd_dbus_handle_disable_softap), service); - g_signal_connect(meshd_dbus_object, "handle-add-mesh-network", - G_CALLBACK(_meshd_dbus_handle_add_mesh_network), service); - g_signal_connect(meshd_dbus_object, "handle-get-saved-mesh-network", - G_CALLBACK(_meshd_dbus_handle_get_saved_mesh_network), service); - g_signal_connect(meshd_dbus_object, "handle-select-saved-mesh-network", - G_CALLBACK(_meshd_dbus_handle_select_saved_mesh_network), service); - g_signal_connect(meshd_dbus_object, "handle-forget-saved-mesh-network", - G_CALLBACK(_meshd_dbus_handle_forget_saved_mesh_network), service); + g_signal_connect(meshd_dbus_object, "handle-create-mesh-network", + G_CALLBACK(_meshd_dbus_handle_create_mesh_network), service); + g_signal_connect(meshd_dbus_object, "handle-connect-mesh-network", + G_CALLBACK(_meshd_dbus_handle_connect_mesh_network), service); + g_signal_connect(meshd_dbus_object, "handle-disconnect-mesh-network", + G_CALLBACK(_meshd_dbus_handle_disconnect_mesh_network), service); + g_signal_connect(meshd_dbus_object, "handle-forget-mesh-network", + G_CALLBACK(_meshd_dbus_handle_forget_mesh_network), service); + g_signal_connect(meshd_dbus_object, "handle-set-interfaces", + G_CALLBACK(_meshd_dbus_handle_set_interfaces), service); g_signal_connect(meshd_dbus_object, "handle-get-station-info", G_CALLBACK(_meshd_dbus_handle_get_station_info), service); g_signal_connect(meshd_dbus_object, "handle-get-mpath-info", @@ -867,6 +1001,7 @@ static void _meshd_dbus_on_name_acquired(GDBusConnection *conn, const gchar *nam static gboolean _meshd_dbus_interface_init(mesh_service *service) { guint id; + guint activation_dbus_id; meshd_check_null_ret_error("service", service, FALSE); id = g_bus_own_name(G_BUS_TYPE_SYSTEM, @@ -882,10 +1017,24 @@ static gboolean _meshd_dbus_interface_init(mesh_service *service) return FALSE; } + /* Get D-Bus owner to activate mesh service daemon */ + activation_dbus_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + MESH_DBUS_INTERFACE".manager", + G_BUS_NAME_OWNER_FLAGS_REPLACE, + _meshd_dbus_on_activator_bus_acquired, + NULL, + NULL, + service, + NULL); + service->dbus_id = id; + service->activation_dbus_id = activation_dbus_id; service->interface_info = g_new0(mesh_interface_s, 1); service->scanned_mesh_network = NULL; + /* Initialize DBus sendor logic */ + meshd_dbus_start(service); + return TRUE; } @@ -894,7 +1043,11 @@ static void _meshd_dbus_deinit(mesh_service *service) mesh_interface_s *info = NULL; meshd_check_null_ret("service", service); + /* De-Initialize DBus sendor logic */ + meshd_dbus_stop(service); + g_bus_unown_name(service->dbus_id); + g_bus_unown_name(service->activation_dbus_id); info = service->interface_info; meshd_check_null_ret("info", info); @@ -911,20 +1064,24 @@ static void _meshd_dbus_deinit(mesh_service *service) if (service->joined_network) { g_free(service->joined_network->mesh_id); + g_free(service->joined_network->bssid); g_free(service->joined_network); service->joined_network = NULL; } - mesh_request_clear_saved_mesh_network(&service->saved_mesh_network); /* Clear scan list */ g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy); service->scanned_mesh_network = NULL; + /* Clear connected peers list */ + g_list_free_full(service->connected_mesh_peers, _on_peer_info_destroy); + service->connected_mesh_peers = NULL; + g_free(service->interface_info); service->interface_info = NULL; } - /**< mesh service interface initialization */ +/**< Mesh service interface initialization */ gboolean meshd_service_interface_init(mesh_service *service) { guint ret; @@ -933,14 +1090,14 @@ gboolean meshd_service_interface_init(mesh_service *service) /* Initialize dbus interface */ ret = _meshd_dbus_interface_init(service); if (FALSE == ret) { - MESH_LOGE("zigbee_service_dbus_interface_init failed!!!"); + MESH_LOGE("_meshd_dbus_interface_init failed!!!"); return FALSE; } return TRUE; } -/**< Zigbee service interface de-initialization */ +/**< Mesh service interface de-initialization */ void meshd_service_interface_deinit(mesh_service *service) { meshd_check_null_ret("service", service);