212 lines
4.9 KiB
C
212 lines
4.9 KiB
C
#include "app_config.h"
|
|
#include "spp_user.h"
|
|
#include "bt_common.h"
|
|
#include "btstack/avctp_user.h"
|
|
|
|
#if SPP_TRANS_DATA_EN
|
|
|
|
#if 1
|
|
extern void printf_buf(u8 *buf, u32 len);
|
|
#define log_info printf
|
|
#define log_info_hexdump printf_buf
|
|
#else
|
|
#define log_info(...)
|
|
#define log_info_hexdump(...)
|
|
#endif
|
|
|
|
#define TEST_SPP_DATA_RATE 0
|
|
|
|
#if TEST_SPP_DATA_RATE
|
|
#define SPP_TIMER_MS (100)
|
|
static u32 test_data_count;
|
|
static u32 spp_timer_handle = 0;
|
|
static u32 spp_test_start;
|
|
#endif
|
|
|
|
/*
|
|
打开流控使能后,确定配置接口 transport_spp_flow_cfg 被调用初始化配置
|
|
然后使用过程 通过接口 transport_spp_flow_enable 来控制流控开关
|
|
*/
|
|
#define SPP_DATA_RECIEVT_FLOW 0//流控功能使能
|
|
|
|
//流控速度控制,可以不用更改
|
|
#define FLOW_SEND_CREDITS_NUM 1 //控制命令中 控制可接收的数据包个数,发送给对方的,range(1~32)
|
|
#define FLOW_SEND_CREDITS_TRIGGER_NUM 1 //触发更新控制命令的阈值,range(1 to <= FLOW_SEND_CREDITS_NUM)
|
|
|
|
int transport_spp_flow_enable(u8 en);
|
|
void rfcomm_change_credits_setting(u16 init_credits, u8 base);
|
|
int rfcomm_send_cretits_by_profile(u16 rfcomm_cid, u16 credit, u8 auto_flag);
|
|
|
|
static struct spp_operation_t *spp_api = NULL;
|
|
static u8 spp_state;
|
|
static u16 spp_channel;
|
|
|
|
int transport_spp_send_data(u8 *data, u16 len)
|
|
{
|
|
if (spp_api) {
|
|
log_info("spp_api_tx(%d) \n", len);
|
|
/* log_info_hexdump(data, len); */
|
|
clear_sniff_cnt();
|
|
return spp_api->send_data(NULL, data, len);
|
|
}
|
|
return SPP_USER_ERR_SEND_FAIL;
|
|
}
|
|
|
|
int transport_spp_send_data_check(u16 len)
|
|
{
|
|
if (spp_api) {
|
|
if (spp_api->busy_state()) {
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static void transport_spp_state_cbk(u8 state)
|
|
{
|
|
spp_state = state;
|
|
|
|
switch (state) {
|
|
case SPP_USER_ST_CONNECT:
|
|
log_info("SPP_USER_ST_CONNECT ~~~\n");
|
|
break;
|
|
case SPP_USER_ST_DISCONN:
|
|
log_info("SPP_USER_ST_DISCONN ~~~\n");
|
|
spp_channel = 0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void transport_spp_send_wakeup(void)
|
|
{
|
|
putchar('W');
|
|
}
|
|
|
|
static void transport_spp_recieve_cbk(void *priv, u8 *buf, u16 len)
|
|
{
|
|
spp_channel = (u16)priv;
|
|
log_info("spp_api_rx(%d) \n", len);
|
|
log_info_hexdump(buf, len);
|
|
|
|
clear_sniff_cnt();
|
|
|
|
#if TEST_SPP_DATA_RATE
|
|
if ((buf[0] == 'A') && (buf[1] == 'F')) {
|
|
spp_test_start = 1;//start
|
|
} else if ((buf[0] == 'A') && (buf[1] == 'A')) {
|
|
spp_test_start = 0;//stop
|
|
}
|
|
#endif
|
|
|
|
//loop send data for test
|
|
if (transport_spp_send_data_check(len)) {
|
|
transport_spp_send_data(buf, len);
|
|
}
|
|
}
|
|
|
|
#if TEST_SPP_DATA_RATE
|
|
|
|
static void test_spp_send_data(void)
|
|
{
|
|
u16 send_len = 250;
|
|
if (transport_spp_send_data_check(send_len)) {
|
|
test_data_count += send_len;
|
|
transport_spp_send_data(&test_data_count, send_len);
|
|
}
|
|
}
|
|
|
|
static void test_timer_handler(void)
|
|
{
|
|
static u32 t_count = 0;
|
|
|
|
if (SPP_USER_ST_CONNECT != spp_state) {
|
|
test_data_count = 0;
|
|
spp_test_start = 0;
|
|
return;
|
|
}
|
|
|
|
if (spp_test_start) {
|
|
test_spp_send_data();
|
|
}
|
|
|
|
if (++t_count < (1000 / SPP_TIMER_MS)) {
|
|
return;
|
|
}
|
|
t_count = 0;
|
|
|
|
if (test_data_count) {
|
|
log_info("\n-spp_data_rate: %d bps-\n", test_data_count * 8);
|
|
test_data_count = 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void transport_spp_init(void)
|
|
{
|
|
log_info("transport_spp_init\n");
|
|
|
|
#if (USER_SUPPORT_PROFILE_SPP==1)
|
|
spp_state = 0;
|
|
spp_get_operation_table(&spp_api);
|
|
spp_api->regist_recieve_cbk(0, transport_spp_recieve_cbk);
|
|
spp_api->regist_state_cbk(0, transport_spp_state_cbk);
|
|
spp_api->regist_wakeup_send(NULL, transport_spp_send_wakeup);
|
|
#endif
|
|
|
|
#if TEST_SPP_DATA_RATE
|
|
spp_timer_handle = sys_timer_add(NULL, test_timer_handler, SPP_TIMER_MS);
|
|
#endif
|
|
}
|
|
|
|
void transport_spp_disconnect(void)
|
|
{
|
|
if (SPP_USER_ST_CONNECT == spp_state) {
|
|
log_info("transport_spp_disconnect\n");
|
|
user_send_cmd_prepare(USER_CTRL_SPP_DISCONNECT, 0, NULL);
|
|
}
|
|
}
|
|
|
|
static void timer_spp_flow_test(void)
|
|
{
|
|
static u8 sw = 0;
|
|
if (spp_channel) {
|
|
sw = !sw;
|
|
transport_spp_flow_enable(sw);
|
|
}
|
|
}
|
|
|
|
//配置流控制的参数,蓝牙协议栈初始化前调用配置
|
|
void transport_spp_flow_cfg(void)
|
|
{
|
|
#if SPP_DATA_RECIEVT_FLOW
|
|
rfcomm_change_credits_setting(FLOW_SEND_CREDITS_NUM, FLOW_SEND_CREDITS_TRIGGER_NUM);
|
|
|
|
//for test
|
|
/* sys_timer_add(0,timer_spp_flow_test,2000); */
|
|
#endif
|
|
}
|
|
|
|
//流控使能 EN: 1-停止收数 or 0-继续收数
|
|
int transport_spp_flow_enable(u8 en)
|
|
{
|
|
int ret = -1;
|
|
u16 credits = FLOW_SEND_CREDITS_NUM;
|
|
|
|
#if SPP_DATA_RECIEVT_FLOW
|
|
if (spp_channel) {
|
|
if (en) {
|
|
credits = 0;
|
|
}
|
|
ret = rfcomm_send_cretits_by_profile(spp_channel, credits, !en);
|
|
}
|
|
#endif
|
|
|
|
log_info("transport_spp_flow_enable:%02x,%d,%d\n", spp_channel, en, ret);
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|