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