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