Merge branch 'master' into tizen_2.1
[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
27 #include <vconf.h>
28
29 #include "tethering-client-stub.h"
30 #include "marshal.h"
31 #include "tethering_private.h"
32
33 static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
34 static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
35 static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
36 static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
37 static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
38 static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
39 static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
40 static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data);
41 static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data);
42 static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data);
43 static void __handle_security_type_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
44 static void __handle_ssid_visibility_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
45 static void __handle_passphrase_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
46
47 static __tethering_sig_t sigs[] = {
48         {SIGNAL_NAME_NET_CLOSED, __handle_net_closed},
49         {SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on},
50         {SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off},
51         {SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on},
52         {SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off},
53         {SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on},
54         {SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off},
55         {SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout},
56         {SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode},
57         {SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode},
58         {SIGNAL_NAME_SECURITY_TYPE_CHANGED, __handle_security_type_changed},
59         {SIGNAL_NAME_SSID_VISIBILITY_CHANGED, __handle_ssid_visibility_changed},
60         {SIGNAL_NAME_PASSPHRASE_CHANGED, __handle_passphrase_changed},
61         {"", NULL}};
62
63 static bool __any_tethering_is_enabled(tethering_h tethering)
64 {
65         if (tethering_is_enabled(tethering, TETHERING_TYPE_USB) ||
66                         tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) ||
67                         tethering_is_enabled(tethering, TETHERING_TYPE_BT))
68                 return true;
69
70         return false;
71 }
72
73 static tethering_error_e __get_error(int agent_error)
74 {
75         tethering_error_e err = TETHERING_ERROR_NONE;
76
77         switch (agent_error) {
78         case MOBILE_AP_ERROR_NONE:
79                 err = TETHERING_ERROR_NONE;
80                 break;
81
82         case MOBILE_AP_ERROR_RESOURCE:
83                 err = TETHERING_ERROR_OUT_OF_MEMORY;
84                 break;
85
86         case MOBILE_AP_ERROR_INTERNAL:
87                 err = TETHERING_ERROR_OPERATION_FAILED;
88                 break;
89
90         case MOBILE_AP_ERROR_INVALID_PARAM:
91                 err = TETHERING_ERROR_INVALID_PARAMETER;
92                 break;
93
94         case MOBILE_AP_ERROR_ALREADY_ENABLED:
95                 err = TETHERING_ERROR_OPERATION_FAILED;
96                 break;
97
98         case MOBILE_AP_ERROR_NOT_ENABLED:
99                 err = TETHERING_ERROR_NOT_ENABLED;
100                 break;
101
102         case MOBILE_AP_ERROR_NET_OPEN:
103                 err = TETHERING_ERROR_OPERATION_FAILED;
104                 break;
105
106         case MOBILE_AP_ERROR_NET_CLOSE:
107                 err = TETHERING_ERROR_OPERATION_FAILED;
108                 break;
109
110         case MOBILE_AP_ERROR_DHCP:
111                 err = TETHERING_ERROR_OPERATION_FAILED;
112                 break;
113
114         case MOBILE_AP_ERROR_IN_PROGRESS:
115                 err = TETHERING_ERROR_OPERATION_FAILED;
116                 break;
117
118         case MOBILE_AP_ERROR_NOT_PERMITTED:
119                 err = TETHERING_ERROR_NOT_PERMITTED;
120                 break;
121
122         default:
123                 ERR("Not defined error : %d\n", agent_error);
124                 err = TETHERING_ERROR_OPERATION_FAILED;
125                 break;
126         }
127
128         return err;
129 }
130
131 static void __handle_dhcp(DBusGProxy *proxy, const char *member,
132                 guint interface, const char *ip, const char *mac,
133                 const char *name, guint timestamp, gpointer user_data)
134 {
135         DBG("+\n");
136
137         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
138
139         __tethering_h *th = (__tethering_h *)user_data;
140         bool opened = false;
141         tethering_type_e type = 0;
142         tethering_connection_state_changed_cb ccb = NULL;
143         __tethering_client_h client = {0, };
144         void *data = NULL;
145
146         if (!g_strcmp0(member, "DhcpConnected")) {
147                 opened = true;
148         } else if (!g_strcmp0(member, "DhcpLeaseDeleted")) {
149                 opened = false;
150         } else {
151                 ERR("Unknown event [%s]\n", member);
152                 return;
153         }
154
155         if (interface == MOBILE_AP_TYPE_USB)
156                 type = TETHERING_TYPE_USB;
157         else if (interface == MOBILE_AP_TYPE_WIFI)
158                 type = TETHERING_TYPE_WIFI;
159         else if (interface == MOBILE_AP_TYPE_BT)
160                 type = TETHERING_TYPE_BT;
161         else {
162                 ERR("Not supported tethering type [%d]\n", interface);
163                 return;
164         }
165
166         ccb = th->changed_cb[type];
167         if (ccb == NULL)
168                 return;
169         data = th->changed_user_data[type];
170
171         client.interface = type;
172         g_strlcpy(client.ip, ip, sizeof(client.ip));
173         g_strlcpy(client.mac, mac, sizeof(client.mac));
174         g_strlcpy(client.hostname, name, sizeof(client.hostname));
175         client.tm = (time_t)timestamp;
176
177         ccb((tethering_client_h)&client, opened, data);
178
179         return;
180 }
181
182 static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
183 {
184         DBG("+\n");
185
186         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
187
188         __tethering_h *th = (__tethering_h *)user_data;
189         tethering_type_e type = 0;
190         tethering_disabled_cb dcb = NULL;
191         void *data = NULL;
192         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_NETWORK_CLOSE;
193
194         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
195                 dcb = th->disabled_cb[type];
196                 if (dcb == NULL)
197                         continue;
198                 data = th->disabled_user_data[type];
199
200                 dcb(TETHERING_ERROR_NONE, type, code, data);
201         }
202
203         return;
204 }
205
206 static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
207 {
208         DBG("+\n");
209
210         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
211
212         __tethering_h *th = (__tethering_h *)user_data;
213         tethering_type_e type = TETHERING_TYPE_WIFI;
214         bool is_requested = false;
215         tethering_enabled_cb ecb = NULL;
216         void *data = NULL;
217
218         ecb = th->enabled_cb[type];
219         if (ecb == NULL)
220                 return;
221         data = th->enabled_user_data[type];
222
223         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
224 }
225
226 static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
227 {
228         DBG("+\n");
229
230         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
231
232         __tethering_h *th = (__tethering_h *)user_data;
233         tethering_type_e type = TETHERING_TYPE_WIFI;
234         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
235         tethering_disabled_cb dcb = NULL;
236         void *data = NULL;
237
238         dcb = th->disabled_cb[type];
239         if (dcb == NULL)
240                 return;
241         data = th->disabled_user_data[type];
242
243         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
244                 code = TETHERING_DISABLED_BY_WIFI_ON;
245         else if (!g_strcmp0(value_name, SIGNAL_MSG_TIMEOUT))
246                 code = TETHERING_DISABLED_BY_TIMEOUT;
247
248         dcb(TETHERING_ERROR_NONE, type, code, data);
249
250         return;
251 }
252
253 static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
254 {
255         DBG("+\n");
256
257         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
258
259         __tethering_h *th = (__tethering_h *)user_data;
260         tethering_type_e type = TETHERING_TYPE_USB;
261         bool is_requested = false;
262         tethering_enabled_cb ecb = NULL;
263         void *data = NULL;
264
265         ecb = th->enabled_cb[type];
266         if (ecb == NULL)
267                 return;
268         data = th->enabled_user_data[type];
269
270         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
271 }
272
273 static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
274 {
275         DBG("+\n");
276
277         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
278
279         __tethering_h *th = (__tethering_h *)user_data;
280         tethering_type_e type = TETHERING_TYPE_USB;
281         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
282         tethering_disabled_cb dcb = NULL;
283         void *data = NULL;
284
285         dcb = th->disabled_cb[type];
286         if (dcb == NULL)
287                 return;
288         data = th->disabled_user_data[type];
289
290         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
291                 code = TETHERING_DISABLED_BY_USB_DISCONNECTION;
292
293         dcb(TETHERING_ERROR_NONE, type, code, data);
294
295         return;
296 }
297
298 static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
299 {
300         DBG("+\n");
301
302         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
303
304         __tethering_h *th = (__tethering_h *)user_data;
305         tethering_type_e type = TETHERING_TYPE_BT;
306         bool is_requested = false;
307         tethering_enabled_cb ecb = NULL;
308         void *data = NULL;
309
310         ecb = th->enabled_cb[type];
311         if (ecb == NULL)
312                 return;
313         data = th->enabled_user_data[type];
314
315         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
316 }
317
318 static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
319 {
320         DBG("+\n");
321
322         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
323
324         __tethering_h *th = (__tethering_h *)user_data;
325         tethering_type_e type = TETHERING_TYPE_BT;
326         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
327         tethering_disabled_cb dcb = NULL;
328         void *data = NULL;
329
330         dcb = th->disabled_cb[type];
331         if (dcb == NULL)
332                 return;
333         data = th->disabled_user_data[type];
334
335         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
336                 code = TETHERING_DISABLED_BY_BT_OFF;
337         else if (!g_strcmp0(value_name, SIGNAL_MSG_TIMEOUT))
338                 code = TETHERING_DISABLED_BY_TIMEOUT;
339
340         dcb(TETHERING_ERROR_NONE, type, code, data);
341
342         return;
343 }
344
345 static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data)
346 {
347         DBG("+\n");
348
349         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
350
351         __tethering_h *th = (__tethering_h *)user_data;
352         tethering_type_e type = 0;
353         tethering_disabled_cb dcb = NULL;
354         void *data = NULL;
355         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_TIMEOUT;
356
357         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
358                 dcb = th->disabled_cb[type];
359                 if (dcb == NULL)
360                         continue;
361                 data = th->disabled_user_data[type];
362
363                 dcb(TETHERING_ERROR_NONE, type, code, data);
364         }
365 }
366
367 static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
368 {
369         DBG("+\n");
370
371         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
372
373         __tethering_h *th = (__tethering_h *)user_data;
374         tethering_type_e type = 0;
375         tethering_disabled_cb dcb = NULL;
376         void *data = NULL;
377         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY;
378
379         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
380                 dcb = th->disabled_cb[type];
381                 if (dcb == NULL)
382                         continue;
383                 data = th->disabled_user_data[type];
384
385                 dcb(TETHERING_ERROR_NONE, type, code, data);
386         }
387 }
388
389 static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
390 {
391         DBG("+\n");
392
393         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
394
395         __tethering_h *th = (__tethering_h *)user_data;
396         tethering_type_e type = 0;
397         tethering_disabled_cb dcb = NULL;
398         void *data = NULL;
399         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE;
400
401         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
402                 dcb = th->disabled_cb[type];
403                 if (dcb == NULL)
404                         continue;
405                 data = th->disabled_user_data[type];
406
407                 dcb(TETHERING_ERROR_NONE, type, code, data);
408         }
409 }
410
411 static void __handle_security_type_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
412 {
413         DBG("+\n");
414
415         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
416
417         __tethering_h *th = (__tethering_h *)user_data;
418         tethering_wifi_security_type_changed_cb scb = NULL;
419         void *data = NULL;
420         tethering_wifi_security_type_e security_type;
421
422         scb = th->security_type_changed_cb;
423         if (scb == NULL)
424                 return;
425
426         data = th->security_type_user_data;
427         if (g_strcmp0(value_name, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
428                 security_type = TETHERING_WIFI_SECURITY_TYPE_NONE;
429         else if (g_strcmp0(value_name, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
430                 security_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
431         else {
432                 ERR("Unknown security type : %s\n", value_name);
433                 return;
434         }
435
436         scb(security_type, data);
437
438         return;
439 }
440
441 static void __handle_ssid_visibility_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
442 {
443         DBG("+\n");
444
445         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
446
447         __tethering_h *th = (__tethering_h *)user_data;
448         tethering_wifi_ssid_visibility_changed_cb scb = NULL;
449         void *data = NULL;
450         bool visible = false;
451
452         scb = th->ssid_visibility_changed_cb;
453         if (scb == NULL)
454                 return;
455
456         data = th->ssid_visibility_user_data;
457         if (g_strcmp0(value_name, SIGNAL_MSG_SSID_VISIBLE) == 0)
458                 visible = true;
459
460         scb(visible, data);
461
462         return;
463 }
464
465 static void __handle_passphrase_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
466 {
467         DBG("+\n");
468
469         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
470
471         __tethering_h *th = (__tethering_h *)user_data;
472         tethering_wifi_passphrase_changed_cb pcb = NULL;
473         void *data = NULL;
474
475         pcb = th->passphrase_changed_cb;
476         if (pcb == NULL)
477                 return;
478
479         data = th->passphrase_user_data;
480
481         pcb(data);
482
483         return;
484 }
485
486 static void __cfm_cb(DBusGProxy *remoteobj, guint event, guint info,
487                 GError *g_error, gpointer user_data)
488 {
489         DBG("+\n");
490
491         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
492
493         tethering_h tethering = (tethering_h)user_data;
494         __tethering_h *th = (__tethering_h *)tethering;
495         DBusGProxy *proxy = th->client_bus_proxy;
496
497         tethering_type_e type = 0;
498         tethering_error_e error = __get_error(info);
499         bool is_requested = true;
500         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_REQUEST;
501
502         tethering_enabled_cb ecb = NULL;
503         tethering_disabled_cb dcb = NULL;
504         void *data = NULL;
505
506         if (g_error) {
507                 ERR("DBus error [%s]\n", g_error->message);
508                 g_error_free(g_error);
509                 return;
510         }
511
512         DBG("cfm event : %d info : %d\n", event, info);
513         switch (event) {
514         case MOBILE_AP_ENABLE_WIFI_TETHERING_CFM:
515                 type = TETHERING_TYPE_WIFI;
516                 ecb = th->enabled_cb[type];
517                 data = th->enabled_user_data[type];
518                 if (ecb)
519                         ecb(error, type, is_requested, data);
520                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
521                                 G_CALLBACK(__handle_wifi_tether_on),
522                                 (gpointer)tethering, NULL);
523                 break;
524
525         case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM:
526                 type = TETHERING_TYPE_WIFI;
527                 dcb = th->disabled_cb[type];
528                 data = th->disabled_user_data[type];
529                 if (dcb)
530                         dcb(error, type, code, data);
531                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
532                                 G_CALLBACK(__handle_wifi_tether_off),
533                                 (gpointer)tethering, NULL);
534                 break;
535
536         case MOBILE_AP_ENABLE_BT_TETHERING_CFM:
537                 type = TETHERING_TYPE_BT;
538                 ecb = th->enabled_cb[type];
539                 data = th->enabled_user_data[type];
540                 if (ecb)
541                         ecb(error, type, is_requested, data);
542                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
543                                 G_CALLBACK(__handle_bt_tether_on),
544                                 (gpointer)tethering, NULL);
545                 break;
546
547         case MOBILE_AP_DISABLE_BT_TETHERING_CFM:
548                 type = TETHERING_TYPE_BT;
549                 dcb = th->disabled_cb[type];
550                 data = th->disabled_user_data[type];
551                 if (dcb)
552                         dcb(error, type, code, data);
553                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
554                                 G_CALLBACK(__handle_bt_tether_off),
555                                 (gpointer)tethering, NULL);
556                 break;
557
558         case MOBILE_AP_ENABLE_USB_TETHERING_CFM:
559                 type = TETHERING_TYPE_USB;
560                 ecb = th->enabled_cb[type];
561                 data = th->enabled_user_data[type];
562                 if (ecb)
563                         ecb(error, type, is_requested, data);
564                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
565                                 G_CALLBACK(__handle_usb_tether_on),
566                                 (gpointer)tethering, NULL);
567                 break;
568
569         case MOBILE_AP_DISABLE_USB_TETHERING_CFM:
570                 type = TETHERING_TYPE_USB;
571                 dcb = th->disabled_cb[type];
572                 data = th->disabled_user_data[type];
573                 if (dcb)
574                         dcb(error, type, code, data);
575                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
576                                 G_CALLBACK(__handle_usb_tether_off),
577                                 (gpointer)tethering, NULL);
578                 break;
579
580         case MOBILE_AP_DISABLE_CFM:
581                 for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
582                         dcb = th->disabled_cb[type];
583                         if (dcb == NULL)
584                                 continue;
585                         data = th->disabled_user_data[type];
586
587                         dcb(error, type, code, data);
588                 }
589
590                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
591                                 G_CALLBACK(__handle_usb_tether_off),
592                                 (gpointer)tethering, NULL);
593                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
594                                 G_CALLBACK(__handle_wifi_tether_off),
595                                 (gpointer)tethering, NULL);
596                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
597                                 G_CALLBACK(__handle_bt_tether_off),
598                                 (gpointer)tethering, NULL);
599                 break;
600
601         default:
602                 ERR("Invalid event\n");
603                 return;
604         }
605
606         return;
607 }
608
609 static void __get_data_usage_cb(DBusGProxy *remoteobj, guint event,
610                 guint64 tx_bytes, guint64 rx_bytes,
611                 GError *error, gpointer user_data)
612 {
613         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
614
615         __tethering_h *th = (__tethering_h *)user_data;
616
617         if (th->data_usage_cb == NULL) {
618                 ERR("There is no data_usage_cb\n");
619                 return;
620         }
621
622         if (error || event != MOBILE_AP_GET_DATA_PACKET_USAGE_CFM) {
623                 if (error)  {
624                         ERR("DBus fail [%s]\n", error->message);
625                         g_error_free(error);
626                 }
627
628                 th->data_usage_cb(TETHERING_ERROR_OPERATION_FAILED,
629                                 0LL, 0LL, th->data_usage_user_data);
630
631                 th->data_usage_cb = NULL;
632                 th->data_usage_user_data = NULL;
633
634                 return;
635         }
636
637         th->data_usage_cb(TETHERING_ERROR_NONE,
638                         rx_bytes, tx_bytes, th->data_usage_user_data);
639
640         th->data_usage_cb = NULL;
641         th->data_usage_user_data = NULL;
642
643         return;
644 }
645
646 static void __ip_forward_cb(DBusGProxy *remoteobj, gint result,
647                 GError *error, gpointer user_data)
648 {
649         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
650
651         if (error) {
652                 ERR("DBus fail [%s]\n", error->message);
653                 g_error_free(error);
654         }
655
656         return;
657 }
658
659 static void __connect_signals(tethering_h tethering)
660 {
661         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
662
663         __tethering_h *th = (__tethering_h *)tethering;
664         DBusGProxy *proxy = th->client_bus_proxy;
665         int i = 0;
666
667         for (i = 0; sigs[i].cb != NULL; i++) {
668                 dbus_g_proxy_add_signal(proxy, sigs[i].name,
669                                 G_TYPE_STRING, G_TYPE_INVALID);
670                 dbus_g_proxy_connect_signal(proxy, sigs[i].name,
671                                 G_CALLBACK(sigs[i].cb), (gpointer)tethering, NULL);
672         }
673
674         dbus_g_object_register_marshaller(marshal_VOID__STRING_UINT_STRING_STRING_STRING_UINT,
675                         G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
676                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID);
677         dbus_g_proxy_add_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
678                         G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
679                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID);
680         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
681                         G_CALLBACK(__handle_dhcp), (gpointer)tethering, NULL);
682
683         return;
684 }
685
686 static void __disconnect_signals(tethering_h tethering)
687 {
688         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
689
690         __tethering_h *th = (__tethering_h *)tethering;
691         DBusGProxy *proxy = th->client_bus_proxy;
692
693         int i = 0;
694
695         for (i = 0; sigs[i].cb != NULL; i++) {
696                 dbus_g_proxy_disconnect_signal(proxy, sigs[i].name,
697                                 G_CALLBACK(sigs[i].cb), (gpointer)tethering);
698         }
699
700         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
701                         G_CALLBACK(__handle_dhcp), (gpointer)tethering);
702
703         return;
704 }
705
706 static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len)
707 {
708         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
709
710         switch (type) {
711         case TETHERING_TYPE_USB:
712                 g_strlcpy(buf, TETHERING_USB_IF, len);
713                 break;
714
715         case TETHERING_TYPE_WIFI:
716                 g_strlcpy(buf, TETHERING_WIFI_IF, len);
717                 break;
718
719         case TETHERING_TYPE_BT:
720                 g_strlcpy(buf, TETHERING_BT_IF, len);
721                 break;
722
723         default:
724                 ERR("Not supported type : %d\n", type);
725                 return false;
726         }
727
728         return true;
729 }
730
731 static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int len)
732 {
733         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
734
735         switch (type) {
736         case TETHERING_TYPE_USB:
737                 g_strlcpy(buf, TETHERING_USB_GATEWAY, len);
738                 break;
739
740         case TETHERING_TYPE_WIFI:
741                 g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len);
742                 break;
743
744         case TETHERING_TYPE_BT:
745                 g_strlcpy(buf, TETHERING_BT_GATEWAY, len);
746                 break;
747
748         default:
749                 ERR("Not supported type : %d\n", type);
750                 return false;
751         }
752
753         return true;
754 }
755
756 static void __deinit_cb(DBusGProxy *remoteobj,
757                 GError *error, gpointer user_data)
758 {
759         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
760
761         if (error) {
762                 ERR("DBus fail [%s]\n", error->message);
763                 g_error_free(error);
764         }
765
766         return;
767 }
768
769 static void __wifi_set_security_type_cb(DBusGProxy *remoteobj,
770                 GError *error, gpointer user_data)
771 {
772         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
773
774         tethering_h tethering = (tethering_h)user_data;
775         __tethering_h *th = (__tethering_h *)tethering;
776         DBusGProxy *proxy = th->client_bus_proxy;
777
778         if (error) {
779                 ERR("DBus fail [%s]\n", error->message);
780                 g_error_free(error);
781         }
782
783         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_SECURITY_TYPE_CHANGED,
784                         G_CALLBACK(__handle_security_type_changed),
785                         (gpointer)tethering, NULL);
786
787         return;
788 }
789
790 static void __wifi_set_ssid_visibility_cb(DBusGProxy *remoteobj,
791                 GError *error, gpointer user_data)
792 {
793         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
794
795         tethering_h tethering = (tethering_h)user_data;
796         __tethering_h *th = (__tethering_h *)tethering;
797         DBusGProxy *proxy = th->client_bus_proxy;
798
799         if (error) {
800                 ERR("DBus fail [%s]\n", error->message);
801                 g_error_free(error);
802         }
803
804         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
805                         G_CALLBACK(__handle_ssid_visibility_changed),
806                         (gpointer)tethering, NULL);
807
808         return;
809 }
810
811 static void __wifi_set_passphrase_cb(DBusGProxy *remoteobj,
812                 GError *error, gpointer user_data)
813 {
814         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
815
816         tethering_h tethering = (tethering_h)user_data;
817         __tethering_h *th = (__tethering_h *)tethering;
818         DBusGProxy *proxy = th->client_bus_proxy;
819
820         if (error) {
821                 ERR("DBus fail [%s]\n", error->message);
822                 g_error_free(error);
823         }
824
825         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_PASSPHRASE_CHANGED,
826                         G_CALLBACK(__handle_passphrase_changed),
827                         (gpointer)tethering, NULL);
828
829         return;
830 }
831
832 /**
833  * @brief  Creates the handle of tethering.
834  * @remarks  The @a tethering must be released tethering_destroy() by you.
835  * @param[out]  tethering  A handle of a new mobile ap handle on success
836  * @return  0 on success, otherwise a negative error value.
837  * @retval  #TETHERING_ERROR_NONE  Successful
838  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
839  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
840  * @retval  #TETHERING_ERROR_NOT_SUPPORT_API  API is not supported
841  * @see  tethering_destroy()
842  */
843 API int tethering_create(tethering_h *tethering)
844 {
845         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
846                         "parameter(tethering) is NULL\n");
847
848         __tethering_h *th = NULL;
849         GError *error = NULL;
850         int retry = TETHERING_DBUS_MAX_RETRY_COUNT;
851
852         th = (__tethering_h *)malloc(sizeof(__tethering_h));
853         _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
854                         "malloc is failed\n");
855         memset(th, 0x00, sizeof(__tethering_h));
856
857 #if !GLIB_CHECK_VERSION(2,35,0)
858         g_type_init();
859 #endif
860         th->client_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
861         if (error) {
862                 ERR("Couldn't connect to the System bus[%s]", error->message);
863                 g_error_free(error);
864                 free(th);
865                 return TETHERING_ERROR_OPERATION_FAILED;
866         }
867
868         th->client_bus_proxy = dbus_g_proxy_new_for_name(th->client_bus,
869                         TETHERING_SERVICE_NAME,
870                         TETHERING_SERVICE_OBJECT_PATH,
871                         TETHERING_SERVICE_INTERFACE);
872         if (!th->client_bus_proxy) {
873                 ERR("Couldn't create the proxy object");
874                 dbus_g_connection_unref(th->client_bus);
875                 free(th);
876                 return TETHERING_ERROR_OPERATION_FAILED;
877         }
878
879         while (retry--) {
880                 org_tizen_tethering_init(th->client_bus_proxy, &error);
881                 if (error != NULL) {
882                         ERR("Couldn't connect to the System bus[%s]",
883                                         error->message);
884
885                         if (error->code == DBUS_GERROR_SERVICE_UNKNOWN) {
886                                 DBG("Tethering is not supported\n");
887                                 g_error_free(error);
888                                 error = NULL;
889                                 dbus_g_connection_unref(th->client_bus);
890                                 free(th);
891                                 return TETHERING_ERROR_NOT_SUPPORT_API;
892                         }
893
894                         g_error_free(error);
895                         error = NULL;
896                         if (retry == 0) {
897                                 dbus_g_connection_unref(th->client_bus);
898                                 free(th);
899                                 return TETHERING_ERROR_OPERATION_FAILED;
900                         }
901                 } else {
902                         break;
903                 }
904         }
905
906         __connect_signals((tethering_h)th);
907
908         *tethering = (tethering_h)th;
909         DBG("Tethering Handle : 0x%X\n", th);
910
911         return TETHERING_ERROR_NONE;
912 }
913
914 /**
915  * @brief  Destroys the handle of tethering.
916  * @param[in]  tethering  The handle of tethering
917  * @return  0 on success, otherwise a negative error value.
918  * @retval  #TETHERING_ERROR_NONE  Successful
919  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
920  * @see  tethering_create()
921  */
922 API int tethering_destroy(tethering_h tethering)
923 {
924         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
925                         "parameter(tethering) is NULL\n");
926
927         __tethering_h *th = (__tethering_h *)tethering;
928
929         DBG("Tethering Handle : 0x%X\n", th);
930         __disconnect_signals(tethering);
931
932         org_tizen_tethering_deinit_async(th->client_bus_proxy, __deinit_cb,
933                         (gpointer)tethering);
934
935         if (th->ssid)
936                 free(th->ssid);
937         g_object_unref(th->client_bus_proxy);
938         dbus_g_connection_unref(th->client_bus);
939         memset(th, 0x00, sizeof(__tethering_h));
940         free(th);
941
942         return TETHERING_ERROR_NONE;
943 }
944
945 /**
946  * @brief Enables the tethering, asynchronously.
947  * @param[in]  tethering  The handle of tethering
948  * @param[in]  type  The type of tethering
949  * @return 0 on success, otherwise negative error value.
950  * @retval  #TETHERING_ERROR_NONE  Successful
951  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
952  * @post tethering_enabled_cb() will be invoked.
953  * @see  tethering_is_enabled()
954  * @see  tethering_disable()
955  */
956 API int tethering_enable(tethering_h tethering, tethering_type_e type)
957 {
958         DBG("+\n");
959
960         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
961                         "parameter(tethering) is NULL\n");
962
963         __tethering_h *th = (__tethering_h *)tethering;
964         DBusGProxy *proxy = th->client_bus_proxy;
965
966         switch (type) {
967         case TETHERING_TYPE_USB:
968                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
969                                 G_CALLBACK(__handle_usb_tether_on),
970                                 (gpointer)tethering);
971                 org_tizen_tethering_enable_usb_tethering_async(proxy,
972                                 __cfm_cb, (gpointer)tethering);
973                 break;
974
975         case TETHERING_TYPE_WIFI:
976                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
977                                 G_CALLBACK(__handle_wifi_tether_on),
978                                 (gpointer)tethering);
979                 org_tizen_tethering_enable_wifi_tethering_async(proxy,
980                                 th->ssid ? th->ssid : "", "", false,
981                                 __cfm_cb, (gpointer)tethering);
982                 break;
983
984         case TETHERING_TYPE_BT:
985                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
986                                 G_CALLBACK(__handle_bt_tether_on),
987                                 (gpointer)tethering);
988                 org_tizen_tethering_enable_bt_tethering_async(proxy,
989                                 __cfm_cb, (gpointer)tethering);
990
991                 break;
992
993         case TETHERING_TYPE_ALL:
994                 /* TETHERING_TYPE_USB */
995                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
996                                 G_CALLBACK(__handle_usb_tether_on),
997                                 (gpointer)tethering);
998                 org_tizen_tethering_enable_usb_tethering_async(proxy,
999                                 __cfm_cb, (gpointer)tethering);
1000
1001                 /* TETHERING_TYPE_WIFI */
1002                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
1003                                 G_CALLBACK(__handle_wifi_tether_on),
1004                                 (gpointer)tethering);
1005                 org_tizen_tethering_enable_wifi_tethering_async(proxy,
1006                                 th->ssid ? th->ssid : "", "", false,
1007                                 __cfm_cb, (gpointer)tethering);
1008
1009                 /* TETHERING_TYPE_BT */
1010                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
1011                                 G_CALLBACK(__handle_bt_tether_on),
1012                                 (gpointer)tethering);
1013                 org_tizen_tethering_enable_bt_tethering_async(proxy,
1014                                 __cfm_cb, (gpointer)tethering);
1015                 break;
1016
1017         default:
1018                 ERR("Unknown type : %d\n", type);
1019                 return TETHERING_ERROR_INVALID_PARAMETER;
1020         }
1021
1022         return TETHERING_ERROR_NONE;
1023 }
1024
1025 /**
1026  * @brief Disables the tethering, asynchronously.
1027  * @param[in]  tethering  The handle of tethering
1028  * @param[in]  type  The type of tethering
1029  * @return 0 on success, otherwise negative error value.
1030  * @retval  #TETHERING_ERROR_NONE  Successful
1031  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1032  * @post tethering_disabled_cb() will be invoked.
1033  * @see  tethering_is_enabled()
1034  * @see  tethering_enable()
1035  */
1036 API int tethering_disable(tethering_h tethering, tethering_type_e type)
1037 {
1038         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1039                         "parameter(tethering) is NULL\n");
1040
1041         __tethering_h *th = (__tethering_h *)tethering;
1042         DBusGProxy *proxy = th->client_bus_proxy;
1043
1044         switch (type) {
1045         case TETHERING_TYPE_USB:
1046                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
1047                                 G_CALLBACK(__handle_usb_tether_off),
1048                                 (gpointer)tethering);
1049                 org_tizen_tethering_disable_usb_tethering_async(proxy,
1050                                 __cfm_cb, (gpointer)tethering);
1051                 break;
1052
1053         case TETHERING_TYPE_WIFI:
1054                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
1055                                 G_CALLBACK(__handle_wifi_tether_off),
1056                                 (gpointer)tethering);
1057                 org_tizen_tethering_disable_wifi_tethering_async(proxy,
1058                                 __cfm_cb, (gpointer)tethering);
1059                 break;
1060         case TETHERING_TYPE_BT:
1061                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
1062                                 G_CALLBACK(__handle_bt_tether_off),
1063                                 (gpointer)tethering);
1064                 org_tizen_tethering_disable_bt_tethering_async(proxy,
1065                                 __cfm_cb, (gpointer)tethering);
1066                 break;
1067
1068         case TETHERING_TYPE_ALL:
1069                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
1070                                 G_CALLBACK(__handle_usb_tether_off),
1071                                 (gpointer)tethering);
1072                 org_tizen_tethering_disable_usb_tethering_async(proxy,
1073                                 __cfm_cb, (gpointer)tethering);
1074
1075                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
1076                                 G_CALLBACK(__handle_wifi_tether_off),
1077                                 (gpointer)tethering);
1078                 org_tizen_tethering_disable_wifi_tethering_async(proxy,
1079                                 __cfm_cb, (gpointer)tethering);
1080
1081                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
1082                                 G_CALLBACK(__handle_bt_tether_off),
1083                                 (gpointer)tethering);
1084                 org_tizen_tethering_disable_bt_tethering_async(proxy,
1085                                 __cfm_cb, (gpointer)tethering);
1086                 break;
1087
1088         default :
1089                 ERR("Not supported tethering type [%d]\n", type);
1090                 return TETHERING_ERROR_INVALID_PARAMETER;
1091                 break;
1092         }
1093
1094         return TETHERING_ERROR_NONE;
1095 }
1096
1097 /**
1098  * @brief  Checks whetehr the tethering is enabled or not.
1099  * @param[in]  tethering  The handle of tethering
1100  * @param[in]  type  The type of tethering
1101  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
1102  */
1103 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
1104 {
1105         int is_on = 0;
1106         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
1107
1108         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0) {
1109                 return FALSE;
1110         }
1111
1112         switch (type) {
1113         case TETHERING_TYPE_USB:
1114                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
1115                 break;
1116
1117         case TETHERING_TYPE_WIFI:
1118                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
1119                 break;
1120
1121         case TETHERING_TYPE_BT:
1122                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
1123                 break;
1124
1125         default:
1126                 ERR("Not supported type : %d\n", type);
1127                 break;
1128         }
1129
1130         return is_on & vconf_type ? true : false;
1131 }
1132
1133 /**
1134  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
1135  * @remarks @a mac_address must be released with free() by you.
1136  * @param[in]  tethering  The handle of tethering
1137  * @param[in]  type  The type of tethering
1138  * @param[out]  mac_address  The MAC address
1139  * @return  0 on success, otherwise a negative error value.
1140  * @retval  #TETHERING_ERROR_NONE  Successful
1141  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1142  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1143  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1144  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1145  * @pre  tethering must be enabled.
1146  * @see  tethering_is_enabled()
1147  * @see  tethering_enable()
1148  */
1149 API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
1150 {
1151         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1152                         "parameter(tethering) is NULL\n");
1153         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1154                         "parameter(mac_address) is NULL\n");
1155         _retvm_if(tethering_is_enabled(tethering, type) == false,
1156                         TETHERING_ERROR_NOT_ENABLED,
1157                         "tethering type[%d] is not enabled\n", type);
1158
1159         struct ifreq ifr;
1160         int s = 0;
1161         char *macbuf = NULL;
1162
1163         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1164                         TETHERING_ERROR_OPERATION_FAILED,
1165                         "getting interface name is failed\n");
1166
1167         s = socket(AF_INET, SOCK_DGRAM, 0);
1168         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1169                         "getting socket is failed\n");
1170         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
1171                 ERR("getting mac is failed\n");
1172                 close(s);
1173                 return TETHERING_ERROR_OPERATION_FAILED;
1174         }
1175         close(s);
1176
1177         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
1178         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1179                         "Not enough memory\n");
1180         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
1181                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
1182                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
1183                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
1184                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
1185                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
1186                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
1187
1188         *mac_address = macbuf;
1189
1190         return TETHERING_ERROR_NONE;
1191 }
1192
1193 /**
1194  * @brief Gets the name of network interface. For example, usb0.
1195  * @remarks @a interface_name must be released with free() by you.
1196  * @param[in]  tethering  The handle of tethering
1197  * @param[in]  type  The type of tethering
1198  * @param[out]  interface_name  The name of network interface
1199  * @return 0 on success, otherwise negative error value.
1200  * @retval  #TETHERING_ERROR_NONE  Successful
1201  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1202  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1203  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1204  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1205  * @pre  tethering must be enabled.
1206  * @see  tethering_is_enabled()
1207  * @see  tethering_enable()
1208  */
1209 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
1210 {
1211         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1212                         "parameter(tethering) is NULL\n");
1213         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1214                         "parameter(interface_name) is NULL\n");
1215         _retvm_if(tethering_is_enabled(tethering, type) == false,
1216                         TETHERING_ERROR_NOT_ENABLED,
1217                         "tethering type[%d] is not enabled\n", type);
1218
1219         char intf[TETHERING_STR_INFO_LEN] = {0, };
1220
1221         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
1222                         TETHERING_ERROR_OPERATION_FAILED,
1223                         "getting interface name is failed\n");
1224         *interface_name = strdup(intf);
1225         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1226                         "Not enough memory\n");
1227
1228         return TETHERING_ERROR_NONE;
1229 }
1230
1231 /**
1232  * @brief Gets the local IP address.
1233  * @remarks @a ip_address must be released with free() by you.
1234  * @param[in]  tethering  The handle of tethering
1235  * @param[in]  type  The type of tethering
1236  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1237  * @param[out]  ip_address  The local IP address
1238  * @return 0 on success, otherwise negative error value.
1239  * @retval  #TETHERING_ERROR_NONE  Successful
1240  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1241  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1242  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1243  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1244  * @pre  tethering must be enabled.
1245  * @see  tethering_is_enabled()
1246  * @see  tethering_enable()
1247  */
1248 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
1249 {
1250         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1251                         "parameter(tethering) is NULL\n");
1252         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1253                         "parameter(ip_address) is NULL\n");
1254         _retvm_if(tethering_is_enabled(tethering, type) == false,
1255                         TETHERING_ERROR_NOT_ENABLED,
1256                         "tethering type[%d] is not enabled\n", type);
1257
1258         struct ifreq ifr;
1259         int s = 0;
1260         char *ipbuf = NULL;
1261
1262         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1263                         TETHERING_ERROR_OPERATION_FAILED,
1264                         "getting interface name is failed\n");
1265
1266         s = socket(AF_INET, SOCK_DGRAM, 0);
1267         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1268                         "getting socket is failed\n");
1269         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
1270                 ERR("ioctl is failed\n");
1271                 close(s);
1272                 return TETHERING_ERROR_OPERATION_FAILED;
1273         }
1274         close(s);
1275
1276         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
1277         *ip_address = strdup(ipbuf);
1278         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1279                         "Not enough memory\n");
1280
1281         return TETHERING_ERROR_NONE;
1282 }
1283
1284 /**
1285  * @brief Gets the Gateway address.
1286  * @remarks @a gateway_address must be released with free() by you.
1287  * @param[in]  tethering  The handle of tethering
1288  * @param[in]  type  The type of tethering
1289  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1290  * @param[out]  gateway_address  The local IP address
1291  * @return 0 on success, otherwise negative error value.
1292  * @retval  #TETHERING_ERROR_NONE  Successful
1293  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1294  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1295  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1296  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1297  * @pre  tethering must be enabled.
1298  * @see  tethering_is_enabled()
1299  * @see  tethering_enable()
1300  */
1301 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
1302 {
1303         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1304                         "parameter(tethering) is NULL\n");
1305         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1306                         "parameter(gateway_address) is NULL\n");
1307         _retvm_if(tethering_is_enabled(tethering, type) == false,
1308                         TETHERING_ERROR_NOT_ENABLED,
1309                         "tethering type[%d] is not enabled\n", type);
1310
1311         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
1312
1313         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
1314                         TETHERING_ERROR_OPERATION_FAILED,
1315                         "getting gateway address is failed\n");
1316
1317         *gateway_address = strdup(gateway_buf);
1318
1319         return TETHERING_ERROR_NONE;
1320 }
1321
1322 /**
1323  * @brief Gets the Subnet Mask.
1324  * @remarks @a subnet_mask must be released with free() by you.
1325  * @param[in]  tethering  The handle of tethering
1326  * @param[in]  type  The type of tethering
1327  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1328  * @param[out]  subnet_mask  The local IP address
1329  * @return 0 on success, otherwise negative error value.
1330  * @retval  #TETHERING_ERROR_NONE  Successful
1331  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1332  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1333  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1334  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1335  * @pre  tethering must be enabled.
1336  * @see  tethering_is_enabled()
1337  * @see  tethering_enable()
1338  */
1339 API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
1340 {
1341         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1342                         "parameter(tethering) is NULL\n");
1343         _retvm_if(tethering_is_enabled(tethering, type) == false,
1344                         TETHERING_ERROR_NOT_ENABLED,
1345                         "tethering is not enabled\n");
1346         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1347                         "parameter(subnet_mask) is NULL\n");
1348
1349         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
1350         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1351                         "Not enough memory\n");
1352
1353         return TETHERING_ERROR_NONE;
1354 }
1355
1356 /**
1357  * @brief Gets the data usage.
1358  * @param[in]  tethering  The handle of tethering
1359  * @param[out]  usage  The data usage
1360  * @return 0 on success, otherwise negative error value.
1361  * @retval  #TETHERING_ERROR_NONE  Successful
1362  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1363  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1364  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1365  * @pre  tethering must be enabled.
1366  * @see  tethering_is_enabled()
1367  * @see  tethering_enable()
1368  */
1369 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
1370 {
1371         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1372                         "parameter(tethering) is NULL\n");
1373         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1374                         "parameter(callback) is NULL\n");
1375         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1376                         TETHERING_ERROR_NOT_ENABLED,
1377                         "tethering is not enabled\n");
1378
1379         __tethering_h *th = (__tethering_h *)tethering;
1380         DBusGProxy *proxy = th->client_bus_proxy;
1381
1382         th->data_usage_cb = callback;
1383         th->data_usage_user_data = user_data;
1384
1385         org_tizen_tethering_get_data_packet_usage_async(proxy,
1386                         __get_data_usage_cb, (gpointer)th);
1387
1388         return TETHERING_ERROR_NONE;
1389 }
1390
1391 /**
1392  * @brief Gets the client which is connected by USB tethering.
1393  * @param[in]  tethering  The handle of tethering
1394  * @param[in]  type  The type of tethering
1395  * @param[in]  callback  The callback function to invoke
1396  * @param[in]  user_data  The user data to be passed to the callback function
1397  * @retval  #TETHERING_ERROR_NONE  Successful
1398  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1399  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1400  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1401  * @pre  tethering must be enabled.
1402  * @see  tethering_is_enabled()
1403  * @see  tethering_enable()
1404  */
1405 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
1406 {
1407         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1408                         "parameter(tethering) is NULL\n");
1409         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1410                         "parameter(callback) is NULL\n");
1411         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1412                         TETHERING_ERROR_NOT_ENABLED,
1413                         "tethering is not enabled\n");
1414
1415         __tethering_h *th = (__tethering_h *)tethering;
1416         __tethering_client_h client = {0, };
1417
1418         guint event = 0;
1419         GPtrArray *array = NULL;
1420         GValue value = {0, {{0}}};
1421         GError *error = NULL;
1422         int i = 0;
1423         int no_of_client = 0;
1424         guint interface = 0;
1425         gchar *ip = NULL;
1426         gchar *mac = NULL;
1427         gchar *hostname = NULL;
1428         guint timestamp = 0;
1429
1430         org_tizen_tethering_get_station_info(th->client_bus_proxy, &event,
1431                         &array, &error);
1432         if (error != NULL) {
1433                 ERR("DBus fail : %s\n", error->message);
1434                 g_error_free(error);
1435                 return TETHERING_ERROR_OPERATION_FAILED;
1436         }
1437
1438         g_value_init(&value, DBUS_STRUCT_STATIONS);
1439         no_of_client = array->len;
1440         for (i = 0; i < no_of_client; i++) {
1441                 g_value_set_boxed(&value, g_ptr_array_index(array, i));
1442
1443                 dbus_g_type_struct_get(&value, 0, &interface, 1, &ip,
1444                                 2, &mac, 3, &hostname, 4, &timestamp, G_MAXUINT);
1445
1446                 if (interface == MOBILE_AP_TYPE_USB)
1447                         client.interface = TETHERING_TYPE_USB;
1448                 else if (interface == MOBILE_AP_TYPE_WIFI)
1449                         client.interface = TETHERING_TYPE_WIFI;
1450                 else if (interface == MOBILE_AP_TYPE_BT)
1451                         client.interface = TETHERING_TYPE_BT;
1452
1453                 if (client.interface != type && TETHERING_TYPE_ALL != type)
1454                         continue;
1455
1456                 g_strlcpy(client.ip, ip, sizeof(client.ip));
1457                 g_strlcpy(client.mac, mac, sizeof(client.mac));
1458                 g_strlcpy(client.hostname, hostname, sizeof(client.hostname));
1459                 client.tm = (time_t)timestamp;
1460
1461                 if (callback((tethering_client_h)&client, user_data) == false) {
1462                         DBG("iteration is stopped\n");
1463                         return TETHERING_ERROR_NONE;
1464                 }
1465         }
1466
1467         if (array->len > 0)
1468                 g_ptr_array_free(array, TRUE);
1469
1470         return TETHERING_ERROR_NONE;
1471 }
1472
1473 /**
1474  * @brief Set the ip forward status
1475  * @param[in]  tethering  The handle of tethering
1476  * @param[in]  status  The ip forward status: (@c true = enable, @c false = disable)
1477  * @retval  #TETHERING_ERROR_NONE  Successful
1478  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1479  * @see  tethering_get_ip_forward_status()
1480  */
1481 API int tethering_set_ip_forward_status(tethering_h tethering, bool status)
1482 {
1483         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1484                         "parameter(tethering) is NULL\n");
1485
1486         __tethering_h *th = (__tethering_h *)tethering;
1487         DBusGProxy *proxy = th->client_bus_proxy;
1488
1489         org_tizen_tethering_set_ip_forward_status_async(proxy, status,
1490                         __ip_forward_cb, (gpointer)tethering);
1491
1492         return TETHERING_ERROR_NONE;
1493 }
1494
1495 /**
1496  * @brief Get the ip forward status
1497  * @param[in]  tethering  The handle of tethering
1498  * @param[out]  status  The ip forward status: (@c true = enable, @c false = disable)
1499  * @retval  #TETHERING_ERROR_NONE  Successful
1500  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1501  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1502  * @see  tethering_set_ip_forward_status()
1503  */
1504 API int tethering_get_ip_forward_status(tethering_h tethering, bool *status)
1505 {
1506         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1507                         "parameter(tethering) is NULL\n");
1508         _retvm_if(status == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1509                         "parameter(status) is NULL\n");
1510
1511         __tethering_h *th = (__tethering_h *)tethering;
1512         DBusGProxy *proxy = th->client_bus_proxy;
1513         GError *error = NULL;
1514         int forward_mode = 0;
1515
1516         org_tizen_tethering_get_ip_forward_status(proxy, &forward_mode, &error);
1517         if (error != NULL) {
1518                 ERR("DBus fail : %s\n", error->message);
1519                 g_error_free(error);
1520                 return TETHERING_ERROR_OPERATION_FAILED;
1521         }
1522
1523         if (forward_mode == 1)
1524                 *status = true;
1525         else
1526                 *status = false;
1527
1528         return TETHERING_ERROR_NONE;
1529 }
1530
1531
1532 /**
1533  * @brief Registers the callback function called when tethering is enabled.
1534  * @param[in]  tethering  The handle of tethering
1535  * @param[in]  type  The type of tethering
1536  * @param[in]  callback  The callback function to invoke
1537  * @param[in]  user_data  The user data to be passed to the callback function
1538  * @retval  #TETHERING_ERROR_NONE  Successful
1539  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1540  * @see  tethering_unset_enabled_cb()
1541  */
1542 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
1543 {
1544         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1545                         "parameter(tethering) is NULL\n");
1546         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1547                         "parameter(callback) is NULL\n");
1548
1549         __tethering_h *th = (__tethering_h *)tethering;
1550         tethering_type_e ti;
1551
1552         if (type != TETHERING_TYPE_ALL) {
1553                 th->enabled_cb[type] = callback;
1554                 th->enabled_user_data[type] = user_data;
1555
1556                 return TETHERING_ERROR_NONE;
1557         }
1558
1559         /* TETHERING_TYPE_ALL */
1560         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1561                 th->enabled_cb[ti] = callback;
1562                 th->enabled_user_data[ti] = user_data;
1563         }
1564
1565         return TETHERING_ERROR_NONE;
1566 }
1567
1568 /**
1569  * @brief Unregisters the callback function called when tethering is disabled.
1570  * @param[in]  tethering  The handle of tethering
1571  * @param[in]  type  The type of tethering
1572  * @retval  #TETHERING_ERROR_NONE  Successful
1573  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1574  * @see  tethering_set_enabled_cb()
1575  */
1576 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
1577 {
1578         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1579                         "parameter(tethering) is NULL\n");
1580
1581         __tethering_h *th = (__tethering_h *)tethering;
1582         tethering_type_e ti;
1583
1584         if (type != TETHERING_TYPE_ALL) {
1585                 th->enabled_cb[type] = NULL;
1586                 th->enabled_user_data[type] = NULL;
1587
1588                 return TETHERING_ERROR_NONE;
1589         }
1590
1591         /* TETHERING_TYPE_ALL */
1592         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1593                 th->enabled_cb[ti] = NULL;
1594                 th->enabled_user_data[ti] = NULL;
1595         }
1596
1597         return TETHERING_ERROR_NONE;
1598 }
1599
1600 /**
1601  * @brief Registers the callback function called when tethering is disabled.
1602  * @param[in]  tethering  The handle of tethering
1603  * @param[in]  type  The type of tethering
1604  * @param[in]  callback  The callback function to invoke
1605  * @param[in]  user_data  The user data to be passed to the callback function
1606  * @retval  #TETHERING_ERROR_NONE  Successful
1607  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1608  * @see  tethering_unset_disabled_cb()
1609  */
1610 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
1611 {
1612         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1613                         "parameter(tethering) is NULL\n");
1614         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1615                         "parameter(callback) is NULL\n");
1616
1617         __tethering_h *th = (__tethering_h *)tethering;
1618         tethering_type_e ti;
1619
1620         if (type != TETHERING_TYPE_ALL) {
1621                 th->disabled_cb[type] = callback;
1622                 th->disabled_user_data[type] = user_data;
1623
1624                 return TETHERING_ERROR_NONE;
1625         }
1626
1627         /* TETHERING_TYPE_ALL */
1628         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1629                 th->disabled_cb[ti] = callback;
1630                 th->disabled_user_data[ti] = user_data;
1631         }
1632
1633         return TETHERING_ERROR_NONE;
1634 }
1635
1636 /**
1637  * @brief Unregisters the callback function called when tethering is disabled.
1638  * @param[in]  tethering  The handle of tethering
1639  * @param[in]  type  The type of tethering
1640  * @retval  #TETHERING_ERROR_NONE  Successful
1641  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1642  * @see  tethering_set_disabled_cb()
1643  */
1644 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
1645 {
1646         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1647                         "parameter(tethering) is NULL\n");
1648
1649         __tethering_h *th = (__tethering_h *)tethering;
1650         tethering_type_e ti;
1651
1652         if (type != TETHERING_TYPE_ALL) {
1653                 th->disabled_cb[type] = NULL;
1654                 th->disabled_user_data[type] = NULL;
1655
1656                 return TETHERING_ERROR_NONE;
1657         }
1658
1659         /* TETHERING_TYPE_ALL */
1660         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1661                 th->disabled_cb[ti] = NULL;
1662                 th->disabled_user_data[ti] = NULL;
1663         }
1664
1665         return TETHERING_ERROR_NONE;
1666 }
1667
1668 /**
1669  * @brief Registers the callback function called when the state of connection is changed.
1670  * @param[in]  tethering  The handle of tethering
1671  * @param[in]  type  The type of tethering
1672  * @param[in]  callback  The callback function to invoke
1673  * @param[in]  user_data  The user data to be passed to the callback function
1674  * @retval  #TETHERING_ERROR_NONE  Successful
1675  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1676  * @see  tethering_unset_connection_state_changed_cb_cb()
1677  */
1678 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
1679 {
1680         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1681                         "parameter(tethering) is NULL\n");
1682         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1683                         "parameter(callback) is NULL\n");
1684
1685         __tethering_h *th = (__tethering_h *)tethering;
1686         tethering_type_e ti;
1687
1688         if (type != TETHERING_TYPE_ALL) {
1689                 th->changed_cb[type] = callback;
1690                 th->changed_user_data[type] = user_data;
1691
1692                 return TETHERING_ERROR_NONE;
1693         }
1694
1695         /* TETHERING_TYPE_ALL */
1696         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1697                 th->changed_cb[ti] = callback;
1698                 th->changed_user_data[ti] = user_data;
1699         }
1700
1701         return TETHERING_ERROR_NONE;
1702 }
1703
1704 /**
1705  * @brief Unregisters the callback function called when the state of connection is changed.
1706  * @param[in]  tethering  The handle of tethering
1707  * @param[in]  type  The type of tethering
1708  * @retval  #TETHERING_ERROR_NONE  Successful
1709  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1710  * @see  tethering_set_connection_state_changed_cb()
1711  */
1712 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
1713 {
1714         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1715                         "parameter(tethering) is NULL\n");
1716
1717         __tethering_h *th = (__tethering_h *)tethering;
1718         tethering_type_e ti;
1719
1720         if (type != TETHERING_TYPE_ALL) {
1721                 th->changed_cb[type] = NULL;
1722                 th->changed_user_data[type] = NULL;
1723
1724                 return TETHERING_ERROR_NONE;
1725         }
1726
1727         /* TETHERING_TYPE_ALL */
1728         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1729                 th->changed_cb[ti] = NULL;
1730                 th->changed_user_data[ti] = NULL;
1731         }
1732
1733         return TETHERING_ERROR_NONE;
1734 }
1735
1736 /**
1737  * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed.
1738  * @param[in]  tethering  The handle of tethering
1739  * @param[in]  callback  The callback function to invoke
1740  * @param[in]  user_data  The user data to be passed to the callback function
1741  * @retval  #TETHERING_ERROR_NONE  Successful
1742  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1743  * @see  tethering_wifi_unset_security_type_changed_cb()
1744  */
1745 API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data)
1746 {
1747         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1748                         "parameter(tethering) is NULL\n");
1749         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1750                         "parameter(callback) is NULL\n");
1751
1752         __tethering_h *th = (__tethering_h *)tethering;
1753
1754         th->security_type_changed_cb = callback;
1755         th->security_type_user_data = user_data;
1756
1757         return TETHERING_ERROR_NONE;
1758
1759 }
1760
1761 /**
1762  * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed.
1763  * @param[in]  tethering  The handle of tethering
1764  * @param[in]  type  The type of tethering
1765  * @retval  #TETHERING_ERROR_NONE  Successful
1766  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1767  * @see  tethering_wifi_set_security_type_changed_cb()
1768  */
1769 API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering)
1770 {
1771         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1772                         "parameter(tethering) is NULL\n");
1773
1774         __tethering_h *th = (__tethering_h *)tethering;
1775
1776         th->security_type_changed_cb = NULL;
1777         th->security_type_user_data = NULL;
1778
1779         return TETHERING_ERROR_NONE;
1780 }
1781
1782 /**
1783  * @brief Registers the callback function called when the visibility of SSID is changed.
1784  * @param[in]  tethering  The handle of tethering
1785  * @param[in]  callback  The callback function to invoke
1786  * @param[in]  user_data  The user data to be passed to the callback function
1787  * @retval  #TETHERING_ERROR_NONE  Successful
1788  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1789  * @see  tethering_wifi_unset_ssid_visibility_changed_cb_cb()
1790  */
1791 API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data)
1792 {
1793         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1794                         "parameter(tethering) is NULL\n");
1795         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1796                         "parameter(callback) is NULL\n");
1797
1798         __tethering_h *th = (__tethering_h *)tethering;
1799
1800         th->ssid_visibility_changed_cb = callback;
1801         th->ssid_visibility_user_data = user_data;
1802
1803         return TETHERING_ERROR_NONE;
1804 }
1805
1806 /**
1807  * @brief Unregisters the callback function called when the visibility of SSID is changed.
1808  * @param[in]  tethering  The handle of tethering
1809  * @retval  #TETHERING_ERROR_NONE  Successful
1810  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1811  * @see  tethering_wifi_set_ssid_visibility_changed_cb()
1812  */
1813 API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering)
1814 {
1815         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1816                         "parameter(tethering) is NULL\n");
1817
1818         __tethering_h *th = (__tethering_h *)tethering;
1819
1820         th->ssid_visibility_changed_cb = NULL;
1821         th->ssid_visibility_user_data = NULL;
1822
1823         return TETHERING_ERROR_NONE;
1824 }
1825
1826 /**
1827  * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed.
1828  * @param[in]  tethering  The handle of tethering
1829  * @param[in]  callback  The callback function to invoke
1830  * @param[in]  user_data  The user data to be passed to the callback function
1831  * @retval  #TETHERING_ERROR_NONE  Successful
1832  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1833  * @see  tethering_wifi_unset_passphrase_changed_cb()
1834  */
1835 API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data)
1836 {
1837         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1838                         "parameter(tethering) is NULL\n");
1839         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1840                         "parameter(callback) is NULL\n");
1841
1842         __tethering_h *th = (__tethering_h *)tethering;
1843
1844         th->passphrase_changed_cb = callback;
1845         th->passphrase_user_data = user_data;
1846
1847         return TETHERING_ERROR_NONE;
1848 }
1849
1850 /**
1851  * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed.
1852  * @param[in]  tethering  The handle of tethering
1853  * @retval  #TETHERING_ERROR_NONE  Successful
1854  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1855  * @see  tethering_wifi_set_passphrase_changed_cb()
1856  */
1857 API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering)
1858 {
1859         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1860                         "parameter(tethering) is NULL\n");
1861
1862         __tethering_h *th = (__tethering_h *)tethering;
1863
1864         th->passphrase_changed_cb = NULL;
1865         th->passphrase_user_data = NULL;
1866
1867         return TETHERING_ERROR_NONE;
1868 }
1869
1870 /**
1871  * @brief Sets the security type of Wi-Fi tethering.
1872  * @remarks This change is applied next time Wi-Fi tethering is enabled
1873  * @param[in]  tethering  The handle of tethering
1874  * @param[in]  type  The security type
1875  * @return 0 on success, otherwise negative error value.
1876  * @retval  #TETHERING_ERROR_NONE  Successful
1877  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1878  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1879  * @see  tethering_wifi_get_security_type()
1880  */
1881 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
1882 {
1883         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1884                         "parameter(tethering) is NULL\n");
1885         DBG("+\n");
1886
1887         __tethering_h *th = (__tethering_h *)tethering;
1888         DBusGProxy *proxy = th->client_bus_proxy;
1889         char *type_str = NULL;
1890
1891         if (type == TETHERING_WIFI_SECURITY_TYPE_NONE) {
1892                 type_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
1893         } else if (type == TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) {
1894                 type_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
1895         } else {
1896                 ERR("Unsupported type\n");
1897                 return TETHERING_ERROR_INVALID_PARAMETER;
1898         }
1899
1900         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SECURITY_TYPE_CHANGED,
1901                         G_CALLBACK(__handle_security_type_changed),
1902                         (gpointer)tethering);
1903
1904         org_tizen_tethering_set_wifi_tethering_security_type_async(proxy, type_str,
1905                         __wifi_set_security_type_cb, (gpointer)tethering);
1906
1907         DBG("-\n");
1908         return TETHERING_ERROR_NONE;
1909 }
1910
1911 /**
1912  * @brief Gets the security type of Wi-Fi tethering.
1913  * @param[in]  tethering  The handle of tethering
1914  * @param[out]  type  The security type
1915  * @return 0 on success, otherwise negative error value.
1916  * @retval  #TETHERING_ERROR_NONE  Successful
1917  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1918  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1919  * @see  tethering_wifi_set_security_type()
1920  */
1921 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
1922 {
1923         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1924                         "parameter(tethering) is NULL\n");
1925         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1926                         "parameter(type) is NULL\n");
1927         DBG("+\n");
1928
1929         __tethering_h *th = (__tethering_h *)tethering;
1930         DBusGProxy *proxy = th->client_bus_proxy;
1931         GError *error = NULL;
1932         char *type_str = NULL;
1933
1934         org_tizen_tethering_get_wifi_tethering_security_type(proxy, &type_str, &error);
1935         if (error != NULL) {
1936                 ERR("DBus fail : %s\n", error->message);
1937                 g_error_free(error);
1938                 return TETHERING_ERROR_OPERATION_FAILED;
1939         }
1940
1941         if (type_str == NULL)
1942                 return TETHERING_ERROR_OPERATION_FAILED;
1943
1944         DBG("security type : %s\n", type_str);
1945         if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
1946                 *type = TETHERING_WIFI_SECURITY_TYPE_NONE;
1947         else if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
1948                 *type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
1949         else {
1950                 ERR("Unknown security type : %s\n", type_str);
1951                 g_free(type_str);
1952                 return TETHERING_ERROR_OPERATION_FAILED;
1953         }
1954
1955         g_free(type_str);
1956
1957         DBG("-\n");
1958         return TETHERING_ERROR_NONE;
1959 }
1960
1961 /**
1962  * @brief Sets the SSID (service set identifier).
1963  * @details If SSID is not set, Device name is used as SSID
1964  * @remarks This change is applied next time Wi-Fi tethering is enabled with same @a tethering handle
1965  * @param[in]  tethering  The handle of tethering
1966  * @param[out]  ssid  The SSID
1967  * @return 0 on success, otherwise negative error value.
1968  * @retval  #TETHERING_ERROR_NONE  Successful
1969  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1970  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1971  */
1972 API int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid)
1973 {
1974         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1975                         "parameter(tethering) is NULL\n");
1976         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1977                         "parameter(ssid) is NULL\n");
1978
1979         __tethering_h *th = (__tethering_h *)tethering;
1980         char *p_ssid;
1981         int ssid_len;
1982
1983         ssid_len = strlen(ssid);
1984         if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) {
1985                 ERR("parameter(ssid) is too long");
1986                 return TETHERING_ERROR_INVALID_PARAMETER;
1987         }
1988
1989         p_ssid = strdup(ssid);
1990         _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1991                         "strdup is failed\n");
1992
1993         if (th->ssid)
1994                 free(th->ssid);
1995         th->ssid = p_ssid;
1996
1997         return TETHERING_ERROR_NONE;
1998 }
1999
2000 /**
2001  * @brief Gets the SSID (service set identifier).
2002  * @remarks @a ssid must be released with free() by you.
2003  * @param[in]  tethering  The handle of tethering
2004  * @param[out]  ssid  The SSID
2005  * @return 0 on success, otherwise negative error value.
2006  * @retval  #TETHERING_ERROR_NONE  Successful
2007  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2008  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2009  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2010  */
2011 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
2012 {
2013         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2014                         "parameter(tethering) is NULL\n");
2015         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2016                         "parameter(ssid) is NULL\n");
2017         DBG("+\n");
2018
2019         __tethering_h *th = (__tethering_h *)tethering;
2020         DBusGProxy *proxy = th->client_bus_proxy;
2021         GError *error = NULL;
2022         char *ssid_buf = NULL;
2023
2024         if (tethering_is_enabled(NULL, TETHERING_TYPE_WIFI) == false &&
2025                         th->ssid != NULL) {
2026                 DBG("Private SSID is set : %s\n", th->ssid);
2027                 *ssid = strdup(th->ssid);
2028                 if (*ssid == NULL) {
2029                         ERR("Memory allocation failed\n");
2030                         return TETHERING_ERROR_OUT_OF_MEMORY;
2031                 }
2032                 DBG("-\n");
2033                 return TETHERING_ERROR_NONE;
2034         }
2035
2036         org_tizen_tethering_get_wifi_tethering_ssid(proxy, &ssid_buf, &error);
2037         if (error != NULL) {
2038                 ERR("dbus fail : %s\n", error->message);
2039                 g_error_free(error);
2040                 return TETHERING_ERROR_OPERATION_FAILED;
2041         }
2042
2043         if (ssid_buf == NULL)
2044                 return TETHERING_ERROR_OPERATION_FAILED;
2045
2046         *ssid = strdup(ssid_buf);
2047         if (*ssid == NULL) {
2048                 ERR("Memory allocation failed\n");
2049                 return TETHERING_ERROR_OUT_OF_MEMORY;
2050         }
2051
2052         g_free(ssid_buf);
2053
2054         DBG("-\n");
2055         return TETHERING_ERROR_NONE;
2056 }
2057
2058 /**
2059  * @brief Sets the visibility of SSID(service set identifier).
2060  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
2061  * @remarks This change is applied next time Wi-Fi tethering is enabled
2062  * @param[in]  tethering  The handle of tethering
2063  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
2064  * @return 0 on success, otherwise negative error value.
2065  * @retval  #TETHERING_ERROR_NONE  Successful
2066  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2067  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2068  * @see  tethering_wifi_get_ssid_visibility()
2069  */
2070 API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
2071 {
2072         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2073                         "parameter(tethering) is NULL\n");
2074         DBG("+\n");
2075
2076         __tethering_h *th = (__tethering_h *)tethering;
2077         DBusGProxy *proxy = th->client_bus_proxy;
2078         int hide_mode = 0;
2079
2080         if (visible)
2081                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_OFF;
2082         else
2083                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_ON;
2084
2085         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
2086                         G_CALLBACK(__handle_ssid_visibility_changed),
2087                         (gpointer)tethering);
2088
2089         org_tizen_tethering_set_wifi_tethering_hide_mode_async(proxy, hide_mode,
2090                         __wifi_set_ssid_visibility_cb, (gpointer)tethering);
2091
2092         DBG("-\n");
2093         return TETHERING_ERROR_NONE;
2094 }
2095
2096 /**
2097  * @brief Gets the visibility of SSID(service set identifier).
2098  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
2099  * @param[in]  tethering  The handle of tethering
2100  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
2101  * @return 0 on success, otherwise negative error value.
2102  * @retval  #TETHERING_ERROR_NONE  Successful
2103  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2104  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2105  * @see  tethering_wifi_set_ssid_visibility()
2106  */
2107 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
2108 {
2109         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2110                         "parameter(tethering) is NULL\n");
2111         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2112                         "parameter(visible) is NULL\n");
2113         DBG("+\n");
2114
2115         __tethering_h *th = (__tethering_h *)tethering;
2116         DBusGProxy *proxy = th->client_bus_proxy;
2117         GError *error = NULL;
2118         int hide_mode = 0;
2119
2120         org_tizen_tethering_get_wifi_tethering_hide_mode(proxy, &hide_mode, &error);
2121         if (error != NULL) {
2122                 ERR("dbus fail : %s\n", error->message);
2123                 g_error_free(error);
2124                 return TETHERING_ERROR_OPERATION_FAILED;
2125         }
2126         DBG("hide mode : %d\n", hide_mode);
2127
2128         if (hide_mode == VCONFKEY_MOBILE_AP_HIDE_OFF)
2129                 *visible = true;
2130         else
2131                 *visible = false;
2132
2133         DBG("-\n");
2134         return TETHERING_ERROR_NONE;
2135 }
2136
2137 /**
2138  * @brief Sets the passphrase.
2139  * @remarks This change is applied next time Wi-Fi tethering is enabled
2140  * @param[in]  tethering  The handle of tethering
2141  * @param[in]  passphrase  The passphrase
2142  * @return 0 on success, otherwise negative error value.
2143  * @retval  #TETHERING_ERROR_NONE  Successful
2144  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2145  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2146  * @see  tethering_wifi_get_passphrase()
2147  */
2148 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
2149 {
2150         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2151                         "parameter(tethering) is NULL\n");
2152         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2153                         "parameter(passphrase) is NULL\n");
2154         DBG("+\n");
2155
2156         __tethering_h *th = (__tethering_h *)tethering;
2157         DBusGProxy *proxy = th->client_bus_proxy;
2158         int passphrase_len;
2159
2160         passphrase_len = strlen(passphrase);
2161         if (passphrase_len < TETHERING_WIFI_KEY_MIN_LEN ||
2162                         passphrase_len > TETHERING_WIFI_KEY_MAX_LEN) {
2163                 ERR("parameter(passphrase) is too short or long\n");
2164                 return TETHERING_ERROR_INVALID_PARAMETER;
2165         }
2166
2167         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_PASSPHRASE_CHANGED,
2168                         G_CALLBACK(__handle_passphrase_changed),
2169                         (gpointer)tethering);
2170
2171         org_tizen_tethering_set_wifi_tethering_passphrase_async(proxy,
2172                         passphrase, passphrase_len,
2173                         __wifi_set_passphrase_cb, (gpointer)tethering);
2174
2175         DBG("-\n");
2176         return TETHERING_ERROR_NONE;
2177 }
2178
2179 /**
2180  * @brief Gets the passphrase.
2181  * @remarks @a passphrase must be released with free() by you.
2182  * @param[in]  tethering  The handle of tethering
2183  * @param[out]  passphrase  The passphrase
2184  * @return 0 on success, otherwise negative error value.
2185  * @retval  #TETHERING_ERROR_NONE  Successful
2186  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2187  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2188  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2189  * @see  tethering_wifi_set_passphrase()
2190  */
2191 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
2192 {
2193         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2194                         "parameter(tethering) is NULL\n");
2195         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2196                         "parameter(passphrase) is NULL\n");
2197         DBG("+\n");
2198
2199         __tethering_h *th = (__tethering_h *)tethering;
2200         DBusGProxy *proxy = th->client_bus_proxy;
2201         GError *error = NULL;
2202         char *passphrase_buf = NULL;
2203         unsigned int len = 0;
2204
2205         org_tizen_tethering_get_wifi_tethering_passphrase(proxy,
2206                         &passphrase_buf, &len, &error);
2207         if (error != NULL) {
2208                 ERR("dbus fail : %s\n", error->message);
2209                 g_error_free(error);
2210                 return TETHERING_ERROR_OPERATION_FAILED;
2211         }
2212
2213         if (passphrase_buf == NULL)
2214                 return TETHERING_ERROR_OPERATION_FAILED;
2215
2216         *passphrase = strdup(passphrase_buf);
2217         if (*passphrase == NULL) {
2218                 ERR("Memory allocation failed\n");
2219                 return TETHERING_ERROR_OUT_OF_MEMORY;
2220         }
2221
2222         g_free(passphrase_buf);
2223
2224         DBG("-\n");
2225         return TETHERING_ERROR_NONE;
2226 }