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_control_get_property(int type)
218 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
220 bt_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 avrcp_ct_player_property_type_t oal_type;
229 _bt_convert_addr_string_to_type(
232 if (type == STATUS) {
233 status = avrcp_ct_get_play_status(&device_address);
234 if (status != OAL_STATUS_SUCCESS) {
235 BT_ERR("Get play status err: [%d]", status);
236 result = BLUETOOTH_ERROR_INTERNAL;
239 oal_type = __media_prop_to_oal_type(type);
240 retv_if(0 > oal_type, BLUETOOTH_ERROR_INVALID_PARAM);
242 status = avrcp_ct_get_property(&device_address, oal_type);
243 if (status != OAL_STATUS_SUCCESS) {
244 BT_ERR("Get peoperty err: [%d]", status);
245 result = BLUETOOTH_ERROR_INTERNAL;
249 BT_ERR("Device is not connected:");
250 return BLUETOOTH_ERROR_NOT_CONNECTED;
255 int _bt_avrcp_control_get_track_info(void)
257 char connected_address[BT_ADDRESS_STRING_SIZE + 1];
259 bluetooth_device_address_t device_address;
260 oal_status_t status = OAL_STATUS_SUCCESS;
261 int result = BLUETOOTH_ERROR_NONE;
263 connected = _bt_is_headset_type_connected(BT_AVRCP, connected_address);
266 _bt_convert_addr_string_to_type(
270 status = avrcp_ct_get_media_attribute((bt_address_t*)&device_address);
271 if (status != OAL_STATUS_SUCCESS) {
272 BT_ERR("Get track info err: [%d]", status);
273 result = BLUETOOTH_ERROR_INTERNAL;
276 BT_ERR("Device is not connected:");
277 return BLUETOOTH_ERROR_NOT_CONNECTED;
282 static void __bt_reply_avrcp_ct_connection_pending_request(bluetooth_device_address_t *address)
285 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
286 int result = BLUETOOTH_ERROR_NONE;
287 bluetooth_device_address_t device_address;
289 invocation_info_t *req_info;
290 memcpy(device_address.addr, address->addr, BLUETOOTH_ADDRESS_LENGTH);
291 _bt_convert_addr_type_to_string(addr, address->addr);
293 req_info = _bt_get_request_info_data(BT_AVRCP_CONTROL_CONNECT, addr);
294 if (NULL == req_info) {
295 BT_INFO("AVRCP CT Connect request not found or possibly already replied");
298 BT_INFO("AVRCP CT Connect request found for [%s]", addr);
301 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
302 g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
303 _bt_service_method_return(req_info->context,
305 g_array_free(out_param, TRUE);
306 g_free(req_info->user_data);
307 _bt_free_info_from_invocation_list(req_info);
310 static void __bt_handle_avrcp_target_connected_state(bluetooth_device_address_t *address)
312 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
314 int result = BLUETOOTH_ERROR_NONE;
315 ret_if(NULL == address);
318 _bt_convert_addr_type_to_string(addr, address->addr);
319 BT_INFO("Address of connected device [%s]", addr);
321 /* Add data from the connected list */
322 _bt_add_headset_to_list(BT_AVRCP, BT_STATE_CONNECTED, addr);
324 /* Replay to avrcp cotroller connect */
325 __bt_reply_avrcp_ct_connection_pending_request(address);
327 /* Send AVRCP(TARGET Role) connected event to Application */
328 param = g_variant_new("(is)", result, addr);
329 _bt_send_event(BT_AVRCP_CONTROL_EVENT, BLUETOOTH_EVENT_AVRCP_CONNECTED, param);
334 static void __bt_reply_avrcp_ct_disconnection_pending_request(bluetooth_device_address_t *address)
336 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
337 int result = BLUETOOTH_ERROR_NONE;
339 invocation_info_t *req_info;
342 _bt_convert_addr_type_to_string(addr, address->addr);
344 req_info = _bt_get_request_info_data(BT_AVRCP_CONTROL_DISCONNECT, addr);
345 if (NULL == req_info) {
346 BT_INFO("AVRCP CT Disconnect request not found or possibly already replied");
349 BT_INFO("AVRCP CT Disconnect request found for [%s]", addr);
352 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
353 g_array_append_vals(out_param, addr, BT_ADDRESS_STRING_SIZE);
354 _bt_service_method_return(req_info->context,
356 g_array_free(out_param, TRUE);
357 g_free(req_info->user_data);
358 _bt_free_info_from_invocation_list(req_info);
361 static void __bt_avrcp_ct_reply_pending_requests(void)
364 int result = BLUETOOTH_ERROR_INTERNAL;
366 invocation_info_t *req_info;
369 for (l = _bt_get_invocation_list(); l != NULL;) {
373 if (req_info == NULL)
376 /* Create out param */
377 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
379 BT_INFO("service_function: [0x%X]", req_info->service_function);
380 switch (req_info->service_function) {
381 case BT_AVRCP_GET_TRACK_INFO:
382 case BT_AVRCP_CONTROL_GET_PROPERTY: {
383 _bt_service_method_return(req_info->context, out_param, result);
389 _bt_free_info_from_invocation_list(req_info);
390 g_array_free(out_param, TRUE);
395 static void __bt_handle_avrcp_target_disconnected_state(bluetooth_device_address_t *address)
397 char addr[BT_ADDRESS_STRING_SIZE] = { 0 };
399 int result = BLUETOOTH_ERROR_NONE;
400 ret_if(NULL == address);
403 _bt_convert_addr_type_to_string(addr, address->addr);
404 BT_INFO("Address of disconnected device [%s]", addr);
406 /* Remove data from the connected list */
407 _bt_remove_headset_from_list(BT_AVRCP, addr);
409 /* Reply to avrcp cotroller connect */
410 __bt_reply_avrcp_ct_disconnection_pending_request(address);
412 /* Reply AVRCP CT pending requests */
413 __bt_avrcp_ct_reply_pending_requests();
415 /* Send AVRCP(TARGET Role) disconnected event to Application */
416 param = g_variant_new("(is)", result, addr);
417 _bt_send_event(BT_AVRCP_CONTROL_EVENT, BLUETOOTH_EVENT_AVRCP_DISCONNECTED, param);
422 static int __bt_oal_to_bt_event(int oal_event)
427 case OAL_EVENT_AVRCP_CT_EQUALIZER_STATUS:
428 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_EQUALIZER_STATUS;
430 case OAL_EVENT_AVRCP_CT_REPEAT_STATUS:
431 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_REPEAT_STATUS;
433 case OAL_EVENT_AVRCP_CT_SHUFFLE_STATUS:
434 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_SHUFFLE_STATUS;
436 case OAL_EVENT_AVRCP_CT_SCAN_STATUS:
437 ret = BLUETOOTH_EVENT_AVRCP_CONTROL_SCAN_STATUS;
439 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_POS_CHANGED:
440 ret = BLUETOOTH_EVENT_AVRCP_SONG_POSITION_STATUS;
442 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_STATUS_CHANGED:
443 ret = BLUETOOTH_EVENT_AVRCP_PLAY_STATUS_CHANGED;
451 static void __bt_handle_avrcp_target_player_property(unsigned int property_value, int oal_event)
455 /* Send AVRCP Target player property event to Application */
456 param = g_variant_new("(u)", property_value);
457 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
458 __bt_oal_to_bt_event(oal_event), param);
461 static void __bt_handle_avrcp_track_info_changed(event_avrcp_ct_media_info_t* metadata)
464 unsigned int total_track = 0;
465 unsigned int track_number = 0;
466 unsigned int playing_time = 0;
470 total_track = (unsigned int)(metadata->total_track);
471 track_number = (unsigned int)(metadata->track_number);
472 playing_time = (unsigned int)(metadata->playing_time);
473 /* Send AVRCP Target player track info changed event to application*/
474 param = g_variant_new("(ssssuuu)",
475 metadata->title_info,
476 metadata->artist_info,
477 metadata->album_info,
478 metadata->genre_info,
483 BT_INFO("Total_track: %u, track_number: %u, playing_time: %u",
484 total_track, track_number, playing_time);
485 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
486 BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED, param);
489 static invocation_info_t* __bt_get_request_info(int service_function)
492 invocation_info_t *req_info = NULL;
495 /* Get method invocation context */
496 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
498 if (req_info == NULL || req_info->service_function != service_function)
505 static void __bt_handle_avrcp_track_info(event_avrcp_ct_media_info_t* metadata)
507 media_metadata_t meta_data;
508 invocation_info_t *req_info = NULL;
509 GArray *out_param = NULL;
510 int result = BLUETOOTH_ERROR_NONE;
512 req_info = __bt_get_request_info(BT_AVRCP_GET_TRACK_INFO);
513 ret_if(NULL == req_info);
515 memset(&meta_data, 0x00, sizeof(media_metadata_t));
517 memcpy(&meta_data.title, &metadata->title_info,
518 strlen((char *)metadata->title_info));
519 meta_data.title[strlen((char *)metadata->title_info)] = '\0';
521 memcpy(&meta_data.artist, &metadata->artist_info,
522 strlen((char *)metadata->artist_info));
523 meta_data.artist[strlen((char *)metadata->artist_info)] = '\0';
525 memcpy(&meta_data.album, &metadata->album_info,
526 strlen((char *)metadata->album_info));
527 meta_data.album[strlen((char *)metadata->album_info)] = '\0';
529 memcpy(&meta_data.genre, &metadata->genre_info,
530 strlen((char *)metadata->genre_info));
531 meta_data.genre[strlen((char *)metadata->genre_info)] = '\0';
533 meta_data.total_tracks = metadata->total_track;
534 meta_data.number = metadata->track_number;
535 meta_data.duration = metadata->playing_time;
537 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
538 g_array_append_vals(out_param, &meta_data, sizeof(media_metadata_t));
540 _bt_service_method_return(req_info->context, out_param, result);
541 g_array_free(out_param, TRUE);
542 _bt_free_info_from_invocation_list(req_info);
545 static void __bt_handle_avrcp_pass_cmd_res(avrcp_ct_pass_cmd_t *pass_cmd)
547 BT_INFO(" Send Command Response [%d]", pass_cmd->key_code);
550 static void __bt_handle_avrcp_player_setting_res(avrcp_ct_playersetting_t *player_setting_res)
552 BT_INFO("Set Property Response [%d]", player_setting_res->accepted);
555 static void __bt_handle_avrcp_get_property_res_event(avrcp_ct_player_property_type_t oal_type, int value)
557 invocation_info_t *req_info = NULL;
558 GArray *out_param = NULL;
559 int result = BLUETOOTH_ERROR_NONE;
566 prop_type = __oal_type_to_media_prop(oal_type);
567 ret_if(0 > prop_type);
569 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
570 g_array_append_vals(out_param, &value, sizeof(value));
572 /* Find and reply to all get requests for prop_type */
573 for (l = _bt_get_invocation_list(); l != NULL;) {
577 if (req_info == NULL)
580 type = *((int *)req_info->user_data);
581 if (req_info->service_function != BT_AVRCP_CONTROL_GET_PROPERTY
582 || type != prop_type)
585 BT_INFO("Request found");
586 _bt_service_method_return(req_info->context, out_param, result);
587 g_free(req_info->user_data);
588 _bt_free_info_from_invocation_list(req_info);
591 g_array_free(out_param, TRUE);
595 void _bt_avrcp_ctrl_event_handler(int oal_event, gpointer event_data)
598 bluetooth_device_address_t* bd_addr;
601 case OAL_EVENT_AVRCP_CT_CONNECTED: {
602 BT_INFO("AVRCP Controller Profile connected..");
603 bd_addr = (bluetooth_device_address_t*)event_data;
604 __bt_handle_avrcp_target_connected_state(bd_addr);
607 case OAL_EVENT_AVRCP_CT_DISCONNECTED: {
608 BT_INFO("AVRCP Controller Profile dissconnected..");
609 bd_addr = (bluetooth_device_address_t*)event_data;
610 __bt_handle_avrcp_target_disconnected_state(bd_addr);
613 case OAL_EVENT_AVRCP_CT_EQUALIZER_STATUS:
614 case OAL_EVENT_AVRCP_CT_REPEAT_STATUS:
615 case OAL_EVENT_AVRCP_CT_SHUFFLE_STATUS:
616 case OAL_EVENT_AVRCP_CT_SCAN_STATUS: {
617 avrcp_ct_property_value_t* property_val;
618 property_val = (avrcp_ct_property_value_t*)event_data;
619 __bt_handle_avrcp_target_player_property(property_val->value, oal_event);
622 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_STATUS_CHANGED:{
623 event_notif_avrcp_ct_notif_info_t* play_status_val;
624 play_status_val = (event_notif_avrcp_ct_notif_info_t*)event_data;
625 __bt_handle_avrcp_target_player_property(play_status_val->play_status, oal_event);
628 case OAL_EVENT_AVRCP_CT_NOTIF_PLAY_POS_CHANGED: {
629 event_notif_avrcp_ct_notif_info_t* play_position;
630 play_position = (event_notif_avrcp_ct_notif_info_t*)event_data;
631 __bt_handle_avrcp_target_player_property(play_position->song_pos, oal_event);
634 case OAL_EVENT_AVRCP_CT_NOTIF_TRACK_CHANGE: {
635 BT_INFO("AVRCP Controller Track Changed event..");
636 event_avrcp_ct_media_info_t* metadata = event_data;
638 __bt_handle_avrcp_track_info_changed(metadata);
641 case OAL_EVENT_AVRCP_CT_MEDIA_INFO: {
642 BT_INFO("AVRCP Controller Track Info event..");
643 event_avrcp_ct_media_info_t* metadata;
645 metadata = (event_avrcp_ct_media_info_t*)event_data;
646 __bt_handle_avrcp_track_info(metadata);
649 case OAL_EVENT_AVRCP_CT_GET_PROPERTY_RES: {
650 BT_INFO("AVRCP Controller Get Property response event..");
651 avrcp_ct_property_value_t *property = (avrcp_ct_property_value_t *)event_data;
652 __bt_handle_avrcp_get_property_res_event(property->type, property->value);
655 case OAL_EVENT_AVRCP_CT_PLAY_STATUS: {
656 BT_INFO("AVRCP Controller Get Play status response event..");
657 event_avrcp_ct_play_status_t *play_status_info = (event_avrcp_ct_play_status_t *)event_data;
658 __bt_handle_avrcp_get_property_res_event(OAL_PLAY_STATUS, play_status_info->play_status);
661 case OAL_EVENT_AVRCP_CT_PASS_CMD_RES: {
662 BT_INFO("AVRCP Controller Pass Command Res");
663 avrcp_ct_pass_cmd_t *pass_cmd;
665 pass_cmd = (avrcp_ct_pass_cmd_t *)event_data;
666 __bt_handle_avrcp_pass_cmd_res(pass_cmd);
669 case OAL_EVENT_AVRCP_CT_PLAYER_SETTING_RES: {
670 BT_INFO("AVRCP Player setting response");
671 avrcp_ct_playersetting_t *player_setting_res;
673 player_setting_res = (avrcp_ct_playersetting_t *)event_data;
674 __bt_handle_avrcp_player_setting_res(player_setting_res);
678 BT_INFO("Invalid Event = %d", oal_event);