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