4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 #include <dbus/dbus-glib.h>
22 #include <dbus/dbus-glib-bindings.h>
23 #include <dbus/dbus-glib-lowlevel.h>
27 #include "bluetooth-api.h"
28 #include "bt-service-common.h"
29 #include "bt-service-util.h"
30 #include "bt-service-event.h"
31 #include "bt-service-adapter.h"
32 #include "bt-service-device.h"
33 #include "bt-service-hid.h"
34 #include "bt-service-network.h"
35 #include "bt-service-audio.h"
36 #include "bt-service-oob.h"
37 #include "bt-service-avrcp.h"
38 #include "bt-service-opp-client.h"
39 #include "bt-service-obex-server.h"
40 #include "bt-service-rfcomm-client.h"
41 #include "bt-service-rfcomm-server.h"
42 #include "bt-request-handler.h"
44 /* auto generated header by bt-request-service.xml*/
45 #include "bt-service-method.h"
47 DBusGConnection *bt_service_conn;
48 BtService *service_object;
50 GType bt_service_get_type (void);
52 G_DEFINE_TYPE(BtService, bt_service, G_TYPE_OBJECT);
54 /*This is part of platform provided code skeleton for client server model*/
55 static void bt_service_class_init (BtServiceClass *service_class)
57 dbus_g_object_type_install_info(G_TYPE_FROM_CLASS(service_class),
58 &dbus_glib_bt_object_info);
61 /*This is part of platform provided code skeleton for client server model*/
62 static void bt_service_init (BtService *service)
66 static int __bt_bluez_request(int function_name,
69 DBusGMethodInvocation *context,
76 int result = BLUETOOTH_ERROR_NONE;
78 switch (function_name) {
79 case BT_ENABLE_ADAPTER:
80 result = _bt_enable_adapter();
82 case BT_DISABLE_ADAPTER:
83 result = _bt_disable_adapter();
85 case BT_RESET_ADAPTER:
86 result = _bt_reset_adapter();
88 case BT_CHECK_ADAPTER: {
91 result = _bt_check_adapter(&enabled);
93 g_array_append_vals(*out_param1, &enabled,
97 case BT_GET_LOCAL_ADDRESS: {
98 bluetooth_device_address_t local_address = { {0} };
99 result = _bt_get_local_address(&local_address);
101 g_array_append_vals(*out_param1, &local_address,
102 sizeof(bluetooth_device_address_t));
105 case BT_GET_LOCAL_NAME: {
106 bluetooth_device_name_t local_name = { {0} };
107 result = _bt_get_local_name(&local_name);
109 g_array_append_vals(*out_param1, &local_name,
110 sizeof(bluetooth_device_name_t));
114 case BT_SET_LOCAL_NAME: {
115 bluetooth_device_name_t local_name = { {0} };
117 local_name = g_array_index(in_param1,
118 bluetooth_device_name_t, 0);
120 result = _bt_set_local_name(local_name.name);
124 case BT_IS_SERVICE_USED: {
126 gboolean used = FALSE;
128 uuid = &g_array_index(in_param1, char, 0);
130 result = _bt_is_service_used(uuid, &used);
132 if (result == BLUETOOTH_ERROR_NONE) {
133 g_array_append_vals(*out_param1, &used,
138 case BT_GET_DISCOVERABLE_MODE: {
139 int mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
141 result = _bt_get_discoverable_mode(&mode);
143 g_array_append_vals(*out_param1, &mode, sizeof(int));
146 case BT_SET_DISCOVERABLE_MODE: {
147 int mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
150 mode = g_array_index(in_param1, int, 0);
151 time = g_array_index(in_param2, int, 0);
153 result = _bt_set_discoverable_mode(mode, time);
156 case BT_GET_DISCOVERABLE_TIME: {
159 result = _bt_get_timeout_value(&timeout);
161 g_array_append_vals(*out_param1, &timeout, sizeof(int));
164 case BT_START_DISCOVERY:
165 result = _bt_start_discovery();
168 case BT_CANCEL_DISCOVERY:
169 result = _bt_cancel_discovery();
172 case BT_IS_DISCOVERYING: {
173 gboolean discovering = FALSE;
174 discovering = _bt_is_discovering();
176 g_array_append_vals(*out_param1, &discovering, sizeof(gboolean));
179 case BT_GET_BONDED_DEVICES:
180 result = _bt_get_bonded_devices(out_param1);
183 case BT_GET_BONDED_DEVICE: {
184 bluetooth_device_address_t address = { {0} };
185 bluetooth_device_info_t dev_info;
187 address = g_array_index(in_param1,
188 bluetooth_device_address_t, 0);
190 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
191 result = _bt_get_bonded_device_info(&address, &dev_info);
193 if (result == BLUETOOTH_ERROR_NONE) {
194 g_array_append_vals(*out_param1, &dev_info,
195 sizeof(bluetooth_device_info_t));
199 case BT_BOND_DEVICE: {
200 bluetooth_device_address_t address = { {0} };
202 address = g_array_index(in_param1,
203 bluetooth_device_address_t, 0);
205 result = _bt_bond_device(request_id, &address, out_param1);
208 case BT_CANCEL_BONDING: {
209 result = _bt_cancel_bonding();
212 case BT_UNBOND_DEVICE: {
213 bluetooth_device_address_t address = { {0} };
215 address = g_array_index(in_param1,
216 bluetooth_device_address_t, 0);
218 result = _bt_unbond_device(request_id, &address, out_param1);
223 bluetooth_device_address_t address = { {0} };
224 const char *local_name;
226 address = g_array_index(in_param1,
227 bluetooth_device_address_t, 0);
229 local_name = &g_array_index(in_param2, char, 0);
231 result = _bt_set_alias(&address, local_name);
234 case BT_SEARCH_SERVICE: {
235 bluetooth_device_address_t address = { {0} };
237 address = g_array_index(in_param1,
238 bluetooth_device_address_t, 0);
240 result = _bt_search_device(request_id, &address);
241 if (result != BLUETOOTH_ERROR_NONE) {
242 g_array_append_vals(*out_param1, &address,
243 sizeof(bluetooth_device_address_t));
247 case BT_CANCEL_SEARCH_SERVICE: {
248 result = _bt_cancel_search_device();
251 case BT_SET_AUTHORIZATION: {
252 bluetooth_device_address_t address = { {0} };
255 address = g_array_index(in_param1,
256 bluetooth_device_address_t, 0);
258 authorize = g_array_index(in_param2, gboolean, 0);
260 result = _bt_set_authorization(&address, authorize);
263 case BT_IS_DEVICE_CONNECTED: {
264 bluetooth_device_address_t address = { {0} };
266 gboolean connected = FALSE;
268 address = g_array_index(in_param1,
269 bluetooth_device_address_t, 0);
271 type = g_array_index(in_param2, int, 0);
273 result = _bt_is_device_connected(&address, type, &connected);
275 if (result == BLUETOOTH_ERROR_NONE) {
276 g_array_append_vals(*out_param1, &connected,
282 case BT_HID_CONNECT: {
283 bluetooth_device_address_t address = { {0} };
285 address = g_array_index(in_param1,
286 bluetooth_device_address_t, 0);
288 result = _bt_hid_connect(request_id, &address);
289 if (result != BLUETOOTH_ERROR_NONE) {
290 g_array_append_vals(*out_param1, &address,
291 sizeof(bluetooth_device_address_t));
295 case BT_HID_DISCONNECT: {
296 bluetooth_device_address_t address = { {0} };
298 address = g_array_index(in_param1,
299 bluetooth_device_address_t, 0);
301 result = _bt_hid_disconnect(request_id, &address);
302 if (result != BLUETOOTH_ERROR_NONE) {
303 g_array_append_vals(*out_param1, &address,
304 sizeof(bluetooth_device_address_t));
308 case BT_NETWORK_ACTIVATE:
309 result = _bt_network_activate();
311 case BT_NETWORK_DEACTIVATE:
312 result = _bt_network_deactivate();
314 case BT_NETWORK_CONNECT: {
315 bluetooth_device_address_t address = { {0} };
318 address = g_array_index(in_param1,
319 bluetooth_device_address_t, 0);
321 role = g_array_index(in_param2, int, 0);
323 result = _bt_network_connect(request_id, role, &address);
324 if (result != BLUETOOTH_ERROR_NONE) {
325 g_array_append_vals(*out_param1, &address,
326 sizeof(bluetooth_device_address_t));
330 case BT_NETWORK_DISCONNECT: {
331 bluetooth_device_address_t address = { {0} };
333 address = g_array_index(in_param1,
334 bluetooth_device_address_t, 0);
336 result = _bt_network_disconnect(request_id, &address);
337 if (result != BLUETOOTH_ERROR_NONE) {
338 g_array_append_vals(*out_param1, &address,
339 sizeof(bluetooth_device_address_t));
343 case BT_AUDIO_CONNECT: {
344 bluetooth_device_address_t address = { {0} };
346 address = g_array_index(in_param1,
347 bluetooth_device_address_t, 0);
349 result = _bt_audio_connect(request_id, BT_AUDIO_ALL,
350 &address, out_param1);
353 case BT_AUDIO_DISCONNECT: {
354 bluetooth_device_address_t address = { {0} };
356 address = g_array_index(in_param1,
357 bluetooth_device_address_t, 0);
359 result = _bt_audio_disconnect(request_id, BT_AUDIO_ALL,
360 &address, out_param1);
363 case BT_AG_CONNECT: {
364 bluetooth_device_address_t address = { {0} };
366 address = g_array_index(in_param1,
367 bluetooth_device_address_t, 0);
369 result = _bt_audio_connect(request_id, BT_AUDIO_HSP,
370 &address, out_param1);
373 case BT_AG_DISCONNECT: {
374 bluetooth_device_address_t address = { {0} };
376 address = g_array_index(in_param1,
377 bluetooth_device_address_t, 0);
379 result = _bt_audio_disconnect(request_id, BT_AUDIO_HSP,
380 &address, out_param1);
383 case BT_AV_CONNECT: {
384 bluetooth_device_address_t address = { {0} };
386 address = g_array_index(in_param1,
387 bluetooth_device_address_t, 0);
389 result = _bt_audio_connect(request_id, BT_AUDIO_A2DP,
390 &address, out_param1);
393 case BT_AV_DISCONNECT: {
394 bluetooth_device_address_t address = { {0} };
396 address = g_array_index(in_param1,
397 bluetooth_device_address_t, 0);
399 result = _bt_audio_disconnect(request_id, BT_AUDIO_A2DP,
400 &address, out_param1);
403 case BT_GET_SPEAKER_GAIN: {
406 result = _bt_audio_get_speaker_gain(&volume);
408 g_array_append_vals(*out_param1, &volume,
409 sizeof(unsigned int));
412 case BT_SET_SPEAKER_GAIN: {
415 volume = g_array_index(in_param1,
418 result = _bt_audio_set_speaker_gain(volume);
422 case BT_OOB_READ_LOCAL_DATA: {
423 bt_oob_data_t local_oob_data;
425 memset(&local_oob_data, 0x00, sizeof(bt_oob_data_t));
426 result = _bt_oob_read_local_data(&local_oob_data);
428 g_array_append_vals(*out_param1, &local_oob_data,
429 sizeof(bt_oob_data_t));
433 case BT_OOB_ADD_REMOTE_DATA: {
434 bluetooth_device_address_t address = { {0} };
435 bt_oob_data_t local_oob_data;
437 address = g_array_index(in_param1,
438 bluetooth_device_address_t, 0);
440 local_oob_data = g_array_index(in_param2,
443 result = _bt_oob_add_remote_data(&address, &local_oob_data);
447 case BT_OOB_REMOVE_REMOTE_DATA: {
448 bluetooth_device_address_t address = { {0} };
450 address = g_array_index(in_param1,
451 bluetooth_device_address_t, 0);
453 result = _bt_oob_remove_remote_data(&address);
457 case BT_AVRCP_SET_TRACK_INFO: {
458 media_metadata_t data;
459 media_metadata_attributes_t meta_data;
461 memset(&data, 0x00, sizeof(media_metadata_t));
462 memset(&meta_data, 0x00, sizeof(media_metadata_attributes_t));
464 data = g_array_index(in_param1,
465 media_metadata_t, 0);
467 meta_data.title = g_strdup(data.title);
468 meta_data.artist = g_strdup(data.artist);
469 meta_data.album = g_strdup(data.album);
470 meta_data.genre = g_strdup(data.genre);
471 meta_data.total_tracks = data.total_tracks;
472 meta_data.number = data.number;
473 meta_data.duration = data.duration;
475 result = _bt_avrcp_set_track_info(&meta_data);
477 g_free((gpointer)meta_data.title);
478 g_free((gpointer)meta_data.artist);
479 g_free((gpointer)meta_data.album);
480 g_free((gpointer)meta_data.genre);
484 case BT_AVRCP_SET_PROPERTY: {
488 type = g_array_index(in_param1, int, 0);
489 value = g_array_index(in_param2, unsigned int, 0);
491 result = _bt_avrcp_set_property(type, value);
495 case BT_AVRCP_SET_PROPERTIES: {
496 media_player_settings_t properties;
498 memset(&properties, 0x00, sizeof(media_player_settings_t));
500 properties = g_array_index(in_param1,
501 media_player_settings_t, 0);
503 result = _bt_avrcp_set_properties(&properties);
507 case BT_RFCOMM_CLIENT_CONNECT: {
508 bluetooth_device_address_t address = { {0} };
512 address = g_array_index(in_param1,
513 bluetooth_device_address_t, 0);
515 input_string = &g_array_index(in_param2, char, 0);
517 connect_type = g_array_index(in_param3, int, 0);
519 if (connect_type == BT_RFCOMM_UUID) {
520 result = _bt_rfcomm_connect_using_uuid(request_id,
521 &address, input_string);
523 result = _bt_rfcomm_connect_using_channel(request_id,
524 &address, input_string);
527 if (result != BLUETOOTH_ERROR_NONE) {
528 g_array_append_vals(*out_param1, &address,
529 sizeof(bluetooth_device_address_t));
533 case BT_RFCOMM_CLIENT_CANCEL_CONNECT:
534 result = _bt_rfcomm_cancel_connect();
536 case BT_RFCOMM_CLIENT_IS_CONNECTED: {
537 gboolean connected = FALSE;
538 result = _bt_rfcomm_is_connected(&connected);
540 g_array_append_vals(*out_param1, &connected, sizeof(gboolean));
543 case BT_RFCOMM_SOCKET_DISCONNECT: {
546 socket_fd = g_array_index(in_param1, int, 0);
548 result = _bt_rfcomm_disconnect(socket_fd);
551 case BT_RFCOMM_SOCKET_WRITE: {
556 socket_fd = g_array_index(in_param1, int, 0);
557 length = g_array_index(in_param2, int, 0);
558 buffer = &g_array_index(in_param3, char, 0);
560 result = _bt_rfcomm_write(socket_fd, buffer, length);
563 case BT_RFCOMM_CREATE_SOCKET: {
569 sender = dbus_g_method_get_sender(context);
570 uuid = &g_array_index(in_param1, char, 0);
572 result = _bt_rfcomm_create_socket(sender, uuid);
576 result = BLUETOOTH_ERROR_NONE;
579 g_array_append_vals(*out_param1, &socket_fd, sizeof(int));
584 case BT_RFCOMM_REMOVE_SOCKET: {
587 socket_fd = g_array_index(in_param1, int, 0);
589 result = _bt_rfcomm_remove_socket(socket_fd);
592 case BT_RFCOMM_LISTEN: {
597 socket_fd = g_array_index(in_param1, int, 0);
598 pending = g_array_index(in_param2, int, 0);
599 is_native = g_array_index(in_param3, gboolean, 0);
601 result = _bt_rfcomm_listen(socket_fd, pending, is_native);
604 case BT_RFCOMM_IS_UUID_AVAILABLE: {
605 gboolean available = TRUE;
608 uuid = &g_array_index(in_param1, char, 0);
610 result = _bt_rfcomm_is_uuid_available(uuid, &available);
612 g_array_append_vals(*out_param1, &available, sizeof(gboolean));
615 case BT_RFCOMM_ACCEPT_CONNECTION: {
618 socket_fd = g_array_index(in_param1, int, 0);
620 result = _bt_rfcomm_accept_connection(socket_fd, request_id);
623 case BT_RFCOMM_REJECT_CONNECTION: {
626 socket_fd = g_array_index(in_param1, int, 0);
628 result = _bt_rfcomm_reject_connection(socket_fd);
632 result = BLUETOOTH_ERROR_INTERNAL;
639 static int __bt_obexd_request(int function_name,
642 DBusGMethodInvocation *context,
651 switch (function_name) {
652 case BT_OPP_PUSH_FILES: {
654 bluetooth_device_address_t address = { {0} };
659 address = g_array_index(in_param1,
660 bluetooth_device_address_t, 0);
662 file_count = g_array_index(in_param3, int, 0);
664 file_path = g_new0(char *, file_count + 1);
666 for (i = 0; i < file_count; i++) {
667 path = g_array_index(in_param2,
670 file_path[i] = g_strdup(path.path);
673 result = _bt_opp_client_push_files(request_id, context,
677 for (i = 0; i < file_count; i++) {
678 g_free(file_path[i]);
685 case BT_OPP_CANCEL_PUSH: {
686 result = _bt_opp_client_cancel_push();
690 case BT_OPP_IS_PUSHING_FILES: {
691 gboolean is_sending = FALSE;
693 result = _bt_opp_client_is_sending(&is_sending);
695 g_array_append_vals(*out_param1, &is_sending,
699 case BT_OBEX_SERVER_ALLOCATE: {
705 sender = dbus_g_method_get_sender(context);
706 path = &g_array_index(in_param1, char, 0);
707 is_native = g_array_index(in_param2, gboolean, 0);
708 app_pid = g_array_index(in_param3, int, 0);
710 result = _bt_obex_server_allocate(sender, path, app_pid, is_native);
715 case BT_OBEX_SERVER_DEALLOCATE: {
719 is_native = g_array_index(in_param1, gboolean, 0);
720 app_pid = g_array_index(in_param2, int, 0);
722 result = _bt_obex_server_deallocate(app_pid, is_native);
725 case BT_OBEX_SERVER_IS_ACTIVATED: {
726 gboolean is_activated = FALSE;
728 result = _bt_obex_server_is_activated(&is_activated);
730 g_array_append_vals(*out_param1, &is_activated,
735 case BT_OBEX_SERVER_ACCEPT_CONNECTION: {
736 result = _bt_obex_server_accept_connection(request_id);
740 case BT_OBEX_SERVER_REJECT_CONNECTION: {
741 result = _bt_obex_server_reject_connection();
745 case BT_OBEX_SERVER_ACCEPT_FILE: {
748 file_name = &g_array_index(in_param1, char, 0);
750 result = _bt_obex_server_accept_authorize(file_name, TRUE);
754 case BT_OBEX_SERVER_REJECT_FILE: {
755 result = _bt_obex_server_reject_authorize();
759 case BT_OBEX_SERVER_SET_PATH: {
761 char *destination_path;
763 destination_path = &g_array_index(in_param1, char, 0);
764 is_native = g_array_index(in_param2, gboolean, 0);
766 result = _bt_obex_server_set_destination_path(destination_path,
771 case BT_OBEX_SERVER_SET_ROOT: {
774 root = &g_array_index(in_param1, char, 0);
776 result = _bt_obex_server_set_root(root);
780 case BT_OBEX_SERVER_CANCEL_TRANSFER: {
783 transfer_id = g_array_index(in_param1, int, 0);
785 result = _bt_obex_server_cancel_transfer(transfer_id);
789 case BT_OBEX_SERVER_CANCEL_ALL_TRANSFERS: {
790 result = _bt_obex_server_cancel_all_transfers();
795 BT_ERR("Unknown function!");
796 result = BLUETOOTH_ERROR_INTERNAL;
803 gboolean bt_service_request(
806 int service_function,
813 DBusGMethodInvocation *context)
817 GArray *out_param1 = NULL;
818 GArray *out_param2 = NULL;
820 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
821 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
823 if (request_type == BT_ASYNC_REQ
824 || service_function == BT_OBEX_SERVER_ACCEPT_CONNECTION
825 || service_function == BT_RFCOMM_ACCEPT_CONNECTION) {
827 request_id = _bt_assign_request_id();
828 if (request_id < 0) {
829 BT_ERR("Fail to assign the request id");
830 result = BLUETOOTH_ERROR_INTERNAL;
835 switch (service_type) {
836 case BT_BLUEZ_SERVICE:
837 result = __bt_bluez_request(service_function, request_type,
838 request_id, context, in_param1, in_param2,
839 in_param3, in_param4, &out_param1);
841 case BT_OBEX_SERVICE:
842 result = __bt_obexd_request(service_function, request_type,
843 request_id, context, in_param1,
844 in_param2, in_param3,
845 in_param4, &out_param1);
848 BT_ERR("Unknown service type");
849 result = BLUETOOTH_ERROR_INTERNAL;
853 if (result != BLUETOOTH_ERROR_NONE) {
854 BT_ERR("result is not error none: %x", result);
858 g_array_append_vals(out_param2, &result, sizeof(int));
860 if (request_type == BT_ASYNC_REQ
861 || service_function == BT_OBEX_SERVER_ACCEPT_CONNECTION
862 || service_function == BT_RFCOMM_ACCEPT_CONNECTION) {
863 _bt_insert_request_list(request_id, service_function,
867 dbus_g_method_return(context, out_param1, out_param2);
870 g_array_free(out_param1, TRUE);
871 g_array_free(out_param2, TRUE);
875 g_array_append_vals(out_param2, &result, sizeof(int));
876 dbus_g_method_return(context, out_param1, out_param2);
878 g_array_free(out_param1, TRUE);
879 g_array_free(out_param2, TRUE);
881 if (request_type == BT_ASYNC_REQ)
882 _bt_delete_request_id(request_id);
887 int _bt_service_register(void)
889 BtService *bt_service;
890 DBusGConnection *conn;
895 conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
896 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
898 proxy = dbus_g_proxy_new_for_name(conn, DBUS_SERVICE_DBUS,
899 DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
902 BT_ERR("proxy is NULL");
906 if (!dbus_g_proxy_call(proxy, "RequestName", &err, G_TYPE_STRING,
907 BT_SERVICE_NAME, G_TYPE_UINT, 0, G_TYPE_INVALID,
908 G_TYPE_UINT, &result, G_TYPE_INVALID)) {
910 BT_ERR("RequestName RPC failed[%s]\n", err->message);
913 g_object_unref(proxy);
918 g_object_unref(proxy);
920 if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
921 BT_ERR("Failed to get the primary well-known name.\n");
925 bt_service = g_object_new(BT_SERVICE_TYPE, NULL);
926 if (bt_service == NULL) {
927 BT_ERR("bt_service is NULL");
931 dbus_g_connection_register_g_object(conn, BT_SERVICE_PATH,
932 G_OBJECT(bt_service));
934 service_object = bt_service;
935 bt_service_conn = conn;
937 return BLUETOOTH_ERROR_NONE;
940 if (bt_service_conn) {
941 dbus_g_connection_unref(bt_service_conn);
942 bt_service_conn = NULL;
945 return BLUETOOTH_ERROR_INTERNAL;
948 void _bt_service_unregister(void)
950 if (bt_service_conn) {
951 if (service_object) {
952 dbus_g_connection_unregister_g_object(bt_service_conn,
953 G_OBJECT(service_object));
954 g_object_unref(service_object);
955 service_object = NULL;
958 dbus_g_connection_unref(bt_service_conn);
959 bt_service_conn = NULL;