/*************************************************************************** * * Copyright 2015-2019 BES. * All rights reserved. All unpublished rights reserved. * * No part of this work may be used or reproduced in any form or by any * means, or stored in a database or retrieval system, without prior written * permission of BES. * * Use of this work is governed by a license granted by BES. * This work contains confidential and proprietary information of * BES. which is protected by copyright, trade secret, * trademark and other intellectual property rights. * ****************************************************************************/ #include "app_audio.h" #include "cmsis_os.h" #include "hal_timer.h" #include "hal_trace.h" #include "stdio.h" #include "a2dp_api.h" #include "app_bt.h" #include "btapp.h" #include "btusb_audio.h" #include "usb_audio_app.h" extern void btusbaudio_entry(void); extern void btusbaudio_exit(void); extern a2dp_stream_t *app_bt_get_steam(enum BT_DEVICE_ID_T id); extern int app_bt_get_bt_addr(enum BT_DEVICE_ID_T id, bt_bdaddr_t *bdaddr); extern bool app_bt_a2dp_service_is_connected(void); int app_bt_A2DP_OpenStream(a2dp_stream_t *Stream, bt_bdaddr_t *Addr); int app_bt_A2DP_CloseStream(a2dp_stream_t *Stream); extern bool btapp_hfp_is_call_active(void); static bool btusb_usb_is_on = false; static enum BTUSB_MODE btusb_mode = BTUSB_MODE_INVALID; static bool btusb_bt_audio_is_suspend = false; #define BT_USB_DEBUG() // TRACE(2,"_debug: %s,%d",__func__,__LINE__) extern struct BT_DEVICE_T app_bt_device; static void _btusb_stream_open(unsigned int timeout_ms) { a2dp_stream_t *stream = NULL; bt_bdaddr_t bdaddr; uint32_t stime = 0; uint32_t etime = 0; stime = hal_sys_timer_get(); // BT_USB_DEBUG(); stream = (a2dp_stream_t *)app_bt_get_steam(BT_DEVICE_ID_1); app_bt_get_bt_addr(BT_DEVICE_ID_1, &bdaddr); if (stream) { // struct BT_DEVICE_T *bt_dev = &app_bt_device; // A2DP_Register((a2dp_stream_t // *)bt_dev->a2dp_stream[BT_DEVICE_ID_1]->a2dp_stream, &a2dp_avdtpcodec, // NULL, (A2dpCallback) a2dp_callback); AVRCP_Register((AvrcpChannel // *)bt_dev->avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle, // (AvrcpCallback)avrcp_callback_CT, BTIF_AVRCP_CT_CATEGORY_1 | // BTIF_AVRCP_CT_CATEGORY_2 | BTIF_AVRCP_TG_CATEGORY_2); BT_USB_DEBUG(); osDelay(10); app_bt_A2DP_OpenStream(stream, &bdaddr); } else { BT_USB_DEBUG(); return; } while (1) { if (app_bt_a2dp_service_is_connected()) { etime = hal_sys_timer_get(); TRACE(1, "_debug: a2dp service connected, wait time = 0x%x.", TICKS_TO_MS(etime - stime)); break; } else { etime = hal_sys_timer_get(); if (TICKS_TO_MS(etime - stime) >= timeout_ms) { TRACE(1, "_debug: a2dp service connect timeout = 0x%x.", TICKS_TO_MS(etime - stime)); break; } osDelay(10); } } // BT_USB_DEBUG(); } static void _btusb_stream_close(unsigned int timeout_ms) { a2dp_stream_t *stream = NULL; uint32_t stime = 0; uint32_t etime = 0; stime = hal_sys_timer_get(); BT_USB_DEBUG(); stream = (a2dp_stream_t *)app_bt_get_steam(BT_DEVICE_ID_1); if (stream) { BT_USB_DEBUG(); app_bt_A2DP_CloseStream(stream); } else { BT_USB_DEBUG(); return; } stime = hal_sys_timer_get(); while (1) { if (!app_bt_a2dp_service_is_connected()) { // struct BT_DEVICE_T *bt_dev = &app_bt_device; // AVRCP_Deregister(bt_dev->avrcp_channel[BT_DEVICE_ID_1]->avrcp_channel_handle); // A2DP_Deregister(stream); etime = hal_sys_timer_get(); TRACE(1, "a2dp service diconnected, wait time = 0x%x.", TICKS_TO_MS(etime - stime)); break; } else { etime = hal_sys_timer_get(); if (TICKS_TO_MS(etime - stime) >= timeout_ms) { TRACE(1, "a2dp service diconnect timeout = 0x%x.", TICKS_TO_MS(etime - stime)); break; } osDelay(10); } } BT_USB_DEBUG(); } static void btusb_usbaudio_entry(void) { BT_USB_DEBUG(); btusbaudio_entry(); btusb_usb_is_on = true; } void btusb_usbaudio_open(void) { BT_USB_DEBUG(); if (!btusb_usb_is_on) { btusb_usbaudio_entry(); BT_USB_DEBUG(); } else { usb_audio_app(1); } BT_USB_DEBUG(); } void btusb_usbaudio_close(void) { BT_USB_DEBUG(); if (btusb_usb_is_on) { usb_audio_app(0); BT_USB_DEBUG(); } else { BT_USB_DEBUG(); } } void btusb_btaudio_close(bool is_wait) { BT_USB_DEBUG(); // if(!btusb_bt_audio_is_suspend) { BT_USB_DEBUG(); if (is_wait) { app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSEALL, 0); _btusb_stream_close(BTUSB_OUTTIME_MS); } else { _btusb_stream_close(0); } btusb_bt_audio_is_suspend = true; } } void btusb_btaudio_open(bool is_wait) { BT_USB_DEBUG(); // if(btusb_bt_audio_is_suspend) { TRACE(2, "%s: %d.", __func__, __LINE__); if (is_wait) { _btusb_stream_open(BTUSB_OUTTIME_MS); app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_CLOSE, 0); app_audio_sendrequest(APP_PLAY_BACK_AUDIO, (uint8_t)APP_BT_SETTING_SETUP, 0); } else { _btusb_stream_open(0); } TRACE(2, "%s: %d.", __func__, __LINE__); btusb_bt_audio_is_suspend = false; } } void btusb_switch(enum BTUSB_MODE mode) { // BT_USB_DEBUG(); if (mode != BTUSB_MODE_BT && mode != BTUSB_MODE_USB) { ASSERT(0, "%s:%d, mode = %d.", __func__, __LINE__, mode); } if (btusb_mode == mode) { BT_USB_DEBUG(); return; } if (btusb_mode == BTUSB_MODE_INVALID) { if (mode == BTUSB_MODE_BT) { TRACE(1, "%s: switch to BT mode.", __func__); btusb_mode = BTUSB_MODE_BT; } else { TRACE(1, "%s: switch to USB mode.", __func__); // btusb_btaudio_close(true); osDelay(500); btusb_usbaudio_open(); btusb_mode = BTUSB_MODE_USB; } } else { if (mode == BTUSB_MODE_BT) { TRACE(1, "%s: switch to BT mode.", __func__); if (btusb_usb_is_on) { TRACE(1, "%s: btusb_usbaudio_close.", __func__); btusb_usbaudio_close(); TRACE(1, "%s: btusb_usbaudio_close done.", __func__); osDelay(500); } btusb_mode = BTUSB_MODE_BT; btusb_btaudio_open(true); TRACE(1, "%s: switch to BT mode done.", __func__); } else { if (btapp_hfp_is_call_active() == 1) { TRACE(1, "%s: hfp is call active.", __func__); return; } TRACE(1, "%s: switch to USB mode.", __func__); btusb_btaudio_close(true); TRACE(1, "%s: btusb_btaudio_close done.", __func__); osDelay(500); btusb_usbaudio_open(); btusb_mode = BTUSB_MODE_USB; TRACE(1, "%s: switch to USB mode done.", __func__); } } } bool btusb_is_bt_mode(void) { BT_USB_DEBUG(); return btusb_mode == BTUSB_MODE_BT ? true : false; } bool btusb_is_usb_mode(void) { return btusb_mode == BTUSB_MODE_USB ? true : false; } #if defined(BT_USB_AUDIO_DUAL_MODE_TEST) void test_btusb_switch(void) { if (btusb_mode == BTUSB_MODE_BT) { btusb_switch(BTUSB_MODE_USB); } else { btusb_switch(BTUSB_MODE_BT); } } void test_btusb_switch_to_bt(void) { btusb_switch(BTUSB_MODE_BT); } void test_btusb_switch_to_usb(void) { btusb_switch(BTUSB_MODE_USB); } #endif