[Add] tether plugin 78/186278/5
authorMilind Murhekar <m.murhekar@samsung.com>
Wed, 8 Aug 2018 12:25:21 +0000 (17:55 +0530)
committerMilind Murhekar <m.murhekar@samsung.com>
Mon, 20 Aug 2018 11:58:34 +0000 (11:58 +0000)
This change adds a plugin called "tether"
to support data usage for tethering client stations.

Change-Id: I823c832f42613f0b607b96e0d863e532fe892e63
Signed-off-by: Milind Murhekar <m.murhekar@samsung.com>
include/stc-manager-plugin-tether.h [new file with mode: 0644]
packaging/stc-manager.spec
plugin/CMakeLists.txt
plugin/tether/CMakeLists.txt [new file with mode: 0644]
plugin/tether/include/stc-plugin-tether.h [new file with mode: 0644]
plugin/tether/stc-plugin-tether.c [new file with mode: 0644]
src/CMakeLists.txt
src/stc-manager-plugin-tether.c [new file with mode: 0644]
src/stc-manager.c

diff --git a/include/stc-manager-plugin-tether.h b/include/stc-manager-plugin-tether.h
new file mode 100644 (file)
index 0000000..bdee306
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 __STC_MANAGER_PLUGIN_TETHER_H__
+#define __STC_MANAGER_PLUGIN_TETHER_H__
+
+#define STC_PLUGIN_TETHER_FILEPATH             "/usr/lib/stc-plugin-tether.so"
+
+#include "stc-plugin-tether.h"
+
+int stc_plugin_tether_init(void);
+int stc_plugin_tether_deinit(void);
+stc_error_e stc_plugin_tether_load(void);
+stc_error_e stc_plugin_tether_status_changed(void);
+
+#endif /* __STC_MANAGER_PLUGIN_TETHER_H__ */
index b227159..6b0b965 100644 (file)
@@ -57,6 +57,12 @@ Summary: STC manager exception proc file system plugin
 %description plugin-procfs
 A smart traffic control manager extension for proc file system plugin
 
+%package plugin-tether
+Summary: Tethering plugin for data usage of tethering clients
+
+%description plugin-tether
+A smart traffic control manager extension for tethering client data usage plugin
+
 %prep
 %setup -q
 chmod 644 %{SOURCE0}
@@ -144,3 +150,7 @@ cp resources/dbus/stc-manager.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/st
 %files plugin-procfs
 %manifest %{name}.manifest
 %attr(500,root,root) %{_libdir}/stc-plugin-procfs.so
+
+%files plugin-tether
+%manifest %{name}.manifest
+%attr(500,root,root) %{_libdir}/stc-plugin-tether.so
index ce92a27..e591d7a 100644 (file)
@@ -18,3 +18,4 @@ INCLUDE_DIRECTORIES(${MONITOR_SOURCE_DIR}/include)
 ADD_SUBDIRECTORY(appstatus)
 ADD_SUBDIRECTORY(exception)
 ADD_SUBDIRECTORY(procfs)
