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