Update inital peer-monitoring function
authorsaerome kim <saerome.kim@samsung.com>
Thu, 8 Jun 2017 04:59:24 +0000 (13:59 +0900)
committersaerome.kim <saerome.kim@samsung.com>
Mon, 17 Jul 2017 02:35:36 +0000 (11:35 +0900)
Signed-off-by: saerome kim <saerome.kim@samsung.com>
include/mesh-monitor.h [new file with mode: 0644]
include/mesh-netlink.h
src/mesh-monitor.c [new file with mode: 0644]
src/mesh-netlink.c
src/mesh-service.c

diff --git a/include/mesh-monitor.h b/include/mesh-monitor.h
new file mode 100644 (file)
index 0000000..0cff15c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+ #ifndef __MESH_MONITOR_H__
+#define __MESH_MONITOR_H__
+
+int mesh_start_peer_monitor(void *pdata);
+
+int mesh_stop_peer_monitor(void *pdata);
+
+#endif /* __MESH_MONITOR_H__ */
\ No newline at end of file
index ba60ad2..659e194 100644 (file)
@@ -35,6 +35,7 @@ int mesh_netlink_set_mesh_parameter(const char* mesh_if_name,
                const char* param_name, unsigned int value);
 
 int mesh_netlink_get_station_info(const char* mesh_if_name, GList **station_list);
+int mesh_netlink_del_station_info(const char* mesh_if_name, char *peer);
 int mesh_netlink_get_mpath_info(const char* mesh_if_name, GList **mpath_list);
 
 int mesh_netlink_register_event_handler();
