gio-unix-2.0
glib-2.0
ua-plugins
+ capi-network-connection
+ capi-network-wifi
)
FOREACH(flag ${PKGS_WIFI_CFLAGS})
MESSAGE (${CMAKE_C_FLAGS})
SET(SRCS_WIFI
src/wifi-plugin.c
+ src/wifi-networkmanager.c
+ src/wifi-scan.c
+ src/wifi-util.c
)
# library build
/*
- * User Awareness Manager API
- *
- * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2019 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.
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __WIFI_NETWORKMANAGER_PLUGIN_H__
+#define __WIFI_NETWORKMANAGER_PLUGIN_H__
+
+#include <log.h>
+#include <wifi-scan.h>
+#include <net_connection.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool __nm_init();
+
+bool __nm_get_interface_name(char** iface_name);
+
+connection_type_e __nm_get_connection_type();
+
+void __nm_get_connection_profile_handler(connection_profile_h *profile);
+
+void __nm_destroy_profile_iterator();
+
+bool __nm_get_gateway_address(char* gateway);
+
+void __nm_get_linux_arp_table(char* ip_addr, char* mac_addr);
+
+void __nm_get_ips_mac(char* ip_addr, char* mac_addr);
+
+void __nm_update_network_type(bool isConnect);
+
+bool __nm_get_mac_address(char** dest_mac_addr);
+
+char* __nm_get_ip_address(void);
+
+void __nm_get_connected_bssid(char** connect_bssid);
+
+bool __nm_is_network_connected();
+
+void __nm_deinit();
+#ifdef __cplusplus
+}
+#endif
+#endif /* __WIFI_NETWORKMANAGER_PLUGIN_H__*/
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __WIFI_PLUGIN_UTIL_H__
+#define __WIFI_PLUGIN_UTIL_H__
+
+#include <wifi-plugin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ret_if(expr) \
+ do { \
+ if (expr) { \
+ UA_WIFI_ERR("(%s) return", #expr); \
+ return; \
+ } \
+ } while (0)
+
+#define retv_if(expr, val) \
+ do { \
+ if (expr) { \
+ UA_WIFI_ERR("(%s) return", #expr); \
+ return (val); \
+ } \
+ } while (0)
+
+uas_wifi_info_t *_wifi_plugin_util_get_wifi_info_from_dev_info(uas_device_info_t *dev_info);
+
+uas_device_info_t *_wifi_plugin_util_get_dev_info_from_wifi_info(uas_wifi_info_t *wifi_info);
+
+void _wifi_plugin_util_uas_device_info_free(uas_device_info_t *device);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __WIFI_PLUGIN_UTIL_H__*/
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __WIFI_PLUGIN_H__
+#define __WIFI_PLUGIN_H__
+
+#include <log.h>
+#include <stdbool.h>
+#include <ua-plugin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UAS_DEVICE_ID_MAX_LEN 50 /** Max device ID length */
+#define MAC_ADDRESS_STRING_SIZE 18 /**< Max MAC address string length */
+#define IP_ADDRESS_STRING_SIZE 16 /* Max IPv4 address string length */
+
+typedef enum {
+ WIFI_PRESENCE_STATUS_ABSENCE, /**< ABSENCE detected */
+ WIFI_PRESENCE_STATUS_PRESENCE, /**< PRESENCE detected */
+} wifi_presence_status_e;
+
+typedef struct {
+ int user_id; /**< User ID which is saved in DB */
+ int os; /**< Operating system type eg) Tizen, Android and iOS */
+ char mobile_id[UAS_DEVICE_ID_MAX_LEN]; /**< MObile ID which is saved in DB */
+ char mac_addr[MAC_ADDRESS_STRING_SIZE]; /**< MAC address which is saved in DB */
+ char ip_addr[IP_ADDRESS_STRING_SIZE]; /**< IP address which is saved in DB */
+ int absence_count; /**< How many detect ABSENCE of the target dev. */
+ int mobile_flag; /**< The order of the target dev. */
+ gboolean new_device; /**< Is newly added device ?*/
+ unsigned int supported_techs; /**< Operating system type of the target dev. */
+ wifi_presence_status_e presence; /**< Detected type (see. wifi_presence_status_e) */
+} uas_wifi_info_t;
+
+void __check_device_found(char* sbuf, char* ip_sbuf);
+
+void __check_mobilelist();
+
+void __check_mobile_list_finish(bool is_check);
+#ifdef __cplusplus
+}
+#endif
+#endif /* __WIFI_PLUGIN_H__*/
--- /dev/null
+/*
+ * Copyright (c) 2019 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 __WIFI_SCAN_PLUGIN_H__
+#define __WIFI_SCAN_PLUGIN_H__
+
+#include <log.h>
+#include <ua-plugin.h>
+#include <net_connection.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <netinet/ether.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <net/ethernet.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/if_packet.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define MAC_ADD_LENGTH 6 /**< MAC address bytes size */
+#define IP_ADD_LENGTH 4 /**< IPv4 size */
+#define MAX_SIZE_ERROR_BUFFER 256 /**< Error buffer size */
+#define MAX_SIZE_BUFFER 128 /**< Max. buffer size */
+#define SEND_MAC_TIMER 10 /**< Timer value until sending ARP request */
+#define ARP_MAC_TIMER 5 /**< Timer value until receiving ARP response */
+#define BROADCAST_MAC_ADDR "ff:ff:ff:ff:ff:ff" /**< Broadcast adress */
+#define MAX_MAC_ARP_COUNT 1 /**< Max. count of ARP request */
+#define ARP_PACKET_SIZE 60 /**< MAX ARP payload size */
+
+union uchar_to_uint {
+ unsigned int uint; /**< IP addess for interger */
+ unsigned char uchar[IP_ADD_LENGTH]; /**< IP address for human */
+};
+
+struct arp_message {
+ /* Ethernet header */
+ unsigned char h_dest[MAC_ADD_LENGTH]; /**< destination ether addr */
+ unsigned char h_source[MAC_ADD_LENGTH]; /**< source ether addr */
+ uint16_t h_proto; /**< packet type ID field */
+
+ /* ARP packet */
+ uint16_t hw_type;/**< hardware type(ARPHRD_ETHER) */
+ uint16_t p_type;/**< protocol type(ETH_P_IP) */
+ uint8_t p_len; /**< protocol address length */
+ uint8_t hw_len;/**< hardware address length */
+ uint16_t operation;/* ARP opcode */
+ uint8_t s_hwaddr[MAC_ADD_LENGTH]; /**< sender hardware address */
+ uint8_t s_IPaddr[IP_ADD_LENGTH]; /**< sender IP address */
+ uint8_t t_hwaddr[MAC_ADD_LENGTH]; /**< target hardware address */
+ uint8_t t_IPaddr[IP_ADD_LENGTH]; /**< target IP address */
+ uint8_t pad[18]; /**< pad for min. Ethernet payload (60 bytes) */
+};
+
+struct arping_data {
+ struct arp_message arp; /**< ARP structure */
+ struct sockaddr_ll addr; /**< Socket address structure */
+ GIOChannel *arp_sock_io; /**< GIO channel */
+ int arp_id; /**< Raw socket descriptor ID */
+ int arp_data_id; /**< GIO ID to recieve ARP response */
+ int is_arp_init; /**< Create ARP packet done */
+ char arp_source_ip[MAX_SIZE_BUFFER]; /**< Source IP address */
+ char arp_source_mac[MAX_SIZE_BUFFER]; /**< Source MAC address */
+ char arp_target_mac[MAX_SIZE_BUFFER]; /**< Target MAC address */
+ guint arp_send_packet_timer; /**< Timer ID until sending ARP request */
+ unsigned int arp_send_ip_addr; /**< Sender's IP address (int type) */
+ unsigned int arp_mac_count; /**< How many received ARP response from the target dev. */
+ gboolean mobile_detection; /**< Whether receiving ARP resp. from the target device */
+};
+
+int __initialize_arp_data(void);
+
+int __start_wifi_detection(const char* ip, const char* mac);
+
+int __start_arp(const char* ip, const char* mac);
+
+int __init_ip_mac_count(void);
+
+int __start_wifi_add_device(const char* ip, const char* mac);
+
+bool __is_device_exists(char *device_id);
+
+void __deinit_arp_data(void);
+#ifdef __cplusplus
+}
+#endif
+#endif /* __WIFI_SCAN_PLUGIN_H__*/
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(gio-unix-2.0)
+BuildRequires: pkgconfig(libtzplatform-config)
BuildRequires: pkgconfig(ua-plugins)
+BuildRequires: pkgconfig(capi-network-connection)
+BuildRequires: pkgconfig(capi-network-wifi)
%if 0%{?gtests:1}
BuildRequires: pkgconfig(gmock)
export LDFLAGS+=" -lgcov"
%endif
-%define NETWORK_FW_DATADIR /opt/usr/data/network
-%define DBDIR /opt/usr/data
+%define NETWORK_FW_DATADIR %{TZ_SYS_GLOBALUSER_DATA}/network
+%define DBDIR %{TZ_SYS_GLOBALUSER_DATA}/
cmake . -DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_LIB_DIR=%{_libdir} \
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include <wifi-networkmanager.h>
+
+typedef enum {
+ NM_NETWORK_TYPE_UNKNOWN, /**< Netwrok type unknown */
+ NM_NETWORK_TYPE_DISCONNECTED, /**< Netwrok type disconnected */
+ NM_NETWORK_TYPE_ETHERNET, /**< Netwrok type ethernet */
+ NM_NETWORK_TYPE_WIFI /**< Netwrok type Wi-Fi */
+} nm_network_type;
+
+typedef struct {
+ char ip_addr[MAX_SIZE_BUFFER]; /**< IP address of the network interface */
+ char hw_type[MAX_SIZE_BUFFER]; /**< HW type for the network interface */
+ char flags[MAX_SIZE_BUFFER]; /**< Network interface flag */
+ char hw_addr[MAX_SIZE_BUFFER]; /**< MAC address of the network interface */
+ char mask[MAX_SIZE_BUFFER]; /**< Submnet mask of the network interface */
+ char device[MAX_SIZE_BUFFER]; /**< Name of the network interface */
+} nm_linux_arp_entry;
+
+#define NETCONN_LOCAL_MAC "00:00:00:00:00:00" /**< So called, link local MAC address */
+#define PROC_ARP_PATH "/proc/net/arp" /**< ARP table in linux */
+
+connection_h h_conn = NULL;
+connection_profile_iterator_h profile_iter = NULL;
+
+nm_network_type network_type = NM_NETWORK_TYPE_UNKNOWN;
+static char connected_bssid[MAX_SIZE_BUFFER];
+
+bool __nm_init()
+{
+ FUNC_ENTER;
+ int ret;
+
+ if (h_conn != NULL) {
+ UA_WIFI_ERR("h_conn was already created!!!");
+ FUNC_EXIT;
+ return false;
+ }
+
+ ret = connection_create(&h_conn);
+
+ if (ret != CONNECTION_ERROR_NONE) {
+ UA_WIFI_ERR("connection_create is fail");
+ h_conn = NULL;
+ FUNC_EXIT;
+ return false;
+ }
+
+ __nm_update_network_type(true);
+
+ FUNC_EXIT;
+ return true;
+}
+
+void __nm_deinit()
+{
+ FUNC_ENTER;
+ if (h_conn == NULL) {
+ UA_WIFI_INFO("h_conn is NULL");
+ return;
+ }
+
+ if (connection_destroy(h_conn) != CONNECTION_ERROR_NONE) {
+ UA_WIFI_INFO("Failed to destroy connection");
+ return;
+ }
+
+ UA_WIFI_INFO("Connection destroyed successfully");
+ h_conn = NULL;
+ FUNC_EXIT;
+ return;
+
+}
+
+bool __nm_get_interface_name(char** iface_name)
+{
+ FUNC_ENTER;
+ bool ret = true;
+
+ if (network_type == NM_NETWORK_TYPE_WIFI) {
+ UA_WIFI_INFO("currently network status WIFI");
+ *iface_name = strdup("wlan0");
+ } else if (network_type == NM_NETWORK_TYPE_ETHERNET) {
+ UA_WIFI_INFO("currently network status Wired");
+ *iface_name = strdup("eth0");
+ } else {
+ UA_WIFI_INFO("No Network or Network status not available");
+ FUNC_EXIT;
+ return false;
+ }
+
+ FUNC_EXIT;
+ return ret;
+}
+
+connection_type_e __nm_get_connection_type()
+{
+ FUNC_ENTER;
+ connection_type_e connection_type = CONNECTION_TYPE_DISCONNECTED;
+
+ if (connection_get_type(h_conn, &connection_type) != CONNECTION_ERROR_NONE)
+ UA_WIFI_ERR("connection_get_type error");
+
+ UA_WIFI_INFO("connection get type %d", connection_type);
+ FUNC_EXIT;
+ return connection_type;
+}
+
+void __nm_get_connection_profile_handler(connection_profile_h *profile)
+{
+ FUNC_ENTER;
+
+ /* TODO: Need to check if hconnection can be use instead of connection
+ * So, There should not be need of connection_create if m_hconnection is not NULL.
+ */
+ connection_h connection = NULL;
+ connection_profile_h profile_handlelocal;
+ connection_profile_type_e profile_type;
+
+ int ret = -1;
+
+ ret = connection_create(&connection);
+
+ UA_WIFI_INFO("ret: %d, m_Connection: %p", ret, connection);
+
+ if (!connection) {
+ UA_WIFI_INFO("connection is NULL");
+ return;
+ }
+
+ ret = connection_get_profile_iterator(connection, CONNECTION_ITERATOR_TYPE_REGISTERED,
+ &profile_iter);
+ if (CONNECTION_ERROR_NONE != ret)
+ UA_WIFI_INFO("Failed to get connection profile iterator");
+
+
+ while (connection_profile_iterator_has_next(profile_iter)) {
+
+ ret = connection_profile_iterator_next(profile_iter, &profile_handlelocal);
+ if (CONNECTION_ERROR_NONE != ret) {
+ UA_WIFI_INFO("failed to get connection profile iterator");
+ break;
+ }
+
+ if (connection_profile_get_type(profile_handlelocal, &profile_type)) {
+ UA_WIFI_INFO("failed to get profile get type");
+ break;
+ }
+
+ UA_WIFI_INFO("Profile Type: [%d]", profile_type);
+
+ if ((profile_type == CONNECTION_PROFILE_TYPE_ETHERNET) ||
+ (profile_type == CONNECTION_PROFILE_TYPE_WIFI)) {
+ *profile = profile_handlelocal;
+ UA_WIFI_INFO("Successfully obtained connection profile handle");
+ break;
+ }
+ }
+ FUNC_EXIT;
+}
+
+void __nm_destroy_profile_iterator()
+{
+ FUNC_ENTER;
+
+ if (profile_iter) {
+ if (connection_destroy_profile_iterator(profile_iter) == CONNECTION_ERROR_NONE) {
+ profile_iter = NULL;
+ UA_WIFI_DBG("Destroyed profile iterator");
+ } else
+ UA_WIFI_DBG("Failed to Destroy profile iterator");
+ }
+
+ FUNC_EXIT;
+}
+
+bool __nm_get_gateway_address(char* gateway)
+{
+ FUNC_ENTER;
+ int ret = -1;
+ char* gateway_local = NULL;
+ connection_profile_h profile;
+
+ __nm_get_connection_profile_handler(&profile);
+
+ if (profile) {
+ ret = connection_profile_get_gateway_address(profile,
+ CONNECTION_ADDRESS_FAMILY_IPV4, &gateway_local);
+
+ if (ret == CONNECTION_ERROR_NONE) {
+ g_strlcpy(gateway, gateway_local, 16);
+ free(gateway_local);
+ } else {
+ UA_WIFI_ERR("get gateway failed");
+ strncpy(gateway, "0.0.0.0", 7);
+ }
+ } else {
+ UA_WIFI_ERR("Failed to get profile handle !!!");
+ strncpy(gateway, "0.0.0.0", 7);
+ }
+
+ UA_WIFI_INFO("gateway is [%s]", gateway);
+ __nm_destroy_profile_iterator();
+ return true;
+}
+
+void __nm_get_linux_arp_table(char* ip_addr, char* mac_addr)
+{
+ FUNC_ENTER;
+
+ FILE *fp = NULL;
+ char data[1024];
+ int matches;
+
+ fp = fopen(PROC_ARP_PATH, "r");
+
+ if (!fp) {
+ UA_WIFI_ERR("fail to read %s", PROC_ARP_PATH);
+ FUNC_EXIT;
+ return;
+ }
+
+ if (!fgets(data, sizeof(data), fp)) {
+ UA_WIFI_ERR("failed to read arp table");
+ fclose(fp);
+ FUNC_EXIT;
+ return;
+ }
+
+ while (fgets(data, sizeof(data) - 1, fp)) {
+ nm_linux_arp_entry entry;
+ matches = sscanf(data, "%128s%128s%128s%128s%128s%128s",
+ entry.ip_addr, entry.hw_type, entry.flags, entry.hw_addr,
+ entry.mask, entry.device);
+
+ if ((matches == 6) && !strcmp(ip_addr, entry.ip_addr)) {
+ UA_WIFI_INFO("IP[%s] found in ARP table", ip_addr);
+ memcpy(mac_addr, entry.hw_addr, strlen(entry.hw_addr)+1);
+ fclose(fp);
+ FUNC_EXIT;
+ return;
+ }
+ }
+
+ UA_WIFI_ERR("IP[%s] not found in ARP table", ip_addr);
+ fclose(fp);
+ FUNC_EXIT;
+ return;
+}
+
+void __nm_get_ips_mac(char *ip_addr, char *mac_addr)
+{
+ FUNC_ENTER;
+
+ UA_WIFI_INFO("IP address of GetIPsMAC: %s", ip_addr);
+ memcpy(mac_addr, NETCONN_LOCAL_MAC, strlen(NETCONN_LOCAL_MAC)+1);
+
+ /*! local IP has a wildcard MAC address, for now at least */
+ if (!strcmp(ip_addr, "127.0.0.1"))
+ UA_WIFI_INFO("local IP[%s]", ip_addr);
+ else
+ __nm_get_linux_arp_table(ip_addr, mac_addr);
+
+ FUNC_EXIT;
+ return;
+}
+
+void __nm_update_network_type(bool isConnect)
+{
+ FUNC_ENTER;
+
+ if (!isConnect)
+ network_type = NM_NETWORK_TYPE_DISCONNECTED;
+ else {
+ connection_type_e eType = __nm_get_connection_type();
+
+ switch (eType) {
+ case CONNECTION_TYPE_ETHERNET:
+ network_type = NM_NETWORK_TYPE_ETHERNET;
+ break;
+ case CONNECTION_TYPE_WIFI:
+ network_type = NM_NETWORK_TYPE_WIFI;
+ break;
+ default:
+ network_type = NM_NETWORK_TYPE_UNKNOWN;
+ break;
+ }
+ }
+
+ UA_WIFI_INFO("isConnect : %d, network_type : %d", isConnect, network_type);
+
+ if (isConnect) {
+ UA_WIFI_INFO("update network status %s", isConnect ? "CONNECT" : "DISCONNECT");
+ char gateway[16];
+ char macaddr[128];
+
+ memset(gateway, 0, 16);
+
+ if (__nm_get_gateway_address(gateway) == true)
+ UA_WIFI_INFO("currently gateway address : %s", gateway);
+
+
+ __nm_get_ips_mac(gateway, macaddr);
+
+ UA_WIFI_INFO("IPv4 mac address of the resource: %s", macaddr);
+
+ strncpy(connected_bssid, macaddr, strlen(macaddr));
+ connected_bssid[strlen(macaddr) + 1] = '\0';
+ } else {
+ UA_WIFI_INFO("update network status %s", isConnect ? "CONNECT" : "DISCONNECT");
+ memset(connected_bssid, 0, sizeof(connected_bssid));
+ }
+
+ FUNC_EXIT;
+}
+
+bool __nm_get_mac_address(char** mac_addr)
+{
+ FUNC_ENTER;
+ connection_type_e conn_type;
+
+ if (!h_conn) {
+ UA_WIFI_ERR("Connection is not created");
+ return false;
+ }
+
+ if (network_type == NM_NETWORK_TYPE_WIFI) {
+ UA_WIFI_INFO("Currently Network Status WIFI");
+ conn_type = CONNECTION_TYPE_WIFI;
+ } else if (network_type == NM_NETWORK_TYPE_ETHERNET) {
+ UA_WIFI_INFO("Currently Network Status Wired");
+ conn_type = CONNECTION_TYPE_ETHERNET;
+ } else {
+ UA_WIFI_INFO("No Network or Network status not available");
+ FUNC_EXIT;
+ return false;
+ }
+
+ if (connection_get_mac_address(h_conn, conn_type, mac_addr) != CONNECTION_ERROR_NONE) {
+ UA_WIFI_ERR("Fail to get MAC address");
+ FUNC_EXIT;
+ return false;
+ }
+
+ FUNC_EXIT;
+ return true;
+}
+
+char* __nm_get_ip_address(void)
+{
+ char *ip_addr = NULL;
+ int ret = connection_get_ip_address(h_conn, CONNECTION_ADDRESS_FAMILY_IPV4, &ip_addr);
+ if ( CONNECTION_ERROR_NONE != ret) {
+ UA_WIFI_ERR("Error in getting ip address");
+
+ if (NULL != ip_addr) {
+ free(ip_addr);
+ ip_addr = NULL;
+ }
+
+ return NULL;
+ }
+
+ //UA_WIFI_DBG("Connected AP's IP : %s", ip_addr);
+ return ip_addr;
+}
+
+void __nm_get_connected_bssid(char** connect_bssid)
+{
+ if (connect_bssid == NULL) {
+ *connect_bssid = NULL;
+ return;
+ }
+
+ *connect_bssid = g_strdup(connected_bssid);
+ return;
+}
+
/*
- * UAFW plugins interface
- *
- * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2019 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.
#include <glib.h>
#include <log.h>
-#include <ua-plugin.h>
+#include <wifi-plugin.h>
+#include <wifi-plugin-util.h>
+#include <wifi-scan.h>
+#include <wifi-networkmanager.h>
#define NAME "wifi-plugin"
#define AUTHOR "Samsung"
#define VERSION "0.1"
+#define DETECTION_CYCLE_DEFAULT 900 /* 15 minutes -> 15 * 60 = 900 seconds */
+#define DETECTION_PERIOD_DEFAULT 60 /* 1 minute -> 1 * 60 = 60 seconds */
+#define ABSENCE_THRESHOLD_DEFAULT 1
+
+static int wifi_detection_cycle = DETECTION_CYCLE_DEFAULT;
+static int wifi_detection_period = DETECTION_PERIOD_DEFAULT;
+static int wifi_detection_retries = ABSENCE_THRESHOLD_DEFAULT;
+static guint detection_cycle_timer = 0;
+static bool initial_bursts = true;
+
+static gboolean lpm_enabled = FALSE; /**< Low power mode */
+
static const uas_callbacks_t *uas_cbs = NULL; /**< Interfaces for ua_manager */
+static uas_state_e curr_state = UAS_STATE_NOT_READY; /**< Plugin state */
+static GSList *dev_list = NULL; /**< Device lists */
+static unsigned int detect_count;
+static int wifi_detection_type = 0;
static int init(const uas_callbacks_t *callbacks)
{
FUNC_ENTER;
- uas_cbs = callbacks;
+ retv_if(NULL == callbacks, UAS_STATUS_FAIL);
+
+ if (uas_cbs != NULL) {
+ UA_WIFI_DBG("Wi-Fi plugin is already initialized");
+ FUNC_EXIT;
+ return UAS_STATUS_ALREADY_DONE;
+ } else {
+ uas_cbs = callbacks;
+ }
+
+ detect_count = 0;
+
+ if (__nm_init() != true) {
+ UA_WIFI_ERR("Fail to initialize network manager");
+ FUNC_EXIT;
+ return UAS_STATUS_FAIL;
+ }
+
+ if (__initialize_arp_data() != UAS_STATUS_SUCCESS) {
+ UA_WIFI_ERR("Fail to initialize arp data");
+ FUNC_EXIT;
+ return UAS_STATUS_FAIL;
+ }
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
static int deinit(void)
{
FUNC_ENTER;
+ if (dev_list) {
+ g_slist_free_full(dev_list, g_free);
+ dev_list = NULL;
+ }
+ __nm_deinit();
+ __deinit_arp_data();
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
}
{
FUNC_ENTER;
+ *state = curr_state;
+
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
}
{
FUNC_ENTER;
+ retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
+
*capability = UAS_SUPPORT_USER;
FUNC_EXIT;
static int set_registered_devices(int num_devices, uas_device_info_t *devices)
{
FUNC_ENTER;
+ int i, dev_count = 0;
+
+ retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
+
+ if (dev_list) {
+ g_slist_free_full(dev_list, g_free);
+ dev_list = NULL;
+ }
+
+ for (i = 0; i < num_devices; i++) {
+ uas_wifi_info_t* wifi_info;
+
+ wifi_info = _wifi_plugin_util_get_wifi_info_from_dev_info(&(devices[i]));
+
+ if (!wifi_info)
+ continue;
+ else
+ dev_count++;
+
+ wifi_info->mobile_flag = dev_count;
+ dev_list = g_slist_prepend(dev_list, wifi_info);
+ }
+
+ detect_count = dev_count;
+
+ if (uas_cbs->state_changed_cb) {
+ switch (curr_state) {
+ case UAS_STATE_NOT_READY:
+ if (dev_list) {
+ uas_cbs->state_changed_cb(UAS_STATE_READY);
+ curr_state = UAS_STATE_READY;
+ }
+ break;
+ case UAS_STATE_READY:
+ if (!dev_list) {
+ uas_cbs->state_changed_cb(UAS_STATE_NOT_READY);
+ curr_state = UAS_STATE_NOT_READY;
+ }
+ break;
+ }
+ }
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
}
+void __check_mobilelist()
+{
+ int ret;
+ GSList *l;
+
+ if (!dev_list) {
+ UA_WIFI_ERR("No devices to scan");
+ return ;
+ }
+
+ for (l = dev_list; NULL != l; l = g_slist_next(l)) {
+ uas_wifi_info_t *wifi_info = l->data;
+
+ if (wifi_info->mobile_flag != detect_count)
+ continue;
+
+ if (WIFI_PRESENCE_STATUS_ABSENCE == wifi_info->presence) {
+ UA_WIFI_INFO("Detect this mobild id %s start presence request MAC %s",
+ wifi_info->mobile_id, wifi_info->mac_addr);
+ if (initial_bursts == true) {
+ if (UAS_STATUS_SUCCESS !=__init_ip_mac_count()) {
+ UA_WIFI_ERR("ARP Init fail");
+ return;
+ } else
+ initial_bursts = false;
+ }
+
+ ret = __start_wifi_detection(wifi_info->ip_addr, wifi_info->mac_addr);
+ if (UAS_STATUS_SUCCESS != ret) {
+ UA_WIFI_ERR("ARP Init fail");
+ wifi_info->presence = WIFI_PRESENCE_STATUS_ABSENCE;
+ detect_count--;
+ continue;
+ }
+ break;
+ } else {
+ UA_WIFI_INFO("Already detected, So skip");
+ detect_count--;
+ }
+ }
+
+ __check_mobile_list_finish(false);
+}
+
+void __reset_wifi_info()
+{
+ GSList *l;
+ detect_count = g_slist_length(dev_list);
+
+ for (l = dev_list; NULL != l; l = g_slist_next(l)) {
+ uas_wifi_info_t *wifi_info = l->data;
+ wifi_info->presence = WIFI_PRESENCE_STATUS_ABSENCE;
+ }
+}
+
+static gboolean __start_wifi_scan(gpointer user_data)
+{
+ FUNC_ENTER;
+
+ initial_bursts = true;
+ __reset_wifi_info();
+ __check_mobilelist();
+
+ /* Send detection started */
+ if (uas_cbs && uas_cbs->detection_state_cb)
+ uas_cbs->detection_state_cb(1);
+
+ FUNC_EXIT;
+ return TRUE;
+}
+
+void __check_device_found(char* sbuf, char* ip_sbuf)
+{
+ FUNC_ENTER;
+ GSList *l;
+
+ for (l = dev_list; NULL != l; l = g_slist_next(l)) {
+ uas_wifi_info_t *wifi_info = l->data;
+ uas_device_info_t *dev_info = NULL;
+
+ if (wifi_info->mobile_flag == detect_count) {
+ wifi_info->presence = WIFI_PRESENCE_STATUS_PRESENCE;
+
+ g_strlcpy(wifi_info->mac_addr, sbuf, MAC_ADDRESS_STRING_SIZE);
+ g_strlcpy(wifi_info->ip_addr, ip_sbuf, IP_ADDRESS_STRING_SIZE);
+
+ wifi_info->absence_count = 0;
+
+ if (!(UAS_PRESENCE & wifi_detection_type))
+ break;
+
+ if (!uas_cbs && !uas_cbs->device_detected_cb)
+ break;
+
+ /* Send PRESENCE callback */
+ dev_info = _wifi_plugin_util_get_dev_info_from_wifi_info(wifi_info);
+ if (!dev_info) {
+ UA_WIFI_ERR("Unable to get dev_info");
+ break;
+ }
+
+ uas_cbs->device_detected_cb(UAS_PRESENCE, dev_info);
+ UA_WIFI_INFO("Called uas_cbs->device_detected_cb(UAS_PRESENCE)");
+ _wifi_plugin_util_uas_device_info_free(dev_info);
+ break;
+ }
+ }
+ FUNC_EXIT;
+}
+
+void __check_mobile_list_finish(bool is_check)
+{
+ FUNC_ENTER;
+ uas_device_info_t *dev_info = NULL;
+
+ if (is_check == true)
+ detect_count--;
+
+ UA_WIFI_INFO("find next mobile flag %d", detect_count);
+
+ if (!detect_count) {
+
+ GSList *l;
+
+ UA_WIFI_INFO("Already All mobile detected");
+
+ initial_bursts = true;
+
+
+ UA_WIFI_INFO("Detection mode unicast finish");
+
+ for (l = dev_list; NULL != l; l = g_slist_next(l)) {
+ uas_wifi_info_t *wifi_info = l->data;
+
+ if (!wifi_info)
+ continue;
+
+ if (wifi_info->presence) {
+ wifi_info->presence = WIFI_PRESENCE_STATUS_ABSENCE;
+ continue;
+ }
+
+ wifi_info->absence_count += 1;
+
+ UA_WIFI_INFO("absence_count = %d", wifi_info->absence_count);
+
+ if ((UAS_ABSENCE & wifi_detection_type) &&
+ (wifi_detection_retries <= wifi_info->absence_count) &&
+ (uas_cbs && uas_cbs->device_detected_cb)) {
+ dev_info = _wifi_plugin_util_get_dev_info_from_wifi_info(wifi_info);
+ if (!dev_info) {
+ UA_WIFI_ERR("Unable to get dev_info");
+ break;
+ }
+
+ uas_cbs->device_detected_cb(UAS_ABSENCE, dev_info);
+ UA_WIFI_INFO("Called uas_cbs->device_detected_cb(UAS_ABSENCE)");
+ _wifi_plugin_util_uas_device_info_free(dev_info);
+ }
+
+ wifi_info->presence = WIFI_PRESENCE_STATUS_ABSENCE;
+ }
+
+ /* Send detection stopped */
+ if (uas_cbs && uas_cbs->detection_state_cb)
+ uas_cbs->detection_state_cb(0);
+
+ } else {
+ if (is_check == true) {
+ initial_bursts = true;
+ __check_mobilelist();
+ }
+ }
+
+ FUNC_EXIT;
+}
+
static int add_device(uas_device_info_t *device)
{
FUNC_ENTER;
- uas_cbs->device_added_cb(UAS_STATUS_SUCCESS, device);
+ uas_wifi_info_t *wifi_info;
+ int mac_len;
+ int ip_len;
+
+ retv_if(NULL == device, UAS_STATUS_FAIL);
+ retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
+
+ wifi_info = _wifi_plugin_util_get_wifi_info_from_dev_info(device);
+ retv_if(NULL == wifi_info, UAS_STATUS_FAIL);
+
+ mac_len = strlen(wifi_info->mac_addr);
+ ip_len = strlen(wifi_info->ip_addr);
+ if (!mac_len && !ip_len) {
+ free(wifi_info);
+ FUNC_EXIT;
+ return UAS_STATUS_FAIL;
+ }
+
+ /* Add to list */
+ dev_list = g_slist_prepend(dev_list,
+ g_memdup(wifi_info, sizeof(uas_wifi_info_t)));
+ UA_WIFI_DBG("Added device to list, num devices = %d", g_slist_length(dev_list));
+
+ if (mac_len && ip_len &&
+ (strcasecmp(wifi_info->mac_addr, BROADCAST_MAC_ADDR) != 0)) {
+ initial_bursts = true;
+ uas_cbs->device_added_cb(UAS_STATUS_SUCCESS, device);
+ }
+
+ free(wifi_info);
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
static int remove_device(uas_device_info_t *device)
{
FUNC_ENTER;
+ GSList *l;
+
+ retv_if(NULL == device, UAS_STATUS_FAIL);
+ retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
+
+ for (l = dev_list; NULL != l; l = g_slist_next(l)) {
+ uas_wifi_info_t *wifi_info = l->data;
+
+ if (!strcasecmp(wifi_info->mobile_id, device->device_id)) {
+ dev_list = g_slist_remove(dev_list, wifi_info);
+ free(wifi_info);
+ return UAS_STATUS_SUCCESS;
+ }
+ }
FUNC_EXIT;
- return UAS_STATUS_SUCCESS;
+ return UAS_STATUS_FAIL;
}
static int start_detection(unsigned int detection_type)
{
FUNC_ENTER;
+ retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
+ retv_if((wifi_detection_type & detection_type), UAS_STATUS_ALREADY_DONE);
+
+ /* Check if detection already in progress */
+ if (0 != wifi_detection_type) {
+ wifi_detection_type |= detection_type;
+ goto done;
+ }
+
+ wifi_detection_type |= detection_type;
+ /* Check if lpm enabled */
+ if (lpm_enabled) {
+ FUNC_EXIT;
+ return UAS_STATUS_SUCCESS;
+ }
+
+ /* Schedule detection cycle */
+ if (0 < detection_cycle_timer)
+ g_source_remove(detection_cycle_timer);
+
+ detection_cycle_timer = g_timeout_add_seconds(
+ wifi_detection_cycle, __start_wifi_scan, NULL);
+
+ /* Start detection */
+ __start_wifi_scan(NULL);
+
+done:
+ UA_WIFI_INFO("wifi_detection_type = 0x%8.8X", wifi_detection_type);
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
}
{
FUNC_ENTER;
+ retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
+ retv_if(0 == wifi_detection_type, UAS_STATUS_ALREADY_DONE);
+
+ wifi_detection_type &= ~detection_type;
+ UA_WIFI_INFO("wifi_detection_type = 0x%8.8X", wifi_detection_type);
+
+ if (0 != wifi_detection_type)
+ goto done;
+
+ /* Remove detection cycle timer */
+ if (0 < detection_cycle_timer) {
+ g_source_remove(detection_cycle_timer);
+ detection_cycle_timer = 0;
+ }
+
+done:
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
}
{
FUNC_ENTER;
+ if (0 == mode)
+ lpm_enabled = FALSE;
+ else
+ lpm_enabled = TRUE;
+
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
}
{
FUNC_ENTER;
+ retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
+ retv_if(detection_period > detection_cycle, UAS_STATUS_FAIL);
+ retv_if(0 >= detection_retries, UAS_STATUS_FAIL);
+
+ wifi_detection_cycle = detection_cycle;
+ wifi_detection_period = detection_period;
+ wifi_detection_retries = detection_retries;
+
FUNC_EXIT;
return UAS_STATUS_SUCCESS;
}
{
FUNC_ENTER;
+ UA_WIFI_INFO("presence_threshold = %d, absence_threshold = %d",
+ presence_threshold, absence_threshold);
+
FUNC_EXIT;
- return UAS_STATUS_SUCCESS;
+ return UAS_STATUS_UNSUPPORTED;
}
static uas_api_t wifi_api = {
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include <log.h>
+#include <ua-plugin.h>
+#include <wifi-plugin.h>
+#include <wifi-networkmanager.h>
+#include <wifi-scan.h>
+
+struct arping_data *arp_data;
+
+static int __arp_packet_make(const char* mac)
+{
+ FUNC_ENTER;
+ bool ret = false;
+ struct ether_addr* source_mac = NULL;
+ struct ether_addr* dest_mac = NULL;
+ char* source_mac_address = NULL;
+
+ ret = __nm_get_mac_address(&source_mac_address);
+
+ if (ret == false) {
+ UA_WIFI_ERR("Get Mac Fail");
+ return UAS_STATUS_FAIL;
+ }
+
+ memcpy(arp_data->arp_source_mac, source_mac_address, strlen(source_mac_address));
+ source_mac = ether_aton(source_mac_address);
+
+ if (source_mac == NULL) {
+ UA_WIFI_ERR("Wrong Mac address");
+ free(source_mac_address);
+ return UAS_STATUS_FAIL;
+ }
+
+ UA_WIFI_INFO("currently Network mac Address = %s source_mac = %s",
+ source_mac_address, ether_ntoa(source_mac));
+
+ memset(&arp_data->arp, 0, sizeof(arp_data->arp));
+ memcpy(arp_data->arp.h_source, source_mac, MAC_ADD_LENGTH);
+ memcpy(arp_data->arp.s_hwaddr, source_mac, MAC_ADD_LENGTH);
+
+ dest_mac = ether_aton(mac);
+
+ if (dest_mac == NULL) {
+ UA_WIFI_ERR("Destination Mac address is wrong");
+ return UAS_STATUS_FAIL;
+ }
+
+ UA_WIFI_INFO("Scan mac Address = %s dest_mac =%s", mac, ether_ntoa(dest_mac));
+
+ memcpy(arp_data->arp.h_dest, dest_mac, MAC_ADD_LENGTH);
+ memcpy(arp_data->arp.t_hwaddr, dest_mac, MAC_ADD_LENGTH);
+
+ arp_data->arp.h_proto = htons(ETH_P_ARP); /* protocol type (Ethernet) */
+ arp_data->arp.hw_type = htons(ARPHRD_ETHER); /* hardware type */
+ arp_data->arp.p_type = htons(ETH_P_IP); /* protocol type (ARP message) */
+ arp_data->arp.hw_len = MAC_ADD_LENGTH; /* hardware address length */
+ arp_data->arp.p_len = IP_ADD_LENGTH; /* protocol address length */
+ arp_data->arp.operation = htons(ARPOP_REQUEST); /* ARP op code */
+
+ UA_WIFI_INFO("Init arp packet success");
+ free(source_mac_address);
+ FUNC_EXIT;
+ return UAS_STATUS_SUCCESS;
+}
+
+static unsigned int __convert_uchar_to_uint(unsigned char b[IP_ADD_LENGTH])
+{
+ int idx = 0;
+ union uchar_to_uint u;
+ for (; idx < IP_ADD_LENGTH; ++idx)
+ u.uchar[idx] = b[idx];
+
+ return u.uint;
+}
+
+static gboolean clean_socket()
+{
+ GError* error = NULL;
+
+ if (NULL == arp_data->arp_sock_io || arp_data->arp_id == -1) {
+ UA_WIFI_ERR(" Gateway socket or io channel not initilized yet.");
+ return true;
+ }
+
+ UA_WIFI_INFO("arp Closing socket[%d] , and shutdown io channel[%p]",
+ arp_data->arp_id, arp_data->arp_sock_io);
+
+ /* Closing socket descriptor. */
+ if (-1 < arp_data->arp_id) {
+ if (G_IO_STATUS_NORMAL != g_io_channel_shutdown(
+ arp_data->arp_sock_io, FALSE, &error)) {
+ UA_WIFI_ERR("Failure received while shutdown io channel[%d]:[%s]",
+ error->code, error->message);
+ g_error_free(error);
+ return false;
+ }
+
+ g_source_remove(arp_data->arp_data_id);
+ arp_data->arp_data_id = -1;
+ arp_data->arp_id = -1;
+ arp_data->arp_sock_io = NULL;
+ }
+
+ arp_data->is_arp_init = 0;
+ return true;
+}
+
+static void __stop_send_arp_packettimer()
+{
+ UA_WIFI_INFO("Stop send arp pcket timer");
+
+ if (arp_data->arp_send_packet_timer) {
+ g_source_remove(arp_data->arp_send_packet_timer);
+ arp_data->arp_send_ip_addr = 0 ;
+ arp_data->arp_send_packet_timer = 0;
+ }
+}
+
+gboolean __arp_packet_receive(GIOChannel *source, GIOCondition condition,
+ gpointer data)
+{
+ gchar buffer[ARP_PACKET_SIZE];
+ gsize bytes_read = 0;
+ struct arp_message arp_recv;
+ char sbuf[MAC_ADDRESS_STRING_SIZE];
+ char tbuf[MAC_ADDRESS_STRING_SIZE];
+ char ip_sbuff[IP_ADDRESS_STRING_SIZE];
+ char ip_tbuff[IP_ADDRESS_STRING_SIZE];
+ int mac_cmp;
+
+ memset(buffer, '\0', ARP_PACKET_SIZE);
+ memset(sbuf, '\0', MAC_ADDRESS_STRING_SIZE);
+ memset(tbuf, '\0', MAC_ADDRESS_STRING_SIZE);
+ memset(ip_sbuff, '\0', IP_ADDRESS_STRING_SIZE);
+ memset(ip_sbuff, '\0', IP_ADDRESS_STRING_SIZE);
+
+ if (!arp_data->is_arp_init)
+ return false;
+
+ switch (condition) {
+ case G_IO_IN:
+ if (g_io_channel_read_chars(
+ source, buffer, ARP_PACKET_SIZE, &bytes_read, NULL) == G_IO_STATUS_NORMAL) {
+ uint32_t target_ip = 0;
+
+ memset(&arp_recv, 0, sizeof(arp_recv));
+ memcpy(&arp_recv, buffer, sizeof(buffer));
+
+ target_ip = inet_addr(arp_data->arp_source_ip);
+
+ if (arp_recv.operation != htons(ARPOP_REPLY))
+ break;
+
+ UA_WIFI_INFO("target mac address = %02x:%02x:%02x:%02x:%02x:%02x",
+ arp_recv.t_hwaddr[0], arp_recv.t_hwaddr[1], arp_recv.t_hwaddr[2],
+ arp_recv.t_hwaddr[3], arp_recv.t_hwaddr[4], arp_recv.t_hwaddr[5]);
+ UA_WIFI_INFO("source mac address = %02x:%02x:%02x:%02x:%02x:%02x",
+ arp_recv.s_hwaddr[0], arp_recv.s_hwaddr[1], arp_recv.s_hwaddr[2],
+ arp_recv.s_hwaddr[3], arp_recv.s_hwaddr[4], arp_recv.s_hwaddr[5]);
+
+ snprintf(tbuf, MAC_ADDRESS_STRING_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
+ arp_recv.t_hwaddr[0], arp_recv.t_hwaddr[1], arp_recv.t_hwaddr[2],
+ arp_recv.t_hwaddr[3], arp_recv.t_hwaddr[4], arp_recv.t_hwaddr[5]);
+ snprintf(sbuf, MAC_ADDRESS_STRING_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
+ arp_recv.s_hwaddr[0], arp_recv.s_hwaddr[1], arp_recv.s_hwaddr[2],
+ arp_recv.s_hwaddr[3], arp_recv.s_hwaddr[4], arp_recv.s_hwaddr[5]);
+
+ if (strcasecmp(tbuf, arp_data->arp_source_mac)) {
+ UA_WIFI_INFO("Packet not intended to us.");
+ break;
+ }
+
+ if (!strcasecmp(tbuf , "00:00:00:00:00:00"))
+ UA_WIFI_INFO("Broadcast packet.");
+
+ snprintf(ip_sbuff, IP_ADDRESS_STRING_SIZE, "%d.%d.%d.%d",
+ arp_recv.s_IPaddr[0], arp_recv.s_IPaddr[1],
+ arp_recv.s_IPaddr[2], arp_recv.s_IPaddr[3]);
+ UA_WIFI_INFO("source ip_sbuff = %s target ip = %d source ip = %d",
+ ip_sbuff, target_ip, __convert_uchar_to_uint(arp_recv.s_IPaddr));
+
+ snprintf(ip_tbuff, IP_ADDRESS_STRING_SIZE, "%d.%d.%d.%d",
+ arp_recv.t_IPaddr[0], arp_recv.t_IPaddr[1],
+ arp_recv.t_IPaddr[2], arp_recv.t_IPaddr[3]);
+ UA_WIFI_INFO("target ip_tbuff = %s target ip = %d source ip = %d",
+ ip_tbuff, target_ip, __convert_uchar_to_uint(arp_recv.s_IPaddr));
+
+ mac_cmp = strcasecmp(sbuf, arp_data->arp_target_mac);//same target mac ip is valid
+
+ if (!mac_cmp) {
+ UA_WIFI_INFO("%d ARP packet - received info and init arp_mac_count",
+ arp_data->arp_mac_count);
+ arp_data->arp_mac_count = MAX_MAC_ARP_COUNT;
+ } else {
+ UA_WIFI_INFO("received arp source mac and our made target mac is " \
+ "different, wrong arp packet");
+ break;
+ }
+
+ UA_WIFI_INFO("device found");
+
+ if (arp_data->mobile_detection == true)
+ __check_device_found(sbuf, ip_sbuff);
+
+ UA_WIFI_INFO("find device set ARP Count MAX");
+ clean_socket();
+ __stop_send_arp_packettimer();
+ }
+ break;
+ case G_IO_HUP:
+ UA_WIFI_INFO("G_IO_HUP event received.");
+ break;
+ case G_IO_ERR:
+ UA_WIFI_INFO("G_IO_ERR event received.");
+ break;
+ case G_IO_NVAL:
+ UA_WIFI_INFO("G_IO_NVAL event received.");
+ break;
+ default:
+ UA_WIFI_INFO("Unknown event received.");
+ break;
+ }
+
+ return true;
+}
+
+gboolean __arp_packet_callback()
+{
+ if (arp_data && arp_data->is_arp_init)
+ clean_socket();
+
+ if (arp_data->arp_mac_count <= 0)
+ return false;
+
+ arp_data->arp_mac_count++;
+ UA_WIFI_INFO("Next Send ARP count %d", arp_data->arp_mac_count);
+
+ if (arp_data->arp_mac_count <= MAX_MAC_ARP_COUNT) {
+ UA_WIFI_INFO("Next Send %d ARP Packet number", arp_data->arp_mac_count);
+ if (arp_data->mobile_detection == true)
+ __check_mobilelist();
+ } else {
+ UA_WIFI_INFO("Finish ARP because already send count %d init arp_mac_count",
+ arp_data->arp_mac_count);
+ arp_data->arp_mac_count = 0;
+ if (arp_data->mobile_detection == true)
+ __check_mobile_list_finish(true);
+ }
+
+ return false;
+}
+
+static int __init_arp(const char* mac)
+{
+ struct ifreq net_ifr;
+ char error_buf[MAX_SIZE_ERROR_BUFFER];
+ char *iface_name = NULL;
+ int val = 1;
+ int if_name_len ;
+ struct ether_addr *dest_mac = NULL;
+
+ dest_mac = ether_aton(mac);
+
+ if (dest_mac == NULL) {
+ UA_WIFI_ERR("Destination Mac address is wrong");
+ return UAS_STATUS_FAIL;
+ }
+
+ UA_WIFI_INFO("Scan mac Address = %s uni_dest_mac =%s", mac, ether_ntoa(dest_mac));
+
+ memset(&(arp_data->addr), 0, sizeof(arp_data->addr));
+ memset(&net_ifr, 0, sizeof(net_ifr));
+ memset(error_buf, 0, MAX_SIZE_ERROR_BUFFER);
+
+ arp_data->arp_id = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
+
+ if (arp_data->arp_id == -1) {
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
+ UA_WIFI_ERR("Socket failed. Error: %s", error_buf);
+ return UAS_STATUS_FAIL;
+ }
+
+ if (setsockopt(arp_data->arp_id, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)) == -1) {
+ UA_WIFI_ERR("setsocketopt on socket failed");
+ close(arp_data->arp_id);
+ arp_data->arp_id = -1;
+ return UAS_STATUS_FAIL;
+ }
+
+ /* ifreq structure creation */
+ if (__nm_get_interface_name(&iface_name) == false) {
+ UA_WIFI_ERR("interface is wrong");
+ return UAS_STATUS_FAIL;
+ }
+
+ UA_WIFI_INFO("Network interface %s", iface_name);
+ if_name_len = strlen(iface_name);
+
+ if (if_name_len < sizeof(net_ifr.ifr_name)) {
+ memcpy(net_ifr.ifr_name, iface_name, if_name_len);
+ net_ifr.ifr_name[if_name_len] = 0;
+ } else {
+ UA_WIFI_ERR("Error : Interface name is too long");
+ free(iface_name);
+ return UAS_STATUS_FAIL;
+ }
+
+ free(iface_name);
+
+ if (ioctl(arp_data->arp_id, SIOCGIFINDEX, &net_ifr) == -1) {
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
+ UA_WIFI_ERR("ioctl failed. Error: %s", error_buf);
+ return UAS_STATUS_FAIL;
+ }
+
+ /* Construct the destination address */
+ arp_data->addr.sll_family = AF_PACKET;
+ arp_data->addr.sll_ifindex = net_ifr.ifr_ifindex;
+ arp_data->addr.sll_halen = ETHER_ADDR_LEN;
+ arp_data->addr.sll_protocol = htons(ETH_P_ARP);
+ memcpy(arp_data->addr.sll_addr, dest_mac, ETHER_ADDR_LEN);
+
+ arp_data->arp_sock_io = g_io_channel_unix_new(arp_data->arp_id);
+
+ if (arp_data->arp_sock_io == NULL) {
+ UA_WIFI_ERR("Failed to create channel");
+ close(arp_data->arp_id);
+ arp_data->arp_id = -1;
+ return UAS_STATUS_FAIL;
+ }
+
+ if (G_IO_STATUS_NORMAL != g_io_channel_set_encoding(
+ arp_data->arp_sock_io, NULL, NULL)) {
+ UA_WIFI_ERR("Failed to set encoding NULL on io channel");
+ close(arp_data->arp_id);
+ arp_data->arp_id = -1;
+ return UAS_STATUS_FAIL;
+ }
+
+ if (G_IO_STATUS_NORMAL != g_io_channel_set_flags(
+ arp_data->arp_sock_io, G_IO_FLAG_NONBLOCK, NULL)) {
+ UA_WIFI_ERR("Failed to set flags on io channel");
+ close(arp_data->arp_id);
+ arp_data->arp_id = -1;
+ return UAS_STATUS_FAIL;
+ }
+
+ arp_data->arp_data_id = g_io_add_watch(
+ arp_data->arp_sock_io, G_IO_IN, __arp_packet_receive, NULL);
+ g_io_channel_unref(arp_data->arp_sock_io);
+
+ UA_WIFI_INFO("Init arp socket success");
+ return UAS_STATUS_SUCCESS;
+}
+
+gboolean __send_arp_ip_packet_timeout(gpointer user_data)
+{
+ uint32_t source_ip = 0;
+ uint32_t target_ip = 0;
+
+ char arp_target_ip[MAX_SIZE_BUFFER];
+ char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
+
+ memset(arp_target_ip, '\0', MAX_SIZE_BUFFER);
+
+ source_ip = inet_addr(__nm_get_ip_address());
+ memcpy(arp_data->arp.s_IPaddr, &source_ip, IP_ADD_LENGTH); // source IP address
+ //snprintf(ip_buff, 16, "%d.%d.%d.%d",
+ // arp.s_IPaddr[0],arp.s_IPaddr[1],arp.s_IPaddr[2],pArping->arp_send_ip_addr);
+
+ target_ip = inet_addr(arp_data->arp_source_ip);
+ memcpy(arp_data->arp.t_IPaddr, &target_ip, IP_ADD_LENGTH); // target IP address
+ memcpy(arp_target_ip, arp_data->arp_source_ip , strlen(arp_data->arp_source_ip));
+
+ UA_WIFI_INFO("arp_target_ip = %s ", arp_target_ip);
+
+ if (sendto(arp_data->arp_id, &arp_data->arp, sizeof(arp_data->arp), 0,
+ (struct sockaddr*)&arp_data->addr, sizeof(arp_data->addr)) < 0) {
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
+ UA_WIFI_ERR("Sending ARP Packet Failed. Error: %s", error_buf);
+ }
+
+ arp_data->arp_send_packet_timer = 0;
+ return G_SOURCE_REMOVE;
+}
+
+gboolean __send_arp_unimul_packet_timeout(gpointer user_data)
+{
+ uint32_t source_ip = 0;
+ uint32_t target_ip = 0;
+ char arp_target_ip[MAX_SIZE_BUFFER];
+ char error_buf[MAX_SIZE_ERROR_BUFFER];
+ char ip_buff[IP_ADDRESS_STRING_SIZE];
+
+ memset(arp_target_ip, '\0', MAX_SIZE_BUFFER);
+ memset(error_buf, '\0', MAX_SIZE_ERROR_BUFFER);
+ memset(ip_buff, '\0', IP_ADDRESS_STRING_SIZE);
+ source_ip = inet_addr(__nm_get_ip_address());
+ memcpy(arp_data->arp.s_IPaddr, &source_ip, IP_ADD_LENGTH); // source IP address
+ snprintf(ip_buff, IP_ADDRESS_STRING_SIZE, "%d.%d.%d.%d",
+ arp_data->arp.s_IPaddr[0], arp_data->arp.s_IPaddr[1],
+ arp_data->arp.s_IPaddr[2], arp_data->arp_send_ip_addr);
+
+ if (arp_target_ip[0])
+ UA_WIFI_INFO("Arp source ip: %s", arp_target_ip);
+
+ target_ip = inet_addr(ip_buff);
+ memcpy(arp_target_ip, ip_buff, strlen(ip_buff));
+ memcpy(arp_data->arp.t_IPaddr, &target_ip, IP_ADD_LENGTH); // target IP address
+
+ if (arp_data->arp_send_ip_addr == 1 || arp_data->arp_send_ip_addr == 255)
+ UA_WIFI_INFO("Arp target ip: %s", arp_target_ip);
+
+ if (sendto(arp_data->arp_id, &arp_data->arp, sizeof(arp_data->arp), 0,
+ (struct sockaddr*)&arp_data->addr, sizeof(arp_data->addr)) < 0) {
+ strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
+ UA_WIFI_ERR("Sending ARP Packet Failed. Error: %s", error_buf);
+ }
+
+ if (arp_data->arp_send_ip_addr == 255) {
+ arp_data->arp_send_ip_addr = 0;
+ arp_data->arp_send_packet_timer = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ arp_data->arp_send_ip_addr++;
+ return G_SOURCE_CONTINUE;
+}
+
+static void __send_arp_uni_mode(const char* ip)
+{
+ guint Time;
+
+ if (arp_data->arp_send_packet_timer == 0) {
+ arp_data->arp_send_ip_addr = 1;
+ arp_data->arp_send_packet_timer = g_timeout_add(SEND_MAC_TIMER,
+ __send_arp_unimul_packet_timeout, NULL);
+ UA_WIFI_INFO("SendArpPacket Timer Id is %d Starting Timer ",
+ arp_data->arp_send_packet_timer);
+ }
+
+ Time = ARP_MAC_TIMER * 1000;//1sec
+ arp_data->is_arp_init = 1;
+ g_timeout_add(Time, __arp_packet_callback, NULL);
+ UA_WIFI_INFO("Send %d UNICAST ARP Packet", arp_data->arp_mac_count);
+}
+
+static int __arp_make_send(const char* ip, const char* mac)
+{
+ FUNC_ENTER;
+ int ret;
+
+ ret = __arp_packet_make(mac);
+
+ if (ret != UAS_STATUS_SUCCESS) {
+ UA_WIFI_ERR("Fail to make arp packet");
+ FUNC_EXIT;
+ return ret;
+ }
+
+ ret = __init_arp(mac);
+
+ if (ret != UAS_STATUS_SUCCESS) {
+ UA_WIFI_ERR("Fail to init arp");
+ FUNC_EXIT;
+ return ret;
+ }
+
+ memcpy(arp_data->arp_target_mac, mac, strlen(mac));
+ UA_WIFI_INFO("Request mac address %s IP address %s", mac, ip);
+ __send_arp_uni_mode(ip);
+
+ FUNC_EXIT;
+ return UAS_STATUS_SUCCESS;
+}
+
+int __start_arp(const char* ip, const char* mac)
+{
+ int ret;
+
+ if (arp_data && arp_data->is_arp_init == 1) {
+ UA_WIFI_ERR("Already initialized");
+ return UAS_STATUS_FAIL;
+ }
+
+ arp_data->arp_data_id = -1;
+ arp_data->arp_id = -1;
+ arp_data->arp_sock_io = NULL;
+ memset(arp_data->arp_source_mac, '\0', MAX_SIZE_BUFFER);
+ memset(arp_data->arp_source_ip, '\0', MAX_SIZE_BUFFER);
+ memset(arp_data->arp_target_mac, '\0', MAX_SIZE_BUFFER);
+
+ ret = __arp_make_send(ip, mac);
+
+ return ret;
+}
+
+int __init_ip_mac_count(void)
+{
+ if (!arp_data) {
+ UA_WIFI_ERR("ARP data is not initialized");
+ return UAS_STATUS_FAIL;
+ }
+ arp_data->arp_mac_count = 1;
+
+ return UAS_STATUS_SUCCESS;
+}
+
+int __start_wifi_detection(const char* ip, const char* mac)
+{
+ int ret;
+
+ if (!arp_data) {
+ UA_WIFI_ERR("ARP data is not initialized");
+ return UAS_STATUS_FAIL;
+ }
+
+ arp_data->mobile_detection = true;
+
+ ret = __start_arp(ip, mac);
+
+ return ret;
+}
+
+int __start_wifi_add_device(const char* ip, const char* mac)
+{
+ int ret;
+
+ if (!arp_data) {
+ UA_WIFI_ERR("ARP data is not initialized");
+ return UAS_STATUS_FAIL;
+ }
+
+ arp_data->mobile_detection = false;
+
+ ret = __start_arp(ip, mac);
+
+ return ret;
+}
+
+int __initialize_arp_data(void)
+{
+ if (!arp_data)
+ arp_data = g_try_malloc0(sizeof(struct arping_data));
+
+ if (arp_data == NULL) {
+ UA_WIFI_ERR("Failed to malloc arping_data");
+ return UAS_STATUS_FAIL;
+ }
+
+ return UAS_STATUS_SUCCESS;
+}
+
+void __deinit_arp_data(void)
+{
+ if (arp_data)
+ g_free(arp_data);
+
+ arp_data = NULL;
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#include <wifi-plugin.h>
+#include <wifi-plugin-util.h>
+
+uas_wifi_info_t *_wifi_plugin_util_get_wifi_info_from_dev_info(
+ uas_device_info_t *dev_info)
+{
+ FUNC_ENTER;
+ uas_wifi_info_t* wifi_info;
+ int i;
+ int found = 0;
+
+ retv_if(NULL == dev_info, NULL);
+ retv_if(NULL == dev_info->device_id, NULL);
+
+ wifi_info = g_new0(uas_wifi_info_t, 1);
+ wifi_info->user_id = dev_info->user_id;
+ wifi_info->os = dev_info->os;
+ wifi_info->absence_count = 0;
+ wifi_info->supported_techs = dev_info->supported_techs;
+
+ g_strlcpy(wifi_info->mobile_id, dev_info->device_id, UAS_DEVICE_ID_MAX_LEN);
+
+ for (i = 0; i < dev_info->num_addr; i++) {
+ if (UAS_ADDR_TYPE_WIFI == dev_info->addr_list[i].type) {
+ g_strlcpy(wifi_info->mac_addr,
+ dev_info->addr_list[i].address,
+ MAC_ADDRESS_STRING_SIZE);
+ found = 1;
+ } else if (UAS_ADDR_TYPE_IPv4 == dev_info->addr_list[i].type) {
+ g_strlcpy(wifi_info->ip_addr,
+ dev_info->addr_list[i].address,
+ IP_ADDRESS_STRING_SIZE);
+ found = 1;
+ }
+ }
+
+ if (!found) {
+ UA_WIFI_ERR("Wi-Fi info not present in dev_info structure");
+ g_free(wifi_info);
+ return NULL;
+ }
+
+ UA_WIFI_DBG("User Id: [0x%X], OS: [0x%X], Device Id: [%s], \
+ MAC Addr: [%s], IP Addr: [%s]",
+ wifi_info->user_id, wifi_info->os, wifi_info->mobile_id,
+ wifi_info->mac_addr, wifi_info->ip_addr);
+
+ FUNC_EXIT;
+ return wifi_info;
+}
+
+uas_device_info_t *_wifi_plugin_util_get_dev_info_from_wifi_info(
+ uas_wifi_info_t *wifi_info)
+{
+ FUNC_ENTER;
+ uas_device_info_t *dev_info;
+ int count = 0, i;
+ int is_mac = 0, is_ip = 0;
+
+ retv_if(NULL == wifi_info, NULL);
+
+ dev_info = g_new0(uas_device_info_t, 1);
+ dev_info->user_id = wifi_info->user_id;
+ dev_info->os = wifi_info->os;
+ dev_info->supported_techs = wifi_info->supported_techs;
+ dev_info->device_id = g_strdup(wifi_info->mobile_id);
+
+ if (strlen(wifi_info->mac_addr) != 0) {
+ count++;
+ is_mac = 1;
+ }
+
+ if (strlen(wifi_info->ip_addr) != 0) {
+ count++;
+ is_ip = 1;
+ }
+
+ if (count) {
+ dev_info->addr_list = g_new0(uas_address_info_t, count);
+
+ for (i = 0; i < count; i++) {
+ if (is_mac) {
+ dev_info->addr_list[i].type = UAS_ADDR_TYPE_WIFI;
+ dev_info->addr_list[i].address = g_strdup(wifi_info->mac_addr);
+ is_mac = 0;
+ } else if (is_ip) {
+ dev_info->addr_list[i].type = UAS_ADDR_TYPE_IPv4;
+ dev_info->addr_list[i].address = g_strdup(wifi_info->ip_addr);
+ is_ip = 0;
+ }
+ }
+ }
+
+ dev_info->num_addr = count;
+
+ for (int i = 0; i < count; i++) {
+ UA_WIFI_DBG("User Id: [0x%X], OS: [0x%X], Device Id: [%s], MAC/IP Addr: [%s]",
+ dev_info->user_id, dev_info->os, dev_info->device_id,
+ dev_info->addr_list[i].address);
+ }
+
+ FUNC_EXIT;
+ return dev_info;
+}
+
+void _wifi_plugin_util_uas_device_info_free(uas_device_info_t *device)
+{
+ FUNC_ENTER;
+ int i;
+
+ ret_if(NULL == device);
+
+ g_free(device->device_id);
+
+ for (i = 0; i < device->num_addr; i++)
+ g_free(device->addr_list[i].address);
+
+ g_free(device->addr_list);
+
+ g_free(device);
+
+ FUNC_EXIT;
+}
+