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