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