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