+ADD_SUBDIRECTORY(tether)
diff --git a/plugin/tether/CMakeLists.txt b/plugin/tether/CMakeLists.txt
new file mode 100644 (file)
index 0000000..889f44a
--- /dev/null
@@ -0,0 +1,36 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(stc-plugin-tether C)
+
+# Set required packages
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(tether_plugin REQUIRED
+       dlog
+       gio-2.0
+       gio-unix-2.0
+       glib-2.0
+       )
+
+FOREACH(flag ${tether_plugin_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -g -Werror -fvisibility=hidden")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+ADD_DEFINITIONS("-DUSE_DLOG")
+
+SET(SRCS_PLUGIN
+       stc-plugin-tether.c
+       )
+
+# library build
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS_PLUGIN})
+ADD_DEPENDENCIES(${PROJECT_NAME} GENERATED_DBUS_CODE)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${tether_plugin_LDFLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME})
+
+# install
+INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${LIBDIR})
diff --git a/plugin/tether/include/stc-plugin-tether.h b/plugin/tether/include/stc-plugin-tether.h
new file mode 100644 (file)
index 0000000..b3d4439
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 __STC_PLUGIN_TETHER_H__
+#define __STC_PLUGIN_TETHER_H__
+
+#include <glib.h>
+#include "stc-error.h"
+#include "stc-manager.h"
+
+#define TETHERING_SERVICE_INTERFACE   "org.tizen.tethering"
+#define SIGNAL_NAME_DHCP_STATUS       "dhcp_status"
+#define STATION_STR_INFO_LEN          54
+#define STATION_STR_HOSTNAME_LEN      33
+
+typedef struct {
+       gchar *station_id;
+       gchar name[STATION_STR_HOSTNAME_LEN + 1];
+       gchar ip[STATION_STR_INFO_LEN + 1];
+       gchar mac[STATION_STR_INFO_LEN + 1];
+} tether_sta_info_s;
+
+typedef struct {
+       int (*init) (void);
+       void (*deinit) (void);
+       int (*status_changed) (void);
+} stc_plugin_tether_s;
+
+int tether_init(void);
+void tether_deinit(void);
+stc_error_e tether_plugin_status_changed(void);
+
+#endif /* __STC_PLUGIN_TETHER_H__ */
diff --git a/plugin/tether/stc-plugin-tether.c b/plugin/tether/stc-plugin-tether.c
new file mode 100644 (file)
index 0000000..ed3ccd4
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 <vconf/vconf.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <glib.h>
+
+#include "stc-monitor.h"
+#include "stc-plugin-tether.h"
+
+static GSList *station_list = NULL;
+static GDBusConnection *connection = NULL;
+static GCancellable *cancellable = NULL;
+static int g_mobileap_signal_sub_id = 0;
+
+static int _compare_sta_by_mac_func(gconstpointer a,
+               gconstpointer b)
+{
+       tether_sta_info_s *si = (tether_sta_info_s *)a;
+       return g_ascii_strcasecmp(si->mac, (const char *)b);
+}
+
+static int _get_station_info(gconstpointer data, GCompareFunc func,
+               tether_sta_info_s **si)
+{
+       GSList *list = station_list;
+       tether_sta_info_s *info = NULL;
+
+       if (func == NULL || si == NULL)
+               return -1;
+
+       if (!list)
+               return -1;
+
+       list = g_slist_find_custom(list, data, func);
+       if (list == NULL)
+               return -1;
+
+       info = list->data;
+       *si = info;
+       return 0;
+}
+
+static void _remove_station_info(gconstpointer data, GCompareFunc func)
+{
+       GSList *list = station_list;
+       tether_sta_info_s *info = NULL;
+       if (func == NULL)
+               return;
+
+       if (!list)
+               return;
+
+       list = g_slist_find_custom(list, data, func);
+       if (list == NULL)
+               return;
+
+       info = (tether_sta_info_s *)list->data;
+       STC_LOGI("STA-REMOVED: (%s) (%s) (%s)", info->ip, info->mac, info->name);
+       g_free(info->station_id);
+       g_free(info);
+
+       station_list = g_slist_delete_link(station_list, list);
+}
+
+static void _add_station_info(tether_sta_info_s *info)
+{
+       tether_sta_info_s *tmp = NULL;
+       if (info == NULL) {
+               STC_LOGE("info is NULL");
+               return;
+       }
+
+       if (_get_station_info(info->mac, _compare_sta_by_mac_func, &tmp) == 0) {
+               if (!g_strcmp0(tmp->name, info->name) && !g_strcmp0(tmp->ip, info->ip))
+                       return;
+
+               //Remove the station if dhcp info changed.
+               _remove_station_info(info->mac, _compare_sta_by_mac_func);
+       }
+
+       station_list = g_slist_prepend(station_list, info);
+       STC_LOGI("STA-ADDED: (%s) (%s) (%s)", info->ip, info->mac, info->name);
+       info->station_id = g_strdup_printf("%s_%s", info->mac, info->name);
+}
+
+static void _mobileap_signal_cb(GDBusConnection *conn,
+                              const gchar *name, const gchar *path,
+                              const gchar *interface, const gchar *sig,
+                              GVariant *param, gpointer user_data)
+{
+       int type;
+       int tm;
+       char *ip = NULL;
+       char *mac = NULL;
+       char *hostname = NULL;
+       char *state = NULL;
+       tether_sta_info_s *sta = NULL;
+
+       ret_msg_if(sig == NULL, "signal name NULL");
+       ret_msg_if(param == NULL, "param NULL");
+
+       STC_LOGI("%s interface(%s)", sig, interface);
+
+       sta = (tether_sta_info_s *)g_malloc0(sizeof(tether_sta_info_s));
+       if (sta == NULL) {
+               STC_LOGE("g_malloc0 failed");
+               return;
+       }
+
+       g_variant_get(param, "(susssu)", &state, &type, &ip, &mac, &hostname, &tm);
+       STC_LOGI("%s: ip(%s) mac(%s) name(%s) tm(%d)", state, ip, mac, hostname, tm);
+
+       if (!g_strcmp0(state, "DhcpConnected")) {
+               g_strlcpy(sta->ip, ip, STATION_STR_INFO_LEN);
+               g_strlcpy(sta->mac, mac, STATION_STR_INFO_LEN);
+               g_strlcpy(sta->name, hostname, STATION_STR_HOSTNAME_LEN);
+               _add_station_info(sta);
+       } else if (!g_strcmp0(state, "DhcpLeaseDeleted")) {
+               _remove_station_info(mac, _compare_sta_by_mac_func);
+       }
+
+       g_free(state);
+       g_free(ip);
+       g_free(mac);
+       g_free(hostname);
+}
+
+stc_error_e tether_plugin_status_changed(void)
+{
+       return STC_ERROR_NONE;
+}
+
+int tether_plugin_init(void)
+{
+       GError *error = NULL;
+
+       if (connection)
+               return 0;
+
+       connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+       if (!connection) {
+               g_error_free(error);
+               return -1;
+       }
+
+       cancellable = g_cancellable_new();
+
+       g_mobileap_signal_sub_id = g_dbus_connection_signal_subscribe(connection,
+                                                  NULL,
+                                                  TETHERING_SERVICE_INTERFACE,
+                                                  SIGNAL_NAME_DHCP_STATUS,
+                                                  NULL, NULL,
+                                                  G_DBUS_SIGNAL_FLAGS_NONE,
+                                                  _mobileap_signal_cb,
+                                                  NULL, NULL);
+
+       STC_LOGI("tether plugin initialised");
+       return 0;
+}
+
+void tether_plugin_deinit(void)
+{
+       if (!connection)
+               return;
+
+       g_object_unref(connection);
+       g_object_unref(cancellable);
+       connection = NULL;
+       cancellable = NULL;
+       STC_LOGI("tether plugin deinitialised");
+}
+
+/* Tether Plugin APIs */
+API stc_plugin_tether_s tether_plugin = {
+       .init = tether_plugin_init,
+       .deinit = tether_plugin_deinit,
+       .status_changed = tether_plugin_status_changed
+};
index 809897a..c845dd0 100644 (file)
@@ -31,6 +31,7 @@ SET(PLUGIN_DIR                  ${CMAKE_SOURCE_DIR}/plugin)
 SET(APPSTATUS_SOURCE_DIR        ${PLUGIN_DIR}/appstatus)
 SET(EXCEPTION_SOURCE_DIR        ${PLUGIN_DIR}/exception)
 SET(PROCFS_SOURCE_DIR           ${PLUGIN_DIR}/procfs)
