2 * Network Configuration Module
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This file implements wifi direct utility functions.
23 * @file wifi-direct-util.c
24 * @author Gibyoung Kim (lastkgb.kim@samsung.com)
31 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/ioctl.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
43 #include <sys/utsname.h>
48 #include <tzplatform_config.h>
49 #include <system_info.h>
50 #include <systemd/sd-login.h>
52 #include <wifi-direct.h>
54 #include "wifi-direct-ipc.h"
55 #include "wifi-direct-manager.h"
56 #include "wifi-direct-state.h"
57 #include "wifi-direct-util.h"
58 #include "wifi-direct-oem.h"
59 #include "wifi-direct-group.h"
60 #include "wifi-direct-session.h"
61 #include "wifi-direct-error.h"
62 #include "wifi-direct-log.h"
63 #include "wifi-direct-dbus.h"
64 #include "wifi-direct-asp.h"
66 #include <linux/unistd.h>
67 #include <asm/types.h>
68 #include <linux/netlink.h>
69 #include <linux/rtnetlink.h>
71 #include <netlink/netlink.h>
72 #include <netlink/socket.h>
73 #include <netlink/route/neighbour.h>
75 #define ASP_FEATURE "http://tizen.org/feature/network.asp"
76 #define WIFI_DIRECT_DISPLAY_FEATURE "http://tizen.org/feature/network.wifi.direct.display"
77 #define WIFI_DIRECT_SERVICE_DISCOVERY_FEATURE "http://tizen.org/feature/network.wifi.direct.service_discovery"
78 #define TETHERING_WIFI_FEATURE "http://tizen.org/feature/network.tethering.wifi"
79 #define TETHERING_WIFI_DIRECT_FEATURE "http://tizen.org/feature/network.tethering.wifi.direct"
81 #define TIZEN_P2P_GO_IPADDR "192.168.49.1"
82 #define MAX_SIZE_ERROR_BUFFER 256
83 #define MAX_FILE_PATH_LEN 256
84 #define DEFAULT_MAC_FILE_PATH "/sys/class/net/p2p0/address"
86 #define COUNTRY_CODE_FILE tzplatform_mkpath(TZ_SYS_RO_ETC, "wifi-direct/ccode.conf")
87 #define WFD_MANGER_CONF_FILE tzplatform_mkpath(TZ_SYS_RO_ETC, "wifi-direct/wifi-direct-manager.conf")
88 #define WFD_CONF_GROUP_NAME "wfd-manager"
90 enum wfd_util_conf_key {
92 WFD_CONF_CONNECTION_AGENT,
93 WFD_CONF_IP_OVER_EAPOL,
95 WFD_CONF_P2P_IFACE_NAME,
96 WFD_CONF_GROUP_IFACE_NAME,
97 WFD_CONF_DEFAULT_DEVICE_NAME,
98 WFD_CONF_PRIMARY_DEVICE_TYPE,
99 WFD_CONF_SECONDARY_DEVICE_TYPE,
101 WFD_CONF_PERSISTENT_RE,
102 WFD_CONF_LISTEN_REG_CLASS,
103 WFD_CONF_LISTEN_CHANNEL,
104 WFD_CONF_OPER_REG_CLASS,
105 WFD_CONF_OPER_CHANNEL,
106 WFD_CONF_CONFIG_METHOD,
107 WFD_CONF_NO_GROUP_IFACE,
108 WFD_CONF_GROUP_OPER_FREQ,
120 static GKeyFile *__load_key_file()
122 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
123 GKeyFile *key_file = NULL;
124 GError *error = NULL;
126 key_file = g_key_file_new();
127 if (!g_key_file_load_from_file(key_file, WFD_MANGER_CONF_FILE, G_KEY_FILE_NONE, &error)) {
128 WDS_LOGE("Unable to load %s: %s", WFD_MANGER_CONF_FILE, error->message);
129 g_clear_error(&error);
130 g_key_file_free(key_file);
134 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
139 static void __load_wfd_config(GKeyFile **key_file, struct key_value *conf_key_val)
141 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
143 GError *error = NULL;
146 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
150 result = __load_key_file();
152 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
156 for (i = 0; i < WFD_CONF_MAX; i++) {
158 if ((!g_strcmp0(conf_key_val[i].key, "primary_device_type")) ||
159 (!g_strcmp0(conf_key_val[i].key, "secondary_device_type")) ||
160 (!g_strcmp0(conf_key_val[i].key, "go_intent")) ||
161 (!g_strcmp0(conf_key_val[i].key, "listen_reg_class")) ||
162 (!g_strcmp0(conf_key_val[i].key, "listen_channel")) ||
163 (!g_strcmp0(conf_key_val[i].key, "operating_reg_class")) ||
164 (!g_strcmp0(conf_key_val[i].key, "operating_channel")) ||
165 (!g_strcmp0(conf_key_val[i].key, "group_operating_freq"))) {
167 conf_key_val[i].int_value = g_key_file_get_integer(result,
168 WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
170 WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
171 g_clear_error(&error);
174 WDS_LOGD("key [%s] value [%d]\n",
175 conf_key_val[i].key, conf_key_val[i].int_value);
181 if (!g_strcmp0(conf_key_val[i].key, "persistent_reconnect") ||
182 !g_strcmp0(conf_key_val[i].key, "no_group_iface")) {
184 conf_key_val[i].bool_value = g_key_file_get_boolean(result,
185 WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
187 WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
188 g_clear_error(&error);
191 WDS_LOGD("key [%s] value [%d]\n",
192 conf_key_val[i].key, conf_key_val[i].bool_value);
198 conf_key_val[i].value = g_key_file_get_string(result,
199 WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
200 if (!conf_key_val[i].value) {
201 WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
202 g_clear_error(&error);
205 WDS_LOGD("key [%s] value [%s]\n",
206 conf_key_val[i].key, conf_key_val[i].value);
208 if (conf_key_val[i].value && strlen(conf_key_val[i].value) == 0) {
209 g_free(conf_key_val[i].value);
210 conf_key_val[i].value = NULL;
215 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
219 static void __unload_wfd_config(GKeyFile *key_file, struct key_value *conf_key_val)
221 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
223 if (!key_file || !conf_key_val) {
224 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
228 for (i = 0; i < WFD_CONF_MAX; i++) {
229 g_free(conf_key_val[i].value);
233 g_key_file_unref(key_file);
234 __WDS_LOG_FUNC_EXIT__;
239 void *wfd_util_plugin_init(wfd_manager_s *manager)
241 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
243 struct utsname kernel_info;
245 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
248 WDS_LOGE("Invalid parameter");
249 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
253 res = uname(&kernel_info);
255 WDS_LOGE("Failed to detect target type");
256 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
259 WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
263 #if defined(TIZEN_ARCH_64)
264 handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
266 handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
269 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
270 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
275 int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
276 plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
278 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
279 WDS_LOGE("Failed to load symbol. Error = [%s]", error_buf);
281 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
285 wfd_oem_ops_s *temp_ops;
286 (*plugin_load)(&temp_ops);
287 manager->oem_ops = temp_ops;
289 res = wfd_oem_init(temp_ops);
291 WDS_LOGE("Failed to initialize OEM");
293 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
297 /* Configure the plugin here,
298 * using config file parameters */
299 res = wfd_oem_configure(manager->oem_ops, manager->wfd_oem_conf);
301 WDS_LOGE("Failed to configure OEM");
303 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
307 WDS_LOGD("Succeeded to initialize OEM");
309 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
313 int wfd_util_plugin_deinit(wfd_manager_s *manager)
315 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
317 if (!manager || !manager->plugin_handle) {
318 WDS_LOGE("Invalid parameter");
319 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
323 dlclose(manager->plugin_handle);
324 manager->plugin_handle = NULL;
326 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
330 #if defined TIZEN_ENABLE_PRD
331 void *wfd_util_prd_plugin_init(wfd_manager_s *manager)
333 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
335 struct utsname kernel_info;
339 WDS_LOGE("Invalid parameter");
340 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
344 res = uname(&kernel_info);
346 WDS_LOGE("Failed to detect target type");
347 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
350 WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
354 #if defined(TIZEN_ARCH_64)
355 handle = dlopen(SUPPL_PRD_PLUGIN_64BIT_PATH, RTLD_NOW);
357 handle = dlopen(SUPPL_PRD_PLUGIN_PATH, RTLD_NOW);
360 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
361 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
366 int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
367 plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_prd_plugin_load");
369 WDS_LOGE("Failed to load symbol. Error = [%s]", strerror(errno));
371 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
375 (*plugin_load)((wfd_oem_ops_s **)&manager->oem_ops);
377 res = wfd_oem_prd_init((wfd_oem_ops_s *)manager->oem_ops);
379 WDS_LOGE("Failed to initialize PRD OEM");
381 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
384 WDS_LOGD("Succeeded to initialize PRD OEM");
386 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
390 int wfd_util_prd_plugin_deinit(wfd_manager_s *manager)
392 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
394 if (!manager || !manager->prd_plugin_handle) {
395 WDS_LOGE("Invalid parameter");
396 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
400 dlclose(manager->prd_plugin_handle);
401 manager->prd_plugin_handle = NULL;
403 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
406 #endif /* TIZEN_ENABLE_PRD */
409 void wfd_util_load_wfd_conf(wfd_manager_s * manager)
411 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
413 GKeyFile *key_file = NULL;
414 wfd_oem_config_s *oem_conf = NULL;
415 struct key_value wfd_conf[] = {
416 {WFD_CONF_ON_DEMAND, "on_demand", NULL, 0, FALSE},
417 {WFD_CONF_CONNECTION_AGENT, "connection_agent", NULL, 0, FALSE},
418 {WFD_CONF_IP_OVER_EAPOL, "ip_over_eapol", NULL, 0, FALSE},
419 {WFD_CONF_IFACE_NAME, "interface", NULL, 0, FALSE},
420 {WFD_CONF_P2P_IFACE_NAME, "p2p_interface", NULL, 0, FALSE},
421 {WFD_CONF_GROUP_IFACE_NAME, "group_interface", NULL, 0, FALSE},
422 {WFD_CONF_DEFAULT_DEVICE_NAME, "device_name", NULL, 0, FALSE},
423 {WFD_CONF_PRIMARY_DEVICE_TYPE, "primary_device_type", NULL, 0, FALSE},
424 {WFD_CONF_SECONDARY_DEVICE_TYPE, "secondary_device_type", NULL, 0, FALSE},
425 {WFD_CONF_GO_INTENT, "go_intent", NULL, 0, FALSE},
426 {WFD_CONF_PERSISTENT_RE, "persistent_reconnect", NULL, 0, FALSE},
427 {WFD_CONF_LISTEN_REG_CLASS, "listen_reg_class", NULL, 0, FALSE},
428 {WFD_CONF_LISTEN_CHANNEL, "listen_channel", NULL, 0, FALSE},
429 {WFD_CONF_OPER_REG_CLASS, "operating_reg_class", NULL, 0, FALSE},
430 {WFD_CONF_OPER_CHANNEL, "operating_channel", NULL, 0, FALSE},
431 {WFD_CONF_CONFIG_METHOD, "config_methods", NULL, 0, FALSE},
432 {WFD_CONF_NO_GROUP_IFACE, "no_group_iface", NULL, 0, FALSE},
433 {WFD_CONF_GROUP_OPER_FREQ, "group_operating_freq", NULL, 0, FALSE},
434 {WFD_CONF_MAX, NULL, NULL, 0, FALSE},
438 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
442 oem_conf = (wfd_oem_config_s*) manager->wfd_oem_conf;
444 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
448 __load_wfd_config(&key_file, wfd_conf);
450 if (wfd_conf[WFD_CONF_ON_DEMAND].value &&
451 g_strcmp0(wfd_conf[WFD_CONF_ON_DEMAND].value, "yes") == 0)
452 manager->is_on_demand = true;
454 manager->is_on_demand = false;
456 if (wfd_conf[WFD_CONF_CONNECTION_AGENT].value &&
457 g_strcmp0(wfd_conf[WFD_CONF_CONNECTION_AGENT].value, "yes") == 0)
458 manager->is_connection_agent = true;
460 manager->is_connection_agent = false;
462 if (wfd_conf[WFD_CONF_IP_OVER_EAPOL].value &&
463 g_strcmp0(wfd_conf[WFD_CONF_IP_OVER_EAPOL].value, "yes") == 0)
464 manager->is_ip_over_eapol = true;
466 manager->is_ip_over_eapol = false;
468 if (wfd_conf[WFD_CONF_IFACE_NAME].value &&
469 strlen(wfd_conf[WFD_CONF_IFACE_NAME].value) > 0)
470 g_strlcpy(oem_conf->ifname, wfd_conf[WFD_CONF_IFACE_NAME].value,
473 g_strlcpy(oem_conf->ifname, DEFAULT_IFNAME, IFACE_NAME_LEN+1);
475 if (wfd_conf[WFD_CONF_P2P_IFACE_NAME].value &&
476 strlen(wfd_conf[WFD_CONF_P2P_IFACE_NAME].value) > 0)
477 g_strlcpy(oem_conf->p2p_ifname, wfd_conf[WFD_CONF_P2P_IFACE_NAME].value,
480 g_strlcpy(oem_conf->p2p_ifname, DEFAULT_IFNAME, IFACE_NAME_LEN+1);
483 if (wfd_conf[WFD_CONF_GROUP_IFACE_NAME].value &&
484 strlen(wfd_conf[WFD_CONF_GROUP_IFACE_NAME].value) > 0)
485 g_strlcpy(oem_conf->group_ifname,
486 wfd_conf[WFD_CONF_GROUP_IFACE_NAME].value, IFACE_NAME_LEN+1);
488 g_strlcpy(oem_conf->group_ifname, GROUP_IFNAME, IFACE_NAME_LEN+1);
490 if (wfd_conf[WFD_CONF_DEFAULT_DEVICE_NAME].value &&
491 strlen(wfd_conf[WFD_CONF_DEFAULT_DEVICE_NAME].value) > 0)
492 g_strlcpy(oem_conf->device_name,
493 wfd_conf[WFD_CONF_DEFAULT_DEVICE_NAME].value, DEV_NAME_LEN+1);
495 g_strlcpy(oem_conf->device_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN+1);
497 if (wfd_conf[WFD_CONF_PRIMARY_DEVICE_TYPE].int_value > 0)
498 oem_conf->pri_dev_type = wfd_conf[WFD_CONF_PRIMARY_DEVICE_TYPE].int_value;
500 oem_conf->pri_dev_type = DEFAULT_PRIMARY_DEVICE_TYPE;
502 if (wfd_conf[WFD_CONF_SECONDARY_DEVICE_TYPE].int_value > 0)
503 oem_conf->sec_dev_type = wfd_conf[WFD_CONF_SECONDARY_DEVICE_TYPE].int_value;
505 oem_conf->sec_dev_type = DEFAULT_SECONDARY_DEVICE_TYPE;
507 if (wfd_conf[WFD_CONF_GO_INTENT].int_value > 0)
508 oem_conf->go_intent = wfd_conf[WFD_CONF_GO_INTENT].int_value;
510 oem_conf->go_intent = DEFAULT_GO_INTENT;
512 if (wfd_conf[WFD_CONF_PERSISTENT_RE].bool_value == TRUE)
513 oem_conf->persistent_reconnect = TRUE;
515 oem_conf->persistent_reconnect = FALSE;
517 if (wfd_conf[WFD_CONF_LISTEN_REG_CLASS].int_value > 0)
518 oem_conf->listen_reg_class = wfd_conf[WFD_CONF_LISTEN_REG_CLASS].int_value;
520 oem_conf->listen_reg_class = DEFAULT_LISTEN_REG_CLASS;
522 if (wfd_conf[WFD_CONF_LISTEN_CHANNEL].int_value > 0)
523 oem_conf->listen_channel = wfd_conf[WFD_CONF_LISTEN_CHANNEL].int_value;
525 oem_conf->listen_channel = DEFAULT_LISTEN_CHANNEL;
527 if (wfd_conf[WFD_CONF_OPER_REG_CLASS].int_value > 0)
528 oem_conf->operating_reg_class = wfd_conf[WFD_CONF_OPER_REG_CLASS].int_value;
530 oem_conf->operating_reg_class = DEFAULT_OPER_REG_CLASS;
532 if (wfd_conf[WFD_CONF_OPER_CHANNEL].int_value > 0)
533 oem_conf->operating_channel = wfd_conf[WFD_CONF_OPER_CHANNEL].int_value;
535 oem_conf->operating_channel = DEFAULT_OPER_CHANNEL;
537 if (wfd_conf[WFD_CONF_CONFIG_METHOD].value)
538 g_strlcpy(oem_conf->config_methods,
539 wfd_conf[WFD_CONF_CONFIG_METHOD].value, OEM_CONFIG_METHOD_LEN+1);
541 g_strlcpy(oem_conf->config_methods,
542 DEFAULT_CONFIG_METHOD, OEM_CONFIG_METHOD_LEN+1);
544 if (wfd_conf[WFD_CONF_NO_GROUP_IFACE].bool_value == TRUE)
545 oem_conf->no_group_iface = TRUE;
547 oem_conf->no_group_iface = FALSE;
549 if (wfd_conf[WFD_CONF_GROUP_OPER_FREQ].int_value > 0)
550 oem_conf->group_operating_freq = wfd_conf[WFD_CONF_GROUP_OPER_FREQ].int_value;
552 oem_conf->group_operating_freq = 0;
554 __unload_wfd_config(key_file, wfd_conf);
556 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
560 static int _txt_to_mac(char *txt, unsigned char *mac)
565 mac[i++] = (char) strtoul(txt, &txt, 16);
566 if (i == MACADDR_LEN || !*txt++)
570 if (i != MACADDR_LEN)
573 WDS_LOGD("Converted MAC address [" MACSECSTR "]",
578 static int _txt_to_ip(char *txt, unsigned char *ip)
583 ip[i++] = (char) strtoul(txt, &txt, 10);
584 if (i == IPADDR_LEN || !*txt++)
591 WDS_LOGD("Converted IP address [" IPSECSTR "]", IP2SECSTR(ip));
595 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
596 int wfd_util_get_current_time(unsigned long *cur_time)
598 struct timespec time;
600 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
603 res = clock_gettime(CLOCK_REALTIME, &time);
605 WDS_LOGD("Succeeded to get current real time");
606 *cur_time = time.tv_sec;
609 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
610 WDS_LOGE("Failed to get current real time(%s)", error_buf);
613 res = clock_gettime(CLOCK_MONOTONIC, &time);
615 WDS_LOGD("Succeeded to get current system time");
616 *cur_time = time.tv_sec;
619 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
620 WDS_LOGE("Failed to get current system time(%s)", error_buf);
626 static int __wfd_util_find_login_user(uid_t *uid)
632 ret = sd_get_uids(&uids);
636 for (i = 0; i < ret ; i++) {
637 if (sd_uid_get_state(uids[i], &state) < 0) {
641 if (!strncmp(state, "online", 6)) {
654 gboolean wfd_util_execute_file(const char *file_path,
655 char *const args[], char *const envs[])
660 register unsigned int index = 0;
661 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
663 while (args[index] != NULL) {
664 WDS_LOGD("[%s]", args[index]);
668 if (!(pid = fork())) {
669 WDS_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
670 WDS_LOGD("Inside child, exec (%s) command", file_path);
673 if (execve(file_path, args, envs) == -1) {
674 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
675 WDS_LOGE("Fail to execute command (%s)", error_buf);
678 } else if (pid > 0) {
679 if (waitpid(pid, &rv, 0) == -1)
680 WDS_LOGD("wait pid (%u) rv (%d)", pid, rv);
682 WDS_LOGD("exited, rv=%d", WEXITSTATUS(rv));
683 else if (WIFSIGNALED(rv))
684 WDS_LOGD("killed by signal %d", WTERMSIG(rv));
685 else if (WIFSTOPPED(rv))
686 WDS_LOGD("stopped by signal %d", WSTOPSIG(rv));
687 else if (WIFCONTINUED(rv))
688 WDS_LOGD("continued");
692 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
693 WDS_LOGE("failed to fork (%s)", error_buf);
697 int wfd_util_channel_to_freq(int channel)
699 if (channel < 1 || channel > 161 ||
700 (channel > 48 && channel < 149) ||
701 (channel > 14 && channel < 36)) {
702 WDS_LOGE("Unsupported channel[%d]", channel);
707 return 5000 + 5*channel;
708 else if (channel == 14)
711 return 2407 + 5*channel;
714 int wfd_util_freq_to_channel(int freq)
716 if (freq < 2412 || freq > 5825 ||
717 (freq > 2484 && freq < 5180)) {
718 WDS_LOGE("Unsupported frequency[%d]", freq);
723 return 36 + (freq - 5180)/5;
724 else if (freq <= 2472)
725 return 1 + (freq - 2412)/5;
726 else if (freq == 2484)
733 int wfd_util_get_phone_name(char *phone_name)
735 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
738 name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
740 WDS_LOGE("Failed to get vconf value for %s", VCONFKEY_SETAPPL_DEVICE_NAME_STR);
743 g_strlcpy(phone_name, name, DEV_NAME_LEN + 1);
744 WDS_LOGD("[%s: %s]", VCONFKEY_SETAPPL_DEVICE_NAME_STR, phone_name);
746 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
750 void _wfd_util_dev_name_changed_cb(keynode_t *key, void *data)
752 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
753 char dev_name[DEV_NAME_LEN+1] = {0, };
756 res = wfd_util_get_phone_name(dev_name);
758 WDS_LOGE("Failed to get phone name(vconf)");
761 WDS_LOGD("Device name changed as [%s]", dev_name);
763 res = wfd_local_set_dev_name(dev_name);
765 WDS_LOGE("Failed to set device name");
766 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
770 void wfd_util_set_dev_name_notification()
772 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
775 res = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb, NULL);
777 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
781 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
785 void wfd_util_unset_dev_name_notification()
787 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
790 res = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb);
792 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
796 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
800 void _wfd_util_check_country_cb(keynode_t *key, void *data)
802 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
803 wfd_manager_s *manager = (wfd_manager_s*) data;
808 GKeyFile *keyfile = NULL;
809 const char *file_path = COUNTRY_CODE_FILE;
813 WDS_LOGE("Invalid parameter");
817 res = vconf_get_int(VCONFKEY_TELEPHONY_PLMN, &plmn);
819 WDS_LOGE("Failed to get vconf value for PLMN(%d)", res);
823 snprintf(mcc, 4, "%d", plmn);
825 keyfile = g_key_file_new();
826 res = g_key_file_load_from_file(keyfile, file_path, 0, &err);
828 WDS_LOGE("Failed to load key file(%s)", err->message);
829 g_key_file_free(keyfile);
833 ccode = g_key_file_get_string(keyfile, "ccode_map", mcc, &err);
835 WDS_LOGE("Failed to get country code string(%s)", err->message);
836 g_key_file_free(keyfile);
840 res = wfd_oem_set_country(manager->oem_ops, ccode);
842 WDS_LOGE("Failed to set contry code");
844 WDS_LOGD("Succeeded to set country code(%s)", ccode);
846 g_key_file_free(keyfile);
849 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
853 int wfd_util_check_wifi_state()
855 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
859 /* vconf key and value (vconf-keys.h)
860 #define VCONFKEY_WIFI_STATE "memory/wifi/state"
862 VCONFKEY_WIFI_OFF = 0x00,
863 VCONFKEY_WIFI_UNCONNECTED,
864 VCONFKEY_WIFI_CONNECTED,
865 VCONFKEY_WIFI_TRANSFER,
866 VCONFKEY_WIFI_STATE_MAX
869 res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
871 WDS_LOGE("Failed to get vconf value [%s]", VCONFKEY_WIFI_STATE);
872 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
875 WDS_LOGD("[%s: %d]", VCONFKEY_WIFI_STATE, wifi_state);
877 if (wifi_state > VCONFKEY_WIFI_OFF) {
878 WDS_LOGD("Wi-Fi is on");
879 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
882 WDS_LOGD("OK. Wi-Fi is off\n");
884 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
888 int wfd_util_check_mobile_ap_state()
890 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
891 int mobile_ap_state = 0;
894 res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobile_ap_state);
896 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
897 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
900 WDS_LOGD("[%s: %d]", VCONFKEY_MOBILE_HOTSPOT_MODE, mobile_ap_state);
902 if ((mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)
903 || (mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP)) {
904 WDS_LOGD("Mobile AP is on");
905 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
908 WDS_LOGD("OK. Mobile AP is off\n");
910 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
915 int wfd_util_set_country()
917 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
918 wfd_manager_s *manager = wfd_get_manager();
921 _wfd_util_check_country_cb(NULL, manager);
923 res = vconf_notify_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb, manager);
925 WDS_LOGE("Failed to set vconf notification callback(TELEPHONY_PLMN)");
929 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
933 int wfd_util_unset_country()
935 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
938 res = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb);
940 WDS_LOGE("Failed to unset vconf notification callback(TELEPHONY_PLMN)");
944 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
948 static void __check_feature_supported(const char *key,
949 bool *feature_supported)
951 if (system_info_get_platform_bool(key, feature_supported) < 0) {
952 WDS_LOGE("system-info failed to get feature supported flag");
953 *feature_supported = false;
958 static bool __is_wifi_direct_display_feature_supported()
960 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
963 __check_feature_supported(WIFI_DIRECT_DISPLAY_FEATURE, &supported);
965 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
969 static bool __is_wifi_direct_service_discovery_feature_supported()
971 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
974 __check_feature_supported(WIFI_DIRECT_SERVICE_DISCOVERY_FEATURE, &supported);
976 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
980 static bool __is_asp_feature_supported()
982 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
985 __check_feature_supported(ASP_FEATURE, &supported);
987 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
991 static bool __is_tethering_wifi_feature_supported()
993 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
996 __check_feature_supported(TETHERING_WIFI_FEATURE, &supported);
998 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1002 static bool __is_tethering_wifi_direct_feature_supported()
1004 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1007 __check_feature_supported(TETHERING_WIFI_DIRECT_FEATURE, &supported);
1009 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1013 void wfd_util_check_features(wfd_manager_s * manager)
1015 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1018 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1022 manager->is_on_demand_supported = TRUE;
1024 if (__is_wifi_direct_display_feature_supported())
1025 manager->is_wifi_display_supported = TRUE;
1027 manager->is_wifi_display_supported = FALSE;
1029 if (__is_wifi_direct_service_discovery_feature_supported())
1030 manager->is_service_discovery_supported = TRUE;
1032 manager->is_service_discovery_supported = FALSE;
1034 if (__is_asp_feature_supported())
1035 manager->is_asp_supported = TRUE;
1037 manager->is_asp_supported = FALSE;
1039 if (__is_tethering_wifi_feature_supported())
1040 manager->is_tethering_wifi_supported = TRUE;
1042 manager->is_tethering_wifi_supported = FALSE;
1044 if (__is_tethering_wifi_direct_feature_supported())
1045 manager->is_tethering_wifi_direct_supported = TRUE;
1047 manager->is_tethering_wifi_direct_supported = FALSE;
1049 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1054 int wfd_util_check_p2p_hotspot_state()
1056 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1057 int hotspot_state = 0;
1060 wfd_manager_s * manager = wfd_get_manager();
1064 if (!manager->is_tethering_wifi_direct_supported)
1067 res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_state);
1069 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
1070 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1074 if (hotspot_state & VCONFKEY_MOBILE_HOTSPOT_MODE_P2P) {
1075 WDS_LOGD("P2P Hotspot is on");
1076 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1080 WDS_LOGD("P2P Hotspot is off");
1081 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1085 int wfd_util_wifi_direct_activatable()
1087 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1089 #if defined TIZEN_TETHERING_ENABLE
1092 res_mobap = wfd_util_check_mobile_ap_state();
1093 if (res_mobap < 0) {
1094 WDS_LOGE("Failed to check Mobile AP state");
1095 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1096 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1097 } else if (res_mobap > 0) {
1098 WDS_LOGE("Mobile AP is On");
1099 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1100 return WIFI_DIRECT_ERROR_MOBILE_AP_USED;
1102 WDS_LOGE("Mobile AP is Off");
1103 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1104 return WIFI_DIRECT_ERROR_NONE;
1108 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1109 return WIFI_DIRECT_ERROR_NONE;
1113 int wfd_util_get_wifi_direct_state()
1115 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1119 res = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &state);
1121 WDS_LOGE("Failed to get vconf value [%s]\n", VCONFKEY_WIFI_DIRECT_STATE);
1122 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1126 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1131 int wfd_util_set_wifi_direct_state(int state)
1133 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1134 static int last_state = WIFI_DIRECT_STATE_DEACTIVATED;
1135 int vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATED;
1138 if (state < WIFI_DIRECT_STATE_DEACTIVATED ||
1139 state > WIFI_DIRECT_STATE_GROUP_OWNER) {
1140 WDS_LOGE("Invalid parameter");
1141 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1145 if (last_state == state) {
1146 WDS_LOGD("No change in state, not updating vconf [%s]",
1147 VCONFKEY_WIFI_DIRECT_STATE);
1148 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1152 if (state == WIFI_DIRECT_STATE_ACTIVATED)
1153 vconf_state = VCONFKEY_WIFI_DIRECT_ACTIVATED;
1154 else if (state == WIFI_DIRECT_STATE_DEACTIVATED)
1155 vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATED;
1156 else if (state == WIFI_DIRECT_STATE_CONNECTED)
1157 vconf_state = VCONFKEY_WIFI_DIRECT_CONNECTED;
1158 else if (state == WIFI_DIRECT_STATE_GROUP_OWNER)
1159 vconf_state = VCONFKEY_WIFI_DIRECT_GROUP_OWNER;
1160 else if (state == WIFI_DIRECT_STATE_DISCOVERING)
1161 vconf_state = VCONFKEY_WIFI_DIRECT_DISCOVERING;
1162 else if (state == WIFI_DIRECT_STATE_DEACTIVATING)
1163 vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATING;
1164 else if (state == WIFI_DIRECT_STATE_ACTIVATING)
1165 vconf_state = VCONFKEY_WIFI_DIRECT_ACTIVATING;
1166 else if (state == WIFI_DIRECT_STATE_CONNECTING)
1167 vconf_state = VCONFKEY_WIFI_DIRECT_CONNECTING;
1168 else if (state == WIFI_DIRECT_STATE_DISCONNECTING)
1169 vconf_state = VCONFKEY_WIFI_DIRECT_DISCONNECTING;
1171 WDS_LOGE("This state cannot be set as wifi_direct vconf state[%d]", state);
1175 WDS_LOGD("Vconf key set [%s: %d]", VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
1177 res = vconf_set_int(VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
1179 WDS_LOGE("Failed to set vconf [%s]", VCONFKEY_WIFI_DIRECT_STATE);
1180 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1186 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1190 int wfd_util_get_local_dev_mac(unsigned char *dev_mac)
1192 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1193 char file_path[MAX_FILE_PATH_LEN] = {0, };
1195 char local_mac[MACSTR_LEN] = {0, };
1198 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1199 wfd_manager_s *manager = wfd_get_manager();
1204 wfd_oem_config_s *config = manager->wfd_oem_conf;
1206 g_snprintf(file_path, sizeof(file_path),
1207 "/sys/class/net/%s/address", config->ifname);
1209 g_strlcpy(file_path, DEFAULT_MAC_FILE_PATH, sizeof(file_path));
1212 fd = fopen(file_path, "r");
1214 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1215 WDS_LOGE("Failed to open MAC info file [%s] (%s)", file_path , error_buf);
1216 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1221 ptr = fgets(local_mac, MACSTR_LEN, fd);
1223 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1224 WDS_LOGE("Failed to read file or no data read(%s)", error_buf);
1226 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1229 WDS_SECLOGD("Local MAC address [%s]", ptr);
1231 res = _txt_to_mac(local_mac, dev_mac);
1233 WDS_LOGE("Failed to convert text to MAC address");
1235 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1239 WDS_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(dev_mac));
1242 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1246 int wfd_util_start_wifi_direct_popup()
1251 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1252 #if !defined(BUILD_GTESTS)
1253 ret = __wfd_util_find_login_user(&uid);
1255 WDS_LOGE("__wfd_util_find_login_user Failed !");
1256 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1260 if (AUL_R_OK != aul_launch_app_async_for_uid(
1261 "org.tizen.wifi-direct-popup", NULL, uid)) {
1262 WDS_LOGE("aul_launch_for_uid Failed !");
1263 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1267 WDS_LOGD("Succeeded to launch wifi-direct-popup");
1268 #endif /* BUILD_GTESTS */
1269 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1273 int wfd_util_stop_wifi_direct_popup()
1278 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1279 #if !defined(BUILD_GTESTS)
1280 ret = __wfd_util_find_login_user(&uid);
1282 WDS_LOGE("__wfd_util_find_login_user Failed !");
1283 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1287 int pid = aul_app_get_pid_for_uid("org.tizen.wifi-direct-popup", uid);
1289 if (aul_terminate_pid_async_for_uid(pid, uid) != AUL_R_OK) {
1290 WDS_LOGD("Failed to destroy wifi-direct-popup pid[%d]", pid);
1291 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1294 WDS_LOGD("Succeeded to destroy wifi-direct-popup");
1297 WDS_LOGD("Wifi-direct-popup not running");
1299 #endif /* BUILD_GTESTS */
1300 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1304 int _connect_remote_device(char *ip_str)
1309 struct sockaddr_in remo_addr;
1310 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1313 sock = socket(PF_INET, SOCK_STREAM, 0);
1315 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1316 WDS_LOGE("Failed to create socket to remote device(%s)", error_buf);
1320 flags = fcntl(sock, F_GETFL, 0);
1321 res = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
1323 WDS_LOGE("File descriptor create failed");
1325 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1329 memset(&remo_addr, 0x0, sizeof(remo_addr));
1330 remo_addr.sin_family = AF_INET;
1331 remo_addr.sin_addr.s_addr = inet_addr(ip_str);
1332 remo_addr.sin_port = htons(9999);
1335 res = connect(sock, (struct sockaddr*) &remo_addr, sizeof(remo_addr));
1337 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1338 WDS_LOGE("Failed to connect to server socket [%s]", error_buf);
1340 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1344 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1345 WDS_SECLOGD("Status of connection to remote device[%s] - (%s)", ip_str, error_buf);
1353 static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
1355 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1356 wfd_device_s *peer = (wfd_device_s*) data;
1358 char buf[MAX_DHCP_DUMP_SIZE];
1359 char ip_str[IPSTR_LEN] = {0, };
1360 char intf_str[MACSTR_LEN];
1361 unsigned char intf_addr[MACADDR_LEN];
1362 char peer_mac_address[MACSTR_LEN+1] = {0,};
1363 char assigned_ip_address[IPSTR_LEN+1] = {0,};
1365 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1368 WDS_LOGD("Invalid parameter");
1371 WDS_LOGD("DHCP server: IP leased");
1374 fp = fopen(DHCP_DUMP_FILE, "r");
1376 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1377 WDS_LOGE("Could not read the file(%s). [%s]", DHCP_DUMP_FILE, error_buf);
1381 while (fgets(buf, MAX_DHCP_DUMP_SIZE, fp) != NULL) {
1382 WDS_LOGD("Read line [%s]", buf);
1383 n = sscanf(buf, "%17s %15s", intf_str, ip_str);
1384 WDS_LOGD("ip=[%s], mac=[%s]", ip_str, intf_str);
1388 _txt_to_mac(intf_str, intf_addr);
1389 if (!memcmp(peer->intf_addr, intf_addr, MACADDR_LEN)) {
1390 WDS_LOGD("Peer intf mac found");
1391 _txt_to_ip(ip_str, peer->ip_addr);
1392 _connect_remote_device(ip_str);
1393 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1394 g_snprintf(assigned_ip_address, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1395 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1397 g_variant_new("(ss)", peer_mac_address,
1398 assigned_ip_address));
1401 WDS_LOGD("Different interface address peer[" MACSECSTR "] vs dhcp[" MACSECSTR "]",
1402 MAC2SECSTR(peer->intf_addr), MAC2SECSTR(intf_addr));
1407 vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
1408 vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1410 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1414 static gboolean _polling_ip(gpointer user_data)
1416 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1417 wfd_manager_s *manager = wfd_get_manager();
1418 wfd_device_s *local = (wfd_device_s*) manager->local;
1419 wfd_device_s *peer = (wfd_device_s*) user_data;
1420 char *ifname = NULL;
1421 char ip_str[IPSTR_LEN] = {0, };
1422 static int count = 0;
1426 WDS_LOGE("peer data is not exists");
1430 res = wfd_manager_get_goup_ifname(&ifname);
1431 if (res < 0 || !ifname) {
1432 WDS_LOGE("Failed to get group interface name");
1437 WDS_LOGE("Failed to get IP");
1439 wfd_oem_destroy_group(manager->oem_ops, ifname);
1440 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1443 res = wfd_util_local_get_ip(ifname, local->ip_addr, 0);
1445 WDS_LOGE("Failed to get local IP for interface %s(count=%d)", ifname, count++);
1446 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1449 WDS_LOGD("Succeeded to get local(client) IP [" IPSECSTR "] for iface[%s]",
1450 IP2SECSTR(local->ip_addr), ifname);
1452 res = wfd_util_dhcpc_get_server_ip(peer->ip_addr);
1454 WDS_LOGE("Failed to get peer(server) IP(count=%d)", count++);
1455 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1458 WDS_LOGD("Succeeded to get server IP [" IPSECSTR "]", IP2SECSTR(peer->ip_addr));
1461 g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1462 _connect_remote_device(ip_str);
1464 char peer_mac_address[MACSTR_LEN+1] = {0, };
1466 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1467 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1469 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1470 WFD_EVENT_CONNECTION_RSP,
1473 wfd_session_s *session = manager->session;
1474 if (wfd_asp_is_asp_session(session)) {
1475 wfd_asp_connect_status(session->session_mac,
1476 session->session_id,
1477 ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
1481 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1482 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1483 wfd_destroy_session(manager);
1485 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1490 int wfd_util_dhcps_start(char *ifname)
1492 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1493 gboolean rv = FALSE;
1494 char *const iface = ifname;
1495 const char *path = "/usr/bin/wifi-direct-dhcp.sh";
1496 char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "server", iface, NULL };
1497 char *const envs[] = { NULL };
1498 wfd_manager_s *manager = wfd_get_manager();
1500 vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1502 rv = wfd_util_execute_file(path, args, envs);
1505 WDS_LOGE("Failed to start wifi-direct-dhcp.sh server");
1510 * As we are GO so IP should be updated
1511 * before sending Group Created Event
1513 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_IFNAME, GROUP_IFNAME);
1514 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_LOCAL_IP, "192.168.49.1");
1515 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_SUBNET_MASK, "255.255.255.0");
1516 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_GATEWAY, "192.168.49.1");
1518 WDS_LOGD("Successfully started wifi-direct-dhcp.sh server");
1520 _txt_to_ip(TIZEN_P2P_GO_IPADDR, manager->local->ip_addr);
1522 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1526 int wfd_util_dhcps_wait_ip_leased(wfd_device_s *peer)
1528 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1531 WDS_LOGE("Invalid parameter");
1535 vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
1536 vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1537 vconf_notify_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb, peer);
1539 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1543 int wfd_util_dhcps_stop(char *ifname)
1545 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1546 gboolean rv = FALSE;
1547 char *const iface = ifname;
1548 const char *path = "/usr/bin/wifi-direct-dhcp.sh";
1549 char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", iface, NULL };
1550 char *const envs[] = { NULL };
1552 vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
1553 vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1555 rv = wfd_util_execute_file(path, args, envs);
1558 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
1561 WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
1563 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1567 int wfd_util_dhcpc_start(char *ifname, wfd_device_s *peer)
1569 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1570 gboolean rv = FALSE;
1571 char *const iface = ifname;
1572 const char *path = "/usr/bin/wifi-direct-dhcp.sh";
1573 char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "client", iface, NULL };
1574 char *const envs[] = { NULL };
1577 WDS_LOGE("Invalid parameter");
1581 rv = wfd_util_execute_file(path, args, envs);
1583 WDS_LOGE("Failed to start wifi-direct-dhcp.sh client");
1586 WDS_LOGD("Successfully started wifi-direct-dhcp.sh client");
1588 g_timeout_add(250, (GSourceFunc) _polling_ip, peer);
1590 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1594 int wfd_util_dhcpc_stop(char *ifname)
1596 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1597 gboolean rv = FALSE;
1598 char *const iface = ifname;
1599 const char *path = "/usr/bin/wifi-direct-dhcp.sh";
1600 char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", iface, NULL };
1601 char *const envs[] = { NULL };
1603 rv = wfd_util_execute_file(path, args, envs);
1606 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
1609 WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
1611 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1615 int wfd_util_local_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6)
1617 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1619 struct sockaddr_in *sin = NULL;
1620 char *ip_str = NULL;
1623 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1625 if (!ifname || !ip_addr) {
1626 WDS_LOGE("Invalid parameter");
1627 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1632 sock = socket(AF_INET, SOCK_DGRAM, 0);
1633 if (sock < SOCK_FD_MIN) {
1634 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1635 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1638 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1642 ifr.ifr_addr.sa_family = AF_INET;
1643 memset(ifr.ifr_name, 0x00, IFNAMSIZ);
1644 g_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
1647 res = ioctl(sock, SIOCGIFADDR, &ifr);
1649 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1650 WDS_LOGE("Failed to get IP from socket. [%s]", error_buf);
1652 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1657 sin = (struct sockaddr_in*) &ifr.ifr_broadaddr;
1658 ip_str = inet_ntoa(sin->sin_addr);
1659 _txt_to_ip(ip_str, ip_addr);
1660 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1665 int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr)
1667 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1668 char* get_str = NULL;
1672 WDS_LOGE("Invalid parameter");
1673 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1677 while (count < 10) {
1678 get_str = vconf_get_str(VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1680 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1681 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1685 if (strcmp(get_str, ZEROIP) == 0) {
1686 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1688 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1692 WDS_LOGD("VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP(%s) : %s\n", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP, get_str);
1693 _txt_to_ip(get_str, ip_addr);
1700 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1705 static int _wfd_util_set_vconf_for_static_ip(const char *ifname, char *static_ip)
1707 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1709 if (!ifname || !static_ip)
1712 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_IFNAME, ifname);
1713 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_LOCAL_IP, static_ip);
1714 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_SUBNET_MASK, "255.255.255.0");
1715 vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_GATEWAY, "192.168.49.1");
1717 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1723 static int _wfd_util_static_ip_set(const char *ifname, unsigned char *static_ip)
1725 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1727 unsigned char ip_addr[IPADDR_LEN];
1728 char ip_str[IPSTR_LEN] = {0, };
1732 struct sockaddr_nl dst_addr;
1736 struct ifaddrmsg ifa;
1741 struct msghdr nl_msg;
1743 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1745 if (!ifname || !static_ip) {
1746 WDS_LOGE("Invalid parameter");
1747 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1751 /* Get index of interface */
1752 if_index = if_nametoindex(ifname);
1754 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1755 WDS_LOGE("Failed to get interface index. [%s]", error_buf);
1756 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1760 WDS_LOGD("Creating a Netlink Socket");
1761 nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1763 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1764 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1765 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1769 memset(&dst_addr, 0, sizeof(dst_addr));
1770 dst_addr.nl_family = AF_NETLINK;
1771 dst_addr.nl_pid = 0;
1773 memset(&req, 0, sizeof(req));
1774 req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1775 req.nh.nlmsg_type = RTM_NEWADDR;
1776 req.nh.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL | NLM_F_REQUEST;
1778 req.ifa.ifa_family = AF_INET;
1779 req.ifa.ifa_prefixlen = 24;
1780 req.ifa.ifa_flags = IFA_F_PERMANENT;
1781 req.ifa.ifa_scope = 0;
1782 req.ifa.ifa_index = if_index;
1784 rta = (struct rtattr *)(req.attrbuf);
1785 rta->rta_type = IFA_LOCAL;
1786 rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1787 memcpy(RTA_DATA(rta), static_ip, IPADDR_LEN);
1788 req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
1790 rta = (struct rtattr *)(req.attrbuf + rta->rta_len);
1791 rta->rta_type = IFA_BROADCAST;
1792 rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1793 memcpy(ip_addr, static_ip, IPADDR_LEN);
1795 memcpy(RTA_DATA(rta), ip_addr, IPADDR_LEN);
1796 req.nh.nlmsg_len += rta->rta_len;
1798 memset(&iov, 0, sizeof(iov));
1799 iov.iov_base = &req;
1800 iov.iov_len = req.nh.nlmsg_len;
1802 memset(&nl_msg, 0, sizeof(nl_msg));
1803 nl_msg.msg_name = (void *)&dst_addr;
1804 nl_msg.msg_namelen = sizeof(dst_addr);
1805 nl_msg.msg_iov = &iov;
1806 nl_msg.msg_iovlen = 1;
1808 res = sendmsg(nl_sock, &nl_msg, 0);
1810 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1811 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1813 WDS_LOGD("Succed to sendmsg. [%d]", res);
1817 WDS_LOGE("Succeeded to set local(client) IP [" IPSTR "] for iface[%s]",
1818 IP2STR(static_ip), ifname);
1820 snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(static_ip));
1821 _wfd_util_set_vconf_for_static_ip(ifname, ip_str);
1823 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1827 int wfd_util_ip_over_eap_assign(wfd_device_s *peer, const char *ifname)
1829 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1830 wfd_manager_s *manager = wfd_get_manager();
1831 wfd_device_s *local = (wfd_device_s*) manager->local;
1833 char ip_str[IPSTR_LEN] = {0, };
1836 WDS_LOGE("Invalid paramater");
1840 _wfd_util_static_ip_set(ifname, peer->client_ip_addr);
1841 memcpy(peer->ip_addr, peer->go_ip_addr, IPADDR_LEN);
1842 memcpy(local->ip_addr, peer->client_ip_addr, IPADDR_LEN);
1844 g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1845 _connect_remote_device(ip_str);
1847 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1852 int wfd_util_ip_unset(const char *ifname)
1854 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1856 unsigned char ip_addr[IPADDR_LEN];
1857 char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1861 struct sockaddr_nl dst_addr;
1865 struct ifaddrmsg ifa;
1870 struct msghdr nl_msg;
1873 WDS_LOGE("Invalid parameter");
1874 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1878 res = wfd_util_local_get_ip((char *)ifname, ip_addr, 0);
1880 WDS_LOGE("Failed to get local IP for interface %s", ifname);
1881 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1884 WDS_LOGE("Succeeded to get local(client) IP [" IPSTR "] for iface[%s]",
1885 IP2STR(ip_addr), ifname);
1887 if_index = if_nametoindex(ifname);
1889 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1890 WDS_LOGE("Failed to get interface index. [%s]", error_buf);
1891 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1895 WDS_LOGD("Creating a Netlink Socket");
1896 nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1898 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1899 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1900 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1904 WDS_LOGD("Set dst socket address to kernel");
1905 memset(&dst_addr, 0, sizeof(dst_addr));
1906 dst_addr.nl_family = AF_NETLINK;
1907 dst_addr.nl_pid = 0;
1909 memset(&req, 0, sizeof(req));
1910 req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1911 req.nh.nlmsg_type = RTM_DELADDR;
1912 req.nh.nlmsg_flags = NLM_F_REQUEST;
1914 req.ifa.ifa_family = AF_INET;
1915 req.ifa.ifa_prefixlen = 32;
1916 req.ifa.ifa_flags = IFA_F_PERMANENT;
1917 req.ifa.ifa_scope = 0;
1918 req.ifa.ifa_index = if_index;
1920 rta = (struct rtattr *)(req.attrbuf);
1921 rta->rta_type = IFA_LOCAL;
1922 rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1923 memcpy(RTA_DATA(rta), ip_addr, IPADDR_LEN);
1924 req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
1926 memset(&iov, 0, sizeof(iov));
1927 iov.iov_base = &req;
1928 iov.iov_len = req.nh.nlmsg_len;
1930 memset(&nl_msg, 0, sizeof(nl_msg));
1931 nl_msg.msg_name = (void *)&dst_addr;
1932 nl_msg.msg_namelen = sizeof(dst_addr);
1933 nl_msg.msg_iov = &iov;
1934 nl_msg.msg_iovlen = 1;
1936 res = sendmsg(nl_sock, &nl_msg, 0);
1938 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1939 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1941 WDS_LOGD("Succeed to sendmsg. [%d]", res);
1946 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1951 gboolean wfd_util_is_remove_group_allowed(void)
1953 wfd_manager_s *manager = wfd_get_manager();
1955 if (!manager->auto_group_remove_enable)