Skip to content

Commit 6177115

Browse files
committed
Merge branch 'fear/add_avrcp_init_state_event' into 'master'
feat(bt/bluedroid): Add events to indicate the initialization states of AVRCP Closes CBI-1400 and BTQABR2023-507 See merge request espressif/esp-idf!39278
2 parents 4ffb3fb + a8ed013 commit 6177115

File tree

4 files changed

+168
-78
lines changed

4 files changed

+168
-78
lines changed

components/bt/host/bluedroid/api/include/api/esp_avrc_api.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ typedef enum {
145145
ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT = 7, /*!< set absolute volume response event */
146146
ESP_AVRC_CT_COVER_ART_STATE_EVT = 8, /*!< cover art client connection state changed event */
147147
ESP_AVRC_CT_COVER_ART_DATA_EVT = 9, /*!< cover art client data event */
148+
ESP_AVRC_CT_PROF_STATE_EVT = 10, /*!< Indicate AVRCP controller init or deinit complete */
148149
} esp_avrc_ct_cb_event_t;
149150

150151
/// AVRC Target callback events
@@ -155,6 +156,7 @@ typedef enum {
155156
ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT = 3, /*!< set absolute volume command from remote device */
156157
ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT = 4, /*!< register notification event */
157158
ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT = 5, /*!< set application attribute value, attribute refer to esp_avrc_ps_attr_ids_t */
159+
ESP_AVRC_TG_PROF_STATE_EVT = 6, /*!< Indicate AVRCP target init or deinit complete */
158160
} esp_avrc_tg_cb_event_t;
159161

160162
/// AVRC metadata attribute mask
@@ -303,6 +305,18 @@ typedef struct {
303305
uint8_t ct_cover_art_conn_num; /*!< Number of cover art client connections */
304306
} esp_avrc_profile_status_t;
305307

308+
/**
309+
* @brief Bluetooth AVRCP Initiation states
310+
*/
311+
typedef enum {
312+
ESP_AVRC_INIT_SUCCESS = 0, /*!< Indicate init successful */
313+
ESP_AVRC_INIT_ALREADY, /*!< Indicate init repeated */
314+
ESP_AVRC_INIT_FAIL, /*!< Indicate init fail */
315+
ESP_AVRC_DEINIT_SUCCESS, /*!< Indicate deinit successful */
316+
ESP_AVRC_DEINIT_ALREADY, /*!< Indicate deinit repeated */
317+
ESP_AVRC_DEINIT_FAIL, /*!< Indicate deinit fail */
318+
} esp_avrc_init_state_t;
319+
306320
/// AVRC controller callback parameters
307321
typedef union {
308322
/**
@@ -390,6 +404,14 @@ typedef union {
390404
uint16_t data_len; /*!< the data length of this data event, in bytes */
391405
uint8_t *p_data; /*!< pointer to data, should copy to other buff before event callback return */
392406
} cover_art_data; /*!< AVRC Cover Art data event */
407+
408+
/**
409+
* @brief ESP_AVRC_CT_PROF_STATE_EVT
410+
*/
411+
struct avrc_ct_init_stat_param {
412+
esp_avrc_init_state_t state; /*!< avrc ct initialization param */
413+
} avrc_ct_init_stat; /*!< status to indicate avrcp ct init or deinit */
414+
393415
} esp_avrc_ct_cb_param_t;
394416

395417
/// AVRC target callback parameters
@@ -442,6 +464,13 @@ typedef union {
442464
esp_avrc_set_app_value_param_t *p_vals; /*!< point to the id and value of player application attribute */
443465
} set_app_value; /*!< set player application value */
444466

467+
/**
468+
* @brief ESP_AVRC_TG_PROF_STATE_EVT
469+
*/
470+
struct avrc_tg_init_stat_param {
471+
esp_avrc_init_state_t state; /*!< avrc tg initialization param */
472+
} avrc_tg_init_stat; /*!< status to indicate avrcp tg init or deinit */
473+
445474
} esp_avrc_tg_cb_param_t;
446475

