This commit is contained in:
lmx
2025-10-29 13:10:02 +08:00
commit 49a07fa419
2284 changed files with 642060 additions and 0 deletions

View File

@ -0,0 +1,191 @@
#include "adapter_idev.h"
#include "adapter_odev.h"
#include "adapter_idev_bt.h"
//#include "adapter_odev_dac.h"
#include "adapter_process.h"
#include "adapter_media.h"
//#include "application/audio_dig_vol.h"
#include "le_client_demo.h"
#include "system/malloc.h"
#include "key_event_deal.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define WIRELESS_MIC_SLAVE_OUTPUT_DAC 0
#define WIRELESS_MIC_SLAVE_OUTPUT_USB_MIC 1
#define WIRELESS_MIC_SLAVE_OUTPUT_SEL WIRELESS_MIC_SLAVE_OUTPUT_DAC//WIRELESS_MIC_SLAVE_OUTPUT_DAC//WIRELESS_MIC_SLAVE_OUTPUT_USB_MIC//
#if (APP_MAIN == APP_WIRELESS_MIC)
extern u8 get_charge_online_flag(void);
extern u8 app_common_device_event_deal(struct sys_event *event);
//bt idev config
struct _idev_bt_parm idev_bt_parm_list = {
.mode = BIT(IDEV_BLE),
};
//bt odev config
static const u8 dongle_remoter_name1[] = "S2_MIC_0";
static const client_match_cfg_t match_dev01 = {
.create_conn_mode = BIT(CLI_CREAT_BY_NAME),
.compare_data_len = sizeof(dongle_remoter_name1) - 1, //去结束符
.compare_data = dongle_remoter_name1,
.bonding_flag = 0,
};
static client_conn_cfg_t ble_conn_config = {
.match_dev_cfg[0] = &match_dev01, //匹配指定的名字
.match_dev_cfg[1] = NULL,
.match_dev_cfg[2] = NULL,
.search_uuid_cnt = 0,
.security_en = 0, //加密配对
};
struct _odev_bt_parm odev_bt_parm_list = {
.mode = BIT(ODEV_BLE), //only support BLE
//for BLE config
.ble_parm.cfg_t = &ble_conn_config,
};
u8 wl_mic_mode = 0;
void wireless_mic_change_mode(u8 mode)
{
#ifdef APP_WIRELESS_MIC_MASTER
return;
#endif
wl_mic_mode = mode;
printf("%s = %d", __func__, wl_mic_mode);
syscfg_write(CFG_USER_WIRELESSMIC_MODE, &wl_mic_mode, sizeof(wl_mic_mode));
os_time_dly(1);
cpu_reset();
}
extern u8 key_table[KEY_NUM_MAX][KEY_EVENT_MAX];
static int adapter_key_event_handler(struct sys_event *event)
{
int ret = 0;
struct key_event *key = &event->u.key;
u8 key_event = event->u.key.event;
key_event = key_table[key->value][key->event];
static u8 cnt = 0;
printf("key_event:%d %d %d\n", key_event, key->value, key->event);
switch (key_event) {
case KEY_POWEROFF:
printf("KEY_EVENT_LONG\n");
wireless_mic_change_mode(1);
ret = 1;
break;
case KEY_NULL:
break;
}
return ret;
}
extern int app_charge_event_handler(struct device_event *dev);
static int event_handle_callback(struct sys_event *event)
{
//处理用户关注的事件
int ret = 0;
switch (event->type) {
case SYS_KEY_EVENT:
ret = adapter_key_event_handler(event);
break;
case SYS_DEVICE_EVENT:
//app_common_device_event_deal(event);
if ((u32)event->arg == DEVICE_EVENT_FROM_CHARGE) {
#if TCFG_CHARGE_ENABLE
return app_charge_event_handler(&event->u.dev);
#endif
}
break;
default:
break;
}
return ret;
}
void wireless_mic_main_run(void)
{
int ret = 0;
printf("%s\n", __func__);
#ifdef APP_WIRELESS_MIC_SLAVE
ret = syscfg_read(CFG_USER_WIRELESSMIC_MODE, &wl_mic_mode, sizeof(wl_mic_mode));
printf("sizeof(wl_mic_mode) = %d,ret = %d", sizeof(wl_mic_mode), ret);
if (sizeof(wl_mic_mode) == ret) {
printf("wl_mic_mode = %d", wl_mic_mode);
} else {
wl_mic_mode = 0;
printf("wl_mic_mode = %d,read_micless_mode_err!!!!", wl_mic_mode);
}
if (wl_mic_mode == 1) {
printf("return EARPHONE MODE");
return;
}
#endif
while (1) {
//初始化
#ifdef APP_WIRELESS_MIC_MASTER
struct idev *idev = adapter_idev_open(ADAPTER_IDEV_MIC, NULL);
struct odev *odev = adapter_odev_open(ADAPTER_ODEV_BT, (void *)&odev_bt_parm_list);
struct adapter_media *media = adapter_media_open(NULL);
printf("app_main_wireless_master ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
#endif//APP_WIRELESS_MIC_MASTER
#ifdef APP_WIRELESS_MIC_SLAVE
struct idev *idev = adapter_idev_open(ADAPTER_IDEV_BT, (void *)&idev_bt_parm_list);
#if (WIRELESS_MIC_SLAVE_OUTPUT_SEL == WIRELESS_MIC_SLAVE_OUTPUT_USB_MIC)
struct odev *odev = adapter_odev_open(ADAPTER_ODEV_USB, NULL);
#else
struct odev *odev = adapter_odev_open(ADAPTER_ODEV_DAC, NULL);
#endif
struct adapter_media *media = adapter_media_open(NULL);
printf("app_main_wireless_slave ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
#endif//APP_WIRELESS_MIC_SLAVE
ASSERT(idev);
ASSERT(odev);
ASSERT(media);
struct adapter_pro *pro = adapter_process_open(idev, odev, media, event_handle_callback);//event_handle_callback 用户想拦截处理的事件
ASSERT(pro, "adapter_process_open fail!!\n");
//执行(包括事件解析、事件执行、媒体启动/停止, HID等事件转发)
adapter_process_run(pro);
//退出/关闭
adapter_process_close(&pro);
adapter_media_close(media);
adapter_idev_close(idev);
adapter_odev_close(odev);
///run idle off poweroff
printf("enter poweroff !!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
if (get_charge_online_flag()) {
printf("charge_online,cpu reset");
cpu_reset();
} else {
power_set_soft_poweroff();
}
}
}
#endif //(APP_MAIN == APP_WIRELESS_MIC)
#else
#include "system/includes.h"
void app_main_run(void)
{
printf("app_main_wireless_mic");
}
#endif

View File

@ -0,0 +1,271 @@
#include "adapter_adc.h"
#include "media/includes.h"
#include "audio_config.h"
#include "asm/dac.h"
#include "audio_splicing.h"
#include "app_config.h"
#if (TCFG_WIRELESS_MIC_ENABLE)
#if (TCFG_AUDIO_ADC_ENABLE)
#define ADAPTER_ADC_MIC_BUF_NUM 3
#if (TCFG_WIRELESS_MIC_STEREO_EN)
#define ADAPTER_ADC_MIC_ADC_CH 2
#else
#define ADAPTER_ADC_MIC_ADC_CH 1
#endif
#define BUF_ALIN(var,al) ((((var)+(al)-1)/(al))*(al))
static u16 adapter_adc_irq_points = 0;
extern struct audio_adc_hdl adc_hdl;
extern struct audio_dac_hdl dac_hdl;
extern struct adc_platform_data adc_data;
void adapter_adc_init(void)
{
audio_adc_init(&adc_hdl, &adc_data);
#if TCFG_AUDIO_DAC_ENABLE
//dac要开一下然后关一下, 否则mic不正常
audio_dac_start(&dac_hdl);
audio_dac_stop(&dac_hdl);
#endif//TCFG_AUDIO_DAC_ENABLE
}
struct __adapter_adc_mic {
s16 *adc_buf;//[ADAPTER_ADC_MIC_BUF_SIZE]; //align 4Bytes
u8 *pcm_buf;//[ADAPTER_PCM_BUF_SIZE];
struct audio_adc_output_hdl adc_output;
struct adc_mic_ch mic_ch;
cbuffer_t cbuf;
u16 skip_cnt; //用来丢掉刚开mic时的前几包异常数据
volatile u8 start;
void *resume_priv;
void (*resume)(void *resume_priv);
void *data_callback_priv;
void (*data_callback)(void *data_callback_priv, u8 *data, u16 len);
};
short test_sin_441k[441] = {
0x0000, 0x122d, 0x23fb, 0x350f, 0x450f, 0x53aa, 0x6092, 0x6b85, 0x744b, 0x7ab5, 0x7ea2, 0x7fff, 0x7ec3, 0x7af6, 0x74ab, 0x6c03,
0x612a, 0x545a, 0x45d4, 0x35e3, 0x24db, 0x1314, 0x00e9, 0xeeba, 0xdce5, 0xcbc6, 0xbbb6, 0xad08, 0xa008, 0x94fa, 0x8c18, 0x858f,
0x8181, 0x8003, 0x811d, 0x84ca, 0x8af5, 0x9380, 0x9e3e, 0xaaf7, 0xb969, 0xc94a, 0xda46, 0xec06, 0xfe2d, 0x105e, 0x223a, 0x3365,
0x4385, 0x5246, 0x5f5d, 0x6a85, 0x7384, 0x7a2d, 0x7e5b, 0x7ffa, 0x7f01, 0x7b75, 0x7568, 0x6cfb, 0x6258, 0x55b7, 0x4759, 0x3789,
0x2699, 0x14e1, 0x02bc, 0xf089, 0xdea7, 0xcd71, 0xbd42, 0xae6d, 0xa13f, 0x95fd, 0x8ce1, 0x861a, 0x81cb, 0x800b, 0x80e3, 0x844e,
0x8a3c, 0x928c, 0x9d13, 0xa99c, 0xb7e6, 0xc7a5, 0xd889, 0xea39, 0xfc5a, 0x0e8f, 0x2077, 0x31b8, 0x41f6, 0x50de, 0x5e23, 0x697f,
0x72b8, 0x799e, 0x7e0d, 0x7fee, 0x7f37, 0x7bed, 0x761f, 0x6ded, 0x6380, 0x570f, 0x48db, 0x392c, 0x2855, 0x16ad, 0x048f, 0xf259,
0xe06b, 0xcf20, 0xbed2, 0xafd7, 0xa27c, 0x9705, 0x8db0, 0x86ab, 0x821c, 0x801a, 0x80b0, 0x83da, 0x8988, 0x919c, 0x9bee, 0xa846,
0xb666, 0xc603, 0xd6ce, 0xe86e, 0xfa88, 0x0cbf, 0x1eb3, 0x3008, 0x4064, 0x4f73, 0x5ce4, 0x6874, 0x71e6, 0x790a, 0x7db9, 0x7fdc,
0x7f68, 0x7c5e, 0x76d0, 0x6ed9, 0x64a3, 0x5863, 0x4a59, 0x3acc, 0x2a0f, 0x1878, 0x0661, 0xf42a, 0xe230, 0xd0d0, 0xc066, 0xb145,
0xa3bd, 0x9813, 0x8e85, 0x8743, 0x8274, 0x8030, 0x8083, 0x836b, 0x88da, 0x90b3, 0x9acd, 0xa6f5, 0xb4ea, 0xc465, 0xd515, 0xe6a3,
0xf8b6, 0x0aee, 0x1ced, 0x2e56, 0x3ecf, 0x4e02, 0x5ba1, 0x6764, 0x710e, 0x786f, 0x7d5e, 0x7fc3, 0x7f91, 0x7cc9, 0x777a, 0x6fc0,
0x65c1, 0x59b3, 0x4bd3, 0x3c6a, 0x2bc7, 0x1a41, 0x0833, 0xf5fb, 0xe3f6, 0xd283, 0xc1fc, 0xb2b7, 0xa503, 0x9926, 0x8f60, 0x87e1,
0x82d2, 0x804c, 0x805d, 0x8303, 0x8833, 0x8fcf, 0x99b2, 0xa5a8, 0xb372, 0xc2c9, 0xd35e, 0xe4da, 0xf6e4, 0x091c, 0x1b26, 0x2ca2,
0x3d37, 0x4c8e, 0x5a58, 0x664e, 0x7031, 0x77cd, 0x7cfd, 0x7fa3, 0x7fb4, 0x7d2e, 0x781f, 0x70a0, 0x66da, 0x5afd, 0x4d49, 0x3e04,
0x2d7d, 0x1c0a, 0x0a05, 0xf7cd, 0xe5bf, 0xd439, 0xc396, 0xb42d, 0xa64d, 0x9a3f, 0x9040, 0x8886, 0x8337, 0x806f, 0x803d, 0x82a2,
0x8791, 0x8ef2, 0x989c, 0xa45f, 0xb1fe, 0xc131, 0xd1aa, 0xe313, 0xf512, 0x074a, 0x195d, 0x2aeb, 0x3b9b, 0x4b16, 0x590b, 0x6533,
0x6f4d, 0x7726, 0x7c95, 0x7f7d, 0x7fd0, 0x7d8c, 0x78bd, 0x717b, 0x67ed, 0x5c43, 0x4ebb, 0x3f9a, 0x2f30, 0x1dd0, 0x0bd6, 0xf99f,
0xe788, 0xd5f1, 0xc534, 0xb5a7, 0xa79d, 0x9b5d, 0x9127, 0x8930, 0x83a2, 0x8098, 0x8024, 0x8247, 0x86f6, 0x8e1a, 0x978c, 0xa31c,
0xb08d, 0xbf9c, 0xcff8, 0xe14d, 0xf341, 0x0578, 0x1792, 0x2932, 0x39fd, 0x499a, 0x57ba, 0x6412, 0x6e64, 0x7678, 0x7c26, 0x7f50,
0x7fe6, 0x7de4, 0x7955, 0x7250, 0x68fb, 0x5d84, 0x5029, 0x412e, 0x30e0, 0x1f95, 0x0da7, 0xfb71, 0xe953, 0xd7ab, 0xc6d4, 0xb725,
0xa8f1, 0x9c80, 0x9213, 0x89e1, 0x8413, 0x80c9, 0x8012, 0x81f3, 0x8662, 0x8d48, 0x9681, 0xa1dd, 0xaf22, 0xbe0a, 0xce48, 0xdf89,
0xf171, 0x03a6, 0x15c7, 0x2777, 0x385b, 0x481a, 0x5664, 0x62ed, 0x6d74, 0x75c4, 0x7bb2, 0x7f1d, 0x7ff5, 0x7e35, 0x79e6, 0x731f,
0x6a03, 0x5ec1, 0x5193, 0x42be, 0x328f, 0x2159, 0x0f77, 0xfd44, 0xeb1f, 0xd967, 0xc877, 0xb8a7, 0xaa49, 0x9da8, 0x9305, 0x8a98,
0x848b, 0x80ff, 0x8006, 0x81a5, 0x85d3, 0x8c7c, 0x957b, 0xa0a3, 0xadba, 0xbc7b, 0xcc9b, 0xddc6, 0xefa2, 0x01d3, 0x13fa, 0x25ba,
0x36b6, 0x4697, 0x5509, 0x61c2, 0x6c80, 0x750b, 0x7b36, 0x7ee3, 0x7ffd, 0x7e7f, 0x7a71, 0x73e8, 0x6b06, 0x5ff8, 0x52f8, 0x444a,
0x343a, 0x231b, 0x1146, 0xff17, 0xecec, 0xdb25, 0xca1d, 0xba2c, 0xaba6, 0x9ed6, 0x93fd, 0x8b55, 0x850a, 0x813d, 0x8001, 0x815e,
0x854b, 0x8bb5, 0x947b, 0x9f6e, 0xac56, 0xbaf1, 0xcaf1, 0xdc05, 0xedd3
};
static u16 tx_s_cnt = 0;
int get_sine_data(u16 *s_cnt, s16 *data, u16 points, u8 ch)
{
while (points--) {
if (*s_cnt >= 441) {
*s_cnt = 0;
}
*data++ = test_sin_441k[*s_cnt];
if (ch == 2) {
*data++ = test_sin_441k[*s_cnt];
}
(*s_cnt)++;
}
return 0;
}
static u32 sine_send_count = 0;
static u8 sine_send_flag = 0;
static struct __adapter_adc_mic *adapter_adc_mic = NULL;
#define MY_IO_DEBUG_0(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);}
#define MY_IO_DEBUG_1(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);}
static void adapter_adc_mic_output(void *priv, s16 *data, int len)
{
if (adapter_adc_mic == NULL || adapter_adc_mic->start == 0) {
return ;
}
int olen;
#if (TCFG_WIRELESS_MIC_STEREO_EN)
olen = len * 2;
#else
olen = len;
#endif
//printf("len = %d,olen = %d\n", len, olen);
if (adapter_adc_mic->skip_cnt) {
adapter_adc_mic->skip_cnt--;
memset(data, 0, olen);
}
//memset(data, 0, olen);
//putchar('A');
#if 0
sine_send_count ++;
if (sine_send_count >= 200) {
sine_send_count = 0;
sine_send_flag = !sine_send_flag;
}
if (sine_send_flag) {
JL_PORTA->DIR &= ~BIT(4);
JL_PORTA->OUT |= BIT(4);
get_sine_data(&tx_s_cnt, data, olen / 2, 1);
} else {
JL_PORTA->DIR &= ~BIT(4);
JL_PORTA->OUT &= ~BIT(4);
}
#else
//get_sine_data(&tx_s_cnt, data, olen / 2, 1);
#endif
if (adapter_adc_mic->data_callback) {
adapter_adc_mic->data_callback(adapter_adc_mic->data_callback_priv, (u8 *)data, olen);
} else {
int wlen = cbuf_write(&adapter_adc_mic->cbuf, data, olen);
if (wlen != olen) {
//putchar('M');
}
if (adapter_adc_mic->resume) {
adapter_adc_mic->resume(adapter_adc_mic->resume_priv);
}
}
}
int adapter_adc_mic_data_read(void *priv, void *data, int len)
{
if (adapter_adc_mic) {
int rlen = adapter_adc_irq_points << 1;
return cbuf_read(&adapter_adc_mic->cbuf, data, rlen);
}
return 0;
}
int adapter_adc_mic_open(u16 sample_rate, u8 gain, u16 irq_points)
{
#if (TCFG_WIRELESS_MIC_STEREO_EN)
gain = 0;//如果是linein gain只能为0 或 1 并且前级增益为0db
#endif
u32 buf_size = BUF_ALIN(sizeof(struct __adapter_adc_mic), 4)
+ BUF_ALIN(irq_points * ADAPTER_ADC_MIC_BUF_NUM * ADAPTER_ADC_MIC_ADC_CH * 2, 4)
+ BUF_ALIN(irq_points * 2 * 3, 4);
u32 offset = 0;
u8 *buf = zalloc(buf_size);
struct __adapter_adc_mic *hdl = (struct __adapter_adc_mic *)(buf + offset);
offset += BUF_ALIN(sizeof(struct __adapter_adc_mic), 4);
hdl->adc_buf = (s16 *)(buf + offset);
offset += BUF_ALIN(irq_points * ADAPTER_ADC_MIC_BUF_NUM * ADAPTER_ADC_MIC_ADC_CH * 2, 4);
hdl->pcm_buf = (buf + offset);
offset += BUF_ALIN(irq_points * 2 * 3, 4);
if (hdl == NULL) {
log_e("adapter_adc_mic zalloc fail\n");
return -1;
}
// 打开mic驱动
audio_adc_mic_open(&hdl->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl);
audio_adc_mic_set_gain(&hdl->mic_ch, gain);
#if (TCFG_WIRELESS_MIC_STEREO_EN)
audio_mic_0dB_en(1);
audio_adc_mic1_open(&hdl->mic_ch, AUDIO_ADC_MIC_CH, &adc_hdl);
audio_adc_mic1_set_gain(&hdl->mic_ch, gain);
audio_mic1_0dB_en(1);
#endif
audio_adc_mic_set_sample_rate(&hdl->mic_ch, sample_rate);
audio_adc_mic_set_buffs(
&hdl->mic_ch,
hdl->adc_buf,
irq_points * 2,
ADAPTER_ADC_MIC_BUF_NUM
);
hdl->adc_output.priv = NULL;
hdl->adc_output.handler = adapter_adc_mic_output;
audio_adc_add_output_handler(&adc_hdl, &hdl->adc_output);
cbuf_init(&hdl->cbuf, hdl->pcm_buf, irq_points * 2 * 3);
adapter_adc_irq_points = irq_points;
hdl->skip_cnt = 30;
hdl->start = 0;
local_irq_disable();
adapter_adc_mic = hdl;
local_irq_enable();
return 0;
}
void adapter_adc_mic_data_output_resume_register(void (*callback)(void *priv), void *priv)
{
if (adapter_adc_mic) {
adapter_adc_mic->resume = callback;
adapter_adc_mic->resume_priv = priv;
}
}
void adapter_adc_mic_data_callback_register(void (*callback)(void *priv, u8 *data, u16 len), void *priv)
{
if (adapter_adc_mic) {
adapter_adc_mic->data_callback = callback;
adapter_adc_mic->data_callback_priv = priv;
}
}
void adapter_adc_mic_close(void)
{
if (adapter_adc_mic) {
adapter_adc_mic->start = 0;
audio_adc_mic_close(&adapter_adc_mic->mic_ch);
audio_adc_del_output_handler(&adc_hdl, &adapter_adc_mic->adc_output);
local_irq_disable();
free(adapter_adc_mic);
adapter_adc_mic = NULL;
local_irq_enable();
}
}
void adapter_adc_mic_start(void)
{
if (adapter_adc_mic) {
adapter_adc_mic->start = 1;
audio_adc_mic_start(&adapter_adc_mic->mic_ch);
}
}
#endif//TCFG_AUDIO_ADC_ENABLE
#endif//TCFG_WIRELESS_MIC_ENABLE

View File

@ -0,0 +1,17 @@
#ifndef __ADAPTER_ADC_H___
#define __ADAPTER_ADC_H___
#include "generic/typedef.h"
void adapter_adc_init(void);
struct audio_adc_hdl *adapter_adc_get_handle(void);
int adapter_adc_mic_data_read(void *hdl, void *data, int len);
int adapter_adc_mic_open(u16 sample_rate, u8 gain, u16 irq_points);
void adapter_adc_mic_data_output_resume_register(void (*callback)(void *priv), void *priv);
void adapter_adc_mic_data_callback_register(void (*callback)(void *priv, u8 *data, u16 len), void *priv);
void adapter_adc_mic_close(void);
void adapter_adc_mic_start(void);
#endif//__ADAPTER_ADC_H___

View File

@ -0,0 +1,72 @@
#include "adapter_media.h"
#include "adapter_adc.h"
#include "adapter_wireless_dec.h"
#include "adapter_wireless_enc.h"
#if (TCFG_WIRELESS_MIC_ENABLE)
struct adapter_media g_adapter_media = {0};
static void adapter_adc_mic_data_callback(void *priv, void *buf, int len)
{
adapter_wireless_enc_write(buf, len);
}
struct adapter_media *adapter_media_open(void *parm)
{
memset(&g_adapter_media, 0, sizeof(struct adapter_media));
return &g_adapter_media;
}
void adapter_media_close(struct adapter_media *media)
{
adapter_media_stop(media);
}
void adapter_media_stop(struct adapter_media *media)
{
printf("adapter_media_stop\n");
if (media) {
if (media->idev && media->odev) {
if (media->status) {
if (media->idev->id == ADAPTER_IDEV_MIC && media->odev->id == ADAPTER_ODEV_BT) {
printf("adapter_media_stop 1\n");
adapter_adc_mic_close();
adapter_wireless_enc_close();
} else if (media->idev->id == ADAPTER_IDEV_BT && media->odev->id == ADAPTER_ODEV_DAC) {
printf("adapter_media_stop 2\n");
adapter_wireless_dec_close();
}
media->status = 0;
}
}
}
}
int adapter_media_start(struct adapter_media *media)
{
if (media) {
if (media->idev && media->odev) {
if (media->status) {
printf("media start aready\n");
return 0;
}
//start编解码
if (media->idev->id == ADAPTER_IDEV_MIC && media->odev->id == ADAPTER_ODEV_BT) {
//启动音频编码发射
adapter_adc_mic_open(44100, 10, 120);
adapter_wireless_enc_open();
adapter_adc_mic_data_callback_register(adapter_adc_mic_data_callback, NULL);
adapter_adc_mic_start();
} else if (media->idev->id == ADAPTER_IDEV_BT && media->odev->id == ADAPTER_ODEV_DAC) {
//启动解码输出dac
adapter_wireless_dec_open();
}
media->status = 1;
}
}
return 0;
}
#endif//TCFG_WIRELESS_MIC_ENABLE

View File

@ -0,0 +1,25 @@
#ifndef __ADAPTER_MEDIA_H__
#define __ADAPTER_MEDIA_H__
#include "app_config.h"
#include "generic/typedef.h"
#include "media/includes.h"
#include "adapter_idev.h"
#include "adapter_odev.h"
struct adapter_media {
u8 status;
//...
struct idev *idev;
struct odev *odev;
};
struct adapter_media *adapter_media_open(void *parm);
void adapter_media_close(struct adapter_media *media);
int adapter_media_start(struct adapter_media *media);
void adapter_media_stop(struct adapter_media *media);
#endif//__ADAPTER_MEDIA_H__

View File

@ -0,0 +1,582 @@
#include "adapter_wireless_dec.h"
#include "asm/includes.h"
#include "system/includes.h"
#include "app_config.h"
#include "audio_config.h"
//#include "adapter_decoder.h"
#include "adapter_process.h"
#if TCFG_WIRELESS_MIC_ENABLE
//#define WIRELESS_DECODER_SEL AUDIO_CODING_SBC
#define WIRELESS_DECODER_SEL AUDIO_CODING_LC3
#define WIRELESS_PACKET_HEADER_LEN (2)//(2)/*包头Max Length*/
#define WIRELESS_DAC_MAX_DELAY (16)
#define WIRELESS_DAC_START_DELAY (10)
struct __adapter_wireless_dec {
struct audio_decoder decoder; // 解码器
struct audio_res_wait wait; // 资源等待句柄
struct audio_mixer_ch mix_ch; // 叠加句柄
u8 start; // 解码开始
u8 wait_resume;// 需要激活
u8 remain; // 解码剩余数据标记
int coding_type;// 解码类型
};
extern struct audio_decoder_task decode_task;
extern struct audio_dac_hdl dac_hdl;
extern struct audio_mixer mixer;
extern const int LC3_SUPPORT_CH;
extern const int LC3_DMS_VAL; //单位ms, 【只支持 25,50,100】
#define ADAPTER_WIRELESS_FRAME_LBUF_SIZE (150*LC3_SUPPORT_CH)
struct __adapter_wireless_dec *adapter_wireless_dec = NULL;
int adapter_wireless_media_get_packet(u8 **frame);
void adapter_wireless_media_free_packet(void *_packet);
void *adapter_wireless_media_fetch_packet(int *len, void *prev_packet);
int adapter_wireless_media_get_packet_num(void);
int adapter_wireless_dec_close(void);
// 解码获取数据
static int adapter_wireless_dec_get_frame(struct audio_decoder *decoder, u8 **frame)
{
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
u8 *packet = NULL;
int len = 0;
// 获取数据
len = adapter_wireless_media_get_packet(&packet);
if (len < 0) {
// 失败
putchar('X');
return len;
}
// putchar('g');
*frame = packet;
return len;
}
// 解码释放数据空间
static void adapter_wireless_dec_put_frame(struct audio_decoder *decoder, u8 *frame)
{
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
if (frame) {
adapter_wireless_media_free_packet((void *)(frame));
}
}
// 解码查询数据
static int adapter_wireless_dec_fetch_frame(struct audio_decoder *decoder, u8 **frame)
{
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
u8 *packet = NULL;
int len = 0;
u32 wait_timeout = 0;
if (!dec->start) {
wait_timeout = jiffies + msecs_to_jiffies(500);
}
__retry_fetch:
packet = adapter_wireless_media_fetch_packet(&len, NULL);
if (packet) {
*frame = packet;
} else if (!dec->start) {
// 解码启动前获取数据来做格式信息获取等
if (time_before(jiffies, wait_timeout)) {
os_time_dly(1);
goto __retry_fetch;
}
}
printf("adapter_wireless_dec_fetch_frame ok\n");
return len;
}
static const struct audio_dec_input adapter_wireless_input = {
.coding_type = WIRELESS_DECODER_SEL,
.data_type = AUDIO_INPUT_FRAME,
.ops = {
.frame = {
.fget = adapter_wireless_dec_get_frame,
.fput = adapter_wireless_dec_put_frame,
.ffetch = adapter_wireless_dec_fetch_frame,
}
}
};
// 解码预处理
static int adapter_wireless_dec_probe_handler(struct audio_decoder *decoder)
{
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
if (adapter_wireless_media_get_packet_num() < 1) {
// 没有数据时返回负数,等有数据时激活解码
dec->wait_resume = 1;
audio_decoder_suspend(decoder, 0);
return -EINVAL;
}
return 0;
}
// 解码后处理
static int adapter_wireless_dec_post_handler(struct audio_decoder *decoder)
{
return 0;
}
static int adapter_wireless_dec_output_handler(struct audio_decoder *decoder, s16 *data, int len, void *priv)
{
struct __adapter_wireless_dec *dec = container_of(decoder, struct __adapter_wireless_dec, decoder);
if (!dec->remain) {
/* put_u16hex(len); */
}
int wlen = 0;
do {
wlen = audio_mixer_ch_write(&dec->mix_ch, data, len);
} while (0);
int remain_len = len - wlen;
if (remain_len == 0) {
dec->remain = 0;
} else {
dec->remain = 1;
}
return wlen;
}
static const struct audio_dec_handler adapter_wireless_dec_handler = {
.dec_probe = adapter_wireless_dec_probe_handler,
.dec_output = adapter_wireless_dec_output_handler,
.dec_post = adapter_wireless_dec_post_handler,
};
// 解码释放
static void adapter_wireless_dec_release(void)
{
// 删除解码资源等待
audio_decoder_task_del_wait(&decode_task, &adapter_wireless_dec->wait);
// 释放空间
local_irq_disable();
free(adapter_wireless_dec);
adapter_wireless_dec = NULL;
local_irq_enable();
}
// 解码关闭
static void adapter_wireless_audio_res_close(void)
{
if (adapter_wireless_dec->start == 0) {
printf("adapter_wireless_dec->start == 0");
return ;
}
// 关闭数据流节点
adapter_wireless_dec->start = 0;
audio_decoder_close(&adapter_wireless_dec->decoder);
audio_mixer_ch_close(&adapter_wireless_dec->mix_ch);
//adapter_audio_stream_close(&adapter_wireless_dec->stream);
app_audio_state_exit(APP_AUDIO_STATE_MUSIC);
}
// 解码事件处理
static void adapter_wireless_dec_event_handler(struct audio_decoder *decoder, int argc, int *argv)
{
switch (argv[0]) {
case AUDIO_DEC_EVENT_END:
printf("AUDIO_DEC_EVENT_END\n");
adapter_wireless_dec_close();
break;
}
}
// 解码数据流激活
static void adapter_wireless_out_stream_resume(void *p)
{
struct __adapter_wireless_dec *dec = (struct __adapter_wireless_dec *)p;
audio_decoder_resume(&dec->decoder);
}
// 收到数据后的处理
void adapter_wireless_media_rx_notice_to_decode(void)
{
if (adapter_wireless_dec && adapter_wireless_dec->start && adapter_wireless_dec->wait_resume) {
adapter_wireless_dec->wait_resume = 0;
audio_decoder_resume(&adapter_wireless_dec->decoder);
}
}
// 解码start
static int adapter_wireless_dec_start(void)
{
int err;
struct audio_fmt *fmt;
struct __adapter_wireless_dec *dec = adapter_wireless_dec;
if (!adapter_wireless_dec) {
return -EINVAL;
}
printf("adapter_wireless_dec_start: in\n");
// 打开adapter_wireless解码
err = audio_decoder_open(&dec->decoder, &adapter_wireless_input, &decode_task);
if (err) {
goto __err1;
}
// 设置运行句柄
audio_decoder_set_handler(&dec->decoder, &adapter_wireless_dec_handler);
#if (WIRELESS_DECODER_SEL == AUDIO_CODING_SBC)
if (dec->coding_type != adapter_wireless_input.coding_type) {
struct audio_fmt f = {0};
f.coding_type = dec->coding_type;
err = audio_decoder_set_fmt(&dec->decoder, &f);
if (err) {
goto __err2;
}
}
// 获取解码格式
err = audio_decoder_get_fmt(&dec->decoder, &fmt);
if (err) {
goto __err2;
}
#else
struct audio_fmt f = {0};
f.coding_type = WIRELESS_DECODER_SEL;
f.channel = LC3_SUPPORT_CH;
f.sample_rate = 44100;
f.bit_rate = 64000;
f.frame_len = LC3_DMS_VAL;
dec->decoder.fmt.channel = f.channel;
dec->decoder.fmt.sample_rate = f.sample_rate;
dec->decoder.fmt.bit_rate = f.bit_rate;
dec->decoder.fmt.frame_len = f.frame_len;
err = audio_decoder_set_fmt(&dec->decoder, &f);
if (err) {
goto __err2;
}
#endif
// 使能事件回调
audio_decoder_set_event_handler(&dec->decoder, adapter_wireless_dec_event_handler, 0);
// 设置输出声道类型
#if (TCFG_AUDIO_DAC_CONNECT_MODE == DAC_OUTPUT_LR)
audio_decoder_set_output_channel(&dec->decoder, AUDIO_CH_LR);
#else
audio_decoder_set_output_channel(&dec->decoder, AUDIO_CH_DIFF);
#endif
#if TCFG_AUDIO_DAC_ENABLE
//设定延时,
audio_dac_set_delay_time(&dac_hdl, WIRELESS_DAC_START_DELAY, WIRELESS_DAC_MAX_DELAY);
#endif//TCFG_AUDIO_DAC_ENABLE
// 设置音频输出类型
audio_mixer_ch_open(&dec->mix_ch, &mixer);
audio_mixer_ch_set_sample_rate(&dec->mix_ch, f.sample_rate);
audio_mixer_ch_set_resume_handler(&dec->mix_ch, (void *)&dec->decoder, (void (*)(void *))audio_decoder_resume);
app_audio_state_switch(APP_AUDIO_STATE_MUSIC, get_max_sys_vol());
// 开始解码
dec->start = 1;
err = audio_decoder_start(&dec->decoder);
if (err) {
goto __err3;
}
return 0;
__err3:
__err2:
dec->start = 0;
audio_decoder_close(&dec->decoder);
__err1:
adapter_wireless_dec_release();
return err;
}
// 解码资源等待回调
static int adapter_wireless_wait_res_handler(struct audio_res_wait *wait, int event)
{
int err = 0;
y_printf("adapter_wireless_wait_res_handler: %d\n", event);
if (event == AUDIO_RES_GET) {
// 可以开始解码
err = adapter_wireless_dec_start();
} else if (event == AUDIO_RES_PUT) {
// 被打断
if (adapter_wireless_dec->start) {
adapter_wireless_audio_res_close();
}
}
return err;
}
// 打开解码
//int adapter_wireless_dec_open(struct adapter_decoder_fmt *fmt, struct adapter_media_parm *media_parm)
int adapter_wireless_dec_open(void)
{
struct __adapter_wireless_dec *dec;
if (adapter_wireless_dec) {
return 0;
}
printf("adapter_wireless_dec_open \n");
dec = zalloc(sizeof(*dec));
ASSERT(dec);
/* dec->fmt = fmt; */
/* dec->media_parm = media_parm; */
adapter_wireless_dec = dec;
dec->coding_type = WIRELESS_DECODER_SEL; // 解码类型
dec->wait.priority = 1; // 解码优先级
dec->wait.preemption = 0; // 不使能直接抢断解码
//dec->wait.snatch_same_prio = 1; // 可抢断同优先级解码
dec->wait.handler = adapter_wireless_wait_res_handler;
adapter_wireless_dec_frame_init();
audio_decoder_task_add_wait(&decode_task, &dec->wait);
return 0;
}
// 关闭解码
int adapter_wireless_dec_close(void)
{
printf("adapter_wireless_dec_close 1\n");
if (!adapter_wireless_dec) {
return 0;
}
if (adapter_wireless_dec->start) {
adapter_wireless_audio_res_close();
}
adapter_wireless_dec_release();
adapter_wireless_dec_frame_close();
printf("adapter_wireless_dec_close 2\n");
return 1;
}
/* static void adapter_wireless_dec_set_vol(u32 channel, u8 vol) */
/* { */
/* if (adapter_wireless_dec && adapter_wireless_dec->stream) { */
/* adapter_audio_stream_set_vol(adapter_wireless_dec->stream, channel, vol); */
/* } */
/* } */
/////////////////////////////////////////////////////////////////////////////////////////////
//
struct adapter_wireless_media_rx_bulk {
struct list_head entry;
int data_len;
u8 data[0];
};
static u16 adapter_wireless_rx_seqn = 0;
static u32 *adapter_wireless_media_buf = NULL;
static LIST_HEAD(adapter_wireless_media_head);
// 获取frame数据
int adapter_wireless_media_get_packet(u8 **frame)
{
struct adapter_wireless_media_rx_bulk *p;
local_irq_disable();
if (adapter_wireless_media_head.next != &adapter_wireless_media_head) {
p = list_entry((&adapter_wireless_media_head)->next, typeof(*p), entry);
__list_del_entry(&p->entry);
*frame = p->data;
local_irq_enable();
return p->data_len;
}
local_irq_enable();
return 0;
}
// 释放frame数据
void adapter_wireless_media_free_packet(void *data)
{
struct adapter_wireless_media_rx_bulk *rx = container_of(data, struct adapter_wireless_media_rx_bulk, data);
local_irq_disable();
__list_del_entry(&rx->entry);
local_irq_enable();
lbuf_free(rx);
}
// 检查frame数据
void *adapter_wireless_media_fetch_packet(int *len, void *prev_packet)
{
struct adapter_wireless_media_rx_bulk *p;
local_irq_disable();
if (adapter_wireless_media_head.next != &adapter_wireless_media_head) {
if (prev_packet) {
p = container_of(prev_packet, struct adapter_wireless_media_rx_bulk, data);
if (p->entry.next != &adapter_wireless_media_head) {
p = list_entry(p->entry.next, typeof(*p), entry);
*len = p->data_len;
local_irq_enable();
return p->data;
}
} else {
p = list_entry((&adapter_wireless_media_head)->next, typeof(*p), entry);
*len = p->data_len;
local_irq_enable();
return p->data;
}
}
local_irq_enable();
return NULL;
}
// 获取数据量
int adapter_wireless_media_get_packet_num(void)
{
struct adapter_wireless_media_rx_bulk *p;
u32 num = 0;
local_irq_disable();
list_for_each_entry(p, &adapter_wireless_media_head, entry) {
num++;
}
local_irq_enable();
return num;
}
int adapter_wireless_dec_frame_write(void *data, u16 len)
{
// printf("rx len = %d ", len);
struct adapter_wireless_media_rx_bulk *p;
local_irq_disable();
if (adapter_wireless_media_buf) {
if (len < WIRELESS_PACKET_HEADER_LEN) {
local_irq_enable();
return 0;
}
u16 rx_seqn = 0;
u8 *buf = data;
rx_seqn |= (u16)(buf[0] << 8);
rx_seqn |= buf[1];
if (adapter_wireless_rx_seqn == rx_seqn) {
putchar('1');
local_irq_enable();
return 0;
}
adapter_wireless_rx_seqn ++;
if (rx_seqn != adapter_wireless_rx_seqn) {
// putchar('2');
adapter_wireless_rx_seqn = rx_seqn;
}
// putchar('R');
len -= 2;
buf += 2;
p = lbuf_alloc((struct lbuff_head *)adapter_wireless_media_buf, sizeof(*p) + len);
if (p == NULL) {
printf("lbuf full !!\n");
/* putchar('!'); */
local_irq_enable();
adapter_wireless_media_rx_notice_to_decode();
return 0;
}
//putchar('W');
// 填数
p->data_len = len;//sizeof(sbc_data);
memcpy(p->data, buf, len);
list_add_tail(&p->entry, &adapter_wireless_media_head);
// 告诉上层有数据
adapter_wireless_media_rx_notice_to_decode();
local_irq_enable();
return 1;
}
local_irq_enable();
return 0;
}
// 模拟定时关闭
void adapter_wireless_dec_frame_close(void)
{
y_printf("%s,%d \n", __func__, __LINE__);
local_irq_disable();
__list_del_entry(&adapter_wireless_media_head);
if (adapter_wireless_media_buf) {
printf("meida_buf free!!!!!!!!!!!!!!!");
free(adapter_wireless_media_buf);
adapter_wireless_media_buf = NULL;
}
local_irq_enable();
}
void adapter_wireless_dec_frame_init(void)
{
printf("%s,%d \n", __func__, __LINE__);
if (adapter_wireless_media_buf) {
return;
}
// 申请空间
u32 buf_size = ADAPTER_WIRELESS_FRAME_LBUF_SIZE;
void *buf = malloc(buf_size);
ASSERT(buf);
// 初始化lbuf
local_irq_disable();
lbuf_init(buf, buf_size, 4, 0);
INIT_LIST_HEAD(&adapter_wireless_media_head);
local_irq_enable();
// 启动解码
adapter_wireless_media_buf = buf;
}
#endif//TCFG_WIRELESS_MIC_ENABLE

View File

@ -0,0 +1,13 @@
#ifndef __ADAPTER_WIRELESS_DEC_H__
#define __ADAPTER_WIRELESS_DEC_H__
#include "generic/typedef.h"
#include "media/includes.h"
void adapter_wireless_dec_frame_init(void);
void adapter_wireless_dec_frame_close(void);
int adapter_wireless_dec_frame_write(void *data, u16 len);
int adapter_wireless_dec_open(void);
int adapter_wireless_dec_close(void);
#endif//__ADAPTER_WIRELESS_DEC_H__

View File

@ -0,0 +1,368 @@
#include "adapter_wireless_enc.h"
//#include "adapter_encoder.h"
#include "media/sbc_enc.h"
#include "app_config.h"
#if TCFG_WIRELESS_MIC_ENABLE
/* #define WIRELESS_ENCODER_SEL AUDIO_CODING_SBC */
#define WIRELESS_ENCODER_SEL AUDIO_CODING_LC3
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_SBC)
#define WIRELESS_ENC_IN_SIZE 512
#else
#define WIRELESS_ENC_IN_SIZE 480
#endif
#define WIRELESS_ENC_OUT_SIZE 256
#define WIRELESS_FRAME_SUM (1)/*一包多少帧*/
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_LC3)
#define WIRELESS_PACKET_HEADER_LEN (2)//(2 + 2)//(2)/*包头Max Length*/
#else
#define WIRELESS_PACKET_HEADER_LEN (2)//(2)/*包头Max Length*/
#endif
#define WIRELESS_PACKET_REPEAT_SUM (1)/*包重发次数*/
#define WIRELESS_ENC_OUT_BUF_SIZE (WIRELESS_ENC_OUT_SIZE * WIRELESS_FRAME_SUM)
#define WIRELESS_ENC_PCM_BUF_LEN (WIRELESS_ENC_IN_SIZE * 4)
struct __adapter_wireless_enc {
struct audio_encoder encoder;
cbuffer_t cbuf_pcm;
s16 pcm_buf[WIRELESS_ENC_PCM_BUF_LEN / 2];
s16 output_frame[WIRELESS_ENC_OUT_SIZE / 2]; // 编码输出帧
int input_frame[WIRELESS_ENC_IN_SIZE / 4];
u8 out_buf[WIRELESS_PACKET_HEADER_LEN + WIRELESS_ENC_OUT_BUF_SIZE]; // sbc帧缓存
u16 frame_in_size; // 帧输入大小
u8 frame_cnt; // 帧打包计数
u16 frame_len; // 帧长
u16 tx_seqn; // 传输计数
volatile u8 start; // 启动标志
};
static struct audio_encoder_task *wireless_encode_task = NULL;
#define MY_IO_DEBUG_0(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);}
#define MY_IO_DEBUG_1(i,x) {JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);}
static int adapter_wireless_enc_push(struct __adapter_wireless_enc *hdl, void *buf, int len)
{
if (!hdl->start) {
return 0;
}
// printf("len = %d\n", len);
int ret = 0;
extern int wireless_mic_ble_send(void *priv, u8 * buf, u16 len);
for (int i = 0; i < WIRELESS_PACKET_REPEAT_SUM; i++) {
ret = wireless_mic_ble_send(NULL, buf, len);
if (ret) {
// printf("lost ###################\n");
putchar('E');
} else {
// putchar('O');
}
}
return len;
}
static int adapter_wireless_enc_write_pcm(struct __adapter_wireless_enc *hdl, void *buf, int len)
{
if (!hdl->start) {
return 0;
}
//putchar('w');
int wlen = cbuf_write(&hdl->cbuf_pcm, buf, len);
if (cbuf_get_data_len(&hdl->cbuf_pcm) >= (hdl->frame_in_size)) {
audio_encoder_resume(&hdl->encoder);
}
return wlen;
}
static void adapter_wireless_enc_packet_pack(struct __adapter_wireless_enc *hdl, u16 len)
{
//将包的序列号写到头部
hdl->tx_seqn++;
#if (WIRELESS_PACKET_HEADER_LEN)
hdl->out_buf[0] = hdl->tx_seqn >> 8;
hdl->out_buf[1] = hdl->tx_seqn & 0xff;
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_LC3)
//memcpy(&hdl->out_buf[2], &len, 2);
#endif//AUDIO_CODING_LC3
#endif
}
static int adapter_wireless_enc_pcm_get(struct audio_encoder *encoder, s16 **frame, u16 frame_len)
{
struct __adapter_wireless_enc *hdl = container_of(encoder, struct __adapter_wireless_enc, encoder);
int pcm_len = 0;
//printf("frame_len = %d ", frame_len);
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_SBC)
frame_len = hdl->frame_in_size;
#else
if (frame_len > hdl->frame_in_size) {
printf("frame_len over limit !!!!, %d\n", frame_len);
return 0;
}
#endif
//printf("frame_len = %d\n", frame_len);
pcm_len = cbuf_read(&hdl->cbuf_pcm, hdl->input_frame, frame_len);
if (pcm_len != frame_len) {
/* putchar('L'); */
} else {
/* put_u16hex(frame_len); */
}
*frame = (s16 *)hdl->input_frame;
return pcm_len;
}
static void adapter_wireless_enc_pcm_put(struct audio_encoder *encoder, s16 *frame)
{
}
static const struct audio_enc_input adapter_wireless_enc_input = {
.fget = adapter_wireless_enc_pcm_get,
.fput = adapter_wireless_enc_pcm_put,
};
static int adapter_wireless_enc_probe_handler(struct audio_encoder *encoder)
{
return 0;
}
static int adapter_wireless_enc_output_handler(struct audio_encoder *encoder, u8 *frame, int len)
{
struct __adapter_wireless_enc *enc = container_of(encoder, struct __adapter_wireless_enc, encoder);
//检查上次是否还有数据没有发出
if (enc->frame_cnt >= WIRELESS_FRAME_SUM) {
//putchar('&');
int wlen = adapter_wireless_enc_push(enc, enc->out_buf, enc->frame_len);
if (wlen != enc->frame_len) {
return 0;
}
enc->frame_cnt = 0;
}
if (enc->frame_cnt == 0) {
//重新打包, 加包头
adapter_wireless_enc_packet_pack(enc, len);
enc->frame_len = WIRELESS_PACKET_HEADER_LEN;
}
//拼接数据内容
memcpy(&enc->out_buf[enc->frame_len], frame, len);
enc->frame_len += len;
enc->frame_cnt ++;
//检查是否达到发送条件
if (enc->frame_cnt >= WIRELESS_FRAME_SUM) {
//putchar('@');
int wlen = adapter_wireless_enc_push(enc, enc->out_buf, enc->frame_len);
if (wlen == enc->frame_len) {
enc->frame_cnt = 0;
//audio_encoder_resume(&enc->encoder);
}
}
return len;
}
const static struct audio_enc_handler adapter_wireless_enc_handler = {
.enc_probe = adapter_wireless_enc_probe_handler,
.enc_output = adapter_wireless_enc_output_handler,
};
static void adapter_wireless_enc_stop(struct __adapter_wireless_enc *hdl)
{
if (hdl->start) {
hdl->start = 0;
audio_encoder_close(&hdl->encoder);
}
}
static struct __adapter_wireless_enc *wireless_enc = NULL;
void adapter_wireless_enc_close(void)
{
if (!wireless_enc) {
return ;
}
adapter_wireless_enc_stop(wireless_enc);
local_irq_disable();
free(wireless_enc);
wireless_enc = NULL;
local_irq_enable();
}
#if 1
int adapter_wireless_enc_open_base(struct audio_fmt *fmt, u16 frame_in_size)
{
int err = 0;
if (fmt == NULL) {
log_e("wireless_enc_open parm error\n");
return -1;
}
struct __adapter_wireless_enc *hdl = zalloc(sizeof(struct __adapter_wireless_enc));
if (!hdl) {
return -1;
}
hdl->frame_in_size = frame_in_size;
// 变量初始化
cbuf_init(&hdl->cbuf_pcm, hdl->pcm_buf, sizeof(hdl->pcm_buf));
if (!wireless_encode_task) {
///这里不用SDK本身的编码线程因为编码线程成不能高于协议栈线程
wireless_encode_task = zalloc(sizeof(struct audio_encoder_task));
if (!wireless_encode_task) {
printf("wireless_encode_task NULL !!!\n");
}
printf("wireless_encode_task 1111\n");
audio_encoder_task_create(wireless_encode_task, "wl_mic_enc");
}
printf("wireless_encode_task 2222\n");
audio_encoder_open(&hdl->encoder, &adapter_wireless_enc_input, wireless_encode_task);
audio_encoder_set_handler(&hdl->encoder, &adapter_wireless_enc_handler);
audio_encoder_set_fmt(&hdl->encoder, fmt);
audio_encoder_set_output_buffs(&hdl->encoder, hdl->output_frame, sizeof(hdl->output_frame), 1);
if (!hdl->encoder.enc_priv) {
log_e("encoder err, maybe coding(0x%x) disable \n", fmt.coding_type);
err = -EINVAL;
goto __err;
}
printf("wireless_encode_task 3333\n");
audio_encoder_start(&hdl->encoder);
printf("wireless_encode_task 4444\n");
hdl->start = 1;
local_irq_disable();
wireless_enc = hdl;
local_irq_enable();
return 0;
__err:
audio_encoder_close(&hdl->encoder);
local_irq_disable();
free(hdl);
hdl = NULL;
local_irq_enable();
return err;
}
#endif
int adapter_wireless_enc_write(void *buf, int len)
{
if (!wireless_enc) {
return 0;
}
int wlen = adapter_wireless_enc_write_pcm(wireless_enc, buf, len);
if (wlen != len) {
putchar('L');
}
return wlen;
}
//static struct audio_stream_entry g_entry; // 音频流入口
static sbc_t g_sbc_param = {0};
u16 g_sample_rate = 44100;
u8 g_channel = 2;
static int adapter_wireless_enc_data_handler(struct audio_stream_entry *entry, struct audio_data_frame *in,
struct audio_data_frame *out)
{
int wlen = adapter_wireless_enc_write(in->data, in->data_len);
if (wlen == in->data_len) {
//putchar('W');
} else {
//putchar('M');
}
return in->data_len;
}
int adapter_wireless_enc_open(void)
{
struct audio_fmt fmt = {0};
u16 frame_in_size = 0;
#if (WIRELESS_ENCODER_SEL == AUDIO_CODING_SBC)
sbc_t *sbc_param = &g_sbc_param;
sbc_param->frequency = SBC_FREQ_44100;
sbc_param->blocks = SBC_BLK_16;
sbc_param->subbands = SBC_SB_8;
sbc_param->mode = SBC_MODE_STEREO;
sbc_param->allocation = 0;
sbc_param->endian = SBC_LE;
sbc_param->bitpool = 19;//53;
printf("sbc_param->bitpool ============================ %d\n", sbc_param->bitpool);
switch (g_sample_rate) {
case 16000:
sbc_param->frequency = SBC_FREQ_16000;
break;
case 32000:
sbc_param->frequency = SBC_FREQ_32000;
break;
case 44100:
sbc_param->frequency = SBC_FREQ_44100;
break;
case 48000:
sbc_param->frequency = SBC_FREQ_48000;
break;
}
if (g_channel == 1) {
sbc_param->mode = SBC_MODE_MONO;
frame_in_size = WIRELESS_ENC_IN_SIZE / 2;
} else {
sbc_param->mode = SBC_MODE_STEREO;
frame_in_size = WIRELESS_ENC_IN_SIZE;
}
fmt.coding_type = AUDIO_CODING_SBC;
fmt.sample_rate = g_sample_rate;
fmt.channel = g_channel;
fmt.priv = &g_sbc_param;
#else
extern const int LC3_DMS_VAL; //单位ms, 【只支持 25,50,100】
fmt.coding_type = AUDIO_CODING_LC3;
fmt.sample_rate = 44100;//g_sample_rate;
#if (TCFG_WIRELESS_MIC_STEREO_EN)
fmt.channel = 2;
#else
fmt.channel = 1;
#endif
fmt.bit_rate = 64000;//128000;//64000;//128000;
fmt.frame_len = LC3_DMS_VAL;//2.5 * 10;
if (fmt.channel == 1) {
frame_in_size = WIRELESS_ENC_IN_SIZE / 2;
} else {
frame_in_size = WIRELESS_ENC_IN_SIZE;
}
#endif
adapter_wireless_enc_open_base(&fmt, frame_in_size);
return 0;
}
#endif//TCFG_WIRELESS_MIC_ENABLE

