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