+SET(TETHER_SOURCE_DIR           ${PLUGIN_DIR}/tether)
 
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/interfaces)
@@ -53,6 +54,7 @@ INCLUDE_DIRECTORIES(${LIMITATION_SOURCE_DIR}/include)
 INCLUDE_DIRECTORIES(${APPSTATUS_SOURCE_DIR}/include)
 INCLUDE_DIRECTORIES(${EXCEPTION_SOURCE_DIR}/include)
 INCLUDE_DIRECTORIES(${PROCFS_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${TETHER_SOURCE_DIR}/include)
 
 FILE(GLOB SOURCE_SRCS        ${SOURCE_DIR}/*.c)
 FILE(GLOB HELPER_SRCS        ${HELPER_SOURCE_DIR}/*.c)
diff --git a/src/stc-manager-plugin-tether.c b/src/stc-manager-plugin-tether.c
new file mode 100644 (file)
index 0000000..1813e40
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * 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 <dlfcn.h>
+
+#include "stc-manager.h"
+#include "stc-manager-plugin-tether.h"
+
+static gboolean stc_tether_plugin_enabled = FALSE;
+static void *tether_plugin_handle;
+static stc_plugin_tether_s *plugin;
+
+int stc_plugin_tether_init(void)
+{
+       __STC_LOG_FUNC_ENTER__;
+
+       tether_plugin_handle = dlopen(STC_PLUGIN_TETHER_FILEPATH, RTLD_NOW);
+       if (!tether_plugin_handle) {
+               STC_LOGE("Can't load %s: %s", STC_PLUGIN_TETHER_FILEPATH, dlerror());
+               __STC_LOG_FUNC_EXIT__;
+               return STC_ERROR_UNINITIALIZED;
+       }
+
+       plugin = dlsym(tether_plugin_handle, "tether_plugin");
+       if (!plugin) {
+               STC_LOGE("Can't load symbol: %s", dlerror());
+               dlclose(tether_plugin_handle);
+               __STC_LOG_FUNC_EXIT__;
+               return STC_ERROR_UNINITIALIZED;
+       }
+
+       plugin->init();
+       stc_tether_plugin_enabled = TRUE;
+
+       __STC_LOG_FUNC_EXIT__;
+       return STC_ERROR_NONE;
+}
+
+int stc_plugin_tether_deinit(void)
+{
+       __STC_LOG_FUNC_ENTER__;
+
+       if (!stc_tether_plugin_enabled) {
+               __STC_LOG_FUNC_EXIT__;
+               return STC_ERROR_UNINITIALIZED;
+       }
+
+       plugin->deinit();
+       stc_tether_plugin_enabled = FALSE;
+       dlclose(tether_plugin_handle);
+
+       __STC_LOG_FUNC_EXIT__;
+       return STC_ERROR_NONE;
+}
index 436ee29..58f6531 100644 (file)
@@ -31,6 +31,7 @@
 #include "stc-manager-plugin-appstatus.h"
 #include "stc-manager-plugin-exception.h"
 #include "stc-manager-plugin-procfs.h"
+#include "stc-manager-plugin-tether.h"
 
 #define BUF_SIZE_FOR_ERR 100
 
@@ -89,6 +90,7 @@ static void __stc_manager_deinit(void)
        stc_plugin_appstatus_deinit();
        stc_plugin_exception_deinit();
        stc_plugin_procfs_deinit();
+       stc_plugin_tether_deinit();
 
        inotify_deregister(INFO_STORAGE_DIR);
        inotify_deinitialize();
@@ -123,6 +125,7 @@ static stc_s *__stc_manager_init(void)
        stc_plugin_appstatus_init();
        stc_plugin_exception_init();
        stc_plugin_procfs_init();
+       stc_plugin_tether_init();
 
        stc_firewall_init();