Implement CAPI
authorsaerome.kim <saerome.kim@samsung.com>
Sun, 12 Mar 2017 23:46:06 +0000 (08:46 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 17 Jul 2017 02:09:10 +0000 (11:09 +0900)
 - event handler
 - APIs related to network management

Signed-off-by: saerome.kim <saerome.kim@samsung.com>
include/mesh.h [changed mode: 0755->0644]
include/mesh_dbus.h
include/mesh_private.h [changed mode: 0755->0644]
src/mesh.c [changed mode: 0755->0644]
src/mesh_dbus.c [changed mode: 0755->0644]
test/main.c [changed mode: 0755->0644]
test/mesh_device.c [changed mode: 0755->0644]
test/mesh_network.c [changed mode: 0755->0644]

old mode 100755 (executable)
new mode 100644 (file)
index fac1ef1..a0d1b71
@@ -64,28 +64,29 @@ typedef enum {
 } mesh_error_e;
 
 /**
- * @brief Events for mesh_event_cb
- *
- * @since_tizen 4.0
- */
-typedef enum {
-       MESH_EVENT_ENABLED = 0x00, /**< This event is received after enabling mesh network service */
-       MESH_EVENT_SCAN_DONE = 0x01, /**< This event comes from coming mesh network scan completed */
-       MESH_EVENT_STATION_JOINED = 0x02, /**< This event takes place when new mesh station joined */
-       MESH_EVENT_STATION_DISJOINED = 0x03, /**< This event takes place when new mesh station dis-joined */
-} mesh_event_e;
-
-/**
 * @}
 */
 
-
 /**
 * @addtogroup CAPI_NETWORK_MESH_MONITOR_MODULE
 * @{
 */
 
 /**
+ * @brief The maximum length of mesh id
+ *
+ * @since_tizen 4.0
+ */
+#define MAX_MESHID_LEN 32
+
+/**
+ * @brief The maximum length of BSSID
+ *
+ * @since_tizen 4.0
+ */
+#define MAX_BSSID_LEN 18
+
+/**
  * @brief Enumeration for the state of the Mesh network.
  * @since_tizen 4.0
  */
@@ -95,6 +96,54 @@ typedef enum {
 } mesh_state_e;
 
 /**
+ * @brief The events for mesh_event_cb
+ *
+ * @since_tizen 4.0
+ */
+typedef enum {
+       MESH_MESH_ENABLED_EVENT = 0x00, /**< This event is received after enabling mesh network */
+       MESH_SCAN_DONE_EVENT = 0x01, /**< This event comes after scanning operation completed */
+       MESH_JOIN_NETWORK_EVENT = 0x02, /**< This event comes after joiing a mesh network */
+       MESH_LEFT_NETWORK_EVENT = 0x03, /**< This event comes after left the current mesh network */
+       MESH_STATION_JOIN_EVENT = 0x04, /**< This event takes place when new station joined */
+       MESH_STATION_LEFT_EVENT = 0x05, /**< This event takes place when existing station left */
+} mesh_event_e;
+
+/**
+ * @brief The structure type for the MESH_MESH_ENABLED_EVENT callback data.
+ * @details The result of creating or joining mesh network.
+ *
+ * @since_tizen 4.0
+ */
+typedef struct {
+       unsigned int result; /**< The result of creating or joining mesh network */
+} mesh_mesh_enabled_event_s;
+
+/**
+ * @brief The structure type for the MESH_STATION_JOIN_EVENT or MESH_STATION_LEFT_EVENT callback data.
+ * @details Result of join or left event of other station.
+ *
+ * @since_tizen 4.0
+ */
+typedef struct {
+       char bssid[MAX_BSSID_LEN]; /**< The BSSID of the station that generated the event */
+} mesh_other_station_event_s;
+
+/**
+ * @brief The structure type for response data of mesh_event_cb.
+ * @details This function can receive events from the devices in the network.
+ * ex) join, re-join, leave and attribute change report
+ *
+ * @since_tizen 4.0
+ */
+typedef struct {
+       union {
+               mesh_mesh_enabled_event_s *mesh_enable; /**< The result of enabling zigbee system service. */
+               mesh_other_station_event_s *sta_info; /**< This event comes from other stations. */
+       } data;
+} mesh_event_data_s;
+
+/**
 * @}
 */
 
@@ -122,19 +171,6 @@ typedef void* mesh_station_info_h;
 */
 typedef void* mesh_path_info_h;
 
-/**
- * @brief The maximum length of mesh id
- *
- * @since_tizen 4.0
- */
-#define MAX_MESHID_LEN 32
-
-/**
- * @brief The maximum length of BSSID
- *
- * @since_tizen 4.0
- */
-#define MAX_BSSID_LEN 18
 
 /**
  * @brief Creates network handle for network information.
@@ -241,7 +277,7 @@ void mesh_network_destroy(mesh_network_h network);
  * @see mesh_network_set_meshid()
  *
  */
-int mesh_network_get_meshid(mesh_network_h network, char *meshid);
+int mesh_network_get_meshid(mesh_network_h network, char **meshid);
 
 /**
  * @brief Sets network mesh network id.
@@ -277,7 +313,7 @@ int mesh_network_set_meshid(mesh_network_h network, const char *meshid);
  * @see mesh_network_set_bssid()
  *
  */
-int mesh_network_get_bssid(mesh_network_h network, char *bssid);
+int mesh_network_get_bssid(mesh_network_h network, char **bssid);
 
 /**
  * @brief Sets BSSID.
@@ -959,7 +995,7 @@ int mesh_get_path_info(mesh_h handle, mesh_path_info_h path);
  * @retval #MESH_ERROR_IO_ERROR Unexpected d-bus error
  *
  */
-int mesh_set_interface(mesh_h handle,
+int mesh_set_interfaces(mesh_h handle,
        const char *mesh, const char* gate, const char *softap);
 /**
  * @}
index 0897aaf..7ac980b 100644 (file)
@@ -43,7 +43,7 @@ int _mesh_foreach_found_mesh_network(mesh_h handle,
 int _mesh_enable_mesh(mesh_h handle);
 int _mesh_disable_mesh(mesh_h handle);
 int _mesh_is_joined(mesh_h handle, int* is_joined);
-int _mesh_get_joined_mesh_network(mesh_h handle, mesh_network_h _network);
+int _mesh_get_joined_mesh_network(mesh_h handle, mesh_network_h* _network);
 int _mesh_set_gate(mesh_h handle, bool stp, bool gate_announce);
 int _mesh_unset_gate(mesh_h handle);
 int _mesh_set_softap(mesh_h handle, const char* ssid, const char* key, const char* mode,
@@ -58,7 +58,7 @@ int _mesh_remove_network(mesh_h handle, mesh_network_h _network);
 int _mesh_set_interface(mesh_h handle, const char *mesh, const char *gate, const char *softap);
 int _mesh_get_station_info(mesh_h handle, void *station);
 int _mesh_get_path_info(mesh_h handle, void *mpath_data);
-int _mesh_set_interface(mesh_h handle, const char *mesh, const char *gate, const char *softap);
+int _mesh_set_interfaces(mesh_h handle, const char *mesh, const char *gate, const char *softap);
 
 #ifdef __cplusplus
 }
old mode 100755 (executable)
new mode 100644 (file)
index e2db364..587438a
@@ -66,9 +66,10 @@ typedef enum {
        MESH_ITNL_ERR_IO_ERROR = -0xF5,       /** DBus error */
 } mesh_internal_err_e;
 
-struct mesh_handle {
+typedef struct mesh_handle {
        gpointer dbus_connection;
        GCancellable *ca;
+       GList *dbus_sub_ids;
        mesh_event_cb event_handler;
 /* TODO: Below members are related with event callback
  *     Need to be considered
old mode 100755 (executable)
new mode 100644 (file)
index 4527784..cda3cb5
@@ -40,7 +40,7 @@ EXPORT_API int mesh_network_new(mesh_network_h* network)
                LOGE("Out of memory"); //LCOV_EXCL_LINE
                return MESH_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
        }
-       network = (mesh_network_h)net;
+       *network = (mesh_network_h)net;
 
        return MESH_ERROR_NONE;
 }
@@ -48,6 +48,7 @@ EXPORT_API int mesh_network_new(mesh_network_h* network)
 EXPORT_API int mesh_network_clone(mesh_network_h* dst, mesh_network_h src)
 {
        struct mesh_network_s *net;
+       struct mesh_network_s *_src = src;;
 
        CHECK_FEATURE_SUPPORTED(MESH_FEATURE);
 
@@ -61,8 +62,18 @@ EXPORT_API int mesh_network_clone(mesh_network_h* dst, mesh_network_h src)
                LOGE("Out of memory"); //LCOV_EXCL_LINE
                return MESH_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
        }
-       memcpy(dst, src, sizeof(struct mesh_network_s));
-       dst = (mesh_network_h)net;
+       memcpy(net->meshid, _src->meshid, MAX_MESHID_LEN);
+       memcpy(net->bssid, _src->bssid, MAX_BSSID_LEN);
+       //net->meshid = g_strdup(_src->meshid);
+       LOGE("net->meshid=%s _src->meshid=%s", net->meshid, _src->meshid);
+       //net->bssid = g_strdup(_src->bssid);
+       LOGE("net->bssid=%s _src->bssid=%s", net->bssid, _src->bssid);
+       net->channel = _src->channel;
+       net->rssi = _src->rssi;
+       net->data_rate = _src->data_rate;
+       net->security = _src->security;
+
+       *dst = (mesh_network_h)net;
 
        return MESH_ERROR_NONE;
 }
@@ -80,34 +91,47 @@ EXPORT_API int mesh_network_new_with(mesh_network_h* network, const char *meshid
        }
 
        net = calloc(1, sizeof(struct mesh_network_s));
-       memcpy(net->meshid, meshid, MAX_MESHID_LEN);
-       memcpy(net->bssid, bssid, MAX_BSSID_LEN);
+       if (meshid) memcpy(net->meshid, meshid, MAX_MESHID_LEN);
+       if (bssid) memcpy(net->bssid, bssid, MAX_BSSID_LEN);
        net->channel = channel;
        net->rssi = rssi;
        net->data_rate = data_rate;
-       network = (mesh_network_h)net;
+       *network = (mesh_network_h)net;
+
+       LOGE("KSR");
 
        return MESH_ERROR_NONE;
 }
 
 EXPORT_API void mesh_network_destroy(mesh_network_h network)
 {
+       struct mesh_network_s *net = network;
        CHECK_FEATURE_SUPPORTED(MESH_FEATURE);
-       free(network);
+
+       if (net == NULL) {
+               LOGE("Invalid parameter"); //LCOV_EXCL_LINE
+               return; //LCOV_EXCL_LINE
+       }
+#if 0
+       free(net->meshid);
+       free(net->bssid);
+#endif
+       free(net);
 }
 
-EXPORT_API int mesh_network_get_meshid(mesh_network_h network, char *meshid)
+EXPORT_API int mesh_network_get_meshid(mesh_network_h network, char **meshid)
 {
-       struct mesh_network_s *net = (struct mesh_network_s *)network;
+       struct mesh_network_s *net = network;
 
        CHECK_FEATURE_SUPPORTED(MESH_FEATURE);
 
-       if (network == NULL || meshid == NULL ) {
+       if (network == NULL || meshid == NULL) {
                LOGE("Invalid parameter"); //LCOV_EXCL_LINE
                return MESH_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
        }
 
-       meshid = net->meshid;
+       LOGE("net->meshid = %s", net->meshid);
+       *meshid = net->meshid;
 
        return MESH_ERROR_NONE;
 }
@@ -128,18 +152,19 @@ EXPORT_API int mesh_network_set_meshid(mesh_network_h network, const char *meshi
        return MESH_ERROR_NONE;
 }
 
-EXPORT_API int mesh_network_get_bssid(mesh_network_h network, char *bssid)
+EXPORT_API int mesh_network_get_bssid(mesh_network_h network, char **bssid)
 {
        struct mesh_network_s *net = (struct mesh_network_s *)network;
 
        CHECK_FEATURE_SUPPORTED(MESH_FEATURE);
 
-       if (network == NULL || bssid == NULL ) {
+       if (network == NULL || bssid == NULL) {
                LOGE("Invalid parameter"); //LCOV_EXCL_LINE
                return MESH_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
        }
 
-       bssid = net->bssid;
+       *bssid = net->bssid;
+       LOGE("net->bssid = %s", net->bssid);
 
        return MESH_ERROR_NONE;
 }
@@ -637,7 +662,7 @@ EXPORT_API int mesh_get_path_info(mesh_h handle, mesh_path_info_h path)
        return MESH_ERROR_NONE;
 }
 
-EXPORT_API int mesh_set_interface(mesh_h handle,
+EXPORT_API int mesh_set_interfaces(mesh_h handle,
        const char *mesh, const char* gate, const char *softap)
 {
        int rv = 0;
@@ -646,7 +671,7 @@ EXPORT_API int mesh_set_interface(mesh_h handle,
        RETV_IF(NULL == mesh, MESH_ERROR_INVALID_PARAMETER);
        RETV_IF(NULL == handle, MESH_ERROR_INVALID_PARAMETER);
 
-       rv = _mesh_set_interface(handle, mesh, gate, softap);
+       rv = _mesh_set_interfaces(handle, mesh, gate, softap);
        if (rv == MESH_ITNL_ERR_IO_ERROR) {
                return MESH_ERROR_IO_ERROR;
        }
old mode 100755 (executable)
new mode 100644 (file)
index 13ce925..d578b43
@@ -99,6 +99,220 @@ static int _mesh_close_gdbus_call(mesh_h handle)
        return MESH_ITNL_ERR_NONE;
 }
 
+struct mesh_network_list_s {
+
+       int count;
+       GList *list;
+};
+struct mesh_network_list_s g_networks;
+
+static void _mesh_free_network(gpointer data)
+{
+       struct mesh_network_s *network = data;
+       //g_free(network->meshid);
+       //g_free(network->bssid);
+       g_free(network);
+       network = 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);
+}
+
+static void _mesh_remove_networks()
+{
+       if (g_networks.list)
+               g_list_free_full(g_networks.list, _mesh_free_network);
+       g_networks.count = 0;
+}
+
+static int _mesh_get_scan_result(mesh_h handle)
+{
+       GVariant *variant = NULL;
+       unsigned int result;
+       GError *error = NULL;
+       struct mesh_handle *h = handle;
+
+       GVariantIter *iter = NULL;
+       GVariantIter *iter_row = NULL;
+
+       gchar *key;
+       GVariant *val;
+       gsize len = 0;
+
+       _mesh_remove_networks();
+
+       RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
+       RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
+
+       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "get_found_mesh_networks",
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -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)  {
+                                       //network_info->meshid = g_variant_dup_string(val, &len);
+                                       const char *buf = g_variant_get_string(val, &len);
+                                       memcpy(network_info->meshid, buf, len);
+                                       LOGE("meshid=%s", network_info->meshid);
+                               }
+                               else if (strcasecmp(key, "bssid") == 0)  {
+                                       //network_info->bssid = g_variant_dup_string(val, &len);
+                                       const char *buf = g_variant_get_string(val, &len);
+                                       memcpy(network_info->bssid, buf, len);
+                                       LOGE("bssid = %s", network_info->bssid);
+                               }
+                               else if (strcasecmp(key, "rssi") == 0)  {
+                                       network_info->rssi = g_variant_get_int32(val);
+                                       LOGE("rssi = %d", network_info->rssi);
+                               }
+                               else if (strcasecmp(key, "channel") == 0)  {
+                                       network_info->channel = g_variant_get_uint32(val);
+                                       LOGE("channel = %d", network_info->channel);
+
+                                       /* Last element */
+                                       _mesh_append_network(network_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_ITNL_ERR_IO_ERROR;
+       }
+
+       return MESH_ITNL_ERR_NONE;
+}
+
+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)
+{
+       mesh_handle_s *h = user_data;
+
+       RETM_IF(NULL == h, "user_data is null");
+       RETM_IF(NULL == h->event_handler, "event_handler is null");
+       LOGD("signal received = %s", signal_name);
+
+       if (0 == g_strcmp0(signal_name, "mesh_enabled")) {
+               unsigned int result;
+               g_variant_get(parameters, "(u)", &result);
+
+               mesh_event_data_s ev;
+               ev.data.mesh_enable = calloc(1, sizeof(mesh_mesh_enabled_event_s));
+               RETM_IF(NULL == ev.data.mesh_enable, "Failed to memory allocation !");
+               ev.data.mesh_enable->result = result;
+               h->event_handler(MESH_MESH_ENABLED_EVENT, &ev);
+               g_free(ev.data.mesh_enable);
+       } else if (0 == g_strcmp0(signal_name, "scan_done")) {
+               /* Read scan results first */
+               _mesh_get_scan_result(h);
+               /* Then, notify of scan_done event */
+               h->event_handler(MESH_SCAN_DONE_EVENT, NULL);
+       } else if (0 == g_strcmp0(signal_name, "joined_network")) {
+               h->event_handler(MESH_JOIN_NETWORK_EVENT, NULL);
+       } else if (0 == g_strcmp0(signal_name, "left_network")) {
+               h->event_handler(MESH_LEFT_NETWORK_EVENT, NULL);
+       } else if (0 == g_strcmp0(signal_name, "sta_joined")) {
+               char *bssid = NULL;
+               mesh_event_data_s ev;
+               ev.data.sta_info = calloc(1, sizeof(mesh_other_station_event_s));
+               RETM_IF(NULL == ev.data.sta_info, "Failed to memory allocation !");
+               g_variant_get(parameters, "(s)", bssid);
+               memcpy(ev.data.sta_info->bssid, bssid, MAX_BSSID_LEN);
+               h->event_handler(MESH_STATION_JOIN_EVENT, &ev);
+               g_free(ev.data.sta_info);
+       } else if (0 == g_strcmp0(signal_name, "sta_left")) {
+               char *bssid = NULL;
+               mesh_event_data_s ev;
+               ev.data.sta_info = calloc(1, sizeof(mesh_other_station_event_s));
+               RETM_IF(NULL == ev.data.sta_info, "Failed to memory allocation !");
+               g_variant_get(parameters, "(s)", bssid);
+               memcpy(ev.data.sta_info->bssid, bssid, MAX_BSSID_LEN);
+               h->event_handler(MESH_STATION_LEFT_EVENT, &ev);
+               g_free(ev.data.sta_info);
+       }
+}
+
+static void _mesh_subscribe_event(mesh_h handle)
+{
+       unsigned int id;
+       struct mesh_handle *h = handle;
+
+       id = g_dbus_connection_signal_subscribe((GDBusConnection *)h->dbus_connection,
+                       NULL, MESH_SERVER_NAME, "mesh_enabled", MESH_OBJECT_PATH, NULL,
+                       G_DBUS_CALL_FLAGS_NONE, _mesh_signal_handler, h, NULL);
+       if (0 == id) {
+               LOGE("g_dbus_connection_signal_subscribe(mesh_enabled) Fail(%d)", errno);
+               return;
+       }
+       h->dbus_sub_ids = g_list_append(h->dbus_sub_ids, GUINT_TO_POINTER(id));
+       LOGD("subscribed for mesh_enabled signal %d", id);
+
+       id = g_dbus_connection_signal_subscribe(h->dbus_connection, NULL, MESH_SERVER_NAME,
+                       "scan_done", MESH_OBJECT_PATH, NULL,
+                       G_DBUS_CALL_FLAGS_NONE, _mesh_signal_handler, h, NULL);
+       if (0 == id) {
+               LOGE("g_dbus_connection_signal_subscribe(scan_done) Fail(%d)", errno);
+               return;
+       }
+       h->dbus_sub_ids = g_list_append(h->dbus_sub_ids, GUINT_TO_POINTER(id));
+       LOGD("subscribed for scan_done signal %d", id);
+
+       id = g_dbus_connection_signal_subscribe(h->dbus_connection, NULL, MESH_SERVER_NAME,
+                       "joined_network", MESH_OBJECT_PATH, NULL,
+                       G_DBUS_CALL_FLAGS_NONE, _mesh_signal_handler, h, NULL);
+       if (0 == id) {
+               LOGE("g_dbus_connection_signal_subscribe(joined_network) Fail(%d)", errno);
+               return;
+       }
+       h->dbus_sub_ids = g_list_append(h->dbus_sub_ids, GUINT_TO_POINTER(id));
+       LOGD("subscribed for joined_network signal %d", id);
+
+       id = g_dbus_connection_signal_subscribe(h->dbus_connection, NULL, MESH_SERVER_NAME,
+                       "left_network", MESH_OBJECT_PATH, NULL,
+                       G_DBUS_CALL_FLAGS_NONE, _mesh_signal_handler, h, NULL);
+       if (0 == id) {
+               LOGE("g_dbus_connection_signal_subscribe(left_network) Fail(%d)", errno);
+               return;
+       }
+       h->dbus_sub_ids = g_list_append(h->dbus_sub_ids, GUINT_TO_POINTER(id));
+       LOGD("subscribed for left_network signal %d", id);
+
+
+       id = g_dbus_connection_signal_subscribe(h->dbus_connection, NULL, MESH_SERVER_NAME,
+                       "sta_joined", MESH_OBJECT_PATH, NULL,
+                       G_DBUS_CALL_FLAGS_NONE, _mesh_signal_handler, h, NULL);
+       if (0 == id) {
+               LOGE("g_dbus_connection_signal_subscribe(sta_joined) Fail(%d)", errno);
+               return;
+       }
+       h->dbus_sub_ids = g_list_append(h->dbus_sub_ids, GUINT_TO_POINTER(id));
+       LOGD("subscribed for sta_joined signal %d", id);
+
+       id = g_dbus_connection_signal_subscribe(h->dbus_connection, NULL, MESH_SERVER_NAME,
+                       "sta_left", MESH_OBJECT_PATH, NULL,
+                       G_DBUS_CALL_FLAGS_NONE, _mesh_signal_handler, h, NULL);
+       if (0 == id) {
+               LOGE("g_dbus_connection_signal_subscribe(sta_left) Fail(%d)", errno);
+               return;
+       }
+       h->dbus_sub_ids = g_list_append(h->dbus_sub_ids, GUINT_TO_POINTER(id));
+       LOGD("subscribed for sta_left signal %d", id);
+}
+
 int _mesh_dbus_start(mesh_h handle)
 {
        struct mesh_handle *h = handle;
@@ -117,6 +331,9 @@ int _mesh_dbus_start(mesh_h handle)
        g_dbus_proxy_set_default_timeout(
                        G_DBUS_PROXY(_gproxy_mesh_service), MESH_DBUS_PROXY_TIMEOUT);
 
+       /* Subscribe events */
+       _mesh_subscribe_event(handle);
+
        return MESH_ITNL_ERR_NONE;
 }
 
@@ -142,33 +359,6 @@ int _mesh_dbus_stop(mesh_h handle)
        return rv;
 }
 
