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