4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Nilesh Trimbake <t.shripati@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include <sys/socket.h>
23 #include <sys/errno.h>
28 #include "oal-hardware.h"
29 #include "oal-device-mgr.h"
30 #include <oal-manager.h>
31 #include <oal-avrcp-ct.h>
33 #include <bt-service-avrcp-ctrl.h>
34 #include <bluetooth-media-control.h>
35 #include <bt-service-event.h>
37 static int __media_prop_to_oal_type(int type)
43 oal_type = OAL_EQUALIZER;
46 oal_type = OAL_SHUFFLE;
49 oal_type = OAL_REPEAT;
55 oal_type = OAL_PLAY_POSITION;
58 oal_type = OAL_PLAY_STATUS;
61 BT_ERR("Unknown type: %d", type);
68 static int __oal_type_to_media_prop(int oal_type)
85 case OAL_PLAY_POSITION:
92 BT_ERR("Unknown type: %d", oal_type);
99 int _bt_avrcp_connect_remote_target(bluetooth_device_address_t *device_address)
101 oal_status_t status = OAL_STATUS_SUCCESS;
102 int result = BLUETOOTH_ERROR_NONE;
105 status = avrcp_ct_connect((bt_address_t*)device_address);
106 if (status != OAL_STATUS_SUCCESS) {
107 BT_ERR("Connection could not be established, err: [%d]", status);
108 result = BLUETOOTH_ERROR_INTERNAL;
113 int _bt_avrcp_disconnect_remote_target(bluetooth_device_address_t *device_address)
115 oal_status_t status = OAL_STATUS_SUCCESS;
116 int result = BLUETOOTH_ERROR_NONE;
119 status = avrcp_ct_disconnect((bt_address_t*)device_address);
120 if (status != OAL_STATUS_SUCCESS) {
121 BT_ERR("DisConnection err: [%d]", status);
122 result = BLUETOOTH_ERROR_INTERNAL;
127 int _bt_avrcp_control_cmd(int type)
129 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
131 bluetooth_device_address_t device_address;
132 oal_status_t status = OAL_STATUS_SUCCESS;
133 int result = BLUETOOTH_ERROR_NONE;
136 connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
139 _bt_convert_addr_string_to_type(device_address.addr,
142 case RC_PASS_CMD_PLAY:
143 status = avrcp_ct_play((bt_address_t*)&device_address);
145 case RC_PASS_CMD_PAUSE:
146 status = avrcp_ct_pause((bt_address_t*)&device_address);
148 case RC_PASS_CMD_STOP:
149 status = avrcp_ct_stop((bt_address_t*)&device_address);
151 case RC_PASS_CMD_NEXT:
152 status = avrcp_ct_next_track((bt_address_t*)&device_address);
154 case RC_PASS_CMD_PREVIOUS:
155 status = avrcp_ct_prev_track((bt_address_t*)&device_address);
157 case RC_PASS_CMD_PRESS_FAST_FORWARD:
158 status = avrcp_ct_fforward((bt_address_t*)&device_address, PRESS_STATE);
160 case RC_PASS_CMD_RELEASE_FAST_FORWARD:
161 status = avrcp_ct_fforward((bt_address_t*)&device_address, RELEASE_STATE);
163 case RC_PASS_CMD_PRESS_REWIND:
164 status = avrcp_ct_rewind((bt_address_t*)&device_address, PRESS_STATE);
166 case RC_PASS_CMD_RELEASE_REWIND:
167 status = avrcp_ct_rewind((bt_address_t*)&device_address, RELEASE_STATE);
173 if (status != OAL_STATUS_SUCCESS) {
174 BT_ERR("Send pass through command err: [%d]", status);
175 result = BLUETOOTH_ERROR_INTERNAL;
178 BT_ERR("Device is not connected:");
179 return BLUETOOTH_ERROR_NOT_CONNECTED;
185 int _bt_avrcp_control_set_property(int type, unsigned int value)
187 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
189 bluetooth_device_address_t device_address;
190 oal_status_t status = OAL_STATUS_SUCCESS;
191 int result = BLUETOOTH_ERROR_NONE;
193 connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
198 oal_type = __media_prop_to_oal_type(type);
199 retv_if(0 > oal_type, BLUETOOTH_ERROR_INVALID_PARAM);
201 _bt_convert_addr_string_to_type(device_address.addr,
203 status = avrcp_ct_set_property((bt_address_t*)&device_address,
205 if (status != OAL_STATUS_SUCCESS) {
206 BT_ERR("Set peoperty err: [%d]", status);
207 result = BLUETOOTH_ERROR_INTERNAL;
210 BT_ERR("Device is not connected:");
211 return BLUETOOTH_ERROR_NOT_CONNECTED;
216 int _bt_avrcp_transport_set_property(int type, unsigned int value)
218 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
220 bluetooth_device_address_t device_address;
221 oal_status_t status = OAL_STATUS_SUCCESS;
222 int result = BLUETOOTH_ERROR_NONE;
224 connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
227 _bt_convert_addr_string_to_type(device_address.addr,
229 status = avrcp_transport_set_property((bt_address_t*)&device_address,
231 if (status != OAL_STATUS_SUCCESS) {
232 BT_ERR("Set peoperty err: [%d]", status);
233 result = BLUETOOTH_ERROR_INTERNAL;
236 BT_ERR("Device is not connected:");
237 return BLUETOOTH_ERROR_NOT_CONNECTED;
242 int _bt_avrcp_control_get_property(int type)
244 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
246 bt_address_t device_address;
247 oal_status_t status = OAL_STATUS_SUCCESS;
248 int result = BLUETOOTH_ERROR_NONE;
250 connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
253 avrcp_ct_player_property_type_t oal_type;
255 _bt_convert_addr_string_to_type(
258 if (type == STATUS) {
259 status = avrcp_ct_get_play_status(&device_address);
260 if (status != OAL_STATUS_SUCCESS) {
261 BT_ERR("Get play status err: [%d]", status);
262 result = BLUETOOTH_ERROR_INTERNAL;
265 oal_type = __media_prop_to_oal_type(type);
266 retv_if(0 > oal_type, BLUETOOTH_ERROR_INVALID_PARAM);
268 status = avrcp_ct_get_property(&device_address, oal_type);
269 if (status != OAL_STATUS_SUCCESS) {
270 BT_ERR("Get peoperty err: [%d]", status);
271 result = BLUETOOTH_ERROR_INTERNAL;
275 BT_ERR("Device is not connected:");
276 return BLUETOOTH_ERROR_NOT_CONNECTED;
281 int _bt_avrcp_control_get_track_info(void)
283 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
285 bluetooth_device_address_t device_address;
286 oal_status_t status = OAL_STATUS_SUCCESS;
287 int result = BLUETOOTH_ERROR_NONE;
289 connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
292 _bt_convert_addr_string_to_type(
296 status = avrcp_ct_get_media_attribute((bt_address_t*)&device_address);
297 if (status != OAL_STATUS_SUCCESS) {
298 BT_ERR("Get track info err: [%d]", status);
299 result = BLUETOOTH_ERROR_INTERNAL;
302 BT_ERR("Device is not connected:");
303 return BLUETOOTH_ERROR_NOT_CONNECTED;
308 static void __bt_reply_avrcp_ct_connection_pending_request(bluetooth_device_address_t *address)
311 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
312 int result = BLUETOOTH_ERROR_NONE;
313 bluetooth_device_address_t device_address;
315 invocation_info_t *req_info;
316 memcpy(device_address.addr, address->addr, BLUETOOTH_ADDRESS_LENGTH);
317 _bt_convert_addr_type_to_string(addr, address->addr);
319 req_info = _bt_get_request_info_data(BT_AVRCP_CONTROL_CONNECT, addr);
320 if (NULL == req_info) {
321 BT_INFO("AVRCP CT Connect request not found or possibly already replied");
324 BT_INFO("AVRCP CT Connect request found for [%s]", addr);
327 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
328 g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
329 _bt_service_method_return(req_info->context,
331 g_array_free(out_param, TRUE);
332 g_free(req_info->user_data);
333 _bt_free_info_from_invocation_list(req_info);
336 static void __bt_handle_avrcp_target_connected_state(bluetooth_device_address_t *address)
338 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
340 int result = BLUETOOTH_ERROR_NONE;
341 ret_if(NULL == address);
344 _bt_convert_addr_type_to_string(addr, address->addr);
345 BT_INFO("Address of connected device [%s]", addr);
347 /* Add data from the connected list */
348 _bt_add_headset_to_list(BT_AVRCP, BT_STATE_CONNECTED, addr);
350 /* Replay to avrcp cotroller connect */
351 __bt_reply_avrcp_ct_connection_pending_request(address);
353 /* Send AVRCP(TARGET Role) connected event to Application */
354 param = g_variant_new("(is)", result, addr);
355 _bt_send_event(BT_AVRCP_CONTROL_EVENT, BLUETOOTH_EVENT_AVRCP_CONNECTED, param);
360 static void __bt_reply_avrcp_ct_disconnection_pending_request(bluetooth_device_address_t *address)
362 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
363 int result = BLUETOOTH_ERROR_NONE;
365 invocation_info_t *req_info;
368 _bt_convert_addr_type_to_string(addr, address->addr);
370 req_info = _bt_get_request_info_data(BT_AVRCP_CONTROL_DISCONNECT, addr);
371 if (NULL == req_info) {
372 BT_INFO("AVRCP CT Disconnect request not found or possibly already replied");
375 BT_INFO("AVRCP CT Disconnect request found for [%s]", addr);
378 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
379 g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
380 _bt_service_method_return(req_info->context,
382 g_array_free(out_param, TRUE);
383 g_free(req_info->user_data);
384 _bt_free_info_from_invocation_list(req_info);
387 static void __bt_avrcp_ct_reply_pending_requests(void)
390 int result = BLUETOOTH_ERROR_INTERNAL;
392 invocation_info_t *req_info;
395 for (l = _bt_get_invocation_list(); l != NULL;) {
399 if (req_info == NULL)
402 /* Create out param */
403 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
405 BT_INFO("service_function: [0x%X]", req_info->service_function);
406 switch (req_info->service_function) {
407 case BT_AVRCP_GET_TRACK_INFO:
408 case BT_AVRCP_CONTROL_GET_PROPERTY: {
409 _bt_service_method_return(req_info->context, out_param, result);
415 _bt_free_info_from_invocation_list(req_info);
416 g_array_free(out_param, TRUE);
421 static void __bt_handle_avrcp_target_disconnected_state(bluetooth_device_address_t *address)
423 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
425 int result = BLUETOOTH_ERROR_NONE;
426 ret_if(NULL == address);
429 _bt_convert_addr_type_to_string(addr, address->addr);
430 BT_INFO("Address of disconnected device [%s]", addr);
432 /* Remove data from the connected list */
433 _bt_remove_headset_from_list(BT_AVRCP, addr);
435 /* Reply to avrcp cotroller connect */
436 __bt_reply_avrcp_ct_disconnection_pending_request(address);
438 /* Reply AVRCP CT pending requests */
439 __bt_avrcp_ct_reply_pending_requests();
441 /* Send AVRCP(TARGET Role) disconnected event to Application */
442 param = g_variant_new("(is)", result, addr);
443 _bt_send_event(BT_AVRCP_CONTROL_EVENT, BLUETOOTH_EVENT_AVRCP_DISCONNECTED, param);
448 static int __bt_oal_to_bt_event(int oal_event)
453 case OAL_EVENT_AVRCP_CT_EQUALIZER_STATUS:
454 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_EQUALIZER_STATUS;
456 case OAL_EVENT_AVRCP_CT_REPEAT_STATUS:
457 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_REPEAT_STATUS;
459 case OAL_EVENT_AVRCP_CT_SHUFFLE_STATUS:
460 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_SHUFFLE_STATUS;
462 case OAL_EVENT_AVRCP_CT_SCAN_STATUS:
463 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_SCAN_STATUS;
465 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_POS_CHANGED:
466 ret = BLUETOOTH_EVENT_AVRCP_SONG_POSITION_STATUS;
468 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_STATUS_CHANGED:
469 ret = BLUETOOTH_EVENT_AVRCP_PLAY_STATUS_CHANGED;
477 static void __bt_handle_avrcp_target_player_property(unsigned int property_value, int oal_event)
481 /* Send AVRCP Target player property event to Application */
482 param = g_variant_new("(u)", property_value);
483 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
484 __bt_oal_to_bt_event(oal_event), param);
487 static void __bt_handle_avrcp_track_info_changed(event_avrcp_ct_media_info_t* metadata)
490 unsigned int total_track = 0;
491 unsigned int track_number = 0;
492 unsigned int playing_time = 0;
496 total_track = (unsigned int)(metadata->total_track);
497 track_number = (unsigned int)(metadata->track_number);
498 playing_time = (unsigned int)(metadata->playing_time);
499 /* Send AVRCP Target player track info changed event to application*/
500 param = g_variant_new("(ssssuuu)",
501 metadata->title_info,
502 metadata->artist_info,
503 metadata->album_info,
504 metadata->genre_info,
509 BT_INFO("Total_track: %u, track_number: %u, playing_time: %u",
510 total_track, track_number, playing_time);
511 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
512 BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED, param);
515 static invocation_info_t* __bt_get_request_info(int service_function)
518 invocation_info_t *req_info = NULL;
521 /* Get method invocation context */
522 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
524 if (req_info == NULL || req_info->service_function != service_function)
531 static void __bt_handle_avrcp_track_info(event_avrcp_ct_media_info_t* metadata)
533 media_metadata_t meta_data;
534 invocation_info_t *req_info = NULL;
535 GArray *out_param = NULL;
536 int result = BLUETOOTH_ERROR_NONE;
538 req_info = __bt_get_request_info(BT_AVRCP_GET_TRACK_INFO);
539 ret_if(NULL == req_info);
541 memset(&meta_data, 0x00, sizeof(media_metadata_t));
543 memcpy(&meta_data.title, &metadata->title_info,
544 strlen((char *)metadata->title_info));
545 meta_data.title[strlen((char *)metadata->title_info)] = '\0';
547 memcpy(&meta_data.artist, &metadata->artist_info,
548 strlen((char *)metadata->artist_info));
549 meta_data.artist[strlen((char *)metadata->artist_info)] = '\0';
551 memcpy(&meta_data.album, &metadata->album_info,
552 strlen((char *)metadata->album_info));
553 meta_data.album[strlen((char *)metadata->album_info)] = '\0';
555 memcpy(&meta_data.genre, &metadata->genre_info,
556 strlen((char *)metadata->genre_info));
557 meta_data.genre[strlen((char *)metadata->genre_info)] = '\0';
559 meta_data.total_tracks = metadata->total_track;
560 meta_data.number = metadata->track_number;
561 meta_data.duration = metadata->playing_time;
563 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
564 g_array_append_vals(out_param, &meta_data, sizeof(media_metadata_t));
566 _bt_service_method_return(req_info->context, out_param, result);
567 g_array_free(out_param, TRUE);
568 _bt_free_info_from_invocation_list(req_info);
571 static void __bt_handle_avrcp_pass_cmd_res(avrcp_ct_pass_cmd_t *pass_cmd)
573 BT_INFO(" Send Command Response [%d]", pass_cmd->key_code);
576 static void __bt_handle_avrcp_player_setting_res(avrcp_ct_playersetting_t *player_setting_res)
578 BT_INFO("Set Property Response [%d]", player_setting_res->accepted);
581 static void __bt_handle_avrcp_get_property_res_event(avrcp_ct_player_property_type_t oal_type, int value)
583 invocation_info_t *req_info = NULL;
584 GArray *out_param = NULL;
585 int result = BLUETOOTH_ERROR_NONE;
592 prop_type = __oal_type_to_media_prop(oal_type);
593 ret_if(0 > prop_type);
595 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
596 g_array_append_vals(out_param, &value, sizeof(value));
598 /* Find and reply to all get requests for prop_type */
599 for (l = _bt_get_invocation_list(); l != NULL;) {
603 if (req_info == NULL)
606 type = *((int *)req_info->user_data);
607 if (req_info->service_function != BT_AVRCP_CONTROL_GET_PROPERTY
608 || type != prop_type)
611 BT_INFO("Request found");
612 _bt_service_method_return(req_info->context, out_param, result);
613 g_free(req_info->user_data);
614 _bt_free_info_from_invocation_list(req_info);
617 g_array_free(out_param, TRUE);
621 void _bt_avrcp_ctrl_event_handler(int oal_event, gpointer event_data)
624 bluetooth_device_address_t* bd_addr;
627 case OAL_EVENT_AVRCP_CT_CONNECTED: {
628 BT_INFO("AVRCP Controller Profile connected..");
629 bd_addr = (bluetooth_device_address_t*)event_data;
630 __bt_handle_avrcp_target_connected_state(bd_addr);
633 case OAL_EVENT_AVRCP_CT_DISCONNECTED: {
634 BT_INFO("AVRCP Controller Profile dissconnected..");
635 bd_addr = (bluetooth_device_address_t*)event_data;
636 __bt_handle_avrcp_target_disconnected_state(bd_addr);
639 case OAL_EVENT_AVRCP_CT_EQUALIZER_STATUS:
640 case OAL_EVENT_AVRCP_CT_REPEAT_STATUS:
641 case OAL_EVENT_AVRCP_CT_SHUFFLE_STATUS:
642 case OAL_EVENT_AVRCP_CT_SCAN_STATUS: {
643 avrcp_ct_property_value_t* property_val;
644 property_val = (avrcp_ct_property_value_t*)event_data;
645 __bt_handle_avrcp_target_player_property(property_val->value, oal_event);
648 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_STATUS_CHANGED:{
649 event_notif_avrcp_ct_notif_info_t* play_status_val;
650 play_status_val = (event_notif_avrcp_ct_notif_info_t*)event_data;
651 __bt_handle_avrcp_target_player_property(play_status_val->play_status, oal_event);
654 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_POS_CHANGED: {
655 event_notif_avrcp_ct_notif_info_t* play_position;
656 play_position = (event_notif_avrcp_ct_notif_info_t*)event_data;
657 __bt_handle_avrcp_target_player_property(play_position->song_pos, oal_event);
660 case OAL_EVENT_AVRCP_CT_NOTIF_TRACK_CHANGE: {
661 BT_INFO("AVRCP Controller Track Changed event..");
662 event_avrcp_ct_media_info_t* metadata = event_data;
664 __bt_handle_avrcp_track_info_changed(metadata);
667 case OAL_EVENT_AVRCP_CT_MEDIA_INFO: {
668 BT_INFO("AVRCP Controller Track Info event..");
669 event_avrcp_ct_media_info_t* metadata;
671 metadata = (event_avrcp_ct_media_info_t*)event_data;
672 __bt_handle_avrcp_track_info(metadata);
675 case OAL_EVENT_AVRCP_CT_GET_PROPERTY_RES: {
676 BT_INFO("AVRCP Controller Get Property response event..");
677 avrcp_ct_property_value_t *property = (avrcp_ct_property_value_t *)event_data;
678 __bt_handle_avrcp_get_property_res_event(property->type, property->value);
681 case OAL_EVENT_AVRCP_CT_PLAY_STATUS: {
682 BT_INFO("AVRCP Controller Get Play status response event..");
683 event_avrcp_ct_play_status_t *play_status_info = (event_avrcp_ct_play_status_t *)event_data;
684 __bt_handle_avrcp_get_property_res_event(OAL_PLAY_STATUS, play_status_info->play_status);
687 case OAL_EVENT_AVRCP_CT_PASS_CMD_RES: {
688 BT_INFO("AVRCP Controller Pass Command Res");
689 avrcp_ct_pass_cmd_t *pass_cmd;
691 pass_cmd = (avrcp_ct_pass_cmd_t *)event_data;
692 __bt_handle_avrcp_pass_cmd_res(pass_cmd);
695 case OAL_EVENT_AVRCP_CT_PLAYER_SETTING_RES: {
696 BT_INFO("AVRCP Player setting response");
697 avrcp_ct_playersetting_t *player_setting_res;
699 player_setting_res = (avrcp_ct_playersetting_t *)event_data;
700 __bt_handle_avrcp_player_setting_res(player_setting_res);
704 BT_INFO("Invalid Event = %d", oal_event);