From 223bce4b91646dd607f7a281b29237cca45362c4 Mon Sep 17 00:00:00 2001 From: "taesub.kim" Date: Wed, 27 May 2015 09:33:06 +0900 Subject: [PATCH] Add API(ethernet cable state) Change-Id: Idca74e003d61c7163b0cf1dfd11b764555e404ae Signed-off-by: Taesub Kim --- CMakeLists.txt | 1 + include/netdbus.h | 2 + include/network-monitor.h | 47 +++++++ include/network-state.h | 1 + include/util.h | 2 + interfaces/netconfig-iface-network-state.xml | 3 + packaging/net-config.spec | 2 +- src/main.c | 32 +++++ src/network-monitor.c | 122 +++++++++++++++++++ src/network-state.c | 73 +++++++++++ 10 files changed, 284 insertions(+), 1 deletion(-) create mode 100755 include/network-monitor.h create mode 100755 src/network-monitor.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bdc82c..81c9901 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,7 @@ SET(SRCS src/wifi-passpoint.c src/network-clock.c src/network-state.c + src/network-monitor.c src/network-statistics.c src/wifi-indicator.c src/signal-handler.c diff --git a/include/netdbus.h b/include/netdbus.h index 8f58900..db577e1 100644 --- a/include/netdbus.h +++ b/include/netdbus.h @@ -47,6 +47,8 @@ extern "C" { #define NETCONFIG_WIFI_INTERFACE "net.netconfig.wifi" #define NETCONFIG_WIFI_PATH "/net/netconfig/wifi" +#define NETCONFIG_NETWORK_PATH "/net/netconfig/network" +#define NETCONFIG_NETWORK_INTERFACE "net.netconfig.network" #define DBUS_PATH_MAX_BUFLEN 512 #define DBUS_STATE_MAX_BUFLEN 64 diff --git a/include/network-monitor.h b/include/network-monitor.h new file mode 100755 index 0000000..16ed406 --- /dev/null +++ b/include/network-monitor.h @@ -0,0 +1,47 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2014 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 __NETCONFIG_NETWORK_MONITOR_H__ +#define __NETCONFIG_NETWORK_MONITOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ETH_REG_BMSR 0x01 +#define BMSR_LINK_VALID 0x0004 + +#define SIOCGMIIPHY 0x8947 /* Get address of MII PHY in use. */ +#define SIOCGMIIREG 0x8948 /* Read MII PHY register. */ + +struct _stMData { + unsigned short phy_id; + unsigned short reg_num; + unsigned short val_in; + unsigned short val_out; +}; + +int netconfig_ethernet_cable_plugin_status_check(); +int netconfig_get_ethernet_cable_state(int *status); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_NETWORK_MONITOR_H__ */ diff --git a/include/network-state.h b/include/network-state.h index 0f180c8..8833695 100644 --- a/include/network-state.h +++ b/include/network-state.h @@ -43,6 +43,7 @@ typedef struct NetconfigNetworkStateClass NetconfigNetworkStateClass; GType netconfig_network_state_get_type(void); gpointer netconfig_network_state_create_and_init(DBusGConnection *conn); +void netconfig_network_notify_ethernet_cable_state(const char *key); const char *netconfig_get_default_profile(void); const char *netconfig_get_default_ipaddress(void); diff --git a/include/util.h b/include/util.h index 8a37f8a..c6c9b8d 100644 --- a/include/util.h +++ b/include/util.h @@ -28,6 +28,8 @@ extern "C" { #include "wifi.h" +#define MAX_SIZE_ERROR_BUFFER 256 + GKeyFile *netconfig_keyfile_load(const char *pathname); void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname); diff --git a/interfaces/netconfig-iface-network-state.xml b/interfaces/netconfig-iface-network-state.xml index d2dae90..c5ba188 100644 --- a/interfaces/netconfig-iface-network-state.xml +++ b/interfaces/netconfig-iface-network-state.xml @@ -13,5 +13,8 @@ + + + diff --git a/packaging/net-config.spec b/packaging/net-config.spec index a3a97b9..2137b88 100644 --- a/packaging/net-config.spec +++ b/packaging/net-config.spec @@ -1,6 +1,6 @@ Name: net-config Summary: TIZEN Network Configuration Module -Version: 0.1.90_30 +Version: 0.1.90_31 Release: 1 Group: System/Network License: Apache-2.0 diff --git a/src/main.c b/src/main.c index ccdc669..e9e019c 100644 --- a/src/main.c +++ b/src/main.c @@ -17,11 +17,13 @@ * */ +#include #include #include #include #include #include +//#include #include "log.h" #include "wifi.h" @@ -33,11 +35,23 @@ #include "network-statistics.h" #include "signal-handler.h" #include "wifi-agent.h" +#include "network-monitor.h" static GMainLoop *main_loop = NULL; +//#define ETHERNET_FEATURE "http://tizen.org/feature/network.ethernet" static int no_fork = FALSE; +/*Poll the ethernet Cable Plug-in /Plug-out status at every 1000 ms*/ +#define ETH_POLLING_TIME 1000 + +/* Callback to Poll the Ethernet Status*/ +gboolean __net_ethernet_cable_status_polling_callback(gpointer data) +{ + netconfig_ethernet_cable_plugin_status_check(); + return TRUE; +} + void netconfig_signal_handler_SIGTERM(int signum) { g_main_loop_quit(main_loop); @@ -81,6 +95,8 @@ int netconfig_test_input_parameters(int argc, char* argv[]) int main(int argc, char* argv[]) { DBusGConnection *connection; + int check_ethernet_monitor_timer = 0; + //bool ethernet_feature_supported = FALSE; DBG("Network Configuration Module"); @@ -124,6 +140,18 @@ int main(int argc, char* argv[]) /* If its environment uses Emulator, network configuration is set by emulator default */ netconfig_emulator_test_and_start(); +/* + if (!system_info_get_platform_bool(ETHERNET_FEATURE, ðernet_feature_supported)) { + if (ethernet_feature_supported == TRUE) { + //Register the callback to check the ethernet Plug-in /Plug-out Status + check_ethernet_monitor_timer = g_timeout_add(ETH_POLLING_TIME, + __net_ethernet_cable_status_polling_callback, + &check_ethernet_monitor_timer); + } + } else { + ERR("Error - Feature getting from System Info"); + } +*/ // Notyfication to systemd sd_notify(0, "READY=1"); @@ -133,6 +161,10 @@ int main(int argc, char* argv[]) netconfig_deregister_signal(); netconfig_wifi_state_notifier_cleanup(); + /*remove the Timer*/ + if(check_ethernet_monitor_timer >0) + g_source_remove(check_ethernet_monitor_timer); + /* Unregistering the agent */ netconfig_agent_unregister(); diff --git a/src/network-monitor.c b/src/network-monitor.c new file mode 100755 index 0000000..29f8772 --- /dev/null +++ b/src/network-monitor.c @@ -0,0 +1,122 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2014 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 "log.h" +#include "util.h" +#include "netdbus.h" +#include "network-monitor.h" +#include "network-state.h" +#include "wifi-power.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Check send notification status */ +static gboolean g_chk_eth_send_notification = FALSE; + +int netconfig_ethernet_cable_plugin_status_check() +{ + struct ifreq ifr; + int soketfd = -1; + int error = 0; + int ret = 0; + struct _stMData *mdata; + struct timeval tv; + char error_buf[MAX_SIZE_ERROR_BUFFER] = {}; + + soketfd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (soketfd < 0) { + ERR("Failed to create socket"); + return -errno; + } + + /* Set Timeout for IOCTL Call */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + if (setsockopt(soketfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, + sizeof(struct timeval)) < 0) { + + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + ERR("Failed to set socket option : [%d] [%s]", -errno, error_buf); + goto done; + } + + memset(&ifr, 0, sizeof(ifr)); + g_strlcpy(ifr.ifr_name, "eth0", IFNAMSIZ); + if (ioctl(soketfd, SIOCGMIIPHY, &ifr) < 0){ + error = -errno; + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + ERR("SIOCGMIIPHY on eth0 failed : [%d] [%s]", errno, error_buf); + goto done; + } + + mdata = (struct _stMData *)&ifr.ifr_data; + mdata->reg_num = ETH_REG_BMSR; + + if (ioctl(soketfd, SIOCGMIIREG, &ifr) < 0){ + error = -errno; + strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER); + ERR("SIOCGMIIREG on %s failed , [%d] [%s] ", ifr.ifr_name,errno,error_buf); + goto done; + } + ret = mdata->val_out; + ret = ret & BMSR_LINK_VALID; + + if(ret == 4) { + if(!g_chk_eth_send_notification) + netconfig_network_notify_ethernet_cable_state("ATTACHED"); + g_chk_eth_send_notification = TRUE; + } else if (ret == 0) { + if(g_chk_eth_send_notification) + netconfig_network_notify_ethernet_cable_state("DETACHED"); + g_chk_eth_send_notification = FALSE; + } + error = 0; +done: + close(soketfd); + return error; +} + +int netconfig_get_ethernet_cable_state(int *status) +{ + int error = 0; + if(status == NULL) { + DBG("Error !!! Invalid Parameter\n"); + return -1; + } + + if((error = netconfig_ethernet_cable_plugin_status_check()) != 0) { + DBG("Error !!! Failed to check ethernet cable status [%d]\n", error); + return -1; + } + + if(g_chk_eth_send_notification == TRUE) + *status = 1; /* Ethernet cable Attached */ + else + *status = 0; /* Ethernet cable Deattached */ + return 0; +} diff --git a/src/network-state.c b/src/network-state.c index d890e1d..f753213 100644 --- a/src/network-state.c +++ b/src/network-state.c @@ -27,6 +27,7 @@ #include "neterror.h" #include "emulator.h" #include "wifi-state.h" +#include "network-monitor.h" #include "network-state.h" #define NETCONFIG_NETWORK_STATE_PATH "/net/netconfig/network" @@ -46,6 +47,9 @@ gboolean netconfig_iface_network_state_remove_route( gchar *ip_addr, gchar *netmask, gchar *interface, gboolean *result, GError **error); +gboolean netconfig_iface_network_state_ethernet_cable_state( + NetconfigNetworkState *master, gint32 *state, GError **error); + #include "netconfig-iface-network-state-glue.h" enum { @@ -488,6 +492,54 @@ static void __netconfig_update_default_connection_info(void) } } +static void __netconfig_network_notify_result(const char *sig_name, const char *key) +{ + DBusMessage *signals; + DBusConnection *connection = NULL; + DBusMessageIter iter, dict_iter, type, value; + DBusError error; + const char *prop_key = "key"; + + dbus_error_init(&error); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + ERR("Error!!! Failed to get system DBus, error [%s]", error.message); + dbus_error_free(&error); + + return; + } + + signals = dbus_message_new_signal(NETCONFIG_NETWORK_PATH, + NETCONFIG_NETWORK_INTERFACE, sig_name); + if (signals == NULL) { + dbus_connection_unref(connection); + return; + } + + dbus_message_iter_init_append(signals, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", + &dict_iter); + + /* Packing the key */ + dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_DICT_ENTRY, 0, &type); + dbus_message_iter_append_basic(&type, DBUS_TYPE_STRING, &prop_key); + dbus_message_iter_open_container(&type, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &value); + + dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &key); + dbus_message_iter_close_container(&type, &value); + dbus_message_iter_close_container(&dict_iter, &type); + + dbus_message_iter_close_container(&iter, &dict_iter); + + dbus_connection_send(connection, signals, NULL); + + dbus_message_unref(signals); + dbus_connection_unref(connection); + ERR("Sent signal (%s), key (%s)", sig_name, key); + return; +} + const char *netconfig_get_default_profile(void) { return netconfig_default_connection_info.profile; @@ -566,6 +618,12 @@ void netconfig_set_default_profile(const char *profile) __netconfig_update_default_connection_info(); } +/* Check Ethernet Cable Plug-in /Plug-out Status */ +void netconfig_network_notify_ethernet_cable_state(const char *key) +{ + __netconfig_network_notify_result("EthernetCableState", key); +} + gboolean netconfig_iface_network_state_add_route( NetconfigNetworkState *master, gchar *ip_addr, gchar *netmask, @@ -638,6 +696,21 @@ done: return ret; } +gboolean netconfig_iface_network_state_ethernet_cable_state( + NetconfigNetworkState *master, gint32 *state, GError **error) +{ + int ret = 0; + + ret = netconfig_get_ethernet_cable_state(state); + if(ret != 0) { + DBG("Failed to get ethernet cable state"); + return FALSE; + } + + DBG("Successfully get ethernet cable state[%d]", state); + return TRUE; +} + gpointer netconfig_network_state_create_and_init(DBusGConnection *conn) { GObject *object; -- 2.34.1