a2dp taret demo: add volume control

This commit is contained in:
Milanka Ringwald 2019-02-21 15:22:57 +01:00
parent 14e3e2c227
commit 502593062d
3 changed files with 90 additions and 10 deletions

View File

@ -308,7 +308,7 @@ hid_keyboard_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} btstac
hid_mouse_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} btstack_ring_buffer.o hid_device.o btstack_hid_parser.o hid_mouse_demo.o
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
a2dp_source_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_ENCODER_OBJ} ${AVDTP_OBJ} ${HXCMOD_PLAYER_OBJ} avrcp.o avrcp_target.o a2dp_source_demo.c
a2dp_source_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_ENCODER_OBJ} ${AVDTP_OBJ} ${HXCMOD_PLAYER_OBJ} avrcp.o avrcp_controller.o avrcp_target.o a2dp_source_demo.c
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
a2dp_sink_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_DECODER_OBJ} ${AVDTP_OBJ} avrcp.o avrcp_controller.o avrcp_target.o btstack_resample.o a2dp_sink_demo.c

View File

@ -966,8 +966,8 @@ static void show_usage(void){
printf("N - stop rewind\n");
printf("i - forward\n");
printf("I - backward\n");
printf("t - volume up\n");
printf("T - volume down\n");
printf("t - volume up to 70 percent\n");
printf("T - volume down to 10 percent\n");
printf("p - absolute volume of 50 percent\n");
printf("M - mute\n");
printf("r - skip\n");
@ -1063,12 +1063,12 @@ static void stdin_process(char cmd){
status = avrcp_controller_backward(avrcp_controller_cid);
break;
case 't':
printf(" - volume up to 70, avrcp controller cid 0x%02x\n", avrcp_controller_cid);
printf(" - volume up to 70 percent, avrcp target cid 0x%02x\n", avrcp_controller_cid);
// status = avrcp_controller_volume_up(avrcp_controller_cid);
status = avrcp_target_volume_changed(avrcp_target_cid, 70);
break;
case 'T':
printf(" - volume down to 10, avrcp controller cid 0x%02x\n", avrcp_controller_cid);
printf(" - volume down to 10 percent, avrcp target cid 0x%02x\n", avrcp_controller_cid);
// status = avrcp_controller_volume_down(avrcp_controller_cid);
status = avrcp_target_volume_changed(avrcp_target_cid, 10);
break;

View File

@ -152,6 +152,8 @@ static const char * device_addr_string = "00:21:3C:AC:F7:38";
static bd_addr_t device_addr;
static uint8_t sdp_a2dp_source_service_buffer[150];
static uint8_t sdp_avrcp_target_service_buffer[200];
static uint8_t sdp_avrcp_controller_service_buffer[200];
static avdtp_media_codec_configuration_sbc_t sbc_configuration;
static btstack_sbc_encoder_state_t sbc_encoder_state;
@ -166,6 +168,7 @@ static int hxcmod_initialized;
static modcontext mod_context;
static tracker_buffer_state trkbuf;
static uint16_t avrcp_controller_cid = 0;
/* AVRCP Target context START */
static const uint8_t subunit_info[] = {
@ -230,6 +233,7 @@ avrcp_play_status_info_t play_info;
/* LISTING_START(MainConfiguration): Setup Audio Source and AVRCP Target services */
static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size);
static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
#ifdef HAVE_BTSTACK_STDIN
static void stdin_process(char cmd);
#endif
@ -252,7 +256,10 @@ static int a2dp_source_and_avrcp_services_init(void){
// Initialize AVRCP Target.
avrcp_target_init();
avrcp_target_register_packet_handler(&avrcp_target_packet_handler);
// Initialize AVRCP Controller
avrcp_controller_init();
avrcp_controller_register_packet_handler(&avrcp_controller_packet_handler);
// Initialize SDP,
sdp_init();
@ -267,10 +274,15 @@ static int a2dp_source_and_avrcp_services_init(void){
#ifdef AVRCP_BROWSING_ENABLED
supported_features |= (1 << AVRCP_TARGET_SUPPORTED_FEATURE_BROWSING);
#endif
avrcp_target_create_sdp_record(sdp_avrcp_target_service_buffer, 0x10001, supported_features, NULL, NULL);
sdp_register_service(sdp_avrcp_target_service_buffer);
// setup AVRCP Controller
memset(sdp_avrcp_controller_service_buffer, 0, sizeof(sdp_avrcp_controller_service_buffer));
uint16_t controller_supported_features = (1 << AVRCP_TARGET_SUPPORTED_FEATURE_CATEGORY_MONITOR_OR_AMPLIFIER);
avrcp_controller_create_sdp_record(sdp_avrcp_controller_service_buffer, 0x10002, controller_supported_features, NULL, NULL);
sdp_register_service(sdp_avrcp_controller_service_buffer);
// Set local name with a template Bluetooth address, that will be automatically
// replaced with a actual address once it is available, i.e. when BTstack boots
// up and starts talking to a Bluetooth module.
@ -454,8 +466,6 @@ static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, ui
if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return;
printf("A2DP Meta %x\n", hci_event_a2dp_meta_get_subevent_code(packet));
switch (hci_event_a2dp_meta_get_subevent_code(packet)){
case A2DP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
a2dp_subevent_signaling_connection_established_get_bd_addr(packet, address);
@ -598,7 +608,9 @@ static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, u
avrcp_target_set_subunit_info(media_tracker.avrcp_cid, AVRCP_SUBUNIT_TYPE_AUDIO, (uint8_t *)subunit_info, sizeof(subunit_info));
return;
}
case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:
printf("AVRCP Target: new volume %d\n", avrcp_subevent_notification_volume_changed_get_absolute_volume(packet));
break;
case AVRCP_SUBEVENT_EVENT_IDS_QUERY:
status = avrcp_target_supported_events(media_tracker.avrcp_cid, events_num, events, sizeof(events));
break;
@ -645,6 +657,63 @@ static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, u
}
}
static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
UNUSED(channel);
UNUSED(size);
uint16_t local_cid;
uint8_t status = 0xFF;
bd_addr_t adress;
if (packet_type != HCI_EVENT_PACKET) return;
if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
switch (packet[2]){
case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: {
local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet);
if (avrcp_controller_cid != 0 && avrcp_controller_cid != local_cid) {
printf("AVRCP Controller: Connection failed, expected 0x%02X l2cap cid, received 0x%02X\n", avrcp_controller_cid, local_cid);
return;
}
status = avrcp_subevent_connection_established_get_status(packet);
if (status != ERROR_CODE_SUCCESS){
printf("AVRCP Controller: Connection failed: status 0x%02x\n", status);
avrcp_controller_cid = 0;
return;
}
avrcp_controller_cid = local_cid;
avrcp_subevent_connection_established_get_bd_addr(packet, adress);
printf("AVRCP Controller: Channel successfully opened: %s, avrcp_controller_cid 0x%02x\n", bd_addr_to_str(adress), avrcp_controller_cid);
// automatically enable notifications
avrcp_controller_enable_notification(avrcp_controller_cid, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED);
return;
}
case AVRCP_SUBEVENT_CONNECTION_RELEASED:
printf("AVRCP Controller: Channel released: avrcp_controller_cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet));
avrcp_controller_cid = 0;
return;
default:
break;
}
status = packet[5];
if (!avrcp_controller_cid) return;
// ignore INTERIM status
if (status == AVRCP_CTYPE_RESPONSE_INTERIM) return;
switch (packet[2]){
case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:{
int volume_percentage = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet) * 100 / 127;
printf("AVRCP Controller: notification absolute volume changed %d %%\n", volume_percentage);
return;
}
default:
break;
}
}
#ifdef HAVE_BTSTACK_STDIN
static void show_usage(void){
bd_addr_t iut_address;
@ -662,6 +731,8 @@ static void show_usage(void){
printf("p - pause streaming\n");
printf("w - reconfigure stream for 44100 Hz\n");
printf("e - reconfigure stream for 48000 Hz\n");
printf("t - volume up\n");
printf("T - volume down\n");
printf("\n--- Bluetooth AVRCP Target Commands %s ---\n", bd_addr_to_str(iut_address));
printf("---\n");
@ -691,6 +762,15 @@ static void stdin_process(char cmd){
case '\r':
break;
case 't':
printf(" - volume up\n");
status = avrcp_controller_volume_up(avrcp_controller_cid);
break;
case 'T':
printf(" - volume down\n");
status = avrcp_controller_volume_down(avrcp_controller_cid);
break;
case 'x':
if (media_tracker.avrcp_cid){
avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t));