Removed code for resetting MAC address
[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
1387         if (__generate_initial_passphrase(th->passphrase,
1388                         sizeof(th->passphrase)) == 0) {
1389                 ERR("random passphrase generation failed\n"); //LCOV_EXCL_LINE
1390                 free(th);
1391                 return TETHERING_ERROR_OPERATION_FAILED;
1392         }
1393
1394         if (__get_common_ssid(ssid, sizeof(ssid)) != TETHERING_ERROR_NONE) {
1395                 ERR("common ssid get failed\n"); //LCOV_EXCL_LINE
1396                 free(th);
1397                 return TETHERING_ERROR_OPERATION_FAILED;
1398         }
1399
1400 #if !GLIB_CHECK_VERSION(2, 36, 0)
1401         g_type_init();
1402 #endif
1403         GCancellable *cancellable = g_cancellable_new();
1404         th->client_bus = g_bus_get_sync(DBUS_BUS_SYSTEM, cancellable, &error);
1405         if (error) {
1406                 //LCOV_EXCL_START
1407                 ERR("Couldn't connect to the System bus[%s]", error->message);
1408                 g_error_free(error);
1409                 g_cancellable_cancel(cancellable);
1410                 g_object_unref(cancellable);
1411                 free(th);
1412                 return TETHERING_ERROR_OPERATION_FAILED;
1413                 //LCOV_EXCL_STOP
1414         }
1415         th->cancellable = cancellable;
1416
1417         th->client_bus_proxy = g_dbus_proxy_new_sync(th->client_bus, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
1418                         NULL, TETHERING_SERVICE_NAME, TETHERING_SERVICE_OBJECT_PATH,
1419                         TETHERING_SERVICE_INTERFACE, th->cancellable, &error);
1420         if (!th->client_bus_proxy) {
1421                 //LCOV_EXCL_START
1422                 if (error)
1423                         ERR("Couldn't create the proxy object because of %s\n", error->message);
1424                 g_cancellable_cancel(th->cancellable);
1425                 g_object_unref(th->cancellable);
1426                 g_object_unref(th->client_bus);
1427                 free(th);
1428                 return TETHERING_ERROR_OPERATION_FAILED;
1429                 //LCOV_EXCL_STOP
1430         }
1431
1432         __connect_signals((tethering_h)th);
1433
1434         *tethering = (tethering_h)th;
1435         INFO("Tethering Handle : 0x%X\n", th);
1436         INFO("-\n");
1437         return TETHERING_ERROR_NONE;
1438 }
1439
1440 /**
1441  * @internal
1442  * @brief  Destroys the handle of tethering.
1443  * @since_tizen 2.3
1444  * @privlevel platform
1445  * @privilege http://tizen.org/privilege/tethering.admin
1446  * @param[in]  tethering  The handle of tethering
1447  * @return  0 on success, otherwise a negative error value.
1448  * @retval  #TETHERING_ERROR_NONE  Successful
1449  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1450  * @see  tethering_create()
1451  */
1452 API int tethering_destroy(tethering_h tethering)
1453 {
1454         INFO("+\n");
1455         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1456         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1457                         "parameter(tethering) is NULL\n");
1458
1459         __tethering_h *th = (__tethering_h *)tethering;
1460
1461         INFO("Tethering Handle : 0x%X\n", th);
1462
1463         __disconnect_signals(tethering);
1464
1465         if (th->ssid)
1466                 free(th->ssid);
1467
1468         g_object_unref(th->cancellable);
1469         g_object_unref(th->client_bus_proxy);
1470         g_object_unref(th->client_bus);
1471         memset(th, 0x00, sizeof(__tethering_h));
1472         free(th);
1473
1474         INFO("-\n");
1475         return TETHERING_ERROR_NONE;
1476 }
1477
1478 /**
1479  * @internal
1480  * @brief Enables the tethering, asynchronously.
1481  * @since_tizen 2.3
1482  * @privlevel platform
1483  * @privilege http://tizen.org/privilege/tethering.admin
1484  * @param[in]  tethering  The handle of tethering
1485  * @param[in]  type  The type of tethering
1486  * @return 0 on success, otherwise negative error value.
1487  * @retval  #TETHERING_ERROR_NONE  Successful
1488  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1489  * @post tethering_enabled_cb() will be invoked.
1490  * @see  tethering_is_enabled()
1491  * @see  tethering_disable()
1492  */
1493 API int tethering_enable(tethering_h tethering, tethering_type_e type)
1494 {
1495         INFO("+ type :  %d\n", type);
1496         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1497         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1498         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1499         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1500
1501         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1502                         "parameter(tethering) is NULL\n");
1503
1504         tethering_error_e ret = TETHERING_ERROR_NONE;
1505         __tethering_h *th = (__tethering_h *)tethering;
1506         GDBusProxy *proxy = th->client_bus_proxy;
1507         GDBusConnection *connection = th->client_bus;
1508
1509         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE);
1510
1511         if (__check_precondition(type) == FALSE) {
1512                 //LCOV_EXCL_START
1513                 INFO("-\n");
1514                 return TETHERING_ERROR_OPERATION_FAILED;
1515                 //LCOV_EXCL_STOP
1516         }
1517
1518         switch (type) {
1519         //LCOV_EXCL_START
1520         case TETHERING_TYPE_USB:
1521                 g_dbus_connection_signal_unsubscribe(connection,
1522                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1523
1524                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1525                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1526                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1527                 break;
1528         //LCOV_EXCL_STOP
1529
1530         case TETHERING_TYPE_WIFI: {
1531                 _softap_settings_t set = {"", "", "", 0, false};
1532
1533                 ret = __prepare_wifi_settings(tethering, &set);
1534                 if (ret != TETHERING_ERROR_NONE) {
1535                         ERR("softap settings initialization failed\n");
1536                         DBG("-\n");
1537                         return TETHERING_ERROR_OPERATION_FAILED;
1538                 }
1539                 g_dbus_connection_signal_unsubscribe(connection,
1540                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1541
1542                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1543                                 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),
1544                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1545                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1546                 break;
1547         }
1548
1549         case TETHERING_TYPE_BT:
1550                 g_dbus_connection_signal_unsubscribe(connection,
1551                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1552
1553                 g_dbus_proxy_call(proxy, "enable_bt_tethering", NULL,
1554                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1555                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1556
1557                 break;
1558
1559         //LCOV_EXCL_START
1560         case TETHERING_TYPE_ALL: {
1561                 _softap_settings_t set = {"", "", "", 0, false};
1562
1563                 ret = __prepare_wifi_settings(tethering, &set);
1564                 if (ret != TETHERING_ERROR_NONE) {
1565                         ERR("softap settings initialization failed\n");
1566                         return TETHERING_ERROR_OPERATION_FAILED;
1567                 }
1568
1569                 /* TETHERING_TYPE_USB */
1570                 g_dbus_connection_signal_unsubscribe(connection,
1571                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1572
1573                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1574                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1575                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1576
1577                 /* TETHERING_TYPE_WIFI */
1578                 g_dbus_connection_signal_unsubscribe(connection,
1579                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1580
1581                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1582                                 g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type),
1583                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1584                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1585
1586                 /* TETHERING_TYPE_BT */
1587                 g_dbus_connection_signal_unsubscribe(connection,
1588                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1589
1590                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1591                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1592                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1593                 break;
1594                 //LCOV_EXCL_STOP
1595         }
1596         default:
1597                 ERR("Unknown type : %d\n", type);
1598
1599                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1600
1601                 DBG("-\n");
1602                 return TETHERING_ERROR_INVALID_PARAMETER;
1603         }
1604
1605         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1606         INFO("-\n");
1607         return TETHERING_ERROR_NONE;
1608 }
1609
1610 API int tethering_ipv6_enable(tethering_h tethering, tethering_type_e type)
1611 {
1612         DBG("+ type :  %d\n", type);
1613         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1614         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1615         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1616         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1617
1618         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1619                         "parameter(tethering) is NULL\n");
1620
1621         __tethering_h *th = (__tethering_h *)tethering;
1622         GDBusProxy *proxy = th->client_bus_proxy;
1623         GDBusConnection *connection = th->client_bus;
1624         int ret = 0;
1625
1626         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE);
1627
1628         if (__check_precondition(type) == FALSE) {
1629                 //LCOV_EXCL_START
1630                 DBG("-\n");
1631                 return TETHERING_ERROR_OPERATION_FAILED;
1632                 //LCOV_EXCL_STOP
1633         }
1634
1635         switch (type) {
1636         //LCOV_EXCL_START
1637         case TETHERING_TYPE_WIFI: {
1638                 _softap_settings_t set = {"", "", "", 0, false, false, 0, 0};
1639
1640                 ret = __prepare_wifi_settings(tethering, &set);
1641                 if (ret != TETHERING_ERROR_NONE) {
1642                         ERR("softap settings initialization failed\n");
1643                         DBG("-\n");
1644                         return TETHERING_ERROR_OPERATION_FAILED;
1645                 }
1646                 g_dbus_connection_signal_unsubscribe(connection,
1647                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1648                         g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1649                                 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),
1650                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1651                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1652                 break;
1653          }
1654         case TETHERING_TYPE_BT: {
1655                 g_dbus_connection_signal_unsubscribe(connection,
1656                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1657
1658                 /* For TEST */
1659                 g_dbus_proxy_call(proxy, "enable_bt_tethering", g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1660                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1661                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1662
1663                 break;
1664         }
1665
1666         default: {
1667                 ERR("Unknown type : %d\n", type);
1668
1669                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1670
1671                 DBG("-\n");
1672                 return TETHERING_ERROR_INVALID_PARAMETER;
1673         }
1674         }
1675
1676         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1677         DBG("-\n");
1678         return TETHERING_ERROR_NONE;
1679 }
1680
1681 API int tethering_ipv6_disable(tethering_h tethering, tethering_type_e type)
1682 {
1683         DBG("+ type :  %d\n", type);
1684         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1685         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1686         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1687         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1688
1689         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1690                         "parameter(tethering) is NULL\n");
1691
1692         __tethering_h *th = (__tethering_h *)tethering;
1693         GDBusProxy *proxy = th->client_bus_proxy;
1694         GDBusConnection *connection = th->client_bus;
1695
1696         switch (type) {
1697         case TETHERING_TYPE_WIFI:
1698                 DBG("Disable wifi tethering..");
1699                 g_dbus_connection_signal_unsubscribe(connection,
1700                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1701
1702                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1703                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1704                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1705                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1706                 break;
1707         case TETHERING_TYPE_BT:
1708                 g_dbus_connection_signal_unsubscribe(connection,
1709                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1710
1711                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1712                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV6),
1713                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1714                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1715                 break;
1716
1717         default:
1718                 ERR("Not supported tethering type [%d]\n", type);
1719                 DBG("-\n");
1720                 return TETHERING_ERROR_INVALID_PARAMETER;
1721         }
1722         DBG("-\n");
1723         return TETHERING_ERROR_NONE;
1724 }
1725 /**
1726  * @internal
1727  * @brief Disables the tethering, asynchronously.
1728  * @since_tizen 2.3
1729  * @privlevel platform
1730  * @privilege http://tizen.org/privilege/tethering.admin
1731  * @param[in]  tethering  The handle of tethering
1732  * @param[in]  type  The type of tethering
1733  * @return 0 on success, otherwise negative error value.
1734  * @retval  #TETHERING_ERROR_NONE  Successful
1735  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1736  * @post tethering_disabled_cb() will be invoked.
1737  * @see  tethering_is_enabled()
1738  * @see  tethering_enable()
1739  */
1740 API int tethering_disable(tethering_h tethering, tethering_type_e type)
1741 {
1742         INFO("+ type :  %d\n", type);
1743         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1744         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1745         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1746         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1747
1748         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1749                         "parameter(tethering) is NULL\n");
1750
1751         __tethering_h *th = (__tethering_h *)tethering;
1752         GDBusProxy *proxy = th->client_bus_proxy;
1753         GDBusConnection *connection = th->client_bus;
1754
1755         switch (type) {
1756         case TETHERING_TYPE_USB:
1757                 g_dbus_connection_signal_unsubscribe(connection,
1758                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1759
1760                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1761                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1762                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1763
1764                 break;
1765
1766         case TETHERING_TYPE_WIFI:
1767
1768                 g_dbus_connection_signal_unsubscribe(connection,
1769                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1770
1771                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1772                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1773                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1774                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1775                 break;
1776
1777         case TETHERING_TYPE_BT:
1778
1779                 g_dbus_connection_signal_unsubscribe(connection,
1780                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1781
1782                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1783                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1784                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1785                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1786                 break;
1787
1788         case TETHERING_TYPE_ALL:
1789                 g_dbus_connection_signal_unsubscribe(connection,
1790                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1791
1792                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1793                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1794                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1795
1796                 g_dbus_connection_signal_unsubscribe(connection,
1797                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1798
1799                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1800                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1801                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1802                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1803
1804                 g_dbus_connection_signal_unsubscribe(connection,
1805                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1806
1807                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1808                                 g_variant_new("(i)", TETHERING_ADDRESS_FAMILY_IPV4),
1809                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1810                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1811                 break;
1812
1813         default:
1814                 ERR("Not supported tethering type [%d]\n", type);
1815                 DBG("-\n");
1816                 return TETHERING_ERROR_INVALID_PARAMETER;
1817         }
1818         INFO("-\n");
1819         return TETHERING_ERROR_NONE;
1820 }
1821
1822 /**
1823  * @internal
1824  * @brief  Checks whetehr the tethering is enabled or not.
1825  * @since_tizen 2.3
1826  * @privlevel platform
1827  * @privilege http://tizen.org/privilege/tethering.admin
1828  * @param[in]  tethering  The handle of tethering
1829  * @param[in]  type  The type of tethering
1830  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
1831  */
1832 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
1833 {
1834         INFO("+ type :  %d\n", type);
1835         int is_on = 0;
1836         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
1837
1838         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1839
1840         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0)
1841                 return FALSE;
1842
1843         switch (type) {
1844         case TETHERING_TYPE_USB:
1845                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
1846                 break;
1847
1848         case TETHERING_TYPE_WIFI:
1849                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
1850                 break;
1851
1852         case TETHERING_TYPE_BT:
1853                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
1854                 break;
1855
1856         default:
1857                 ERR("Not supported type : %d\n", type);
1858                 break;
1859         }
1860         INFO("- enabled:  %s\n", (is_on & vconf_type) ? "true" : "false");
1861         return is_on & vconf_type ? true : false;
1862 }
1863
1864 /**
1865  * @internal
1866  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
1867  * @since_tizen 2.3
1868  * @privlevel platform
1869  * @privilege http://tizen.org/privilege/tethering.admin
1870  * @remarks @a mac_address must be released with free() by you.
1871  * @param[in]  tethering  The handle of tethering
1872  * @param[in]  type  The type of tethering
1873  * @param[out]  mac_address  The MAC address
1874  * @return  0 on success, otherwise a negative error value.
1875  * @retval  #TETHERING_ERROR_NONE  Successful
1876  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1877  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1878  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1879  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1880  * @pre  tethering must be enabled.
1881  * @see  tethering_is_enabled()
1882  * @see  tethering_enable()
1883  */
1884 API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
1885 {
1886         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1887         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1888         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1889         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1890
1891         _retvm_if(tethering_is_enabled(tethering, type) == false,
1892                         TETHERING_ERROR_NOT_ENABLED,
1893                         "tethering type[%d] is not enabled\n", type);
1894         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1895                         "parameter(tethering) is NULL\n");
1896         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1897                         "parameter(mac_address) is NULL\n");
1898
1899         struct ifreq ifr;
1900         int s = 0;
1901         char *macbuf = NULL;
1902
1903         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1904                         TETHERING_ERROR_OPERATION_FAILED,
1905                         "getting interface name is failed\n");
1906
1907         s = socket(AF_INET, SOCK_DGRAM, 0);
1908         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1909                         "getting socket is failed\n");
1910         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
1911                 ERR("getting mac is failed\n");
1912                 close(s);
1913                 return TETHERING_ERROR_OPERATION_FAILED;
1914         }
1915         close(s);
1916
1917         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
1918         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1919                         "Not enough memory\n");
1920         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
1921                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
1922                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
1923                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
1924                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
1925                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
1926                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
1927
1928         *mac_address = macbuf;
1929
1930         return TETHERING_ERROR_NONE;
1931 }
1932
1933 /**
1934  * @internal
1935  * @brief Gets the name of network interface. For example, usb0.
1936  * @since_tizen 2.3
1937  * @privlevel platform
1938  * @privilege http://tizen.org/privilege/tethering.admin
1939  * @remarks @a interface_name must be released with free() by you.
1940  * @param[in]  tethering  The handle of tethering
1941  * @param[in]  type  The type of tethering
1942  * @param[out]  interface_name  The name of network interface
1943  * @return 0 on success, otherwise negative error value.
1944  * @retval  #TETHERING_ERROR_NONE  Successful
1945  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1946  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1947  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1948  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1949  * @pre  tethering must be enabled.
1950  * @see  tethering_is_enabled()
1951  * @see  tethering_enable()
1952  */
1953 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
1954 {
1955         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1956         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1957         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1958         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1959
1960         _retvm_if(tethering_is_enabled(tethering, type) == false,
1961                         TETHERING_ERROR_NOT_ENABLED,
1962                         "tethering type[%d] is not enabled\n", type);
1963         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1964                         "parameter(tethering) is NULL\n");
1965         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1966                         "parameter(interface_name) is NULL\n");
1967
1968         char intf[TETHERING_STR_INFO_LEN] = {0, };
1969
1970         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
1971                         TETHERING_ERROR_OPERATION_FAILED,
1972                         "getting interface name is failed\n");
1973         *interface_name = strdup(intf);
1974         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1975                         "Not enough memory\n");
1976
1977         return TETHERING_ERROR_NONE;
1978 }
1979
1980 /**
1981  * @internal
1982  * @brief Gets the local IP address.
1983  * @since_tizen 2.3
1984  * @privlevel platform
1985  * @privilege http://tizen.org/privilege/tethering.admin
1986  * @remarks @a ip_address must be released with free() by you.
1987  * @param[in]  tethering  The handle of tethering
1988  * @param[in]  type  The type of tethering
1989  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1990  * @param[out]  ip_address  The local IP address
1991  * @return 0 on success, otherwise negative error value.
1992  * @retval  #TETHERING_ERROR_NONE  Successful
1993  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1994  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1995  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1996  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1997  * @pre  tethering must be enabled.
1998  * @see  tethering_is_enabled()
1999  * @see  tethering_enable()
2000  */
2001 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
2002 {
2003         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2004         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2005         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2006         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2007
2008         _retvm_if(tethering_is_enabled(tethering, type) == false,
2009                         TETHERING_ERROR_NOT_ENABLED,
2010                         "tethering type[%d] is not enabled\n", type);
2011         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2012                         "parameter(tethering) is NULL\n");
2013         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2014                         "parameter(ip_address) is NULL\n");
2015
2016         struct ifreq ifr;
2017         int s = 0;
2018         char *ipbuf = NULL;
2019
2020         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
2021                         TETHERING_ERROR_OPERATION_FAILED,
2022                         "getting interface name is failed\n");
2023
2024         s = socket(AF_INET, SOCK_DGRAM, 0);
2025         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
2026                         "getting socket is failed\n");
2027         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
2028                 ERR("ioctl is failed\n");
2029                 close(s);
2030                 return TETHERING_ERROR_OPERATION_FAILED;
2031         }
2032         close(s);
2033
2034         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
2035         *ip_address = strdup(ipbuf);
2036         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2037                         "Not enough memory\n");
2038
2039         return TETHERING_ERROR_NONE;
2040 }
2041
2042 /**
2043  * @internal
2044  * @brief Gets the Gateway address.
2045  * @since_tizen 2.3
2046  * @privlevel platform
2047  * @privilege http://tizen.org/privilege/tethering.admin
2048  * @remarks @a gateway_address must be released with free() by you.
2049  * @param[in]  tethering  The handle of tethering
2050  * @param[in]  type  The type of tethering
2051  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2052  * @param[out]  gateway_address  The local IP address
2053  * @return 0 on success, otherwise negative error value.
2054  * @retval  #TETHERING_ERROR_NONE  Successful
2055  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2056  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2057  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2058  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2059  * @pre  tethering must be enabled.
2060  * @see  tethering_is_enabled()
2061  * @see  tethering_enable()
2062  */
2063 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
2064 {
2065         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2066         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2067         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2068         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2069
2070         _retvm_if(tethering_is_enabled(tethering, type) == false,
2071                         TETHERING_ERROR_NOT_ENABLED,
2072                         "tethering type[%d] is not enabled\n", type);
2073         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2074                         "parameter(tethering) is NULL\n");
2075         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2076                         "parameter(gateway_address) is NULL\n");
2077
2078         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
2079
2080         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
2081                         TETHERING_ERROR_OPERATION_FAILED,
2082                         "getting gateway address is failed\n");
2083
2084         *gateway_address = strdup(gateway_buf);
2085
2086         return TETHERING_ERROR_NONE;
2087 }
2088
2089 /**
2090  * @internal
2091  * @brief Gets the Subnet Mask.
2092  * @since_tizen 2.3
2093  * @privlevel platform
2094  * @privilege http://tizen.org/privilege/tethering.admin
2095  * @remarks @a subnet_mask must be released with free() by you.
2096  * @param[in]  tethering  The handle of tethering
2097  * @param[in]  type  The type of tethering
2098  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
2099  * @param[out]  subnet_mask  The local IP address
2100  * @return 0 on success, otherwise negative error value.
2101  * @retval  #TETHERING_ERROR_NONE  Successful
2102  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2103  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2104  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2105  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2106  * @pre  tethering must be enabled.
2107  * @see  tethering_is_enabled()
2108  * @see  tethering_enable()
2109  */
2110 API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
2111 {
2112         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2113         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2114         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2115         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2116
2117         _retvm_if(tethering_is_enabled(tethering, type) == false,
2118                         TETHERING_ERROR_NOT_ENABLED,
2119                         "tethering is not enabled\n");
2120         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2121                         "parameter(tethering) is NULL\n");
2122         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2123                         "parameter(subnet_mask) is NULL\n");
2124
2125         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
2126         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2127                         "Not enough memory\n");
2128
2129         return TETHERING_ERROR_NONE;
2130 }
2131
2132 /**
2133  * @internal
2134  * @brief Gets the data usage.
2135  * @since_tizen 2.3
2136  * @privlevel platform
2137  * @privilege http://tizen.org/privilege/tethering.admin
2138  * @param[in]  tethering  The handle of tethering
2139  * @param[out]  usage  The data usage
2140  * @return 0 on success, otherwise negative error value.
2141  * @retval  #TETHERING_ERROR_NONE  Successful
2142  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2143  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2144  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2145  * @pre  tethering must be enabled.
2146  * @see  tethering_is_enabled()
2147  * @see  tethering_enable()
2148  */
2149 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
2150 {
2151         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2152
2153         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2154                         "parameter(tethering) is NULL\n");
2155         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2156                         "parameter(callback) is NULL\n");
2157         _retvm_if(__any_tethering_is_enabled(tethering) == false,
2158                         TETHERING_ERROR_NOT_ENABLED,
2159                         "tethering is not enabled\n");
2160
2161         __tethering_h *th = (__tethering_h *)tethering;
2162         GDBusProxy *proxy = th->client_bus_proxy;
2163
2164         th->data_usage_cb = callback;
2165         th->data_usage_user_data = user_data;
2166
2167         g_dbus_proxy_call(proxy, "get_data_packet_usage",
2168                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
2169                         (GAsyncReadyCallback) __get_data_usage_cb, (gpointer)tethering);
2170
2171         return TETHERING_ERROR_NONE;
2172 }
2173
2174 /**
2175  * @internal
2176  * @brief Gets the client which is connected by tethering "type".
2177  * @since_tizen 2.3
2178  * @privlevel platform
2179  * @privilege http://tizen.org/privilege/tethering.admin
2180  * @param[in]  tethering  The handle of tethering
2181  * @param[in]  type  The type of tethering
2182  * @param[in]  callback  The callback function to invoke
2183  * @param[in]  user_data  The user data to be passed to the callback function
2184  * @retval  #TETHERING_ERROR_NONE  Successful
2185  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2186  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2187  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2188  * @pre  tethering must be enabled.
2189  * @see  tethering_is_enabled()
2190  * @see  tethering_enable()
2191  */
2192 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
2193 {
2194         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2195         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2196         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2197         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2198
2199         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2200                         "parameter(tethering) is NULL\n");
2201         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2202                         "parameter(callback) is NULL\n");
2203         _retvm_if(__any_tethering_is_enabled(tethering) == false,
2204                         TETHERING_ERROR_NOT_ENABLED,
2205                         "tethering is not enabled\n");
2206
2207         mobile_ap_type_e interface;
2208         __tethering_h *th = (__tethering_h *)tethering;
2209         __tethering_client_h client = {0, };
2210         gchar *ip = NULL;
2211         gchar *mac = NULL;
2212         gchar *hostname = NULL;
2213         guint timestamp = 0;
2214         GError *error = NULL;
2215         GVariant *result = NULL;
2216         GVariantIter *outer_iter = NULL;
2217         GVariantIter *inner_iter = NULL;
2218         GVariant *station = NULL;
2219         GVariant *value = NULL;
2220         gchar *key = NULL;
2221
2222         result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_station_info",
2223                         NULL, G_DBUS_CALL_FLAGS_NONE,
2224                         -1, th->cancellable, &error);
2225         if (error)
2226                 ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
2227         g_variant_get(result, "(a(a{sv}))", &outer_iter);
2228         while (g_variant_iter_loop(outer_iter, "(@a{sv})", &station)) {
2229                 g_variant_get(station, "a{sv}", &inner_iter);
2230                 while (g_variant_iter_loop(inner_iter, "{sv}", &key, &value)) {
2231                         if (g_strcmp0(key, "Type") == 0) {
2232                                 interface = g_variant_get_int32(value);
2233                                 if (interface == MOBILE_AP_TYPE_USB)
2234                                         client.interface = TETHERING_TYPE_USB;
2235                                 else if (interface == MOBILE_AP_TYPE_WIFI)
2236                                         client.interface = TETHERING_TYPE_WIFI;
2237                                 else if (interface == MOBILE_AP_TYPE_BT)
2238                                         client.interface = TETHERING_TYPE_BT;
2239                                 else {
2240                                         ERR("Invalid interface\n");
2241                                         g_free(key);
2242                                         g_variant_unref(value);
2243                                         break;
2244                                 }
2245                                 DBG("interface is %d\n", client.interface);
2246                                 if (client.interface != type && (TETHERING_TYPE_ALL != type)) {
2247                                         g_free(key);
2248                                         g_variant_unref(value);
2249                                         break;
2250                                 }
2251                         } else if (g_strcmp0(key, "IP") == 0) {
2252                                 g_variant_get(value, "s", &ip);
2253                                 SDBG("ip is %s\n", ip);
2254                                 g_strlcpy(client.ip, ip, sizeof(client.ip));
2255                         } else if (g_strcmp0(key, "MAC") == 0) {
2256                                 g_variant_get(value, "s", &mac);
2257                                 SDBG("mac is %s\n", mac);
2258                                 g_strlcpy(client.mac, mac, sizeof(client.mac));
2259                         } else if (g_strcmp0(key, "Name") == 0) {
2260                                 g_variant_get(value, "s", &hostname);
2261                                 SDBG("hsotname is %s\n", hostname);
2262                                 if (hostname)
2263                                         client.hostname = g_strdup(hostname);
2264                         } else if (g_strcmp0(key, "Time") == 0) {
2265                                 timestamp = g_variant_get_int32(value);
2266                                 DBG("timestamp is %d\n", timestamp);
2267                                 client.tm = (time_t)timestamp;
2268                         } else {
2269                                 ERR("Key %s not required\n", key);
2270                         }
2271                 }
2272                 g_free(hostname);
2273                 g_free(ip);
2274                 g_free(mac);
2275                 g_variant_iter_free(inner_iter);
2276                 if (callback((tethering_client_h)&client, user_data) == false) {
2277                         DBG("iteration is stopped\n");
2278                         g_free(client.hostname);
2279                         g_variant_iter_free(outer_iter);
2280                         g_variant_unref(station);
2281                         g_variant_unref(result);
2282                         DBG("-\n");
2283                         return TETHERING_ERROR_OPERATION_FAILED;
2284                 }
2285                 g_free(client.hostname);
2286         }
2287         g_variant_iter_free(outer_iter);
2288         g_variant_unref(station);
2289         g_variant_unref(result);
2290         DBG("-\n");
2291         return TETHERING_ERROR_NONE;
2292 }
2293
2294 /**
2295  * @internal
2296  * @brief Registers the callback function called when tethering is enabled.
2297  * @since_tizen 2.3
2298  * @privlevel platform
2299  * @privilege http://tizen.org/privilege/tethering.admin
2300  * @param[in]  tethering  The handle of tethering
2301  * @param[in]  type  The type of tethering
2302  * @param[in]  callback  The callback function to invoke
2303  * @param[in]  user_data  The user data to be passed to the callback function
2304  * @retval  #TETHERING_ERROR_NONE  Successful
2305  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2306  * @see  tethering_unset_enabled_cb()
2307  */
2308 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
2309 {
2310         INFO("+ type: %d\n", type);
2311         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2312         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2313         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2314         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2315
2316         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2317                         "parameter(tethering) is NULL\n");
2318         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2319                         "parameter(callback) is NULL\n");
2320
2321         __tethering_h *th = (__tethering_h *)tethering;
2322         tethering_type_e ti;
2323
2324         if (type != TETHERING_TYPE_ALL) {
2325                 th->enabled_cb[type] = callback;
2326                 th->enabled_user_data[type] = user_data;
2327
2328                 return TETHERING_ERROR_NONE;
2329         }
2330
2331         /* TETHERING_TYPE_ALL */
2332         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2333                 th->enabled_cb[ti] = callback;
2334                 th->enabled_user_data[ti] = user_data;
2335         }
2336
2337         INFO("-\n");
2338         return TETHERING_ERROR_NONE;
2339 }
2340
2341 /**
2342  * @internal
2343  * @brief Unregisters the callback function called when tethering is disabled.
2344  * @since_tizen 2.3
2345  * @privlevel platform
2346  * @privilege http://tizen.org/privilege/tethering.admin
2347  * @param[in]  tethering  The handle of tethering
2348  * @param[in]  type  The type of tethering
2349  * @retval  #TETHERING_ERROR_NONE  Successful
2350  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2351  * @see  tethering_set_enabled_cb()
2352  */
2353 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
2354 {
2355         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2356         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2357         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2358         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2359
2360         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2361                         "parameter(tethering) is NULL\n");
2362
2363         __tethering_h *th = (__tethering_h *)tethering;
2364         tethering_type_e ti;
2365
2366         if (type != TETHERING_TYPE_ALL) {
2367                 th->enabled_cb[type] = NULL;
2368                 th->enabled_user_data[type] = NULL;
2369
2370                 return TETHERING_ERROR_NONE;
2371         }
2372
2373         /* TETHERING_TYPE_ALL */
2374         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2375                 th->enabled_cb[ti] = NULL;
2376                 th->enabled_user_data[ti] = NULL;
2377         }
2378
2379         return TETHERING_ERROR_NONE;
2380 }
2381
2382 /**
2383  * @internal
2384  * @brief Registers the callback function called when tethering is disabled.
2385  * @since_tizen 2.3
2386  * @privlevel platform
2387  * @privilege http://tizen.org/privilege/tethering.admin
2388  * @param[in]  tethering  The handle of tethering
2389  * @param[in]  type  The type of tethering
2390  * @param[in]  callback  The callback function to invoke
2391  * @param[in]  user_data  The user data to be passed to the callback function
2392  * @retval  #TETHERING_ERROR_NONE  Successful
2393  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2394  * @see  tethering_unset_disabled_cb()
2395  */
2396 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
2397 {
2398         INFO("+ type: %d\n", type);
2399         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2400         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2401         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2402         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2403
2404         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2405                         "parameter(tethering) is NULL\n");
2406         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2407                         "parameter(callback) is NULL\n");
2408
2409         __tethering_h *th = (__tethering_h *)tethering;
2410         tethering_type_e ti;
2411
2412         if (type != TETHERING_TYPE_ALL) {
2413                 th->disabled_cb[type] = callback;
2414                 th->disabled_user_data[type] = user_data;
2415
2416                 return TETHERING_ERROR_NONE;
2417         }
2418
2419         /* TETHERING_TYPE_ALL */
2420         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2421                 th->disabled_cb[ti] = callback;
2422                 th->disabled_user_data[ti] = user_data;
2423         }
2424         INFO("-\n");
2425         return TETHERING_ERROR_NONE;
2426 }
2427
2428 /**
2429  * @internal
2430  * @brief Unregisters the callback function called when tethering is disabled.
2431  * @since_tizen 2.3
2432  * @privlevel platform
2433  * @privilege http://tizen.org/privilege/tethering.admin
2434  * @param[in]  tethering  The handle of tethering
2435  * @param[in]  type  The type of tethering
2436  * @retval  #TETHERING_ERROR_NONE  Successful
2437  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2438  * @see  tethering_set_disabled_cb()
2439  */
2440 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
2441 {
2442         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2443         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2444         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2445         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2446
2447         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2448                         "parameter(tethering) is NULL\n");
2449
2450         __tethering_h *th = (__tethering_h *)tethering;
2451         tethering_type_e ti;
2452
2453         if (type != TETHERING_TYPE_ALL) {
2454                 th->disabled_cb[type] = NULL;
2455                 th->disabled_user_data[type] = NULL;
2456
2457                 return TETHERING_ERROR_NONE;
2458         }
2459
2460         /* TETHERING_TYPE_ALL */
2461         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2462                 th->disabled_cb[ti] = NULL;
2463                 th->disabled_user_data[ti] = NULL;
2464         }
2465
2466         return TETHERING_ERROR_NONE;
2467 }
2468
2469 /**
2470  * @internal
2471  * @brief Registers the callback function called when the state of connection is changed.
2472  * @since_tizen 2.3
2473  * @privlevel platform
2474  * @privilege http://tizen.org/privilege/tethering.admin
2475  * @param[in]  tethering  The handle of tethering
2476  * @param[in]  type  The type of tethering
2477  * @param[in]  callback  The callback function to invoke
2478  * @param[in]  user_data  The user data to be passed to the callback function
2479  * @retval  #TETHERING_ERROR_NONE  Successful
2480  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2481  * @see  tethering_unset_connection_state_changed_cb_cb()
2482  */
2483 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
2484 {
2485         INFO("+ type: %d\n", type);
2486         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2487         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2488         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2489         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2490
2491         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2492                         "parameter(tethering) is NULL\n");
2493         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2494                         "parameter(callback) is NULL\n");
2495
2496         __tethering_h *th = (__tethering_h *)tethering;
2497         tethering_type_e ti;
2498
2499         if (type != TETHERING_TYPE_ALL) {
2500                 th->changed_cb[type] = callback;
2501                 th->changed_user_data[type] = user_data;
2502
2503                 return TETHERING_ERROR_NONE;
2504         }
2505
2506         /* TETHERING_TYPE_ALL */
2507         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2508                 th->changed_cb[ti] = callback;
2509                 th->changed_user_data[ti] = user_data;
2510         }
2511         INFO("-\n");
2512         return TETHERING_ERROR_NONE;
2513 }
2514
2515 /**
2516  * @internal
2517  * @brief Unregisters the callback function called when the state of connection is changed.
2518  * @since_tizen 2.3
2519  * @privlevel platform
2520  * @privilege http://tizen.org/privilege/tethering.admin
2521  * @param[in]  tethering  The handle of tethering
2522  * @param[in]  type  The type of tethering
2523  * @retval  #TETHERING_ERROR_NONE  Successful
2524  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2525  * @see  tethering_set_connection_state_changed_cb()
2526  */
2527 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
2528 {
2529         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2530         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
2531         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2532         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
2533
2534         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2535                         "parameter(tethering) is NULL\n");
2536
2537         __tethering_h *th = (__tethering_h *)tethering;
2538         tethering_type_e ti;
2539
2540         if (type != TETHERING_TYPE_ALL) {
2541                 th->changed_cb[type] = NULL;
2542                 th->changed_user_data[type] = NULL;
2543
2544                 return TETHERING_ERROR_NONE;
2545         }
2546
2547         /* TETHERING_TYPE_ALL */
2548         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2549                 th->changed_cb[ti] = NULL;
2550                 th->changed_user_data[ti] = NULL;
2551         }
2552
2553         return TETHERING_ERROR_NONE;
2554 }
2555
2556 /**
2557  * @internal
2558  * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed.
2559  * @since_tizen 2.3
2560  * @privlevel platform
2561  * @privilege http://tizen.org/privilege/tethering.admin
2562  * @param[in]  tethering  The handle of tethering
2563  * @param[in]  callback  The callback function to invoke
2564  * @param[in]  user_data  The user data to be passed to the callback function
2565  * @retval  #TETHERING_ERROR_NONE  Successful
2566  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2567  * @see  tethering_wifi_unset_security_type_changed_cb()
2568  */
2569 API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data)
2570 {
2571         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2572         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2573
2574         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2575                         "parameter(tethering) is NULL\n");
2576         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2577                         "parameter(callback) is NULL\n");
2578
2579         __tethering_h *th = (__tethering_h *)tethering;
2580
2581         th->security_type_changed_cb = callback;
2582         th->security_type_user_data = user_data;
2583
2584         return TETHERING_ERROR_NONE;
2585
2586 }
2587
2588 /**
2589  * @internal
2590  * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed.
2591  * @since_tizen 2.3
2592  * @privlevel platform
2593  * @privilege http://tizen.org/privilege/tethering.admin
2594  * @param[in]  tethering  The handle of tethering
2595  * @param[in]  type  The type of tethering
2596  * @retval  #TETHERING_ERROR_NONE  Successful
2597  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2598  * @see  tethering_wifi_set_security_type_changed_cb()
2599  */
2600 API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering)
2601 {
2602         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2603         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2604
2605         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2606                         "parameter(tethering) is NULL\n");
2607
2608         __tethering_h *th = (__tethering_h *)tethering;
2609
2610         th->security_type_changed_cb = NULL;
2611         th->security_type_user_data = NULL;
2612
2613         return TETHERING_ERROR_NONE;
2614 }
2615
2616 /**
2617  * @internal
2618  * @brief Registers the callback function called when the visibility of SSID is changed.
2619  * @since_tizen 2.3
2620  * @privlevel platform
2621  * @privilege http://tizen.org/privilege/tethering.admin
2622  * @param[in]  tethering  The handle of tethering
2623  * @param[in]  callback  The callback function to invoke
2624  * @param[in]  user_data  The user data to be passed to the callback function
2625  * @retval  #TETHERING_ERROR_NONE  Successful
2626  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2627  * @see  tethering_wifi_unset_ssid_visibility_changed_cb_cb()
2628  */
2629 API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data)
2630 {
2631         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2632         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2633
2634         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2635                         "parameter(tethering) is NULL\n");
2636         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2637                         "parameter(callback) is NULL\n");
2638
2639         __tethering_h *th = (__tethering_h *)tethering;
2640
2641         th->ssid_visibility_changed_cb = callback;
2642         th->ssid_visibility_user_data = user_data;
2643
2644         return TETHERING_ERROR_NONE;
2645 }
2646
2647 /**
2648  * @internal
2649  * @brief Unregisters the callback function called when the visibility of SSID is changed.
2650  * @since_tizen 2.3
2651  * @privlevel platform
2652  * @privilege http://tizen.org/privilege/tethering.admin
2653  * @param[in]  tethering  The handle of tethering
2654  * @retval  #TETHERING_ERROR_NONE  Successful
2655  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2656  * @see  tethering_wifi_set_ssid_visibility_changed_cb()
2657  */
2658 API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering)
2659 {
2660         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2661         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2662
2663         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2664                         "parameter(tethering) is NULL\n");
2665
2666         __tethering_h *th = (__tethering_h *)tethering;
2667
2668         th->ssid_visibility_changed_cb = NULL;
2669         th->ssid_visibility_user_data = NULL;
2670
2671         return TETHERING_ERROR_NONE;
2672 }
2673
2674 /**
2675  * @internal
2676  * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed.
2677  * @since_tizen 2.3
2678  * @privlevel platform
2679  * @privilege http://tizen.org/privilege/tethering.admin
2680  * @param[in]  tethering  The handle of tethering
2681  * @param[in]  callback  The callback function to invoke
2682  * @param[in]  user_data  The user data to be passed to the callback function
2683  * @retval  #TETHERING_ERROR_NONE  Successful
2684  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2685  * @see  tethering_wifi_unset_passphrase_changed_cb()
2686  */
2687 API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data)
2688 {
2689         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2690         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2691
2692         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2693                         "parameter(tethering) is NULL\n");
2694         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2695                         "parameter(callback) is NULL\n");
2696
2697         __tethering_h *th = (__tethering_h *)tethering;
2698
2699         th->passphrase_changed_cb = callback;
2700         th->passphrase_user_data = user_data;
2701
2702         return TETHERING_ERROR_NONE;
2703 }
2704
2705 /**
2706  * @internal
2707  * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed.
2708  * @since_tizen 2.3
2709  * @privlevel platform
2710  * @privilege http://tizen.org/privilege/tethering.admin
2711  * @param[in]  tethering  The handle of tethering
2712  * @retval  #TETHERING_ERROR_NONE  Successful
2713  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2714  * @see  tethering_wifi_set_passphrase_changed_cb()
2715  */
2716 API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering)
2717 {
2718         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2719         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2720
2721         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2722                         "parameter(tethering) is NULL\n");
2723
2724         __tethering_h *th = (__tethering_h *)tethering;
2725
2726         th->passphrase_changed_cb = NULL;
2727         th->passphrase_user_data = NULL;
2728
2729         return TETHERING_ERROR_NONE;
2730 }
2731
2732 /**
2733  * @internal
2734  * @brief Sets the security type of Wi-Fi tethering.
2735  * @since_tizen 2.3
2736  * @privlevel platform
2737  * @privilege http://tizen.org/privilege/tethering.admin
2738  * @remarks This change is applied next time Wi-Fi tethering is enabled
2739  * @param[in]  tethering  The handle of tethering
2740  * @param[in]  type  The security type
2741  * @return 0 on success, otherwise negative error value.
2742  * @retval  #TETHERING_ERROR_NONE  Successful
2743  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2744  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2745  * @see  tethering_wifi_get_security_type()
2746  */
2747 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
2748 {
2749         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2750         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2751
2752         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2753                         "parameter(tethering) is NULL\n");
2754
2755         __tethering_h *th = (__tethering_h *)tethering;
2756         tethering_error_e ret = TETHERING_ERROR_NONE;
2757         char *sec_str = NULL;
2758
2759         ret = __set_security_type(type);
2760         if (ret == TETHERING_ERROR_NONE) {
2761
2762                 switch (type) {
2763                 case TETHERING_WIFI_SECURITY_TYPE_NONE:
2764                         sec_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
2765                         break;
2766                 case TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK:
2767                         sec_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
2768                         break;
2769                 case TETHERING_WIFI_SECURITY_TYPE_WPS:
2770                         sec_str = TETHERING_WIFI_SECURITY_TYPE_WPS_STR;
2771                         break;
2772                 }
2773
2774                 __send_dbus_signal(th->client_bus,
2775                                 SIGNAL_NAME_SECURITY_TYPE_CHANGED, sec_str);
2776         }
2777         return ret;
2778 }
2779
2780 /**
2781  * @internal
2782  * @brief Gets the security type of Wi-Fi tethering.
2783  * @since_tizen 2.3
2784  * @privlevel platform
2785  * @privilege http://tizen.org/privilege/tethering.admin
2786  * @param[in]  tethering  The handle of tethering
2787  * @param[out]  type  The security type
2788  * @return 0 on success, otherwise negative error value.
2789  * @retval  #TETHERING_ERROR_NONE  Successful
2790  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2791  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2792  * @see  tethering_wifi_set_security_type()
2793  */
2794 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
2795 {
2796         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2797         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2798
2799         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2800                         "parameter(type) is NULL\n");
2801
2802         return __get_security_type(type);
2803 }
2804
2805 /**
2806  * @internal
2807  * @brief Sets the SSID (service set identifier).
2808  * @since_tizen 2.3
2809  * @privlevel platform
2810  * @privilege http://tizen.org/privilege/tethering.admin
2811  * @details If SSID is not set, Device name is used as SSID
2812  * @remarks This change is applied next time Wi-Fi tethering is enabled with same @a tethering handle
2813  * @param[in]  tethering  The handle of tethering
2814  * @param[out]  ssid  The SSID
2815  * @return 0 on success, otherwise negative error value.
2816  * @retval  #TETHERING_ERROR_NONE  Successful
2817  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2818  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2819  */
2820 API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid)
2821 {
2822         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2823         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2824
2825         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2826                         "parameter(tethering) is NULL\n");
2827         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2828                         "parameter(ssid) is NULL\n");
2829
2830         __tethering_h *th = (__tethering_h *)tethering;
2831         char *p_ssid = NULL;
2832         int ssid_len = 0;
2833
2834         ssid_len = strlen(ssid);
2835         if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) {
2836                 ERR("parameter(ssid) is too long");
2837                 return TETHERING_ERROR_INVALID_PARAMETER;
2838         }
2839
2840         p_ssid = strdup(ssid);
2841         _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2842                         "strdup is failed\n");
2843
2844         if (th->ssid)
2845                 free(th->ssid);
2846         th->ssid = p_ssid;
2847
2848         return TETHERING_ERROR_NONE;
2849 }
2850
2851 /**
2852  * @internal
2853  * @brief Gets the SSID (service set identifier).
2854  * @since_tizen 2.3
2855  * @privlevel platform
2856  * @privilege http://tizen.org/privilege/tethering.admin
2857  * @remarks @a ssid must be released with free() by you.
2858  * @param[in]  tethering  The handle of tethering
2859  * @param[out]  ssid  The SSID
2860  * @return 0 on success, otherwise negative error value.
2861  * @retval  #TETHERING_ERROR_NONE  Successful
2862  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2863  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2864  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2865  */
2866 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
2867 {
2868         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2869         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2870
2871         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2872                         "parameter(tethering) is NULL\n");
2873         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2874                         "parameter(ssid) is NULL\n");
2875         DBG("+\n");
2876
2877         __tethering_h *th = (__tethering_h *)tethering;
2878         char val[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, };
2879
2880         if (!tethering_is_enabled(NULL, TETHERING_TYPE_WIFI)) {
2881                 if (th->ssid != NULL) {
2882                         DBG("Private SSID is set\n");
2883                         *ssid = strdup(th->ssid);
2884                 } else {
2885                         if (__get_ssid_from_vconf(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
2886                                                 val, sizeof(val)) == false) {
2887                                 return TETHERING_ERROR_OPERATION_FAILED;
2888                         }
2889                         *ssid = strdup(val);
2890                 }
2891         } else {
2892                 if (__get_ssid_from_vconf(VCONFKEY_MOBILE_HOTSPOT_SSID,
2893                                         val, sizeof(val)) == false) {
2894                         return TETHERING_ERROR_OPERATION_FAILED;
2895                 }
2896                 *ssid = strdup(val);
2897         }
2898
2899         if (*ssid == NULL) {
2900                 ERR("strdup is failed\n");
2901                 return TETHERING_ERROR_OUT_OF_MEMORY;
2902         }
2903
2904         return TETHERING_ERROR_NONE;
2905 }
2906
2907 /**
2908  * @internal
2909  * @brief Sets the visibility of SSID(service set identifier).
2910  * @since_tizen 2.3
2911  * @privlevel platform
2912  * @privilege http://tizen.org/privilege/tethering.admin
2913  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
2914  * @remarks This change is applied next time Wi-Fi tethering is enabled
2915  * @param[in]  tethering  The handle of tethering
2916  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
2917  * @return 0 on success, otherwise negative error value.
2918  * @retval  #TETHERING_ERROR_NONE  Successful
2919  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2920  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2921  * @see  tethering_wifi_get_ssid_visibility()
2922  */
2923 API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
2924 {
2925         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2926         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2927
2928         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2929                         "parameter(tethering) is NULL\n");
2930
2931         __tethering_h *th = (__tethering_h *)tethering;
2932         tethering_error_e ret = TETHERING_ERROR_NONE;
2933
2934         ret = __set_visible(visible);
2935         if (ret == TETHERING_ERROR_NONE) {
2936
2937                 __send_dbus_signal(th->client_bus,
2938                                 SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
2939                                 visible ? SIGNAL_MSG_SSID_VISIBLE :
2940                                 SIGNAL_MSG_SSID_HIDE);
2941         }
2942         return ret;
2943 }
2944
2945 /**
2946  * @internal
2947  * @brief Gets the visibility of SSID(service set identifier).
2948  * @since_tizen 2.3
2949  * @privlevel platform
2950  * @privilege http://tizen.org/privilege/tethering.admin
2951  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
2952  * @param[in]  tethering  The handle of tethering
2953  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
2954  * @return 0 on success, otherwise negative error value.
2955  * @retval  #TETHERING_ERROR_NONE  Successful
2956  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2957  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2958  * @see  tethering_wifi_set_ssid_visibility()
2959  */
2960 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
2961 {
2962         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2963         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2964
2965         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2966                         "parameter(visible) is NULL\n");
2967
2968         return __get_visible(visible);
2969 }
2970
2971 /**
2972  * @internal
2973  * @brief Sets the passphrase.
2974  * @since_tizen 2.3
2975  * @privlevel platform
2976  * @privilege http://tizen.org/privilege/tethering.admin
2977  * @remarks This change is applied next time Wi-Fi tethering is enabled
2978  * @param[in]  tethering  The handle of tethering
2979  * @param[in]  passphrase  The passphrase
2980  * @return 0 on success, otherwise negative error value.
2981  * @retval  #TETHERING_ERROR_NONE  Successful
2982  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2983  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2984  * @see  tethering_wifi_get_passphrase()
2985  */
2986 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
2987 {
2988         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
2989         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
2990
2991         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2992                         "parameter(tethering) is NULL\n");
2993         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2994                         "parameter(passphrase) is NULL\n");
2995
2996         __tethering_h *th = (__tethering_h *)tethering;
2997         GDBusProxy *proxy = th->client_bus_proxy;
2998         GVariant *parameters;
2999         GError *error = NULL;
3000         int passphrase_len = 0;
3001         int ret = 0;
3002
3003         DBG("+");
3004         passphrase_len = strlen(passphrase);
3005         if (passphrase_len < TETHERING_WIFI_KEY_MIN_LEN ||
3006                         passphrase_len > TETHERING_WIFI_KEY_MAX_LEN) {
3007                 ERR("parameter(passphrase) is too short or long\n");
3008                 return TETHERING_ERROR_INVALID_PARAMETER;
3009         }
3010
3011         parameters = g_dbus_proxy_call_sync(proxy, "set_wifi_tethering_passphrase",
3012                         g_variant_new("(s)", passphrase), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3013
3014         if (error) {
3015                 //LCOV_EXCL_START
3016                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3017
3018                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3019                         ret = TETHERING_ERROR_PERMISSION_DENIED;
3020                 else
3021                         ret = TETHERING_ERROR_OPERATION_FAILED;
3022
3023                 g_error_free(error);
3024                 return ret;
3025                 //LCOV_EXCL_STOP
3026         }
3027
3028         g_variant_get(parameters, "(u)", &ret);
3029         g_variant_unref(parameters);
3030
3031         if (ret == TETHERING_ERROR_NONE) {
3032                 __send_dbus_signal(th->client_bus,
3033                                 SIGNAL_NAME_PASSPHRASE_CHANGED, NULL);
3034         }
3035
3036         DBG("-");
3037         return ret;
3038 }
3039
3040 /**
3041  * @internal
3042  * @brief Gets the passphrase.
3043  * @since_tizen 2.3
3044  * @privlevel platform
3045  * @privilege http://tizen.org/privilege/tethering.admin
3046  * @remarks @a passphrase must be released with free() by you.
3047  * @param[in]  tethering  The handle of tethering
3048  * @param[out]  passphrase  The passphrase
3049  * @return 0 on success, otherwise negative error value.
3050  * @retval  #TETHERING_ERROR_NONE  Successful
3051  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3052  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
3053  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3054  * @see  tethering_wifi_set_passphrase()
3055  */
3056 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
3057 {
3058         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3059         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3060
3061         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3062                         "parameter(tethering) is NULL\n");
3063         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3064                         "parameter(passphrase) is NULL\n");
3065
3066         __tethering_h *th = (__tethering_h *)tethering;
3067         GDBusProxy *proxy = th->client_bus_proxy;
3068         GVariant *parameters;
3069         GError *error = NULL;
3070         unsigned int len = 0;
3071         tethering_error_e ret = TETHERING_ERROR_NONE;
3072
3073         parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_passphrase",
3074                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3075
3076         if (error) {
3077                 //LCOV_EXCL_START
3078                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3079
3080                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3081                         ret = TETHERING_ERROR_PERMISSION_DENIED;
3082                 else
3083                         ret = TETHERING_ERROR_OPERATION_FAILED;
3084
3085                 g_error_free(error);
3086                 return ret;
3087                 //LCOV_EXCL_STOP
3088         }
3089
3090         if (parameters != NULL) {
3091                 g_variant_get(parameters, "(siu)", passphrase, &len, &ret);
3092                 g_variant_unref(parameters);
3093         }
3094
3095         return TETHERING_ERROR_NONE;
3096 }
3097
3098 API int tethering_wifi_set_channel(tethering_h tethering, int channel)
3099 {
3100         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3101         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3102
3103         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3104                         "parameter(tethering) is NULL\n");
3105
3106         __tethering_h *th = (__tethering_h *)tethering;
3107         th->channel = channel;
3108
3109         return TETHERING_ERROR_NONE;
3110 }
3111
3112 API int tethering_wifi_get_channel(tethering_h tethering, int *channel)
3113 {
3114         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3115         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3116
3117         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3118                         "parameter(tethering) is NULL\n");
3119
3120         _retvm_if(channel == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3121                         "parameter(channel) is NULL\n");
3122
3123         __tethering_h *th = (__tethering_h *)tethering;
3124         *channel = th->channel;
3125
3126         return TETHERING_ERROR_NONE;
3127 }
3128
3129 API int tethering_wifi_set_mode(tethering_h tethering, tethering_wifi_mode_type_e type)
3130 {
3131         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3132         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3133
3134         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3135                         "parameter(tethering) is NULL\n");
3136
3137         __tethering_h *th = (__tethering_h *)tethering;
3138
3139         th->mode_type = type;
3140
3141         return TETHERING_ERROR_NONE;
3142 }
3143
3144 API int tethering_wifi_get_mode(tethering_h tethering, tethering_wifi_mode_type_e *type)
3145 {
3146         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3147         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3148
3149         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3150                         "parameter(tethering) is NULL\n");
3151         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3152                         "parameter(type) is NULL\n");
3153
3154         __tethering_h *th = (__tethering_h *)tethering;
3155         *type = th->mode_type;
3156
3157         return TETHERING_ERROR_NONE;
3158 }
3159
3160
3161 /**
3162  * @internal
3163  * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility).
3164  * @since_tizen 2.3
3165  * @privlevel platform
3166  * @privilege http://tizen.org/privilege/tethering.admin
3167  * @remarks Connected devices via Wi-Fi tethering or MobileAP will be disconnected when the settings are reloaded
3168  * @param[in]  tethering  The handle of tethering
3169  * @param[in]  callback  The callback function to invoke
3170  * @param[in]  user_data  The user data to be passed to the callback function
3171  * @return 0 on success, otherwise negative error value.
3172  * @retval  #TETHERING_ERROR_NONE  Successful
3173  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
3174  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
3175  */
3176 API int tethering_wifi_reload_settings(tethering_h tethering, tethering_wifi_settings_reloaded_cb callback, void *user_data)
3177
3178 {
3179         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3180         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3181
3182         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3183                         "parameter(tethering) is NULL\n");
3184         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3185                         "parameter(callback) is NULL\n");
3186
3187         __tethering_h *th = (__tethering_h *)tethering;
3188         _softap_settings_t set = {"", "", "", 0, false};
3189         GDBusProxy *proxy = th->client_bus_proxy;
3190         int ret = 0;
3191
3192         DBG("+\n");
3193
3194         if (th->settings_reloaded_cb) {
3195                 ERR("Operation in progress\n");
3196                 return TETHERING_ERROR_OPERATION_FAILED;
3197         }
3198
3199         ret = __prepare_wifi_settings(tethering, &set);
3200         if (ret != TETHERING_ERROR_NONE) {
3201                 ERR("softap settings initialization failed\n");
3202                 return TETHERING_ERROR_OPERATION_FAILED;
3203         }
3204
3205         th->settings_reloaded_cb = callback;
3206         th->settings_reloaded_user_data = user_data;
3207
3208         g_dbus_proxy_call(proxy, "reload_wifi_settings",
3209                         g_variant_new("(sssiiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.max_connected, set.sec_type),
3210                         G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
3211                         (GAsyncReadyCallback) __settings_reloaded_cb, (gpointer)tethering);
3212
3213         return TETHERING_ERROR_NONE;
3214 }
3215
3216 API int tethering_wifi_set_mac_filter(tethering_h tethering, bool mac_filter)
3217 {
3218         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3219         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3220
3221         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3222                         "parameter(tethering) is NULL\n");
3223
3224         __tethering_h *th = (__tethering_h *)tethering;
3225         th->mac_filter = mac_filter;
3226
3227         return TETHERING_ERROR_NONE;
3228 }
3229
3230 API int tethering_wifi_get_mac_filter(tethering_h tethering, bool *mac_filter)
3231 {
3232         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3233         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3234
3235         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3236                         "parameter(mac_filter) is NULL\n");
3237         _retvm_if(mac_filter == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3238                         "parameter(mac_filter) is NULL\n");
3239
3240         __tethering_h *th = (__tethering_h *)tethering;
3241         *mac_filter = th->mac_filter;
3242
3243         return TETHERING_ERROR_NONE;
3244 }
3245
3246 static int __add_mac_to_file(const char *filepath, const char *mac)
3247 {
3248         FILE *fp = NULL;
3249         char line[MAX_BUF_SIZE] = "\0";
3250         bool mac_exist = false;
3251         char *p_mac = NULL;
3252
3253         p_mac = strdup(mac);
3254         if (p_mac == NULL) {
3255                 ERR("strdup failed\n");
3256                 return TETHERING_ERROR_OUT_OF_MEMORY;
3257         }
3258
3259         fp = fopen(filepath, "a+");
3260         if (!fp) {
3261                 ERR("fopen is failed\n");
3262                 return TETHERING_ERROR_OPERATION_FAILED;
3263         }
3264
3265         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3266                 if (strncmp(mac, line, 17) == 0) {
3267                         DBG("MAC %s already exist in the list\n", mac);
3268                         mac_exist = true;
3269                         break;
3270                 }
3271         }
3272
3273         if (!mac_exist) {
3274                 fprintf(fp, "%s\n", mac);
3275
3276                 if ((strcmp(filepath, ALLOWED_LIST) == 0))
3277                         allowed_list = g_slist_append(allowed_list, p_mac);
3278                 else if ((strcmp(filepath, BLOCKED_LIST) == 0))
3279                         blocked_list = g_slist_append(blocked_list, p_mac);
3280         }
3281
3282         fclose(fp);
3283
3284         return TETHERING_ERROR_NONE;
3285 }
3286
3287 static int __remove_mac_from_file(const char *filepath, const char *mac)
3288 {
3289         FILE *fp = NULL;
3290         FILE *fp1 = NULL;
3291         char line[MAX_BUF_SIZE] = "\0";
3292
3293         fp = fopen(filepath, "r");
3294         if (!fp) {
3295                 ERR("fopen is failed\n");
3296                 return TETHERING_ERROR_OPERATION_FAILED;
3297         }
3298
3299         fp1 = fopen(TEMP_LIST, "w+");
3300         if (!fp1) {
3301                 fclose(fp);
3302                 ERR("fopen is failed\n");
3303                 return TETHERING_ERROR_OPERATION_FAILED;
3304         }
3305
3306         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3307                 if (strncmp(mac, line, 17) == 0) {
3308                         DBG("MAC %s found in the list\n", mac);
3309
3310                         if ((strcmp(filepath, ALLOWED_LIST) == 0)) {
3311                                 GSList *list = NULL;
3312                                 for (list = allowed_list; list != NULL; list = list->next) {
3313                                         char *p_mac = (char *)list->data;
3314                                         if (strncmp(mac, p_mac, strlen(mac)) == 0)
3315                                                 allowed_list = g_slist_remove(allowed_list, p_mac);
3316                                 }
3317                         } else if ((strcmp(filepath, BLOCKED_LIST) == 0)) {
3318                                 GSList *list = NULL;
3319                                 for (list = blocked_list; list != NULL; list = list->next) {
3320                                         char *p_mac = (char *)list->data;
3321                                         if (strncmp(mac, p_mac, strlen(mac)) == 0)
3322                                                 blocked_list = g_slist_remove(blocked_list, p_mac);
3323                                 }
3324                         }
3325                 } else {
3326                         fprintf(fp1, "%s", line);
3327                 }
3328         }
3329
3330         fclose(fp);
3331         fclose(fp1);
3332
3333         if ((strcmp(filepath, ALLOWED_LIST) == 0))
3334                 rename(TEMP_LIST, ALLOWED_LIST);
3335         else if ((strcmp(filepath, BLOCKED_LIST) == 0))
3336                 rename(TEMP_LIST, BLOCKED_LIST);
3337
3338         return TETHERING_ERROR_NONE;
3339 }
3340
3341 API int tethering_wifi_add_allowed_mac_list(tethering_h tethering, const char *mac)
3342 {
3343         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3344         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3345
3346         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3347                         "parameter(tethering) is NULL\n");
3348         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3349                         "parameter(mac) is NULL\n");
3350
3351         return __add_mac_to_file(ALLOWED_LIST, mac);
3352 }
3353
3354 API int tethering_wifi_remove_allowed_mac_list(tethering_h tethering, const char *mac)
3355 {
3356         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3357         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3358
3359         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3360                         "parameter(tethering) is NULL\n");
3361         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3362                         "parameter(mac) is NULL\n");
3363
3364         return __remove_mac_from_file(ALLOWED_LIST, mac);
3365 }
3366
3367 API int tethering_wifi_get_allowed_mac_list(tethering_h tethering, void **allowed_mac_list)
3368 {
3369         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3370         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3371
3372         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3373                         "parameter(tethering) is NULL\n");
3374         _retvm_if(allowed_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3375                         "parameter(allowed_mac_list) is NULL\n");
3376
3377         *allowed_mac_list = g_slist_copy(allowed_list);
3378         return TETHERING_ERROR_NONE;
3379 }
3380
3381 API int tethering_wifi_add_blocked_mac_list(tethering_h tethering, const char *mac)
3382 {
3383         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3384         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3385
3386         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3387                         "parameter(tethering) is NULL\n");
3388         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3389                         "parameter(mac) is NULL\n");
3390
3391         return __add_mac_to_file(BLOCKED_LIST, mac);
3392 }
3393
3394 API int tethering_wifi_remove_blocked_mac_list(tethering_h tethering, const char *mac)
3395 {
3396         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3397         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3398
3399         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3400                         "parameter(tethering) is NULL\n");
3401         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3402                         "parameter(mac) is NULL\n");
3403
3404         return __remove_mac_from_file(BLOCKED_LIST, mac);
3405 }
3406
3407 API int tethering_wifi_get_blocked_mac_list(tethering_h tethering, void **blocked_mac_list)
3408 {
3409         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3410         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3411
3412         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3413                         "parameter(tethering) is NULL\n");
3414         _retvm_if(blocked_mac_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3415                         "parameter(blocked_mac_list) is NULL\n");
3416
3417         *blocked_mac_list = g_slist_copy(blocked_list);
3418         return TETHERING_ERROR_NONE;
3419 }
3420
3421 API int tethering_wifi_enable_dhcp(tethering_h tethering, bool enable)
3422 {
3423         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3424         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3425
3426         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3427                         "parameter(tethering) is NULL\n");
3428
3429         GVariant *parameters;
3430         GError *error = NULL;
3431         guint result;
3432
3433         __tethering_h *th = (__tethering_h *)tethering;
3434
3435         GDBusProxy *proxy = th->client_bus_proxy;
3436
3437         parameters = g_dbus_proxy_call_sync(proxy, "enable_dhcp",
3438                         g_variant_new("(b)", enable),
3439                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3440
3441         if (error) {
3442                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3443                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3444                         result = TETHERING_ERROR_PERMISSION_DENIED;
3445                 else
3446                         result = TETHERING_ERROR_OPERATION_FAILED;
3447
3448                 g_error_free(error);
3449                 th->dhcp_enabled = false;
3450
3451                 return result;
3452         }
3453
3454         g_variant_get(parameters, "(u)", &result);
3455         g_variant_unref(parameters);
3456
3457         if (enable)
3458                 th->dhcp_enabled = true;
3459         else
3460                 th->dhcp_enabled = false;
3461
3462         return TETHERING_ERROR_NONE;
3463 }
3464
3465 API int tethering_wifi_set_dhcp_range(tethering_h tethering, char *rangestart, char *rangestop)
3466 {
3467         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3468         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3469
3470         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3471                         "parameter(tethering) is NULL\n");
3472         _retvm_if(rangestart == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3473                         "parameter(rangestart) is NULL\n");
3474         _retvm_if(rangestop == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3475                         "parameter(rangestop) is NULL\n");
3476
3477         GVariant *parameters;
3478         GError *error = NULL;
3479         guint result;
3480
3481         __tethering_h *th = (__tethering_h *)tethering;
3482
3483         GDBusProxy *proxy = th->client_bus_proxy;
3484
3485         parameters = g_dbus_proxy_call_sync(proxy, "dhcp_range",
3486                         g_variant_new("(ss)", rangestart, rangestop),
3487                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3488         if (error) {
3489                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3490
3491                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3492                         result = TETHERING_ERROR_PERMISSION_DENIED;
3493                 else
3494                         result = TETHERING_ERROR_OPERATION_FAILED;
3495
3496                 g_error_free(error);
3497                 th->dhcp_enabled = false;
3498
3499                 return result;
3500         }
3501
3502         g_variant_get(parameters, "(u)", &result);
3503         g_variant_unref(parameters);
3504
3505         th->dhcp_enabled = true;
3506
3507         return TETHERING_ERROR_NONE;
3508 }
3509
3510 API int tethering_wifi_is_dhcp_enabled(tethering_h tethering, bool *dhcp_enabled)
3511 {
3512         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3513         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3514
3515         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3516                         "parameter(tethering) is NULL\n");
3517         _retvm_if(dhcp_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3518                         "parameter(dhcp_enabled) is NULL\n");
3519
3520         __tethering_h *th = (__tethering_h *)tethering;
3521         *dhcp_enabled = th->dhcp_enabled;
3522
3523         return TETHERING_ERROR_NONE;
3524 }
3525
3526 API int tethering_wifi_set_txpower(tethering_h tethering, unsigned int txpower)
3527 {
3528         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3529         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3530
3531         GError *error = NULL;
3532
3533         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3534                         "parameter(tethering) is NULL\n");
3535         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false,
3536                         TETHERING_ERROR_NOT_ENABLED,
3537                         "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI);
3538         __tethering_h *th = (__tethering_h *)tethering;
3539
3540         g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_set_txpower",
3541                         g_variant_new("(u)", txpower),
3542                         G_DBUS_CALL_FLAGS_NONE,
3543                         -1, th->cancellable, &error);
3544         if (error) {
3545                 ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
3546                 g_clear_error(&error);
3547                 return TETHERING_ERROR_OPERATION_FAILED;
3548         }
3549         return TETHERING_ERROR_NONE;
3550 }
3551
3552 API int tethering_wifi_get_txpower(tethering_h tethering, unsigned int *txpower)
3553 {
3554         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3555         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3556
3557         GError *error = NULL;
3558         GVariant *result = NULL;
3559
3560         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3561                         "parameter(tethering) is NULL\n");
3562         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == false,
3563                         TETHERING_ERROR_NOT_ENABLED,
3564                         "tethering type[%d] is not enabled\n", TETHERING_TYPE_WIFI);
3565
3566         __tethering_h *th = (__tethering_h *)tethering;
3567
3568         result = g_dbus_proxy_call_sync(th->client_bus_proxy, "hostapd_get_txpower",
3569                         NULL,
3570                         G_DBUS_CALL_FLAGS_NONE,
3571                         -1, th->cancellable, &error);
3572
3573         if (result != NULL) {
3574                 g_variant_get(result, "(u)", txpower);
3575                 g_variant_unref(result);
3576         } else {
3577                 if (error)
3578                         ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
3579                 g_clear_error(&error);
3580                 return TETHERING_ERROR_OPERATION_FAILED;
3581         }
3582         g_clear_error(&error);
3583         return TETHERING_ERROR_NONE;
3584 }
3585
3586 API int tethering_wifi_set_mtu(tethering_h tethering, unsigned int mtu)
3587 {
3588         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3589         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3590
3591         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3592                         "parameter(tethering) is NULL\n");
3593
3594         GVariant *parameters;
3595         GError *error = NULL;
3596         guint result;
3597
3598         __tethering_h *th = (__tethering_h *)tethering;
3599
3600         GDBusProxy *proxy = th->client_bus_proxy;
3601
3602         parameters = g_dbus_proxy_call_sync(proxy, "set_mtu",
3603                         g_variant_new("(u)", mtu),
3604                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3605         if (error) {
3606                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3607
3608                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3609                         result = TETHERING_ERROR_PERMISSION_DENIED;
3610                 else
3611                         result = TETHERING_ERROR_OPERATION_FAILED;
3612
3613                 g_error_free(error);
3614                 return result;
3615         }
3616
3617         g_variant_get(parameters, "(u)", &result);
3618
3619         g_variant_unref(parameters);
3620
3621         return TETHERING_ERROR_NONE;
3622 }
3623
3624 API int tethering_wifi_change_mac(tethering_h tethering, char *mac)
3625 {
3626         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3627         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3628
3629         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3630                         "parameter(tethering) is NULL\n");
3631         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3632                         "parameter(mac) is NULL\n");
3633
3634         GVariant *parameters;
3635         GError *error = NULL;
3636         guint result;
3637
3638         __tethering_h *th = (__tethering_h *)tethering;
3639
3640         GDBusProxy *proxy = th->client_bus_proxy;
3641
3642         parameters = g_dbus_proxy_call_sync(proxy, "change_mac",
3643                         g_variant_new("(s)", mac),
3644                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3645         if (error) {
3646                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3647
3648                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3649                         result = TETHERING_ERROR_PERMISSION_DENIED;
3650                 else
3651                         result = TETHERING_ERROR_OPERATION_FAILED;
3652
3653                 g_error_free(error);
3654                 return result;
3655         }
3656
3657         g_variant_get(parameters, "(u)", &result);
3658         g_variant_unref(parameters);
3659
3660         if (result == MOBILE_AP_ERROR_NOT_PERMITTED)
3661                 return TETHERING_ERROR_NOT_SUPPORT_API;
3662
3663         return TETHERING_ERROR_NONE;
3664 }
3665
3666 API int tethering_wifi_set_max_connected_device(tethering_h tethering, int max_device)
3667 {
3668         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3669         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3670
3671         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3672                         "parameter(tethering) is NULL\n");
3673
3674         __tethering_h *th = (__tethering_h *)tethering;
3675
3676         th->wifi_max_connected = max_device;
3677
3678         return TETHERING_ERROR_NONE;
3679 }
3680
3681 API int tethering_wifi_get_max_connected_device(tethering_h tethering, int *max_device)
3682 {
3683         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3684         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3685
3686         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3687                         "parameter(tethering) is NULL\n");
3688         _retvm_if(max_device == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3689                         "parameter(max_device) is NULL\n");
3690
3691         __tethering_h *th = (__tethering_h *)tethering;
3692
3693         *max_device = th->wifi_max_connected;
3694         return TETHERING_ERROR_NONE;
3695 }
3696
3697 API int tethering_wifi_enable_port_forwarding(tethering_h tethering, bool enable)
3698 {
3699         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3700         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3701
3702         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3703                         "parameter(tethering) is NULL\n");
3704
3705         GVariant *parameters;
3706         GError *error = NULL;
3707         guint result;
3708
3709         __tethering_h *th = (__tethering_h *)tethering;
3710
3711         GDBusProxy *proxy = th->client_bus_proxy;
3712
3713         parameters = g_dbus_proxy_call_sync(proxy, "enable_port_forwarding",
3714                         g_variant_new("(b)", enable),
3715                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3716         if (error) {
3717                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3718
3719                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3720                         result = TETHERING_ERROR_PERMISSION_DENIED;
3721                 else
3722                         result = TETHERING_ERROR_OPERATION_FAILED;
3723
3724                 g_error_free(error);
3725                 return result;
3726         }
3727
3728         g_variant_get(parameters, "(u)", &result);
3729         g_variant_unref(parameters);
3730
3731         th->port_forwarding = true;
3732
3733         return TETHERING_ERROR_NONE;
3734 }
3735
3736 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)
3737 {
3738         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3739         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3740
3741         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3742                         "parameter(tethering) is NULL\n");
3743         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3744                         "parameter(protocol) is NULL\n");
3745
3746         GVariant *parameters;
3747         GError *error = NULL;
3748         guint result;
3749         char cmd[MAX_BUF_SIZE] = { 0, };
3750         char *list = NULL;
3751
3752         __tethering_h *th = (__tethering_h *)tethering;
3753
3754         GDBusProxy *proxy = th->client_bus_proxy;
3755
3756         parameters = g_dbus_proxy_call_sync(proxy, "add_port_forwarding_rule",
3757                         g_variant_new("(sssisi)", ifname, protocol, org_ip, org_port, final_ip, final_port),
3758                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3759         if (error) {
3760                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3761
3762                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3763                         result = TETHERING_ERROR_PERMISSION_DENIED;
3764                 else
3765                         result = TETHERING_ERROR_OPERATION_FAILED;
3766
3767                 g_error_free(error);
3768                 return result;
3769         }
3770
3771         g_variant_get(parameters, "(u)", &result);
3772         g_variant_unref(parameters);
3773
3774         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);
3775
3776         list = strdup(cmd);
3777         if (list == NULL) {
3778                 ERR("strdup failed\n");
3779                 return TETHERING_ERROR_OUT_OF_MEMORY;
3780         }
3781
3782         port_forwarding = g_slist_append(port_forwarding, list);
3783
3784         return TETHERING_ERROR_NONE;
3785 }
3786
3787 API int tethering_wifi_reset_port_forwarding_rule(tethering_h tethering)
3788 {
3789         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3790         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3791
3792         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3793                         "parameter(tethering) is NULL\n");
3794
3795         GVariant *parameters;
3796         GError *error = NULL;
3797         guint result;
3798
3799         __tethering_h *th = (__tethering_h *)tethering;
3800
3801         GDBusProxy *proxy = th->client_bus_proxy;
3802
3803         parameters = g_dbus_proxy_call_sync(proxy, "reset_port_forwarding_rule",
3804                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3805         if (error) {
3806                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3807
3808                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3809                         result = TETHERING_ERROR_PERMISSION_DENIED;
3810                 else
3811                         result = TETHERING_ERROR_OPERATION_FAILED;
3812
3813                 g_error_free(error);
3814                 return result;
3815         }
3816
3817         g_variant_get(parameters, "(u)", &result);
3818
3819         g_variant_unref(parameters);
3820
3821         return TETHERING_ERROR_NONE;
3822 }
3823
3824 API int tethering_wifi_is_port_forwarding_enabled(tethering_h tethering, bool* forwarding_enabled)
3825 {
3826         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3827         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3828
3829         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3830                         "parameter(tethering) is NULL\n");
3831         _retvm_if(forwarding_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3832                         "parameter(forwarding_enabled) is NULL\n");
3833
3834         __tethering_h *th = (__tethering_h *)tethering;
3835
3836         *forwarding_enabled = th->port_forwarding;
3837
3838         return TETHERING_ERROR_NONE;
3839 }
3840
3841 API int tethering_wifi_get_port_forwarding_rule(tethering_h tethering, void **port_forwarding_list)
3842 {
3843         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3844         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3845
3846         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3847                         "parameter(tethering) is NULL\n");
3848         _retvm_if(port_forwarding_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3849                         "parameter(port_forwarding_list) is NULL\n");
3850
3851         *port_forwarding_list = g_slist_copy(port_forwarding);
3852         return TETHERING_ERROR_NONE;
3853 }
3854
3855 API int tethering_wifi_enable_port_filtering(tethering_h tethering, bool enable)
3856 {
3857         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3858         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3859
3860         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3861                         "parameter(tethering) is NULL\n");
3862
3863         GVariant *parameters;
3864         GError *error = NULL;
3865         guint result;
3866
3867         __tethering_h *th = (__tethering_h *)tethering;
3868
3869         GDBusProxy *proxy = th->client_bus_proxy;
3870
3871         parameters = g_dbus_proxy_call_sync(proxy, "enable_port_filtering",
3872                         g_variant_new("(b)", enable),
3873                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3874         if (error) {
3875                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3876
3877                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3878                         result = TETHERING_ERROR_PERMISSION_DENIED;
3879                 else
3880                         result = TETHERING_ERROR_OPERATION_FAILED;
3881
3882                 g_error_free(error);
3883                 return result;
3884         }
3885
3886         g_variant_get(parameters, "(u)", &result);
3887         g_variant_unref(parameters);
3888
3889         th->port_filtering = true;
3890
3891         return TETHERING_ERROR_NONE;
3892 }
3893
3894 API int tethering_wifi_add_port_filtering_rule(tethering_h tethering, int port, char *protocol, bool allow)
3895 {
3896         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3897         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3898
3899         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3900                         "parameter(tethering) is NULL\n");
3901         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3902                         "parameter(protocol) is NULL\n");
3903
3904         GVariant *parameters;
3905         GError *error = NULL;
3906         guint result;
3907         char cmd[MAX_BUF_SIZE] = { 0, };
3908         char *list = NULL;
3909
3910         __tethering_h *th = (__tethering_h *)tethering;
3911
3912         GDBusProxy *proxy = th->client_bus_proxy;
3913
3914         parameters = g_dbus_proxy_call_sync(proxy, "add_port_filtering_rule",
3915                         g_variant_new("(isb)", port, protocol, allow),
3916                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3917         if (error) {
3918                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3919
3920                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3921                         result = TETHERING_ERROR_PERMISSION_DENIED;
3922                 else
3923                         result = TETHERING_ERROR_OPERATION_FAILED;
3924
3925                 g_error_free(error);
3926                 return result;
3927         }
3928
3929         g_variant_get(parameters, "(u)", &result);
3930         g_variant_unref(parameters);
3931
3932         if (allow)
3933                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_ACCEPT);
3934         else
3935                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port, ACTION_DROP);
3936
3937         DBG("cmd:%s", cmd);
3938
3939         list = strdup(cmd);
3940         if (list == NULL) {
3941                 ERR("strdup failed\n");
3942                 return TETHERING_ERROR_OUT_OF_MEMORY;
3943         }
3944
3945         port_filtering = g_slist_append(port_filtering, list);
3946
3947         return TETHERING_ERROR_NONE;
3948 }
3949
3950 API int tethering_wifi_add_custom_port_filtering_rule(tethering_h tethering, int port1, int port2, char *protocol, bool allow)
3951 {
3952         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
3953         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
3954
3955         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3956                         "parameter(tethering) is NULL\n");
3957         _retvm_if(protocol == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3958                         "parameter(protocol) is NULL\n");
3959
3960         GVariant *parameters;
3961         GError *error = NULL;
3962         guint result;
3963         char cmd[MAX_BUF_SIZE] = { 0, };
3964         char *list = NULL;
3965
3966         __tethering_h *th = (__tethering_h *)tethering;
3967
3968         GDBusProxy *proxy = th->client_bus_proxy;
3969
3970         parameters = g_dbus_proxy_call_sync(proxy, "add_custom_port_filtering_rule",
3971                         g_variant_new("(iisb)", port1, port2, protocol, allow),
3972                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3973         if (error) {
3974                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3975
3976                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3977                         result = TETHERING_ERROR_PERMISSION_DENIED;
3978                 else
3979                         result = TETHERING_ERROR_OPERATION_FAILED;
3980
3981                 g_error_free(error);
3982                 return result;
3983         }
3984
3985         g_variant_get(parameters, "(u)", &result);
3986         g_variant_unref(parameters);
3987
3988         if (allow)
3989                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_ACCEPT);
3990         else
3991                 snprintf(cmd, sizeof(cmd), "%s "FILTERING_MULTIPORT_RULE_STR, IPTABLES, TABLE_FILTER, TETH_FILTER_FW, protocol, port1, port2, ACTION_DROP);
3992
3993         DBG("cmd:%s", cmd);
3994
3995         list = strdup(cmd);
3996         if (list == NULL) {
3997                 ERR("strdup failed\n");
3998                 return TETHERING_ERROR_OUT_OF_MEMORY;
3999         }
4000
4001         custom_port_filtering = g_slist_append(custom_port_filtering, list);
4002
4003         return TETHERING_ERROR_NONE;
4004 }
4005
4006 API int tethering_wifi_get_port_filtering_rule(tethering_h tethering, void **port_filtering_list)
4007 {
4008         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4009         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4010
4011         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4012                         "parameter(tethering) is NULL\n");
4013         _retvm_if(port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4014                         "parameter(port_filtering_list) is NULL\n");
4015
4016         *port_filtering_list = g_slist_copy(port_filtering);
4017         return TETHERING_ERROR_NONE;
4018 }
4019
4020 API int tethering_wifi_get_custom_port_filtering_rule(tethering_h tethering, void **custom_port_filtering_list)
4021 {
4022         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4023         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4024
4025         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4026                         "parameter(tethering) is NULL\n");
4027         _retvm_if(custom_port_filtering_list == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4028                         "parameter(custom_port_filtering_list) is NULL\n");
4029
4030         *custom_port_filtering_list = g_slist_copy(custom_port_filtering);
4031         return TETHERING_ERROR_NONE;
4032 }
4033
4034 API int tethering_wifi_is_port_filtering_enabled(tethering_h tethering, bool* filtering_enabled)
4035 {
4036         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4037         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4038
4039         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4040                         "parameter(tethering) is NULL\n");
4041         _retvm_if(filtering_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4042                         "parameter(filtering_enabled) is NULL\n");
4043
4044         __tethering_h *th = (__tethering_h *)tethering;
4045
4046         *filtering_enabled = th->port_filtering;
4047
4048         return TETHERING_ERROR_NONE;
4049 }
4050
4051 API int tethering_wifi_set_vpn_passthrough_rule(tethering_h tethering, tethering_vpn_passthrough_type_e type, bool enable)
4052 {
4053         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4054         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4055
4056         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4057                         "parameter(tethering) is NULL\n");
4058
4059         GVariant *parameters;
4060         GError *error = NULL;
4061         guint result;
4062
4063         __tethering_h *th = (__tethering_h *)tethering;
4064
4065         GDBusProxy *proxy = th->client_bus_proxy;
4066
4067         parameters = g_dbus_proxy_call_sync(proxy, "set_vpn_passthrough_rule",
4068                         g_variant_new("(ib)", type, enable),
4069                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4070         if (error) {
4071                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4072
4073                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4074                         result = TETHERING_ERROR_PERMISSION_DENIED;
4075                 else
4076                         result = TETHERING_ERROR_OPERATION_FAILED;
4077
4078                 g_error_free(error);
4079                 return result;
4080         }
4081
4082         g_variant_get(parameters, "(u)", &result);
4083
4084         g_variant_unref(parameters);
4085
4086         return TETHERING_ERROR_NONE;
4087 }
4088
4089 API int tethering_wifi_push_wps_button(tethering_h tethering)
4090 {
4091         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4092         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4093
4094         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4095                         "parameter(tethering) is NULL");
4096         __tethering_h *th = (__tethering_h *)tethering;
4097         GDBusProxy *proxy = th->client_bus_proxy;
4098         GVariant *parameters = NULL;
4099         int ret = 0;
4100         GError *error = NULL;
4101
4102         parameters = g_dbus_proxy_call_sync(proxy, "push_wps_button",
4103                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4104
4105         if (error) {
4106                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4107
4108                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4109                         ret = TETHERING_ERROR_PERMISSION_DENIED;
4110                 else
4111                         ret = TETHERING_ERROR_OPERATION_FAILED;
4112
4113                 g_error_free(error);
4114                 return ret;
4115         }
4116
4117         if (parameters != NULL) {
4118                 g_variant_get(parameters, "(u)", &ret);
4119                 g_variant_unref(parameters);
4120         }
4121
4122         return TETHERING_ERROR_NONE;
4123 }
4124
4125 API int tethering_wifi_set_wps_pin(tethering_h tethering, const char *wps_pin)
4126 {
4127         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
4128         CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
4129
4130         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
4131                         "parameter(tethering) is NULL");
4132         __tethering_h *th = (__tethering_h *)tethering;
4133         GDBusProxy *proxy = th->client_bus_proxy;
4134         GVariant *parameters = NULL;
4135         int ret = 0;
4136         GError *error = NULL;
4137
4138         parameters = g_dbus_proxy_call_sync(proxy, "set_wps_pin",
4139                         g_variant_new("(s)", wps_pin), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
4140
4141         if (error) {
4142                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
4143
4144                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
4145                         ret = TETHERING_ERROR_PERMISSION_DENIED;
4146                 else
4147                         ret = TETHERING_ERROR_OPERATION_FAILED;
4148
4149                 g_error_free(error);
4150                 return ret;
4151         }
4152
4153         if (parameters != NULL) {
4154                 g_variant_get(parameters, "(u)", &ret);
4155                 g_variant_unref(parameters);
4156         }
4157
4158         return TETHERING_ERROR_NONE;
4159 }
4160
4161