Fix unnecessary condition checking
[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_CONNECTION_TIMEOUT,
110         WFD_CONF_MAX,
111 };
112
113 struct key_value {
114         int num;
115         const char *key;
116         char *value;
117         int int_value;
118         gboolean bool_value;
119 };
120
121 static GKeyFile *__load_key_file()
122 {
123         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
124         GKeyFile *key_file = NULL;
125         GError *error = NULL;
126
127         key_file = g_key_file_new();
128         if (!g_key_file_load_from_file(key_file, WFD_MANGER_CONF_FILE, G_KEY_FILE_NONE, &error)) {
129                 WDS_LOGE("Unable to load %s: %s", WFD_MANGER_CONF_FILE, error->message);
130                 g_clear_error(&error);
131                 g_key_file_free(key_file);
132                 key_file = NULL;
133         }
134
135         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
136         return key_file;
137 }
138
139
140 static void __load_wfd_config(GKeyFile **key_file, struct key_value *conf_key_val)
141 {
142         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
143         GKeyFile *result;
144         GError *error = NULL;
145         int i = 0;
146         if (!conf_key_val) {
147                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
148                 return;
149         }
150
151         result = __load_key_file();
152         if (!result) {
153                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
154                 return;
155         }
156
157         for (i = 0; i < WFD_CONF_MAX; i++) {
158
159                 if ((!g_strcmp0(conf_key_val[i].key, "primary_device_type")) ||
160                         (!g_strcmp0(conf_key_val[i].key, "secondary_device_type")) ||
161                         (!g_strcmp0(conf_key_val[i].key, "go_intent")) ||
162                         (!g_strcmp0(conf_key_val[i].key, "listen_reg_class")) ||
163                         (!g_strcmp0(conf_key_val[i].key, "listen_channel")) ||
164                         (!g_strcmp0(conf_key_val[i].key, "operating_reg_class")) ||
165                         (!g_strcmp0(conf_key_val[i].key, "operating_channel")) ||
166                         (!g_strcmp0(conf_key_val[i].key, "group_operating_freq")) ||
167                         (!g_strcmp0(conf_key_val[i].key, "connection_timeout"))) {
168
169                         conf_key_val[i].int_value = g_key_file_get_integer(result,
170                                         WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
171                         if (error) {
172                                 WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
173                                 g_clear_error(&error);
174
175                         } else {
176                         WDS_LOGD("key [%s] value [%d]\n",
177                                 conf_key_val[i].key, conf_key_val[i].int_value);
178                         }
179
180                         continue;
181                 }
182
183                 if (!g_strcmp0(conf_key_val[i].key, "persistent_reconnect") ||
184                         !g_strcmp0(conf_key_val[i].key, "no_group_iface")) {
185
186                         conf_key_val[i].bool_value = g_key_file_get_boolean(result,
187                                         WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
188                         if (error) {
189                                 WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
190                                 g_clear_error(&error);
191
192                         } else {
193                         WDS_LOGD("key [%s] value [%d]\n",
194                                 conf_key_val[i].key, conf_key_val[i].bool_value);
195                         }
196
197                         continue;
198                 }
199
200                 conf_key_val[i].value = g_key_file_get_string(result,
201                                 WFD_CONF_GROUP_NAME, conf_key_val[i].key, &error);
202                 if (!conf_key_val[i].value) {
203                         WDS_LOGE("Unable to load %s : %s", conf_key_val[i].key, error->message);
204                         g_clear_error(&error);
205
206                 } else {
207                         WDS_LOGD("key [%s] value [%s]\n",
208                                         conf_key_val[i].key, conf_key_val[i].value);
209                 }
210                 if (conf_key_val[i].value && strlen(conf_key_val[i].value) == 0) {
211                         g_free(conf_key_val[i].value);
212                         conf_key_val[i].value = NULL;
213                 }
214         }
215
216         *key_file = result;
217         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
218         return;
219 }
220
221 static void __unload_wfd_config(GKeyFile *key_file, struct key_value *conf_key_val)
222 {
223         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
224         int i = 0;
225         if (!key_file || !conf_key_val) {
226                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
227                 return;
228         }
229
230         for (i = 0; i < WFD_CONF_MAX; i++) {
231                 g_free(conf_key_val[i].value);
232         }
233
234         if (key_file)
235                 g_key_file_unref(key_file);
236         __WDS_LOG_FUNC_EXIT__;
237         return;
238 }
239
240 //LCOV_EXCL_START
241 void *wfd_util_plugin_init(wfd_manager_s *manager)
242 {
243         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
244         void *handle;
245         struct utsname kernel_info;
246         int res;
247         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
248
249         if (!manager) {
250                 WDS_LOGE("Invalid parameter");
251                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
252                 return NULL;
253         }
254
255         res = uname(&kernel_info);
256         if (res) {
257                 WDS_LOGE("Failed to detect target type");
258                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
259                 return NULL;
260         }
261         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
262
263         errno = 0;
264
265 #if defined(TIZEN_ARCH_64)
266         handle = dlopen(SUPPL_PLUGIN_64BIT_PATH, RTLD_NOW);
267 #else
268         handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
269 #endif
270         if (!handle) {
271                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
272                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
273                 return NULL;
274         }
275
276         errno = 0;
277         int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
278         plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
279         if (!plugin_load) {
280                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
281                 WDS_LOGE("Failed to load symbol. Error = [%s]", error_buf);
282                 dlclose(handle);
283                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
284                 return NULL;
285         }
286
287         wfd_oem_ops_s *temp_ops;
288         (*plugin_load)(&temp_ops);
289         manager->oem_ops = temp_ops;
290
291         res = wfd_oem_init(temp_ops);
292         if (res < 0) {
293                 WDS_LOGE("Failed to initialize OEM");
294                 dlclose(handle);
295                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
296                 return NULL;
297         }
298
299         /* Configure the plugin here,
300          * using config file parameters */
301         res = wfd_oem_configure(manager->oem_ops, manager->wfd_oem_conf);
302         if (res < 0) {
303                 WDS_LOGE("Failed to configure OEM");
304                 dlclose(handle);
305                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
306                 return NULL;
307         }
308
309         WDS_LOGD("Succeeded to initialize OEM");
310
311         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
312         return handle;
313 }
314
315 int wfd_util_plugin_deinit(wfd_manager_s *manager)
316 {
317         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
318
319         if (!manager || !manager->plugin_handle) {
320                 WDS_LOGE("Invalid parameter");
321                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
322                 return -1;
323         }
324
325         dlclose(manager->plugin_handle);
326         manager->plugin_handle = NULL;
327
328         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
329         return 0;
330 }
331
332 #if defined TIZEN_ENABLE_PRD
333 void *wfd_util_prd_plugin_init(wfd_manager_s *manager)
334 {
335         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
336         void *handle;
337         struct utsname kernel_info;
338         int res;
339
340         if (!manager) {
341                 WDS_LOGE("Invalid parameter");
342                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
343                 return NULL;
344         }
345
346         res = uname(&kernel_info);
347         if (res) {
348                 WDS_LOGE("Failed to detect target type");
349                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
350                 return NULL;
351         }
352         WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
353
354         errno = 0;
355
356 #if defined(TIZEN_ARCH_64)
357         handle = dlopen(SUPPL_PRD_PLUGIN_64BIT_PATH, RTLD_NOW);
358 #else
359         handle = dlopen(SUPPL_PRD_PLUGIN_PATH, RTLD_NOW);
360 #endif
361         if (!handle) {
362                 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
363                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
364                 return NULL;
365         }
366
367         errno = 0;
368         int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
369         plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_prd_plugin_load");
370         if (!plugin_load) {
371                 WDS_LOGE("Failed to load symbol. Error = [%s]", strerror(errno));
372                 dlclose(handle);
373                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
374                 return NULL;
375         }
376
377         (*plugin_load)((wfd_oem_ops_s **)&manager->oem_ops);
378
379         res = wfd_oem_prd_init((wfd_oem_ops_s *)manager->oem_ops);
380         if (res < 0) {
381                 WDS_LOGE("Failed to initialize PRD OEM");
382                 dlclose(handle);
383                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
384                 return NULL;
385         }
386         WDS_LOGD("Succeeded to initialize PRD OEM");
387
388         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
389         return handle;
390 }
391
392 int wfd_util_prd_plugin_deinit(wfd_manager_s *manager)
393 {
394         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
395
396         if (!manager || !manager->prd_plugin_handle) {
397                 WDS_LOGE("Invalid parameter");
398                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
399                 return -1;
400         }
401
402         dlclose(manager->prd_plugin_handle);
403         manager->prd_plugin_handle = NULL;
404
405         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
406         return 0;
407 }
408 #endif /* TIZEN_ENABLE_PRD */
409 //LCOV_EXCL_STOP
410
411 void wfd_util_load_wfd_conf(wfd_manager_s * manager)
412 {
413         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
414
415         GKeyFile *key_file = NULL;
416         wfd_oem_config_s *oem_conf = NULL;
417         struct key_value wfd_conf[] = {
418                 {WFD_CONF_ON_DEMAND, "on_demand", NULL, 0, FALSE},
419                 {WFD_CONF_CONNECTION_AGENT, "connection_agent", NULL, 0, FALSE},
420                 {WFD_CONF_IP_OVER_EAPOL, "ip_over_eapol", NULL, 0, FALSE},
421                 {WFD_CONF_IFACE_NAME, "interface", NULL, 0, FALSE},
422                 {WFD_CONF_P2P_IFACE_NAME, "p2p_interface", NULL, 0, FALSE},
423                 {WFD_CONF_GROUP_IFACE_NAME, "group_interface", NULL, 0, FALSE},
424                 {WFD_CONF_DEFAULT_DEVICE_NAME, "device_name", NULL, 0, FALSE},
425                 {WFD_CONF_PRIMARY_DEVICE_TYPE, "primary_device_type", NULL, 0, FALSE},
426                 {WFD_CONF_SECONDARY_DEVICE_TYPE, "secondary_device_type", NULL, 0, FALSE},
427                 {WFD_CONF_GO_INTENT, "go_intent", NULL, 0, FALSE},
428                 {WFD_CONF_PERSISTENT_RE, "persistent_reconnect", NULL, 0, FALSE},
429                 {WFD_CONF_LISTEN_REG_CLASS, "listen_reg_class", NULL, 0, FALSE},
430                 {WFD_CONF_LISTEN_CHANNEL, "listen_channel", NULL, 0, FALSE},
431                 {WFD_CONF_OPER_REG_CLASS, "operating_reg_class", NULL, 0, FALSE},
432                 {WFD_CONF_OPER_CHANNEL, "operating_channel", NULL, 0, FALSE},
433                 {WFD_CONF_CONFIG_METHOD, "config_methods", NULL, 0, FALSE},
434                 {WFD_CONF_NO_GROUP_IFACE, "no_group_iface", NULL, 0, FALSE},
435                 {WFD_CONF_GROUP_OPER_FREQ, "group_operating_freq", NULL, 0, FALSE},
436                 {WFD_CONF_CONNECTION_TIMEOUT, "connection_timeout", NULL, 0, FALSE},
437                 {WFD_CONF_MAX, NULL, NULL, 0, FALSE},
438         };
439
440         if (!manager) {
441                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
442                 return;
443         }
444
445         oem_conf = (wfd_oem_config_s*) manager->wfd_oem_conf;
446         if (!oem_conf) {
447                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
448                 return;
449         }
450
451         __load_wfd_config(&key_file, wfd_conf);
452
453         if (wfd_conf[WFD_CONF_ON_DEMAND].value &&
454                         g_strcmp0(wfd_conf[WFD_CONF_ON_DEMAND].value, "yes") == 0)
455                 manager->is_on_demand = true;
456         else
457                 manager->is_on_demand = false;
458
459         if (wfd_conf[WFD_CONF_CONNECTION_AGENT].value &&
460                         g_strcmp0(wfd_conf[WFD_CONF_CONNECTION_AGENT].value, "yes") == 0)
461                 manager->is_connection_agent = true;
462         else
463                 manager->is_connection_agent = false;
464
465         if (wfd_conf[WFD_CONF_IP_OVER_EAPOL].value &&
466                         g_strcmp0(wfd_conf[WFD_CONF_IP_OVER_EAPOL].value, "yes") == 0)
467                 manager->is_ip_over_eapol = true;
468         else
469                 manager->is_ip_over_eapol = false;
470
471         if (wfd_conf[WFD_CONF_IFACE_NAME].value &&
472                         strlen(wfd_conf[WFD_CONF_IFACE_NAME].value) > 0)
473                 g_strlcpy(oem_conf->ifname, wfd_conf[WFD_CONF_IFACE_NAME].value,
474                                 IFACE_NAME_LEN+1);
475         else
476                 g_strlcpy(oem_conf->ifname, DEFAULT_IFNAME, IFACE_NAME_LEN+1);
477
478         if (wfd_conf[WFD_CONF_P2P_IFACE_NAME].value &&
479                         strlen(wfd_conf[WFD_CONF_P2P_IFACE_NAME].value) > 0)
480                 g_strlcpy(oem_conf->p2p_ifname, wfd_conf[WFD_CONF_P2P_IFACE_NAME].value,
481                                 IFACE_NAME_LEN+1);
482         else
483                 g_strlcpy(oem_conf->p2p_ifname, DEFAULT_IFNAME, IFACE_NAME_LEN+1);
484
485
486         if (wfd_conf[WFD_CONF_GROUP_IFACE_NAME].value &&
487                         strlen(wfd_conf[WFD_CONF_GROUP_IFACE_NAME].value) > 0)
488                 g_strlcpy(oem_conf->group_ifname,
489                                 wfd_conf[WFD_CONF_GROUP_IFACE_NAME].value, IFACE_NAME_LEN+1);
490         else
491                 g_strlcpy(oem_conf->group_ifname, GROUP_IFNAME, IFACE_NAME_LEN+1);
492
493         if (wfd_conf[WFD_CONF_DEFAULT_DEVICE_NAME].value &&
494                         strlen(wfd_conf[WFD_CONF_DEFAULT_DEVICE_NAME].value) > 0)
495                 g_strlcpy(oem_conf->device_name,
496                                 wfd_conf[WFD_CONF_DEFAULT_DEVICE_NAME].value, DEV_NAME_LEN+1);
497         else
498                 g_strlcpy(oem_conf->device_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN+1);
499
500         if (wfd_conf[WFD_CONF_PRIMARY_DEVICE_TYPE].int_value > 0)
501                 oem_conf->pri_dev_type = wfd_conf[WFD_CONF_PRIMARY_DEVICE_TYPE].int_value;
502         else
503                 oem_conf->pri_dev_type = DEFAULT_PRIMARY_DEVICE_TYPE;
504
505         if (wfd_conf[WFD_CONF_SECONDARY_DEVICE_TYPE].int_value > 0)
506                 oem_conf->sec_dev_type = wfd_conf[WFD_CONF_SECONDARY_DEVICE_TYPE].int_value;
507         else
508                 oem_conf->sec_dev_type = DEFAULT_SECONDARY_DEVICE_TYPE;
509
510         if (wfd_conf[WFD_CONF_GO_INTENT].int_value > 0)
511                 oem_conf->go_intent = wfd_conf[WFD_CONF_GO_INTENT].int_value;
512         else
513                 oem_conf->go_intent = DEFAULT_GO_INTENT;
514
515         if (wfd_conf[WFD_CONF_PERSISTENT_RE].bool_value == TRUE)
516                 oem_conf->persistent_reconnect = TRUE;
517         else
518                 oem_conf->persistent_reconnect = FALSE;
519
520         if (wfd_conf[WFD_CONF_LISTEN_REG_CLASS].int_value > 0)
521                 oem_conf->listen_reg_class = wfd_conf[WFD_CONF_LISTEN_REG_CLASS].int_value;
522         else
523                 oem_conf->listen_reg_class = DEFAULT_LISTEN_REG_CLASS;
524
525         if (wfd_conf[WFD_CONF_LISTEN_CHANNEL].int_value > 0)
526                 oem_conf->listen_channel = wfd_conf[WFD_CONF_LISTEN_CHANNEL].int_value;
527         else
528                 oem_conf->listen_channel = DEFAULT_LISTEN_CHANNEL;
529
530         if (wfd_conf[WFD_CONF_OPER_REG_CLASS].int_value > 0)
531                 oem_conf->operating_reg_class = wfd_conf[WFD_CONF_OPER_REG_CLASS].int_value;
532         else
533                 oem_conf->operating_reg_class = DEFAULT_OPER_REG_CLASS;
534
535         if (wfd_conf[WFD_CONF_OPER_CHANNEL].int_value > 0)
536                 oem_conf->operating_channel = wfd_conf[WFD_CONF_OPER_CHANNEL].int_value;
537         else
538                 oem_conf->operating_channel = DEFAULT_OPER_CHANNEL;
539
540         if (wfd_conf[WFD_CONF_CONFIG_METHOD].value)
541                 g_strlcpy(oem_conf->config_methods,
542                                 wfd_conf[WFD_CONF_CONFIG_METHOD].value, OEM_CONFIG_METHOD_LEN+1);
543         else
544                 g_strlcpy(oem_conf->config_methods,
545                                 DEFAULT_CONFIG_METHOD, OEM_CONFIG_METHOD_LEN+1);
546
547         if (wfd_conf[WFD_CONF_NO_GROUP_IFACE].bool_value == TRUE)
548                 oem_conf->no_group_iface = TRUE;
549         else
550                 oem_conf->no_group_iface = FALSE;
551
552         if (wfd_conf[WFD_CONF_GROUP_OPER_FREQ].int_value > 0)
553                 oem_conf->group_operating_freq = wfd_conf[WFD_CONF_GROUP_OPER_FREQ].int_value;
554         else
555                 oem_conf->group_operating_freq = 0;
556
557         if (wfd_conf[WFD_CONF_CONNECTION_TIMEOUT].int_value > 0)
558                 manager->connection_timeout = wfd_conf[WFD_CONF_CONNECTION_TIMEOUT].int_value;
559         else
560                 manager->connection_timeout = DEFAULT_CONNECTION_TIMEOUT;
561
562         __unload_wfd_config(key_file, wfd_conf);
563
564         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
565         return;
566 }
567
568 static int _txt_to_mac(char *txt, unsigned char *mac)
569 {
570         int i = 0;
571
572         for (;;) {
573                 mac[i++] = (char) strtoul(txt, &txt, 16);
574                 if (i == MACADDR_LEN || !*txt++)
575                         break;
576         }
577
578         if (i != MACADDR_LEN)
579                 return -1;
580
581         WDS_LOGD("Converted MAC address [" MACSECSTR "]",
582                                         MAC2SECSTR(mac));
583         return 0;
584 }
585
586 static int _txt_to_ip(char *txt, unsigned char *ip)
587 {
588         int i = 0;
589
590         for (;;) {
591                 ip[i++] = (char) strtoul(txt, &txt, 10);
592                 if (i == IPADDR_LEN || !*txt++)
593                         break;
594         }
595
596         if (i != IPADDR_LEN)
597                 return -1;
598
599         WDS_LOGD("Converted IP address [" IPSECSTR "]", IP2SECSTR(ip));
600         return 0;
601 }
602
603 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
604 int wfd_util_get_current_time(unsigned long *cur_time)
605 {
606         struct timespec time;
607         int res;
608         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
609
610         errno = 0;
611         res = clock_gettime(CLOCK_REALTIME, &time);
612         if (!res) {
613                 WDS_LOGD("Succeeded to get current real time");
614                 *cur_time = time.tv_sec;
615                 return 0;
616         }
617         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
618         WDS_LOGE("Failed to get current real time(%s)", error_buf);
619
620         errno = 0;
621         res = clock_gettime(CLOCK_MONOTONIC, &time);
622         if (!res) {
623                 WDS_LOGD("Succeeded to get current system time");
624                 *cur_time = time.tv_sec;
625                 return 0;
626         }
627         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
628         WDS_LOGE("Failed to get current system time(%s)", error_buf);
629
630         return -1;
631 }
632 #endif
633
634 static int __wfd_util_find_login_user(uid_t *uid)
635 {
636         uid_t *uids;
637         int ret, i;
638         char *state;
639
640         ret = sd_get_uids(&uids);
641         if (ret <= 0)
642                 return -1;
643
644         for (i = 0; i < ret ; i++) {
645                 if (sd_uid_get_state(uids[i], &state) < 0) {
646                         free(uids);
647                         return -1;
648                 } else {
649                         if (!strncmp(state, "online", 6)) {
650                                 *uid = uids[i];
651                                 free(uids);
652                                 free(state);
653                                 return 0;
654                         }
655                 }
656          }
657         free(uids);
658         free(state);
659         return -1;
660 }
661
662 gboolean wfd_util_execute_file(const char *file_path,
663         char *const args[], char *const envs[])
664 {
665         pid_t pid = 0;
666         int rv = 0;
667         errno = 0;
668         register unsigned int index = 0;
669         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
670
671         while (args[index] != NULL) {
672                 WDS_LOGD("[%s]", args[index]);
673                 index++;
674         }
675
676         if (!(pid = fork())) {
677                 WDS_LOGD("pid(%d), ppid(%d)", getpid(), getppid());
678                 WDS_LOGD("Inside child, exec (%s) command", file_path);
679
680                 errno = 0;
681                 if (execve(file_path, args, envs) == -1) {
682                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
683                         WDS_LOGE("Fail to execute command (%s)", error_buf);
684                         exit(1);
685                 }
686         } else if (pid > 0) {
687                 if (waitpid(pid, &rv, 0) == -1)
688                         WDS_LOGD("wait pid (%u) rv (%d)", pid, rv);
689                 if (WIFEXITED(rv))
690                         WDS_LOGD("exited, rv=%d", WEXITSTATUS(rv));
691                 else if (WIFSIGNALED(rv))
692                         WDS_LOGD("killed by signal %d", WTERMSIG(rv));
693                 else if (WIFSTOPPED(rv))
694                         WDS_LOGD("stopped by signal %d", WSTOPSIG(rv));
695                 else if (WIFCONTINUED(rv))
696                         WDS_LOGD("continued");
697                 return TRUE;
698         }
699
700         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
701         WDS_LOGE("failed to fork (%s)", error_buf);
702         return FALSE;
703 }
704
705 int wfd_util_channel_to_freq(int channel)
706 {
707         if (channel < 1 || channel > 161 ||
708                 (channel > 48 && channel < 149) ||
709                 (channel > 14 && channel < 36)) {
710                 WDS_LOGE("Unsupported channel[%d]", channel);
711                 return -1;
712         }
713
714         if (channel >= 36)
715                 return 5000 + 5*channel;
716         else if (channel == 14)
717                 return 2484;
718         else
719                 return 2407 + 5*channel;
720 }
721
722 int wfd_util_freq_to_channel(int freq)
723 {
724         if (freq < 2412 || freq > 5825 ||
725                 (freq > 2484 && freq < 5180)) {
726                 WDS_LOGE("Unsupported frequency[%d]", freq);
727                 return -1;
728         }
729
730         if (freq >= 5180)
731                 return 36 + (freq - 5180)/5;
732         else if (freq <= 2472)
733                 return 1 + (freq - 2412)/5;
734         else if (freq == 2484)
735                 return 14;
736         else
737                 return -1;
738 }
739
740 //LCOV_EXCL_START
741 int wfd_util_get_phone_name(char *phone_name)
742 {
743         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
744         char *name = NULL;
745
746         name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
747         if (!name) {
748                 WDS_LOGE("Failed to get vconf value for %s", VCONFKEY_SETAPPL_DEVICE_NAME_STR);
749                 return -1;
750         }
751         g_strlcpy(phone_name, name, DEV_NAME_LEN + 1);
752         WDS_LOGD("[%s: %s]", VCONFKEY_SETAPPL_DEVICE_NAME_STR, phone_name);
753         g_free(name);
754         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
755         return 0;
756 }
757
758 void _wfd_util_dev_name_changed_cb(keynode_t *key, void *data)
759 {
760         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
761         char dev_name[DEV_NAME_LEN+1] = {0, };
762         int res = 0;
763
764         res = wfd_util_get_phone_name(dev_name);
765         if (res < 0) {
766                 WDS_LOGE("Failed to get phone name(vconf)");
767                 return;
768         }
769         WDS_LOGD("Device name changed as [%s]", dev_name);
770
771         res = wfd_local_set_dev_name(dev_name);
772         if (res < 0)
773                 WDS_LOGE("Failed to set device name");
774         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
775         return;
776 }
777
778 void wfd_util_set_dev_name_notification()
779 {
780         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
781         int res = 0;
782
783         res = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb, NULL);
784         if (res) {
785                 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
786                 return;
787         }
788
789         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
790         return;
791 }
792
793 void wfd_util_unset_dev_name_notification()
794 {
795         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
796         int res = 0;
797
798         res = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR, _wfd_util_dev_name_changed_cb);
799         if (res) {
800                 WDS_LOGE("Failed to set vconf notification callback(SETAPPL_DEVICE_NAME_STR)");
801                 return;
802         }
803
804         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
805         return;
806 }
807
808 int wfd_util_check_wifi_state()
809 {
810         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
811         int wifi_state = 0;
812         int res = 0;
813
814 /* vconf key and value (vconf-keys.h)
815 #define VCONFKEY_WIFI_STATE     "memory/wifi/state"
816 enum {
817         VCONFKEY_WIFI_OFF = 0x00,
818         VCONFKEY_WIFI_UNCONNECTED,
819         VCONFKEY_WIFI_CONNECTED,
820         VCONFKEY_WIFI_TRANSFER,
821         VCONFKEY_WIFI_STATE_MAX
822 };
823 */
824         res = vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
825         if (res < 0) {
826                 WDS_LOGE("Failed to get vconf value [%s]", VCONFKEY_WIFI_STATE);
827                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
828                 return -1;
829         }
830         WDS_LOGD("[%s: %d]", VCONFKEY_WIFI_STATE, wifi_state);
831
832         if (wifi_state > VCONFKEY_WIFI_OFF) {
833                 WDS_LOGD("Wi-Fi is on");
834                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
835                 return 1;
836         }
837         WDS_LOGD("OK. Wi-Fi is off\n");
838
839         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
840         return 0;
841 }
842
843 int wfd_util_check_mobile_ap_state()
844 {
845         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
846         int mobile_ap_state = 0;
847         int res = 0;
848
849         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobile_ap_state);
850         if (res < 0) {
851                 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
852                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
853                 return -1;
854         }
855         WDS_LOGD("[%s: %d]", VCONFKEY_MOBILE_HOTSPOT_MODE, mobile_ap_state);
856
857         if ((mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)
858                 || (mobile_ap_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP)) {
859                 WDS_LOGD("Mobile AP is on");
860                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
861                 return 1;
862         }
863         WDS_LOGD("OK. Mobile AP is off\n");
864
865         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
866         return 0;
867 }
868
869 //LCOV_EXCL_STOP
870
871 static void __check_feature_supported(const char *key,
872                  bool *feature_supported)
873 {
874         if (system_info_get_platform_bool(key, feature_supported) < 0) {
875                 WDS_LOGE("system-info failed to get feature supported flag");
876                 *feature_supported = false;
877         }
878         return;
879 }
880
881 static bool __is_wifi_direct_display_feature_supported()
882 {
883         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
884         bool supported;
885
886         __check_feature_supported(WIFI_DIRECT_DISPLAY_FEATURE, &supported);
887
888         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
889         return supported;
890 }
891
892 static bool __is_wifi_direct_service_discovery_feature_supported()
893 {
894         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
895         bool supported;
896
897         __check_feature_supported(WIFI_DIRECT_SERVICE_DISCOVERY_FEATURE, &supported);
898
899         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
900         return supported;
901 }
902
903 static bool __is_asp_feature_supported()
904 {
905         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
906         bool supported;
907
908         __check_feature_supported(ASP_FEATURE, &supported);
909
910         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
911         return supported;
912 }
913
914 static bool __is_tethering_wifi_feature_supported()
915 {
916         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
917         bool supported;
918
919         __check_feature_supported(TETHERING_WIFI_FEATURE, &supported);
920
921         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
922         return supported;
923 }
924
925 static bool __is_tethering_wifi_direct_feature_supported()
926 {
927         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
928         bool supported;
929
930         __check_feature_supported(TETHERING_WIFI_DIRECT_FEATURE, &supported);
931
932         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
933         return supported;
934 }
935
936 void wfd_util_check_features(wfd_manager_s * manager)
937 {
938         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
939
940         if (!manager) {
941                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
942                 return;
943         }
944
945         manager->is_on_demand_supported = TRUE;
946
947         if (__is_wifi_direct_display_feature_supported())
948                 manager->is_wifi_display_supported = TRUE;
949         else
950                 manager->is_wifi_display_supported = FALSE;
951
952         if (__is_wifi_direct_service_discovery_feature_supported())
953                 manager->is_service_discovery_supported = TRUE;
954         else
955                 manager->is_service_discovery_supported = FALSE;
956
957         if (__is_asp_feature_supported())
958                 manager->is_asp_supported = TRUE;
959         else
960                 manager->is_asp_supported = FALSE;
961
962         if (__is_tethering_wifi_feature_supported())
963                 manager->is_tethering_wifi_supported = TRUE;
964         else
965                 manager->is_tethering_wifi_supported = FALSE;
966
967         if (__is_tethering_wifi_direct_feature_supported())
968                 manager->is_tethering_wifi_direct_supported = TRUE;
969         else
970                 manager->is_tethering_wifi_direct_supported = FALSE;
971
972         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
973         return;
974
975 }
976
977 int wfd_util_check_p2p_hotspot_state()
978 {
979         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
980         int hotspot_state = 0;
981         int res = 0;
982
983         wfd_manager_s * manager = wfd_get_manager();
984         if (!manager)
985                 return -1;
986
987         if (!manager->is_tethering_wifi_direct_supported)
988                 return -1;
989
990         res = vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &hotspot_state);
991         if (res < 0) {
992                 WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_MOBILE_HOTSPOT_MODE);
993                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
994                 return -1;
995         }
996
997         if (hotspot_state & VCONFKEY_MOBILE_HOTSPOT_MODE_P2P) {
998                 WDS_LOGD("P2P Hotspot is on");
999                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1000                 return 1;
1001         }
1002
1003         WDS_LOGD("P2P Hotspot is off");
1004         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1005         return 0;
1006 }
1007
1008 int wfd_util_wifi_direct_activatable()
1009 {
1010         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1011
1012 #if defined TIZEN_TETHERING_ENABLE
1013         int res_mobap = 0;
1014
1015         res_mobap = wfd_util_check_mobile_ap_state();
1016         if (res_mobap < 0) {
1017                 WDS_LOGE("Failed to check Mobile AP state");
1018                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1019                 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
1020         } else if (res_mobap > 0) {
1021                 WDS_LOGE("Mobile AP is On");
1022                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1023                 return WIFI_DIRECT_ERROR_MOBILE_AP_USED;
1024         } else {
1025                 WDS_LOGE("Mobile AP is Off");
1026                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1027                 return WIFI_DIRECT_ERROR_NONE;
1028         }
1029 #endif
1030
1031         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1032         return WIFI_DIRECT_ERROR_NONE;
1033 }
1034
1035 #if 0
1036 int wfd_util_get_wifi_direct_state()
1037 {
1038         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1039         int state = 0;
1040         int res = 0;
1041
1042         res = vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &state);
1043         if (res < 0) {
1044                 WDS_LOGE("Failed to get vconf value [%s]\n", VCONFKEY_WIFI_DIRECT_STATE);
1045                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1046                 return -1;
1047         }
1048
1049         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1050         return state;
1051 }
1052 #endif
1053
1054 int wfd_util_set_wifi_direct_state(int state)
1055 {
1056         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1057         static int last_state = WIFI_DIRECT_STATE_DEACTIVATED;
1058         int vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATED;
1059         int res = 0;
1060
1061         if (state < WIFI_DIRECT_STATE_DEACTIVATED ||
1062             state > WIFI_DIRECT_STATE_GROUP_OWNER) {
1063                 WDS_LOGE("Invalid parameter");
1064                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1065                 return -1;
1066         }
1067
1068         if (last_state == state) {
1069                 WDS_LOGD("No change in state, not updating vconf [%s]",
1070                          VCONFKEY_WIFI_DIRECT_STATE);
1071                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1072                 return 0;
1073         }
1074
1075         if (state == WIFI_DIRECT_STATE_ACTIVATED)
1076                 vconf_state = VCONFKEY_WIFI_DIRECT_ACTIVATED;
1077         else if (state == WIFI_DIRECT_STATE_DEACTIVATED)
1078                 vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATED;
1079         else if (state == WIFI_DIRECT_STATE_CONNECTED)
1080                 vconf_state = VCONFKEY_WIFI_DIRECT_CONNECTED;
1081         else if (state == WIFI_DIRECT_STATE_GROUP_OWNER)
1082                 vconf_state = VCONFKEY_WIFI_DIRECT_GROUP_OWNER;
1083         else if (state == WIFI_DIRECT_STATE_DISCOVERING)
1084                 vconf_state = VCONFKEY_WIFI_DIRECT_DISCOVERING;
1085         else if (state == WIFI_DIRECT_STATE_DEACTIVATING)
1086                 vconf_state = VCONFKEY_WIFI_DIRECT_DEACTIVATING;
1087         else if (state == WIFI_DIRECT_STATE_ACTIVATING)
1088                 vconf_state = VCONFKEY_WIFI_DIRECT_ACTIVATING;
1089         else if (state == WIFI_DIRECT_STATE_CONNECTING)
1090                 vconf_state = VCONFKEY_WIFI_DIRECT_CONNECTING;
1091         else if (state == WIFI_DIRECT_STATE_DISCONNECTING)
1092                 vconf_state = VCONFKEY_WIFI_DIRECT_DISCONNECTING;
1093         else {
1094                 WDS_LOGE("This state cannot be set as wifi_direct vconf state[%d]", state);
1095                 return 0;
1096         }
1097
1098         WDS_LOGD("Vconf key set [%s: %d]", VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
1099
1100         res = vconf_set_int(VCONFKEY_WIFI_DIRECT_STATE, vconf_state);
1101         if (res < 0) {
1102                 WDS_LOGE("Failed to set vconf [%s]", VCONFKEY_WIFI_DIRECT_STATE);
1103                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1104                 return -1;
1105         }
1106
1107         last_state = state;
1108
1109         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1110         return 0;
1111 }
1112
1113 int wfd_util_get_local_dev_mac(unsigned char *dev_mac)
1114 {
1115         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1116         char file_path[MAX_FILE_PATH_LEN] = {0, };
1117         FILE *fd = NULL;
1118         char local_mac[MACSTR_LEN] = {0, };
1119         char *ptr = NULL;
1120         int res = 0;
1121         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1122         wfd_manager_s *manager = wfd_get_manager();
1123
1124         if (!manager)
1125                 return -1;
1126
1127         wfd_oem_config_s *config = manager->wfd_oem_conf;
1128         if (config)
1129                 g_snprintf(file_path, sizeof(file_path),
1130                                 "/sys/class/net/%s/address", config->ifname);
1131         else
1132                 g_strlcpy(file_path, DEFAULT_MAC_FILE_PATH, sizeof(file_path));
1133
1134         errno = 0;
1135         fd = fopen(file_path, "r");
1136         if (!fd) {
1137                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1138                 WDS_LOGE("Failed to open MAC info file [%s] (%s)", file_path , error_buf);
1139                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1140                 return -1;
1141         }
1142
1143         errno = 0;
1144         ptr = fgets(local_mac, MACSTR_LEN, fd);
1145         if (!ptr) {
1146                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1147                 WDS_LOGE("Failed to read file or no data read(%s)", error_buf);
1148                 fclose(fd);
1149                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1150                 return -1;
1151         }
1152         WDS_SECLOGD("Local MAC address [%s]", ptr);
1153
1154         res = _txt_to_mac(local_mac, dev_mac);
1155         if (res < 0) {
1156                 WDS_LOGE("Failed to convert text to MAC address");
1157                 fclose(fd);
1158                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1159                 return -1;
1160         }
1161
1162         WDS_LOGD("Local Device MAC address [" MACSECSTR "]", MAC2SECSTR(dev_mac));
1163
1164         fclose(fd);
1165         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1166         return 0;
1167 }
1168
1169 int wfd_util_start_wifi_direct_popup()
1170 {
1171         uid_t uid = 0;
1172         int ret = 0;
1173
1174         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1175 #if !defined(BUILD_GTESTS)
1176         ret = __wfd_util_find_login_user(&uid);
1177         if (ret < 0) {
1178                 WDS_LOGE("__wfd_util_find_login_user Failed !");
1179                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1180                 return -1;
1181         }
1182
1183         if (AUL_R_OK != aul_launch_app_async_for_uid(
1184                 "org.tizen.wifi-direct-popup", NULL, uid)) {
1185                 WDS_LOGE("aul_launch_for_uid Failed !");
1186                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1187                 return -1;
1188         }
1189
1190         WDS_LOGD("Succeeded to launch wifi-direct-popup");
1191 #endif /* BUILD_GTESTS */
1192         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1193         return 0;
1194 }
1195
1196 int wfd_util_stop_wifi_direct_popup()
1197 {
1198         uid_t uid = 0;
1199         int ret = 0;
1200
1201         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1202 #if !defined(BUILD_GTESTS)
1203         ret = __wfd_util_find_login_user(&uid);
1204         if (ret < 0) {
1205                 WDS_LOGE("__wfd_util_find_login_user Failed !");
1206                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1207                 return -1;
1208         }
1209
1210         int pid = aul_app_get_pid_for_uid("org.tizen.wifi-direct-popup", uid);
1211         if (pid > 0) {
1212                 if (aul_terminate_pid_async_for_uid(pid, uid) != AUL_R_OK) {
1213                         WDS_LOGD("Failed to destroy wifi-direct-popup pid[%d]", pid);
1214                         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1215                         return -1;
1216                 } else {
1217                         WDS_LOGD("Succeeded to destroy wifi-direct-popup");
1218                 }
1219         } else {
1220                 WDS_LOGD("Wifi-direct-popup not running");
1221         }
1222 #endif /* BUILD_GTESTS */
1223         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1224         return 0;
1225 }
1226
1227 int _connect_remote_device(char *ip_str)
1228 {
1229         int sock;
1230         int flags;
1231         int res = 0;
1232         struct sockaddr_in remo_addr;
1233         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1234
1235         errno = 0;
1236         sock = socket(PF_INET, SOCK_STREAM, 0);
1237         if (sock == -1) {
1238                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1239                 WDS_LOGE("Failed to create socket to remote device(%s)", error_buf);
1240                 return -1;
1241         }
1242
1243         flags = fcntl(sock, F_GETFL, 0);
1244         res = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
1245         if (res < 0) {
1246                 WDS_LOGE("File descriptor create failed");
1247                 close(sock);
1248                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1249                 return -1;
1250         }
1251
1252         memset(&remo_addr, 0x0, sizeof(remo_addr));
1253         remo_addr.sin_family = AF_INET;
1254         remo_addr.sin_addr.s_addr = inet_addr(ip_str);
1255         remo_addr.sin_port = htons(9999);
1256
1257         errno = 0;
1258         res = connect(sock, (struct sockaddr*) &remo_addr, sizeof(remo_addr));
1259         if (res < 0) {
1260                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1261                 WDS_LOGE("Failed to connect to server socket [%s]", error_buf);
1262                 close(sock);
1263                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1264                 return -1;
1265         }
1266
1267         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1268         WDS_SECLOGD("Status of connection to remote device[%s] - (%s)", ip_str, error_buf);
1269
1270         close(sock);
1271
1272         return 0;
1273 }
1274
1275 //LCOV_EXCL_START
1276 static void _dhcps_ip_leased_cb(keynode_t *key, void* data)
1277 {
1278         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1279         wfd_device_s *peer = (wfd_device_s*) data;
1280         FILE *fp = NULL;
1281         char buf[MAX_DHCP_DUMP_SIZE];
1282         char ip_str[IPSTR_LEN] = {0, };
1283         char intf_str[MACSTR_LEN];
1284         unsigned char intf_addr[MACADDR_LEN];
1285         char peer_mac_address[MACSTR_LEN+1] = {0,};
1286         char assigned_ip_address[IPSTR_LEN+1] = {0,};
1287         int n = 0;
1288         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1289
1290         if (!peer) {
1291                 WDS_LOGD("Invalid parameter");
1292                 return;
1293         }
1294         WDS_LOGD("DHCP server: IP leased");
1295
1296         errno = 0;
1297         fp = fopen(DHCP_DUMP_FILE, "r");
1298         if (NULL == fp) {
1299                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1300                 WDS_LOGE("Could not read the file(%s). [%s]", DHCP_DUMP_FILE, error_buf);
1301                 return;
1302         }
1303
1304         while (fgets(buf, MAX_DHCP_DUMP_SIZE, fp) != NULL) {
1305                 WDS_LOGD("Read line [%s]", buf);
1306                 n = sscanf(buf, "%17s %15s", intf_str, ip_str);
1307                 WDS_LOGD("ip=[%s], mac=[%s]", ip_str, intf_str);
1308                 if (n != 2)
1309                         continue;
1310
1311                 _txt_to_mac(intf_str, intf_addr);
1312                 if (!memcmp(peer->intf_addr, intf_addr, MACADDR_LEN)) {
1313                         WDS_LOGD("Peer intf mac found");
1314                         _txt_to_ip(ip_str, peer->ip_addr);
1315                         _connect_remote_device(ip_str);
1316                         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1317                         g_snprintf(assigned_ip_address, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1318                         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1319                                                      "PeerIPAssigned",
1320                                                      g_variant_new("(ss)", peer_mac_address,
1321                                                                            assigned_ip_address));
1322                         break;
1323                 } else {
1324                         WDS_LOGD("Different interface address peer[" MACSECSTR "] vs dhcp[" MACSECSTR "]",
1325                                                 MAC2SECSTR(peer->intf_addr), MAC2SECSTR(intf_addr));
1326                 }
1327         }
1328         fclose(fp);
1329
1330         vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
1331         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1332
1333         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1334         return;
1335 }
1336
1337 static gboolean _polling_ip(gpointer user_data)
1338 {
1339         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1340         wfd_manager_s *manager = wfd_get_manager();
1341         wfd_device_s *local = (wfd_device_s*) manager->local;
1342         wfd_device_s *peer = (wfd_device_s*) user_data;
1343         char *ifname = NULL;
1344         char ip_str[IPSTR_LEN] = {0, };
1345         static int count = 0;
1346         int res = 0;
1347
1348         if (!peer) {
1349                 WDS_LOGE("peer data is not exists");
1350                 return FALSE;
1351         }
1352
1353         res = wfd_manager_get_goup_ifname(&ifname);
1354         if (res < 0 || !ifname) {
1355                 WDS_LOGE("Failed to get group interface name");
1356                 return FALSE;
1357         }
1358
1359         if (count > 28) {
1360                 WDS_LOGE("Failed to get IP");
1361                 count = 0;
1362                 wfd_oem_destroy_group(manager->oem_ops, ifname);
1363                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1364                 return FALSE;
1365         }
1366         res = wfd_util_local_get_ip(ifname, local->ip_addr, 0);
1367         if (res < 0) {
1368                 WDS_LOGE("Failed to get local IP for interface %s(count=%d)", ifname, count++);
1369                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1370                 return TRUE;
1371         }
1372         WDS_LOGD("Succeeded to get local(client) IP [" IPSECSTR "] for iface[%s]",
1373                                     IP2SECSTR(local->ip_addr), ifname);
1374
1375         res = wfd_util_dhcpc_get_server_ip(peer->ip_addr);
1376         if (res < 0) {
1377                 WDS_LOGE("Failed to get peer(server) IP(count=%d)", count++);
1378                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1379                 return TRUE;
1380         }
1381         WDS_LOGD("Succeeded to get server IP [" IPSECSTR "]", IP2SECSTR(peer->ip_addr));
1382         count = 0;
1383
1384         g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1385         _connect_remote_device(ip_str);
1386
1387         char peer_mac_address[MACSTR_LEN+1] = {0, };
1388
1389         g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
1390         wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1391                                      "Connection",
1392                                      g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1393                                                             WFD_EVENT_CONNECTION_RSP,
1394                                                             peer_mac_address));
1395
1396         wfd_session_s *session = manager->session;
1397         if (wfd_asp_is_asp_session(session)) {
1398                 wfd_asp_connect_status(session->session_mac,
1399                                                         session->session_id,
1400                                                         ASP_CONNECT_STATUS_GROUP_FORMATION_COMPLETED,
1401                                                         NULL);
1402         }
1403
1404         wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
1405         wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
1406         wfd_destroy_session(manager);
1407
1408         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1409         return FALSE;
1410 }
1411 //LCOV_EXCL_STOP
1412
1413 int wfd_util_dhcps_start(char *ifname)
1414 {
1415         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1416         gboolean rv = FALSE;
1417         char *const iface = ifname;
1418         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
1419         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "server", iface, NULL };
1420         char *const envs[] = { NULL };
1421         wfd_manager_s *manager = wfd_get_manager();
1422
1423         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1424
1425         rv = wfd_util_execute_file(path, args, envs);
1426
1427         if (rv != TRUE) {
1428                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh server");
1429                 return -1;
1430         }
1431
1432         /*
1433          * As we are GO so IP should be updated
1434          * before sending Group Created Event
1435          */
1436         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_IFNAME, GROUP_IFNAME);
1437         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_LOCAL_IP, "192.168.49.1");
1438         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_SUBNET_MASK, "255.255.255.0");
1439         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_GATEWAY, "192.168.49.1");
1440
1441         WDS_LOGD("Successfully started wifi-direct-dhcp.sh server");
1442
1443         _txt_to_ip(TIZEN_P2P_GO_IPADDR, manager->local->ip_addr);
1444
1445         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1446         return 0;
1447 }
1448
1449 int wfd_util_dhcps_wait_ip_leased(wfd_device_s *peer)
1450 {
1451         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1452
1453         if (!peer) {
1454                 WDS_LOGE("Invalid parameter");
1455                 return -1;
1456         }
1457
1458         vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
1459         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1460         vconf_notify_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb, peer);
1461
1462         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1463         return 0;
1464 }
1465
1466 int wfd_util_dhcps_stop(char *ifname)
1467 {
1468         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1469         gboolean rv = FALSE;
1470         char *const iface = ifname;
1471         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
1472         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", iface, NULL };
1473         char *const envs[] = { NULL };
1474
1475         vconf_ignore_key_changed(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, _dhcps_ip_leased_cb);
1476         vconf_set_int(VCONFKEY_WIFI_DIRECT_DHCP_IP_LEASE, 0);
1477
1478         rv = wfd_util_execute_file(path, args, envs);
1479
1480         if (rv != TRUE) {
1481                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
1482                 return -1;
1483         }
1484         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
1485
1486         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1487         return 0;
1488 }
1489
1490 int wfd_util_dhcpc_start(char *ifname, wfd_device_s *peer)
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", "client", iface, NULL };
1497         char *const envs[] = { NULL };
1498
1499         if (!peer) {
1500                 WDS_LOGE("Invalid parameter");
1501                 return -1;
1502         }
1503
1504         rv = wfd_util_execute_file(path, args, envs);
1505         if (rv != TRUE) {
1506                 WDS_LOGE("Failed to start wifi-direct-dhcp.sh client");
1507                 return -1;
1508         }
1509         WDS_LOGD("Successfully started wifi-direct-dhcp.sh client");
1510
1511         g_timeout_add(250, (GSourceFunc) _polling_ip, peer);
1512
1513         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1514         return 0;
1515 }
1516
1517 int wfd_util_dhcpc_stop(char *ifname)
1518 {
1519         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1520         gboolean rv = FALSE;
1521         char *const iface = ifname;
1522         const char *path = "/usr/bin/wifi-direct-dhcp.sh";
1523         char *const args[] = { "/usr/bin/wifi-direct-dhcp.sh", "stop", iface, NULL };
1524         char *const envs[] = { NULL };
1525
1526         rv = wfd_util_execute_file(path, args, envs);
1527
1528         if (rv != TRUE) {
1529                 WDS_LOGE("Failed to stop wifi-direct-dhcp.sh");
1530                 return -1;
1531         }
1532         WDS_LOGD("Successfully stopped wifi-direct-dhcp.sh");
1533
1534         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1535         return 0;
1536 }
1537
1538 int wfd_util_local_get_ip(char *ifname, unsigned char *ip_addr, int is_IPv6)
1539 {
1540         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1541         struct ifreq ifr;
1542         struct sockaddr_in *sin = NULL;
1543         char *ip_str = NULL;
1544         int sock = -1;
1545         int res = -1;
1546         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1547
1548         if (!ifname || !ip_addr) {
1549                 WDS_LOGE("Invalid parameter");
1550                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1551                 return -1;
1552         }
1553
1554         errno = 0;
1555         sock = socket(AF_INET, SOCK_DGRAM, 0);
1556         if (sock < SOCK_FD_MIN) {
1557                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1558                 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1559                 if (sock >= 0)
1560                         close(sock);
1561                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1562                 return -1;
1563         }
1564
1565         ifr.ifr_addr.sa_family = AF_INET;
1566         memset(ifr.ifr_name, 0x00, IFNAMSIZ);
1567         g_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
1568
1569         errno = 0;
1570         res = ioctl(sock, SIOCGIFADDR, &ifr);
1571         if (res < 0) {
1572                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1573                 WDS_LOGE("Failed to get IP from socket. [%s]", error_buf);
1574                 close(sock);
1575                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1576                 return -1;
1577         }
1578         close(sock);
1579
1580         sin = (struct sockaddr_in*) &ifr.ifr_broadaddr;
1581         ip_str = inet_ntoa(sin->sin_addr);
1582         _txt_to_ip(ip_str, ip_addr);
1583         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1584         return 0;
1585 }
1586
1587 //LCOV_EXCL_START
1588 int wfd_util_dhcpc_get_server_ip(unsigned char* ip_addr)
1589 {
1590         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1591         char* get_str = NULL;
1592         int count = 0;
1593
1594         if (!ip_addr) {
1595                 WDS_LOGE("Invalid parameter");
1596                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1597                 return -1;
1598         }
1599
1600         while (count < 10) {
1601                 get_str = vconf_get_str(VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1602                 if (!get_str) {
1603                         WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1604                         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1605                         return -1;
1606                 }
1607
1608                 if (strcmp(get_str, ZEROIP) == 0) {
1609                         WDS_LOGE("Failed to get vconf value[%s]", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP);
1610                         g_free(get_str);
1611                         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1612                         return -1;
1613                 }
1614
1615                 WDS_LOGD("VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP(%s) : %s\n", VCONFKEY_WIFI_DIRECT_DHCPC_SERVER_IP, get_str);
1616                 _txt_to_ip(get_str, ip_addr);
1617                 g_free(get_str);
1618                 if (*ip_addr)
1619                         break;
1620                 count++;
1621         }
1622
1623         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1624         return 0;
1625 }
1626 //LCOV_EXCL_STOP
1627
1628 static int _wfd_util_set_vconf_for_static_ip(const char *ifname, char *static_ip)
1629 {
1630         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1631
1632         if (!ifname || !static_ip)
1633                 return -1;
1634
1635         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_IFNAME, ifname);
1636         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_LOCAL_IP, static_ip);
1637         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_SUBNET_MASK, "255.255.255.0");
1638         vconf_set_str(VCONFKEY_WIFI_DIRECT_P2P_GATEWAY, "192.168.49.1");
1639
1640         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1641
1642         return 0;
1643 }
1644
1645
1646 static int _wfd_util_static_ip_set(const char *ifname, unsigned char *static_ip)
1647 {
1648         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1649         int res = 0;
1650         unsigned char ip_addr[IPADDR_LEN];
1651         char ip_str[IPSTR_LEN] = {0, };
1652
1653         int if_index;
1654         int nl_sock = -1;
1655         struct sockaddr_nl dst_addr;
1656
1657         struct {
1658                 struct nlmsghdr     nh;
1659                 struct ifaddrmsg    ifa;
1660                 char            attrbuf[1024];
1661         } req;
1662         struct rtattr *rta;
1663         struct iovec iov;
1664         struct msghdr nl_msg;
1665
1666         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1667
1668         if (!ifname || !static_ip) {
1669                 WDS_LOGE("Invalid parameter");
1670                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1671                 return -1;
1672         }
1673
1674         /* Get index of interface */
1675         if_index = if_nametoindex(ifname);
1676         if (if_index < 0) {
1677                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1678                 WDS_LOGE("Failed to get interface index. [%s]", error_buf);
1679                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1680                 return -1;
1681         }
1682
1683         WDS_LOGD("Creating a Netlink Socket");
1684         nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1685         if (nl_sock < 0) {
1686                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1687                 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1688                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1689                 return -1;
1690         }
1691
1692         memset(&dst_addr, 0, sizeof(dst_addr));
1693         dst_addr.nl_family =  AF_NETLINK;
1694         dst_addr.nl_pid = 0;
1695
1696         memset(&req, 0, sizeof(req));
1697         req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1698         req.nh.nlmsg_type = RTM_NEWADDR;
1699         req.nh.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL | NLM_F_REQUEST;
1700
1701         req.ifa.ifa_family = AF_INET;
1702         req.ifa.ifa_prefixlen = 24;
1703         req.ifa.ifa_flags = IFA_F_PERMANENT;
1704         req.ifa.ifa_scope = 0;
1705         req.ifa.ifa_index = if_index;
1706
1707         rta = (struct rtattr *)(req.attrbuf);
1708         rta->rta_type = IFA_LOCAL;
1709         rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1710         memcpy(RTA_DATA(rta), static_ip, IPADDR_LEN);
1711         req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
1712
1713         rta = (struct rtattr *)(req.attrbuf + rta->rta_len);
1714         rta->rta_type = IFA_BROADCAST;
1715         rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1716         memcpy(ip_addr, static_ip, IPADDR_LEN);
1717         ip_addr[3] = 0xff;
1718         memcpy(RTA_DATA(rta), ip_addr, IPADDR_LEN);
1719         req.nh.nlmsg_len += rta->rta_len;
1720
1721         memset(&iov, 0, sizeof(iov));
1722         iov.iov_base = &req;
1723         iov.iov_len = req.nh.nlmsg_len;
1724
1725         memset(&nl_msg, 0, sizeof(nl_msg));
1726         nl_msg.msg_name = (void *)&dst_addr;
1727         nl_msg.msg_namelen = sizeof(dst_addr);
1728         nl_msg.msg_iov = &iov;
1729         nl_msg.msg_iovlen = 1;
1730
1731         res = sendmsg(nl_sock, &nl_msg, 0);
1732         if (res < 0) {
1733                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1734                 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1735         } else {
1736                 WDS_LOGD("Succed to sendmsg. [%d]", res);
1737         }
1738
1739         close(nl_sock);
1740         WDS_LOGE("Succeeded to set local(client) IP [" IPSTR "] for iface[%s]",
1741                                 IP2STR(static_ip), ifname);
1742
1743         snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(static_ip));
1744         _wfd_util_set_vconf_for_static_ip(ifname, ip_str);
1745
1746         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1747         return res;
1748 }
1749
1750 int wfd_util_ip_over_eap_assign(wfd_device_s *peer, const char *ifname)
1751 {
1752         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1753         wfd_manager_s *manager = wfd_get_manager();
1754         wfd_device_s *local = (wfd_device_s*) manager->local;
1755
1756         char ip_str[IPSTR_LEN] = {0, };
1757
1758         if (!peer) {
1759                 WDS_LOGE("Invalid paramater");
1760                 return -1;
1761         }
1762
1763         _wfd_util_static_ip_set(ifname, peer->client_ip_addr);
1764         memcpy(peer->ip_addr, peer->go_ip_addr, IPADDR_LEN);
1765         memcpy(local->ip_addr, peer->client_ip_addr, IPADDR_LEN);
1766
1767         g_snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(peer->ip_addr));
1768         _connect_remote_device(ip_str);
1769
1770         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1771         return 0;
1772 }
1773
1774 //LCOV_EXCL_START
1775 int wfd_util_ip_unset(const char *ifname)
1776 {
1777         __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
1778         int res = 0;
1779         unsigned char ip_addr[IPADDR_LEN];
1780         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
1781
1782         int if_index;
1783         int nl_sock = -1;
1784         struct sockaddr_nl dst_addr;
1785
1786         struct {
1787                 struct nlmsghdr     nh;
1788                 struct ifaddrmsg    ifa;
1789                 char            attrbuf[1024];
1790         } req;
1791         struct rtattr *rta;
1792         struct iovec iov;
1793         struct msghdr nl_msg;
1794
1795         if (!ifname) {
1796                 WDS_LOGE("Invalid parameter");
1797                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1798                 return -1;
1799         }
1800
1801         res = wfd_util_local_get_ip((char *)ifname, ip_addr, 0);
1802         if (res < 0) {
1803                 WDS_LOGE("Failed to get local IP for interface %s", ifname);
1804                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1805                 return -1;
1806         }
1807         WDS_LOGE("Succeeded to get local(client) IP [" IPSTR "] for iface[%s]",
1808                         IP2STR(ip_addr), ifname);
1809
1810         if_index = if_nametoindex(ifname);
1811         if (if_index < 0) {
1812                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1813                 WDS_LOGE("Failed to get interface index. [%s]", error_buf);
1814                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1815                 return -1;
1816         }
1817
1818         WDS_LOGD("Creating a Netlink Socket");
1819         nl_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
1820         if (nl_sock < 0) {
1821                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1822                 WDS_LOGE("Failed to create socket. [%s]", error_buf);
1823                 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1824                 return -1;
1825         }
1826
1827         WDS_LOGD("Set dst socket address to kernel");
1828         memset(&dst_addr, 0, sizeof(dst_addr));
1829         dst_addr.nl_family =  AF_NETLINK;
1830         dst_addr.nl_pid = 0;
1831
1832         memset(&req, 0, sizeof(req));
1833         req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1834         req.nh.nlmsg_type = RTM_DELADDR;
1835         req.nh.nlmsg_flags = NLM_F_REQUEST;
1836
1837         req.ifa.ifa_family = AF_INET;
1838         req.ifa.ifa_prefixlen = 32;
1839         req.ifa.ifa_flags = IFA_F_PERMANENT;
1840         req.ifa.ifa_scope = 0;
1841         req.ifa.ifa_index = if_index;
1842
1843         rta = (struct rtattr *)(req.attrbuf);
1844         rta->rta_type = IFA_LOCAL;
1845         rta->rta_len = RTA_LENGTH(IPADDR_LEN);
1846         memcpy(RTA_DATA(rta), ip_addr, IPADDR_LEN);
1847         req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
1848
1849         memset(&iov, 0, sizeof(iov));
1850         iov.iov_base = &req;
1851         iov.iov_len = req.nh.nlmsg_len;
1852
1853         memset(&nl_msg, 0, sizeof(nl_msg));
1854         nl_msg.msg_name = (void *)&dst_addr;
1855         nl_msg.msg_namelen = sizeof(dst_addr);
1856         nl_msg.msg_iov = &iov;
1857         nl_msg.msg_iovlen = 1;
1858
1859         res = sendmsg(nl_sock, &nl_msg, 0);
1860         if (res < 0) {
1861                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
1862                 WDS_LOGE("Failed to sendmsg. [%s]", error_buf);
1863         } else {
1864                 WDS_LOGD("Succeed to sendmsg. [%d]", res);
1865         }
1866
1867         close(nl_sock);
1868
1869         __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1870         return res;
1871 }
1872 //LCOV_EXCL_STOP
1873
1874 gboolean wfd_util_is_remove_group_allowed(void)
1875 {
1876         wfd_manager_s *manager = wfd_get_manager();
1877
1878         if (!manager->auto_group_remove_enable)
1879                 return FALSE;
1880
1881         return TRUE;
1882 }