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