447476
/**
@@ -482,6 +511,7 @@ esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
482511
* @brief Initialize the bluetooth AVRCP controller module, This function should be called
483512
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
484513
* AVRC should be used along with A2DP and AVRC should be initialized before A2DP.
514+
* ESP_AVRC_CT_PROF_STATE_EVT with ESP_AVRC_INIT_SUCCESS will reported to the APP layer.
485515
*
486516
* @return
487517
* - ESP_OK: success
@@ -496,6 +526,7 @@ esp_err_t esp_avrc_ct_init(void);
496526
* @brief De-initialize AVRCP controller module. This function should be called after
497527
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
498528
* AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP.
529+
* ESP_AVRC_CT_PROF_STATE_EVT with ESP_AVRC_DEINIT_SUCCESS will reported to the APP layer.
499530
*
500531
* @return
501532
* - ESP_OK: success
@@ -636,6 +667,7 @@ esp_err_t esp_avrc_tg_register_callback(esp_avrc_tg_cb_t callback);
636667
* @brief Initialize the bluetooth AVRCP target module, This function should be called
637668
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
638669
* AVRC should be used along with A2DP and AVRC should be initialized before A2DP.
670+
* ESP_AVRC_TG_PROF_STATE_EVT with ESP_AVRC_INIT_SUCCESS will reported to the APP layer.
639671
*
640672
* @return
641673
* - ESP_OK: success
@@ -650,6 +682,7 @@ esp_err_t esp_avrc_tg_init(void);
650682
* @brief De-initialize AVRCP target module. This function should be called after
651683
* after esp_bluedroid_enable() completes successfully. Note: AVRC cannot work independently,
652684
* AVRC should be used along with A2DP and AVRC should be deinitialized before A2DP.
685+
* ESP_AVRC_TG_PROF_STATE_EVT with ESP_AVRC_DEINIT_SUCCESS will reported to the APP layer.
653686
*
654687
* @return
655688
* - ESP_OK: success

components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c

Lines changed: 107 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,6 @@ static bool btc_avrc_tg_set_rn_supported_evt(uint16_t evt_set)
303303

304304
static inline void btc_avrc_ct_cb_to_app(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param)
305305
{
306-
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
307-
return;
308-
}
309-
310306
esp_avrc_ct_cb_t btc_avrc_ct_cb = (esp_avrc_ct_cb_t)btc_profile_cb_get(BTC_PID_AVRC_CT);
311307
if (btc_avrc_ct_cb) {
312308
btc_avrc_ct_cb(event, param);
@@ -315,10 +311,6 @@ static inline void btc_avrc_ct_cb_to_app(esp_avrc_ct_cb_event_t event, esp_avrc_
315311

316312
static inline void btc_avrc_tg_cb_to_app(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param)
317313
{
318-
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
319-
return;
320-
}
321-
322314
esp_avrc_tg_cb_t btc_avrc_tg_cb = (esp_avrc_tg_cb_t)btc_profile_cb_get(BTC_PID_AVRC_TG);
323315
if (btc_avrc_tg_cb) {
324316
btc_avrc_tg_cb(event, param);
@@ -1108,27 +1100,39 @@ BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr)
11081100
*******************************************************************************/
11091101
static void btc_avrc_ct_init(void)
11101102
{
1111-
BTC_TRACE_DEBUG("## %s ##", __FUNCTION__);
1112-
if (s_rc_ct_init == BTC_RC_CT_INIT_MAGIC) {
1113-
BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
1114-
return;
1115-
}
1103+
esp_avrc_init_state_t state = ESP_AVRC_INIT_SUCCESS;
11161104

1117-
/// initialize CT-specific resources
1118-
s_rc_ct_init = BTC_RC_CT_INIT_MAGIC;
1105+
BTC_TRACE_DEBUG("## %s ##", __FUNCTION__);
11191106

1120-
/// initialize CT-TG shared resources
1121-
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
1122-
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
1107+
do {
11231108

1124-
if (!g_av_with_rc) {
1125-
g_av_with_rc = true;
1109+
if (s_rc_ct_init == BTC_RC_CT_INIT_MAGIC) {
1110+
BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
1111+
state = ESP_AVRC_INIT_ALREADY;
1112+
break;
11261113
}
11271114

1128-
if (g_a2dp_on_init) {
1129-
BTC_TRACE_WARNING("AVRC Controller is expected to be initialized in advance of A2DP !!!");
1115+
/// initialize CT-TG shared resources
1116+
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
1117+
if (g_a2dp_on_init) {
1118+
BTC_TRACE_WARNING("AVRC Controller is expected to be initialized in advance of A2DP !!!");
1119+
state = ESP_AVRC_INIT_FAIL;
1120+
break;
1121+
}
1122+
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
1123+
1124+
if (!g_av_with_rc) {
1125+
g_av_with_rc = true;
1126+
}
11301127
}
1131-
}
1128+
1129+
/// initialize CT-specific resources
1130+
s_rc_ct_init = BTC_RC_CT_INIT_MAGIC;
1131+
} while (0);
1132+
1133+
esp_avrc_ct_cb_param_t param = {0};
1134+
param.avrc_ct_init_stat.state = state;
1135+
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_PROF_STATE_EVT, &param);
11321136
}
11331137