diff --git a/src/mesh-monitor.c b/src/mesh-monitor.c
new file mode 100644 (file)
index 0000000..058fcc1
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Network Configuration Module
+ *
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <glib.h>
+
+#if 0
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#endif
+
+#include "mesh.h"
+#include "mesh-log.h"
+#include "mesh-util.h"
+#include "mesh-request.h"
+#include "mesh-netlink.h"
+#include "mesh-monitor.h"
+
+#define MESH_MONITORING_TIME 5
+#define MESH_MAXIMUM_BEACON_LOST_COUNT 10
+
+static guint g_timer = 0;
+
+static void _on_station_list_destroy(gpointer data)
+{
+       mesh_station_info_s *info = (mesh_station_info_s*)data;
+
+       if (info) {
+               g_free(info->bssid);
+               g_free(info);
+       }
+}
+#if 0
+static void _on_mpath_list_destroy(gpointer data)
+{
+       mesh_mpath_info_s *info = (mesh_mpath_info_s*)data;
+
+       if (info) {
+               g_free(info->dest_addr);
+               g_free(info->next_hop);
+               g_free(info->interface);
+               g_free(info);
+       }
+}
+#endif
+
+static int _get_station_info(void *pdata)
+{
+       int is_new;
+       int ret = MESHD_ERROR_NONE;
+
+       GList *iter = NULL;
+       GList *sta_list = NULL;
+       GList *cmp_iter = NULL;
+
+       mesh_service *service = (mesh_service *)pdata;
+       mesh_interface_s *info = service->interface_info;
+
+       ret = mesh_request_get_station_info(info->mesh_interface, &sta_list);
+       if (MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to mesh_request_get_station_info");
+               return ret;
+       }
+
+       iter = service->station_list;
+       while (iter) {
+               mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
+               MESH_LOGE("KSR1 : [%s]", item->bssid);
+               iter = g_list_next(iter);
+       }
+
+       iter = sta_list;
+       while (iter) {
+               mesh_station_info_s *item = (mesh_station_info_s*)iter->data;
+
+               /* Found this in th existing station infomation list. */
+               if (item->inactive_time > item->beacon_interval * MESH_MAXIMUM_BEACON_LOST_COUNT) {
+                       /* Remove this node from station list in kernel */
+                       mesh_netlink_del_station_info(info->mesh_interface, item->bssid);
+                       /* Remove current linked list */
+                       iter = g_list_remove(iter, item);
+                       /* Send existing node disjoined */
+                       MESH_LOGE("[%s] disjoined", item->bssid);
+
+               }
+
+               is_new = TRUE;
+               cmp_iter = service->station_list;
+               while (cmp_iter) {
+                       mesh_station_info_s *cmp_item = (mesh_station_info_s*)cmp_iter->data;
+                       if (0 == strncmp(item->bssid, cmp_item->bssid, sizeof("11:22:33:44:55:66"))) {
+                               is_new = FALSE;
+                               break;
+                       }
+                       cmp_iter = g_list_next(cmp_iter);
+               }
+
+               if (is_new) {
+                       /* Send new station joined event */
+                       MESH_LOGE("[%s] joined", item->bssid);
+               }
+
+               iter = g_list_next(iter);
+       }
+
+       /* Clear mesh station list */
+       g_list_free_full(service->station_list, _on_station_list_destroy);
+       /* Copy new mesh station list */
+       service->station_list = sta_list;
+
+       iter = service->station_list;
+       while (iter) {
+               mesh_station_info_s *item2 = (mesh_station_info_s*)iter->data;
+               MESH_LOGE("KSR2 : [%s]", item2->bssid);
+               iter = g_list_next(iter);
+       }
+
+       return ret;
+}
+#if 0
+static gboolean _get_mpath_info(void *pdata)
+{
+       int ret = MESHD_ERROR_NONE;
+       GVariantBuilder builder;
+       GVariant* mpath_data;
+       GList *iter = NULL;
+
+       mesh_service *service = (mesh_service *)pdata;
+       mesh_interface_s *info = service->interface_info;
+
+       /* Clear mesh path list */
+       g_list_free_full(service->mpath_list, _on_mpath_list_destroy);
+       service->mpath_list = NULL;
+
+       ret = mesh_request_get_mpath_info(info->mesh_interface, &service->mpath_list);
+       if (MESHD_ERROR_NONE == ret) {
+       /*
+        * Example) sh-3.2# iw mesh0 mpath dump
+        * DEST ADDR         NEXT HOP          IFACE    SN      METRIC  QLEN    EXPTIME         DTIM    DRET    FLAGS
+        * 7c:dd:90:62:37:cf 7c:dd:90:62:37:cf mesh0    221     152             0               10                      100             0               0x5
+        */
+               /* Get mesh path information and make variant data */
+               g_variant_builder_init(&builder, G_VARIANT_TYPE("aa{sv}"));
+
+               iter = service->mpath_list;
+               while (iter != NULL) {
+                       mesh_mpath_info_s *item = (mesh_mpath_info_s*)iter->data;
+
+                       g_variant_builder_open(&builder, G_VARIANT_TYPE_VARDICT);
+                       g_variant_builder_add(&builder, "{sv}", "DEST_ADDR",
+                                               g_variant_new_string(item->dest_addr));
+                       g_variant_builder_add(&builder, "{sv}", "NEXT_HOP",
+                                               g_variant_new_string(item->next_hop));
+                       g_variant_builder_add(&builder, "{sv}", "IFACE",
+                                               g_variant_new_string(item->interface));
+                       g_variant_builder_add(&builder, "{sv}", "SN",
+                                               g_variant_new_uint32(item->sn));
+                       g_variant_builder_add(&builder, "{sv}", "METRIC",
+                                               g_variant_new_uint32(item->metric));
+                       g_variant_builder_add(&builder, "{sv}", "QLEN",
+                                               g_variant_new_uint32(item->qlen));
+                       g_variant_builder_add(&builder, "{sv}", "EXPTIME",
+                                               g_variant_new_uint32(item->exptime));
+                       g_variant_builder_add(&builder, "{sv}", "DTIM",
+                                               g_variant_new_uint32(item->discovery_timeout));
+                       g_variant_builder_add(&builder, "{sv}", "DRET",
+                                               g_variant_new_byte(item->discovery_retries));
+                       g_variant_builder_add(&builder, "{sv}", "FLAGS",
+                                               g_variant_new_byte(item->flags));
+                       g_variant_builder_close(&builder);
+
+                       iter = g_list_next(iter);
+               }
+
+               mpath_data = g_variant_builder_end(&builder);
+               g_object_unref(mpath_data);
+       }else
+               MESH_LOGE("Failed to mesh_request_get_mpath_info");
+
+       return ret;
+}
+#endif
+static gboolean _on_mesh_monitor_cb(gpointer pdata)
+{
+       mesh_service *service = (mesh_service *)pdata;
+
+       MESH_LOGD("Evaluting...");
+#if 0
+       _get_mpath_info(service);
+#endif
+       _get_station_info(service);
+
+       return G_SOURCE_CONTINUE;
+}
+
+int mesh_start_peer_monitor(void *pdata)
+{
+       int ret = MESHD_ERROR_NONE;
+       mesh_service *service = (mesh_service *)pdata;
+
+       if (g_timer)
+               mesh_stop_peer_monitor(pdata);
+
+       g_timer = g_timeout_add_seconds(MESH_MONITORING_TIME, _on_mesh_monitor_cb, service);
+
+       MESH_LOGD("Peer Monitoring Service Started");
+
+       return ret;
+}
+
+int mesh_stop_peer_monitor(void *pdata)
+{
+       int ret = MESHD_ERROR_NONE;
+       mesh_service *service = (mesh_service *)pdata;
+
+       NOTUSED(service);
+
+       if (g_timer) {
+               g_source_remove(g_timer);
+               g_timer = 0;
+       }
+
+       MESH_LOGD("Peer Monitoring Service Stopped");
+       return ret;
+}
index 4edcc8f..841de3f 100644 (file)
@@ -51,6 +51,7 @@
 #define MESH_PARAM_STR_LEN_MAX    23
 #define MESH_ELEMENT_ID           114
 #define MAX_MAC_ADDR_LEN          18
+#define ETH_ALEN 6
 
 #define BIT(x) (1ULL<<(x))
 
@@ -1622,7 +1623,7 @@ static int _on_receive_mpath_info(struct nl_msg *msg, void *arg)
        if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
        mpath_info->interface = g_strdup(dev);
        MESH_LOGD("Interface : %s", mpath_info->interface);
