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