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