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