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