-       
+
        if (pinfo[NL80211_MPATH_INFO_SN]) {
                mpath_info->sn = nla_get_u32(pinfo[NL80211_MPATH_INFO_SN]);
                MESH_LOGD("SN : %u", mpath_info->sn);
@@ -2474,6 +2475,73 @@ nla_put_failure:
        return MESHD_ERROR_OPERATION_FAILED;
 }
 
+static int _send_nl_del_station_info(const char* if_name, char* peer)
+{
+       mesh_nl_state state = {
+               .nl80211_id = -1,
+               .callback_state = MESH_NL_CALLBACK_FINISHED,
+               .event_source = 0,
+               .nl_socket = NULL,
+               .msg = NULL,
+               .cb = NULL,
+               .s_cb = NULL,
+               .scanning_interface = (char*)if_name,
+               .station_list = NULL,
+       };
+       int err = MESHD_ERROR_NONE;
+       int device_index = 0;
+       int ret;
+
+       ret = __initialize_nl80211(&state);
+       if (MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to initialize nl80211");
+               return ret;
+       }
+
+       ret = __initialize_netlink_message(&state);
+       if (MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to initialize netlink message");
+               goto DESTROY;
+       }
+
+       /* Set command into message */
+       genlmsg_put(state.msg, 0, 0, state.nl80211_id, 0,
+                   NLM_F_DUMP, NL80211_CMD_DEL_STATION, 0);
+
+       /* Add attributes into message */
+       MESH_LOGD("Delete a station [%s] with interface [%s]", peer, if_name);
+       ret = __get_device_index_from_string(if_name, &device_index);
+       if (MESHD_ERROR_NONE != ret) {
+               MESH_LOGE("Failed to get mesh interface device index");
+               err = ret;
+               goto DESTROY;
+       }
+       NLA_PUT_U32(state.msg, NL80211_ATTR_IFINDEX, device_index);
+       NLA_PUT(state.msg, NL80211_ATTR_MAC, ETH_ALEN, peer);
+
+       /* Send message into kernel */
+       ret = nl_send_auto(state.nl_socket, state.msg);
+       if (ret < 0) {
+               MESH_LOGE("Failed to nl_send_auto() [%s](%d)",
+                               nl_geterror(ret), ret);
+               err = MESHD_ERROR_OPERATION_FAILED;
+               goto DESTROY;
+       }
+
+DESTROY:
+       __clean_netlink_message(&state);
+       __clean_nl80211(&state);
+
+       return err;
+
+nla_put_failure:
+       MESH_LOGE("Failed to message build");
+       __clean_netlink_message(&state);
+       __clean_nl80211(&state);
+
+       return MESHD_ERROR_OPERATION_FAILED;
+}
+
 static int _send_nl_get_mpath_info(const char* if_name, GList **mpath_list)
 {
        mesh_nl_state state = {
@@ -2823,6 +2891,26 @@ int mesh_netlink_get_station_info(const char* mesh_if_name, GList **station_list
        return ret;
 }
 
+int mesh_netlink_del_station_info(const char* mesh_if_name, char *peer)
+{
+       int ret = MESHD_ERROR_NONE;
+       //unsigned char peer_mac[ETH_ALEN] = {0,};
+
+       if (NULL == mesh_if_name || strlen(mesh_if_name) > IFNAMSIZ) {
+               MESH_LOGE("Invalid parameter [%p]", mesh_if_name);
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == peer) {
+               MESH_LOGE("Invalid parameter [%p]", peer);
+               return MESHD_ERROR_INVALID_PARAMETER;
+       }
+
+       MESH_LOGD("Del connected station : [%s]", peer);
+       ret = _send_nl_del_station_info(mesh_if_name, peer);
+
+       return ret;
+}
+
 int mesh_netlink_get_mpath_info(const char* mesh_if_name, GList **mpath_list)
 {
        int ret = MESHD_ERROR_NONE;
index 69126bb..5a7abbc 100644 (file)
@@ -22,6 +22,7 @@
 #include "mesh-log.h"
 #include "mesh-util.h"
 #include "mesh-service.h"
+#include "mesh-monitor.h"
 
 mesh_service *meshd_service_new()
 {
@@ -55,6 +56,8 @@ gboolean meshd_service_run(mesh_service *service)
 {
        meshd_check_null_ret_error("service", service, FALSE);
        meshd_check_null_ret_error("service->main_loop", service->main_loop, FALSE);
+       /* Start Mesh Node Monitoring Service */
+       mesh_start_peer_monitor(service);
 
        g_main_loop_run(service->main_loop);
 
@@ -65,6 +68,8 @@ gboolean meshd_service_exit(mesh_service *service)
 {
        meshd_check_null_ret_error("service", service, FALSE);
        meshd_check_null_ret_error("service->main_loop", service->main_loop, FALSE);
+       /* Stop Mesh Node Monitoring Service */
+       mesh_stop_peer_monitor(service);
 
        g_main_loop_quit(service->main_loop);