-struct mesh_network_list_s {
-       int count;
-       GList *list;
-};
-struct mesh_network_list_s g_networks;
-
-static void _mesh_free_network(gpointer data)
-{
-       struct mesh_network_s *network = data;
-       g_free(network->meshid);
-       g_free(network->bssid);
-       g_free(network);
-       network = NULL;
-}
-
-static void _mesh_append_network(gpointer data)
-{
-       g_networks.list = g_list_append(g_networks.list, data);
-       g_networks.count++;
-}
-
-static void _mesh_remove_networks()
-{
-       g_list_free_full(g_networks.list, _mesh_free_network);
-       g_networks.count = 0;
-}
-
 struct mesh_mpath_list_s {
        int count;
        GList *list;
@@ -207,6 +397,8 @@ int _mesh_enable(mesh_h handle, mesh_event_cb event_handler)
        RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
 
+       h->event_handler = event_handler;
+
        variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "enable",
                                NULL,
                                G_DBUS_CALL_FLAGS_NONE,
@@ -220,7 +412,6 @@ int _mesh_enable(mesh_h handle, mesh_event_cb event_handler)
                g_error_free(error);
                return MESH_ITNL_ERR_IO_ERROR;
        }
-       h->event_handler = event_handler;
 
        return MESH_ITNL_ERR_NONE;
 }
