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