mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-15 23:42:52 +00:00
avrcp: use l2cap cid instead of handle
This commit is contained in:
parent
8a2c6c7c4b
commit
b193c45e22
@ -1453,26 +1453,26 @@ typedef uint8_t sm_key_t[16];
|
||||
/** AVRCP Subevent */
|
||||
|
||||
/**
|
||||
* @format 1H12B
|
||||
* @format 11BH2
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param status 0 == OK
|
||||
* @param local_cid
|
||||
* @param bd_addr
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_CONNECTION_ESTABLISHED 0x01
|
||||
|
||||
/**
|
||||
* @format 1H
|
||||
* @format 12
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_CONNECTION_RELEASED 0x02
|
||||
|
||||
/**
|
||||
* @format 1H1114JVJVJVJV
|
||||
* @format 121114JVJVJVJV
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param track
|
||||
* @param total_tracks
|
||||
@ -1489,9 +1489,9 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVRCP_SUBEVENT_NOW_PLAYING_INFO 0x03
|
||||
|
||||
/**
|
||||
* @format 1H111
|
||||
* @format 12111
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param repeat_mode
|
||||
* @param shuffle_mode
|
||||
@ -1499,9 +1499,9 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE 0x04
|
||||
|
||||
/**
|
||||
* @format 1H1441
|
||||
* @format 121441
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param song_length
|
||||
* @param song_position
|
||||
@ -1510,88 +1510,88 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVRCP_SUBEVENT_PLAY_STATUS 0x05
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param playback_status
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED 0x06
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param track_status
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED 0x07
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @format 121
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED 0x08
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @format 121
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED 0x09
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param absolute_volume
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED 0x0A
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param absolute_volume
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE 0x0B
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param notification_id
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_ENABLE_NOTIFICATION_COMPLETE 0x0C
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param operation_id
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_OPERATION_START 0x0D
|
||||
|
||||
/**
|
||||
* @format 1H11
|
||||
* @format 1211
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
* @param operation_id
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_OPERATION_COMPLETE 0x0E
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @format 121
|
||||
* @param subevent_code
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param status
|
||||
*/
|
||||
#define AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE 0x0F
|
||||
|
@ -4699,15 +4699,6 @@ static inline uint8_t a2dp_subevent_stream_released_get_local_seid(const uint8_t
|
||||
return event[5];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_connection_established_get_con_handle(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field status from event AVRCP_SUBEVENT_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
@ -4715,16 +4706,7 @@ static inline hci_con_handle_t avrcp_subevent_connection_established_get_con_han
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avrcp_subevent_connection_established_get_status(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
* @brief Get field local_cid from event AVRCP_SUBEVENT_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return local_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline uint16_t avrcp_subevent_connection_established_get_local_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 6);
|
||||
return event[3];
|
||||
}
|
||||
/**
|
||||
* @brief Get field bd_addr from event AVRCP_SUBEVENT_CONNECTION_ESTABLISHED
|
||||
@ -4733,26 +4715,44 @@ static inline uint16_t avrcp_subevent_connection_established_get_local_cid(const
|
||||
* @note: btstack_type B
|
||||
*/
|
||||
static inline void avrcp_subevent_connection_established_get_bd_addr(const uint8_t * event, bd_addr_t bd_addr){
|
||||
reverse_bd_addr(&event[8], bd_addr);
|
||||
reverse_bd_addr(&event[4], bd_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_CONNECTION_RELEASED
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_connection_released_get_con_handle(const uint8_t * event){
|
||||
static inline hci_con_handle_t avrcp_subevent_connection_established_get_con_handle(const uint8_t * event){
|
||||
return little_endian_read_16(event, 10);
|
||||
}
|
||||
/**
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline uint16_t avrcp_subevent_connection_established_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 12);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_CONNECTION_RELEASED
|
||||
* @param event packet
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline uint16_t avrcp_subevent_connection_released_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_NOW_PLAYING_INFO
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_NOW_PLAYING_INFO
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_now_playing_info_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_now_playing_info_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4865,12 +4865,12 @@ static inline const uint8_t * avrcp_subevent_now_playing_info_get_genre(const ui
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_shuffle_and_repeat_mode_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_shuffle_and_repeat_mode_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4902,12 +4902,12 @@ static inline uint8_t avrcp_subevent_shuffle_and_repeat_mode_get_shuffle_mode(co
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_PLAY_STATUS
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_PLAY_STATUS
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_play_status_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_play_status_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4948,12 +4948,12 @@ static inline uint8_t avrcp_subevent_play_status_get_play_status(const uint8_t *
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_NOTIFICATION_PLAYBACK_STATUS_CHANGED
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_notification_playback_status_changed_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_notification_playback_status_changed_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -4976,12 +4976,12 @@ static inline uint8_t avrcp_subevent_notification_playback_status_changed_get_pl
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_NOTIFICATION_TRACK_CHANGED
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_notification_track_changed_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_notification_track_changed_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5004,12 +5004,12 @@ static inline uint8_t avrcp_subevent_notification_track_changed_get_track_status
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_NOTIFICATION_NOW_PLAYING_CONTENT_CHANGED
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_notification_now_playing_content_changed_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_notification_now_playing_content_changed_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5023,12 +5023,12 @@ static inline uint8_t avrcp_subevent_notification_now_playing_content_changed_ge
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_NOTIFICATION_AVAILABLE_PLAYERS_CHANGED
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_notification_available_players_changed_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_notification_available_players_changed_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5042,12 +5042,12 @@ static inline uint8_t avrcp_subevent_notification_available_players_changed_get_
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_notification_volume_changed_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_notification_volume_changed_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5070,12 +5070,12 @@ static inline uint8_t avrcp_subevent_notification_volume_changed_get_absolute_vo
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_set_absolute_volume_response_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_set_absolute_volume_response_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5098,12 +5098,12 @@ static inline uint8_t avrcp_subevent_set_absolute_volume_response_get_absolute_v
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_ENABLE_NOTIFICATION_COMPLETE
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_ENABLE_NOTIFICATION_COMPLETE
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_enable_notification_complete_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_enable_notification_complete_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5126,12 +5126,12 @@ static inline uint8_t avrcp_subevent_enable_notification_complete_get_notificati
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_OPERATION_START
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_OPERATION_START
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_operation_start_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_operation_start_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5154,12 +5154,12 @@ static inline uint8_t avrcp_subevent_operation_start_get_operation_id(const uint
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_OPERATION_COMPLETE
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_OPERATION_COMPLETE
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_operation_complete_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_operation_complete_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
@ -5182,12 +5182,12 @@ static inline uint8_t avrcp_subevent_operation_complete_get_operation_id(const u
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get field con_handle from event AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE
|
||||
* @brief Get field avrcp_cid from event AVRCP_SUBEVENT_PLAYER_APPLICATION_VALUE_RESPONSE
|
||||
* @param event packet
|
||||
* @return con_handle
|
||||
* @note: btstack_type H
|
||||
* @return avrcp_cid
|
||||
* @note: btstack_type 2
|
||||
*/
|
||||
static inline hci_con_handle_t avrcp_subevent_player_application_value_response_get_con_handle(const uint8_t * event){
|
||||
static inline uint16_t avrcp_subevent_player_application_value_response_get_avrcp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
|
@ -327,14 +327,31 @@ void avrcp_target_create_sdp_record(uint8_t * service, uint32_t service_record_h
|
||||
avrcp_create_sdp_record(0, service, service_record_handle, browsing, supported_features, service_name, service_provider_name);
|
||||
}
|
||||
|
||||
static void avrcp_emit_repeat_and_shuffle_mode(btstack_packet_handler_t callback, uint16_t con_handle, uint8_t status, avrcp_repeat_mode_t repeat_mode, avrcp_shuffle_mode_t shuffle_mode){
|
||||
static void avrcp_emit_connection_established(btstack_packet_handler_t callback, uint8_t status, bd_addr_t addr, uint16_t con_handle, uint16_t avrcp_cid){
|
||||
if (!callback) return;
|
||||
uint8_t event[14];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVRCP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVRCP_SUBEVENT_CONNECTION_ESTABLISHED;
|
||||
event[pos++] = status;
|
||||
reverse_bd_addr(addr,&event[pos]);
|
||||
pos += 6;
|
||||
little_endian_store_16(event, pos, con_handle);
|
||||
pos += 2;
|
||||
little_endian_store_16(event, pos, avrcp_cid);
|
||||
pos += 2;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void avrcp_emit_repeat_and_shuffle_mode(btstack_packet_handler_t callback, uint16_t avrcp_cid, uint8_t status, avrcp_repeat_mode_t repeat_mode, avrcp_shuffle_mode_t shuffle_mode){
|
||||
if (!callback) return;
|
||||
uint8_t event[8];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVRCP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE;
|
||||
little_endian_store_16(event, pos, con_handle);
|
||||
little_endian_store_16(event, pos, avrcp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = status;
|
||||
event[pos++] = repeat_mode;
|
||||
@ -342,45 +359,28 @@ static void avrcp_emit_repeat_and_shuffle_mode(btstack_packet_handler_t callback
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void avrcp_emit_connection_established(btstack_packet_handler_t callback, uint16_t con_handle, uint8_t status, uint16_t local_cid, bd_addr_t addr){
|
||||
if (!callback) return;
|
||||
uint8_t event[14];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVRCP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVRCP_SUBEVENT_CONNECTION_ESTABLISHED;
|
||||
little_endian_store_16(event, pos, con_handle);
|
||||
pos += 2;
|
||||
event[pos++] = status;
|
||||
little_endian_store_16(event, pos, local_cid);
|
||||
pos += 2;
|
||||
reverse_bd_addr(addr,&event[pos]);
|
||||
pos += 6;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void avrcp_emit_operation_status(btstack_packet_handler_t callback, uint8_t subevent, uint16_t con_handle, uint8_t status, uint8_t operation_id){
|
||||
static void avrcp_emit_operation_status(btstack_packet_handler_t callback, uint8_t subevent, uint16_t avrcp_cid, uint8_t status, uint8_t operation_id){
|
||||
if (!callback) return;
|
||||
uint8_t event[7];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVRCP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = subevent;
|
||||
little_endian_store_16(event, pos, con_handle);
|
||||
little_endian_store_16(event, pos, avrcp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = status;
|
||||
event[pos++] = operation_id;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void avrcp_emit_connection_closed(btstack_packet_handler_t callback, uint16_t con_handle){
|
||||
static void avrcp_emit_connection_closed(btstack_packet_handler_t callback, uint16_t avrcp_cid){
|
||||
if (!callback) return;
|
||||
uint8_t event[5];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVRCP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVRCP_SUBEVENT_CONNECTION_RELEASED;
|
||||
little_endian_store_16(event, pos, con_handle);
|
||||
little_endian_store_16(event, pos, avrcp_cid);
|
||||
pos += 2;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
@ -396,17 +396,6 @@ static avrcp_connection_t * get_avrcp_connection_for_bd_addr(bd_addr_t addr){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static avrcp_connection_t * get_avrcp_connection_for_con_handle(hci_con_handle_t con_handle){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avrcp_connections);
|
||||
while (btstack_linked_list_iterator_has_next(&it)){
|
||||
avrcp_connection_t * connection = (avrcp_connection_t *)btstack_linked_list_iterator_next(&it);
|
||||
if (connection->con_handle != con_handle) continue;
|
||||
return connection;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static avrcp_connection_t * get_avrcp_connection_for_l2cap_signaling_cid(uint16_t l2cap_cid){
|
||||
btstack_linked_list_iterator_t it;
|
||||
btstack_linked_list_iterator_init(&it, (btstack_linked_list_t *) &avrcp_connections);
|
||||
@ -459,8 +448,8 @@ static void request_pass_through_release_control_cmd(avrcp_connection_t * connec
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
}
|
||||
|
||||
static void request_pass_through_press_control_cmd(uint16_t con_handle, avrcp_operation_id_t opid, uint16_t playback_speed){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
static void request_pass_through_press_control_cmd(uint16_t avrcp_cid, avrcp_operation_id_t opid, uint16_t playback_speed){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp: could not find a connection.");
|
||||
return;
|
||||
@ -999,10 +988,12 @@ static void avrcp_handle_can_send_now(avrcp_connection_t * connection){
|
||||
switch (connection->state){
|
||||
case AVCTP_W2_SEND_PRESS_COMMAND:
|
||||
connection->state = AVCTP_W2_RECEIVE_PRESS_RESPONSE;
|
||||
avrcp_send_cmd(connection->l2cap_signaling_cid, connection);
|
||||
break;
|
||||
case AVCTP_W2_SEND_COMMAND:
|
||||
case AVCTP_W2_SEND_RELEASE_COMMAND:
|
||||
connection->state = AVCTP_W2_RECEIVE_RESPONSE;
|
||||
avrcp_send_cmd(connection->l2cap_signaling_cid, connection);
|
||||
break;
|
||||
case AVCTP_CONNECTION_OPENED:
|
||||
if (connection->disconnect){
|
||||
@ -1027,7 +1018,6 @@ static void avrcp_handle_can_send_now(avrcp_connection_t * connection){
|
||||
default:
|
||||
return;
|
||||
}
|
||||
avrcp_send_cmd(connection->l2cap_signaling_cid, connection);
|
||||
}
|
||||
|
||||
static avrcp_connection_t * avrcp_create_connection(bd_addr_t remote_addr){
|
||||
@ -1079,7 +1069,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
}
|
||||
psm = l2cap_event_channel_opened_get_psm(packet);
|
||||
if (psm != BLUETOOTH_PROTOCOL_AVCTP){
|
||||
log_error("unexpected PSM - Not implemented yet: L2CAP_EVENT_CHANNEL_OPENED");
|
||||
log_error("L2CAP_EVENT_CHANNEL_OPENED avrcp: unexpected PSM");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1088,13 +1078,20 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
|
||||
con_handle = l2cap_event_channel_opened_get_handle(packet);
|
||||
local_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
|
||||
if (connection->l2cap_signaling_cid != local_cid) {
|
||||
log_info("Connection is not established, expected 0x%02X l2cap cid, received 0x%02X\n", connection->l2cap_signaling_cid, local_cid);
|
||||
break;
|
||||
}
|
||||
|
||||
// printf("L2CAP_EVENT_CHANNEL_OPENED: Channel successfully opened: %s, handle 0x%02x, psm 0x%02x, local cid 0x%02x, remote cid 0x%02x\n",
|
||||
// bd_addr_to_str(event_addr), con_handle, psm, local_cid, l2cap_event_channel_opened_get_remote_cid(packet));
|
||||
if (connection->l2cap_signaling_cid == 0) {
|
||||
|
||||
if (connection->con_handle == 0) {
|
||||
connection->l2cap_signaling_cid = local_cid;
|
||||
connection->con_handle = con_handle;
|
||||
connection->state = AVCTP_CONNECTION_OPENED;
|
||||
avrcp_emit_connection_established(avrcp_callback, con_handle, 0, local_cid, event_addr);
|
||||
avrcp_emit_connection_established(avrcp_callback, 0, event_addr, con_handle, local_cid);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1137,7 +1134,7 @@ void avrcp_register_packet_handler(btstack_packet_handler_t callback){
|
||||
avrcp_callback = callback;
|
||||
}
|
||||
|
||||
uint8_t avrcp_connect(bd_addr_t bd_addr){
|
||||
uint8_t avrcp_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_bd_addr(bd_addr);
|
||||
if (connection){
|
||||
return ERROR_CODE_COMMAND_DISALLOWED;
|
||||
@ -1150,12 +1147,15 @@ uint8_t avrcp_connect(bd_addr_t bd_addr){
|
||||
}
|
||||
|
||||
connection->state = AVCTP_CONNECTION_W4_L2CAP_CONNECTED;
|
||||
l2cap_create_channel(packet_handler, connection->remote_addr, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, NULL);
|
||||
l2cap_create_channel(packet_handler, connection->remote_addr, BLUETOOTH_PROTOCOL_AVCTP, 0xffff, &connection->l2cap_signaling_cid);
|
||||
if (avrcp_cid) {
|
||||
*avrcp_cid = connection->l2cap_signaling_cid;
|
||||
}
|
||||
return ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void avrcp_unit_info(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_unit_info(uint16_t avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_unit_info: could not find a connection.");
|
||||
return;
|
||||
@ -1173,8 +1173,8 @@ void avrcp_unit_info(uint16_t con_handle){
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
}
|
||||
|
||||
static void avrcp_get_capabilities(uint16_t con_handle, uint8_t capability_id){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
static void avrcp_get_capabilities(uint16_t avrcp_cid, uint8_t capability_id){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_capabilities: could not find a connection.");
|
||||
return;
|
||||
@ -1196,57 +1196,57 @@ static void avrcp_get_capabilities(uint16_t con_handle, uint8_t capability_id){
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
}
|
||||
|
||||
void avrcp_get_supported_company_ids(uint16_t con_handle){
|
||||
avrcp_get_capabilities(con_handle, AVRCP_CAPABILITY_ID_COMPANY);
|
||||
void avrcp_get_supported_company_ids(uint16_t avrcp_cid){
|
||||
avrcp_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_COMPANY);
|
||||
}
|
||||
|
||||
void avrcp_get_supported_events(uint16_t con_handle){
|
||||
avrcp_get_capabilities(con_handle, AVRCP_CAPABILITY_ID_EVENT);
|
||||
void avrcp_get_supported_events(uint16_t avrcp_cid){
|
||||
avrcp_get_capabilities(avrcp_cid, AVRCP_CAPABILITY_ID_EVENT);
|
||||
}
|
||||
|
||||
|
||||
void avrcp_play(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_PLAY, 0);
|
||||
void avrcp_play(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PLAY, 0);
|
||||
}
|
||||
|
||||
void avrcp_stop(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_STOP, 0);
|
||||
void avrcp_stop(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_STOP, 0);
|
||||
}
|
||||
|
||||
void avrcp_pause(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_PAUSE, 0);
|
||||
void avrcp_pause(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_PAUSE, 0);
|
||||
}
|
||||
|
||||
void avrcp_forward(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_FORWARD, 0);
|
||||
void avrcp_forward(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FORWARD, 0);
|
||||
}
|
||||
|
||||
void avrcp_backward(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_BACKWARD, 0);
|
||||
void avrcp_backward(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_BACKWARD, 0);
|
||||
}
|
||||
|
||||
void avrcp_start_rewind(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_REWIND, 0);
|
||||
void avrcp_start_rewind(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_REWIND, 0);
|
||||
}
|
||||
|
||||
void avrcp_volume_up(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_VOLUME_UP, 0);
|
||||
void avrcp_volume_up(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_UP, 0);
|
||||
}
|
||||
|
||||
void avrcp_volume_down(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_VOLUME_DOWN, 0);
|
||||
void avrcp_volume_down(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_VOLUME_DOWN, 0);
|
||||
}
|
||||
|
||||
void avrcp_mute(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_MUTE, 0);
|
||||
void avrcp_mute(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_MUTE, 0);
|
||||
}
|
||||
|
||||
void avrcp_skip(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_SKIP, 0);
|
||||
void avrcp_skip(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_SKIP, 0);
|
||||
}
|
||||
|
||||
void avrcp_stop_rewind(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_stop_rewind(uint16_t avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_stop_rewind: could not find a connection.");
|
||||
return;
|
||||
@ -1255,12 +1255,12 @@ void avrcp_stop_rewind(uint16_t con_handle){
|
||||
request_pass_through_release_control_cmd(connection);
|
||||
}
|
||||
|
||||
void avrcp_start_fast_forward(uint16_t con_handle){
|
||||
request_pass_through_press_control_cmd(con_handle, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
|
||||
void avrcp_start_fast_forward(uint16_t avrcp_cid){
|
||||
request_pass_through_press_control_cmd(avrcp_cid, AVRCP_OPERATION_ID_FAST_FORWARD, 0);
|
||||
}
|
||||
|
||||
void avrcp_stop_fast_forward(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_stop_fast_forward(uint16_t avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_stop_fast_forward: could not find a connection.");
|
||||
return;
|
||||
@ -1269,8 +1269,8 @@ void avrcp_stop_fast_forward(uint16_t con_handle){
|
||||
request_pass_through_release_control_cmd(connection);
|
||||
}
|
||||
|
||||
void avrcp_get_play_status(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_get_play_status(uint16_t avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_play_status: could not find a connection.");
|
||||
return;
|
||||
@ -1291,8 +1291,8 @@ void avrcp_get_play_status(uint16_t con_handle){
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
}
|
||||
|
||||
void avrcp_enable_notification(uint16_t con_handle, avrcp_notification_event_id_t event_id){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_play_status: could not find a connection.");
|
||||
return;
|
||||
@ -1300,8 +1300,8 @@ void avrcp_enable_notification(uint16_t con_handle, avrcp_notification_event_id_
|
||||
avrcp_register_notification(connection, event_id);
|
||||
}
|
||||
|
||||
void avrcp_disable_notification(uint16_t con_handle, avrcp_notification_event_id_t event_id){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_play_status: could not find a connection.");
|
||||
return;
|
||||
@ -1309,8 +1309,8 @@ void avrcp_disable_notification(uint16_t con_handle, avrcp_notification_event_id
|
||||
connection->notifications_to_deregister |= (1 << event_id);
|
||||
}
|
||||
|
||||
void avrcp_get_now_playing_info(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_get_now_playing_info(uint16_t avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_capabilities: could not find a connection.");
|
||||
return;
|
||||
@ -1345,8 +1345,8 @@ void avrcp_get_now_playing_info(uint16_t con_handle){
|
||||
|
||||
}
|
||||
|
||||
void avrcp_set_absolute_volume(uint16_t con_handle, uint8_t volume){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_capabilities: could not find a connection.");
|
||||
return;
|
||||
@ -1374,8 +1374,8 @@ void avrcp_set_absolute_volume(uint16_t con_handle, uint8_t volume){
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
}
|
||||
|
||||
void avrcp_query_shuffle_and_repeat_modes(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_query_shuffle_and_repeat_modes(uint16_t avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_capabilities: could not find a connection.");
|
||||
return;
|
||||
@ -1403,8 +1403,8 @@ void avrcp_query_shuffle_and_repeat_modes(uint16_t con_handle){
|
||||
}
|
||||
|
||||
|
||||
static void avrcp_set_current_player_application_setting_value(uint16_t con_handle, uint8_t attribute_id, uint8_t attribute_value){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
static void avrcp_set_current_player_application_setting_value(uint16_t avrcp_cid, uint8_t attribute_id, uint8_t attribute_value){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_capabilities: could not find a connection.");
|
||||
return;
|
||||
@ -1433,18 +1433,18 @@ static void avrcp_set_current_player_application_setting_value(uint16_t con_hand
|
||||
avrcp_request_can_send_now(connection, connection->l2cap_signaling_cid);
|
||||
}
|
||||
|
||||
void avrcp_set_shuffle_mode(uint16_t con_handle, avrcp_shuffle_mode_t mode){
|
||||
void avrcp_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode){
|
||||
if (mode < AVRCP_SHUFFLE_MODE_OFF || mode > AVRCP_SHUFFLE_MODE_GROUP) return;
|
||||
avrcp_set_current_player_application_setting_value(con_handle, 0x03, mode);
|
||||
avrcp_set_current_player_application_setting_value(avrcp_cid, 0x03, mode);
|
||||
}
|
||||
|
||||
void avrcp_set_repeat_mode(uint16_t con_handle, avrcp_repeat_mode_t mode){
|
||||
void avrcp_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode){
|
||||
if (mode < AVRCP_REPEAT_MODE_OFF || mode > AVRCP_REPEAT_MODE_GROUP) return;
|
||||
avrcp_set_current_player_application_setting_value(con_handle, 0x02, mode);
|
||||
avrcp_set_current_player_application_setting_value(avrcp_cid, 0x02, mode);
|
||||
}
|
||||
|
||||
void avrcp_disconnect(uint16_t con_handle){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_con_handle(con_handle);
|
||||
void avrcp_disconnect(uint16_t avrcp_cid){
|
||||
avrcp_connection_t * connection = get_avrcp_connection_for_l2cap_signaling_cid(avrcp_cid);
|
||||
if (!connection){
|
||||
log_error("avrcp_get_capabilities: could not find a connection.");
|
||||
return;
|
||||
|
@ -189,7 +189,7 @@ typedef struct {
|
||||
bd_addr_t remote_addr;
|
||||
hci_con_handle_t con_handle;
|
||||
uint16_t l2cap_signaling_cid;
|
||||
|
||||
|
||||
avctp_connection_state_t state;
|
||||
uint8_t wait_to_send;
|
||||
|
||||
@ -269,136 +269,138 @@ void avrcp_register_packet_handler(btstack_packet_handler_t callback);
|
||||
/**
|
||||
* @brief Connect to device with a bluetooth address.
|
||||
* @param bd_addr
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
uint8_t avrcp_connect(bd_addr_t bd_addr);
|
||||
void avrcp_disconnect(uint16_t con_handle);
|
||||
uint8_t avrcp_connect(bd_addr_t bd_addr, uint16_t * avrcp_cid);
|
||||
|
||||
void avrcp_disconnect(uint16_t avrcp_cid);
|
||||
/**
|
||||
* @brief Unit info.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_unit_info(uint16_t con_handle);
|
||||
void avrcp_unit_info(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Get capabilities.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_get_supported_company_ids(uint16_t con_handle);
|
||||
void avrcp_get_supported_events(uint16_t con_handle);
|
||||
void avrcp_get_supported_company_ids(uint16_t avrcp_cid);
|
||||
void avrcp_get_supported_events(uint16_t avrcp_cid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Play. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_play(uint16_t con_handle);
|
||||
void avrcp_play(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Stop. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_stop(uint16_t con_handle);
|
||||
void avrcp_stop(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Pause. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_pause(uint16_t con_handle);
|
||||
void avrcp_pause(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Fast forward. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_start_fast_forward(uint16_t con_handle);
|
||||
void avrcp_stop_fast_forward(uint16_t con_handle);
|
||||
void avrcp_start_fast_forward(uint16_t avrcp_cid);
|
||||
void avrcp_stop_fast_forward(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Rewind. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_start_rewind(uint16_t con_handle);
|
||||
void avrcp_stop_rewind(uint16_t con_handle);
|
||||
void avrcp_start_rewind(uint16_t avrcp_cid);
|
||||
void avrcp_stop_rewind(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Forward. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_forward(uint16_t con_handle);
|
||||
void avrcp_forward(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Backward. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_backward(uint16_t con_handle);
|
||||
void avrcp_backward(uint16_t avrcp_cid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get play status. Returns event of type AVRCP_SUBEVENT_PLAY_STATUS (length, position, play_status).
|
||||
* If TG does not support SongLength And SongPosition on TG, then TG shall return 0xFFFFFFFF.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_get_play_status(uint16_t con_handle);
|
||||
void avrcp_get_play_status(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Register notification. Response via AVRCP_SUBEVENT_ENABLE_NOTIFICATION_COMPLETE.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
* @param event_id
|
||||
*/
|
||||
void avrcp_enable_notification(uint16_t con_handle, avrcp_notification_event_id_t event_id);
|
||||
void avrcp_disable_notification(uint16_t con_handle, avrcp_notification_event_id_t event_id);
|
||||
void avrcp_enable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id);
|
||||
void avrcp_disable_notification(uint16_t avrcp_cid, avrcp_notification_event_id_t event_id);
|
||||
|
||||
/**
|
||||
* @brief Get info on now playing media.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_get_now_playing_info(uint16_t con_handle);
|
||||
void avrcp_get_now_playing_info(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Set absolute volume 0-127 (corresponds to 0-100%). Response via AVRCP_SUBEVENT_SET_ABSOLUTE_VOLUME_RESPONSE
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_set_absolute_volume(uint16_t con_handle, uint8_t volume);
|
||||
void avrcp_set_absolute_volume(uint16_t avrcp_cid, uint8_t volume);
|
||||
|
||||
/**
|
||||
* @brief Turns the volume to high. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_volume_up(uint16_t con_handle);
|
||||
void avrcp_volume_up(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Turns the volume to low. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_volume_down(uint16_t con_handle);
|
||||
void avrcp_volume_down(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Puts the sound out. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_mute(uint16_t con_handle);
|
||||
void avrcp_mute(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Skip to next playing media. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_skip(uint16_t con_handle);
|
||||
void avrcp_skip(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Query repeat and shuffle mode. Response via AVRCP_SUBEVENT_SHUFFLE_AND_REPEAT_MODE.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_query_shuffle_and_repeat_modes(uint16_t con_handle);
|
||||
void avrcp_query_shuffle_and_repeat_modes(uint16_t avrcp_cid);
|
||||
|
||||
/**
|
||||
* @brief Set shuffle mode. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_set_shuffle_mode(uint16_t con_handle, avrcp_shuffle_mode_t mode);
|
||||
void avrcp_set_shuffle_mode(uint16_t avrcp_cid, avrcp_shuffle_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Set repeat mode. Event AVRCP_SUBEVENT_OPERATION_COMPLETE returns operation id and status.
|
||||
* @param con_handle
|
||||
* @param avrcp_cid
|
||||
*/
|
||||
void avrcp_set_repeat_mode(uint16_t con_handle, avrcp_repeat_mode_t mode);
|
||||
void avrcp_set_repeat_mode(uint16_t avrcp_cid, avrcp_repeat_mode_t mode);
|
||||
|
||||
const char * avrcp_subunit2str(uint16_t index);
|
||||
const char * avrcp_event2str(uint16_t index);
|
||||
|
@ -64,6 +64,7 @@ static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
|
||||
|
||||
static bd_addr_t device_addr;
|
||||
static uint16_t avrcp_cid = 0;
|
||||
// iPhone SE
|
||||
// static const char * device_addr_string = "BC:EC:5D:E6:15:03";
|
||||
|
||||
@ -90,19 +91,24 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
case HCI_EVENT_AVRCP_META:
|
||||
switch (packet[2]){
|
||||
case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: {
|
||||
local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet);
|
||||
if (avrcp_cid != local_cid) {
|
||||
printf("Connection is not established, expected 0x%02X l2cap cid, received 0x%02X\n", avrcp_cid, local_cid);
|
||||
break;
|
||||
}
|
||||
|
||||
status = avrcp_subevent_connection_established_get_status(packet);
|
||||
avrcp_con_handle = avrcp_subevent_connection_established_get_con_handle(packet);
|
||||
local_cid = avrcp_subevent_connection_established_get_local_cid(packet);
|
||||
avrcp_subevent_connection_established_get_bd_addr(packet, event_addr);
|
||||
printf("Channel successfully opened: %s, handle 0x%02x, local cid 0x%02x\n", bd_addr_to_str(event_addr), avrcp_con_handle, local_cid);
|
||||
// automatically enable notifications
|
||||
avrcp_enable_notification(avrcp_con_handle, AVRCP_NOTIFICATION_EVENT_PLAYBACK_STATUS_CHANGED);
|
||||
//avrcp_enable_notification(avrcp_con_handle, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED);
|
||||
avrcp_enable_notification(avrcp_con_handle, AVRCP_NOTIFICATION_EVENT_NOW_PLAYING_CONTENT_CHANGED);
|
||||
return;
|
||||
}
|
||||
case AVRCP_SUBEVENT_CONNECTION_RELEASED:
|
||||
printf("Channel released: con_handle 0x%02x\n", avrcp_subevent_connection_released_get_con_handle(packet));
|
||||
avrcp_con_handle = 0;
|
||||
printf("Channel released: avrcp_cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet));
|
||||
avrcp_cid = 0;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
@ -233,99 +239,99 @@ static void stdin_process(char cmd){
|
||||
switch (cmd){
|
||||
case 'c':
|
||||
printf(" - Create AVRCP connection to addr %s.\n", bd_addr_to_str(device_addr));
|
||||
avrcp_connect(device_addr);
|
||||
avrcp_connect(device_addr, &avrcp_cid);
|
||||
break;
|
||||
case 'D':
|
||||
printf(" - Disconnect\n");
|
||||
avrcp_disconnect(avrcp_con_handle);
|
||||
avrcp_disconnect(avrcp_cid);
|
||||
break;
|
||||
case 'i':
|
||||
printf(" - get play status\n");
|
||||
avrcp_get_play_status(avrcp_con_handle);
|
||||
avrcp_get_play_status(avrcp_cid);
|
||||
break;
|
||||
case 'j':
|
||||
printf(" - get now playing info\n");
|
||||
avrcp_get_now_playing_info(avrcp_con_handle);
|
||||
avrcp_get_now_playing_info(avrcp_cid);
|
||||
break;
|
||||
case 'k':
|
||||
printf(" - play\n");
|
||||
avrcp_play(avrcp_con_handle);
|
||||
avrcp_play(avrcp_cid);
|
||||
break;
|
||||
case 'K':
|
||||
printf(" - stop\n");
|
||||
avrcp_stop(avrcp_con_handle);
|
||||
avrcp_stop(avrcp_cid);
|
||||
break;
|
||||
case 'L':
|
||||
printf(" - pause\n");
|
||||
avrcp_pause(avrcp_con_handle);
|
||||
avrcp_pause(avrcp_cid);
|
||||
break;
|
||||
case 'm':
|
||||
printf(" - start fast forward\n");
|
||||
avrcp_start_fast_forward(avrcp_con_handle);
|
||||
avrcp_start_fast_forward(avrcp_cid);
|
||||
break;
|
||||
case 'M':
|
||||
printf(" - stop fast forward\n");
|
||||
avrcp_stop_fast_forward(avrcp_con_handle);
|
||||
avrcp_stop_fast_forward(avrcp_cid);
|
||||
break;
|
||||
case 'n':
|
||||
printf(" - start rewind\n");
|
||||
avrcp_start_rewind(avrcp_con_handle);
|
||||
avrcp_start_rewind(avrcp_cid);
|
||||
break;
|
||||
case 'N':
|
||||
printf(" - stop rewind\n");
|
||||
avrcp_stop_rewind(avrcp_con_handle);
|
||||
avrcp_stop_rewind(avrcp_cid);
|
||||
break;
|
||||
case 'o':
|
||||
printf(" - forward\n");
|
||||
avrcp_forward(avrcp_con_handle);
|
||||
avrcp_forward(avrcp_cid);
|
||||
break;
|
||||
case 'O':
|
||||
printf(" - backward\n");
|
||||
avrcp_backward(avrcp_con_handle);
|
||||
avrcp_backward(avrcp_cid);
|
||||
break;
|
||||
case 'p':
|
||||
printf(" - volume up\n");
|
||||
avrcp_volume_up(avrcp_con_handle);
|
||||
avrcp_volume_up(avrcp_cid);
|
||||
break;
|
||||
case 'P':
|
||||
printf(" - volume down\n");
|
||||
avrcp_volume_down(avrcp_con_handle);
|
||||
avrcp_volume_down(avrcp_cid);
|
||||
break;
|
||||
case 'r':
|
||||
printf(" - absolute volume of 50 percent\n");
|
||||
avrcp_set_absolute_volume(avrcp_con_handle, 50);
|
||||
avrcp_set_absolute_volume(avrcp_cid, 50);
|
||||
break;
|
||||
case 's':
|
||||
printf(" - mute\n");
|
||||
avrcp_mute(avrcp_con_handle);
|
||||
avrcp_mute(avrcp_cid);
|
||||
break;
|
||||
case 't':
|
||||
printf(" - skip\n");
|
||||
avrcp_skip(avrcp_con_handle);
|
||||
avrcp_skip(avrcp_cid);
|
||||
break;
|
||||
case 'u':
|
||||
printf(" - query repeat and shuffle mode\n");
|
||||
avrcp_query_shuffle_and_repeat_modes(avrcp_con_handle);
|
||||
avrcp_query_shuffle_and_repeat_modes(avrcp_cid);
|
||||
break;
|
||||
case 'v':
|
||||
printf(" - repeat single track\n");
|
||||
avrcp_set_repeat_mode(avrcp_con_handle, AVRCP_REPEAT_MODE_SINGLE_TRACK);
|
||||
avrcp_set_repeat_mode(avrcp_cid, AVRCP_REPEAT_MODE_SINGLE_TRACK);
|
||||
break;
|
||||
case 'x':
|
||||
printf(" - repeat all tracks\n");
|
||||
avrcp_set_repeat_mode(avrcp_con_handle, AVRCP_REPEAT_MODE_ALL_TRACKS);
|
||||
avrcp_set_repeat_mode(avrcp_cid, AVRCP_REPEAT_MODE_ALL_TRACKS);
|
||||
break;
|
||||
case 'X':
|
||||
printf(" - disable repeat mode\n");
|
||||
avrcp_set_repeat_mode(avrcp_con_handle, AVRCP_REPEAT_MODE_OFF);
|
||||
avrcp_set_repeat_mode(avrcp_cid, AVRCP_REPEAT_MODE_OFF);
|
||||
break;
|
||||
case 'z':
|
||||
printf(" - shuffle all tracks\n");
|
||||
avrcp_set_shuffle_mode(avrcp_con_handle, AVRCP_SHUFFLE_MODE_ALL_TRACKS);
|
||||
avrcp_set_shuffle_mode(avrcp_cid, AVRCP_SHUFFLE_MODE_ALL_TRACKS);
|
||||
break;
|
||||
case 'Z':
|
||||
printf(" - disable shuffle mode\n");
|
||||
avrcp_set_shuffle_mode(avrcp_con_handle, AVRCP_SHUFFLE_MODE_OFF);
|
||||
avrcp_set_shuffle_mode(avrcp_cid, AVRCP_SHUFFLE_MODE_OFF);
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
@ -337,7 +343,6 @@ int btstack_main(int argc, const char * argv[]);
|
||||
int btstack_main(int argc, const char * argv[]){
|
||||
UNUSED(argc);
|
||||
(void)argv;
|
||||
avrcp_con_handle = 0;
|
||||
/* Register for HCI events */
|
||||
hci_event_callback_registration.callback = &packet_handler;
|
||||
hci_add_event_handler(&hci_event_callback_registration);
|
||||
|
Loading…
x
Reference in New Issue
Block a user