Add lcov comments for line coverage
[platform/core/api/tethering.git] / src / tethering.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #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 "tethering_private.h"
33
34 #define ALLOWED_LIST    "/etc/hostapd.accept"
35 #define BLOCKED_LIST    "/etc/hostapd.deny"
36 #define TEMP_LIST       "/etc/hostapd_tmp"
37 #define MAC_ADDR_LEN    18
38 #define MAX_BUF_SIZE    80
39
40 static void __handle_wifi_tether_on(GDBusConnection *connection, const gchar *sender_name,
41                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
42                         GVariant *parameters, gpointer user_data);
43
44 static void __handle_wifi_tether_off(GDBusConnection *connection, const gchar *sender_name,
45                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
46                 GVariant *parameters, gpointer user_data);
47
48 static void __handle_usb_tether_on(GDBusConnection *connection, const gchar *sender_name,
49                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
50                 GVariant *parameters, gpointer user_data);
51
52 static void __handle_usb_tether_off(GDBusConnection *connection, const gchar *sender_name,
53                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
54                 GVariant *parameters, gpointer user_data);
55
56 static void __handle_bt_tether_on(GDBusConnection *connection, const gchar *sender_name,
57                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
58                 GVariant *parameters, gpointer user_data);
59
60 static void __handle_bt_tether_off(GDBusConnection *connection, const gchar *sender_name,
61                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
62                 GVariant *parameters, gpointer user_data);
63
64 static void __handle_net_closed(GDBusConnection *connection, const gchar *sender_name,
65                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
66                 GVariant *parameters, gpointer user_data);
67
68 static void __handle_no_data_timeout(GDBusConnection *connection, const gchar *sender_name,
69                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
70                 GVariant *parameters, gpointer user_data);
71
72 static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name,
73                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
74                 GVariant *parameters, gpointer user_data);
75
76 static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name,
77                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
78                 GVariant *parameters, gpointer user_data);
79
80 static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name,
81                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
82                 GVariant *parameters, gpointer user_data);
83
84 static void __handle_ssid_visibility_changed(GDBusConnection *connection, const gchar *sender_name,
85                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
86                 GVariant *parameters, gpointer user_data);
87
88 static void __handle_passphrase_changed(GDBusConnection *connection, const gchar *sender_name,
89                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
90                 GVariant *parameters, gpointer user_data);
91
92 static void __handle_dhcp(GDBusConnection *connection, const gchar *sender_name,
93                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
94                 GVariant *parameters, gpointer user_data);
95
96 static __tethering_sig_t sigs[] = {
97         {0, SIGNAL_NAME_NET_CLOSED, __handle_net_closed},
98         {0, SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on},
99         {0, SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off},
100         {0, SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on},
101         {0, SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off},
102         {0, SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on},
103         {0, SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off},
104         {0, SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout},
105         {0, SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode},
106         {0, SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode},
107         {0, SIGNAL_NAME_SECURITY_TYPE_CHANGED, __handle_security_type_changed},
108         {0, SIGNAL_NAME_SSID_VISIBILITY_CHANGED, __handle_ssid_visibility_changed},
109         {0, SIGNAL_NAME_PASSPHRASE_CHANGED, __handle_passphrase_changed},
110         {0, SIGNAL_NAME_DHCP_STATUS, __handle_dhcp},
111         {0, "", NULL} };
112
113 static int retry = 0;
114
115 static void __send_dbus_signal(GDBusConnection *conn, const char *signal_name, const char *arg)
116 {
117         if (conn == NULL || signal_name == NULL)
118                 return; //LCOV_EXCL_LINE
119
120         GVariant *message = NULL;
121         GError *error = NULL;
122
123         if (arg)
124                 message = g_variant_new("(s)", arg);
125
126         g_dbus_connection_emit_signal(conn, NULL, TETHERING_SERVICE_OBJECT_PATH,
127                                         TETHERING_SERVICE_INTERFACE, signal_name, message, &error);
128         if (error) {
129                 ERR("g_dbus_connection_emit_signal is failed because  %s\n", error->message); //LCOV_EXCL_LINE
130                 g_error_free(error); //LCOV_EXCL_LINE
131         }
132         g_variant_unref(message);
133 }
134
135 static bool __any_tethering_is_enabled(tethering_h tethering)
136 {
137         if (tethering_is_enabled(tethering, TETHERING_TYPE_USB) ||
138                         tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) ||
139                         tethering_is_enabled(tethering, TETHERING_TYPE_BT))
140                 return true;
141
142         return false;
143 }
144
145 static tethering_error_e __set_security_type(const tethering_wifi_security_type_e security_type)
146 {
147         if (security_type != TETHERING_WIFI_SECURITY_TYPE_NONE &&
148                         security_type != TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) {
149                 ERR("Invalid param\n");
150                 return TETHERING_ERROR_INVALID_PARAMETER;
151         }
152
153         if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY, security_type) < 0) {
154                 ERR("vconf_set_int is failed\n"); 
155                 return TETHERING_ERROR_OPERATION_FAILED;
156         }
157
158         return TETHERING_ERROR_NONE;
159 }
160
161 static tethering_error_e __get_security_type(tethering_wifi_security_type_e *security_type)
162 {
163         if (security_type == NULL) {
164                 ERR("Invalid param\n");
165                 return TETHERING_ERROR_INVALID_PARAMETER;
166         }
167
168         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_SECURITY,
169                                 (int *)security_type) < 0) {
170                 ERR("vconf_get_int is failed\n");
171                 return TETHERING_ERROR_OPERATION_FAILED;
172         }
173
174         return TETHERING_ERROR_NONE;
175 }
176
177 static bool __get_ssid_from_vconf(const char *path, char *ssid, unsigned int size)
178 {
179         if (path == NULL || ssid == NULL || size == 0)
180                 return false;
181
182         char *ptr = NULL;
183         char *ptr_tmp = NULL;
184
185         ptr = vconf_get_str(path);
186         if (ptr == NULL)
187                 return false;
188
189         if (!g_utf8_validate(ptr, -1, (const char **)&ptr_tmp))
190                 *ptr_tmp = '\0';
191
192         g_strlcpy(ssid, ptr, size);
193         free(ptr);
194
195         return true;
196 }
197
198 static tethering_error_e __set_visible(const bool visible)
199 {
200         if (vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, visible ? 0 : 1) < 0) {
201                 ERR("vconf_set_int is failed\n");
202                 return TETHERING_ERROR_OPERATION_FAILED;
203         }
204
205         return TETHERING_ERROR_NONE;
206 }
207
208 static tethering_error_e __get_visible(bool *visible)
209 {
210         if (visible == NULL) {
211                 ERR("Invalid param\n");
212                 return TETHERING_ERROR_INVALID_PARAMETER;
213         }
214
215         int hide = 0;
216
217         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_HIDE, &hide) < 0) {
218                 ERR("vconf_get_int is failed\n");
219                 return TETHERING_ERROR_OPERATION_FAILED;
220         }
221
222         if (hide)
223                 *visible = false;
224         else
225                 *visible = true;
226         return TETHERING_ERROR_NONE;
227 }
228
229 static unsigned int __generate_initial_passphrase(char *passphrase, unsigned int size)
230 {
231         if (passphrase == NULL ||
232                         size == 0 || size < TETHERING_WIFI_KEY_MIN_LEN + 1)
233                 return 0;
234
235         guint32 rand_int = 0;
236         int index = 0;
237
238         for (index = 0; index < TETHERING_WIFI_KEY_MIN_LEN; index++) {
239                 rand_int = g_random_int_range('a', 'z');
240                 passphrase[index] = rand_int;
241         }
242         passphrase[index] = '\0';
243
244         return index;
245 }
246
247 static tethering_error_e __get_error(int agent_error)
248 {
249         tethering_error_e err = TETHERING_ERROR_NONE;
250
251         switch (agent_error) {
252         case MOBILE_AP_ERROR_NONE:
253                 err = TETHERING_ERROR_NONE;
254                 break;
255
256         //LCOV_EXCL_START
257         case MOBILE_AP_ERROR_RESOURCE:
258                 err = TETHERING_ERROR_OUT_OF_MEMORY;
259                 break;
260         //LCOV_EXCL_STOP
261
262         case MOBILE_AP_ERROR_INTERNAL:
263                 err = TETHERING_ERROR_OPERATION_FAILED;
264                 break;
265
266         case MOBILE_AP_ERROR_INVALID_PARAM:
267                 err = TETHERING_ERROR_INVALID_PARAMETER;
268                 break;
269
270         case MOBILE_AP_ERROR_ALREADY_ENABLED:
271                 err = TETHERING_ERROR_OPERATION_FAILED;
272                 break;
273
274         case MOBILE_AP_ERROR_NOT_ENABLED:
275                 err = TETHERING_ERROR_NOT_ENABLED;
276                 break;
277
278         case MOBILE_AP_ERROR_NET_OPEN:
279                 err = TETHERING_ERROR_OPERATION_FAILED;
280                 break;
281
282         case MOBILE_AP_ERROR_NET_CLOSE:
283                 err = TETHERING_ERROR_OPERATION_FAILED;
284                 break;
285
286         case MOBILE_AP_ERROR_DHCP:
287                 err = TETHERING_ERROR_OPERATION_FAILED;
288                 break;
289
290         case MOBILE_AP_ERROR_IN_PROGRESS:
291                 err = TETHERING_ERROR_OPERATION_FAILED;
292                 break;
293
294         //LCOV_EXCL_START
295         case MOBILE_AP_ERROR_NOT_PERMITTED:
296                 err = TETHERING_ERROR_NOT_PERMITTED;
297                 break;
298
299         case MOBILE_AP_ERROR_PERMISSION_DENIED:
300                 err = TETHERING_ERROR_PERMISSION_DENIED;
301                 break;
302         //LCOV_EXCL_STOP
303         default:
304                 ERR("Not defined error : %d\n", agent_error);
305                 err = TETHERING_ERROR_OPERATION_FAILED;
306                 break;
307         }
308
309         return err;
310 }
311
312 //LCOV_EXCL_START
313 static void __handle_dhcp(GDBusConnection *connection, const gchar *sender_name,
314                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
315                 GVariant *parameters, gpointer user_data)
316 {
317         DBG("+\n");
318
319         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
320
321         __tethering_h *th = (__tethering_h *)user_data;
322         bool opened = false;
323         tethering_type_e type = 0;
324         mobile_ap_type_e ap_type = 0;
325         tethering_connection_state_changed_cb ccb = NULL;
326         __tethering_client_h client;
327         void *data = NULL;
328         char *buf = NULL;
329         char *name = NULL;
330         char *mac = NULL;
331         char *ip = NULL;
332         guint timestamp;
333
334         memset(&client, 0, sizeof(__tethering_client_h));
335         g_variant_get(parameters, "(susssu)", &buf, &ap_type, &ip, &mac, &name, &timestamp);
336
337         if (!g_strcmp0(buf, "DhcpConnected")) {
338                 opened = true;
339         } else if (!g_strcmp0(buf, "DhcpLeaseDeleted")) {
340                 opened = false;
341         } else {
342                 ERR("Unknown event [%s]\n", buf);
343                 goto DONE;
344         }
345
346         if (ap_type == MOBILE_AP_TYPE_USB)
347                 type = TETHERING_TYPE_USB;
348         else if (ap_type == MOBILE_AP_TYPE_WIFI)
349                 type = TETHERING_TYPE_WIFI;
350         else if (ap_type == MOBILE_AP_TYPE_BT)
351                 type = TETHERING_TYPE_BT;
352         else {
353                 ERR("Not supported tethering type [%d]\n", ap_type);
354                 goto DONE;
355         }
356
357         ccb = th->changed_cb[type];
358         if (ccb == NULL)
359                 goto DONE;
360         data = th->changed_user_data[type];
361
362         client.interface = type;
363         g_strlcpy(client.ip, ip, sizeof(client.ip));
364         g_strlcpy(client.mac, mac, sizeof(client.mac));
365         if (name != NULL)
366                 client.hostname = g_strdup(name);
367         client.tm = (time_t)timestamp;
368
369         ccb((tethering_client_h)&client, opened, data);
370         g_free(client.hostname);
371 DONE:
372         g_free(buf);
373         g_free(ip);
374         g_free(mac);
375         g_free(name);
376         DBG("-\n");
377 }
378 //LCOV_EXCL_STOP
379
380 //LCOV_EXCL_START
381 static void __handle_net_closed(GDBusConnection *connection, const gchar *sender_name,
382                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
383                 GVariant *parameters, gpointer user_data)
384 {
385         DBG("+\n");
386
387         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
388
389         __tethering_h *th = (__tethering_h *)user_data;
390         tethering_type_e type = 0;
391         tethering_disabled_cb dcb = NULL;
392         void *data = NULL;
393         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_NETWORK_CLOSE;
394
395         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
396                 dcb = th->disabled_cb[type];
397                 if (dcb == NULL)
398                         continue;
399                 data = th->disabled_user_data[type];
400
401                 dcb(TETHERING_ERROR_NONE, type, code, data);
402         }
403
404         DBG("-\n");
405 }
406 //LCOV_EXCL_STOP
407
408 static void __handle_wifi_tether_on(GDBusConnection *connection, const gchar *sender_name,
409                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
410                         GVariant *parameters, gpointer user_data)
411 {
412         DBG("+\n");
413
414         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
415
416         __tethering_h *th = (__tethering_h *)user_data;
417         tethering_type_e type = TETHERING_TYPE_WIFI;
418         bool is_requested = false;
419         tethering_enabled_cb ecb = NULL;
420         void *data = NULL;
421
422         ecb = th->enabled_cb[type];
423         if (ecb == NULL)
424                 return;
425         data = th->enabled_user_data[type];
426
427         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
428         DBG("-\n");
429 }
430
431 static void __handle_wifi_tether_off(GDBusConnection *connection, const gchar *sender_name,
432                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
433                         GVariant *parameters, gpointer user_data)
434 {
435         DBG("+\n");
436
437         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
438
439         __tethering_h *th = (__tethering_h *)user_data;
440         tethering_type_e type = TETHERING_TYPE_WIFI;
441         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
442         tethering_disabled_cb dcb = NULL;
443         void *data = NULL;
444         char *buf = NULL;
445
446         dcb = th->disabled_cb[type];
447         if (dcb == NULL)
448                 return;
449         data = th->disabled_user_data[type];
450         g_variant_get(parameters, "(s)", &buf);
451         if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
452                 code = TETHERING_DISABLED_BY_WIFI_ON;
453         else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT))
454                 code = TETHERING_DISABLED_BY_TIMEOUT;
455
456         g_free(buf);
457         dcb(TETHERING_ERROR_NONE, type, code, data);
458
459         DBG("-\n");
460 }
461
462 //LCOV_EXCL_START
463 static void __handle_usb_tether_on(GDBusConnection *connection, const gchar *sender_name,
464                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
465                         GVariant *parameters, gpointer user_data)
466 {
467         DBG("+\n");
468
469         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
470
471         __tethering_h *th = (__tethering_h *)user_data;
472         tethering_type_e type = TETHERING_TYPE_USB;
473         bool is_requested = false;
474         tethering_enabled_cb ecb = NULL;
475         void *data = NULL;
476
477         ecb = th->enabled_cb[type];
478         if (ecb == NULL)
479                 return;
480         data = th->enabled_user_data[type];
481
482         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
483         DBG("-\n");
484 }
485
486 static void __handle_usb_tether_off(GDBusConnection *connection, const gchar *sender_name,
487                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
488                         GVariant *parameters, gpointer user_data)
489 {
490         DBG("+\n");
491
492         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
493
494         __tethering_h *th = (__tethering_h *)user_data;
495         tethering_type_e type = TETHERING_TYPE_USB;
496         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
497         tethering_disabled_cb dcb = NULL;
498         void *data = NULL;
499         char *buf = NULL;
500
501         dcb = th->disabled_cb[type];
502         if (dcb == NULL)
503                 return;
504         data = th->disabled_user_data[type];
505
506         g_variant_get(parameters, "(s)", &buf);
507         if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
508                 code = TETHERING_DISABLED_BY_USB_DISCONNECTION;
509
510         dcb(TETHERING_ERROR_NONE, type, code, data);
511         g_free(buf);
512         DBG("-\n");
513 }
514 //LCOV_EXCL_STOP
515
516 static void __handle_bt_tether_on(GDBusConnection *connection, const gchar *sender_name,
517                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
518                         GVariant *parameters, gpointer user_data)
519 {
520         DBG("+\n");
521
522         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
523
524         __tethering_h *th = (__tethering_h *)user_data;
525         tethering_type_e type = TETHERING_TYPE_BT;
526         bool is_requested = false;
527         tethering_enabled_cb ecb = NULL;
528         void *data = NULL;
529
530         ecb = th->enabled_cb[type];
531         if (ecb == NULL)
532                 return;
533         data = th->enabled_user_data[type];
534
535         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
536         DBG("-\n");
537 }
538
539 static void __handle_bt_tether_off(GDBusConnection *connection, const gchar *sender_name,
540                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
541                         GVariant *parameters, gpointer user_data)
542 {
543         DBG("+\n");
544
545         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
546
547         __tethering_h *th = (__tethering_h *)user_data;
548         tethering_type_e type = TETHERING_TYPE_BT;
549         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
550         tethering_disabled_cb dcb = NULL;
551         void *data = NULL;
552         char *buf = NULL;
553
554         dcb = th->disabled_cb[type];
555         if (dcb == NULL)
556                 return;
557         data = th->disabled_user_data[type];
558         g_variant_get(parameters, "(s)", &buf);
559         if (!g_strcmp0(buf, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
560                 code = TETHERING_DISABLED_BY_BT_OFF;
561         else if (!g_strcmp0(buf, SIGNAL_MSG_TIMEOUT))
562                 code = TETHERING_DISABLED_BY_TIMEOUT;
563
564         dcb(TETHERING_ERROR_NONE, type, code, data);
565
566         g_free(buf);
567         DBG("-\n");
568 }
569
570 //LCOV_EXCL_START
571 static void __handle_no_data_timeout(GDBusConnection *connection, const gchar *sender_name,
572                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
573                         GVariant *parameters, gpointer user_data)
574 {
575         DBG("+\n");
576
577         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
578
579         __tethering_h *th = (__tethering_h *)user_data;
580         tethering_type_e type = 0;
581         tethering_disabled_cb dcb = NULL;
582         void *data = NULL;
583         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_TIMEOUT;
584
585         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
586                 dcb = th->disabled_cb[type];
587                 if (dcb == NULL)
588                         continue;
589                 data = th->disabled_user_data[type];
590
591                 dcb(TETHERING_ERROR_NONE, type, code, data);
592         }
593         DBG("-\n");
594 }
595
596 static void __handle_low_battery_mode(GDBusConnection *connection, const gchar *sender_name,
597                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
598                         GVariant *parameters, gpointer user_data)
599 {
600         DBG("+\n");
601
602         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
603
604         __tethering_h *th = (__tethering_h *)user_data;
605         tethering_type_e type = 0;
606         tethering_disabled_cb dcb = NULL;
607         void *data = NULL;
608         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY;
609
610         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
611                 dcb = th->disabled_cb[type];
612                 if (dcb == NULL)
613                         continue;
614                 data = th->disabled_user_data[type];
615
616                 dcb(TETHERING_ERROR_NONE, type, code, data);
617         }
618         DBG("-\n");
619 }
620
621 static void __handle_flight_mode(GDBusConnection *connection, const gchar *sender_name,
622                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
623                         GVariant *parameters, gpointer user_data)
624 {
625         DBG("+\n");
626
627         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
628
629         __tethering_h *th = (__tethering_h *)user_data;
630         tethering_type_e type = 0;
631         tethering_disabled_cb dcb = NULL;
632         void *data = NULL;
633         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE;
634
635         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
636                 dcb = th->disabled_cb[type];
637                 if (dcb == NULL)
638                         continue;
639                 data = th->disabled_user_data[type];
640
641                 dcb(TETHERING_ERROR_NONE, type, code, data);
642         }
643         DBG("-\n");
644 }
645 //LCOV_EXCL_STOP
646
647 static void __handle_security_type_changed(GDBusConnection *connection, const gchar *sender_name,
648                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
649                 GVariant *parameters, gpointer user_data)
650
651 {
652         DBG("+\n");
653
654         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
655         __tethering_h *th = (__tethering_h *)user_data;
656
657         tethering_wifi_security_type_changed_cb scb = NULL;
658         void *data = NULL;
659         tethering_wifi_security_type_e security_type;
660         char *buf = NULL;
661
662         scb = th->security_type_changed_cb;
663         if (scb == NULL)
664                 return;
665
666         g_variant_get(parameters, "(s)", &buf);
667         data = th->security_type_user_data;
668         if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
669                 security_type = TETHERING_WIFI_SECURITY_TYPE_NONE;
670         else if (g_strcmp0(buf, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
671                 security_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
672         else {
673                 SERR("Unknown type : %s\n", buf);
674                 g_free(buf);
675                 return;
676         }
677         g_free(buf);
678         scb(security_type, data);
679
680         return;
681 }
682
683 static void __handle_ssid_visibility_changed(GDBusConnection *connection, const gchar *sender_name,
684                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
685                 GVariant *parameters, gpointer user_data)
686 {
687         DBG("+\n");
688
689         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
690         __tethering_h *th = (__tethering_h *)user_data;
691
692         tethering_wifi_ssid_visibility_changed_cb scb = NULL;
693         void *data = NULL;
694         bool visible = false;
695         char *buf = NULL;
696
697         scb = th->ssid_visibility_changed_cb;
698         if (scb == NULL) {
699                 DBG("-\n");
700                 return;
701         }
702         g_variant_get(parameters, "(s)", &buf);
703         data = th->ssid_visibility_user_data;
704         if (g_strcmp0(buf, SIGNAL_MSG_SSID_VISIBLE) == 0)
705                 visible = true;
706
707         scb(visible, data);
708         g_free(buf);
709         DBG("-\n");
710 }
711
712 static void __handle_passphrase_changed(GDBusConnection *connection, const gchar *sender_name,
713                 const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
714                 GVariant *parameters, gpointer user_data)
715 {
716         DBG("+\n");
717
718         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
719         __tethering_h *th = (__tethering_h *)user_data;
720
721         tethering_wifi_passphrase_changed_cb pcb = NULL;
722         void *data = NULL;
723
724         pcb = th->passphrase_changed_cb;
725         if (pcb == NULL)
726                 return;
727
728         data = th->passphrase_user_data;
729
730         pcb(data);
731         DBG("-\n");
732 }
733
734 static void __wifi_enabled_cfm_cb(GObject *source_object, GAsyncResult *res,
735                 gpointer user_data)
736 {
737         DBG("+\n");
738
739         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
740         GError *g_error = NULL;
741         GVariant *g_var;
742         guint info;
743         tethering_error_e error;
744         __tethering_h *th = (__tethering_h *)user_data;
745         tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_WIFI];
746         void *data = th->enabled_user_data[TETHERING_TYPE_WIFI];
747
748         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
749         if (g_error) {
750                 //LCOV_EXCL_START
751                 ERR("DBus error [%s]\n", g_error->message);
752                 if (g_error->code == G_DBUS_ERROR_NO_REPLY &&
753                                 ++retry < TETHERING_ERROR_RECOVERY_MAX) {
754                         g_error_free(g_error);
755                         tethering_enable((tethering_h)th, TETHERING_TYPE_WIFI);
756                         return;
757                 } else if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
758                         error = TETHERING_ERROR_PERMISSION_DENIED;
759                 else
760                         error = TETHERING_ERROR_OPERATION_FAILED;
761                 g_error_free(g_error);
762                 //LCOV_EXCL_STOP
763         } else {
764                 g_variant_get(g_var, "(u)", &info);
765                 error = __get_error(info);
766         }
767         retry = 0;
768
769         sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
770                         NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_ON].name,
771                         TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
772                         sigs[E_SIGNAL_WIFI_TETHER_ON].cb, (gpointer)th, NULL);
773
774         if (!ecb) {
775                 DBG("-\n");
776                 return;
777         }
778         ecb(error, TETHERING_TYPE_WIFI, true, data);
779         g_variant_unref(g_var);
780         DBG("-\n");
781 }
782
783 static void __bt_enabled_cfm_cb(GObject *source_object, GAsyncResult *res,
784                 gpointer user_data)
785 {
786         DBG("+\n");
787         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
788         GError *g_error = NULL;
789         GVariant *g_var;
790         guint info;
791         tethering_error_e error;
792
793         __tethering_h *th = (__tethering_h *)user_data;
794         tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_BT];
795         void *data = th->enabled_user_data[TETHERING_TYPE_BT];
796
797         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
798         if (g_error) {
799                 //LCOV_EXCL_START
800                 ERR("DBus error [%s]\n", g_error->message);
801                 if (g_error->code == G_DBUS_ERROR_NO_REPLY &&
802                                 ++retry < TETHERING_ERROR_RECOVERY_MAX) {
803                         g_error_free(g_error);
804                         tethering_enable((tethering_h)th, TETHERING_TYPE_BT);
805                         DBG("-\n");
806                         return;
807                 }
808                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
809                         error = TETHERING_ERROR_PERMISSION_DENIED;
810                 else
811                         error = TETHERING_ERROR_OPERATION_FAILED;
812                 g_error_free(g_error);
813                 //LCOV_EXCL_STOP
814         } else {
815                 g_variant_get(g_var, "(u)", &info);
816                 g_variant_unref(g_var);
817                 error = __get_error(info);
818         }
819         retry = 0;
820
821         sigs[E_SIGNAL_BT_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
822                         NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_ON].name,
823                         TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
824                         sigs[E_SIGNAL_BT_TETHER_ON].cb, (gpointer)th, NULL);
825
826         if (!ecb) {
827                 DBG("-\n");
828                 return;
829         }
830
831         ecb(error, TETHERING_TYPE_BT, true, data);
832         DBG("-\n");
833 }
834
835 //LCOV_EXCL_START
836 static void __usb_enabled_cfm_cb(GObject *source_object, GAsyncResult *res,
837                                         gpointer user_data)
838 {
839         DBG("+\n");
840
841         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
842         __tethering_h *th = (__tethering_h *)user_data;
843         GError *g_error = NULL;
844         GVariant *g_var;
845         guint info;
846         tethering_error_e error;
847         tethering_enabled_cb ecb = th->enabled_cb[TETHERING_TYPE_USB];
848         void *data = th->enabled_user_data[TETHERING_TYPE_USB];
849
850         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
851         if (g_error) {
852                 ERR("DBus error [%s]\n", g_error->message);
853                 if (g_error->code == G_DBUS_ERROR_NO_REPLY &&
854                                 ++retry < TETHERING_ERROR_RECOVERY_MAX) {
855                         g_error_free(g_error);
856                         tethering_enable((tethering_h)th, TETHERING_TYPE_USB);
857                         DBG("-\n");
858                         return;
859                 }
860                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
861                         error = TETHERING_ERROR_PERMISSION_DENIED;
862                 else
863                         error = TETHERING_ERROR_OPERATION_FAILED;
864                 g_error_free(g_error);
865         } else {
866                 g_variant_get(g_var, "(u)", &info);
867                 g_variant_unref(g_var);
868                 error = __get_error(info);
869         }
870         retry = 0;
871
872         sigs[E_SIGNAL_USB_TETHER_ON].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
873                         NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_USB_TETHER_ON].name,
874                         TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
875                         sigs[E_SIGNAL_USB_TETHER_ON].cb, (gpointer)th, NULL);
876
877         if (!ecb) {
878                 DBG("-\n");
879                 return;
880         }
881
882         ecb(error, TETHERING_TYPE_USB, true, data);
883         DBG("-\n");
884 }
885 //LCOV_EXCL_STOP
886
887 static void __disabled_cfm_cb(GObject *source_object, GAsyncResult *res,
888                 gpointer user_data)
889 {
890         DBG("+\n");
891
892         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
893         GError *g_error = NULL;
894         GVariant *g_var;
895         guint info, event_type;
896         tethering_error_e error;
897         tethering_type_e type;
898         tethering_h tethering = (tethering_h)user_data;
899         __tethering_h *th = (__tethering_h *)tethering;
900         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_REQUEST;
901         tethering_disabled_cb dcb = NULL;
902         void *data = NULL;
903
904         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
905         if (g_error) {
906                 //LCOV_EXCL_START
907                 ERR("DBus error [%s]\n", g_error->message);
908                 g_error_free(g_error);
909                 return;
910                 //LCOV_EXCL_STOP
911         }
912         g_variant_get(g_var, "(uu)", &event_type, &info);
913         DBG("cfm event : %d info : %d\n", event_type, info);
914         g_variant_unref(g_var);
915         error = __get_error(info);
916         DBG("cfm event : %d info : %d\n", event_type, error);
917         switch (event_type) {
918         case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM:
919                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
920                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_OFF].name,
921                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
922                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].cb, (gpointer)th, NULL);
923
924                 type = TETHERING_TYPE_WIFI;
925                 dcb = th->disabled_cb[type];
926                 data = th->disabled_user_data[type];
927                 if (dcb)
928                         dcb(error, type, code, data);
929                 break;
930
931         case MOBILE_AP_DISABLE_BT_TETHERING_CFM:
932                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
933                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_OFF].name,
934                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
935                                 sigs[E_SIGNAL_BT_TETHER_OFF].cb, (gpointer)th, NULL);
936
937                 type = TETHERING_TYPE_BT;
938                 dcb = th->disabled_cb[type];
939                 data = th->disabled_user_data[type];
940                 if (dcb)
941                         dcb(error, type, code, data);
942                 break;
943
944         //LCOV_EXCL_START
945         case MOBILE_AP_DISABLE_USB_TETHERING_CFM:
946                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
947                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_USB_TETHER_OFF].name,
948                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
949                                 sigs[E_SIGNAL_USB_TETHER_OFF].cb, (gpointer)th, NULL);
950
951                 type = TETHERING_TYPE_USB;
952                 dcb = th->disabled_cb[type];
953                 data = th->disabled_user_data[type];
954                 if (dcb)
955                         dcb(error, type, code, data);
956                 break;
957         //LCOV_EXCL_STOP
958
959         case MOBILE_AP_DISABLE_CFM:
960
961                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
962                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_WIFI_TETHER_OFF].name,
963                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
964                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].cb, (gpointer)th, NULL);
965                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id = g_dbus_connection_signal_subscribe(th->client_bus,
966                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[E_SIGNAL_BT_TETHER_OFF].name,
967                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
968                                 sigs[E_SIGNAL_BT_TETHER_OFF].cb, (gpointer)th, NULL);
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                 for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
975                         dcb = th->disabled_cb[type];
976                         if (dcb == NULL)
977                                 continue;
978                         data = th->disabled_user_data[type];
979
980                         dcb(error, type, code, data);
981                 }
982                 break;
983
984         default:
985                 ERR("Invalid event\n");
986                 break;
987         }
988         DBG("-\n");
989 }
990
991 static void __get_data_usage_cb(GObject *source_object, GAsyncResult *res,
992                                 gpointer user_data)
993 {
994         DBG("+\n");
995
996         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
997
998         GError *g_error = NULL;
999         GVariant *g_var;
1000         guint event_type;
1001         guint64 tx_bytes, rx_bytes;
1002         __tethering_h *th = (__tethering_h *)user_data;
1003         tethering_error_e tethering_error = TETHERING_ERROR_NONE;
1004         bool flag = false;
1005
1006         g_var = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
1007         if (g_error) {
1008                 //LCOV_EXCL_START
1009                 ERR("DBus fail [%s]\n", g_error->message);
1010                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
1011                         tethering_error = TETHERING_ERROR_PERMISSION_DENIED;
1012                 else
1013                         tethering_error = TETHERING_ERROR_OPERATION_FAILED;
1014
1015                 flag = true;
1016                 //LCOV_EXCL_STOP
1017         }
1018         if (th->data_usage_cb == NULL) {
1019                 ERR("There is no data_usage_cb\n");
1020                 return;
1021         }
1022         if (flag) {
1023                 th->data_usage_cb(tethering_error, 0LL, 0LL, th->data_usage_user_data);
1024         } else {
1025                 g_variant_get(g_var, "(utt)", &event_type, &tx_bytes, &rx_bytes);
1026                 th->data_usage_cb(TETHERING_ERROR_NONE,
1027                         rx_bytes, tx_bytes, th->data_usage_user_data);
1028                 g_variant_unref(g_var);
1029         }
1030         th->data_usage_cb = NULL;
1031         th->data_usage_user_data = NULL;
1032
1033         DBG("-\n");
1034 }
1035
1036 static void __settings_reloaded_cb(GObject *source_object, GAsyncResult *res,
1037                 gpointer user_data)
1038 {
1039         DBG("+\n");
1040
1041         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
1042         GError *g_error = NULL;
1043         GVariant *g_var;
1044         guint info;
1045         __tethering_h *th = (__tethering_h *)user_data;
1046         tethering_error_e tethering_error;
1047
1048         g_var  = g_dbus_proxy_call_finish(th->client_bus_proxy, res, &g_error);
1049         if (g_error) {
1050                 ERR("DBus fail [%s]\n", g_error->message);
1051                 if (g_error->code == G_DBUS_ERROR_ACCESS_DENIED)
1052                         tethering_error = TETHERING_ERROR_PERMISSION_DENIED;
1053                 else
1054                         tethering_error = TETHERING_ERROR_OPERATION_FAILED;
1055                 g_error_free(g_error);
1056         }
1057         if (th->settings_reloaded_cb == NULL) {
1058                 DBG("There is no settings_reloaded_cb\n-\n");
1059                 return;
1060         }
1061         g_variant_get(g_var, "(u)", &info);
1062         tethering_error = __get_error(info);
1063         g_variant_unref(g_var);
1064
1065         th->settings_reloaded_cb(tethering_error,
1066                         th->settings_reloaded_user_data);
1067
1068         th->settings_reloaded_cb = NULL;
1069         th->settings_reloaded_user_data = NULL;
1070         DBG("-\n");
1071 }
1072
1073 static void __connect_signals(tethering_h tethering)
1074 {
1075         DBG("+\n");
1076         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
1077
1078         __tethering_h *th = (__tethering_h *)tethering;
1079         GDBusConnection *connection = th->client_bus;
1080         int i = 0;
1081
1082         for (i = E_SIGNAL_NET_CLOSED; i < E_SIGNAL_MAX; i++) {
1083                 sigs[i].sig_id = g_dbus_connection_signal_subscribe(connection,
1084                                 NULL, TETHERING_SERVICE_INTERFACE, sigs[i].name,
1085                                 TETHERING_SERVICE_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
1086                                 sigs[i].cb, tethering, NULL);
1087         }
1088         DBG("-\n");
1089 }
1090
1091 static void __disconnect_signals(tethering_h tethering)
1092 {
1093         DBG("+\n");
1094
1095         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
1096
1097         __tethering_h *th = (__tethering_h *)tethering;
1098         GDBusConnection *connection = th->client_bus;
1099
1100         int i = 0;
1101
1102         for (i = E_SIGNAL_NET_CLOSED; i < E_SIGNAL_MAX; i++)
1103                 g_dbus_connection_signal_unsubscribe(connection, sigs[i].sig_id);
1104         DBG("-\n");
1105 }
1106
1107
1108
1109 static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len)
1110 {
1111         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
1112
1113         switch (type) {
1114         //LCOV_EXCL_START
1115         case TETHERING_TYPE_USB:
1116                 g_strlcpy(buf, TETHERING_USB_IF, len);
1117                 break;
1118         //LCOV_EXCL_STOP
1119         case TETHERING_TYPE_WIFI:
1120                 g_strlcpy(buf, TETHERING_WIFI_IF, len);
1121                 break;
1122
1123         case TETHERING_TYPE_BT:
1124                 g_strlcpy(buf, TETHERING_BT_IF, len);
1125                 break;
1126
1127         default:
1128                 ERR("Not supported type : %d\n", type);
1129                 return false;
1130         }
1131         return true;
1132 }
1133
1134 static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int len)
1135 {
1136         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
1137
1138         switch (type) {
1139         case TETHERING_TYPE_USB:
1140                 g_strlcpy(buf, TETHERING_USB_GATEWAY, len);
1141                 break;
1142
1143         case TETHERING_TYPE_WIFI:
1144                 g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len);
1145                 break;
1146
1147         case TETHERING_TYPE_BT:
1148                 g_strlcpy(buf, TETHERING_BT_GATEWAY, len);
1149                 break;
1150
1151         default:
1152                 ERR("Not supported type : %d\n", type);
1153                 return false;
1154         }
1155         return true;
1156 }
1157
1158 static int __get_common_ssid(char *ssid, unsigned int size)
1159 {
1160         if (ssid == NULL) {
1161                 ERR("ssid is null\n"); //LCOV_EXCL_LINE
1162                 return TETHERING_ERROR_INVALID_PARAMETER;
1163         }
1164
1165         char *ptr = NULL;
1166         char *ptr_tmp = NULL;
1167
1168         ptr = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
1169         if (ptr == NULL) {
1170                 ERR("vconf_get_str is failed and set default ssid");
1171                 g_strlcpy(ssid, TETHERING_DEFAULT_SSID, size);
1172         } else
1173                 g_strlcpy(ssid, ptr, size);
1174
1175         free(ptr);
1176
1177         if (!g_utf8_validate(ssid, -1, (const char **)&ptr_tmp))
1178                 *ptr_tmp = '\0';
1179
1180         return TETHERING_ERROR_NONE;
1181 }
1182
1183 static bool __get_wifi_mode_type(tethering_wifi_mode_type_e type, char **buf)
1184 {
1185         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
1186
1187         switch (type) {
1188         case TETHERING_WIFI_MODE_TYPE_B:
1189                 *buf = g_strdup("b");
1190                 break;
1191         case TETHERING_WIFI_MODE_TYPE_G:
1192                 *buf = g_strdup("g");
1193                 break;
1194         case TETHERING_WIFI_MODE_TYPE_A:
1195                 *buf = g_strdup("a");
1196                 break;
1197         case TETHERING_WIFI_MODE_TYPE_AD:
1198                 *buf = g_strdup("ad");
1199                 break;
1200         default:
1201                 ERR("Not supported type : %d\n", type);
1202                 return false;
1203         }
1204         return true;
1205 }
1206
1207 static int __prepare_wifi_settings(tethering_h tethering, _softap_settings_t *set)
1208 {
1209         DBG("+\n");
1210
1211         __tethering_h *th = (__tethering_h *)tethering;
1212         tethering_error_e ret = TETHERING_ERROR_NONE;
1213         char *ptr = NULL;
1214
1215         if (th == NULL || set == NULL) {
1216                 ERR("null parameter\n-\n");
1217                 return TETHERING_ERROR_INVALID_PARAMETER;
1218         }
1219
1220         if (th->ssid == NULL)
1221                 __get_common_ssid(set->ssid, sizeof(set->ssid));
1222         else
1223                 g_strlcpy(set->ssid, th->ssid, sizeof(set->ssid));
1224
1225         ret = __get_security_type(&set->sec_type);
1226         if (ret != TETHERING_ERROR_NONE)
1227                 set->sec_type = th->sec_type;
1228
1229         ret = __get_visible(&set->visibility);
1230         if (ret != TETHERING_ERROR_NONE)
1231                 set->visibility = th->visibility;
1232
1233         set->mac_filter = th->mac_filter;
1234         set->channel = th->channel;
1235
1236         __get_wifi_mode_type(th->mode_type, &ptr);
1237         if (ptr == NULL) {
1238                 g_strlcpy(set->mode, "", sizeof(set->mode));
1239         } else {
1240                 g_strlcpy(set->mode, ptr, sizeof(set->mode));
1241                 free(ptr);
1242         }
1243
1244         if (set->sec_type == TETHERING_WIFI_SECURITY_TYPE_NONE) {
1245                 g_strlcpy(set->key, "", sizeof(set->key));
1246         } else {
1247                 GDBusProxy *proxy = th->client_bus_proxy;
1248                 GVariant *parameters;
1249                 GError *error = NULL;
1250                 char *passphrase = NULL;
1251                 unsigned int len = 0;
1252
1253                 parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_passphrase",
1254                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1255
1256                 if (error) {
1257                         //LCOV_EXCL_START
1258                         ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
1259
1260                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
1261                                 ret = TETHERING_ERROR_PERMISSION_DENIED;
1262                         else
1263                                 ret = TETHERING_ERROR_OPERATION_FAILED;
1264
1265                         g_error_free(error);
1266                         return ret;
1267                         //LCOV_EXCL_STOP
1268                 }
1269
1270                 if (parameters != NULL) {
1271                         g_variant_get(parameters, "(siu)", &passphrase, &len, &ret);
1272                         g_variant_unref(parameters);
1273                 }
1274
1275                 g_strlcpy(set->key, passphrase, sizeof(set->key));
1276         }
1277         DBG("-\n");
1278         return TETHERING_ERROR_NONE;
1279 }
1280
1281 static bool __check_precondition(tethering_type_e type)
1282 {
1283         int dnet_state = 0;
1284         int cellular_state = 0;
1285         int wifi_state = 0;
1286
1287         /* data network through cellular */
1288         vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state);
1289         if (cellular_state == VCONFKEY_NETWORK_CELLULAR_ON) {
1290                 ERR("Data Network can be connected later");
1291                 return TRUE;
1292         }
1293
1294         vconf_get_int(VCONFKEY_DNET_STATE, &dnet_state);
1295         if (dnet_state > VCONFKEY_DNET_OFF) {
1296                 ERR("Data Network is connected");
1297                 return TRUE;
1298         }
1299
1300         /* data network through wifi */
1301         if (type != TETHERING_TYPE_WIFI) {
1302                 vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
1303                 if (wifi_state > VCONFKEY_WIFI_UNCONNECTED) {
1304                         ERR("Wi-Fi is connected!");
1305                         return TRUE;
1306                 }
1307         }
1308
1309         ERR("Network is not available!");
1310         return FALSE;
1311 }
1312
1313 /**
1314  * @internal
1315  * @brief  Creates the handle of tethering.
1316  * @since_tizen 2.3
1317  * @privlevel platform
1318  * @privilege http://tizen.org/privilege/tethering.admin
1319  * @remarks  The @a tethering must be released tethering_destroy() by you.
1320  * @param[out]  tethering  A handle of a new mobile ap handle on success
1321  * @return  0 on success, otherwise a negative error value.
1322  * @retval  #TETHERING_ERROR_NONE  Successful
1323  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1324  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1325  * @retval  #TETHERING_ERROR_NOT_SUPPORT_API  API is not supported
1326  * @see  tethering_destroy()
1327  */
1328 API int tethering_create(tethering_h *tethering)
1329 {
1330         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1331         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1332                         "parameter(tethering) is NULL\n");
1333         DBG("+\n");
1334
1335         __tethering_h *th = NULL;
1336         GError *error = NULL;
1337         char ssid[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, };
1338
1339         th = (__tethering_h *)malloc(sizeof(__tethering_h));
1340
1341         _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1342                         "malloc is failed\n");
1343         memset(th, 0x00, sizeof(__tethering_h));
1344         th->sec_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
1345         th->visibility = true;
1346         th->mac_filter = false;
1347         th->channel = 6;
1348         th->mode_type = TETHERING_WIFI_MODE_TYPE_G;
1349
1350         if (__generate_initial_passphrase(th->passphrase,
1351                         sizeof(th->passphrase)) == 0) {
1352                 ERR("random passphrase generation failed\n"); //LCOV_EXCL_LINE
1353                 free(th);
1354                 return TETHERING_ERROR_OPERATION_FAILED;
1355         }
1356
1357         if (__get_common_ssid(ssid, sizeof(ssid)) != TETHERING_ERROR_NONE) {
1358                 ERR("common ssid get failed\n"); //LCOV_EXCL_LINE
1359                 free(th);
1360                 return TETHERING_ERROR_OPERATION_FAILED;
1361         }
1362
1363 #if !GLIB_CHECK_VERSION(2, 36, 0)
1364         g_type_init();
1365 #endif
1366         GCancellable *cancellable = g_cancellable_new();
1367         th->client_bus = g_bus_get_sync(DBUS_BUS_SYSTEM, cancellable, &error);
1368         if (error) {
1369                 //LCOV_EXCL_START
1370                 ERR("Couldn't connect to the System bus[%s]", error->message);
1371                 g_error_free(error);
1372                 g_cancellable_cancel(cancellable);
1373                 g_object_unref(cancellable);
1374                 free(th);
1375                 return TETHERING_ERROR_OPERATION_FAILED;
1376                 //LCOV_EXCL_STOP
1377         }
1378         th->cancellable = cancellable;
1379
1380         th->client_bus_proxy = g_dbus_proxy_new_sync(th->client_bus, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
1381                         NULL, TETHERING_SERVICE_NAME, TETHERING_SERVICE_OBJECT_PATH,
1382                         TETHERING_SERVICE_INTERFACE, th->cancellable, &error);
1383         if (!th->client_bus_proxy) {
1384                 //LCOV_EXCL_START
1385                 if (error)
1386                         ERR("Couldn't create the proxy object because of %s\n", error->message);
1387                 g_cancellable_cancel(th->cancellable);
1388                 g_object_unref(th->cancellable);
1389                 g_object_unref(th->client_bus);
1390                 free(th);
1391                 return TETHERING_ERROR_OPERATION_FAILED;
1392                 //LCOV_EXCL_STOP
1393         }
1394
1395         __connect_signals((tethering_h)th);
1396
1397         *tethering = (tethering_h)th;
1398         DBG("Tethering Handle : 0x%X\n", th);
1399         DBG("-\n");
1400         return TETHERING_ERROR_NONE;
1401 }
1402
1403 /**
1404  * @internal
1405  * @brief  Destroys the handle of tethering.
1406  * @since_tizen 2.3
1407  * @privlevel platform
1408  * @privilege http://tizen.org/privilege/tethering.admin
1409  * @param[in]  tethering  The handle of tethering
1410  * @return  0 on success, otherwise a negative error value.
1411  * @retval  #TETHERING_ERROR_NONE  Successful
1412  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1413  * @see  tethering_create()
1414  */
1415 API int tethering_destroy(tethering_h tethering)
1416 {
1417         DBG("+\n");
1418         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1419         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1420                         "parameter(tethering) is NULL\n");
1421
1422         __tethering_h *th = (__tethering_h *)tethering;
1423
1424         DBG("Tethering Handle : 0x%X\n", th);
1425         __disconnect_signals(tethering);
1426
1427         if (th->ssid)
1428                 free(th->ssid);
1429
1430         g_object_unref(th->cancellable);
1431         g_object_unref(th->client_bus_proxy);
1432         g_object_unref(th->client_bus);
1433         memset(th, 0x00, sizeof(__tethering_h));
1434         free(th);
1435
1436         DBG("-\n");
1437         return TETHERING_ERROR_NONE;
1438 }
1439
1440 /**
1441  * @internal
1442  * @brief Enables the tethering, asynchronously.
1443  * @since_tizen 2.3
1444  * @privlevel platform
1445  * @privilege http://tizen.org/privilege/tethering.admin
1446  * @param[in]  tethering  The handle of tethering
1447  * @param[in]  type  The type of tethering
1448  * @return 0 on success, otherwise negative error value.
1449  * @retval  #TETHERING_ERROR_NONE  Successful
1450  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1451  * @post tethering_enabled_cb() will be invoked.
1452  * @see  tethering_is_enabled()
1453  * @see  tethering_disable()
1454  */
1455 API int tethering_enable(tethering_h tethering, tethering_type_e type)
1456 {
1457         DBG("+ type :  %d\n", type);
1458         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1459         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_USB_FEATURE);
1460         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_WIFI_FEATURE);
1461         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_BT_FEATURE);
1462
1463         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1464                         "parameter(tethering) is NULL\n");
1465
1466         tethering_error_e ret = TETHERING_ERROR_NONE;
1467         __tethering_h *th = (__tethering_h *)tethering;
1468         GDBusProxy *proxy = th->client_bus_proxy;
1469         GDBusConnection *connection = th->client_bus;
1470
1471         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_INFINITE);
1472
1473         if (__check_precondition(type) == FALSE) {
1474                 //LCOV_EXCL_START
1475                 DBG("-\n");
1476                 return TETHERING_ERROR_OPERATION_FAILED;
1477                 //LCOV_EXCL_STOP
1478         }
1479
1480         switch (type) {
1481         //LCOV_EXCL_START
1482         case TETHERING_TYPE_USB:
1483                 g_dbus_connection_signal_unsubscribe(connection,
1484                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1485
1486                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1487                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1488                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1489                 break;
1490         //LCOV_EXCL_STOP
1491
1492         case TETHERING_TYPE_WIFI: {
1493                 _softap_settings_t set = {"", "", "", 0, false};
1494
1495                 ret = __prepare_wifi_settings(tethering, &set);
1496                 if (ret != TETHERING_ERROR_NONE) {
1497                         ERR("softap settings initialization failed\n");
1498                         DBG("-\n");
1499                         return TETHERING_ERROR_OPERATION_FAILED;
1500                 }
1501                 g_dbus_connection_signal_unsubscribe(connection,
1502                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1503
1504                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1505                                 g_variant_new("(sssiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.sec_type),
1506                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1507                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1508                 break;
1509         }
1510
1511         case TETHERING_TYPE_BT:
1512                 g_dbus_connection_signal_unsubscribe(connection,
1513                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1514
1515                 g_dbus_proxy_call(proxy, "enable_bt_tethering", NULL,
1516                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1517                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1518
1519                 break;
1520
1521         //LCOV_EXCL_START
1522         case TETHERING_TYPE_ALL: {
1523                 _softap_settings_t set = {"", "", "", 0, false};
1524
1525                 ret = __prepare_wifi_settings(tethering, &set);
1526                 if (ret != TETHERING_ERROR_NONE) {
1527                         ERR("softap settings initialization failed\n");
1528                         return TETHERING_ERROR_OPERATION_FAILED;
1529                 }
1530
1531                 /* TETHERING_TYPE_USB */
1532                 g_dbus_connection_signal_unsubscribe(connection,
1533                                 sigs[E_SIGNAL_USB_TETHER_ON].sig_id);
1534
1535                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1536                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1537                                 (GAsyncReadyCallback) __usb_enabled_cfm_cb, (gpointer)tethering);
1538
1539                 /* TETHERING_TYPE_WIFI */
1540                 g_dbus_connection_signal_unsubscribe(connection,
1541                                 sigs[E_SIGNAL_WIFI_TETHER_ON].sig_id);
1542
1543                 g_dbus_proxy_call(proxy, "enable_wifi_tethering",
1544                                 g_variant_new("(ssii)", set.ssid, set.key, set.visibility, set.sec_type),
1545                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1546                                 (GAsyncReadyCallback) __wifi_enabled_cfm_cb, (gpointer)tethering);
1547
1548                 /* TETHERING_TYPE_BT */
1549                 g_dbus_connection_signal_unsubscribe(connection,
1550                                 sigs[E_SIGNAL_BT_TETHER_ON].sig_id);
1551
1552                 g_dbus_proxy_call(proxy, "enable_usb_tethering", NULL,
1553                                 G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1554                                 (GAsyncReadyCallback) __bt_enabled_cfm_cb, (gpointer)tethering);
1555                 break;
1556                 //LCOV_EXCL_STOP
1557         }
1558         default:
1559                 ERR("Unknown type : %d\n", type);
1560
1561                 g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1562
1563                 DBG("-\n");
1564                 return TETHERING_ERROR_INVALID_PARAMETER;
1565         }
1566
1567         g_dbus_proxy_set_default_timeout(proxy, DBUS_TIMEOUT_USE_DEFAULT);
1568         DBG("-\n");
1569         return TETHERING_ERROR_NONE;
1570 }
1571
1572 /**
1573  * @internal
1574  * @brief Disables the tethering, asynchronously.
1575  * @since_tizen 2.3
1576  * @privlevel platform
1577  * @privilege http://tizen.org/privilege/tethering.admin
1578  * @param[in]  tethering  The handle of tethering
1579  * @param[in]  type  The type of tethering
1580  * @return 0 on success, otherwise negative error value.
1581  * @retval  #TETHERING_ERROR_NONE  Successful
1582  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1583  * @post tethering_disabled_cb() will be invoked.
1584  * @see  tethering_is_enabled()
1585  * @see  tethering_enable()
1586  */
1587 API int tethering_disable(tethering_h tethering, tethering_type_e type)
1588 {
1589         DBG("+ type :  %d\n", type);
1590         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
1591         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
1592         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
1593
1594         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1595                         "parameter(tethering) is NULL\n");
1596
1597         __tethering_h *th = (__tethering_h *)tethering;
1598         GDBusProxy *proxy = th->client_bus_proxy;
1599         GDBusConnection *connection = th->client_bus;
1600
1601         switch (type) {
1602         case TETHERING_TYPE_USB:
1603                 g_dbus_connection_signal_unsubscribe(connection,
1604                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1605
1606                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1607                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1608                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1609
1610                 break;
1611
1612         case TETHERING_TYPE_WIFI:
1613
1614                 g_dbus_connection_signal_unsubscribe(connection,
1615                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1616
1617                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1618                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1619                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1620                 break;
1621
1622         case TETHERING_TYPE_BT:
1623
1624                 g_dbus_connection_signal_unsubscribe(connection,
1625                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1626
1627                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1628                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1629                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1630                 break;
1631
1632         case TETHERING_TYPE_ALL:
1633                 g_dbus_connection_signal_unsubscribe(connection,
1634                                 sigs[E_SIGNAL_USB_TETHER_OFF].sig_id);
1635
1636                 g_dbus_proxy_call(proxy, "disable_usb_tethering",
1637                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1638                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1639
1640                 g_dbus_connection_signal_unsubscribe(connection,
1641                                 sigs[E_SIGNAL_WIFI_TETHER_OFF].sig_id);
1642
1643                 g_dbus_proxy_call(proxy, "disable_wifi_tethering",
1644                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1645                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1646
1647                 g_dbus_connection_signal_unsubscribe(connection,
1648                                 sigs[E_SIGNAL_BT_TETHER_OFF].sig_id);
1649
1650                 g_dbus_proxy_call(proxy, "disable_bt_tethering",
1651                                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
1652                                 (GAsyncReadyCallback) __disabled_cfm_cb, (gpointer)tethering);
1653                 break;
1654
1655         default:
1656                 ERR("Not supported tethering type [%d]\n", type);
1657                 DBG("-\n");
1658                 return TETHERING_ERROR_INVALID_PARAMETER;
1659         }
1660         DBG("-\n");
1661         return TETHERING_ERROR_NONE;
1662 }
1663
1664 /**
1665  * @internal
1666  * @brief  Checks whetehr the tethering is enabled or not.
1667  * @since_tizen 2.3
1668  * @privlevel platform
1669  * @privilege http://tizen.org/privilege/tethering.admin
1670  * @param[in]  tethering  The handle of tethering
1671  * @param[in]  type  The type of tethering
1672  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
1673  */
1674 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
1675 {
1676         int is_on = 0;
1677         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
1678
1679         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1680
1681         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0)
1682                 return FALSE;
1683
1684         switch (type) {
1685         case TETHERING_TYPE_USB:
1686                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
1687                 break;
1688
1689         case TETHERING_TYPE_WIFI:
1690                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
1691                 break;
1692
1693         case TETHERING_TYPE_BT:
1694                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
1695                 break;
1696
1697         default:
1698                 ERR("Not supported type : %d\n", type);
1699                 break;
1700         }
1701         return is_on & vconf_type ? true : false;
1702 }
1703
1704 /**
1705  * @internal
1706  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
1707  * @since_tizen 2.3
1708  * @privlevel platform
1709  * @privilege http://tizen.org/privilege/tethering.admin
1710  * @remarks @a mac_address must be released with free() by you.
1711  * @param[in]  tethering  The handle of tethering
1712  * @param[in]  type  The type of tethering
1713  * @param[out]  mac_address  The MAC address
1714  * @return  0 on success, otherwise a negative error value.
1715  * @retval  #TETHERING_ERROR_NONE  Successful
1716  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1717  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1718  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1719  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1720  * @pre  tethering must be enabled.
1721  * @see  tethering_is_enabled()
1722  * @see  tethering_enable()
1723  */
1724 API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
1725 {
1726         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
1727         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
1728         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
1729
1730         _retvm_if(tethering_is_enabled(tethering, type) == false,
1731                         TETHERING_ERROR_NOT_ENABLED,
1732                         "tethering type[%d] is not enabled\n", type);
1733         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1734                         "parameter(tethering) is NULL\n");
1735         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1736                         "parameter(mac_address) is NULL\n");
1737
1738         struct ifreq ifr;
1739         int s = 0;
1740         char *macbuf = NULL;
1741
1742         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1743                         TETHERING_ERROR_OPERATION_FAILED,
1744                         "getting interface name is failed\n");
1745
1746         s = socket(AF_INET, SOCK_DGRAM, 0);
1747         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1748                         "getting socket is failed\n");
1749         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
1750                 ERR("getting mac is failed\n");
1751                 close(s);
1752                 return TETHERING_ERROR_OPERATION_FAILED;
1753         }
1754         close(s);
1755
1756         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
1757         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1758                         "Not enough memory\n");
1759         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
1760                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
1761                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
1762                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
1763                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
1764                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
1765                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
1766
1767         *mac_address = macbuf;
1768
1769         return TETHERING_ERROR_NONE;
1770 }
1771
1772 /**
1773  * @internal
1774  * @brief Gets the name of network interface. For example, usb0.
1775  * @since_tizen 2.3
1776  * @privlevel platform
1777  * @privilege http://tizen.org/privilege/tethering.admin
1778  * @remarks @a interface_name must be released with free() by you.
1779  * @param[in]  tethering  The handle of tethering
1780  * @param[in]  type  The type of tethering
1781  * @param[out]  interface_name  The name of network interface
1782  * @return 0 on success, otherwise negative error value.
1783  * @retval  #TETHERING_ERROR_NONE  Successful
1784  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1785  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1786  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1787  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1788  * @pre  tethering must be enabled.
1789  * @see  tethering_is_enabled()
1790  * @see  tethering_enable()
1791  */
1792 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
1793 {
1794         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
1795         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
1796         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
1797
1798         _retvm_if(tethering_is_enabled(tethering, type) == false,
1799                         TETHERING_ERROR_NOT_ENABLED,
1800                         "tethering type[%d] is not enabled\n", type);
1801         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1802                         "parameter(tethering) is NULL\n");
1803         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1804                         "parameter(interface_name) is NULL\n");
1805
1806         char intf[TETHERING_STR_INFO_LEN] = {0, };
1807
1808         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
1809                         TETHERING_ERROR_OPERATION_FAILED,
1810                         "getting interface name is failed\n");
1811         *interface_name = strdup(intf);
1812         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1813                         "Not enough memory\n");
1814
1815         return TETHERING_ERROR_NONE;
1816 }
1817
1818 /**
1819  * @internal
1820  * @brief Gets the local IP address.
1821  * @since_tizen 2.3
1822  * @privlevel platform
1823  * @privilege http://tizen.org/privilege/tethering.admin
1824  * @remarks @a ip_address must be released with free() by you.
1825  * @param[in]  tethering  The handle of tethering
1826  * @param[in]  type  The type of tethering
1827  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1828  * @param[out]  ip_address  The local IP address
1829  * @return 0 on success, otherwise negative error value.
1830  * @retval  #TETHERING_ERROR_NONE  Successful
1831  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1832  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1833  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1834  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1835  * @pre  tethering must be enabled.
1836  * @see  tethering_is_enabled()
1837  * @see  tethering_enable()
1838  */
1839 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
1840 {
1841
1842         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
1843         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
1844         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
1845
1846         _retvm_if(tethering_is_enabled(tethering, type) == false,
1847                         TETHERING_ERROR_NOT_ENABLED,
1848                         "tethering type[%d] is not enabled\n", type);
1849         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1850                         "parameter(tethering) is NULL\n");
1851         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1852                         "parameter(ip_address) is NULL\n");
1853
1854         struct ifreq ifr;
1855         int s = 0;
1856         char *ipbuf = NULL;
1857
1858         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1859                         TETHERING_ERROR_OPERATION_FAILED,
1860                         "getting interface name is failed\n");
1861
1862         s = socket(AF_INET, SOCK_DGRAM, 0);
1863         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1864                         "getting socket is failed\n");
1865         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
1866                 ERR("ioctl is failed\n");
1867                 close(s);
1868                 return TETHERING_ERROR_OPERATION_FAILED;
1869         }
1870         close(s);
1871
1872         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
1873         *ip_address = strdup(ipbuf);
1874         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1875                         "Not enough memory\n");
1876
1877         return TETHERING_ERROR_NONE;
1878 }
1879
1880 /**
1881  * @internal
1882  * @brief Gets the Gateway address.
1883  * @since_tizen 2.3
1884  * @privlevel platform
1885  * @privilege http://tizen.org/privilege/tethering.admin
1886  * @remarks @a gateway_address must be released with free() by you.
1887  * @param[in]  tethering  The handle of tethering
1888  * @param[in]  type  The type of tethering
1889  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1890  * @param[out]  gateway_address  The local IP address
1891  * @return 0 on success, otherwise negative error value.
1892  * @retval  #TETHERING_ERROR_NONE  Successful
1893  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1894  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1895  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1896  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1897  * @pre  tethering must be enabled.
1898  * @see  tethering_is_enabled()
1899  * @see  tethering_enable()
1900  */
1901 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
1902 {
1903
1904         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
1905         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
1906         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
1907
1908         _retvm_if(tethering_is_enabled(tethering, type) == false,
1909                         TETHERING_ERROR_NOT_ENABLED,
1910                         "tethering type[%d] is not enabled\n", type);
1911         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1912                         "parameter(tethering) is NULL\n");
1913         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1914                         "parameter(gateway_address) is NULL\n");
1915
1916         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
1917
1918         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
1919                         TETHERING_ERROR_OPERATION_FAILED,
1920                         "getting gateway address is failed\n");
1921
1922         *gateway_address = strdup(gateway_buf);
1923
1924         return TETHERING_ERROR_NONE;
1925 }
1926
1927 /**
1928  * @internal
1929  * @brief Gets the Subnet Mask.
1930  * @since_tizen 2.3
1931  * @privlevel platform
1932  * @privilege http://tizen.org/privilege/tethering.admin
1933  * @remarks @a subnet_mask must be released with free() by you.
1934  * @param[in]  tethering  The handle of tethering
1935  * @param[in]  type  The type of tethering
1936  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1937  * @param[out]  subnet_mask  The local IP address
1938  * @return 0 on success, otherwise negative error value.
1939  * @retval  #TETHERING_ERROR_NONE  Successful
1940  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1941  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1942  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1943  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1944  * @pre  tethering must be enabled.
1945  * @see  tethering_is_enabled()
1946  * @see  tethering_enable()
1947  */
1948 API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
1949 {
1950         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
1951         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
1952         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
1953
1954         _retvm_if(tethering_is_enabled(tethering, type) == false,
1955                         TETHERING_ERROR_NOT_ENABLED,
1956                         "tethering is not enabled\n");
1957         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1958                         "parameter(tethering) is NULL\n");
1959         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1960                         "parameter(subnet_mask) is NULL\n");
1961
1962         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
1963         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1964                         "Not enough memory\n");
1965
1966         return TETHERING_ERROR_NONE;
1967 }
1968
1969 /**
1970  * @internal
1971  * @brief Gets the data usage.
1972  * @since_tizen 2.3
1973  * @privlevel platform
1974  * @privilege http://tizen.org/privilege/tethering.admin
1975  * @param[in]  tethering  The handle of tethering
1976  * @param[out]  usage  The data usage
1977  * @return 0 on success, otherwise negative error value.
1978  * @retval  #TETHERING_ERROR_NONE  Successful
1979  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1980  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1981  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1982  * @pre  tethering must be enabled.
1983  * @see  tethering_is_enabled()
1984  * @see  tethering_enable()
1985  */
1986 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
1987 {
1988         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE);
1989
1990         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1991                         "parameter(tethering) is NULL\n");
1992         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1993                         "parameter(callback) is NULL\n");
1994         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1995                         TETHERING_ERROR_NOT_ENABLED,
1996                         "tethering is not enabled\n");
1997
1998         __tethering_h *th = (__tethering_h *)tethering;
1999         GDBusProxy *proxy = th->client_bus_proxy;
2000
2001         th->data_usage_cb = callback;
2002         th->data_usage_user_data = user_data;
2003
2004         g_dbus_proxy_call(proxy, "get_data_packet_usage",
2005                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
2006                         (GAsyncReadyCallback) __get_data_usage_cb, (gpointer)tethering);
2007
2008         return TETHERING_ERROR_NONE;
2009 }
2010
2011 /**
2012  * @internal
2013  * @brief Gets the client which is connected by tethering "type".
2014  * @since_tizen 2.3
2015  * @privlevel platform
2016  * @privilege http://tizen.org/privilege/tethering.admin
2017  * @param[in]  tethering  The handle of tethering
2018  * @param[in]  type  The type of tethering
2019  * @param[in]  callback  The callback function to invoke
2020  * @param[in]  user_data  The user data to be passed to the callback function
2021  * @retval  #TETHERING_ERROR_NONE  Successful
2022  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2023  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
2024  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2025  * @pre  tethering must be enabled.
2026  * @see  tethering_is_enabled()
2027  * @see  tethering_enable()
2028  */
2029 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
2030 {
2031         DBG("+\n");
2032         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
2033         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2034         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
2035
2036         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2037                         "parameter(tethering) is NULL\n");
2038         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2039                         "parameter(callback) is NULL\n");
2040         _retvm_if(__any_tethering_is_enabled(tethering) == false,
2041                         TETHERING_ERROR_NOT_ENABLED,
2042                         "tethering is not enabled\n");
2043
2044         mobile_ap_type_e interface;
2045         __tethering_h *th = (__tethering_h *)tethering;
2046         __tethering_client_h client = {0, };
2047         gchar *ip = NULL;
2048         gchar *mac = NULL;
2049         gchar *hostname = NULL;
2050         guint timestamp = 0;
2051         GError *error = NULL;
2052         GVariant *result = NULL;
2053         GVariantIter *outer_iter = NULL;
2054         GVariantIter *inner_iter = NULL;
2055         GVariant *station = NULL;
2056         GVariant *value = NULL;
2057         gchar *key = NULL;
2058
2059         result = g_dbus_proxy_call_sync(th->client_bus_proxy, "get_station_info",
2060                         NULL, G_DBUS_CALL_FLAGS_NONE,
2061                         -1, th->cancellable, &error);
2062         if (error)
2063                 ERR("g_dbus_proxy_call_sync is failed and error is %s\n", error->message);
2064         g_variant_get(result, "(a(a{sv}))", &outer_iter);
2065         while (g_variant_iter_loop(outer_iter, "(@a{sv})", &station)) {
2066                 g_variant_get(station, "a{sv}", &inner_iter);
2067                 while (g_variant_iter_loop(inner_iter, "{sv}", &key, &value)) {
2068                         if (g_strcmp0(key, "Type") == 0) {
2069                                 interface = g_variant_get_int32(value);
2070                                 if (interface == MOBILE_AP_TYPE_USB)
2071                                         client.interface = TETHERING_TYPE_USB;
2072                                 else if (interface == MOBILE_AP_TYPE_WIFI)
2073                                         client.interface = TETHERING_TYPE_WIFI;
2074                                 else if (interface == MOBILE_AP_TYPE_BT)
2075                                         client.interface = TETHERING_TYPE_BT;
2076                                 else {
2077                                         ERR("Invalid interface\n");
2078                                         g_free(key);
2079                                         g_variant_unref(value);
2080                                         break;
2081                                 }
2082                                 DBG("interface is %d\n", client.interface);
2083                                 if (client.interface != type && (TETHERING_TYPE_ALL != type)) {
2084                                         g_free(key);
2085                                         g_variant_unref(value);
2086                                         break;
2087                                 }
2088                         } else if (g_strcmp0(key, "IP") == 0) {
2089                                 g_variant_get(value, "s", &ip);
2090                                 SDBG("ip is %s\n", ip);
2091                                 g_strlcpy(client.ip, ip, sizeof(client.ip));
2092                         } else if (g_strcmp0(key, "MAC") == 0) {
2093                                 g_variant_get(value, "s", &mac);
2094                                 SDBG("mac is %s\n", mac);
2095                                 g_strlcpy(client.mac, mac, sizeof(client.mac));
2096                         } else if (g_strcmp0(key, "Name") == 0) {
2097                                 g_variant_get(value, "s", &hostname);
2098                                 SDBG("hsotname is %s\n", hostname);
2099                                 if (hostname)
2100                                         client.hostname = g_strdup(hostname);
2101                         } else if (g_strcmp0(key, "Time") == 0) {
2102                                 timestamp = g_variant_get_int32(value);
2103                                 DBG("timestamp is %d\n", timestamp);
2104                                 client.tm = (time_t)timestamp;
2105                         } else {
2106                                 ERR("Key %s not required\n", key);
2107                         }
2108                 }
2109                 g_free(hostname);
2110                 g_free(ip);
2111                 g_free(mac);
2112                 g_variant_iter_free(inner_iter);
2113                 if (callback((tethering_client_h)&client, user_data) == false) {
2114                         DBG("iteration is stopped\n");
2115                         g_free(client.hostname);
2116                         g_variant_iter_free(outer_iter);
2117                         g_variant_unref(station);
2118                         g_variant_unref(result);
2119                         DBG("-\n");
2120                         return TETHERING_ERROR_OPERATION_FAILED;
2121                 }
2122                 g_free(client.hostname);
2123         }
2124         g_variant_iter_free(outer_iter);
2125         g_variant_unref(station);
2126         g_variant_unref(result);
2127         DBG("-\n");
2128         return TETHERING_ERROR_NONE;
2129 }
2130
2131 /**
2132  * @internal
2133  * @brief Registers the callback function called when tethering is enabled.
2134  * @since_tizen 2.3
2135  * @privlevel platform
2136  * @privilege http://tizen.org/privilege/tethering.admin
2137  * @param[in]  tethering  The handle of tethering
2138  * @param[in]  type  The type of tethering
2139  * @param[in]  callback  The callback function to invoke
2140  * @param[in]  user_data  The user data to be passed to the callback function
2141  * @retval  #TETHERING_ERROR_NONE  Successful
2142  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2143  * @see  tethering_unset_enabled_cb()
2144  */
2145 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
2146 {
2147         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
2148         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2149         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
2150
2151         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2152                         "parameter(tethering) is NULL\n");
2153         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2154                         "parameter(callback) is NULL\n");
2155
2156         __tethering_h *th = (__tethering_h *)tethering;
2157         tethering_type_e ti;
2158
2159         if (type != TETHERING_TYPE_ALL) {
2160                 th->enabled_cb[type] = callback;
2161                 th->enabled_user_data[type] = user_data;
2162
2163                 return TETHERING_ERROR_NONE;
2164         }
2165
2166         /* TETHERING_TYPE_ALL */
2167         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2168                 th->enabled_cb[ti] = callback;
2169                 th->enabled_user_data[ti] = user_data;
2170         }
2171
2172         return TETHERING_ERROR_NONE;
2173 }
2174
2175 /**
2176  * @internal
2177  * @brief Unregisters the callback function called when tethering is disabled.
2178  * @since_tizen 2.3
2179  * @privlevel platform
2180  * @privilege http://tizen.org/privilege/tethering.admin
2181  * @param[in]  tethering  The handle of tethering
2182  * @param[in]  type  The type of tethering
2183  * @retval  #TETHERING_ERROR_NONE  Successful
2184  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2185  * @see  tethering_set_enabled_cb()
2186  */
2187 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
2188 {
2189         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
2190         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2191         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
2192
2193         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2194                         "parameter(tethering) is NULL\n");
2195
2196         __tethering_h *th = (__tethering_h *)tethering;
2197         tethering_type_e ti;
2198
2199         if (type != TETHERING_TYPE_ALL) {
2200                 th->enabled_cb[type] = NULL;
2201                 th->enabled_user_data[type] = NULL;
2202
2203                 return TETHERING_ERROR_NONE;
2204         }
2205
2206         /* TETHERING_TYPE_ALL */
2207         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2208                 th->enabled_cb[ti] = NULL;
2209                 th->enabled_user_data[ti] = NULL;
2210         }
2211
2212         return TETHERING_ERROR_NONE;
2213 }
2214
2215 /**
2216  * @internal
2217  * @brief Registers the callback function called when tethering is disabled.
2218  * @since_tizen 2.3
2219  * @privlevel platform
2220  * @privilege http://tizen.org/privilege/tethering.admin
2221  * @param[in]  tethering  The handle of tethering
2222  * @param[in]  type  The type of tethering
2223  * @param[in]  callback  The callback function to invoke
2224  * @param[in]  user_data  The user data to be passed to the callback function
2225  * @retval  #TETHERING_ERROR_NONE  Successful
2226  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2227  * @see  tethering_unset_disabled_cb()
2228  */
2229 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
2230 {
2231         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
2232         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2233         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
2234
2235         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2236                         "parameter(tethering) is NULL\n");
2237         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2238                         "parameter(callback) is NULL\n");
2239
2240         __tethering_h *th = (__tethering_h *)tethering;
2241         tethering_type_e ti;
2242
2243         if (type != TETHERING_TYPE_ALL) {
2244                 th->disabled_cb[type] = callback;
2245                 th->disabled_user_data[type] = user_data;
2246
2247                 return TETHERING_ERROR_NONE;
2248         }
2249
2250         /* TETHERING_TYPE_ALL */
2251         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2252                 th->disabled_cb[ti] = callback;
2253                 th->disabled_user_data[ti] = user_data;
2254         }
2255
2256         return TETHERING_ERROR_NONE;
2257 }
2258
2259 /**
2260  * @internal
2261  * @brief Unregisters the callback function called when tethering is disabled.
2262  * @since_tizen 2.3
2263  * @privlevel platform
2264  * @privilege http://tizen.org/privilege/tethering.admin
2265  * @param[in]  tethering  The handle of tethering
2266  * @param[in]  type  The type of tethering
2267  * @retval  #TETHERING_ERROR_NONE  Successful
2268  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2269  * @see  tethering_set_disabled_cb()
2270  */
2271 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
2272 {
2273         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
2274         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2275         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
2276
2277         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2278                         "parameter(tethering) is NULL\n");
2279
2280         __tethering_h *th = (__tethering_h *)tethering;
2281         tethering_type_e ti;
2282
2283         if (type != TETHERING_TYPE_ALL) {
2284                 th->disabled_cb[type] = NULL;
2285                 th->disabled_user_data[type] = NULL;
2286
2287                 return TETHERING_ERROR_NONE;
2288         }
2289
2290         /* TETHERING_TYPE_ALL */
2291         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2292                 th->disabled_cb[ti] = NULL;
2293                 th->disabled_user_data[ti] = NULL;
2294         }
2295
2296         return TETHERING_ERROR_NONE;
2297 }
2298
2299 /**
2300  * @internal
2301  * @brief Registers the callback function called when the state of connection is changed.
2302  * @since_tizen 2.3
2303  * @privlevel platform
2304  * @privilege http://tizen.org/privilege/tethering.admin
2305  * @param[in]  tethering  The handle of tethering
2306  * @param[in]  type  The type of tethering
2307  * @param[in]  callback  The callback function to invoke
2308  * @param[in]  user_data  The user data to be passed to the callback function
2309  * @retval  #TETHERING_ERROR_NONE  Successful
2310  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2311  * @see  tethering_unset_connection_state_changed_cb_cb()
2312  */
2313 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
2314 {
2315         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
2316         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2317         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
2318
2319         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2320                         "parameter(tethering) is NULL\n");
2321         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2322                         "parameter(callback) is NULL\n");
2323
2324         __tethering_h *th = (__tethering_h *)tethering;
2325         tethering_type_e ti;
2326
2327         if (type != TETHERING_TYPE_ALL) {
2328                 th->changed_cb[type] = callback;
2329                 th->changed_user_data[type] = user_data;
2330
2331                 return TETHERING_ERROR_NONE;
2332         }
2333
2334         /* TETHERING_TYPE_ALL */
2335         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2336                 th->changed_cb[ti] = callback;
2337                 th->changed_user_data[ti] = user_data;
2338         }
2339
2340         return TETHERING_ERROR_NONE;
2341 }
2342
2343 /**
2344  * @internal
2345  * @brief Unregisters the callback function called when the state of connection is changed.
2346  * @since_tizen 2.3
2347  * @privlevel platform
2348  * @privilege http://tizen.org/privilege/tethering.admin
2349  * @param[in]  tethering  The handle of tethering
2350  * @param[in]  type  The type of tethering
2351  * @retval  #TETHERING_ERROR_NONE  Successful
2352  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2353  * @see  tethering_set_connection_state_changed_cb()
2354  */
2355 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
2356 {
2357         if (type == TETHERING_TYPE_USB) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_USB_FEATURE);
2358         else if (type == TETHERING_TYPE_WIFI) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2359         else if (type == TETHERING_TYPE_BT) CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_BT_FEATURE);
2360
2361         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2362                         "parameter(tethering) is NULL\n");
2363
2364         __tethering_h *th = (__tethering_h *)tethering;
2365         tethering_type_e ti;
2366
2367         if (type != TETHERING_TYPE_ALL) {
2368                 th->changed_cb[type] = NULL;
2369                 th->changed_user_data[type] = NULL;
2370
2371                 return TETHERING_ERROR_NONE;
2372         }
2373
2374         /* TETHERING_TYPE_ALL */
2375         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
2376                 th->changed_cb[ti] = NULL;
2377                 th->changed_user_data[ti] = NULL;
2378         }
2379
2380         return TETHERING_ERROR_NONE;
2381 }
2382
2383 /**
2384  * @internal
2385  * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed.
2386  * @since_tizen 2.3
2387  * @privlevel platform
2388  * @privilege http://tizen.org/privilege/tethering.admin
2389  * @param[in]  tethering  The handle of tethering
2390  * @param[in]  callback  The callback function to invoke
2391  * @param[in]  user_data  The user data to be passed to the callback function
2392  * @retval  #TETHERING_ERROR_NONE  Successful
2393  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2394  * @see  tethering_wifi_unset_security_type_changed_cb()
2395  */
2396 API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data)
2397 {
2398         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2399
2400         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2401                         "parameter(tethering) is NULL\n");
2402         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2403                         "parameter(callback) is NULL\n");
2404
2405         __tethering_h *th = (__tethering_h *)tethering;
2406
2407         th->security_type_changed_cb = callback;
2408         th->security_type_user_data = user_data;
2409
2410         return TETHERING_ERROR_NONE;
2411
2412 }
2413
2414 /**
2415  * @internal
2416  * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed.
2417  * @since_tizen 2.3
2418  * @privlevel platform
2419  * @privilege http://tizen.org/privilege/tethering.admin
2420  * @param[in]  tethering  The handle of tethering
2421  * @param[in]  type  The type of tethering
2422  * @retval  #TETHERING_ERROR_NONE  Successful
2423  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2424  * @see  tethering_wifi_set_security_type_changed_cb()
2425  */
2426 API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering)
2427 {
2428         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2429
2430         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2431                         "parameter(tethering) is NULL\n");
2432
2433         __tethering_h *th = (__tethering_h *)tethering;
2434
2435         th->security_type_changed_cb = NULL;
2436         th->security_type_user_data = NULL;
2437
2438         return TETHERING_ERROR_NONE;
2439 }
2440
2441 /**
2442  * @internal
2443  * @brief Registers the callback function called when the visibility of SSID is changed.
2444  * @since_tizen 2.3
2445  * @privlevel platform
2446  * @privilege http://tizen.org/privilege/tethering.admin
2447  * @param[in]  tethering  The handle of tethering
2448  * @param[in]  callback  The callback function to invoke
2449  * @param[in]  user_data  The user data to be passed to the callback function
2450  * @retval  #TETHERING_ERROR_NONE  Successful
2451  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2452  * @see  tethering_wifi_unset_ssid_visibility_changed_cb_cb()
2453  */
2454 API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data)
2455 {
2456         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2457
2458         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2459                         "parameter(tethering) is NULL\n");
2460         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2461                         "parameter(callback) is NULL\n");
2462
2463         __tethering_h *th = (__tethering_h *)tethering;
2464
2465         th->ssid_visibility_changed_cb = callback;
2466         th->ssid_visibility_user_data = user_data;
2467
2468         return TETHERING_ERROR_NONE;
2469 }
2470
2471 /**
2472  * @internal
2473  * @brief Unregisters the callback function called when the visibility of SSID is changed.
2474  * @since_tizen 2.3
2475  * @privlevel platform
2476  * @privilege http://tizen.org/privilege/tethering.admin
2477  * @param[in]  tethering  The handle of tethering
2478  * @retval  #TETHERING_ERROR_NONE  Successful
2479  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2480  * @see  tethering_wifi_set_ssid_visibility_changed_cb()
2481  */
2482 API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering)
2483 {
2484         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2485
2486         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2487                         "parameter(tethering) is NULL\n");
2488
2489         __tethering_h *th = (__tethering_h *)tethering;
2490
2491         th->ssid_visibility_changed_cb = NULL;
2492         th->ssid_visibility_user_data = NULL;
2493
2494         return TETHERING_ERROR_NONE;
2495 }
2496
2497 /**
2498  * @internal
2499  * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed.
2500  * @since_tizen 2.3
2501  * @privlevel platform
2502  * @privilege http://tizen.org/privilege/tethering.admin
2503  * @param[in]  tethering  The handle of tethering
2504  * @param[in]  callback  The callback function to invoke
2505  * @param[in]  user_data  The user data to be passed to the callback function
2506  * @retval  #TETHERING_ERROR_NONE  Successful
2507  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2508  * @see  tethering_wifi_unset_passphrase_changed_cb()
2509  */
2510 API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data)
2511 {
2512         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2513
2514         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2515                         "parameter(tethering) is NULL\n");
2516         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2517                         "parameter(callback) is NULL\n");
2518
2519         __tethering_h *th = (__tethering_h *)tethering;
2520
2521         th->passphrase_changed_cb = callback;
2522         th->passphrase_user_data = user_data;
2523
2524         return TETHERING_ERROR_NONE;
2525 }
2526
2527 /**
2528  * @internal
2529  * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed.
2530  * @since_tizen 2.3
2531  * @privlevel platform
2532  * @privilege http://tizen.org/privilege/tethering.admin
2533  * @param[in]  tethering  The handle of tethering
2534  * @retval  #TETHERING_ERROR_NONE  Successful
2535  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2536  * @see  tethering_wifi_set_passphrase_changed_cb()
2537  */
2538 API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering)
2539 {
2540         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2541
2542         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2543                         "parameter(tethering) is NULL\n");
2544
2545         __tethering_h *th = (__tethering_h *)tethering;
2546
2547         th->passphrase_changed_cb = NULL;
2548         th->passphrase_user_data = NULL;
2549
2550         return TETHERING_ERROR_NONE;
2551 }
2552
2553 /**
2554  * @internal
2555  * @brief Sets the security type of Wi-Fi tethering.
2556  * @since_tizen 2.3
2557  * @privlevel platform
2558  * @privilege http://tizen.org/privilege/tethering.admin
2559  * @remarks This change is applied next time Wi-Fi tethering is enabled
2560  * @param[in]  tethering  The handle of tethering
2561  * @param[in]  type  The security type
2562  * @return 0 on success, otherwise negative error value.
2563  * @retval  #TETHERING_ERROR_NONE  Successful
2564  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2565  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2566  * @see  tethering_wifi_get_security_type()
2567  */
2568 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
2569 {
2570         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2571
2572         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2573                         "parameter(tethering) is NULL\n");
2574
2575         __tethering_h *th = (__tethering_h *)tethering;
2576         tethering_error_e ret = TETHERING_ERROR_NONE;
2577
2578         ret = __set_security_type(type);
2579         if (ret == TETHERING_ERROR_NONE) {
2580
2581                 __send_dbus_signal(th->client_bus,
2582                                 SIGNAL_NAME_SECURITY_TYPE_CHANGED,
2583                                 type == TETHERING_WIFI_SECURITY_TYPE_NONE ?
2584                                 TETHERING_WIFI_SECURITY_TYPE_OPEN_STR :
2585                                 TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR);
2586         }
2587         return ret;
2588 }
2589
2590 /**
2591  * @internal
2592  * @brief Gets the security type of Wi-Fi tethering.
2593  * @since_tizen 2.3
2594  * @privlevel platform
2595  * @privilege http://tizen.org/privilege/tethering.admin
2596  * @param[in]  tethering  The handle of tethering
2597  * @param[out]  type  The security type
2598  * @return 0 on success, otherwise negative error value.
2599  * @retval  #TETHERING_ERROR_NONE  Successful
2600  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2601  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2602  * @see  tethering_wifi_set_security_type()
2603  */
2604 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
2605 {
2606         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2607
2608         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2609                         "parameter(type) is NULL\n");
2610
2611         return __get_security_type(type);
2612 }
2613
2614 /**
2615  * @internal
2616  * @brief Sets the SSID (service set identifier).
2617  * @since_tizen 2.3
2618  * @privlevel platform
2619  * @privilege http://tizen.org/privilege/tethering.admin
2620  * @details If SSID is not set, Device name is used as SSID
2621  * @remarks This change is applied next time Wi-Fi tethering is enabled with same @a tethering handle
2622  * @param[in]  tethering  The handle of tethering
2623  * @param[out]  ssid  The SSID
2624  * @return 0 on success, otherwise negative error value.
2625  * @retval  #TETHERING_ERROR_NONE  Successful
2626  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2627  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2628  */
2629 API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid)
2630 {
2631         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2632
2633         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2634                         "parameter(tethering) is NULL\n");
2635         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2636                         "parameter(ssid) is NULL\n");
2637
2638         __tethering_h *th = (__tethering_h *)tethering;
2639         char *p_ssid = NULL;
2640         int ssid_len = 0;
2641
2642         ssid_len = strlen(ssid);
2643         if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) {
2644                 ERR("parameter(ssid) is too long");
2645                 return TETHERING_ERROR_INVALID_PARAMETER;
2646         }
2647
2648         p_ssid = strdup(ssid);
2649         _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
2650                         "strdup is failed\n");
2651
2652         if (th->ssid)
2653                 free(th->ssid);
2654         th->ssid = p_ssid;
2655
2656         return TETHERING_ERROR_NONE;
2657 }
2658
2659 /**
2660  * @internal
2661  * @brief Gets the SSID (service set identifier).
2662  * @since_tizen 2.3
2663  * @privlevel platform
2664  * @privilege http://tizen.org/privilege/tethering.admin
2665  * @remarks @a ssid must be released with free() by you.
2666  * @param[in]  tethering  The handle of tethering
2667  * @param[out]  ssid  The SSID
2668  * @return 0 on success, otherwise negative error value.
2669  * @retval  #TETHERING_ERROR_NONE  Successful
2670  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2671  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2672  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2673  */
2674 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
2675 {
2676         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2677
2678         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2679                         "parameter(tethering) is NULL\n");
2680         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2681                         "parameter(ssid) is NULL\n");
2682         DBG("+\n");
2683
2684         __tethering_h *th = (__tethering_h *)tethering;
2685         char val[TETHERING_WIFI_SSID_MAX_LEN + 1] = {0, };
2686
2687         if (!tethering_is_enabled(NULL, TETHERING_TYPE_WIFI)) {
2688                 if (th->ssid != NULL) {
2689                         DBG("Private SSID is set\n");
2690                         *ssid = strdup(th->ssid);
2691                 } else {
2692                         if (__get_ssid_from_vconf(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
2693                                                 val, sizeof(val)) == false) {
2694                                 return TETHERING_ERROR_OPERATION_FAILED;
2695                         }
2696                         *ssid = strdup(val);
2697                 }
2698         } else {
2699                 if (__get_ssid_from_vconf(VCONFKEY_MOBILE_HOTSPOT_SSID,
2700                                         val, sizeof(val)) == false) {
2701                         return TETHERING_ERROR_OPERATION_FAILED;
2702                 }
2703                 *ssid = strdup(val);
2704         }
2705
2706         if (*ssid == NULL) {
2707                 ERR("strdup is failed\n");
2708                 return TETHERING_ERROR_OUT_OF_MEMORY;
2709         }
2710
2711         return TETHERING_ERROR_NONE;
2712 }
2713
2714 /**
2715  * @internal
2716  * @brief Sets the visibility of SSID(service set identifier).
2717  * @since_tizen 2.3
2718  * @privlevel platform
2719  * @privilege http://tizen.org/privilege/tethering.admin
2720  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
2721  * @remarks This change is applied next time Wi-Fi tethering is enabled
2722  * @param[in]  tethering  The handle of tethering
2723  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
2724  * @return 0 on success, otherwise negative error value.
2725  * @retval  #TETHERING_ERROR_NONE  Successful
2726  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2727  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2728  * @see  tethering_wifi_get_ssid_visibility()
2729  */
2730 API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
2731 {
2732         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2733
2734         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2735                         "parameter(tethering) is NULL\n");
2736
2737         __tethering_h *th = (__tethering_h *)tethering;
2738         tethering_error_e ret = TETHERING_ERROR_NONE;
2739
2740         ret = __set_visible(visible);
2741         if (ret == TETHERING_ERROR_NONE) {
2742
2743                 __send_dbus_signal(th->client_bus,
2744                                 SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
2745                                 visible ? SIGNAL_MSG_SSID_VISIBLE :
2746                                 SIGNAL_MSG_SSID_HIDE);
2747         }
2748         return ret;
2749 }
2750
2751 /**
2752  * @internal
2753  * @brief Gets the visibility of SSID(service set identifier).
2754  * @since_tizen 2.3
2755  * @privlevel platform
2756  * @privilege http://tizen.org/privilege/tethering.admin
2757  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
2758  * @param[in]  tethering  The handle of tethering
2759  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
2760  * @return 0 on success, otherwise negative error value.
2761  * @retval  #TETHERING_ERROR_NONE  Successful
2762  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2763  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2764  * @see  tethering_wifi_set_ssid_visibility()
2765  */
2766 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
2767 {
2768         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2769
2770         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2771                         "parameter(visible) is NULL\n");
2772
2773         return __get_visible(visible);
2774 }
2775
2776 /**
2777  * @internal
2778  * @brief Sets the passphrase.
2779  * @since_tizen 2.3
2780  * @privlevel platform
2781  * @privilege http://tizen.org/privilege/tethering.admin
2782  * @remarks This change is applied next time Wi-Fi tethering is enabled
2783  * @param[in]  tethering  The handle of tethering
2784  * @param[in]  passphrase  The passphrase
2785  * @return 0 on success, otherwise negative error value.
2786  * @retval  #TETHERING_ERROR_NONE  Successful
2787  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2788  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2789  * @see  tethering_wifi_get_passphrase()
2790  */
2791 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
2792 {
2793         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2794
2795         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2796                         "parameter(tethering) is NULL\n");
2797         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2798                         "parameter(passphrase) is NULL\n");
2799
2800         __tethering_h *th = (__tethering_h *)tethering;
2801         GDBusProxy *proxy = th->client_bus_proxy;
2802         GVariant *parameters;
2803         GError *error = NULL;
2804         int passphrase_len = 0;
2805         int ret = 0;
2806
2807         DBG("+");
2808         passphrase_len = strlen(passphrase);
2809         if (passphrase_len < TETHERING_WIFI_KEY_MIN_LEN ||
2810                         passphrase_len > TETHERING_WIFI_KEY_MAX_LEN) {
2811                 ERR("parameter(passphrase) is too short or long\n");
2812                 return TETHERING_ERROR_INVALID_PARAMETER;
2813         }
2814
2815         parameters = g_dbus_proxy_call_sync(proxy, "set_wifi_tethering_passphrase",
2816                         g_variant_new("(s)", passphrase), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2817
2818         if (error) {
2819                 //LCOV_EXCL_START
2820                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
2821
2822                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
2823                         ret = TETHERING_ERROR_PERMISSION_DENIED;
2824                 else
2825                         ret = TETHERING_ERROR_OPERATION_FAILED;
2826
2827                 g_error_free(error);
2828                 return ret;
2829                 //LCOV_EXCL_STOP
2830         }
2831
2832         g_variant_get(parameters, "(u)", &ret);
2833         g_variant_unref(parameters);
2834
2835         if (ret == TETHERING_ERROR_NONE) {
2836                 __send_dbus_signal(th->client_bus,
2837                                 SIGNAL_NAME_PASSPHRASE_CHANGED, NULL);
2838         }
2839
2840         DBG("-");
2841         return ret;
2842 }
2843
2844 /**
2845  * @internal
2846  * @brief Gets the passphrase.
2847  * @since_tizen 2.3
2848  * @privlevel platform
2849  * @privilege http://tizen.org/privilege/tethering.admin
2850  * @remarks @a passphrase must be released with free() by you.
2851  * @param[in]  tethering  The handle of tethering
2852  * @param[out]  passphrase  The passphrase
2853  * @return 0 on success, otherwise negative error value.
2854  * @retval  #TETHERING_ERROR_NONE  Successful
2855  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2856  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2857  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2858  * @see  tethering_wifi_set_passphrase()
2859  */
2860 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
2861 {
2862         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2863
2864         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2865                         "parameter(tethering) is NULL\n");
2866         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2867                         "parameter(passphrase) is NULL\n");
2868
2869         __tethering_h *th = (__tethering_h *)tethering;
2870         GDBusProxy *proxy = th->client_bus_proxy;
2871         GVariant *parameters;
2872         GError *error = NULL;
2873         unsigned int len = 0;
2874         tethering_error_e ret = TETHERING_ERROR_NONE;
2875
2876         parameters = g_dbus_proxy_call_sync(proxy, "get_wifi_tethering_passphrase",
2877                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
2878
2879         if (error) {
2880                 //LCOV_EXCL_START
2881                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
2882
2883                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
2884                         ret = TETHERING_ERROR_PERMISSION_DENIED;
2885                 else
2886                         ret = TETHERING_ERROR_OPERATION_FAILED;
2887
2888                 g_error_free(error);
2889                 return ret;
2890                 //LCOV_EXCL_STOP
2891         }
2892
2893         if (parameters != NULL) {
2894                 g_variant_get(parameters, "(siu)", passphrase, &len, &ret);
2895                 g_variant_unref(parameters);
2896         }
2897
2898         return TETHERING_ERROR_NONE;
2899 }
2900
2901 API int tethering_wifi_set_channel(tethering_h tethering, int channel)
2902 {
2903         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2904         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2905                         "parameter(tethering) is NULL\n");
2906
2907         __tethering_h *th = (__tethering_h *)tethering;
2908         th->channel = channel;
2909
2910         return TETHERING_ERROR_NONE;
2911 }
2912
2913 API int tethering_wifi_get_channel(tethering_h tethering, int *channel)
2914 {
2915         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2916         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2917                         "parameter(tethering) is NULL\n");
2918
2919         _retvm_if(channel == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2920                         "parameter(channel) is NULL\n");
2921
2922         __tethering_h *th = (__tethering_h *)tethering;
2923         *channel = th->channel;
2924
2925         return TETHERING_ERROR_NONE;
2926 }
2927
2928 API int tethering_wifi_set_mode(tethering_h tethering, tethering_wifi_mode_type_e type)
2929 {
2930         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2931         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2932                         "parameter(tethering) is NULL\n");
2933
2934         __tethering_h *th = (__tethering_h *)tethering;
2935
2936         th->mode_type = type;
2937
2938         return TETHERING_ERROR_NONE;
2939 }
2940
2941 API int tethering_wifi_get_mode(tethering_h tethering, tethering_wifi_mode_type_e *type)
2942 {
2943         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2944         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2945                         "parameter(tethering) is NULL\n");
2946         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2947                         "parameter(type) is NULL\n");
2948
2949         __tethering_h *th = (__tethering_h *)tethering;
2950         *type = th->mode_type;
2951
2952         return TETHERING_ERROR_NONE;
2953 }
2954
2955
2956 /**
2957  * @internal
2958  * @brief Reload the settings (SSID / Passphrase / Security type / SSID visibility).
2959  * @since_tizen 2.3
2960  * @privlevel platform
2961  * @privilege http://tizen.org/privilege/tethering.admin
2962  * @remarks Connected devices via Wi-Fi tethering or MobileAP will be disconnected when the settings are reloaded
2963  * @param[in]  tethering  The handle of tethering
2964  * @param[in]  callback  The callback function to invoke
2965  * @param[in]  user_data  The user data to be passed to the callback function
2966  * @return 0 on success, otherwise negative error value.
2967  * @retval  #TETHERING_ERROR_NONE  Successful
2968  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2969  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2970  */
2971 API int tethering_wifi_reload_settings(tethering_h tethering, tethering_wifi_settings_reloaded_cb callback, void *user_data)
2972
2973 {
2974         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
2975
2976         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2977                         "parameter(tethering) is NULL\n");
2978         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2979                         "parameter(callback) is NULL\n");
2980
2981         __tethering_h *th = (__tethering_h *)tethering;
2982         _softap_settings_t set = {"", "", "", 0, false};
2983         GDBusProxy *proxy = th->client_bus_proxy;
2984         int ret = 0;
2985
2986         DBG("+\n");
2987
2988         if (th->settings_reloaded_cb) {
2989                 ERR("Operation in progress\n");
2990                 return TETHERING_ERROR_OPERATION_FAILED;
2991         }
2992
2993         ret = __prepare_wifi_settings(tethering, &set);
2994         if (ret != TETHERING_ERROR_NONE) {
2995                 ERR("softap settings initialization failed\n");
2996                 return TETHERING_ERROR_OPERATION_FAILED;
2997         }
2998
2999         th->settings_reloaded_cb = callback;
3000         th->settings_reloaded_user_data = user_data;
3001
3002         g_dbus_proxy_call(proxy, "reload_wifi_settings",
3003                         g_variant_new("(sssiiii)", set.ssid, set.key, set.mode, set.channel, set.visibility, set.mac_filter, set.sec_type),
3004                         G_DBUS_CALL_FLAGS_NONE, -1, th->cancellable,
3005                         (GAsyncReadyCallback) __settings_reloaded_cb, (gpointer)tethering);
3006
3007         return TETHERING_ERROR_NONE;
3008 }
3009
3010 API int tethering_wifi_set_mac_filter(tethering_h tethering, bool mac_filter)
3011 {
3012         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
3013
3014         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3015                         "parameter(tethering) is NULL\n");
3016
3017         __tethering_h *th = (__tethering_h *)tethering;
3018         th->mac_filter = mac_filter;
3019
3020         return TETHERING_ERROR_NONE;
3021 }
3022
3023 API int tethering_wifi_get_mac_filter(tethering_h tethering, bool *mac_filter)
3024 {
3025         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
3026
3027         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3028                         "parameter(mac_filter) is NULL\n");
3029         _retvm_if(mac_filter == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3030                         "parameter(mac_filter) is NULL\n");
3031
3032         __tethering_h *th = (__tethering_h *)tethering;
3033         *mac_filter = th->mac_filter;
3034
3035         return TETHERING_ERROR_NONE;
3036 }
3037
3038 static int __add_mac_to_file(const char *filepath, const char *mac)
3039 {
3040         FILE *fp = NULL;
3041         char line[MAX_BUF_SIZE] = "\0";
3042         bool mac_exist = false;
3043
3044         fp = fopen(filepath, "a+");
3045         if (!fp) {
3046                 ERR("fopen is failed\n");
3047                 return TETHERING_ERROR_OPERATION_FAILED;
3048         }
3049
3050         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3051                 if (strncmp(mac, line, 17) == 0) {
3052                         DBG("MAC %s already exist in the list\n", mac);
3053                         mac_exist = true;
3054                         break;
3055                 }
3056         }
3057
3058         if (!mac_exist)
3059                 fprintf(fp, "%s\n", mac);
3060
3061         fclose(fp);
3062
3063         return TETHERING_ERROR_NONE;
3064 }
3065
3066 static int __remove_mac_from_file(const char *filepath, const char *mac)
3067 {
3068         FILE *fp = NULL;
3069         FILE *fp1 = NULL;
3070         char line[MAX_BUF_SIZE] = "\0";
3071
3072         fp = fopen(filepath, "r");
3073         if (!fp) {
3074                 ERR("fopen is failed\n");
3075                 return TETHERING_ERROR_OPERATION_FAILED;
3076         }
3077
3078         fp1 = fopen(TEMP_LIST, "w+");
3079         if (!fp1) {
3080                 fclose(fp);
3081                 ERR("fopen is failed\n");
3082                 return TETHERING_ERROR_OPERATION_FAILED;
3083         }
3084
3085         while (fgets(line, MAX_BUF_SIZE, fp) != NULL) {
3086                 if (strncmp(mac, line, 17) == 0)
3087                         DBG("MAC %s found in the list\n", mac);
3088                 else
3089                         fprintf(fp1, "%s", line);
3090         }
3091
3092         fclose(fp);
3093         fclose(fp1);
3094
3095         if ((strcmp(filepath, ALLOWED_LIST) == 0))
3096                 rename(TEMP_LIST, ALLOWED_LIST);
3097         else if ((strcmp(filepath, BLOCKED_LIST) == 0))
3098                 rename(TEMP_LIST, BLOCKED_LIST);
3099
3100         return TETHERING_ERROR_NONE;
3101 }
3102
3103 API int tethering_wifi_add_allowed_mac_list(tethering_h tethering, const char *mac)
3104 {
3105         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
3106
3107         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3108                         "parameter(tethering) is NULL\n");
3109         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3110                         "parameter(mac) is NULL\n");
3111
3112         return __add_mac_to_file(ALLOWED_LIST, mac);
3113 }
3114
3115 API int tethering_wifi_remove_allowed_mac_list(tethering_h tethering, const char *mac)
3116 {
3117         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3118                         "parameter(tethering) is NULL\n");
3119         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3120                         "parameter(mac) is NULL\n");
3121
3122         return __remove_mac_from_file(ALLOWED_LIST, mac);
3123 }
3124
3125 API int tethering_wifi_add_blocked_mac_list(tethering_h tethering, const char *mac)
3126 {
3127         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3128                         "parameter(tethering) is NULL\n");
3129         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3130                         "parameter(mac) is NULL\n");
3131
3132         return __add_mac_to_file(BLOCKED_LIST, mac);
3133 }
3134
3135 API int tethering_wifi_remove_blocked_mac_list(tethering_h tethering, const char *mac)
3136 {
3137         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3138                         "parameter(tethering) is NULL\n");
3139         _retvm_if(mac == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3140                         "parameter(mac) is NULL\n");
3141
3142         return __remove_mac_from_file(BLOCKED_LIST, mac);
3143 }
3144
3145 API int tethering_wifi_enable_dhcp(tethering_h tethering, bool enable)
3146 {
3147         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
3148
3149         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3150                         "parameter(tethering) is NULL\n");
3151
3152         GVariant *parameters;
3153         GError *error = NULL;
3154         guint result;
3155
3156         __tethering_h *th = (__tethering_h *)tethering;
3157
3158         GDBusProxy *proxy = th->client_bus_proxy;
3159
3160         parameters = g_dbus_proxy_call_sync(proxy, "enable_dhcp",
3161                         g_variant_new("(b)", enable),
3162                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3163
3164         if (error) {
3165                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3166                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3167                         result = TETHERING_ERROR_PERMISSION_DENIED;
3168                 else
3169                         result = TETHERING_ERROR_OPERATION_FAILED;
3170
3171                 g_error_free(error);
3172                 th->dhcp_enabled = false;
3173
3174                 return result;
3175         }
3176
3177         g_variant_get(parameters, "(u)", &result);
3178         g_variant_unref(parameters);
3179
3180         if (enable)
3181                 th->dhcp_enabled = true;
3182         else
3183                 th->dhcp_enabled = false;
3184
3185         return TETHERING_ERROR_NONE;
3186 }
3187
3188 API int tethering_wifi_set_dhcp_range(tethering_h tethering, char *rangestart, char *rangestop)
3189 {
3190         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
3191
3192         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3193                         "parameter(tethering) is NULL\n");
3194         _retvm_if(rangestart == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3195                         "parameter(rangestart) is NULL\n");
3196         _retvm_if(rangestop == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3197                         "parameter(rangestop) is NULL\n");
3198
3199         GVariant *parameters;
3200         GError *error = NULL;
3201         guint result;
3202
3203         __tethering_h *th = (__tethering_h *)tethering;
3204
3205         GDBusProxy *proxy = th->client_bus_proxy;
3206
3207         parameters = g_dbus_proxy_call_sync(proxy, "dhcp_range",
3208                         g_variant_new("(ss)", rangestart, rangestop),
3209                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
3210         if (error) {
3211                 ERR("g_dbus_proxy_call_sync failed because  %s\n", error->message);
3212
3213                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
3214                         result = TETHERING_ERROR_PERMISSION_DENIED;
3215                 else
3216                         result = TETHERING_ERROR_OPERATION_FAILED;
3217
3218                 g_error_free(error);
3219                 th->dhcp_enabled = false;
3220
3221                 return result;
3222         }
3223
3224         g_variant_get(parameters, "(u)", &result);
3225         g_variant_unref(parameters);
3226
3227         th->dhcp_enabled = true;
3228
3229         return TETHERING_ERROR_NONE;
3230 }
3231
3232 API int tethering_wifi_is_dhcp_enabled(tethering_h tethering, bool *dhcp_enabled)
3233 {
3234         CHECK_FEATURE_SUPPORTED(TETHERING_FEATURE, TETHERING_WIFI_FEATURE);
3235         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3236                         "parameter(tethering) is NULL\n");
3237         _retvm_if(dhcp_enabled == NULL, TETHERING_ERROR_INVALID_PARAMETER,
3238                         "parameter(dhcp_enabled) is NULL\n");
3239
3240         __tethering_h *th = (__tethering_h *)tethering;
3241         *dhcp_enabled = th->dhcp_enabled;
3242
3243         return TETHERING_ERROR_NONE;
3244 }