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