Fix several invalid read/write memory and definitely lost memory
[platform/core/connectivity/wifi-direct-manager.git] / src / wifi-direct-util.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 /**
21  * This file implements wifi direct utility functions.
22  *
23  * @file                wifi-direct-util.c
24  * @author      Gibyoung Kim (lastkgb.kim@samsung.com)
25  * @version     0.7
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <sys/socket.h>
34 #include <sys/ioctl.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <net/if.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <time.h>
41 #include <errno.h>
42 #include <dlfcn.h>
43 #include <sys/utsname.h>
44
45 #include <glib.h>
46
47 #include <vconf.h>
48 #include <tzplatform_config.h>
49 #include <system_info.h>
50 #include <systemd/sd-login.h>
51 #include <aul.h>
52 #include <wifi-direct.h>
53
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"
65
66 #include <linux/unistd.h>
67 #include <asm/types.h>
68 #include <linux/netlink.h>
69 #include <linux/rtnetlink.h>
70
71 #include <netlink/netlink.h>
72 #include <netlink/socket.h>
73 #include <netlink/route/neighbour.h>
74
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"
80
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"
85
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"
89
90 enum wfd_util_conf_key {
91         WFD_CONF_ON_DEMAND,
92         WFD_CONF_CONNECTION_AGENT,
93         WFD_CONF_IP_OVER_EAPOL,
94         WFD_CONF_IFACE_NAME,
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,
100         WFD_CONF_GO_INTENT,
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,
109         WFD_CONF_MAX,
110 };
111
112 struct key_value {
113         int num;
114         const char *key;
115         char *value;
116         int int_value;
117         gboolean bool_value;
118 };
119
120 static GKeyFile *__load_key_file()
121 {
122         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
123         GKeyFile *key_file = NULL;
124         GError *error = NULL;
125
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);
131                 key_file = NULL;
132         }
133
134         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
135         return key_file;
136 }
137
138
139 static void __load_wfd_config(GKeyFile **key_file, struct key_value *conf_key_val)
140 {
141         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
142         GKeyFile *result;
143         GError *error = NULL;
144         int i = 0;
145         if (!conf_key_val) {
146                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
147                 return;
148         }
149
150         result = __load_key_file();
151         if (!result) {
152                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
153                 return;
154         }
155
156         for (i = 0; i < WFD_CONF_MAX; i++) {
157
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"))) {
166
167                         conf_key_val[i].int_value = g_key_file_get_integer(result,
168                                         WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
169                         if (error) {
170                                 WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
171                                 g_clear_error(&error);
172
173                         } else {
174                         WDS_LOGD("key [%s] value [%d]\n",
175                                 conf_key_val[i].key, conf_key_val[i].int_value);
176                         }
177
178                         continue;
179                 }
180
181                 if (!g_strcmp0(conf_key_val[i].key, "persistent_reconnect") ||
182                         !g_strcmp0(conf_key_val[i].key, "no_group_iface")) {
183
184                         conf_key_val[i].bool_value = g_key_file_get_boolean(result,
185                                         WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
186                         if (error) {
187                                 WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
188                                 g_clear_error(&error);
189
190                         } else {
191                         WDS_LOGD("key [%s] value [%d]\n",
192                                 conf_key_val[i].key, conf_key_val[i].bool_value);
193                         }
194
195                         continue;
196                 }
197
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);
203
204                 } else {
205                         WDS_LOGD("key [%s] value [%s]\n",
206                                         conf_key_val[i].key, conf_key_val[i].value);
207                 }
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;
211                 }
212         }
213
214         *key_file = result;
215         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
216         return;
217 }
218
219 static void __unload_wfd_config(GKeyFile *key_file, struct key_value *conf_key_val)
220 {
221         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
222         int i = 0;
223         if (!key_file || !conf_key_val) {
224                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
225                 return;
226         }
227
228         for (i = 0; i < WFD_CONF_MAX; i++) {
229                 g_free(conf_key_val[i].value);
230         }
231
232         if (key_file)
233                 g_key_file_unref(key_file);
234         __WDS_LOG_FUNC_EXIT__;
235         return;
236 }
237
238 //LCOV_EXCL_START
239 void *wfd_util_plugin_init(wfd_manager_s *manager)
240 {
241         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
242         void *handle;
243         struct utsname kernel_info;
244         int res;
245         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
246
247         if (!manager) {
248                 WDS_LOGE("Invalid parameter");
249                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
250                 return NULL;
251         }
252
253         res = uname(&kernel_info);
254         if (res) {
255                 WDS_LOGE("Failed to detect target type");
256                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
257                 return NULL;
258         }
259         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
260
261         errno = 0;
262
263 #if defined(TIZEN_ARCH_64)
264         handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
265 #else
266         handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
267 #endif
268         if (!handle) {
269                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
270                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
271                 return NULL;
272         }
273
274         errno = 0;
275         int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
276         plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
277         if (!plugin_load) {
278                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
279                 WDS_LOGE("Failed to load symbol. Error = [%s]", error_buf);
280                 dlclose(handle);
281                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
282                 return NULL;
283         }
284
285         wfd_oem_ops_s *temp_ops;
286         (*plugin_load)(&temp_ops);
287         manager->oem_ops = temp_ops;
288
289         res = wfd_oem_init(temp_ops);
290         if (res < 0) {
291                 WDS_LOGE("Failed to initialize OEM");
292                 dlclose(handle);
293                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
294                 return NULL;
295         }
296
297         /* Configure the plugin here,
298          * using config file parameters */
299         res = wfd_oem_configure(manager->oem_ops, manager->wfd_oem_conf);
300         if (res < 0) {
301                 WDS_LOGE("Failed to configure OEM");
302                 dlclose(handle);
303                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
304                 return NULL;
305         }
306
307         WDS_LOGD("Succeeded to initialize OEM");
308
309         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
310         return handle;
311 }
312
313 int wfd_util_plugin_deinit(wfd_manager_s *manager)
314 {
315         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
316
317         if (!manager || !manager->plugin_handle) {
318                 WDS_LOGE("Invalid parameter");
319                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
320                 return -1;
321         }
322
323         dlclose(manager->plugin_handle);
324         manager->plugin_handle = NULL;
325
326         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
327         return 0;
328 }
329
330 #if defined TIZEN_ENABLE_PRD
331 void *wfd_util_prd_plugin_init(wfd_manager_s *manager)
332 {
333         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
334         void *handle;
335         struct utsname kernel_info;
336         int res;
337
338         if (!manager) {
339                 WDS_LOGE("Invalid parameter");
340                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
341                 return NULL;
342         }
343
344         res = uname(&kernel_info);
345         if (res) {
346                 WDS_LOGE("Failed to detect target type");
347                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
348                 return NULL;
349         }
350         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
351
352         errno = 0;
353
354 #if defined(TIZEN_ARCH_64)
355         handle = dlopen(SUPPL_PRD_PLUGIN_64BIT_PATH, RTLD_NOW);
356 #else
357         handle = dlopen(SUPPL_PRD_PLUGIN_PATH, RTLD_NOW);
358 #endif
359         if (!handle) {
360                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
361                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
362                 return NULL;
363         }
364
365         errno = 0;
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");
368         if (!plugin_load) {
369                 WDS_LOGE("Failed to load symbol. Error = [%s]", strerror(errno));
370                 dlclose(handle);
371                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
372                 return NULL;
373         }
374
375         (*plugin_load)((wfd_oem_ops_s **)&manager->oem_ops);
376
377         res = wfd_oem_prd_init((wfd_oem_ops_s *)manager->oem_ops);
378         if (res < 0) {
379                 WDS_LOGE("Failed to initialize PRD OEM");
380                 dlclose(handle);
381                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
382                 return NULL;
383         }
384         WDS_LOGD("Succeeded to initialize PRD OEM");
385
386         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
387         return handle;
388 }
389
390 int wfd_util_prd_plugin_deinit(wfd_manager_s *manager)
391 {
392         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
393
394         if (!manager || !manager->prd_plugin_handle) {
395                 WDS_LOGE("Invalid parameter");
396                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
397                 return -1;
398         }
399
400         dlclose(manager->prd_plugin_handle);
401         manager->prd_plugin_handle = NULL;
402
403         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
404         return 0;
405 }
406 #endif /* TIZEN_ENABLE_PRD */
407 //LCOV_EXCL_STOP
408
409 void wfd_util_load_wfd_conf(wfd_manager_s * manager)
410 {
411         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
412
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},
435         };
436
437         if (!manager) {
438                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
439                 return;
440         }
441
442         oem_conf = (wfd_oem_config_s*) manager->wfd_oem_conf;
443         if (!oem_conf) {
444                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
445                 return;
446         }
447
448         __load_wfd_config(&key_file, wfd_conf);
449
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;
453         else
454                 manager->is_on_demand = false;
455
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;
459         else
460                 manager->is_connection_agent = false;
461
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;
465         else
466                 manager->is_ip_over_eapol = false;
467
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,
471                                 IFACE_NAME_LEN+1);
472         else
473                 g_strlcpy(oem_conf->ifname, DEFAULT_IFNAME, IFACE_NAME_LEN+1);
474
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,
478                                 IFACE_NAME_LEN+1);
479         else
480                 g_strlcpy(oem_conf->p2p_ifname, DEFAULT_IFNAME, IFACE_NAME_LEN+1);
481
482
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);
487         else
488                 g_strlcpy(oem_conf->group_ifname, GROUP_IFNAME, IFACE_NAME_LEN+1);
489
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);
494         else
495                 g_strlcpy(oem_conf->device_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN+1);
496
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;
499         else
500                 oem_conf->pri_dev_type = DEFAULT_PRIMARY_DEVICE_TYPE;
501
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;
504         else
505                 oem_conf->sec_dev_type = DEFAULT_SECONDARY_DEVICE_TYPE;
506
507         if (wfd_conf[WFD_CONF_GO_INTENT].int_value > 0)
508                 oem_conf->go_intent = wfd_conf[WFD_CONF_GO_INTENT].int_value;
509         else
510                 oem_conf->go_intent = DEFAULT_GO_INTENT;
511
512         if (wfd_conf[WFD_CONF_PERSISTENT_RE].bool_value == TRUE)
513                 oem_conf->persistent_reconnect = TRUE;
514         else
515                 oem_conf->persistent_reconnect = FALSE;
516
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;
519         else
520                 oem_conf->listen_reg_class = DEFAULT_LISTEN_REG_CLASS;
521
522         if (wfd_conf[WFD_CONF_LISTEN_CHANNEL].int_value > 0)
523                 oem_conf->listen_channel = wfd_conf[WFD_CONF_LISTEN_CHANNEL].int_value;
524         else
525                 oem_conf->listen_channel = DEFAULT_LISTEN_CHANNEL;
526
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;
529         else
530                 oem_conf->operating_reg_class = DEFAULT_OPER_REG_CLASS;
531
532         if (wfd_conf[WFD_CONF_OPER_CHANNEL].int_value > 0)
533                 oem_conf->operating_channel = wfd_conf[WFD_CONF_OPER_CHANNEL].int_value;
534         else
535                 oem_conf->operating_channel = DEFAULT_OPER_CHANNEL;
536
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);
540         else
541                 g_strlcpy(oem_conf->config_methods,
542                                 DEFAULT_CONFIG_METHOD, OEM_CONFIG_METHOD_LEN+1);
543
544         if (wfd_conf[WFD_CONF_NO_GROUP_IFACE].bool_value == TRUE)
545                 oem_conf->no_group_iface = TRUE;
546         else
547                 oem_conf->no_group_iface = FALSE;
548
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;
551         else
552                 oem_conf->group_operating_freq = 0;
553
554         __unload_wfd_config(key_file, wfd_conf);
555
556         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
557         return;
558 }
559
560 static int _txt_to_mac(char *txt, unsigned char *mac)
561 {
562         int i = 0;
563
564         for (;;) {
565                 mac[i++] = (char) strtoul(txt, &txt, 16);
566                 if (i == MACADDR_LEN || !*txt++)
567                         break;
568         }
569
570         if (i != MACADDR_LEN)
571                 return -1;
572
573         WDS_LOGD("Converted MAC address [" MACSECSTR "]",
574                                         MAC2SECSTR(mac));
575         return 0;
576 }
577
578 static int _txt_to_ip(char *txt, unsigned char *ip)
579 {
580         int i = 0;
581
582         for (;;) {
583                 ip[i++] = (char) strtoul(txt, &txt, 10);
584                 if (i == IPADDR_LEN || !*txt++)
585                         break;
586         }
587
588         if (i != IPADDR_LEN)
589                 return -1;
590
591         WDS_LOGD("Converted IP address [" IPSECSTR "]", IP2SECSTR(ip));
592         return 0;
593 }
594
595 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
596 int wfd_util_get_current_time(unsigned long *cur_time)
597 {
598         struct timespec time;
599         int res;
600         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
601
602         errno = 0;
603         res = clock_gettime(CLOCK_REALTIME, &time);
604         if (!res) {
605                 WDS_LOGD("Succeeded to get current real time");
606                 *cur_time = time.tv_sec;
607                 return 0;
608         }
609         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
610         WDS_LOGE("Failed to get current real time(%s)", error_buf);
611
612         errno = 0;
613         res = clock_gettime(CLOCK_MONOTONIC, &time);
614         if (!res) {
615                 WDS_LOGD("Succeeded to get current system time");
616                 *cur_time = time.tv_sec;
617                 return 0;
618         }
619         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
620         WDS_LOGE("Failed to get current system time(%s)", error_buf);
621
622         return -1;
623 }
624 #endif
625
626 static int __wfd_util_find_login_user(uid_t *uid)
627 {
628         uid_t *uids;
629         int ret, i;
630         char *state;
631
632         ret = sd_get_uids(&uids);
633         if (ret <= 0)
634                 return -1;
635
636         for (i = 0; i < ret ; i++) {
637                 if (sd_uid_get_state(uids[i], &state) < 0) {
638                         free(uids);
639                         return -1;
640                 } else {
641                         if (!strncmp(state, "online", 6)) {
642                                 *uid = uids[i];
643                                 free(uids);
644                                 free(state);
645                                 return 0;
646                         }
647                 }
648          }
649         free(uids);
650         free(state);
651         return -1;
652 }
653
654 gboolean wfd_util_execute_file(const char *file_path,
655         char *const args[], char *const envs[])
656 {
657         pid_t pid = 0;
658         int rv = 0;
659         errno = 0;
660         register unsigned int index = 0;
661         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
662
663         while (args[index] != NULL) {
664                 WDS_LOGD("[%s]", args[index]);
665                 index++;
666         }
667
668         if (!(pid = fork())) {
669                 WDS_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
670                 WDS_LOGD("Inside child, exec (%s) command", file_path);
671
672                 errno = 0;
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);
676                         exit(1);
677                 }
678         } else if (pid > 0) {
679                 if (waitpid(pid, &rv, 0) == -1)
680                         WDS_LOGD("wait pid (%u) rv (%d)", pid, rv);
681                 if (WIFEXITED(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");
689                 return TRUE;
690         }
691
692         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
693         WDS_LOGE("failed to fork (%s)", error_buf);
694         return FALSE;
695 }
696
697 int wfd_util_channel_to_freq(int channel)
698 {
699         if (channel < 1 || channel > 161 ||
700                 (channel > 48 && channel < 149) ||
701                 (channel > 14 && channel < 36)) {
702                 WDS_LOGE("Unsupported channel[%d]", channel);
703                 return -1;
704         }
705
706         if (channel >= 36)
707                 return 5000 + 5*channel;
708         else if (channel == 14)
709                 return 2484;
710         else
711                 return 2407 + 5*channel;
712 }
713
714 int wfd_util_freq_to_channel(int freq)
715 {
716         if (freq < 2412 || freq > 5825 ||
717                 (freq > 2484 && freq < 5180)) {
718                 WDS_LOGE("Unsupported frequency[%d]", freq);
719                 return -1;
720         }
721
722         if (freq >= 5180)
723                 return 36 + (freq - 5180)/5;
724         else if (freq <= 2472)
725                 return 1 + (freq - 2412)/5;
726         else if (freq == 2484)
727                 return 14;
728         else
729                 return -1;
730 }
731
732 //LCOV_EXCL_START
733 int wfd_util_get_phone_name(char *phone_name)
734 {
735         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
736         char *name = NULL;
737
738         name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
739         if (!name) {
740                 WDS_LOGE("Failed to get vconf value for %s", VCONFKEY_SETAPPL_DEVICE_NAME_STR);
741                 return -1;
742         }
743         g_strlcpy(phone_name, name, DEV_NAME_LEN + 1);
744         WDS_LOGD("[%s: %s]", VCONFKEY_SETAPPL_DEVICE_NAME_STR, phone_name);
745         g_free(name);
746         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
747         return 0;
748 }
749
750 void _wfd_util_dev_name_changed_cb(keynode_t *key, void *data)
751 {
752         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
753         char dev_name[DEV_NAME_LEN+1] = {0, };
754         int res = 0;
755
756         res = wfd_util_get_phone_name(dev_name);
757         if (res < 0) {
758                 WDS_LOGE("Failed to get phone name(vconf)");
759                 return;
760         }
761         WDS_LOGD("Device name changed as [%s]", dev_name);
762
763         res = wfd_local_set_dev_name(dev_name);
764         if (res < 0)
765                 WDS_LOGE("Failed to set device name");
766         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
767         return;
768 }
769
770 void wfd_util_set_dev_name_notification()
771 {
772         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
773         int res = 0;
774
775         res = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb, NULL);
776         if (res) {
777                 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
778                 return;
779         }
780
781         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
782         return;
783 }
784
785 void wfd_util_unset_dev_name_notification()
786 {
787         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
788         int res = 0;
789
790         res = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb);
791         if (res) {
792                 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
793                 return;
794         }
795
796         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
797         return;
798 }
799
800 void _wfd_util_check_country_cb(keynode_t *key, void *data)
801 {
802         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
803         wfd_manager_s *manager = (wfd_manager_s*) data;
804         int res = 0;
805         int plmn = 0;
806         char mcc[4] = {0, };
807         char *ccode;
808         GKeyFile *keyfile = NULL;
809         const char *file_path = COUNTRY_CODE_FILE;
810         GError * err = NULL;
811
812         if (!manager) {
813                 WDS_LOGE("Invalid parameter");
814                 return;
815         }
816
817         res = vconf_get_int(VCONFKEY_TELEPHONY_PLMN, &plmn);
818         if (res) {
819                 WDS_LOGE("Failed to get vconf value for PLMN(%d)", res);
820                 return;
821         }
822
823         snprintf(mcc, 4, "%d", plmn);
824
825         keyfile = g_key_file_new();
826         res = g_key_file_load_from_file(keyfile, file_path, 0, &err);
827         if (!res) {
828                 WDS_LOGE("Failed to load key file(%s)", err->message);
829                 g_key_file_free(keyfile);
830                 return;
831         }
832
833         ccode = g_key_file_get_string(keyfile, "ccode_map", mcc, &err);
834         if (!ccode) {
835                 WDS_LOGE("Failed to get country code string(%s)", err->message);
836                 g_key_file_free(keyfile);
837                 return;
838         }
839
840         res = wfd_oem_set_country(manager->oem_ops, ccode);
841         if (res < 0)
842                 WDS_LOGE("Failed to set contry code");
843         else
844                 WDS_LOGD("Succeeded to set country code(%s)", ccode);
845
846         g_key_file_free(keyfile);
847         g_free(ccode);
848
849         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
850         return;
851 }
852
853 int wfd_util_check_wifi_state()
854 {
855         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
856         int wifi_state = 0;
857         int res = 0;
858
859 /* vconf key and value (vconf-keys.h)
860 #define VCONFKEY_WIFI_STATE     "memory/wifi/state"
861 enum {
862         VCONFKEY_WIFI_OFF = 0x00,
863         VCONFKEY_WIFI_UNCONNECTED,
864         VCONFKEY_WIFI_CONNECTED,
865         VCONFKEY_WIFI_TRANSFER,
866         VCONFKEY_WIFI_STATE_MAX
867 };
868 */
869         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
870         if (res < 0) {
871                 WDS_LOGE("Failed to get vconf value [%s]", VCONFKEY_WIFI_STATE);
872                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
873                 return -1;
874         }
875         WDS_LOGD("[%s: %d]", VCONFKEY_WIFI_STATE, wifi_state);
876
877         if (wifi_state > VCONFKEY_WIFI_OFF) {
878                 WDS_LOGD("Wi-Fi is on");
879                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
880                 return 1;
881         }
882         WDS_LOGD("OK. Wi-Fi is off\n");
883
884         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
885         return 0;
886 }
887
888 int wfd_util_check_mobile_ap_state()
889 {
890         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
891         int mobile_ap_state = 0;
892         int res = 0;
893
894         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobile_ap_state);
895         if (res < 0) {
896                 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
897                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
898                 return -1;
899         }
900         WDS_LOGD("[%s: %d]", VCONFKEY_MOBILE_HOTSPOT_MODE, mobile_ap_state);
901
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
906                 return 1;
907         }
908         WDS_LOGD("OK. Mobile AP is off\n");
909
910         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
911         return 0;
912 }
913
914 //LCOV_EXCL_STOP
915 int wfd_util_set_country()
916 {
917         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
918         wfd_manager_s *manager = wfd_get_manager();
919         int res = 0;
920
921         _wfd_util_check_country_cb(NULL, manager);
922
923         res = vconf_notify_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb, manager);
924         if (res) {
925                 WDS_LOGE("Failed to set vconf notification callback(TELEPHONY_PLMN)");
926                 return -1;
927         }
928
929         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
930         return 0;
931 }
932
933 int wfd_util_unset_country()
934 {
935         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
936         int res = 0;
937
938         res = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_PLMN, _wfd_util_check_country_cb);
939         if (res) {
940                 WDS_LOGE("Failed to unset vconf notification callback(TELEPHONY_PLMN)");
941                 return -1;
942         }
943
944         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
945         return 0;
946 }
947
948 static void __check_feature_supported(const char *key,
949                  bool *feature_supported)
950 {
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;
954         }
955         return;
956 }
957
958 static bool __is_wifi_direct_display_feature_supported()
959 {
960         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
961         bool supported;
962
963         __check_feature_supported(WIFI_DIRECT_DISPLAY_FEATURE, &supported);
964
965         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
966         return supported;
967 }
968
969 static bool __is_wifi_direct_service_discovery_feature_supported()
970 {
971         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
972         bool supported;
973
974         __check_feature_supported(WIFI_DIRECT_SERVICE_DISCOVERY_FEATURE, &supported);
975
976         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
977         return supported;
978 }
979
980 static bool __is_asp_feature_supported()
981 {
982         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
983         bool supported;
984
985         __check_feature_supported(ASP_FEATURE, &supported);
986
987         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
988         return supported;
989 }
990
991 static bool __is_tethering_wifi_feature_supported()
992 {
993         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
994         bool supported;
995
996         __check_feature_supported(TETHERING_WIFI_FEATURE, &supported);
997
998         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
999         return supported;
1000 }
1001
1002 static bool __is_tethering_wifi_direct_feature_supported()
1003 {
1004         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1005         bool supported;
1006
1007         __check_feature_supported(TETHERING_WIFI_DIRECT_FEATURE, &supported);
1008
1009         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1010         return supported;
1011 }
1012
1013 void wfd_util_check_features(wfd_manager_s * manager)
1014 {
1015         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1016
1017         if (!manager) {
1018                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1019                 return;
1020         }
1021
1022         manager->is_on_demand_supported = TRUE;
1023
1024         if (__is_wifi_direct_display_feature_supported())
1025                 manager->is_wifi_display_supported = TRUE;
1026         else
1027                 manager->is_wifi_display_supported = FALSE;
1028
1029         if (__is_wifi_direct_service_discovery_feature_supported())
1030                 manager->is_service_discovery_supported = TRUE;
1031         else
1032                 manager->is_service_discovery_supported = FALSE;
1033
1034         if (__is_asp_feature_supported())
1035                 manager->is_asp_supported = TRUE;
1036         else
1037                 manager->is_asp_supported = FALSE;
1038
1039         if (__is_tethering_wifi_feature_supported())
1040                 manager->is_tethering_wifi_supported = TRUE;
1041         else
1042                 manager->is_tethering_wifi_supported = FALSE;
1043
1044         if (__is_tethering_wifi_direct_feature_supported())
1045                 manager->is_tethering_wifi_direct_supported = TRUE;
1046         else
1047                 manager->is_tethering_wifi_direct_supported = FALSE;
1048
1049         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1050         return;
1051
1052 }
1053
1054 int wfd_util_check_p2p_hotspot_state()
1055 {
1056         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1057         int hotspot_state = 0;
1058         int res = 0;
1059
1060         wfd_manager_s * manager = wfd_get_manager();
1061         if (!manager)
1062                 return -1;
1063
1064         if (!manager->is_tethering_wifi_direct_supported)
1065                 return -1;
1066
1067         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_state);
1068         if (res < 0) {
1069                 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
1070                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1071                 return -1;
1072         }
1073
1074         if (hotspot_state & VCONFKEY_MOBILE_HOTSPOT_MODE_P2P) {
1075                 WDS_LOGD("P2P Hotspot is on");
1076                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1077                 return 1;
1078         }
1079
1080         WDS_LOGD("P2P Hotspot is off");
1081         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1082         return 0;
1083 }
1084
1085 int wfd_util_wifi_direct_activatable()
1086 {
1087         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1088
1089 #if defined TIZEN_TETHERING_ENABLE
1090         int res_mobap = 0;
1091
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;
1101         } else {
1102                 WDS_LOGE("Mobile AP is Off");
1103                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1104                 return WIFI_DIRECT_ERROR_NONE;
1105         }
1106 #endif
1107
1108         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1109         return WIFI_DIRECT_ERROR_NONE;
1110 }
1111
1112 #if 0
1113 int wfd_util_get_wifi_direct_state()
1114 {
1115         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1116         int state = 0;
1117         int res = 0;
1118
1119         res = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &state);
1120         if (res < 0) {
1121                 WDS_LOGE("Failed to get vconf value [%s]\n", VCONFKEY_WIFI_DIRECT_STATE);
1122                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1123                 return -1;
1124         }
1125
1126         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1127         return state;
1128 }
1129 #endif
1130
1131 int wfd_util_set_wifi_direct_state(int state)
1132 {
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;
1136         int res = 0;
1137
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
1142                 return -1;
1143         }
1144
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
1149                 return 0;
1150         }
1151
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;
1170         else {
1171                 WDS_LOGE("This state cannot be set as wifi_direct vconf state[%d]", state);
1172                 return 0;
1173         }
1174
1175         WDS_LOGD("Vconf key set [%s: %d]", VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
1176
1177         res = vconf_set_int(VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
1178         if (res < 0) {
1179                 WDS_LOGE("Failed to set vconf [%s]", VCONFKEY_WIFI_DIRECT_STATE);
1180                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1181                 return -1;
1182         }
1183
1184         last_state = state;
1185
1186         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1187         return 0;
1188 }
1189
1190 int wfd_util_get_local_dev_mac(unsigned char *dev_mac)
1191 {
1192         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1193         char file_path[MAX_FILE_PATH_LEN] = {0, };
1194         FILE *fd = NULL;
1195         char local_mac[MACSTR_LEN] = {0, };
1196         char *ptr = NULL;
1197         int res = 0;
1198         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1199         wfd_manager_s *manager = wfd_get_manager();
1200
1201         if (!manager)
1202                 return -1;
1203
1204         wfd_oem_config_s *config = manager->wfd_oem_conf;
1205         if (config)
1206                 g_snprintf(file_path, sizeof(file_path),
1207                                 "/sys/class/net/%s/address", config->ifname);
1208         else
1209                 g_strlcpy(file_path, DEFAULT_MAC_FILE_PATH, sizeof(file_path));
1210
1211         errno = 0;
1212         fd = fopen(file_path, "r");
1213         if (!fd) {
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
1217                 return -1;
1218         }
1219
1220         errno = 0;
1221         ptr = fgets(local_mac, MACSTR_LEN, fd);
1222         if (!ptr) {
1223                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1224                 WDS_LOGE("Failed to read file or no data read(%s)", error_buf);
1225                 fclose(fd);
1226                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1227                 return -1;
1228         }
1229         WDS_SECLOGD("Local MAC address [%s]", ptr);
1230
1231         res = _txt_to_mac(local_mac, dev_mac);
1232         if (res < 0) {
1233                 WDS_LOGE("Failed to convert text to MAC address");
1234                 fclose(fd);
1235                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1236                 return -1;
1237         }
1238
1239         WDS_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(dev_mac));
1240
1241         fclose(fd);
1242         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1243         return 0;
1244 }
1245
1246 int wfd_util_start_wifi_direct_popup()
1247 {
1248         uid_t uid = 0;
1249         int ret = 0;
1250
1251         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1252 #if !defined(BUILD_GTESTS)
1253         ret = __wfd_util_find_login_user(&uid);
1254         if (ret < 0) {
1255                 WDS_LOGE("__wfd_util_find_login_user Failed !");
1256                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1257                 return -1;
1258         }
1259
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
1264                 return -1;
1265         }
1266
1267         WDS_LOGD("Succeeded to launch wifi-direct-popup");
1268 #endif /* BUILD_GTESTS */
1269         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1270         return 0;
1271 }
1272
1273 int wfd_util_stop_wifi_direct_popup()
1274 {
1275         uid_t uid = 0;
1276         int ret = 0;
1277
1278         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1279 #if !defined(BUILD_GTESTS)
1280         ret = __wfd_util_find_login_user(&uid);
1281         if (ret < 0) {
1282                 WDS_LOGE("__wfd_util_find_login_user Failed !");
1283                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1284                 return -1;
1285         }
1286
1287         int pid = aul_app_get_pid_for_uid("org.tizen.wifi-direct-popup", uid);
1288         if (pid > 0) {
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
1292                         return -1;
1293                 } else {
1294                         WDS_LOGD("Succeeded to destroy wifi-direct-popup");
1295                 }
1296         } else {
1297                 WDS_LOGD("Wifi-direct-popup not running");
1298         }
1299 #endif /* BUILD_GTESTS */
1300         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1301         return 0;
1302 }
1303
1304 int _connect_remote_device(char *ip_str)
1305 {
1306         int sock;
1307         int flags;
1308         int res = 0;
1309         struct sockaddr_in remo_addr;
1310         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1311
1312         errno = 0;
1313         sock = socket(PF_INET, SOCK_STREAM, 0);
1314         if (sock == -1) {
1315                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1316                 WDS_LOGE("Failed to create socket to remote device(%s)", error_buf);
1317                 return -1;
1318         }
1319
1320         flags = fcntl(sock, F_GETFL, 0);
1321         res = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
1322         if (res < 0) {
1323                 WDS_LOGE("File descriptor create failed");
1324                 close(sock);
1325                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1326                 return -1;
1327         }
1328
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);
1333
1334         errno = 0;
1335         res = connect(sock, (struct sockaddr*) &remo_addr, sizeof(remo_addr));
1336         if (res < 0) {
1337                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1338                 WDS_LOGE("Failed to connect to server socket [%s]", error_buf);
1339                 close(sock);
1340                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1341                 return -1;
1342         }
1343
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);
1346
1347         close(sock);
1348
1349         return 0;
1350 }
1351
1352 //LCOV_EXCL_START
1353 static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
1354 {
1355         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1356         wfd_device_s *peer = (wfd_device_s*) data;
1357         FILE *fp = NULL;
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,};
1364         int n = 0;
1365         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1366
1367         if (!peer) {
1368                 WDS_LOGD("Invalid parameter");
1369                 return;
1370         }
1371         WDS_LOGD("DHCP server: IP leased");
1372
1373         errno = 0;
1374         fp = fopen(DHCP_DUMP_FILE, "r");
1375         if (NULL == fp) {
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);
1378                 return;
1379         }
1380
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);
1385                 if (n != 2)
1386                         continue;
1387
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,
1396                                                      "PeerIPAssigned",
1397                                                      g_variant_new("(ss)", peer_mac_address,
1398                                                                            assigned_ip_address));
1399                         break;
1400                 } else {
1401                         WDS_LOGD("Different interface address peer[" MACSECSTR "] vs dhcp[" MACSECSTR "]",
1402                                                 MAC2SECSTR(peer->intf_addr), MAC2SECSTR(intf_addr));
1403                 }
1404         }
1405         fclose(fp);
1406
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);
1409
1410         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1411         return;
1412 }
1413
1414 static gboolean _polling_ip(gpointer user_data)
1415 {
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;
1423         int res = 0;
1424
1425         if (!peer) {
1426                 WDS_LOGE("peer data is not exists");
1427                 return FALSE;
1428         }
1429
1430         res = wfd_manager_get_goup_ifname(&ifname);
1431         if (res < 0 || !ifname) {
1432                 WDS_LOGE("Failed to get group interface name");
1433                 return FALSE;
1434         }
1435
1436         if (count > 28) {
1437                 WDS_LOGE("Failed to get IP");
1438                 count = 0;
1439                 wfd_oem_destroy_group(manager->oem_ops, ifname);
1440                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1441                 return FALSE;
1442         }
1443         res = wfd_util_local_get_ip(ifname, local->ip_addr, 0);
1444         if (res < 0) {
1445                 WDS_LOGE("Failed to get local IP for interface %s(count=%d)", ifname, count++);
1446                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1447                 return TRUE;
1448         }
1449         WDS_LOGD("Succeeded to get local(client) IP [" IPSECSTR "] for iface[%s]",
1450                                     IP2SECSTR(local->ip_addr), ifname);
1451
1452         res = wfd_util_dhcpc_get_server_ip(peer->ip_addr);
1453         if (res < 0) {
1454                 WDS_LOGE("Failed to get peer(server) IP(count=%d)", count++);
1455                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1456                 return TRUE;
1457         }
1458         WDS_LOGD("Succeeded to get server IP [" IPSECSTR "]", IP2SECSTR(peer->ip_addr));
1459         count = 0;
1460
1461         g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1462         _connect_remote_device(ip_str);
1463
1464         char peer_mac_address[MACSTR_LEN+1] = {0, };
1465
1466         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1467         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1468                                      "Connection",
1469                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1470                                                             WFD_EVENT_CONNECTION_RSP,
1471                                                             peer_mac_address));
1472
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,
1478                                                         NULL);
1479         }
1480
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);
1484
1485         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1486         return FALSE;
1487 }
1488 //LCOV_EXCL_STOP
1489
1490 int wfd_util_dhcps_start(char *ifname)
1491 {
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();
1499
1500         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1501
1502         rv = wfd_util_execute_file(path, args, envs);
1503
1504         if (rv != TRUE) {
1505                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh server");
1506                 return -1;
1507         }
1508
1509         /*
1510          * As we are GO so IP should be updated
1511          * before sending Group Created Event
1512          */
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");
1517
1518         WDS_LOGD("Successfully started wifi-direct-dhcp.sh server");
1519
1520         _txt_to_ip(TIZEN_P2P_GO_IPADDR, manager->local->ip_addr);
1521
1522         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1523         return 0;
1524 }
1525
1526 int wfd_util_dhcps_wait_ip_leased(wfd_device_s *peer)
1527 {
1528         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1529
1530         if (!peer) {
1531                 WDS_LOGE("Invalid parameter");
1532                 return -1;
1533         }
1534
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);
1538
1539         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1540         return 0;
1541 }
1542
1543 int wfd_util_dhcps_stop(char *ifname)
1544 {
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 };
1551
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);
1554
1555         rv = wfd_util_execute_file(path, args, envs);
1556
1557         if (rv != TRUE) {
1558                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
1559                 return -1;
1560         }
1561         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
1562
1563         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1564         return 0;
1565 }
1566
1567 int wfd_util_dhcpc_start(char *ifname, wfd_device_s *peer)
1568 {
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 };
1575
1576         if (!peer) {
1577                 WDS_LOGE("Invalid parameter");
1578                 return -1;
1579         }
1580
1581         rv = wfd_util_execute_file(path, args, envs);
1582         if (rv != TRUE) {
1583                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh client");
1584                 return -1;
1585         }
1586         WDS_LOGD("Successfully started wifi-direct-dhcp.sh client");
1587
1588         g_timeout_add(250, (GSourceFunc) _polling_ip, peer);
1589
1590         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1591         return 0;
1592 }
1593
1594 int wfd_util_dhcpc_stop(char *ifname)
1595 {
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 };
1602
1603         rv = wfd_util_execute_file(path, args, envs);
1604
1605         if (rv != TRUE) {
1606                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
1607                 return -1;
1608         }
1609         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
1610
1611         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1612         return 0;
1613 }
1614
1615 int wfd_util_local_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6)
1616 {
1617         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1618         struct ifreq ifr;
1619         struct sockaddr_in *sin = NULL;
1620         char *ip_str = NULL;
1621         int sock = -1;
1622         int res = -1;
1623         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1624
1625         if (!ifname || !ip_addr) {
1626                 WDS_LOGE("Invalid parameter");
1627                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1628                 return -1;
1629         }
1630
1631         errno = 0;
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);
1636                 if (sock >= 0)
1637                         close(sock);
1638                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1639                 return -1;
1640         }
1641
1642         ifr.ifr_addr.sa_family = AF_INET;
1643         memset(ifr.ifr_name, 0x00, IFNAMSIZ);
1644         g_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
1645
1646         errno = 0;
1647         res = ioctl(sock, SIOCGIFADDR, &ifr);
1648         if (res < 0) {
1649                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1650                 WDS_LOGE("Failed to get IP from socket. [%s]", error_buf);
1651                 close(sock);
1652                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1653                 return -1;
1654         }
1655         close(sock);
1656
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
1661         return 0;
1662 }
1663
1664 //LCOV_EXCL_START
1665 int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr)
1666 {
1667         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1668         char* get_str = NULL;
1669         int count = 0;
1670
1671         if (!ip_addr) {
1672                 WDS_LOGE("Invalid parameter");
1673                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1674                 return -1;
1675         }
1676
1677         while (count < 10) {
1678                 get_str = vconf_get_str(VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1679                 if (!get_str) {
1680                         WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1681                         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1682                         return -1;
1683                 }
1684
1685                 if (strcmp(get_str, ZEROIP) == 0) {
1686                         WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1687                         g_free(get_str);
1688                         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1689                         return -1;
1690                 }
1691
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);
1694                 g_free(get_str);
1695                 if (*ip_addr)
1696                         break;
1697                 count++;
1698         }
1699
1700         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1701         return 0;
1702 }
1703 //LCOV_EXCL_STOP
1704
1705 static int _wfd_util_set_vconf_for_static_ip(const char *ifname, char *static_ip)
1706 {
1707         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1708
1709         if (!ifname || !static_ip)
1710                 return -1;
1711
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");
1716
1717         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1718
1719         return 0;
1720 }
1721
1722
1723 static int _wfd_util_static_ip_set(const char *ifname, unsigned char *static_ip)
1724 {
1725         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1726         int res = 0;
1727         unsigned char ip_addr[IPADDR_LEN];
1728         char ip_str[IPSTR_LEN] = {0, };
1729
1730         int if_index;
1731         int nl_sock = -1;
1732         struct sockaddr_nl dst_addr;
1733
1734         struct {
1735                 struct nlmsghdr     nh;
1736                 struct ifaddrmsg    ifa;
1737                 char            attrbuf[1024];
1738         } req;
1739         struct rtattr *rta;
1740         struct iovec iov;
1741         struct msghdr nl_msg;
1742
1743         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1744
1745         if (!ifname || !static_ip) {
1746                 WDS_LOGE("Invalid parameter");
1747                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1748                 return -1;
1749         }
1750
1751         /* Get index of interface */
1752         if_index = if_nametoindex(ifname);
1753         if (if_index < 0) {
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
1757                 return -1;
1758         }
1759
1760         WDS_LOGD("Creating a Netlink Socket");
1761         nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1762         if (nl_sock < 0) {
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
1766                 return -1;
1767         }
1768
1769         memset(&dst_addr, 0, sizeof(dst_addr));
1770         dst_addr.nl_family =  AF_NETLINK;
1771         dst_addr.nl_pid = 0;
1772
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;
1777
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;
1783
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;
1789
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);
1794         ip_addr[3] = 0xff;
1795         memcpy(RTA_DATA(rta), ip_addr, IPADDR_LEN);
1796         req.nh.nlmsg_len += rta->rta_len;
1797
1798         memset(&iov, 0, sizeof(iov));
1799         iov.iov_base = &req;
1800         iov.iov_len = req.nh.nlmsg_len;
1801
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;
1807
1808         res = sendmsg(nl_sock, &nl_msg, 0);
1809         if (res < 0) {
1810                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1811                 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1812         } else {
1813                 WDS_LOGD("Succed to sendmsg. [%d]", res);
1814         }
1815
1816         close(nl_sock);
1817         WDS_LOGE("Succeeded to set local(client) IP [" IPSTR "] for iface[%s]",
1818                                 IP2STR(static_ip), ifname);
1819
1820         snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(static_ip));
1821         _wfd_util_set_vconf_for_static_ip(ifname, ip_str);
1822
1823         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1824         return res;
1825 }
1826
1827 int wfd_util_ip_over_eap_assign(wfd_device_s *peer, const char *ifname)
1828 {
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;
1832
1833         char ip_str[IPSTR_LEN] = {0, };
1834
1835         if (!peer) {
1836                 WDS_LOGE("Invalid paramater");
1837                 return -1;
1838         }
1839
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);
1843
1844         g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1845         _connect_remote_device(ip_str);
1846
1847         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1848         return 0;
1849 }
1850
1851 //LCOV_EXCL_START
1852 int wfd_util_ip_unset(const char *ifname)
1853 {
1854         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1855         int res = 0;
1856         unsigned char ip_addr[IPADDR_LEN];
1857         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1858
1859         int if_index;
1860         int nl_sock = -1;
1861         struct sockaddr_nl dst_addr;
1862
1863         struct {
1864                 struct nlmsghdr     nh;
1865                 struct ifaddrmsg    ifa;
1866                 char            attrbuf[1024];
1867         } req;
1868         struct rtattr *rta;
1869         struct iovec iov;
1870         struct msghdr nl_msg;
1871
1872         if (!ifname) {
1873                 WDS_LOGE("Invalid parameter");
1874                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1875                 return -1;
1876         }
1877
1878         res = wfd_util_local_get_ip((char *)ifname, ip_addr, 0);
1879         if (res < 0) {
1880                 WDS_LOGE("Failed to get local IP for interface %s", ifname);
1881                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1882                 return -1;
1883         }
1884         WDS_LOGE("Succeeded to get local(client) IP [" IPSTR "] for iface[%s]",
1885                         IP2STR(ip_addr), ifname);
1886
1887         if_index = if_nametoindex(ifname);
1888         if (if_index < 0) {
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
1892                 return -1;
1893         }
1894
1895         WDS_LOGD("Creating a Netlink Socket");
1896         nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1897         if (nl_sock < 0) {
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
1901                 return -1;
1902         }
1903
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;
1908
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;
1913
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;
1919
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;
1925
1926         memset(&iov, 0, sizeof(iov));
1927         iov.iov_base = &req;
1928         iov.iov_len = req.nh.nlmsg_len;
1929
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;
1935
1936         res = sendmsg(nl_sock, &nl_msg, 0);
1937         if (res < 0) {
1938                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1939                 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1940         } else {
1941                 WDS_LOGD("Succeed to sendmsg. [%d]", res);
1942         }
1943
1944         close(nl_sock);
1945
1946         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1947         return res;
1948 }
1949 //LCOV_EXCL_STOP
1950
1951 gboolean wfd_util_is_remove_group_allowed(void)
1952 {
1953         wfd_manager_s *manager = wfd_get_manager();
1954
1955         if (!manager->auto_group_remove_enable)
1956                 return FALSE;
1957
1958         return TRUE;
1959 }