558 lines
16 KiB
C
558 lines
16 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "app_protocol_api.h"
|
|
#include "system/includes.h"
|
|
#include "vm.h"
|
|
#include "audio_config.h"
|
|
#include "app_power_manage.h"
|
|
#include "user_cfg.h"
|
|
|
|
#if APP_PROTOCOL_GMA_CODE
|
|
|
|
#if 1
|
|
#define APP_GMA_LOG printf
|
|
#define APP_GMA_DUMP put_buf
|
|
#else
|
|
#define APP_GMA_LOG(...)
|
|
#define APP_GMA_DUMP(...)
|
|
#endif
|
|
|
|
//*********************************************************************************//
|
|
// GMA认证信息 //
|
|
//*********************************************************************************//
|
|
|
|
#define GMA_GMA_FROM_FLASH 0
|
|
#define GMA_GMA_FROM_FILE 1
|
|
|
|
#define GMA_GMA_SOURCH GMA_GMA_FROM_FLASH
|
|
|
|
|
|
extern int le_controller_set_mac(void *addr);
|
|
extern void lmp_hci_write_local_address(const u8 *addr);
|
|
extern void lmp_hci_read_local_address(u8 *addr);
|
|
extern void bt_update_testbox_addr(u8 *addr);
|
|
|
|
typedef struct {
|
|
uint8_t mac[6];
|
|
uint32_t pid;
|
|
uint8_t secret[16];
|
|
} ali_para_s;
|
|
|
|
static ali_para_s ali_para;
|
|
static ali_para_s *active_ali_para = NULL;
|
|
|
|
///mac reverse
|
|
void gma_mac_addr_reverse_get(uint8_t *buf)
|
|
{
|
|
memcpy(buf, (const void *)active_ali_para->mac, 6);
|
|
}
|
|
|
|
#define LEGAL_PID_NUM(cha) (cha>='0' && cha<='9')
|
|
#define LEGAL_MAC_NUM(cha) ((cha>='0'&&cha<='9') || (cha>='a'&&cha<='f') || (cha>='A'&&cha<='F') || (cha==':'))
|
|
#define LEGAL_SECRET_NUM(cha) ((cha>='0'&&cha<='9') || (cha>='a'&&cha<='f') || (cha>='A'&&cha<='F'))
|
|
|
|
#define USELESS_CHAR ':'
|
|
#define GMA_ALI_PARA_END_CHAR ','
|
|
#define GMA_ALI_PARA_MAC_CHAR_NUMS (sizeof(((ali_para_s *)0)->mac))
|
|
#define GMA_ALI_PARA_PID_CHAR_NUMS 4//(sizeof(((ali_para_s *)0)->pid))
|
|
#define GMA_ALI_PARA_SECRET_CHAR_NUMS (sizeof(((ali_para_s *)0)->secret))
|
|
|
|
static u8 gma_ali_para_char2num(u8 cha)
|
|
{
|
|
u8 num = 0;
|
|
|
|
if (cha >= '0' && cha <= '9') {
|
|
num = cha - '0';
|
|
} else if (cha >= 'a' && cha <= 'f') {
|
|
num = cha - 'a' + 10;
|
|
} else if (cha >= 'A' && cha <= 'F') {
|
|
num = cha - 'A' + 10;
|
|
}
|
|
|
|
return num;
|
|
}
|
|
|
|
static int gma_license_set(ali_para_s *ali_para)
|
|
{
|
|
const u8 *gma_ptr = (u8 *)app_protocal_get_license_ptr();
|
|
|
|
if (gma_ptr == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
///license fill
|
|
//pid
|
|
memcpy((u8 *) & (ali_para->pid), gma_ptr, sizeof(ali_para->pid));
|
|
gma_ptr += sizeof(ali_para->pid);
|
|
APP_GMA_LOG("gma pid:%d \n", ali_para->pid);
|
|
//secret
|
|
memcpy((u8 *)(ali_para->secret), gma_ptr, sizeof(ali_para->secret));
|
|
gma_ptr += sizeof(ali_para->secret);
|
|
APP_GMA_LOG("gma secret:");
|
|
APP_GMA_DUMP(ali_para->secret, sizeof(ali_para->secret));
|
|
//mac
|
|
memcpy((u8 *)(ali_para->mac), gma_ptr, sizeof(ali_para->mac));
|
|
gma_ptr += sizeof(ali_para->mac);
|
|
{
|
|
//mac reverse
|
|
u8 mac_backup_buf[6];
|
|
memcpy(mac_backup_buf, ali_para->mac, 6);
|
|
int i;
|
|
for (i = 0; i < 6; i++) {
|
|
ali_para->mac[i] = (mac_backup_buf)[5 - i];
|
|
}
|
|
}
|
|
APP_GMA_LOG("gma mac:");
|
|
APP_GMA_DUMP(ali_para->mac, sizeof(ali_para->mac));
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if GMA_GMA_SOURCH == GMA_GMA_FROM_FILE
|
|
|
|
#define ALI_PARA_ACTIVE_NUM 1
|
|
|
|
static const char *ali_para_string[] = {
|
|
"jl_auif",
|
|
//Product ID,Device Secret,Mac,Md5
|
|
//此处可以用户自行填写从阿里申请的三元组信息
|
|
" ",
|
|
};
|
|
|
|
static bool gma_ali_para_info_fill(const u8 *para, ali_para_s *ali_para)
|
|
{
|
|
const u8 *para_string = para;
|
|
u8 highbit_en = 0;
|
|
uint32_t pid = 0;
|
|
uint32_t char_nums = 0;
|
|
uint8_t *secret = ali_para->secret;
|
|
uint8_t *mac = ali_para->mac;
|
|
|
|
while (*para_string && *para_string != GMA_ALI_PARA_END_CHAR) {
|
|
if (!LEGAL_PID_NUM(*para_string)) {
|
|
/* APP_GMA_LOG("pid illegal character !!! \n"); */
|
|
para_string++;
|
|
continue;
|
|
}
|
|
|
|
///check pid character numbers legal scope
|
|
char_nums++;
|
|
if (char_nums > GMA_ALI_PARA_PID_CHAR_NUMS) {
|
|
APP_GMA_LOG("pid character numbers overflow !!! \n");
|
|
return false;
|
|
}
|
|
|
|
pid *= 10;
|
|
pid += gma_ali_para_char2num(*para_string);
|
|
para_string++;
|
|
}
|
|
|
|
///check pid character numbers legal scope
|
|
if (char_nums != GMA_ALI_PARA_PID_CHAR_NUMS) {
|
|
APP_GMA_LOG("pid character numbers error:%d !!! \n", char_nums);
|
|
return false;
|
|
}
|
|
|
|
APP_GMA_LOG(">>pid:%d \n", pid);
|
|
ali_para->pid = pid;
|
|
|
|
para_string++;
|
|
char_nums = 0;
|
|
memset(ali_para->secret, 0x00, sizeof(ali_para->secret));
|
|
while (*para_string != GMA_ALI_PARA_END_CHAR) {
|
|
if (!LEGAL_SECRET_NUM(*para_string)) {
|
|
APP_GMA_LOG("secret illegal character !!! \n");
|
|
para_string++;
|
|
continue;
|
|
}
|
|
|
|
///assignment secret
|
|
if (!highbit_en) {
|
|
*secret += gma_ali_para_char2num(*para_string);
|
|
highbit_en ^= 1;
|
|
} else {
|
|
///check secret character numbers legal scope
|
|
char_nums++;
|
|
if (char_nums > GMA_ALI_PARA_SECRET_CHAR_NUMS) {
|
|
APP_GMA_LOG("secret character number overflow !!! \n");
|
|
return false;
|
|
}
|
|
|
|
*secret <<= 4;
|
|
*secret++ += gma_ali_para_char2num(*para_string);
|
|
highbit_en ^= 1;
|
|
}
|
|
|
|
para_string++;
|
|
}
|
|
|
|
///check secret character numbers legal scope
|
|
if (char_nums != GMA_ALI_PARA_SECRET_CHAR_NUMS) {
|
|
APP_GMA_LOG("secret character number error !!! :%d \n", char_nums);
|
|
return false;
|
|
}
|
|
|
|
///print secret
|
|
APP_GMA_LOG(">>ali_para secret: ");
|
|
for (int i = 0; i < sizeof(ali_para->secret) / sizeof(ali_para->secret[0]); i++) {
|
|
APP_GMA_LOG("%x ", ali_para->secret[i]);
|
|
}
|
|
|
|
memset(ali_para->mac, 0x00, sizeof(ali_para->mac));
|
|
para_string++;
|
|
highbit_en = 0;
|
|
char_nums = 0;
|
|
while (*para_string != GMA_ALI_PARA_END_CHAR) {
|
|
//if legal character
|
|
if (!LEGAL_MAC_NUM(*para_string)) {
|
|
APP_GMA_LOG("mac illegal character !!! \n");
|
|
para_string++;
|
|
continue;
|
|
// return false;
|
|
}
|
|
|
|
if (*para_string == USELESS_CHAR) {
|
|
para_string++;
|
|
continue;
|
|
}
|
|
|
|
///assignment mac
|
|
if (!highbit_en) {
|
|
*mac += gma_ali_para_char2num(*para_string);
|
|
highbit_en ^= 1;
|
|
} else {
|
|
//check mac character numbers legal scope
|
|
char_nums++;
|
|
if (char_nums > GMA_ALI_PARA_MAC_CHAR_NUMS) {
|
|
APP_GMA_LOG("mac character numbers overflow !!! \n");
|
|
return false;
|
|
}
|
|
|
|
*mac <<= 4;
|
|
*mac++ += gma_ali_para_char2num(*para_string);
|
|
highbit_en ^= 1;
|
|
}
|
|
|
|
para_string++;
|
|
}
|
|
|
|
//check mac character numbers legal scope
|
|
if (char_nums != GMA_ALI_PARA_MAC_CHAR_NUMS) {
|
|
APP_GMA_LOG("mac character numbers error !!! \n");
|
|
return false;
|
|
}
|
|
|
|
///mac reverse
|
|
for (int i = 0, tmp_mac = 0, array_size = (sizeof(ali_para->mac) / sizeof(ali_para->mac[0])); \
|
|
i < (sizeof(ali_para->mac) / sizeof(ali_para->mac[0]) / 2); i++) {
|
|
tmp_mac = ali_para->mac[i];
|
|
ali_para->mac[i] = ali_para->mac[array_size - 1 - i];
|
|
ali_para->mac[array_size - 1 - i] = tmp_mac;
|
|
}
|
|
|
|
///print secret
|
|
APP_GMA_LOG(">>ali_para mac: ");
|
|
for (int i = 0; i < sizeof(ali_para->mac) / sizeof(ali_para->mac[0]); i++) {
|
|
APP_GMA_LOG("%x ", ali_para->mac[i]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static int gma_license2flash(const ali_para_s *ali_para)
|
|
{
|
|
int i;
|
|
u8 mac[6];
|
|
u8 rdata[sizeof(ali_para_s)];
|
|
|
|
for (i = 0; i < sizeof(mac); i++) {
|
|
mac[i] = ali_para->mac[5 - i];
|
|
}
|
|
memcpy(rdata, &ali_para->pid, sizeof(ali_para->pid));
|
|
memcpy(rdata + sizeof(ali_para->pid), ali_para->secret, sizeof(ali_para->secret));
|
|
memcpy(rdata + sizeof(ali_para->pid) + sizeof(ali_para->secret), mac, sizeof(mac));
|
|
|
|
return app_protocol_license2flash(rdata, sizeof(rdata));
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#if TCFG_USER_TWS_ENABLE
|
|
#include "bt_tws.h"
|
|
static ali_para_s ali_para_remote; //对耳的三元组
|
|
|
|
//VM_GMA_MAC 对耳的地址
|
|
//VM_GMA_ALI_PARA 对耳的三元组
|
|
|
|
static int gma_strcmp(const u8 *ptr1, const u8 *ptr2, u8 len)
|
|
{
|
|
while (len--) {
|
|
if (*ptr1 != *ptr2) {
|
|
return (*ptr1 - *ptr2);
|
|
}
|
|
|
|
ptr1++;
|
|
ptr2++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
///mac reverse
|
|
u8 *gma_sibling_mac_get() //获取地址较小的那个
|
|
{
|
|
ali_para_s *sibling_ali_para = NULL;//&ali_para;
|
|
if (active_ali_para == &ali_para) {
|
|
printf("ali_para active \n");
|
|
sibling_ali_para = &ali_para_remote;
|
|
}
|
|
|
|
if (active_ali_para == &ali_para_remote) {
|
|
printf("ali_para active \n");
|
|
sibling_ali_para = &ali_para;
|
|
}
|
|
|
|
return (sibling_ali_para ? sibling_ali_para->mac : NULL);
|
|
}
|
|
|
|
int gma_select_ali_para_by_common_mac()
|
|
{
|
|
u8 ret = 0;
|
|
u8 mac[6];
|
|
u8 mac_buf_tmp[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
|
ret = syscfg_read(CFG_TWS_COMMON_ADDR, mac, 6);
|
|
if (ret != 6 || !memcmp(mac, mac_buf_tmp, 6)) {
|
|
printf("tws no conn\n");
|
|
return -1;
|
|
}
|
|
APP_GMA_LOG("active mac:");
|
|
APP_GMA_DUMP(mac, 6);
|
|
///select para
|
|
ali_para_s ali_para_temp;
|
|
syscfg_read(VM_GMA_ALI_PARA, (u8 *) &ali_para_temp, sizeof(ali_para_s));
|
|
if (ali_para_temp.pid == ali_para.pid) {
|
|
memcpy(&ali_para_remote, &ali_para_temp, sizeof(ali_para_s));
|
|
APP_GMA_LOG("remote mac:");
|
|
APP_GMA_DUMP(ali_para_remote.mac, 6);
|
|
APP_GMA_LOG("remote pid:%d \n", ali_para_remote.pid);
|
|
APP_GMA_LOG("remote secret:");
|
|
APP_GMA_DUMP(ali_para_remote.secret, sizeof(ali_para_remote.secret));
|
|
if (gma_strcmp(mac, ali_para_remote.mac, 6) == 0) {
|
|
APP_GMA_LOG("used remote para \n");
|
|
active_ali_para = &ali_para_remote;
|
|
return 0;
|
|
} else if (gma_strcmp(mac, ali_para.mac, 6) == 0) {
|
|
APP_GMA_LOG("used local para \n");
|
|
active_ali_para = &ali_para;
|
|
return 0;
|
|
} else {
|
|
APP_GMA_LOG("MAC ERROR !!!!!!!!!!!!!!!!\n");
|
|
return -1;
|
|
}
|
|
} else {
|
|
APP_GMA_LOG("no remote mac \n");
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void gma_slave_sync_remote_addr(u8 *buf)
|
|
{
|
|
u8 common_addr[6];
|
|
///remote ali_para fill
|
|
memcpy(&ali_para_remote, buf, sizeof(ali_para_remote));
|
|
syscfg_write(VM_GMA_MAC, ali_para_remote.mac, 6);
|
|
|
|
///write ali para to vm
|
|
syscfg_write(VM_GMA_ALI_PARA, (u8 *)&ali_para_remote, sizeof(ali_para_remote));
|
|
|
|
tws_api_get_local_addr(common_addr);
|
|
if (memcmp(active_ali_para->mac, common_addr, 6)) { //common地址发生变化
|
|
APP_GMA_LOG("gma addr change");
|
|
///used slave address
|
|
active_ali_para = &ali_para_remote;
|
|
app_protocol_set_tws_sibling_mac(ali_para.mac);
|
|
app_protocol_set_info_group(GMA_HANDLER_ID, active_ali_para); //设置三元组
|
|
//断开APP接口
|
|
if (is_tws_master_role()) {
|
|
APP_GMA_LOG("gma need reconn app");
|
|
app_protocol_disconnect(NULL);
|
|
app_protocol_ble_adv_switch(0);
|
|
le_controller_set_mac(active_ali_para->mac);
|
|
app_protocol_ble_adv_switch(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_NEW_BREDR_ENABLE
|
|
void tws_host_get_common_addr(u8 *remote_addr, u8 *common_addr, char channel)
|
|
#else
|
|
void tws_host_get_common_addr(u8 *local_addr, u8 *remote_addr, u8 *common_addr, char channel)
|
|
#endif
|
|
{
|
|
APP_GMA_LOG(">>>>>>>>>tws_host_get_common_addr ch:%c \n", channel);
|
|
|
|
u8 mac_buf[6];
|
|
gma_mac_addr_reverse_get(mac_buf);
|
|
APP_GMA_LOG(">>>local mac: ");
|
|
APP_GMA_DUMP(mac_buf, 6);
|
|
///used the bigger one as host bt mac
|
|
if (gma_strcmp(mac_buf, (const u8 *)remote_addr, 6) < 0) {
|
|
///used slave mac addr;remote_addr from slave addr reverse
|
|
memcpy(common_addr, remote_addr, 6);
|
|
} else {
|
|
///used master mac addr
|
|
gma_mac_addr_reverse_get(common_addr);
|
|
}
|
|
APP_GMA_LOG("common_addr: ");
|
|
APP_GMA_DUMP((const u8 *)common_addr, 6);
|
|
APP_GMA_LOG("remote_addr: ");
|
|
APP_GMA_DUMP((const u8 *)remote_addr, 6);
|
|
}
|
|
|
|
void gma_kick_license_to_sibling(void)
|
|
{
|
|
APP_GMA_LOG("send license info to sibling\n");
|
|
app_protocol_tws_send_to_sibling(GMA_TWS_CMD_SYNC_LIC, (u8 *) & (ali_para), sizeof(ali_para));;
|
|
}
|
|
|
|
void gma_tws_remove_paired(void)
|
|
{
|
|
ali_para_s ali_para_temp;
|
|
memset(&ali_para_temp, 0xff, sizeof(ali_para_s));
|
|
syscfg_write(VM_GMA_ALI_PARA, (u8 *)&ali_para_temp, sizeof(ali_para_s));
|
|
|
|
active_ali_para = &ali_para;
|
|
app_protocol_set_tws_sibling_mac(ali_para_temp.mac);
|
|
app_protocol_set_info_group(GMA_HANDLER_ID, active_ali_para); //设置三元组
|
|
|
|
app_protocol_disconnect(NULL);
|
|
app_protocol_ble_adv_switch(0);
|
|
le_controller_set_mac(active_ali_para->mac);
|
|
app_protocol_ble_adv_switch(1);
|
|
}
|
|
|
|
#endif
|
|
|
|
__attribute__((weak))
|
|
void bt_update_testbox_addr(u8 *addr)
|
|
{
|
|
|
|
}
|
|
int gma_prev_init(void)
|
|
{
|
|
int err = 0;
|
|
/* ali_para_s ali_para; */
|
|
#if GMA_GMA_SOURCH == GMA_GMA_FROM_FLASH
|
|
err = gma_license_set(&ali_para);
|
|
#elif GMA_GMA_SOURCH == GMA_GMA_FROM_FILE
|
|
u8 *ali_str = ali_para_string[ALI_PARA_ACTIVE_NUM];
|
|
u8 ali_license[128] = {0};
|
|
|
|
//check if exist flash file
|
|
if (read_cfg_file(ali_license, sizeof(ali_license), SDFILE_RES_ROOT_PATH"license.txt") == TRUE) {
|
|
ali_str = ali_license;
|
|
}
|
|
APP_GMA_LOG("ali_str:%s\n", ali_str);
|
|
if (gma_ali_para_info_fill((const u8 *)ali_str, &ali_para) == false) {
|
|
APP_GMA_LOG("array context not good \n");
|
|
///read license from flash
|
|
err = gma_license_set(&ali_para);
|
|
}
|
|
///write license to flash
|
|
if (!err) {
|
|
/* gma_license2flash(&ali_para); */
|
|
}
|
|
#endif
|
|
if (!err) {
|
|
active_ali_para = &ali_para;
|
|
#if TCFG_USER_TWS_ENABLE
|
|
if (!gma_select_ali_para_by_common_mac()) {
|
|
app_protocol_set_tws_sibling_mac(gma_sibling_mac_get());
|
|
}
|
|
#endif
|
|
app_protocol_set_info_group(GMA_HANDLER_ID, active_ali_para); //设置三元组
|
|
bt_update_mac_addr(active_ali_para->mac);
|
|
lmp_hci_write_local_address(active_ali_para->mac);
|
|
app_protocol_ble_adv_switch(0);
|
|
le_controller_set_mac(active_ali_para->mac); //修改BLE地址
|
|
bt_update_testbox_addr(ali_para.mac);
|
|
}
|
|
return err;
|
|
}
|
|
|
|
|
|
//*********************************************************************************//
|
|
// GMA 提示音 //
|
|
//*********************************************************************************//
|
|
const char *gma_tone_tab[APP_RROTOCOL_TONE_MAX] = {
|
|
[APP_RROTOCOL_TONE_SPEECH_KEY_START] = TONE_NORMAL,
|
|
};
|
|
|
|
//*********************************************************************************//
|
|
// DMA私有消息处理 //
|
|
//*********************************************************************************//
|
|
#if TCFG_USER_TWS_ENABLE
|
|
void gma_rx_tws_data_deal(u16 opcode, u8 *data, u16 len)
|
|
{
|
|
switch (opcode) {
|
|
case GMA_TWS_CMD_SYNC_LIC:
|
|
printf(">>> TWS_AI_GMA_START_SYNC_LIC \n");
|
|
gma_slave_sync_remote_addr(data);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void gma_bt_tws_event_handler(struct bt_event *bt)
|
|
{
|
|
int role = bt->args[0];
|
|
int phone_link_connection = bt->args[1];
|
|
int reason = bt->args[2];
|
|
|
|
switch (bt->event) {
|
|
case TWS_EVENT_CONNECTED:
|
|
gma_kick_license_to_sibling();
|
|
break;
|
|
case TWS_EVENT_REMOVE_PAIRS:
|
|
gma_tws_remove_paired();
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static int gma_bt_status_event_handler(struct bt_event *bt)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int gma_sys_event_deal(struct sys_event *event)
|
|
{
|
|
switch (event->type) {
|
|
case SYS_BT_EVENT:
|
|
if ((u32)event->arg == SYS_BT_EVENT_TYPE_CON_STATUS) {
|
|
gma_bt_status_event_handler(&event->u.bt);
|
|
}
|
|
#if TCFG_USER_TWS_ENABLE
|
|
else if (((u32)event->arg == SYS_BT_EVENT_FROM_TWS)) {
|
|
gma_bt_tws_event_handler(&event->u.bt);
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
struct app_protocol_private_handle_t gma_private_handle = {
|
|
#if TCFG_USER_TWS_ENABLE
|
|
.tws_rx_from_siblling = gma_rx_tws_data_deal,
|
|
#endif
|
|
/* .tws_sync_func = ; */
|
|
.sys_event_handler = gma_sys_event_deal,
|
|
};
|
|
#endif
|
|
|