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