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