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