View File

@ -0,0 +1,13 @@
#ifndef __ADAPTER_WIRELESS_ENC_H__
#define __ADAPTER_WIRELESS_ENC_H__
#include "asm/includes.h"
#include "generic/typedef.h"
#include "media/includes.h"
int adapter_wireless_enc_write(void *buf, int len);
int adapter_wireless_enc_open(void);
void adapter_wireless_enc_close(void);
#endif//__ADAPTER_WIRELESS_ENC_H__

View File

@ -0,0 +1,453 @@
#include "system/includes.h"
#include "media/includes.h"
#include "app_config.h"
#include "app_task.h"
#include "btstack/avctp_user.h"
#include "btstack/btstack_task.h"
#include "btstack/bluetooth.h"
#include "btstack/btstack_error.h"
#include "btctrler/btctrler_task.h"
#include "classic/hci_lmp.h"
#include "bt_ble.h"
#include "bt_common.h"
#include "spp_user.h"
#include "app_chargestore.h"
#include "app_charge.h"
#include "app_main.h"
#include "app_power_manage.h"
#include "user_cfg.h"
#include "asm/pwm_led.h"
#include "system/timer.h"
#include "asm/hwi.h"
#include "cpu.h"
#include "ui/ui_api.h"
#include "tone_player.h"
#include "bt_edr_fun.h"
#include "adapter_process.h"
//#include "adapter_decoder.h"
#include "aec_user.h"
#include "ui_manage.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[BT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
struct app_bt_opr app_bt_hdl = {
.exit_flag = 1,
.replay_tone_flag = 1,
.esco_dump_packet = ESCO_DUMP_PACKET_CALL,
.hid_mode = 0,
.wait_exit = 0,
};
#define __this (&app_bt_hdl)
extern BT_USER_PRIV_VAR bt_user_priv_var;
u8 get_bt_init_status(void)
{
return __this->init_ok;
}
u8 is_call_now(void)
{
if (get_call_status() != BT_CALL_HANGUP) {
return 1;
}
return 0;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙模式led状态更新
@param
@return status : 蓝牙状态
@note
*/
/*----------------------------------------------------------------------------*/
void bt_set_led_status(u8 status)
{
#if 1
static u8 bt_status = STATUS_BT_INIT_OK;
if (status) {
bt_status = status;
}
pwm_led_mode_set(PWM_LED_ALL_OFF);
ui_update_status(bt_status);
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙spp 协议数据 回调
@param packet_type:数据类型
ch :
packet :数据缓存
size :数据长度
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void spp_data_handler(u8 packet_type, u16 ch, u8 *packet, u16 size)
{
switch (packet_type) {
case 1:
log_debug("spp connect\n");
break;
case 2:
log_debug("spp disconnect\n");
break;
case 7:
//log_info("spp_rx:");
//put_buf(packet,size);
#if AEC_DEBUG_ONLINE
aec_debug_online(packet, size);
#endif
break;
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙获取在连接设备名字回调
@param status : 1获取失败 0获取成功
addr : 配对设备地址
name :配对设备名字
@return
@note 需要连接上设备后发起USER_CTRL_READ_REMOTE_NAME
命令来
*/
/*----------------------------------------------------------------------------*/
__attribute__((weak))
void remote_name_speciali_deal(u8 status, u8 *addr, u8 *name)
{
}
static void bt_read_remote_name(u8 status, u8 *addr, u8 *name)
{
if (status) {
log_debug("remote_name fail \n");
} else {
log_debug("remote_name : %s \n", name);
}
log_debug_hexdump(addr, 6);
remote_name_speciali_deal(status, addr, name);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙歌词信息获取回调
@param
@return
@note
const u8 more_avctp_cmd_support = 1;置上1
需要在void bredr_handle_register()注册回调函数
要动态获取播放时间的可以发送USER_CTRL_AVCTP_OPID_GET_PLAY_TIME命令就可以了
要半秒或者1秒获取就做个定时发这个命令
*/
/*----------------------------------------------------------------------------*/
static void user_get_bt_music_info(u8 type, u32 time, u8 *info, u16 len)
{
//profile define type: 1-title 2-artist name 3-album names 4-track number 5-total number of tracks 6-genre 7-playing time
//JL define 0x10-total time , 0x11 current play position
u8 min, sec;
//printf("type %d\n", type );
if ((info != NULL) && (len != 0)) {
log_debug(" %s \n", info);
}
if (time != 0) {
min = time / 1000 / 60;
sec = time / 1000 - (min * 60);
log_debug(" time %d %d\n ", min, sec);
}
}
//音量同步
static void vol_sys_tab_init(void)
{
}
static void bt_set_music_device_volume(int volume)
{
r_printf("bt_set_music_device_volume : %d\n", volume);
}
static int phone_get_device_vol(void)
{
//音量同步最大是127请计数比例
#if 0
return (app_var.sys_vol_l * get_max_sys_vol() / 127) ;
#else
return app_var.opid_play_vol_sync;
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙模式协议栈功能配置
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_function_select_init()
{
set_idle_period_slot(1600);
////设置协议栈支持设备数
__set_user_ctrl_conn_num(TCFG_BD_NUM);
////msbc功能使能
__set_support_msbc_flag(1);
#if TCFG_BT_SUPPORT_AAC
////AAC功能使能
__set_support_aac_flag(1);
#else
__set_support_aac_flag(0);
#endif
#if BT_SUPPORT_DISPLAY_BAT
////设置更新电池电量的时间间隔
__bt_set_update_battery_time(60);
#else
__bt_set_update_battery_time(0);
#endif
////回连搜索时间长度设置,可使用该函数注册使用ms单位,u16
__set_page_timeout_value(8000);
////回连时超时参数设置。ms单位。做主机有效
__set_super_timeout_value(8000);
#if (TCFG_BD_NUM == 2)
////设置开机回链的设备个数
__set_auto_conn_device_num(2);
#endif
#if BT_SUPPORT_MUSIC_VOL_SYNC
////设置音乐音量同步的表
vol_sys_tab_init();
#endif
////设置蓝牙是否跑后台
__set_user_background_goback(BACKGROUND_GOBACK); // 后台链接是否跳回蓝牙 1:跳回
////设置蓝牙加密的level
//io_capabilities ; /*0: Display only 1: Display YesNo 2: KeyboardOnly 3: NoInputNoOutput*/
//authentication_requirements: 0:not protect 1 :protect
__set_simple_pair_param(3, 0, 2);
#if (USER_SUPPORT_PROFILE_PBAP==1)
////设置蓝牙设备类型
__change_hci_class_type(BD_CLASS_CAR_AUDIO);
#endif
#if (TCFG_BT_SNIFF_ENABLE == 0)
void lmp_set_sniff_disable(void);
lmp_set_sniff_disable();
#endif
/*
TX RX
AI800x PA13 PA12
AC692x PA13 PA12
AC693x PA8 PA9
AC695x PA9 PA10
AC696x PA9 PA10
AC694x PB1 PB2
AC697x PC2 PC3
AC631x PA7 PA8
*/
////设置蓝牙接收状态io输出可以外接pa
/* bt_set_rxtx_status_enable(1); */
#if TCFG_USER_BLE_ENABLE
{
u8 tmp_ble_addr[6];
lib_make_ble_address(tmp_ble_addr, (void *)bt_get_mac_addr());
le_controller_set_mac((void *)tmp_ble_addr);
printf("\n-----edr + ble 's address-----");
printf_buf((void *)bt_get_mac_addr(), 6);
printf_buf((void *)tmp_ble_addr, 6);
}
#endif // TCFG_USER_BLE_ENABLE
#if (CONFIG_BT_MODE != BT_NORMAL)
set_bt_enhanced_power_control(1);
#endif
}
extern u8 get_cur_battery_level(void);
static int bt_get_battery_value()
{
//取消默认蓝牙定时发送电量给手机需要更新电量给手机使用USER_CTRL_HFP_CMD_UPDATE_BATTARY命令
/*电量协议的是0-9个等级请比例换算*/
return get_cur_battery_level();
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙模式协议栈回调函数
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
static void bredr_handle_register()
{
#if (USER_SUPPORT_PROFILE_SPP==1)
#if APP_ONLINE_DEBUG
extern void online_spp_init(void);
spp_data_deal_handle_register(user_spp_data_handler);
online_spp_init();
#else
spp_data_deal_handle_register(spp_data_handler);
#endif
#endif
#if BT_SUPPORT_MUSIC_VOL_SYNC
///蓝牙音乐和通话音量同步
music_vol_change_handle_register(bt_set_music_device_volume, phone_get_device_vol);
#endif
#if BT_SUPPORT_DISPLAY_BAT
///电量显示获取电量的接口
get_battery_value_register(bt_get_battery_value);
#endif
extern void bt_fast_test_api(void);
///被测试盒链接上进入快速测试回调
bt_fast_test_handle_register(bt_fast_test_api);
//extern void bt_dut_api(u8 value);
///样机进入dut被测试仪器链接上回调
//bt_dut_test_handle_register(bt_dut_api);
///获取远端设备蓝牙名字回调
read_remote_name_handle_register(bt_read_remote_name);
////获取歌曲信息回调
/* bt_music_info_handle_register(user_get_bt_music_info); */
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙直接开关
@param
@return
@note 如果想后台开机不需要进蓝牙可以在poweron模式
直接调用这个函数初始化蓝牙
*/
/*----------------------------------------------------------------------------*/
extern void sys_auto_shut_down_enable(void);
extern void sys_auto_sniff_controle(u8 enable, u8 *addr);
void bt_init()
{
if (__this->bt_direct_init) {
return;
}
log_info(" bt_direct_init \n");
u32 sys_clk = clk_get("sys");
bt_pll_para(TCFG_CLOCK_OSC_HZ, sys_clk, 0, 0);
__this->ignore_discon_tone = 0;
__this->bt_direct_init = 1;
bt_function_select_init();
bredr_handle_register();
btstack_init();
/* 按键消息使能 */
sys_key_event_enable();
sys_auto_shut_down_enable();
sys_auto_sniff_controle(1, NULL);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙 退出蓝牙等待蓝牙状态可以退出
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_close_check(void *priv)
{
if (bt_user_priv_var.auto_connection_timer) {
sys_timeout_del(bt_user_priv_var.auto_connection_timer);
bt_user_priv_var.auto_connection_timer = 0;
}
if (__this->init_ok == 0) {
/* putchar('#'); */
return;
}
// if (bt_audio_is_running()) {
// /* putchar('$'); */
// return;
// }
#if TCFG_USER_BLE_ENABLE
bt_ble_exit();
#endif
btstack_exit();
log_info(" bt_direct_close_check ok\n");
sys_timer_del(__this->timer);
__this->init_ok = 0;
__this->init_start = 0;
__this->timer = 0;
__this->bt_direct_init = 0;
set_stack_exiting(0);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙后台直接关闭
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void bt_close(void)
{
if (__this->init_ok == 0) {
/* putchar('#'); */
return;
}
log_info(" bt_direct_close");
__this->ignore_discon_tone = 1;
sys_auto_shut_down_disable();
set_stack_exiting(1);
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
if (__this->timer == 0) {
__this->tmr_cnt = 0;
__this->timer = sys_timer_add(NULL, bt_close_check, 10);
printf("set exit timer\n");
}
}
#endif

View File

@ -0,0 +1,710 @@
#include "app_config.h"
#include "app_task.h"
#include "btstack/avctp_user.h"
#include "btstack/btstack_task.h"
#include "btstack/bluetooth.h"
#include "btstack/btstack_error.h"
#include "btctrler/btctrler_task.h"
#include "classic/hci_lmp.h"
#include "bt_ble.h"
#include "bt_common.h"
#include "spp_user.h"
#include "app_main.h"
#include "app_power_manage.h"
#include "ui/ui_api.h"
#include "bt_edr_fun.h"
#include "adapter_process.h"
//#include "adapter_decoder.h"
#include "adapter_odev_bt.h"
//#include "dongle_1t2.h"
#include "ui_manage.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[BT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
u8 set_call_vol_flag = 0;
#define __this (&app_bt_hdl)
static u8 bt_dev_role = 0;
void set_bt_dev_role(u8 role)
{
bt_dev_role |= BIT(role);
}
/*************************************************************
蓝牙模式协议栈状态事件处理
**************************************************************/
static void bt_status_init_ok(struct bt_event *bt)
{
__this->init_ok = 1;
if (__this->init_ok_time == 0) {
__this->init_ok_time = timer_get_ms();
__this->auto_exit_limit_time = POWERON_AUTO_CONN_TIME * 1000;
}
#if TCFG_USER_BLE_ENABLE
if (BT_MODE_IS(BT_BQB)) {
ble_bqb_test_thread_init();
} else {
}
#endif
bt_set_led_status(STATUS_BT_INIT_OK);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 设备连接上状态
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_connect(struct bt_event *bt)
{
sys_auto_sniff_controle(1, NULL);
sys_auto_shut_down_disable();
#if (TCFG_BD_NUM == 2)
if (get_current_poweron_memory_search_index(NULL) == 0) {
#if !USER_SUPPORT_DUAL_A2DP_SOURCE
bt_wait_phone_connect_control(1);
#endif
}
#endif
bt_set_led_status(STATUS_BT_CONN); //单台在此处设置连接状态,对耳的连接状态需要同步在bt_tws.c中去设置
#if (TCFG_AUTO_STOP_PAGE_SCAN_TIME && TCFG_BD_NUM == 2)
if (get_total_connect_dev() == 1) { //当前有一台连接上了
if (app_var.auto_stop_page_scan_timer == 0) {
app_var.auto_stop_page_scan_timer = sys_timeout_add(NULL, bt_close_page_scan, (TCFG_AUTO_STOP_PAGE_SCAN_TIME * 1000)); //2
}
} else {
if (app_var.auto_stop_page_scan_timer) {
sys_timeout_del(app_var.auto_stop_page_scan_timer);
app_var.auto_stop_page_scan_timer = 0;
}
}
#endif //endif AUTO_STOP_PAGE_SCAN_TIME
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 设备断开连接
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_disconnect(struct bt_event *bt)
{
log_info("BT_STATUS_DISCONNECT\n");
sys_auto_sniff_controle(0, NULL);
__this->call_flag = 0;
if (get_total_connect_dev() == 0) { //已经没有设备连接
if (!app_var.goto_poweroff_flag) { /*关机时不改UI*/
bt_set_led_status(STATUS_BT_DISCONN);
}
sys_auto_shut_down_enable();
}
#if USER_SUPPORT_DUAL_A2DP_SOURCE
dongle_1t2_bt_disconn(bt);
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机来电
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_phone_income(struct bt_event *bt)
{
__this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
ui_update_status(STATUS_PHONE_INCOME);
u8 tmp_bd_addr[6];
memcpy(tmp_bd_addr, bt->args, 6);
/*
*(1)1t2有一台通话的时候另一台如果来电不要提示
*(2)1t2两台同时来电现来的题示后来的不播
*/
if ((check_esco_state_via_addr(tmp_bd_addr) != BD_ESCO_BUSY_OTHER) && (bt_user_priv_var.phone_ring_flag == 0)) {
#if BT_INBAND_RINGTONE
extern u8 get_device_inband_ringtone_flag(void);
bt_user_priv_var.inband_ringtone = get_device_inband_ringtone_flag();
#else
bt_user_priv_var.inband_ringtone = 0 ;
lmp_private_esco_suspend_resume(3);
#endif
bt_user_priv_var.phone_ring_flag = 1;
bt_user_priv_var.phone_income_flag = 1;
#if 0
#if BT_PHONE_NUMBER
phone_num_play_start();
#else
phone_ring_play_start();
#endif
#endif
user_send_cmd_prepare(USER_CTRL_HFP_CALL_CURRENT, 0, NULL); //发命令获取电话号码
} else {
/* log_debug("SCO busy now:%d,%d\n", check_esco_state_via_addr(tmp_bd_addr), bt_user_priv_var.phone_ring_flag); */
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机打出电话
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_phone_out(struct bt_event *bt)
{
lmp_private_esco_suspend_resume(4);
__this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
ui_update_status(STATUS_PHONE_OUT);
bt_user_priv_var.phone_income_flag = 0;
user_send_cmd_prepare(USER_CTRL_HFP_CALL_CURRENT, 0, NULL); //发命令获取电话号码
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙通话音量同步,设置音量
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void phone_sync_vol(void *priv)
{
log_debug("phone_sync_vol\n");
bt_user_priv_var.phone_vol = 14;
user_send_cmd_prepare(USER_CTRL_HFP_CALL_SET_VOLUME, 1, &bt_user_priv_var.phone_vol);
user_send_cmd_prepare(USER_CTRL_HFP_CALL_VOLUME_UP, 0, NULL);
bt_user_priv_var.phone_vol = 15;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机接通电话
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_phone_active(struct bt_event *bt)
{
ui_update_status(STATUS_PHONE_ACTIV);
if (bt_user_priv_var.phone_call_dec_begin) {
/* log_debug("call_active,dump_packet clear\n"); */
__this->esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
}
if (bt_user_priv_var.phone_ring_flag) {
bt_user_priv_var.phone_ring_flag = 0;
//tone_play_stop();
if (bt_user_priv_var.phone_timer_id) {
sys_timeout_del(bt_user_priv_var.phone_timer_id);
bt_user_priv_var.phone_timer_id = 0;
}
}
lmp_private_esco_suspend_resume(4);
bt_user_priv_var.phone_income_flag = 0;
bt_user_priv_var.phone_num_flag = 0;
bt_user_priv_var.phone_con_sync_num_ring = 0;
bt_user_priv_var.phone_con_sync_ring = 0;
bt_user_priv_var.phone_vol = 15;
/* log_debug("phone_active:%d\n", app_var.call_volume); */
#ifdef PHONE_CALL_DEFAULT_MAX_VOL
set_call_vol_flag |= BIT(1);
if ((BIT(1) | BIT(2)) == set_call_vol_flag) {
//app_audio_set_volume(APP_AUDIO_STATE_CALL, 15, 1);
sys_timeout_add(NULL, phone_sync_vol, 1200);
}
#else
//app_audio_set_volume(APP_AUDIO_STATE_CALL, app_var.call_volume, 1);
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机挂断电话
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_phone_hangup(struct bt_event *bt)
{
__this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
/* log_info("phone_handup\n"); */
if (bt_user_priv_var.phone_ring_flag) {
bt_user_priv_var.phone_ring_flag = 0;
//tone_play_stop();
if (bt_user_priv_var.phone_timer_id) {
sys_timeout_del(bt_user_priv_var.phone_timer_id);
bt_user_priv_var.phone_timer_id = 0;
}
}
lmp_private_esco_suspend_resume(4);
bt_user_priv_var.phone_num_flag = 0;
bt_user_priv_var.phone_con_sync_num_ring = 0;
bt_user_priv_var.phone_con_sync_ring = 0;
__this->call_back_flag &= ~BIT(0);
if (get_call_status() == BT_CALL_HANGUP) {
//call handup
set_call_vol_flag = 0;
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机来电号码
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_phone_number(struct bt_event *bt)
{
u8 *phone_number = NULL;
phone_number = (u8 *)bt->value;
//put_buf(phone_number, strlen((const char *)phone_number));
if (bt_user_priv_var.phone_num_flag == 1) {
return ;
}
bt_user_priv_var.income_phone_len = 0;
memset(bt_user_priv_var.income_phone_num, '\0', sizeof(bt_user_priv_var.income_phone_num));
for (int i = 0; i < strlen((const char *)phone_number); i++) {
if (phone_number[i] >= '0' && phone_number[i] <= '9') {
//过滤,只有数字才能报号
bt_user_priv_var.income_phone_num[bt_user_priv_var.income_phone_len++] = phone_number[i];
if (bt_user_priv_var.income_phone_len >= sizeof(bt_user_priv_var.income_phone_num)) {
return; /*buffer 空间不够,后面不要了*/
}
}
}
if (bt_user_priv_var.income_phone_len > 0) {
bt_user_priv_var.phone_num_flag = 1;
} else {
log_debug("PHONE_NUMBER len err\n");
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机来电铃声
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_inband_ringtone(struct bt_event *bt)
{
#if BT_INBAND_RINGTONE
bt_user_priv_var.inband_ringtone = bt->value;
#else
bt_user_priv_var.inband_ringtone = 0;
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机高级音频开始播放
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_a2dp_media_start(struct bt_event *bt)
{
__this->call_flag = 0;
__this->a2dp_start_flag = 1;
//a2dp_dec_open(bt->value);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机高级音频停止播放
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_a2dp_media_stop(struct bt_event *bt)
{
__this->a2dp_start_flag = 0;
//a2dp_dec_close();
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机通话链路切换
@param
@return
@note 手机音频切换、微信等都会有这个状态
*/
/*----------------------------------------------------------------------------*/
static void bt_status_sco_change(struct bt_event *bt, struct _odev_bt *odev_bt)
{
extern void mem_stats(void);
mem_stats();
struct _odev_edr *edr = odev_bt->edr;
/* log_info(" BT_STATUS_SCO_STATUS_CHANGE len:%d ,type:%d", (bt->value >> 16), (bt->value & 0x0000ffff)); */
if (bt->value != 0xff) {
#ifdef PHONE_CALL_DEFAULT_MAX_VOL
set_call_vol_flag |= BIT(2);
if ((BIT(1) | BIT(2)) == set_call_vol_flag) {
sys_timeout_add(NULL, phone_sync_vol, 1200);
}
#endif
log_info("<<<<<<<<<<<esco_dec_stat : %x\n", bt->value);
__this->call_back_flag |= BIT(1);
//app_reset_vddiom_lev(VDDIOM_VOL_32V);
__this->sco_info = bt->value;
if (edr->fun) {
edr->fun(edr->priv, edr->mode, 1, &bt->value);
}
/* esco_dec_open(&bt->value, 0); */
bt_user_priv_var.phone_call_dec_begin = 1;
if (get_call_status() == BT_CALL_ACTIVE) {
log_debug("dec_begin,dump_packet clear\n");
__this->esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
}
} else {
log_info("<<<<<<<<<<<esco_dec_stop\n");
__this->call_back_flag &= ~BIT(1);
//app_reset_vddiom_lev(VDDIOM_VOL_34V);
set_call_vol_flag &= ~BIT(2);
bt_user_priv_var.phone_call_dec_begin = 0;
__this->esco_dump_packet = ESCO_DUMP_PACKET_CALL;
#if 0
if (edr->fun) {
edr->fun(edr->priv, edr->mode, 0, &bt->value);
}
#endif
if (odev_edr.start_a2dp_flag) {
//start a2dp
y_printf("start a2dp\n");
extern int a2dp_pp(u8 pp);
a2dp_pp(1);
odev_edr.start_a2dp_flag = 0;
}
/* esco_dec_close(); */
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机通话过程中设置音量产生状态
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_call_vol_change(struct bt_event *bt)
{
u8 volume = bt->value; //app_audio_get_max_volume() * bt->value / 15;
u8 call_status = get_call_status();
bt_user_priv_var.phone_vol = bt->value;
if ((call_status == BT_CALL_ACTIVE) || (call_status == BT_CALL_OUTGOING) || app_var.siri_stu) {
//app_audio_set_volume(APP_AUDIO_STATE_CALL, volume, 1);
} else if (call_status != BT_CALL_HANGUP) {
/*只保存不设置到dac*/
app_var.call_volume = volume;
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 样机和链接设备进入sniff模式后返回来的状态
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_sniff_state_update(struct bt_event *bt)
{
if (bt->value == 0) {
sys_auto_sniff_controle(1, bt->args);
} else {
sys_auto_sniff_controle(0, bt->args);
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 最后拨打电话类型
@param
@return
@note 只区分打入和打出
*/
/*----------------------------------------------------------------------------*/
static void bt_status_last_call_type_change(struct bt_event *bt)
{
__this->call_back_flag |= BIT(0);
bt_user_priv_var.last_call_type = bt->value;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 高级音频链接上
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_conn_a2dp_ch(struct bt_event *bt)
{
r_printf("bt_status_conn_a2dp_ch\n");
extern void adapter_process_event_notify(u8 event, int value);
#if USER_SUPPORT_DUAL_A2DP_SOURCE
if (get_total_connect_dev() == 2) {
r_printf("%s,%d", __func__, __LINE__);
__emitter_send_media_toggle(bt->args, 1);
} else {
r_printf("%s,%d", __func__, __LINE__);
adapter_process_event_notify(ADAPTER_EVENT_ODEV_MEDIA_OPEN, 0);
}
dongle_1t2_connect(bt);
#else
adapter_process_event_notify(ADAPTER_EVENT_ODEV_MEDIA_OPEN, 0);
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 手机音频链接上
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_conn_hfp_ch(struct bt_event *bt)
{
#if !TCFG_USER_EMITTER_ENABLE
if ((!is_1t2_connection()) && (get_current_poweron_memory_search_index(NULL))) { //回连下一个device
if (get_esco_coder_busy_flag()) {
clear_current_poweron_memory_search_index(0);
} else {
user_send_cmd_prepare(USER_CTRL_START_CONNECTION, 0, NULL);
}
}
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 获取手机厂商
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_phone_menufactuer(struct bt_event *bt)
{
extern const u8 hid_conn_depend_on_dev_company;
app_var.remote_dev_company = bt->value;
if (hid_conn_depend_on_dev_company) {
if (bt->value) {
//user_send_cmd_prepare(USER_CTRL_HID_CONN, 0, NULL);
} else {
user_send_cmd_prepare(USER_CTRL_HID_DISCONNECT, 0, NULL);
}
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 语音识别
@param
@return
@note bt->value 0-siri关闭状态
1-siri开启状态
2-手动打开siri成功状态.
3-安卓手机上选择语音识别软件状态
*/
/*----------------------------------------------------------------------------*/
static void bt_status_voice_recognition(struct bt_event *bt)
{
__this->esco_dump_packet = ESCO_DUMP_PACKET_DEFAULT;
app_var.siri_stu = bt->value;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙status 接收远端设备发过来的avrcp命令
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void bt_status_avrcp_income_opid(struct bt_event *bt)
{
#define AVC_VOLUME_UP 0x41
#define AVC_VOLUME_DOWN 0x42
log_debug("BT_STATUS_AVRCP_INCOME_OPID:%d\n", bt->value);
if (bt->value == AVC_VOLUME_UP) {
}
if (bt->value == AVC_VOLUME_DOWN) {
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙模式协议栈对应状态处理函数
@param bt:事件
@return
@note 蓝牙初始化完成、链接、通话播歌等状态
*/
/*----------------------------------------------------------------------------*/
int bt_connction_status_event_handler(struct bt_event *bt, struct _odev_bt *odev_bt)
{
g_printf("-----------------------bt_connction_status_event_handler %d\n", bt->event);
switch (bt->event) {
case BT_STATUS_EXIT_OK:
log_info("BT_STATUS_EXIT_OK\n");
break;
case BT_STATUS_INIT_OK:
log_info("BT_STATUS_INIT_OK\n");
bt_status_init_ok(bt);
extern void adapter_process_event_notify(u8 event, int value);
if (bt_dev_role & BIT(BT_AS_IDEV)) {
adapter_process_event_notify(ADAPTER_EVENT_IDEV_INIT_OK, 0);
}
if (bt_dev_role & BIT(BT_AS_ODEV)) {
adapter_process_event_notify(ADAPTER_EVENT_ODEV_INIT_OK, 0);
}
log_info("BT_STATUS_INIT_OK &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n");
break;
case BT_STATUS_START_CONNECTED:
log_info(" BT_STATUS_START_CONNECTED\n");
break;
case BT_STATUS_ENCRY_COMPLETE:
log_info(" BT_STATUS_ENCRY_COMPLETE\n");
break;
case BT_STATUS_SECOND_CONNECTED:
log_info(" BT_STATUS_SECOND_CONNECTED\n");
clear_current_poweron_memory_search_index(0);
case BT_STATUS_FIRST_CONNECTED:
log_info("BT_STATUS_CONNECTED\n");
bt_status_connect(bt);
break;
case BT_STATUS_FIRST_DISCONNECT:
case BT_STATUS_SECOND_DISCONNECT:
log_info(" BT_STATUS_SECOND_DISCONNECT\n");
bt_status_disconnect(bt);
break;
case BT_STATUS_PHONE_INCOME:
log_info("BT_STATUS_PHONE_INCOME\n");
bt_status_phone_income(bt);
break;
case BT_STATUS_PHONE_OUT:
log_info("BT_STATUS_PHONE_OUT\n");
bt_status_phone_out(bt);
break;
case BT_STATUS_PHONE_ACTIVE:
log_info("BT_STATUS_PHONE_ACTIVE\n");
bt_status_phone_active(bt);
break;
case BT_STATUS_PHONE_HANGUP:
log_info(" BT_STATUS_PHONE_HANGUP\n");
bt_status_phone_hangup(bt);
break;
case BT_STATUS_PHONE_NUMBER:
log_info("BT_STATUS_PHONE_NUMBER\n");
bt_status_phone_number(bt);
break;
case BT_STATUS_INBAND_RINGTONE:
log_info("BT_STATUS_INBAND_RINGTONE\n");
bt_status_inband_ringtone(bt);
break;
case BT_STATUS_BEGIN_AUTO_CON:
log_info("BT_STATUS_BEGIN_AUTO_CON\n");
break;
case BT_STATUS_A2DP_MEDIA_START:
log_info(" BT_STATUS_A2DP_MEDIA_START\n");
bt_status_a2dp_media_start(bt);
break;
case BT_STATUS_A2DP_MEDIA_STOP:
log_info(" BT_STATUS_A2DP_MEDIA_STOP");
bt_status_a2dp_media_stop(bt);
break;
case BT_STATUS_SCO_STATUS_CHANGE:
log_info(" BT_STATUS_SCO_STATUS_CHANGE");
bt_status_sco_change(bt, odev_bt);
break;
case BT_STATUS_CALL_VOL_CHANGE:
log_info(" BT_STATUS_CALL_VOL_CHANGE ");
bt_status_call_vol_change(bt);
break;
case BT_STATUS_SNIFF_STATE_UPDATE:
log_info(" BT_STATUS_SNIFF_STATE_UPDATE \n"); //0退出SNIFF
bt_status_sniff_state_update(bt);
break;
case BT_STATUS_LAST_CALL_TYPE_CHANGE:
log_info("BT_STATUS_LAST_CALL_TYPE_CHANGE\n");
bt_status_last_call_type_change(bt);
break;
case BT_STATUS_CONN_A2DP_CH:
bt_status_conn_a2dp_ch(bt);
/* break; */
case BT_STATUS_CONN_HFP_CH:
bt_status_conn_hfp_ch(bt);
break;
case BT_STATUS_PHONE_MANUFACTURER:
log_info("BT_STATUS_PHONE_MANUFACTURER\n");
bt_status_phone_menufactuer(bt);
break;
case BT_STATUS_VOICE_RECOGNITION:
log_info(" BT_STATUS_VOICE_RECOGNITION \n");
bt_status_voice_recognition(bt);
break;
case BT_STATUS_AVRCP_INCOME_OPID:
log_info(" BT_STATUS_AVRCP_INCOME_OPID \n");
bt_status_avrcp_income_opid(bt);
break;
case BT_STATUS_RECONN_OR_CONN:
log_info(" BT_STATUS_RECONN_OR_CONN \n");
break;
default:
log_info(" BT STATUS DEFAULT\n");
break;
}
return 0;
}
#endif

View File

@ -0,0 +1,52 @@
#include "adapter_idev.h"
#include "app_config.h"
#if TCFG_WIRELESS_MIC_ENABLE
struct idev *adapter_idev_open(u16 id, void *parm)
{
struct idev *dev = NULL;
list_for_each_adapter_idev(dev) {
if (dev->id == id) {
if (dev->open) {
dev->open(parm);
}
return dev;
}
}
return NULL;
}
void adapter_idev_close(struct idev *dev)
{
if (dev && dev->close) {
dev->close();
}
}
int adapter_idev_start(struct idev *dev, struct adapter_media *media)
{
if (dev && dev->start) {
return dev->start(media);
}
return 0;
}
void adapter_idev_stop(struct idev *dev)
{
if (dev && dev->stop) {
dev->stop();
}
}
int adapter_idev_event_deal(struct idev *dev, struct sys_event *event)
{
if (dev && dev->event_fun) {
return dev->event_fun(event);
}
return 0;
}
#endif

View File

@ -0,0 +1,43 @@
#ifndef __ADAPTER_IDEV_H__
#define __ADAPTER_IDEV_H__
#include "generic/typedef.h"
#include "adapter_media.h"
#include "wireless_mic_test.h"
#include "app_config.h"
enum adapter_idev_type {
ADAPTER_IDEV_USB = 0x0,
ADAPTER_IDEV_MIC,
ADAPTER_IDEV_BT,
};
struct idev {
u16 id;
int (*open)(void *parm);
void (*close)(void);
int (*start)(struct adapter_media *media);
void (*stop)(void);
int (*event_fun)(struct sys_event *);
//其他操作
};
struct idev *adapter_idev_open(u16 id, void *parm);
void adapter_idev_close(struct idev *dev);
int adapter_idev_start(struct idev *dev, struct adapter_media *media);
void adapter_idev_stop(struct idev *dev);
int adapter_idev_event_deal(struct idev *dev, struct sys_event *event);
#define REGISTER_ADAPTER_IDEV(ops) \
const struct idev ops sec(.adapter_idev)
extern const struct idev adapter_idev_begin[];
extern const struct idev adapter_idev_end[];
#define list_for_each_adapter_idev(p) \
for (p = adapter_idev_begin; p < adapter_idev_end; p++)
#endif//__ADAPTER_IDEV_H__

View File

@ -0,0 +1,118 @@
#include "adapter_idev.h"
#include "adapter_idev_bt.h"
#include "adapter_idev_ble.h"
#include "list.h"
#include "os/os_api.h"
#include "circular_buf.h"
#include "app_config.h"
#include "adapter_process.h"
#include "bt_edr_fun.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[IDEV_BT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
struct _idev_bt idev_bt;
#define __this (&idev_bt)
static int adapter_idev_bt_open(void *parm)
{
r_printf("adapter_idev_bt_open\n");
memset(__this, 0, sizeof(struct _idev_bt));
set_bt_dev_role(BT_AS_IDEV);
__this->parm = (struct _idev_bt_parm *)parm;
if (__this->parm->mode & BIT(IDEV_BLE)) {
adapter_idev_ble_open(&__this->parm->ble_parm);
}
bt_init();
__this->ble = &idev_ble;
return 0;
}
static int adapter_idev_bt_start(struct adapter_media *media)
{
printf("adapter_idev_bt_start\n");
if (__this->parm->mode & BIT(IDEV_BLE)) {
adapter_idev_ble_start(NULL);
}
return 0;
}
static int adapter_idev_bt_office(struct sys_event *event)
{
int ret = 0;
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
bt_connction_status_event_handler(&event->u.bt, __this);
} else if ((u32)event->arg == SYS_BT_EVENT_TYPE_HCI_STATUS) {
//bt_hci_event_handler(&event->u.bt, __this);
}
return ret;
}
static int adapter_idev_bt_event_deal(struct sys_event *event)
{
//r_printf("adapter_odev_bt_event_deal\n");
int ret = 0;
switch (event->type) {
case SYS_KEY_EVENT:
break;
case SYS_DEVICE_EVENT:
break;
case SYS_BT_EVENT:
adapter_idev_bt_office(event);
ret = 1;
break;
default:
break;
}
return ret;
}
static int adapter_idev_bt_close(void)
{
r_printf("adapter_idev_bt_close\n");
if (__this->parm->mode & BIT(IDEV_BLE)) {
adapter_idev_ble_close(NULL);
}
return 0;
}
static int adapter_idev_bt_stop(void *priv)
{
r_printf("adapter_idev_bt_stop\n");
if (__this->parm->mode & BIT(IDEV_BLE)) {
adapter_idev_ble_stop(NULL);
}
return 0;
}
REGISTER_ADAPTER_IDEV(adapter_idev_bt) = {
.id = ADAPTER_IDEV_BT,
.open = adapter_idev_bt_open,
.close = adapter_idev_bt_close,
.start = adapter_idev_bt_start,
.stop = adapter_idev_bt_stop,
.event_fun = adapter_idev_bt_event_deal,
};
#endif

View File

@ -0,0 +1,155 @@
#include "adapter_idev.h"
#include "adapter_idev_bt.h"
#include "adapter_idev_ble.h"
#include "app_config.h"
#include "btstack/le/att.h"
#include "btstack/le/le_user.h"
#include "ble_user.h"
#include "btcontroller_modules.h"
#include "adapter_process.h"
#include "adapter_wireless_dec.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[IDEV_BLE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
struct _idev_ble idev_ble;
#define __this (&idev_ble)
extern void bt_ble_adv_enable(u8 enable);
extern void bt_ble_init(void);
int adpter_ble_send_data(u8 *data, u16 len)
{
if (__this->ble_opt) {
u32 vaild_len = __this->ble_opt->get_buffer_vaild(0);
if (vaild_len >= len) {
return __this->ble_opt->send_data(NULL, data, len);
}
}
return 0;
}
static void adapter_ble_send_wakeup(void)
{
//putchar('W');
}
static void adapter_ble_status_callback(void *priv, ble_state_e status)
{
switch (status) {
case BLE_ST_IDLE:
break;
case BLE_ST_ADV:
break;
case BLE_ST_CONNECT:
break;
case BLE_ST_DISCONN:
case BLE_ST_SEND_DISCONN:
adapter_process_event_notify(ADAPTER_EVENT_IDEV_MEDIA_CLOSE, 0);
break;
case BLE_ST_NOTIFY_IDICATE:
break;
case BLE_ST_CONNECTION_UPDATE_OK:
adapter_process_event_notify(ADAPTER_EVENT_IDEV_MEDIA_OPEN, 0);
break;
default:
break;
}
}
static void adapter_ble_recieve_cbk(void *priv, u8 *buf, u16 len)
{
//r_printf("adapter --- ble_api_rx(%d) \n", len);
//printf_buf(buf, len);
adapter_wireless_dec_frame_write(buf, len);
}
int adapter_idev_ble_open(void *priv)
{
r_printf("adapter_idev_ble_open\n");
if (__this->status == IDEV_BLE_OPEN) {
g_printf("adapter_idev_ble_already_open\n");
return 0;
}
memset(__this, 0, sizeof(struct _idev_ble));
#if TRANS_DATA_EN || BLE_WIRELESS_MIC_SERVER_EN
ble_get_server_operation_table(&__this->ble_opt);
__this->ble_opt->regist_recieve_cbk(0, adapter_ble_recieve_cbk);
__this->ble_opt->regist_state_cbk(0, adapter_ble_status_callback);
__this->ble_opt->regist_wakeup_send(NULL, adapter_ble_send_wakeup);
#endif
__this->status = IDEV_BLE_OPEN;
return 0;
}
int adapter_idev_ble_start(void *priv)
{
r_printf("adapter_idev_ble_start\n");
if (__this->status == IDEV_BLE_START) {
r_printf("adapter_idev_ble_already_start\n");
return 0;
}
__this->status = IDEV_BLE_START;
#if TRANS_DATA_EN || BLE_WIRELESS_MIC_SERVER_EN
bt_ble_init();
#endif
return 0;
}
int adapter_idev_ble_stop(void *priv)
{
r_printf("adapter_idev_ble_stop\n");
if (__this->status == IDEV_BLE_STOP) {
r_printf("adapter_idev_ble_already_stop\n");
return 0;
}
__this->status = IDEV_BLE_STOP;
#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_SERVER_EN
ble_module_enable(0);
#endif
return 0;
}
int adapter_idev_ble_close(void *priv)
{
r_printf("adapter_idev_ble_close\n");
if (__this->status == IDEV_BLE_CLOSE) {
r_printf("adapter_idev_ble_already_close\n");
return 0;
}
__this->status = IDEV_BLE_CLOSE;
#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_SERVER_EN
ble_module_enable(0);
#endif
return 0;
}
int adapter_idev_ble_config(int cmd, void *parm)
{
switch (cmd) {
case 0:
break;
default:
break;
}
return 0;
}
#endif

View File

@ -0,0 +1,31 @@
#ifndef __ADAPTER_IDEV_BLE_H__
#define __ADAPTER_IDEV_BLE_H__
#include "generic/typedef.h"
enum {
IDEV_BLE_CLOSE,
IDEV_BLE_OPEN,
IDEV_BLE_START,
IDEV_BLE_STOP,
};
struct _idev_ble_parm {
};
struct _idev_ble {
u8 status;
struct ble_server_operation_t *ble_opt;
};
int adapter_idev_ble_open(void *priv);
int adapter_idev_ble_start(void *priv);
int adapter_idev_ble_stop(void *priv);
int adapter_idev_ble_close(void *priv);
int adapter_idev_ble_config(int cmd, void *parm);
extern struct _idev_ble idev_ble;
#endif//__ADAPTER_IDEV_BLE_H__

View File

@ -0,0 +1,24 @@
#ifndef __ADAPTER_IDEV_BT_H__
#define __ADAPTER_IDEV_BT_H__
#include "generic/typedef.h"
#include "adapter_idev_ble.h"
enum {
IDEV_EDR = 0x0,
IDEV_BLE,
};
struct _idev_bt_parm {
u8 mode;
struct _idev_ble_parm ble_parm;
};
struct _idev_bt {
struct _idev_bt_parm *parm;
struct _idev_ble *ble;
};
#endif//__ADAPTER_IDEV_BT_H__

View File

@ -0,0 +1,92 @@
#include "adapter_idev_mic.h"
#include "adapter_process.h"
#include "adapter_adc.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define ADAPTER_IDEV_MIC_DEBUG_ENABLE
#ifdef ADAPTER_IDEV_MIC_DEBUG_ENABLE
#define adapter_idev_mic_printf printf
#define adapter_idev_mic_putchar putchar
#define adapter_idev_mic_putbuf put_buf
#else
#define adapter_idev_mic_printf (...)
#define adapter_idev_mic_putchar(...)
#define adapter_idev_mic_putbuf (...)
#endif //ADAPTER_IDEV_MIC_DEBUG_ENABLE
#if (TCFG_AUDIO_ADC_ENABLE)
#define ADAPTER_IDEV_MIC_DEBUG_ENABLE
#ifdef ADAPTER_IDEV_MIC_DEBUG_ENABLE
#define adapter_idev_mic_printf printf
#define adapter_idev_mic_putchar putchar
#define adapter_idev_mic_putbuf put_buf
#else
#define adapter_idev_mic_printf (...)
#define adapter_idev_mic_putchar(...)
#define adapter_idev_mic_putbuf (...)
#endif //ADAPTER_IDEV_MIC_DEBUG_ENABLE
static int adapter_idev_mic_open(void *parm)
{
//adc初始化
adapter_adc_init();
//事件通知主流程, idev设备初始化完成
adapter_process_event_notify(ADAPTER_EVENT_IDEV_INIT_OK, 0);
return 0;
}
static int adapter_idev_mic_close(void)
{
//事件通知主流程停止媒体
adapter_process_event_notify(ADAPTER_EVENT_IDEV_MEDIA_CLOSE, 0);
return 0;
}
static int adapter_idev_mic_start(struct adapter_media *media)
{
//idev设备启动这里mic输入比较简单 这里直接告知主流程请求启动音频媒体
adapter_process_event_notify(ADAPTER_EVENT_IDEV_MEDIA_OPEN, 0);
return 0;
}
static void adapter_idev_mic_stop(void)
{
}
static int adapter_idev_mic_event_handle(struct sys_event *e)
{
//这里可以响应系统事件,根据设备情景, 将idev设备需要响应的事件在这里统一处理
//可以响应按键事件、设备事件等, 根据实际情景自行解析
int ret = 0;
switch (e->type) {
case SYS_DEVICE_EVENT:
break;
default:
break;
}
return ret;
}
REGISTER_ADAPTER_IDEV(adapter_idev_mic) = {
.id = ADAPTER_IDEV_MIC,
.open = adapter_idev_mic_open,
.close = adapter_idev_mic_close,
.start = adapter_idev_mic_start,
.stop = adapter_idev_mic_stop,
.event_fun = adapter_idev_mic_event_handle,
};
#endif//TCFG_AUDIO_ADC_ENABLE
#endif

View File

@ -0,0 +1,9 @@
#ifndef __ADAPTER_IDEV_MIC_H__
#define __ADAPTER_IDEV_MIC_H__
#include "generic/typedef.h"
#include "adapter_idev.h"
#endif //__ADAPTER_IDEV_MIC_H__

View File

@ -0,0 +1,100 @@
#include "adapter_odev.h"
#if TCFG_WIRELESS_MIC_ENABLE
struct odev *adapter_odev_open(u16 id, void *parm)
{
g_printf("adapter_odev_open\n");
struct odev *dev = NULL;
list_for_each_adapter_odev(dev) {
if (dev->id == id) {
if (dev->open) {
dev->open(parm);
}
return dev;
}
}
return NULL;
}
void adapter_odev_start(struct odev *dev, struct adapter_media *media)
{
g_printf("adapter_odev_start\n");
if (dev && dev->start) {
dev->start(NULL, media);
}
return;
}
void adapter_odev_stop(struct odev *dev)
{
g_printf("adapter_odev_stop\n");
if (dev && dev->stop) {
dev->stop(NULL);
}
return;
}
void adapter_odev_close(struct odev *dev)
{
g_printf("adapter_odev_close\n");
if (dev && dev->close) {
dev->close(NULL);
}
return;
}
int adapter_odev_get_status(struct odev *dev)
{
g_printf("adapter_odev_get_status\n");
if (dev && dev->get_status) {
return (dev->get_status(NULL));
}
return 0;
}
int adapter_odev_media_pp(struct odev *dev, u8 pp)
{
g_printf("adapter_odev_media_pp\n");
if (dev && dev->media_pp) {
return (dev->media_pp(pp));
}
return 0;
}
int adapter_odev_media_prepare(struct odev *dev, u8 mode, int (*fun)(void *, u8, u8, void *), void *priv)
{
g_printf("adapter_odev_media_prepare\n");
if (dev && dev->media_prepare) {
return dev->media_prepare(mode, fun, priv);
}
return -1;
}
int adapter_odev_event_deal(struct odev *dev, struct sys_event *event)
{
if (dev && dev->event_fun) {
return dev->event_fun(event);
}
return 0;
}
void adapter_odev_config(struct odev *dev, int cmd, void *priv)
{
g_printf("adapter_odev_config\n");
if (dev && dev->config) {
dev->config(cmd, priv);
}
return;
}
int adapter_odev_output(struct odev *dev, void *priv, u8 *buf, u16 len)
{
int ret = 0;
if (dev && dev->output) {
ret = dev->output(priv, buf, len);
}
return ret;
}
#endif

View File

@ -0,0 +1,56 @@
#ifndef __ADAPTER_ODEV_H__
#define __ADAPTER_ODEV_H__
#include "generic/typedef.h"
#include "adapter_odev_bt.h"
#include "adapter_media.h"
#include "wireless_mic_test.h"
#include "event.h"
enum adapter_odev_type {
ADAPTER_ODEV_BT = 0x0,
ADAPTER_ODEV_DAC,
ADAPTER_ODEV_USB,
};
enum {
ADAPTER_ODEV_PAUSE = 0x0,
ADAPTER_ODEV_PLAY,
};
struct odev {
u16 id;
int (*open)(void *);
int (*start)(void *, struct adapter_media *);
int (*stop)(void *);
int (*close)(void *);
int (*get_status)(void *);
int (*media_pp)(u8);
int (*media_prepare)(u8, int (*fun)(void *, u8, u8, void *), void *);
int (*event_fun)(struct sys_event *);
int (*config)(int cmd, void *parm);
int (*output)(void *, u8 *, u16);
};
struct odev *adapter_odev_open(u16 id, void *parm);
void adapter_odev_start(struct odev *dev, struct adapter_media *media);
void adapter_odev_stop(struct odev *dev);
void adapter_odev_close(struct odev *dev);
int adapter_odev_get_status(struct odev *dev);
int adapter_odev_media_pp(struct odev *dev, u8 pp);
int adapter_odev_media_prepare(struct odev *dev, u8 mode, int (*fun)(void *, u8, u8, void *), void *priv);
int adapter_odev_event_deal(struct odev *dev, struct sys_event *event);
void adapter_odev_config(struct odev *dev, int cmd, void *priv);
int adapter_odev_output(struct odev *dev, void *priv, u8 *buf, u16 len);
#define REGISTER_ADAPTER_ODEV(ops) \
const struct odev ops sec(.adapter_odev)
extern const struct odev adapter_odev_begin[];
extern const struct odev adapter_odev_end[];
#define list_for_each_adapter_odev(p) \
for (p = adapter_odev_begin; p < adapter_odev_end; p++)
#endif//__ADAPTER_ODEV_H__

View File

@ -0,0 +1,213 @@
#include "adapter_odev.h"
#include "adapter_odev_bt.h"
#include "adapter_odev_edr.h"
#include "adapter_odev_ble.h"
#include "btstack/avctp_user.h"
#include "classic/hci_lmp.h"
#include "list.h"
#include "os/os_api.h"
#include "circular_buf.h"
#include "app_config.h"
#include "adapter_process.h"
#include "btstack/bluetooth.h"
#include "btstack/btstack_error.h"
#include "bt_edr_fun.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[ODEV_BT]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
struct _odev_bt odev_bt;
#define __this (&odev_bt)
static int adapter_odev_bt_open(void *parm)
{
r_printf("adapter_odev_bt_open\n");
memset(__this, 0, sizeof(struct _odev_bt));
set_bt_dev_role(BT_AS_ODEV);
__this->parm = (struct _odev_bt_parm *)parm;
#if 0 //parm test
g_printf("bt filt:%d spp filt:%d addr filt:%d\n", __this->parm->edr_parm.bt_name_filt_num, __this->parm->edr_parm.spp_name_filt_num, __this->parm->edr_parm.bd_addr_filt_num);
for (u8 i = 0; i < __this->parm->edr_parm.bt_name_filt_num; i++) {
printf("%d:%s\n", i, __this->parm->edr_parm.bt_name_filt[i]);
}
for (u8 i = 0; i < __this->parm->edr_parm.spp_name_filt_num; i++) {
printf("%d:%s\n", i, __this->parm->edr_parm.spp_name_filt[i]);
}
for (u8 i = 0; i < __this->parm->edr_parm.bd_addr_filt_num; i++) {
put_buf(__this->parm->edr_parm.bd_addr_filt[i], 6);
}
#endif
if (__this->parm->mode & BIT(ODEV_BLE)) {
adapter_odev_ble_open(&__this->parm->ble_parm);
}
bt_init();
if (__this->parm->mode & BIT(ODEV_EDR)) {
#if 0 //for test,config edr_bt_name by config_tool
extern const char *bt_get_local_name();
memset(__this->parm->edr_parm.bt_name_filt[0], 0x00, LOCAL_NAME_LEN);
memcpy(__this->parm->edr_parm.bt_name_filt[0], (u8 *)(bt_get_local_name()), LOCAL_NAME_LEN);
#endif
adapter_odev_edr_open(&__this->parm->edr_parm);
}
__this->edr = &odev_edr;
__this->ble = &odev_ble;
return 0;
}
static int adapter_odev_bt_start(void *priv, struct adapter_media *media)
{
r_printf("adapter_odev_bt_start\n");
if (__this->parm->mode & BIT(ODEV_EDR)) {
adapter_odev_edr_start(NULL);
}
if (__this->parm->mode & BIT(ODEV_BLE)) {
adapter_odev_ble_start(NULL);
}
return 0;
}
static int adapter_odev_bt_stop(void *priv)
{
r_printf("adapter_odev_bt_stop\n");
if (__this->parm->mode & BIT(ODEV_EDR)) {
adapter_odev_edr_stop(NULL);
}
if (__this->parm->mode & BIT(ODEV_BLE)) {
adapter_odev_ble_stop(NULL);
}
return 0;
}
static int adapter_odev_bt_close(void)
{
r_printf("adapter_odev_bt_close\n");
if (__this->parm->mode & BIT(ODEV_EDR)) {
adapter_odev_edr_close(NULL);
}
if (__this->parm->mode & BIT(ODEV_BLE)) {
adapter_odev_ble_close(NULL);
}
return 0;
}
static int adapter_odev_bt_get_status(void *priv)
{
if (__this->parm->mode & BIT(ODEV_EDR)) {
return adapter_odev_edr_get_status(NULL);
}
return 0;
}
static int adapter_odev_bt_pp_ctl(u8 pp)
{
if (__this->parm->mode & BIT(ODEV_EDR)) {
return adapter_odev_edr_pp(pp);
}
return 0;
}
static int adapter_odev_bt_media_prepare(u8 mode, int (*fun)(void *, u8, u8, void *), void *priv)
{
if (__this->parm->mode & BIT(ODEV_EDR)) {
return adapter_odev_edr_media_prepare(mode, fun, priv);
}
return -1;
}
static int adapter_odev_bt_office(struct sys_event *event)
{
int ret = 0;
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
bt_connction_status_event_handler(&event->u.bt, __this);
} else if ((u32)event->arg == SYS_BT_EVENT_TYPE_HCI_STATUS) {
//bt_hci_event_handler(&event->u.bt, __this);
}
return ret;
}
static int adapter_odev_bt_event_deal(struct sys_event *event)
{
//r_printf("adapter_odev_bt_event_deal\n");
int ret = 0;
switch (event->type) {
case SYS_KEY_EVENT:
break;
case SYS_DEVICE_EVENT:
break;
case SYS_BT_EVENT:
adapter_odev_bt_office(event);
ret = 1;
break;
default:
break;
}
return ret;
}
static int adapter_odev_bt_config(int cmd, void *parm)
{
r_printf("adapter_odev_bt_config\n");
if (__this->parm->mode & BIT(ODEV_EDR)) {
adapter_odev_edr_config(cmd, parm);
}
if (__this->parm->mode & BIT(ODEV_BLE)) {
adapter_odev_ble_config(cmd, parm);
}
return 0;
}
static int adapter_odev_bt_send(void *priv, u8 *buf, u16 len)
{
int ret = -1;
if (__this->parm->mode & BIT(ODEV_BLE)) {
ret = adapter_odev_ble_send(priv, buf, len);
}
return ret;
}
REGISTER_ADAPTER_ODEV(adapter_odev_bt) = {
.id = ADAPTER_ODEV_BT,
.open = adapter_odev_bt_open,
.start = adapter_odev_bt_start,
.stop = adapter_odev_bt_stop,
.close = adapter_odev_bt_close,
.media_pp = adapter_odev_bt_pp_ctl,
.get_status = adapter_odev_bt_get_status,
.media_prepare = adapter_odev_bt_media_prepare,
.event_fun = adapter_odev_bt_event_deal,
.config = adapter_odev_bt_config,
.output = adapter_odev_bt_send,
};
#endif

View File

@ -0,0 +1,64 @@
#ifndef __ADAPTER_ODEV_BLE_H__
#define __ADAPTER_ODEV_BLE_H__
#include "generic/typedef.h"
#include "le_client_demo.h"
#include "app_config.h"
#define DEVICE_RSSI_LEVEL (-50)
#define POWER_ON_PAIR_TIME (3500)//unit ms,切换搜索回连周期
struct _odev_ble_parm {
client_conn_cfg_t *cfg_t;
};
enum {
ODEV_BLE_CLOSE,
ODEV_BLE_OPEN,
ODEV_BLE_START,
ODEV_BLE_STOP,
};
enum {
MATCH_KEYBOARD,
MATCH_MOUSE,
MATCH_NULL,
};
struct _odev_ble {
u16 ble_connected;
u16 ble_timer_id;
u8 status;
u8 match_type;
struct ble_client_operation_t *ble_client_api;
struct _odev_ble_parm *parm;
};
int adapter_odev_ble_open(void *priv);
int adapter_odev_ble_start(void *priv);
int adapter_odev_ble_stop(void *priv);
int adapter_odev_ble_close(void *priv);
int adapter_odev_ble_config(int cmd, void *parm);
int adapter_odev_ble_send(void *priv, u8 *buf, u16 len);
void adapter_odev_ble_search_device(void);
//dongle
void dongle_ble_report_data_deal(att_data_report_t *report_data, target_uuid_t *search_uuid);
void dongle_adapter_event_callback(le_client_event_e event, u8 *packet, int size);
int dongle_ble_send(void *priv, u8 *buf, u16 len);
//wireless_mic
void wireless_mic_ble_report_data_deal(att_data_report_t *report_data, target_uuid_t *search_uuid);
void wireless_adapter_event_callback(le_client_event_e event, u8 *packet, int size);
int wireless_mic_ble_send(void *priv, u8 *buf, u16 len);
#define BLE_REPORT_DATA_DEAL(a,b) wireless_mic_ble_report_data_deal(a,b)
#define ADAPTER_EVENT_CALLBACK(a,b,c) wireless_adapter_event_callback(a,b,c)
#define ADAPTER_ODEV_BLE_SEND(a,b,c) wireless_mic_ble_send(a,b,c)
extern struct _odev_ble odev_ble;
extern client_conn_cfg_t odev_ble_conn_config;
#endif//__ADAPTER_ODEV_BLE_H__

View File

@ -0,0 +1,26 @@
#ifndef __ADAPTER_ODEV_BT_H__
#define __ADAPTER_ODEV_BT_H__
#include "generic/typedef.h"
#include "adapter_odev_edr.h"
#include "adapter_odev_ble.h"
enum {
ODEV_EDR = 0x0,
ODEV_BLE,
};
struct _odev_bt_parm {
u8 mode;
struct _odev_edr_parm edr_parm;
struct _odev_ble_parm ble_parm;
};
struct _odev_bt {
struct _odev_bt_parm *parm;
struct _odev_edr *edr;
struct _odev_ble *ble;
};
#endif//__ADAPTER_ODEV_BT_H__

View File

@ -0,0 +1,80 @@
#ifndef __ADAPTER_ODEV_EDR_H__
#define __ADAPTER_ODEV_EDR_H__
#include "generic/typedef.h"
#include "user_cfg.h"
#include "event.h"
#include "sbc_enc.h"
#define SEARCH_BD_ADDR_LIMITED 0
#define SEARCH_BD_NAME_LIMITED 1
#define SEARCH_CUSTOM_LIMITED 2
#define SEARCH_NULL_LIMITED 3
#define SEARCH_LIMITED_MODE SEARCH_BD_NAME_LIMITED
enum {
ODEV_EDR_CLOSE,
ODEV_EDR_OPEN,
ODEV_EDR_START,
ODEV_EDR_STOP,
};
struct _odev_edr {
struct list_head inquiry_noname_head;
u8 edr_search_busy;
u8 edr_read_name_start;
u8 edr_search_spp;
u8 status;
int (*fun)(void *, u8, u8, void *);
void *priv;
u8 mode;
u16 call_timeout;
volatile u16 start_a2dp_flag;
struct _odev_edr_parm *parm;
};
struct _odev_edr_parm {
u8 poweron_start_search : 1;
u8 disable_filt : 1;
u8 discon_always_search : 1;
u8 inquiry_len;
u8 search_type;
u8 bt_name_filt_num;
u8(*bt_name_filt)[LOCAL_NAME_LEN];
u8 spp_name_filt_num;
u8(*spp_name_filt)[LOCAL_NAME_LEN];
u8 bd_addr_filt_num;
u8(*bd_addr_filt)[6];
};
typedef enum {
AVCTP_OPID_VOLUME_UP = 0x41,
AVCTP_OPID_VOLUME_DOWN = 0x42,
AVCTP_OPID_MUTE = 0x43,
AVCTP_OPID_PLAY = 0x44,
AVCTP_OPID_STOP = 0x45,
AVCTP_OPID_PAUSE = 0x46,
AVCTP_OPID_NEXT = 0x4B,
AVCTP_OPID_PREV = 0x4C,
} AVCTP_CMD_TYPE;
int adapter_odev_edr_open(void *priv);
int adapter_odev_edr_start(void *priv);
int adapter_odev_edr_stop(void *priv);
int adapter_odev_edr_close(void *priv);
int adapter_odev_edr_get_status(void *priv);
int adapter_odev_edr_config(int cmd, void *parm);
int adapter_odev_edr_pp(u8 pp);
int adapter_odev_edr_media_prepare(u8 mode, int (*fun)(void *, u8, u8, void *), void *priv);
void adapter_odev_edr_search_device(void);
void adapter_odev_edr_search_stop();
extern struct _odev_edr odev_edr;
#endif//__ADAPTER_ODEV_BT_H__

View File

@ -0,0 +1,197 @@
#include "adapter_odev.h"
#include "adapter_odev_ble.h"
#include "app_config.h"
#include "btstack/le/att.h"
#include "btstack/le/le_user.h"
#include "ble_user.h"
#include "btcontroller_modules.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[ODEV_BLE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
struct _odev_ble odev_ble;
#define __this (&odev_ble)
extern void ble_module_enable(u8 en);
extern void bt_ble_init(void);
static void ble_report_data_deal(att_data_report_t *report_data, target_uuid_t *search_uuid)
{
/* dongle_ble_report_data_deal(report_data,search_uuid); */
/* wireless_mic_ble_report_data_deal(report_data,search_uuid); */
BLE_REPORT_DATA_DEAL(report_data, search_uuid);
}
static void adapter_event_callback(le_client_event_e event, u8 *packet, int size)
{
/* dongle_adapter_event_callback(event,packet,size); */
/* wireless_adapter_event_callback(event,packet,size); */
ADAPTER_EVENT_CALLBACK(event, packet, size);
}
//client default 信息
client_conn_cfg_t odev_ble_conn_config = {
.match_dev_cfg[0] = NULL, //匹配指定的名字
.match_dev_cfg[1] = NULL,
.match_dev_cfg[2] = NULL,
.search_uuid_cnt = 0,
.security_en = 0, //加密配对
.report_data_callback = ble_report_data_deal,
.event_callback = adapter_event_callback,
};
int adapter_odev_ble_open(void *priv)
{
r_printf("adapter_odev_ble_open\n");
if (__this->status == ODEV_BLE_OPEN) {
r_printf("adapter_odev_ble_already_open\n");
return 0;
}
memset(__this, 0, sizeof(struct _odev_ble));
__this->status = ODEV_BLE_OPEN;
__this->match_type = MATCH_NULL;
if (priv) {
__this->parm = (struct _odev_ble_parm *)priv;
if (__this->parm->cfg_t->match_dev_cfg[0]) {
odev_ble_conn_config.match_dev_cfg[0] = __this->parm->cfg_t->match_dev_cfg[0];
}
if (__this->parm->cfg_t->match_dev_cfg[1]) {
odev_ble_conn_config.match_dev_cfg[1] = __this->parm->cfg_t->match_dev_cfg[1];
}
if (__this->parm->cfg_t->match_dev_cfg[2]) {
odev_ble_conn_config.match_dev_cfg[2] = __this->parm->cfg_t->match_dev_cfg[2];
}
if (__this->parm->cfg_t->search_uuid_table) {
odev_ble_conn_config.search_uuid_table = __this->parm->cfg_t->search_uuid_table;
}
odev_ble_conn_config.search_uuid_cnt = __this->parm->cfg_t->search_uuid_cnt;
odev_ble_conn_config.security_en = __this->parm->cfg_t->security_en;
if (odev_ble_conn_config.match_dev_cfg[0]) {
y_printf("match_dev_cfg[0] : %s\n", odev_ble_conn_config.match_dev_cfg[0]->compare_data);
}
if (odev_ble_conn_config.match_dev_cfg[1]) {
y_printf("match_dev_cfg[1] : %s\n", odev_ble_conn_config.match_dev_cfg[1]->compare_data);
}
if (odev_ble_conn_config.match_dev_cfg[2]) {
y_printf("match_dev_cfg[2] : %s\n", odev_ble_conn_config.match_dev_cfg[2]->compare_data);
}
}
#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_CLIENT_EN
__this->ble_client_api = ble_get_client_operation_table();
ASSERT(__this->ble_client_api, "%s : %s : %d\n", __FUNCTION__, "ble_client_api == NULL", __LINE__);
__this->ble_client_api->init_config(0, &odev_ble_conn_config);
extern void ble_vendor_set_hold_prio(u8 role, u8 enable);
ble_vendor_set_hold_prio(0, 1);
#ifndef CONFIG_NEW_BREDR_ENABLE
//优化多连接,卡音
bredr_link_vendor_support_packet_enable(PKT_TYPE_2DH5_EU, 0);
#endif //CONFIG_NEW_BREDR_ENABLE
#endif //#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_CLIENT_EN
return 0;
}
void adapter_odev_ble_search_device(void)
{
#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_CLIENT_EN
ble_module_enable(1);
#endif
}
int adapter_odev_ble_start(void *priv)
{
r_printf("adapter_odev_ble_start\n");
if (__this->status == ODEV_BLE_START) {
r_printf("adapter_odev_ble_already_start\n");
return 0;
}
__this->status = ODEV_BLE_START;
#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_CLIENT_EN
bt_ble_init();
#endif
return 0;
}
int adapter_odev_ble_stop(void *priv)
{
r_printf("adapter_odev_ble_stop\n");
if (__this->status == ODEV_BLE_STOP) {
r_printf("adapter_odev_ble_already_stop\n");
return 0;
}
__this->status = ODEV_BLE_STOP;
#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_CLIENT_EN
ble_module_enable(0);
#endif
return 0;
}
int adapter_odev_ble_close(void *priv)
{
r_printf("adapter_odev_ble_close\n");
if (__this->status == ODEV_BLE_CLOSE) {
r_printf("adapter_odev_ble_already_close\n");
return 0;
}
__this->status = ODEV_BLE_CLOSE;
#if BLE_CLIENT_EN || TRANS_MULTI_BLE_EN || BLE_WIRELESS_MIC_CLIENT_EN
ble_module_enable(0);
#endif
__this->ble_client_api = NULL;
return 0;
}
int adapter_odev_ble_send(void *priv, u8 *buf, u16 len)
{
int ret = 0;
if (!__this->ble_connected) {
r_printf("adapter_odev_ble not connect\n");
return -1;
}
ret = ADAPTER_ODEV_BLE_SEND(priv, buf, len);
return ret;
}
int adapter_odev_ble_config(int cmd, void *parm)
{
switch (cmd) {
case 0:
break;
default:
break;
}
return 0;
}
#endif

View File

@ -0,0 +1,153 @@
#include "adapter_odev.h"
#include "adapter_odev_ble.h"
#include "app_config.h"
#include "btstack/le/att.h"
#include "btstack/le/le_user.h"
#include "ble_user.h"
#include "btcontroller_modules.h"
#include "adapter_process.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[ODEV_BLE]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if (APP_MAIN == APP_WIRELESS_MIC)
#define __this (&odev_ble)
#define CLIENT_SENT_TEST 0
static u16 ble_client_timer = 0;
static void client_test_write(void)
{
static u8 count = 0;
u32 maxVaildAttValue = 141;
u8 test_buf[145];
printf(" %x ", count);
memset(test_buf, count, sizeof(test_buf));
int ret = __this->ble_client_api->opt_comm_send(0x0006, &test_buf, maxVaildAttValue + 4, ATT_OP_WRITE_WITHOUT_RESPOND);
if (APP_BLE_BUFF_FULL != ret) {
count++;
}
}
void wireless_mic_ble_report_data_deal(att_data_report_t *report_data, target_uuid_t *search_uuid)
{
switch (report_data->packet_type) {
case GATT_EVENT_NOTIFICATION:
//notify
y_printf("value_handle:%x conn_handle:%x uuid:%x\n", report_data->value_handle, report_data->conn_handle, search_uuid->services_uuid16);
break;
case GATT_EVENT_INDICATION: //indicate
log_info("indication handle:%04x,len= %d\n", report_data->value_handle, report_data->blob_length);
put_buf(report_data->blob, report_data->blob_length);
break;
case GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT: //read
log_info("read handle:%04x,len= %d\n", report_data->value_handle, report_data->blob_length);
put_buf(report_data->blob, report_data->blob_length);
break;
case GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT: //read long
log_info("read_long handle:%04x,len= %d\n", report_data->value_handle, report_data->blob_length);
put_buf(report_data->blob, report_data->blob_length);
break;
default:
break;
}
}
void wireless_adapter_event_callback(le_client_event_e event, u8 *packet, int size)
{
printf(" wireless_adapter_event_callback==================\n");
switch (event) {
case CLI_EVENT_MATCH_DEV:
client_match_cfg_t *match_dev = packet;
log_info("match_name:%s\n", match_dev->compare_data);
break;
case CLI_EVENT_MATCH_UUID:
r_printf("CLI_EVENT_MATCH_UUID\n");
opt_handle_t *opt_hdl = packet;
log_info("match_uuid handle : %x\n", opt_hdl->value_handle);
break;
case CLI_EVENT_SEARCH_PROFILE_COMPLETE:
log_info("search profile commplete");
__this->ble_connected = 2;
break;
case CLI_EVENT_CONNECTED:
log_info("bt connected");
__this->ble_connected = 1;
break;
case CLI_EVENT_CONNECTION_UPDATE:
printf("==============================CLI_EVENT_CONNECTION_UPDATE\n");
#if CLIENT_SENT_TEST
ble_client_timer = sys_timer_add(NULL, client_test_write, 100);
#endif
adapter_process_event_notify(ADAPTER_EVENT_ODEV_MEDIA_OPEN, 0);
break;
case CLI_EVENT_DISCONNECT:
__this->ble_connected = 0;
#if CLIENT_SENT_TEST
if (ble_client_timer) {
sys_timer_del(ble_client_timer);
}
ble_client_timer = 0;
#endif
adapter_process_event_notify(ADAPTER_EVENT_ODEV_MEDIA_CLOSE, 0);
log_info("bt disconnec");
break;
default:
break;
}
}
int wireless_mic_ble_send(void *priv, u8 *buf, u16 len)
{
// if (len > 145) {
// printf("ble send max len is 145 !!!!!, len = %d\n", len);
// return -1;
// }
int ret = __this->ble_client_api->opt_comm_send(0x0006, buf, len, ATT_OP_WRITE_WITHOUT_RESPOND);
return ret;
}
#else
void wireless_mic_ble_report_data_deal(att_data_report_t *report_data, target_uuid_t *search_uuid)
{
}
void wireless_adapter_event_callback(le_client_event_e event, u8 *packet, int size)
{
}
int wireless_mic_ble_send(void *priv, u8 *buf, u16 len)
{
return 0;
}
#endif
#endif

View File

@ -0,0 +1,702 @@
#include "adapter_odev.h"
#include "adapter_odev_bt.h"
#include "adapter_odev_edr.h"
//#include "wireless_mic/bt.h"
#include "btstack/avctp_user.h"
#include "classic/hci_lmp.h"
#include "list.h"
#include "os/os_api.h"
#include "circular_buf.h"
#include "app_config.h"
#include "event.h"
#include "bt_edr_fun.h"
#include "usb/device/hid.h"
#if TCFG_WIRELESS_MIC_ENABLE
#define LOG_TAG_CONST WIRELESSMIC
#define LOG_TAG "[ODEV_EDR]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
struct _odev_edr odev_edr;
#define __this (&odev_edr)
struct inquiry_noname_remote {
struct list_head entry;
u8 match;
s8 rssi;
u8 addr[6];
u32 class;
};
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射发起搜索设备
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void adapter_odev_edr_search_device(void)
{
if (!get_bt_init_status()) {
return;
}
printf("__this->edr_search_busy = %d", __this->edr_search_busy);
if (__this->edr_search_busy) {
return;
}
////断开链接
if (get_curr_channel_state() != 0) {
user_send_cmd_prepare(USER_CTRL_POWER_OFF, 0, NULL);
} else {
if (hci_standard_connect_check()) {
user_send_cmd_prepare(USER_CTRL_PAGE_CANCEL, 0, NULL);
user_send_cmd_prepare(USER_CTRL_CONNECTION_CANCEL, 0, NULL);
}
}
/* if there are some connected channel ,then disconnect*/
////关闭可发现可链接
user_send_cmd_prepare(USER_CTRL_WRITE_SCAN_DISABLE, 0, NULL);
user_send_cmd_prepare(USER_CTRL_WRITE_CONN_DISABLE, 0, NULL);
__this->edr_read_name_start = 0;
__this->edr_search_busy = 1;
u8 inquiry_length = __this->parm->inquiry_len; // inquiry_length * 1.28s
user_send_cmd_prepare(USER_CTRL_SEARCH_DEVICE, 1, &inquiry_length);
printf("[adapter] %s, %d\n", __FUNCTION__, __LINE__);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射发起搜索spp设备
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void adapter_odev_edr_search_spp_device()
{
__this->edr_search_spp = 1;
set_start_search_spp_device(1);
adapter_odev_edr_search_device();
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射停止搜索
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void adapter_odev_edr_search_stop()
{
log_info("adapter_odev_edr_search_stop\n");
struct inquiry_noname_remote *remote, *n;
__this->edr_search_spp = 0;
__this->edr_search_busy = 0;
set_start_search_spp_device(0);
list_for_each_entry_safe(remote, n, &__this->inquiry_noname_head, entry) {
list_del(&remote->entry);
free(remote);
}
__this->edr_read_name_start = 0;
}
//搜索完成回调
void bt_hci_event_inquiry(struct bt_event *bt)
{
r_printf("bt_hci_event_inquiry result : %d\n", bt->value);
if (!__this->parm->discon_always_search) {
return;
}
adapter_odev_edr_search_stop();
if (!bt->value) {
adapter_odev_edr_search_device();
}
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过名字过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
static u8 adapter_odev_edr_search_bd_name_filt(char *data, u8 len, u32 dev_class, char rssi)
{
char bd_name[64] = {0};
u8 i;
if ((len > (sizeof(bd_name))) || (len == 0)) {
r_printf("bd_name_len error:%d\n", len);
return FALSE;
}
memset(bd_name, 0, sizeof(bd_name));
memcpy(bd_name, data, len);
g_printf("edr name:%s,len:%d,class %x ,rssi %d\n", bd_name, len, dev_class, rssi);
if (__this->edr_search_spp) {
for (i = 0; i < __this->parm->spp_name_filt_num; i++) {
if (memcmp(data, __this->parm->spp_name_filt[i], len) == 0) {
y_printf("*****find spp dev ok******\n");
return TRUE;
}
}
} else {
for (i = 0; i < __this->parm->bt_name_filt_num; i++) {
/* r_printf("%d : %s\n",i,__this->parm->bt_name_filt[i]); */
if (memcmp(data, __this->parm->bt_name_filt[i], len) == 0) {
y_printf("*****find dev ok******\n");
return TRUE;
}
}
}
return FALSE;
}
#endif //(SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索通过地址过滤
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
#if (SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
static u8 adapter_odev_edr_search_bd_addr_filt(u8 *addr)
{
u8 i;
log_info("search_bd_addr_filt:");
log_info_hexdump(addr, 6);
for (i = 0; i < __this->parm->bd_addr_filt_num; i++) {
if (memcmp(addr, __this->parm->bd_addr_filt[i], 6) == 0) {
y_printf("bd_addr match:%d\n", i);
return TRUE;
}
}
y_printf("bd_addr not match\n");
return FALSE;
}
#endif //(SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索结果回调处理
@param name : 设备名字
name_len: 设备名字长度
addr: 设备地址
dev_class: 设备类型
rssi: 设备信号强度
@return 无
@note
蓝牙设备搜索结果,可以做名字/地址过滤,也可以保存搜到的所有设备
在选择一个进行连接,获取其他你想要的操作。
返回TRUE表示搜到指定的想要的设备搜索结束直接连接当前设备
返回FALSE则继续搜索直到搜索完成或者超时
*/
/*----------------------------------------------------------------------------*/
static u8 adapter_odev_edr_search_result(char *name, u8 name_len, u8 *addr, u32 dev_class, char rssi)
{
if (__this->parm->disable_filt) {
return TRUE;
}
if (name == NULL) {
struct inquiry_noname_remote *remote = malloc(sizeof(struct inquiry_noname_remote));
remote->match = 0;
remote->class = dev_class;
remote->rssi = rssi;
memcpy(remote->addr, addr, 6);
local_irq_disable();
list_add_tail(&remote->entry, &__this->inquiry_noname_head);
local_irq_enable();
if (__this->edr_read_name_start == 0) {
__this->edr_read_name_start = 1;
user_send_cmd_prepare(USER_CTRL_READ_REMOTE_NAME, 6, addr);
}
}
#if (SEARCH_LIMITED_MODE == SEARCH_BD_NAME_LIMITED)
return adapter_odev_edr_search_bd_name_filt(name, name_len, dev_class, rssi);
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_BD_ADDR_LIMITED)
return adapter_odev_edr_search_bd_addr_filt(addr);
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_CUSTOM_LIMITED)
/*以下为搜索结果自定义处理*/
log_info("name:%s,len:%d,class %x ,rssi %d\n", bt_name, name_len, dev_class, rssi);
return FALSE;
#endif
#if (SEARCH_LIMITED_MODE == SEARCH_NULL_LIMITED)
/*没有指定限制,则搜到什么就连接什么*/
return TRUE;
#endif
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射搜索设备没有名字的设备,放进需要获取名字链表
@param status : 获取成功 0获取失败
addr:设备地址
name设备名字
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
static void adapter_odev_edr_search_noname(u8 status, u8 *addr, u8 *name)
{
u8 res = 0;
struct inquiry_noname_remote *remote, *n;
if (__this->status != ODEV_EDR_START) {
return ;
}
local_irq_disable();
if (status) {
list_for_each_entry_safe(remote, n, &__this->inquiry_noname_head, entry) {
if (!memcmp(addr, remote->addr, 6)) {
list_del(&remote->entry);
free(remote);
}
}
goto __find_next;
}
list_for_each_entry_safe(remote, n, &__this->inquiry_noname_head, entry) {
if (!memcmp(addr, remote->addr, 6)) {
res = adapter_odev_edr_search_result(name, strlen(name), addr, remote->class, remote->rssi);
if (res) {
__this->edr_read_name_start = 0;
remote->match = 1;
user_send_cmd_prepare(USER_CTRL_INQUIRY_CANCEL, 0, NULL);
local_irq_enable();
return;
}
list_del(&remote->entry);
free(remote);
}
}
__find_next:
__this->edr_read_name_start = 0;
remote = NULL;
if (!list_empty(&__this->inquiry_noname_head)) {
remote = list_first_entry(&__this->inquiry_noname_head, struct inquiry_noname_remote, entry);
}
local_irq_enable();
if (remote) {
__this->edr_read_name_start = 1;
user_send_cmd_prepare(USER_CTRL_READ_REMOTE_NAME, 6, remote->addr);
}
}
void remote_name_speciali_deal(u8 status, u8 *addr, u8 *name)
{
adapter_odev_edr_search_noname(status, addr, name);
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射接收到设备按键消息
@param cmd:按键命令
@return 无
@note
发射器收到接收器发过来的控制命令处理
根据实际需求可以在收到控制命令之后做相应的处理
蓝牙库里面定义的是weak函数直接再定义一个同名可获取信息
*/
/*----------------------------------------------------------------------------*/
void emitter_rx_avctp_opid_deal(u8 cmd, u8 id) //属于库的弱函数重写
{
log_debug("avctp_rx_cmd:%x\n", cmd);
#if (USB_DEVICE_CLASS_CONFIG & HID_CLASS)
switch (cmd) {
case AVCTP_OPID_NEXT:
log_info("AVCTP_OPID_NEXT\n");
adapter_avctp_key_handler(USB_AUDIO_NEXTFILE);
break;
case AVCTP_OPID_PREV:
log_info("AVCTP_OPID_PREV\n");
adapter_avctp_key_handler(USB_AUDIO_PREFILE);
break;
case AVCTP_OPID_PAUSE:
case AVCTP_OPID_PLAY:
log_info("AVCTP_OPID_PP\n");
adapter_avctp_key_handler(USB_AUDIO_PP);
break;
case AVCTP_OPID_VOLUME_UP:
log_info("AVCTP_OPID_VOLUME_UP\n");
adapter_avctp_key_handler(USB_AUDIO_VOLUP);
break;
case AVCTP_OPID_VOLUME_DOWN:
log_info("AVCTP_OPID_VOLUME_DOWN\n");
adapter_avctp_key_handler(USB_AUDIO_VOLDOWN);
break;
default:
break;
}
#endif//(USB_DEVICE_CLASS_CONFIG & HID_CLASS)
return ;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射接收设备同步音量
@param vol:接收到设备同步音量
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
void emitter_rx_vol_change(u8 vol) //属于库的弱函数重写
{
log_info("vol_change:%d \n", vol);
}
//pin code 轮询功能
const char pin_code_list[10][4] = {
{'0', '0', '0', '0'},
{'1', '2', '3', '4'},
{'8', '8', '8', '8'},
{'1', '3', '1', '4'},
{'4', '3', '2', '1'},
{'1', '1', '1', '1'},
{'2', '2', '2', '2'},
{'3', '3', '3', '3'},
{'5', '6', '7', '8'},
{'5', '5', '5', '5'}
};
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙发射链接pincode 轮询
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
const char *bt_get_emitter_pin_code(u8 flag) //属于库的弱函数重写
{
static u8 index_flag = 0;
int pincode_num = sizeof(pin_code_list) / sizeof(pin_code_list[0]);
if (flag == 1) {
//reset index
index_flag = 0;
} else if (flag == 2) {
//查询是否要开始继续回连尝试pin code。
if (index_flag >= pincode_num) {
//之前已经遍历完了
return NULL;
} else {
index_flag++; //准备使用下一个
}
} else {
log_debug("get pin code index %d\n", index_flag);
}
return &pin_code_list[index_flag][0];
}
/*----------------------------------------------------------------------------*/
/**@brief get source status
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
u8 bt_emitter_stu_get(void) //属于库的弱函数重写
{
//extern int adapter_audio_sbc_enc_is_work(void);
//return adapter_audio_sbc_enc_is_work();
return 1;
}
/*----------------------------------------------------------------------------*/
/**@brief set source status
@param 无
@return 无
@note
*/
/*----------------------------------------------------------------------------*/
static u8 adapter_odev_edr_stu_set(u8 on)
{
if (!(get_emitter_curr_channel_state() & A2DP_SRC_CH)) {
__emitter_send_media_toggle(NULL, 0);
return 0;
}
log_debug("total con dev:%d ", get_total_connect_dev());
if (on && (get_total_connect_dev() == 0)) {
on = 0;
}
r_printf("adapter_odev_edr_stu_set:%d\n", on);
__emitter_send_media_toggle(NULL, on);
return on;
}
static void esco_call_timeout(void *priv)
{
g_printf("esco_call_timeout\n");
__this->call_timeout = 0;
user_emitter_cmd_prepare(USER_CTRL_HFP_CALL_ANSWER, 0, NULL);
}
#define ESCO_CALL_TIMEOUT_MSEC (50)
static int esco_pp(u8 pp)
{
if (pp) {
user_emitter_cmd_prepare(USER_CTRL_HFP_CALL_LAST_NO, 0, NULL);
if (__this->call_timeout == 0) {
__this->call_timeout = sys_timeout_add(NULL, esco_call_timeout, ESCO_CALL_TIMEOUT_MSEC);
} else {
sys_timer_modify(__this->call_timeout, ESCO_CALL_TIMEOUT_MSEC);
}
} else {
user_emitter_cmd_prepare(USER_CTRL_HFP_CALL_HANGUP, 0, NULL);
}
return pp;
}
int a2dp_pp(u8 pp)
{
if (get_total_connect_dev() == 0) {
return 0;
}
if (!(get_emitter_curr_channel_state() & A2DP_SRC_CH)) {
return 0;
}
return adapter_odev_edr_stu_set(pp);
}
int adapter_odev_edr_pp(u8 pp)
{
int ret = 0;
if (__this->mode) { //esco
g_printf("esco mode\n");
ret = esco_pp(pp);
} else { //a2dp
g_printf("a2dp mode\n");
ret = a2dp_pp(pp);
}
return ret;
}
int adapter_odev_edr_open(void *priv)
{
r_printf("adapter_odev_edr_open\n");
if (__this->status == ODEV_EDR_OPEN) {
r_printf("adapter_odev_edr_already_open\n");
return 0;
}
__this->status = ODEV_EDR_OPEN;
memset(__this, 0, sizeof(struct _odev_edr));
__this->parm = (struct _odev_edr_parm *)priv;
return 0;
}
int adapter_odev_edr_start(void *priv)
{
r_printf("adapter_odev_edr_start\n");
if (__this->status == ODEV_EDR_START) {
r_printf("adapter_odev_edr_already_start\n");
return 0;
}
__this->status = ODEV_EDR_START;
INIT_LIST_HEAD(&__this->inquiry_noname_head);
lmp_set_sniff_establish_by_remote(1);
inquiry_result_handle_register(adapter_odev_edr_search_result);
bredr_bulk_change(0);
////切换样机状态
__set_emitter_enable_flag(1);
a2dp_source_init(NULL, 0, 1);
#if (USER_SUPPORT_PROFILE_HFP_AG==1)
hfp_ag_buf_init(NULL, 0, 1);
#endif
#if USER_SUPPORT_DUAL_A2DP_SOURCE
dongle_1t2_init(__this);
#endif
if (connect_last_device_from_vm()) {
r_printf("start connect device vm addr\n");
} else {
if (__this->parm->poweron_start_search) {
r_printf("start search device ...\n");
adapter_odev_edr_search_device();
}
}
return 0;
}
int adapter_odev_edr_stop(void *priv)
{
if (__this->status == ODEV_EDR_STOP) {
r_printf("adapter_odev_edr_already_stop\n");
return 0;
}
__this->status = ODEV_EDR_STOP;
if (__this->edr_search_busy) {
adapter_odev_edr_search_stop();
} else {
adapter_odev_edr_pp(0);
}
return 0;
}
int adapter_odev_edr_close(void *priv)
{
if (__this->status == ODEV_EDR_CLOSE) {
r_printf("adapter_odev_edr_already_close\n");
return 0;
}
__this->status = ODEV_EDR_CLOSE;
adapter_odev_edr_search_stop();
return 0;
}
int adapter_odev_edr_get_status(void *priv)
{
g_printf("adapter_odev_edr_get_status : %x\n", get_emitter_curr_channel_state());
if ((get_emitter_curr_channel_state() & A2DP_SRC_CH) && (get_emitter_curr_channel_state() & HFP_AG_CH)) {
return 1;
} else {
return 0;
}
}
int adapter_odev_edr_media_prepare(u8 mode, int (*fun)(void *, u8, u8, void *), void *priv)
{
__this->mode = mode;
__this->fun = fun;
__this->priv = priv;
u8 call_status = get_call_status();
r_printf("mode : %d pp status:%d call status:%d\n", mode, bt_emitter_stu_get(), call_status);
if (mode) { //esco
//stop a2dp
y_printf("stop a2dp\n");
a2dp_pp(0);
if (call_status == BT_CALL_HANGUP) {
//start esco
y_printf("start esco\n");
esco_pp(1);
} else if (call_status == BT_CALL_ACTIVE) {
extern struct app_bt_opr app_bt_hdl;
if (__this->fun) {
__this->fun(__this->priv, __this->mode, 1, &app_bt_hdl.sco_info);
}
}
} else { //a2dp
if (call_status != BT_CALL_HANGUP) {
//stop esco
y_printf("stop esco\n");
esco_pp(0);
__this->start_a2dp_flag = 1;
} else {
y_printf("start a2dp\n");
a2dp_pp(1);
}
}
return 0;
}
/*----------------------------------------------------------------------------*/
/**@brief 蓝牙SBC编码初始化函数,属于库的弱函数重写
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
int a2dp_sbc_encoder_init(void *sbc_struct)
{
if (!__this->fun) {
return 0;
}
if (sbc_struct) { //start a2dp
__this->fun(__this->priv, __this->mode, 1, sbc_struct);
} else { //stop a2dp
/* __this->fun(__this->priv, __this->mode, 0, sbc_struct); */
}
return 0;
}
int adapter_odev_edr_config(int cmd, void *parm)
{
switch (cmd) {
case 0:
break;
default:
break;
}
return 0;
}
#endif

View File

@ -0,0 +1,67 @@
#include "adapter_odev.h"
#include "adapter_process.h"
#include "adapter_odev_dac.h"
#include "audio_config.h"
//#include "adapter_audio_stream.h"
#include "asm/dac.h"
#if TCFG_WIRELESS_MIC_ENABLE
#if (TCFG_AUDIO_DAC_ENABLE)
//struct audio_dac_channel default_dac = {0};
extern struct audio_dac_hdl dac_hdl;
static int adapter_odev_dac_open(void *parm)
{
adapter_process_event_notify(ADAPTER_EVENT_ODEV_INIT_OK, 0);
return 0;
}
static int adapter_odev_dac_start(void *priv, struct adapter_media *media)
{
//通知主流程请求启动音频媒体
adapter_process_event_notify(ADAPTER_EVENT_ODEV_MEDIA_OPEN, 0);
return 0;
}
static int adapter_odev_dac_stop(void *priv)
{
return 0;
}
static int adapter_odev_dac_close(void)
{
//通知主流程请求停止音频媒体
adapter_process_event_notify(ADAPTER_EVENT_ODEV_MEDIA_CLOSE, 0);
return 0;
}
static int adapter_odev_dac_pp_ctl(u8 pp)
{
return 0;
}
static int adapter_odev_dac_get_status(void *priv)
{
return 0;
}
static int adapter_odev_dac_config(int cmd, void *parm)
{
return 0;
}
REGISTER_ADAPTER_ODEV(adapter_odev_dac) = {
.id = ADAPTER_ODEV_DAC,
.open = adapter_odev_dac_open,
.start = adapter_odev_dac_start,
.stop = adapter_odev_dac_stop,
.close = adapter_odev_dac_close,
.media_pp = NULL,
.get_status = NULL,
.media_prepare = NULL,
.event_fun = NULL,
.config = NULL,
};
#endif
#endif//TCFG_AUDIO_DAC_ENABLE

View File

@ -0,0 +1,11 @@
#ifndef __ADAPTER_ODEV_DAC_H__
#define __ADAPTER_ODEV_DAC_H__
#include "generic/typedef.h"
struct _odev_dac {
};
#endif//__ADAPTER_ODEV_DAC_H__

View File

@ -0,0 +1,204 @@
#include "adapter_process.h"
//#include "adapter_media.h"
#include "app_task.h"
#include "adapter_idev.h"
#include "adapter_odev.h"
#if TCFG_WIRELESS_MIC_ENABLE
#include "clock_cfg.h"
static int adapter_process_media_start_callback(void *priv, u8 mode, u8 status, void *parm)
{
struct adapter_pro *pro = (struct adapter_pro *)priv;
if (pro == NULL || pro->media == NULL) {
return 0;
}
adapter_media_stop(pro->media);
pro->media->idev = pro->in;
pro->media->odev = pro->out;
adapter_media_start(pro->media);
pro->media_lock = 0;
return 0;
}
struct adapter_pro *adapter_process_open(struct idev *in, struct odev *out, struct adapter_media *media, int (*event)(struct sys_event *event))
{
struct adapter_pro *pro = zalloc(sizeof(struct adapter_pro));
if (pro == NULL) {
return NULL;
}
pro->in = in;
pro->out = out;
pro->media = media;
pro->event_handle = event;
clock_add_set(ADAPTER_PROCESS_CLK);
return pro;
}
void adapter_process_close(struct adapter_pro **hdl)
{
if (hdl == NULL || *hdl == NULL) {
return ;
}
struct adapter_pro *pro = *hdl;
//其他模块关闭
adapter_media_stop(pro->media);
adapter_idev_stop(pro->in);
adapter_odev_stop(pro->out);
//释放句柄
local_irq_disable();
free(pro);
*hdl = NULL;
local_irq_enable();
clock_remove_set(ADAPTER_PROCESS_CLK);
}
static int adapter_device_event_parse(struct adapter_pro *pro, struct sys_event *e)
{
u8 event = e->u.dev.event;
int value = e->u.dev.value;
switch (event) {
//初始化完成
case ADAPTER_EVENT_IDEV_INIT_OK:
printf("ADAPTER_EVENT_IDEV_INIT_OK\n");
adapter_idev_start(pro->in, pro->media);
break;
case ADAPTER_EVENT_ODEV_INIT_OK:
printf("ADAPTER_EVENT_ODEV_INIT_OK\n");
adapter_odev_start(pro->out, pro->media);
break;
//媒体相关事件
case ADAPTER_EVENT_IDEV_MEDIA_OPEN:
printf("ADAPTER_EVENT_IDEV_MEDIA_OPEN\n");
pro->mode = (u8)value;
pro->dev_status |= BIT(ADAPTER_INDEX_IDEV);
if ((pro->dev_status & 0x3) == 0x3) {
//prepare media
if (pro->media_lock == 0) {
pro->media_lock = 1;
if (adapter_odev_media_prepare(pro->out, pro->mode, adapter_process_media_start_callback, (void *)pro)) {
//prepare 返回值为非0 需要主动启动媒体
printf("adapter_odev_media_prepare null\n");
adapter_process_media_start_callback(pro, pro->mode, 1, NULL);
}
} else {
g_f_printf("%s, %d, pro->media_lock!!!!!\n", __FUNCTION__, __LINE__);
}
}
break;
case ADAPTER_EVENT_IDEV_MEDIA_CLOSE:
pro->mode = 0xff;
pro->dev_status &= ~BIT(ADAPTER_INDEX_IDEV);
adapter_odev_media_pp(pro->out, 0);
adapter_media_stop(pro->media);
break;
case ADAPTER_EVENT_ODEV_MEDIA_OPEN:
printf("==================ADAPTER_EVENT_ODEV_MEDIA_OPEN\n");
pro->dev_status |= BIT(ADAPTER_INDEX_ODEV);
if ((pro->dev_status & 0x3) == 0x3) {
//prepare media
if (pro->media_lock == 0) {
pro->media_lock = 1;
if (adapter_odev_media_prepare(pro->out, pro->mode, adapter_process_media_start_callback, (void *)pro)) {
//prepare 返回值为非0 需要主动启动媒体
printf("adapter_odev_media_prepare null\n");
adapter_process_media_start_callback(pro, pro->mode, 1, NULL);
}
} else {
g_f_printf("%s, %d, pro->media_lock!!!!!\n", __FUNCTION__, __LINE__);
}
}
break;
case ADAPTER_EVENT_ODEV_MEDIA_CLOSE:
pro->media_lock = 0;
pro->dev_status &= ~BIT(ADAPTER_INDEX_ODEV);
adapter_media_stop(pro->media);
break;
default:
break;
}
return 0;
}
static int adapter_process_event_parse(struct adapter_pro *pro, struct sys_event *e)
{
int ret = 0;
//输入设备事件处理
ret = adapter_idev_event_deal(pro->in, e);
if (ret) {
return ret;
}
//输出设备事件处理
ret = adapter_odev_event_deal(pro->out, e);
if (ret) {
return ret;
}
//公共事件处理
switch (e->type) {
case SYS_KEY_EVENT:
break;
case SYS_DEVICE_EVENT:
switch ((u32)e->arg) {
case DEVICE_EVENT_FROM_ADAPTER:
ret = adapter_device_event_parse(pro, e);
break;
default:
break;
}
break;
default:
break;
}
return ret;
}
int adapter_process_run(struct adapter_pro *pro)
{
if (pro == NULL) {
return false;
}
int msg[32];
int ret = 0;
while (1) {
app_task_get_msg(msg, ARRAY_SIZE(msg), 1);
if (adapter_process_event_parse(pro, (struct sys_event *)&msg[1]) == 0) {
if (pro->event_handle) {
ret = pro->event_handle((struct sys_event *)(&msg[1]));
}
}
if (ret) {
break;
}
}
return ret;
}
void adapter_process_event_notify(u8 event, int value)
{
struct sys_event e;
e.type = SYS_DEVICE_EVENT;
e.arg = (void *)DEVICE_EVENT_FROM_ADAPTER;
e.u.dev.event = event;
e.u.dev.value = value;
sys_event_notify(&e);
}
#endif

View File

@ -0,0 +1,73 @@
#ifndef __ADAPTER_PROCESS_H__
#define __ADAPTER_PROCESS_H__
#include "app_config.h"
#include "generic/typedef.h"
#include "media/includes.h"
#include "stream/stream_entry.h"
#include "adapter_idev.h"
#include "adapter_odev.h"
//#include "adapter_media.h"
#define ADAPTER_INDEX_IDEV 0x0
#define ADAPTER_INDEX_ODEV 0x1
enum adapter_event {
/* --- 适配事件定义 --- */
ADAPTER_EVENT_IDEV_INIT_OK = 0x0,
ADAPTER_EVENT_IDEV_MEDIA_OPEN,
ADAPTER_EVENT_IDEV_MEDIA_CLOSE,
ADAPTER_EVENT_ODEV_INIT_OK = 0x80,
ADAPTER_EVENT_ODEV_MEDIA_OPEN,
ADAPTER_EVENT_ODEV_MEDIA_CLOSE,
};
struct adapter_pro {
/* --- 适配器process模块控制句柄 --- */
u8 mode; /*!< 跟音频媒体media_sel一样 指的当前媒体选择 */
u8 dev_status; /*!< idev和odev 音频请求状态, idev&&odev都请求启动音频媒体音频媒体才会正式启动*/
u8 media_lock; /*!< 音频媒体锁定状态标记 */
struct idev *in; /*!< idev控制句柄 */
struct odev *out; /*!< odev控制句柄 */
struct adapter_media *media; /*!< 音频媒体控制句柄 */
int (*event_handle)(struct sys_event *event); /*!< 用户事件拦截回调函数 */
};
/**
* @brief 适配器主流程创建
*
* @param in idev控制句柄
* @param out odev控制句柄
* @param media 音频媒体控制句柄
* @param event 用户自定义事件拦截回调函数
* @return 适配器主流程控制句柄
*/
struct adapter_pro *adapter_process_open(struct idev *in, struct odev *out, struct adapter_media *media, int (*event)(struct sys_event *event));
/**
* @brief 适配器主流程关闭
*
* @param hdl 适配器主流程控制句柄双重指针
*/
void adapter_process_close(struct adapter_pro **hdl);
/**
* @brief 适配器主流程关闭
*
* @param pro 适配器主流程控制句柄
*/
int adapter_process_run(struct adapter_pro *pro);
/**
* @brief 适配器主流程事件通知接口
*
* @param event 事件
* @param value 事件参数或者附带内容值
*/
void adapter_process_event_notify(u8 event, int value);
#endif//__ADAPTER_PROCESS_H__