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