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