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