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