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