525 lines
21 KiB
C++
525 lines
21 KiB
C++
/*----------------------------------------------------------------------------
|
||
* Copyright (c) TJD Technologies Co., Ltd. 2025. All rights reserved.
|
||
*
|
||
* Description: TjdUiBTHeadsetEvent.cpp
|
||
*
|
||
* Author: luziquan@ss-tjd.com
|
||
*
|
||
* Create: 2025-04-09
|
||
*--------------------------------------------------------------------------*/
|
||
|
||
#include "TjdUiAppPlayerModel.h"
|
||
#include "TjdUiAppPlayerView.h"
|
||
#include "audio_manager.h"
|
||
#include "bt_audio.h"
|
||
#include "bts_avrcp_controller.h"
|
||
#include "bts_avrcp_target.h"
|
||
#include "bts_br_gap.h"
|
||
#include "bts_def.h"
|
||
#include "graphic_service.h"
|
||
#include "sys_config.h"
|
||
#include "td_type.h"
|
||
|
||
using namespace OHOS;
|
||
using namespace ::Audio;
|
||
|
||
namespace TJD {
|
||
|
||
#define ENABLE_PRINT_INFO 1
|
||
#define ENABLE_DEBUG 1
|
||
#if ENABLE_PRINT_INFO
|
||
#define static_print_info(...) sys_ui_log_i(__VA_ARGS__) // 一般信息打印宏控制
|
||
#define static_print_warn(...) sys_ui_log_w(__VA_ARGS__) // 警告信息打印一般常开
|
||
#define static_print_error(...) sys_ui_log_e(__VA_ARGS__) // 错误信息打印一般常开
|
||
#if ENABLE_DEBUG
|
||
#define static_print_debug(...) sys_ui_log_d(__VA_ARGS__) // 调试信息打印一般常开
|
||
#else
|
||
#define static_print_debug(...)
|
||
#endif
|
||
#else
|
||
#define static_print_info(...)
|
||
#define static_print_warn(...)
|
||
#define static_print_error(...)
|
||
#endif
|
||
|
||
static void UsingPressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue);
|
||
static void MediaStatusCallback(bt_avrcp_tg_evt_status_param *eventStatusParam);
|
||
static void PressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue);
|
||
static void ConnCtStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t state);
|
||
static void ConnectTgStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t state);
|
||
|
||
enum AVRCP_SRV_STATE
|
||
{
|
||
AVRCP_SRV_PRESS_VALUE,
|
||
AVRCP_SRV_RELEASED_VALUE,
|
||
AVRCP_SRV_INIT_VALUE
|
||
};
|
||
|
||
#define AVRCP_CT_AUTO_REG_TYPE 1
|
||
static uint8_t g_avrcp_tg_local_media_vol = AVRCP_ABSOLUTE_VOLUME_INVALID;
|
||
#define BT_A2DP_MEDIA_VOL_LEVEL 100
|
||
|
||
static bt_avrcp_tg_bts_cbk g_avrcp_tg_audio_cb = {};
|
||
static avrcp_ct_callbacks_t g_avrcp_ct_cb = {};
|
||
static avrcp_tg_callbacks_t g_avrcp_tg_cb = {};
|
||
static BtAvrcpTgInf g_avrcp_srv_inf;
|
||
|
||
BtAvrcpTgInf *GetAvrcpTgInf(void)
|
||
{
|
||
return &g_avrcp_srv_inf;
|
||
}
|
||
|
||
void BtAvrcpVolumeChangedSyncMedia(uint8_t a2dp_volume)
|
||
{
|
||
static_print_info("[BtAvrcpVolumeChangedSyncMedia]::a2dp_volume = 0x%x", a2dp_volume);
|
||
int32_t audio_volume = a2dp_volume * BT_A2DP_MEDIA_VOL_LEVEL / AVRCP_ABSOLUTE_VOLUME_PERCENTAGE_100;
|
||
AudioManager::GetInstance().SetVolume(AUDIO_STREAM_A2DP_MUSIC, audio_volume); /* 设置增益音量 */
|
||
g_avrcp_tg_local_media_vol = a2dp_volume;
|
||
avrcp_tg_notify_volume_changed(a2dp_volume);
|
||
TjdUiAppPlayerView *view = TjdUiAppPlayerView::GetInstance();
|
||
if (view != nullptr) {
|
||
if (view->GetCurrentView() == PlayerViewIndex::VOLUME_VIEW) {
|
||
view->ChangedVolume(audio_volume);
|
||
}
|
||
}
|
||
}
|
||
|
||
/* tg通知媒体状态 */
|
||
static void BtAvrcpTgNotifyMeidaStatus(bt_avrcp_tg_evt_status_param *notifyEventStatusParam)
|
||
{
|
||
if (notifyEventStatusParam == nullptr || notifyEventStatusParam->event_id >= AVRCP_NOTIFY_EVENT_RESERVED) {
|
||
static_print_error("[BtAvrcpTgNotifyMeidaStatus] param is error");
|
||
return;
|
||
}
|
||
switch (notifyEventStatusParam->event_id) {
|
||
case AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED:
|
||
avrcp_tg_notify_playback_status_changed(*(td_u8 *)notifyEventStatusParam->event_status);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_TRACK_CHANGED:
|
||
avrcp_tg_notify_track_changed(*(unsigned long long *)notifyEventStatusParam->event_status);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_TRACK_REACHED_END:
|
||
avrcp_tg_notify_track_reached_end();
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_TRACK_REACHED_START:
|
||
avrcp_tg_notify_track_reached_start();
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_PLAYBACK_POS_CHANGED:
|
||
avrcp_tg_notify_playback_pos_changed(*(td_u32 *)notifyEventStatusParam->event_status);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_BATT_STATUS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_SYSTEM_STATUS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_NOW_PLAYING_CONTENT_CHANGED:
|
||
avrcp_tg_notify_now_playing_content_changed();
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_AVAILABLE_PLAYERS_CHANGED:
|
||
avrcp_tg_notify_available_players_changed();
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_ADDRESSED_PLAYER_CHANGED:
|
||
avrcp_tg_notify_addressed_players_changed(*(td_u16 *)notifyEventStatusParam->event_status,
|
||
*(td_u16 *)(notifyEventStatusParam->event_status + sizeof(td_u16)));
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_UIDS_CHANGED:
|
||
avrcp_tg_notify_uid_changed(*(td_u16 *)notifyEventStatusParam->event_status);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_VOLUME_CHANGED:
|
||
BtAvrcpVolumeChangedSyncMedia(notifyEventStatusParam->event_status[0]);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_RESERVED:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void PressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue)
|
||
{
|
||
static_print_debug("[PressButtonStatusCallback]::keyValue = 0x%x keyOperation = 0x%x", keyValue, keyOperation);
|
||
GraphicService::GetInstance()->PostGraphicEvent(std::bind(UsingPressButtonStatusCallback, keyOperation, keyValue));
|
||
}
|
||
|
||
void BtAvrcpTgNotifyVolumeChangedProc(uint8_t a2dp_volume)
|
||
{
|
||
int32_t audio_volume = a2dp_volume * BT_A2DP_MEDIA_VOL_LEVEL / AVRCP_ABSOLUTE_VOLUME_PERCENTAGE_100;
|
||
static_print_info("NotifyVolume = %d", audio_volume);
|
||
AudioManager::GetInstance().SetVolume(AUDIO_STREAM_MUSIC, audio_volume); // 耳机连接手表场景调节手表音量
|
||
}
|
||
|
||
void UsingPressButtonStatusCallback(td_u32 keyOperation, td_u32 keyValue)
|
||
{
|
||
bt_avrcp_tg_evt_status_param event;
|
||
switch (keyOperation) {
|
||
case AVRCP_KEY_VOLUME_UP: // 耳机控制手表加减音量不走key_operation事件
|
||
case AVRCP_KEY_VOLUME_DOWN: // 减小音量
|
||
break;
|
||
case AVRCP_KEY_MUTE: // 静音
|
||
event.event_status[0] = AVRCP_ABSOLUTE_VOLUME_PERCENTAGE_0;
|
||
event.event_id = AVRCP_NOTIFY_EVENT_VOLUME_CHANGED;
|
||
break;
|
||
case AVRCP_KEY_PLAY: // 播放
|
||
// (void)TjdUiAppPlayerModel::GetInstance()->PlayerPlay();
|
||
event.event_status[0] = AVRCP_PLAY_STATUS_PLAYING;
|
||
event.event_id = AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED;
|
||
break;
|
||
case AVRCP_KEY_STOP: // 停止
|
||
// (void)TjdUiAppPlayerModel::GetInstance()->PlayerStop();
|
||
event.event_status[0] = AVRCP_PLAY_STATUS_STOPPED;
|
||
event.event_id = AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED;
|
||
break;
|
||
case AVRCP_KEY_PAUSE: // 暂停
|
||
// (void)TjdUiAppPlayerModel::GetInstance()->PlayerPause();
|
||
event.event_status[0] = AVRCP_PLAY_STATUS_PAUSED;
|
||
event.event_id = AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED;
|
||
break;
|
||
case AVRCP_KEY_FORWARD: // 下一曲
|
||
// TjdUiAppPlayerModel::GetInstance()->LoopingPlayout();
|
||
event.event_status[0] = AVRCP_PLAY_STATUS_FWD_SEEK;
|
||
event.event_id = AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED;
|
||
break;
|
||
case AVRCP_KEY_BACKWARD: // 上一曲
|
||
// TjdUiAppPlayerModel::GetInstance()->PreviousPlayout();
|
||
event.event_status[0] = AVRCP_PLAY_STATUS_REV_SEEK;
|
||
event.event_id = AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED;
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_VOLUME_CHANGED:
|
||
/* 手机连接手表场景,控制手表喇叭声音 */
|
||
event.event_status[0] = keyValue;
|
||
event.event_id = AVRCP_NOTIFY_EVENT_VOLUME_CHANGED;
|
||
BtAvrcpTgNotifyVolumeChangedProc((uint8_t)keyValue);
|
||
default:
|
||
break;
|
||
}
|
||
|
||
BtAvrcpTgNotifyMeidaStatus(&event);
|
||
}
|
||
|
||
uint8_t BtAvrcpTgGetLocMediaVolume(void)
|
||
{
|
||
if (g_avrcp_tg_local_media_vol == AVRCP_ABSOLUTE_VOLUME_INVALID) {
|
||
int32_t audio_volume = AudioManager::GetInstance().GetVolume(AUDIO_STREAM_A2DP_MUSIC);
|
||
uint8_t a2dp_volume = (uint8_t)(audio_volume * AVRCP_ABSOLUTE_VOLUME_PERCENTAGE_100 / BT_A2DP_MEDIA_VOL_LEVEL);
|
||
static_print_info("audio_volume 0x%x, a2dp_volume 0x%x", audio_volume, a2dp_volume);
|
||
g_avrcp_tg_local_media_vol = a2dp_volume;
|
||
}
|
||
|
||
static_print_info("get local media volume, a2dp_volume = 0x%x", g_avrcp_tg_local_media_vol);
|
||
return g_avrcp_tg_local_media_vol;
|
||
}
|
||
|
||
void MediaStatusCallback(bt_avrcp_tg_evt_status_param *eventStatusParam)
|
||
{
|
||
if (eventStatusParam == nullptr) {
|
||
static_print_error("eventStatusParam is nullptr");
|
||
return;
|
||
}
|
||
|
||
int32_t playerStatus = TjdUiAppPlayerModel::GetInstance()->GetPlayerStatus();
|
||
static_print_debug("playerStatus = %d", playerStatus);
|
||
|
||
switch (eventStatusParam->event_id) {
|
||
case AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED:
|
||
eventStatusParam->event_status[0] = playerStatus;
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_TRACK_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_TRACK_REACHED_END:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_TRACK_REACHED_START:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_PLAYBACK_POS_CHANGED:
|
||
eventStatusParam->event_status[0] = 0xFF;
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_BATT_STATUS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_SYSTEM_STATUS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_NOW_PLAYING_CONTENT_CHANGED:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_AVAILABLE_PLAYERS_CHANGED:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_ADDRESSED_PLAYER_CHANGED:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_UIDS_CHANGED:
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_VOLUME_CHANGED:
|
||
eventStatusParam->event_status[0] = BtAvrcpTgGetLocMediaVolume();
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_RESERVED:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void ConnCtStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t state)
|
||
{
|
||
static_print_debug("avrcp ct update conn stat:%u", state);
|
||
if (bdAddr == nullptr) {
|
||
static_print_error("bdaddr nullptr");
|
||
return;
|
||
}
|
||
static_print_debug("ConnCtStateChangedCallback addr: %02x%02x%02x%02x%02x%02x ", bdAddr->addr[5], bdAddr->addr[4],
|
||
bdAddr->addr[3], /* 5 4 3 idx */
|
||
bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* 2 1 0 idx */
|
||
(void)memcpy_s(g_avrcp_srv_inf.bd_addr.addr, BD_ADDR_LEN, bdAddr->addr, BD_ADDR_LEN);
|
||
g_avrcp_srv_inf.avrcp_srv_conn_stat = state;
|
||
}
|
||
|
||
static bd_addr_t *BtAvrcpSrvGetActiveAddr(void) { return &g_avrcp_srv_inf.bd_addr; }
|
||
|
||
void ConnectTgStateChangedCallback(const bd_addr_t *bdAddr, profile_connect_state_t state)
|
||
{
|
||
static_print_info("avrcp tg update conn stat:%u", state);
|
||
if (bdAddr == nullptr) {
|
||
static_print_error("bdaddr nullptr");
|
||
return;
|
||
}
|
||
|
||
static_print_debug("ConnCtStateChangedCallback addr: %02x%02x%02x%02x%02x%02x ", bdAddr->addr[5], bdAddr->addr[4],
|
||
bdAddr->addr[3], /* 5 4 3 idx */
|
||
bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* 2 1 0 idx */
|
||
(void)memcpy_s(g_avrcp_srv_inf.bd_addr.addr, BD_ADDR_LEN, bdAddr->addr, BD_ADDR_LEN);
|
||
g_avrcp_srv_inf.avrcp_srv_conn_stat = state;
|
||
|
||
/* 手表耳机链接场景时,耳机控制音量是一个事件而非key_operation,故需要在手表侧向耳机注册音量变更事件 */
|
||
if (state == PROFILE_STATE_CONNECTED) {
|
||
(void)avrcp_ct_get_supported_events(BtAvrcpSrvGetActiveAddr());
|
||
}
|
||
}
|
||
|
||
static void BtAvrcpCtPressButtonRspCallback(const bd_addr_t *bd_addr, int32_t key_operation)
|
||
{
|
||
if (bd_addr == nullptr) {
|
||
static_print_error("null pointer");
|
||
return;
|
||
}
|
||
if (g_avrcp_srv_inf.avrcp_button_flag == AVRCP_SRV_RELEASED_VALUE) {
|
||
static_print_debug("avrcp ct press button button_flag change:%u->%u", g_avrcp_srv_inf.avrcp_button_flag,
|
||
AVRCP_SRV_PRESS_VALUE);
|
||
g_avrcp_srv_inf.avrcp_button_flag = AVRCP_SRV_PRESS_VALUE;
|
||
}
|
||
static_print_debug("avrcp ct press button cbk key:%d button_flag:%u", key_operation,
|
||
g_avrcp_srv_inf.avrcp_button_flag);
|
||
}
|
||
|
||
static void BtAvrcpPressReleaseButtonLog(uint32_t key_operation)
|
||
{
|
||
switch (key_operation) {
|
||
case AVRCP_KEY_VOLUME_UP:
|
||
static_print_debug("AVRCP_KEY_VOLUME_UP");
|
||
break;
|
||
case AVRCP_KEY_VOLUME_DOWN:
|
||
static_print_debug("AVRCP_KEY_VOLUME_DOWN");
|
||
break;
|
||
case AVRCP_KEY_MUTE:
|
||
static_print_debug("AVRCP_KEY_VOLUME_MUTE");
|
||
break;
|
||
case AVRCP_KEY_PLAY:
|
||
static_print_debug("AVRCP_KEY_PLAY");
|
||
break;
|
||
case AVRCP_KEY_STOP:
|
||
static_print_debug("AVRCP_KEY_STOP");
|
||
break;
|
||
case AVRCP_KEY_PAUSE:
|
||
static_print_debug("AVRCP_KEY_PAUSE");
|
||
break;
|
||
case AVRCP_KEY_FORWARD:
|
||
static_print_debug("AVRCP_KEY_FORWARD");
|
||
break;
|
||
case AVRCP_KEY_BACKWARD:
|
||
static_print_debug("AVRCP_KEY_BACKWARD");
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_VOLUME_CHANGED:
|
||
static_print_debug("AVRCP_EVENT_VOLUME_CHANGED");
|
||
break;
|
||
default:
|
||
static_print_debug("invalid");
|
||
break;
|
||
}
|
||
}
|
||
|
||
static void BtAvrcpCtReleaseButtonRspCallback(const bd_addr_t *bd_addr, int32_t key_operation)
|
||
{
|
||
UNUSED(bd_addr);
|
||
static_print_debug("avrcp ct release button cbk key:%d", key_operation);
|
||
if (g_avrcp_srv_inf.avrcp_button_flag == AVRCP_SRV_PRESS_VALUE) {
|
||
static_print_debug("avrcp ct released button button_flag change:%u->%u", g_avrcp_srv_inf.avrcp_button_flag,
|
||
AVRCP_SRV_RELEASED_VALUE);
|
||
g_avrcp_srv_inf.avrcp_button_flag = AVRCP_SRV_RELEASED_VALUE;
|
||
}
|
||
BtAvrcpPressReleaseButtonLog((uint32_t)key_operation);
|
||
}
|
||
|
||
static void BtAvrcpCtSupportCompanyCallback(const bd_addr_t *bd_addr, avrcp_ct_support_company_para_t *company)
|
||
{
|
||
if (bd_addr == nullptr || company == nullptr || company->company_id == nullptr) {
|
||
static_print_error("null pointer");
|
||
return;
|
||
}
|
||
static_print_debug("get company list:");
|
||
for (uint8_t i = 0; i < company->company_num; i++) {
|
||
static_print_debug(" 0x%x ", *company->company_id);
|
||
}
|
||
}
|
||
|
||
static void BtAvrcpCtSupportEventCallback(const bd_addr_t *bd_addr, avrcp_ct_support_event_para_t *event)
|
||
{
|
||
if (bd_addr == nullptr || event == nullptr || event->event_id == nullptr) {
|
||
static_print_debug("null pointer");
|
||
return;
|
||
}
|
||
|
||
for (uint8_t i = 0; i < event->event_num; i++) {
|
||
if (event->event_id[i] == AVRCP_NOTIFY_EVENT_VOLUME_CHANGED) {
|
||
int ret = avrcp_ct_register_notification(bd_addr, event->event_id[i], 0);
|
||
static_print_info("register event_id: 0x%x, ret = 0x%x", event->event_id[i], ret);
|
||
}
|
||
}
|
||
|
||
for (uint8_t i = 0; i < event->event_num; i++) {
|
||
if (event->event_id[i] != AVRCP_NOTIFY_EVENT_VOLUME_CHANGED) {
|
||
int ret = avrcp_ct_register_notification(bd_addr, event->event_id[i], 0);
|
||
static_print_info("register event_id: 0x%x, ret = 0x%x", event->event_id[i], ret);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void BtAvrcpCtGetElementAttriCallback(const bd_addr_t *bd_addr, avrcp_ct_element_attr_para_cb_t *attr_cb_para)
|
||
{
|
||
if (bd_addr == nullptr || attr_cb_para == nullptr || attr_cb_para->attr_value == nullptr) {
|
||
static_print_error("null pointer");
|
||
return;
|
||
}
|
||
|
||
static_print_debug("attr_cb_para->attr_num = %u", attr_cb_para->attr_num);
|
||
|
||
for (uint8_t i = 0; i < attr_cb_para->attr_num; i++) {
|
||
static_print_debug("attrId-charaId-valLen: 0x%x-0x%x-%u ", attr_cb_para->attr_value[i].attr_id,
|
||
attr_cb_para->attr_value[i].character_set_id, attr_cb_para->attr_value[i].value_len);
|
||
switch (attr_cb_para->attr_value[i].attr_id) {
|
||
case AVRCP_CT_ELEMENT_ATTR_TITLE:
|
||
static_print_debug("Attr Title:");
|
||
break;
|
||
case AVRCP_CT_ELEMENT_ATTR_ARTIST_NAME:
|
||
static_print_debug("Attr Name:");
|
||
break;
|
||
case AVRCP_CT_ELEMENT_ATTR_ALBUM_NAME:
|
||
static_print_debug("Attr Album:");
|
||
break;
|
||
case AVRCP_CT_ELEMENT_ATTR_TRACK_NUMBER:
|
||
static_print_debug("Attr Track Number:");
|
||
break;
|
||
case AVRCP_CT_ELEMENT_ATTR_TOTAL_NUMBER_OF_TRACKS:
|
||
static_print_debug("Attr Total Number Of Track:");
|
||
break;
|
||
case AVRCP_CT_ELEMENT_ATTR_TRACK_GENRE:
|
||
static_print_debug("Attr Track GENRE:");
|
||
break;
|
||
case AVRCP_CT_ELEMENT_ATTR_TRACK_PLAYING_TIME:
|
||
static_print_debug("Attr Track Playing Time_ms:");
|
||
break;
|
||
default:
|
||
static_print_debug("Other:");
|
||
break;
|
||
}
|
||
|
||
uint8_t *value = (uint8_t *)(void *)malloc(attr_cb_para->attr_value[i].value_len + 1);
|
||
if (attr_cb_para->attr_value[i].value_len > 0 && attr_cb_para->attr_value[i].value != nullptr) {
|
||
if (memcpy_s(value, attr_cb_para->attr_value[i].value_len, attr_cb_para->attr_value[i].value,
|
||
attr_cb_para->attr_value[i].value_len) != EOK) {
|
||
free(value);
|
||
static_print_error("memcpy_s fail.");
|
||
return;
|
||
}
|
||
}
|
||
value[attr_cb_para->attr_value[i].value_len] = '\0';
|
||
static_print_debug(" %s ", value);
|
||
free(value);
|
||
}
|
||
}
|
||
|
||
static void BtAvrcpCtGetPlayStatusCallback(const bd_addr_t *bd_addr, avrcp_ct_play_status_cb_t *status)
|
||
{
|
||
if (bd_addr == nullptr || status == nullptr) {
|
||
static_print_error("null pointer");
|
||
return;
|
||
}
|
||
static_print_debug("test get play status songlen:%u, songpos:%u, playstatus:%u:", status->song_length,
|
||
status->song_position, status->play_status);
|
||
}
|
||
|
||
static void BtAvrcpCtHdlNotifyVolumeRspCbk(avrcp_ct_notification_value_cb_t *notification)
|
||
{
|
||
static_print_info("Set local volume: 0x%x", notification->volume); /* 注册事件后通知的音量 */
|
||
BtAvrcpTgNotifyVolumeChangedProc((uint8_t)notification->volume);
|
||
}
|
||
|
||
static void BtAvrcpCtNotificationCallback(const bd_addr_t *bd_addr, avrcp_notify_event_t event_id,
|
||
avrcp_ct_notification_value_cb_t *notification)
|
||
{
|
||
if (bd_addr == nullptr || notification == nullptr) {
|
||
static_print_error("null pointer");
|
||
return;
|
||
}
|
||
|
||
// static_print_debug("ct notification cbk event_id:0x%x", event_id);
|
||
bool notify_flag = true;
|
||
switch (event_id) {
|
||
case AVRCP_NOTIFY_EVENT_PLAYBACK_STATUS_CHANGED:
|
||
static_print_debug("tg notify ct playback status changed :%u", notification->play_status);
|
||
// TODO:手机音乐状态改变
|
||
TjdUiAppPlayerModel::GetInstance()->AvrcpCtStatusNotification(notification->play_status); // 播放状态改变
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_VOLUME_CHANGED:
|
||
BtAvrcpCtHdlNotifyVolumeRspCbk(notification);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_NOW_PLAYING_CONTENT_CHANGED:
|
||
static_print_debug("play conent changed event_id:0x%x", event_id);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_TRACK_CHANGED:
|
||
static_print_debug("track changed event_id:0x%x", event_id);
|
||
break;
|
||
case AVRCP_NOTIFY_EVENT_TRACK_REACHED_END:
|
||
case AVRCP_NOTIFY_EVENT_TRACK_REACHED_START:
|
||
case AVRCP_NOTIFY_EVENT_PLAYBACK_POS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_BATT_STATUS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_SYSTEM_STATUS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_PLAYER_APPLICATION_SETTING_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_AVAILABLE_PLAYERS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_ADDRESSED_PLAYER_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_UIDS_CHANGED:
|
||
case AVRCP_NOTIFY_EVENT_RESERVED:
|
||
default:
|
||
notify_flag = false;
|
||
// static_print_info("invalid event id event_id:0x%x", event_id);
|
||
break;
|
||
}
|
||
if (notify_flag) {
|
||
static_print_debug("notify reg event_id: 0x%x", event_id);
|
||
avrcp_ct_register_notification(bd_addr, event_id, 0); /* TG通知变化后CT重新注册事件 */
|
||
}
|
||
}
|
||
|
||
void TjdUiAppPlayerModel::InitBtHeadsetEvent()
|
||
{
|
||
g_avrcp_tg_audio_cb.notify_pass_through_status_cbk = PressButtonStatusCallback;
|
||
g_avrcp_tg_audio_cb.get_media_status_cbk = MediaStatusCallback;
|
||
|
||
g_avrcp_tg_cb.conn_state_changed_cb = ConnectTgStateChangedCallback;
|
||
|
||
g_avrcp_ct_cb.conn_state_changed_cb = ConnCtStateChangedCallback;
|
||
g_avrcp_ct_cb.press_button_cb = BtAvrcpCtPressButtonRspCallback;
|
||
g_avrcp_ct_cb.release_button_cb = BtAvrcpCtReleaseButtonRspCallback;
|
||
g_avrcp_ct_cb.supported_companies_cb = BtAvrcpCtSupportCompanyCallback;
|
||
g_avrcp_ct_cb.supported_event_cb = BtAvrcpCtSupportEventCallback;
|
||
g_avrcp_ct_cb.element_attr_cb = BtAvrcpCtGetElementAttriCallback;
|
||
g_avrcp_ct_cb.play_status_cb = BtAvrcpCtGetPlayStatusCallback;
|
||
g_avrcp_ct_cb.notification_cb = BtAvrcpCtNotificationCallback;
|
||
|
||
avrcp_tg_register_callbacks(&g_avrcp_tg_cb);
|
||
avrcp_ct_register_callbacks(&g_avrcp_ct_cb);
|
||
bt_avrcp_tg_register_audio_cbk(&g_avrcp_tg_audio_cb);
|
||
}
|
||
|
||
} // namespace TJD
|