11341138

@@ -1143,29 +1147,37 @@ static void btc_avrc_ct_init(void)
11431147
***************************************************************************/
11441148
static void btc_avrc_ct_deinit(void)
11451149
{
1150+
esp_avrc_init_state_t state = ESP_AVRC_DEINIT_SUCCESS;
1151+
11461152
BTC_TRACE_API("## %s ##", __FUNCTION__);
11471153

1148-
if (g_a2dp_on_deinit) {
1149-
BTC_TRACE_WARNING("A2DP already deinit, AVRC CT should deinit in advance of A2DP !!!");
1150-
}
1154+
do {
1155+
if (g_a2dp_on_deinit) {
1156+
BTC_TRACE_WARNING("A2DP already deinit, AVRC CT should deinit in advance of A2DP !!!");
1157+
}
11511158

1152-
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
1153-
BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
1154-
return;
1155-
}
1159+
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
1160+
BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
1161+
state = ESP_AVRC_DEINIT_ALREADY;
1162+
break;
1163+
}
11561164

1157-
/// deinit CT-specific resources
1158-
s_rc_ct_init = 0;
1165+
/// deinit CT-specific resources
1166+
s_rc_ct_init = 0;
11591167

1160-
/// deinit CT-TG shared resources
1161-
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
1162-
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
1163-
if (g_av_with_rc) {
1164-
g_av_with_rc = false;
1168+
/// deinit CT-TG shared resources
1169+
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
1170+
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb_t));
1171+
if (g_av_with_rc) {
1172+
g_av_with_rc = false;
1173+
}
11651174
}
1166-
}
1175+
BTC_TRACE_API("## %s ## completed", __FUNCTION__);
1176+
} while (0);
11671177

1168-
BTC_TRACE_API("## %s ## completed", __FUNCTION__);
1178+
esp_avrc_ct_cb_param_t param = {0};
1179+
param.avrc_ct_init_stat.state = state;
1180+
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_PROF_STATE_EVT, &param);
11691181
}
11701182

