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