Source code upload
[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
44 static __tethering_sig_t sigs[] = {
45         {SIGNAL_NAME_NET_CLOSED, __handle_net_closed},
46         {SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on},
47         {SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off},
48         {SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on},
49         {SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off},
50         {SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on},
51         {SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off},
52         {SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout},
53         {SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode},
54         {SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode},
55         {"", NULL}};
56
57 static bool __any_tethering_is_enabled(tethering_h tethering)
58 {
59         if (tethering_is_enabled(tethering, TETHERING_TYPE_USB) ||
60                         tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) ||
61                         tethering_is_enabled(tethering, TETHERING_TYPE_BT))
62                 return true;
63
64         return false;
65 }
66
67 static tethering_error_e __get_error(int agent_error)
68 {
69         tethering_error_e err = TETHERING_ERROR_NONE;
70
71         switch (agent_error) {
72         case MOBILE_AP_ERROR_NONE:
73                 err = TETHERING_ERROR_NONE;
74                 break;
75
76         case MOBILE_AP_ERROR_RESOURCE:
77                 err = TETHERING_ERROR_OUT_OF_MEMORY;
78                 break;
79
80         case MOBILE_AP_ERROR_INTERNAL:
81                 err = TETHERING_ERROR_OPERATION_FAILED;
82                 break;
83
84         case MOBILE_AP_ERROR_INVALID_PARAM:
85                 err = TETHERING_ERROR_INVALID_PARAMETER;
86                 break;
87
88         case MOBILE_AP_ERROR_ALREADY_ENABLED:
89                 err = TETHERING_ERROR_OPERATION_FAILED;
90                 break;
91
92         case MOBILE_AP_ERROR_NOT_ENABLED:
93                 err = TETHERING_ERROR_NOT_ENABLED;
94                 break;
95
96         case MOBILE_AP_ERROR_NET_OPEN:
97                 err = TETHERING_ERROR_OPERATION_FAILED;
98                 break;
99
100         case MOBILE_AP_ERROR_NET_CLOSE:
101                 err = TETHERING_ERROR_OPERATION_FAILED;
102                 break;
103
104         case MOBILE_AP_ERROR_DHCP:
105                 err = TETHERING_ERROR_OPERATION_FAILED;
106                 break;
107
108         case MOBILE_AP_ERROR_IN_PROGRESS:
109                 err = TETHERING_ERROR_OPERATION_FAILED;
110                 break;
111
112         case MOBILE_AP_ERROR_NOT_PERMITTED:
113                 err = TETHERING_ERROR_OPERATION_FAILED;
114                 break;
115
116         default:
117                 ERR("Not defined error : %d\n", agent_error);
118                 err = TETHERING_ERROR_OPERATION_FAILED;
119                 break;
120         }
121
122         return err;
123 }
124
125 static void __handle_dhcp(DBusGProxy *proxy, const char *member,
126                 guint interface, const char *ip, const char *mac,
127                 const char *name, gpointer user_data)
128 {
129         DBG("+\n");
130
131         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
132
133         __tethering_h *th = (__tethering_h *)user_data;
134         bool opened = false;
135         tethering_type_e type = 0;
136         tethering_connection_state_changed_cb ccb = NULL;
137         __tethering_client_h client = {0, };
138         void *data = NULL;
139
140         if (!g_strcmp0(member, "DhcpConnected")) {
141                 opened = true;
142         } else if (!g_strcmp0(member, "DhcpLeaseDeleted")) {
143                 opened = false;
144         } else {
145                 ERR("Unknown event [%s]\n", member);
146                 return;
147         }
148
149         if (interface == MOBILE_AP_TYPE_USB)
150                 type = TETHERING_TYPE_USB;
151         else if (interface == MOBILE_AP_TYPE_WIFI)
152                 type = TETHERING_TYPE_WIFI;
153         else if (interface == MOBILE_AP_TYPE_BT)
154                 type = TETHERING_TYPE_BT;
155         else {
156                 ERR("Not supported tethering type [%d]\n", interface);
157                 return;
158         }
159
160         ccb = th->changed_cb[type];
161         if (ccb == NULL)
162                 return;
163         data = th->changed_user_data[type];
164
165         client.interface = type;
166         g_strlcpy(client.ip, ip, sizeof(client.ip));
167         g_strlcpy(client.mac, mac, sizeof(client.mac));
168         g_strlcpy(client.hostname, name, sizeof(client.hostname));
169
170         ccb((tethering_client_h)&client, opened, data);
171
172         return;
173 }
174
175 static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
176 {
177         DBG("+\n");
178
179         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
180
181         __tethering_h *th = (__tethering_h *)user_data;
182         tethering_type_e type = 0;
183         tethering_disabled_cb dcb = NULL;
184         void *data = NULL;
185         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_NETWORK_CLOSE;
186
187         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
188                 dcb = th->disabled_cb[type];
189                 if (dcb == NULL)
190                         continue;
191                 data = th->disabled_user_data[type];
192
193                 dcb(TETHERING_ERROR_NONE, type, code, data);
194         }
195
196         return;
197 }
198
199 static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
200 {
201         DBG("+\n");
202
203         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
204
205         __tethering_h *th = (__tethering_h *)user_data;
206         tethering_type_e type = TETHERING_TYPE_WIFI;
207         bool is_requested = false;
208         tethering_enabled_cb ecb = NULL;
209         void *data = NULL;
210
211         ecb = th->enabled_cb[type];
212         if (ecb == NULL)
213                 return;
214         data = th->enabled_user_data[type];
215
216         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
217 }
218
219 static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
220 {
221         DBG("+\n");
222
223         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
224
225         __tethering_h *th = (__tethering_h *)user_data;
226         tethering_type_e type = TETHERING_TYPE_WIFI;
227         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
228         tethering_disabled_cb dcb = NULL;
229         void *data = NULL;
230
231         dcb = th->disabled_cb[type];
232         if (dcb == NULL)
233                 return;
234         data = th->disabled_user_data[type];
235
236         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
237                 code = TETHERING_DISABLED_BY_WIFI_ON;
238         dcb(TETHERING_ERROR_NONE, type, code, data);
239
240         return;
241 }
242
243 static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
244 {
245         DBG("+\n");
246
247         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
248
249         __tethering_h *th = (__tethering_h *)user_data;
250         tethering_type_e type = TETHERING_TYPE_USB;
251         bool is_requested = false;
252         tethering_enabled_cb ecb = NULL;
253         void *data = NULL;
254
255         ecb = th->enabled_cb[type];
256         if (ecb == NULL)
257                 return;
258         data = th->enabled_user_data[type];
259
260         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
261 }
262
263 static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
264 {
265         DBG("+\n");
266
267         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
268
269         __tethering_h *th = (__tethering_h *)user_data;
270         tethering_type_e type = TETHERING_TYPE_USB;
271         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
272         tethering_disabled_cb dcb = NULL;
273         void *data = NULL;
274
275         dcb = th->disabled_cb[type];
276         if (dcb == NULL)
277                 return;
278         data = th->disabled_user_data[type];
279
280         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
281                 code = TETHERING_DISABLED_BY_USB_DISCONNECTION;
282         dcb(TETHERING_ERROR_NONE, type, code, data);
283
284         return;
285 }
286
287 static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
288 {
289         DBG("+\n");
290
291         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
292
293         __tethering_h *th = (__tethering_h *)user_data;
294         tethering_type_e type = TETHERING_TYPE_BT;
295         bool is_requested = false;
296         tethering_enabled_cb ecb = NULL;
297         void *data = NULL;
298
299         ecb = th->enabled_cb[type];
300         if (ecb == NULL)
301                 return;
302         data = th->enabled_user_data[type];
303
304         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
305 }
306
307 static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
308 {
309         DBG("+\n");
310
311         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
312
313         __tethering_h *th = (__tethering_h *)user_data;
314         tethering_type_e type = TETHERING_TYPE_BT;
315         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
316         tethering_disabled_cb dcb = NULL;
317         void *data = NULL;
318
319         dcb = th->disabled_cb[type];
320         if (dcb == NULL)
321                 return;
322         data = th->disabled_user_data[type];
323
324         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
325                 code = TETHERING_DISABLED_BY_BT_OFF;
326         dcb(TETHERING_ERROR_NONE, type, code, data);
327
328         return;
329 }
330
331 static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data)
332 {
333         DBG("+\n");
334
335         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
336
337         __tethering_h *th = (__tethering_h *)user_data;
338         tethering_type_e type = 0;
339         tethering_disabled_cb dcb = NULL;
340         void *data = NULL;
341         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_TIMEOUT;
342
343         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
344                 dcb = th->disabled_cb[type];
345                 if (dcb == NULL)
346                         continue;
347                 data = th->disabled_user_data[type];
348
349                 dcb(TETHERING_ERROR_NONE, type, code, data);
350         }
351 }
352
353 static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
354 {
355         DBG("+\n");
356
357         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
358
359         __tethering_h *th = (__tethering_h *)user_data;
360         tethering_type_e type = 0;
361         tethering_disabled_cb dcb = NULL;
362         void *data = NULL;
363         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY;
364
365         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
366                 dcb = th->disabled_cb[type];
367                 if (dcb == NULL)
368                         continue;
369                 data = th->disabled_user_data[type];
370
371                 dcb(TETHERING_ERROR_NONE, type, code, data);
372         }
373 }
374
375 static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
376 {
377         DBG("+\n");
378
379         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
380
381         __tethering_h *th = (__tethering_h *)user_data;
382         tethering_type_e type = 0;
383         tethering_disabled_cb dcb = NULL;
384         void *data = NULL;
385         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE;
386
387         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
388                 dcb = th->disabled_cb[type];
389                 if (dcb == NULL)
390                         continue;
391                 data = th->disabled_user_data[type];
392
393                 dcb(TETHERING_ERROR_NONE, type, code, data);
394         }
395 }
396
397 static void __cfm_cb(DBusGProxy *remoteobj, guint event, guint info,
398                 GError *g_error, gpointer user_data)
399 {
400         DBG("+\n");
401
402         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
403
404         tethering_h tethering = (tethering_h)user_data;
405         __tethering_h *th = (__tethering_h *)tethering;
406         DBusGProxy *proxy = th->client_bus_proxy;
407
408         tethering_type_e type = 0;
409         tethering_error_e error = __get_error(info);
410         bool is_requested = true;
411         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_REQUEST;
412
413         tethering_enabled_cb ecb = NULL;
414         tethering_disabled_cb dcb = NULL;
415         void *data = NULL;
416
417         if (g_error) {
418                 ERR("DBus error [%s]\n", g_error->message);
419                 return;
420         }
421
422         DBG("cfm event : %d info : %d\n", event, info);
423         switch (event) {
424         case MOBILE_AP_ENABLE_WIFI_TETHERING_CFM:
425                 type = TETHERING_TYPE_WIFI;
426                 ecb = th->enabled_cb[type];
427                 data = th->enabled_user_data[type];
428                 if (ecb)
429                         ecb(error, type, is_requested, data);
430                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
431                                 G_CALLBACK(__handle_wifi_tether_on),
432                                 (gpointer)tethering, NULL);
433                 break;
434
435         case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM:
436                 type = TETHERING_TYPE_WIFI;
437                 dcb = th->disabled_cb[type];
438                 data = th->disabled_user_data[type];
439                 if (dcb)
440                         dcb(error, type, code, data);
441                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
442                                 G_CALLBACK(__handle_wifi_tether_off),
443                                 (gpointer)tethering, NULL);
444                 break;
445
446         case MOBILE_AP_ENABLE_BT_TETHERING_CFM:
447                 type = TETHERING_TYPE_BT;
448                 ecb = th->enabled_cb[type];
449                 data = th->enabled_user_data[type];
450                 if (ecb)
451                         ecb(error, type, is_requested, data);
452                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
453                                 G_CALLBACK(__handle_bt_tether_on),
454                                 (gpointer)tethering, NULL);
455                 break;
456
457         case MOBILE_AP_DISABLE_BT_TETHERING_CFM:
458                 type = TETHERING_TYPE_BT;
459                 dcb = th->disabled_cb[type];
460                 data = th->disabled_user_data[type];
461                 if (dcb)
462                         dcb(error, type, code, data);
463                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
464                                 G_CALLBACK(__handle_bt_tether_off),
465                                 (gpointer)tethering, NULL);
466                 break;
467
468         case MOBILE_AP_ENABLE_USB_TETHERING_CFM:
469                 type = TETHERING_TYPE_USB;
470                 ecb = th->enabled_cb[type];
471                 data = th->enabled_user_data[type];
472                 if (ecb)
473                         ecb(error, type, is_requested, data);
474                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
475                                 G_CALLBACK(__handle_usb_tether_on),
476                                 (gpointer)tethering, NULL);
477                 break;
478
479         case MOBILE_AP_DISABLE_USB_TETHERING_CFM:
480                 type = TETHERING_TYPE_USB;
481                 dcb = th->disabled_cb[type];
482                 data = th->disabled_user_data[type];
483                 if (dcb)
484                         dcb(error, type, code, data);
485                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
486                                 G_CALLBACK(__handle_usb_tether_off),
487                                 (gpointer)tethering, NULL);
488                 break;
489
490         case MOBILE_AP_DISABLE_CFM:
491                 for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
492                         dcb = th->disabled_cb[type];
493                         if (dcb == NULL)
494                                 continue;
495                         data = th->disabled_user_data[type];
496
497                         dcb(error, type, code, data);
498                 }
499
500                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
501                                 G_CALLBACK(__handle_usb_tether_off),
502                                 (gpointer)tethering, NULL);
503                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
504                                 G_CALLBACK(__handle_wifi_tether_off),
505                                 (gpointer)tethering, NULL);
506                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
507                                 G_CALLBACK(__handle_bt_tether_off),
508                                 (gpointer)tethering, NULL);
509                 break;
510
511         default:
512                 ERR("Invalid event\n");
513                 return;
514         }
515
516         return;
517 }
518
519 static void __get_data_usage_cb(DBusGProxy *remoteobj, guint event,
520                 guint64 tx_bytes, guint64 rx_bytes,
521                 GError *error, gpointer user_data)
522 {
523         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
524
525         __tethering_h *th = (__tethering_h *)user_data;
526
527         if (th->data_usage_cb == NULL) {
528                 ERR("There is no data_usage_cb\n");
529                 return;
530         }
531
532         if (error || event != MOBILE_AP_GET_DATA_PACKET_USAGE_CFM) {
533                 if (error)  {
534                         ERR("DBus fail [%s]\n", error->message);
535                         g_error_free(error);
536                 }
537
538                 th->data_usage_cb(TETHERING_ERROR_OPERATION_FAILED,
539                                 0LL, 0LL, th->data_usage_user_data);
540
541                 th->data_usage_cb = NULL;
542                 th->data_usage_user_data = NULL;
543
544                 return;
545         }
546
547         th->data_usage_cb(TETHERING_ERROR_NONE,
548                         rx_bytes, tx_bytes, th->data_usage_user_data);
549
550         th->data_usage_cb = NULL;
551         th->data_usage_user_data = NULL;
552
553         return;
554 }
555
556 static void __connect_signals(tethering_h tethering)
557 {
558         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
559
560         __tethering_h *th = (__tethering_h *)tethering;
561         DBusGProxy *proxy = th->client_bus_proxy;
562         int i = 0;
563
564         for (i = 0; sigs[i].cb != NULL; i++) {
565                 dbus_g_proxy_add_signal(proxy, sigs[i].name,
566                                 G_TYPE_STRING, G_TYPE_INVALID);
567                 dbus_g_proxy_connect_signal(proxy, sigs[i].name,
568                                 G_CALLBACK(sigs[i].cb), (gpointer)tethering, NULL);
569         }
570
571         dbus_g_object_register_marshaller(marshal_VOID__STRING_UINT_STRING_STRING_STRING,
572                         G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
573                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
574         dbus_g_proxy_add_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
575                         G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
576                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
577         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
578                         G_CALLBACK(__handle_dhcp), (gpointer)tethering, NULL);
579
580         return;
581 }
582
583 static void __disconnect_signals(tethering_h tethering)
584 {
585         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
586
587         __tethering_h *th = (__tethering_h *)tethering;
588         DBusGProxy *proxy = th->client_bus_proxy;
589
590         int i = 0;
591
592         for (i = 0; sigs[i].cb != NULL; i++) {
593                 dbus_g_proxy_disconnect_signal(proxy, sigs[i].name,
594                                 G_CALLBACK(sigs[i].cb), (gpointer)tethering);
595         }
596
597         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
598                         G_CALLBACK(__handle_dhcp), (gpointer)tethering);
599
600         return;
601 }
602
603 static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len)
604 {
605         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
606
607         switch (type) {
608         case TETHERING_TYPE_USB:
609                 g_strlcpy(buf, TETHERING_USB_IF, len);
610                 break;
611
612         case TETHERING_TYPE_WIFI:
613                 g_strlcpy(buf, TETHERING_WIFI_IF, len);
614                 break;
615
616         case TETHERING_TYPE_BT:
617                 g_strlcpy(buf, TETHERING_BT_IF, len);
618                 break;
619
620         default:
621                 ERR("Not supported type : %d\n", type);
622                 return false;
623         }
624
625         return true;
626 }
627
628 static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int len)
629 {
630         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
631
632         switch (type) {
633         case TETHERING_TYPE_USB:
634                 g_strlcpy(buf, TETHERING_USB_GATEWAY, len);
635                 break;
636
637         case TETHERING_TYPE_WIFI:
638                 g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len);
639                 break;
640
641         case TETHERING_TYPE_BT:
642                 g_strlcpy(buf, TETHERING_BT_GATEWAY, len);
643                 break;
644
645         default:
646                 ERR("Not supported type : %d\n", type);
647                 return false;
648         }
649
650         return true;
651 }
652
653 /**
654  * @brief  Creates the handle of tethering.
655  * @remarks  The @a tethering must be released tethering_destroy() by you.
656  * @param[out]  tethering  A handle of a new mobile ap handle on success
657  * @return  0 on success, otherwise a negative error value.
658  * @retval  #TETHERING_ERROR_NONE  Successful
659  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
660  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
661  * @see  tethering_destroy()
662  */
663 API int tethering_create(tethering_h *tethering)
664 {
665         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
666                         "parameter(tethering) is NULL\n");
667
668         __tethering_h *th = NULL;
669         GError *error = NULL;
670
671         th = (__tethering_h *)malloc(sizeof(__tethering_h));
672         _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
673                         "malloc is failed\n");
674         memset(th, 0x00, sizeof(__tethering_h));
675
676         g_type_init();
677         th->client_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
678         if (error) {
679                 ERR("Couldn't connect to the System bus[%s]", error->message);
680                 g_error_free(error);
681                 free(th);
682                 return TETHERING_ERROR_OPERATION_FAILED;
683         }
684
685         th->client_bus_proxy = dbus_g_proxy_new_for_name(th->client_bus,
686                         TETHERING_SERVICE_NAME,
687                         TETHERING_SERVICE_OBJECT_PATH,
688                         TETHERING_SERVICE_INTERFACE);
689         if (!th->client_bus_proxy) {
690                 ERR("Couldn't create the proxy object");
691                 dbus_g_connection_unref(th->client_bus);
692                 free(th);
693                 return TETHERING_ERROR_OPERATION_FAILED;
694         }
695
696         __connect_signals((tethering_h)th);
697
698         *tethering = (tethering_h)th;
699         DBG("Tethering Handle : 0x%X\n", th);
700
701         return TETHERING_ERROR_NONE;
702 }
703
704 /**
705  * @brief  Destroys the handle of tethering.
706  * @param[in]  tethering  The handle of tethering
707  * @return  0 on success, otherwise a negative error value.
708  * @retval  #TETHERING_ERROR_NONE  Successful
709  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
710  * @see  tethering_create()
711  */
712 API int tethering_destroy(tethering_h tethering)
713 {
714         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
715                         "parameter(tethering) is NULL\n");
716
717         __tethering_h *th = (__tethering_h *)tethering;
718         GError *error = NULL;
719
720         DBG("Tethering Handle : 0x%X\n", th);
721         com_samsung_mobileap_deinit(th->client_bus_proxy, &error);
722         if (error) {
723                 ERR("tethering_destroy is failed [%s]", error->message);
724                 g_error_free(error);
725         }
726         __disconnect_signals(tethering);
727
728         g_object_unref(th->client_bus_proxy);
729         dbus_g_connection_unref(th->client_bus);
730         memset(th, 0x00, sizeof(__tethering_h));
731         free(th);
732
733         return TETHERING_ERROR_NONE;
734 }
735
736 /**
737  * @brief Enables the tethering, asynchronously.
738  * @param[in]  tethering  The handle of tethering
739  * @param[in]  type  The type of tethering
740  * @return 0 on success, otherwise negative error value.
741  * @retval  #TETHERING_ERROR_NONE  Successful
742  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
743  * @post tethering_enabled_cb() will be invoked.
744  * @see  tethering_is_enabled()
745  * @see  tethering_disable()
746  */
747 int tethering_enable(tethering_h tethering, tethering_type_e type)
748 {
749         DBG("+\n");
750
751         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
752                         "parameter(tethering) is NULL\n");
753
754         __tethering_h *th = (__tethering_h *)tethering;
755         DBusGProxy *proxy = th->client_bus_proxy;
756
757         switch (type) {
758         case TETHERING_TYPE_USB:
759                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
760                                 G_CALLBACK(__handle_usb_tether_on),
761                                 (gpointer)tethering);
762                 com_samsung_mobileap_enable_usb_tethering_async(proxy,
763                                 __cfm_cb, (gpointer)tethering);
764                 break;
765
766         case TETHERING_TYPE_WIFI:
767                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
768                                 G_CALLBACK(__handle_wifi_tether_on),
769                                 (gpointer)tethering);
770                 com_samsung_mobileap_enable_wifi_tethering_async(proxy, "", "", false,
771                                 __cfm_cb, (gpointer)tethering);
772                 break;
773
774         case TETHERING_TYPE_BT:
775                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
776                                 G_CALLBACK(__handle_bt_tether_on),
777                                 (gpointer)tethering);
778                 com_samsung_mobileap_enable_bt_tethering_async(proxy,
779                                 __cfm_cb, (gpointer)tethering);
780
781                 break;
782
783         case TETHERING_TYPE_ALL:
784                 /* TETHERING_TYPE_USB */
785                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
786                                 G_CALLBACK(__handle_usb_tether_on),
787                                 (gpointer)tethering);
788                 com_samsung_mobileap_enable_usb_tethering_async(proxy,
789                                 __cfm_cb, (gpointer)tethering);
790
791                 /* TETHERING_TYPE_WIFI */
792                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
793                                 G_CALLBACK(__handle_wifi_tether_on),
794                                 (gpointer)tethering);
795                 com_samsung_mobileap_enable_wifi_tethering_async(proxy, "", "", false,
796                                 __cfm_cb, (gpointer)tethering);
797
798                 /* TETHERING_TYPE_BT */
799                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
800                                 G_CALLBACK(__handle_bt_tether_on),
801                                 (gpointer)tethering);
802                 com_samsung_mobileap_enable_bt_tethering_async(proxy,
803                                 __cfm_cb, (gpointer)tethering);
804                 break;
805
806         default:
807                 ERR("Unknown type : %d\n", type);
808                 return TETHERING_ERROR_INVALID_PARAMETER;
809         }
810
811         return TETHERING_ERROR_NONE;
812 }
813
814 /**
815  * @brief Disables the tethering, asynchronously.
816  * @param[in]  tethering  The handle of tethering
817  * @param[in]  type  The type of tethering
818  * @return 0 on success, otherwise negative error value.
819  * @retval  #TETHERING_ERROR_NONE  Successful
820  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
821  * @post tethering_disabled_cb() will be invoked.
822  * @see  tethering_is_enabled()
823  * @see  tethering_enable()
824  */
825 API int tethering_disable(tethering_h tethering, tethering_type_e type)
826 {
827         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
828                         "parameter(tethering) is NULL\n");
829
830         __tethering_h *th = (__tethering_h *)tethering;
831         DBusGProxy *proxy = th->client_bus_proxy;
832
833         switch (type) {
834         case TETHERING_TYPE_USB:
835                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
836                                 G_CALLBACK(__handle_usb_tether_off),
837                                 (gpointer)tethering);
838                 com_samsung_mobileap_disable_usb_tethering_async(proxy,
839                                 __cfm_cb, (gpointer)tethering);
840                 break;
841
842         case TETHERING_TYPE_WIFI:
843                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
844                                 G_CALLBACK(__handle_wifi_tether_off),
845                                 (gpointer)tethering);
846                 com_samsung_mobileap_disable_wifi_tethering_async(proxy,
847                                 __cfm_cb, (gpointer)tethering);
848                 break;
849         case TETHERING_TYPE_BT:
850                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
851                                 G_CALLBACK(__handle_bt_tether_off),
852                                 (gpointer)tethering);
853                 com_samsung_mobileap_disable_bt_tethering_async(proxy,
854                                 __cfm_cb, (gpointer)tethering);
855                 break;
856
857         case TETHERING_TYPE_ALL:
858                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
859                                 G_CALLBACK(__handle_usb_tether_off),
860                                 (gpointer)tethering);
861                 com_samsung_mobileap_disable_usb_tethering_async(proxy,
862                                 __cfm_cb, (gpointer)tethering);
863
864                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
865                                 G_CALLBACK(__handle_wifi_tether_off),
866                                 (gpointer)tethering);
867                 com_samsung_mobileap_disable_wifi_tethering_async(proxy,
868                                 __cfm_cb, (gpointer)tethering);
869
870                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
871                                 G_CALLBACK(__handle_bt_tether_off),
872                                 (gpointer)tethering);
873                 com_samsung_mobileap_disable_bt_tethering_async(proxy,
874                                 __cfm_cb, (gpointer)tethering);
875                 break;
876
877         default :
878                 ERR("Not supported tethering type [%d]\n", type);
879                 return TETHERING_ERROR_INVALID_PARAMETER;
880                 break;
881         }
882
883         return TETHERING_ERROR_NONE;
884 }
885
886 /**
887  * @brief  Checks whetehr the tethering is enabled or not.
888  * @param[in]  tethering  The handle of tethering
889  * @param[in]  type  The type of tethering
890  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
891  */
892 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
893 {
894         int is_on = 0;
895         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
896
897         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0) {
898                 return FALSE;
899         }
900
901         switch (type) {
902         case TETHERING_TYPE_USB:
903                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
904                 break;
905
906         case TETHERING_TYPE_WIFI:
907                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
908                 break;
909
910         case TETHERING_TYPE_BT:
911                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
912                 break;
913
914         default:
915                 ERR("Not supported type : %d\n", type);
916                 break;
917         }
918
919         return is_on & vconf_type ? true : false;
920 }
921
922 /**
923  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
924  * @remarks @a mac_address must be released with free() by you.
925  * @param[in]  tethering  The handle of tethering
926  * @param[in]  type  The type of tethering
927  * @param[out]  mac_address  The MAC address
928  * @return  0 on success, otherwise a negative error value.
929  * @retval  #TETHERING_ERROR_NONE  Successful
930  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
931  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
932  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
933  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
934  * @pre  tethering must be enabled.
935  * @see  tethering_is_enabled()
936  * @see  tethering_enable()
937  */
938 int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
939 {
940         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
941                         "parameter(tethering) is NULL\n");
942         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
943                         "parameter(mac_address) is NULL\n");
944         _retvm_if(tethering_is_enabled(tethering, type) == false,
945                         TETHERING_ERROR_NOT_ENABLED,
946                         "tethering type[%d] is not enabled\n", type);
947
948         struct ifreq ifr;
949         int s = 0;
950         char *macbuf = NULL;
951
952         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
953                         TETHERING_ERROR_OPERATION_FAILED,
954                         "getting interface name is failed\n");
955
956         s = socket(AF_INET, SOCK_DGRAM, 0);
957         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
958                         "getting socket is failed\n");
959         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
960                 ERR("getting mac is failed\n");
961                 close(s);
962                 return TETHERING_ERROR_OPERATION_FAILED;
963         }
964         close(s);
965
966         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
967         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
968                         "Not enough memory\n");
969         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
970                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
971                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
972                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
973                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
974                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
975                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
976
977         *mac_address = macbuf;
978
979         return TETHERING_ERROR_NONE;
980 }
981
982 /**
983  * @brief Gets the name of network interface. For example, usb0.
984  * @remarks @a interface_name must be released with free() by you.
985  * @param[in]  tethering  The handle of tethering
986  * @param[in]  type  The type of tethering
987  * @param[out]  interface_name  The name of network interface
988  * @return 0 on success, otherwise negative error value.
989  * @retval  #TETHERING_ERROR_NONE  Successful
990  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
991  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
992  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
993  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
994  * @pre  tethering must be enabled.
995  * @see  tethering_is_enabled()
996  * @see  tethering_enable()
997  */
998 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
999 {
1000         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1001                         "parameter(tethering) is NULL\n");
1002         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1003                         "parameter(interface_name) is NULL\n");
1004         _retvm_if(tethering_is_enabled(tethering, type) == false,
1005                         TETHERING_ERROR_NOT_ENABLED,
1006                         "tethering type[%d] is not enabled\n", type);
1007
1008         char intf[TETHERING_STR_INFO_LEN] = {0, };
1009
1010         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
1011                         TETHERING_ERROR_OPERATION_FAILED,
1012                         "getting interface name is failed\n");
1013         *interface_name = strdup(intf);
1014         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1015                         "Not enough memory\n");
1016
1017         return TETHERING_ERROR_NONE;
1018 }
1019
1020 /**
1021  * @brief Gets the local IP address.
1022  * @remarks @a ip_address must be released with free() by you.
1023  * @param[in]  tethering  The handle of tethering
1024  * @param[in]  type  The type of tethering
1025  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1026  * @param[out]  ip_address  The local IP address
1027  * @return 0 on success, otherwise negative error value.
1028  * @retval  #TETHERING_ERROR_NONE  Successful
1029  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1030  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1031  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1032  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1033  * @pre  tethering must be enabled.
1034  * @see  tethering_is_enabled()
1035  * @see  tethering_enable()
1036  */
1037 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
1038 {
1039         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1040                         "parameter(tethering) is NULL\n");
1041         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1042                         "parameter(ip_address) is NULL\n");
1043         _retvm_if(tethering_is_enabled(tethering, type) == false,
1044                         TETHERING_ERROR_NOT_ENABLED,
1045                         "tethering type[%d] is not enabled\n", type);
1046
1047         struct ifreq ifr;
1048         int s = 0;
1049         char *ipbuf = NULL;
1050
1051         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1052                         TETHERING_ERROR_OPERATION_FAILED,
1053                         "getting interface name is failed\n");
1054
1055         s = socket(AF_INET, SOCK_DGRAM, 0);
1056         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1057                         "getting socket is failed\n");
1058         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
1059                 ERR("ioctl is failed\n");
1060                 close(s);
1061                 return TETHERING_ERROR_OPERATION_FAILED;
1062         }
1063         close(s);
1064
1065         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
1066         *ip_address = strdup(ipbuf);
1067         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1068                         "Not enough memory\n");
1069
1070         return TETHERING_ERROR_NONE;
1071 }
1072
1073 /**
1074  * @brief Gets the Gateway address.
1075  * @remarks @a gateway_address must be released with free() by you.
1076  * @param[in]  tethering  The handle of tethering
1077  * @param[in]  type  The type of tethering
1078  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1079  * @param[out]  gateway_address  The local IP address
1080  * @return 0 on success, otherwise negative error value.
1081  * @retval  #TETHERING_ERROR_NONE  Successful
1082  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1083  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1084  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1085  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1086  * @pre  tethering must be enabled.
1087  * @see  tethering_is_enabled()
1088  * @see  tethering_enable()
1089  */
1090 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
1091 {
1092         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1093                         "parameter(tethering) is NULL\n");
1094         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1095                         "parameter(gateway_address) is NULL\n");
1096         _retvm_if(tethering_is_enabled(tethering, type) == false,
1097                         TETHERING_ERROR_NOT_ENABLED,
1098                         "tethering type[%d] is not enabled\n", type);
1099
1100         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
1101
1102         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
1103                         TETHERING_ERROR_OPERATION_FAILED,
1104                         "getting gateway address is failed\n");
1105
1106         *gateway_address = strdup(gateway_buf);
1107
1108         return TETHERING_ERROR_NONE;
1109 }
1110
1111 /**
1112  * @brief Gets the Subnet Mask.
1113  * @remarks @a subnet_mask must be released with free() by you.
1114  * @param[in]  tethering  The handle of tethering
1115  * @param[in]  type  The type of tethering
1116  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1117  * @param[out]  subnet_mask  The local IP address
1118  * @return 0 on success, otherwise negative error value.
1119  * @retval  #TETHERING_ERROR_NONE  Successful
1120  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1121  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1122  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1123  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1124  * @pre  tethering must be enabled.
1125  * @see  tethering_is_enabled()
1126  * @see  tethering_enable()
1127  */
1128 int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
1129 {
1130         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1131                         "parameter(tethering) is NULL\n");
1132         _retvm_if(tethering_is_enabled(tethering, type) == false,
1133                         TETHERING_ERROR_NOT_ENABLED,
1134                         "tethering is not enabled\n");
1135         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1136                         "parameter(subnet_mask) is NULL\n");
1137
1138         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
1139         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1140                         "Not enough memory\n");
1141
1142         return TETHERING_ERROR_NONE;
1143 }
1144
1145 /**
1146  * @brief Gets the data usage.
1147  * @param[in]  tethering  The handle of tethering
1148  * @param[out]  usage  The data usage
1149  * @return 0 on success, otherwise negative error value.
1150  * @retval  #TETHERING_ERROR_NONE  Successful
1151  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1152  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1153  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1154  * @pre  tethering must be enabled.
1155  * @see  tethering_is_enabled()
1156  * @see  tethering_enable()
1157  */
1158 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
1159 {
1160         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1161                         "parameter(tethering) is NULL\n");
1162         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1163                         "parameter(callback) is NULL\n");
1164         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1165                         TETHERING_ERROR_NOT_ENABLED,
1166                         "tethering is not enabled\n");
1167
1168         __tethering_h *th = (__tethering_h *)tethering;
1169         DBusGProxy *proxy = th->client_bus_proxy;
1170
1171         th->data_usage_cb = callback;
1172         th->data_usage_user_data = user_data;
1173
1174         com_samsung_mobileap_get_data_packet_usage_async(proxy,
1175                         __get_data_usage_cb, (gpointer)th);
1176
1177         return TETHERING_ERROR_NONE;
1178 }
1179
1180 /**
1181  * @brief Gets the client which is connected by USB tethering.
1182  * @param[in]  tethering  The handle of tethering
1183  * @param[in]  type  The type of tethering
1184  * @param[in]  callback  The callback function to invoke
1185  * @param[in]  user_data  The user data to be passed to the callback function
1186  * @retval  #TETHERING_ERROR_NONE  Successful
1187  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1188  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1189  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1190  * @pre  tethering must be enabled.
1191  * @see  tethering_is_enabled()
1192  * @see  tethering_enable()
1193  */
1194 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
1195 {
1196         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1197                         "parameter(tethering) is NULL\n");
1198         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1199                         "parameter(callback) is NULL\n");
1200         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1201                         TETHERING_ERROR_NOT_ENABLED,
1202                         "tethering is not enabled\n");
1203
1204         __tethering_h *th = (__tethering_h *)tethering;
1205         __tethering_client_h client = {0, };
1206
1207         guint event = 0;
1208         GPtrArray *array = NULL;
1209         GValue value = {0, {{0}}};
1210         GError *error = NULL;
1211         int i = 0;
1212         int no_of_client = 0;
1213         guint interface = 0;
1214         gchar *ip = NULL;
1215         gchar *mac = NULL;
1216         gchar *hostname = NULL;
1217
1218         com_samsung_mobileap_get_station_info(th->client_bus_proxy, &event,
1219                         &array, &error);
1220         if (error != NULL) {
1221                 ERR("DBus fail : %s\n", error->message);
1222                 g_error_free(error);
1223                 return TETHERING_ERROR_OPERATION_FAILED;
1224         }
1225
1226         g_value_init(&value, DBUS_STRUCT_STATIONS);
1227         no_of_client = array->len;
1228         for (i = 0; i < no_of_client; i++) {
1229                 g_value_set_boxed(&value, g_ptr_array_index(array, i));
1230
1231                 dbus_g_type_struct_get(&value, 0, &interface, 1, &ip,
1232                                 2, &mac, 3, &hostname, G_MAXUINT);
1233
1234                 if (interface == MOBILE_AP_TYPE_USB)
1235                         client.interface = TETHERING_TYPE_USB;
1236                 else if (interface == MOBILE_AP_TYPE_WIFI)
1237                         client.interface = TETHERING_TYPE_WIFI;
1238                 else if (interface == MOBILE_AP_TYPE_BT)
1239                         client.interface = TETHERING_TYPE_BT;
1240
1241                 if (client.interface != type && TETHERING_TYPE_ALL != type)
1242                         continue;
1243
1244                 g_strlcpy(client.ip, ip, sizeof(client.ip));
1245                 g_strlcpy(client.mac, mac, sizeof(client.mac));
1246                 g_strlcpy(client.hostname, hostname, sizeof(client.hostname));
1247
1248                 if (callback((tethering_client_h)&client, user_data) == false) {
1249                         DBG("iteration is stopped\n");
1250                         return TETHERING_ERROR_NONE;
1251                 }
1252         }
1253
1254         if (array->len > 0)
1255                 g_ptr_array_free(array, TRUE);
1256
1257         return TETHERING_ERROR_NONE;
1258 }
1259
1260 /**
1261  * @brief Registers the callback function called when tethering is enabled.
1262  * @param[in]  tethering  The handle of tethering
1263  * @param[in]  type  The type of tethering
1264  * @param[in]  callback  The callback function to invoke
1265  * @param[in]  user_data  The user data to be passed to the callback function
1266  * @retval  #TETHERING_ERROR_NONE  Successful
1267  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1268  * @see  tethering_unset_enabled_cb()
1269  */
1270 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
1271 {
1272         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1273                         "parameter(tethering) is NULL\n");
1274         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1275                         "parameter(callback) is NULL\n");
1276
1277         __tethering_h *th = (__tethering_h *)tethering;
1278         tethering_type_e ti;
1279
1280         if (type != TETHERING_TYPE_ALL) {
1281                 th->enabled_cb[type] = callback;
1282                 th->enabled_user_data[type] = user_data;
1283
1284                 return TETHERING_ERROR_NONE;
1285         }
1286
1287         /* TETHERING_TYPE_ALL */
1288         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1289                 th->enabled_cb[ti] = callback;
1290                 th->enabled_user_data[ti] = user_data;
1291         }
1292
1293         return TETHERING_ERROR_NONE;
1294 }
1295
1296 /**
1297  * @brief Unregisters the callback function called when tethering is disabled.
1298  * @param[in]  tethering  The handle of tethering
1299  * @param[in]  type  The type of tethering
1300  * @retval  #TETHERING_ERROR_NONE  Successful
1301  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1302  * @see  tethering_set_enabled_cb()
1303  */
1304 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
1305 {
1306         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1307                         "parameter(tethering) is NULL\n");
1308
1309         __tethering_h *th = (__tethering_h *)tethering;
1310         tethering_type_e ti;
1311
1312         if (type != TETHERING_TYPE_ALL) {
1313                 th->enabled_cb[type] = NULL;
1314                 th->enabled_user_data[type] = NULL;
1315
1316                 return TETHERING_ERROR_NONE;
1317         }
1318
1319         /* TETHERING_TYPE_ALL */
1320         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1321                 th->enabled_cb[ti] = NULL;
1322                 th->enabled_user_data[ti] = NULL;
1323         }
1324
1325         return TETHERING_ERROR_NONE;
1326 }
1327
1328 /**
1329  * @brief Registers the callback function called when tethering is disabled.
1330  * @param[in]  tethering  The handle of tethering
1331  * @param[in]  type  The type of tethering
1332  * @param[in]  callback  The callback function to invoke
1333  * @param[in]  user_data  The user data to be passed to the callback function
1334  * @retval  #TETHERING_ERROR_NONE  Successful
1335  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1336  * @see  tethering_unset_disabled_cb()
1337  */
1338 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
1339 {
1340         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1341                         "parameter(tethering) is NULL\n");
1342         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1343                         "parameter(callback) is NULL\n");
1344
1345         __tethering_h *th = (__tethering_h *)tethering;
1346         tethering_type_e ti;
1347
1348         if (type != TETHERING_TYPE_ALL) {
1349                 th->disabled_cb[type] = callback;
1350                 th->disabled_user_data[type] = user_data;
1351
1352                 return TETHERING_ERROR_NONE;
1353         }
1354
1355         /* TETHERING_TYPE_ALL */
1356         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1357                 th->disabled_cb[ti] = callback;
1358                 th->disabled_user_data[ti] = user_data;
1359         }
1360
1361         return TETHERING_ERROR_NONE;
1362 }
1363
1364 /**
1365  * @brief Unregisters the callback function called when tethering is disabled.
1366  * @param[in]  tethering  The handle of tethering
1367  * @param[in]  type  The type of tethering
1368  * @retval  #TETHERING_ERROR_NONE  Successful
1369  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1370  * @see  tethering_set_disabled_cb()
1371  */
1372 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
1373 {
1374         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1375                         "parameter(tethering) is NULL\n");
1376
1377         __tethering_h *th = (__tethering_h *)tethering;
1378         tethering_type_e ti;
1379
1380         if (type != TETHERING_TYPE_ALL) {
1381                 th->disabled_cb[type] = NULL;
1382                 th->disabled_user_data[type] = NULL;
1383
1384                 return TETHERING_ERROR_NONE;
1385         }
1386
1387         /* TETHERING_TYPE_ALL */
1388         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1389                 th->disabled_cb[ti] = NULL;
1390                 th->disabled_user_data[ti] = NULL;
1391         }
1392
1393         return TETHERING_ERROR_NONE;
1394 }
1395
1396 /**
1397  * @brief Registers the callback function called when the state of connection is changed.
1398  * @param[in]  tethering  The handle of tethering
1399  * @param[in]  type  The type of tethering
1400  * @param[in]  callback  The callback function to invoke
1401  * @param[in]  user_data  The user data to be passed to the callback function
1402  * @retval  #TETHERING_ERROR_NONE  Successful
1403  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1404  * @see  tethering_unset_connection_state_changed_cb_cb()
1405  */
1406 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
1407 {
1408         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1409                         "parameter(tethering) is NULL\n");
1410         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1411                         "parameter(callback) is NULL\n");
1412
1413         __tethering_h *th = (__tethering_h *)tethering;
1414         tethering_type_e ti;
1415
1416         if (type != TETHERING_TYPE_ALL) {
1417                 th->changed_cb[type] = callback;
1418                 th->changed_user_data[type] = user_data;
1419
1420                 return TETHERING_ERROR_NONE;
1421         }
1422
1423         /* TETHERING_TYPE_ALL */
1424         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1425                 th->changed_cb[ti] = callback;
1426                 th->changed_user_data[ti] = user_data;
1427         }
1428
1429         return TETHERING_ERROR_NONE;
1430 }
1431
1432 /**
1433  * @brief Unregisters the callback function called when the state of connection is changed.
1434  * @param[in]  tethering  The handle of tethering
1435  * @param[in]  type  The type of tethering
1436  * @retval  #TETHERING_ERROR_NONE  Successful
1437  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1438  * @see  tethering_set_connection_state_changed_cb()
1439  */
1440 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
1441 {
1442         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1443                         "parameter(tethering) is NULL\n");
1444
1445         __tethering_h *th = (__tethering_h *)tethering;
1446         tethering_type_e ti;
1447
1448         if (type != TETHERING_TYPE_ALL) {
1449                 th->changed_cb[type] = NULL;
1450                 th->changed_user_data[type] = NULL;
1451
1452                 return TETHERING_ERROR_NONE;
1453         }
1454
1455         /* TETHERING_TYPE_ALL */
1456         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1457                 th->changed_cb[ti] = NULL;
1458                 th->changed_user_data[ti] = NULL;
1459         }
1460
1461         return TETHERING_ERROR_NONE;
1462 }
1463
1464 /**
1465  * @brief Sets the security type of Wi-Fi tethering.
1466  * @remarks You must set this value when Wi-Fi tethering is disabled.
1467  * @param[in]  tethering  The handle of tethering
1468  * @param[in]  type  The security type
1469  * @return 0 on success, otherwise negative error value.
1470  * @retval  #TETHERING_ERROR_NONE  Successful
1471  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1472  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1473  * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
1474  * @pre  Wi-Fi tethering must be disabled.
1475  * @see  tethering_is_enabled()
1476  * @see  tethering_wifi_get_security_type()
1477  */
1478 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
1479 {
1480         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1481                         "parameter(tethering) is NULL\n");
1482         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == true,
1483                         TETHERING_ERROR_INVALID_OPERATION,
1484                         "Wi-Fi tethering is enabled\n");
1485         DBG("+\n");
1486
1487         __tethering_h *th = (__tethering_h *)tethering;
1488         DBusGProxy *proxy = th->client_bus_proxy;
1489         GError *error = NULL;
1490         char *type_str = NULL;
1491
1492         if (type == TETHERING_WIFI_SECURITY_TYPE_NONE) {
1493                 type_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
1494         } else if (type == TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) {
1495                 type_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
1496         } else {
1497                 ERR("Unsupported type\n");
1498                 return TETHERING_ERROR_INVALID_PARAMETER;
1499         }
1500
1501         com_samsung_mobileap_set_wifi_tethering_security_type(proxy, type_str, &error);
1502         if (error != NULL) {
1503                 ERR("DBus fail : %s\n", error->message);
1504                 g_error_free(error);
1505                 return TETHERING_ERROR_OPERATION_FAILED;
1506         }
1507
1508         DBG("-\n");
1509         return TETHERING_ERROR_NONE;
1510 }
1511
1512 /**
1513  * @brief Gets the security type of Wi-Fi tethering.
1514  * @param[in]  tethering  The handle of tethering
1515  * @param[out]  type  The security type
1516  * @return 0 on success, otherwise negative error value.
1517  * @retval  #TETHERING_ERROR_NONE  Successful
1518  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1519  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1520  * @see  tethering_wifi_set_security_type()
1521  */
1522 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
1523 {
1524         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1525                         "parameter(tethering) is NULL\n");
1526         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1527                         "parameter(type) is NULL\n");
1528         DBG("+\n");
1529
1530         __tethering_h *th = (__tethering_h *)tethering;
1531         DBusGProxy *proxy = th->client_bus_proxy;
1532         GError *error = NULL;
1533         char *type_str = NULL;
1534
1535         com_samsung_mobileap_get_wifi_tethering_security_type(proxy, &type_str, &error);
1536         if (error != NULL) {
1537                 ERR("DBus fail : %s\n", error->message);
1538                 g_error_free(error);
1539                 return TETHERING_ERROR_OPERATION_FAILED;
1540         }
1541
1542         if (type_str == NULL)
1543                 return TETHERING_ERROR_OPERATION_FAILED;
1544
1545         DBG("security type : %s\n", type_str);
1546         if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
1547                 *type = TETHERING_WIFI_SECURITY_TYPE_NONE;
1548         else if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
1549                 *type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
1550         else {
1551                 ERR("Unknown security type : %s\n", type_str);
1552                 g_free(type_str);
1553                 return TETHERING_ERROR_OPERATION_FAILED;
1554         }
1555
1556         g_free(type_str);
1557
1558         DBG("-\n");
1559         return TETHERING_ERROR_NONE;
1560 }
1561
1562 /**
1563  * @brief Gets the SSID (service set identifier).
1564  * @remarks @a ssid must be released with free() by you.
1565  * @param[in]  tethering  The handle of tethering
1566  * @param[out]  ssid  The SSID
1567  * @return 0 on success, otherwise negative error value.
1568  * @retval  #TETHERING_ERROR_NONE  Successful
1569  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1570  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1571  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1572  */
1573 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
1574 {
1575         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1576                         "parameter(tethering) is NULL\n");
1577         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1578                         "parameter(ssid) is NULL\n");
1579         DBG("+\n");
1580
1581         __tethering_h *th = (__tethering_h *)tethering;
1582         DBusGProxy *proxy = th->client_bus_proxy;
1583         GError *error = NULL;
1584         char *ssid_buf = NULL;
1585
1586         com_samsung_mobileap_get_wifi_tethering_ssid(proxy, &ssid_buf, &error);
1587         if (error != NULL) {
1588                 ERR("dbus fail : %s\n", error->message);
1589                 g_error_free(error);
1590                 return TETHERING_ERROR_OPERATION_FAILED;
1591         }
1592
1593         if (ssid_buf == NULL)
1594                 return TETHERING_ERROR_OPERATION_FAILED;
1595
1596         *ssid = strdup(ssid_buf);
1597         if (*ssid == NULL) {
1598                 ERR("Memory allocation failed\n");
1599                 return TETHERING_ERROR_OUT_OF_MEMORY;
1600         }
1601
1602         g_free(ssid_buf);
1603
1604         DBG("-\n");
1605         return TETHERING_ERROR_NONE;
1606 }
1607
1608 /**
1609  * @brief Sets the visibility of SSID(service set identifier).
1610  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
1611  * @remarks You must set this value when Wi-Fi tethering is disabled.
1612  * @param[in]  tethering  The handle of tethering
1613  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
1614  * @return 0 on success, otherwise negative error value.
1615  * @retval  #TETHERING_ERROR_NONE  Successful
1616  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1617  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1618  * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
1619  * @pre  Wi-Fi tethering must be disabled.
1620  * @see  tethering_is_enabled()
1621  * @see  tethering_wifi_get_ssid_visibility()
1622  */
1623 int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
1624 {
1625         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1626                         "parameter(tethering) is NULL\n");
1627         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == true,
1628                         TETHERING_ERROR_INVALID_OPERATION,
1629                         "Wi-Fi tethering is enabled\n");
1630         DBG("+\n");
1631
1632         __tethering_h *th = (__tethering_h *)tethering;
1633         DBusGProxy *proxy = th->client_bus_proxy;
1634         GError *error = NULL;
1635         int hide_mode = 0;
1636
1637         if (visible)
1638                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_OFF;
1639         else
1640                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_ON;
1641
1642         com_samsung_mobileap_set_wifi_tethering_hide_mode(proxy, hide_mode, &error);
1643         if (error != NULL) {
1644                 ERR("dbus fail : %s\n", error->message);
1645                 g_error_free(error);
1646                 return TETHERING_ERROR_OPERATION_FAILED;
1647         }
1648
1649         DBG("-\n");
1650         return TETHERING_ERROR_NONE;
1651 }
1652
1653 /**
1654  * @brief Gets the visibility of SSID(service set identifier).
1655  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
1656  * @param[in]  tethering  The handle of tethering
1657  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
1658  * @return 0 on success, otherwise negative error value.
1659  * @retval  #TETHERING_ERROR_NONE  Successful
1660  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1661  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1662  * @see  tethering_wifi_set_ssid_visibility()
1663  */
1664 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
1665 {
1666         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1667                         "parameter(tethering) is NULL\n");
1668         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1669                         "parameter(enabled) is NULL\n");
1670         DBG("+\n");
1671
1672         __tethering_h *th = (__tethering_h *)tethering;
1673         DBusGProxy *proxy = th->client_bus_proxy;
1674         GError *error = NULL;
1675         int hide_mode = 0;
1676
1677         com_samsung_mobileap_get_wifi_tethering_hide_mode(proxy, &hide_mode, &error);
1678         if (error != NULL) {
1679                 ERR("dbus fail : %s\n", error->message);
1680                 g_error_free(error);
1681                 return TETHERING_ERROR_OPERATION_FAILED;
1682         }
1683         DBG("hide mode : %d\n", hide_mode);
1684
1685         if (hide_mode == VCONFKEY_MOBILE_AP_HIDE_OFF)
1686                 *visible = true;
1687         else
1688                 *visible = false;
1689
1690         DBG("-\n");
1691         return TETHERING_ERROR_NONE;
1692 }
1693
1694 /**
1695  * @brief Sets the passphrase.
1696  * @remarks You must set this value when Wi-Fi tethering is disabled.
1697  * @param[in]  tethering  The handle of tethering
1698  * @param[in]  passphrase  The passphrase
1699  * @return 0 on success, otherwise negative error value.
1700  * @retval  #TETHERING_ERROR_NONE  Successful
1701  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1702  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1703  * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
1704  * @pre  Wi-Fi tethering must be disabled.
1705  * @see  tethering_is_enabled()
1706  * @see  tethering_wifi_get_passphrase()
1707  */
1708 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
1709 {
1710         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1711                         "parameter(tethering) is NULL\n");
1712         _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == true,
1713                         TETHERING_ERROR_INVALID_OPERATION,
1714                         "Wi-Fi tethering is enabled\n");
1715         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1716                         "parameter(passphrase) is NULL\n");
1717         DBG("+\n");
1718
1719         __tethering_h *th = (__tethering_h *)tethering;
1720         DBusGProxy *proxy = th->client_bus_proxy;
1721         GError *error = NULL;
1722
1723         com_samsung_mobileap_set_wifi_tethering_passphrase(proxy,
1724                         passphrase, strlen(passphrase), &error);
1725         if (error != NULL) {
1726                 ERR("dbus fail : %s\n", error->message);
1727                 g_error_free(error);
1728                 return TETHERING_ERROR_OPERATION_FAILED;
1729         }
1730
1731         DBG("-\n");
1732         return TETHERING_ERROR_NONE;
1733 }
1734
1735 /**
1736  * @brief Gets the passphrase.
1737  * @remarks @a passphrase must be released with free() by you.
1738  * @param[in]  tethering  The handle of tethering
1739  * @param[out]  passphrase  The passphrase
1740  * @return 0 on success, otherwise negative error value.
1741  * @retval  #TETHERING_ERROR_NONE  Successful
1742  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1743  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1744  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1745  * @see  tethering_wifi_set_passphrase()
1746  */
1747 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
1748 {
1749         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1750                         "parameter(tethering) is NULL\n");
1751         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1752                         "parameter(passphrase) is NULL\n");
1753         DBG("+\n");
1754
1755         __tethering_h *th = (__tethering_h *)tethering;
1756         DBusGProxy *proxy = th->client_bus_proxy;
1757         GError *error = NULL;
1758         char *passphrase_buf = NULL;
1759         unsigned int len = 0;
1760
1761         com_samsung_mobileap_get_wifi_tethering_passphrase(proxy,
1762                         &passphrase_buf, &len, &error);
1763         if (error != NULL) {
1764                 ERR("dbus fail : %s\n", error->message);
1765                 g_error_free(error);
1766                 return TETHERING_ERROR_OPERATION_FAILED;
1767         }
1768
1769         if (passphrase_buf == NULL)
1770                 return TETHERING_ERROR_OPERATION_FAILED;
1771
1772         *passphrase = strdup(passphrase_buf);
1773         if (*passphrase == NULL) {
1774                 ERR("Memory allocation failed\n");
1775                 return TETHERING_ERROR_OUT_OF_MEMORY;
1776         }
1777
1778         g_free(passphrase_buf);
1779
1780         DBG("-\n");
1781         return TETHERING_ERROR_NONE;
1782 }