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