mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-30 16:20:24 +00:00
avrcp_controller: automatically query supported events when registering for notifications
This commit is contained in:
parent
1f94eaa583
commit
2ac1dc76c9
@ -29,13 +29,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
|
||||
### Fixed
|
||||
- A2DP Source: fix reconfigure
|
||||
- AVRCP Controller: prevent registering notifications for unsupported events
|
||||
- RFCOMM: fixed handling of remote port configuration command
|
||||
- HFP AG: fix accept incoming connection while audio connection is established
|
||||
- PBAP Client: handle chunked vCard Listing
|
||||
- SM: Work around for unexpected Windows 10 disconnect for BR Secure Connections (SMP over BR timeout)
|
||||
- SM: support storing bonding information for devices with identical IRK but different public addresses
|
||||
- GAP: restart advertising when private address changes
|
||||
|
||||
|
||||
### Changed
|
||||
- Drop iOS support
|
||||
- HCI: provide status instead of undocumented int error code and bool for API functions
|
||||
@ -51,6 +52,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||
- HFP: enhanced VRA: HFP_SUBEVENT_VOICE_RECOGNITION_ACTIVATED is emitted after VRA is ready and the the audio connection is established. This simplifies HFP HF client logic, i.e. client can call `hfp_hf_enhanced_voice_recognition_report_ready_for_audio directly` upon reception of HFP_SUBEVENT_VOICE_RECOGNITION_ACTIVATED event.
|
||||
- AVDTP: media config validator is called with preview of media codec configuration event and configured separately for sink/source
|
||||
- AVRCP: use PANEL as default unit + subunit info
|
||||
- AVRCP Controller: automatically query supported events when registering for notifications
|
||||
- Run Loop: new functionality for HCI transport drivers and inter-process communication
|
||||
- *btstack_run_loop_poll_data_sources_from_irq*: used to transfer control from IRQ handler to main thread/run loop
|
||||
- *btstack_run_loop_execute_on_main_thread*: schedule code execution on main thread from other thread
|
||||
|
@ -752,11 +752,14 @@ static void avrcp_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
|
||||
media_tracker.avrcp_cid = local_cid;
|
||||
avrcp_subevent_connection_established_get_bd_addr(packet, event_addr);
|
||||
|
||||
printf("AVRCP: Channel to %s successfully opened, avrcp_cid 0x%02x\n", bd_addr_to_str(event_addr), media_tracker.avrcp_cid);
|
||||
|
||||
avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, NULL, sizeof(tracks)/sizeof(avrcp_track_t));
|
||||
|
||||
avrcp_controller_get_supported_events(media_tracker.avrcp_cid);
|
||||
|
||||
printf("AVRCP: Channel successfully opened: media_tracker.avrcp_cid 0x%02x\n", media_tracker.avrcp_cid);
|
||||
printf("Enable Volume Change notification\n");
|
||||
avrcp_controller_enable_notification(media_tracker.avrcp_cid, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED);
|
||||
printf("Enable Battery Status Change notification\n");
|
||||
avrcp_controller_enable_notification(media_tracker.avrcp_cid, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED);
|
||||
return;
|
||||
|
||||
case AVRCP_SUBEVENT_CONNECTION_RELEASED:
|
||||
@ -846,14 +849,6 @@ static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channe
|
||||
// see avrcp_battery_status_t
|
||||
printf("AVRCP Controller: battery status changed %d\n", avrcp_subevent_notification_event_batt_status_changed_get_battery_status(packet));
|
||||
break;
|
||||
case AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID:
|
||||
printf("Remote supports EVENT_ID 0x%02x\n", avrcp_subevent_get_capability_event_id_get_event_id(packet));
|
||||
break;
|
||||
case AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID_DONE:
|
||||
printf("automatically enable notifications\n");
|
||||
avrcp_controller_enable_notification(media_tracker.avrcp_cid, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED);
|
||||
avrcp_controller_enable_notification(media_tracker.avrcp_cid, AVRCP_NOTIFICATION_EVENT_BATT_STATUS_CHANGED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -557,7 +557,8 @@ typedef struct {
|
||||
|
||||
uint16_t remote_supported_notifications;
|
||||
bool remote_supported_notifications_queried;
|
||||
|
||||
bool remote_supported_notifications_suppress_emit_result;
|
||||
|
||||
uint16_t notifications_to_register;
|
||||
uint16_t notifications_to_deregister;
|
||||
uint8_t notifications_transaction_label[AVRCP_NOTIFICATION_EVENT_MAX_VALUE+1];
|
||||
|
@ -93,35 +93,37 @@ static int avrcp_controller_supports_browsing(uint16_t controller_supported_feat
|
||||
}
|
||||
|
||||
static void avrcp_controller_emit_supported_events(avrcp_connection_t * connection){
|
||||
uint8_t event_id;
|
||||
uint8_t offset;
|
||||
uint8_t event[9];
|
||||
uint8_t ctype = (uint8_t) AVRCP_CTYPE_RESPONSE_CHANGED_STABLE;
|
||||
uint8_t event_id;
|
||||
|
||||
for (event_id = (uint8_t) AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED; event_id < (uint8_t) AVRCP_NOTIFICATION_EVENT_MAX_VALUE; event_id++){
|
||||
if ( (connection->remote_supported_notifications & (1<<event_id)) == 0){
|
||||
continue;
|
||||
}
|
||||
offset = 0;
|
||||
event[offset++] = HCI_EVENT_AVRCP_META;
|
||||
event[offset++] = sizeof(event) - 2;
|
||||
event[offset++] = AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID;
|
||||
little_endian_store_16(event, offset, connection->avrcp_cid);
|
||||
offset += 2;
|
||||
event[offset++] = ctype;
|
||||
event[offset++] = 0;
|
||||
event[offset++] = event_id;
|
||||
(*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, offset);
|
||||
uint8_t event[8];
|
||||
uint8_t pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVRCP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID;
|
||||
little_endian_store_16(event, pos, connection->avrcp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = ctype;
|
||||
event[pos++] = 0;
|
||||
event[pos++] = event_id;
|
||||
UNUSED(pos);
|
||||
(*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
event[offset++] = HCI_EVENT_AVRCP_META;
|
||||
event[offset++] = sizeof(event) - 2;
|
||||
event[offset++] = AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID_DONE;
|
||||
little_endian_store_16(event, offset, connection->avrcp_cid);
|
||||
offset += 2;
|
||||
event[offset++] = ctype;
|
||||
event[offset++] = 0;
|
||||
uint8_t event[7];
|
||||
uint8_t pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVRCP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVRCP_SUBEVENT_GET_CAPABILITY_EVENT_ID_DONE;
|
||||
little_endian_store_16(event, pos, connection->avrcp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = ctype;
|
||||
event[pos++] = 0;
|
||||
UNUSED(pos);
|
||||
(*avrcp_controller_context.avrcp_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
@ -655,7 +657,7 @@ static void avrcp_controller_get_capabilities_for_connection(avrcp_connection_t
|
||||
}
|
||||
|
||||
static uint8_t avrcp_controller_register_notification(avrcp_connection_t * connection, avrcp_notification_event_id_t event_id){
|
||||
if ( (connection->remote_supported_notifications & (1 << event_id)) == 0){
|
||||
if (connection->remote_supported_notifications_queried && (connection->remote_supported_notifications & (1 << event_id)) == 0){
|
||||
return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
|
||||
}
|
||||
if ( (connection->notifications_to_deregister & (1 << event_id)) != 0){
|
||||
@ -669,6 +671,12 @@ static uint8_t avrcp_controller_register_notification(avrcp_connection_t * conne
|
||||
}
|
||||
|
||||
connection->notifications_to_register |= (1 << event_id);
|
||||
|
||||
if (!connection->remote_supported_notifications_queried){
|
||||
connection->remote_supported_notifications_suppress_emit_result = true;
|
||||
avrcp_controller_get_capabilities_for_connection(connection, AVRCP_CAPABILITY_ID_EVENT);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
@ -1000,6 +1008,10 @@ static void avrcp_handle_l2cap_data_packet_for_signaling_connection(avrcp_connec
|
||||
uint8_t event_id = packet[pos++];
|
||||
connection->remote_supported_notifications |= (1 << event_id);
|
||||
}
|
||||
if (connection->remote_supported_notifications_suppress_emit_result){
|
||||
connection->remote_supported_notifications_suppress_emit_result = false;
|
||||
break;
|
||||
}
|
||||
avrcp_controller_emit_supported_events(connection);
|
||||
break;
|
||||
|
||||
@ -1400,7 +1412,13 @@ uint8_t avrcp_controller_get_supported_events(uint16_t avrcp_cid){
|
||||
return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
}
|
||||
|
||||
avrcp_controller_get_capabilities_for_connection(connection, AVRCP_CAPABILITY_ID_EVENT);
|
||||
if (!connection->remote_supported_notifications_queried){
|
||||
connection->remote_supported_notifications_queried = true;
|
||||
avrcp_controller_get_capabilities_for_connection(connection, AVRCP_CAPABILITY_ID_EVENT);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
avrcp_controller_emit_supported_events(connection);
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user