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