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