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