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