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