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