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