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