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