11711183
static bt_status_t btc_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id)
@@ -1474,30 +1486,42 @@ static void btc_avrc_ct_cover_art_get_linked_thumbnail(UINT8 *image_handle)
14741486
*******************************************************************************/
14751487
static void btc_avrc_tg_init(void)
14761488
{
1489+
esp_avrc_init_state_t state = ESP_AVRC_INIT_SUCCESS;
1490+
14771491
BTC_TRACE_DEBUG("## %s ##", __FUNCTION__);
1478-
if (s_rc_tg_init == BTC_RC_TG_INIT_MAGIC) {
1479-
BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
1480-
return;
1481-
}
14821492

1483-
/// initialize TG-specific resources
1484-
memcpy(s_psth_supported_cmd, cs_psth_dft_supported_cmd, sizeof(s_psth_supported_cmd));
1485-
s_rn_supported_evt = cs_rn_dft_supported_evt;
1493+
do {
1494+
if (s_rc_tg_init == BTC_RC_TG_INIT_MAGIC) {
1495+
BTC_TRACE_WARNING("%s already initialized", __FUNCTION__);
1496+
state = ESP_AVRC_INIT_ALREADY;
1497+
break;
1498+
}
1499+
1500+
/// initialize CT-TG shared resources
1501+
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
1502+
if (g_a2dp_on_init) {
1503+
BTC_TRACE_WARNING("AVRC Target is expected to be initialized in advance of A2DP !!!");
1504+
state = ESP_AVRC_INIT_FAIL;
1505+
break;
1506+
}
14861507

1487-
/// initialize CT-TG shared resources
1488-
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
1489-
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
1508+
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
14901509

1491-
if (!g_av_with_rc) {
1492-
g_av_with_rc = true;
1510+
if (!g_av_with_rc) {
1511+
g_av_with_rc = true;
1512+
}
14931513
}
14941514

1495-
if (g_a2dp_on_init) {
1496-
BTC_TRACE_WARNING("AVRC Target is expected to be initialized in advance of A2DP !!!");
1497-
}
1498-
}
1515+
/// initialize TG-specific resources
1516+
memcpy(s_psth_supported_cmd, cs_psth_dft_supported_cmd, sizeof(s_psth_supported_cmd));
1517+
s_rn_supported_evt = cs_rn_dft_supported_evt;
14991518

1500-
s_rc_tg_init = BTC_RC_TG_INIT_MAGIC;
1519+
s_rc_tg_init = BTC_RC_TG_INIT_MAGIC;
1520+
} while (0);
1521+
1522+
esp_avrc_tg_cb_param_t param = {0};
1523+
param.avrc_tg_init_stat.state = state;
1524+
btc_avrc_tg_cb_to_app(ESP_AVRC_TG_PROF_STATE_EVT, &param);
15011525
}
15021526

15031527

@@ -1512,31 +1536,40 @@ static void btc_avrc_tg_init(void)
15121536
***************************************************************************/
15131537
static void btc_avrc_tg_deinit(void)
15141538
{
1539+
esp_avrc_init_state_t state = ESP_AVRC_DEINIT_SUCCESS;
1540+
15151541
BTC_TRACE_API("## %s ##", __FUNCTION__);
15161542

1517-
if (g_a2dp_on_deinit) {
1518-
BTC_TRACE_WARNING("A2DP already deinit, AVRC TG should deinit in advance of A2DP !!!");
1519-
}
1543+
do {
1544+
if (g_a2dp_on_deinit) {
1545+
BTC_TRACE_WARNING("A2DP already deinit, AVRC TG should deinit in advance of A2DP !!!");
1546+
}
15201547

1521-
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
1522-
BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
1523-
return;
1524-
}
1548+
if (s_rc_tg_init != BTC_RC_TG_INIT_MAGIC) {
1549+
BTC_TRACE_WARNING("%s not initialized", __FUNCTION__);
1550+
state = ESP_AVRC_DEINIT_ALREADY;
1551+
break;
1552+
}
15251553

1526-
/// deinit TG-specific resources
1527-
memset(s_psth_supported_cmd, 0, sizeof(s_psth_supported_cmd));
1528-
s_rn_supported_evt = 0;
1529-
s_rc_tg_init = 0;
1554+
/// deinit TG-specific resources
1555+
memset(s_psth_supported_cmd, 0, sizeof(s_psth_supported_cmd));
1556+
s_rn_supported_evt = 0;
1557+
s_rc_tg_init = 0;
15301558

1531-
/// deinit CT-TG shared resources
1532-
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
1533-
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
1534-
if (g_av_with_rc) {
1535-
g_av_with_rc = false;
1559+
/// deinit CT-TG shared resources
1560+
if (s_rc_ct_init != BTC_RC_CT_INIT_MAGIC) {
1561+
memset (&btc_rc_cb, 0, sizeof(btc_rc_cb));
1562+
if (g_av_with_rc) {
1563+
g_av_with_rc = false;
1564+
}
15361565
}
1537-
}
15381566

1539-
BTC_TRACE_API("## %s ## completed", __FUNCTION__);
1567+
BTC_TRACE_API("## %s ## completed", __FUNCTION__);
1568+
} while (0);
1569+
1570+
esp_avrc_tg_cb_param_t param = {0};
1571+
param.avrc_tg_init_stat.state = state;
1572+
btc_avrc_tg_cb_to_app(ESP_AVRC_TG_PROF_STATE_EVT, &param);
15401573
}
15411574

