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