Initial connman integration
authorJiwan Kim <ji-wan.kim@samsung.com>
Fri, 26 May 2017 06:58:00 +0000 (15:58 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 17 Jul 2017 02:35:36 +0000 (11:35 +0900)
include/mesh-gdbus.h
include/mesh-request.h
include/mesh.h
src/mesh-gdbus.c
src/mesh-request.c
src/mesh-service-interface.c

index 7579975..1e4a1ce 100644 (file)
@@ -25,7 +25,7 @@ extern "C" {
 
 /* DBus object paths of connman */
 #define CONNMAN_SERVER_NAME "net.connman"
-#define CONNMAN_OBJECT_PATH "/net/connman"
+#define CONNMAN_OBJECT_PATH "/"
 #define CONNMAN_OBJECT_PATH_MESH "/net/connman/mesh"
 #define CONNMAN_OBJECT_PATH_TECH_MESH "/net/connman/technology/mesh"
 
@@ -40,6 +40,16 @@ int meshd_dbus_start(mesh_service *service);
 int meshd_dbus_stop(mesh_service *service);
 
 int mesh_ipc_create_mesh_interface(mesh_service *service);
+int mesh_ipc_remove_mesh_interface(mesh_service *service);
+int mesh_ipc_mesh_scan(mesh_service *service);
+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_connect_network(mesh_service *service, mesh_scan_result_s *info);
+int mesh_ipc_disconnect_network(mesh_service *service, mesh_scan_result_s *info);
+int mesh_ipc_remove_network(mesh_service *service, mesh_scan_result_s *info);
 
 #ifdef __cplusplus
 }
index c101ec9..2f02972 100644 (file)
 int mesh_request_dhcp(const char* interface);
 int mesh_request_stop_dhcp();
 
+/* Newly functions */
+int mesh_request_ipc_enable_network(mesh_service *service);
+int mesh_request_ipc_disable_network(mesh_service *service);
+int mesh_request_ipc_mesh_scan(mesh_service *service);
+int mesh_request_ipc_mesh_specific_scan(mesh_service *service, gchar *mesh_id,
+        gint channel);
+int mesh_request_ipc_mesh_cancel_scan(mesh_service *service);
+int mesh_request_ipc_mesh_get_peers(mesh_service *service);
+int mesh_request_ipc_connect_mesh_network(mesh_service *service, gchar *mesh_id,
+               gint channel, gint security);
+int mesh_request_ipc_disconnect_mesh_network(mesh_service *service,
+               gchar *mesh_id, gint channel, gint security);
+int mesh_request_ipc_remove_mesh_network(mesh_service *service,
+               gchar *mesh_id, gint channel, gint security);
+
 int mesh_request_enable_mesh(const char* base_interface,
                const char* mesh_interface, GList *saved_network,
                mesh_network_info_s **joined_network);
index b823982..4fbb743 100644 (file)
@@ -56,6 +56,7 @@ typedef struct _mesh_network_info {
 
 /**< Mesh network scan result structure */
 typedef struct {
+       gchar *object_path; /**< Object path from connman */
        gchar *mesh_id; /**< The mesh id */
        gint mesh_id_len; /**< Length of mesh id */
        gchar *bssid; /**< BSSID */
index 1253fa7..255e7fd 100644 (file)
@@ -17,6 +17,9 @@
 #include "mesh-log.h"
 #include "mesh-util.h"
 #include "mesh-gdbus.h"
+#include "mesh-request.h"
+
+#include "nl80211.h"
 
 static GDBusProxy *_gproxy_connman = NULL;
 static GDBusProxy *_gproxy_connman_mesh = NULL;
@@ -24,6 +27,48 @@ static GDBusProxy *_gproxy_connman_technology = NULL;
 
 static int _meshd_close_gdbus_call(mesh_service *service);
 
+static int __channel_to_frequency(int channel, enum nl80211_band band)
+{
+       if (channel <= 0)
+               return 0;
+
+       switch (band) {
+       case NL80211_BAND_2GHZ:
+               if (channel == 14)
+                       return 2484;
+               else if (channel < 14)
+                       return 2407 + channel * 5;
+               break;
+       case NL80211_BAND_5GHZ:
+               if (channel >= 182 && channel <= 196)
+                       return 4000 + channel * 5;
+               else
+                       return 5000 + channel * 5;
+               break;
+       default:
+               break;
+       }
+
+       /* not supported */
+       return 0;
+}
+
+static int __frequency_to_channel(int freq)
+{
+       if (freq == 2484)
+               return 14;
+       else if (freq < 2484)
+               return (freq - 2407) / 5;
+       else if (freq >= 4910 && freq <= 4980)
+               return (freq - 4000) / 5;
+       else if (freq <= 45000)
+               return (freq - 5000) / 5;
+       else if (freq >= 58320 && freq <= 64800)
+               return (freq - 56160) / 2160;
+       else
+               return 0;
+}
+
 static GDBusProxy *_proxy_get_connman(mesh_service *service)
 {
        GDBusProxy *proxy = NULL;
@@ -118,7 +163,7 @@ static int _meshd_create_gdbus_call(mesh_service *service)
        id = g_signal_connect(service->connection, "notify::g-name-owner",
                        G_CALLBACK(_dbus_name_owner_notify), service);
        if (0 == id) {
-               LOGE("g_signal_connect() Fail");
+               MESH_LOGE("g_signal_connect() Fail");
                g_object_unref(service->connection);
                service->connection = NULL;
                return MESHD_ERROR_IO_ERROR;
@@ -153,9 +198,10 @@ static void _meshd_signal_handler(GDBusConnection *connection,
 
        NOTUSED(service);
 
-       LOGD("signal received = %s", signal_name);
-       if (0 == g_strcmp0(signal_name, "scan_done")) {
+       MESH_LOGD("signal received = %s", signal_name);
+       if (0 == g_strcmp0(signal_name, "ScanDone")) {
                /* TODO: Handle event */
+               mesh_notify_scan_done();
        }
 }
 
@@ -169,11 +215,11 @@ static void _meshd_subscribe_event(mesh_service *service)
                        "ScanDone", "/", NULL,
                        G_DBUS_CALL_FLAGS_NONE, _meshd_signal_handler, service, NULL);
        if (0 == id) {
-               LOGE("g_dbus_connection_signal_subscribe(ScanDone) Fail(%d)", errno);
+               MESH_LOGE("g_dbus_connection_signal_subscribe(ScanDone) Fail(%d)", errno);
                return;
        }
        service->dbus_sub_ids = g_list_append(service->dbus_sub_ids, GUINT_TO_POINTER(id));
-       LOGD("[Signal subscribe] : ScanDone (%d)", id);
+       MESH_LOGD("[Signal subscribe] : ScanDone (%d)", id);
 
        /* End of subscription */
 }
@@ -248,6 +294,7 @@ int mesh_ipc_create_mesh_interface(mesh_service *service)
        GError *error = NULL;
        GVariant *var_dict = NULL;
        GVariantDict dict;
+       mesh_interface_s *info = NULL;
 
        meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
        meshd_check_null_ret_error("connection", service->connection,
@@ -255,21 +302,22 @@ int mesh_ipc_create_mesh_interface(mesh_service *service)
        meshd_check_null_ret_error("_gproxy_connman_technology",
                        _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
 
+       info = service->interface_info;
+
        g_variant_dict_init(&dict, NULL);
-       g_variant_dict_insert(&dict, "Ifname", "s", "mesh0");
-       g_variant_dict_insert(&dict, "ParentIfname", "s", "wlan0");
-       g_variant_dict_insert(&dict, "BridgeIfname", "s", "br0");
+       g_variant_dict_insert(&dict, "Ifname", "s", info->mesh_interface);
+       g_variant_dict_insert(&dict, "ParentIfname", "s", info->base_interface);
+       g_variant_dict_insert(&dict, "BridgeIfname", "s", info->bridge_interface);
        var_dict = g_variant_dict_end(&dict);
 
        variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
-                               g_variant_new("sv", "MeshInterfaceAdd", var_dict),
+                               g_variant_new("(sv)", "MeshInterfaceAdd", var_dict),
                                G_DBUS_CALL_FLAGS_NONE,
-                               -1,
-                               NULL, &error);
+                               -1, NULL, &error);
        if (variant) {
                MESH_LOGD("Successfully requested. [MeshInterfaceAdd]");
        } else if (error) {
-               LOGE("Failed DBus call [%s]", error->message);
+               MESH_LOGE("Failed DBus call [%s]", error->message);
                g_error_free(error);
                return MESHD_ERROR_IO_ERROR;
        }
@@ -277,98 +325,293 @@ int mesh_ipc_create_mesh_interface(mesh_service *service)
        return MESHD_ERROR_NONE;
 }
 
-#if 0
-struct mesh_network_list_s {
-       int count;
-       GList *list;
-};
-struct mesh_network_list_s g_networks;
-
-static void _mesh_free_network(gpointer data)
+int mesh_ipc_remove_mesh_interface(mesh_service *service)
 {
-       struct mesh_network_s *network = data;
-       if (network) g_free(network);
-       network = NULL;
-}
+       GVariant *variant = NULL;
+       GError *error = NULL;
+       GVariant *var_dict = NULL;
+       GVariantDict dict;
+       mesh_interface_s *info = 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);
+       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_technology",
+                       _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
+
+       info = service->interface_info;
+
+       g_variant_dict_init(&dict, NULL);
+       g_variant_dict_insert(&dict, "Ifname", "s", info->mesh_interface);
+       var_dict = g_variant_dict_end(&dict);
+
+       variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
+                               g_variant_new("(sv)", "MeshInterfaceRemove", var_dict),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+       if (variant) {
+               MESH_LOGD("Successfully requested. [MeshInterfaceRemove]");
+       } else if (error) {
+               MESH_LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESHD_ERROR_IO_ERROR;
+       }
+
+       return MESHD_ERROR_NONE;
 }
 
-static void _mesh_remove_networks()
+int mesh_ipc_mesh_scan(mesh_service *service)
 {
-       if (g_networks.list)
-               g_list_free_full(g_networks.list, _mesh_free_network);
-       g_networks.list = NULL;
-       g_networks.count = 0;
+       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_technology",
+                       _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
+
+       variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "Scan",
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+       if (variant) {
+               MESH_LOGD("Successfully requested. [Scan]");
+       } else if (error) {
+               MESH_LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESHD_ERROR_IO_ERROR;
+       }
+
+       return MESHD_ERROR_NONE;
 }
 
-static int _mesh_get_scan_result(mesh_h handle)
+int mesh_ipc_mesh_specific_scan(mesh_service *service, gchar *mesh_id,
+        gint channel)
 {
        GVariant *variant = NULL;
-       unsigned int result;
        GError *error = NULL;
-       struct mesh_handle *h = handle;
+       GVariant *var_dict = NULL;
+       GVariantDict dict;
+
+       enum nl80211_band band = (channel <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
+       gushort freq = __channel_to_frequency(channel, band);
+
+       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_technology",
+                       _gproxy_connman_technology, MESHD_ERROR_IO_ERROR);
+
+       g_variant_dict_init(&dict, NULL);
+       g_variant_dict_insert(&dict, "Name", "s", mesh_id);
+       g_variant_dict_insert(&dict, "Frequency", "q", freq);
+       var_dict = g_variant_dict_end(&dict);
+
+       variant = g_dbus_proxy_call_sync(_gproxy_connman_technology, "MeshCommands",
+                               g_variant_new("(sv)", "MeshSpecificScan", var_dict),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, &error);
+       if (variant) {
+               MESH_LOGD("Successfully requested. [MeshSpecificScan]");
+       } else if (error) {
+               MESH_LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESHD_ERROR_IO_ERROR;
+       }
 
-       GVariantIter *iter = NULL;
-       GVariantIter *iter_row = NULL;
+       return MESHD_ERROR_NONE;
+}
 
-       gchar *key;
-       GVariant *val;
+static void _on_scan_result_destroy(gpointer data)
+{
+       mesh_scan_result_s *scan_item = (mesh_scan_result_s *)data;
+
+       if (scan_item) {
+               g_free(scan_item->mesh_id);
+               g_free(scan_item->bssid);
+               g_free(scan_item->object_path);
+       }
+}
+
+static void _get_mesh_peers(mesh_service *service, GVariant *variant)
+{
+       GVariantIter *peer = NULL;
+       GVariantIter *property = NULL;
+       gchar *key = NULL;
+       GVariant *val = NULL;
        gsize len = 0;
+       GVariant *child;
+       gchar *var_string = NULL;
+       const gchar* obj_path = NULL;
+
+       g_variant_get(variant, "(a(oa{sv}))", &peer);
+       //while (g_variant_iter_next(peer, "oa{sv}", &tmp, &property)) {
+       while ((child = g_variant_iter_next_value(peer))) {
+               mesh_scan_result_s *scan_info = NULL;
+
+               scan_info = g_try_new0(mesh_scan_result_s, 1);
+               if (NULL == scan_info) {
+                       MESH_LOGE("Failed to allocate !");
+                       return;
+               }
+
+               MESH_LOGD("    Child : [%s]", g_variant_get_type_string(child));
+               var_string = g_variant_print(child, FALSE);
+               MESH_LOGD("    %s", var_string);
+               g_free(var_string);
+
+               g_variant_get(child, "(oa{sv})", &obj_path, &property);
+               if (NULL == obj_path) {
+                       MESH_LOGE("Null object");
+                       continue;
+               }
+               MESH_LOGD("    Obj path : [%s]", obj_path);
+               scan_info->object_path = g_strdup(obj_path);
+
+               while (g_variant_iter_loop(property, "{sv}", &key, &val)) {
+                       if (strcasecmp(key, "Name") == 0)  {
+                               const char *buf = g_variant_get_string(val, &len);
+                               scan_info->mesh_id = g_strdup(buf);
+                               MESH_LOGD("    Mesh ID : %s", scan_info->mesh_id);
+                       }
+                       else if (strcasecmp(key, "Address") == 0)  {
+                               const char *buf = g_variant_get_string(val, &len);
+                               scan_info->bssid = g_strdup(buf);
+                               MESH_LOGD("    BSSID : %s", scan_info->bssid);
+                       }
+                       else if (strcasecmp(key, "Frequency") == 0)  {
+                               scan_info->channel = __frequency_to_channel(g_variant_get_uint16(val));
+                               MESH_LOGD("    Channel : %d", scan_info->channel);
+                       }
+                       else if (strcasecmp(key, "Strength") == 0)  {
+                               scan_info->rssi = (gint)g_variant_get_byte(val);
+                               MESH_LOGD("    RSSI : %d", scan_info->rssi);
 
-       /* Clear previous scan results */
-       _mesh_remove_networks();
+                               /* Last element */
+                               service->scanned_mesh_network =
+                                       g_list_prepend(service->scanned_mesh_network, scan_info);
+                       }
+               }
+               g_variant_iter_free(property);
+       }
+       g_variant_iter_free(peer);
+}
+
+int mesh_ipc_get_mesh_peers(mesh_service *service)
+{
+       GVariant *variant = NULL;
+       GError *error = NULL;
 
-       RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
-       RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
+       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_mesh_service, "get_found_mesh_networks",
+       variant = g_dbus_proxy_call_sync(_gproxy_connman, "GetMeshPeers",
                                NULL,
                                G_DBUS_CALL_FLAGS_NONE,
-                               -1,
-                               NULL, &error);
+                               -1, NULL, &error);
        if (variant) {
-               g_variant_get(variant, "(aa{sv}u)", &iter, &result);
-               while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
-                       struct mesh_network_s *network_info =
-                               g_malloc0(sizeof(struct mesh_network_s));
-                       while (g_variant_iter_loop(iter_row, "{sv}", &key, &val)) {
-                               if (strcasecmp(key, "mesh_id") == 0)  {
-                                       const char *buf = g_variant_get_string(val, &len);
-                                       memcpy(network_info->meshid, buf, len);
-                                       //LOGD("meshid=%s", network_info->meshid);
-                               }
-                               else if (strcasecmp(key, "bssid") == 0)  {
-                                       const char *buf = g_variant_get_string(val, &len);
-                                       memcpy(network_info->bssid, buf, len);
-                                       //LOGD("bssid = %s", network_info->bssid);
-                               }
-                               else if (strcasecmp(key, "rssi") == 0)  {
-                                       network_info->rssi = g_variant_get_int32(val);
-                                       //LOGD("rssi = %d", network_info->rssi);
-                               }
-                               else if (strcasecmp(key, "channel") == 0)  {
-                                       network_info->channel = g_variant_get_uint32(val);
-                                       //LOGD("channel = %d", network_info->channel);
-
-                                       /* Last element */
-                                       _mesh_append_network(network_info);
-                               }
-                       }
-                       g_variant_iter_free(iter_row);
+               MESH_LOGD("Successfully requested. [GetMeshPeers]");
+
+               if (service->scanned_mesh_network) {
+                       g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
+                       service->scanned_mesh_network = NULL;
                }
-               g_variant_iter_free(iter);
 
+               _get_mesh_peers(service, variant);
+
+               /* List item is saved with reversed order for efficiency. */
+               service->scanned_mesh_network =
+                               g_list_reverse(service->scanned_mesh_network);
+       } 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_connect_network(mesh_service *service, mesh_scan_result_s *info)
+{
+       GVariant *variant = NULL;
+       GError *error = NULL;
+
+       meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
+       meshd_check_null_ret_error("info", info, MESHD_ERROR_INVALID_PARAMETER);
+
+       variant = g_dbus_connection_call_sync(service->connection,
+                       CONNMAN_SERVER_NAME,
+                       info->object_path,
+                       CONNMAN_INTERFACE_MESH,
+                       "Connect",
+                       NULL, NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1, NULL, &error);
+       if (variant) {
+               MESH_LOGD("Successfully requested. [Connect]");
+       } else if (error) {
+               LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESHD_ERROR_IO_ERROR;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_ipc_disconnect_network(mesh_service *service, mesh_scan_result_s *info)
+{
+       GVariant *variant = NULL;
+       GError *error = NULL;
+
+       meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
+       meshd_check_null_ret_error("info", info, MESHD_ERROR_INVALID_PARAMETER);
+
+       variant = g_dbus_connection_call_sync(service->connection,
+                       CONNMAN_SERVER_NAME,
+                       info->object_path,
+                       CONNMAN_INTERFACE_MESH,
+                       "Disconnect",
+                       NULL, NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1, NULL, &error);
+       if (variant) {
+               MESH_LOGD("Successfully requested. [Disconnect]");
        } else if (error) {
                LOGE("Failed DBus call [%s]", error->message);
                g_error_free(error);
-               return MESH_ITNL_ERR_IO_ERROR;
+               return MESHD_ERROR_IO_ERROR;
        }
 
-       return MESH_ITNL_ERR_NONE;
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_ipc_remove_network(mesh_service *service, mesh_scan_result_s *info)
+{
+       GVariant *variant = NULL;
+       GError *error = NULL;
+
+       meshd_check_null_ret_error("service", service, MESHD_ERROR_INVALID_PARAMETER);
+       meshd_check_null_ret_error("info", info, MESHD_ERROR_INVALID_PARAMETER);
+
+       variant = g_dbus_connection_call_sync(service->connection,
+                       CONNMAN_SERVER_NAME,
+                       info->object_path,
+                       CONNMAN_INTERFACE_MESH,
+                       "Remove",
+                       NULL, NULL,
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1, NULL, &error);
+       if (variant) {
+               MESH_LOGD("Successfully requested. [Remove]");
+       } else if (error) {
+               LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESHD_ERROR_IO_ERROR;
+       }
+
+       return MESHD_ERROR_NONE;
 }
-#endif
index 0041ea2..464edc4 100644 (file)
@@ -34,6 +34,7 @@
 #include "mesh-request.h"
 #include "mesh-network.h"
 #include "mesh-softap.h"
+#include "mesh-gdbus.h"
 
 static void _on_dhcp_finished(const char* interface, const char* ip_address,
                void *user_data)
@@ -682,6 +683,246 @@ int mesh_request_unregister_event_handler()
        return MESHD_ERROR_NONE;
 }
 
+int mesh_request_ipc_enable_network(mesh_service *service)
+{
+       int ret;
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Enable mesh network");
+
+       ret = mesh_ipc_create_mesh_interface(service);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to create mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_request_ipc_disable_network(mesh_service *service)
+{
+       int ret;
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Disable mesh network");
+
+       ret = mesh_ipc_remove_mesh_interface(service);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to create mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_request_ipc_mesh_scan(mesh_service *service)
+{
+       int ret;
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Request scan for mesh network");
+
+       ret = mesh_ipc_mesh_scan(service);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to request scan for mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_request_ipc_mesh_specific_scan(mesh_service *service, gchar *mesh_id,
+        gint channel)
+{
+       int ret;
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Request specific scan for mesh network");
+
+       ret = mesh_ipc_mesh_specific_scan(service, mesh_id, channel);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to request specific scan for mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_request_ipc_mesh_cancel_scan(mesh_service *service)
+{
+       int ret;
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Cancel scan for mesh network");
+
+       ret = mesh_ipc_mesh_scan(service);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to cancel scan for mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_request_ipc_mesh_get_peers(mesh_service *service)
+{
+       int ret;
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Get mesh peers");
+
+       ret = mesh_ipc_get_mesh_peers(service);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to get mesh peers");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+static int _select_matched_network(GList *scanned_network,
+               const char *mesh_id, int mesh_channel, int security,
+               mesh_scan_result_s **info)
+{
+       int ret = MESHD_ERROR_NONE;
+       GList *iter = NULL;
+       mesh_scan_result_s *item = NULL;
+       gboolean found = FALSE;
+
+       NOTUSED(security);
+
+       meshd_check_null_ret_error("scanned_network", scanned_network,
+                       MESHD_ERROR_INVALID_PARAMETER);
+
+       iter = scanned_network;
+       while (iter != NULL) {
+               item = (mesh_scan_result_s*)iter->data;
+
+               if (g_strcmp0(mesh_id, item->mesh_id) == 0) {
+                       if (item->channel == mesh_channel)
+                       {
+                               *info = item;
+                               found = TRUE;
+                               break;
+                       }
+               }
+               iter = g_list_next(iter);
+       }
+
+       if (FALSE == found)
+               return MESHD_ERROR_NO_DATA;
+
+       return ret;
+}
+
+int mesh_request_ipc_connect_mesh_network(mesh_service *service, gchar *mesh_id,
+               gint channel, gint security)
+{
+       int ret;
+       mesh_scan_result_s *info = NULL;
+
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Connect mesh network");
+
+       /* Get mesh_id and channel from saved network */
+       ret = _select_matched_network(service->scanned_mesh_network,
+                       mesh_id, channel, security, &info);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to mesh_network_get_first_mesh_network");
+               return ret;
+       }
+
+       ret = mesh_ipc_connect_network(service, info);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to connect mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_request_ipc_disconnect_mesh_network(mesh_service *service,
+               gchar *mesh_id, gint channel, gint security)
+{
+       int ret;
+       mesh_scan_result_s *info = NULL;
+
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Disconnect mesh network");
+
+       /* Get mesh_id and channel from saved network */
+       ret = _select_matched_network(service->scanned_mesh_network,
+                       mesh_id, channel, security, &info);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to _select_matched_network");
+               return ret;
+       }
+
+       ret = mesh_ipc_disconnect_network(service, info);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to disconnect mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
+int mesh_request_ipc_remove_mesh_network(mesh_service *service,
+               gchar *mesh_id, gint channel, gint security)
+{
+       int ret;
+       mesh_scan_result_s *info = NULL;
+
+       if (NULL == service) {
+               MESH_LOGE("Invalid parameter");
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("[IPC] Remove mesh network");
+
+       /* Get mesh_id and channel from saved network */
+       ret = _select_matched_network(service->scanned_mesh_network,
+                       mesh_id, channel, security, &info);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to _select_matched_network");
+               return ret;
+       }
+
+       ret = mesh_ipc_remove_network(service, info);
+       if(MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to remove mesh network");
+               return ret;
+       }
+
+       return MESHD_ERROR_NONE;
+}
+
 /* Notifications */
 void mesh_notify_scan_done()
 {
index 16e1e58..f81efe8 100644 (file)
@@ -25,6 +25,7 @@
 #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"
@@ -222,6 +223,11 @@ static gboolean _meshd_dbus_handle_scan(NetMesh *object,
 
        meshd_check_null_ret_error("info", info, FALSE);
 
+       ret = mesh_request_ipc_mesh_scan(service);
+       if (MESHD_ERROR_NONE != ret)
+               MESH_LOGE("Failed to mesh_request_ipc_mesh_scan !");
+
+#if 0
        ret = mesh_request_scan(info->mesh_interface);
        if (MESHD_ERROR_NONE != ret) {
                MESH_LOGE("Failed to mesh_request_scan on mesh interface[%s] !",
@@ -235,7 +241,7 @@ static gboolean _meshd_dbus_handle_scan(NetMesh *object,
                        MESH_LOGE("Failed to mesh_request_scan on base interface[%s] !",
                                        info->base_interface);
        }
-
+#endif
        net_mesh_complete_scan(object, invocation, ret);
 
        return TRUE;
@@ -253,6 +259,11 @@ static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
 
        meshd_check_null_ret_error("info", info, FALSE);
 
+       ret = mesh_ipc_mesh_specific_scan(service, mesh_id, channel);
+       if (MESHD_ERROR_NONE != ret)
+               MESH_LOGE("Failed to mesh_request_specific_scan !");
+
+#if 0
        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]",
@@ -266,7 +277,7 @@ static gboolean _meshd_dbus_handle_specific_scan(NetMesh *object,
                        MESH_LOGE("Failed to mesh_request_specific_scan on base interface[%s]",
                                        info->base_interface);
        }
-
+#endif
        net_mesh_complete_specific_scan(object, invocation, ret);
 
        return TRUE;
@@ -297,6 +308,7 @@ 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);
        }
 }
 
@@ -328,7 +340,7 @@ 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;
+       //mesh_interface_s *info = service->interface_info;
 
        GVariantBuilder builder;
        GVariant* networks;
@@ -337,6 +349,11 @@ static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
 
        MESH_LOGD("Request to get scanned mesh network list");
 
+       ret = mesh_request_ipc_mesh_get_peers(service);
+       if (MESHD_ERROR_NONE != ret)
+               MESH_LOGE("Failed to mesh_request_ipc_mesh_get_peers");
+
+#if 0
        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");
@@ -352,7 +369,7 @@ static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
                                        G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Request Failed");
                }
        }
-
+#endif
        g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
 
        iter = service->scanned_mesh_network;
@@ -374,10 +391,11 @@ static gboolean _meshd_dbus_handle_get_found_mesh_networks(NetMesh *object,
        }
 
        /* Clear scan list */
-       g_list_free_full(service->scanned_mesh_network, _on_scan_result_destroy);
-       service->scanned_mesh_network = NULL;
+       //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;
@@ -389,8 +407,9 @@ 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;
+       //mesh_interface_s *info = service->interface_info;
 
+#if 0 ///////////////////
        /* Create or join mesh network and create bridge */
        ret = mesh_request_enable_mesh(info->base_interface, info->mesh_interface,
                                service->saved_mesh_network, &service->joined_network);
@@ -404,7 +423,14 @@ static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
                MESH_LOGE("Failed to mesh_request_create_bridge [%d]", ret);
                goto FINISH;
        }
+#endif
+       ret = mesh_request_ipc_enable_network(service);
+       if (MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to mesh_request_ipc_enable_network [%d]", ret);
+               goto FINISH;
+       }
 
+#if 0
        /* Detect external network state (i.e. Ethernet)
                        and decide to make gate enabled */
        ret = mesh_request_set_mesh_gate(info->bridge_interface,
@@ -413,7 +439,7 @@ static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
                MESH_LOGE("Failed to mesh_request_set_mesh_gate [%d]", ret);
        }
 
-#if 0
+
        /* TODO: Check if specific scan is required */
        ret = mesh_request_specific_scan(info->mesh_interface,
                        info->mesh_id, info->mesh_channel);
@@ -422,7 +448,6 @@ static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
        }
        ret = mesh_request_get_scan_result(info->mesh_interface,
                        &service->scanned_mesh_network);
-#endif
 
        /* Request DHCP on bridge interface */
        ret = mesh_request_dhcp(info->bridge_interface);
@@ -431,6 +456,7 @@ static gboolean _meshd_dbus_handle_enable_mesh(NetMesh *object,
        }
 
        /* TODO: Notify bridge status to Connman */
+#endif
 
 FINISH:
        net_mesh_complete_enable_mesh(object, invocation, ret);
@@ -447,14 +473,14 @@ static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
        mesh_interface_s *info = service->interface_info;
 
        meshd_check_null_ret_error("info", info, FALSE);
-
+#if 0
        /* 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;
        }
-
+#endif
        if (FALSE == service->mesh_activated) {
                MESH_LOGD("Mesh network is not activated yet");
                ret = MESHD_ERROR_OPERATION_FAILED;
@@ -462,6 +488,11 @@ static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
                return TRUE;
        }
 
+       ret = mesh_request_ipc_disable_network(service);
+       if (MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to disable mesh network !");
+       }
+#if 0
        /* If DHCP is on progress, stop it */
        ret = mesh_request_stop_dhcp();
        if (MESHD_ERROR_NONE != ret) {
@@ -477,7 +508,7 @@ static gboolean _meshd_dbus_handle_disable_mesh(NetMesh *object,
        if (MESHD_ERROR_NONE != ret) {
                MESH_LOGE("Failed to mesh_request_remove_bridge");
        }
-
+#endif
        /* Make response */
        net_mesh_complete_disable_mesh(object, invocation, ret);
 
@@ -686,8 +717,12 @@ static gboolean _meshd_dbus_handle_select_saved_mesh_network(NetMesh *object,
        int ret = MESHD_ERROR_NONE;
        mesh_service *service = (mesh_service *)user_data;
 
-       ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
-                       mesh_id, channel, security);
+       //ret = mesh_request_select_saved_mesh_network(&service->saved_mesh_network,
+       //              mesh_id, channel, security);
+
+/* ADDED */
+       ret = mesh_request_ipc_connect_mesh_network(service, mesh_id, channel, security);
+/* ADDED */
 
        net_mesh_complete_select_saved_mesh_network(object, invocation, ret);
 
@@ -702,7 +737,9 @@ static gboolean _meshd_dbus_handle_forget_saved_mesh_network(NetMesh *object,
        int ret = MESHD_ERROR_NONE;
        mesh_service *service = (mesh_service *)user_data;
 
-       ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
+       //ret = mesh_request_forget_saved_mesh_network(&service->saved_mesh_network,
+       //              mesh_id, channel, security);
+       ret = mesh_request_ipc_disconnect_mesh_network(service,
                        mesh_id, channel, security);
 
        net_mesh_complete_forget_saved_mesh_network(object, invocation, ret);
@@ -1139,6 +1176,9 @@ static gboolean _meshd_dbus_interface_init(mesh_service *service)
        service->interface_info = g_new0(mesh_interface_s, 1);
        service->scanned_mesh_network = NULL;
 
+       /* Initialize DBus sendor logic */
+       meshd_dbus_start(service);
+
        return TRUE;
 }
 
@@ -1147,8 +1187,10 @@ static void _meshd_dbus_deinit(mesh_service *service)
        mesh_interface_s *info = NULL;
        meshd_check_null_ret("service", service);
 
-       g_bus_unown_name(service->dbus_id);
+       /* 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;