801 lines
27 KiB
C
801 lines
27 KiB
C
|
#include <stdint.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include "fr30xx.h"
|
||
|
|
||
|
#include "co_util.h"
|
||
|
|
||
|
#include "bt_types.h"
|
||
|
#include "me_api.h"
|
||
|
#include "hfg_api.h"
|
||
|
#include "gatt_api.h"
|
||
|
|
||
|
#include "app_at.h"
|
||
|
#include "app_task.h"
|
||
|
#include "app_ble.h"
|
||
|
#include "app_bt.h"
|
||
|
#include "app_audio.h"
|
||
|
#include "app_hw.h"
|
||
|
#include "btdm_mem.h"
|
||
|
#include "fdb_app.h"
|
||
|
#include "heap.h"
|
||
|
#include "app_ble.h"
|
||
|
#include "user_bt.h"
|
||
|
#include "user_ipc_st.h"
|
||
|
#include "dsp_mem.h"
|
||
|
|
||
|
#define AT_RECV_MAX_LEN 32
|
||
|
|
||
|
static uint8_t app_at_recv_char;
|
||
|
static uint8_t at_recv_buffer[AT_RECV_MAX_LEN];
|
||
|
static uint8_t at_recv_index = 0;
|
||
|
static uint8_t at_recv_state = 0;
|
||
|
|
||
|
|
||
|
|
||
|
void btdm_host_send_vendor_cmd(uint8_t type, uint8_t length, void *data);
|
||
|
|
||
|
void btdm_host_vendor_cmd_cmp_evt(uint8_t status, uint8_t len, uint8_t const *param)
|
||
|
{
|
||
|
printf("status: 0x%02x.\r\n", status);
|
||
|
for (uint32_t i=0; i<len; i++) {
|
||
|
printf("%02x ", param[i]);
|
||
|
}
|
||
|
printf("\r\n");
|
||
|
}
|
||
|
|
||
|
void btdm_host_recv_vendor_evt(uint8_t len, uint8_t *param)
|
||
|
{
|
||
|
if (param[1] == 0x10) {
|
||
|
float acc[3];
|
||
|
memcpy((void *)&acc[0], ¶m[3], sizeof(float) * 3);
|
||
|
printf("%0.6f, \t%0.6f, \t%0.6f\r\n", acc[0], acc[1], acc[2]);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//gsensor event:
|
||
|
// if (param[1] == 0x0A) {
|
||
|
// _gsensor_evt *evt = (_gsensor_evt *)¶m[3];
|
||
|
// printf("EVENT: %d step:%d calorie:%d sleep:%d action:%d \n",evt->evt_id,evt->step,evt->calorie,evt->sleep,evt->action);
|
||
|
// }
|
||
|
|
||
|
// printf("EVENT: ");
|
||
|
// for (uint32_t i=0; i<len; i++) {
|
||
|
// printf("%02x ", param[i]);
|
||
|
// }
|
||
|
// printf("\r\n");
|
||
|
// if ((param[1] | (param[2]<<8)) == 0x000c)
|
||
|
{
|
||
|
// extern void fr_system_host_recv_vendor(uint8_t *recv_data,uint8_t len);
|
||
|
// fr_system_host_recv_vendor(param,len);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
__RAM_CODE static void app_at_recv_cmd_A(uint8_t sub_cmd, uint8_t *data)
|
||
|
{
|
||
|
switch(sub_cmd)
|
||
|
{
|
||
|
case 'A':
|
||
|
{
|
||
|
uint8_t addr = ascii_strn2val((const char *)&data[0], 16, 2);
|
||
|
btdm_host_send_vendor_cmd(0x00, 1, &addr);
|
||
|
}
|
||
|
printf("OK\r\n");
|
||
|
break;
|
||
|
case 'B':
|
||
|
{
|
||
|
uint8_t buffer[2];
|
||
|
buffer[0] = ascii_strn2val((const char *)&data[0], 16, 2);
|
||
|
buffer[1] = ascii_strn2val((const char *)&data[3], 16, 2);
|
||
|
btdm_host_send_vendor_cmd(0x01, 2, (void *)&buffer[0]);
|
||
|
}
|
||
|
printf("OK\r\n");
|
||
|
break;
|
||
|
// case 'C':
|
||
|
// {
|
||
|
// uint32_t addr = ascii_strn2val((const char *)&data[0], 16, 8);
|
||
|
// btdm_host_send_vendor_cmd(0x02, 4, (void *)&addr);
|
||
|
// }
|
||
|
// printf("OK\r\n");
|
||
|
// break;
|
||
|
// case 'D':
|
||
|
// {
|
||
|
// uint32_t buffer[2];
|
||
|
// buffer[0] = ascii_strn2val((const char *)&data[0], 16, 8);
|
||
|
// buffer[1] = ascii_strn2val((const char *)&data[9], 16, 8);
|
||
|
// btdm_host_send_vendor_cmd(0x03, 8, (void *)&buffer[0]);
|
||
|
// }
|
||
|
// printf("OK\r\n");
|
||
|
// break;
|
||
|
case 'C':
|
||
|
{
|
||
|
btdm_host_send_vendor_cmd(0x15, 0, NULL);
|
||
|
}
|
||
|
printf("OK\r\n");
|
||
|
break;
|
||
|
case 'D':
|
||
|
// {
|
||
|
// uint8_t mode = ascii_strn2val((const char *)&data[0], 16, 2);
|
||
|
// btdm_host_send_vendor_cmd(0x14, 1, &mode);
|
||
|
// }
|
||
|
btdm_host_send_vendor_cmd(0x17, 0, NULL);
|
||
|
printf("OK\r\n");
|
||
|
break;
|
||
|
case 'E':
|
||
|
{
|
||
|
uint8_t sleep_dur[2];
|
||
|
sleep_dur[0] = ascii_strn2val((const char *)&data[0], 16, 2);
|
||
|
sleep_dur[1] = ascii_strn2val((const char *)&data[3], 16, 2);
|
||
|
btdm_host_send_vendor_cmd(0x16, 2, &sleep_dur);
|
||
|
}
|
||
|
break;
|
||
|
case 'F':
|
||
|
{
|
||
|
static uint8_t hour = 0;
|
||
|
static uint8_t minute = 0;
|
||
|
static uint8_t second = 0;
|
||
|
static uint16_t mini_second = 0;
|
||
|
uint8_t gsensor_cmd[] = {0x00, 0xe7, 0x07, 0x09, 0x12, 0x14, 0x36, 0x10, 0x20, 0x00, 0x2c, 0x01};
|
||
|
mini_second += 200;
|
||
|
if (mini_second >= 1000) {
|
||
|
mini_second = 0;
|
||
|
second++;
|
||
|
if (second >= 60) {
|
||
|
second = 0;
|
||
|
minute++;
|
||
|
if (minute >= 60) {
|
||
|
minute = 0;
|
||
|
hour++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
gsensor_cmd[5] = hour;
|
||
|
gsensor_cmd[6] = minute;
|
||
|
gsensor_cmd[7] = second;
|
||
|
gsensor_cmd[8] = mini_second;
|
||
|
gsensor_cmd[9] = mini_second >> 8;
|
||
|
btdm_host_send_vendor_cmd(0x12, sizeof(gsensor_cmd), gsensor_cmd);
|
||
|
}
|
||
|
break;
|
||
|
case 'G':
|
||
|
printf("hello world!\r\n");
|
||
|
break;
|
||
|
case 'H':
|
||
|
printf("VAL: 0x%08x.\r\n", *(volatile uint32_t *)ascii_strn2val((const char *)&data[0], 16, 8));
|
||
|
break;
|
||
|
case 'I':
|
||
|
*(volatile uint32_t *)ascii_strn2val((const char *)&data[0], 16, 8) = ascii_strn2val((const char *)&data[9], 16, 8);
|
||
|
printf("OK\r\n");
|
||
|
break;
|
||
|
case 'J':
|
||
|
printf("OOL VAL: 0x%02x.\r\n", ool_read(ascii_strn2val((const char *)&data[0], 16, 2)));
|
||
|
break;
|
||
|
case 'K':
|
||
|
ool_write(ascii_strn2val((const char *)&data[0], 16, 2), ascii_strn2val((const char *)&data[3], 16, 2));
|
||
|
printf("OK\r\n");
|
||
|
break;
|
||
|
case 'L':
|
||
|
printf("VAL: 0x%02x.\r\n", *(volatile uint8_t *)(ascii_strn2val((const char *)&data[0], 16, 8)));
|
||
|
break;
|
||
|
case 'M':
|
||
|
*(volatile uint8_t *)(ascii_strn2val((const char *)&data[0], 16, 8)) = ascii_strn2val((const char *)&data[9], 16, 2);
|
||
|
printf("OK\r\n");
|
||
|
break;
|
||
|
// case 'P':
|
||
|
// co_printf("VAL: 0x%02x.\r\n", *(uint8_t *)(MODEM_BASE + ascii_strn2val((const char *)&data[0], 16, 2)));
|
||
|
// break;
|
||
|
// case 'Q':
|
||
|
// *(uint8_t *)(MODEM_BASE + ascii_strn2val((const char *)&data[0], 16, 2)) = ascii_strn2val((const char *)&data[3], 16, 2);
|
||
|
// co_printf("OK\r\n");
|
||
|
// break;
|
||
|
// case 'S':
|
||
|
// co_printf("VAL: 0x%02x.\r\n", frspim_rd(FR_SPI_RF_COB_CHAN, ascii_strn2val((const char *)&data[0], 16, 2), 1));
|
||
|
// break;
|
||
|
// case 'T':
|
||
|
// frspim_wr(FR_SPI_RF_COB_CHAN, ascii_strn2val((const char *)&data[0], 16, 2), 1, ascii_strn2val((const char *)&data[3], 16, 2));
|
||
|
// co_printf("OK\r\n");
|
||
|
// break;
|
||
|
case 'U':
|
||
|
{
|
||
|
uint32_t *ptr = (uint32_t *)(ascii_strn2val((const char *)&data[0], 16, 8) & (~3));
|
||
|
uint8_t count = ascii_strn2val((const char *)&data[9], 16, 2);
|
||
|
uint32_t *start = (uint32_t *)((uint32_t)ptr & (~0x0f));
|
||
|
for(uint8_t i=0; i<count;) {
|
||
|
if(((uint32_t)start & 0x0c) == 0) {
|
||
|
printf("0x%08x: ", (uint32_t)start);
|
||
|
}
|
||
|
if(start < ptr) {
|
||
|
printf(" ");
|
||
|
}
|
||
|
else {
|
||
|
i++;
|
||
|
printf("%08x", *start);
|
||
|
}
|
||
|
if(((uint32_t)start & 0x0c) == 0x0c) {
|
||
|
printf("\r\n");
|
||
|
}
|
||
|
else {
|
||
|
printf(" ");
|
||
|
}
|
||
|
start++;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 'V':
|
||
|
flash_erase(QSPI0, ascii_strn2val((const char *)&data[0], 16, 8), ascii_strn2val((const char *)&data[9], 16, 8));
|
||
|
break;
|
||
|
case 'W':
|
||
|
{
|
||
|
uint32_t curr_free, min_free;
|
||
|
dsp_mem_get_usage(&curr_free, &min_free);
|
||
|
printf("DSP MEM: %d, %d\r\n", curr_free, min_free);
|
||
|
}
|
||
|
break;
|
||
|
case 'X':
|
||
|
{
|
||
|
void system_reset(void);
|
||
|
system_reset();
|
||
|
}
|
||
|
break;
|
||
|
case 'Y':
|
||
|
heap_dump_used_mem(ascii_strn2val((const char *)&data[0], 16, 2));
|
||
|
break;
|
||
|
case 'Z':
|
||
|
printf("MEM usage\r\n \
|
||
|
\tHEAP_TYPE_SRAM_BLOCK: %d, %d\r\n \
|
||
|
\tHEAP_TYPE_DRAM_BLOCK: %d, %d\r\n \
|
||
|
\tHEAP_TYPE_BTDM_BLOCK: %d, %d\r\n \
|
||
|
\tTOTAL USAGE: %d\r\n", \
|
||
|
heap_get_mem_usage(HEAP_TYPE_SRAM_BLOCK), heap_get_mem_usage_single(HEAP_TYPE_SRAM_BLOCK), \
|
||
|
heap_get_mem_usage(HEAP_TYPE_DRAM_BLOCK), heap_get_mem_usage_single(HEAP_TYPE_DRAM_BLOCK), \
|
||
|
heap_get_mem_usage(HEAP_TYPE_BTDM_BLOCK), heap_get_mem_usage_single(HEAP_TYPE_BTDM_BLOCK), \
|
||
|
heap_get_max_mem_usage());
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void user_hci_callback(const BtEvent *event)
|
||
|
{
|
||
|
printf("event type = %d\r\n",event->eType);
|
||
|
if(event->eType == BTEVENT_COMMAND_COMPLETE){
|
||
|
btdm_free(event->p.meToken);
|
||
|
}
|
||
|
}
|
||
|
__RAM_CODE static void app_at_recv_cmd_B(uint8_t sub_cmd, uint8_t *data)
|
||
|
{
|
||
|
struct gap_ble_addr peer_addr;
|
||
|
BD_ADDR addr;
|
||
|
HfgResponse *rsp;
|
||
|
BtStatus status;
|
||
|
MeCommandToken *token;
|
||
|
uint16_t page_timeout = 0x400;
|
||
|
|
||
|
switch(sub_cmd) {
|
||
|
case 'A':
|
||
|
// AT#BA00
|
||
|
//app_ble_advertising_start(ascii_strn2val((const char *)&data[0], 16, 2));
|
||
|
break;
|
||
|
case 'B':
|
||
|
// AT#BB01
|
||
|
//app_ble_advertising_stop(ascii_strn2val((const char *)&data[0], 16, 2));
|
||
|
break;
|
||
|
case 'C':
|
||
|
app_ble_scan_start();
|
||
|
break;
|
||
|
case 'D':
|
||
|
app_ble_scan_stop();
|
||
|
break;
|
||
|
case 'E':
|
||
|
// AT#BE0123456789ab_01
|
||
|
peer_addr.addr.addr[5] = ascii_strn2val((const char *)&data[0], 16, 2);
|
||
|
peer_addr.addr.addr[4] = ascii_strn2val((const char *)&data[2], 16, 2);
|
||
|
peer_addr.addr.addr[3] = ascii_strn2val((const char *)&data[4], 16, 2);
|
||
|
peer_addr.addr.addr[2] = ascii_strn2val((const char *)&data[6], 16, 2);
|
||
|
peer_addr.addr.addr[1] = ascii_strn2val((const char *)&data[8], 16, 2);
|
||
|
peer_addr.addr.addr[0] = ascii_strn2val((const char *)&data[10], 16, 2);
|
||
|
peer_addr.addr_type = ascii_strn2val((const char *)&data[13], 16, 2);
|
||
|
app_ble_conn_start(&peer_addr);
|
||
|
break;
|
||
|
case 'F':
|
||
|
app_ble_conn_stop();
|
||
|
break;
|
||
|
#if BTDM_STACK_ENABLE_BT == 1
|
||
|
case 'H':
|
||
|
ME_Inquiry(BT_IAC_GIAC, 5, 5);
|
||
|
break;
|
||
|
case 'I':
|
||
|
ME_CancelInquiry();
|
||
|
break;
|
||
|
case 'J':
|
||
|
{
|
||
|
BtStatus status;
|
||
|
addr.A[0] = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
addr.A[1] = ascii_strn2val((const char*)&data[2],16,2);
|
||
|
addr.A[2] = ascii_strn2val((const char*)&data[4],16,2);
|
||
|
addr.A[3] = ascii_strn2val((const char*)&data[6],16,2);
|
||
|
addr.A[4] = ascii_strn2val((const char*)&data[8],16,2);
|
||
|
addr.A[5] = ascii_strn2val((const char*)&data[10],16,2);
|
||
|
|
||
|
status = HFG_CreateServiceLink(&hfg_channel[0], &addr);
|
||
|
|
||
|
if (status == BT_STATUS_PENDING) {
|
||
|
printf("Opening Channel...\r\n");
|
||
|
} else {
|
||
|
printf("Could not open channel, status: %d\r\n", status);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 'K':
|
||
|
status = BT_STATUS_NO_RESOURCES;
|
||
|
rsp = (HfgResponse *)btdm_malloc(sizeof(HfgResponse));
|
||
|
if(rsp != NULL){
|
||
|
status = HFG_CreateCodecConnection(&hfg_channel[0], 1, rsp);
|
||
|
}
|
||
|
if(status != BT_STATUS_PENDING){
|
||
|
btdm_free((void *)rsp);
|
||
|
}
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'L':
|
||
|
flashdb_del(FDB_KEY_BT_LINKKEY);
|
||
|
|
||
|
break;
|
||
|
case 'M':
|
||
|
token = btdm_malloc(sizeof(MeCommandToken));
|
||
|
token->p.general.in.hciCommand = 0x0c18;//HCC_WRITE_PAGE_TIMEOUT;
|
||
|
token->p.general.in.parmLen = 2;
|
||
|
token->p.general.in.parms = (uint8_t *)&page_timeout;
|
||
|
token->callback = user_hci_callback; //token is freed at this callback
|
||
|
status = ME_SendHciCommandAsync(token);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'N':
|
||
|
{
|
||
|
addr.A[0] = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
addr.A[1] = ascii_strn2val((const char*)&data[2],16,2);
|
||
|
addr.A[2] = ascii_strn2val((const char*)&data[4],16,2);
|
||
|
addr.A[3] = ascii_strn2val((const char*)&data[6],16,2);
|
||
|
addr.A[4] = ascii_strn2val((const char*)&data[8],16,2);
|
||
|
addr.A[5] = ascii_strn2val((const char*)&data[10],16,2);
|
||
|
user_bt_env.connect_times = 3;
|
||
|
status = bt_connect(&addr);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
case 'O':
|
||
|
// {
|
||
|
// uint8_t battery_level[15] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
||
|
// struct gatt_send_event ntf[6];
|
||
|
// uint8_t i=0;
|
||
|
// for(i=0;i<6;i++){
|
||
|
// ntf[i].conidx = 0;
|
||
|
// ntf[i].svc_id = svc_id;
|
||
|
// ntf[i].att_idx = 2;
|
||
|
// ntf[i].data_len = 15;
|
||
|
// ntf[i].p_data = &battery_level[0];
|
||
|
// gatt_notification(&ntf[i]);
|
||
|
// }
|
||
|
// }
|
||
|
break;
|
||
|
case 'P':
|
||
|
addr.A[0] = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
addr.A[1] = ascii_strn2val((const char*)&data[2],16,2);
|
||
|
addr.A[2] = ascii_strn2val((const char*)&data[4],16,2);
|
||
|
addr.A[3] = ascii_strn2val((const char*)&data[6],16,2);
|
||
|
addr.A[4] = ascii_strn2val((const char*)&data[8],16,2);
|
||
|
addr.A[5] = ascii_strn2val((const char*)&data[10],16,2);
|
||
|
bt_disconnect(&addr,false);
|
||
|
break;
|
||
|
|
||
|
case 'Q':
|
||
|
addr.A[0] = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
addr.A[1] = ascii_strn2val((const char*)&data[2],16,2);
|
||
|
addr.A[2] = ascii_strn2val((const char*)&data[4],16,2);
|
||
|
addr.A[3] = ascii_strn2val((const char*)&data[6],16,2);
|
||
|
addr.A[4] = ascii_strn2val((const char*)&data[8],16,2);
|
||
|
addr.A[5] = ascii_strn2val((const char*)&data[10],16,2);
|
||
|
bt_disconnect(&addr,true);
|
||
|
break;
|
||
|
|
||
|
case 'R':
|
||
|
// ME_SetLocalDeviceName((const uint8_t *)"FR30xx_m", sizeof("FR30xx_m"));
|
||
|
//app_btdm_init();
|
||
|
|
||
|
break;
|
||
|
case 'S':
|
||
|
{
|
||
|
BtAccessModeInfo access_mode_nc = {
|
||
|
.inqInterval = 0x800,
|
||
|
.inqWindow = 0x12,
|
||
|
.pageInterval = 0x800,
|
||
|
.pageWindow = 0x12,
|
||
|
};
|
||
|
status = ME_SetAccessibleModeNC(BAM_GENERAL_ACCESSIBLE, &access_mode_nc);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'T':
|
||
|
{
|
||
|
status = ME_SetAccessibleModeNC(BAM_NOT_ACCESSIBLE, NULL);
|
||
|
printf("status = %d\r\n",status);
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
printf("OK\r\n");
|
||
|
}
|
||
|
#include "user_bt_pbap.h"
|
||
|
uint8_t voltage_str[] = "AT+IPHONEACCEV=1,1,6";
|
||
|
uint8_t cmps_str[] = "AT+CPMS=?";
|
||
|
//bt hf&pbap related cmd
|
||
|
static void app_at_recv_cmd_C(uint8_t sub_cmd, uint8_t *data)
|
||
|
{
|
||
|
printf("%s \r\n", __func__);
|
||
|
BtStatus status;
|
||
|
uint8_t state;
|
||
|
BD_ADDR addr;
|
||
|
switch(sub_cmd) {
|
||
|
case 'A':
|
||
|
status = bt_answer_call(user_bt_env.last_active_index);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'B':
|
||
|
status = bt_hang_up(user_bt_env.last_active_index);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'C':
|
||
|
status = bt_redial(user_bt_env.last_active_index);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'D':
|
||
|
{
|
||
|
//uint8_t number[] = "15907515643";
|
||
|
status = bt_dial_number(user_bt_env.last_active_index,&data[1],data[0]);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'E':
|
||
|
status = bt_list_current_calls(user_bt_env.last_active_index);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'F':
|
||
|
status = bt_transfer_sco(user_bt_env.last_active_index);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'G':
|
||
|
{
|
||
|
uint8_t dtmf = data[0];
|
||
|
status = bt_send_dtmf(user_bt_env.last_active_index,dtmf);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'H':
|
||
|
{
|
||
|
//vol---[0x00,0x0f]
|
||
|
uint8_t vol = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
status = bt_report_spk_volume(user_bt_env.last_active_index,vol);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'I':
|
||
|
{
|
||
|
status = bt_send_hf_cmd(user_bt_env.last_active_index,voltage_str);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'J':
|
||
|
{
|
||
|
uint8_t enabled = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
status = bt_enable_voice_recognition(user_bt_env.last_active_index, enabled);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'K':
|
||
|
printf("voice recog enabled : %d\r\n",bt_is_voice_rec_active(user_bt_env.last_active_index));
|
||
|
break;
|
||
|
|
||
|
case 'L':
|
||
|
//BD_ADDR addr;
|
||
|
//user_bt_env.dev[0].remote_bd;
|
||
|
|
||
|
#if BTDM_STACK_ENABLE_PBAP
|
||
|
state = user_bt_get_state(user_bt_env.last_active_index);
|
||
|
if(state >=BT_STATE_CONNECTED)
|
||
|
{
|
||
|
memcpy(&addr.A[0], &user_bt_env.dev[user_bt_env.last_active_index].remote_bd, 6);
|
||
|
//printf("%x%x%x%x%x%x\r\n",addr.A[0],addr.A[1],addr.A[2],addr.A[3],addr.A[4],addr.A[5]);
|
||
|
}
|
||
|
else {
|
||
|
addr.A[0] = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
addr.A[1] = ascii_strn2val((const char*)&data[2],16,2);
|
||
|
addr.A[2] = ascii_strn2val((const char*)&data[4],16,2);
|
||
|
addr.A[3] = ascii_strn2val((const char*)&data[6],16,2);
|
||
|
addr.A[4] = ascii_strn2val((const char*)&data[8],16,2);
|
||
|
addr.A[5] = ascii_strn2val((const char*)&data[10],16,2);
|
||
|
}
|
||
|
status = PBAP_ClientConnect(&pbap_client[0],&addr);
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
break;
|
||
|
case 'M':
|
||
|
#if BTDM_STACK_ENABLE_PBAP
|
||
|
status = PBAP_ClientDisconnect(&pbap_client[0]);
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
break;
|
||
|
case 'N':
|
||
|
{
|
||
|
#if BTDM_STACK_ENABLE_PBAP
|
||
|
uint8_t pbName[64];
|
||
|
PbapPullPbParms parms;
|
||
|
|
||
|
memcpy(pbName,PB_LOCAL_MCH_NAME,sizeof(PB_LOCAL_MCH_NAME));
|
||
|
parms.pbName = pbName;
|
||
|
memset(parms.filter.byte,0,PBAP_FILTER_SIZE);
|
||
|
parms.filter.byte[0] = 0x84;
|
||
|
parms.listStartOffset = 0;
|
||
|
parms.maxListCount = 100; //0---search missed call and total pb size
|
||
|
parms.format= VCARD_FORMAT_30;
|
||
|
status = PBAP_PullPhonebook(&pbap_client[0], &parms);
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
case 'O':
|
||
|
{
|
||
|
#if BTDM_STACK_ENABLE_PBAP
|
||
|
PbapPullVcardListingParms parms;
|
||
|
uint8_t search_val[12]; //= "13262651013";
|
||
|
memcpy(search_val,&data[0],11);
|
||
|
uint8_t folder[] = "telecom/pb";
|
||
|
parms.folderName = folder;
|
||
|
parms.order = VCARD_SORT_ORDER_INDEXED;
|
||
|
parms.listStartOffset = 0x00;
|
||
|
parms.maxListCount = 4;
|
||
|
parms.searchAttribute = VCARD_SEARCH_ATTRIB_NUMBER;
|
||
|
parms.searchValue = (const char *)search_val;
|
||
|
status = PBAP_PullVcardListing(&pbap_client[0], &parms);
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
case 'P':
|
||
|
{
|
||
|
#if BTDM_STACK_ENABLE_PBAP
|
||
|
uint8_t pbName[64];
|
||
|
PbapPullPbParms parms;
|
||
|
|
||
|
memcpy(pbName,PB_LOCAL_STORE_NAME,sizeof(PB_LOCAL_STORE_NAME));
|
||
|
parms.pbName = pbName;
|
||
|
memset(parms.filter.byte,0,PBAP_FILTER_SIZE);
|
||
|
parms.filter.byte[0] = 0x07;//0x84;
|
||
|
parms.listStartOffset = 0;
|
||
|
parms.maxListCount = 20; //0---search missed call and total pb size
|
||
|
parms.format= VCARD_FORMAT_30;
|
||
|
status = PBAP_PullPhonebook(&pbap_client[0], &parms);
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
case 'R':
|
||
|
{
|
||
|
user_connect_pbap_client();
|
||
|
}
|
||
|
break;
|
||
|
case 'T':
|
||
|
{
|
||
|
user_pull_phonebook(0,0,25);
|
||
|
}
|
||
|
break;
|
||
|
case 'X':
|
||
|
{
|
||
|
uint8_t mute_str[] = "AT+CMUT=1";
|
||
|
status = bt_send_hf_cmd(user_bt_env.last_active_index,mute_str);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'Y':
|
||
|
{
|
||
|
flash_wr_test();
|
||
|
}
|
||
|
break;
|
||
|
case 'Q':
|
||
|
{
|
||
|
user_del_pbap_info();
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
printf("OK\r\n");
|
||
|
}
|
||
|
|
||
|
///bt media related cmd
|
||
|
static void app_at_recv_cmd_E(uint8_t sub_cmd, uint8_t *data)
|
||
|
{
|
||
|
BD_ADDR addr;
|
||
|
BtStatus status;
|
||
|
switch(sub_cmd) {
|
||
|
case 'A':
|
||
|
status = AVRCP_SetPanelKey(user_bt_env.dev[user_bt_env.last_active_index].rcp_chan, AVRCP_POP_PLAY, TRUE);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'B':
|
||
|
status = AVRCP_SetPanelKey(user_bt_env.dev[user_bt_env.last_active_index].rcp_chan, AVRCP_POP_PAUSE, TRUE);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'C':
|
||
|
status = AVRCP_SetPanelKey(user_bt_env.dev[user_bt_env.last_active_index].rcp_chan, AVRCP_POP_FORWARD, TRUE);
|
||
|
printf("status = %d\r\n",status);
|
||
|
break;
|
||
|
case 'D':
|
||
|
{
|
||
|
status = AVRCP_SetPanelKey(user_bt_env.dev[user_bt_env.last_active_index].rcp_chan, AVRCP_POP_BACKWARD, TRUE);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'E':
|
||
|
{
|
||
|
printf("vol %d\r\n",data[0]);
|
||
|
uint8_t vol = data[0];//ascii_strn2val((const char*)&data[0],16,2);
|
||
|
status = bt_set_media_volume(user_bt_env.last_active_index,vol);
|
||
|
printf("status = %d %d\r\n",status,vol);
|
||
|
}
|
||
|
break;
|
||
|
case 'F':
|
||
|
{
|
||
|
status = bt_get_media_info(user_bt_env.last_active_index,0x41);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'G':
|
||
|
{
|
||
|
status = bt_get_playstatus(user_bt_env.last_active_index);
|
||
|
printf("status = %d\r\n",status);
|
||
|
}
|
||
|
break;
|
||
|
case 'H':
|
||
|
#if BTDM_STACK_ENABLE_SPP
|
||
|
addr.A[0] = ascii_strn2val((const char*)&data[0],16,2);
|
||
|
addr.A[1] = ascii_strn2val((const char*)&data[2],16,2);
|
||
|
addr.A[2] = ascii_strn2val((const char*)&data[4],16,2);
|
||
|
addr.A[3] = ascii_strn2val((const char*)&data[6],16,2);
|
||
|
addr.A[4] = ascii_strn2val((const char*)&data[8],16,2);
|
||
|
addr.A[5] = ascii_strn2val((const char*)&data[10],16,2);
|
||
|
status = spp_connect(&spp_dev[0],&addr);
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
break;
|
||
|
case 'I':
|
||
|
#if BTDM_STACK_ENABLE_SPP
|
||
|
status = spp_disconnect(&spp_dev[0]);
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
break;
|
||
|
case 'J':
|
||
|
{
|
||
|
#if BTDM_STACK_ENABLE_SPP
|
||
|
uint8_t test_data[] = {'1','2','3','4'};
|
||
|
status = spp_send(&spp_dev[0],test_data,sizeof(test_data));
|
||
|
printf("status = %d\r\n",status);
|
||
|
#endif
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
printf("OK\r\n");
|
||
|
}
|
||
|
__RAM_CODE static void app_at_recv_cmd_D(uint8_t sub_cmd, uint8_t *data)
|
||
|
{
|
||
|
switch(sub_cmd) {
|
||
|
case 'A':
|
||
|
flash_erase(QSPI0, ascii_strn2val((const char*)&data[0],16,8), 0x1000);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
printf("OK\r\n");
|
||
|
}
|
||
|
|
||
|
__RAM_CODE void app_at_cmd_recv_handler(uint8_t *data, uint16_t length)
|
||
|
{
|
||
|
switch(data[0])
|
||
|
{
|
||
|
case 'A':
|
||
|
app_at_recv_cmd_A(data[1], &data[2]);
|
||
|
break;
|
||
|
case 'B':
|
||
|
app_at_recv_cmd_B(data[1], &data[2]);
|
||
|
break;
|
||
|
case 'C':
|
||
|
app_at_recv_cmd_C(data[1], &data[2]);
|
||
|
break;
|
||
|
case 'D':
|
||
|
app_at_recv_cmd_D(data[1], &data[2]);
|
||
|
break;
|
||
|
case 'E':
|
||
|
app_at_recv_cmd_E(data[1], &data[2]);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void app_at_recv_c(uint8_t c)
|
||
|
{
|
||
|
switch(at_recv_state)
|
||
|
{
|
||
|
case 0:
|
||
|
if(c == 'A')
|
||
|
{
|
||
|
at_recv_state++;
|
||
|
}
|
||
|
break;
|
||
|
case 1:
|
||
|
if(c == 'T')
|
||
|
at_recv_state++;
|
||
|
else
|
||
|
at_recv_state = 0;
|
||
|
break;
|
||
|
case 2:
|
||
|
if(c == '#')
|
||
|
at_recv_state++;
|
||
|
else
|
||
|
at_recv_state = 0;
|
||
|
break;
|
||
|
case 3:
|
||
|
at_recv_buffer[at_recv_index++] = c;
|
||
|
if((c == '\n')
|
||
|
||(at_recv_index >= AT_RECV_MAX_LEN))
|
||
|
{
|
||
|
struct app_task_event *event;
|
||
|
event = app_task_event_alloc(APP_TASK_EVENT_AT_CMD, at_recv_index, false);
|
||
|
if(event) {
|
||
|
memcpy(event->param, at_recv_buffer, at_recv_index);
|
||
|
app_task_event_post(event, false);
|
||
|
}
|
||
|
at_recv_state = 0;
|
||
|
at_recv_index = 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void app_at_rx_done(struct __UART_HandleTypeDef *handle)
|
||
|
{
|
||
|
app_at_recv_c(app_at_recv_char);
|
||
|
if (handle) {
|
||
|
uart_receive_IT(handle, &app_at_recv_char, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void app_at_init(void)
|
||
|
{
|
||
|
hw_log_init(false);
|
||
|
|
||
|
uart_receive_IT(&uart_log_handle, &app_at_recv_char, 1);
|
||
|
}
|
||
|
|
||
|
void uart3_irq(void)
|
||
|
{
|
||
|
uart_IRQHandler(&uart_log_handle);
|
||
|
}
|
||
|
|
||
|
int fputc(int c, FILE *fp)
|
||
|
{
|
||
|
uart_transmit(&uart_log_handle, (void *)&c, 1);
|
||
|
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
void uart_transmit_byte(uint8_t *p,uint32_t len)
|
||
|
{
|
||
|
uart_transmit(&uart_log_handle, (void *)p, len);
|
||
|
|
||
|
}
|