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