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