@@ -245,7 +436,7 @@ int _mesh_disable(mesh_h handle)
                                NULL, &error);
        if (variant) {
                g_variant_get(variant, "(u)", &result);
-               LOGD("isabled status 0x%x", result);
+               LOGD("Disabled status 0x%x", result);
        } else if (error) {
                LOGE("Failed DBus call [%s]", error->message);
                g_error_free(error);
@@ -274,6 +465,10 @@ int _mesh_scan(mesh_h handle)
        if (variant) {
                g_variant_get(variant, "(u)", &result);
                LOGD("scan status 0x%x", result);
+
+               /* Read again */
+               if (MESH_ITNL_ERR_NONE != result)
+                       _mesh_get_scan_result(h);
        } else if (error) {
                LOGE("Failed DBus call [%s]", error->message);
                g_error_free(error);
@@ -340,78 +535,33 @@ int _mesh_cancel_scan(mesh_h handle)
 int _mesh_foreach_found_mesh_network(mesh_h handle,
        mesh_found_mesh_netwrok_cb cb, void *user_data)
 {
-       GVariant *variant = NULL;
-       unsigned int result;
-       GError *error = NULL;
+       int i;
+       GList *iter = NULL;
+       struct mesh_network_s *data = NULL;
        struct mesh_handle *h = handle;
 
-       GVariant *params = NULL;
-       GVariant *inner_params = NULL;
-       GVariantIter iter, inner_iter;
-
-       gchar *key;
-       GVariant *val;
-       gsize len = 0;
-
-       _mesh_remove_networks();
-
        RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
 
-       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "get_found_mesh_networks",
-                               NULL,
-                               G_DBUS_CALL_FLAGS_NONE,
-                               -1,
-                               NULL, &error);
-       if (variant) {
-               /* handle station list here */
-               g_variant_get(variant, "(a(a{sv})u)", &params, &result);
-
-               g_variant_iter_init(&iter, params);
-               while (g_variant_iter_loop(&iter, "(a{sv})", &inner_params)) {
+       if (0 >= g_list_length(g_networks.list)) {
+               LOGD("No scan result");
+               return MESH_ITNL_ERR_NONE;
+       }
 
-                       struct mesh_network_s *network_info =
-                               g_malloc0(sizeof(struct mesh_network_s));
+       /* Get a first item */
+       i = 0;
+       iter = g_list_first(g_networks.list);
 
-                       g_variant_iter_init(&inner_iter, inner_params);
-                       while (g_variant_iter_loop(&inner_iter, "{sv}", &key, &val)) {
-                               if (strcasecmp(key, "meshid") == 0)  {
-                                       const char *buf = g_variant_get_string(val, &len);
-                                       memcpy(network_info->meshid, buf, len);
-                                       //network_info->meshid = g_variant_get_string(val, &len);
-                                       LOGE("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);
-                                       //network_info->bssid = g_variant_dup_string(val, &len);
-                                       LOGE("bssid = %s", network_info->bssid);
-                               }
-                               else if (strcasecmp(key, "channel") == 0)  {
-                                       network_info->channel = g_variant_get_int32(val);
-                                       LOGE("channel = %d", network_info->channel);
-                               }
-                               else if (strcasecmp(key, "rssi") == 0)  {
-                                       network_info->rssi = g_variant_get_int32(val);
-                                       LOGE("rssi = %d", network_info->rssi);
-                               }
-                               else if (strcasecmp(key, "data_rate") == 0)  {
-                                       network_info->data_rate = g_variant_get_int32(val);
-                                       LOGE("data_rate = %d", network_info->data_rate);
-                                       /* Last element */
-                                       _mesh_append_network(network_info);
-                                       if (cb) cb(network_info, user_data);
-                               }
-                       }
-                       g_variant_unref(inner_params);
+       while (NULL != iter) {
+               data = iter->data;
+               if (cb) {
+                       LOGD("[%d] meshid=%s bssid=%s channel=%d", i, data->meshid, data->bssid, data->channel);
+                       cb(data, user_data);
                }
-               g_variant_unref(params);
-               LOGD("get_found_mesh_networks status 0x%x", result);
-
-       } else if (error) {
-               LOGE("Failed DBus call [%s]", error->message);
-               g_error_free(error);
-               return MESH_ITNL_ERR_IO_ERROR;
+               LOGD("%d", i);
+               /* Next item */
+               i++;
+               iter = g_list_next(iter);
        }
 
        return MESH_ITNL_ERR_NONE;
@@ -499,7 +649,9 @@ int _mesh_is_joined(mesh_h handle, int* is_joined)
        return MESH_ITNL_ERR_NONE;
 }
 
-int _mesh_get_joined_mesh_network(mesh_h handle, mesh_network_h _network)
+struct mesh_network_s g_joined_network;
+
+int _mesh_get_joined_mesh_network(mesh_h handle, mesh_network_h* _network)
 {
        GVariant *variant = NULL;
        GError *error = NULL;
@@ -515,23 +667,29 @@ int _mesh_get_joined_mesh_network(mesh_h handle, mesh_network_h _network)
                                -1,
                                NULL, &error);
        if (variant) {
-               struct mesh_network_s *n = _network;
+
                int len;
                char *meshid = NULL;
                char *bssid = NULL;
-               int channel, max_speed;
+               int channel;
                unsigned int result;
 
-               g_variant_get(variant, "(ssiiu)", meshid, bssid, &channel, &max_speed, &result);
+               g_variant_get(variant, "(ssiu)", meshid, bssid, &channel, &result);
                LOGD("get_joined_mesh_network status 0x%x", result);
 
+               if (MESH_ITNL_ERR_NONE != result)
+                       return (int)result;
+
                len = strlen(meshid);
-               memcpy(n->meshid, meshid, len > 32 ? 32 : len);
+               LOGE("meshid=%s len=%d", meshid, len);
+               memcpy(g_joined_network.meshid, meshid, len > 32 ? 32 : len);
                len = strlen(bssid);
-               memcpy(n->bssid, bssid, len > 32 ? 32 : len);
-               n->channel = channel;
-               n->data_rate = max_speed;
-               n->rssi = -1;
+               LOGE("bssid=%s len=%d", bssid, len);
+               memcpy(g_joined_network.bssid, bssid, len > 32 ? 32 : len);
+               g_joined_network.channel = channel;
+               g_joined_network.rssi = -1;
+
+               *_network= &g_joined_network;
 
        } else if (error) {
                LOGE("Failed DBus call [%s]", error->message);
@@ -692,7 +850,7 @@ int _mesh_add_network(mesh_h handle, mesh_network_h _network)
        RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
 
-       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "add_network",
+       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "add_mesh_network",
                                g_variant_new("(sii)", n->meshid, n->channel, n->security),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
@@ -717,59 +875,49 @@ int _mesh_foreach_saved_mesh_netwrok(mesh_h handle,
        GError *error = NULL;
        struct mesh_handle *h = handle;
 
-       GVariant *params = NULL;
-       GVariant *inner_params = NULL;
-       GVariantIter iter, inner_iter;
+       GVariantIter *iter = NULL;
+       GVariantIter *iter_row = NULL;
 
        gchar *key;
        GVariant *val;
        gsize len = 0;
 
-       _mesh_remove_networks();
+       struct mesh_network_s network_info;
 
        RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
 
-       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "get_found_mesh_networks",
+       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "get_saved_mesh_network",
                                NULL,
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
                                NULL, &error);
        if (variant) {
                /* handle station list here */
-               g_variant_get(variant, "(a(a{sv})u)", &params, &result);
-
-               g_variant_iter_init(&iter, params);
-               while (g_variant_iter_loop(&iter, "(a{sv})", &inner_params)) {
-
-                       struct mesh_network_s *network_info =
-                               g_malloc0(sizeof(struct mesh_network_s));
-
-                       g_variant_iter_init(&inner_iter, inner_params);
-                       while (g_variant_iter_loop(&inner_iter, "{sv}", &key, &val)) {
-                               if (strcasecmp(key, "meshid") == 0)  {
+               g_variant_get(variant, "(aa{sv}u)", &iter, &result);
+               while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
+                       memset(&network_info, 0, 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);
+                                       memcpy(network_info.meshid, buf, len);
                                        //network_info->meshid = g_variant_dup_string(val, &len);
-                                       LOGE("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);
-                                       //network_info->bssid = g_variant_dup_string(val, &len);
-                                       LOGE("bssid = %s", network_info->bssid);
+                                       LOGE("meshid=%s", network_info.meshid);
                                }
                                else if (strcasecmp(key, "channel") == 0)  {
-                                       network_info->channel = g_variant_get_int32(val);
-                                       LOGE("channel = %d", network_info->channel);
+                                       network_info.channel = g_variant_get_uint32(val);
+                                       LOGE("channel = %d", network_info.channel);
+                               }
+                               else if (strcasecmp(key, "security") == 0)  {
+                                       network_info.security = g_variant_get_uint32(val);
+                                       LOGE("security = %d", network_info.security);
 
-                                       _mesh_append_network(network_info);
-                                       if (cb) cb(network_info, user_data);
+                                       if (cb) cb(&network_info, user_data);
                                }
                        }
-                       g_variant_unref(inner_params);
+                       g_variant_iter_free(iter_row);
                }
-               g_variant_unref(params);
+               g_variant_iter_free(iter);
                LOGD("get_saved_mesh_networks status 0x%x", result);
 
        } else if (error) {
@@ -792,7 +940,7 @@ int _mesh_select_network(mesh_h handle, mesh_network_h _network)
        RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
 
-       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "select_network",
+       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "select_saved_mesh_network",
                                g_variant_new("(sii)", n->meshid, n->channel, n->security),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
@@ -820,7 +968,9 @@ int _mesh_remove_network(mesh_h handle, mesh_network_h _network)
        RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
 
-       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "remove_network",
+       LOGD("mesid=%s channel=%d security=%d", n->meshid, n->channel, n->security);
+
+       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "forget_saved_mesh_network",
                                g_variant_new("(sii)", n->meshid, n->channel, n->security),
                                G_DBUS_CALL_FLAGS_NONE,
                                -1,
@@ -869,11 +1019,11 @@ int _mesh_get_station_info(mesh_h handle, void *station)
                                -1,
                                NULL, &error);
        if (variant) {
-               g_variant_get(variant, "(a(a{sv})u)", &params, &result);
+               g_variant_get(variant, "(aa{sv}u)", &params, &result);
 
                /* TODO: handle station list here */
                g_variant_iter_init(&iter, params);
-               while (g_variant_iter_loop(&iter, "(a{sv})", &inner_params)) {
+               while (g_variant_iter_loop(&iter, "a{sv}", &inner_params)) {
 
                        g_variant_iter_init(&inner_iter, inner_params);
                        while (g_variant_iter_loop(&inner_iter, "{sv}", &key, &val)) {
@@ -928,13 +1078,13 @@ int _mesh_get_path_info(mesh_h handle, void* mpath_data)
                                -1,
                                NULL, &error);
        if (variant) {
-               g_variant_get(variant, "(a(a{sv})u)", &params, &result);
+               g_variant_get(variant, "(aa{sv}u)", &params, &result);
 
                /* handle station list here */
                _mesh_remove_mpath();
 
                g_variant_iter_init(&iter, params);
-               while (g_variant_iter_loop(&iter, "(a{sv})", &inner_params)) {
+               while (g_variant_iter_loop(&iter, "a{sv}", &inner_params)) {
                        struct mesh_mpath_dump_s *mpath = g_malloc0(sizeof(struct mesh_mpath_dump_s));
                        g_variant_iter_init(&inner_iter, inner_params);
                        while (g_variant_iter_loop(&inner_iter, "{sv}", &key, &val)) {
@@ -967,18 +1117,30 @@ int _mesh_get_path_info(mesh_h handle, void* mpath_data)
        return MESH_ITNL_ERR_NONE;
 }
 
-int _mesh_set_interface(mesh_h handle, const char *mesh, const char *gate, const char *softap)
+int _mesh_set_interfaces(mesh_h handle, const char *mesh, const char *gate, const char *softap)
 {
+       GVariant *variant = NULL;
+       unsigned int result;
+       GError *error = NULL;
        struct mesh_handle *h = handle;
 
        RETV_IF(NULL == h->dbus_connection, MESH_ITNL_ERR_IO_ERROR);
        RETV_IF(NULL == _gproxy_mesh_service, MESH_ITNL_ERR_IO_ERROR);
 
-       LOGE("Not implemented yet!!");
+       variant = g_dbus_proxy_call_sync(_gproxy_mesh_service, "set_interfaces",
+                               g_variant_new("(sss)", mesh, gate, softap),
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1,
+                               NULL, &error);
+       if (variant) {
+               g_variant_get(variant, "(u)", &result);
+               LOGD("set_interfaces status 0x%x", result);
+       } else if (error) {
+               LOGE("Failed DBus call [%s]", error->message);
+               g_error_free(error);
+               return MESH_ITNL_ERR_IO_ERROR;
+       }
 
-       NOTUSED(mesh);
-       NOTUSED(gate);
-       NOTUSED(softap);
        return MESH_ITNL_ERR_NONE;
 }
 
old mode 100755 (executable)
new mode 100644 (file)
index 6c4b2ef..29cfcc5
@@ -58,13 +58,50 @@ const char* mesh_error_to_string(mesh_error_e err)
        }
 }
 
-void event_cb(mesh_event_e event_type, void* param)
+static const char* _mesh_event_to_string(mesh_event_e e)
 {
+       switch (e) {
+       /* CHECK: List all enum values here */
+       CASE_TO_STR(MESH_MESH_ENABLED_EVENT)
+       CASE_TO_STR(MESH_SCAN_DONE_EVENT)
+       CASE_TO_STR(MESH_JOIN_NETWORK_EVENT)
+       CASE_TO_STR(MESH_LEFT_NETWORK_EVENT)
+       CASE_TO_STR(MESH_STATION_JOIN_EVENT)
+       CASE_TO_STR(MESH_STATION_LEFT_EVENT)
+       default :
+               return "MESH_EVENT_UNKNOWN";
+       }
+}
 
+void event_cb(mesh_event_e event_type, mesh_event_data_s* event)
+{
+       msgp("event received = %s", _mesh_event_to_string(event_type));
+
+       switch(event_type) {
+               case MESH_MESH_ENABLED_EVENT: {
+                       msgp("Mesh Network Enabled Result = %d", event->data.mesh_enable->result);
+               } break;
+               case MESH_SCAN_DONE_EVENT: {
+                       msgp("Mesh Scan Done");
+               } break;
+               case MESH_JOIN_NETWORK_EVENT:{
+                       msgp("Joined Network");
+               } break;
+               case MESH_LEFT_NETWORK_EVENT: {
+                       msgp("Left Current Network");
+               } break;
+               case MESH_STATION_JOIN_EVENT: {
+                       msgp("New Station Joined = %s", event->data.sta_info->bssid);
+               } break;
+               case MESH_STATION_LEFT_EVENT: {
+                       msgp("A Station Left = %s", event->data.sta_info->bssid);
+               } break;
+       }
 }
 
 static int __init_func(MManager *mm, struct menu_data *menu)
 {
+#if 0
        int ret = -1;
 
        ret = mesh_initialize(&mesh);
@@ -73,7 +110,7 @@ static int __init_func(MManager *mm, struct menu_data *menu)
                                mesh_error_to_string(ret), ret);
                return RET_FAILURE;
        }
-
+#endif
        return RET_SUCCESS;
 }
 
@@ -124,8 +161,11 @@ int main(int arg, char **argv)
        g_main_loop_run(mainloop);
 
 OUT:
-       g_hash_table_remove_all(g_hash_scan_net_list);
-       g_hash_table_remove_all(g_hash_saved_net_list);
+       if (g_hash_scan_net_list)
+               g_hash_table_remove_all(g_hash_scan_net_list);
+       if (g_hash_saved_net_list)
+               g_hash_table_remove_all(g_hash_saved_net_list);
+
        g_main_loop_unref(mainloop);
        msg("******* Bye bye *******");
 
old mode 100755 (executable)
new mode 100644 (file)
index c6377c9..a2eee8d
@@ -90,17 +90,17 @@ static int run_mesh_disable(MManager *mm, struct menu_data *menu)
        return RET_SUCCESS;
 }
 
-static char mesh_interface[MENU_DATA_SIZE + 1] = "wlan0";
+static char mesh_interface[MENU_DATA_SIZE + 1] = "mesh0";
 static char gate_interface[MENU_DATA_SIZE + 1] = "eth0";
 static char softap_interface[MENU_DATA_SIZE + 1] = "wlan1";
-static int run_mesh_set_interface(MManager *mm, struct menu_data *menu)
+static int run_mesh_set_interfaces(MManager *mm, struct menu_data *menu)
 {
        int ret;
        msg("set_interfaces");
 
-       ret = mesh_set_interface(mesh, mesh_interface, gate_interface, softap_interface);
+       ret = mesh_set_interfaces(mesh, mesh_interface, gate_interface, softap_interface);
        if (ret != 0) {
-               msg("Failed to set interface: [%s(0x%X)]",
+               msg("Failed to set interfaces: [%s(0x%X)]",
                                mesh_error_to_string(ret), ret);
                return RET_FAILURE;
        }
@@ -112,7 +112,7 @@ static struct menu_data menu_mesh_interface[] = {
        { "1", "mesh", NULL, NULL, mesh_interface },
        { "2", "gate", NULL, NULL, gate_interface },
        { "3", "softap", NULL, NULL, softap_interface },
-       { "4", "run", NULL, run_mesh_set_interface, NULL },
+       { "4", "run", NULL, run_mesh_set_interfaces, NULL },
        { NULL, NULL, },
 };
 
old mode 100755 (executable)
new mode 100644 (file)
index 4c8cfab..5a695db
@@ -33,7 +33,7 @@ static char stp[MENU_DATA_SIZE + 1] = "1";
 static char gate_announce[MENU_DATA_SIZE + 1] = "1";
 
 static char ssid[MENU_DATA_SIZE + 1] = "meshnet";
-static char key[MENU_DATA_SIZE + 1] = "11223344";
+static char passphrase[MENU_DATA_SIZE + 1] = "11223344";
 static char mode[MENU_DATA_SIZE + 1] = "ac";
 static char softap_channel[MENU_DATA_SIZE + 1] = "36";
 static char visibility[MENU_DATA_SIZE + 1] = "1";
@@ -57,41 +57,45 @@ void found_mesh_netwrok_cb(mesh_network_h network, void* user_data)
 {
        int ret;
        mesh_network_h net = NULL;
-       char meshid[MAX_MESHID_LEN] = {0,};
-       char bssid[MAX_BSSID_LEN] = {0,};
+       char *meshid = NULL;
+       char *bssid = NULL;
        int channel;
+
        ret = mesh_network_clone(&net, network);
        if (0 != ret) {
                msg("Failed to clone scaned network: [%s(0x%X)]", mesh_error_to_string(ret), ret);
                return;
        }
+
        if (g_hash_table_insert(g_hash_scan_net_list, GINT_TO_POINTER(g_scan_net_idx), net)) {
-               g_scan_net_idx++;
-               mesh_network_get_meshid(net, meshid);
-               mesh_network_get_bssid(net, bssid);
+               mesh_network_get_meshid(net, &meshid);
+               mesh_network_get_bssid(net, &bssid);
                mesh_network_get_channel(net, &channel);
-               msg("[%d] meshid=%s bssid=%s channel=%d", g_scan_net_idx, meshid, bssid, channel);
+               msgb("[%d] meshid=%s bssid=%s channel=%d", g_scan_net_idx, meshid, bssid, channel);
+
+               g_scan_net_idx++;
        }
+
 }
 
 void saved_mesh_netwrok_cb(mesh_network_h network, void* user_data)
 {
-       int ret;
        mesh_network_h net = NULL;
-       char meshid[MAX_MESHID_LEN] = {0,};
-       char bssid[MAX_BSSID_LEN] = {0,};
+       int ret = mesh_network_clone(&net, network);
+
+       char *meshid = NULL;
        int channel;
-       ret = mesh_network_clone(&net, network);
+
        if (0 != ret) {
                msg("Failed to clone configured network: [%s(0x%X)]", mesh_error_to_string(ret), ret);
                return;
        }
        if (g_hash_table_insert(g_hash_saved_net_list, GINT_TO_POINTER(g_saved_net_idx), net)) {
-               g_saved_net_idx++;
-               mesh_network_get_meshid(net, meshid);
-               mesh_network_get_bssid(net, meshid);
+               mesh_network_get_meshid(net, &meshid);
                mesh_network_get_channel(net, &channel);
-               msg("[%d] meshid=%s bssid=%s channel=%d", g_saved_net_idx, meshid, bssid, channel);
+               msg("[%d] meshid=%s channel=%d", g_saved_net_idx, meshid, channel);
+
+               g_saved_net_idx++;
        }
 }
 
@@ -115,9 +119,11 @@ static int run_get_scanned_mesh_network(MManager *mm, struct menu_data *menu)
        msg("Get Scanned Mesh Network");
 
        /* Clear previous scanned network list */
-       g_scan_net_idx = 0;
+       g_scan_net_idx = 1;
        if (g_hash_scan_net_list) g_hash_table_remove_all(g_hash_scan_net_list);
-       g_hash_scan_net_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, free);
+
+       g_hash_scan_net_list =
+               g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, mesh_network_destroy);
 
        ret = mesh_foreach_scanned_mesh_netwrok(mesh, found_mesh_netwrok_cb, NULL);
        if (ret != 0) {
@@ -137,7 +143,7 @@ static int run_mesh_specific_scan(MManager *mm, struct menu_data *menu)
        msg("Specific scan");
 
        if (strlen(mesh_channel))
-               channel = (unsigned short)strtol(mesh_channel, NULL, 16);
+               channel = (unsigned short)strtol(mesh_channel, NULL, 10);
 
        ret = mesh_specific_scan(mesh, meshid, channel);
        if (ret != 0) {
@@ -221,7 +227,7 @@ static int run_set_gate(MManager *mm, struct menu_data *menu)
        if (strlen(stp))
                _stp = (unsigned short)strtol(stp, NULL, 16);
        if (strlen(gate_announce))
-               _gate_announce = (unsigned short)strtol(gate_announce, NULL, 16);
+               _gate_announce = (unsigned short)strtol(gate_announce, NULL, 10);
 
        ret = mesh_set_gate(mesh, _stp, _gate_announce);
        if (ret != 0) {
@@ -259,19 +265,19 @@ static int run_set_softap(MManager *mm, struct menu_data *menu)
 
 
        if (strlen(softap_channel))
-               _channel = (unsigned short)strtol(softap_channel, NULL, 16);
+               _channel = (unsigned short)strtol(softap_channel, NULL, 10);
        if (strlen(visibility)) {
-               _visibility = (unsigned short)strtol(visibility, NULL, 16);
+               _visibility = (unsigned short)strtol(visibility, NULL, 10);
                if (1 != _visibility) _visibility = 0;
        }
        if (strlen(max_stations))
-               _max_stations = (unsigned short)strtol(max_stations, NULL, 16);
+               _max_stations = (unsigned short)strtol(max_stations, NULL, 10);
        if (strlen(security))
-               _security = (unsigned short)strtol(security, NULL, 16);
+               _security = (unsigned short)strtol(security, NULL, 10);
 
-       ret = mesh_set_softap(mesh, ssid, key, _channel, _visibility, _max_stations, _security);
+       ret = mesh_set_softap(mesh, ssid, passphrase, _channel, _visibility, _max_stations, _security);
        if (ret != 0) {
-               msg("Failed to unset gate option: [%s(0x%X)]",
+               msg("Failed to set softap options: [%s(0x%X)]",
                        mesh_error_to_string(ret), ret);
                return RET_FAILURE;
        }
@@ -313,9 +319,11 @@ static int run_get_saved_network(MManager *mm, struct menu_data *menu)
        msg("Get Saved Mesh Network Configuration");
 
        /* Clear previous saved network configurations */
-       g_saved_net_idx = 0;
+       g_saved_net_idx = 1;
        if (g_hash_saved_net_list) g_hash_table_remove_all(g_hash_saved_net_list);
-       g_hash_saved_net_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, free);
+
+       g_hash_saved_net_list =
+               g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, mesh_network_destroy);
 
        ret = mesh_foreach_saved_mesh_network(mesh, saved_mesh_netwrok_cb, NULL);
        if (ret != 0) {
@@ -335,15 +343,69 @@ static int run_add_network(MManager *mm, struct menu_data *menu)
        msg("Add Network Configuration");
 
        if (strlen(network_idx))
-               idx = (unsigned short)strtol(network_idx, NULL, 16);
+               idx = (unsigned short)strtol(network_idx, NULL, 10);
+
+       if (g_hash_saved_net_list) {
+               net = g_hash_table_lookup(g_hash_saved_net_list, GINT_TO_POINTER(idx));
+               if (NULL != net) {
+                       msg("Already added");
+                       return RET_FAILURE;
+               }
+       }
 
-       net = g_hash_table_lookup(g_hash_scan_net_list, GINT_TO_POINTER(idx));
        if (NULL == net) {
-               msg("Failed to g_hash_table_lookup");
+               msg("Failed to get existing network from scan list");
+               return RET_FAILURE;
+       }
+
+       ret = mesh_add_mesh_network(mesh, net);
+       if (ret != 0) {
+               msg("Failed to mesh_add_mesh_network: [%s(0x%X)]",
+                               mesh_error_to_string(ret), ret);
                return RET_FAILURE;
        }
 
+       return RET_SUCCESS;
+}
+
+static int run_add_new_network(MManager *mm, struct menu_data *menu)
+{
+       int ret;
+       int chan;
+       unsigned short _mesh_channel = 1;
+       mesh_network_h net = NULL;
+       msg("Add New Network Configuration");
+
+       if (strlen(mesh_channel))
+               _mesh_channel = (unsigned short)strtol(mesh_channel, NULL, 10);
+
+       if (g_hash_scan_net_list) {
+
+               char *_meshid = NULL;
+               int _channel;
+
+               GList *values = g_hash_table_get_values(g_hash_scan_net_list);
+               GList *iter_list = values;
+
+               while (iter_list != NULL) {
+                       mesh_network_h _net = iter_list->data;
+                       mesh_network_get_meshid(_net, &_meshid);
+                       mesh_network_get_channel(_net, &_channel);
+                       if (0 == g_strcmp0(_meshid, meshid) && _channel == _mesh_channel) {
+                               msg("Already added");
+                               return RET_FAILURE;
+                       }
+                       iter_list = g_list_next(iter_list);
+               }
+
+               g_list_free(values);
+       }
+
+       mesh_network_new_with(&net, meshid, NULL, _mesh_channel, 0, 0);
        ret = mesh_add_mesh_network(mesh, net);
+       mesh_network_get_channel(net, &chan);
+       msg("channel = %d %d", _mesh_channel, chan);
+       mesh_network_destroy(net);
        if (ret != 0) {
                msg("Failed to mesh_add_mesh_network: [%s(0x%X)]",
                                mesh_error_to_string(ret), ret);
@@ -353,6 +415,7 @@ static int run_add_network(MManager *mm, struct menu_data *menu)
        return RET_SUCCESS;
 }
 
+
 static int run_select_network(MManager *mm, struct menu_data *menu)
 {
        int ret;
@@ -361,12 +424,14 @@ static int run_select_network(MManager *mm, struct menu_data *menu)
        msg("Select Save Network Configuration");
 
        if (strlen(network_idx))
-               idx = (unsigned short)strtol(network_idx, NULL, 16);
-
-       net = g_hash_table_lookup(g_hash_scan_net_list, GINT_TO_POINTER(idx));
-       if (NULL == net) {
-               msg("Failed to g_hash_table_lookup");
-               return RET_FAILURE;
+               idx = (unsigned short)strtol(network_idx, NULL, 10);
+
+       if (g_hash_scan_net_list) {
+               net = g_hash_table_lookup(g_hash_scan_net_list, GINT_TO_POINTER(idx));
+               if (NULL == net) {
+                       msg("Failed to g_hash_table_lookup");
+                       return RET_FAILURE;
+               }
        }
 
        ret = mesh_select_mesh_network(mesh, net);
@@ -379,6 +444,17 @@ static int run_select_network(MManager *mm, struct menu_data *menu)
        return RET_SUCCESS;
 }
 
+static gboolean _mesh_lookup_by_id(gpointer key, gpointer value, gpointer user_data)
+{
+       int k = (int)key;
+       int id = (int)user_data;
+
+       if (k == id)
+               return TRUE;
+
+       return FALSE;
+}
+
 static int run_remove_network(MManager *mm, struct menu_data *menu)
 {
        int ret;
@@ -387,15 +463,37 @@ static int run_remove_network(MManager *mm, struct menu_data *menu)
        msg("Remove Save Network Configuration");
 
        if (strlen(network_idx))
-               idx = (unsigned short)strtol(network_idx, NULL, 16);
+               idx = (unsigned short)strtol(network_idx, NULL, 10);
 
-       net = g_hash_table_lookup(g_hash_scan_net_list, GINT_TO_POINTER(idx));
-       if (NULL == net) {
-               msg("Failed to g_hash_table_lookup");
-               return RET_FAILURE;
+       if (g_hash_saved_net_list) {
+
+               char *_meshid = NULL;
+               int _channel;
+
+               GList *values = g_hash_table_get_values(g_hash_saved_net_list);
+               GList *iter_list = values;
+
+               while (iter_list != NULL) {
+                       mesh_network_h _net = iter_list->data;
+                       mesh_network_get_meshid(_net, &_meshid);
+                       mesh_network_get_channel(_net, &_channel);
+                       //msgb("meshid=%s channel=%d", _meshid, _channel);
+                       iter_list = g_list_next(iter_list);
+               }
+
+               g_list_free(values);
        }
 
-       ret = mesh_select_mesh_network(mesh, net);
+
+       if (g_hash_saved_net_list) {
+               net = g_hash_table_find(g_hash_saved_net_list, _mesh_lookup_by_id, GINT_TO_POINTER(idx));
+               if (NULL == net) {
+                       msg("Failed to g_hash_table_find");
+                       return RET_FAILURE;
+               }
+       }
+
+       ret = mesh_remove_mesh_network(mesh, net);
        if (ret != 0) {
                msg("Failed to mesh_remove_mesh_network: [%s(0x%X)]",
                                mesh_error_to_string(ret), ret);
@@ -432,7 +530,7 @@ static struct menu_data menu_gate_option[] = {
 
 static struct menu_data menu_softap_option[] = {
        { "1", "ssid", NULL, NULL, ssid },
-       { "2", "key", NULL, NULL, key },
+       { "2", "passphrase", NULL, NULL, passphrase },
        { "3", "802.11 mode", NULL, NULL, mode },
        { "4", "channel", NULL, NULL, softap_channel },
        { "5", "ssid broadcast=1, hidden=0", NULL, NULL, visibility },
@@ -443,21 +541,27 @@ static struct menu_data menu_softap_option[] = {
 };
 
 static struct menu_data menu_add_network[] = {
+       { "1", "index", NULL, NULL, network_idx },
+       { "2", "run", NULL, run_add_network, NULL },
+       { NULL, NULL, },
+};
+
+static struct menu_data menu_add_new_network[] = {
        { "1", "meshid", NULL, NULL, meshid },
        { "2", "channel", NULL, NULL, mesh_channel },
-       { "3", "run", NULL, run_add_network, NULL },
+       { "3", "run", NULL, run_add_new_network, NULL },
        { NULL, NULL, },
 };
 
 static struct menu_data menu_select_network[] = {
        { "1", "index", NULL, NULL, network_idx },
-       { "3", "run", NULL, run_select_network, NULL },
+       { "2", "run", NULL, run_select_network, NULL },
        { NULL, NULL, },
 };
 
 static struct menu_data menu_remove_network[] = {
        { "1", "index", NULL, NULL, network_idx },
-       { "3", "run", NULL, run_remove_network, NULL },
+       { "2", "run", NULL, run_remove_network, NULL },
        { NULL, NULL, },
 };
 
@@ -477,9 +581,10 @@ struct menu_data menu_mesh_network[] = {
        { "12", "disable softap", NULL, run_disable_softap, NULL },
        { "13", "Get Saved Mesh Network", NULL, run_get_saved_network, NULL },
        { "14", "add network", menu_add_network, NULL, NULL },
-       { "15", "select network", menu_select_network, NULL, NULL },
-       { "16", "remove network", menu_remove_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 },
+       { "15", "add new network", menu_add_new_network, NULL, NULL },
+       { "16", "select network", menu_select_network, NULL, NULL },
+       { "17", "remove network", menu_remove_network, NULL, 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, },
 };