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