Code Sync [Tizen3.0]: Merged the tizen_2.4 Spin code to tizen.org
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-network.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <dbus/dbus-glib.h>
25 #include <dbus/dbus.h>
26 #include <glib.h>
27 #include <dlog.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include <syspopup_caller.h>
31 #include <net_connection.h>
32
33 #include "bluetooth-api.h"
34 #include "bt-service-network.h"
35 #include "bt-service-common.h"
36 #include "bt-service-event.h"
37 #include "bt-service-util.h"
38 #include "bt-internal-types.h"
39
40 void _bt_util_addr_type_to_addr_net_string(char *address,
41                                         unsigned char *addr)
42 {
43         ret_if(address == NULL);
44         ret_if(addr == NULL);
45
46         snprintf(address, BT_ADDRESS_STR_LEN, "%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X", addr[0],
47                         addr[1], addr[2], addr[3], addr[4], addr[5]);
48 }
49
50 static connection_profile_h __bt_get_net_profile(void *connection,
51                                                 connection_iterator_type_e type,
52                                                 unsigned char *address)
53 {
54         int result;
55         gchar **split_string;
56         char net_address[BT_ADDRESS_STR_LEN + 1] = { 0 };
57         char *profile_name = NULL;
58         connection_profile_iterator_h profile_iter;
59         connection_profile_h profile_h;
60         connection_profile_type_e profile_type;
61
62         retv_if(connection == NULL, NULL);
63         retv_if(address == NULL, NULL);
64
65         BT_DBG("net_conn: %x", connection);
66
67         _bt_util_addr_type_to_addr_net_string(net_address, address);
68
69         result = connection_get_profile_iterator(connection,
70                                                         type,
71                                                         &profile_iter);
72         if (result != CONNECTION_ERROR_NONE) {
73                 BT_ERR("Fail to get profile iterator [%d]", result);
74                 return NULL;
75         }
76
77         while (connection_profile_iterator_has_next(profile_iter)) {
78                         profile_name = NULL;
79                         profile_h = NULL;
80                         split_string = NULL;
81
82                         if (connection_profile_iterator_next(profile_iter,
83                                                 &profile_h) != CONNECTION_ERROR_NONE) {
84                                 BT_ERR("Fail to get profile handle");
85                                 return NULL;
86                         }
87
88                         if (connection_profile_get_type(profile_h,
89                                                 &profile_type) != CONNECTION_ERROR_NONE) {
90                                 BT_ERR("Fail to get profile type");
91                                 continue;
92                         }
93
94                         if (profile_type != CONNECTION_PROFILE_TYPE_BT)
95                                 continue;
96
97                         if (connection_profile_get_name(profile_h,
98                                                 &profile_name) != CONNECTION_ERROR_NONE) {
99                                 BT_ERR("Fail to get profile name");
100                                 return NULL;
101                         }
102
103                         split_string = g_strsplit(profile_name, "_", 3);
104
105                         g_free(profile_name);
106
107                         if (g_strv_length(split_string) < 3)
108                                 continue;
109
110                         if (g_ascii_strcasecmp(split_string[2], net_address) == 0) {
111                                 BT_DBG("matched profile");
112                                 g_strfreev(split_string);
113                                 return profile_h;
114                         }
115
116                         g_strfreev(split_string);
117         }
118
119         return NULL;
120 }
121
122 int _bt_is_network_connected(void *connection, unsigned char *address,
123                                         gboolean *is_connected)
124 {
125         void *handle = NULL;
126         handle = __bt_get_net_profile(connection,
127                                 CONNECTION_ITERATOR_TYPE_CONNECTED,
128                                 address);
129         if(handle)
130                 *is_connected = TRUE;
131         else
132                 *is_connected = FALSE;
133
134         return BLUETOOTH_ERROR_NONE;
135 }
136
137 static void __bt_network_connect_cb(DBusGProxy *proxy, DBusGProxyCall *call,
138                                     gpointer user_data)
139 {
140         GError *g_error = NULL;
141         char *device = NULL;
142         GArray *out_param1 = NULL;
143         GArray *out_param2 = NULL;
144         bluetooth_device_address_t device_addr = { {0} };
145         int result = BLUETOOTH_ERROR_NONE;
146         bt_function_data_t *func_data;
147         request_info_t *req_info;
148
149         dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_STRING, &device, G_TYPE_INVALID);
150
151         g_object_unref(proxy);
152
153         func_data = user_data;
154
155         if (func_data == NULL) {
156                 /* Send reply */
157                 BT_ERR("func_data == NULL");
158                 goto done;
159         }
160
161         req_info = _bt_get_request_info(func_data->req_id);
162         if (req_info == NULL) {
163                 BT_ERR("req_info == NULL");
164                 goto done;
165         }
166
167         if (g_error != NULL) {
168                 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
169                 result = BLUETOOTH_ERROR_INTERNAL;
170         }
171
172         if (req_info->context == NULL)
173                 goto done;
174
175         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
176         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
177
178         _bt_convert_addr_string_to_type(device_addr.addr,
179                                         func_data->address);
180
181         g_array_append_vals(out_param1, &device_addr,
182                                 sizeof(bluetooth_device_address_t));
183         g_array_append_vals(out_param2, &result, sizeof(int));
184
185         dbus_g_method_return(req_info->context, out_param1, out_param2);
186
187         g_array_free(out_param1, TRUE);
188         g_array_free(out_param2, TRUE);
189
190         _bt_delete_request_list(req_info->req_id);
191 done:
192         if (g_error)
193                 g_error_free(g_error);
194
195         if (func_data) {
196                 g_free(func_data->address);
197                 g_free(func_data);
198         }
199 }
200
201 static void __bt_network_disconnect_cb(DBusGProxy *proxy, DBusGProxyCall *call,
202                                     gpointer user_data)
203 {
204         GError *g_error = NULL;
205         GArray *out_param1 = NULL;
206         GArray *out_param2 = NULL;
207         bluetooth_device_address_t device_addr = { {0} };
208         int result = BLUETOOTH_ERROR_NONE;
209         bt_function_data_t *func_data;
210         request_info_t *req_info;
211
212         dbus_g_proxy_end_call(proxy, call, &g_error, G_TYPE_INVALID);
213
214         g_object_unref(proxy);
215
216         func_data = user_data;
217
218         if (func_data == NULL) {
219                 /* Send reply */
220                 BT_ERR("func_data == NULL");
221                 goto done;
222         }
223
224         req_info = _bt_get_request_info(func_data->req_id);
225         if (req_info == NULL) {
226                 BT_ERR("req_info == NULL");
227                 goto done;
228         }
229
230         if (g_error != NULL) {
231                 BT_ERR("Network Connect Dbus Call Error: %s\n", g_error->message);
232                 result = BLUETOOTH_ERROR_INTERNAL;
233         }
234
235         if (req_info->context == NULL)
236                 goto done;
237
238         out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
239         out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
240
241         _bt_convert_addr_string_to_type(device_addr.addr,
242                                         func_data->address);
243
244         g_array_append_vals(out_param1, &device_addr,
245                                 sizeof(bluetooth_device_address_t));
246         g_array_append_vals(out_param2, &result, sizeof(int));
247
248         dbus_g_method_return(req_info->context, out_param1, out_param2);
249
250         g_array_free(out_param1, TRUE);
251         g_array_free(out_param2, TRUE);
252
253         _bt_delete_request_list(req_info->req_id);
254 done:
255         if (g_error)
256                 g_error_free(g_error);
257
258         if (func_data) {
259                 g_free(func_data->address);
260                 g_free(func_data);
261         }
262 }
263
264 int _bt_network_activate(void)
265 {
266         int ret = BLUETOOTH_ERROR_NONE;
267         char *adapter_path;
268         GError *err = NULL;
269         DBusGConnection *conn;
270         DBusGProxy *server_proxy;
271
272         conn = _bt_get_system_gconn();
273         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
274
275         adapter_path = _bt_get_adapter_path();
276         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
277
278         server_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
279                              adapter_path, BT_NETWORK_SERVER_INTERFACE);
280
281         g_free(adapter_path);
282
283         if (server_proxy == NULL) {
284                 BT_ERR("Failed to get the network server proxy\n");
285                 return BLUETOOTH_ERROR_INTERNAL;
286         }
287
288         if (!dbus_g_proxy_call(server_proxy, "Register", &err,
289                         G_TYPE_STRING, NAP_UUID_NAME,
290                         G_TYPE_STRING, NET_BRIDGE_INTERFACE,
291                         G_TYPE_INVALID, G_TYPE_INVALID)) {
292                 if (err != NULL) {
293                         BT_ERR("Network server register Error: %s\n", err->message);
294                         if (g_strcmp0(err->message, "Already Exists") == 0) {
295                                 ret = BLUETOOTH_ERROR_ALREADY_INITIALIZED;
296                         } else {
297                                 ret = BLUETOOTH_ERROR_INTERNAL;
298                         }
299                         g_error_free(err);
300                 }
301         }
302
303         g_object_unref(server_proxy);
304
305         return ret;
306 }
307
308 int _bt_network_deactivate(void)
309 {
310         char *adapter_path;
311         GError *err = NULL;
312         DBusGConnection *conn;
313         DBusGProxy *server_proxy;
314         int ret = BLUETOOTH_ERROR_NONE;
315
316         conn = _bt_get_system_gconn();
317         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
318
319         adapter_path = _bt_get_adapter_path();
320         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
321
322         server_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
323                              adapter_path, BT_NETWORK_SERVER_INTERFACE);
324
325         g_free(adapter_path);
326
327         if (server_proxy == NULL) {
328                 BT_ERR("Failed to get the network server proxy\n");
329                 return BLUETOOTH_ERROR_INTERNAL;
330         }
331
332         if (!dbus_g_proxy_call(server_proxy, "Unregister", &err,
333                         G_TYPE_STRING, NAP_UUID_NAME,
334                         G_TYPE_INVALID, G_TYPE_INVALID)) {
335                 if (err != NULL) {
336                         BT_ERR("Network server unregister Error: %s\n", err->message);
337                         if (g_strcmp0(err->message,
338                                         "Operation currently not available") == 0) {
339                                 ret = BLUETOOTH_ERROR_ALREADY_DEACTIVATED;
340                         } else {
341                                 ret = BLUETOOTH_ERROR_INTERNAL;
342                         }
343                         g_error_free(err);
344                 }
345         }
346
347         g_object_unref(server_proxy);
348
349         return ret;
350 }
351
352 int _bt_network_connect(int request_id, int role,
353                 bluetooth_device_address_t *device_address)
354 {
355         gchar *device_path = NULL;
356         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
357         char remote_role[BLUETOOTH_UUID_STRING_MAX] = { 0 };
358         bt_function_data_t *func_data;
359         DBusGProxy *adapter_proxy;
360         DBusGProxy *profile_proxy;
361         DBusGConnection *conn;
362
363         BT_CHECK_PARAMETER(device_address, return);
364
365         switch (role) {
366         case BLUETOOTH_NETWORK_PANU_ROLE:
367                 g_strlcpy(remote_role, PANU_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
368                 break;
369
370         case BLUETOOTH_NETWORK_NAP_ROLE:
371                 g_strlcpy(remote_role, NAP_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
372                 break;
373
374         case BLUETOOTH_NETWORK_GN_ROLE:
375                 g_strlcpy(remote_role, GN_UUID_NAME, BLUETOOTH_UUID_STRING_MAX);
376                 break;
377         default:
378                 BT_ERR("Unknown role");
379                 return BLUETOOTH_ERROR_INTERNAL;
380         }
381
382         adapter_proxy = _bt_get_adapter_proxy();
383         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
384
385         conn = _bt_get_system_gconn();
386         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
387
388         _bt_convert_addr_type_to_string(address, device_address->addr);
389
390         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
391                           G_TYPE_STRING, address, G_TYPE_INVALID,
392                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
393
394         if (device_path == NULL) {
395                 BT_ERR("No paired device");
396                 return BLUETOOTH_ERROR_NOT_PAIRED;
397         }
398
399         profile_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
400                                       device_path, BT_NETWORK_CLIENT_INTERFACE);
401         g_free(device_path);
402         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
403         func_data = g_malloc0(sizeof(bt_function_data_t));
404
405         func_data->address = g_strdup(address);
406         func_data->req_id = request_id;
407
408         if (!dbus_g_proxy_begin_call(profile_proxy, "Connect",
409                         (DBusGProxyCallNotify)__bt_network_connect_cb,
410                         func_data, NULL,
411                         G_TYPE_STRING, remote_role,
412                         G_TYPE_INVALID)) {
413                 BT_ERR("network connect Dbus Call Error");
414                 g_object_unref(profile_proxy);
415                 return BLUETOOTH_ERROR_INTERNAL;
416         }
417
418         return BLUETOOTH_ERROR_NONE;
419 }
420
421 int _bt_network_disconnect(int request_id,
422                 bluetooth_device_address_t *device_address)
423 {
424         gchar *device_path = NULL;
425         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
426         bt_function_data_t *func_data;
427         DBusGProxy *adapter_proxy;
428         DBusGProxy *profile_proxy;
429         DBusGConnection *conn;
430
431         BT_CHECK_PARAMETER(device_address, return);
432
433         adapter_proxy = _bt_get_adapter_proxy();
434         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
435
436         conn = _bt_get_system_gconn();
437         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
438
439         _bt_convert_addr_type_to_string(address, device_address->addr);
440
441         dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
442                           G_TYPE_STRING, address, G_TYPE_INVALID,
443                           DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
444
445         if (device_path == NULL) {
446                 BT_ERR("No paired device");
447                 return BLUETOOTH_ERROR_NOT_PAIRED;
448         }
449
450         profile_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
451                                       device_path, BT_NETWORK_CLIENT_INTERFACE);
452         g_free(device_path);
453         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
454         func_data = g_malloc0(sizeof(bt_function_data_t));
455
456         func_data->address = g_strdup(address);
457         func_data->req_id = request_id;
458
459         if (!dbus_g_proxy_begin_call(profile_proxy, "Disconnect",
460                         (DBusGProxyCallNotify)__bt_network_disconnect_cb,
461                         func_data, NULL, G_TYPE_INVALID)) {
462                 BT_ERR("network disconnect Dbus Call Error");
463                 g_object_unref(profile_proxy);
464                 return BLUETOOTH_ERROR_INTERNAL;
465         }
466
467         return BLUETOOTH_ERROR_NONE;
468 }
469
470 int _bt_network_server_disconnect(int request_id,
471                 bluetooth_device_address_t *device_address)
472 {
473         gchar *adapter_path = NULL;
474         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
475         bt_function_data_t *func_data;
476         DBusGProxy *profile_proxy;
477         DBusGConnection *conn;
478
479         BT_CHECK_PARAMETER(device_address, return);
480
481         conn = _bt_get_system_gconn();
482         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
483
484         adapter_path = _bt_get_adapter_path();
485         if (adapter_path == NULL) {
486                 BT_ERR("No adapter found");
487                 return BLUETOOTH_ERROR_INTERNAL;
488         }
489
490         _bt_convert_addr_type_to_string(address, device_address->addr);
491
492         profile_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
493                                       adapter_path, BT_NETWORK_SERVER_INTERFACE);
494         g_free(adapter_path);
495         retv_if(profile_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
496         func_data = g_malloc0(sizeof(bt_function_data_t));
497
498         func_data->address = g_strdup(address);
499         func_data->req_id = request_id;
500
501         if (!dbus_g_proxy_begin_call(profile_proxy, "Disconnect",
502                         (DBusGProxyCallNotify)__bt_network_disconnect_cb,
503                         func_data, NULL, G_TYPE_STRING, address,
504                         G_TYPE_INVALID)) {
505                 BT_ERR("network server disconnect Dbus Call Error");
506                 g_free(func_data->address);
507                 g_free(func_data);
508                 g_object_unref(profile_proxy);
509                 return BLUETOOTH_ERROR_INTERNAL;
510         }
511
512         return BLUETOOTH_ERROR_NONE;
513 }