Fix memory leak
[platform/core/api/tethering.git] / src / tethering.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/ioctl.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <net/if.h>
25 #include <arpa/inet.h>
26 #include <unistd.h>
27 #include <dbus/dbus.h>
28 #include <gio/gio.h>
29 #include <vconf.h>
30 #include <ckmc/ckmc-manager.h>
31 #include <tzplatform_config.h>
32 #include "tethering_private.h"
33
34 #define ALLOWED_LIST    tzplatform_mkpath(TZ_SYS_VAR, "/lib/hostapd/hostapd.accept")
35 #define BLOCKED_LIST    tzplatform_mkpath(TZ_SYS_VAR, "/lib/hostapd/hostapd.deny")
36 #define TEMP_LIST       tzplatform_mkpath(TZ_SYS_VAR, "/lib/hostapd/.hostapd_tmp")
37 #define MAC_ADDR_LEN    18
38 #define MAX_BUF_SIZE    80
39
40 #define IPTABLES        "/usr/sbin/iptables"
41 #define TABLE_NAT       "nat"
42 #define TETH_NAT_PRE        "teth_nat_pre"
43 #define TABLE_FILTER        "filter"
44 #define TETH_FILTER_FW      "teth_filter_fw"
45 #define ACTION_DROP     "DROP"
46 #define ACTION_ACCEPT       "ACCEPT"
47 #define PORT_FORWARD_RULE_STR   "-t %s -A %s -i %s -p %s -d %s --dport %d -j DNAT --to %s:%d"
48 #define FILTERING_MULTIPORT_RULE_STR    "-t %s -A %s -p %s -m multiport --dport %d,%d -j %s"
49 #define FILTERING_RULE_STR  "-t %s -A %s -p %s --dport %d -j %s"
50
51 static GSList *allowed_list = NULL;
52 static GSList *blocked_list = NULL;
53 static GSList *port_forwarding = NULL;
54 static GSList *port_filtering = NULL;
55 static GSList *custom_port_filtering = NULL;
56
57 static void __handle_wifi_tether_on(GDBusConnection *connection, const gchar *sender_name,
58                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
59                         GVariant *parameters, gpointer user_data);
60
61 static void __handle_wifi_tether_off(GDBusConnection *connection, const gchar *sender_name,
62                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
63                 GVariant *parameters, gpointer user_data);
64
65 static void __handle_usb_tether_on(GDBusConnection *connection, const gchar *sender_name,
66                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
67                 GVariant *parameters, gpointer user_data);
68
69 static void __handle_usb_tether_off(GDBusConnection *connection, const gchar *sender_name,
70                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
71                 GVariant *parameters, gpointer user_data);
72
73 static void __handle_bt_tether_on(GDBusConnection *connection, const gchar *sender_name,
74                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
75                 GVariant *parameters, gpointer user_data);
76
77 static void __handle_bt_tether_off(GDBusConnection *connection, const gchar *sender_name,
78                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
79                 GVariant *parameters, gpointer user_data);
80
81 static void __handle_net_closed(GDBusConnection *connection, const gchar *sender_name,
82                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
83                 GVariant *parameters, gpointer user_data);
84
85 static void __handle_no_data_timeout(GDBusConnection *connection, const gchar *sender_name,
86                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
87                 GVariant *parameters, gpointer user_data);
88
89 static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name,
90                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
91                 GVariant *parameters, gpointer user_data);
92
93 static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name,
94                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
95                 GVariant *parameters, gpointer user_data);
96
97 static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name,
98                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
99                 GVariant *parameters, gpointer user_data);
100
101 static void __handle_ssid_visibility_changed(GDBusConnection *connection, const gchar *sender_name,
102                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
103                 GVariant *parameters, gpointer user_data);
104
105 static void __handle_passphrase_changed(GDBusConnection *connection, const gchar *sender_name,
106                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
107                 GVariant *parameters, gpointer user_data);
108
109 static void __handle_dhcp(GDBusConnection *connection, const gchar *sender_name,
110                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
111                 GVariant *parameters, gpointer user_data);
112
113 static __tethering_sig_t sigs[] = {
114         {0, SIGNAL_NAME_NET_CLOSED, __handle_net_closed},
115         {0, SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on},
116         {0, SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off},
117         {0, SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on},
118         {0, SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off},
119         {0, SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on},
120         {0, SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off},
121         {0, SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout},
122         {0, SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode},
123         {0, SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode},
124         {0, SIGNAL_NAME_SECURITY_TYPE_CHANGED, __handle_security_type_changed},
125         {0, SIGNAL_NAME_SSID_VISIBILITY_CHANGED, __handle_ssid_visibility_changed},
126         {0, SIGNAL_NAME_PASSPHRASE_CHANGED, __handle_passphrase_changed},
127         {0, SIGNAL_NAME_DHCP_STATUS, __handle_dhcp} };
128
129 static int retry = 0;
130
131 static void __send_dbus_signal(GDBusConnection *conn, const char *signal_name, const char *arg)
132 {
133         if (conn == NULL || signal_name == NULL)
134                 return; //LCOV_EXCL_LINE
135
136         GVariant *message = NULL;
137         GError *error = NULL;
138
139         if (arg)
140                 message = g_variant_new("(s)", arg);
141
142         g_dbus_connection_emit_signal(conn, NULL, TETHERING_SERVICE_OBJECT_PATH,
143                                         TETHERING_SERVICE_INTERFACE, signal_name, message, &error);
144         if (error) {
145                 ERR("g_dbus_connection_emit_signal is failed because  %s\n", error->message); //LCOV_EXCL_LINE
146                 g_error_free(error); //LCOV_EXCL_LINE
147         }
148 }
149
150 static bool __any_tethering_is_enabled(tethering_h tethering)
151 {
152         if (tethering_is_enabled(tethering, TETHERING_TYPE_USB) ||
153                         tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) ||
154                         tethering_is_enabled(tethering, TETHERING_TYPE_BT) ||
155                         tethering_is_enabled(tethering, TETHERING_TYPE_P2P))
156                 return true;
157
158         return false;
159 }
160
161 static tethering_error_e __set_security_type(const tethering_wifi_security_type_e security_type)
162 {
163         if (security_type != TETHERING_WIFI_SECURITY_TYPE_NONE &&
164                         security_type != TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK &&
165                         security_type != TETHERING_WIFI_SECURITY_TYPE_WPS &&
166                         security_type != TETHERING_WIFI_SECURITY_TYPE_SAE) {
167                 ERR("Invalid param\n"); //LCOV_EXCL_LINE
168                 return TETHERING_ERROR_INVALID_PARAMETER;
169         }
170
171         if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, security_type) < 0) {
172                 ERR("vconf_set_int is failed\n"); //LCOV_EXCL_LINE
173                 return TETHERING_ERROR_OPERATION_FAILED;
174         }
175
176         return TETHERING_ERROR_NONE;
177 }
178
179 static tethering_error_e __get_security_type(tethering_wifi_security_type_e *security_type)
180 {
181         if (security_type == NULL) {
182                 ERR("Invalid param\n"); //LCOV_EXCL_LINE
183                 return TETHERING_ERROR_INVALID_PARAMETER;
184         }
185
186         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY,
187                                 (int *)security_type) < 0) {
188                 ERR("vconf_get_int is failed\n"); //LCOV_EXCL_LINE
189                 return TETHERING_ERROR_OPERATION_FAILED;
190         }
191
192         return TETHERING_ERROR_NONE;
193 }
194
195 static bool __get_ssid_from_vconf(const char *path, char *ssid, unsigned int size)
196 {
197         if (path == NULL || ssid == NULL || size == 0)
198                 return false;
199
200         char *ptr = NULL;
201         char *ptr_tmp = NULL;
202
203         ptr = vconf_get_str(path);
204         if (ptr == NULL)
205                 return false;
206
207         if (!g_utf8_validate(ptr, -1, (const char **)&ptr_tmp))
208                 *ptr_tmp = '\0';
209
210         g_strlcpy(ssid, ptr, size);
211         free(ptr);
212
213         return true;
214 }
215
216 static tethering_error_e __set_visible(const bool visible)
217 {
218         if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, visible ? 0 : 1) < 0) {
219                 ERR("vconf_set_int is failed\n"); //LCOV_EXCL_LINE
220                 return TETHERING_ERROR_OPERATION_FAILED;
221         }
222
223         return TETHERING_ERROR_NONE;
224 }
225
226 static tethering_error_e __get_visible(bool *visible)
227 {
228         if (visible == NULL) {
229                 ERR("Invalid param\n"); //LCOV_EXCL_LINE
230                 return TETHERING_ERROR_INVALID_PARAMETER;
231         }
232
233         int hide = 0;
234
235         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, &hide) < 0) {
236                 ERR("vconf_get_int is failed\n"); //LCOV_EXCL_LINE
237                 return TETHERING_ERROR_OPERATION_FAILED;
238         }
239
240         if (hide)
241                 *visible = false;
242         else
243                 *visible = true;
244         return TETHERING_ERROR_NONE;
245 }
246
247 static unsigned int __generate_initial_passphrase(char *passphrase, unsigned int size)
248 {
249         if (passphrase == NULL ||
250                         size == 0 || size < TETHERING_WIFI_KEY_MIN_LEN + 1)
251                 return 0;
252
253         guint32 rand_int = 0;
254         int index = 0;
255
256         for (index = 0; index < TETHERING_WIFI_KEY_MIN_LEN; index++) {
257                 rand_int = g_random_int_range('a', 'z');
258                 passphrase[index] = rand_int;
259         }
260         passphrase[index] = '\0';
261
262         return index;
263 }
264
265 static tethering_error_e __get_error(int agent_error)
266 {
267         tethering_error_e err = TETHERING_ERROR_NONE;
268
269         switch (agent_error) {
270         case MOBILE_AP_ERROR_NONE:
271                 err = TETHERING_ERROR_NONE;
272                 break;
273
274         //LCOV_EXCL_START
275         case MOBILE_AP_ERROR_RESOURCE:
276                 err = TETHERING_ERROR_OUT_OF_MEMORY;
277                 break;
278         //LCOV_EXCL_STOP
279
280         case MOBILE_AP_ERROR_INTERNAL:
281                 err = TETHERING_ERROR_OPERATION_FAILED;
282                 break;
283
284         case MOBILE_AP_ERROR_INVALID_PARAM:
285                 err = TETHERING_ERROR_INVALID_PARAMETER;
286                 break;
287
288         //LCOV_EXCL_START
289         case MOBILE_AP_ERROR_ALREADY_ENABLED:
290                 err = TETHERING_ERROR_OPERATION_FAILED;
291                 break;
292
293         case MOBILE_AP_ERROR_NOT_ENABLED:
294                 err = TETHERING_ERROR_NOT_ENABLED;
295                 break;
296
297         case MOBILE_AP_ERROR_NET_OPEN:
298                 err = TETHERING_ERROR_OPERATION_FAILED;
299                 break;
300
301         case MOBILE_AP_ERROR_NET_CLOSE:
302                 err = TETHERING_ERROR_OPERATION_FAILED;
303                 break;
304
305         case MOBILE_AP_ERROR_DHCP:
306                 err = TETHERING_ERROR_OPERATION_FAILED;
307                 break;
308
309         case MOBILE_AP_ERROR_IN_PROGRESS:
310                 err = TETHERING_ERROR_OPERATION_FAILED;
311                 break;
312
313         case MOBILE_AP_ERROR_NOT_PERMITTED:
314                 err = TETHERING_ERROR_NOT_PERMITTED;
315                 break;
316
317         case MOBILE_AP_ERROR_PERMISSION_DENIED:
318                 err = TETHERING_ERROR_PERMISSION_DENIED;
319                 break;
320         //LCOV_EXCL_STOP
321         default:
322                 ERR("Not defined error : %d\n", agent_error);
323                 err = TETHERING_ERROR_OPERATION_FAILED;
324                 break;
325         }
326
327         return err;
328 }
329
330 //LCOV_EXCL_START
331 static void __handle_dhcp(GDBusConnection *connection, const gchar *sender_name,
332                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
333                 GVariant *parameters, gpointer user_data)
334 {
335         DBG("+\n");
336
337         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
338
339         __tethering_h *th = (__tethering_h *)user_data;
340         bool opened = false;
341         tethering_type_e type = 0;
342         mobile_ap_type_e ap_type = 0;
343         tethering_connection_state_changed_cb ccb = NULL;
344         __tethering_client_h client;
345         void *data = NULL;
346         char *buf = NULL;
347         char *name = NULL;
348         char *mac = NULL;
349         char *ip = NULL;
350         guint timestamp;
351
352         memset(&client, 0, sizeof(__tethering_client_h));
353         g_variant_get(parameters, "(susssu)", &buf, &ap_type, &ip, &mac, &name, &timestamp);
354
355         if (!g_strcmp0(buf, "DhcpConnected")) {
356                 opened = true;
357         } else if (!g_strcmp0(buf, "DhcpLeaseDeleted")) {
358                 opened = false;
359         } else {
360                 ERR("Unknown event [%s]\n", buf);
361                 goto DONE;
362         }
363
364         if (ap_type == MOBILE_AP_TYPE_USB)
365                 type = TETHERING_TYPE_USB;
366         else if (ap_type == MOBILE_AP_TYPE_WIFI)
367                 type = TETHERING_TYPE_WIFI;
368         else if (ap_type == MOBILE_AP_TYPE_BT)
369                 type = TETHERING_TYPE_BT;
370         else if (ap_type == MOBILE_AP_TYPE_P2P)
371                 type = TETHERING_TYPE_P2P;
372         else {
373                 ERR("Not supported tethering type [%d]\n", ap_type);
374                 goto DONE;
375         }
376
377         ccb = th->changed_cb[type];
378         if (ccb == NULL)
379                 goto DONE;
380         data = th->changed_user_data[type];
381
382         client.interface = type;
383         g_strlcpy(client.ip, ip, sizeof(client.ip));
384         g_strlcpy(client.mac, mac, sizeof(client.mac));
385         if (name != NULL)
386                 client.hostname = g_strdup(name);
387         client.tm = (time_t)timestamp;
388
389         ccb((tethering_client_h)&client, opened, data);
390         g_free(client.hostname);
391 DONE:
392         g_free(buf);
393         g_free(ip);
394         g_free(mac);
395         g_free(name);
396         DBG("-\n");
397 }
398
399 static void __handle_net_closed(GDBusConnection *connection, const gchar *sender_name,
400                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
401                 GVariant *parameters, gpointer user_data)
402 {
403         DBG("+\n");
404
405         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
406
407         __tethering_h *th = (__tethering_h *)user_data;
408         tethering_type_e type = 0;
409         tethering_disabled_cb dcb = NULL;
410         void *data = NULL;
411         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_NETWORK_CLOSE;
412
413         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
414                 dcb = th->disabled_cb[type];
415                 if (dcb == NULL)
416                         continue;
417                 data = th->disabled_user_data[type];
418
419                 dcb(TETHERING_ERROR_NONE, type, code, data);
420         }
421
422         DBG("-\n");
423 }
424 //LCOV_EXCL_STOP
425
426 static void __handle_wifi_tether_on(GDBusConnection *connection, const gchar *sender_name,
427                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
428                         GVariant *parameters, gpointer user_data)
429 {
430         DBG("+\n");
431
432         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
433
434         __tethering_h *th = (__tethering_h *)user_data;
435         tethering_type_e type = TETHERING_TYPE_WIFI;
436         bool is_requested = false;
437         tethering_enabled_cb ecb = NULL;
438         void *data = NULL;
439
440         ecb = th->enabled_cb[type];
441         if (ecb == NULL)
442                 return;
443         data = th->enabled_user_data[type];
444
445         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
446         DBG("-\n");
447 }
448
449 static void __handle_wifi_tether_off(GDBusConnection *connection, const gchar *sender_name,
450                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
451                         GVariant *parameters, gpointer user_data)
452 {
453         DBG("+\n");
454
455         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
456
457         __tethering_h *th = (__tethering_h *)user_data;
458         tethering_type_e type = TETHERING_TYPE_WIFI;
459         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
460         tethering_disabled_cb dcb = NULL;
461         void *data = NULL;
462         char *buf = NULL;
463
464         dcb = th->disabled_cb[type];
465         if (dcb == NULL)
466                 return;
467         data = th->disabled_user_data[type];
468         g_variant_get(parameters, "(s)", &buf);
469         if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
470                 code = TETHERING_DISABLED_BY_WIFI_ON;
471         else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT))
472                 code = TETHERING_DISABLED_BY_TIMEOUT;
473
474         g_free(buf);
475         dcb(TETHERING_ERROR_NONE, type, code, data);
476
477         DBG("-\n");
478 }
479
480 //LCOV_EXCL_START
481 static void __handle_usb_tether_on(GDBusConnection *connection, const gchar *sender_name,
482                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
483                         GVariant *parameters, gpointer user_data)
484 {
485         DBG("+\n");
486
487         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
488
489         __tethering_h *th = (__tethering_h *)user_data;
490         tethering_type_e type = TETHERING_TYPE_USB;
491         bool is_requested = false;
492         tethering_enabled_cb ecb = NULL;
493         void *data = NULL;
494
495         ecb = th->enabled_cb[type];
496         if (ecb == NULL)
497                 return;
498         data = th->enabled_user_data[type];
499
500         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
501         DBG("-\n");
502 }
503
504 static void __handle_usb_tether_off(GDBusConnection *connection, const gchar *sender_name,
505                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
506                         GVariant *parameters, gpointer user_data)
507 {
508         DBG("+\n");
509
510         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
511
512         __tethering_h *th = (__tethering_h *)user_data;
513         tethering_type_e type = TETHERING_TYPE_USB;
514         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
515         tethering_disabled_cb dcb = NULL;
516         void *data = NULL;
517         char *buf = NULL;
518
519         dcb = th->disabled_cb[type];
520         if (dcb == NULL)
521                 return;
522         data = th->disabled_user_data[type];
523
524         g_variant_get(parameters, "(s)", &buf);
525         if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
526                 code = TETHERING_DISABLED_BY_USB_DISCONNECTION;
527
528         dcb(TETHERING_ERROR_NONE, type, code, data);
529         g_free(buf);
530         DBG("-\n");
531 }
532 //LCOV_EXCL_STOP
533
534 static void __handle_bt_tether_on(GDBusConnection *connection, const gchar *sender_name,
535                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
536                         GVariant *parameters, gpointer user_data)
537 {
538         DBG("+\n");
539
540         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
541
542         __tethering_h *th = (__tethering_h *)user_data;
543         tethering_type_e type = TETHERING_TYPE_BT;
544         bool is_requested = false;
545         tethering_enabled_cb ecb = NULL;
546         void *data = NULL;
547
548         ecb = th->enabled_cb[type];
549         if (ecb == NULL)
550                 return;
551         data = th->enabled_user_data[type];
552
553         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
554         DBG("-\n");
555 }
556
557 static void __handle_bt_tether_off(GDBusConnection *connection, const gchar *sender_name,
558                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
559                         GVariant *parameters, gpointer user_data)
560 {
561         DBG("+\n");
562
563         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
564
565         __tethering_h *th = (__tethering_h *)user_data;
566         tethering_type_e type = TETHERING_TYPE_BT;
567         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
568         tethering_disabled_cb dcb = NULL;
569         void *data = NULL;
570         char *buf = NULL;
571
572         dcb = th->disabled_cb[type];
573         if (dcb == NULL)
574                 return;
575         data = th->disabled_user_data[type];
576         g_variant_get(parameters, "(s)", &buf);
577         if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
578                 code = TETHERING_DISABLED_BY_BT_OFF;
579         else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT))
580                 code = TETHERING_DISABLED_BY_TIMEOUT;
581
582         dcb(TETHERING_ERROR_NONE, type, code, data);
583
584         g_free(buf);
585         DBG("-\n");
586 }
587
588 //LCOV_EXCL_START
589 static void __handle_no_data_timeout(GDBusConnection *connection, const gchar *sender_name,
590                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
591                         GVariant *parameters, gpointer user_data)
592 {
593         DBG("+\n");
594
595         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
596
597         __tethering_h *th = (__tethering_h *)user_data;
598         tethering_type_e type = 0;
599         tethering_disabled_cb dcb = NULL;
600         void *data = NULL;
601         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_TIMEOUT;
602
603         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
604                 dcb = th->disabled_cb[type];
605                 if (dcb == NULL)
606                         continue;
607                 data = th->disabled_user_data[type];
608
609                 dcb(TETHERING_ERROR_NONE, type, code, data);
610         }
611         DBG("-\n");
612 }
613
614 static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name,
615                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
616                         GVariant *parameters, gpointer user_data)
617 {
618         DBG("+\n");
619
620         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
621
622         __tethering_h *th = (__tethering_h *)user_data;
623         tethering_type_e type = 0;
624         tethering_disabled_cb dcb = NULL;
625         void *data = NULL;
626         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY;
627
628         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
629                 dcb = th->disabled_cb[type];
630                 if (dcb == NULL)
631                         continue;
632                 data = th->disabled_user_data[type];
633
634                 dcb(TETHERING_ERROR_NONE, type, code, data);
635         }
636         DBG("-\n");
637 }
638
639 static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name,
640                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
641                         GVariant *parameters, gpointer user_data)
642 {
643         DBG("+\n");
644
645         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
646
647         __tethering_h *th = (__tethering_h *)user_data;
648         tethering_type_e type = 0;
649         tethering_disabled_cb dcb = NULL;
650         void *data = NULL;
651         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE;
652
653         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
654                 dcb = th->disabled_cb[type];
655                 if (dcb == NULL)
656                         continue;
657                 data = th->disabled_user_data[type];
658
659                 dcb(TETHERING_ERROR_NONE, type, code, data);
660         }
661         DBG("-\n");
662 }
663 //LCOV_EXCL_STOP
664
665 static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name,
666                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
667                 GVariant *parameters, gpointer user_data)
668
669 {
670         DBG("+\n");
671
672         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
673         __tethering_h *th = (__tethering_h *)user_data;
674
675         tethering_wifi_security_type_changed_cb scb = NULL;
676         void *data = NULL;
677         tethering_wifi_security_type_e security_type;
678         char *buf = NULL;
679
680         scb = th->security_type_changed_cb;
681         if (scb == NULL)
682                 return;
683
684         g_variant_get(parameters, "(s)", &buf);
685         data = th->security_type_user_data;
686         if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
687                 security_type = TETHERING_WIFI_SECURITY_TYPE_NONE;
688         else if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
689                 security_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
690         else if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_WPS_STR) == 0)
691                 security_type = TETHERING_WIFI_SECURITY_TYPE_WPS;
692         else if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_SAE_STR) == 0)
693                 security_type = TETHERING_WIFI_SECURITY_TYPE_SAE;
694         else {
695                 SERR("Unknown type : %s\n", buf); //LCOV_EXCL_LINE
696                 g_free(buf);
697                 return;
698         }
699         g_free(buf);
700         scb(security_type, data);
701
702         return;
703 }
704
705 static void __handle_ssid_visibility_changed(GDBusConnection *connection, const gchar *sender_name,
706                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
707                 GVariant *parameters, gpointer user_data)
708 {
709         DBG("+\n"); //LCOV_EXCL_LINE
710
711         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
712         __tethering_h *th = (__tethering_h *)user_data;
713
714         tethering_wifi_ssid_visibility_changed_cb scb = NULL;
715         void *data = NULL;
716         bool visible = false;
717         char *buf = NULL;
718
719         scb = th->ssid_visibility_changed_cb;
720         if (scb == NULL) {
721                 DBG("-\n"); //LCOV_EXCL_LINE
722                 return;
723         }
724         g_variant_get(parameters, "(s)", &buf);
725         data = th->ssid_visibility_user_data;
726         if (g_strcmp0(buf, SIGNAL_MSG_SSID_VISIBLE) == 0)
727                 visible = true;
728
729         scb(visible, data);
730         g_free(buf);
731         DBG("-\n"); //LCOV_EXCL_LINE
732 }
733
734 static void __handle_passphrase_changed(GDBusConnection *connection, const gchar *sender_name,
735                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
736                 GVariant *parameters, gpointer user_data)
737 {
738         DBG("+\n"); //LCOV_EXCL_LINE
739
740         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
741         __tethering_h *th = (__tethering_h *)user_data;
742
743         tethering_wifi_passphrase_changed_cb pcb = NULL;
744         void *data = NULL;
745
746         pcb = th->passphrase_changed_cb;
747         if (pcb == NULL)
748                 return;
749
750         data = th->passphrase_user_data;
751
752         pcb(data);
753         DBG("-\n"); //LCOV_EXCL_LINE
754 }
755
756 static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res,
757                 gpointer user_data)
758 {
759         INFO("+\n"); //LCOV_EXCL_LINE
760
761         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
762         GError *g_error = NULL;
763         GVariant *g_var;
764         guint info;
765         tethering_error_e error;
766         __tethering_h *th = (__tethering_h *)user_data;
767         tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_WIFI];
768         void *data = th->enabled_user_data[TETHERING_TYPE_WIFI];
769
770         if (!_tethering_check_handle((tethering_h)user_data))
771                 return;
772
773         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
774         if (g_error) {
775                 //LCOV_EXCL_START
776                 ERR("DBus error [%s]\n", g_error->message);
777                 if (g_error->code == G_DBUS_ERROR_NO_REPLY &&
778                                 ++retry < TETHERING_ERROR_RECOVERY_MAX) {
779                         g_error_free(g_error);
780                         tethering_enable((tethering_h)th, TETHERING_TYPE_WIFI);
781                         return;
782                 } else if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
783                         error = TETHERING_ERROR_PERMISSION_DENIED;
784                 else
785                         error = TETHERING_ERROR_OPERATION_FAILED;
786                 g_error_free(g_error);
787                 //LCOV_EXCL_STOP
788         } else {
789                 g_variant_get(g_var, "(u)", &info);
790                 error = __get_error(info);
791         }
792         retry = 0;
793
794         INFO("cfm event : wifi tethering enable info : %d\n", error); //LCOV_EXCL_LINE
795
796         sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
797                         NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_ON].name,
798                         TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
799                         sigs[E_SIGNAL_WIFI_TETHER_ON].cb, (gpointer)th, NULL);
800
801         if (!ecb) {
802                 INFO("-\n"); //LCOV_EXCL_LINE
803                 return;
804         }
805         ecb(error, TETHERING_TYPE_WIFI, true, data);
806         g_variant_unref(g_var);
807         INFO("-\n"); //LCOV_EXCL_LINE
808 }
809
810 static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res,
811                 gpointer user_data)
812 {
813         DBG("+\n"); //LCOV_EXCL_LINE
814         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
815         GError *g_error = NULL;
816         GVariant *g_var;
817         guint info;
818         tethering_error_e error;
819
820         __tethering_h *th = (__tethering_h *)user_data;
821         tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_BT];
822         void *data = th->enabled_user_data[TETHERING_TYPE_BT];
823
824         if (!_tethering_check_handle((tethering_h)user_data))
825                 return;
826
827         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
828         if (g_error) {
829                 //LCOV_EXCL_START
830                 ERR("DBus error [%s]\n", g_error->message);
831                 if (g_error->code == G_DBUS_ERROR_NO_REPLY &&
832                                 ++retry < TETHERING_ERROR_RECOVERY_MAX) {
833                         g_error_free(g_error);
834                         tethering_enable((tethering_h)th, TETHERING_TYPE_BT);
835                         DBG("-\n");
836                         return;
837                 }
838                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
839                         error = TETHERING_ERROR_PERMISSION_DENIED;
840                 else
841                         error = TETHERING_ERROR_OPERATION_FAILED;
842                 g_error_free(g_error);
843                 //LCOV_EXCL_STOP
844         } else {
845                 g_variant_get(g_var, "(u)", &info);
846                 g_variant_unref(g_var);
847                 error = __get_error(info);
848         }
849         retry = 0;
850
851         sigs[E_SIGNAL_BT_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
852                         NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_ON].name,
853                         TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
854                         sigs[E_SIGNAL_BT_TETHER_ON].cb, (gpointer)th, NULL);
855
856         if (!ecb) {
857                 DBG("-\n"); //LCOV_EXCL_LINE
858                 return;
859         }
860
861         ecb(error, TETHERING_TYPE_BT, true, data);
862         DBG("-\n");
863 }
864
865 //LCOV_EXCL_START
866 static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res,
867                                         gpointer user_data)
868 {
869         DBG("+\n");
870
871         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
872         __tethering_h *th = (__tethering_h *)user_data;
873         GError *g_error = NULL;
874         GVariant *g_var;
875         guint info;
876         tethering_error_e error;
877         tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_USB];
878         void *data = th->enabled_user_data[TETHERING_TYPE_USB];
879
880         if (!_tethering_check_handle((tethering_h)user_data))
881                 return;
882
883         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
884         if (g_error) {
885                 ERR("DBus error [%s]\n", g_error->message);
886                 if (g_error->code == G_DBUS_ERROR_NO_REPLY &&
887                                 ++retry < TETHERING_ERROR_RECOVERY_MAX) {
888                         g_error_free(g_error);
889                         tethering_enable((tethering_h)th, TETHERING_TYPE_USB);
890                         DBG("-\n");
891                         return;
892                 }
893                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
894                         error = TETHERING_ERROR_PERMISSION_DENIED;
895                 else
896                         error = TETHERING_ERROR_OPERATION_FAILED;
897                 g_error_free(g_error);
898         } else {
899                 g_variant_get(g_var, "(u)", &info);
900                 g_variant_unref(g_var);
901                 error = __get_error(info);
902         }
903         retry = 0;
904
905         sigs[E_SIGNAL_USB_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
906                         NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_USB_TETHER_ON].name,
907                         TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
908                         sigs[E_SIGNAL_USB_TETHER_ON].cb, (gpointer)th, NULL);
909
910         if (!ecb) {
911                 DBG("-\n");
912                 return;
913         }
914
915         ecb(error, TETHERING_TYPE_USB, true, data);
916         DBG("-\n");
917 }
918
919 static void __p2p_enabled_cfm_cb(GObject *source_object, GAsyncResult *res,
920                                         gpointer user_data)
921 {
922         DBG("+\n");
923
924         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
925         __tethering_h *th = (__tethering_h *)user_data;
926         GError *g_error = NULL;
927         GVariant *g_var;
928         guint info;
929         tethering_error_e error;
930         tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_P2P];
931         void *data = th->enabled_user_data[TETHERING_TYPE_P2P];
932
933         if (!_tethering_check_handle((tethering_h)user_data))
934                 return;
935
936         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
937         if (g_error) {
938                 ERR("DBus error [%s]\n", g_error->message);
939                 if (g_error->code == G_DBUS_ERROR_NO_REPLY &&
940                                 ++retry < TETHERING_ERROR_RECOVERY_MAX) {
941                         g_error_free(g_error);
942                         tethering_enable((tethering_h)th, TETHERING_TYPE_P2P);
943                         DBG("-\n");
944                         return;
945                 }
946                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
947                         error = TETHERING_ERROR_PERMISSION_DENIED;
948                 else
949                         error = TETHERING_ERROR_OPERATION_FAILED;
950                 g_error_free(g_error);
951         } else {
952                 g_variant_get(g_var, "(u)", &info);
953                 g_variant_unref(g_var);
954                 error = __get_error(info);
955         }
956         retry = 0;
957
958         if (!ecb) {
959                 DBG("-\n");
960                 return;
961         }
962
963         ecb(error, TETHERING_TYPE_P2P, true, data);
964         DBG("-\n");
965 }
966 //LCOV_EXCL_STOP
967
968 static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res,
969                 gpointer user_data)
970 {
971         INFO("+\n"); //LCOV_EXCL_LINE
972
973         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
974         GError *g_error = NULL;
975         GVariant *g_var;
976         guint info, event_type;
977         tethering_error_e error;
978         tethering_type_e type;
979         tethering_h tethering = (tethering_h)user_data;
980         __tethering_h *th = (__tethering_h *)tethering;
981         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_REQUEST;
982         tethering_disabled_cb dcb = NULL;
983         void *data = NULL;
984
985         if (!_tethering_check_handle((tethering_h)user_data))
986                 return;
987
988         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
989         if (g_error) {
990                 //LCOV_EXCL_START
991                 ERR("DBus error [%s]\n", g_error->message);
992                 g_error_free(g_error);
993                 return;
994                 //LCOV_EXCL_STOP
995         }
996         g_variant_get(g_var, "(uu)", &event_type, &info);
997         INFO("cfm event : %d info : %d\n", event_type, info);
998         g_variant_unref(g_var);
999         error = __get_error(info);
1000         INFO("cfm event : %d info : %d\n", event_type, error);
1001         switch (event_type) {
1002         case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM:
1003                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
1004                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_OFF].name,
1005                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1006                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].cb, (gpointer)th, NULL);
1007
1008                 type = TETHERING_TYPE_WIFI;
1009                 dcb = th->disabled_cb[type];
1010                 data = th->disabled_user_data[type];
1011                 if (dcb)
1012                         dcb(error, type, code, data);
1013                 break;
1014
1015         case MOBILE_AP_DISABLE_BT_TETHERING_CFM:
1016                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
1017                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_OFF].name,
1018                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1019                                 sigs[E_SIGNAL_BT_TETHER_OFF].cb, (gpointer)th, NULL);
1020
1021                 type = TETHERING_TYPE_BT;
1022                 dcb = th->disabled_cb[type];
1023                 data = th->disabled_user_data[type];
1024                 if (dcb)
1025                         dcb(error, type, code, data);
1026                 break;
1027
1028         //LCOV_EXCL_START
1029         case MOBILE_AP_DISABLE_USB_TETHERING_CFM:
1030                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
1031                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_USB_TETHER_OFF].name,
1032                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1033                                 sigs[E_SIGNAL_USB_TETHER_OFF].cb, (gpointer)th, NULL);
1034
1035                 type = TETHERING_TYPE_USB;
1036                 dcb = th->disabled_cb[type];
1037                 data = th->disabled_user_data[type];
1038                 if (dcb)
1039                         dcb(error, type, code, data);
1040                 break;
1041
1042         case MOBILE_AP_DISABLE_P2P_TETHERING_CFM:
1043                 type = TETHERING_TYPE_P2P;
1044                 dcb = th->disabled_cb[type];
1045                 data = th->disabled_user_data[type];
1046                 if (dcb)
1047                         dcb(error, type, code, data);
1048                 break;
1049
1050         case MOBILE_AP_DISABLE_CFM:
1051
1052                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
1053                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_OFF].name,
1054                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1055                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].cb, (gpointer)th, NULL);
1056                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
1057                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_OFF].name,
1058                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1059                                 sigs[E_SIGNAL_BT_TETHER_OFF].cb, (gpointer)th, NULL);
1060                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
1061                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_USB_TETHER_OFF].name,
1062                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1063                                 sigs[E_SIGNAL_USB_TETHER_OFF].cb, (gpointer)th, NULL);
1064
1065                 for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
1066                         dcb = th->disabled_cb[type];
1067                         if (dcb == NULL)
1068                                 continue;
1069                         data = th->disabled_user_data[type];
1070
1071                         dcb(error, type, code, data);
1072                 }
1073                 break;
1074
1075         default:
1076                 ERR("Invalid event\n");
1077                 break;
1078         //LCOV_EXCL_STOP
1079         }
1080         INFO("-\n"); //LCOV_EXCL_LINE
1081 }
1082
1083 static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res,
1084                                 gpointer user_data)
1085 {
1086         DBG("+\n");
1087
1088         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
1089
1090         GError *g_error = NULL;
1091         GVariant *g_var;
1092         guint event_type;
1093         guint64 tx_bytes, rx_bytes;
1094         __tethering_h *th = (__tethering_h *)user_data;
1095         tethering_error_e tethering_error = TETHERING_ERROR_NONE;
1096         bool flag = false;
1097
1098         g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
1099         if (g_error) {
1100                 //LCOV_EXCL_START
1101                 ERR("DBus fail [%s]\n", g_error->message);
1102                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
1103                         tethering_error = TETHERING_ERROR_PERMISSION_DENIED;
1104                 else
1105                         tethering_error = TETHERING_ERROR_OPERATION_FAILED;
1106
1107                 flag = true;
1108                 //LCOV_EXCL_STOP
1109         }
1110         if (th->data_usage_cb == NULL) {
1111                 ERR("There is no data_usage_cb\n"); //LCOV_EXCL_LINE
1112                 return;
1113         }
1114         if (flag) {
1115                 th->data_usage_cb(tethering_error, 0LL, 0LL, th->data_usage_user_data);
1116         } else {
1117                 g_variant_get(g_var, "(utt)", &event_type, &tx_bytes, &rx_bytes);
1118                 th->data_usage_cb(TETHERING_ERROR_NONE,
1119                         rx_bytes, tx_bytes, th->data_usage_user_data);
1120                 g_variant_unref(g_var);
1121         }
1122         th->data_usage_cb = NULL;
1123         th->data_usage_user_data = NULL;
1124
1125         DBG("-\n");
1126 }
1127
1128 static void __settings_reloaded_cb(GObject *source_object, GAsyncResult *res,
1129                 gpointer user_data)
1130 {
1131         DBG("+\n");
1132
1133         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
1134         GError *g_error = NULL;
1135         GVariant *g_var;
1136         guint info;
1137         __tethering_h *th = (__tethering_h *)user_data;
1138         tethering_error_e tethering_error = TETHERING_ERROR_NONE;
1139
1140         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
1141         if (g_error) {
1142                 ERR("DBus fail [%s]\n", g_error->message); //LCOV_EXCL_LINE
1143                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
1144                         tethering_error = TETHERING_ERROR_PERMISSION_DENIED;
1145                 else
1146                         tethering_error = TETHERING_ERROR_OPERATION_FAILED;
1147                 g_error_free(g_error);
1148         } else {
1149                 g_variant_get(g_var, "(u)", &info);
1150                 if (tethering_error == TETHERING_ERROR_NONE)
1151                         tethering_error = __get_error(info);
1152                 g_variant_unref(g_var);
1153         }
1154
1155         if (th->settings_reloaded_cb == NULL) {
1156                 DBG("There is no settings_reloaded_cb\n-\n");
1157                 return;
1158         }
1159
1160         th->settings_reloaded_cb(tethering_error,
1161                         th->settings_reloaded_user_data);
1162
1163         th->settings_reloaded_cb = NULL;
1164         th->settings_reloaded_user_data = NULL;
1165         DBG("-\n");
1166 }
1167
1168 static void __connect_signals(tethering_h tethering)
1169 {
1170         DBG("+\n");
1171         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
1172
1173         __tethering_h *th = (__tethering_h *)tethering;
1174         GDBusConnection *connection = th->client_bus;
1175         int i = 0;
1176
1177         for (i = E_SIGNAL_NET_CLOSED; i < E_SIGNAL_MAX; i++) {
1178                 sigs[i].sig_id = g_dbus_connection_signal_subscribe(connection,
1179                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[i].name,
1180                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1181                                 sigs[i].cb, tethering, NULL);
1182         }
1183         DBG("-\n");
1184 }
1185
1186 static void __disconnect_signals(tethering_h tethering)
1187 {
1188         DBG("+\n");
1189
1190         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
1191
1192         __tethering_h *th = (__tethering_h *)tethering;
1193         GDBusConnection *connection = th->client_bus;
1194
1195         int i = 0;
1196
1197         for (i = E_SIGNAL_NET_CLOSED; i < E_SIGNAL_MAX; i++)
1198                 g_dbus_connection_signal_unsubscribe(connection, sigs[i].sig_id);
1199         DBG("-\n");
1200 }
1201
1202
1203
1204 static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len)
1205 {
1206         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
1207
1208         switch (type) {
1209         //LCOV_EXCL_START
1210         case TETHERING_TYPE_USB:
1211                 g_strlcpy(buf, TETHERING_USB_IF, len);
1212                 break;
1213         //LCOV_EXCL_STOP
1214         case TETHERING_TYPE_WIFI:
1215                 g_strlcpy(buf, TETHERING_WIFI_IF, len);
1216                 break;
1217
1218         case TETHERING_TYPE_BT:
1219                 g_strlcpy(buf, TETHERING_BT_IF, len);
1220                 break;
1221
1222         //LCOV_EXCL_START
1223         default:
1224                 ERR("Not supported type : %d\n", type);
1225                 return false;
1226         //LCOV_EXCL_STOP
1227         }
1228         return true;
1229 }
1230
1231 static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int len)
1232 {
1233         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
1234
1235         switch (type) {
1236         //LCOV_EXCL_START
1237         case TETHERING_TYPE_USB:
1238                 g_strlcpy(buf, TETHERING_USB_GATEWAY, len);
1239                 break;
1240         //LCOV_EXCL_STOP
1241         case TETHERING_TYPE_WIFI:
1242                 g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len);
1243                 break;
1244
1245         case TETHERING_TYPE_BT:
1246                 g_strlcpy(buf, TETHERING_BT_GATEWAY, len);
1247                 break;
1248         //LCOV_EXCL_START
1249         default:
1250                 ERR("Not supported type : %d\n", type);
1251                 return false;
1252         //LCOV_EXCL_STOP
1253         }
1254         return true;
1255 }
1256
1257 static int __get_common_ssid(char *ssid, unsigned int size)
1258 {
1259         if (ssid == NULL) {
1260                 ERR("ssid is null\n"); //LCOV_EXCL_LINE
1261                 return TETHERING_ERROR_INVALID_PARAMETER;
1262         }
1263
1264         char *ptr = NULL;
1265         char *ptr_tmp = NULL;
1266
1267         ptr = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1268         if (ptr == NULL) {
1269                 ERR("vconf_get_str is failed and set default ssid");
1270                 g_strlcpy(ssid, TETHERING_DEFAULT_SSID, size);
1271         } else
1272                 g_strlcpy(ssid, ptr, size);
1273
1274         free(ptr);
1275
1276         if (!g_utf8_validate(ssid, -1, (const char **)&ptr_tmp))
1277                 *ptr_tmp = '\0';
1278
1279         return TETHERING_ERROR_NONE;
1280 }
1281
1282 static bool __get_wifi_mode_type(tethering_wifi_mode_type_e type, char **buf)
1283 {
1284         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
1285
1286         switch (type) {
1287         case TETHERING_WIFI_MODE_TYPE_B:
1288                 *buf = g_strdup("b");
1289                 break;
1290         case TETHERING_WIFI_MODE_TYPE_G:
1291                 *buf = g_strdup("g");
1292                 break;
1293         case TETHERING_WIFI_MODE_TYPE_A:
1294                 *buf = g_strdup("a");
1295                 break;
1296         case TETHERING_WIFI_MODE_TYPE_AD:
1297                 *buf = g_strdup("ad");
1298                 break;
1299         default:
1300                 ERR("Not supported type : %d\n", type);
1301                 return false;
1302         }
1303         return true;
1304 }
1305
1306 static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *set)
1307 {
1308         INFO("+\n");
1309
1310         __tethering_h *th = (__tethering_h *)tethering;
1311         tethering_error_e ret = TETHERING_ERROR_NONE;
1312         char *ptr = NULL;
1313
1314         if (th == NULL || set == NULL) {
1315                 ERR("null parameter\n-\n"); //LCOV_EXCL_LINE
1316                 return TETHERING_ERROR_INVALID_PARAMETER;
1317         }
1318
1319         if (th->ssid == NULL)
1320                 __get_common_ssid(set->ssid, sizeof(set->ssid));
1321         else
1322                 g_strlcpy(set->ssid, th->ssid, sizeof(set->ssid));
1323
1324         ret = __get_security_type(&set->sec_type);
1325         if (ret != TETHERING_ERROR_NONE)
1326                 set->sec_type = th->sec_type;
1327
1328         ret = __get_visible(&set->visibility);
1329         if (ret != TETHERING_ERROR_NONE)
1330                 set->visibility = th->visibility;
1331
1332         set->mac_filter = th->mac_filter;
1333         set->max_connected = th->wifi_max_connected;
1334         set->channel = th->channel;
1335
1336         __get_wifi_mode_type(th->mode_type, &ptr);
1337         if (ptr == NULL) {
1338                 g_strlcpy(set->mode, "", sizeof(set->mode));
1339         } else {
1340                 g_strlcpy(set->mode, ptr, sizeof(set->mode));
1341                 free(ptr);
1342         }
1343
1344         if (set->sec_type == TETHERING_WIFI_SECURITY_TYPE_NONE) {
1345                 g_strlcpy(set->key, "", sizeof(set->key));
1346         } else {
1347                 GDBusProxy *proxy = th->client_bus_proxy;
1348                 GVariant *parameters;
1349                 GError *error = NULL;
1350                 char *passphrase = NULL;
1351                 unsigned int len = 0;
1352
1353                 parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_passphrase",
1354                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1355
1356                 if (error) {
1357                         //LCOV_EXCL_START
1358                         ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
1359
1360                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
1361                                 ret = TETHERING_ERROR_PERMISSION_DENIED;
1362                         else
1363                                 ret = TETHERING_ERROR_OPERATION_FAILED;
1364
1365                         g_error_free(error);
1366                         return ret;
1367                         //LCOV_EXCL_STOP
1368                 }
1369
1370                 if (parameters != NULL) {
1371                         g_variant_get(parameters, "(siu)", &passphrase, &len, &ret);
1372                         g_strlcpy(set->key, passphrase, sizeof(set->key) - 1);
1373                         g_free(passphrase);
1374                         g_variant_unref(parameters);
1375                 }
1376         }
1377
1378         INFO("ssid: %s security: %d mode: %s channel: %d visibility: %s\n",
1379                  set->ssid, set->sec_type, set->mode, set->channel,
1380                  (set->visibility) ? "true" : "false");
1381         INFO("-\n");
1382         return TETHERING_ERROR_NONE;
1383 }
1384
1385 static bool __check_precondition(tethering_type_e type)
1386 {
1387         int dnet_status = 0;
1388         int cellular_state = 0;
1389
1390         /* data network through cellular */
1391         vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state);
1392         if (cellular_state == VCONFKEY_NETWORK_CELLULAR_ON) {
1393                 INFO("Data Network can be connected later");
1394                 return TRUE;
1395         }
1396
1397         /* data network status */
1398         vconf_get_int(VCONFKEY_NETWORK_STATUS, &dnet_status);
1399         if ((dnet_status == VCONFKEY_NETWORK_WIFI
1400                         && type != TETHERING_TYPE_WIFI)
1401                 || dnet_status == VCONFKEY_NETWORK_ETHERNET)
1402                 return TRUE;
1403
1404         ERR("Network is not available!");
1405         return FALSE;
1406 }
1407
1408 /**
1409  * @internal
1410  * @brief  Creates the handle of tethering.
1411  * @since_tizen 2.3
1412  * @privlevel platform
1413  * @privilege http://tizen.org/privilege/tethering.admin
1414  * @remarks  The @a tethering must be released tethering_destroy() by you.
1415  * @param[out]  tethering  A handle of a new mobile ap handle on success
1416  * @return  0 on success, otherwise a negative error value.
1417  * @retval  #TETHERING_ERROR_NONE  Successful
1418  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1419  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1420  * @retval  #TETHERING_ERROR_NOT_SUPPORT_API  API is not supported
1421  * @see  tethering_destroy()
1422  */
1423 API int tethering_create(tethering_h *tethering)
1424 {
1425         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1426         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1427                         "parameter(tethering) is NULL\n");
1428         INFO("+\n");
1429
1430         __tethering_h *th = NULL;
1431         GError *error = NULL;
1432         char ssid[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, };
1433
1434         th = (__tethering_h *)malloc(sizeof(__tethering_h));
1435
1436         _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1437                         "malloc is failed\n");
1438         memset(th, 0x00, sizeof(__tethering_h));
1439         th->sec_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
1440         th->visibility = true;
1441         th->mac_filter = false;
1442         th->channel = TETHERING_WIFI_CHANNEL;
1443         th->mode_type = TETHERING_WIFI_MODE_TYPE_G;
1444         th->wifi_max_connected = TETHERING_WIFI_MAX_STA;
1445
1446         if (__generate_initial_passphrase(th->passphrase,
1447                         sizeof(th->passphrase)) == 0) {
1448                 //LCOV_EXCL_START
1449                 ERR("random passphrase generation failed\n");
1450                 free(th);
1451                 return TETHERING_ERROR_OPERATION_FAILED;
1452                 //LCOV_EXCL_STOP
1453         }
1454
1455         if (__get_common_ssid(ssid, sizeof(ssid)) != TETHERING_ERROR_NONE) {
1456                 //LCOV_EXCL_START
1457                 ERR("common ssid get failed\n");
1458                 free(th);
1459                 return TETHERING_ERROR_OPERATION_FAILED;
1460                 //LCOV_EXCL_STOP
1461         }
1462
1463 #if !GLIB_CHECK_VERSION(2, 36, 0)
1464         g_type_init();
1465 #endif
1466         GCancellable *cancellable = g_cancellable_new();
1467         th->client_bus = g_bus_get_sync(DBUS_BUS_SYSTEM, cancellable, &error);
1468         if (error) {
1469                 //LCOV_EXCL_START
1470                 ERR("Couldn't connect to the System bus[%s]", error->message);
1471                 g_error_free(error);
1472                 g_cancellable_cancel(cancellable);
1473                 g_object_unref(cancellable);
1474                 free(th);
1475                 return TETHERING_ERROR_OPERATION_FAILED;
1476                 //LCOV_EXCL_STOP
1477         }
1478         th->cancellable = cancellable;
1479
1480         th->client_bus_proxy = g_dbus_proxy_new_sync(th->client_bus, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
1481                         NULL, TETHERING_SERVICE_NAME, TETHERING_SERVICE_OBJECT_PATH,
1482                         TETHERING_SERVICE_INTERFACE, th->cancellable, &error);
1483         if (!th->client_bus_proxy) {
1484                 //LCOV_EXCL_START
1485                 if (error)
1486                         ERR("Couldn't create the proxy object because of %s\n", error->message);
1487                 g_cancellable_cancel(th->cancellable);
1488                 g_object_unref(th->cancellable);
1489                 g_object_unref(th->client_bus);
1490                 free(th);
1491                 return TETHERING_ERROR_OPERATION_FAILED;
1492                 //LCOV_EXCL_STOP
1493         }
1494
1495         __connect_signals((tethering_h)th);
1496
1497         *tethering = (tethering_h)th;
1498         _tethering_add_handle(th);
1499         INFO("Tethering Handle : %p\n", th);
1500         INFO("-\n");
1501         return TETHERING_ERROR_NONE;
1502 }
1503
1504 /**
1505  * @internal
1506  * @brief  Destroys the handle of tethering.
1507  * @since_tizen 2.3
1508  * @privlevel platform
1509  * @privilege http://tizen.org/privilege/tethering.admin
1510  * @param[in]  tethering  The handle of tethering
1511  * @return  0 on success, otherwise a negative error value.
1512  * @retval  #TETHERING_ERROR_NONE  Successful
1513  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1514  * @see  tethering_create()
1515  */
1516 API int tethering_destroy(tethering_h tethering)
1517 {
1518         INFO("+\n");
1519         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1520         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1521                         "parameter(tethering) is NULL\n");
1522
1523         __tethering_h *th = (__tethering_h *)tethering;
1524
1525         INFO("Tethering Handle : %p\n", th);
1526
1527         __disconnect_signals(tethering);
1528         _tethering_remove_handle(th);
1529
1530         if (th->ssid)
1531                 free(th->ssid);
1532
1533         g_object_unref(th->cancellable);
1534         g_object_unref(th->client_bus_proxy);
1535         g_object_unref(th->client_bus);
1536         memset(th, 0x00, sizeof(__tethering_h));
1537
1538         free(th);
1539
1540         INFO("-\n");
1541         return TETHERING_ERROR_NONE;
1542 }
1543
1544 /**
1545  * @internal
1546  * @brief Enables the tethering, asynchronously.
1547  * @since_tizen 2.3
1548  * @privlevel platform
1549  * @privilege http://tizen.org/privilege/tethering.admin
1550  * @param[in]  tethering  The handle of tethering
1551  * @param[in]  type  The type of tethering
1552  * @return 0 on success, otherwise negative error value.
1553  * @retval  #TETHERING_ERROR_NONE  Successful
1554  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1555  * @post tethering_enabled_cb() will be invoked.
1556  * @see  tethering_is_enabled()
1557  * @see  tethering_disable()
1558  */
1559 API int tethering_enable(tethering_h tethering, tethering_type_e type)
1560 {
1561         INFO("+ type :  %d\n", type);
1562         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1563         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1564         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1565         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1566
1567         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1568                         "parameter(tethering) is NULL\n");
1569
1570         tethering_error_e ret = TETHERING_ERROR_NONE;
1571         __tethering_h *th = (__tethering_h *)tethering;
1572         GDBusProxy *proxy = th->client_bus_proxy;
1573         GDBusConnection *connection = th->client_bus;
1574
1575         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE);
1576
1577         if (__check_precondition(type) == FALSE) {
1578                 //LCOV_EXCL_START
1579                 INFO("-\n");
1580                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1581                 return TETHERING_ERROR_OPERATION_FAILED;
1582                 //LCOV_EXCL_STOP
1583         }
1584
1585         switch (type) {
1586         //LCOV_EXCL_START
1587         case TETHERING_TYPE_USB:
1588                 g_dbus_connection_signal_unsubscribe(connection,
1589                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1590
1591                 g_dbus_proxy_call(proxy, "enable_usb_tethering",
1592                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1593                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1594                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1595                 break;
1596         //LCOV_EXCL_STOP
1597
1598         case TETHERING_TYPE_WIFI: {
1599                 _softap_settings_t set = {"", "", "", 0, false};
1600
1601                 ret = __prepare_wifi_settings(tethering, &set);
1602                 if (ret != TETHERING_ERROR_NONE) {
1603                         //LCOV_EXCL_START
1604                         ERR("softap settings initialization failed\n");
1605                         DBG("-\n");
1606                         return TETHERING_ERROR_OPERATION_FAILED;
1607                         //LCOV_EXCL_STOP
1608                 }
1609                 g_dbus_connection_signal_unsubscribe(connection,
1610                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1611
1612                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1613                                 g_variant_new("(sssiiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type, TETHERING_ADDRESS_FAMILY_IPV4),
1614                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1615                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1616                 break;
1617         }
1618
1619         case TETHERING_TYPE_BT:
1620                 g_dbus_connection_signal_unsubscribe(connection,
1621                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1622
1623                 g_dbus_proxy_call(proxy, "enable_bt_tethering",
1624                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1625                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1626                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1627
1628                 break;
1629
1630         //LCOV_EXCL_START
1631         case TETHERING_TYPE_P2P: {
1632                 _softap_settings_t p2p_set = {"", "", "", 0, false};
1633                 ret = __prepare_wifi_settings(tethering, &p2p_set);
1634                 if (ret != TETHERING_ERROR_NONE) {
1635                         ERR("p2p settings initialization failed\n");
1636                         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1637                         DBG("-\n");
1638                         return TETHERING_ERROR_OPERATION_FAILED;
1639                 }
1640
1641                 g_dbus_proxy_call(proxy, "enable_p2p_tethering",
1642                                 g_variant_new("(ssi)", p2p_set.ssid, p2p_set.key, p2p_set.channel),
1643                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1644                                 (GAsyncReadyCallback) __p2p_enabled_cfm_cb, (gpointer)tethering);
1645                 break;
1646         }
1647
1648         case TETHERING_TYPE_ALL: {
1649                 _softap_settings_t set = {"", "", "", 0, false};
1650
1651                 ret = __prepare_wifi_settings(tethering, &set);
1652                 if (ret != TETHERING_ERROR_NONE) {
1653                         ERR("softap settings initialization failed\n");
1654                         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1655                         return TETHERING_ERROR_OPERATION_FAILED;
1656                 }
1657
1658                 /* TETHERING_TYPE_USB */
1659                 g_dbus_connection_signal_unsubscribe(connection,
1660                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1661
1662                 g_dbus_proxy_call(proxy, "enable_usb_tethering",
1663                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1664                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1665                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1666
1667                 /* TETHERING_TYPE_WIFI */
1668                 g_dbus_connection_signal_unsubscribe(connection,
1669                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1670
1671                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1672                                 g_variant_new("(sssiiiiii)", set.ssid, set.key, set.mode,
1673                                 set.channel, set.visibility, set.mac_filter, set.max_connected,
1674                                 set.sec_type, TETHERING_ADDRESS_FAMILY_IPV4),
1675                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1676                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1677
1678                 /* TETHERING_TYPE_BT */
1679                 g_dbus_connection_signal_unsubscribe(connection,
1680                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1681
1682                 g_dbus_proxy_call(proxy, "enable_bt_tethering",
1683                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1684                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1685                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1686                 break;
1687         }
1688         default:
1689                 ERR("Unknown type : %d\n", type);
1690
1691                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1692
1693                 DBG("-\n");
1694                 return TETHERING_ERROR_INVALID_PARAMETER;
1695         }
1696         //LCOV_EXCL_STOP
1697
1698         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1699         INFO("-\n");
1700         return TETHERING_ERROR_NONE;
1701 }
1702
1703 API int tethering_ipv6_enable(tethering_h tethering, tethering_type_e type)
1704 {
1705         DBG("+ type :  %d\n", type);
1706         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1707         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1708         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1709         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1710
1711         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1712                         "parameter(tethering) is NULL\n");
1713
1714         __tethering_h *th = (__tethering_h *)tethering;
1715         GDBusProxy *proxy = th->client_bus_proxy;
1716         GDBusConnection *connection = th->client_bus;
1717         int ret = 0;
1718
1719         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE);
1720
1721         if (__check_precondition(type) == FALSE) {
1722                 //LCOV_EXCL_START
1723                 DBG("-\n");
1724                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1725                 return TETHERING_ERROR_OPERATION_FAILED;
1726                 //LCOV_EXCL_STOP
1727         }
1728
1729         switch (type) {
1730         case TETHERING_TYPE_USB: {
1731                 g_dbus_connection_signal_unsubscribe(connection,
1732                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1733
1734                 g_dbus_proxy_call(proxy, "enable_usb_tethering",
1735                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1736                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1737                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1738                 break;
1739         }
1740
1741         case TETHERING_TYPE_WIFI: {
1742                 _softap_settings_t set = {"", "", "", 0, false, false, 0, 0};
1743
1744                 ret = __prepare_wifi_settings(tethering, &set);
1745                 if (ret != TETHERING_ERROR_NONE) {
1746                         ERR("softap settings initialization failed\n");
1747                         DBG("-\n");
1748                         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1749                         return TETHERING_ERROR_OPERATION_FAILED;
1750                 }
1751                 g_dbus_connection_signal_unsubscribe(connection,
1752                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1753                         g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1754                                 g_variant_new("(sssiiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type, TETHERING_ADDRESS_FAMILY_IPV6),
1755                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1756                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1757                 break;
1758          }
1759
1760         case TETHERING_TYPE_BT: {
1761                 g_dbus_connection_signal_unsubscribe(connection,
1762                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1763
1764                 g_dbus_proxy_call(proxy, "enable_bt_tethering",
1765                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1766                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1767                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1768
1769                 break;
1770         }
1771
1772         default: {
1773                 ERR("Unknown type : %d\n", type);
1774
1775                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1776
1777                 DBG("-\n");
1778                 return TETHERING_ERROR_INVALID_PARAMETER;
1779         }
1780         }
1781
1782         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1783         DBG("-\n");
1784         return TETHERING_ERROR_NONE;
1785 }
1786
1787 API int tethering_ipv6_disable(tethering_h tethering, tethering_type_e type)
1788 {
1789         DBG("+ type :  %d\n", type);
1790         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1791         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1792         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1793         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1794
1795         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1796                         "parameter(tethering) is NULL\n");
1797
1798         __tethering_h *th = (__tethering_h *)tethering;
1799         GDBusProxy *proxy = th->client_bus_proxy;
1800         GDBusConnection *connection = th->client_bus;
1801
1802         switch (type) {
1803         case TETHERING_TYPE_USB:
1804                 g_dbus_connection_signal_unsubscribe(connection,
1805                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1806
1807                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1808                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1809                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1810                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1811                 break;
1812
1813         case TETHERING_TYPE_WIFI:
1814                 DBG("Disable wifi tethering..");
1815                 g_dbus_connection_signal_unsubscribe(connection,
1816                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1817
1818                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1819                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1820                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1821                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1822                 break;
1823
1824         case TETHERING_TYPE_BT:
1825                 g_dbus_connection_signal_unsubscribe(connection,
1826                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1827
1828                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1829                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1830                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1831                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1832                 break;
1833
1834         default:
1835                 ERR("Not supported tethering type [%d]\n", type);
1836                 DBG("-\n");
1837                 return TETHERING_ERROR_INVALID_PARAMETER;
1838         }
1839         DBG("-\n");
1840         return TETHERING_ERROR_NONE;
1841 }
1842 /**
1843  * @internal
1844  * @brief Disables the tethering, asynchronously.
1845  * @since_tizen 2.3
1846  * @privlevel platform
1847  * @privilege http://tizen.org/privilege/tethering.admin
1848  * @param[in]  tethering  The handle of tethering
1849  * @param[in]  type  The type of tethering
1850  * @return 0 on success, otherwise negative error value.
1851  * @retval  #TETHERING_ERROR_NONE  Successful
1852  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1853  * @post tethering_disabled_cb() will be invoked.
1854  * @see  tethering_is_enabled()
1855  * @see  tethering_enable()
1856  */
1857 API int tethering_disable(tethering_h tethering, tethering_type_e type)
1858 {
1859         INFO("+ type :  %d\n", type);
1860         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1861         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1862         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1863         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1864
1865         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1866                         "parameter(tethering) is NULL\n");
1867
1868         __tethering_h *th = (__tethering_h *)tethering;
1869         GDBusProxy *proxy = th->client_bus_proxy;
1870         GDBusConnection *connection = th->client_bus;
1871
1872         switch (type) {
1873         //LCOV_EXCL_START
1874         case TETHERING_TYPE_USB:
1875                 g_dbus_connection_signal_unsubscribe(connection,
1876                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1877
1878                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1879                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1880                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1881                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1882
1883                 break;
1884         //LCOV_EXCL_STOP
1885
1886         case TETHERING_TYPE_WIFI:
1887
1888                 g_dbus_connection_signal_unsubscribe(connection,
1889                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1890
1891                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1892                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1893                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1894                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1895                 break;
1896
1897         case TETHERING_TYPE_BT:
1898
1899                 g_dbus_connection_signal_unsubscribe(connection,
1900                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1901
1902                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1903                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1904                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1905                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1906                 break;
1907
1908         //LCOV_EXCL_START
1909         case TETHERING_TYPE_P2P:
1910                 g_dbus_proxy_call(proxy, "disable_p2p_tethering",
1911                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1912                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1913                 break;
1914
1915         case TETHERING_TYPE_ALL:
1916                 g_dbus_connection_signal_unsubscribe(connection,
1917                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1918
1919                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1920                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1921                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1922                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1923
1924                 g_dbus_connection_signal_unsubscribe(connection,
1925                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1926
1927                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1928                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1929                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1930                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1931
1932                 g_dbus_connection_signal_unsubscribe(connection,
1933                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1934
1935                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1936                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1937                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1938                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1939                 break;
1940
1941         default:
1942                 ERR("Not supported tethering type [%d]\n", type);
1943                 DBG("-\n");
1944                 return TETHERING_ERROR_INVALID_PARAMETER;
1945         //LCOV_EXCL_STOP
1946         }
1947         INFO("-\n");
1948         return TETHERING_ERROR_NONE;
1949 }
1950
1951 /**
1952  * @internal
1953  * @brief  Checks whetehr the tethering is enabled or not.
1954  * @since_tizen 2.3
1955  * @privlevel platform
1956  * @privilege http://tizen.org/privilege/tethering.admin
1957  * @param[in]  tethering  The handle of tethering
1958  * @param[in]  type  The type of tethering
1959  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
1960  */
1961 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
1962 {
1963         INFO("+ type :  %d\n", type);
1964         int is_on = 0;
1965         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
1966
1967         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1968
1969         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0)
1970                 return FALSE;
1971
1972         switch (type) {
1973         case TETHERING_TYPE_USB:
1974                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
1975                 break;
1976
1977         case TETHERING_TYPE_WIFI:
1978                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
1979                 break;
1980
1981         case TETHERING_TYPE_BT:
1982                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
1983                 break;
1984
1985         case TETHERING_TYPE_P2P:
1986                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_P2P;
1987                 break;
1988
1989         default:
1990                 ERR("Not supported type : %d\n", type);
1991                 break;
1992         }
1993         INFO("- enabled:  %s\n", (is_on & vconf_type) ? "true" : "false");
1994         return is_on & vconf_type ? true : false;
1995 }
1996
1997 /**
1998  * @internal
1999  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
2000  * @since_tizen 2.3
2001  * @privlevel platform
2002  * @privilege http://tizen.org/privilege/tethering.admin
2003  * @remarks @a mac_address must be released with free() by you.
2004  * @param[in]  tethering  The handle of tethering
2005  * @param[in]  type  The type of tethering
2006  * @param[out]  mac_address  The MAC address
2007  * @return  0 on success, otherwise a negative error value.
2008  * @retval  #TETHERING_ERROR_NONE  Successful
2009  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2010  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2011  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2012  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2013  * @pre  tethering must be enabled.
2014  * @see  tethering_is_enabled()
2015  * @see  tethering_enable()
2016  */
2017 API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
2018 {
2019         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2020         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); //LCOV_EXCL_LINE
2021         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2022         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); //LCOV_EXCL_LINE
2023
2024         _retvm_if(tethering_is_enabled(tethering, type) == false,
2025                         TETHERING_ERROR_NOT_ENABLED,
2026                         "tethering type[%d] is not enabled\n", type);
2027         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2028                         "parameter(tethering) is NULL\n");
2029         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2030                         "parameter(mac_address) is NULL\n");
2031
2032         struct ifreq ifr;
2033         int s = 0;
2034         char *macbuf = NULL;
2035
2036         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
2037                         TETHERING_ERROR_OPERATION_FAILED,
2038                         "getting interface name is failed\n");
2039
2040         s = socket(AF_INET, SOCK_DGRAM, 0);
2041         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
2042                         "getting socket is failed\n");
2043         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
2044                 //LCOV_EXCL_START
2045                 ERR("getting mac is failed\n");
2046                 close(s);
2047                 return TETHERING_ERROR_OPERATION_FAILED;
2048                 //LCOV_EXCL_STOP
2049         }
2050         close(s);
2051
2052         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
2053         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2054                         "Not enough memory\n");
2055         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
2056                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
2057                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
2058                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
2059                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
2060                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
2061                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
2062
2063         *mac_address = macbuf;
2064
2065         return TETHERING_ERROR_NONE;
2066 }
2067
2068 /**
2069  * @internal
2070  * @brief Gets the name of network interface. For example, usb0.
2071  * @since_tizen 2.3
2072  * @privlevel platform
2073  * @privilege http://tizen.org/privilege/tethering.admin
2074  * @remarks @a interface_name must be released with free() by you.
2075  * @param[in]  tethering  The handle of tethering
2076  * @param[in]  type  The type of tethering
2077  * @param[out]  interface_name  The name of network interface
2078  * @return 0 on success, otherwise negative error value.
2079  * @retval  #TETHERING_ERROR_NONE  Successful
2080  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2081  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2082  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2083  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2084  * @pre  tethering must be enabled.
2085  * @see  tethering_is_enabled()
2086  * @see  tethering_enable()
2087  */
2088 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
2089 {
2090         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2091         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2092         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2093         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2094
2095         _retvm_if(tethering_is_enabled(tethering, type) == false,
2096                         TETHERING_ERROR_NOT_ENABLED,
2097                         "tethering type[%d] is not enabled\n", type);
2098         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2099                         "parameter(tethering) is NULL\n");
2100         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2101                         "parameter(interface_name) is NULL\n");
2102
2103         char intf[TETHERING_STR_INFO_LEN] = {0, };
2104
2105         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
2106                         TETHERING_ERROR_OPERATION_FAILED,
2107                         "getting interface name is failed\n");
2108         *interface_name = strdup(intf);
2109         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2110                         "Not enough memory\n");
2111
2112         return TETHERING_ERROR_NONE;
2113 }
2114
2115 /**
2116  * @internal
2117  * @brief Gets the local IP address.
2118  * @since_tizen 2.3
2119  * @privlevel platform
2120  * @privilege http://tizen.org/privilege/tethering.admin
2121  * @remarks @a ip_address must be released with free() by you.
2122  * @param[in]  tethering  The handle of tethering
2123  * @param[in]  type  The type of tethering
2124  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2125  * @param[out]  ip_address  The local IP address
2126  * @return 0 on success, otherwise negative error value.
2127  * @retval  #TETHERING_ERROR_NONE  Successful
2128  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2129  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2130  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2131  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2132  * @pre  tethering must be enabled.
2133  * @see  tethering_is_enabled()
2134  * @see  tethering_enable()
2135  */
2136 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
2137 {
2138         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2139         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); //LCOV_EXCL_LINE
2140         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2141         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); //LCOV_EXCL_LINE
2142
2143         _retvm_if(tethering_is_enabled(tethering, type) == false,
2144                         TETHERING_ERROR_NOT_ENABLED,
2145                         "tethering type[%d] is not enabled\n", type);
2146         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2147                         "parameter(tethering) is NULL\n");
2148         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2149                         "parameter(ip_address) is NULL\n");
2150
2151         struct ifreq ifr;
2152         int s = 0;
2153         char *ipbuf = NULL;
2154
2155         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
2156                         TETHERING_ERROR_OPERATION_FAILED,
2157                         "getting interface name is failed\n");
2158
2159         s = socket(AF_INET, SOCK_DGRAM, 0);
2160         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
2161                         "getting socket is failed\n");
2162         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
2163                 ERR("ioctl is failed\n");
2164                 close(s);
2165                 return TETHERING_ERROR_OPERATION_FAILED;
2166         }
2167         close(s);
2168
2169         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
2170         *ip_address = strdup(ipbuf);
2171         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2172                         "Not enough memory\n");
2173
2174         return TETHERING_ERROR_NONE;
2175 }
2176
2177 /**
2178  * @internal
2179  * @brief Gets the Gateway address.
2180  * @since_tizen 2.3
2181  * @privlevel platform
2182  * @privilege http://tizen.org/privilege/tethering.admin
2183  * @remarks @a gateway_address must be released with free() by you.
2184  * @param[in]  tethering  The handle of tethering
2185  * @param[in]  type  The type of tethering
2186  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2187  * @param[out]  gateway_address  The local IP address
2188  * @return 0 on success, otherwise negative error value.
2189  * @retval  #TETHERING_ERROR_NONE  Successful
2190  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2191  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2192  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2193  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2194  * @pre  tethering must be enabled.
2195  * @see  tethering_is_enabled()
2196  * @see  tethering_enable()
2197  */
2198 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
2199 {
2200         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2201         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2202         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2203         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2204
2205         _retvm_if(tethering_is_enabled(tethering, type) == false,
2206                         TETHERING_ERROR_NOT_ENABLED,
2207                         "tethering type[%d] is not enabled\n", type);
2208         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2209                         "parameter(tethering) is NULL\n");
2210         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2211                         "parameter(gateway_address) is NULL\n");
2212
2213         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
2214
2215         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
2216                         TETHERING_ERROR_OPERATION_FAILED,
2217                         "getting gateway address is failed\n");
2218
2219         *gateway_address = strdup(gateway_buf);
2220
2221         return TETHERING_ERROR_NONE;
2222 }
2223
2224 /**
2225  * @internal
2226  * @brief Gets the Subnet Mask.
2227  * @since_tizen 2.3
2228  * @privlevel platform
2229  * @privilege http://tizen.org/privilege/tethering.admin
2230  * @remarks @a subnet_mask must be released with free() by you.
2231  * @param[in]  tethering  The handle of tethering
2232  * @param[in]  type  The type of tethering
2233  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2234  * @param[out]  subnet_mask  The local IP address
2235  * @return 0 on success, otherwise negative error value.
2236  * @retval  #TETHERING_ERROR_NONE  Successful
2237  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2238  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2239  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2240  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2241  * @pre  tethering must be enabled.
2242  * @see  tethering_is_enabled()
2243  * @see  tethering_enable()
2244  */
2245 API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
2246 {
2247         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2248         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2249         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2250         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2251
2252         _retvm_if(tethering_is_enabled(tethering, type) == false,
2253                         TETHERING_ERROR_NOT_ENABLED,
2254                         "tethering is not enabled\n");
2255         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2256                         "parameter(tethering) is NULL\n");
2257         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2258                         "parameter(subnet_mask) is NULL\n");
2259
2260         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
2261         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2262                         "Not enough memory\n");
2263
2264         return TETHERING_ERROR_NONE;
2265 }
2266
2267 /**
2268  * @internal
2269  * @brief Gets the data usage.
2270  * @since_tizen 2.3
2271  * @privlevel platform
2272  * @privilege http://tizen.org/privilege/tethering.admin
2273  * @param[in]  tethering  The handle of tethering
2274  * @param[out]  usage  The data usage
2275  * @return 0 on success, otherwise negative error value.
2276  * @retval  #TETHERING_ERROR_NONE  Successful
2277  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2278  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2279  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2280  * @pre  tethering must be enabled.
2281  * @see  tethering_is_enabled()
2282  * @see  tethering_enable()
2283  */
2284 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
2285 {
2286         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2287
2288         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2289                         "parameter(tethering) is NULL\n");
2290         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2291                         "parameter(callback) is NULL\n");
2292         _retvm_if(__any_tethering_is_enabled(tethering) == false,
2293                         TETHERING_ERROR_NOT_ENABLED,
2294                         "tethering is not enabled\n");
2295
2296         __tethering_h *th = (__tethering_h *)tethering;
2297         GDBusProxy *proxy = th->client_bus_proxy;
2298
2299         th->data_usage_cb = callback;
2300         th->data_usage_user_data = user_data;
2301
2302         g_dbus_proxy_call(proxy, "get_data_packet_usage",
2303                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
2304                         (GAsyncReadyCallback) __get_data_usage_cb, (gpointer)tethering);
2305
2306         return TETHERING_ERROR_NONE;
2307 }
2308
2309 /**
2310  * @internal
2311  * @brief Gets the client which is connected by tethering "type".
2312  * @since_tizen 2.3
2313  * @privlevel platform
2314  * @privilege http://tizen.org/privilege/tethering.admin
2315  * @param[in]  tethering  The handle of tethering
2316  * @param[in]  type  The type of tethering
2317  * @param[in]  callback  The callback function to invoke
2318  * @param[in]  user_data  The user data to be passed to the callback function
2319  * @retval  #TETHERING_ERROR_NONE  Successful
2320  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2321  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2322  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2323  * @pre  tethering must be enabled.
2324  * @see  tethering_is_enabled()
2325  * @see  tethering_enable()
2326  */
2327 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
2328 {
2329         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2330         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2331         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2332         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2333
2334         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2335                         "parameter(tethering) is NULL\n");
2336         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2337                         "parameter(callback) is NULL\n");
2338         _retvm_if(__any_tethering_is_enabled(tethering) == false,
2339                         TETHERING_ERROR_NOT_ENABLED,
2340                         "tethering is not enabled\n");
2341
2342         mobile_ap_type_e interface;
2343         __tethering_h *th = (__tethering_h *)tethering;
2344         __tethering_client_h client = {0, };
2345         gchar *ip = NULL;
2346         gchar *mac = NULL;
2347         gchar *hostname = NULL;
2348         guint timestamp = 0;
2349         GError *error = NULL;
2350         GVariant *result = NULL;
2351         GVariantIter *outer_iter = NULL;
2352         GVariantIter *inner_iter = NULL;
2353         GVariant *station = NULL;
2354         GVariant *value = NULL;
2355         gchar *key = NULL;
2356
2357         result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_station_info",
2358                         NULL, G_DBUS_CALL_FLAGS_NONE,
2359                         -1, th->cancellable, &error);
2360         if (error)
2361                 ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); //LCOV_EXCL_LINE
2362         g_variant_get(result, "(a(a{sv}))", &outer_iter);
2363         //LCOV_EXCL_START
2364         while (g_variant_iter_loop(outer_iter, "(@a{sv})", &station)) {
2365                 g_variant_get(station, "a{sv}", &inner_iter);
2366                 while (g_variant_iter_loop(inner_iter, "{sv}", &key, &value)) {
2367                         if (g_strcmp0(key, "Type") == 0) {
2368                                 interface = g_variant_get_int32(value);
2369                                 if (interface == MOBILE_AP_TYPE_USB)
2370                                         client.interface = TETHERING_TYPE_USB;
2371                                 else if (interface == MOBILE_AP_TYPE_WIFI)
2372                                         client.interface = TETHERING_TYPE_WIFI;
2373                                 else if (interface == MOBILE_AP_TYPE_BT)
2374                                         client.interface = TETHERING_TYPE_BT;
2375                                 else if (interface == MOBILE_AP_TYPE_P2P)
2376                                         client.interface = TETHERING_TYPE_P2P;
2377                                 else {
2378                                         ERR("Invalid interface\n");
2379                                         g_free(key);
2380                                         g_variant_unref(value);
2381                                         break;
2382                                 }
2383                                 DBG("interface is %d\n", client.interface);
2384                                 if (client.interface != type && (TETHERING_TYPE_ALL != type)) {
2385                                         g_free(key);
2386                                         g_variant_unref(value);
2387                                         break;
2388                                 }
2389                         } else if (g_strcmp0(key, "IP") == 0) {
2390                                 g_variant_get(value, "s", &ip);
2391                                 SDBG("ip is %s\n", ip);
2392                                 g_strlcpy(client.ip, ip, sizeof(client.ip));
2393                         } else if (g_strcmp0(key, "MAC") == 0) {
2394                                 g_variant_get(value, "s", &mac);
2395                                 SDBG("mac is %s\n", mac);
2396                                 g_strlcpy(client.mac, mac, sizeof(client.mac));
2397                         } else if (g_strcmp0(key, "Name") == 0) {
2398                                 g_variant_get(value, "s", &hostname);
2399                                 SDBG("hsotname is %s\n", hostname);
2400                                 if (hostname)
2401                                         client.hostname = g_strdup(hostname);
2402                         } else if (g_strcmp0(key, "Time") == 0) {
2403                                 timestamp = g_variant_get_int32(value);
2404                                 DBG("timestamp is %d\n", timestamp);
2405                                 client.tm = (time_t)timestamp;
2406                         } else {
2407                                 ERR("Key %s not required\n", key);
2408                         }
2409                 }
2410                 g_free(hostname);
2411                 g_free(ip);
2412                 g_free(mac);
2413
2414                 hostname = NULL;
2415                 ip = NULL;
2416                 mac = NULL;
2417
2418                 g_variant_iter_free(inner_iter);
2419                 if (callback((tethering_client_h)&client, user_data) == false) {
2420                         DBG("iteration is stopped\n");
2421                         g_free(client.hostname);
2422                         client.hostname = NULL;
2423                         g_variant_iter_free(outer_iter);
2424                         g_variant_unref(station);
2425                         g_variant_unref(result);
2426                         DBG("-\n");
2427                         return TETHERING_ERROR_OPERATION_FAILED;
2428                 }
2429                 g_free(client.hostname);
2430                 client.hostname = NULL;
2431         }
2432         //LCOV_EXCL_STOP
2433         g_variant_iter_free(outer_iter);
2434         g_variant_unref(station);
2435         g_variant_unref(result);
2436         DBG("-\n");
2437         return TETHERING_ERROR_NONE;
2438 }
2439
2440 /**
2441  * @internal
2442  * @brief Registers the callback function called when tethering is enabled.
2443  * @since_tizen 2.3
2444  * @privlevel platform
2445  * @privilege http://tizen.org/privilege/tethering.admin
2446  * @param[in]  tethering  The handle of tethering
2447  * @param[in]  type  The type of tethering
2448  * @param[in]  callback  The callback function to invoke
2449  * @param[in]  user_data  The user data to be passed to the callback function
2450  * @retval  #TETHERING_ERROR_NONE  Successful
2451  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2452  * @see  tethering_unset_enabled_cb()
2453  */
2454 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
2455 {
2456         INFO("+ type: %d\n", type);
2457         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2458         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2459         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2460         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2461
2462         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2463                         "parameter(tethering) is NULL\n");
2464         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2465                         "parameter(callback) is NULL\n");
2466
2467         __tethering_h *th = (__tethering_h *)tethering;
2468         tethering_type_e ti;
2469
2470         if (type != TETHERING_TYPE_ALL) {
2471                 th->enabled_cb[type] = callback;
2472                 th->enabled_user_data[type] = user_data;
2473
2474                 return TETHERING_ERROR_NONE;
2475         }
2476
2477         /* TETHERING_TYPE_ALL */
2478         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2479                 th->enabled_cb[ti] = callback;
2480                 th->enabled_user_data[ti] = user_data;
2481         }
2482
2483         INFO("-\n");
2484         return TETHERING_ERROR_NONE;
2485 }
2486
2487 /**
2488  * @internal
2489  * @brief Unregisters the callback function called when tethering is disabled.
2490  * @since_tizen 2.3
2491  * @privlevel platform
2492  * @privilege http://tizen.org/privilege/tethering.admin
2493  * @param[in]  tethering  The handle of tethering
2494  * @param[in]  type  The type of tethering
2495  * @retval  #TETHERING_ERROR_NONE  Successful
2496  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2497  * @see  tethering_set_enabled_cb()
2498  */
2499 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
2500 {
2501         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2502         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2503         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2504         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2505
2506         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2507                         "parameter(tethering) is NULL\n");
2508
2509         __tethering_h *th = (__tethering_h *)tethering;
2510         tethering_type_e ti;
2511
2512         if (type != TETHERING_TYPE_ALL) {
2513                 th->enabled_cb[type] = NULL;
2514                 th->enabled_user_data[type] = NULL;
2515
2516                 return TETHERING_ERROR_NONE;
2517         }
2518
2519         /* TETHERING_TYPE_ALL */
2520         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2521                 th->enabled_cb[ti] = NULL;
2522                 th->enabled_user_data[ti] = NULL;
2523         }
2524
2525         return TETHERING_ERROR_NONE;
2526 }
2527
2528 /**
2529  * @internal
2530  * @brief Registers the callback function called when tethering is disabled.
2531  * @since_tizen 2.3
2532  * @privlevel platform
2533  * @privilege http://tizen.org/privilege/tethering.admin
2534  * @param[in]  tethering  The handle of tethering
2535  * @param[in]  type  The type of tethering
2536  * @param[in]  callback  The callback function to invoke
2537  * @param[in]  user_data  The user data to be passed to the callback function
2538  * @retval  #TETHERING_ERROR_NONE  Successful
2539  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2540  * @see  tethering_unset_disabled_cb()
2541  */
2542 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
2543 {
2544         INFO("+ type: %d\n", type);
2545         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2546         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2547         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2548         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2549
2550         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2551                         "parameter(tethering) is NULL\n");
2552         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2553                         "parameter(callback) is NULL\n");
2554
2555         __tethering_h *th = (__tethering_h *)tethering;
2556         tethering_type_e ti;
2557
2558         if (type != TETHERING_TYPE_ALL) {
2559                 th->disabled_cb[type] = callback;
2560                 th->disabled_user_data[type] = user_data;
2561
2562                 return TETHERING_ERROR_NONE;
2563         }
2564
2565         /* TETHERING_TYPE_ALL */
2566         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2567                 th->disabled_cb[ti] = callback;
2568                 th->disabled_user_data[ti] = user_data;
2569         }
2570         INFO("-\n");
2571         return TETHERING_ERROR_NONE;
2572 }
2573
2574 /**
2575  * @internal
2576  * @brief Unregisters the callback function called when tethering is disabled.
2577  * @since_tizen 2.3
2578  * @privlevel platform
2579  * @privilege http://tizen.org/privilege/tethering.admin
2580  * @param[in]  tethering  The handle of tethering
2581  * @param[in]  type  The type of tethering
2582  * @retval  #TETHERING_ERROR_NONE  Successful
2583  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2584  * @see  tethering_set_disabled_cb()
2585  */
2586 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
2587 {
2588         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2589         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2590         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2591         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2592
2593         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2594                         "parameter(tethering) is NULL\n");
2595
2596         __tethering_h *th = (__tethering_h *)tethering;
2597         tethering_type_e ti;
2598
2599         if (type != TETHERING_TYPE_ALL) {
2600                 th->disabled_cb[type] = NULL;
2601                 th->disabled_user_data[type] = NULL;
2602
2603                 return TETHERING_ERROR_NONE;
2604         }
2605
2606         /* TETHERING_TYPE_ALL */
2607         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2608                 th->disabled_cb[ti] = NULL;
2609                 th->disabled_user_data[ti] = NULL;
2610         }
2611
2612         return TETHERING_ERROR_NONE;
2613 }
2614
2615 /**
2616  * @internal
2617  * @brief Registers the callback function called when the state of connection is changed.
2618  * @since_tizen 2.3
2619  * @privlevel platform
2620  * @privilege http://tizen.org/privilege/tethering.admin
2621  * @param[in]  tethering  The handle of tethering
2622  * @param[in]  type  The type of tethering
2623  * @param[in]  callback  The callback function to invoke
2624  * @param[in]  user_data  The user data to be passed to the callback function
2625  * @retval  #TETHERING_ERROR_NONE  Successful
2626  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2627  * @see  tethering_unset_connection_state_changed_cb_cb()
2628  */
2629 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
2630 {
2631         INFO("+ type: %d\n", type);
2632         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2633         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2634         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2635         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2636
2637         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2638                         "parameter(tethering) is NULL\n");
2639         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2640                         "parameter(callback) is NULL\n");
2641
2642         __tethering_h *th = (__tethering_h *)tethering;
2643         tethering_type_e ti;
2644
2645         if (type != TETHERING_TYPE_ALL) {
2646                 th->changed_cb[type] = callback;
2647                 th->changed_user_data[type] = user_data;
2648
2649                 return TETHERING_ERROR_NONE;
2650         }
2651
2652         /* TETHERING_TYPE_ALL */
2653         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2654                 th->changed_cb[ti] = callback;
2655                 th->changed_user_data[ti] = user_data;
2656         }
2657         INFO("-\n");
2658         return TETHERING_ERROR_NONE;
2659 }
2660
2661 /**
2662  * @internal
2663  * @brief Unregisters the callback function called when the state of connection is changed.
2664  * @since_tizen 2.3
2665  * @privlevel platform
2666  * @privilege http://tizen.org/privilege/tethering.admin
2667  * @param[in]  tethering  The handle of tethering
2668  * @param[in]  type  The type of tethering
2669  * @retval  #TETHERING_ERROR_NONE  Successful
2670  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2671  * @see  tethering_set_connection_state_changed_cb()
2672  */
2673 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
2674 {
2675         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2676         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2677         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2678         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2679
2680         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2681                         "parameter(tethering) is NULL\n");
2682
2683         __tethering_h *th = (__tethering_h *)tethering;
2684         tethering_type_e ti;
2685
2686         if (type != TETHERING_TYPE_ALL) {
2687                 th->changed_cb[type] = NULL;
2688                 th->changed_user_data[type] = NULL;
2689
2690                 return TETHERING_ERROR_NONE;
2691         }
2692
2693         /* TETHERING_TYPE_ALL */
2694         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2695                 th->changed_cb[ti] = NULL;
2696                 th->changed_user_data[ti] = NULL;
2697         }
2698
2699         return TETHERING_ERROR_NONE;
2700 }
2701
2702 /**
2703  * @internal
2704  * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed.
2705  * @since_tizen 2.3
2706  * @privlevel platform
2707  * @privilege http://tizen.org/privilege/tethering.admin
2708  * @param[in]  tethering  The handle of tethering
2709  * @param[in]  callback  The callback function to invoke
2710  * @param[in]  user_data  The user data to be passed to the callback function
2711  * @retval  #TETHERING_ERROR_NONE  Successful
2712  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2713  * @see  tethering_wifi_unset_security_type_changed_cb()
2714  */
2715 API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data)
2716 {
2717         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2718         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2719
2720         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2721                         "parameter(tethering) is NULL\n");
2722         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2723                         "parameter(callback) is NULL\n");
2724
2725         __tethering_h *th = (__tethering_h *)tethering;
2726
2727         th->security_type_changed_cb = callback;
2728         th->security_type_user_data = user_data;
2729
2730         return TETHERING_ERROR_NONE;
2731
2732 }
2733
2734 /**
2735  * @internal
2736  * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed.
2737  * @since_tizen 2.3
2738  * @privlevel platform
2739  * @privilege http://tizen.org/privilege/tethering.admin
2740  * @param[in]  tethering  The handle of tethering
2741  * @param[in]  type  The type of tethering
2742  * @retval  #TETHERING_ERROR_NONE  Successful
2743  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2744  * @see  tethering_wifi_set_security_type_changed_cb()
2745  */
2746 API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering)
2747 {
2748         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2749         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2750
2751         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2752                         "parameter(tethering) is NULL\n");
2753
2754         __tethering_h *th = (__tethering_h *)tethering;
2755
2756         th->security_type_changed_cb = NULL;
2757         th->security_type_user_data = NULL;
2758
2759         return TETHERING_ERROR_NONE;
2760 }
2761
2762 /**
2763  * @internal
2764  * @brief Registers the callback function called when the visibility of SSID is changed.
2765  * @since_tizen 2.3
2766  * @privlevel platform
2767  * @privilege http://tizen.org/privilege/tethering.admin
2768  * @param[in]  tethering  The handle of tethering
2769  * @param[in]  callback  The callback function to invoke
2770  * @param[in]  user_data  The user data to be passed to the callback function
2771  * @retval  #TETHERING_ERROR_NONE  Successful
2772  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2773  * @see  tethering_wifi_unset_ssid_visibility_changed_cb_cb()
2774  */
2775 API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data)
2776 {
2777         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2778         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2779
2780         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2781                         "parameter(tethering) is NULL\n");
2782         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2783                         "parameter(callback) is NULL\n");
2784
2785         __tethering_h *th = (__tethering_h *)tethering;
2786
2787         th->ssid_visibility_changed_cb = callback;
2788         th->ssid_visibility_user_data = user_data;
2789
2790         return TETHERING_ERROR_NONE;
2791 }
2792
2793 /**
2794  * @internal
2795  * @brief Unregisters the callback function called when the visibility of SSID is changed.
2796  * @since_tizen 2.3
2797  * @privlevel platform
2798  * @privilege http://tizen.org/privilege/tethering.admin
2799  * @param[in]  tethering  The handle of tethering
2800  * @retval  #TETHERING_ERROR_NONE  Successful
2801  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2802  * @see  tethering_wifi_set_ssid_visibility_changed_cb()
2803  */
2804 API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering)
2805 {
2806         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2807         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2808
2809         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2810                         "parameter(tethering) is NULL\n");
2811
2812         __tethering_h *th = (__tethering_h *)tethering;
2813
2814         th->ssid_visibility_changed_cb = NULL;
2815         th->ssid_visibility_user_data = NULL;
2816
2817         return TETHERING_ERROR_NONE;
2818 }
2819
2820 /**
2821  * @internal
2822  * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed.
2823  * @since_tizen 2.3
2824  * @privlevel platform
2825  * @privilege http://tizen.org/privilege/tethering.admin
2826  * @param[in]  tethering  The handle of tethering
2827  * @param[in]  callback  The callback function to invoke
2828  * @param[in]  user_data  The user data to be passed to the callback function
2829  * @retval  #TETHERING_ERROR_NONE  Successful
2830  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2831  * @see  tethering_wifi_unset_passphrase_changed_cb()
2832  */
2833 API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data)
2834 {
2835         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2836         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2837
2838         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2839                         "parameter(tethering) is NULL\n");
2840         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2841                         "parameter(callback) is NULL\n");
2842
2843         __tethering_h *th = (__tethering_h *)tethering;
2844
2845         th->passphrase_changed_cb = callback;
2846         th->passphrase_user_data = user_data;
2847
2848         return TETHERING_ERROR_NONE;
2849 }
2850
2851 /**
2852  * @internal
2853  * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed.
2854  * @since_tizen 2.3
2855  * @privlevel platform
2856  * @privilege http://tizen.org/privilege/tethering.admin
2857  * @param[in]  tethering  The handle of tethering
2858  * @retval  #TETHERING_ERROR_NONE  Successful
2859  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2860  * @see  tethering_wifi_set_passphrase_changed_cb()
2861  */
2862 API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering)
2863 {
2864         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2865         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2866
2867         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2868                         "parameter(tethering) is NULL\n");
2869
2870         __tethering_h *th = (__tethering_h *)tethering;
2871
2872         th->passphrase_changed_cb = NULL;
2873         th->passphrase_user_data = NULL;
2874
2875         return TETHERING_ERROR_NONE;
2876 }
2877
2878 /**
2879  * @internal
2880  * @brief Sets the security type of Wi-Fi tethering.
2881  * @since_tizen 2.3
2882  * @privlevel platform
2883  * @privilege http://tizen.org/privilege/tethering.admin
2884  * @remarks This change is applied next time Wi-Fi tethering is enabled
2885  * @param[in]  tethering  The handle of tethering
2886  * @param[in]  type  The security type
2887  * @return 0 on success, otherwise negative error value.
2888  * @retval  #TETHERING_ERROR_NONE  Successful
2889  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2890  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2891  * @see  tethering_wifi_get_security_type()
2892  */
2893 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
2894 {
2895         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2896         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2897
2898         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2899                         "parameter(tethering) is NULL\n");
2900
2901         __tethering_h *th = (__tethering_h *)tethering;
2902         tethering_error_e ret = TETHERING_ERROR_NONE;
2903         char *sec_str = NULL;
2904
2905         ret = __set_security_type(type);
2906         if (ret == TETHERING_ERROR_NONE) {
2907
2908                 switch (type) {
2909                 case TETHERING_WIFI_SECURITY_TYPE_NONE:
2910                         sec_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
2911                         break;
2912                 case TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK:
2913                         sec_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
2914                         break;
2915                 case TETHERING_WIFI_SECURITY_TYPE_WPS:
2916                         sec_str = TETHERING_WIFI_SECURITY_TYPE_WPS_STR;
2917                         break;
2918                 case TETHERING_WIFI_SECURITY_TYPE_SAE:
2919                         sec_str = TETHERING_WIFI_SECURITY_TYPE_SAE_STR;
2920                         break;
2921                 }
2922
2923                 __send_dbus_signal(th->client_bus,
2924                                 SIGNAL_NAME_SECURITY_TYPE_CHANGED, sec_str);
2925         }
2926         return ret;
2927 }
2928
2929 /**
2930  * @internal
2931  * @brief Gets the security type of Wi-Fi tethering.
2932  * @since_tizen 2.3
2933  * @privlevel platform
2934  * @privilege http://tizen.org/privilege/tethering.admin
2935  * @param[in]  tethering  The handle of tethering
2936  * @param[out]  type  The security type
2937  * @return 0 on success, otherwise negative error value.
2938  * @retval  #TETHERING_ERROR_NONE  Successful
2939  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2940  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2941  * @see  tethering_wifi_set_security_type()
2942  */
2943 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
2944 {
2945         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2946         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2947
2948         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2949                         "parameter(type) is NULL\n");
2950
2951         return __get_security_type(type);
2952 }
2953
2954 /**
2955  * @internal
2956  * @brief Sets the SSID (service set identifier).
2957  * @since_tizen 2.3
2958  * @privlevel platform
2959  * @privilege http://tizen.org/privilege/tethering.admin
2960  * @details If SSID is not set, Device name is used as SSID
2961  * @remarks This change is applied next time Wi-Fi tethering is enabled with same @a tethering handle
2962  * @param[in]  tethering  The handle of tethering
2963  * @param[out]  ssid  The SSID
2964  * @return 0 on success, otherwise negative error value.
2965  * @retval  #TETHERING_ERROR_NONE  Successful
2966  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2967  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2968  */
2969 API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid)
2970 {
2971         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2972         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2973
2974         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2975                         "parameter(tethering) is NULL\n");
2976         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2977                         "parameter(ssid) is NULL\n");
2978
2979         __tethering_h *th = (__tethering_h *)tethering;
2980         char *p_ssid = NULL;
2981         int ssid_len = 0;
2982
2983         ssid_len = strlen(ssid);
2984         if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) {
2985                 ERR("parameter(ssid) is too long");
2986                 return TETHERING_ERROR_INVALID_PARAMETER;
2987         }
2988
2989         p_ssid = strdup(ssid);
2990         _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2991                         "strdup is failed\n");
2992
2993         if (th->ssid)
2994                 free(th->ssid);
2995         th->ssid = p_ssid;
2996
2997         return TETHERING_ERROR_NONE;
2998 }
2999
3000 /**
3001  * @internal
3002  * @brief Gets the SSID (service set identifier).
3003  * @since_tizen 2.3
3004  * @privlevel platform
3005  * @privilege http://tizen.org/privilege/tethering.admin
3006  * @remarks @a ssid must be released with free() by you.
3007  * @param[in]  tethering  The handle of tethering
3008  * @param[out]  ssid  The SSID
3009  * @return 0 on success, otherwise negative error value.
3010  * @retval  #TETHERING_ERROR_NONE  Successful
3011  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3012  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
3013  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3014  */
3015 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
3016 {
3017         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3018         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3019
3020         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3021                         "parameter(tethering) is NULL\n");
3022         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3023                         "parameter(ssid) is NULL\n");
3024         DBG("+\n");
3025
3026         __tethering_h *th = (__tethering_h *)tethering;
3027         char val[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, };
3028
3029         if (!tethering_is_enabled(NULL, TETHERING_TYPE_WIFI)) {
3030                 if (th->ssid != NULL) {
3031                         DBG("Private SSID is set\n");
3032                         *ssid = strdup(th->ssid);
3033                 } else {
3034                         if (__get_ssid_from_vconf(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
3035                                                 val, sizeof(val)) == false) {
3036                                 return TETHERING_ERROR_OPERATION_FAILED;
3037                         }
3038                         *ssid = strdup(val);
3039                 }
3040         } else {
3041                 if (__get_ssid_from_vconf(VCONFKEY_MOBILE_HOTSPOT_SSID,
3042                                         val, sizeof(val)) == false) {
3043                         return TETHERING_ERROR_OPERATION_FAILED;
3044                 }
3045                 *ssid = strdup(val);
3046         }
3047
3048         if (*ssid == NULL) {
3049                 ERR("strdup is failed\n"); //LCOV_EXCL_LINE
3050                 return TETHERING_ERROR_OUT_OF_MEMORY;
3051         }
3052
3053         return TETHERING_ERROR_NONE;
3054 }
3055
3056 /**
3057  * @internal
3058  * @brief Sets the visibility of SSID(service set identifier).
3059  * @since_tizen 2.3
3060  * @privlevel platform
3061  * @privilege http://tizen.org/privilege/tethering.admin
3062  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
3063  * @remarks This change is applied next time Wi-Fi tethering is enabled
3064  * @param[in]  tethering  The handle of tethering
3065  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
3066  * @return 0 on success, otherwise negative error value.
3067  * @retval  #TETHERING_ERROR_NONE  Successful
3068  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3069  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3070  * @see  tethering_wifi_get_ssid_visibility()
3071  */
3072 API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
3073 {
3074         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3075         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3076
3077         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3078                         "parameter(tethering) is NULL\n");
3079
3080         __tethering_h *th = (__tethering_h *)tethering;
3081         tethering_error_e ret = TETHERING_ERROR_NONE;
3082
3083         ret = __set_visible(visible);
3084         if (ret == TETHERING_ERROR_NONE) {
3085                 __send_dbus_signal(th->client_bus,
3086                                 SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
3087                                 visible ? SIGNAL_MSG_SSID_VISIBLE :
3088                                 SIGNAL_MSG_SSID_HIDE);
3089         }
3090         return ret;
3091 }
3092
3093 /**
3094  * @internal
3095  * @brief Gets the visibility of SSID(service set identifier).
3096  * @since_tizen 2.3
3097  * @privlevel platform
3098  * @privilege http://tizen.org/privilege/tethering.admin
3099  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
3100  * @param[in]  tethering  The handle of tethering
3101  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
3102  * @return 0 on success, otherwise negative error value.
3103  * @retval  #TETHERING_ERROR_NONE  Successful
3104  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3105  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3106  * @see  tethering_wifi_set_ssid_visibility()
3107  */
3108 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
3109 {
3110         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3111         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3112
3113         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3114                         "parameter(visible) is NULL\n");
3115
3116         return __get_visible(visible);
3117 }
3118
3119 /**
3120  * @internal
3121  * @brief Sets the passphrase.
3122  * @since_tizen 2.3
3123  * @privlevel platform
3124  * @privilege http://tizen.org/privilege/tethering.admin
3125  * @remarks This change is applied next time Wi-Fi tethering is enabled
3126  * @param[in]  tethering  The handle of tethering
3127  * @param[in]  passphrase  The passphrase
3128  * @return 0 on success, otherwise negative error value.
3129  * @retval  #TETHERING_ERROR_NONE  Successful
3130  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3131  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3132  * @see  tethering_wifi_get_passphrase()
3133  */
3134 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
3135 {
3136         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3137         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3138
3139         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3140                         "parameter(tethering) is NULL\n");
3141         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3142                         "parameter(passphrase) is NULL\n");
3143
3144         __tethering_h *th = (__tethering_h *)tethering;
3145         GDBusProxy *proxy = th->client_bus_proxy;
3146         GVariant *parameters;
3147         GError *error = NULL;
3148         int passphrase_len = 0;
3149         int ret = 0;
3150
3151         DBG("+");
3152         passphrase_len = strlen(passphrase);
3153         if (passphrase_len < TETHERING_WIFI_KEY_MIN_LEN ||
3154                         passphrase_len > TETHERING_WIFI_KEY_MAX_LEN) {
3155                 ERR("parameter(passphrase) is too short or long\n");
3156                 return TETHERING_ERROR_INVALID_PARAMETER;
3157         }
3158
3159         parameters = g_dbus_proxy_call_sync(proxy, "set_wifi_tethering_passphrase",
3160                         g_variant_new("(s)", passphrase), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3161
3162         if (error) {
3163                 //LCOV_EXCL_START
3164                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3165
3166                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3167                         ret = TETHERING_ERROR_PERMISSION_DENIED;
3168                 else
3169                         ret = TETHERING_ERROR_OPERATION_FAILED;
3170
3171                 g_error_free(error);
3172                 return ret;
3173                 //LCOV_EXCL_STOP
3174         }
3175
3176         g_variant_get(parameters, "(u)", &ret);
3177         g_variant_unref(parameters);
3178
3179         if (ret == TETHERING_ERROR_NONE) {
3180                 __send_dbus_signal(th->client_bus,
3181                                 SIGNAL_NAME_PASSPHRASE_CHANGED, NULL);
3182         }
3183
3184         DBG("-");
3185         return ret;
3186 }
3187
3188 /**
3189  * @internal
3190  * @brief Gets the passphrase.
3191  * @since_tizen 2.3
3192  * @privlevel platform
3193  * @privilege http://tizen.org/privilege/tethering.admin
3194  * @remarks @a passphrase must be released with free() by you.
3195  * @param[in]  tethering  The handle of tethering
3196  * @param[out]  passphrase  The passphrase
3197  * @return 0 on success, otherwise negative error value.
3198  * @retval  #TETHERING_ERROR_NONE  Successful
3199  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3200  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
3201  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3202  * @see  tethering_wifi_set_passphrase()
3203  */
3204 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
3205 {
3206         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3207         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3208
3209         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3210                         "parameter(tethering) is NULL\n");
3211         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3212                         "parameter(passphrase) is NULL\n");
3213
3214         __tethering_h *th = (__tethering_h *)tethering;
3215         GDBusProxy *proxy = th->client_bus_proxy;
3216         GVariant *parameters;
3217         GError *error = NULL;
3218         unsigned int len = 0;
3219         tethering_error_e ret = TETHERING_ERROR_NONE;
3220
3221         parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_passphrase",
3222                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3223
3224         if (error) {
3225                 //LCOV_EXCL_START
3226                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3227
3228                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3229                         ret = TETHERING_ERROR_PERMISSION_DENIED;
3230                 else
3231                         ret = TETHERING_ERROR_OPERATION_FAILED;
3232
3233                 g_error_free(error);
3234                 return ret;
3235                 //LCOV_EXCL_STOP
3236         }
3237
3238         if (parameters != NULL) {
3239                 g_variant_get(parameters, "(siu)", passphrase, &len, &ret);
3240                 g_variant_unref(parameters);
3241         }
3242
3243         return TETHERING_ERROR_NONE;
3244 }
3245
3246 API int tethering_wifi_set_channel(tethering_h tethering, int channel)
3247 {
3248         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3249         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3250
3251         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3252                         "parameter(tethering) is NULL\n");
3253
3254         __tethering_h *th = (__tethering_h *)tethering;
3255         th->channel = channel;
3256
3257         return TETHERING_ERROR_NONE;
3258 }
3259
3260 API int tethering_wifi_get_channel(tethering_h tethering, int *channel)
3261 {
3262         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3263         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3264
3265         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3266                         "parameter(tethering) is NULL\n");
3267
3268         _retvm_if(channel == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3269                         "parameter(channel) is NULL\n");
3270
3271         __tethering_h *th = (__tethering_h *)tethering;
3272         *channel = th->channel;
3273
3274         return TETHERING_ERROR_NONE;
3275 }
3276
3277 API int tethering_wifi_set_mode(tethering_h tethering, tethering_wifi_mode_type_e type)
3278 {
3279         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3280         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3281
3282         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3283                         "parameter(tethering) is NULL\n");
3284
3285         __tethering_h *th = (__tethering_h *)tethering;
3286
3287         th->mode_type = type;
3288
3289         return TETHERING_ERROR_NONE;
3290 }
3291
3292 API int tethering_wifi_get_mode(tethering_h tethering, tethering_wifi_mode_type_e *type)
3293 {
3294         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3295         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3296
3297         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3298                         "parameter(tethering) is NULL\n");
3299         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3300                         "parameter(type) is NULL\n");
3301
3302         __tethering_h *th = (__tethering_h *)tethering;
3303         *type = th->mode_type;
3304
3305         return TETHERING_ERROR_NONE;
3306 }
3307
3308
3309 /**
3310  * @internal
3311  * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility).
3312  * @since_tizen 2.3
3313  * @privlevel platform
3314  * @privilege http://tizen.org/privilege/tethering.admin
3315  * @remarks Connected devices via Wi-Fi tethering or MobileAP will be disconnected when the settings are reloaded
3316  * @param[in]  tethering  The handle of tethering
3317  * @param[in]  callback  The callback function to invoke
3318  * @param[in]  user_data  The user data to be passed to the callback function
3319  * @return 0 on success, otherwise negative error value.
3320  * @retval  #TETHERING_ERROR_NONE  Successful
3321  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3322  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3323  */
3324 API int tethering_wifi_reload_settings(tethering_h tethering, tethering_wifi_settings_reloaded_cb callback, void *user_data)
3325
3326 {
3327         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3328         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3329
3330         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3331                         "parameter(tethering) is NULL\n");
3332         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3333                         "parameter(callback) is NULL\n");
3334
3335         __tethering_h *th = (__tethering_h *)tethering;
3336         _softap_settings_t set = {"", "", "", 0, false};
3337         GDBusProxy *proxy = th->client_bus_proxy;
3338         int ret = 0;
3339
3340         DBG("+\n");
3341
3342         if (th->settings_reloaded_cb) {
3343                 ERR("Operation in progress\n"); //LCOV_EXCL_LINE
3344                 return TETHERING_ERROR_OPERATION_FAILED;
3345         }
3346
3347         ret = __prepare_wifi_settings(tethering, &set);
3348         if (ret != TETHERING_ERROR_NONE) {
3349                 ERR("softap settings initialization failed\n"); //LCOV_EXCL_LINE
3350                 return TETHERING_ERROR_OPERATION_FAILED;
3351         }
3352
3353         th->settings_reloaded_cb = callback;
3354         th->settings_reloaded_user_data = user_data;
3355
3356         g_dbus_proxy_call(proxy, "reload_wifi_settings",
3357                         g_variant_new("(sssiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type),
3358                         G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
3359                         (GAsyncReadyCallback) __settings_reloaded_cb, (gpointer)tethering);
3360
3361         return TETHERING_ERROR_NONE;
3362 }
3363
3364 API int tethering_wifi_set_mac_filter(tethering_h tethering, bool mac_filter)
3365 {
3366         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3367         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3368
3369         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3370                         "parameter(tethering) is NULL\n");
3371
3372         __tethering_h *th = (__tethering_h *)tethering;
3373         th->mac_filter = mac_filter;
3374
3375         return TETHERING_ERROR_NONE;
3376 }
3377
3378 API int tethering_wifi_get_mac_filter(tethering_h tethering, bool *mac_filter)
3379 {
3380         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3381         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3382
3383         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3384                         "parameter(mac_filter) is NULL\n");
3385         _retvm_if(mac_filter == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3386                         "parameter(mac_filter) is NULL\n");
3387
3388         __tethering_h *th = (__tethering_h *)tethering;
3389         *mac_filter = th->mac_filter;
3390
3391         return TETHERING_ERROR_NONE;
3392 }
3393
3394 static int __add_mac_to_file(const char *filepath, const char *mac)
3395 {
3396         FILE *fp = NULL;
3397         char line[MAX_BUF_SIZE] = "\0";
3398         bool mac_exist = false;
3399         char *p_mac = NULL;
3400
3401         fp = fopen(filepath, "a+");
3402         if (!fp) {
3403                 ERR("fopen is failed\n"); //LCOV_EXCL_LINE
3404                 return TETHERING_ERROR_OPERATION_FAILED;
3405         }
3406
3407         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3408                 if (strncmp(mac, line, 17) == 0) {
3409                         DBG("MAC %s already exist in the list\n", mac); //LCOV_EXCL_LINE
3410                         mac_exist = true;
3411                         break;
3412                 }
3413         }
3414
3415         if (!mac_exist) {
3416                 p_mac = strdup(mac);
3417                 if (p_mac == NULL) {
3418                         ERR("strdup failed\n"); //LCOV_EXCL_LINE
3419                         fclose(fp);
3420                         return TETHERING_ERROR_OUT_OF_MEMORY;
3421                 }
3422
3423                 fprintf(fp, "%s\n", mac);
3424
3425                 if ((strcmp(filepath, ALLOWED_LIST) == 0))
3426                         allowed_list = g_slist_append(allowed_list, p_mac);
3427                 else if ((strcmp(filepath, BLOCKED_LIST) == 0))
3428                         blocked_list = g_slist_append(blocked_list, p_mac);
3429                 else
3430                         free(p_mac);
3431         }
3432
3433         fclose(fp);
3434
3435         return TETHERING_ERROR_NONE;
3436 }
3437
3438 static int __remove_mac_from_file(const char *filepath, const char *mac)
3439 {
3440         FILE *fp = NULL;
3441         FILE *fp1 = NULL;
3442         char line[MAX_BUF_SIZE] = "\0";
3443
3444         fp = fopen(filepath, "r");
3445         if (!fp) {
3446                 ERR("fopen is failed\n");
3447                 return TETHERING_ERROR_OPERATION_FAILED;
3448         }
3449
3450         fp1 = fopen(TEMP_LIST, "w+");
3451         if (!fp1) {
3452                 fclose(fp);
3453                 ERR("fopen is failed\n");
3454                 return TETHERING_ERROR_OPERATION_FAILED;
3455         }
3456
3457         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3458                 if (strncmp(mac, line, 17) == 0) {
3459                         DBG("MAC %s found in the list\n", mac);
3460
3461                         if ((strcmp(filepath, ALLOWED_LIST) == 0)) {
3462                                 GSList *list = NULL;
3463                                 for (list = allowed_list; list != NULL; list = list->next) {
3464                                         char *p_mac = (char *)list->data;
3465                                         if (strncmp(mac, p_mac, strlen(mac)) == 0)
3466                                                 allowed_list = g_slist_remove(allowed_list, p_mac);
3467                                 }
3468                         } else if ((strcmp(filepath, BLOCKED_LIST) == 0)) {
3469                                 GSList *list = NULL;
3470                                 for (list = blocked_list; list != NULL; list = list->next) {
3471                                         char *p_mac = (char *)list->data;
3472                                         if (strncmp(mac, p_mac, strlen(mac)) == 0)
3473                                                 blocked_list = g_slist_remove(blocked_list, p_mac);
3474                                 }
3475                         }
3476                 } else {
3477                         fprintf(fp1, "%s", line);
3478                 }
3479         }
3480
3481         fclose(fp);
3482         fclose(fp1);
3483
3484         if ((strcmp(filepath, ALLOWED_LIST) == 0)) {
3485                 if (rename(TEMP_LIST, ALLOWED_LIST) != 0) {
3486                         ERR("rename is failed (%s -> %s)", TEMP_LIST, ALLOWED_LIST);
3487                         return TETHERING_ERROR_OPERATION_FAILED;
3488                 }
3489         } else if ((strcmp(filepath, BLOCKED_LIST) == 0)) {
3490                 if (rename(TEMP_LIST, BLOCKED_LIST) != 0) {
3491                         ERR("rename is failed (%s -> %s)", TEMP_LIST, BLOCKED_LIST);
3492                         return TETHERING_ERROR_OPERATION_FAILED;
3493                 }
3494         }
3495
3496         return TETHERING_ERROR_NONE;
3497 }
3498
3499 API int tethering_wifi_add_allowed_mac_list(tethering_h tethering, const char *mac)
3500 {
3501         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3502         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3503
3504         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3505                         "parameter(tethering) is NULL\n");
3506         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3507                         "parameter(mac) is NULL\n");
3508
3509         return __add_mac_to_file(ALLOWED_LIST, mac);
3510 }
3511
3512 API int tethering_wifi_remove_allowed_mac_list(tethering_h tethering, const char *mac)
3513 {
3514         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3515         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3516
3517         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3518                         "parameter(tethering) is NULL\n");
3519         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3520                         "parameter(mac) is NULL\n");
3521
3522         return __remove_mac_from_file(ALLOWED_LIST, mac);
3523 }
3524
3525 API int tethering_wifi_get_allowed_mac_list(tethering_h tethering, void **allowed_mac_list)
3526 {
3527         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3528         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3529
3530         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3531                         "parameter(tethering) is NULL\n");
3532         _retvm_if(allowed_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3533                         "parameter(allowed_mac_list) is NULL\n");
3534
3535         *allowed_mac_list = g_slist_copy(allowed_list);
3536         return TETHERING_ERROR_NONE;
3537 }
3538
3539 API int tethering_wifi_add_blocked_mac_list(tethering_h tethering, const char *mac)
3540 {
3541         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3542         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3543
3544         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3545                         "parameter(tethering) is NULL\n");
3546         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3547                         "parameter(mac) is NULL\n");
3548
3549         return __add_mac_to_file(BLOCKED_LIST, mac);
3550 }
3551
3552 API int tethering_wifi_remove_blocked_mac_list(tethering_h tethering, const char *mac)
3553 {
3554         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3555         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3556
3557         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3558                         "parameter(tethering) is NULL\n");
3559         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3560                         "parameter(mac) is NULL\n");
3561
3562         return __remove_mac_from_file(BLOCKED_LIST, mac);
3563 }
3564
3565 API int tethering_wifi_get_blocked_mac_list(tethering_h tethering, void **blocked_mac_list)
3566 {
3567         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3568         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3569
3570         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3571                         "parameter(tethering) is NULL\n");
3572         _retvm_if(blocked_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3573                         "parameter(blocked_mac_list) is NULL\n");
3574
3575         *blocked_mac_list = g_slist_copy(blocked_list);
3576         return TETHERING_ERROR_NONE;
3577 }
3578
3579 API int tethering_wifi_enable_dhcp(tethering_h tethering, bool enable)
3580 {
3581         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3582         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3583
3584         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3585                         "parameter(tethering) is NULL\n");
3586
3587         GVariant *parameters;
3588         GError *error = NULL;
3589         guint result;
3590
3591         __tethering_h *th = (__tethering_h *)tethering;
3592
3593         GDBusProxy *proxy = th->client_bus_proxy;
3594
3595         parameters = g_dbus_proxy_call_sync(proxy, "enable_dhcp",
3596                         g_variant_new("(b)", enable),
3597                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3598
3599         if (error) {
3600                 //LCOV_EXCL_START
3601                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3602                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3603                         result = TETHERING_ERROR_PERMISSION_DENIED;
3604                 else
3605                         result = TETHERING_ERROR_OPERATION_FAILED;
3606
3607                 g_error_free(error);
3608                 th->dhcp_enabled = false;
3609
3610                 return result;
3611                 //LCOV_EXCL_STOP
3612         }
3613
3614         g_variant_get(parameters, "(u)", &result);
3615         g_variant_unref(parameters);
3616
3617         if (enable)
3618                 th->dhcp_enabled = true;
3619         else
3620                 th->dhcp_enabled = false;
3621
3622         return TETHERING_ERROR_NONE;
3623 }
3624
3625 API int tethering_wifi_set_dhcp_range(tethering_h tethering, char *rangestart, char *rangestop)
3626 {
3627         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3628         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3629
3630         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3631                         "parameter(tethering) is NULL\n");
3632         _retvm_if(rangestart == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3633                         "parameter(rangestart) is NULL\n");
3634         _retvm_if(rangestop == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3635                         "parameter(rangestop) is NULL\n");
3636
3637         GVariant *parameters;
3638         GError *error = NULL;
3639         guint result;
3640
3641         __tethering_h *th = (__tethering_h *)tethering;
3642
3643         GDBusProxy *proxy = th->client_bus_proxy;
3644
3645         parameters = g_dbus_proxy_call_sync(proxy, "dhcp_range",
3646                         g_variant_new("(ss)", rangestart, rangestop),
3647                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3648         if (error) {
3649                 //LCOV_EXCL_START
3650                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3651
3652                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3653                         result = TETHERING_ERROR_PERMISSION_DENIED;
3654                 else
3655                         result = TETHERING_ERROR_OPERATION_FAILED;
3656
3657                 g_error_free(error);
3658                 th->dhcp_enabled = false;
3659
3660                 return result;
3661                 //LCOV_EXCL_STOP
3662         }
3663
3664         g_variant_get(parameters, "(u)", &result);
3665         g_variant_unref(parameters);
3666
3667         th->dhcp_enabled = true;
3668
3669         return TETHERING_ERROR_NONE;
3670 }
3671
3672 API int tethering_wifi_is_dhcp_enabled(tethering_h tethering, bool *dhcp_enabled)
3673 {
3674         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3675         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3676
3677         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3678                         "parameter(tethering) is NULL\n");
3679         _retvm_if(dhcp_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3680                         "parameter(dhcp_enabled) is NULL\n");
3681
3682         __tethering_h *th = (__tethering_h *)tethering;
3683         *dhcp_enabled = th->dhcp_enabled;
3684
3685         return TETHERING_ERROR_NONE;
3686 }
3687
3688 API int tethering_wifi_set_txpower(tethering_h tethering, unsigned int txpower)
3689 {
3690         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3691         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3692
3693         GError *error = NULL;
3694
3695         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3696                         "parameter(tethering) is NULL\n");
3697         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false,
3698                         TETHERING_ERROR_NOT_ENABLED,
3699                         "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI);
3700         __tethering_h *th = (__tethering_h *)tethering;
3701
3702         g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_set_txpower",
3703                         g_variant_new("(u)", txpower),
3704                         G_DBUS_CALL_FLAGS_NONE,
3705                         -1, th->cancellable, &error);
3706         if (error) {
3707                 //LCOV_EXCL_START
3708                 ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
3709                 g_clear_error(&error);
3710                 return TETHERING_ERROR_OPERATION_FAILED;
3711                 //LCOV_EXCL_STOP
3712         }
3713         return TETHERING_ERROR_NONE;
3714 }
3715
3716 API int tethering_wifi_get_txpower(tethering_h tethering, unsigned int *txpower)
3717 {
3718         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3719         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3720
3721         GError *error = NULL;
3722         GVariant *result = NULL;
3723
3724         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3725                         "parameter(tethering) is NULL\n");
3726         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false,
3727                         TETHERING_ERROR_NOT_ENABLED,
3728                         "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI);
3729
3730         __tethering_h *th = (__tethering_h *)tethering;
3731
3732         result = g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_get_txpower",
3733                         NULL,
3734                         G_DBUS_CALL_FLAGS_NONE,
3735                         -1, th->cancellable, &error);
3736
3737         if (result != NULL) {
3738                 g_variant_get(result, "(u)", txpower);
3739                 g_variant_unref(result);
3740         } else {
3741                 //LCOV_EXCL_START
3742                 if (error)
3743                         ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
3744                 g_clear_error(&error);
3745                 return TETHERING_ERROR_OPERATION_FAILED;
3746                 //LCOV_EXCL_STOP
3747         }
3748         g_clear_error(&error);
3749         return TETHERING_ERROR_NONE;
3750 }
3751
3752 API int tethering_wifi_set_mtu(tethering_h tethering, unsigned int mtu)
3753 {
3754         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3755         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3756
3757         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3758                         "parameter(tethering) is NULL\n");
3759
3760         GVariant *parameters;
3761         GError *error = NULL;
3762         guint result;
3763
3764         __tethering_h *th = (__tethering_h *)tethering;
3765
3766         GDBusProxy *proxy = th->client_bus_proxy;
3767
3768         parameters = g_dbus_proxy_call_sync(proxy, "set_mtu",
3769                         g_variant_new("(u)", mtu),
3770                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3771         if (error) {
3772                 //LCOV_EXCL_START
3773                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3774
3775                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3776                         result = TETHERING_ERROR_PERMISSION_DENIED;
3777                 else
3778                         result = TETHERING_ERROR_OPERATION_FAILED;
3779
3780                 g_error_free(error);
3781                 return result;
3782                 //LCOV_EXCL_STOP
3783         }
3784
3785         g_variant_get(parameters, "(u)", &result);
3786
3787         g_variant_unref(parameters);
3788
3789         return TETHERING_ERROR_NONE;
3790 }
3791
3792 API int tethering_wifi_change_mac(tethering_h tethering, char *mac)
3793 {
3794         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3795         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3796
3797         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3798                         "parameter(tethering) is NULL\n");
3799         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3800                         "parameter(mac) is NULL\n");
3801
3802         GVariant *parameters;
3803         GError *error = NULL;
3804         guint result;
3805
3806         __tethering_h *th = (__tethering_h *)tethering;
3807
3808         GDBusProxy *proxy = th->client_bus_proxy;
3809
3810         parameters = g_dbus_proxy_call_sync(proxy, "change_mac",
3811                         g_variant_new("(s)", mac),
3812                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3813         if (error) {
3814                 //LCOV_EXCL_START
3815                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3816
3817                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3818                         result = TETHERING_ERROR_PERMISSION_DENIED;
3819                 else
3820                         result = TETHERING_ERROR_OPERATION_FAILED;
3821
3822                 g_error_free(error);
3823                 return result;
3824                 //LCOV_EXCL_STOP
3825         }
3826
3827         g_variant_get(parameters, "(u)", &result);
3828         g_variant_unref(parameters);
3829
3830         if (result == MOBILE_AP_ERROR_NOT_PERMITTED)
3831                 return TETHERING_ERROR_NOT_SUPPORT_API;
3832
3833         return TETHERING_ERROR_NONE;
3834 }
3835
3836 API int tethering_wifi_set_max_connected_device(tethering_h tethering, int max_device)
3837 {
3838         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3839         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3840
3841         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3842                         "parameter(tethering) is NULL\n");
3843
3844         __tethering_h *th = (__tethering_h *)tethering;
3845
3846         th->wifi_max_connected = max_device;
3847
3848         return TETHERING_ERROR_NONE;
3849 }
3850
3851 API int tethering_wifi_get_max_connected_device(tethering_h tethering, int *max_device)
3852 {
3853         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3854         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3855
3856         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3857                         "parameter(tethering) is NULL\n");
3858         _retvm_if(max_device == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3859                         "parameter(max_device) is NULL\n");
3860
3861         __tethering_h *th = (__tethering_h *)tethering;
3862
3863         *max_device = th->wifi_max_connected;
3864         return TETHERING_ERROR_NONE;
3865 }
3866
3867 API int tethering_wifi_enable_port_forwarding(tethering_h tethering, bool enable)
3868 {
3869         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3870         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3871
3872         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3873                         "parameter(tethering) is NULL\n");
3874
3875         GVariant *parameters;
3876         GError *error = NULL;
3877         guint result;
3878
3879         __tethering_h *th = (__tethering_h *)tethering;
3880
3881         GDBusProxy *proxy = th->client_bus_proxy;
3882
3883         parameters = g_dbus_proxy_call_sync(proxy, "enable_port_forwarding",
3884                         g_variant_new("(b)", enable),
3885                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3886         if (error) {
3887                 //LCOV_EXCL_START
3888                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3889
3890                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3891                         result = TETHERING_ERROR_PERMISSION_DENIED;
3892                 else
3893                         result = TETHERING_ERROR_OPERATION_FAILED;
3894
3895                 g_error_free(error);
3896                 return result;
3897                 //LCOV_EXCL_STOP
3898         }
3899
3900         g_variant_get(parameters, "(u)", &result);
3901         g_variant_unref(parameters);
3902
3903         th->port_forwarding = true;
3904
3905         return TETHERING_ERROR_NONE;
3906 }
3907
3908 API int tethering_wifi_add_port_forwarding_rule(tethering_h tethering, char *ifname, char *protocol, char *org_ip, int org_port, char *final_ip, int final_port)
3909 {
3910         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3911         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3912
3913         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3914                         "parameter(tethering) is NULL\n");
3915         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3916                         "parameter(protocol) is NULL\n");
3917
3918         GVariant *parameters;
3919         GError *error = NULL;
3920         guint result;
3921         char cmd[MAX_BUF_SIZE] = { 0, };
3922         char *list = NULL;
3923
3924         __tethering_h *th = (__tethering_h *)tethering;
3925
3926         GDBusProxy *proxy = th->client_bus_proxy;
3927
3928         parameters = g_dbus_proxy_call_sync(proxy, "add_port_forwarding_rule",
3929                         g_variant_new("(sssisi)", ifname, protocol, org_ip, org_port, final_ip, final_port),
3930                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3931         if (error) {
3932                 //LCOV_EXCL_START
3933                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3934
3935                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3936                         result = TETHERING_ERROR_PERMISSION_DENIED;
3937                 else
3938                         result = TETHERING_ERROR_OPERATION_FAILED;
3939
3940                 g_error_free(error);
3941                 return result;
3942                 //LCOV_EXCL_STOP
3943         }
3944
3945         g_variant_get(parameters, "(u)", &result);
3946         g_variant_unref(parameters);
3947
3948         snprintf(cmd, sizeof(cmd), "%s "PORT_FORWARD_RULE_STR, IPTABLES, TABLE_NAT, TETH_NAT_PRE, ifname, protocol, org_ip, org_port, final_ip, final_port);
3949
3950         list = strdup(cmd);
3951         if (list == NULL) {
3952                 ERR("strdup failed\n"); //LCOV_EXCL_LINE
3953                 return TETHERING_ERROR_OUT_OF_MEMORY;
3954         }
3955
3956         port_forwarding = g_slist_append(port_forwarding, list);
3957
3958         return TETHERING_ERROR_NONE;
3959 }
3960
3961 API int tethering_wifi_reset_port_forwarding_rule(tethering_h tethering)
3962 {
3963         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3964         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3965
3966         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3967                         "parameter(tethering) is NULL\n");
3968
3969         GVariant *parameters;
3970         GError *error = NULL;
3971         guint result;
3972
3973         __tethering_h *th = (__tethering_h *)tethering;
3974
3975         GDBusProxy *proxy = th->client_bus_proxy;
3976
3977         parameters = g_dbus_proxy_call_sync(proxy, "reset_port_forwarding_rule",
3978                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3979         if (error) {
3980                 //LCOV_EXCL_START
3981                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3982
3983                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3984                         result = TETHERING_ERROR_PERMISSION_DENIED;
3985                 else
3986                         result = TETHERING_ERROR_OPERATION_FAILED;
3987
3988                 g_error_free(error);
3989                 return result;
3990                 //LCOV_EXCL_STOP
3991         }
3992
3993         g_variant_get(parameters, "(u)", &result);
3994
3995         g_variant_unref(parameters);
3996
3997         return TETHERING_ERROR_NONE;
3998 }
3999
4000 API int tethering_wifi_is_port_forwarding_enabled(tethering_h tethering, bool* forwarding_enabled)
4001 {
4002         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4003         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4004
4005         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4006                         "parameter(tethering) is NULL\n");
4007         _retvm_if(forwarding_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4008                         "parameter(forwarding_enabled) is NULL\n");
4009
4010         __tethering_h *th = (__tethering_h *)tethering;
4011
4012         *forwarding_enabled = th->port_forwarding;
4013
4014         return TETHERING_ERROR_NONE;
4015 }
4016
4017 API int tethering_wifi_get_port_forwarding_rule(tethering_h tethering, void **port_forwarding_list)
4018 {
4019         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4020         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4021
4022         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4023                         "parameter(tethering) is NULL\n");
4024         _retvm_if(port_forwarding_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4025                         "parameter(port_forwarding_list) is NULL\n");
4026
4027         *port_forwarding_list = g_slist_copy(port_forwarding);
4028         return TETHERING_ERROR_NONE;
4029 }
4030
4031 API int tethering_wifi_enable_port_filtering(tethering_h tethering, bool enable)
4032 {
4033         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4034         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4035
4036         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4037                         "parameter(tethering) is NULL\n");
4038
4039         GVariant *parameters;
4040         GError *error = NULL;
4041         guint result;
4042
4043         __tethering_h *th = (__tethering_h *)tethering;
4044
4045         GDBusProxy *proxy = th->client_bus_proxy;
4046
4047         parameters = g_dbus_proxy_call_sync(proxy, "enable_port_filtering",
4048                         g_variant_new("(b)", enable),
4049                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4050         if (error) {
4051                 //LCOV_EXCL_START
4052                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4053
4054                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4055                         result = TETHERING_ERROR_PERMISSION_DENIED;
4056                 else
4057                         result = TETHERING_ERROR_OPERATION_FAILED;
4058
4059                 g_error_free(error);
4060                 return result;
4061                 //LCOV_EXCL_STOP
4062         }
4063
4064         g_variant_get(parameters, "(u)", &result);
4065         g_variant_unref(parameters);
4066
4067         th->port_filtering = true;
4068
4069         return TETHERING_ERROR_NONE;
4070 }
4071
4072 API int tethering_wifi_add_port_filtering_rule(tethering_h tethering, int port, char *protocol, bool allow)
4073 {
4074         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4075         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4076
4077         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4078                         "parameter(tethering) is NULL\n");
4079         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4080                         "parameter(protocol) is NULL\n");
4081
4082         GVariant *parameters;
4083         GError *error = NULL;
4084         guint result;
4085         char *list = NULL;
4086         int ret;
4087
4088         __tethering_h *th = (__tethering_h *)tethering;
4089
4090         GDBusProxy *proxy = th->client_bus_proxy;
4091
4092         parameters = g_dbus_proxy_call_sync(proxy, "add_port_filtering_rule",
4093                         g_variant_new("(isb)", port, protocol, allow),
4094                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4095         if (error) {
4096                 //LCOV_EXCL_START
4097                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4098
4099                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4100                         result = TETHERING_ERROR_PERMISSION_DENIED;
4101                 else
4102                         result = TETHERING_ERROR_OPERATION_FAILED;
4103
4104                 g_error_free(error);
4105                 return result;
4106                 //LCOV_EXCL_STOP
4107         }
4108
4109         g_variant_get(parameters, "(u)", &result);
4110         g_variant_unref(parameters);
4111
4112         if (allow)
4113                 ret = asprintf(&list, "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_ACCEPT);
4114         else
4115                 ret = asprintf(&list, "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_DROP);
4116
4117         if (ret == -1 || list == NULL) {
4118                 ERR("asprintf failed\n"); //LCOV_EXCL_LINE
4119                 return TETHERING_ERROR_OUT_OF_MEMORY;
4120         }
4121
4122         DBG("cmd:%s", list);
4123
4124         port_filtering = g_slist_append(port_filtering, list);
4125
4126         return TETHERING_ERROR_NONE;
4127 }
4128
4129 API int tethering_wifi_add_custom_port_filtering_rule(tethering_h tethering, int port1, int port2, char *protocol, bool allow)
4130 {
4131         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4132         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4133
4134         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4135                         "parameter(tethering) is NULL\n");
4136         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4137                         "parameter(protocol) is NULL\n");
4138
4139         GVariant *parameters;
4140         GError *error = NULL;
4141         guint result;
4142         char *list = NULL;
4143         int ret;
4144
4145         __tethering_h *th = (__tethering_h *)tethering;
4146
4147         GDBusProxy *proxy = th->client_bus_proxy;
4148
4149         parameters = g_dbus_proxy_call_sync(proxy, "add_custom_port_filtering_rule",
4150                         g_variant_new("(iisb)", port1, port2, protocol, allow),
4151                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4152         if (error) {
4153                 //LCOV_EXCL_START
4154                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4155
4156                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4157                         result = TETHERING_ERROR_PERMISSION_DENIED;
4158                 else
4159                         result = TETHERING_ERROR_OPERATION_FAILED;
4160
4161                 g_error_free(error);
4162                 return result;
4163                 //LCOV_EXCL_STOP
4164         }
4165
4166         g_variant_get(parameters, "(u)", &result);
4167         g_variant_unref(parameters);
4168
4169         if (allow)
4170                 ret = asprintf(&list, "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_ACCEPT);
4171         else
4172                 ret = asprintf(&list, "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_DROP);
4173
4174         if (ret == -1 || list == NULL) {
4175                 ERR("asprintf failed\n"); //LCOV_EXCL_LINE
4176                 return TETHERING_ERROR_OUT_OF_MEMORY;
4177         }
4178
4179         DBG("cmd:%s", list);
4180
4181         custom_port_filtering = g_slist_append(custom_port_filtering, list);
4182
4183         return TETHERING_ERROR_NONE;
4184 }
4185
4186 API int tethering_wifi_get_port_filtering_rule(tethering_h tethering, void **port_filtering_list)
4187 {
4188         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4189         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4190
4191         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4192                         "parameter(tethering) is NULL\n");
4193         _retvm_if(port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4194                         "parameter(port_filtering_list) is NULL\n");
4195
4196         *port_filtering_list = g_slist_copy(port_filtering);
4197         return TETHERING_ERROR_NONE;
4198 }
4199
4200 API int tethering_wifi_get_custom_port_filtering_rule(tethering_h tethering, void **custom_port_filtering_list)
4201 {
4202         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4203         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4204
4205         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4206                         "parameter(tethering) is NULL\n");
4207         _retvm_if(custom_port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4208                         "parameter(custom_port_filtering_list) is NULL\n");
4209
4210         *custom_port_filtering_list = g_slist_copy(custom_port_filtering);
4211         return TETHERING_ERROR_NONE;
4212 }
4213
4214 API int tethering_wifi_is_port_filtering_enabled(tethering_h tethering, bool* filtering_enabled)
4215 {
4216         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4217         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4218
4219         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4220                         "parameter(tethering) is NULL\n");
4221         _retvm_if(filtering_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4222                         "parameter(filtering_enabled) is NULL\n");
4223
4224         __tethering_h *th = (__tethering_h *)tethering;
4225
4226         *filtering_enabled = th->port_filtering;
4227
4228         return TETHERING_ERROR_NONE;
4229 }
4230
4231 API int tethering_wifi_set_vpn_passthrough_rule(tethering_h tethering, tethering_vpn_passthrough_type_e type, bool enable)
4232 {
4233         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4234         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4235
4236         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4237                         "parameter(tethering) is NULL\n");
4238
4239         GVariant *parameters;
4240         GError *error = NULL;
4241         guint result;
4242
4243         __tethering_h *th = (__tethering_h *)tethering;
4244
4245         GDBusProxy *proxy = th->client_bus_proxy;
4246
4247         parameters = g_dbus_proxy_call_sync(proxy, "set_vpn_passthrough_rule",
4248                         g_variant_new("(ib)", type, enable),
4249                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4250         if (error) {
4251                 //LCOV_EXCL_START
4252                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4253
4254                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4255                         result = TETHERING_ERROR_PERMISSION_DENIED;
4256                 else
4257                         result = TETHERING_ERROR_OPERATION_FAILED;
4258
4259                 g_error_free(error);
4260                 return result;
4261                 //LCOV_EXCL_STOP
4262         }
4263
4264         g_variant_get(parameters, "(u)", &result);
4265
4266         g_variant_unref(parameters);
4267
4268         return TETHERING_ERROR_NONE;
4269 }
4270
4271 API int tethering_wifi_push_wps_button(tethering_h tethering)
4272 {
4273         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4274         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4275
4276         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4277                         "parameter(tethering) is NULL");
4278         __tethering_h *th = (__tethering_h *)tethering;
4279         GDBusProxy *proxy = th->client_bus_proxy;
4280         GVariant *parameters = NULL;
4281         int ret = 0;
4282         GError *error = NULL;
4283
4284         parameters = g_dbus_proxy_call_sync(proxy, "push_wps_button",
4285                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4286
4287         if (error) {
4288                 //LCOV_EXCL_START
4289                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4290
4291                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4292                         ret = TETHERING_ERROR_PERMISSION_DENIED;
4293                 else
4294                         ret = TETHERING_ERROR_OPERATION_FAILED;
4295
4296                 g_error_free(error);
4297                 return ret;
4298                 //LCOV_EXCL_STOP
4299         }
4300
4301         if (parameters != NULL) {
4302                 g_variant_get(parameters, "(u)", &ret);
4303                 g_variant_unref(parameters);
4304         }
4305
4306         return TETHERING_ERROR_NONE;
4307 }
4308
4309 API int tethering_wifi_set_wps_pin(tethering_h tethering, const char *wps_pin)
4310 {
4311         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4312         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4313
4314         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4315                         "parameter(tethering) is NULL");
4316         __tethering_h *th = (__tethering_h *)tethering;
4317         GDBusProxy *proxy = th->client_bus_proxy;
4318         GVariant *parameters = NULL;
4319         int ret = 0;
4320         GError *error = NULL;
4321
4322         parameters = g_dbus_proxy_call_sync(proxy, "set_wps_pin",
4323                         g_variant_new("(s)", wps_pin), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4324
4325         if (error) {
4326                 //LCOV_EXCL_START
4327                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4328
4329                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4330                         ret = TETHERING_ERROR_PERMISSION_DENIED;
4331                 else
4332                         ret = TETHERING_ERROR_OPERATION_FAILED;
4333
4334                 g_error_free(error);
4335                 return ret;
4336                 //LCOV_EXCL_STOP
4337         }
4338
4339         if (parameters != NULL) {
4340                 g_variant_get(parameters, "(u)", &ret);
4341                 g_variant_unref(parameters);
4342         }
4343
4344         return TETHERING_ERROR_NONE;
4345 }
4346
4347