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