Fixed precondition check for the ethernet network
[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_status = 0;
1381         int cellular_state = 0;
1382
1383         /* data network through cellular */
1384         vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state);
1385         if (cellular_state == VCONFKEY_NETWORK_CELLULAR_ON) {
1386                 INFO("Data Network can be connected later");
1387                 return TRUE;
1388         }
1389
1390         /* data network status */
1391         vconf_get_int(VCONFKEY_NETWORK_STATUS, &dnet_status);
1392         if ((dnet_status == VCONFKEY_NETWORK_WIFI
1393                         && type != TETHERING_TYPE_WIFI)
1394                 || dnet_status == VCONFKEY_NETWORK_ETHERNET)
1395                 return TRUE;
1396
1397         ERR("Network is not available!");
1398         return FALSE;
1399 }
1400
1401 /**
1402  * @internal
1403  * @brief  Creates the handle of tethering.
1404  * @since_tizen 2.3
1405  * @privlevel platform
1406  * @privilege http://tizen.org/privilege/tethering.admin
1407  * @remarks  The @a tethering must be released tethering_destroy() by you.
1408  * @param[out]  tethering  A handle of a new mobile ap handle on success
1409  * @return  0 on success, otherwise a negative error value.
1410  * @retval  #TETHERING_ERROR_NONE  Successful
1411  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1412  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1413  * @retval  #TETHERING_ERROR_NOT_SUPPORT_API  API is not supported
1414  * @see  tethering_destroy()
1415  */
1416 API int tethering_create(tethering_h *tethering)
1417 {
1418         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1419         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1420                         "parameter(tethering) is NULL\n");
1421         INFO("+\n");
1422
1423         __tethering_h *th = NULL;
1424         GError *error = NULL;
1425         char ssid[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, };
1426
1427         th = (__tethering_h *)malloc(sizeof(__tethering_h));
1428
1429         _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1430                         "malloc is failed\n");
1431         memset(th, 0x00, sizeof(__tethering_h));
1432         th->sec_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
1433         th->visibility = true;
1434         th->mac_filter = false;
1435         th->channel = 6;
1436         th->mode_type = TETHERING_WIFI_MODE_TYPE_G;
1437         th->wifi_max_connected = TETHERING_WIFI_MAX_STA;
1438
1439         if (__generate_initial_passphrase(th->passphrase,
1440                         sizeof(th->passphrase)) == 0) {
1441                 //LCOV_EXCL_START
1442                 ERR("random passphrase generation failed\n");
1443                 free(th);
1444                 return TETHERING_ERROR_OPERATION_FAILED;
1445                 //LCOV_EXCL_STOP
1446         }
1447
1448         if (__get_common_ssid(ssid, sizeof(ssid)) != TETHERING_ERROR_NONE) {
1449                 //LCOV_EXCL_START
1450                 ERR("common ssid get failed\n");
1451                 free(th);
1452                 return TETHERING_ERROR_OPERATION_FAILED;
1453                 //LCOV_EXCL_STOP
1454         }
1455
1456 #if !GLIB_CHECK_VERSION(2, 36, 0)
1457         g_type_init();
1458 #endif
1459         GCancellable *cancellable = g_cancellable_new();
1460         th->client_bus = g_bus_get_sync(DBUS_BUS_SYSTEM, cancellable, &error);
1461         if (error) {
1462                 //LCOV_EXCL_START
1463                 ERR("Couldn't connect to the System bus[%s]", error->message);
1464                 g_error_free(error);
1465                 g_cancellable_cancel(cancellable);
1466                 g_object_unref(cancellable);
1467                 free(th);
1468                 return TETHERING_ERROR_OPERATION_FAILED;
1469                 //LCOV_EXCL_STOP
1470         }
1471         th->cancellable = cancellable;
1472
1473         th->client_bus_proxy = g_dbus_proxy_new_sync(th->client_bus, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
1474                         NULL, TETHERING_SERVICE_NAME, TETHERING_SERVICE_OBJECT_PATH,
1475                         TETHERING_SERVICE_INTERFACE, th->cancellable, &error);
1476         if (!th->client_bus_proxy) {
1477                 //LCOV_EXCL_START
1478                 if (error)
1479                         ERR("Couldn't create the proxy object because of %s\n", error->message);
1480                 g_cancellable_cancel(th->cancellable);
1481                 g_object_unref(th->cancellable);
1482                 g_object_unref(th->client_bus);
1483                 free(th);
1484                 return TETHERING_ERROR_OPERATION_FAILED;
1485                 //LCOV_EXCL_STOP
1486         }
1487
1488         __connect_signals((tethering_h)th);
1489
1490         *tethering = (tethering_h)th;
1491         _tethering_add_handle(th);
1492         INFO("Tethering Handle : 0x%X\n", th);
1493         INFO("-\n");
1494         return TETHERING_ERROR_NONE;
1495 }
1496
1497 /**
1498  * @internal
1499  * @brief  Destroys the handle of tethering.
1500  * @since_tizen 2.3
1501  * @privlevel platform
1502  * @privilege http://tizen.org/privilege/tethering.admin
1503  * @param[in]  tethering  The handle of tethering
1504  * @return  0 on success, otherwise a negative error value.
1505  * @retval  #TETHERING_ERROR_NONE  Successful
1506  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1507  * @see  tethering_create()
1508  */
1509 API int tethering_destroy(tethering_h tethering)
1510 {
1511         INFO("+\n");
1512         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1513         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1514                         "parameter(tethering) is NULL\n");
1515
1516         __tethering_h *th = (__tethering_h *)tethering;
1517
1518         INFO("Tethering Handle : 0x%X\n", th);
1519
1520         __disconnect_signals(tethering);
1521         _tethering_remove_handle(th);
1522
1523         if (th->ssid)
1524                 free(th->ssid);
1525
1526         g_object_unref(th->cancellable);
1527         g_object_unref(th->client_bus_proxy);
1528         g_object_unref(th->client_bus);
1529         memset(th, 0x00, sizeof(__tethering_h));
1530
1531         free(th);
1532
1533         INFO("-\n");
1534         return TETHERING_ERROR_NONE;
1535 }
1536
1537 /**
1538  * @internal
1539  * @brief Enables the tethering, asynchronously.
1540  * @since_tizen 2.3
1541  * @privlevel platform
1542  * @privilege http://tizen.org/privilege/tethering.admin
1543  * @param[in]  tethering  The handle of tethering
1544  * @param[in]  type  The type of tethering
1545  * @return 0 on success, otherwise negative error value.
1546  * @retval  #TETHERING_ERROR_NONE  Successful
1547  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1548  * @post tethering_enabled_cb() will be invoked.
1549  * @see  tethering_is_enabled()
1550  * @see  tethering_disable()
1551  */
1552 API int tethering_enable(tethering_h tethering, tethering_type_e type)
1553 {
1554         INFO("+ type :  %d\n", type);
1555         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1556         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1557         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1558         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1559
1560         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1561                         "parameter(tethering) is NULL\n");
1562
1563         tethering_error_e ret = TETHERING_ERROR_NONE;
1564         __tethering_h *th = (__tethering_h *)tethering;
1565         GDBusProxy *proxy = th->client_bus_proxy;
1566         GDBusConnection *connection = th->client_bus;
1567
1568         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE);
1569
1570         if (__check_precondition(type) == FALSE) {
1571                 //LCOV_EXCL_START
1572                 INFO("-\n");
1573                 return TETHERING_ERROR_OPERATION_FAILED;
1574                 //LCOV_EXCL_STOP
1575         }
1576
1577         switch (type) {
1578         //LCOV_EXCL_START
1579         case TETHERING_TYPE_USB:
1580                 g_dbus_connection_signal_unsubscribe(connection,
1581                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1582
1583                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1584                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1585                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1586                 break;
1587         //LCOV_EXCL_STOP
1588
1589         case TETHERING_TYPE_WIFI: {
1590                 _softap_settings_t set = {"", "", "", 0, false};
1591
1592                 ret = __prepare_wifi_settings(tethering, &set);
1593                 if (ret != TETHERING_ERROR_NONE) {
1594                         //LCOV_EXCL_START
1595                         ERR("softap settings initialization failed\n");
1596                         DBG("-\n");
1597                         return TETHERING_ERROR_OPERATION_FAILED;
1598                         //LCOV_EXCL_STOP
1599                 }
1600                 g_dbus_connection_signal_unsubscribe(connection,
1601                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1602
1603                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1604                                 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),
1605                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1606                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1607                 break;
1608         }
1609
1610         case TETHERING_TYPE_BT:
1611                 g_dbus_connection_signal_unsubscribe(connection,
1612                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1613
1614                 g_dbus_proxy_call(proxy, "enable_bt_tethering",
1615                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1616                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1617                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1618
1619                 break;
1620
1621         //LCOV_EXCL_START
1622         case TETHERING_TYPE_P2P: {
1623                 _softap_settings_t p2p_set = {"", "", "", 0, false};
1624                 ret = __prepare_wifi_settings(tethering, &p2p_set);
1625                 if (ret != TETHERING_ERROR_NONE) {
1626                         ERR("p2p settings initialization failed\n");
1627                         DBG("-\n");
1628                         return TETHERING_ERROR_OPERATION_FAILED;
1629                 }
1630
1631                 g_dbus_proxy_call(proxy, "enable_p2p_tethering",
1632                                 g_variant_new("(ssi)", p2p_set.ssid, p2p_set.key, p2p_set.channel),
1633                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1634                                 (GAsyncReadyCallback) __p2p_enabled_cfm_cb, (gpointer)tethering);
1635                 break;
1636         }
1637
1638         case TETHERING_TYPE_ALL: {
1639                 _softap_settings_t set = {"", "", "", 0, false};
1640
1641                 ret = __prepare_wifi_settings(tethering, &set);
1642                 if (ret != TETHERING_ERROR_NONE) {
1643                         ERR("softap settings initialization failed\n");
1644                         return TETHERING_ERROR_OPERATION_FAILED;
1645                 }
1646
1647                 /* TETHERING_TYPE_USB */
1648                 g_dbus_connection_signal_unsubscribe(connection,
1649                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1650
1651                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1652                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1653                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1654
1655                 /* TETHERING_TYPE_WIFI */
1656                 g_dbus_connection_signal_unsubscribe(connection,
1657                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1658
1659                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1660                                 g_variant_new("(sssiiiiii)", set.ssid, set.key, set.mode,
1661                                 set.channel, set.visibility, set.mac_filter, set.max_connected,
1662                                 set.sec_type, TETHERING_ADDRESS_FAMILY_IPV4),
1663                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1664                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1665
1666                 /* TETHERING_TYPE_BT */
1667                 g_dbus_connection_signal_unsubscribe(connection,
1668                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1669
1670                 g_dbus_proxy_call(proxy, "enable_bt_tethering",
1671                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1672                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1673                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1674                 break;
1675         }
1676         default:
1677                 ERR("Unknown type : %d\n", type);
1678
1679                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1680
1681                 DBG("-\n");
1682                 return TETHERING_ERROR_INVALID_PARAMETER;
1683         }
1684         //LCOV_EXCL_STOP
1685
1686         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1687         INFO("-\n");
1688         return TETHERING_ERROR_NONE;
1689 }
1690
1691 API int tethering_ipv6_enable(tethering_h tethering, tethering_type_e type)
1692 {
1693         DBG("+ type :  %d\n", type);
1694         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1695         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1696         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1697         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1698
1699         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1700                         "parameter(tethering) is NULL\n");
1701
1702         __tethering_h *th = (__tethering_h *)tethering;
1703         GDBusProxy *proxy = th->client_bus_proxy;
1704         GDBusConnection *connection = th->client_bus;
1705         int ret = 0;
1706
1707         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE);
1708
1709         if (__check_precondition(type) == FALSE) {
1710                 //LCOV_EXCL_START
1711                 DBG("-\n");
1712                 return TETHERING_ERROR_OPERATION_FAILED;
1713                 //LCOV_EXCL_STOP
1714         }
1715
1716         switch (type) {
1717         case TETHERING_TYPE_WIFI: {
1718                 _softap_settings_t set = {"", "", "", 0, false, false, 0, 0};
1719
1720                 ret = __prepare_wifi_settings(tethering, &set);
1721                 if (ret != TETHERING_ERROR_NONE) {
1722                         ERR("softap settings initialization failed\n");
1723                         DBG("-\n");
1724                         return TETHERING_ERROR_OPERATION_FAILED;
1725                 }
1726                 g_dbus_connection_signal_unsubscribe(connection,
1727                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1728                         g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1729                                 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),
1730                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1731                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1732                 break;
1733          }
1734         case TETHERING_TYPE_BT: {
1735                 g_dbus_connection_signal_unsubscribe(connection,
1736                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1737
1738                 /* For TEST */
1739                 g_dbus_proxy_call(proxy, "enable_bt_tethering", g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1740                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1741                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1742
1743                 break;
1744         }
1745
1746         default: {
1747                 ERR("Unknown type : %d\n", type);
1748
1749                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1750
1751                 DBG("-\n");
1752                 return TETHERING_ERROR_INVALID_PARAMETER;
1753         }
1754         }
1755
1756         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1757         DBG("-\n");
1758         return TETHERING_ERROR_NONE;
1759 }
1760
1761 API int tethering_ipv6_disable(tethering_h tethering, tethering_type_e type)
1762 {
1763         DBG("+ type :  %d\n", type);
1764         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1765         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1766         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1767         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1768
1769         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1770                         "parameter(tethering) is NULL\n");
1771
1772         __tethering_h *th = (__tethering_h *)tethering;
1773         GDBusProxy *proxy = th->client_bus_proxy;
1774         GDBusConnection *connection = th->client_bus;
1775
1776         switch (type) {
1777         case TETHERING_TYPE_WIFI:
1778                 DBG("Disable wifi tethering..");
1779                 g_dbus_connection_signal_unsubscribe(connection,
1780                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1781
1782                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1783                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1784                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1785                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1786                 break;
1787         case TETHERING_TYPE_BT:
1788                 g_dbus_connection_signal_unsubscribe(connection,
1789                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1790
1791                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1792                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1793                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1794                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1795                 break;
1796
1797         default:
1798                 ERR("Not supported tethering type [%d]\n", type);
1799                 DBG("-\n");
1800                 return TETHERING_ERROR_INVALID_PARAMETER;
1801         }
1802         DBG("-\n");
1803         return TETHERING_ERROR_NONE;
1804 }
1805 /**
1806  * @internal
1807  * @brief Disables the tethering, asynchronously.
1808  * @since_tizen 2.3
1809  * @privlevel platform
1810  * @privilege http://tizen.org/privilege/tethering.admin
1811  * @param[in]  tethering  The handle of tethering
1812  * @param[in]  type  The type of tethering
1813  * @return 0 on success, otherwise negative error value.
1814  * @retval  #TETHERING_ERROR_NONE  Successful
1815  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1816  * @post tethering_disabled_cb() will be invoked.
1817  * @see  tethering_is_enabled()
1818  * @see  tethering_enable()
1819  */
1820 API int tethering_disable(tethering_h tethering, tethering_type_e type)
1821 {
1822         INFO("+ type :  %d\n", type);
1823         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1824         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1825         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1826         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1827
1828         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1829                         "parameter(tethering) is NULL\n");
1830
1831         __tethering_h *th = (__tethering_h *)tethering;
1832         GDBusProxy *proxy = th->client_bus_proxy;
1833         GDBusConnection *connection = th->client_bus;
1834
1835         switch (type) {
1836         //LCOV_EXCL_START
1837         case TETHERING_TYPE_USB:
1838                 g_dbus_connection_signal_unsubscribe(connection,
1839                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1840
1841                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1842                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1843                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1844
1845                 break;
1846         //LCOV_EXCL_STOP
1847
1848         case TETHERING_TYPE_WIFI:
1849
1850                 g_dbus_connection_signal_unsubscribe(connection,
1851                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1852
1853                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1854                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1855                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1856                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1857                 break;
1858
1859         case TETHERING_TYPE_BT:
1860
1861                 g_dbus_connection_signal_unsubscribe(connection,
1862                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1863
1864                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1865                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1866                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1867                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1868                 break;
1869
1870         //LCOV_EXCL_START
1871         case TETHERING_TYPE_P2P:
1872                 g_dbus_proxy_call(proxy, "disable_p2p_tethering",
1873                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1874                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1875                 break;
1876
1877         case TETHERING_TYPE_ALL:
1878                 g_dbus_connection_signal_unsubscribe(connection,
1879                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1880
1881                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1882                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1883                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1884
1885                 g_dbus_connection_signal_unsubscribe(connection,
1886                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1887
1888                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1889                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1890                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1891                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1892
1893                 g_dbus_connection_signal_unsubscribe(connection,
1894                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1895
1896                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1897                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1898                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1899                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1900                 break;
1901
1902         default:
1903                 ERR("Not supported tethering type [%d]\n", type);
1904                 DBG("-\n");
1905                 return TETHERING_ERROR_INVALID_PARAMETER;
1906         //LCOV_EXCL_STOP
1907         }
1908         INFO("-\n");
1909         return TETHERING_ERROR_NONE;
1910 }
1911
1912 /**
1913  * @internal
1914  * @brief  Checks whetehr the tethering is enabled or not.
1915  * @since_tizen 2.3
1916  * @privlevel platform
1917  * @privilege http://tizen.org/privilege/tethering.admin
1918  * @param[in]  tethering  The handle of tethering
1919  * @param[in]  type  The type of tethering
1920  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
1921  */
1922 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
1923 {
1924         INFO("+ type :  %d\n", type);
1925         int is_on = 0;
1926         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
1927
1928         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1929
1930         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0)
1931                 return FALSE;
1932
1933         switch (type) {
1934         case TETHERING_TYPE_USB:
1935                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
1936                 break;
1937
1938         case TETHERING_TYPE_WIFI:
1939                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
1940                 break;
1941
1942         case TETHERING_TYPE_BT:
1943                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
1944                 break;
1945
1946         case TETHERING_TYPE_P2P:
1947                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_P2P;
1948                 break;
1949
1950         default:
1951                 ERR("Not supported type : %d\n", type);
1952                 break;
1953         }
1954         INFO("- enabled:  %s\n", (is_on & vconf_type) ? "true" : "false");
1955         return is_on & vconf_type ? true : false;
1956 }
1957
1958 /**
1959  * @internal
1960  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
1961  * @since_tizen 2.3
1962  * @privlevel platform
1963  * @privilege http://tizen.org/privilege/tethering.admin
1964  * @remarks @a mac_address must be released with free() by you.
1965  * @param[in]  tethering  The handle of tethering
1966  * @param[in]  type  The type of tethering
1967  * @param[out]  mac_address  The MAC address
1968  * @return  0 on success, otherwise a negative error value.
1969  * @retval  #TETHERING_ERROR_NONE  Successful
1970  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1971  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1972  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1973  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1974  * @pre  tethering must be enabled.
1975  * @see  tethering_is_enabled()
1976  * @see  tethering_enable()
1977  */
1978 API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
1979 {
1980         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1981         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); //LCOV_EXCL_LINE
1982         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1983         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); //LCOV_EXCL_LINE
1984
1985         _retvm_if(tethering_is_enabled(tethering, type) == false,
1986                         TETHERING_ERROR_NOT_ENABLED,
1987                         "tethering type[%d] is not enabled\n", type);
1988         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1989                         "parameter(tethering) is NULL\n");
1990         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1991                         "parameter(mac_address) is NULL\n");
1992
1993         struct ifreq ifr;
1994         int s = 0;
1995         char *macbuf = NULL;
1996
1997         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1998                         TETHERING_ERROR_OPERATION_FAILED,
1999                         "getting interface name is failed\n");
2000
2001         s = socket(AF_INET, SOCK_DGRAM, 0);
2002         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
2003                         "getting socket is failed\n");
2004         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
2005                 //LCOV_EXCL_START
2006                 ERR("getting mac is failed\n");
2007                 close(s);
2008                 return TETHERING_ERROR_OPERATION_FAILED;
2009                 //LCOV_EXCL_STOP
2010         }
2011         close(s);
2012
2013         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
2014         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2015                         "Not enough memory\n");
2016         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
2017                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
2018                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
2019                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
2020                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
2021                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
2022                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
2023
2024         *mac_address = macbuf;
2025
2026         return TETHERING_ERROR_NONE;
2027 }
2028
2029 /**
2030  * @internal
2031  * @brief Gets the name of network interface. For example, usb0.
2032  * @since_tizen 2.3
2033  * @privlevel platform
2034  * @privilege http://tizen.org/privilege/tethering.admin
2035  * @remarks @a interface_name must be released with free() by you.
2036  * @param[in]  tethering  The handle of tethering
2037  * @param[in]  type  The type of tethering
2038  * @param[out]  interface_name  The name of network interface
2039  * @return 0 on success, otherwise negative error value.
2040  * @retval  #TETHERING_ERROR_NONE  Successful
2041  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2042  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2043  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2044  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2045  * @pre  tethering must be enabled.
2046  * @see  tethering_is_enabled()
2047  * @see  tethering_enable()
2048  */
2049 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
2050 {
2051         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2052         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2053         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2054         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2055
2056         _retvm_if(tethering_is_enabled(tethering, type) == false,
2057                         TETHERING_ERROR_NOT_ENABLED,
2058                         "tethering type[%d] is not enabled\n", type);
2059         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2060                         "parameter(tethering) is NULL\n");
2061         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2062                         "parameter(interface_name) is NULL\n");
2063
2064         char intf[TETHERING_STR_INFO_LEN] = {0, };
2065
2066         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
2067                         TETHERING_ERROR_OPERATION_FAILED,
2068                         "getting interface name is failed\n");
2069         *interface_name = strdup(intf);
2070         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2071                         "Not enough memory\n");
2072
2073         return TETHERING_ERROR_NONE;
2074 }
2075
2076 /**
2077  * @internal
2078  * @brief Gets the local IP address.
2079  * @since_tizen 2.3
2080  * @privlevel platform
2081  * @privilege http://tizen.org/privilege/tethering.admin
2082  * @remarks @a ip_address must be released with free() by you.
2083  * @param[in]  tethering  The handle of tethering
2084  * @param[in]  type  The type of tethering
2085  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2086  * @param[out]  ip_address  The local IP address
2087  * @return 0 on success, otherwise negative error value.
2088  * @retval  #TETHERING_ERROR_NONE  Successful
2089  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2090  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2091  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2092  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2093  * @pre  tethering must be enabled.
2094  * @see  tethering_is_enabled()
2095  * @see  tethering_enable()
2096  */
2097 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
2098 {
2099         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2100         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE); //LCOV_EXCL_LINE
2101         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2102         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE); //LCOV_EXCL_LINE
2103
2104         _retvm_if(tethering_is_enabled(tethering, type) == false,
2105                         TETHERING_ERROR_NOT_ENABLED,
2106                         "tethering type[%d] is not enabled\n", type);
2107         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2108                         "parameter(tethering) is NULL\n");
2109         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2110                         "parameter(ip_address) is NULL\n");
2111
2112         struct ifreq ifr;
2113         int s = 0;
2114         char *ipbuf = NULL;
2115
2116         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
2117                         TETHERING_ERROR_OPERATION_FAILED,
2118                         "getting interface name is failed\n");
2119
2120         s = socket(AF_INET, SOCK_DGRAM, 0);
2121         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
2122                         "getting socket is failed\n");
2123         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
2124                 ERR("ioctl is failed\n");
2125                 close(s);
2126                 return TETHERING_ERROR_OPERATION_FAILED;
2127         }
2128         close(s);
2129
2130         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
2131         *ip_address = strdup(ipbuf);
2132         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2133                         "Not enough memory\n");
2134
2135         return TETHERING_ERROR_NONE;
2136 }
2137
2138 /**
2139  * @internal
2140  * @brief Gets the Gateway address.
2141  * @since_tizen 2.3
2142  * @privlevel platform
2143  * @privilege http://tizen.org/privilege/tethering.admin
2144  * @remarks @a gateway_address must be released with free() by you.
2145  * @param[in]  tethering  The handle of tethering
2146  * @param[in]  type  The type of tethering
2147  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2148  * @param[out]  gateway_address  The local IP address
2149  * @return 0 on success, otherwise negative error value.
2150  * @retval  #TETHERING_ERROR_NONE  Successful
2151  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2152  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2153  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2154  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2155  * @pre  tethering must be enabled.
2156  * @see  tethering_is_enabled()
2157  * @see  tethering_enable()
2158  */
2159 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
2160 {
2161         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2162         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2163         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2164         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2165
2166         _retvm_if(tethering_is_enabled(tethering, type) == false,
2167                         TETHERING_ERROR_NOT_ENABLED,
2168                         "tethering type[%d] is not enabled\n", type);
2169         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2170                         "parameter(tethering) is NULL\n");
2171         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2172                         "parameter(gateway_address) is NULL\n");
2173
2174         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
2175
2176         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
2177                         TETHERING_ERROR_OPERATION_FAILED,
2178                         "getting gateway address is failed\n");
2179
2180         *gateway_address = strdup(gateway_buf);
2181
2182         return TETHERING_ERROR_NONE;
2183 }
2184
2185 /**
2186  * @internal
2187  * @brief Gets the Subnet Mask.
2188  * @since_tizen 2.3
2189  * @privlevel platform
2190  * @privilege http://tizen.org/privilege/tethering.admin
2191  * @remarks @a subnet_mask must be released with free() by you.
2192  * @param[in]  tethering  The handle of tethering
2193  * @param[in]  type  The type of tethering
2194  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2195  * @param[out]  subnet_mask  The local IP address
2196  * @return 0 on success, otherwise negative error value.
2197  * @retval  #TETHERING_ERROR_NONE  Successful
2198  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2199  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2200  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2201  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2202  * @pre  tethering must be enabled.
2203  * @see  tethering_is_enabled()
2204  * @see  tethering_enable()
2205  */
2206 API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
2207 {
2208         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2209         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2210         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2211         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2212
2213         _retvm_if(tethering_is_enabled(tethering, type) == false,
2214                         TETHERING_ERROR_NOT_ENABLED,
2215                         "tethering is not enabled\n");
2216         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2217                         "parameter(tethering) is NULL\n");
2218         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2219                         "parameter(subnet_mask) is NULL\n");
2220
2221         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
2222         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2223                         "Not enough memory\n");
2224
2225         return TETHERING_ERROR_NONE;
2226 }
2227
2228 /**
2229  * @internal
2230  * @brief Gets the data usage.
2231  * @since_tizen 2.3
2232  * @privlevel platform
2233  * @privilege http://tizen.org/privilege/tethering.admin
2234  * @param[in]  tethering  The handle of tethering
2235  * @param[out]  usage  The data usage
2236  * @return 0 on success, otherwise negative error value.
2237  * @retval  #TETHERING_ERROR_NONE  Successful
2238  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2239  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2240  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2241  * @pre  tethering must be enabled.
2242  * @see  tethering_is_enabled()
2243  * @see  tethering_enable()
2244  */
2245 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
2246 {
2247         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2248
2249         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2250                         "parameter(tethering) is NULL\n");
2251         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2252                         "parameter(callback) is NULL\n");
2253         _retvm_if(__any_tethering_is_enabled(tethering) == false,
2254                         TETHERING_ERROR_NOT_ENABLED,
2255                         "tethering is not enabled\n");
2256
2257         __tethering_h *th = (__tethering_h *)tethering;
2258         GDBusProxy *proxy = th->client_bus_proxy;
2259
2260         th->data_usage_cb = callback;
2261         th->data_usage_user_data = user_data;
2262
2263         g_dbus_proxy_call(proxy, "get_data_packet_usage",
2264                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
2265                         (GAsyncReadyCallback) __get_data_usage_cb, (gpointer)tethering);
2266
2267         return TETHERING_ERROR_NONE;
2268 }
2269
2270 /**
2271  * @internal
2272  * @brief Gets the client which is connected by tethering "type".
2273  * @since_tizen 2.3
2274  * @privlevel platform
2275  * @privilege http://tizen.org/privilege/tethering.admin
2276  * @param[in]  tethering  The handle of tethering
2277  * @param[in]  type  The type of tethering
2278  * @param[in]  callback  The callback function to invoke
2279  * @param[in]  user_data  The user data to be passed to the callback function
2280  * @retval  #TETHERING_ERROR_NONE  Successful
2281  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2282  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2283  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2284  * @pre  tethering must be enabled.
2285  * @see  tethering_is_enabled()
2286  * @see  tethering_enable()
2287  */
2288 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
2289 {
2290         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2291         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2292         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2293         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2294
2295         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2296                         "parameter(tethering) is NULL\n");
2297         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2298                         "parameter(callback) is NULL\n");
2299         _retvm_if(__any_tethering_is_enabled(tethering) == false,
2300                         TETHERING_ERROR_NOT_ENABLED,
2301                         "tethering is not enabled\n");
2302
2303         mobile_ap_type_e interface;
2304         __tethering_h *th = (__tethering_h *)tethering;
2305         __tethering_client_h client = {0, };
2306         gchar *ip = NULL;
2307         gchar *mac = NULL;
2308         gchar *hostname = NULL;
2309         guint timestamp = 0;
2310         GError *error = NULL;
2311         GVariant *result = NULL;
2312         GVariantIter *outer_iter = NULL;
2313         GVariantIter *inner_iter = NULL;
2314         GVariant *station = NULL;
2315         GVariant *value = NULL;
2316         gchar *key = NULL;
2317
2318         result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_station_info",
2319                         NULL, G_DBUS_CALL_FLAGS_NONE,
2320                         -1, th->cancellable, &error);
2321         if (error)
2322                 ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message); //LCOV_EXCL_LINE
2323         g_variant_get(result, "(a(a{sv}))", &outer_iter);
2324         //LCOV_EXCL_START
2325         while (g_variant_iter_loop(outer_iter, "(@a{sv})", &station)) {
2326                 g_variant_get(station, "a{sv}", &inner_iter);
2327                 while (g_variant_iter_loop(inner_iter, "{sv}", &key, &value)) {
2328                         if (g_strcmp0(key, "Type") == 0) {
2329                                 interface = g_variant_get_int32(value);
2330                                 if (interface == MOBILE_AP_TYPE_USB)
2331                                         client.interface = TETHERING_TYPE_USB;
2332                                 else if (interface == MOBILE_AP_TYPE_WIFI)
2333                                         client.interface = TETHERING_TYPE_WIFI;
2334                                 else if (interface == MOBILE_AP_TYPE_BT)
2335                                         client.interface = TETHERING_TYPE_BT;
2336                                 else {
2337                                         ERR("Invalid interface\n");
2338                                         g_free(key);
2339                                         g_variant_unref(value);
2340                                         break;
2341                                 }
2342                                 DBG("interface is %d\n", client.interface);
2343                                 if (client.interface != type && (TETHERING_TYPE_ALL != type)) {
2344                                         g_free(key);
2345                                         g_variant_unref(value);
2346                                         break;
2347                                 }
2348                         } else if (g_strcmp0(key, "IP") == 0) {
2349                                 g_variant_get(value, "s", &ip);
2350                                 SDBG("ip is %s\n", ip);
2351                                 g_strlcpy(client.ip, ip, sizeof(client.ip));
2352                         } else if (g_strcmp0(key, "MAC") == 0) {
2353                                 g_variant_get(value, "s", &mac);
2354                                 SDBG("mac is %s\n", mac);
2355                                 g_strlcpy(client.mac, mac, sizeof(client.mac));
2356                         } else if (g_strcmp0(key, "Name") == 0) {
2357                                 g_variant_get(value, "s", &hostname);
2358                                 SDBG("hsotname is %s\n", hostname);
2359                                 if (hostname)
2360                                         client.hostname = g_strdup(hostname);
2361                         } else if (g_strcmp0(key, "Time") == 0) {
2362                                 timestamp = g_variant_get_int32(value);
2363                                 DBG("timestamp is %d\n", timestamp);
2364                                 client.tm = (time_t)timestamp;
2365                         } else {
2366                                 ERR("Key %s not required\n", key);
2367                         }
2368                 }
2369                 g_free(hostname);
2370                 g_free(ip);
2371                 g_free(mac);
2372                 g_variant_iter_free(inner_iter);
2373                 if (callback((tethering_client_h)&client, user_data) == false) {
2374                         DBG("iteration is stopped\n");
2375                         g_free(client.hostname);
2376                         g_variant_iter_free(outer_iter);
2377                         g_variant_unref(station);
2378                         g_variant_unref(result);
2379                         DBG("-\n");
2380                         return TETHERING_ERROR_OPERATION_FAILED;
2381                 }
2382                 g_free(client.hostname);
2383         }
2384         //LCOV_EXCL_STOP
2385         g_variant_iter_free(outer_iter);
2386         g_variant_unref(station);
2387         g_variant_unref(result);
2388         DBG("-\n");
2389         return TETHERING_ERROR_NONE;
2390 }
2391
2392 /**
2393  * @internal
2394  * @brief Registers the callback function called when tethering is enabled.
2395  * @since_tizen 2.3
2396  * @privlevel platform
2397  * @privilege http://tizen.org/privilege/tethering.admin
2398  * @param[in]  tethering  The handle of tethering
2399  * @param[in]  type  The type of tethering
2400  * @param[in]  callback  The callback function to invoke
2401  * @param[in]  user_data  The user data to be passed to the callback function
2402  * @retval  #TETHERING_ERROR_NONE  Successful
2403  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2404  * @see  tethering_unset_enabled_cb()
2405  */
2406 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
2407 {
2408         INFO("+ type: %d\n", type);
2409         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2410         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2411         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2412         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2413
2414         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2415                         "parameter(tethering) is NULL\n");
2416         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2417                         "parameter(callback) is NULL\n");
2418
2419         __tethering_h *th = (__tethering_h *)tethering;
2420         tethering_type_e ti;
2421
2422         if (type != TETHERING_TYPE_ALL) {
2423                 th->enabled_cb[type] = callback;
2424                 th->enabled_user_data[type] = user_data;
2425
2426                 return TETHERING_ERROR_NONE;
2427         }
2428
2429         /* TETHERING_TYPE_ALL */
2430         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2431                 th->enabled_cb[ti] = callback;
2432                 th->enabled_user_data[ti] = user_data;
2433         }
2434
2435         INFO("-\n");
2436         return TETHERING_ERROR_NONE;
2437 }
2438
2439 /**
2440  * @internal
2441  * @brief Unregisters the callback function called when tethering is disabled.
2442  * @since_tizen 2.3
2443  * @privlevel platform
2444  * @privilege http://tizen.org/privilege/tethering.admin
2445  * @param[in]  tethering  The handle of tethering
2446  * @param[in]  type  The type of tethering
2447  * @retval  #TETHERING_ERROR_NONE  Successful
2448  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2449  * @see  tethering_set_enabled_cb()
2450  */
2451 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
2452 {
2453         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2454         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2455         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2456         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2457
2458         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2459                         "parameter(tethering) is NULL\n");
2460
2461         __tethering_h *th = (__tethering_h *)tethering;
2462         tethering_type_e ti;
2463
2464         if (type != TETHERING_TYPE_ALL) {
2465                 th->enabled_cb[type] = NULL;
2466                 th->enabled_user_data[type] = NULL;
2467
2468                 return TETHERING_ERROR_NONE;
2469         }
2470
2471         /* TETHERING_TYPE_ALL */
2472         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2473                 th->enabled_cb[ti] = NULL;
2474                 th->enabled_user_data[ti] = NULL;
2475         }
2476
2477         return TETHERING_ERROR_NONE;
2478 }
2479
2480 /**
2481  * @internal
2482  * @brief Registers the callback function called when tethering is disabled.
2483  * @since_tizen 2.3
2484  * @privlevel platform
2485  * @privilege http://tizen.org/privilege/tethering.admin
2486  * @param[in]  tethering  The handle of tethering
2487  * @param[in]  type  The type of tethering
2488  * @param[in]  callback  The callback function to invoke
2489  * @param[in]  user_data  The user data to be passed to the callback function
2490  * @retval  #TETHERING_ERROR_NONE  Successful
2491  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2492  * @see  tethering_unset_disabled_cb()
2493  */
2494 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
2495 {
2496         INFO("+ type: %d\n", type);
2497         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2498         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2499         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2500         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2501
2502         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2503                         "parameter(tethering) is NULL\n");
2504         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2505                         "parameter(callback) is NULL\n");
2506
2507         __tethering_h *th = (__tethering_h *)tethering;
2508         tethering_type_e ti;
2509
2510         if (type != TETHERING_TYPE_ALL) {
2511                 th->disabled_cb[type] = callback;
2512                 th->disabled_user_data[type] = user_data;
2513
2514                 return TETHERING_ERROR_NONE;
2515         }
2516
2517         /* TETHERING_TYPE_ALL */
2518         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2519                 th->disabled_cb[ti] = callback;
2520                 th->disabled_user_data[ti] = user_data;
2521         }
2522         INFO("-\n");
2523         return TETHERING_ERROR_NONE;
2524 }
2525
2526 /**
2527  * @internal
2528  * @brief Unregisters the callback function called when tethering is disabled.
2529  * @since_tizen 2.3
2530  * @privlevel platform
2531  * @privilege http://tizen.org/privilege/tethering.admin
2532  * @param[in]  tethering  The handle of tethering
2533  * @param[in]  type  The type of tethering
2534  * @retval  #TETHERING_ERROR_NONE  Successful
2535  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2536  * @see  tethering_set_disabled_cb()
2537  */
2538 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
2539 {
2540         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2541         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2542         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2543         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2544
2545         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2546                         "parameter(tethering) is NULL\n");
2547
2548         __tethering_h *th = (__tethering_h *)tethering;
2549         tethering_type_e ti;
2550
2551         if (type != TETHERING_TYPE_ALL) {
2552                 th->disabled_cb[type] = NULL;
2553                 th->disabled_user_data[type] = NULL;
2554
2555                 return TETHERING_ERROR_NONE;
2556         }
2557
2558         /* TETHERING_TYPE_ALL */
2559         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_P2P; ti++) {
2560                 th->disabled_cb[ti] = NULL;
2561                 th->disabled_user_data[ti] = NULL;
2562         }
2563
2564         return TETHERING_ERROR_NONE;
2565 }
2566
2567 /**
2568  * @internal
2569  * @brief Registers the callback function called when the state of connection is changed.
2570  * @since_tizen 2.3
2571  * @privlevel platform
2572  * @privilege http://tizen.org/privilege/tethering.admin
2573  * @param[in]  tethering  The handle of tethering
2574  * @param[in]  type  The type of tethering
2575  * @param[in]  callback  The callback function to invoke
2576  * @param[in]  user_data  The user data to be passed to the callback function
2577  * @retval  #TETHERING_ERROR_NONE  Successful
2578  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2579  * @see  tethering_unset_connection_state_changed_cb_cb()
2580  */
2581 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
2582 {
2583         INFO("+ type: %d\n", type);
2584         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2585         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2586         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2587         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2588
2589         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2590                         "parameter(tethering) is NULL\n");
2591         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2592                         "parameter(callback) is NULL\n");
2593
2594         __tethering_h *th = (__tethering_h *)tethering;
2595         tethering_type_e ti;
2596
2597         if (type != TETHERING_TYPE_ALL) {
2598                 th->changed_cb[type] = callback;
2599                 th->changed_user_data[type] = user_data;
2600
2601                 return TETHERING_ERROR_NONE;
2602         }
2603
2604         /* TETHERING_TYPE_ALL */
2605         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2606                 th->changed_cb[ti] = callback;
2607                 th->changed_user_data[ti] = user_data;
2608         }
2609         INFO("-\n");
2610         return TETHERING_ERROR_NONE;
2611 }
2612
2613 /**
2614  * @internal
2615  * @brief Unregisters the callback function called when the state of connection is changed.
2616  * @since_tizen 2.3
2617  * @privlevel platform
2618  * @privilege http://tizen.org/privilege/tethering.admin
2619  * @param[in]  tethering  The handle of tethering
2620  * @param[in]  type  The type of tethering
2621  * @retval  #TETHERING_ERROR_NONE  Successful
2622  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2623  * @see  tethering_set_connection_state_changed_cb()
2624  */
2625 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
2626 {
2627         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2628         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2629         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2630         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2631
2632         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2633                         "parameter(tethering) is NULL\n");
2634
2635         __tethering_h *th = (__tethering_h *)tethering;
2636         tethering_type_e ti;
2637
2638         if (type != TETHERING_TYPE_ALL) {
2639                 th->changed_cb[type] = NULL;
2640                 th->changed_user_data[type] = NULL;
2641
2642                 return TETHERING_ERROR_NONE;
2643         }
2644
2645         /* TETHERING_TYPE_ALL */
2646         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2647                 th->changed_cb[ti] = NULL;
2648                 th->changed_user_data[ti] = NULL;
2649         }
2650
2651         return TETHERING_ERROR_NONE;
2652 }
2653
2654 /**
2655  * @internal
2656  * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed.
2657  * @since_tizen 2.3
2658  * @privlevel platform
2659  * @privilege http://tizen.org/privilege/tethering.admin
2660  * @param[in]  tethering  The handle of tethering
2661  * @param[in]  callback  The callback function to invoke
2662  * @param[in]  user_data  The user data to be passed to the callback function
2663  * @retval  #TETHERING_ERROR_NONE  Successful
2664  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2665  * @see  tethering_wifi_unset_security_type_changed_cb()
2666  */
2667 API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data)
2668 {
2669         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2670         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2671
2672         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2673                         "parameter(tethering) is NULL\n");
2674         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2675                         "parameter(callback) is NULL\n");
2676
2677         __tethering_h *th = (__tethering_h *)tethering;
2678
2679         th->security_type_changed_cb = callback;
2680         th->security_type_user_data = user_data;
2681
2682         return TETHERING_ERROR_NONE;
2683
2684 }
2685
2686 /**
2687  * @internal
2688  * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed.
2689  * @since_tizen 2.3
2690  * @privlevel platform
2691  * @privilege http://tizen.org/privilege/tethering.admin
2692  * @param[in]  tethering  The handle of tethering
2693  * @param[in]  type  The type of tethering
2694  * @retval  #TETHERING_ERROR_NONE  Successful
2695  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2696  * @see  tethering_wifi_set_security_type_changed_cb()
2697  */
2698 API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering)
2699 {
2700         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2701         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2702
2703         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2704                         "parameter(tethering) is NULL\n");
2705
2706         __tethering_h *th = (__tethering_h *)tethering;
2707
2708         th->security_type_changed_cb = NULL;
2709         th->security_type_user_data = NULL;
2710
2711         return TETHERING_ERROR_NONE;
2712 }
2713
2714 /**
2715  * @internal
2716  * @brief Registers the callback function called when the visibility of SSID is changed.
2717  * @since_tizen 2.3
2718  * @privlevel platform
2719  * @privilege http://tizen.org/privilege/tethering.admin
2720  * @param[in]  tethering  The handle of tethering
2721  * @param[in]  callback  The callback function to invoke
2722  * @param[in]  user_data  The user data to be passed to the callback function
2723  * @retval  #TETHERING_ERROR_NONE  Successful
2724  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2725  * @see  tethering_wifi_unset_ssid_visibility_changed_cb_cb()
2726  */
2727 API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data)
2728 {
2729         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2730         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2731
2732         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2733                         "parameter(tethering) is NULL\n");
2734         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2735                         "parameter(callback) is NULL\n");
2736
2737         __tethering_h *th = (__tethering_h *)tethering;
2738
2739         th->ssid_visibility_changed_cb = callback;
2740         th->ssid_visibility_user_data = user_data;
2741
2742         return TETHERING_ERROR_NONE;
2743 }
2744
2745 /**
2746  * @internal
2747  * @brief Unregisters the callback function called when the visibility of SSID is changed.
2748  * @since_tizen 2.3
2749  * @privlevel platform
2750  * @privilege http://tizen.org/privilege/tethering.admin
2751  * @param[in]  tethering  The handle of tethering
2752  * @retval  #TETHERING_ERROR_NONE  Successful
2753  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2754  * @see  tethering_wifi_set_ssid_visibility_changed_cb()
2755  */
2756 API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering)
2757 {
2758         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2759         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2760
2761         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2762                         "parameter(tethering) is NULL\n");
2763
2764         __tethering_h *th = (__tethering_h *)tethering;
2765
2766         th->ssid_visibility_changed_cb = NULL;
2767         th->ssid_visibility_user_data = NULL;
2768
2769         return TETHERING_ERROR_NONE;
2770 }
2771
2772 /**
2773  * @internal
2774  * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed.
2775  * @since_tizen 2.3
2776  * @privlevel platform
2777  * @privilege http://tizen.org/privilege/tethering.admin
2778  * @param[in]  tethering  The handle of tethering
2779  * @param[in]  callback  The callback function to invoke
2780  * @param[in]  user_data  The user data to be passed to the callback function
2781  * @retval  #TETHERING_ERROR_NONE  Successful
2782  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2783  * @see  tethering_wifi_unset_passphrase_changed_cb()
2784  */
2785 API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data)
2786 {
2787         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2788         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2789
2790         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2791                         "parameter(tethering) is NULL\n");
2792         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2793                         "parameter(callback) is NULL\n");
2794
2795         __tethering_h *th = (__tethering_h *)tethering;
2796
2797         th->passphrase_changed_cb = callback;
2798         th->passphrase_user_data = user_data;
2799
2800         return TETHERING_ERROR_NONE;
2801 }
2802
2803 /**
2804  * @internal
2805  * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed.
2806  * @since_tizen 2.3
2807  * @privlevel platform
2808  * @privilege http://tizen.org/privilege/tethering.admin
2809  * @param[in]  tethering  The handle of tethering
2810  * @retval  #TETHERING_ERROR_NONE  Successful
2811  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2812  * @see  tethering_wifi_set_passphrase_changed_cb()
2813  */
2814 API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering)
2815 {
2816         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2817         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2818
2819         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2820                         "parameter(tethering) is NULL\n");
2821
2822         __tethering_h *th = (__tethering_h *)tethering;
2823
2824         th->passphrase_changed_cb = NULL;
2825         th->passphrase_user_data = NULL;
2826
2827         return TETHERING_ERROR_NONE;
2828 }
2829
2830 /**
2831  * @internal
2832  * @brief Sets the security type of Wi-Fi tethering.
2833  * @since_tizen 2.3
2834  * @privlevel platform
2835  * @privilege http://tizen.org/privilege/tethering.admin
2836  * @remarks This change is applied next time Wi-Fi tethering is enabled
2837  * @param[in]  tethering  The handle of tethering
2838  * @param[in]  type  The security type
2839  * @return 0 on success, otherwise negative error value.
2840  * @retval  #TETHERING_ERROR_NONE  Successful
2841  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2842  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2843  * @see  tethering_wifi_get_security_type()
2844  */
2845 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
2846 {
2847         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2848         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2849
2850         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2851                         "parameter(tethering) is NULL\n");
2852
2853         __tethering_h *th = (__tethering_h *)tethering;
2854         tethering_error_e ret = TETHERING_ERROR_NONE;
2855         char *sec_str = NULL;
2856
2857         ret = __set_security_type(type);
2858         if (ret == TETHERING_ERROR_NONE) {
2859
2860                 switch (type) {
2861                 case TETHERING_WIFI_SECURITY_TYPE_NONE:
2862                         sec_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
2863                         break;
2864                 case TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK:
2865                         sec_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
2866                         break;
2867                 case TETHERING_WIFI_SECURITY_TYPE_WPS:
2868                         sec_str = TETHERING_WIFI_SECURITY_TYPE_WPS_STR;
2869                         break;
2870                 }
2871
2872                 __send_dbus_signal(th->client_bus,
2873                                 SIGNAL_NAME_SECURITY_TYPE_CHANGED, sec_str);
2874         }
2875         return ret;
2876 }
2877
2878 /**
2879  * @internal
2880  * @brief Gets the security type of Wi-Fi tethering.
2881  * @since_tizen 2.3
2882  * @privlevel platform
2883  * @privilege http://tizen.org/privilege/tethering.admin
2884  * @param[in]  tethering  The handle of tethering
2885  * @param[out]  type  The security type
2886  * @return 0 on success, otherwise negative error value.
2887  * @retval  #TETHERING_ERROR_NONE  Successful
2888  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2889  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2890  * @see  tethering_wifi_set_security_type()
2891  */
2892 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
2893 {
2894         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2895         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2896
2897         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2898                         "parameter(type) is NULL\n");
2899
2900         return __get_security_type(type);
2901 }
2902
2903 /**
2904  * @internal
2905  * @brief Sets the SSID (service set identifier).
2906  * @since_tizen 2.3
2907  * @privlevel platform
2908  * @privilege http://tizen.org/privilege/tethering.admin
2909  * @details If SSID is not set, Device name is used as SSID
2910  * @remarks This change is applied next time Wi-Fi tethering is enabled with same @a tethering handle
2911  * @param[in]  tethering  The handle of tethering
2912  * @param[out]  ssid  The SSID
2913  * @return 0 on success, otherwise negative error value.
2914  * @retval  #TETHERING_ERROR_NONE  Successful
2915  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2916  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2917  */
2918 API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid)
2919 {
2920         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2921         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2922
2923         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2924                         "parameter(tethering) is NULL\n");
2925         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2926                         "parameter(ssid) is NULL\n");
2927
2928         __tethering_h *th = (__tethering_h *)tethering;
2929         char *p_ssid = NULL;
2930         int ssid_len = 0;
2931
2932         ssid_len = strlen(ssid);
2933         if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) {
2934                 ERR("parameter(ssid) is too long");
2935                 return TETHERING_ERROR_INVALID_PARAMETER;
2936         }
2937
2938         p_ssid = strdup(ssid);
2939         _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2940                         "strdup is failed\n");
2941
2942         if (th->ssid)
2943                 free(th->ssid);
2944         th->ssid = p_ssid;
2945
2946         return TETHERING_ERROR_NONE;
2947 }
2948
2949 /**
2950  * @internal
2951  * @brief Gets the SSID (service set identifier).
2952  * @since_tizen 2.3
2953  * @privlevel platform
2954  * @privilege http://tizen.org/privilege/tethering.admin
2955  * @remarks @a ssid must be released with free() by you.
2956  * @param[in]  tethering  The handle of tethering
2957  * @param[out]  ssid  The SSID
2958  * @return 0 on success, otherwise negative error value.
2959  * @retval  #TETHERING_ERROR_NONE  Successful
2960  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2961  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2962  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2963  */
2964 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
2965 {
2966         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2967         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2968
2969         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2970                         "parameter(tethering) is NULL\n");
2971         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2972                         "parameter(ssid) is NULL\n");
2973         DBG("+\n");
2974
2975         __tethering_h *th = (__tethering_h *)tethering;
2976         char val[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, };
2977
2978         if (!tethering_is_enabled(NULL, TETHERING_TYPE_WIFI)) {
2979                 if (th->ssid != NULL) {
2980                         DBG("Private SSID is set\n");
2981                         *ssid = strdup(th->ssid);
2982                 } else {
2983                         if (__get_ssid_from_vconf(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
2984                                                 val, sizeof(val)) == false) {
2985                                 return TETHERING_ERROR_OPERATION_FAILED;
2986                         }
2987                         *ssid = strdup(val);
2988                 }
2989         } else {
2990                 if (__get_ssid_from_vconf(VCONFKEY_MOBILE_HOTSPOT_SSID,
2991                                         val, sizeof(val)) == false) {
2992                         return TETHERING_ERROR_OPERATION_FAILED;
2993                 }
2994                 *ssid = strdup(val);
2995         }
2996
2997         if (*ssid == NULL) {
2998                 ERR("strdup is failed\n"); //LCOV_EXCL_LINE
2999                 return TETHERING_ERROR_OUT_OF_MEMORY;
3000         }
3001
3002         return TETHERING_ERROR_NONE;
3003 }
3004
3005 /**
3006  * @internal
3007  * @brief Sets the visibility of SSID(service set identifier).
3008  * @since_tizen 2.3
3009  * @privlevel platform
3010  * @privilege http://tizen.org/privilege/tethering.admin
3011  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
3012  * @remarks This change is applied next time Wi-Fi tethering is enabled
3013  * @param[in]  tethering  The handle of tethering
3014  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
3015  * @return 0 on success, otherwise negative error value.
3016  * @retval  #TETHERING_ERROR_NONE  Successful
3017  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3018  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3019  * @see  tethering_wifi_get_ssid_visibility()
3020  */
3021 API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
3022 {
3023         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3024         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3025
3026         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3027                         "parameter(tethering) is NULL\n");
3028
3029         __tethering_h *th = (__tethering_h *)tethering;
3030         tethering_error_e ret = TETHERING_ERROR_NONE;
3031
3032         ret = __set_visible(visible);
3033         if (ret == TETHERING_ERROR_NONE) {
3034                 __send_dbus_signal(th->client_bus,
3035                                 SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
3036                                 visible ? SIGNAL_MSG_SSID_VISIBLE :
3037                                 SIGNAL_MSG_SSID_HIDE);
3038         }
3039         return ret;
3040 }
3041
3042 /**
3043  * @internal
3044  * @brief Gets the visibility of SSID(service set identifier).
3045  * @since_tizen 2.3
3046  * @privlevel platform
3047  * @privilege http://tizen.org/privilege/tethering.admin
3048  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
3049  * @param[in]  tethering  The handle of tethering
3050  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
3051  * @return 0 on success, otherwise negative error value.
3052  * @retval  #TETHERING_ERROR_NONE  Successful
3053  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3054  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3055  * @see  tethering_wifi_set_ssid_visibility()
3056  */
3057 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
3058 {
3059         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3060         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3061
3062         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3063                         "parameter(visible) is NULL\n");
3064
3065         return __get_visible(visible);
3066 }
3067
3068 /**
3069  * @internal
3070  * @brief Sets the passphrase.
3071  * @since_tizen 2.3
3072  * @privlevel platform
3073  * @privilege http://tizen.org/privilege/tethering.admin
3074  * @remarks This change is applied next time Wi-Fi tethering is enabled
3075  * @param[in]  tethering  The handle of tethering
3076  * @param[in]  passphrase  The passphrase
3077  * @return 0 on success, otherwise negative error value.
3078  * @retval  #TETHERING_ERROR_NONE  Successful
3079  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3080  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3081  * @see  tethering_wifi_get_passphrase()
3082  */
3083 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
3084 {
3085         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3086         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3087
3088         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3089                         "parameter(tethering) is NULL\n");
3090         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3091                         "parameter(passphrase) is NULL\n");
3092
3093         __tethering_h *th = (__tethering_h *)tethering;
3094         GDBusProxy *proxy = th->client_bus_proxy;
3095         GVariant *parameters;
3096         GError *error = NULL;
3097         int passphrase_len = 0;
3098         int ret = 0;
3099
3100         DBG("+");
3101         passphrase_len = strlen(passphrase);
3102         if (passphrase_len < TETHERING_WIFI_KEY_MIN_LEN ||
3103                         passphrase_len > TETHERING_WIFI_KEY_MAX_LEN) {
3104                 ERR("parameter(passphrase) is too short or long\n");
3105                 return TETHERING_ERROR_INVALID_PARAMETER;
3106         }
3107
3108         parameters = g_dbus_proxy_call_sync(proxy, "set_wifi_tethering_passphrase",
3109                         g_variant_new("(s)", passphrase), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3110
3111         if (error) {
3112                 //LCOV_EXCL_START
3113                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3114
3115                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3116                         ret = TETHERING_ERROR_PERMISSION_DENIED;
3117                 else
3118                         ret = TETHERING_ERROR_OPERATION_FAILED;
3119
3120                 g_error_free(error);
3121                 return ret;
3122                 //LCOV_EXCL_STOP
3123         }
3124
3125         g_variant_get(parameters, "(u)", &ret);
3126         g_variant_unref(parameters);
3127
3128         if (ret == TETHERING_ERROR_NONE) {
3129                 __send_dbus_signal(th->client_bus,
3130                                 SIGNAL_NAME_PASSPHRASE_CHANGED, NULL);
3131         }
3132
3133         DBG("-");
3134         return ret;
3135 }
3136
3137 /**
3138  * @internal
3139  * @brief Gets the passphrase.
3140  * @since_tizen 2.3
3141  * @privlevel platform
3142  * @privilege http://tizen.org/privilege/tethering.admin
3143  * @remarks @a passphrase must be released with free() by you.
3144  * @param[in]  tethering  The handle of tethering
3145  * @param[out]  passphrase  The passphrase
3146  * @return 0 on success, otherwise negative error value.
3147  * @retval  #TETHERING_ERROR_NONE  Successful
3148  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3149  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
3150  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3151  * @see  tethering_wifi_set_passphrase()
3152  */
3153 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
3154 {
3155         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3156         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3157
3158         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3159                         "parameter(tethering) is NULL\n");
3160         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3161                         "parameter(passphrase) is NULL\n");
3162
3163         __tethering_h *th = (__tethering_h *)tethering;
3164         GDBusProxy *proxy = th->client_bus_proxy;
3165         GVariant *parameters;
3166         GError *error = NULL;
3167         unsigned int len = 0;
3168         tethering_error_e ret = TETHERING_ERROR_NONE;
3169
3170         parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_passphrase",
3171                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3172
3173         if (error) {
3174                 //LCOV_EXCL_START
3175                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3176
3177                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3178                         ret = TETHERING_ERROR_PERMISSION_DENIED;
3179                 else
3180                         ret = TETHERING_ERROR_OPERATION_FAILED;
3181
3182                 g_error_free(error);
3183                 return ret;
3184                 //LCOV_EXCL_STOP
3185         }
3186
3187         if (parameters != NULL) {
3188                 g_variant_get(parameters, "(siu)", passphrase, &len, &ret);
3189                 g_variant_unref(parameters);
3190         }
3191
3192         return TETHERING_ERROR_NONE;
3193 }
3194
3195 API int tethering_wifi_set_channel(tethering_h tethering, int channel)
3196 {
3197         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3198         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3199
3200         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3201                         "parameter(tethering) is NULL\n");
3202
3203         __tethering_h *th = (__tethering_h *)tethering;
3204         th->channel = channel;
3205
3206         return TETHERING_ERROR_NONE;
3207 }
3208
3209 API int tethering_wifi_get_channel(tethering_h tethering, int *channel)
3210 {
3211         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3212         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3213
3214         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3215                         "parameter(tethering) is NULL\n");
3216
3217         _retvm_if(channel == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3218                         "parameter(channel) is NULL\n");
3219
3220         __tethering_h *th = (__tethering_h *)tethering;
3221         *channel = th->channel;
3222
3223         return TETHERING_ERROR_NONE;
3224 }
3225
3226 API int tethering_wifi_set_mode(tethering_h tethering, tethering_wifi_mode_type_e type)
3227 {
3228         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3229         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3230
3231         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3232                         "parameter(tethering) is NULL\n");
3233
3234         __tethering_h *th = (__tethering_h *)tethering;
3235
3236         th->mode_type = type;
3237
3238         return TETHERING_ERROR_NONE;
3239 }
3240
3241 API int tethering_wifi_get_mode(tethering_h tethering, tethering_wifi_mode_type_e *type)
3242 {
3243         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3244         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3245
3246         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3247                         "parameter(tethering) is NULL\n");
3248         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3249                         "parameter(type) is NULL\n");
3250
3251         __tethering_h *th = (__tethering_h *)tethering;
3252         *type = th->mode_type;
3253
3254         return TETHERING_ERROR_NONE;
3255 }
3256
3257
3258 /**
3259  * @internal
3260  * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility).
3261  * @since_tizen 2.3
3262  * @privlevel platform
3263  * @privilege http://tizen.org/privilege/tethering.admin
3264  * @remarks Connected devices via Wi-Fi tethering or MobileAP will be disconnected when the settings are reloaded
3265  * @param[in]  tethering  The handle of tethering
3266  * @param[in]  callback  The callback function to invoke
3267  * @param[in]  user_data  The user data to be passed to the callback function
3268  * @return 0 on success, otherwise negative error value.
3269  * @retval  #TETHERING_ERROR_NONE  Successful
3270  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3271  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3272  */
3273 API int tethering_wifi_reload_settings(tethering_h tethering, tethering_wifi_settings_reloaded_cb callback, void *user_data)
3274
3275 {
3276         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3277         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3278
3279         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3280                         "parameter(tethering) is NULL\n");
3281         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3282                         "parameter(callback) is NULL\n");
3283
3284         __tethering_h *th = (__tethering_h *)tethering;
3285         _softap_settings_t set = {"", "", "", 0, false};
3286         GDBusProxy *proxy = th->client_bus_proxy;
3287         int ret = 0;
3288
3289         DBG("+\n");
3290
3291         if (th->settings_reloaded_cb) {
3292                 ERR("Operation in progress\n"); //LCOV_EXCL_LINE
3293                 return TETHERING_ERROR_OPERATION_FAILED;
3294         }
3295
3296         ret = __prepare_wifi_settings(tethering, &set);
3297         if (ret != TETHERING_ERROR_NONE) {
3298                 ERR("softap settings initialization failed\n"); //LCOV_EXCL_LINE
3299                 return TETHERING_ERROR_OPERATION_FAILED;
3300         }
3301
3302         th->settings_reloaded_cb = callback;
3303         th->settings_reloaded_user_data = user_data;
3304
3305         g_dbus_proxy_call(proxy, "reload_wifi_settings",
3306                         g_variant_new("(sssiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type),
3307                         G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
3308                         (GAsyncReadyCallback) __settings_reloaded_cb, (gpointer)tethering);
3309
3310         return TETHERING_ERROR_NONE;
3311 }
3312
3313 API int tethering_wifi_set_mac_filter(tethering_h tethering, bool mac_filter)
3314 {
3315         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3316         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3317
3318         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3319                         "parameter(tethering) is NULL\n");
3320
3321         __tethering_h *th = (__tethering_h *)tethering;
3322         th->mac_filter = mac_filter;
3323
3324         return TETHERING_ERROR_NONE;
3325 }
3326
3327 API int tethering_wifi_get_mac_filter(tethering_h tethering, bool *mac_filter)
3328 {
3329         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3330         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3331
3332         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3333                         "parameter(mac_filter) is NULL\n");
3334         _retvm_if(mac_filter == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3335                         "parameter(mac_filter) is NULL\n");
3336
3337         __tethering_h *th = (__tethering_h *)tethering;
3338         *mac_filter = th->mac_filter;
3339
3340         return TETHERING_ERROR_NONE;
3341 }
3342
3343 static int __add_mac_to_file(const char *filepath, const char *mac)
3344 {
3345         FILE *fp = NULL;
3346         char line[MAX_BUF_SIZE] = "\0";
3347         bool mac_exist = false;
3348         char *p_mac = NULL;
3349
3350         p_mac = strdup(mac);
3351         if (p_mac == NULL) {
3352                 ERR("strdup failed\n"); //LCOV_EXCL_LINE
3353                 return TETHERING_ERROR_OUT_OF_MEMORY;
3354         }
3355
3356         fp = fopen(filepath, "a+");
3357         if (!fp) {
3358                 ERR("fopen is failed\n"); //LCOV_EXCL_LINE
3359                 return TETHERING_ERROR_OPERATION_FAILED;
3360         }
3361
3362         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3363                 if (strncmp(mac, line, 17) == 0) {
3364                         DBG("MAC %s already exist in the list\n", mac); //LCOV_EXCL_LINE
3365                         mac_exist = true;
3366                         break;
3367                 }
3368         }
3369
3370         if (!mac_exist) {
3371                 fprintf(fp, "%s\n", mac);
3372
3373                 if ((strcmp(filepath, ALLOWED_LIST) == 0))
3374                         allowed_list = g_slist_append(allowed_list, p_mac);
3375                 else if ((strcmp(filepath, BLOCKED_LIST) == 0))
3376                         blocked_list = g_slist_append(blocked_list, p_mac);
3377         }
3378
3379         fclose(fp);
3380
3381         return TETHERING_ERROR_NONE;
3382 }
3383
3384 static int __remove_mac_from_file(const char *filepath, const char *mac)
3385 {
3386         FILE *fp = NULL;
3387         FILE *fp1 = NULL;
3388         char line[MAX_BUF_SIZE] = "\0";
3389
3390         fp = fopen(filepath, "r");
3391         if (!fp) {
3392                 ERR("fopen is failed\n");
3393                 return TETHERING_ERROR_OPERATION_FAILED;
3394         }
3395
3396         fp1 = fopen(TEMP_LIST, "w+");
3397         if (!fp1) {
3398                 fclose(fp);
3399                 ERR("fopen is failed\n");
3400                 return TETHERING_ERROR_OPERATION_FAILED;
3401         }
3402
3403         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3404                 if (strncmp(mac, line, 17) == 0) {
3405                         DBG("MAC %s found in the list\n", mac);
3406
3407                         if ((strcmp(filepath, ALLOWED_LIST) == 0)) {
3408                                 GSList *list = NULL;
3409                                 for (list = allowed_list; list != NULL; list = list->next) {
3410                                         char *p_mac = (char *)list->data;
3411                                         if (strncmp(mac, p_mac, strlen(mac)) == 0)
3412                                                 allowed_list = g_slist_remove(allowed_list, p_mac);
3413                                 }
3414                         } else if ((strcmp(filepath, BLOCKED_LIST) == 0)) {
3415                                 GSList *list = NULL;
3416                                 for (list = blocked_list; list != NULL; list = list->next) {
3417                                         char *p_mac = (char *)list->data;
3418                                         if (strncmp(mac, p_mac, strlen(mac)) == 0)
3419                                                 blocked_list = g_slist_remove(blocked_list, p_mac);
3420                                 }
3421                         }
3422                 } else {
3423                         fprintf(fp1, "%s", line);
3424                 }
3425         }
3426
3427         fclose(fp);
3428         fclose(fp1);
3429
3430         if ((strcmp(filepath, ALLOWED_LIST) == 0))
3431                 rename(TEMP_LIST, ALLOWED_LIST);
3432         else if ((strcmp(filepath, BLOCKED_LIST) == 0))
3433                 rename(TEMP_LIST, BLOCKED_LIST);
3434
3435         return TETHERING_ERROR_NONE;
3436 }
3437
3438 API int tethering_wifi_add_allowed_mac_list(tethering_h tethering, const char *mac)
3439 {
3440         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3441         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3442
3443         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3444                         "parameter(tethering) is NULL\n");
3445         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3446                         "parameter(mac) is NULL\n");
3447
3448         return __add_mac_to_file(ALLOWED_LIST, mac);
3449 }
3450
3451 API int tethering_wifi_remove_allowed_mac_list(tethering_h tethering, const char *mac)
3452 {
3453         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3454         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3455
3456         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3457                         "parameter(tethering) is NULL\n");
3458         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3459                         "parameter(mac) is NULL\n");
3460
3461         return __remove_mac_from_file(ALLOWED_LIST, mac);
3462 }
3463
3464 API int tethering_wifi_get_allowed_mac_list(tethering_h tethering, void **allowed_mac_list)
3465 {
3466         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3467         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3468
3469         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3470                         "parameter(tethering) is NULL\n");
3471         _retvm_if(allowed_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3472                         "parameter(allowed_mac_list) is NULL\n");
3473
3474         *allowed_mac_list = g_slist_copy(allowed_list);
3475         return TETHERING_ERROR_NONE;
3476 }
3477
3478 API int tethering_wifi_add_blocked_mac_list(tethering_h tethering, const char *mac)
3479 {
3480         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3481         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3482
3483         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3484                         "parameter(tethering) is NULL\n");
3485         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3486                         "parameter(mac) is NULL\n");
3487
3488         return __add_mac_to_file(BLOCKED_LIST, mac);
3489 }
3490
3491 API int tethering_wifi_remove_blocked_mac_list(tethering_h tethering, const char *mac)
3492 {
3493         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3494         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3495
3496         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3497                         "parameter(tethering) is NULL\n");
3498         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3499                         "parameter(mac) is NULL\n");
3500
3501         return __remove_mac_from_file(BLOCKED_LIST, mac);
3502 }
3503
3504 API int tethering_wifi_get_blocked_mac_list(tethering_h tethering, void **blocked_mac_list)
3505 {
3506         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3507         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3508
3509         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3510                         "parameter(tethering) is NULL\n");
3511         _retvm_if(blocked_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3512                         "parameter(blocked_mac_list) is NULL\n");
3513
3514         *blocked_mac_list = g_slist_copy(blocked_list);
3515         return TETHERING_ERROR_NONE;
3516 }
3517
3518 API int tethering_wifi_enable_dhcp(tethering_h tethering, bool enable)
3519 {
3520         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3521         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3522
3523         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3524                         "parameter(tethering) is NULL\n");
3525
3526         GVariant *parameters;
3527         GError *error = NULL;
3528         guint result;
3529
3530         __tethering_h *th = (__tethering_h *)tethering;
3531
3532         GDBusProxy *proxy = th->client_bus_proxy;
3533
3534         parameters = g_dbus_proxy_call_sync(proxy, "enable_dhcp",
3535                         g_variant_new("(b)", enable),
3536                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3537
3538         if (error) {
3539                 //LCOV_EXCL_START
3540                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3541                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3542                         result = TETHERING_ERROR_PERMISSION_DENIED;
3543                 else
3544                         result = TETHERING_ERROR_OPERATION_FAILED;
3545
3546                 g_error_free(error);
3547                 th->dhcp_enabled = false;
3548
3549                 return result;
3550                 //LCOV_EXCL_STOP
3551         }
3552
3553         g_variant_get(parameters, "(u)", &result);
3554         g_variant_unref(parameters);
3555
3556         if (enable)
3557                 th->dhcp_enabled = true;
3558         else
3559                 th->dhcp_enabled = false;
3560
3561         return TETHERING_ERROR_NONE;
3562 }
3563
3564 API int tethering_wifi_set_dhcp_range(tethering_h tethering, char *rangestart, char *rangestop)
3565 {
3566         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3567         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3568
3569         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3570                         "parameter(tethering) is NULL\n");
3571         _retvm_if(rangestart == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3572                         "parameter(rangestart) is NULL\n");
3573         _retvm_if(rangestop == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3574                         "parameter(rangestop) is NULL\n");
3575
3576         GVariant *parameters;
3577         GError *error = NULL;
3578         guint result;
3579
3580         __tethering_h *th = (__tethering_h *)tethering;
3581
3582         GDBusProxy *proxy = th->client_bus_proxy;
3583
3584         parameters = g_dbus_proxy_call_sync(proxy, "dhcp_range",
3585                         g_variant_new("(ss)", rangestart, rangestop),
3586                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3587         if (error) {
3588                 //LCOV_EXCL_START
3589                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3590
3591                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3592                         result = TETHERING_ERROR_PERMISSION_DENIED;
3593                 else
3594                         result = TETHERING_ERROR_OPERATION_FAILED;
3595
3596                 g_error_free(error);
3597                 th->dhcp_enabled = false;
3598
3599                 return result;
3600                 //LCOV_EXCL_STOP
3601         }
3602
3603         g_variant_get(parameters, "(u)", &result);
3604         g_variant_unref(parameters);
3605
3606         th->dhcp_enabled = true;
3607
3608         return TETHERING_ERROR_NONE;
3609 }
3610
3611 API int tethering_wifi_is_dhcp_enabled(tethering_h tethering, bool *dhcp_enabled)
3612 {
3613         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3614         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3615
3616         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3617                         "parameter(tethering) is NULL\n");
3618         _retvm_if(dhcp_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3619                         "parameter(dhcp_enabled) is NULL\n");
3620
3621         __tethering_h *th = (__tethering_h *)tethering;
3622         *dhcp_enabled = th->dhcp_enabled;
3623
3624         return TETHERING_ERROR_NONE;
3625 }
3626
3627 API int tethering_wifi_set_txpower(tethering_h tethering, unsigned int txpower)
3628 {
3629         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3630         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3631
3632         GError *error = NULL;
3633
3634         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3635                         "parameter(tethering) is NULL\n");
3636         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false,
3637                         TETHERING_ERROR_NOT_ENABLED,
3638                         "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI);
3639         __tethering_h *th = (__tethering_h *)tethering;
3640
3641         g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_set_txpower",
3642                         g_variant_new("(u)", txpower),
3643                         G_DBUS_CALL_FLAGS_NONE,
3644                         -1, th->cancellable, &error);
3645         if (error) {
3646                 //LCOV_EXCL_START
3647                 ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
3648                 g_clear_error(&error);
3649                 return TETHERING_ERROR_OPERATION_FAILED;
3650                 //LCOV_EXCL_STOP
3651         }
3652         return TETHERING_ERROR_NONE;
3653 }
3654
3655 API int tethering_wifi_get_txpower(tethering_h tethering, unsigned int *txpower)
3656 {
3657         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3658         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3659
3660         GError *error = NULL;
3661         GVariant *result = NULL;
3662
3663         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3664                         "parameter(tethering) is NULL\n");
3665         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false,
3666                         TETHERING_ERROR_NOT_ENABLED,
3667                         "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI);
3668
3669         __tethering_h *th = (__tethering_h *)tethering;
3670
3671         result = g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_get_txpower",
3672                         NULL,
3673                         G_DBUS_CALL_FLAGS_NONE,
3674                         -1, th->cancellable, &error);
3675
3676         if (result != NULL) {
3677                 g_variant_get(result, "(u)", txpower);
3678                 g_variant_unref(result);
3679         } else {
3680                 //LCOV_EXCL_START
3681                 if (error)
3682                         ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
3683                 g_clear_error(&error);
3684                 return TETHERING_ERROR_OPERATION_FAILED;
3685                 //LCOV_EXCL_STOP
3686         }
3687         g_clear_error(&error);
3688         return TETHERING_ERROR_NONE;
3689 }
3690
3691 API int tethering_wifi_set_mtu(tethering_h tethering, unsigned int mtu)
3692 {
3693         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3694         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3695
3696         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3697                         "parameter(tethering) is NULL\n");
3698
3699         GVariant *parameters;
3700         GError *error = NULL;
3701         guint result;
3702
3703         __tethering_h *th = (__tethering_h *)tethering;
3704
3705         GDBusProxy *proxy = th->client_bus_proxy;
3706
3707         parameters = g_dbus_proxy_call_sync(proxy, "set_mtu",
3708                         g_variant_new("(u)", mtu),
3709                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3710         if (error) {
3711                 //LCOV_EXCL_START
3712                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3713
3714                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3715                         result = TETHERING_ERROR_PERMISSION_DENIED;
3716                 else
3717                         result = TETHERING_ERROR_OPERATION_FAILED;
3718
3719                 g_error_free(error);
3720                 return result;
3721                 //LCOV_EXCL_STOP
3722         }
3723
3724         g_variant_get(parameters, "(u)", &result);
3725
3726         g_variant_unref(parameters);
3727
3728         return TETHERING_ERROR_NONE;
3729 }
3730
3731 API int tethering_wifi_change_mac(tethering_h tethering, char *mac)
3732 {
3733         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3734         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3735
3736         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3737                         "parameter(tethering) is NULL\n");
3738         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3739                         "parameter(mac) is NULL\n");
3740
3741         GVariant *parameters;
3742         GError *error = NULL;
3743         guint result;
3744
3745         __tethering_h *th = (__tethering_h *)tethering;
3746
3747         GDBusProxy *proxy = th->client_bus_proxy;
3748
3749         parameters = g_dbus_proxy_call_sync(proxy, "change_mac",
3750                         g_variant_new("(s)", mac),
3751                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3752         if (error) {
3753                 //LCOV_EXCL_START
3754                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3755
3756                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3757                         result = TETHERING_ERROR_PERMISSION_DENIED;
3758                 else
3759                         result = TETHERING_ERROR_OPERATION_FAILED;
3760
3761                 g_error_free(error);
3762                 return result;
3763                 //LCOV_EXCL_STOP
3764         }
3765
3766         g_variant_get(parameters, "(u)", &result);
3767         g_variant_unref(parameters);
3768
3769         if (result == MOBILE_AP_ERROR_NOT_PERMITTED)
3770                 return TETHERING_ERROR_NOT_SUPPORT_API;
3771
3772         return TETHERING_ERROR_NONE;
3773 }
3774
3775 API int tethering_wifi_set_max_connected_device(tethering_h tethering, int max_device)
3776 {
3777         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3778         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3779
3780         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3781                         "parameter(tethering) is NULL\n");
3782
3783         __tethering_h *th = (__tethering_h *)tethering;
3784
3785         th->wifi_max_connected = max_device;
3786
3787         return TETHERING_ERROR_NONE;
3788 }
3789
3790 API int tethering_wifi_get_max_connected_device(tethering_h tethering, int *max_device)
3791 {
3792         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3793         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3794
3795         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3796                         "parameter(tethering) is NULL\n");
3797         _retvm_if(max_device == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3798                         "parameter(max_device) is NULL\n");
3799
3800         __tethering_h *th = (__tethering_h *)tethering;
3801
3802         *max_device = th->wifi_max_connected;
3803         return TETHERING_ERROR_NONE;
3804 }
3805
3806 API int tethering_wifi_enable_port_forwarding(tethering_h tethering, bool enable)
3807 {
3808         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3809         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3810
3811         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3812                         "parameter(tethering) is NULL\n");
3813
3814         GVariant *parameters;
3815         GError *error = NULL;
3816         guint result;
3817
3818         __tethering_h *th = (__tethering_h *)tethering;
3819
3820         GDBusProxy *proxy = th->client_bus_proxy;
3821
3822         parameters = g_dbus_proxy_call_sync(proxy, "enable_port_forwarding",
3823                         g_variant_new("(b)", enable),
3824                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3825         if (error) {
3826                 //LCOV_EXCL_START
3827                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3828
3829                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3830                         result = TETHERING_ERROR_PERMISSION_DENIED;
3831                 else
3832                         result = TETHERING_ERROR_OPERATION_FAILED;
3833
3834                 g_error_free(error);
3835                 return result;
3836                 //LCOV_EXCL_STOP
3837         }
3838
3839         g_variant_get(parameters, "(u)", &result);
3840         g_variant_unref(parameters);
3841
3842         th->port_forwarding = true;
3843
3844         return TETHERING_ERROR_NONE;
3845 }
3846
3847 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)
3848 {
3849         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3850         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3851
3852         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3853                         "parameter(tethering) is NULL\n");
3854         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3855                         "parameter(protocol) is NULL\n");
3856
3857         GVariant *parameters;
3858         GError *error = NULL;
3859         guint result;
3860         char cmd[MAX_BUF_SIZE] = { 0, };
3861         char *list = NULL;
3862
3863         __tethering_h *th = (__tethering_h *)tethering;
3864
3865         GDBusProxy *proxy = th->client_bus_proxy;
3866
3867         parameters = g_dbus_proxy_call_sync(proxy, "add_port_forwarding_rule",
3868                         g_variant_new("(sssisi)", ifname, protocol, org_ip, org_port, final_ip, final_port),
3869                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3870         if (error) {
3871                 //LCOV_EXCL_START
3872                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3873
3874                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3875                         result = TETHERING_ERROR_PERMISSION_DENIED;
3876                 else
3877                         result = TETHERING_ERROR_OPERATION_FAILED;
3878
3879                 g_error_free(error);
3880                 return result;
3881                 //LCOV_EXCL_STOP
3882         }
3883
3884         g_variant_get(parameters, "(u)", &result);
3885         g_variant_unref(parameters);
3886
3887         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);
3888
3889         list = strdup(cmd);
3890         if (list == NULL) {
3891                 ERR("strdup failed\n"); //LCOV_EXCL_LINE
3892                 return TETHERING_ERROR_OUT_OF_MEMORY;
3893         }
3894
3895         port_forwarding = g_slist_append(port_forwarding, list);
3896
3897         return TETHERING_ERROR_NONE;
3898 }
3899
3900 API int tethering_wifi_reset_port_forwarding_rule(tethering_h tethering)
3901 {
3902         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3903         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3904
3905         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3906                         "parameter(tethering) is NULL\n");
3907
3908         GVariant *parameters;
3909         GError *error = NULL;
3910         guint result;
3911
3912         __tethering_h *th = (__tethering_h *)tethering;
3913
3914         GDBusProxy *proxy = th->client_bus_proxy;
3915
3916         parameters = g_dbus_proxy_call_sync(proxy, "reset_port_forwarding_rule",
3917                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3918         if (error) {
3919                 //LCOV_EXCL_START
3920                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3921
3922                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3923                         result = TETHERING_ERROR_PERMISSION_DENIED;
3924                 else
3925                         result = TETHERING_ERROR_OPERATION_FAILED;
3926
3927                 g_error_free(error);
3928                 return result;
3929                 //LCOV_EXCL_STOP
3930         }
3931
3932         g_variant_get(parameters, "(u)", &result);
3933
3934         g_variant_unref(parameters);
3935
3936         return TETHERING_ERROR_NONE;
3937 }
3938
3939 API int tethering_wifi_is_port_forwarding_enabled(tethering_h tethering, bool* forwarding_enabled)
3940 {
3941         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3942         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3943
3944         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3945                         "parameter(tethering) is NULL\n");
3946         _retvm_if(forwarding_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3947                         "parameter(forwarding_enabled) is NULL\n");
3948
3949         __tethering_h *th = (__tethering_h *)tethering;
3950
3951         *forwarding_enabled = th->port_forwarding;
3952
3953         return TETHERING_ERROR_NONE;
3954 }
3955
3956 API int tethering_wifi_get_port_forwarding_rule(tethering_h tethering, void **port_forwarding_list)
3957 {
3958         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3959         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3960
3961         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3962                         "parameter(tethering) is NULL\n");
3963         _retvm_if(port_forwarding_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3964                         "parameter(port_forwarding_list) is NULL\n");
3965
3966         *port_forwarding_list = g_slist_copy(port_forwarding);
3967         return TETHERING_ERROR_NONE;
3968 }
3969
3970 API int tethering_wifi_enable_port_filtering(tethering_h tethering, bool enable)
3971 {
3972         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3973         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3974
3975         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3976                         "parameter(tethering) is NULL\n");
3977
3978         GVariant *parameters;
3979         GError *error = NULL;
3980         guint result;
3981
3982         __tethering_h *th = (__tethering_h *)tethering;
3983
3984         GDBusProxy *proxy = th->client_bus_proxy;
3985
3986         parameters = g_dbus_proxy_call_sync(proxy, "enable_port_filtering",
3987                         g_variant_new("(b)", enable),
3988                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3989         if (error) {
3990                 //LCOV_EXCL_START
3991                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3992
3993                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3994                         result = TETHERING_ERROR_PERMISSION_DENIED;
3995                 else
3996                         result = TETHERING_ERROR_OPERATION_FAILED;
3997
3998                 g_error_free(error);
3999                 return result;
4000                 //LCOV_EXCL_STOP
4001         }
4002
4003         g_variant_get(parameters, "(u)", &result);
4004         g_variant_unref(parameters);
4005
4006         th->port_filtering = true;
4007
4008         return TETHERING_ERROR_NONE;
4009 }
4010
4011 API int tethering_wifi_add_port_filtering_rule(tethering_h tethering, int port, char *protocol, bool allow)
4012 {
4013         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4014         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4015
4016         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4017                         "parameter(tethering) is NULL\n");
4018         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4019                         "parameter(protocol) is NULL\n");
4020
4021         GVariant *parameters;
4022         GError *error = NULL;
4023         guint result;
4024         char cmd[MAX_BUF_SIZE] = { 0, };
4025         char *list = NULL;
4026
4027         __tethering_h *th = (__tethering_h *)tethering;
4028
4029         GDBusProxy *proxy = th->client_bus_proxy;
4030
4031         parameters = g_dbus_proxy_call_sync(proxy, "add_port_filtering_rule",
4032                         g_variant_new("(isb)", port, protocol, allow),
4033                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4034         if (error) {
4035                 //LCOV_EXCL_START
4036                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4037
4038                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4039                         result = TETHERING_ERROR_PERMISSION_DENIED;
4040                 else
4041                         result = TETHERING_ERROR_OPERATION_FAILED;
4042
4043                 g_error_free(error);
4044                 return result;
4045                 //LCOV_EXCL_STOP
4046         }
4047
4048         g_variant_get(parameters, "(u)", &result);
4049         g_variant_unref(parameters);
4050
4051         if (allow)
4052                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_ACCEPT);
4053         else
4054                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_DROP);
4055
4056         DBG("cmd:%s", cmd);
4057
4058         list = strdup(cmd);
4059         if (list == NULL) {
4060                 ERR("strdup failed\n"); //LCOV_EXCL_LINE
4061                 return TETHERING_ERROR_OUT_OF_MEMORY;
4062         }
4063
4064         port_filtering = g_slist_append(port_filtering, list);
4065
4066         return TETHERING_ERROR_NONE;
4067 }
4068
4069 API int tethering_wifi_add_custom_port_filtering_rule(tethering_h tethering, int port1, int port2, char *protocol, bool allow)
4070 {
4071         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4072         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4073
4074         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4075                         "parameter(tethering) is NULL\n");
4076         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4077                         "parameter(protocol) is NULL\n");
4078
4079         GVariant *parameters;
4080         GError *error = NULL;
4081         guint result;
4082         char cmd[MAX_BUF_SIZE] = { 0, };
4083         char *list = NULL;
4084
4085         __tethering_h *th = (__tethering_h *)tethering;
4086
4087         GDBusProxy *proxy = th->client_bus_proxy;
4088
4089         parameters = g_dbus_proxy_call_sync(proxy, "add_custom_port_filtering_rule",
4090                         g_variant_new("(iisb)", port1, port2, protocol, allow),
4091                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4092         if (error) {
4093                 //LCOV_EXCL_START
4094                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4095
4096                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4097                         result = TETHERING_ERROR_PERMISSION_DENIED;
4098                 else
4099                         result = TETHERING_ERROR_OPERATION_FAILED;
4100
4101                 g_error_free(error);
4102                 return result;
4103                 //LCOV_EXCL_STOP
4104         }
4105
4106         g_variant_get(parameters, "(u)", &result);
4107         g_variant_unref(parameters);
4108
4109         if (allow)
4110                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_ACCEPT);
4111         else
4112                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_DROP);
4113
4114         DBG("cmd:%s", cmd);
4115
4116         list = strdup(cmd);
4117         if (list == NULL) {
4118                 ERR("strdup failed\n"); //LCOV_EXCL_LINE
4119                 return TETHERING_ERROR_OUT_OF_MEMORY;
4120         }
4121
4122         custom_port_filtering = g_slist_append(custom_port_filtering, list);
4123
4124         return TETHERING_ERROR_NONE;
4125 }
4126
4127 API int tethering_wifi_get_port_filtering_rule(tethering_h tethering, void **port_filtering_list)
4128 {
4129         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4130         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4131
4132         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4133                         "parameter(tethering) is NULL\n");
4134         _retvm_if(port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4135                         "parameter(port_filtering_list) is NULL\n");
4136
4137         *port_filtering_list = g_slist_copy(port_filtering);
4138         return TETHERING_ERROR_NONE;
4139 }
4140
4141 API int tethering_wifi_get_custom_port_filtering_rule(tethering_h tethering, void **custom_port_filtering_list)
4142 {
4143         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4144         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4145
4146         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4147                         "parameter(tethering) is NULL\n");
4148         _retvm_if(custom_port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4149                         "parameter(custom_port_filtering_list) is NULL\n");
4150
4151         *custom_port_filtering_list = g_slist_copy(custom_port_filtering);
4152         return TETHERING_ERROR_NONE;
4153 }
4154
4155 API int tethering_wifi_is_port_filtering_enabled(tethering_h tethering, bool* filtering_enabled)
4156 {
4157         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4158         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4159
4160         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4161                         "parameter(tethering) is NULL\n");
4162         _retvm_if(filtering_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4163                         "parameter(filtering_enabled) is NULL\n");
4164
4165         __tethering_h *th = (__tethering_h *)tethering;
4166
4167         *filtering_enabled = th->port_filtering;
4168
4169         return TETHERING_ERROR_NONE;
4170 }
4171
4172 API int tethering_wifi_set_vpn_passthrough_rule(tethering_h tethering, tethering_vpn_passthrough_type_e type, bool enable)
4173 {
4174         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4175         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4176
4177         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4178                         "parameter(tethering) is NULL\n");
4179
4180         GVariant *parameters;
4181         GError *error = NULL;
4182         guint result;
4183
4184         __tethering_h *th = (__tethering_h *)tethering;
4185
4186         GDBusProxy *proxy = th->client_bus_proxy;
4187
4188         parameters = g_dbus_proxy_call_sync(proxy, "set_vpn_passthrough_rule",
4189                         g_variant_new("(ib)", type, enable),
4190                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4191         if (error) {
4192                 //LCOV_EXCL_START
4193                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4194
4195                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4196                         result = TETHERING_ERROR_PERMISSION_DENIED;
4197                 else
4198                         result = TETHERING_ERROR_OPERATION_FAILED;
4199
4200                 g_error_free(error);
4201                 return result;
4202                 //LCOV_EXCL_STOP
4203         }
4204
4205         g_variant_get(parameters, "(u)", &result);
4206
4207         g_variant_unref(parameters);
4208
4209         return TETHERING_ERROR_NONE;
4210 }
4211
4212 API int tethering_wifi_push_wps_button(tethering_h tethering)
4213 {
4214         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4215         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4216
4217         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4218                         "parameter(tethering) is NULL");
4219         __tethering_h *th = (__tethering_h *)tethering;
4220         GDBusProxy *proxy = th->client_bus_proxy;
4221         GVariant *parameters = NULL;
4222         int ret = 0;
4223         GError *error = NULL;
4224
4225         parameters = g_dbus_proxy_call_sync(proxy, "push_wps_button",
4226                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4227
4228         if (error) {
4229                 //LCOV_EXCL_START
4230                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4231
4232                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4233                         ret = TETHERING_ERROR_PERMISSION_DENIED;
4234                 else
4235                         ret = TETHERING_ERROR_OPERATION_FAILED;
4236
4237                 g_error_free(error);
4238                 return ret;
4239                 //LCOV_EXCL_STOP
4240         }
4241
4242         if (parameters != NULL) {
4243                 g_variant_get(parameters, "(u)", &ret);
4244                 g_variant_unref(parameters);
4245         }
4246
4247         return TETHERING_ERROR_NONE;
4248 }
4249
4250 API int tethering_wifi_set_wps_pin(tethering_h tethering, const char *wps_pin)
4251 {
4252         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4253         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4254
4255         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4256                         "parameter(tethering) is NULL");
4257         __tethering_h *th = (__tethering_h *)tethering;
4258         GDBusProxy *proxy = th->client_bus_proxy;
4259         GVariant *parameters = NULL;
4260         int ret = 0;
4261         GError *error = NULL;
4262
4263         parameters = g_dbus_proxy_call_sync(proxy, "set_wps_pin",
4264                         g_variant_new("(s)", wps_pin), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4265
4266         if (error) {
4267                 //LCOV_EXCL_START
4268                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4269
4270                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4271                         ret = TETHERING_ERROR_PERMISSION_DENIED;
4272                 else
4273                         ret = TETHERING_ERROR_OPERATION_FAILED;
4274
4275                 g_error_free(error);
4276                 return ret;
4277                 //LCOV_EXCL_STOP
4278         }
4279
4280         if (parameters != NULL) {
4281                 g_variant_get(parameters, "(u)", &ret);
4282                 g_variant_unref(parameters);
4283         }
4284
4285         return TETHERING_ERROR_NONE;
4286 }
4287
4288