15421575
static void btc_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_rsp_t rsp, const esp_avrc_rn_param_t *param)

examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/bt_app_av.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,17 @@ static void bt_av_hdl_avrc_ct_evt(uint16_t event, void *p_param)
532532
#endif
533533
break;
534534
}
535+
/* when avrcp controller init or deinit completed, this event comes */
536+
case ESP_AVRC_CT_PROF_STATE_EVT: {
537+
if (ESP_AVRC_INIT_SUCCESS == rc->avrc_ct_init_stat.state) {
538+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Init Complete");
539+
} else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_ct_init_stat.state) {
540+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP CT STATE: Deinit Complete");
541+
} else {
542+
ESP_LOGE(BT_RC_CT_TAG, "AVRCP CT STATE error: %d", rc->avrc_ct_init_stat.state);
543+
}
544+
break;
545+
}
535546
/* others */
536547
default:
537548
ESP_LOGE(BT_RC_CT_TAG, "%s unhandled event: %d", __func__, event);
@@ -587,6 +598,17 @@ static void bt_av_hdl_avrc_tg_evt(uint16_t event, void *p_param)
587598
ESP_LOGI(BT_RC_TG_TAG, "AVRC remote features: %"PRIx32", CT features: %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag);
588599
break;
589600
}
601+
/* when avrcp target init or deinit completed, this event comes */
602+
case ESP_AVRC_TG_PROF_STATE_EVT: {
603+
if (ESP_AVRC_INIT_SUCCESS == rc->avrc_tg_init_stat.state) {
604+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP TG STATE: Init Complete");
605+
} else if (ESP_AVRC_DEINIT_SUCCESS == rc->avrc_tg_init_stat.state) {
606+
ESP_LOGI(BT_RC_CT_TAG, "AVRCP TG STATE: Deinit Complete");
607+
} else {
608+
ESP_LOGE(BT_RC_CT_TAG, "AVRCP TG STATE error: %d", rc->avrc_tg_init_stat.state);
609+
}
610+
break;
611+
}
590612
/* others */
591613
default:
592614
ESP_LOGE(BT_RC_TG_TAG, "%s unhandled event: %d", __func__, event);
@@ -665,7 +687,8 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param
665687
case ESP_AVRC_CT_REMOTE_FEATURES_EVT:
666688
case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT:
667689
case ESP_AVRC_CT_COVER_ART_STATE_EVT:
668-
case ESP_AVRC_CT_COVER_ART_DATA_EVT: {
690+
case ESP_AVRC_CT_COVER_ART_DATA_EVT:
691+
case ESP_AVRC_CT_PROF_STATE_EVT: {
669692
bt_app_work_dispatch(bt_av_hdl_avrc_ct_evt, event, param, sizeof(esp_avrc_ct_cb_param_t), NULL);
670693
break;
671694
}
@@ -684,6 +707,7 @@ void bt_app_rc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param
684707
case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT:
685708
case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT:
686709
case ESP_AVRC_TG_SET_PLAYER_APP_VALUE_EVT:
710+
case ESP_AVRC_TG_PROF_STATE_EVT:
687711
bt_app_work_dispatch(bt_av_hdl_avrc_tg_evt, event, param, sizeof(esp_avrc_tg_cb_param_t), NULL);
688712
break;
689713
default:

0 commit comments

Comments
 (0)