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