CARPLAY版本整理
817
MXC_A27-PCB4.5-270T/app/app_wifi_network.c
Normal file
@ -0,0 +1,817 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "chip.h"
|
||||
#include "animation.h"
|
||||
#include "sfud.h"
|
||||
#include "romfile.h"
|
||||
#include "updatefile.h"
|
||||
#include "sysinfo.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "ff_stdio.h"
|
||||
#include "ota_update.h"
|
||||
#include "md5.h"
|
||||
#include "unzip.h"
|
||||
#include "ff_sddisk.h"
|
||||
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "iperf_task.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "FreeRTOS_DHCP_Server.h"
|
||||
|
||||
#include "sockets.h"
|
||||
|
||||
uint8_t wifi_ota_state = 0;
|
||||
extern int timeout;
|
||||
|
||||
typedef enum {
|
||||
UART_FILE_NORMAL,
|
||||
UART_FILE_TYPE,
|
||||
UART_FILE_START,
|
||||
UART_FILE_FILEXFER,
|
||||
UART_FILE_FINISH,
|
||||
} eWifiFileStatus;
|
||||
|
||||
typedef enum {
|
||||
UART_FILE_AMT630H,
|
||||
UART_FILE_BOOTANIM,
|
||||
UART_FILE_ROM,
|
||||
UART_FILE_UPDATE,
|
||||
UART_FILE_SPILEDR,
|
||||
UART_FILE_STEPLDR,
|
||||
} eWifiFileType;
|
||||
|
||||
static uint8_t file_state = UART_FILE_NORMAL;//文件接收状态
|
||||
static uint8_t uup_file_type = UART_FILE_NORMAL;//文件接收状态
|
||||
uint8_t wifi_file_state = UART_FILE_NORMAL;//文件接收状态
|
||||
|
||||
#define BYTESPERPAGE 256
|
||||
#define PAGESPERSECTORS 32//32//16
|
||||
#define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS)
|
||||
#define NEW_APPLDR_CHECKSUM_OFFSET 0x14
|
||||
static unsigned int checksum = 0,calc_checksum = 0xffffffff,test_checksum = 0xffffffff;
|
||||
|
||||
#define NEW_APPFOOSET 0x17F0000
|
||||
#define AMT630_BIN_MAX_SIZE 0x700000
|
||||
|
||||
static uint32_t uup_burn_offset;
|
||||
// static unsigned char uup_buf[4096];
|
||||
static unsigned char uup_buf[8192];
|
||||
static unsigned int uup_buf_len = 0;
|
||||
static unsigned int uup_buf_len_detection = 0;
|
||||
static uint8_t checksum_flag = 0;
|
||||
|
||||
static int test_flag = 0;
|
||||
// static int number = 0;
|
||||
static void ota_update(char *framebuf, size_t len)
|
||||
{
|
||||
unsigned int framelen;
|
||||
framelen = len;
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
if(strcmp(framebuf, "AT_OTA_FINISH") == 0){
|
||||
if(file_state == UART_FILE_FILEXFER)
|
||||
file_state = UART_FILE_FINISH;
|
||||
}
|
||||
|
||||
switch(file_state){
|
||||
case UART_FILE_NORMAL://检测是否是升级
|
||||
if(strcmp(framebuf, "AT_OTA_START") == 0)
|
||||
file_state = UART_FILE_TYPE;
|
||||
break;
|
||||
case UART_FILE_TYPE://检测传输文件类型
|
||||
if(strncmp(framebuf, "AT_OTA_TYPE=",12) == 0 && (framelen == 13)){
|
||||
uup_file_type = framebuf[12] - '0';
|
||||
printf("uup_file_type = %d .\r\n",uup_file_type);
|
||||
if(uup_file_type<6){
|
||||
//擦除flash
|
||||
uup_burn_offset = NEW_APPFOOSET;
|
||||
printf("start erase add %X , size %X .\r\n",uup_burn_offset,AMT630_BIN_MAX_SIZE);
|
||||
if(sfud_erase(sflash, uup_burn_offset, AMT630_BIN_MAX_SIZE)==SFUD_SUCCESS){
|
||||
vTaskDelay(100);
|
||||
printf("UART_FRAME_START sfud erase ok.\n");
|
||||
}else{
|
||||
vTaskDelay(100);
|
||||
printf("UART_FRAME_START sfud erase fail.\n");
|
||||
}
|
||||
checksum_flag = 1;
|
||||
calc_checksum = 0xffffffff;
|
||||
test_checksum = 0xffffffff;
|
||||
test_flag = 0;
|
||||
uup_buf_len =0;
|
||||
checksum = 0;
|
||||
// number = 0;
|
||||
file_state = UART_FILE_START;
|
||||
}else
|
||||
file_state = UART_FILE_NORMAL;
|
||||
}else{
|
||||
file_state = UART_FILE_NORMAL;
|
||||
}
|
||||
|
||||
break;
|
||||
case UART_FILE_START://第一包数据 用于获取当前数据包的校验和
|
||||
if (uup_file_type == UART_FILE_AMT630H) {//代码文件
|
||||
unsigned int magic = framebuf[0] | (framebuf[1] << 8) | (framebuf[2] << 16) | (framebuf[3] << 24);
|
||||
if (magic != UPFILE_APP_MAGIC) {
|
||||
printf("Wrong app file magic. 0x%08X\n",magic);
|
||||
file_state = UART_FILE_NORMAL;
|
||||
break;
|
||||
}
|
||||
unsigned char *tmp = framebuf + NEW_APPLDR_CHECKSUM_OFFSET;
|
||||
checksum = tmp[0] | (tmp[1] <<8) | (tmp[2] << 16) | (tmp[3] << 24);
|
||||
}else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件
|
||||
BANIHEADER *header = (BANIHEADER *)&framebuf[0];
|
||||
if (header->magic != MKTAG('B', 'A', 'N', 'I')) {
|
||||
printf("Wrong animation file magic.\n");
|
||||
file_state = UART_FILE_NORMAL;
|
||||
break;
|
||||
}
|
||||
checksum = header->checksum;
|
||||
}else if (uup_file_type == UART_FILE_ROM) {//资源文件
|
||||
RomHeader *header = (RomHeader *)&framebuf[0];
|
||||
if (header->magic != MKTAG('R', 'O', 'M', 'A')) {
|
||||
printf("Wrong resource file magic.\n");
|
||||
file_state = UART_FILE_NORMAL;
|
||||
break;
|
||||
}
|
||||
checksum = header->checksum;
|
||||
}
|
||||
printf("uup_file_type = %d ,No1.checksum = 0x%X\n",uup_file_type,checksum);
|
||||
|
||||
uup_buf_len_detection = (uup_buf_len + framelen)>UUP_BUF_SIZE?(UUP_BUF_SIZE-uup_buf_len):0;
|
||||
// printf("1-- framelen = %d uup_buf_len_detection = %d .\r\n",framelen,uup_buf_len_detection);
|
||||
if(!uup_buf_len_detection){
|
||||
memcpy(uup_buf + uup_buf_len, framebuf, framelen);
|
||||
uup_buf_len += framelen;
|
||||
if (uup_buf_len == UUP_BUF_SIZE) {
|
||||
if(!checksum_flag)
|
||||
test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和
|
||||
sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
|
||||
if(checksum_flag){
|
||||
if (uup_file_type == UART_FILE_AMT630H) {//代码文件
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
|
||||
*tmp = 0;
|
||||
}else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}else if (uup_file_type == UART_FILE_ROM) {//资源文件
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}
|
||||
checksum_flag = 0;
|
||||
test_flag = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和
|
||||
if(test_flag){
|
||||
test_checksum = calc_checksum;
|
||||
printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum);
|
||||
test_flag = 0;
|
||||
}
|
||||
|
||||
|
||||
if(calc_checksum != test_checksum){
|
||||
printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum);
|
||||
}
|
||||
uup_buf_len =0;
|
||||
uup_burn_offset += UUP_BUF_SIZE;
|
||||
//number++;
|
||||
//printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum);
|
||||
}
|
||||
}else{
|
||||
memcpy(uup_buf + uup_buf_len, framebuf, uup_buf_len_detection);
|
||||
uup_buf_len += uup_buf_len_detection;
|
||||
|
||||
if (uup_buf_len == UUP_BUF_SIZE) {
|
||||
if(!checksum_flag)
|
||||
test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和
|
||||
sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
|
||||
if(checksum_flag){
|
||||
if (uup_file_type == UART_FILE_AMT630H) {//代码文件
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
|
||||
*tmp = 0;
|
||||
}else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}else if (uup_file_type == UART_FILE_ROM) {//资源文件
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + 0x0F);
|
||||
}
|
||||
checksum_flag = 0;
|
||||
test_flag = 1;
|
||||
}
|
||||
|
||||
calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和
|
||||
if(test_flag){
|
||||
test_checksum = calc_checksum;
|
||||
printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum);
|
||||
test_flag = 0;
|
||||
}
|
||||
if(calc_checksum != test_checksum){
|
||||
printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum);
|
||||
}
|
||||
uup_buf_len =0;
|
||||
uup_burn_offset += UUP_BUF_SIZE;
|
||||
//number++;
|
||||
//printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum);
|
||||
}
|
||||
// printf("2-- (framelen - uup_buf_len_detection) = %d .\r\n",(framelen - uup_buf_len_detection));
|
||||
memcpy(uup_buf + uup_buf_len, framebuf, (framelen - uup_buf_len_detection));
|
||||
uup_buf_len += (framelen - uup_buf_len_detection);
|
||||
}
|
||||
// printf(">>UART_FILE_FILEXFER.\r\n");
|
||||
file_state = UART_FILE_FILEXFER;
|
||||
|
||||
break;
|
||||
case UART_FILE_FILEXFER://传输过程中
|
||||
|
||||
uup_buf_len_detection = (uup_buf_len + framelen)>UUP_BUF_SIZE?(UUP_BUF_SIZE-uup_buf_len):0;
|
||||
// printf("uup_buf_len_detection=%d.\r\n",uup_buf_len_detection);
|
||||
if(!uup_buf_len_detection){
|
||||
memcpy(uup_buf + uup_buf_len, framebuf, framelen);
|
||||
uup_buf_len += framelen;
|
||||
// printf("uup_buf_len = %d .\r\n",uup_buf_len);
|
||||
|
||||
if (uup_buf_len == UUP_BUF_SIZE) {
|
||||
if(!checksum_flag)
|
||||
test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和
|
||||
sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
|
||||
if(checksum_flag){
|
||||
if (uup_file_type == UART_FILE_AMT630H) {//代码文件
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
|
||||
*tmp = 0;
|
||||
}else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}else if (uup_file_type == UART_FILE_ROM) {//资源文件
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + 0x0F);
|
||||
}
|
||||
checksum_flag = 0;
|
||||
test_flag = 1;
|
||||
}
|
||||
|
||||
calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和
|
||||
if(test_flag){
|
||||
test_checksum = calc_checksum;
|
||||
printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum);
|
||||
test_flag = 0;
|
||||
}
|
||||
if(calc_checksum != test_checksum){
|
||||
printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum);
|
||||
}
|
||||
uup_buf_len =0;
|
||||
uup_burn_offset += UUP_BUF_SIZE;
|
||||
//number++;
|
||||
//printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum);
|
||||
}
|
||||
}else{
|
||||
memcpy(uup_buf + uup_buf_len, framebuf, uup_buf_len_detection);
|
||||
uup_buf_len += uup_buf_len_detection;
|
||||
// printf("2---------------- uup_buf_len = %d .\r\n",uup_buf_len);
|
||||
|
||||
if (uup_buf_len == UUP_BUF_SIZE) {
|
||||
if(!checksum_flag)
|
||||
test_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, test_checksum);//计算校验和
|
||||
sfud_write(sflash, uup_burn_offset, UUP_BUF_SIZE, uup_buf);
|
||||
if(checksum_flag){
|
||||
if (uup_file_type == UART_FILE_AMT630H) {//代码文件
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + NEW_APPLDR_CHECKSUM_OFFSET);
|
||||
*tmp = 0;
|
||||
}else if (uup_file_type == UART_FILE_BOOTANIM) {//动画文件
|
||||
BANIHEADER *pheader = (BANIHEADER *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
}else if (uup_file_type == UART_FILE_ROM) {//资源文件
|
||||
RomHeader *pheader = (RomHeader *)uup_buf;
|
||||
pheader->checksum = 0;
|
||||
unsigned int *tmp = (unsigned int *)(uup_buf + 0x0F);
|
||||
}
|
||||
checksum_flag = 0;
|
||||
test_flag = 1;
|
||||
}
|
||||
|
||||
calc_checksum = xcrc32(uup_buf, UUP_BUF_SIZE, calc_checksum);//计算校验和
|
||||
if(test_flag){
|
||||
test_checksum = calc_checksum;
|
||||
printf("test_checksum == calc_checksum 0x%08X.\r\n",test_checksum);
|
||||
test_flag = 0;
|
||||
}
|
||||
if(calc_checksum != test_checksum){
|
||||
printf("error!!!test_checksum=0x%08X,calc_checksum=0x%08X.\r\n",test_checksum,calc_checksum);
|
||||
}
|
||||
uup_buf_len =0;
|
||||
uup_burn_offset += UUP_BUF_SIZE;
|
||||
// number++;
|
||||
// printf("number =%d,checksum = 0x%08X.\n",number,calc_checksum,checksum);
|
||||
}
|
||||
memcpy(uup_buf + uup_buf_len, framebuf, (framelen - uup_buf_len_detection));
|
||||
uup_buf_len += (framelen - uup_buf_len_detection);
|
||||
// printf("2----uup_buf_len = %d .\r\n",uup_buf_len);
|
||||
}
|
||||
// file_state = UART_FILE_FILEXFER;
|
||||
break;
|
||||
case UART_FILE_FINISH://传输完成
|
||||
if(uup_buf_len){//若最后一包数据不为0 则存数据并且继续计算校验和
|
||||
sfud_write(sflash, uup_burn_offset, uup_buf_len, uup_buf);
|
||||
test_checksum = xcrc32(uup_buf, uup_buf_len, test_checksum);//计算校验和
|
||||
calc_checksum = xcrc32(uup_buf, uup_buf_len, calc_checksum);
|
||||
printf("enter2 uup_buf_len =%d calc_checksum================0x%08X,test_checksum=0x%08X\n",uup_buf_len,calc_checksum,test_checksum);
|
||||
}
|
||||
printf("calc_checksum = 0x%08X,checksum = 0x%08X.\n",calc_checksum,checksum);
|
||||
printf("test_checksum=0x%08X.\r\n",test_checksum);
|
||||
if (calc_checksum != checksum) {
|
||||
printf("fail !!!!!!!!!!!!\n");
|
||||
}else
|
||||
printf("whole crc check after burn ok!\n");
|
||||
file_state = UART_FILE_NORMAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(file_state != UART_FILE_FILEXFER)
|
||||
printf("now > file_state = %d .\r\n",file_state);
|
||||
}
|
||||
|
||||
static int uup_rx_state = 0;
|
||||
#define UUP_PACKET_SIZE 128
|
||||
#define UUP_MAX_FRAME_LEN (UUP_PACKET_SIZE + 16)
|
||||
#define UUP_PACKET_A27_SIZE 4096
|
||||
#define UUP_MAX_FRAME_A27_LEN (UUP_PACKET_A27_SIZE + 16)
|
||||
#define UUP_RX_FRAME_NUM 16
|
||||
#define BYTESPERPAGE 256
|
||||
#define PAGESPERSECTORS 16
|
||||
#define UUP_BUF_SIZE (BYTESPERPAGE * PAGESPERSECTORS)
|
||||
|
||||
static unsigned char uup_rx_buf[UUP_RX_FRAME_NUM][4096];
|
||||
static unsigned char *uup_rx_ptr;
|
||||
static int uup_rx_rev_len = 0;
|
||||
static int uup_rx_head = 0;
|
||||
static int uup_rx_tail = 0;
|
||||
static int uup_rx_data_len = 0;
|
||||
|
||||
unsigned char wifi_ota_request[8] = {0x7e,0x01,0x05,0x02,0x03,0x01,0x00,0x01};
|
||||
|
||||
int serverSock = -1, clientSock = -1;
|
||||
|
||||
// 函数定义:发送数据给客户端
|
||||
void sendDataToClient(int clientSock, const char* data, int length) {
|
||||
int ret = send(clientSock, data, length, 0);
|
||||
if (ret <= 0) {
|
||||
close(clientSock);
|
||||
clientSock = -1;
|
||||
printf("Failed to send data to client.\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wifi_uup_send_ack(int type, int ret)
|
||||
{
|
||||
unsigned char buf[8] = {0x55, 0x80, 0xc5, 0x02, 0x00, 0x00, 0x00, 0x00};
|
||||
int i;
|
||||
|
||||
buf[5] = type;
|
||||
buf[6] = ret;
|
||||
if(ret == 0){
|
||||
wifi_ota_state = 0;
|
||||
timeout = 0;
|
||||
wifi_file_state = 0;
|
||||
Set_sys_power_on_self_test(100);
|
||||
Set_sys_return_demo(2);
|
||||
Set_sys_plan(0);
|
||||
Set_sys_pace(0);
|
||||
}
|
||||
for (i = 1; i < 7; i++)
|
||||
buf[7] ^= buf[i];
|
||||
sendDataToClient(clientSock,buf,8);
|
||||
}
|
||||
|
||||
static void wifi_update_judge(char *uartrx, size_t len){
|
||||
uint8_t data = 0;
|
||||
for(int i=0;i<len;i++){
|
||||
switch (uup_rx_state) {
|
||||
case 0:
|
||||
data = *(uartrx++);
|
||||
if (data == 0x7e)
|
||||
uup_rx_state++;
|
||||
break;
|
||||
case 1:
|
||||
data = *(uartrx++);
|
||||
if (data == 0x05)
|
||||
uup_rx_state++;
|
||||
else
|
||||
uup_rx_state = 0;
|
||||
break;
|
||||
case 2:
|
||||
data = *(uartrx++);
|
||||
if (data == 0x02)
|
||||
uup_rx_state++;
|
||||
else
|
||||
uup_rx_state = 0;
|
||||
break;
|
||||
case 3:
|
||||
data = *(uartrx++);
|
||||
if (data == 0x03)
|
||||
uup_rx_state++;
|
||||
else
|
||||
uup_rx_state = 0;
|
||||
break;
|
||||
case 4:
|
||||
data = *(uartrx++);
|
||||
if (data == 0x01)
|
||||
uup_rx_state++;
|
||||
else
|
||||
uup_rx_state = 0;
|
||||
break;
|
||||
case 5:
|
||||
data = *(uartrx++);
|
||||
if (data == Get_sys_softwar_host()){
|
||||
uup_rx_state++;
|
||||
wifi_ota_request[6] = Get_sys_softwar_host();
|
||||
}else{
|
||||
|
||||
uup_rx_state = 0;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
data = *(uartrx++);
|
||||
if (data == Get_sys_softwar_order()){
|
||||
wifi_ota_request[7] = Get_sys_softwar_host();
|
||||
if(Get_sys_veer_velocity()){
|
||||
printf("error ota sj. Speed present\n");
|
||||
wifi_ota_request[1]=1;
|
||||
}else{
|
||||
printf("enter ota sj.\n");
|
||||
Set_sys_power_on_self_test(150);
|
||||
Set_sys_upgrade_Flag(1);//进入ota界面
|
||||
wifi_file_state = UART_FILE_START;
|
||||
wifi_ota_request[1]=0;
|
||||
wifi_ota_state = 1;
|
||||
}
|
||||
}
|
||||
sendDataToClient(clientSock,wifi_ota_request,8);
|
||||
uup_rx_state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void wifi_update_technological_process(char *uartrx, size_t len){
|
||||
int data = 0;
|
||||
#if 1
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch (uup_rx_state) {
|
||||
case 0:
|
||||
data = *(uartrx++);
|
||||
if (data == 0x55) {
|
||||
uup_rx_state++;
|
||||
uup_rx_rev_len = 0;
|
||||
uup_rx_ptr = &uup_rx_buf[uup_rx_head][0];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
data = *(uartrx++);
|
||||
if (data == 0x81)
|
||||
uup_rx_state++;
|
||||
else
|
||||
uup_rx_state = 0;
|
||||
*uup_rx_ptr++ = data;
|
||||
break;
|
||||
case 2:
|
||||
data = *(uartrx++);
|
||||
if (data == 0xc6)
|
||||
uup_rx_state++;
|
||||
else
|
||||
uup_rx_state = 0;
|
||||
*uup_rx_ptr++ = data;
|
||||
break;
|
||||
case 3:
|
||||
data = *(uartrx++);
|
||||
uup_rx_data_len = data;
|
||||
uup_rx_state++;
|
||||
*uup_rx_ptr++ = data;
|
||||
break;
|
||||
case 4:
|
||||
data = *(uartrx++);
|
||||
uup_rx_data_len = (data<<8) | uup_rx_data_len;
|
||||
if((uup_rx_data_len > UUP_PACKET_A27_SIZE + 2)) { //4096 + 2
|
||||
printf("Invalid uup_rx_data_len %d\n", uup_rx_data_len);
|
||||
uup_rx_state = 0;
|
||||
} else {
|
||||
uup_rx_state++;
|
||||
*uup_rx_ptr++ = data;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
data = *(uartrx++);
|
||||
*uup_rx_ptr++ = data;
|
||||
if (++uup_rx_rev_len == uup_rx_data_len)
|
||||
uup_rx_state++;
|
||||
break;
|
||||
case 6:
|
||||
data = *(uartrx++);
|
||||
*uup_rx_ptr++ = data;
|
||||
uup_rx_head = (uup_rx_head + 1) % UUP_RX_FRAME_NUM;
|
||||
// printf("1--- uup_rx_head=%d,uup_rx_tail=%d.\r\n",uup_rx_head,uup_rx_tail);
|
||||
uup_rx_state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (uup_rx_tail != uup_rx_head) {
|
||||
unsigned char *buf;
|
||||
unsigned char checksum = 0;
|
||||
buf = &uup_rx_buf[uup_rx_tail][0];
|
||||
len = buf[2];
|
||||
len = buf[3]<<8 | len;
|
||||
|
||||
for (int i = 0; i < len + 4; i++)
|
||||
checksum ^= buf[i];
|
||||
if (checksum == buf[len + 4]) {
|
||||
// printf("2--- uup_rx_head=%d,uup_rx_tail=%d.\r\n",uup_rx_head,uup_rx_tail);
|
||||
wifi_uup_ota_update(buf + 4, len);
|
||||
} else {
|
||||
printf("rev frame checksum err.\r\n");
|
||||
}
|
||||
uup_rx_tail = (uup_rx_tail + 1) % UUP_RX_FRAME_NUM;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void wifi_ota_update(char *framebuf, size_t len)
|
||||
{
|
||||
unsigned int framelen;
|
||||
framelen = len;
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
// printf("wifi_file_state > %d.\r\n",wifi_file_state);
|
||||
switch(wifi_file_state){
|
||||
case UART_FILE_NORMAL://检测是否是升级
|
||||
wifi_update_judge(framebuf,len);//升级判断
|
||||
printf("wifi_file_state > %d.\r\n",wifi_file_state);
|
||||
break;
|
||||
// case UART_FILE_TYPE://检测传输文件类型
|
||||
// break;
|
||||
case UART_FILE_START://升级流程
|
||||
wifi_update_technological_process(framebuf,len);//升级流程
|
||||
break;
|
||||
// case UART_FILE_FILEXFER://传输过程中
|
||||
// break;
|
||||
// case UART_FILE_FINISH://传输完成
|
||||
// break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
extern char strQrText[200];
|
||||
extern char strCarplayText[200];
|
||||
//TCP接收函数
|
||||
void app_wifi_update_demo(void)
|
||||
{
|
||||
printf("app_wifi_update_demo init.\r\n");
|
||||
strcpy(strCarplayText, strQrText);
|
||||
Send_wifi_name();
|
||||
int err;
|
||||
int testPort, max_fd, ret;
|
||||
fd_set xFD_Set;
|
||||
char buf[4096] = {0};
|
||||
uint8_t data[32] = "Hello, server!";
|
||||
#if 0
|
||||
err = ServerSocketOpen( AF_INET, SOCK_STREAM, IPPROTO_TCP, 8000, &testPort, kSocketBufferSize_DontSet, &serverSock );
|
||||
require_noerr(err, exit);
|
||||
#else
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len;
|
||||
// serverSock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
serverSock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(serverSock < 0) {
|
||||
printf("client socket create failed.\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(10003);
|
||||
sin.sin_addr.s_addr = htonl(INADDR_ANY);//任何ip地址的client都可以连到这个server
|
||||
len = sizeof(struct sockaddr_in);
|
||||
int flag = 1;
|
||||
if (-1 == setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) {
|
||||
printf("setsockopt SO_REUSEADDR fail");
|
||||
}
|
||||
|
||||
flag = 1;
|
||||
if (-1 == setsockopt(serverSock, SOL_SOCKET, SO_REUSEPORT, &flag, sizeof(flag))) {
|
||||
printf("setsockopt SO_REUSEPORT fail");
|
||||
}
|
||||
|
||||
ret = bind(serverSock, (struct sockaddr*)&sin, len);
|
||||
if (ret == -1)
|
||||
goto exit;
|
||||
ret = listen(serverSock, 1);//设置最多连5个client
|
||||
if (ret == -1)
|
||||
goto exit;
|
||||
#endif
|
||||
max_fd = (int)serverSock;
|
||||
|
||||
while (1) {
|
||||
FD_ZERO(&xFD_Set);
|
||||
if (serverSock != -1)
|
||||
FD_SET(serverSock, &xFD_Set);
|
||||
if (clientSock != -1)
|
||||
FD_SET(clientSock, &xFD_Set);
|
||||
|
||||
ret = select( max_fd + 1, &xFD_Set, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if( FD_ISSET ( serverSock, &xFD_Set ) ) {
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
// clientSock = accept(serverSock, NULL, NULL);
|
||||
clientSock = accept(serverSock, NULL, NULL);
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
if (clientSock != -1) {
|
||||
if (clientSock > max_fd)
|
||||
max_fd = (int)clientSock;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if( FD_ISSET ( clientSock, &xFD_Set ) ) {
|
||||
ret = recv(clientSock, buf, sizeof(buf), 0);
|
||||
if (ret <= 0) {
|
||||
close(clientSock);
|
||||
clientSock = -1;
|
||||
printf("client is disconnected\r\n");
|
||||
continue;
|
||||
}
|
||||
// printf("recv len:%d.\r\n", ret);
|
||||
if(timeout)
|
||||
timeout = 0;
|
||||
// if(ret<100)
|
||||
// printf("recv len:%d %s\r\n", ret, buf);
|
||||
// else
|
||||
// printf("recv len:%d.\r\n", ret);
|
||||
wifi_ota_update(buf,ret);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
exit:
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void wifi_update_rx_thread(void *param)
|
||||
{
|
||||
// vTaskDelay(7000);
|
||||
// while(1){
|
||||
app_wifi_update_demo();
|
||||
// vTaskDelay(3000);
|
||||
// }
|
||||
}
|
||||
|
||||
int wifi_update_init(void){
|
||||
/* Create a task to process uart rx data */
|
||||
if (xTaskCreate(wifi_update_rx_thread, "wifi_update_rx_thread", configMINIMAL_STACK_SIZE*20, NULL,
|
||||
configMAX_PRIORITIES / 3, NULL) != pdPASS)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int test_udp_client(const char *ip_str, int port)
|
||||
{
|
||||
/* socket文件描述符 */
|
||||
int sock_fd = -1;
|
||||
|
||||
/* 建立udp socket */
|
||||
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(sock_fd < 0)
|
||||
{
|
||||
printf("client socket create failed.\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* 设置address */
|
||||
struct sockaddr_in addr_serv;
|
||||
int len;
|
||||
memset(&addr_serv, 0, sizeof(addr_serv));
|
||||
addr_serv.sin_family = AF_INET;
|
||||
addr_serv.sin_addr.s_addr = inet_addr(ip_str);
|
||||
addr_serv.sin_port = htons(port);
|
||||
len = sizeof(addr_serv);
|
||||
|
||||
|
||||
int send_num;
|
||||
int recv_num;
|
||||
char send_buf[20] = "hey, who are you?";
|
||||
char recv_buf[20];
|
||||
|
||||
printf("###client send: %s\n", send_buf);
|
||||
|
||||
send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len);
|
||||
|
||||
if(send_num < 0)
|
||||
{
|
||||
printf("sendto erro\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);
|
||||
|
||||
if(recv_num <= 0)
|
||||
{
|
||||
printf("socket recv failed\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
recv_buf[recv_num] = '\0';
|
||||
printf("client receive %d bytes: %s\n", recv_num, recv_buf);
|
||||
exit:
|
||||
|
||||
if (-1 != sock_fd)
|
||||
close(sock_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_udp_server(int port)
|
||||
{
|
||||
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(sock_fd < 0)
|
||||
{
|
||||
printf("server socket create failed.\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr_serv;
|
||||
int len;
|
||||
memset(&addr_serv, 0, sizeof(struct sockaddr_in));
|
||||
addr_serv.sin_family = AF_INET;
|
||||
addr_serv.sin_port = htons(port);
|
||||
|
||||
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
len = sizeof(addr_serv);
|
||||
|
||||
if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
|
||||
{
|
||||
printf("bind error\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
int recv_num;
|
||||
int send_num;
|
||||
char send_buf[20] = "i am server!";
|
||||
char recv_buf[20];
|
||||
struct sockaddr_in addr_client;
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("server wait:\n");
|
||||
|
||||
recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len);
|
||||
|
||||
if(recv_num < 0)
|
||||
{
|
||||
printf("recvfrom error:\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
recv_buf[recv_num] = '\0';
|
||||
printf("server receive %d bytes: %s\n", recv_num, recv_buf);
|
||||
|
||||
send_num = sendto(sock_fd, send_buf, recv_num, 0, (struct sockaddr *)&addr_client, len);
|
||||
|
||||
if(send_num <= 0)
|
||||
{
|
||||
printf("sendto error:");
|
||||
break;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
if (-1 != sock_fd)
|
||||
close(sock_fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
BIN
MXC_A27-PCB4.5-270T/app/carlink-1023.zip
Normal file
BIN
MXC_A27-PCB4.5-270T/app/carlink-12.23-替换后.zip
Normal file
BIN
MXC_A27-PCB4.5-270T/app/carlink/AA/_AndroidAuto.zip
Normal file
124
MXC_A27-PCB4.5-270T/app/carlink/AA/include/AndroidAuto.h
Normal file
@ -0,0 +1,124 @@
|
||||
#ifndef _ANDROID_AUTO_H_H
|
||||
#define _ANDROID_AUTO_H_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LINK_UNSUPPORTED= 0xff,
|
||||
LINK_CONNECTED = 1,
|
||||
LINK_DISCONNECTED = 2,
|
||||
LINK_STARTING = 3,
|
||||
LINK_SUCCESS = 4,
|
||||
LINK_FAIL = 5,
|
||||
LINK_EXITING = 6,
|
||||
LINK_EXITED = 7 ,
|
||||
LINK_REMOVED = 8,
|
||||
LINK_INSERTED = 9,
|
||||
LINK_NOT_INSERTED = 10,
|
||||
LINK_NOT_INSTALL = 11,
|
||||
LINK_CALL_PHONE = 12,
|
||||
LINK_CALL_PHONE_EXITED = 13,
|
||||
LINK_MUTE =14,
|
||||
LINK_UNMUTE = 15,
|
||||
LINK_NODATA = 16,
|
||||
LINK_VIDEOREADY = 17,
|
||||
LINK_BT_DISCONNECT = 18,
|
||||
LINK_FAILED_EAP = 19,
|
||||
LINK_FAILED_UNSTART = 20,
|
||||
LINK_AUTO_BT_UNPAIRED = 21,
|
||||
LINK_AUTO_BT_PAIRED = 22,
|
||||
LINK_AUTO_BT_REQUEST = 23,
|
||||
LINK_EXIT_PROCESS = 24,
|
||||
LINK_KILL_PROCESS = 25,
|
||||
|
||||
LINK_SOCKET_TRUST = 26,
|
||||
LINK_OPEN_CARLIFE = 27,
|
||||
LINK_VOLUME_START = 28,
|
||||
LINK_VOLUME_STOP = 29,
|
||||
LINK_RECONNECT = 30,
|
||||
LINK_ILLLIGHT_ON = 31,
|
||||
LINK_ILLLIGHT_OFF = 32,
|
||||
|
||||
LINK_SIRI_START = 33,
|
||||
LINK_SIRI_STOP = 34,
|
||||
LINK_ASSIST_START = 35,
|
||||
LINK_ASSIST_STOP = 36,
|
||||
LINK_TEL_START = 37,
|
||||
LINK_TEL_STOP = 38,
|
||||
LINK_MUSIC_START = 39,
|
||||
LINK_MUSIC_STOP = 40,
|
||||
|
||||
LINK_SCREEN_CONTROLLER = 62,
|
||||
LINK_SCREEN_ACCESSORY = 63,
|
||||
|
||||
LINK_TAKE_AUDIO = 80,
|
||||
LINK_UNTAKE_AUDIO = 81,
|
||||
|
||||
LINK_USE_USB0 = 82,
|
||||
LINK_USE_USB1 = 83,
|
||||
LINK_NO_ERROR = 0,
|
||||
LINK_BTCONNECT_ERROR = -1000,
|
||||
LINK_BTCOMM_ERROR = -1001,
|
||||
LINK_BTAUTH_ERROR = -1002,
|
||||
LINK_BTIDRECJECT_ERROR = -1003,
|
||||
}Link_STATUS;
|
||||
|
||||
struct IAACallbacks
|
||||
{
|
||||
void (*video_init)(void* cb_ctx, int w, int h, int x, int y);
|
||||
void (*video_uninit)(void* cb_ctx);
|
||||
void (*video_play)(void* cb_ctx, char *buf, int len);
|
||||
|
||||
void (*audio_init_callback)(void* cb_ctx, int type, int sample, int ch, int bits);
|
||||
void (*audio_uninit_callback)(void* cb_ctx, int type);
|
||||
void (*audio_play)(void* cb_ctx, int type, char *buf, int len);
|
||||
|
||||
void (*mic_init_callback)(void* cb_ctx, int sample, int ch, int bits);
|
||||
void (*mic_uninit_callback)(void* cb_ctx);
|
||||
void (*mic_capture)(void* cb_ctx, char *buf, int len);
|
||||
|
||||
void (*bt_paring_request_callback)(void* cb_ctx, const char *phoneAddr, int pairingMethod);
|
||||
|
||||
void (*status_notify)(void* cb_ctx, int status_type);
|
||||
|
||||
int (*rf_read_transfer_cb)(void* cb_ctx, char *buf, int len);//@Deprecated
|
||||
int (*rf_write_transfer_cb)(void* cb_ctx, char *buf, int len);
|
||||
|
||||
|
||||
void (*json_msg_notify)(void* cb_ctx, char *buf, int len);
|
||||
|
||||
void* cb_ctx;
|
||||
};
|
||||
|
||||
typedef struct __auto_cfg_info
|
||||
{
|
||||
short width;//pixel
|
||||
short height;
|
||||
short density;
|
||||
short fps;
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char wifi_channel;
|
||||
bool disable_auto_audio;
|
||||
bool video_auto_start;
|
||||
|
||||
} auto_cfg_info;
|
||||
|
||||
extern auto_cfg_info *g_auto_link_info;
|
||||
|
||||
int android_auto_init(struct IAACallbacks* cbs);
|
||||
int android_auto_rfcomm_read_data_proc(char *buf, int len);
|
||||
void android_auto_start();
|
||||
void android_auto_set_rfcomm_info(const char * ssid, const char * passwd, const char * mac, int securityMode, const char * ip, int port);
|
||||
void android_auto_set_BT_paring_status(bool paired, const char *pinCode, int status);
|
||||
void android_auto_send_touch_event(unsigned int x, unsigned int y, int action);
|
||||
void android_auto_send_mul_touch_event(int pointer_id, unsigned int pointer_x, unsigned int pointer_y, int event_type);
|
||||
void android_auto_send_key_event(unsigned int keycode, int press);
|
||||
void android_auto_send_knob_event(unsigned int keycode, int delta);
|
||||
void android_auto_set_night_mode(bool night);
|
||||
|
||||
void android_auto_get_video_focus(int mode);
|
||||
void android_auto_release_video_focus(int mode);
|
||||
void android_auto_get_audio_focus(int mode);
|
||||
void android_auto_release_audio_focus(int mode);
|
||||
|
||||
#endif
|
BIN
MXC_A27-PCB4.5-270T/app/carlink/AA/lib/AndroidAuto.a
Normal file
302
MXC_A27-PCB4.5-270T/app/carlink/AA/src/carlink_aa-bf.c
Normal file
@ -0,0 +1,302 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "carlink_video.h"
|
||||
#include "carlink_common.h"
|
||||
#include "AndroidAuto.h"
|
||||
#include "board.h"
|
||||
|
||||
#if CARLINK_AA
|
||||
|
||||
struct AAHandle
|
||||
{
|
||||
struct ICalinkEventCallbacks carlinkEventCB;
|
||||
struct IAACallbacks carlinkAACB;
|
||||
|
||||
bool mInitDone;
|
||||
bool mBTConnected;
|
||||
bool mRfcommReady;
|
||||
char mLocalBTMac[6];
|
||||
char mRemoteBTMac[6];
|
||||
char mIp[32];
|
||||
|
||||
};
|
||||
//extern int debug_buf_ref;
|
||||
|
||||
struct AAHandle gAACtx;
|
||||
static bool g_aa_disable = false;
|
||||
|
||||
|
||||
static void android_auto_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
|
||||
{
|
||||
ev->link_type = CARLINK_AUTO_WIRELESS;
|
||||
ev->disable_filter = disable_filter;
|
||||
ev->type = type;
|
||||
carlink_notify_event(ev);
|
||||
}
|
||||
|
||||
static void start_aa(struct AAHandle* pctx)
|
||||
{
|
||||
if (!pctx->mInitDone)
|
||||
return;
|
||||
//if (pctx->mBTConnected)
|
||||
// return;
|
||||
if (!pctx->mRfcommReady)
|
||||
return;
|
||||
if (g_aa_disable)
|
||||
return;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
|
||||
g_auto_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
|
||||
g_auto_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd;
|
||||
android_auto_set_rfcomm_info((const char*)carlink_get_wifi_ssid(),
|
||||
(const char*)carlink_get_wifi_passwd(), (const char*)carlink_get_wifi_mac(), 5, (const char*)pctx->mIp, 0);
|
||||
android_auto_start();
|
||||
}
|
||||
|
||||
static void onEventAA(void* ctx, const struct carlink_event *ev)
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
struct AAHandle* pctx = (struct AAHandle*)ctx;
|
||||
if (NULL == ev)
|
||||
return;
|
||||
if (ev->link_type != CARLINK_AUTO_WIRELESS && !ev->disable_filter)// skip not aa event
|
||||
return;
|
||||
|
||||
type = ev->type;
|
||||
|
||||
switch (type) {
|
||||
case -1: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_INIT_DONE:
|
||||
pctx->mInitDone = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
case CARLINK_EVENT_BT_CONNECT: {
|
||||
pctx->mBTConnected = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_AA_RFCOMM_READY: {
|
||||
pctx->mRfcommReady = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_DISCONNECT: {
|
||||
pctx->mBTConnected = false;
|
||||
pctx->mRfcommReady = false;
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_WIFI_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_STOP: {
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aa_rfcomm_data_read(void* ctx, const void* buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)ctx;
|
||||
|
||||
if (!pctx->mRfcommReady)
|
||||
return;
|
||||
|
||||
android_auto_rfcomm_read_data_proc((char*)buf, len);
|
||||
}
|
||||
|
||||
static int rf_write_transfer_cb(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
int ret = -1;
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
if (!pctx->mRfcommReady)
|
||||
return -1;
|
||||
ret = carlink_auto_rfcomm_data_write(buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void video_init_impl(void* cb_ctx, int w, int h, int x, int y)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
printf("x:%d y:%d w:%d h:%d\r\n", x, y, w, h);
|
||||
set_carlink_active_video_info(x, y);
|
||||
h264_dec_ctx_init();
|
||||
set_carlink_display_state(1);
|
||||
//debug_buf_ref = 1;
|
||||
}
|
||||
|
||||
static void video_uninit_impl(void* cb_ctx)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
set_carlink_display_state(0);
|
||||
set_carlink_active_video_info(0, 0);
|
||||
}
|
||||
|
||||
int g_v_count;
|
||||
static void video_play_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
video_frame_s* frame = NULL;
|
||||
|
||||
get_retry:
|
||||
frame = get_h264_frame_buf();
|
||||
if (NULL == frame) {
|
||||
//printf("h264 frame is empty\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
goto get_retry;
|
||||
//continue;
|
||||
}
|
||||
|
||||
memcpy(frame->cur, buf, len);
|
||||
frame->len = len;
|
||||
|
||||
notify_h264_frame_ready(&frame);
|
||||
if (g_v_count++ > 50) {
|
||||
//android_auto_get_video_focus(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_init_callback_impl(void* cb_ctx, int type, int sample, int ch, int bits)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void audio_uninit_callback_impl(void* cb_ctx, int type)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void audio_play_impl(void* cb_ctx, int type, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
static void mic_init_callback_impl(void* cb_ctx, int sample, int ch, int bits)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void mic_uninit_callback_impl(void* cb_ctx)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
static void mic_capture_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
static void bt_paring_request_callback_impl(void* cb_ctx, const char *phoneAddr, int pairingMethod)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
static void status_notify_impl(void* cb_ctx, int status_type)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
struct carlink_event ev = {0};
|
||||
|
||||
if (status_type == LINK_REMOVED) {
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
android_auto_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_STOP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void json_msg_notify_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int carlink_aa_init()
|
||||
{
|
||||
int ret = -1;
|
||||
struct AAHandle* pctx = &gAACtx;
|
||||
struct IAACallbacks* carlinkAACBPtr = NULL;
|
||||
|
||||
memset((void*)pctx, 0, sizeof(struct AAHandle));
|
||||
|
||||
|
||||
g_auto_link_info->width = CARLINK_VIDEO_WIDTH;
|
||||
g_auto_link_info->height = CARLINK_VIDEO_HEIGHT;
|
||||
g_auto_link_info->fps = 30;
|
||||
g_auto_link_info->density = 160;
|
||||
g_auto_link_info->disable_auto_audio = 1;
|
||||
g_auto_link_info->video_auto_start = 1;
|
||||
|
||||
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
|
||||
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
|
||||
|
||||
ret = carlink_common_init();
|
||||
|
||||
pctx->carlinkEventCB.onEvent = onEventAA;
|
||||
pctx->carlinkEventCB.rfcomm_data_read = aa_rfcomm_data_read;
|
||||
pctx->carlinkEventCB.cb_ctx = (void*)pctx;
|
||||
|
||||
carlink_register_event_callbacks(&pctx->carlinkEventCB);
|
||||
|
||||
ret = carlink_bt_wifi_init();
|
||||
|
||||
carlinkAACBPtr = &pctx->carlinkAACB;
|
||||
carlinkAACBPtr->video_init = video_init_impl;
|
||||
carlinkAACBPtr->video_uninit = video_uninit_impl;
|
||||
carlinkAACBPtr->video_play = video_play_impl;
|
||||
carlinkAACBPtr->audio_init_callback = audio_init_callback_impl;
|
||||
carlinkAACBPtr->audio_uninit_callback = audio_uninit_callback_impl;
|
||||
carlinkAACBPtr->mic_init_callback = mic_init_callback_impl;
|
||||
carlinkAACBPtr->mic_uninit_callback = mic_uninit_callback_impl;
|
||||
carlinkAACBPtr->mic_capture = mic_capture_impl;
|
||||
carlinkAACBPtr->bt_paring_request_callback = bt_paring_request_callback_impl;
|
||||
carlinkAACBPtr->status_notify = status_notify_impl;
|
||||
carlinkAACBPtr->json_msg_notify = json_msg_notify_impl;
|
||||
|
||||
carlinkAACBPtr->rf_read_transfer_cb = NULL;
|
||||
carlinkAACBPtr->rf_write_transfer_cb = rf_write_transfer_cb;
|
||||
carlinkAACBPtr->cb_ctx = (void*)pctx;
|
||||
ret = android_auto_init(&pctx->carlinkAACB);
|
||||
{
|
||||
char ip[4] = {0};
|
||||
carlink_get_ap_ip_addr(ip);
|
||||
sprintf(pctx->mIp, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
android_auto_notify_event(&ev, CARLINK_EVENT_INIT_DONE, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
g_aa_disable = false;
|
||||
} else {
|
||||
g_aa_disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
int carlink_aa_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
369
MXC_A27-PCB4.5-270T/app/carlink/AA/src/carlink_aa.c
Normal file
@ -0,0 +1,369 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "carlink_video.h"
|
||||
#include "carlink_common.h"
|
||||
#include "AndroidAuto.h"
|
||||
#include "board.h"
|
||||
#include "task.h"
|
||||
|
||||
#if CARLINK_AA
|
||||
|
||||
struct AAHandle
|
||||
{
|
||||
struct ICalinkEventCallbacks carlinkEventCB;
|
||||
struct IAACallbacks carlinkAACB;
|
||||
|
||||
bool mInitDone;
|
||||
bool mBTConnected;
|
||||
bool mRfcommReady;
|
||||
char mLocalBTMac[6];
|
||||
char mRemoteBTMac[6];
|
||||
char mIp[32];
|
||||
bool mAAConnected;
|
||||
|
||||
};
|
||||
//extern int debug_buf_ref;
|
||||
|
||||
struct AAHandle gAACtx;
|
||||
static bool g_aa_disable = false;
|
||||
|
||||
|
||||
static void android_auto_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
|
||||
{
|
||||
ev->link_type = CARLINK_AUTO_WIRELESS;
|
||||
ev->disable_filter = disable_filter;
|
||||
ev->type = type;
|
||||
carlink_notify_event(ev);
|
||||
}
|
||||
|
||||
static void start_aa(struct AAHandle* pctx)
|
||||
{
|
||||
if (!pctx->mInitDone)
|
||||
return;
|
||||
//if (pctx->mBTConnected)
|
||||
// return;
|
||||
if (!pctx->mRfcommReady)
|
||||
return;
|
||||
if (g_aa_disable)
|
||||
return;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
|
||||
g_auto_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
|
||||
g_auto_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd;
|
||||
android_auto_set_rfcomm_info((const char*)carlink_get_wifi_ssid(),
|
||||
(const char*)carlink_get_wifi_passwd(), (const char*)carlink_get_wifi_mac(), 5, (const char*)pctx->mIp, 0);
|
||||
android_auto_start();
|
||||
}
|
||||
|
||||
static void carlink_aa_input_event_proc(const struct carlink_event *ev)
|
||||
{
|
||||
uint8_t key = ev->u.para[0];
|
||||
bool pressed = (bool)ev->u.para[1];
|
||||
|
||||
if (key == 19) {//right
|
||||
android_auto_send_knob_event(65536, 1);
|
||||
} else if (key == 20) {
|
||||
android_auto_send_knob_event(65536, -1);
|
||||
} else {
|
||||
if (pressed)
|
||||
android_auto_send_key_event(3, 1);
|
||||
else
|
||||
android_auto_send_key_event(3, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void onEventAA(void* ctx, const struct carlink_event *ev)
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
struct AAHandle* pctx = (struct AAHandle*)ctx;
|
||||
if (NULL == ev)
|
||||
return;
|
||||
if (ev->link_type != CARLINK_AUTO_WIRELESS && !ev->disable_filter)// skip not aa event
|
||||
return;
|
||||
|
||||
type = ev->type;
|
||||
|
||||
switch (type) {
|
||||
case CARLINK_EVENT_KEY_EVENT:
|
||||
if (!pctx->mAAConnected)
|
||||
break;
|
||||
carlink_aa_input_event_proc(ev);
|
||||
break;
|
||||
case -1: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_INIT_DONE:
|
||||
pctx->mInitDone = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
case CARLINK_EVENT_BT_CONNECT: {
|
||||
pctx->mBTConnected = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_AA_RFCOMM_READY: {
|
||||
pctx->mRfcommReady = true;
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_DISCONNECT: {
|
||||
pctx->mBTConnected = false;
|
||||
pctx->mRfcommReady = false;
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_WIFI_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_STOP: {
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
start_aa(pctx);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void aa_rfcomm_data_read(void* ctx, const void* buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)ctx;
|
||||
|
||||
if (!pctx->mRfcommReady)
|
||||
return;
|
||||
|
||||
android_auto_rfcomm_read_data_proc((char*)buf, len);
|
||||
}
|
||||
|
||||
static int rf_write_transfer_cb(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
int ret = -1;
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
if (!pctx->mRfcommReady)
|
||||
return -1;
|
||||
ret = carlink_auto_rfcomm_data_write((unsigned char *)buf, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int g_v_count;
|
||||
static void video_init_impl(void* cb_ctx, int w, int h, int x, int y)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
printf("x:%d y:%d w:%d h:%d\r\n", x, y, w, h);
|
||||
set_carlink_active_video_info(x, y);
|
||||
h264_dec_ctx_init();
|
||||
set_carlink_display_state(1);
|
||||
//carlink_bt_close();
|
||||
g_v_count = 0;
|
||||
//debug_buf_ref = 1;
|
||||
}
|
||||
|
||||
static void video_uninit_impl(void* cb_ctx)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
(void)pctx;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
set_carlink_display_state(0);
|
||||
set_carlink_active_video_info(0, 0);
|
||||
}
|
||||
|
||||
static void video_play_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
video_frame_s* frame = NULL;
|
||||
|
||||
(void)pctx;
|
||||
|
||||
get_retry:
|
||||
frame = get_h264_frame_buf();
|
||||
if (NULL == frame) {
|
||||
//printf("h264 frame is empty\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
goto get_retry;
|
||||
//continue;
|
||||
}
|
||||
|
||||
memcpy(frame->cur, buf, len);
|
||||
frame->len = len;
|
||||
|
||||
notify_h264_frame_ready(&frame);
|
||||
if (g_v_count++ > 50) {//enable_malloc_debug = 1;
|
||||
//android_auto_get_video_focus(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void audio_init_callback_impl(void* cb_ctx, int type, int sample, int ch, int bits)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
static void audio_uninit_callback_impl(void* cb_ctx, int type)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
static void audio_play_impl(void* cb_ctx, int type, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
|
||||
static void mic_init_callback_impl(void* cb_ctx, int sample, int ch, int bits)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
static void mic_uninit_callback_impl(void* cb_ctx)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
static void mic_capture_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
|
||||
static void bt_paring_request_callback_impl(void* cb_ctx, const char *phoneAddr, int pairingMethod)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
|
||||
static void status_notify_impl(void* cb_ctx, int status_type)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
struct carlink_event ev = {0};
|
||||
|
||||
if (status_type == LINK_REMOVED) {
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
android_auto_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_STOP, 0);
|
||||
} else if (status_type == LINK_SUCCESS) {
|
||||
pctx->mAAConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void json_msg_notify_impl(void* cb_ctx, char *buf, int len)
|
||||
{
|
||||
struct AAHandle* pctx = (struct AAHandle*)cb_ctx;
|
||||
|
||||
(void)pctx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _carlink_aa_init()
|
||||
{
|
||||
int ret = -1;
|
||||
struct AAHandle* pctx = &gAACtx;
|
||||
struct IAACallbacks* carlinkAACBPtr = NULL;
|
||||
|
||||
memset((void*)pctx, 0, sizeof(struct AAHandle));
|
||||
|
||||
|
||||
g_auto_link_info->width = CARLINK_VIDEO_WIDTH;
|
||||
g_auto_link_info->height = CARLINK_VIDEO_HEIGHT;
|
||||
g_auto_link_info->fps = 30;
|
||||
g_auto_link_info->density = 160;
|
||||
g_auto_link_info->disable_auto_audio = 1;
|
||||
g_auto_link_info->video_auto_start = 1;
|
||||
|
||||
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
|
||||
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
|
||||
|
||||
ret = carlink_common_init();
|
||||
|
||||
pctx->carlinkEventCB.onEvent = onEventAA;
|
||||
pctx->carlinkEventCB.rfcomm_data_read = aa_rfcomm_data_read;
|
||||
pctx->carlinkEventCB.cb_ctx = (void*)pctx;
|
||||
|
||||
carlink_register_event_callbacks(&pctx->carlinkEventCB);
|
||||
|
||||
ret = carlink_bt_wifi_init();
|
||||
|
||||
carlinkAACBPtr = &pctx->carlinkAACB;
|
||||
carlinkAACBPtr->video_init = video_init_impl;
|
||||
carlinkAACBPtr->video_uninit = video_uninit_impl;
|
||||
carlinkAACBPtr->video_play = video_play_impl;
|
||||
carlinkAACBPtr->audio_init_callback = audio_init_callback_impl;
|
||||
carlinkAACBPtr->audio_uninit_callback = audio_uninit_callback_impl;
|
||||
carlinkAACBPtr->audio_play = audio_play_impl;
|
||||
carlinkAACBPtr->mic_init_callback = mic_init_callback_impl;
|
||||
carlinkAACBPtr->mic_uninit_callback = mic_uninit_callback_impl;
|
||||
carlinkAACBPtr->mic_capture = mic_capture_impl;
|
||||
carlinkAACBPtr->bt_paring_request_callback = bt_paring_request_callback_impl;
|
||||
carlinkAACBPtr->status_notify = status_notify_impl;
|
||||
carlinkAACBPtr->json_msg_notify = json_msg_notify_impl;
|
||||
|
||||
carlinkAACBPtr->rf_read_transfer_cb = NULL;
|
||||
carlinkAACBPtr->rf_write_transfer_cb = rf_write_transfer_cb;
|
||||
carlinkAACBPtr->cb_ctx = (void*)pctx;
|
||||
ret = android_auto_init(&pctx->carlinkAACB);
|
||||
{
|
||||
char ip[4] = {0};
|
||||
carlink_get_ap_ip_addr(ip);
|
||||
sprintf(pctx->mIp, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
android_auto_notify_event(&ev, CARLINK_EVENT_INIT_DONE, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void taskInitCarlinkAA(void* param)
|
||||
{
|
||||
_carlink_aa_init();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
||||
int carlink_aa_init()
|
||||
{
|
||||
xTaskCreate(taskInitCarlinkAA, "initThread", 2048 * 4, NULL, 1, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
g_aa_disable = false;
|
||||
} else {
|
||||
g_aa_disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
int carlink_aa_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_aa_enable(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
7
MXC_A27-PCB4.5-270T/app/carlink/AA/src/carlink_aa.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _CARLINK_AA_H_
|
||||
#define _CARLINK_AA_H_
|
||||
|
||||
int carlink_aa_init();
|
||||
void carlink_aa_enable(int enable);
|
||||
|
||||
#endif
|
25
MXC_A27-PCB4.5-270T/app/carlink/CP/include/audio_callbacks.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef _AUDIO_CALLBACKS_H
|
||||
#define _AUDIO_CALLBACKS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int (*audio_start_callback_f)(void *ctx, int handle, int type, int rate, int bits, int channels);
|
||||
typedef void (*audio_stop_callback_f)(void *ctx, int handle, int type);
|
||||
typedef void ( *audio_reset_DSP_mode_callback_f)(void *ctx, int mode);
|
||||
|
||||
typedef struct audio_callbacks
|
||||
{
|
||||
audio_start_callback_f audio_start_callback;
|
||||
audio_stop_callback_f audio_stop_callback;
|
||||
audio_reset_DSP_mode_callback_f audio_reset_DSP_mode_callback;
|
||||
void *ctx;
|
||||
}audio_callbacks_t;
|
||||
|
||||
void audio_register_callbacks(void *cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
272
MXC_A27-PCB4.5-270T/app/carlink/CP/include/carplay.h
Normal file
@ -0,0 +1,272 @@
|
||||
#ifndef __CARPLAY_IF_H_H
|
||||
#define __CARPLAY_IF_H_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*#ifndef CARLINK_LINK_TYPE
|
||||
#define CARLINK_LINK_TYPE
|
||||
typedef enum
|
||||
{
|
||||
CARPLAY = 0x00,
|
||||
CARLIFE,
|
||||
ANDROID_CARLIFE,
|
||||
ANDROID_MIRROR = 3,
|
||||
IOS_CARLIFE,
|
||||
ANDROID_AUTO = 5,
|
||||
ECLINK = 0x06,
|
||||
CARPLAY_WIRELESS
|
||||
}Link_TYPE;
|
||||
#endif*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CALL_ACCEPT = 2,
|
||||
CALL_DROP = 3,
|
||||
}CALL;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MEDIA_NONE = 0,
|
||||
MEDIA_PLAY,
|
||||
MEDIA_PAUSE,
|
||||
MEDIA_PLAY_PAUSE,
|
||||
MEDIA_NEXT,
|
||||
MEDIA_PREVIOUS
|
||||
}MEDIA;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUDIO_MEDIA = 0,
|
||||
AUDIO_TELEPHONE,
|
||||
AUDIO_RECOGNITION,
|
||||
AUDIO_ALERT,
|
||||
AUDIO_REC,
|
||||
AUDIO_ALT,
|
||||
AUDIO_AUX_IN,
|
||||
AUDIO_AUX_OUT
|
||||
} AUDIO_TYPE;
|
||||
|
||||
/*
|
||||
|
||||
typedef enum _IAP2_LINK_STATUS
|
||||
{
|
||||
IAP2_INIT = -1,
|
||||
IAP2_USB_HOST_INSERTED,
|
||||
IAP2_USB_HOST_REMOVE,
|
||||
IAP2_USB_SWITCH_FAIL,
|
||||
IAP2_CONNECT,
|
||||
IAP2_DISCONNECT,
|
||||
}IAP2_LINK_STATUS;*/
|
||||
|
||||
#ifndef AirplayModeStateAlias
|
||||
#define AirplayModeStateAlias
|
||||
|
||||
typedef int CarplayEntity;
|
||||
#define CarplayEntity_NotApplicable 0
|
||||
#define CarplayEntity_Controller 1
|
||||
#define CarplayEntity_Accessory 2
|
||||
|
||||
typedef int CarplayTransferType;
|
||||
#define CarplayTransferType_NotApplicable 0
|
||||
#define CarplayTransferType_Take 1 // Transfer ownership permanently.
|
||||
#define CarplayTransferType_Untake 2 // Release permanent ownership.
|
||||
#define CarplayTransferType_Borrow 3 // Transfer ownership temporarily.
|
||||
#define CarplayTransferType_Unborrow 4 // Release temporary ownership.
|
||||
|
||||
|
||||
typedef int CarplayTransferPriority;
|
||||
#define CarplayTransferPriority_NotApplicable 0
|
||||
#define CarplayTransferPriority_NiceToHave 100 // Transfer succeeds only if constraint is <= Anytime.
|
||||
#define CarplayTransferPriority_UserInitiated 500 // Transfer succeeds only if constraint is <= UserInitiated.
|
||||
|
||||
|
||||
typedef int CarplayConstraint;
|
||||
#define CarplayConstraint_NotApplicable 0
|
||||
#define CarplayConstraint_Anytime 100 // Resource may be taken/borrowed at any time.
|
||||
#define CarplayConstraint_UserInitiated 500 // Resource may be taken/borrowed if user initiated.
|
||||
#define CarplayConstraint_Never 1000 // Resource may never be taken/borrowed.
|
||||
|
||||
|
||||
typedef int CarplayTriState;
|
||||
#define CarplayTriState_NotApplicable 0
|
||||
#define CarplayTriState_False -1
|
||||
#define CarplayTriState_True 1
|
||||
|
||||
|
||||
typedef int CarplaySpeechMode;
|
||||
#define CarplaySpeechMode_NotApplicable 0
|
||||
#define CarplaySpeechMode_None -1 // No speech-related states are active.
|
||||
#define CarplaySpeechMode_Speaking 1 // Device is speaking to the user.
|
||||
#define CarplaySpeechMode_Recognizing 2 // Device is recording audio to recognize speech from the user.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CarplayEntity entity;
|
||||
CarplaySpeechMode mode;
|
||||
|
||||
}CarPlaySpeechState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CarplayEntity screen; // Owner of the screen.
|
||||
CarplayEntity permScreen; // Permanent owner of screen.
|
||||
CarplayEntity mainAudio; // Owner of main audio.
|
||||
CarplayEntity permMainAudio; // Permanent owner of main audio.
|
||||
CarplayEntity phoneCall; // Owner of phone call.
|
||||
CarPlaySpeechState speech; // Owner of speech and its mode.
|
||||
CarplayEntity turnByTurn; // Owner of navigation.
|
||||
|
||||
} CarPlayModeState;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef void ( *CarplaySessionStarted_f )(void *ctx);
|
||||
typedef void ( *CarplaySessionStop_f )(void *ctx);
|
||||
typedef void ( *CarplaySessionModesChanged_f )(void *ctx, const CarPlayModeState * inState);
|
||||
typedef void ( *CarplaySessionRequestUI_f )(void *ctx);
|
||||
typedef void ( *CarplaySessionDuckAudio_f)(void *ctx, double inDurationSecs, double inVolume);
|
||||
typedef void ( *CarplaySessionUnduckAudio_f)(void *ctx, double inDurationSecs);
|
||||
typedef void ( *CarplayDisableBtSession_f)(void *ctx);
|
||||
typedef void ( *CarplayNotifyDeviceName_f)(void *ctx, const char *name, int len);
|
||||
typedef void ( *CarplayBonjourServiceFound_f)(void *ctx, char phone_bt_mac[6]);
|
||||
typedef void ( *CarplayViewAreaUpdateNotify_f)(void *ctx, int index);
|
||||
//typedef void ( *CarplayMsgNotify_f)(void *ctx, int id, int para1, int para2, const char* msg, int msgLen);
|
||||
typedef void ( *CarplayMsgNotify_f)(void *ctx, const char* msg, int msgLen);
|
||||
|
||||
typedef struct carplay_session_callbacks
|
||||
{
|
||||
CarplaySessionStarted_f SessionStarted;
|
||||
CarplaySessionStop_f SessionStop;
|
||||
CarplaySessionModesChanged_f SessionModesChanged;
|
||||
CarplaySessionRequestUI_f SessionRequestUI;
|
||||
CarplaySessionDuckAudio_f SessionDuckAudio;
|
||||
CarplaySessionUnduckAudio_f SessionUnduckAudio;
|
||||
CarplayDisableBtSession_f DisableBtSession;
|
||||
CarplayNotifyDeviceName_f NotifyDeviceName;
|
||||
CarplayBonjourServiceFound_f BonjourServiceFound;
|
||||
CarplayViewAreaUpdateNotify_f ViewAreaUpdateNotify;
|
||||
|
||||
CarplayMsgNotify_f MsgNotify;
|
||||
void *ctx;
|
||||
}carplay_session_callbacks_t;
|
||||
|
||||
typedef carplay_session_callbacks_t carplaySessionCbs;
|
||||
|
||||
/*
|
||||
* @brief 初始化carplay的基本信息,整个程序的生命周期里面调用一次;
|
||||
*/
|
||||
int carplay_init();
|
||||
void carplay_uninit();
|
||||
/*
|
||||
* @brief 注册carplay plugin的回调函数;
|
||||
* @param cbs指向carplay_session_callbacks_t类型的变量;
|
||||
*/
|
||||
void carplay_register_callbacks(void *cbs);
|
||||
/*
|
||||
* @brief 启动carplay;
|
||||
*/
|
||||
int carplay_start();
|
||||
|
||||
void start_carplay_client_connect();
|
||||
/*
|
||||
* @brief 停止carplay;
|
||||
*/
|
||||
void carplay_stop();
|
||||
/*
|
||||
* @brief 设置要连接手机的蓝牙mac地址,无线连接的时候使用;
|
||||
* @param bt_addr 蓝牙mac地址;
|
||||
*/
|
||||
void carplay_wl_set_iphone_mac_addr(char bt_addr[6]);
|
||||
|
||||
/*
|
||||
* @brief 发送电话按键给苹果;
|
||||
* @param button 类型见enum CALL;
|
||||
*/
|
||||
void Telephone_button_Update(unsigned button);
|
||||
/*
|
||||
* @brief 发送多媒体按键给苹果;
|
||||
* @param button 类型见enum MEDIA;
|
||||
*/
|
||||
void Media_button_Update(unsigned button);
|
||||
/*
|
||||
* @brief 发送siri按键给苹果;
|
||||
* @param button 1表示按下启动siri,0表示释放来结束siri;
|
||||
*/
|
||||
void send_siri_cmd(int button);
|
||||
void send_single_touchscreen_x_y_2_carplay(unsigned short x, unsigned short y, unsigned char pressed);
|
||||
void send_mul_touchscreen_x_y_2_carplay(
|
||||
unsigned char finger_idx1, unsigned char pressed1,
|
||||
unsigned short x1, unsigned short y1,
|
||||
unsigned char finger_idx2, unsigned char pressed2,
|
||||
unsigned short x2, unsigned short y2
|
||||
);
|
||||
/*
|
||||
* @brief 发送旋钮信息给苹果;
|
||||
*/
|
||||
void KnobUpdate(char gSelectButtonPressed,
|
||||
char gHomeButtonPressed,
|
||||
char gBackButtonPressed,
|
||||
double gXPosition,
|
||||
double gYPosition,
|
||||
char gWheelPositionRelative
|
||||
);
|
||||
|
||||
/*
|
||||
* @brief 请求iphone启动一个应用;
|
||||
* @param bundleId app的包名;
|
||||
* @param alert app启动的时候时候弹出警告对话框;
|
||||
*/
|
||||
int apple_app_launcher(char * bundleId, char alert);
|
||||
|
||||
/*
|
||||
* @brief 要求iphone发送关键帧;
|
||||
*/
|
||||
void force_key_frame();
|
||||
/*
|
||||
* @brief 设置夜间模式;
|
||||
* @param inNightMode 1表示进入夜间模式,0表示退出夜间模式
|
||||
*/
|
||||
void set_night_mode(char inNightMode);
|
||||
|
||||
/*
|
||||
* @brief 请求苹果手机输出视频数据;
|
||||
*/
|
||||
void request_UI(char *url);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void borrow_screen(int priority, int unborrow_constraint);
|
||||
void unborrow_screen(void);
|
||||
void take_screen(int priority, int take_constraint, int borrow_constraint);
|
||||
void untake_screen(void);
|
||||
void borrow_audio(int priority, int unborrow_constraint);
|
||||
void unborrow_audio(void);
|
||||
void take_audio(int priority, int take_constraint, int borrow_constraint);
|
||||
void untake_audio(void);
|
||||
void carplay_send_change_modes(CarplayTransferType inScreenType,
|
||||
CarplayTransferPriority inScreenPriority,
|
||||
CarplayConstraint inScreenTake,
|
||||
CarplayConstraint inScreenBorrow,
|
||||
CarplayTransferType inAudioType,
|
||||
CarplayTransferPriority inAudioPriority,
|
||||
CarplayConstraint inAudioTake,
|
||||
CarplayConstraint inAudioBorrow,
|
||||
CarplayTriState inPhone,
|
||||
CarplaySpeechMode inSpeech,
|
||||
CarplayTriState inTurnByTurn);
|
||||
|
||||
int carplay_ipc_start();
|
||||
void carplay_ipc_stop();
|
||||
void process_play_stream(int handle, void *buffer, int len, int frames, unsigned long long timestamp);
|
||||
void process_record_stream(int handle, void *buffer, int len, int frames, unsigned long long timestamp);
|
||||
|
||||
int carplay_get_iphone_ip_addr(char *ipaddr);
|
||||
void carplay_wl_set_iphone_mac_addr(char bt_addr[6]);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
80
MXC_A27-PCB4.5-270T/app/carlink/CP/include/iap.h
Normal file
@ -0,0 +1,80 @@
|
||||
#ifndef __IAP_H_H
|
||||
#define __IAP_H_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum _IAP2_LINK_STATUS
|
||||
{
|
||||
IAP2_INIT = -1,
|
||||
IAP2_USB_HOST_INSERTED,
|
||||
IAP2_CONNECT,
|
||||
IAP2_ID_OK,
|
||||
IAP2_USB_HOST_REMOVE,
|
||||
IAP2_USB_SWITCH_FAIL,
|
||||
IAP2_ID_FAIL,
|
||||
IAP2_DISCONNECT
|
||||
}IAP2_LINK_STATUS;
|
||||
|
||||
typedef void (*iap2_link_status_cb_f)(void *ctx, IAP2_LINK_STATUS status);
|
||||
typedef void (*iap2_msg_time_update_cb_f)(void *ctx, long long time, int zone_offset);
|
||||
typedef void (*iap2_msg_time_zone_update_cb_f)(void *ctx, long long time, int16_t zone, int8_t daylightOff);
|
||||
typedef void (*iap2_msg_gps_cb_f)(void *ctx, unsigned char session, int start);
|
||||
typedef void (*iap2_msg_gps_gprmc_data_status_cb_f)(void *ctx, int value_a, int value_v, int value_x);
|
||||
typedef void (*iap2_msg_identify_cb_f)(void *ctx, int type, int ok);
|
||||
typedef void (*iap2_msg_wl_carplay_update_cb_f)(void *ctx, int status);
|
||||
typedef int (*iap2_usb_switch_cb_f)(void *ctx, int state);
|
||||
typedef int (*iap2_write_data_cb_f)(void *ctx, char *buf, int len);
|
||||
typedef void (*iap2_msg_language_update_cb_f)(void *ctx, const char *lang);
|
||||
typedef void (*iap2_msg_call_state_update_cb_f)(void *ctx,
|
||||
const char *remoteId,
|
||||
const char *displayName,
|
||||
int status,
|
||||
int direction,
|
||||
const char *uuid,
|
||||
const char *addrBookId,
|
||||
const char *label,
|
||||
int service);
|
||||
|
||||
typedef void (*iap2_msg_nowplaying_update_cb_f)(void *ctx,
|
||||
int playback_status, int elapsed_time,
|
||||
uint8_t* media_item_title, int media_item_title_len,
|
||||
uint8_t* media_item_album_title, int media_item_album_title_len,
|
||||
uint8_t* media_item_artist, int media_item_artist_len,
|
||||
int song_length_ms);
|
||||
|
||||
typedef void (*iap2_msg_msg_json_cb_f)(void *ctx, const char* buf, int len);
|
||||
typedef struct iap2_callbacks_st
|
||||
{
|
||||
iap2_link_status_cb_f iap2_link_status_cb;
|
||||
iap2_msg_time_update_cb_f iap2_msg_time_update_cb;
|
||||
iap2_msg_gps_cb_f iap2_msg_gps_cb;
|
||||
iap2_msg_gps_gprmc_data_status_cb_f iap2_msg_gps_gprmc_data_status_cb;
|
||||
iap2_msg_identify_cb_f iap2_msg_identify_cb;
|
||||
iap2_msg_wl_carplay_update_cb_f iap2_msg_wl_carplay_update_cb;
|
||||
iap2_msg_language_update_cb_f iap2_msg_language_update_cb;
|
||||
iap2_msg_call_state_update_cb_f iap2_msg_call_state_update_cb;
|
||||
iap2_usb_switch_cb_f iap2_usb_switch_cb;
|
||||
iap2_write_data_cb_f iap2_write_data_cb;
|
||||
iap2_msg_time_zone_update_cb_f iap2_msg_time_zone_update_cb;
|
||||
iap2_msg_nowplaying_update_cb_f iap2_msg_nowplaying_update_cb;
|
||||
iap2_msg_msg_json_cb_f iap2_msg_msg_json_cb;
|
||||
|
||||
void *ctx;
|
||||
}iap2_callbacks;
|
||||
|
||||
void iap2_register_callbacks(iap2_callbacks *pcb);
|
||||
int iap2_start();
|
||||
int iap2_start_wifi_session();
|
||||
int force_iap2_bt_start();
|
||||
void iap2_stop();
|
||||
int apple_send_pascd(unsigned char session, char *data);
|
||||
int iap2_read_data_proc(char *buf, int len);
|
||||
int apple_start_update_call_state(int start);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
154
MXC_A27-PCB4.5-270T/app/carlink/CP/include/mycommon.h
Normal file
@ -0,0 +1,154 @@
|
||||
#ifndef MYCOMMON_H_H
|
||||
#define MYCOMMON_H_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef CARLINK_LINK_TYPE
|
||||
#define CARLINK_LINK_TYPE
|
||||
typedef enum
|
||||
{
|
||||
CARPLAY = 0x00,
|
||||
CARLIFE,
|
||||
ANDROID_CARLIFE,
|
||||
ANDROID_MIRROR = 3,
|
||||
IOS_CARLIFE,
|
||||
ANDROID_AUTO = 5,
|
||||
ECLINK = 0x06,
|
||||
CARPLAY_WIRELESS,
|
||||
AUTO_WIRELESS
|
||||
}Link_TYPE;
|
||||
#endif
|
||||
|
||||
//general function
|
||||
typedef enum __USB_MODE
|
||||
{
|
||||
UNDEFINED = 0,
|
||||
HOST,
|
||||
PERIPHERAL,
|
||||
OTG
|
||||
}USB_MODE;
|
||||
|
||||
#define LOGV(...) printf(__VA_ARGS__); printf("\r\n");
|
||||
|
||||
struct view_area
|
||||
{
|
||||
short w;
|
||||
short h;
|
||||
short x;
|
||||
short y;
|
||||
};
|
||||
|
||||
typedef struct __carplay_cfg_info
|
||||
{
|
||||
char *iap2_name;
|
||||
char *iap2_modelIdentifier;
|
||||
char *iap2_manfacturer;
|
||||
char *iap2_serialnumber;
|
||||
char *iap2_sw_ver;
|
||||
char *iap2_hw_ver;
|
||||
char *iap2_vehicleInfo_name;
|
||||
char *iap2_product_uuid;
|
||||
char *iap2_usb_serial_num;
|
||||
|
||||
char *manfacturer;
|
||||
char *oem_icon_label;
|
||||
char *oem_icon_path;
|
||||
char *os_info;
|
||||
char *iOSVersionMin;
|
||||
char *limited_ui_elements;
|
||||
char *guuid;
|
||||
char *devid;
|
||||
char link_type;
|
||||
char btmac[6];
|
||||
bool oem_icon_visible;
|
||||
bool limited_ui;
|
||||
bool right_hand_driver;
|
||||
bool night_mode;
|
||||
bool has_knob;
|
||||
bool has_telbutton;
|
||||
bool has_mediabutton;
|
||||
bool has_proxsensor;
|
||||
bool has_EnhancedReqCarUI;
|
||||
bool has_ETCSupported;
|
||||
bool HiFiTouch;
|
||||
bool LoFiTouch;
|
||||
unsigned short usb_country_code;
|
||||
unsigned short tp_verndor_code;
|
||||
unsigned short tp_product_code;
|
||||
unsigned short tel_verndor_code;
|
||||
unsigned short tel_product_code;
|
||||
unsigned short knob_verndor_code;
|
||||
unsigned short knob_product_code;
|
||||
unsigned short proxsensor_verndor_code;
|
||||
unsigned short proxsensor_product_code;
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
short screen_width_phy;//mm
|
||||
short screen_height_phy;
|
||||
|
||||
char encrypt_ic_i2c_bus_num;
|
||||
char encrypt_ic_addr;
|
||||
char usb_idx;
|
||||
char need_sw_aec;
|
||||
char aec_delay;
|
||||
bool tvout_enable;
|
||||
|
||||
bool use_remote_audio;
|
||||
char video_type;
|
||||
short icurrent;
|
||||
int duck_vol;
|
||||
|
||||
char enable_iap_carplay_sess;
|
||||
char *keychain_path_dir;
|
||||
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char* public_key;
|
||||
char* src_version;
|
||||
char ip_v4_addr[4];
|
||||
char wifi_channel;
|
||||
short net_port;
|
||||
|
||||
char carplay_net_ready;
|
||||
char disable_bonjour;
|
||||
char iap_carplay_rej;
|
||||
|
||||
bool enable_enhanced_siri;
|
||||
bool enable_single_ui;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
short mfi_ic_i2c_bus_num;
|
||||
short mfi_ic_addr;
|
||||
|
||||
bool is_old_carplay_ver;
|
||||
|
||||
struct view_area area[3];
|
||||
char view_area_index;
|
||||
|
||||
}carplay_cfg_info;
|
||||
|
||||
#if 0
|
||||
typedef struct __auto_cfg_info
|
||||
{
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char wifi_channel;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
} auto_cfg_info;
|
||||
#endif
|
||||
|
||||
extern carplay_cfg_info *g_link_info;
|
||||
//extern auto_cfg_info *g_auto_link_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
26
MXC_A27-PCB4.5-270T/app/carlink/CP/include/video_callbacks.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef _VIDEO_CALLBACKS_H
|
||||
#define _VIDEO_CALLBACKS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef int (*video_start_callback_f)(void *ctx);
|
||||
typedef void (*video_stop_callback_f)(void *ctx);
|
||||
typedef int (*video_proc_data_callback_f)(void *ctx, char *buf, int len);
|
||||
|
||||
typedef struct video_callbacks
|
||||
{
|
||||
video_start_callback_f video_start_callback;
|
||||
video_stop_callback_f video_stop_callback;
|
||||
video_proc_data_callback_f video_proc_data_callback;
|
||||
void *ctx;
|
||||
}video_callbacks_t;
|
||||
|
||||
void video_register_callbacks(void *cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
BIN
MXC_A27-PCB4.5-270T/app/carlink/CP/lib/carplay.a
Normal file
574
MXC_A27-PCB4.5-270T/app/carlink/CP/src/carlink_cp.c
Normal file
@ -0,0 +1,574 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "iap.h"
|
||||
#include "carplay.h"
|
||||
#include "audio_callbacks.h"
|
||||
#include "video_callbacks.h"
|
||||
#include "carlink_cp.h"
|
||||
//#include "DispatchLite.h"
|
||||
#include "mycommon.h"
|
||||
#include "ff_sfdisk.h"
|
||||
#include "carlink_video.h"
|
||||
#include "carlink_cp_priv.h"
|
||||
|
||||
#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include "carlink_common.h"
|
||||
#include "board.h"
|
||||
|
||||
#if CARLINK_CP
|
||||
|
||||
struct carplay_ctx
|
||||
{
|
||||
struct ICalinkEventCallbacks carlinkEventCB;
|
||||
|
||||
int mPhoneCarplayFlag;
|
||||
bool mInitDone;
|
||||
bool mBTConnected;
|
||||
bool mIapReady;
|
||||
bool mCarplayConnected;
|
||||
char mLocalBTMac[6];
|
||||
char mRemoteBTMac[6];
|
||||
char mIp[32];
|
||||
char mPhoneWifiMac[18];
|
||||
};
|
||||
|
||||
struct carplay_ctx g_cp_handle;
|
||||
static bool g_cp_disable = false;
|
||||
|
||||
|
||||
static void carplay_init_parameter();
|
||||
void start_mdnsd();
|
||||
void start_mdnsd_posix();
|
||||
void stop_mdnsd_posix();
|
||||
|
||||
static void carplay_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
|
||||
{
|
||||
ev->link_type = CARLINK_CARPLAY_WIRELESS;
|
||||
ev->disable_filter = disable_filter;
|
||||
ev->type = type;
|
||||
carlink_notify_event(ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void iap2_link_status(void *ctx, IAP2_LINK_STATUS status){}
|
||||
static int iap2_write_data(void *ctx, char *buf, int len)
|
||||
{
|
||||
(void)ctx;
|
||||
return carlink_iap_data_write((unsigned char *)buf, len);
|
||||
}
|
||||
extern uint32_t tire_front_time;
|
||||
extern uint32_t tire_rear_time;
|
||||
extern uint32_t fml_stamp_to_time(uint32_t timep , uint16_t time[]);
|
||||
extern void Send_list_set_time(uint32_t sum);
|
||||
static void iap2_msg_time_update(void *ctx, long long time, int zone_offset){
|
||||
(void)ctx;
|
||||
printf("iap2_msg_time_update %lld , %d\r\n",time,zone_offset);
|
||||
uint16_t time_transfer[6];
|
||||
uint32_t sum = (uint32_t)time;
|
||||
|
||||
tire_rear_time = sum;
|
||||
tire_front_time = sum;
|
||||
fml_stamp_to_time(sum,time_transfer);
|
||||
Send_list_set_time(sum);
|
||||
}
|
||||
static void iap2_msg_gps(void *ctx, unsigned char session, int start){}
|
||||
static void iap2_msg_gps_gprmc_data_status(void *ctx, int value_a, int value_v, int value_x){}
|
||||
static void iap2_msg_identify(void *ctx, int type, int ok)
|
||||
{
|
||||
if (ok && !g_link_info->enable_iap_carplay_sess) {
|
||||
start_mdnsd_posix();
|
||||
}
|
||||
}
|
||||
static void iap2_msg_wl_carplay_update(void *ctx, int status)//<2F>ֻ<EFBFBD><D6BB><EFBFBD>"Carplay<61><79><EFBFBD><EFBFBD>"<22>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
struct carplay_ctx* pctx = (struct carplay_ctx*)ctx;
|
||||
|
||||
pctx->mPhoneCarplayFlag = status;
|
||||
printf("%s:%d status:%d %d\r\n", __func__, __LINE__, status, pctx->mPhoneCarplayFlag);
|
||||
}
|
||||
//static void iap2_msg_language_update(void *ctx, const char *lang){}
|
||||
|
||||
static void carplay_session_started(void *ctx)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
printf("%s is called\r\n", __func__);
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_CONNECT, 0);
|
||||
}
|
||||
|
||||
static void carplay_session_Stop(void *ctx)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
printf("%s is called\r\n", __func__);
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_MSG_SESSION_STOP, 0);
|
||||
}
|
||||
|
||||
static void carplay_session_modes_changed(void *ctx, const CarPlayModeState * inState){}
|
||||
static void carplay_session_requestUI(void *ctx)
|
||||
{
|
||||
carplay_send_change_modes(CarplayTransferType_Take, CarplayTransferPriority_UserInitiated,
|
||||
CarplayConstraint_UserInitiated, CarplayConstraint_Anytime,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0);
|
||||
}
|
||||
|
||||
static void carplay_session_duck_audio(void *ctx, double inDurationSecs, double inVolume){}
|
||||
static void carplay_session_unduck_audio(void *ctx, double inDurationSecs){}
|
||||
//static void carplay_session_notify_device_name(void *ctx, const char *name, int len){}
|
||||
|
||||
static void carplay_disable_bt_session(void *ctx)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (g_link_info->disable_carplay_audio)
|
||||
return;
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_MSG_DISABLE_BT, 0);
|
||||
}
|
||||
|
||||
static int audio_start_callback_impl(void *ctx, int handle, int type, int rate, int bits, int channels)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = carlink_cp_audio_start(handle, type, rate, bits, channels);
|
||||
return ret;
|
||||
}
|
||||
static void audio_stop_callback_impl(void *ctx, int handle, int type)
|
||||
{
|
||||
carlink_cp_audio_stop(handle, type);
|
||||
}
|
||||
//extern char key_value;
|
||||
|
||||
static int video_start_callback_impl(void *ctx)
|
||||
{
|
||||
h264_dec_ctx_init();
|
||||
set_carlink_display_state(1);
|
||||
//key_value = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void video_stop_callback_impl(void *ctx)
|
||||
{
|
||||
//key_value = 0;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
set_carlink_display_state(0);
|
||||
}
|
||||
static int video_proc_data_callback_impl(void *ctx, char *buf, int len)
|
||||
{
|
||||
video_frame_s* frame = NULL;
|
||||
//printf("video_proc_data len:%d\r\n", len);
|
||||
|
||||
get_retry:
|
||||
frame = get_h264_frame_buf();
|
||||
if (NULL == frame) {
|
||||
//printf("h264 frame is empty\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
goto get_retry;
|
||||
//continue;
|
||||
}
|
||||
|
||||
memcpy(frame->cur, buf, len);
|
||||
frame->len = len;
|
||||
|
||||
notify_h264_frame_ready(&frame);
|
||||
return 0;
|
||||
}
|
||||
static void carplay_viewArea_update_notify(void *ctx, int index){}
|
||||
static void resetDspMode(void *ctx, int mode){}
|
||||
static void carplay_msg_notify(void*ctx, const char* buf, int len){}
|
||||
|
||||
void test_carplay_modules();
|
||||
|
||||
static void start_cp(struct carplay_ctx* pctx)
|
||||
{
|
||||
if (!pctx->mInitDone)
|
||||
return;
|
||||
//if (pctx->mBTConnected)
|
||||
// return;
|
||||
if (!pctx->mIapReady)
|
||||
return;
|
||||
|
||||
if (pctx->mCarplayConnected)
|
||||
return;
|
||||
|
||||
if (g_cp_disable)
|
||||
return;
|
||||
|
||||
g_link_info->enable_iap_carplay_sess = 1;
|
||||
if (g_link_info->enable_iap_carplay_sess == 0) {
|
||||
g_link_info->is_old_carplay_ver = 1;
|
||||
} else {
|
||||
g_link_info->is_old_carplay_ver = 0;
|
||||
}
|
||||
g_link_info->wifi_passwd = (char *)carlink_get_wifi_passwd();
|
||||
g_link_info->wifi_ssid = (char *)carlink_get_wifi_ssid();
|
||||
g_link_info->wifi_channel = 36;
|
||||
|
||||
{
|
||||
char ip[4] = {0};
|
||||
carlink_get_ap_ip_addr(ip);
|
||||
g_link_info->ip_v4_addr[0] = ip[0];
|
||||
g_link_info->ip_v4_addr[1] = ip[1];
|
||||
g_link_info->ip_v4_addr[2] = ip[2];
|
||||
g_link_info->ip_v4_addr[3] = ip[3];
|
||||
}
|
||||
|
||||
carplay_start();
|
||||
}
|
||||
|
||||
uint8_t carplay_flag = 0;
|
||||
static void carlink_cp_input_event_proc(const struct carlink_event *ev)
|
||||
{
|
||||
uint8_t key = ev->u.para[0];
|
||||
bool pressed = (bool)ev->u.para[1];
|
||||
//printf("key %d %d\n", key, (int)pressed);
|
||||
|
||||
#if 0
|
||||
if (key == 19) {//right
|
||||
if (!pressed)
|
||||
KnobUpdate(0, 0, 0, 0, 0, 0);
|
||||
else
|
||||
KnobUpdate(0, 0, 0, 1.0, 0, 0);
|
||||
} else if (key == 20) {
|
||||
if (!pressed)
|
||||
KnobUpdate(0, 0, 0, 0, 0, 0);
|
||||
else
|
||||
KnobUpdate(0, 0, 0, -1.0, 0, 0);
|
||||
}if (key == 18) {//up
|
||||
if (!pressed)
|
||||
KnobUpdate(0, 0, 0, 0, 0, 0);
|
||||
else
|
||||
KnobUpdate(0, 0, 0, 0, 1.0, 0);
|
||||
} else if (key == 17) {//down
|
||||
if (!pressed)
|
||||
KnobUpdate(0, 0, 0, 0, 0, 0);
|
||||
else
|
||||
KnobUpdate(0, 0, 0, 0, -1.0, 0);
|
||||
} else if (key == 27) {
|
||||
KnobUpdate(1, 0, 0, 0, 0, 0);
|
||||
}
|
||||
#else
|
||||
|
||||
if (key == 19) {//right
|
||||
if (!pressed)
|
||||
request_UI("maps:");
|
||||
} else if (key == 20) {
|
||||
if (!pressed)
|
||||
request_UI("music:");
|
||||
} else if (key == 18) {//left
|
||||
if (pressed)
|
||||
KnobUpdate(0, 0, 0, 0, 0, 1);
|
||||
|
||||
} else if (key == 17) {//right
|
||||
if (pressed)
|
||||
KnobUpdate(0, 0, 0, 0, 0, -1);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void onEventCarplay(void* ctx, const struct carlink_event *ev)
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
struct carplay_ctx* pctx = (struct carplay_ctx*)ctx;
|
||||
|
||||
if (NULL == ev)
|
||||
return;
|
||||
if (ev->link_type != CARLINK_CARPLAY_WIRELESS && !ev->disable_filter)// skip not aa event
|
||||
return;
|
||||
|
||||
type = ev->type;
|
||||
|
||||
|
||||
switch (type) {
|
||||
case CARLINK_EVENT_KEY_EVENT:
|
||||
if (!pctx->mCarplayConnected)
|
||||
break;
|
||||
carlink_cp_input_event_proc(ev);
|
||||
break;
|
||||
case -1: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_INIT_DONE:
|
||||
pctx->mInitDone = true;printf("%s:%d\r\n", __func__, __LINE__);
|
||||
start_cp(pctx);
|
||||
break;
|
||||
case CARLINK_EVENT_BT_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_IAP_READY: {
|
||||
pctx->mIapReady = true;
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
start_cp(pctx);
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_DISCONNECT: {
|
||||
printf("bt disconnect, iap disconnect %d %d\r\n", pctx->mIapReady, pctx->mPhoneCarplayFlag);
|
||||
if (pctx->mIapReady && !pctx->mPhoneCarplayFlag) {
|
||||
//<2F>ֻ<EFBFBD><D6BB><EFBFBD>"Carplay<61><79><EFBFBD><EFBFBD>"<22>رգ<D8B1>ͬʱƻ<CAB1><C6BB><EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD>ر<EFBFBD><D8B1>ˣ<EFBFBD>ִ<EFBFBD><D6B4>һ<EFBFBD><D2BB>carplay stop
|
||||
carplay_stop();
|
||||
}
|
||||
pctx->mIapReady = false;
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_WIFI_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
|
||||
printf("CARLINK_EVENT_MSG_SESSION_CONNECT\r\n");
|
||||
pctx->mCarplayConnected = 1;
|
||||
carplay_flag = 1;
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_STOP: {
|
||||
if (0 == pctx->mCarplayConnected) {
|
||||
printf("carplay connect timeout!\n");
|
||||
if (pctx->mPhoneCarplayFlag) {
|
||||
carlink_restart_bt_wifi();
|
||||
}
|
||||
} else {
|
||||
pctx->mCarplayConnected = 0;
|
||||
carplay_flag = 0;
|
||||
carlink_bt_open();
|
||||
printf("%s:%d\r\n", __func__, __LINE__);
|
||||
start_cp(pctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_DISABLE_BT: {
|
||||
printf("%s:%d status:%d\r\n", __func__, __LINE__, pctx->mPhoneCarplayFlag);
|
||||
carlink_bt_close();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void carplay_iap_data_read(void* ctx, const void* buf, int len)
|
||||
{
|
||||
struct carplay_ctx* pctx = (struct carplay_ctx*)ctx;
|
||||
|
||||
if (!pctx->mIapReady)
|
||||
return;
|
||||
|
||||
iap2_read_data_proc((char*)buf, len);
|
||||
}
|
||||
|
||||
|
||||
static void taskInitCarlinkCpProc(void* param)
|
||||
{
|
||||
struct carplay_ctx* pctx = &g_cp_handle;
|
||||
struct carlink_event ev = {0};
|
||||
int ret = -1;
|
||||
#if 0
|
||||
carplay_init_parameter();
|
||||
carlink_bt_wifi_init();
|
||||
//start_mdnsd();
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
carplay_modules_test();
|
||||
vTaskDelete(NULL);
|
||||
return;
|
||||
#endif
|
||||
|
||||
(void)param;
|
||||
|
||||
|
||||
iap2_callbacks iap2_cbs;
|
||||
memset((void *)&iap2_cbs, 0, sizeof(iap2_cbs));
|
||||
iap2_cbs.iap2_link_status_cb = iap2_link_status;
|
||||
iap2_cbs.iap2_write_data_cb = iap2_write_data;
|
||||
iap2_cbs.iap2_msg_time_update_cb = iap2_msg_time_update;
|
||||
iap2_cbs.iap2_msg_gps_cb = iap2_msg_gps;
|
||||
iap2_cbs.iap2_msg_gps_gprmc_data_status_cb = iap2_msg_gps_gprmc_data_status;
|
||||
iap2_cbs.iap2_msg_identify_cb = iap2_msg_identify;
|
||||
iap2_cbs.iap2_msg_wl_carplay_update_cb = iap2_msg_wl_carplay_update;
|
||||
iap2_cbs.iap2_msg_msg_json_cb = carplay_msg_notify;
|
||||
iap2_cbs.ctx = (void *)(pctx);
|
||||
iap2_register_callbacks(&iap2_cbs);
|
||||
|
||||
carplaySessionCbs carplay_cbs;
|
||||
memset((void *)&carplay_cbs, 0, sizeof(carplay_cbs));
|
||||
carplay_cbs.SessionStarted = carplay_session_started;
|
||||
carplay_cbs.SessionStop = carplay_session_Stop;
|
||||
carplay_cbs.SessionModesChanged = carplay_session_modes_changed;
|
||||
carplay_cbs.SessionRequestUI = carplay_session_requestUI;
|
||||
carplay_cbs.SessionDuckAudio = carplay_session_duck_audio;
|
||||
carplay_cbs.SessionUnduckAudio = carplay_session_unduck_audio;
|
||||
carplay_cbs.DisableBtSession = carplay_disable_bt_session;
|
||||
carplay_cbs.ViewAreaUpdateNotify = carplay_viewArea_update_notify;
|
||||
carplay_cbs.MsgNotify = carplay_msg_notify;
|
||||
carplay_cbs.ctx = (void *)(pctx);
|
||||
carplay_register_callbacks((void *)(&carplay_cbs));
|
||||
|
||||
video_callbacks_t video_cbs;
|
||||
memset((void *)&video_cbs, 0, sizeof(video_cbs));
|
||||
video_cbs.video_start_callback = video_start_callback_impl;
|
||||
video_cbs.video_stop_callback = video_stop_callback_impl;
|
||||
video_cbs.video_proc_data_callback = video_proc_data_callback_impl;
|
||||
video_cbs.ctx = NULL;
|
||||
video_register_callbacks((void *)(&video_cbs));
|
||||
|
||||
audio_callbacks_t audio_cbs;
|
||||
memset((void *)&audio_cbs, 0, sizeof(audio_cbs));
|
||||
audio_cbs.audio_start_callback = audio_start_callback_impl;
|
||||
audio_cbs.audio_stop_callback = audio_stop_callback_impl;
|
||||
audio_cbs.audio_reset_DSP_mode_callback = resetDspMode;
|
||||
audio_cbs.ctx = NULL;
|
||||
audio_register_callbacks((void *)(&audio_cbs));
|
||||
|
||||
set_carlink_display_info(0, 0, CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT);
|
||||
set_carlink_video_info(CARLINK_VIDEO_WIDTH, CARLINK_VIDEO_HEIGHT, 30);
|
||||
carplay_init_parameter();
|
||||
|
||||
ret = carlink_common_init();
|
||||
if (0 != ret) {
|
||||
printf("%s:%d failed\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
pctx->carlinkEventCB.onEvent = onEventCarplay;
|
||||
pctx->carlinkEventCB.rfcomm_data_read = carplay_iap_data_read;
|
||||
pctx->carlinkEventCB.cb_ctx = (void*)pctx;
|
||||
|
||||
carlink_register_event_callbacks(&pctx->carlinkEventCB);
|
||||
|
||||
#if 1
|
||||
carlink_bt_wifi_init();
|
||||
carplay_init();
|
||||
|
||||
carplay_notify_event(&ev, CARLINK_EVENT_INIT_DONE, 0);
|
||||
#else
|
||||
carplay_modules_test();
|
||||
#endif
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void carplay_init_parameter()
|
||||
{
|
||||
g_link_info->link_type = CARPLAY_WIRELESS;
|
||||
|
||||
g_link_info->iap2_name = IAP2NAME;
|
||||
g_link_info->iap2_modelIdentifier = IAP2MODEID;
|
||||
g_link_info->iap2_manfacturer =MANFACTURER;
|
||||
g_link_info->iap2_serialnumber = SERIALNUMBER;
|
||||
g_link_info->iap2_sw_ver = SWVER;
|
||||
g_link_info->iap2_hw_ver = HWVER;
|
||||
g_link_info->iap2_vehicleInfo_name = VEHICLENAME;
|
||||
g_link_info->iap2_product_uuid = "101375-0068";
|
||||
|
||||
g_link_info->manfacturer = MANFACTURER;
|
||||
g_link_info->oem_icon_label = OEMICONLABEL;
|
||||
g_link_info->oem_icon_path = OEMICONPATH;
|
||||
g_link_info->os_info = OSINFO;
|
||||
g_link_info->iOSVersionMin = iOS_VER_MIN;
|
||||
g_link_info->limited_ui_elements = LIMITEDUIELEMENTS;
|
||||
g_link_info->guuid = DEFAULTUUID;
|
||||
g_link_info->devid = DEFAULTDEVID;
|
||||
|
||||
g_link_info->oem_icon_visible = 0;//ISOEMICONVISIBLE;
|
||||
g_link_info->limited_ui = ISLIMITEDUI;
|
||||
g_link_info->right_hand_driver = ISRIGHTHANDDRIVER;
|
||||
g_link_info->night_mode = 0;
|
||||
g_link_info->has_knob = HAS_KNOB;
|
||||
g_link_info->has_telbutton = 1;
|
||||
g_link_info->has_mediabutton = 1;
|
||||
g_link_info->has_proxsensor = HAS_PROXSENSOR;
|
||||
g_link_info->has_EnhancedReqCarUI = HAS_EnhancedRequestCarUI;
|
||||
g_link_info->has_ETCSupported = HAS_ETC;
|
||||
g_link_info->HiFiTouch = 1;
|
||||
g_link_info->LoFiTouch = 0;
|
||||
|
||||
g_link_info->usb_country_code = kUSBCountryCodeUS;
|
||||
g_link_info->tp_verndor_code = kUSBVendorTouchScreen;
|
||||
g_link_info->tp_product_code = kUSBProductTouchScreen;
|
||||
g_link_info->tel_verndor_code = kUSBVendorTeleButtons;
|
||||
g_link_info->tel_product_code = kUSBProductTeleButtons;
|
||||
g_link_info->knob_verndor_code = kUSBVendorKnobButtons;
|
||||
g_link_info->knob_product_code = kUSBProductKnobButtons;
|
||||
g_link_info->proxsensor_verndor_code = kUSBVendorProxSensor;
|
||||
g_link_info->proxsensor_product_code = kUSBProductProxSensor;
|
||||
|
||||
g_link_info->width = CARLINK_VIDEO_WIDTH;//pixel
|
||||
g_link_info->height = CARLINK_VIDEO_HEIGHT;
|
||||
g_link_info->fps = 30;
|
||||
g_link_info->screen_width_phy = CARLINK_VIDEO_WIDTH;
|
||||
g_link_info->screen_height_phy = CARLINK_VIDEO_HEIGHT;
|
||||
|
||||
g_link_info->icurrent = 1000;
|
||||
g_link_info->enable_iap_carplay_sess = 1;
|
||||
g_link_info->keychain_path_dir = "/sf";
|
||||
g_link_info->is_old_carplay_ver = 0;
|
||||
g_link_info->enable_single_ui = 1;
|
||||
|
||||
g_link_info->disable_carplay_audio = 1;//1. audio is stream to bt;
|
||||
|
||||
//g_link_info->mfi_ic_addr = 0x22; //cp2.0
|
||||
g_link_info->mfi_ic_addr = 0x20; //cp3.0
|
||||
g_link_info->mfi_ic_i2c_bus_num = 0;
|
||||
|
||||
g_link_info->area[0].w = CARLINK_VIDEO_WIDTH;
|
||||
g_link_info->area[0].h = CARLINK_VIDEO_HEIGHT;
|
||||
g_link_info->area[0].x = 0;
|
||||
g_link_info->area[0].y = 0;
|
||||
|
||||
g_link_info->area[1].w = 1024;
|
||||
g_link_info->area[1].h = 600;
|
||||
g_link_info->area[1].x = 0;
|
||||
g_link_info->area[1].y = 0;
|
||||
|
||||
g_link_info->view_area_index = 0;
|
||||
|
||||
}
|
||||
|
||||
void carplay_modules_test();
|
||||
int carlink_cp_init()
|
||||
{
|
||||
xTaskCreate(taskInitCarlinkCpProc, "CpinitThread", 1024 * 32, NULL, configMAX_PRIORITIES / 4, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_cp_enable(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
g_cp_disable = false;
|
||||
} else {
|
||||
g_cp_disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//int mdnsd_task();
|
||||
static void taskMdnsdProc(void* param)
|
||||
{
|
||||
//mdnsd_task();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void start_mdnsd()
|
||||
{
|
||||
|
||||
xTaskCreate(taskMdnsdProc, "CpinitThread", 2048 * 4, NULL, 2, NULL);
|
||||
}
|
||||
|
||||
#else
|
||||
int carlink_cp_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_cp_enable(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
7
MXC_A27-PCB4.5-270T/app/carlink/CP/src/carlink_cp.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _CARLINK_CP_H_
|
||||
#define _CARLINK_CP_H_
|
||||
|
||||
int carlink_cp_init();
|
||||
void carlink_cp_enable(int enable);
|
||||
|
||||
#endif
|
216
MXC_A27-PCB4.5-270T/app/carlink/CP/src/carlink_cp_audio_impl.c
Normal file
@ -0,0 +1,216 @@
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <task.h>
|
||||
#include "os_adapt.h"
|
||||
#include "carlink_cp_priv.h"
|
||||
#include "carplay.h"
|
||||
#include "board.h"
|
||||
#include "audio.h"
|
||||
|
||||
|
||||
struct cp_audio_ctx
|
||||
{
|
||||
int handle;
|
||||
int type;
|
||||
int rate;
|
||||
int bits;
|
||||
int channels;
|
||||
|
||||
int start;
|
||||
int input;
|
||||
|
||||
struct audio_device *play_handle;
|
||||
struct audio_device *rec_handle;
|
||||
|
||||
pthread_t play_pid;
|
||||
pthread_t *play_pid_ptr;
|
||||
pthread_t rec_pid;
|
||||
pthread_t *rec_pid_ptr;
|
||||
};
|
||||
|
||||
struct audio_node
|
||||
{
|
||||
struct cp_audio_ctx entity;
|
||||
int isUse;
|
||||
};
|
||||
static struct audio_node gnode[8];
|
||||
static pthread_mutex_t g_node_lock = { \
|
||||
.xIsInitialized = pdFALSE, \
|
||||
.xMutex = { { 0 } }, \
|
||||
.xTaskOwner = NULL, \
|
||||
.xAttr = { .iType = 0 } \
|
||||
};
|
||||
|
||||
uint64_t UpTicks( void );
|
||||
|
||||
|
||||
static struct cp_audio_ctx* get_free_audio_node()
|
||||
{
|
||||
int i;
|
||||
struct cp_audio_ctx *pctx = NULL;
|
||||
struct audio_node* ptr= gnode;
|
||||
|
||||
pthread_mutex_lock(&g_node_lock);
|
||||
for (i = 0; i < ARRAY_SIZE(gnode); i++) {
|
||||
if (!ptr[i].isUse) {
|
||||
ptr[i].isUse = 1;
|
||||
pctx = &ptr[i].entity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_node_lock);
|
||||
return pctx;
|
||||
}
|
||||
|
||||
static struct cp_audio_ctx* get_audio_node_by_handle(int handle)
|
||||
{
|
||||
int i;
|
||||
struct cp_audio_ctx *pctx = NULL;
|
||||
struct audio_node* ptr= gnode;
|
||||
|
||||
pthread_mutex_lock(&g_node_lock);
|
||||
for (i = 0; i < ARRAY_SIZE(gnode); i++) {
|
||||
if (ptr[i].isUse) {
|
||||
struct cp_audio_ctx *tmp = &ptr[i].entity;
|
||||
if (tmp->handle == handle) {
|
||||
pctx = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_node_lock);
|
||||
return pctx;
|
||||
}
|
||||
|
||||
|
||||
static void release_audio_node(struct cp_audio_ctx *pctx)
|
||||
{
|
||||
int i;
|
||||
struct audio_node* ptr= gnode;
|
||||
if (NULL == pctx)
|
||||
return;
|
||||
|
||||
memset((void*)pctx, 0, sizeof(struct cp_audio_ctx));
|
||||
pthread_mutex_lock(&g_node_lock);
|
||||
for (i = 0; i < ARRAY_SIZE(gnode); i++) {
|
||||
if (pctx == &ptr[i].entity) {
|
||||
ptr[i].isUse = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_node_lock);
|
||||
}
|
||||
|
||||
static void * _AudioStreamRecordThread( void *inArg )
|
||||
{
|
||||
struct cp_audio_ctx* pctx = (struct cp_audio_ctx*)inArg;
|
||||
(void)pctx;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void * _AudioStreamPlayThread( void *inArg )
|
||||
{
|
||||
struct cp_audio_ctx* pctx = (struct cp_audio_ctx*)inArg;
|
||||
uint8_t buffer[960];
|
||||
int buffer_len = 960;
|
||||
int frame;
|
||||
|
||||
frame = 960 / (pctx->channels * pctx->channels / 8);
|
||||
|
||||
process_play_stream(pctx->handle, buffer, buffer_len, frame, UpTicks());
|
||||
|
||||
while(pctx->start) {
|
||||
process_play_stream(pctx->handle, buffer, buffer_len, frame, UpTicks());
|
||||
audio_dev_write(pctx->play_handle, buffer, buffer_len);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int carlink_cp_audio_start(int handle, int type, int rate, int bits, int channels)
|
||||
{
|
||||
int ret = -1;
|
||||
struct cp_audio_ctx* pctx = NULL;
|
||||
struct audio_caps caps = {0};
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setstacksize(&attr, 4096 * 12);
|
||||
|
||||
pctx = get_free_audio_node();
|
||||
if (NULL == pctx) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pctx->bits = bits;
|
||||
pctx->channels = channels;
|
||||
pctx->rate = rate;
|
||||
pctx->type = type;
|
||||
pctx->handle = handle;
|
||||
|
||||
if (type == AUDIO_TELEPHONE || type == AUDIO_RECOGNITION) {
|
||||
pctx->input = 1;
|
||||
}
|
||||
|
||||
pctx->play_handle = audio_dev_open(AUDIO_FLAG_REPLAY);
|
||||
caps.main_type = AUDIO_TYPE_OUTPUT;
|
||||
caps.sub_type = AUDIO_DSP_PARAM;
|
||||
caps.udata.config.samplerate = rate;
|
||||
caps.udata.config.channels = channels;
|
||||
caps.udata.config.samplebits = bits;
|
||||
audio_dev_configure(pctx->play_handle, &caps);
|
||||
|
||||
pctx->start = 1;
|
||||
if (pctx->input) {
|
||||
pctx->rec_handle = audio_dev_open(AUDIO_FLAG_RECORD);
|
||||
caps.main_type = AUDIO_TYPE_OUTPUT;
|
||||
caps.sub_type = AUDIO_DSP_PARAM;
|
||||
caps.udata.config.samplerate = rate;
|
||||
caps.udata.config.channels = channels;
|
||||
caps.udata.config.samplebits = bits;
|
||||
audio_dev_configure(pctx->play_handle, &caps);
|
||||
ret = pthread_create( &pctx->rec_pid, &attr, _AudioStreamRecordThread, (void*)pctx );
|
||||
if (ret == 0) {
|
||||
pctx->rec_pid_ptr = &pctx->rec_pid;
|
||||
}
|
||||
}
|
||||
|
||||
ret = pthread_create( &pctx->play_pid, &attr, _AudioStreamPlayThread, (void*)pctx );
|
||||
if (ret == 0) {
|
||||
pctx->play_pid_ptr = &pctx->play_pid;
|
||||
}
|
||||
|
||||
//exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void carlink_cp_audio_stop(int handle, int type)
|
||||
{
|
||||
struct cp_audio_ctx *pctx = NULL;
|
||||
|
||||
pctx = get_audio_node_by_handle(handle);
|
||||
|
||||
if (NULL == pctx || !pctx->start)
|
||||
return;
|
||||
|
||||
pctx->start = 0;
|
||||
|
||||
if (pctx->play_pid_ptr) {
|
||||
pthread_join(pctx->play_pid, NULL);
|
||||
pctx->play_pid_ptr = NULL;
|
||||
}
|
||||
|
||||
if (pctx->rec_pid_ptr) {
|
||||
pthread_join(pctx->rec_pid, NULL);
|
||||
pctx->rec_pid_ptr = NULL;
|
||||
}
|
||||
|
||||
release_audio_node(pctx);
|
||||
}
|
||||
|
393
MXC_A27-PCB4.5-270T/app/carlink/CP/src/carlink_cp_bt_wifi.c
Normal file
@ -0,0 +1,393 @@
|
||||
//#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "carlink_utils.h"
|
||||
#include "console.h"
|
||||
#include "fsc_bt.h"
|
||||
#include "iap.h"
|
||||
|
||||
#if !defined(USE_LWIP) || !USE_LWIP
|
||||
#error "Carplay need lwip!"
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
#include "carlink_video.h"
|
||||
#include "mycommon.h"
|
||||
#include "wifi_conf.h"
|
||||
#include "carlink_cp_priv.h"
|
||||
//#define USE_WLAN_STA
|
||||
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t cp_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t cp_ap_passwd[16] = {"88888888"};
|
||||
extern int wps_connect_done;
|
||||
|
||||
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
static int lwip_tcpip_init_done_flag = 0;
|
||||
|
||||
//static int g_bt_iap_ready = 0;
|
||||
//static int g_dhcp_client_cp_ready = 0;
|
||||
|
||||
static struct netif gnetif[4];
|
||||
|
||||
extern int wifi_add_custom_ie(void *cus_ie, int ie_num);
|
||||
int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
static void cp_reset_wifi_ap_info(const char *prefex);
|
||||
static void cp_start_wlan();
|
||||
extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
|
||||
static void tcpip_init_done(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
//lwip_tcpip_init_done_flag = 1;
|
||||
}
|
||||
|
||||
void lwiperf_report_cb_impl(void *arg, enum lwiperf_report_type report_type,
|
||||
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
printf("lwiperf_report_cb_impl bytes:%d %d ms \r\n", bytes_transferred, ms_duration);
|
||||
}
|
||||
|
||||
int cp_wlan_tcp_ip_is_ready()
|
||||
{
|
||||
return lwip_tcpip_init_done_flag;
|
||||
}
|
||||
|
||||
//dd3000a0400000020022020961726B6D6963726F0003064C696E75780004030102030606ffffffffffff070666fadde250c0
|
||||
static u8 carplay_vendor_ie[] = {
|
||||
0xdd, 0x30, 0x00, 0xa0, 0x40, 0x00, 0x00, 0x02, 0x00, 0x22, 0x02, 0x09, 0x61, 0x72, 0x6B, 0x6D,
|
||||
0x69, 0x63, 0x72, 0x6F, 0x00, 0x03, 0x06, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x00, 0x04, 0x03, 0x01,
|
||||
0x02, 0x03, 0x06, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x06, 0x66, 0xfa, 0xdd, 0xe2,
|
||||
0x50, 0xc0
|
||||
};
|
||||
rtw_custom_ie_t carplay_ie[1] = {{carplay_vendor_ie, PROBE_RSP | BEACON}};
|
||||
|
||||
void carplay_add_vendor_ie()
|
||||
{
|
||||
wifi_add_custom_ie((void *)carplay_ie, 1);
|
||||
}
|
||||
|
||||
void carplay_ie_replace_bt_mac(const char* btmac_str, int btmac_str_len)
|
||||
{
|
||||
char btmac[6] = {0};
|
||||
string2hex((char *)btmac_str, btmac_str_len, btmac, 6);
|
||||
memcpy((void*)g_link_info->btmac, (void*)btmac, 6);
|
||||
//sscanf(btmac_str, "%02x%02x%02x%02x%02x%02x", btmac[0], btmac[1], btmac[2], btmac[3], btmac[4], btmac[5]);
|
||||
carplay_vendor_ie[36] = btmac[0];
|
||||
carplay_vendor_ie[37] = btmac[1];
|
||||
carplay_vendor_ie[38] = btmac[2];
|
||||
carplay_vendor_ie[39] = btmac[3];
|
||||
carplay_vendor_ie[40] = btmac[4];
|
||||
carplay_vendor_ie[41] = btmac[5];
|
||||
//memcpy((void*)(carplay_vendor_ie + 36), (void*)btmac, 6);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(carplay_vendor_ie); i++) {
|
||||
printf("0x%02x, ", carplay_vendor_ie[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_WLAN_STA)
|
||||
static void dump_ip_addr(const char *msg, const ip_addr_t *server_addr)
|
||||
{
|
||||
printf("%s %d.%d.%d.%d \r\n", msg,
|
||||
ip4_addr1_16(ip_2_ip4(server_addr)), ip4_addr2_16(ip_2_ip4(server_addr)), ip4_addr3_16(ip_2_ip4(server_addr)), ip4_addr4_16(ip_2_ip4(server_addr)));
|
||||
}
|
||||
|
||||
static void cp_dhcp_client_status_callback(struct netif *netif, int status, const ip_addr_t *server_addr)
|
||||
{
|
||||
if (&gnetif[0] == netif) {
|
||||
dump_ip_addr("dhcp server ip :", (const ip_addr_t *)server_addr);
|
||||
dump_ip_addr("dhcp client ip :", (const ip_addr_t *)&netif->ip_addr);
|
||||
dump_ip_addr("dhcp client netmask:", (const ip_addr_t *)&netif->netmask);
|
||||
dump_ip_addr("dhcp client gw :", (const ip_addr_t *)&netif->gw);
|
||||
ip_addr_t *server_addr1 = (ip_addr_t *)&netif->ip_addr;
|
||||
g_link_info->ip_v4_addr[0] = ip4_addr1_16(ip_2_ip4(server_addr1));
|
||||
g_link_info->ip_v4_addr[1] = ip4_addr2_16(ip_2_ip4(server_addr1));
|
||||
g_link_info->ip_v4_addr[2] = ip4_addr3_16(ip_2_ip4(server_addr1));
|
||||
g_link_info->ip_v4_addr[3] = ip4_addr4_16(ip_2_ip4(server_addr1));
|
||||
//g_dhcp_client_cp_ready = 1;
|
||||
|
||||
//if (g_bt_iap_ready)
|
||||
//carplay_start();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void restart_bt_wifi()
|
||||
{
|
||||
cp_bt_close();
|
||||
netif_set_down(&gnetif[0]);
|
||||
WIFI_Off();
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
cp_bt_open();
|
||||
start_ap(36, (const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
carplay_add_vendor_ie();
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
static void cp_start_wlan()
|
||||
{
|
||||
char ap_prefix[5] = {0};
|
||||
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
while(!g_cp_bt_mac_ready) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
cp_reset_wifi_ap_info(ap_prefix);
|
||||
#if !defined(USE_WLAN_STA)
|
||||
start_ap(36, (const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
#else
|
||||
//start_sta((const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
dhcp_regisger_status_callback(cp_dhcp_client_status_callback);
|
||||
#endif
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(tcpip_init_done, NULL);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
#if !defined(USE_WLAN_STA)
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
//g_dhcp_client_cp_ready = 1;
|
||||
#endif
|
||||
|
||||
//netif_set_up(&gnetif[0]);
|
||||
lwiperf_start_tcp_server_default(lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
carplay_add_vendor_ie();
|
||||
}
|
||||
|
||||
void cp_wlan_start(void){
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
|
||||
static void cp_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
if (prefex) {
|
||||
memset(cp_ap_ssid, 0, sizeof(cp_ap_ssid));
|
||||
sprintf((char *)cp_ap_ssid, "AP630_CP_%s", prefex);
|
||||
}
|
||||
g_link_info->wifi_passwd = cp_ap_passwd;
|
||||
g_link_info->wifi_ssid = cp_ap_ssid;
|
||||
g_link_info->wifi_channel = 36;
|
||||
g_link_info->ip_v4_addr[0] = ucIPAddress[0];
|
||||
g_link_info->ip_v4_addr[1] = ucIPAddress[1];
|
||||
g_link_info->ip_v4_addr[2] = ucIPAddress[2];
|
||||
g_link_info->ip_v4_addr[3] = ucIPAddress[3];
|
||||
}
|
||||
|
||||
static void cp_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd_para = NULL;
|
||||
printf("\r\nfsc_bt_callback_ec %s %d\r\n", cAtStr, strlen(cAtStr));
|
||||
struct cp_event ev;
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
ev.type = -1;
|
||||
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+IAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
iap2_read_data_proc(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTDATA=", 10)) {
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=1",11)) {
|
||||
//ev.type = EC_EVENT_BT_DISCONNECT;
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_DISCONNECT\r\n",__func__ ,__LINE__);
|
||||
ev.type = CP_EVENT_BT_DISCONNECT;
|
||||
carlink_cp_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_CONNECT\r\n",__func__ ,__LINE__);
|
||||
|
||||
ev.type = CP_EVENT_BT_CONNECT;
|
||||
carlink_cp_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=AP630_CP_%s\r\n", (cAtStr + 6 + 8));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=AP630_CP_%s\r\n", (cAtStr + 6 + 8));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
carplay_ie_replace_bt_mac(cAtStr + 6, 12);
|
||||
g_cp_bt_mac_ready = true;
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
char* cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
} else if (0 == strncmp(cAtStr, "+NAME=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+LEADDR\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get LE addr
|
||||
} else if (0 == strncmp(cAtStr, "+LEADDR=", 6)) {
|
||||
char hexMacAddr[6] = {0};
|
||||
char m_tmp_buf[64] = {0};
|
||||
string2hex(&cAtStr[8], 12, hexMacAddr, sizeof(hexMacAddr));
|
||||
sprintf(m_tmp_buf, "AT+ADVDATA=%s\r\n", hexMacAddr);
|
||||
console_send_atcmd(m_tmp_buf, 19);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSENT=", 10)) {
|
||||
return;
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=3", 10)) {
|
||||
//g_bt_iap_ready = 1;
|
||||
|
||||
//if (g_dhcp_client_cp_ready)
|
||||
//carplay_start();
|
||||
|
||||
ev.type = CP_EVENT_BT_IAP_READY;
|
||||
carlink_cp_notify_event(&ev);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int iap_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+IAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
at_str = (uint8_t *)pvPortMalloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
vPortFree(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
void cp_bt_open()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=1\r\n"};
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
}
|
||||
|
||||
void cp_bt_close()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=0\r\n"};
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
}
|
||||
|
||||
|
||||
static void cp_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
char mac_str[32] = {0};
|
||||
char *mac = NULL;
|
||||
|
||||
if (xEvent) {
|
||||
mac = xEvent->xInfo.xAPStationConnected.ucMac;
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
wps_connect_done = 0;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", mac_str);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", mac_str);
|
||||
}
|
||||
}
|
||||
|
||||
static BaseType_t cp_wifi_init()
|
||||
{
|
||||
int status;
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, cp_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bt_set_support_carplay()
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=33962\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
|
||||
int carlink_cp_bt_wifi_init()
|
||||
{
|
||||
carlink_ey_video_init();
|
||||
cp_wifi_init();
|
||||
console_register_cb(NULL, cp_bt_callback);
|
||||
fsc_bt_main();
|
||||
bt_set_support_carplay();
|
||||
cp_bt_open();
|
||||
cp_start_wlan();
|
||||
printf("bt wlan init is ok\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
262
MXC_A27-PCB4.5-270T/app/carlink/CP/src/carlink_cp_bt_wifi1.c
Normal file
@ -0,0 +1,262 @@
|
||||
#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "carlink_utils.h"
|
||||
#include "console.h"
|
||||
#include "fsc_bt.h"
|
||||
#include "iap.h"
|
||||
|
||||
#if !defined(USE_LWIP) || !USE_LWIP
|
||||
#error "Carplay in freertos must use lwip!"
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
#include "carlink_video.h"
|
||||
#include "mycommon.h"
|
||||
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t cp_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t cp_ap_passwd[16] = {"88888888"};
|
||||
extern int wps_connect_done;
|
||||
|
||||
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
static int lwip_tcpip_init_done_flag = 0;
|
||||
|
||||
static struct netif gnetif[4];
|
||||
|
||||
|
||||
int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
static void cp_reset_wifi_ap_info(const char *prefex);
|
||||
static void cp_start_wlan();
|
||||
extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
|
||||
static void tcpip_init_done(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
//lwip_tcpip_init_done_flag = 1;
|
||||
}
|
||||
|
||||
void lwiperf_report_cb_impl(void *arg, enum lwiperf_report_type report_type,
|
||||
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
printf("lwiperf_report_cb_impl bytes:%d %d ms \r\n", bytes_transferred, ms_duration);
|
||||
}
|
||||
|
||||
int cp_wlan_tcp_ip_is_ready()
|
||||
{
|
||||
return lwip_tcpip_init_done_flag;
|
||||
}
|
||||
|
||||
static void cp_start_wlan()
|
||||
{
|
||||
const char *customer = "ark630hv100";
|
||||
char ap_prefix[5] = {0};
|
||||
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
while(!g_cp_bt_mac_ready) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
cp_reset_wifi_ap_info(ap_prefix);
|
||||
start_ap(36, (const char *)cp_ap_ssid, (const char *)cp_ap_passwd, 1);
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(tcpip_init_done, NULL);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
|
||||
lwiperf_start_tcp_server_default(lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void cp_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
memset(cp_ap_ssid, 0, sizeof(cp_ap_ssid));
|
||||
sprintf((char *)cp_ap_ssid, "AP630_%s", prefex);
|
||||
g_link_info->wifi_passwd = cp_ap_passwd;
|
||||
g_link_info->wifi_ssid = cp_ap_ssid;
|
||||
g_link_info->wifi_channel = 36;
|
||||
g_link_info->ip_v4_addr[0] = ucIPAddress[0];
|
||||
g_link_info->ip_v4_addr[1] = ucIPAddress[1];
|
||||
g_link_info->ip_v4_addr[2] = ucIPAddress[2];
|
||||
g_link_info->ip_v4_addr[3] = ucIPAddress[3];
|
||||
}
|
||||
|
||||
static void cp_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd_para = NULL;
|
||||
printf("\r\nfsc_bt_callback_ec %s %d\r\n", cAtStr, strlen(cAtStr));
|
||||
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+IAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
iap2_read_data_proc(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTDATA=", 10)) {
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=1",11)) {
|
||||
//ev.type = EC_EVENT_BT_DISCONNECT;
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_DISCONNECT\r\n",__func__ ,__LINE__);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_CONNECT\r\n",__func__ ,__LINE__);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=EC_%s\r\n", (cAtStr + 6));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=EC_%s\r\n", (cAtStr + 6));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
g_cp_bt_mac_ready = true;
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
char* cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
} else if (0 == strncmp(cAtStr, "+NAME=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+LEADDR\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get LE addr
|
||||
} else if (0 == strncmp(cAtStr, "+LEADDR=", 6)) {
|
||||
char hexMacAddr[6] = {0};
|
||||
char m_tmp_buf[64] = {0};
|
||||
string2hex(&cAtStr[8], 12, hexMacAddr, sizeof(hexMacAddr));
|
||||
sprintf(m_tmp_buf, "AT+ADVDATA=%s\r\n", hexMacAddr);
|
||||
console_send_atcmd(m_tmp_buf, 19);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSENT=", 10)) {
|
||||
return;
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=3", 10)) {
|
||||
carplay_start();
|
||||
}
|
||||
}
|
||||
|
||||
int iap_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+IAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
at_str = (uint8_t *)pvPortMalloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
vPortFree(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static void cp_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
|
||||
wps_connect_done = 0;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", xEvent->xInfo.xAPStationConnected.ucMac);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", xEvent->xInfo.xAPStationDisconnected.ucMac);
|
||||
}
|
||||
}
|
||||
|
||||
static BaseType_t cp_wifi_init()
|
||||
{
|
||||
int status;
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, cp_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bt_set_support_carplay()
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=33962\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
|
||||
int carlink_cp_bt_wifi_init()
|
||||
{
|
||||
carlink_ey_video_init();
|
||||
cp_wifi_init();
|
||||
console_register_cb(NULL, cp_bt_callback);
|
||||
fsc_bt_main();
|
||||
bt_set_support_carplay();
|
||||
cp_start_wlan();
|
||||
printf("bt wlan init is ok\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
53
MXC_A27-PCB4.5-270T/app/carlink/CP/src/carlink_cp_priv.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef __CARLINK_CP_PRI_H
|
||||
#define __CARLINK_CP_PRI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IAP2NAME "KY CAR"
|
||||
#define IAP2MODEID "Linux"
|
||||
#define SERIALNUMBER "0123456789ABCDEF"
|
||||
#define SWVER "sw0.1"
|
||||
#define HWVER "hw0.1"
|
||||
#define VEHICLENAME "audi"
|
||||
|
||||
#define MANFACTURER "ARK"
|
||||
#define OEMICONLABEL "Home"
|
||||
#define OEMICONPATH "/sf/carplay_icon.png"
|
||||
#define OSINFO "rtos"
|
||||
#define iOS_VER_MIN "11D257"
|
||||
//#define LIMITEDUIELEMENTS "softKeyboard"
|
||||
#define LIMITEDUIELEMENTS "japanMaps"
|
||||
#define DEFAULTUUID "e5f7b72d-9b7f-4305-954b-973f612a150b"
|
||||
#define DEFAULTDEVID "10:13:52:33:67:09"
|
||||
#define ISOEMICONVISIBLE 1
|
||||
#define ISRIGHTHANDDRIVER 0
|
||||
#define ISLIMITEDUI 1
|
||||
#define HAS_KNOB 1
|
||||
#define HAS_PROXSENSOR 0
|
||||
#define HAS_ETC 0
|
||||
#define HAS_EnhancedRequestCarUI 0
|
||||
|
||||
#define kUSBCountryCodeUS 33
|
||||
#define kUSBVendorTouchScreen 0x0525
|
||||
#define kUSBProductTouchScreen 0xa4a1
|
||||
#define kUSBVendorTeleButtons 0x0525
|
||||
#define kUSBProductTeleButtons 0xa4a2
|
||||
#define kUSBVendorKnobButtons 0x0525
|
||||
#define kUSBProductKnobButtons 0xa4a2
|
||||
#define kUSBVendorProxSensor 0
|
||||
#define kUSBProductProxSensor 0
|
||||
|
||||
#define PHYSICAL_WIDTH 160
|
||||
#define PHYSICAL_HEIGHT 80
|
||||
|
||||
void carplay_modules_test();
|
||||
int carlink_cp_audio_start(int handle, int type, int rate, int bits, int channels);
|
||||
void carlink_cp_audio_stop(int handle, int type);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
345
MXC_A27-PCB4.5-270T/app/carlink/EC-orig/include/ECTiny.h
Normal file
@ -0,0 +1,345 @@
|
||||
#ifndef __ECTINY_API_H__
|
||||
#define __ECTINY_API_H__
|
||||
|
||||
#include "ECTypes.h"
|
||||
|
||||
#define ECSDK_VERSION "1.0.8.1"
|
||||
|
||||
typedef struct {
|
||||
|
||||
void (*onECConnectStatus)(ECConnectedStatus status, ECConnectedType type);
|
||||
|
||||
void (*onMirrorStatus)(ECMirrorStatus status);
|
||||
/**
|
||||
* @brief Called when EasyConnected status changed.
|
||||
*
|
||||
* @param status The changed EasyConnected message.
|
||||
*/
|
||||
void (*onECStatusMessage)(ECStatusMessage status);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD information.
|
||||
*
|
||||
* @param data HUD information.
|
||||
*/
|
||||
void (*onPhoneAppHUD)(const ECNavigationHudInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD Road Junction Picture.
|
||||
* @param data
|
||||
*/
|
||||
void (*onPhoneAppHUDRoadJunctionPicture)(const ECHudRoadJunctionPictureInfo* data);
|
||||
|
||||
/*
|
||||
* @brief Called when phone app tell the music info.
|
||||
*
|
||||
* @param data The information of music.
|
||||
*/
|
||||
void (*onPhoneAppMusicInfo)(const ECAppMusicInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down some information.
|
||||
*
|
||||
* @param data Buffer of app information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data is json string, the fields includes os, osVersion and ip.
|
||||
* Called when ECSDK::openTransport succeed.
|
||||
*/
|
||||
void (*onPhoneAppInfo)(const void *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when ECSDK wants car to do call operations(dial or hang up) via Bluetooth.
|
||||
*
|
||||
* @param type Operation type.
|
||||
*
|
||||
* @param name The person's name of corresponding number.
|
||||
*
|
||||
* @param number Phone numbers.
|
||||
*
|
||||
* @note Phone app is not able to dial or hang up automatically due to the latest system access limitation,
|
||||
* however, car is able to do it via Bluetooth. Therefore, ECSDK moves the call operations
|
||||
* to car, which can dial or hang up when this method is called.
|
||||
*/
|
||||
void (*onCallAction)(ECCallType type, const char *name, const char *number);
|
||||
|
||||
/**
|
||||
* @brief Called when bulk data is received.
|
||||
*
|
||||
* @param data Buffer of bulk data.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
*/
|
||||
void (*onBulkDataReceived)(const void *data, uint32_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief onRealMirrorSizeChanged
|
||||
* @param realWidth
|
||||
* @param realHeight
|
||||
*
|
||||
* \note The actual size of the projection screen does not equal the size of the video stream in some cases.
|
||||
* The surrounding area is filled with black. This message calls back the actual size of the projection screen
|
||||
*/
|
||||
void (*onMirrorInfoChanged)(const ECVideoInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization failed. After this interface was called,
|
||||
* all connections would be forced closed.
|
||||
*
|
||||
* @param errCode Error code.
|
||||
*
|
||||
* @param errMsg Error message.
|
||||
*/
|
||||
void (*onLicenseAuthFail)(int32_t errCode, const char *errMsg);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization succeed.
|
||||
*
|
||||
* @param code success code. The code can gain specific meaning by ECAuthSuccessCode.
|
||||
*
|
||||
* @param msg success information.
|
||||
*
|
||||
* @param msg the description information.
|
||||
*
|
||||
*/
|
||||
void (*onLicenseAuthSuccess)(int32_t code, const char *msg);
|
||||
|
||||
/**
|
||||
* @brief Called when registered command was triggered by VR.
|
||||
*
|
||||
* @param carCmd The triggered command.
|
||||
*
|
||||
* @note Voice control can be implemented with this method by VR.
|
||||
*
|
||||
* @see ECSDK::registerCarCmds
|
||||
*/
|
||||
void (*onCarCmdNotified)(const ECCarCmd *carCmd);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to start input.
|
||||
*
|
||||
* @param info relevant parameters about the input.
|
||||
*/
|
||||
void (*onInputStart)(const ECInputInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to cancel input.
|
||||
*/
|
||||
void (*onInputCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the selection of input.
|
||||
*/
|
||||
void (*onInputSelection)(int32_t start, int32_t stop);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the text of input.
|
||||
*/
|
||||
void (*onInputText)(const char *text);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app send the text of VR or TTS.
|
||||
*/
|
||||
void (*onVRTextReceived)(const ECVRTextInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the page list.
|
||||
*
|
||||
* @param pages Array of the struct ECPageInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageListReceived)(const ECPageInfo *pages, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the icons.
|
||||
*
|
||||
* @param icons Array of the struct ECIconInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageIconReceived)(const ECIconInfo *icons, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell weather.
|
||||
*
|
||||
* @param data Buffer of weather information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onWeatherReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell vr tips.
|
||||
*
|
||||
* @param data Buffer of tips information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onVRTipsReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when the app requests networking
|
||||
*
|
||||
* @param clientInfo Mobile phone related information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNet)(const ECBTClientInfo *clientInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when canceling networking
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNetCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when networking is completed
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneBuildNetFinish)();
|
||||
|
||||
/**
|
||||
* @brief Called when app sends AP information
|
||||
*
|
||||
* @param netDeviceInfo AP information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneAPInfo)(const ECBTNetInfo* netDeviceInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when mobile phone has a notification message.
|
||||
* @param notification
|
||||
*/
|
||||
void (*onPhoneNotification)(const ECPhoneNotification* notification);
|
||||
} IECCallBack;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*size)(const char* name);
|
||||
int32_t (*read)(const char* name,void *data, uint32_t length);
|
||||
int32_t (*write)(const char* name,void *data, uint32_t length);
|
||||
void (*clear)(const char* name);
|
||||
}IECAccessFile;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(void *data, uint32_t length);
|
||||
int32_t (*write)(void *data, uint32_t length);
|
||||
void (*close)();
|
||||
}IECAccessDevice;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*registHid)(uint32_t deviceId,uint32_t descriptorSize);
|
||||
void (*unRegistHid)(uint32_t deviceId);
|
||||
uint32_t (*sendHiDDescriptor)(uint32_t deviceId, const unsigned char* descriptor, uint32_t len);
|
||||
uint32_t (*sendHidEvent)(uint32_t deviceId, const unsigned char* event, uint32_t len);
|
||||
}IECHidAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(uint8_t* data, uint32_t len);
|
||||
int32_t (*write)(const uint8_t* data, uint32_t len);
|
||||
int32_t (*close)();
|
||||
}IECBTAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(int32_t width, int32_t height);
|
||||
void (*stop)();
|
||||
void (*play)(const void *data, uint32_t len);
|
||||
}IECVideoPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(ECAudioType type, const ECAudioInfo *info);
|
||||
void (*stop)(ECAudioType type);
|
||||
void (*play)(ECAudioType type, const void *data, uint32_t len);
|
||||
void (*setVolume)(ECAudioType type, uint32_t vol);
|
||||
}IECAudioPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*start)(const ECAudioInfo *info);
|
||||
void (*stop)();
|
||||
int32_t (*record)(void *data, uint32_t len);
|
||||
}IECAudioRecorder;
|
||||
|
||||
typedef void *ECConfigHandle;
|
||||
|
||||
ECConfigHandle EC_createECConfig();
|
||||
void EC_destroyECConfig(ECConfigHandle config);
|
||||
void EC_setBaseConfig(ECConfigHandle config,const char *uuid, const char *version,const char *writableDir);
|
||||
void EC_setCommonConfig(ECConfigHandle config, const char *cfgName, const char *value);
|
||||
void EC_setCommonConfig1(ECConfigHandle config, const char *cfgName, int32_t value);
|
||||
|
||||
int32_t EC_initialize(ECConfigHandle config, IECCallBack *listener);
|
||||
int32_t EC_release();
|
||||
int32_t EC_setLogInfo(const ECLogLevel level,const ECLogOutputType type,const char *logDirectory, int32_t module);
|
||||
const char* EC_getVersion();
|
||||
int32_t EC_getVersionCode();
|
||||
int32_t EC_start();
|
||||
int32_t EC_stop();
|
||||
int32_t EC_bindAccessFile(IECAccessFile *handle);
|
||||
int32_t EC_bindUSBDevice(ECTransportType type, IECAccessDevice *dev);
|
||||
int32_t EC_bindWIFIDevice(ECTransportType type, const char *ip);
|
||||
int32_t EC_unbindDevice(ECTransportType type);
|
||||
int32_t EC_bindHidDevice(IECHidAccessDev* dev);
|
||||
int32_t EC_unBindHidDevice();
|
||||
int32_t EC_bindBTDevice( IECAccessDevice* ioHandle);
|
||||
int32_t EC_unBindBTDevice();
|
||||
int32_t EC_setMirrorConfig(const ECMirrorConfig *mirrorCfg);
|
||||
int32_t EC_setVideoPlayer(IECVideoPlayer* video);
|
||||
int32_t EC_setAudioPlayer(IECAudioPlayer* audio);
|
||||
int32_t EC_setAudioRecorder(IECAudioRecorder* audioRecorde);
|
||||
int32_t EC_notifyWifiStateChanged(ECWifiStateAction action, const ECNetWorkInfo* netInfo);
|
||||
int32_t EC_setRequestBuildNetRly(const char *phoneID, const ECBTRequestBuildNetRly *rly);
|
||||
int32_t EC_setNetInterfaceInfo(const ECNetInterfaceInfo *info,const int32_t num);
|
||||
int32_t EC_startMirror();
|
||||
void EC_stopMirror();
|
||||
int32_t EC_pauseMirror();
|
||||
int32_t EC_resumeMirror();
|
||||
int32_t EC_sendTouchEvent(const ECTouchEventData *touch, ECTouchEventType type);
|
||||
int32_t EC_sendBtnEvent(int32_t btnCode, int32_t type);
|
||||
int32_t EC_stopPhoneNavigation();
|
||||
int32_t EC_stopPhoneVR();
|
||||
int32_t EC_uploadNightModeStatus(uint32_t isNightModeOn);
|
||||
int32_t EC_uploadDrivingStatus(ECDrivingStatus status);
|
||||
int32_t EC_enableDownloadPhoneAppAudio(uint32_t supportType, uint32_t autoChangeToBT);
|
||||
void EC_disableDownloadPhoneAppAudio();
|
||||
int32_t EC_enableDownloadPhoneAppHud(uint32_t supportFunction);
|
||||
void EC_disableDownloadPhoneAppHud();
|
||||
int32_t EC_setConnectedBTAddress(const char *carBtMac, const char *phoneBtMac);
|
||||
int32_t EC_sendCarBluetooth(const char *name, const char *adddress, const char *pin);
|
||||
int32_t EC_openAppPage(int32_t page);
|
||||
int32_t EC_queryGPS(uint32_t* status, ECGPSInfo* gps);
|
||||
int32_t EC_queryTime(uint64_t *gmtTime, uint64_t *localTime, char *timeZone, uint32_t len);
|
||||
int32_t EC_sendCarStatus(ECCarStatusType carStatus, ECCarStatusValue value);
|
||||
int32_t EC_registerCarCmds(const ECCarCmd *carCmds, uint32_t length);
|
||||
int32_t EC_playCarTTS(const char *text, uint32_t level);
|
||||
int32_t EC_registerSimilarSoundingWords(const char *data, uint32_t length);
|
||||
int32_t EC_sendInputText(const char* text);
|
||||
int32_t EC_sendInputAction(int32_t actionId, int32_t keyCode);
|
||||
int32_t EC_sendInputSelection(int32_t start, int32_t stop);
|
||||
int32_t EC_queryPageList();
|
||||
int32_t EC_queryPageIcon(int32_t* pages, int32_t length);
|
||||
int32_t EC_queryWeather();
|
||||
int32_t EC_queryVRTips();
|
||||
const char* EC_generateQRCodeUrl(ECQRInfo* info);
|
||||
int32_t EC_startIperfTcpServer(const char* ip, int port);
|
||||
void EC_stopIperfTcpServer();
|
||||
#endif
|
||||
|
1428
MXC_A27-PCB4.5-270T/app/carlink/EC-orig/include/ECTypes.h
Normal file
BIN
MXC_A27-PCB4.5-270T/app/carlink/EC-orig/lib/ECTiny.a
Normal file
1095
MXC_A27-PCB4.5-270T/app/carlink/EC-orig/src/carlink_ec.c
Normal file
6
MXC_A27-PCB4.5-270T/app/carlink/EC-orig/src/carlink_ec.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef _CARLINK_EC_H_
|
||||
#define _CARLINK_EC_H_
|
||||
|
||||
int carlink_ec_init(int argc,char ** argv);
|
||||
|
||||
#endif
|
852
MXC_A27-PCB4.5-270T/app/carlink/EC/include/ECTiny.h
Normal file
@ -0,0 +1,852 @@
|
||||
#ifndef __ECTINY_API_H__
|
||||
#define __ECTINY_API_H__
|
||||
|
||||
#include "ECTypes.h"
|
||||
|
||||
#define ECSDK_VERSION "1.0.10"
|
||||
|
||||
typedef struct {
|
||||
|
||||
void (*onECConnectStatus)(ECConnectedStatus status, ECConnectedType type);
|
||||
|
||||
void (*onMirrorStatus)(ECMirrorStatus status);
|
||||
/**
|
||||
* @brief Called when EasyConnected status changed.
|
||||
*
|
||||
* @param status The changed EasyConnected message.
|
||||
*/
|
||||
void (*onECStatusMessage)(ECStatusMessage status);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD information.
|
||||
*
|
||||
* @param data HUD information.
|
||||
*/
|
||||
void (*onPhoneAppHUD)(const ECNavigationHudInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD Road Junction Picture.
|
||||
* @param data
|
||||
*/
|
||||
void (*onPhoneAppHUDRoadJunctionPicture)(const ECHudRoadJunctionPictureInfo* data);
|
||||
|
||||
/*
|
||||
* @brief Called when phone app tell the music info.
|
||||
*
|
||||
* @param data The information of music.
|
||||
*/
|
||||
void (*onPhoneAppMusicInfo)(const ECAppMusicInfo *data);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down some information.
|
||||
*
|
||||
* @param data Buffer of app information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data is json string, the fields includes os, osVersion and ip.
|
||||
* Called when ECSDK::openTransport succeed.
|
||||
*/
|
||||
void (*onPhoneAppInfo)(const void *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when ECSDK wants car to do call operations(dial or hang up) via Bluetooth.
|
||||
*
|
||||
* @param type Operation type.
|
||||
*
|
||||
* @param name The person's name of corresponding number.
|
||||
*
|
||||
* @param number Phone numbers.
|
||||
*
|
||||
* @note Phone app is not able to dial or hang up automatically due to the latest system access limitation,
|
||||
* however, car is able to do it via Bluetooth. Therefore, ECSDK moves the call operations
|
||||
* to car, which can dial or hang up when this method is called.
|
||||
*/
|
||||
void (*onCallAction)(ECCallType type, const char *name, const char *number);
|
||||
|
||||
/**
|
||||
* @brief Called when bulk data is received.
|
||||
*
|
||||
* @param data Buffer of bulk data.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
*/
|
||||
void (*onBulkDataReceived)(const void *data, uint32_t length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief onRealMirrorSizeChanged
|
||||
* @param realWidth
|
||||
* @param realHeight
|
||||
*
|
||||
* \note The actual size of the projection screen does not equal the size of the video stream in some cases.
|
||||
* The surrounding area is filled with black. This message calls back the actual size of the projection screen
|
||||
*/
|
||||
void (*onMirrorInfoChanged)(const ECVideoInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization failed. After this interface was called,
|
||||
* all connections would be forced closed.
|
||||
*
|
||||
* @param errCode Error code.
|
||||
*
|
||||
* @param errMsg Error message.
|
||||
*/
|
||||
void (*onLicenseAuthFail)(int32_t errCode, const char *errMsg);
|
||||
|
||||
/**
|
||||
* @brief Called when the license authorization succeed.
|
||||
*
|
||||
* @param code success code. The code can gain specific meaning by ECAuthSuccessCode.
|
||||
*
|
||||
* @param msg success information.
|
||||
*
|
||||
* @param msg the description information.
|
||||
*
|
||||
*/
|
||||
void (*onLicenseAuthSuccess)(int32_t code, const char *msg);
|
||||
|
||||
/**
|
||||
* @brief Called when registered command was triggered by VR.
|
||||
*
|
||||
* @param carCmd The triggered command.
|
||||
*
|
||||
* @note Voice control can be implemented with this method by VR.
|
||||
*
|
||||
* @see ECSDK::registerCarCmds
|
||||
*/
|
||||
void (*onCarCmdNotified)(const ECCarCmd *carCmd);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to start input.
|
||||
*
|
||||
* @param info relevant parameters about the input.
|
||||
*/
|
||||
void (*onInputStart)(const ECInputInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app request the HU to cancel input.
|
||||
*/
|
||||
void (*onInputCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the selection of input.
|
||||
*/
|
||||
void (*onInputSelection)(int32_t start, int32_t stop);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the text of input.
|
||||
*/
|
||||
void (*onInputText)(const char *text);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app send the text of VR or TTS.
|
||||
*/
|
||||
void (*onVRTextReceived)(const ECVRTextInfo *info);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the page list.
|
||||
*
|
||||
* @param pages Array of the struct ECPageInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageListReceived)(const ECPageInfo *pages, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell the icons.
|
||||
*
|
||||
* @param icons Array of the struct ECIconInfo.
|
||||
*
|
||||
* @param length The length of the array.
|
||||
*/
|
||||
void (*onPageIconReceived)(const ECIconInfo *icons, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell weather.
|
||||
*
|
||||
* @param data Buffer of weather information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onWeatherReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when phone app tell vr tips.
|
||||
*
|
||||
* @param data Buffer of tips information.
|
||||
*
|
||||
* @param length Buffer length.
|
||||
*
|
||||
* @note data pointed to a json string buffer.
|
||||
*/
|
||||
void (*onVRTipsReceived)(const char *data, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief Called when the app requests networking
|
||||
*
|
||||
* @param clientInfo Mobile phone related information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNet)(const ECBTClientInfo *clientInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when canceling networking
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onRequestBuildNetCancel)();
|
||||
|
||||
/**
|
||||
* @brief Called when networking is completed
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneBuildNetFinish)();
|
||||
|
||||
/**
|
||||
* @brief Called when app sends AP information
|
||||
*
|
||||
* @param netDeviceInfo AP information
|
||||
*
|
||||
* @note
|
||||
*/
|
||||
void (*onPhoneAPInfo)(const ECBTNetInfo* netDeviceInfo);
|
||||
|
||||
/**
|
||||
* @brief Called when mobile phone has a notification message.
|
||||
* @param notification
|
||||
*/
|
||||
void (*onPhoneNotification)(const ECPhoneNotification* notification);
|
||||
|
||||
/**
|
||||
* @brief Called when the phone app sends down HUD lane guidance Picture.
|
||||
* @param notification
|
||||
*/
|
||||
void (*onPhoneAppHUDLaneGuidancePicture)(const ECHudLaneGuidancePictureInfo * data);
|
||||
|
||||
/**
|
||||
* @brief Called when checkOTAUpdate was called, it will tell the result of checkOTAUpdate.
|
||||
*
|
||||
* @param downloadableSoftwares It pointer to a array of ECOTAUpdateSoftware, which is downloadable software.
|
||||
*
|
||||
* @param downloadableLength The length of the downloadable array, if downloadableLength < 0, means check occur error, downloadableLength is error value of ECOTAUpdateErrorCode.
|
||||
*
|
||||
* @param downloadedSoftwares It pointer to a array of ECOTAUpdateSoftware, which is downloaded software.
|
||||
*
|
||||
* @param downloadedLength The length of the downloaded array.
|
||||
*/
|
||||
void (*onOTAUpdateCheckResult)(const ECOTAUpdateSoftware* downloadableSoftwares, const int32_t downloadableLength, const ECOTAUpdateSoftware* downloadedSoftwares, const uint32_t downloadedLength);
|
||||
|
||||
/**
|
||||
* @brief Called when remote downloadable software has been downloaded to phone.
|
||||
*
|
||||
* @param downloadableSoftwares It pointer to a array of ECOTAUpdateSoftware, which has been in phone, can be downloaded from phone to HU.
|
||||
*
|
||||
* @param downloadableLength The length of the downloadable array.
|
||||
*/
|
||||
void (*onOTAUpdateRequestDownload)(const ECOTAUpdateSoftware* downloadableSoftwares, const uint32_t downloadableLength);
|
||||
|
||||
/**
|
||||
* @brief Called when startOTAUpdate is called, it will notify the progress of downloading.
|
||||
*
|
||||
* @param downloadingSoftwareId The id of the downloading software.
|
||||
*
|
||||
* @param progress The progress of the downloading software,which is a percentage.
|
||||
*
|
||||
* @param softwareLeftTime The left time of the downloading software.
|
||||
*
|
||||
* @param otaLeftTime The left time of all the specified software by startOTAUpdate.
|
||||
*/
|
||||
void (*onOTAUpdateProgress)(const char* downloadingSoftwareId, float progress, uint32_t softwareLeftTime, uint32_t otaLeftTime);
|
||||
|
||||
/**
|
||||
* @brief Called when startOTAUpdate is called, it will notify software is downloaded.
|
||||
*
|
||||
* @param downloadedSoftwareId The id of the downloaded software.
|
||||
*
|
||||
* @param md5Path The md5 file path.
|
||||
*
|
||||
* @param packagePath The software path.
|
||||
*
|
||||
* @param iconPath The icon path.
|
||||
*
|
||||
* @param leftSoftwareNum The amount of software remaining to be downloaded.
|
||||
*/
|
||||
void (*onOTAUpdateCompleted)(const char* downloadedSoftwareId, const char* md5Path, const char* packagePath, const char* iconPath, uint32_t leftSoftwareNum);
|
||||
|
||||
/**
|
||||
* @brief Called when checkOTAUpdate or startOTAUpdate failed.
|
||||
*
|
||||
* @param errCode error code, see ECOTAUpdateErrorCode.
|
||||
*
|
||||
* @param softwarId the id of software.
|
||||
*/
|
||||
void (*onOTAUpdateError)(int32_t errCode, const char* softwareId);
|
||||
|
||||
} IECCallBack;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*size)(const char* name);
|
||||
int32_t (*read)(const char* name,void *data, uint32_t length, uint32_t offset);
|
||||
int32_t (*write)(const char* name,void *data, uint32_t length, uint32_t offset);
|
||||
void (*clear)(const char* name);
|
||||
}IECAccessFile;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(void *data, uint32_t length);
|
||||
int32_t (*write)(void *data, uint32_t length);
|
||||
void (*close)();
|
||||
}IECAccessDevice;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t (*registHid)(uint32_t deviceId,uint32_t descriptorSize);
|
||||
void (*unRegistHid)(uint32_t deviceId);
|
||||
uint32_t (*sendHiDDescriptor)(uint32_t deviceId, const unsigned char* descriptor, uint32_t len);
|
||||
uint32_t (*sendHidEvent)(uint32_t deviceId, const unsigned char* event, uint32_t len);
|
||||
}IECHidAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*open)();
|
||||
int32_t (*read)(uint8_t* data, uint32_t len);
|
||||
int32_t (*write)(const uint8_t* data, uint32_t len);
|
||||
int32_t (*close)();
|
||||
}IECBTAccessDev;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(int32_t width, int32_t height);
|
||||
void (*stop)();
|
||||
void (*play)(const void *data, uint32_t len);
|
||||
}IECVideoPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void (*start)(ECAudioType type, const ECAudioInfo *info);
|
||||
void (*stop)(ECAudioType type);
|
||||
void (*play)(ECAudioType type, const void *data, uint32_t len);
|
||||
void (*setVolume)(ECAudioType type, uint32_t vol);
|
||||
}IECAudioPlayer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t (*start)(const ECAudioInfo *info);
|
||||
void (*stop)();
|
||||
int32_t (*record)(void *data, uint32_t len);
|
||||
}IECAudioRecorder;
|
||||
|
||||
typedef void *ECConfigHandle;
|
||||
|
||||
ECConfigHandle EC_createECConfig();
|
||||
void EC_destroyECConfig(ECConfigHandle config);
|
||||
void EC_setBaseConfig(ECConfigHandle config,const char *uuid, const char *version,const char *writableDir);
|
||||
void EC_setCommonConfig(ECConfigHandle config, const char *cfgName, const char *value);
|
||||
/**
|
||||
* @brief 设置 ECTiny 连接的app版本
|
||||
* @param type 0:国内版; 1:海外版
|
||||
*/
|
||||
void EC_setLinkPhoneApp(ECConfigHandle config,int32_t type);
|
||||
void EC_setCommonConfig1(ECConfigHandle config, const char *cfgName, int32_t value);
|
||||
// This function must be called after the EC_start() function.
|
||||
int32_t EC_resetECConfig(const char* config);
|
||||
|
||||
/**
|
||||
* @brief ECTiny 初始化函数
|
||||
* @param config 项目配置
|
||||
* @param listener 回调接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必调用的接口。
|
||||
* 1.除了调用 EC_setBaseConfig() 设置基本的运行配置之外,config 一般不需要额外配置。
|
||||
* 2.listener 的生命周期大于 ECTiny 生命周期。即 listener 在 EC_initialize() 调用前就需要初始化,EC_release()之后才可以释放。
|
||||
*/
|
||||
int32_t EC_initialize(ECConfigHandle config, IECCallBack *listener);
|
||||
|
||||
/**
|
||||
* @brief ECTiny 释放函数
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此函数调用后,后面声明的函数调用都会失效。
|
||||
* 没有互联时,ECTiny线程处于block或者waiting状态,占用系统资源不多,所以ECTiny的一般使用场景不需要调用此函数。
|
||||
*/
|
||||
int32_t EC_release();
|
||||
|
||||
/**
|
||||
* @brief 设置ECTiny日志
|
||||
* @param level 日志级别。调试时设置成:EC_LOG_LEVEL_ALL,生产时设置成:EC_LOG_LEVEL_ERROR或者其他高级别
|
||||
* @param type 日志输出类型,设置成 EC_LOG_OUT_STD标准输出。其余类型暂不支持。
|
||||
* @param logDirectory 日志保存位置,暂不支持
|
||||
* @param module 日志模块,通常设置成:EC_LOG_MODULE_SDK | EC_LOG_MODULE_APP
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必调用的接口。
|
||||
*/
|
||||
int32_t EC_setLogInfo(const ECLogLevel level,const ECLogOutputType type,const char *logDirectory, int32_t module);
|
||||
|
||||
/**
|
||||
* @return 获取 ECTiny 版本号
|
||||
*/
|
||||
const char* EC_getVersion();
|
||||
|
||||
/**
|
||||
* @return 获取 ECTiny 升级版本号
|
||||
*/
|
||||
int32_t EC_getVersionCode();
|
||||
|
||||
/**
|
||||
* @brief 开启互联服务
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必调用的接口。
|
||||
*/
|
||||
int32_t EC_start();
|
||||
|
||||
/**
|
||||
* @brief 停止互联服务
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 没有投屏的情况下, ECTiny线程出于阻塞状态,占用的系统资源很少。
|
||||
* 一般使用场景,调用 EC_start() 之后,不需要调用 EC_stop()。
|
||||
*/
|
||||
int32_t EC_stop();
|
||||
|
||||
/**
|
||||
* @brief 绑定文件读写设备
|
||||
* @param handle 文件操作接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 对于某些 RTOS 系统,没有标准的文件操作接口,因此需要实现此接口,把基本文件操作的接口传给 ECTiny。
|
||||
* ECTiny会使用此接口读写license和OTA。
|
||||
*/
|
||||
int32_t EC_bindAccessFile(IECAccessFile *handle);
|
||||
|
||||
/**
|
||||
* @brief 绑定usb设备
|
||||
* @param type 互联类型
|
||||
* @param dev usb设备操作接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 绑定usb设备读写操作,用于实现usb互联。
|
||||
* @see EC_unbindDevice()
|
||||
*/
|
||||
int32_t EC_bindUSBDevice(ECTransportType type, IECAccessDevice *dev);
|
||||
|
||||
/**
|
||||
* @brief 绑定wifi互联ip
|
||||
* @param type 互联类型
|
||||
* @param ip 对端ip地址
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此函数调用之后, ECTiny会直接连接ip,进行互联。
|
||||
* @see EC_unbindDevice()
|
||||
*/
|
||||
int32_t EC_bindWIFIDevice(ECTransportType type, const char *ip);
|
||||
|
||||
/**
|
||||
* @brief 释放绑定的设备
|
||||
* @param type 互联类型
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此函数与 EC_bindUSBDevice(),EC_bindWIFIDevice(),有绑定与解绑定关系。
|
||||
*/
|
||||
int32_t EC_unbindDevice(ECTransportType type);
|
||||
|
||||
/**
|
||||
* @brief 绑定HID设备
|
||||
* @param dev HID设备
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @see EC_unBindHidDevice()
|
||||
*/
|
||||
int32_t EC_bindHidDevice(IECHidAccessDev* dev);
|
||||
|
||||
/**
|
||||
* @brief 解除HID设备绑定
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @see EC_bindHidDevice()
|
||||
*/
|
||||
int32_t EC_unBindHidDevice();
|
||||
|
||||
/**
|
||||
* @brief 绑定蓝牙ble设备操作接口
|
||||
* @param ioHandle 蓝牙ble设备操作接口
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口用于BLE组网方式的互联。
|
||||
* @see EC_unBindBTDevice()
|
||||
*/
|
||||
int32_t EC_bindBTDevice( IECAccessDevice* ioHandle);
|
||||
|
||||
/**
|
||||
* @brief 蓝牙ble设备解绑定
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @see EC_bindBTDevice()
|
||||
*/
|
||||
int32_t EC_unBindBTDevice();
|
||||
|
||||
/**
|
||||
* @brief 设置投屏参数
|
||||
* @param mirrorCfg 投屏参数
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必执行的接口。
|
||||
*/
|
||||
int32_t EC_setMirrorConfig(const ECMirrorConfig *mirrorCfg);
|
||||
|
||||
/**
|
||||
* @brief 设置解码显示设备
|
||||
* @param video 解码显示器
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 解码显示器 IECVideoPlayer 通过此接口注册给 ECTiny之后,由 ECTiny主动调用解码器的开始和停止。
|
||||
*/
|
||||
int32_t EC_setVideoPlayer(IECVideoPlayer* video);
|
||||
|
||||
/**
|
||||
* @brief 设置音频播放器
|
||||
* @param audio 音频播放器
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 声音数据走usb或者wifi时才需要设置此接口。一般项目声音都是走蓝牙a2dp,不需要设置此接口。
|
||||
*/
|
||||
int32_t EC_setAudioPlayer(IECAudioPlayer* audio);
|
||||
|
||||
/**
|
||||
* @brief 设置录音设备
|
||||
* @param audioRecorde 录音设备
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 需要手机app回声降噪的项目才需要设置此接口。
|
||||
*/
|
||||
int32_t EC_setAudioRecorder(IECAudioRecorder* audioRecorde);
|
||||
|
||||
/**
|
||||
* @brief 仪表wifi状态通知接口
|
||||
* @param action 仪表wifi模式:ap/sta。 目前此值不做要求,填写此枚举任意值即可
|
||||
* @param netInfo 网络状态。ECNetWorkInfo::state 必须填写,其余字段不需要填。
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 仪表/车机wifi发生变化时,通过此接口通知给 ECTiny。wifi连接,此接口必调用
|
||||
*/
|
||||
int32_t EC_notifyWifiStateChanged(ECWifiStateAction action, const ECNetWorkInfo* netInfo);
|
||||
|
||||
/**
|
||||
* @brief 请求组网接口
|
||||
* @param phoneID 手机id
|
||||
* @param rly 组网信息
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有BLE组网的连接方式,才用到此接口。
|
||||
*/
|
||||
int32_t EC_setRequestBuildNetRly(const char *phoneID, const ECBTRequestBuildNetRly *rly);
|
||||
|
||||
/**
|
||||
* @brief 仪表ip地址上报给手机
|
||||
* @param info 仪表网络信息
|
||||
* @param num 仪表网络信息数量
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有BLE组网的连接方式,才用到此接口。
|
||||
*/
|
||||
int32_t EC_setNetInterfaceInfo(const ECNetInterfaceInfo *info,const int32_t num);
|
||||
|
||||
/**
|
||||
* @brief 开始投屏
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口为互联必执行的接口。
|
||||
* 此接口调用后,手机app会把 H264 数据发送给 ECTiny。 ECTiny会自动调用 IECVideoPlayer 解码器解码显示。
|
||||
* onECConnectStatus 回调函数,status==EC_CONNECT_STATUS_CONNECT_SUCCEED 时才可以调用此接口,否则无效。
|
||||
* @see EC_stopMirror()
|
||||
*/
|
||||
int32_t EC_startMirror();
|
||||
|
||||
/**
|
||||
* @brief 停止投屏
|
||||
* @note 此接口为互联必执行的接口。
|
||||
* @see EC_startMirror()
|
||||
*/
|
||||
void EC_stopMirror();
|
||||
|
||||
/**
|
||||
* @brief 暂停/开启 投屏
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 目前不调用。调用 EC_startMirror()/EC_stopMirror()
|
||||
*/
|
||||
int32_t EC_pauseMirror();
|
||||
int32_t EC_resumeMirror();
|
||||
|
||||
/**
|
||||
* @brief 发送触控消息
|
||||
* @param touch 触控数据
|
||||
* @param type 触控类型
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 发送仪表/车机屏幕的触控消息给手机app,互联程序会映射到手机的坐标,让手机app做出响应。
|
||||
*/
|
||||
int32_t EC_sendTouchEvent(const ECTouchEventData *touch, ECTouchEventType type);
|
||||
|
||||
/**
|
||||
* @brief 发送按键消息
|
||||
* @param btnCode 按键键值,取值于:ECBtnCode
|
||||
* @param type 按键类型,取值与:ECBtnEventType
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 发送按键消息给手机app,让手机作出响应。
|
||||
*/
|
||||
int32_t EC_sendBtnEvent(int32_t btnCode, int32_t type);
|
||||
|
||||
/**
|
||||
* @brief 结束手机导航
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_stopPhoneNavigation();
|
||||
|
||||
/**
|
||||
* @brief 结束手机vr语音
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_stopPhoneVR();
|
||||
|
||||
/**
|
||||
* @brief 上传汽车的夜间模式信息到手机
|
||||
* @param isNightModeOn 1:夜间模式; 0: 非夜间模式
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 手机app的显示模式设置为自动时,此接口才能让手机app响应
|
||||
*/
|
||||
int32_t EC_uploadNightModeStatus(uint32_t isNightModeOn);
|
||||
|
||||
/**
|
||||
* @brief 上传汽车的驾驶信息到手机
|
||||
* @param status 驾驶状态
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_uploadDrivingStatus(ECDrivingStatus status);
|
||||
|
||||
/**
|
||||
* @brief 允许手机下发声音数据到仪表/车机
|
||||
* @param supportType 下载的声音类型,取值于 ECAudioType 类型,可以通过或运算下载多种声音
|
||||
* @param autoChangeToBT 是否启用蓝牙优先的策略,当蓝牙连接后,声音自动走蓝牙通道。
|
||||
* 也可通过该接口控制手机端蓝牙连接提示框的弹出,当该参数设置为false后,手机端不再弹出连接蓝牙提示框。
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有在连接层成功建立后,接口调用才能成功。参考 onECConnectStatus()
|
||||
* 该接口调用之后,手机app才会下传相应声音,停止音频下传接口为EC_disableDownloadPhoneAppAudio()
|
||||
*/
|
||||
int32_t EC_enableDownloadPhoneAppAudio(uint32_t supportType, uint32_t autoChangeToBT);
|
||||
|
||||
/**
|
||||
* @brief 停止手机下发声音数据
|
||||
*/
|
||||
void EC_disableDownloadPhoneAppAudio();
|
||||
|
||||
/**
|
||||
* @brief 允许手机下发HUD导航信息
|
||||
* @param supportFunction hud导航功能,取值于 ECAPPHUDSupportFunction 类型,可以通过或运算开启多种hud功能
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 只有在连接层成功建立后,接口调用才能成功。参考 onECConnectStatus()
|
||||
* 此接口调用一次即可生效
|
||||
*/
|
||||
int32_t EC_enableDownloadPhoneAppHud(uint32_t supportFunction);
|
||||
|
||||
/**
|
||||
* @brief 停止手机下发HUD导航信息
|
||||
*/
|
||||
void EC_disableDownloadPhoneAppHud();
|
||||
|
||||
/**
|
||||
* @brief 设置连接的蓝牙
|
||||
* @param carBtMac 车机自己的蓝牙地址
|
||||
* @param phoneBtMac 车机连接的蓝牙Mac地址
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
* @note 此接口的目的是用于对比手机和车机两者连接的蓝牙是不是对方。受限于手机系统限制,无法取得手机的蓝牙物理地址,目前此接口功能已经失效。
|
||||
*/
|
||||
int32_t EC_setConnectedBTAddress(const char *carBtMac, const char *phoneBtMac);
|
||||
|
||||
/**
|
||||
* @brief 发送车机的蓝牙信息给手机
|
||||
* @param name 蓝牙名称
|
||||
* @param adddress 蓝牙地址
|
||||
* @param pin 蓝牙pin码
|
||||
* @return EC_OK 为成功,其余值为失败。此返回值一般不处理
|
||||
*/
|
||||
int32_t EC_sendCarBluetooth(const char *name, const char *adddress, const char *pin);
|
||||
|
||||
/**
|
||||
* @brief 打开手机界面
|
||||
* @param page 快速访问手机APP的相关界面或功能,如导航、音乐、对讲等,具体取值参考:ECAppPage
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 该接口主要用于如下场景,譬如车机端系统桌面集成快捷按钮,可直达互联的指定页面。
|
||||
*/
|
||||
int32_t EC_openAppPage(int32_t page);
|
||||
|
||||
/**
|
||||
* @brief 查询GPS信息
|
||||
* @param status 当前的请求结果是否有效,0:无效;其余值有效
|
||||
* @param gps GPS信息
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 该接口主要用于车机需要使用到手机端GPS的场景,请求网络当前位置。
|
||||
*/
|
||||
int32_t EC_queryGPS(uint32_t* status, ECGPSInfo* gps);
|
||||
|
||||
/**
|
||||
* @brief 查询手机时间
|
||||
* @param gmtTime 返回GMT(UTC)时间,单位毫秒。
|
||||
* @param localTime 返回当前时区的时间,单位毫秒
|
||||
* @param timeZone 返回当前的时区的字符串。
|
||||
* @param len 当前时区字符串的长度
|
||||
* @param dateTime 返回手机app当前时间字符串
|
||||
* @param dateTimeLen 手机app当前时间字符串长度
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 由于GMT时间涉及到系统函数和时区的计算,建议直接使用后两个参数获取当前时间字符串,然后解析字符串获取到时间
|
||||
*/
|
||||
int32_t EC_queryTime(uint64_t *gmtTime, uint64_t *localTime, char *timeZone, uint32_t len, char* dateTime, uint32_t dateTimeLen);
|
||||
|
||||
/**
|
||||
* @brief 同步车机状态到手机
|
||||
* @param carStatus 车机状态类型
|
||||
* @param value 部分status需要携带状态值
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 部分场景下,需要将车机的部分状态信息通知到手机APP,手机APP需要根据状态做互联的相关逻辑处理。
|
||||
* 如手机APP可根据行车状态,在不同的地区做不同的使用限制。该接口主要用于行车模式功能等功能。
|
||||
*/
|
||||
int32_t EC_sendCarStatus(ECCarStatusType carStatus, ECCarStatusValue value);
|
||||
|
||||
/**
|
||||
* @brief 注册控车指令
|
||||
* @param carCmds 控车指令
|
||||
* .type : 指令类型,是一个全局指令或是一个和页面绑定的指令,见枚举 ECCarCmdEFFECTType 。
|
||||
* .id : 指令id,每个需要识别的指令,都有一个唯一的标识。
|
||||
* .cmd : 期望语音识别的指令,当时一个全局指令时,可以是正则表达式;如"(打开|开启)空调",等价于"打开空调" ,"开启空调";而当是一个和页面绑定的指令词,不支持正则表达式,仅支持明确的指令,如"放大地图"。
|
||||
* .vrText : 当前成功匹配的语义,仅用于当 IECCallback::onCarCmdNotified 回调时,可根据匹配的内容处理相关的动作。
|
||||
* .pauseMusic : 该参数仅用于 ECSDK::registerCarCmds ,告知手机如果触发语音识别时,是否需要暂停当前正在播放的音乐。
|
||||
* .responser : 语音指令执行的结果是由车机端播报,还是由手机端播报。0 车机端播报,1,手机端播报。
|
||||
* .thresholdLevel : 可选项,默认值为0,由手机端指定默认的门限值, 范围参考值 1~9999,识别门限值,值越大识别率越低,误唤醒率越低,开发者在使用语音识别功能时,可在项目中调试设置合适的值。该参数仅在 type= EC_CAR_CMD_TYPE_EFFECTIVE_PAGE 生效;
|
||||
* @param length 注册的指令列表的长度。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 当发起语音识别后,通过手机端的VR引擎识别后,会转化后具体的指令,通过回调接口 IECCallback::onCarCmdNotified 响应,须在此进行相关处理。
|
||||
*/
|
||||
int32_t EC_registerCarCmds(const ECCarCmd *carCmds, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief 播放指定的文字
|
||||
* @param text 文字信息
|
||||
* @param level 优先级,0~10,优先级越高,被播放的优先级也越高。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 与手机的通讯建立成功后,把需要播报的文字传输至手机APP。
|
||||
* 如果车机端配置了 ECSDK::enableDownloadPhoneAppAudio 通过车机端播放手机APP音频,此时音频将以TTS类型,通过USB/wifi传输车机端。
|
||||
*/
|
||||
int32_t EC_playCarTTS(const char *text, uint32_t level);
|
||||
|
||||
/**
|
||||
* @brief 注册近似指令
|
||||
* @param data 需要注册的近音词组,数据格式为JSON格式字符串
|
||||
* {
|
||||
* words:
|
||||
* [
|
||||
* ["词1", ..., "词m"], ///< 数据类型为string数组,近音词集合,数组中的第一个词为显示词。
|
||||
* ...
|
||||
* ["词a", ..., "词n"] ///< 数据类型为string数组,近音词集合,数组中的第一个词为显示词。
|
||||
* ]
|
||||
* }
|
||||
* @param length 注册的指令Json字符串的长度。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 该接口主要是对 EC_registerCarCmds() 接口的补充,常见使用场景提高语音控车指令的准确度,如“上身车窗”、“上升车窗”可以正确的被识别为同一个含义。
|
||||
*/
|
||||
int32_t EC_registerSimilarSoundingWords(const char *data, uint32_t length);
|
||||
|
||||
/**
|
||||
* @brief 发送给手机端当前已输入的文字
|
||||
* @param text 当前输入的车机端文字
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 此函数用于车机键盘输入功能
|
||||
*/
|
||||
int32_t EC_sendInputText(const char* text);
|
||||
|
||||
/**
|
||||
* @brief 发送给手机端键盘按键事件
|
||||
* @param actionId 当前输入的动作
|
||||
* @param keyCode 键值
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 如车机端输入法点击Enter键,此时需把事件发送给手机端。所有keycode及ActionId对安卓手机都有效;
|
||||
* 苹果手机仅响应actionid=0 keycode=4,苹果手机处理为隐藏手机端输入法,并把输入状态置为inActive状态。
|
||||
* 此函数用于车机键盘输入功能
|
||||
*/
|
||||
int32_t EC_sendInputAction(int32_t actionId, int32_t keyCode);
|
||||
|
||||
/**
|
||||
* @brief 发送给手机端当前光标位置及选中状态
|
||||
* @param start 光标开始的位置。
|
||||
* @param stop 光标结束的位置。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 如果车机端的光标产生变化,需把对应状态发送至手机端同步。仅对安卓手机有效,苹果手机互联无此回调。
|
||||
* 此函数用于车机键盘输入功能
|
||||
*/
|
||||
int32_t EC_sendInputSelection(int32_t start, int32_t stop);
|
||||
|
||||
/**
|
||||
* @brief 获取快捷方式列表信息
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note ECTiny与手机app传输建立之后。通过 IECCallback::onPageListReceived 回调接口完快捷方式列表信息的接收。
|
||||
*/
|
||||
int32_t EC_queryPageList();
|
||||
|
||||
/**
|
||||
* @brief 获取快捷方式图标资源
|
||||
* @param pages 待请求的page编号的数组,通过 EC_queryPageList 获取。
|
||||
* @param length page编号的数组长度。
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note ECTiny与手机app传输建立之后。通过 IECCallback::onPageIconReceived 回调接口完快捷方式图标资源的的接收。
|
||||
* 为了避免重复的请求,占用带宽资源,以及做到车机端的快捷方式快速显示;车机端系统需要做好缓存策略,对icon的资源信息做到增量更新:
|
||||
* 通过每次互联后 EC_queryPageList 获取最新的列表信息,然后比对车机端缓存的列表信息,仅对增量的资源进行请求更新;
|
||||
*/
|
||||
int32_t EC_queryPageIcon(int32_t* pages, int32_t length);
|
||||
|
||||
/**
|
||||
* @brief 查询天气
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 查询结果通过 IECCallback::onWeatherReceived 回调函数返回
|
||||
*/
|
||||
int32_t EC_queryWeather();
|
||||
|
||||
/**
|
||||
* @brief 车机端语音提醒轮播
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
* @note 在使用车机端本地语音助手时,一般需要有一些常驻提示类的使用帮助,这些文字主要通过手机端传输至车机端,由车机端系统完成展示。
|
||||
*/
|
||||
int32_t EC_queryVRTips();
|
||||
|
||||
/**
|
||||
* @brief 生成二维码url
|
||||
* @param info 二维码信息
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
const char* EC_generateQRCodeUrl(ECQRInfo* info);
|
||||
|
||||
/**
|
||||
* @brief 允许手机下发手机消息
|
||||
* @param enable 0:禁止; 1:允许
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
int32_t EC_requestPhoneNotification(int32_t enable);
|
||||
|
||||
/**
|
||||
* @brief 检测OTA升级
|
||||
* @param cfg ota配置
|
||||
* @param language 语言
|
||||
* @param mode ota升级模式
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
int32_t EC_checkOTAUpdate(const ECOTAConfig* cfg, const ECLanguage language, const ECOTAUpdateCheckMode mode);
|
||||
|
||||
/**
|
||||
* @brief 开始OTA升级
|
||||
* @param softwareIds 需要升级的软件id
|
||||
* @param softwareNum 需要升级的软件id数量
|
||||
* @return EC_OK 为成功,其余值为失败。
|
||||
*/
|
||||
int32_t EC_startOTAUpdate(const char** softwareIds, const int32_t softwareNum);
|
||||
|
||||
/**
|
||||
* @brief 停止OTA升级
|
||||
*/
|
||||
void EC_stopOTAUpdate();
|
||||
|
||||
/**
|
||||
* @brief 开启iperf服务端
|
||||
* @param ip
|
||||
* @param port
|
||||
* @return
|
||||
* @note 简单实现的iperf功能。车机/仪表进行iperf测试时,建议使用标准iperf
|
||||
*/
|
||||
int32_t EC_startIperfTcpServer(const char* ip, int port);
|
||||
void EC_stopIperfTcpServer();
|
||||
#endif
|
||||
|
1525
MXC_A27-PCB4.5-270T/app/carlink/EC/include/ECTypes.h
Normal file
BIN
MXC_A27-PCB4.5-270T/app/carlink/EC/lib/ECTiny.a
Normal file
BIN
MXC_A27-PCB4.5-270T/app/carlink/EC/lib/ECTiny_old.a
Normal file
1333
MXC_A27-PCB4.5-270T/app/carlink/EC/src/__carlink_ec.c
Normal file
607
MXC_A27-PCB4.5-270T/app/carlink/EC/src/carlink_ec.c
Normal file
@ -0,0 +1,607 @@
|
||||
#include "carlink_ec.h"
|
||||
#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "sfud.h"
|
||||
#include "carlink_common.h"
|
||||
#include "carlink_video.h"
|
||||
|
||||
//不支持ble组网
|
||||
|
||||
#if CARLINK_EC
|
||||
#include "ECTiny.h"
|
||||
#include "ECTypes.h"
|
||||
|
||||
#define ENABLE_EC_DASHCAM 0
|
||||
|
||||
#define printf_func printf
|
||||
|
||||
#define FLASH_PRIV_TYPE_BYTE 0x1000
|
||||
#define EC_FLASH_OFFSET 0X38000
|
||||
|
||||
|
||||
static bool mInited = false;
|
||||
static ECConfigHandle mECTinyCfg = NULL;
|
||||
static IECCallBack* mECTinyCallback = NULL;
|
||||
static IECVideoPlayer* mECTinyVideoPlayer = NULL;
|
||||
static IECAccessFile accessFile;
|
||||
static ECQRInfo qr_info;
|
||||
extern int wps_connect_done;
|
||||
static bool g_ec_disable = false;
|
||||
|
||||
#if ENABLE_EC_DASHCAM
|
||||
int start_http_camera();
|
||||
void stop_http_camera();
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void ec_notify_event(struct carlink_event *ev, enum CARLINK_EVENT_TYPE type, bool disable_filter)
|
||||
{
|
||||
ev->link_type = CARLINK_ECLINK_WIRELESS;
|
||||
ev->disable_filter = disable_filter;
|
||||
ev->type = type;
|
||||
carlink_notify_event(ev);
|
||||
}
|
||||
#endif
|
||||
|
||||
void onECConnectStatus(ECConnectedStatus status, ECConnectedType type)
|
||||
{
|
||||
printf("\r\nite onECConnectStatus:status=%d,type=%d", status, type);
|
||||
if (status == EC_CONNECT_STATUS_CONNECT_SUCCEED)
|
||||
{
|
||||
//EC_uploadNightModeStatus(gDayNight);
|
||||
EC_startMirror();
|
||||
|
||||
//EC_startIperfTcpServer("192.168.43.103",11150);
|
||||
}
|
||||
}
|
||||
|
||||
void onMirrorStatus(ECMirrorStatus status)
|
||||
{
|
||||
printf("\r\nonMirrorStatus:status=%d\r\n", status);
|
||||
|
||||
#if ENABLE_EC_DASHCAM
|
||||
if (status == EC_MIRROR_STATUS_MIRROR_STARTED)
|
||||
start_http_camera();
|
||||
#endif
|
||||
}
|
||||
|
||||
void onECStatusMessage(ECStatusMessage status)
|
||||
{
|
||||
printf("\r\nITE onECStatusMessage:status=%d\r\n", status);
|
||||
}
|
||||
|
||||
void onPhoneAppHUD(const ECNavigationHudInfo *data)
|
||||
{
|
||||
printf("\r\nECNavigationHudInfo\r\n");
|
||||
}
|
||||
|
||||
void onPhoneAppMusicInfo(const ECAppMusicInfo *data)
|
||||
{
|
||||
printf("\r\nonPhoneAppMusicInfo\r\n");
|
||||
}
|
||||
|
||||
void onPhoneAppInfo(const void *data, uint32_t length)
|
||||
{
|
||||
printf("\r\nonPhoneAppInfo\r\n");
|
||||
}
|
||||
|
||||
void onCallAction(ECCallType type, const char *name, const char *number)
|
||||
{
|
||||
printf("\r\nonCallAction\r\n");
|
||||
}
|
||||
|
||||
void onBulkDataReceived(const void *data, uint32_t length)
|
||||
{
|
||||
printf("onBulkDataReceived\r\n");
|
||||
}
|
||||
|
||||
void onMirrorInfoChanged(const ECVideoInfo *info)
|
||||
{
|
||||
printf("\r\nonMirrorInfoChanged\r\n");
|
||||
}
|
||||
|
||||
void onLicenseAuthFail(int32_t errCode, const char *errMsg)
|
||||
{
|
||||
Set_sys_uuid_state(0);
|
||||
printf("\r\nonLicenseAuthFail\r\n");
|
||||
}
|
||||
|
||||
void onLicenseAuthSuccess(int32_t code, const char *msg)
|
||||
{
|
||||
Set_sys_uuid_state(1);
|
||||
printf("\r\nonLicenseAuthSuccess\r\n");
|
||||
}
|
||||
|
||||
void onCarCmdNotified(const ECCarCmd *carCmd)
|
||||
{
|
||||
printf("\r\nonCarCmdNotified\r\n");
|
||||
}
|
||||
|
||||
void onInputStart(const ECInputInfo *info)
|
||||
{
|
||||
printf("\r\nonInputStart\r\n");
|
||||
}
|
||||
|
||||
void onInputCancel()
|
||||
{
|
||||
printf("\r\nonInputCancel\r\n");
|
||||
}
|
||||
|
||||
void onInputSelection(int32_t start, int32_t stop)
|
||||
{
|
||||
printf("\r\nonInputSelection\r\n");
|
||||
}
|
||||
|
||||
void onInputText(const char *text)
|
||||
{
|
||||
printf("\r\nonInputText\r\n");
|
||||
}
|
||||
|
||||
void onVRTextReceived(const ECVRTextInfo *info)
|
||||
{
|
||||
printf("\r\nonVRTextReceived\r\n");
|
||||
}
|
||||
|
||||
void onPageListReceived(const ECPageInfo *pages, int32_t length)
|
||||
{
|
||||
printf("\r\nonPageListReceived\r\n");
|
||||
}
|
||||
|
||||
void onPageIconReceived(const ECIconInfo *icons, int32_t length)
|
||||
{
|
||||
printf("\r\nonPageIconReceived\r\n");
|
||||
}
|
||||
|
||||
void onWeatherReceived(const char *data, int32_t length)
|
||||
{
|
||||
printf("\r\nonWeatherReceived\r\n");
|
||||
|
||||
}
|
||||
|
||||
void onVRTipsReceived(const char *data, int32_t length)
|
||||
{
|
||||
printf("\r\nonVRTipsReceived\r\n");
|
||||
}
|
||||
|
||||
void onRequestBuildNet(const ECBTClientInfo *clientInfo)
|
||||
{
|
||||
printf("onRequestBuildNet-----------------------\r\n");
|
||||
printf("TRACE[%s][%d]:",__func__ ,__LINE__);
|
||||
ECBTRequestBuildNetRly rpy;
|
||||
memset((void *)&rpy.netDeviceInfo, 0, sizeof(rpy.netDeviceInfo));
|
||||
printf("packageName %s\r\n", clientInfo->packageName);
|
||||
printf("phoneName %s\r\n", clientInfo->phoneName);
|
||||
printf("phoneID %s\r\n", clientInfo->phoneID);
|
||||
printf("phoneType %d\r\n", clientInfo->phoneType);
|
||||
printf("version %d\r\n", clientInfo->version);
|
||||
printf("TRACE[%s][%d]:",__func__ ,__LINE__);
|
||||
}
|
||||
|
||||
|
||||
void onRequestBuildNetCancel()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void onPhoneBuildNetFinish()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void onPhoneAPInfo(const ECBTNetInfo* netDeviceInfo)
|
||||
{
|
||||
printf("------ onPhoneAPInfo ------\r\n");
|
||||
printf("onPhoneAPInfo ssid=[%s]\r\n",netDeviceInfo->ssid);
|
||||
printf("onPhoneAPInfo pwd=[%s]\r\n",netDeviceInfo->pwd);
|
||||
printf("onPhoneAPInfo auth=[%s]\r\n",netDeviceInfo->auth);
|
||||
printf("onPhoneAPInfo mac=[%s]\r\n",netDeviceInfo->mac);
|
||||
printf("onPhoneAPInfo name=[%s]\r\n",netDeviceInfo->name);
|
||||
printf("onPhoneAPInfo action=[%u]\r\n",netDeviceInfo->action);
|
||||
printf("------ onPhoneAPInfo ------\r\n");
|
||||
}
|
||||
|
||||
|
||||
IECCallBack * registerECCallback()
|
||||
{
|
||||
IECCallBack * callBack = (IECCallBack*)malloc(sizeof(IECCallBack));
|
||||
memset(callBack, 0, sizeof(IECCallBack));
|
||||
callBack->onECConnectStatus = onECConnectStatus;
|
||||
callBack->onMirrorStatus = onMirrorStatus;
|
||||
callBack->onECStatusMessage = onECStatusMessage;
|
||||
callBack->onPhoneAppHUD = onPhoneAppHUD;
|
||||
callBack->onPhoneAppInfo = onPhoneAppInfo;
|
||||
callBack->onPhoneAppMusicInfo = onPhoneAppMusicInfo;
|
||||
callBack->onCallAction = onCallAction;
|
||||
callBack->onBulkDataReceived = onBulkDataReceived;
|
||||
callBack->onMirrorInfoChanged = onMirrorInfoChanged;
|
||||
callBack->onLicenseAuthFail = onLicenseAuthFail;
|
||||
callBack->onLicenseAuthSuccess = onLicenseAuthSuccess;
|
||||
callBack->onCarCmdNotified = onCarCmdNotified;
|
||||
callBack->onInputStart = onInputStart;
|
||||
callBack->onInputCancel = onInputCancel;
|
||||
callBack->onInputSelection = onInputSelection;
|
||||
callBack->onInputText = onInputText;
|
||||
callBack->onVRTextReceived = onVRTextReceived;
|
||||
callBack->onPageListReceived = onPageListReceived;
|
||||
callBack->onPageIconReceived = onPageIconReceived;
|
||||
callBack->onWeatherReceived = onWeatherReceived;
|
||||
callBack->onVRTipsReceived = onVRTipsReceived;
|
||||
callBack->onRequestBuildNet = onRequestBuildNet;
|
||||
callBack->onRequestBuildNetCancel = onRequestBuildNetCancel;
|
||||
callBack->onPhoneBuildNetFinish = onPhoneBuildNetFinish;
|
||||
callBack->onPhoneAPInfo = onPhoneAPInfo;
|
||||
|
||||
return callBack;
|
||||
}
|
||||
void unregisterECCallback(IECCallBack * callBack)
|
||||
{
|
||||
if (callBack)
|
||||
{
|
||||
free(callBack);
|
||||
callBack = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//static uint32_t gts = 0;
|
||||
// video player begin
|
||||
void vp_start(int32_t width, int32_t height)
|
||||
{
|
||||
printf("\r\nstart VideoPlayer,width=%d,height=%d\r\n", width, height);
|
||||
|
||||
h264_dec_ctx_init();
|
||||
//gts = get_timer(0);
|
||||
set_carlink_display_state(1);
|
||||
}
|
||||
|
||||
void vp_stop()
|
||||
{
|
||||
//video_frame_s* frame = NULL;
|
||||
printf("\r\nstop VideoPlayer\r\n");
|
||||
|
||||
set_carlink_display_state(0);
|
||||
}
|
||||
|
||||
void vp_play(const void *data, uint32_t read_len)
|
||||
{
|
||||
//printf("\r\nplay VideoPlayer len = %d ts:%d ms\r\n", read_len, (get_timer(0) -gts) / 1000);
|
||||
//gts = get_timer(0);
|
||||
video_frame_s* frame = NULL;
|
||||
|
||||
get_retry:
|
||||
frame = get_h264_frame_buf();
|
||||
if (NULL == frame) {
|
||||
//printf("h264 frame is empty\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
goto get_retry;
|
||||
//continue;
|
||||
}
|
||||
|
||||
memcpy(frame->cur, data, read_len);
|
||||
frame->len = read_len;
|
||||
|
||||
notify_h264_frame_ready(&frame);
|
||||
}
|
||||
|
||||
IECVideoPlayer * registerVideoPlayer()
|
||||
{
|
||||
IECVideoPlayer* videoPlayer = (IECVideoPlayer*)malloc(sizeof(IECVideoPlayer));
|
||||
videoPlayer->start = vp_start;
|
||||
videoPlayer->stop = vp_stop;
|
||||
videoPlayer->play = vp_play;
|
||||
|
||||
return videoPlayer;
|
||||
}
|
||||
|
||||
void unregisterVideoPlayer(IECVideoPlayer* player)
|
||||
{
|
||||
if (player)
|
||||
{
|
||||
player->stop();
|
||||
|
||||
free(player);
|
||||
player = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ec_access_size(const char* name)
|
||||
{
|
||||
printf_func("TRACE[%s][%d]:name=%s\r\n",__func__ ,__LINE__,name);
|
||||
|
||||
int32_t ret = 0;
|
||||
char num[5] = {0};
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
if( SFUD_SUCCESS == sfud_read(sflash, EC_FLASH_OFFSET, 4, (uint8_t *)num) )
|
||||
{
|
||||
ret = atoi(num);
|
||||
if (ret >= FLASH_PRIV_TYPE_BYTE)
|
||||
{
|
||||
printf_func("TRACE[%s][%d]:ec_access_size sfud_read error,clear name:%s ret:%d\r\n",__func__ ,__LINE__,name,ret);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
printf_func("TRACE[%s][%d]:name=[%s],ret=%d\r\n",__func__ ,__LINE__,name,ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t ec_access_read(const char* name,void *data, uint32_t length, uint32_t offset)
|
||||
{
|
||||
printf_func("TRACE[%s][%d]1:len=%d\r\n",
|
||||
__func__ ,__LINE__,length);
|
||||
|
||||
int32_t ret = 0;
|
||||
char num[5] = {0};
|
||||
uint8_t* readData = malloc(FLASH_PRIV_TYPE_BYTE);
|
||||
memset(readData,0,sizeof(FLASH_PRIV_TYPE_BYTE));
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
if( SFUD_SUCCESS == sfud_read(sflash, EC_FLASH_OFFSET, FLASH_PRIV_TYPE_BYTE, readData) )
|
||||
{
|
||||
memcpy(num,readData,4);
|
||||
ret = atoi(num);
|
||||
if(ret == length)
|
||||
{
|
||||
memcpy(data,readData+4,length);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf_func("TRACE[%s][%d]2:data=[%s],ret=%d\r\n",
|
||||
__func__ ,__LINE__,(char*)data,ret);
|
||||
|
||||
free(readData);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int32_t ec_access_write(const char* name,void *data, uint32_t length, uint32_t offset)
|
||||
{
|
||||
printf_func("TRACE[%s][%d]1:data=[%s],len=%d\r\n",
|
||||
__func__ ,__LINE__,(char*)data,length);
|
||||
|
||||
int32_t ret = 0;
|
||||
char* writeData = malloc(length+4);
|
||||
sprintf(writeData,"%04d%s",length, (char*)data);
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
sfud_erase(sflash, EC_FLASH_OFFSET, FLASH_PRIV_TYPE_BYTE);
|
||||
if( SFUD_SUCCESS == sfud_erase_write(sflash, EC_FLASH_OFFSET, length+4, (void*)writeData) )
|
||||
{
|
||||
ret = length;
|
||||
}
|
||||
|
||||
free(writeData);
|
||||
printf_func("TRACE[%s][%d]2:ret=%d\r\n",
|
||||
__func__ ,__LINE__,ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ec_access_clear(const char* name)
|
||||
{
|
||||
sfud_flash *sflash = sfud_get_device(0);
|
||||
sfud_erase(sflash, EC_FLASH_OFFSET, FLASH_PRIV_TYPE_BYTE);
|
||||
printf_func("TRACE[%s][%d]1:name=[%s]\r\n",
|
||||
__func__ ,__LINE__,name);
|
||||
}
|
||||
|
||||
static void onEventEC(void* ctx, const struct carlink_event *ev)
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
|
||||
if (NULL == ev)
|
||||
return;
|
||||
if (ev->link_type != CARLINK_ECLINK_WIRELESS && !ev->disable_filter)// skip not ec event
|
||||
return;
|
||||
|
||||
type = ev->type;
|
||||
|
||||
switch (type) {
|
||||
case -1: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_INIT_DONE:
|
||||
break;
|
||||
case CARLINK_EVENT_BT_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_AA_RFCOMM_READY: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_BT_DISCONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_WIFI_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_CONNECT: {
|
||||
break;
|
||||
}
|
||||
case CARLINK_EVENT_MSG_SESSION_STOP: {
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ec_ble_data_read(void* ctx, const void* buf, int len)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)buf;
|
||||
(void)len;
|
||||
}
|
||||
|
||||
|
||||
#if defined(AWTK)
|
||||
extern char strQrText[200];
|
||||
extern char UI_uuid[32];
|
||||
#else
|
||||
char strQrText[200];
|
||||
char key_value;
|
||||
#endif
|
||||
void* initECTiny(void* param)
|
||||
{
|
||||
char uuid[32] = {0};
|
||||
const char *bt_mac = carlink_get_bt_mac();
|
||||
|
||||
if (NULL == bt_mac) {
|
||||
printf("\r\n------ bt not ready ------\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mInited)
|
||||
{
|
||||
printf("\r\n------ ECTiny has inited ------\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf("\r\n-------- Sample begin----------\r\n");
|
||||
|
||||
printf("\r\n1.inti ECTiny config\r\n");
|
||||
mECTinyCfg = EC_createECConfig();
|
||||
|
||||
memset(&qr_info, 0, sizeof(ECQRInfo));
|
||||
qr_info.action = EC_QR_ACTION_WIFI_P2P_MODE | EC_QR_ACTION_WIFI_AP_MODE_CUSTOMIZED;
|
||||
sprintf(qr_info.name, "%s", carlink_get_wifi_p2p_name());
|
||||
sprintf(qr_info.ssid, "%s", carlink_get_wifi_ssid());
|
||||
sprintf(qr_info.pwd, "%s", carlink_get_wifi_passwd());
|
||||
sprintf(qr_info.auth, "WPA-PSK");
|
||||
|
||||
sprintf(uuid, "CARBIT%s", bt_mac);
|
||||
printf("carbit uuid :%s\r\n", uuid);
|
||||
strcpy(UI_uuid,uuid);
|
||||
EC_setBaseConfig(mECTinyCfg, uuid, "V0.0.1", "B:/"); //"CARBIT00000001"
|
||||
|
||||
printf("\r\n2.register ECTiny callback functions\r\n");
|
||||
mECTinyCallback = registerECCallback();
|
||||
|
||||
printf("\r\n3.register ECTiny Video player\r\n");
|
||||
mECTinyVideoPlayer = registerVideoPlayer();
|
||||
|
||||
printf("\r\n4.set Mirror config\r\n");
|
||||
ECMirrorConfig mirrorCfg;
|
||||
memset(&mirrorCfg, 0, sizeof(ECMirrorConfig));
|
||||
|
||||
//mirrorCfg.width = 1280;
|
||||
//mirrorCfg.height = 480;
|
||||
mirrorCfg.width = get_carlink_video_width();
|
||||
mirrorCfg.height = get_carlink_video_height();
|
||||
mirrorCfg.height = ((mirrorCfg.height + 0xf) & (~0xf));
|
||||
|
||||
mirrorCfg.touchMode = 2;
|
||||
mirrorCfg.type = EC_VIDEO_TYPE_H264;
|
||||
mirrorCfg.quality = 4 * 1024 * 1024;
|
||||
mirrorCfg.capScreenMode = 0x08;
|
||||
|
||||
printf("\r\n5.init ECTiny\r\n");
|
||||
|
||||
accessFile.size = ec_access_size;
|
||||
accessFile.read = ec_access_read;
|
||||
accessFile.write = ec_access_write;
|
||||
accessFile.clear = ec_access_clear;
|
||||
EC_bindAccessFile(&accessFile);
|
||||
|
||||
//EC_bindAccessFile(&license2File);
|
||||
EC_initialize(mECTinyCfg, mECTinyCallback);
|
||||
|
||||
printf("\r\n6.set log info\r\n");
|
||||
EC_setLogInfo(EC_LOG_LEVEL_ERROR, EC_LOG_OUT_STD, NULL, EC_LOG_MODULE_SDK | EC_LOG_MODULE_APP);
|
||||
|
||||
printf("\r\n7.set Mirror config\r\n");
|
||||
EC_setMirrorConfig(&mirrorCfg);
|
||||
EC_setVideoPlayer(mECTinyVideoPlayer);
|
||||
|
||||
printf("\r\n8.start EC work!\r\n");
|
||||
|
||||
if (!g_ec_disable)
|
||||
EC_start();
|
||||
|
||||
printf("\r\n9.bindBtDevice!\r\n");
|
||||
|
||||
|
||||
printf("------ initECTiny end ------\n");
|
||||
const char *UrlData = EC_generateQRCodeUrl(&qr_info);
|
||||
printf("++++++++++++++++++++++UrlData:%s+++++++++++++++++++++++++++\n", UrlData);
|
||||
strcpy(strQrText, UrlData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void testThread()
|
||||
{
|
||||
int ret = carlink_common_init();
|
||||
ret = carlink_bt_wifi_init();
|
||||
struct ICalinkEventCallbacks carlinkEventCB = {0};
|
||||
carlinkEventCB.onEvent = onEventEC;
|
||||
carlinkEventCB.rfcomm_data_read = ec_ble_data_read;
|
||||
carlink_register_event_callbacks(&carlinkEventCB);
|
||||
initECTiny(NULL);
|
||||
}
|
||||
|
||||
static void taskInitCarlink(void* param)
|
||||
{
|
||||
testThread();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int carlink_ec_init(int argc,char ** argv)
|
||||
{
|
||||
printf("------ TestECTiny begin ------\n");
|
||||
carlink_ey_video_init();
|
||||
|
||||
/* 启动线程初始化:
|
||||
* 1. initECTiny初始化延时过长,导致开机动画和UI显示切换之间存在黑屏时间,因此在线程中初始化
|
||||
* 2. wifi模块未贴或异常时,wifi_init函数无法返回,导致UI无法正常显示。
|
||||
*/
|
||||
xTaskCreate(taskInitCarlink, "initThread", 2048 *4, NULL, configMAX_PRIORITIES / 4, NULL);
|
||||
printf("------ TestECTiny end ------\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_ec_enable(int enable)
|
||||
{
|
||||
if (enable) {
|
||||
if (g_ec_disable) {
|
||||
if (mInited)
|
||||
EC_start();
|
||||
}
|
||||
g_ec_disable = false;
|
||||
} else {
|
||||
if (!g_ec_disable) {
|
||||
if (mInited)
|
||||
EC_stop();
|
||||
}
|
||||
g_ec_disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
int carlink_ec_init(int argc,char ** argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void carlink_ec_enable(int enable)
|
||||
{
|
||||
(void)enable;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
8
MXC_A27-PCB4.5-270T/app/carlink/EC/src/carlink_ec.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _CARLINK_EC_H_
|
||||
#define _CARLINK_EC_H_
|
||||
|
||||
int carlink_ec_init(int argc,char ** argv);
|
||||
void carlink_ec_enable(int enable);
|
||||
|
||||
|
||||
#endif
|
1093
MXC_A27-PCB4.5-270T/app/carlink/EC/src/carlink_ec_no_lwip.c
Normal file
837
MXC_A27-PCB4.5-270T/app/carlink/EY/carlink_ey.c
Normal file
@ -0,0 +1,837 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "mfcapi.h"
|
||||
#include "board.h"
|
||||
#include "lcd.h"
|
||||
#include "timer.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "FreeRTOS_DHCP_Server.h"
|
||||
#include "carlink_video.h"
|
||||
#include "carlink_ey_audio.h"
|
||||
#include "carlink_ey.h"
|
||||
#include "console.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "carlink_utils.h"
|
||||
|
||||
#if CARLINK_EY
|
||||
|
||||
#define EY_BT_EVENT_CONNECT 0
|
||||
#define EY_BT_EVENT_DISCONNECT 1
|
||||
#define EY_BT_EVENT_NOTIFY_PHONE_TYPE 2
|
||||
#define EY_BT_EVENT_NOTIFY_SSID 3
|
||||
#define EY_BT_EVENT_NOTIFY_PASSWD 4
|
||||
#define EY_BT_EVENT_NOTIFY_CONNECT_STATUS 5
|
||||
#define EY_BT_EVENT_NOTIFY_PHONE_AP_READY 6
|
||||
#define EY_BT_EVENT_NOTIFY_USE_TCP 7
|
||||
#define EY_BT_EVENT_BLE_CONNECT 8
|
||||
#define EY_CARLINK_EVENT_CONNECT 9
|
||||
#define EY_CARLINK_EVENT_DISCONNECT 10
|
||||
struct bt_event
|
||||
{
|
||||
int type;
|
||||
uint8_t para[32];
|
||||
};
|
||||
|
||||
static uint8_t gbt_ready = 0;
|
||||
static TaskHandle_t ey_bt_task = NULL;
|
||||
static TaskHandle_t ey_network_task = NULL;
|
||||
static QueueHandle_t ey_bt_event_queue = NULL;
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
static const uint8_t ucDNSServerAddress[4] = {8, 8, 8, 8};
|
||||
static const uint8_t ucMACAddress[6] = {0x30, 0x4a, 0x26, 0x78, 0xfd, 0x12};
|
||||
static uint8_t ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t ap_passwd[16] = {"88888888"};
|
||||
static uint8_t gphone_type = 0;
|
||||
//static uint8_t guse_tcp = 1;
|
||||
static int gWifiOn = 0;
|
||||
//static int gWIfiConnecting = 0;
|
||||
static Socket_t gClientSocket = FREERTOS_INVALID_SOCKET, gXClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
static SemaphoreHandle_t gSocketMutex = NULL;
|
||||
|
||||
void cmd_test(const char* temp_uart_buf);
|
||||
|
||||
static void ey_reset_wifi_ap_info(const char *btmac)
|
||||
{
|
||||
sprintf((char *)ap_ssid, "AP630_%s", btmac);
|
||||
}
|
||||
|
||||
static void notify_carlink_state(int state)
|
||||
{
|
||||
struct bt_event ev = {0};
|
||||
ev.type = -1;
|
||||
|
||||
if (state == 0) {
|
||||
ev.type = EY_CARLINK_EVENT_DISCONNECT;
|
||||
} else {
|
||||
ev.type = EY_CARLINK_EVENT_CONNECT;
|
||||
}
|
||||
|
||||
if (0 != ev.type && NULL != ey_bt_event_queue) {
|
||||
xQueueSend(ey_bt_event_queue, &ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void notify_phone_ip_addr(uint32_t ipAddr);
|
||||
static void ey_wifi_start_ap(const uint8_t* ssid, const uint8_t* passwd, int channel)
|
||||
{
|
||||
char cmd[64] = {0};
|
||||
uint32_t IPAddress = (32 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
|
||||
|
||||
if (gWifiOn == 0) {
|
||||
printf("Turning on wifi ap...\r\n");
|
||||
WIFI_SetMode(eWiFiModeAP);
|
||||
gWifiOn = 1;
|
||||
//WIFI_On();
|
||||
sprintf(cmd, "wifi_ap %s %d %s", ssid, channel, passwd);
|
||||
cmd_test(cmd);
|
||||
|
||||
IPAddress = (20 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
|
||||
dhcpserver_start(ucIPAddress, IPAddress, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#define ucNumNetworks 12
|
||||
|
||||
static int ey_wifi_connect_remote_ap(const char* ssid, const char* passwd)
|
||||
{
|
||||
WIFINetworkParams_t xNetworkParams = {0};
|
||||
WIFIReturnCode_t xWifiStatus;
|
||||
int retry = 0;
|
||||
|
||||
WIFI_Context_init();
|
||||
|
||||
if (gWifiOn == 0) {
|
||||
WIFI_SetMode(eWiFiModeStation);
|
||||
|
||||
printf("Turning on wifi...\r\n");
|
||||
xWifiStatus = WIFI_On();
|
||||
|
||||
printf("Checking status...\r\n");
|
||||
if( xWifiStatus == eWiFiSuccess ) {
|
||||
printf("WiFi module initialized.\r\n");
|
||||
} else {
|
||||
printf("WiFi module failed to initialize.\r\n" );
|
||||
return -1;
|
||||
}
|
||||
gWifiOn = 1;
|
||||
}
|
||||
#if 0
|
||||
while (1) {
|
||||
printf("Starting scan\r\n");
|
||||
WIFIScanResult_t xScanResults[ ucNumNetworks ] = {0};
|
||||
xWifiStatus = WIFI_Scan( xScanResults, ucNumNetworks ); // Initiate scan
|
||||
|
||||
printf("Scan started\r\n");
|
||||
|
||||
// For each scan result, print out the SSID and RSSI
|
||||
if ( xWifiStatus == eWiFiSuccess ) {
|
||||
printf("Scan success\r\n");
|
||||
for ( uint8_t i=0; i < ucNumNetworks; i++ ) {
|
||||
printf("%s : %d \r\n", xScanResults[i].ucSSID, xScanResults[i].cRSSI);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
printf("Scan failed, status code: %d\n", (int)xWifiStatus);
|
||||
goto exit;
|
||||
//return -1;
|
||||
}
|
||||
vTaskDelay(200);
|
||||
}
|
||||
#endif
|
||||
memset(&xNetworkParams, 0, sizeof(xNetworkParams));
|
||||
xNetworkParams.ucSSIDLength = strlen( ssid );
|
||||
memcpy(xNetworkParams.ucSSID, ssid, xNetworkParams.ucSSIDLength);
|
||||
xNetworkParams.xPassword.xWPA.ucLength = strlen( passwd );
|
||||
memcpy(xNetworkParams.xPassword.xWPA.cPassphrase, passwd, xNetworkParams.xPassword.xWPA.ucLength);
|
||||
xNetworkParams.xSecurity = eWiFiSecurityWPA2;
|
||||
wifi_conn_retry:
|
||||
|
||||
xWifiStatus = WIFI_ConnectAP( &( xNetworkParams ) );
|
||||
|
||||
if( xWifiStatus == eWiFiSuccess ) {
|
||||
printf( "WiFi Connected to AP.\r\n" );
|
||||
} else {
|
||||
printf( "WiFi failed to connect to AP.\r\n" );
|
||||
if (retry++ < 15) {vTaskDelay(pdMS_TO_TICKS(300));
|
||||
goto wifi_conn_retry;}
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if ( ipconfigUSE_DHCP_HOOK != 0 )
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
//uint32_t ulStaticIPAddress, ulStaticNetMask;
|
||||
char ip_str[20] = {0};
|
||||
//const uint8_t ucIPAddressDef[4] = {192, 168, 13, 37};
|
||||
|
||||
sprintf(ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
notify_phone_ip_addr(ulIPAddress);//FreeRTOS_GetIPAddress()
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
static void notify_phone_ip_addr(uint32_t ipAddr)
|
||||
{
|
||||
char at_cmd[64] = {0};
|
||||
|
||||
if (!gbt_ready)
|
||||
return;
|
||||
memset(at_cmd, 0, sizeof(at_cmd));
|
||||
//uint32_t IPAddress = (32 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
|
||||
sprintf(at_cmd, "AT+IPADDR=%d.%d.%d.%d\r\n", (ipAddr >> 0) & 0xFF,
|
||||
(ipAddr >> 8) & 0xFF, (ipAddr >> 16) & 0xFF, (ipAddr >> 24) & 0xFF);
|
||||
printf("at_cmd:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
}
|
||||
|
||||
static void notify_iphone_ssid_passwd()
|
||||
{
|
||||
char at_cmd[128] = {0};
|
||||
char bt_ssid_hex_str[64] = {0};
|
||||
char bt_passwd_hex_str[32] = {0};
|
||||
|
||||
if (!gbt_ready)
|
||||
return;
|
||||
|
||||
memset(at_cmd, 0, sizeof(at_cmd));
|
||||
|
||||
str2asiistr((const char *)ap_ssid, strlen((const char *)ap_ssid), bt_ssid_hex_str, 2 * strlen((const char *)ap_ssid));
|
||||
printf("bt_ssid_hex_str:%s\r\n", bt_ssid_hex_str);
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA2%s\r\n", bt_ssid_hex_str);
|
||||
printf("ssid at:%s ||| \r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
|
||||
memset(at_cmd, 0, sizeof(at_cmd));
|
||||
str2asiistr((const char *)ap_passwd, strlen((const char *)ap_passwd), bt_passwd_hex_str, 2 * strlen((const char *)ap_passwd));
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA3%s\r\n", bt_passwd_hex_str);
|
||||
printf("passwd at:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
}
|
||||
|
||||
static void notify_iphone_ap_connect_status(int status)
|
||||
{
|
||||
char at_cmd[128] = {0};
|
||||
char json_str[64] = {0};
|
||||
char json_hex_str[128] = {0};
|
||||
|
||||
if (!gbt_ready)
|
||||
return;
|
||||
|
||||
sprintf(json_str, "{\"fun\": \"hotspot\",\"type\": \"%d\"}", status);
|
||||
printf("\r\n%s \r\n", json_str);
|
||||
str2asiistr(json_str, strlen(json_str), json_hex_str, 2 * strlen(json_str));
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA7%s\r\n", json_hex_str);
|
||||
printf("ssid at:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
}
|
||||
|
||||
static int readn(Socket_t xSocket, uint8_t * pvBuffer, size_t uxBufferLength)
|
||||
{
|
||||
int totalLen = 0, lBytes, retry_count = 0;
|
||||
|
||||
while (uxBufferLength > 0) {
|
||||
lBytes = FreeRTOS_recv( xSocket, (void *)pvBuffer, uxBufferLength, 0);
|
||||
if (lBytes < 0) {
|
||||
printf("FreeRTOS_recv err:%d\r\n", lBytes);
|
||||
totalLen = -1;
|
||||
break;
|
||||
}
|
||||
if (lBytes == 0) {
|
||||
printf("FreeRTOS_recv lBytes:%d\r\n", lBytes);
|
||||
if (retry_count++ > 1)
|
||||
break;
|
||||
}
|
||||
pvBuffer += lBytes;
|
||||
uxBufferLength -= lBytes;
|
||||
totalLen += lBytes;
|
||||
}
|
||||
return totalLen;
|
||||
}
|
||||
|
||||
|
||||
static void set_socket_win(Socket_t xSockets)
|
||||
{
|
||||
WinProperties_t xWinProperties;
|
||||
|
||||
memset(&xWinProperties, '\0', sizeof xWinProperties);
|
||||
|
||||
xWinProperties.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProperties.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
|
||||
xWinProperties.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProperties.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
|
||||
|
||||
FreeRTOS_setsockopt( xSockets, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProperties, sizeof( xWinProperties ) );
|
||||
}
|
||||
|
||||
static void ey_send_hu_info(Socket_t xSockets)
|
||||
{
|
||||
uint8_t reply[13] = {0};
|
||||
|
||||
reply[0] = 'O'; reply[1] = 'K';
|
||||
WRITE_LE16(reply + 2, get_carlink_video_width());
|
||||
WRITE_LE16(reply + 4, get_carlink_video_height());
|
||||
WRITE_LE16(reply + 6, get_carlink_video_width());
|
||||
WRITE_LE16(reply + 8, get_carlink_video_height());
|
||||
reply[10] = get_carlink_video_fps();
|
||||
WRITE_LE16(reply + 11, 2000);
|
||||
FreeRTOS_send(xSockets, reply, sizeof(reply), 0);
|
||||
}
|
||||
uint32_t gey_ts = 0;
|
||||
#define EY_DEBUG 0
|
||||
static void ey_network_task_proc(void* arg)
|
||||
{
|
||||
SocketSet_t xFD_Set;
|
||||
BaseType_t xResult;
|
||||
Socket_t xSockets = FREERTOS_INVALID_SOCKET;
|
||||
Socket_t xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
Socket_t xXSSockets = FREERTOS_INVALID_SOCKET;
|
||||
Socket_t xXSClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
static const TickType_t xNoTimeOut = pdMS_TO_TICKS( 2000 );
|
||||
struct freertos_sockaddr xAddress, xRemoteAddr;
|
||||
uint32_t xClientLength = sizeof( struct freertos_sockaddr );
|
||||
int32_t lBytes;
|
||||
uint8_t *header_ptr;
|
||||
msg_header header;
|
||||
#if EY_DEBUG
|
||||
void *h264SrcBuf = NULL;
|
||||
#endif
|
||||
uint8_t *h264SrcBufPtr = NULL;
|
||||
int32_t h264SrcSize = 0;
|
||||
int i;
|
||||
video_frame_s* frame = NULL;
|
||||
TickType_t xBlockingTime = pdMS_TO_TICKS( 2000 );uint32_t ts/*, r_ts*/;
|
||||
int cur_data_size = 0, pre_data_size = 0, retry_count;
|
||||
int err_flag = 0;
|
||||
|
||||
#if EY_DEBUG
|
||||
h264SrcBuf = pvPortMalloc(H264DEC_INBUF_SIZE);
|
||||
if(!h264SrcBuf) {
|
||||
printf("%s, h264SrcBuf pvPortMalloc failed.\n", __func__);
|
||||
return ;
|
||||
}
|
||||
#endif
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
xSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
configASSERT( xSockets != FREERTOS_INVALID_SOCKET );
|
||||
FreeRTOS_setsockopt(xSockets, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof(xNoTimeOut));
|
||||
//FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, (void *)&option, sizeof(option));
|
||||
set_socket_win(xSockets);
|
||||
xAddress.sin_port = ( uint16_t ) 11111;
|
||||
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
|
||||
FreeRTOS_bind( xSockets, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xSockets, 1 );
|
||||
|
||||
xXSSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
configASSERT( xXSSockets != FREERTOS_INVALID_SOCKET );
|
||||
FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof(xNoTimeOut));
|
||||
//FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, (void *)&option, sizeof(option));
|
||||
set_socket_win(xXSSockets);
|
||||
xAddress.sin_port = ( uint16_t ) 11113;
|
||||
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
|
||||
FreeRTOS_bind( xXSSockets, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xXSSockets, 1 );
|
||||
|
||||
while(1) {
|
||||
if (err_flag != 0) {
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket) {
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
}
|
||||
if (FREERTOS_INVALID_SOCKET != xXSClientSocket) {
|
||||
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_closesocket(xXSClientSocket);
|
||||
xXSClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
gClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
gXClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
notify_carlink_state(0);
|
||||
err_flag = 0;
|
||||
}
|
||||
FreeRTOS_FD_CLR(xSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_CLR(xXSSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xXSSockets, xFD_Set, eSELECT_READ);
|
||||
if (xClientSocket && xClientSocket != FREERTOS_INVALID_SOCKET) {
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
}
|
||||
if (xXSClientSocket && xXSClientSocket != FREERTOS_INVALID_SOCKET) {
|
||||
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
}
|
||||
xResult = FreeRTOS_select( xFD_Set, xBlockingTime );
|
||||
if (xResult == 0) {//printf("select timeout\r\n");
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket) {//maybe socket don't recv close info;
|
||||
if (cur_data_size == pre_data_size) {// no data recv
|
||||
printf("no data, retry count:%d\r\n", retry_count);
|
||||
if (retry_count++ >= 1) {// no data for 4s
|
||||
err_flag = 1;
|
||||
notify_carlink_state(0);
|
||||
}
|
||||
}
|
||||
pre_data_size = cur_data_size;
|
||||
}
|
||||
xBlockingTime = pdMS_TO_TICKS( 2000 );
|
||||
continue;
|
||||
}
|
||||
if (xResult < 0) {
|
||||
break;
|
||||
}
|
||||
pre_data_size = cur_data_size;
|
||||
|
||||
if (0){
|
||||
} else if(FreeRTOS_FD_ISSET ( xSockets, xFD_Set )) {
|
||||
xClientSocket = FreeRTOS_accept( xSockets, &xRemoteAddr, &xClientLength);
|
||||
if((xClientSocket != NULL) && (xClientSocket != FREERTOS_INVALID_SOCKET)) {
|
||||
char pucBuffer[32] = {0};
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_GetRemoteAddress( xClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||||
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||||
set_socket_win(xClientSocket);
|
||||
printf("\r\nServer 11111: Received a connection from %s:%u\r\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||||
cur_data_size = 0;
|
||||
pre_data_size = 0;
|
||||
retry_count = 0;
|
||||
h264_dec_ctx_init();
|
||||
notify_carlink_state(1);
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
gClientSocket = xClientSocket;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
}
|
||||
continue;
|
||||
} else if (FreeRTOS_FD_ISSET ( xXSSockets, xFD_Set )) {
|
||||
xXSClientSocket = FreeRTOS_accept( xXSSockets, &xRemoteAddr, &xClientLength);
|
||||
if ((xXSClientSocket != NULL) && (xXSClientSocket != FREERTOS_INVALID_SOCKET)) {
|
||||
char pucBuffer[32] = {0};
|
||||
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xXSClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_GetRemoteAddress( xXSClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||||
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||||
printf("\r\nServer 11113: Received a connection from %s:%u\r\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||||
set_socket_win(xXSClientSocket);
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
gXClientSocket = xXSClientSocket;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
}
|
||||
continue;
|
||||
} else if (FreeRTOS_FD_ISSET ( xXSClientSocket, xFD_Set )) {
|
||||
lBytes = FreeRTOS_recv( xXSClientSocket, (void*)&header, sizeof(header), 0);
|
||||
if (lBytes < 0) {
|
||||
printf("FreeRTOS_recv port 11113 err:%d\r\n", lBytes);
|
||||
err_flag = 1;
|
||||
} else {
|
||||
cur_data_size += lBytes;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
lBytes = FreeRTOS_recv( xClientSocket, (void*)&header, sizeof(header), 0);
|
||||
|
||||
if (lBytes < 0) {
|
||||
printf("FreeRTOS_recv port 11111 err:%d\r\n", lBytes);
|
||||
err_flag = 1;
|
||||
continue;
|
||||
}
|
||||
cur_data_size += lBytes;
|
||||
|
||||
if (lBytes == 0)
|
||||
continue;
|
||||
|
||||
if (!(header.sync_word[0] == 0xAA && header.sync_word[1] == 0xBB && header.sync_word[2] == 0xCC))
|
||||
continue;
|
||||
|
||||
if (header.type == 4) {
|
||||
uint16_t height, width;
|
||||
header_ptr = (uint8_t *)&header;
|
||||
for (i = 0; i < lBytes; i++) {
|
||||
printf("%02x ", header_ptr[i]);
|
||||
}printf("\r\n");
|
||||
|
||||
height = (header_ptr[12] | (header_ptr[13] << 8));
|
||||
width = (header_ptr[14] | (header_ptr[15] << 8));
|
||||
printf("#receive phone info width:%d height:%d\r\n", width, height);gey_ts = get_timer(0);//r_ts = header.ts;
|
||||
|
||||
ey_send_hu_info(xClientSocket);
|
||||
continue;
|
||||
} else if (header.type == 6) {
|
||||
printf("heart beat\r\n");
|
||||
continue;
|
||||
} else if (header.type != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
h264SrcSize = header.payload_size - 4;//skip timestamp
|
||||
if (h264SrcSize <= 0 || h264SrcSize > H264_FRAME_BUF_SIZE) {
|
||||
printf("h264 data len:%d err\r\n", h264SrcSize);
|
||||
continue;
|
||||
}
|
||||
#if EY_DEBUG
|
||||
h264SrcBufPtr = (uint8_t *)h264SrcBuf;
|
||||
#else
|
||||
get_retry:
|
||||
frame = get_h264_frame_buf();
|
||||
if (NULL == frame) {
|
||||
printf("h264 frame is empty\r\n");
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
goto get_retry;
|
||||
//continue;
|
||||
}
|
||||
|
||||
h264SrcBufPtr = (uint8_t *)frame->cur;
|
||||
frame->len = h264SrcSize;
|
||||
#endif
|
||||
//ts = get_timer(0);
|
||||
//printf("Size:%05d lts:%03d rts:%06d\r\n", h264SrcSize, (ts - gey_ts) / 1000, header.ts - r_ts);
|
||||
gey_ts = ts;//r_ts = header.ts;
|
||||
lBytes = readn(xClientSocket, h264SrcBufPtr, h264SrcSize);
|
||||
if (h264SrcSize != lBytes) {
|
||||
set_h264_frame_free(frame);
|
||||
if (lBytes == -1) {
|
||||
printf("###FreeRTOS_recv port 11111 err:%d\r\n", lBytes);
|
||||
err_flag = 1;
|
||||
} else{
|
||||
cur_data_size += lBytes;
|
||||
}
|
||||
} else {
|
||||
cur_data_size += lBytes;
|
||||
notify_h264_frame_ready(&frame);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s exit...\r\n", __func__);
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
if (FREERTOS_INVALID_SOCKET != xSockets)
|
||||
FreeRTOS_closesocket(xSockets);
|
||||
if (FREERTOS_INVALID_SOCKET != xXSSockets)
|
||||
FreeRTOS_closesocket(xXSSockets);
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket)
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
if (FREERTOS_INVALID_SOCKET != xXSClientSocket)
|
||||
FreeRTOS_closesocket(xXSClientSocket);
|
||||
gClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
gXClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static int ey_start_network()
|
||||
{
|
||||
BaseType_t ret;
|
||||
ret = xTaskCreate(ey_network_task_proc, "ey_network", 2048, NULL, configMAX_PRIORITIES - 3, &ey_network_task);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ey_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
notify_iphone_ap_connect_status(0);
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
|
||||
if (gClientSocket != FREERTOS_INVALID_SOCKET)
|
||||
FreeRTOS_SignalSocket(gClientSocket);// wake up socket recv
|
||||
if (gXClientSocket != FREERTOS_INVALID_SOCKET)
|
||||
FreeRTOS_SignalSocket(gClientSocket);
|
||||
xSemaphoreGive(gSocketMutex);
|
||||
notify_phone_ip_addr(0);
|
||||
notify_carlink_state(0);
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", xEvent->xInfo.xAPStationConnected.ucMac);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", xEvent->xInfo.xAPStationDisconnected.ucMac);
|
||||
//notify_phone_ip_addr(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
static int carlink_ey_network_init()
|
||||
{
|
||||
BaseType_t ret;
|
||||
unsigned int status;
|
||||
|
||||
gSocketMutex = xSemaphoreCreateMutex();
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, ey_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
|
||||
ey_start_network();
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
static void carlink_ey_network_uninit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void ey_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd = NULL, *cmd_para = NULL;
|
||||
struct bt_event ev = {0};
|
||||
ev.type = -1;
|
||||
printf("\r\nfsc_bt_callback %s\r\n", cAtStr);
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+WLCONN", 7)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_PHONE_AP_READY;
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=EY_%s\r\n", (cAtStr + 6));
|
||||
ey_reset_wifi_ap_info(cAtStr + 6);
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=EY_%s\r\n", (cAtStr + 6));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
gbt_ready = 1;
|
||||
} else if (0 == strncmp(cAtStr, "+WLSSID=", 8)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_SSID;
|
||||
cmd_para = cAtStr + 8;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+WLPASSWD=", 10)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_PASSWD;
|
||||
cmd_para = cAtStr + 10;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+HFPSTAT=1", 10)) {
|
||||
ev.type = EY_BT_EVENT_DISCONNECT;
|
||||
} else if (0 == strncmp(cAtStr, "+HFPDEV=", 8)) {
|
||||
ev.type = EY_BT_EVENT_CONNECT;
|
||||
cmd_para = cAtStr + 8;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, 12);
|
||||
} else if (0 == strncmp(cAtStr, "+AAA5=", 6)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_PHONE_TYPE;
|
||||
cmd_para = cAtStr + 6;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+AAA7=", 6)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_CONNECT_STATUS;
|
||||
cmd_para = cAtStr + 7;
|
||||
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3", 11)) {
|
||||
ev.type = EY_BT_EVENT_BLE_CONNECT;
|
||||
} else if (0 == strncmp(cAtStr, "+AAA9", 5)) {
|
||||
ev.type = EY_BT_EVENT_NOTIFY_USE_TCP;
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
}
|
||||
|
||||
if (-1 != ev.type && NULL != ey_bt_event_queue) {
|
||||
xQueueSend(ey_bt_event_queue, &ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void ey_bt_task_proc(void* arg)
|
||||
{
|
||||
struct bt_event ev;
|
||||
char* cmd_para = NULL;
|
||||
char at_cmd[128] = {0};
|
||||
char phone_type = -1;
|
||||
char ssid[32] = {0};
|
||||
char passwd[32] = {0};
|
||||
char bt_mac[12 + 1] = {0};
|
||||
int ret = -1;
|
||||
int carlink_ready_flag = 0;
|
||||
|
||||
for (;;) {
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
if (xQueueReceive(ey_bt_event_queue, &ev, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
cmd_para = (char*)ev.para;
|
||||
if (0) {
|
||||
} else if (EY_BT_EVENT_NOTIFY_CONNECT_STATUS == ev.type) {
|
||||
} else if (EY_BT_EVENT_CONNECT == ev.type) {
|
||||
memcpy(bt_mac, cmd_para, 12);
|
||||
bt_mac[12] = '0';
|
||||
|
||||
} else if (EY_BT_EVENT_DISCONNECT == ev.type) {
|
||||
memset(ssid, 0, sizeof(ssid));
|
||||
memset(passwd, 0, sizeof(passwd));
|
||||
memset(bt_mac, 0, sizeof(bt_mac));
|
||||
phone_type = -1;
|
||||
notify_iphone_ssid_passwd();
|
||||
notify_phone_ip_addr(0);
|
||||
} else if (EY_BT_EVENT_NOTIFY_PHONE_TYPE == ev.type) {
|
||||
string2hex(cmd_para, strlen(cmd_para), &phone_type, 2);
|
||||
printf("\r\nphone type:%d\n", phone_type);
|
||||
if (phone_type != gphone_type) {
|
||||
gWifiOn = 0;// reboot wifi
|
||||
WIFI_Off();
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
}
|
||||
gphone_type = phone_type;
|
||||
if (0 == phone_type) {//android
|
||||
char type_str[5] = {0};
|
||||
char *tmp_buf = "-1";
|
||||
str2asiistr(tmp_buf, strlen(tmp_buf), type_str, 2 * strlen(tmp_buf));
|
||||
sprintf(at_cmd, "AT+GATTSET=AAA2%s\r\n", type_str);
|
||||
printf("\r\nat:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
} else if (1 == phone_type) {//iphone
|
||||
setDhcpClientState(0);
|
||||
vDHCPProcess(1, eInitialWait);
|
||||
xSendDHCPEvent();
|
||||
notify_iphone_ssid_passwd();
|
||||
ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
|
||||
uint32_t ap_addr = (ucIPAddress[0]) | (ucIPAddress[1] << 8) | (ucIPAddress[2] << 16) | (ucIPAddress[3] << 24);
|
||||
notify_phone_ip_addr(ap_addr);
|
||||
}
|
||||
} else if (EY_BT_EVENT_NOTIFY_SSID == ev.type) {
|
||||
memcpy(ssid, cmd_para, strlen(cmd_para) + 1);
|
||||
printf("\r\nssid:%s\r\n", ssid);
|
||||
} else if (EY_BT_EVENT_NOTIFY_PASSWD == ev.type) {
|
||||
memcpy(passwd, cmd_para, strlen(cmd_para) + 1);
|
||||
printf("\r\npasswd:%s\r\n", passwd);
|
||||
} else if (EY_BT_EVENT_NOTIFY_PHONE_AP_READY == ev.type) {
|
||||
printf("\r\nssid:%s passwd:%s\r\n", ssid, passwd);
|
||||
setDhcpClientState(1);
|
||||
vDHCPProcess(1, eInitialWait);
|
||||
xSendDHCPEvent();
|
||||
notify_iphone_ap_connect_status(4);
|
||||
ret = ey_wifi_connect_remote_ap(ssid, passwd);
|
||||
if (ret == 0) {
|
||||
vDHCPProcess(1, eWaitingSendFirstDiscover);
|
||||
xSendDHCPEvent();
|
||||
}
|
||||
} else if (EY_BT_EVENT_NOTIFY_USE_TCP == ev.type) {
|
||||
} else if (EY_BT_EVENT_BLE_CONNECT == ev.type) {
|
||||
char bt_mac_hex_str[25] = {0};
|
||||
str2asiistr(bt_mac, 12, bt_mac_hex_str, 24);
|
||||
sprintf(at_cmd, "AT+GATTSEND=AAA5%s\r\n", bt_mac_hex_str);
|
||||
printf("\r\nat:%s\r\n", at_cmd);
|
||||
console_send_atcmd(at_cmd, strlen(at_cmd));
|
||||
} else if (EY_CARLINK_EVENT_CONNECT == ev.type) {
|
||||
carlink_ready_flag = 1;
|
||||
printf("EY_CARLINK_EVENT_CONNECT\r\n");
|
||||
set_carlink_display_state(1);
|
||||
#if EY_CARLINK_NOTIFY_HOOK
|
||||
carlink_ey_notify_state_hook(CARLINK_EY_READY);
|
||||
#endif
|
||||
} else if (EY_CARLINK_EVENT_DISCONNECT == ev.type) {
|
||||
if (carlink_ready_flag == 1) {
|
||||
printf("EY_CARLINK_EVENT_DISCONNECT\r\n");
|
||||
carlink_ready_flag = 0;
|
||||
set_carlink_display_state(0);
|
||||
#if EY_CARLINK_NOTIFY_HOOK
|
||||
carlink_ey_notify_state_hook(CARLINK_EY_EXIT);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static int carlink_ey_bt_init()
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
ret = fsc_bt_main();
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
console_register_cb(NULL, ey_bt_callback);
|
||||
|
||||
ey_bt_event_queue = xQueueCreate(1, sizeof(struct bt_event));
|
||||
ret = xTaskCreate(ey_bt_task_proc, "ey_bt", 2048, NULL, configMAX_PRIORITIES - 1, &ey_bt_task);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void carlink_ey_bt_uninit()
|
||||
{
|
||||
}
|
||||
|
||||
static void carlink_ey_init_thread(void *param)
|
||||
{
|
||||
carlink_ey_audio_init();
|
||||
carlink_ey_video_init();
|
||||
carlink_ey_network_init();
|
||||
carlink_ey_bt_init();
|
||||
//ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int carlink_ey_init()
|
||||
{
|
||||
#if 0
|
||||
int ret = -1;
|
||||
|
||||
ret = carlink_ey_audio_init();
|
||||
ret = carlink_ey_video_init();
|
||||
ret = carlink_ey_network_init();
|
||||
ret = carlink_ey_bt_init();
|
||||
//ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
//避免wifi模块异常后导致初始化接口阻塞,影响机器正常启动。
|
||||
xTaskCreate(carlink_ey_init_thread, "carlink_ey_init", 1024, NULL, 8, NULL);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void carlink_ey_uninit()
|
||||
{
|
||||
carlink_ey_bt_uninit();
|
||||
carlink_ey_network_uninit();
|
||||
}
|
||||
#else
|
||||
int carlink_ey_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void carlink_ey_uninit()
|
||||
{
|
||||
}
|
||||
#endif
|
33
MXC_A27-PCB4.5-270T/app/carlink/EY/carlink_ey.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef __CARLINK_EY_H
|
||||
#define __CARLINK_EY_H
|
||||
|
||||
|
||||
typedef struct msg_header_st
|
||||
{
|
||||
uint8_t sync_word[3];
|
||||
uint8_t type;
|
||||
uint32_t dummy;
|
||||
uint32_t payload_size;
|
||||
uint32_t ts;
|
||||
}msg_header;
|
||||
|
||||
int carlink_ey_init(void);
|
||||
void carlink_ey_uninit(void);
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps);//set h264 video stream info from phone
|
||||
void set_carlink_display_info(int x, int y, int w, int h);//set carlink show area in lcd
|
||||
void set_carlink_display_state(int on); // on: 1.display carlink; 0. display native ui
|
||||
|
||||
#define EY_CARLINK_NOTIFY_HOOK 0
|
||||
typedef enum
|
||||
{
|
||||
CARLINK_EY_READY,
|
||||
CARLINK_EY_EXIT
|
||||
}CARLINK_EY_STATE;
|
||||
|
||||
#if EY_CARLINK_NOTIFY_HOOK
|
||||
void carlink_ey_notify_state_hook(CARLINK_EY_STATE state);
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
39
MXC_A27-PCB4.5-270T/app/carlink/EY/carlink_ey_audio.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include "carlink_ey_audio.h"
|
||||
|
||||
static int ey_bt_play_state_callback(BT_PLAY_STATE_E state, unsigned short samplerate, unsigned char channel)
|
||||
{
|
||||
printf("\r\ney_bt_play_state_callback state %d samplerate %d channel %d\r\n", state, samplerate, channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ey_bt_a2dp_pcm_data_callback(unsigned char* buffer, unsigned short length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ey_bt_hfp_spk_pcm_data_callback(unsigned char* buffer, unsigned short length)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int ey_bt_hfp_mic_pcm_data_callback(unsigned char* buffer, unsigned short length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int carlink_ey_audio_init()
|
||||
{
|
||||
bt_sw_cfg_t bt_sw_cfg = {0};
|
||||
|
||||
bt_sw_cfg.play_state_cb = ey_bt_play_state_callback;
|
||||
bt_sw_cfg.a2dp_cb = ey_bt_a2dp_pcm_data_callback;
|
||||
bt_sw_cfg.hfp_spk_cb = ey_bt_hfp_spk_pcm_data_callback;
|
||||
//bt_sw_cfg.hfp_mic_cb = ey_bt_hfp_mic_pcm_data_callback;
|
||||
|
||||
fsc_bt_register_pcm_interface((void*)&bt_sw_cfg);
|
||||
return 0;
|
||||
}
|
8
MXC_A27-PCB4.5-270T/app/carlink/EY/carlink_ey_audio.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __CARLINK_EY_AUDIO_H
|
||||
#define __CARLINK_EY_AUDIO_H
|
||||
#include <FreeRTOS.h>
|
||||
#include "fscbt_interface.h"
|
||||
#include "fsc_bt.h"
|
||||
|
||||
int carlink_ey_audio_init();
|
||||
#endif
|
347
MXC_A27-PCB4.5-270T/app/carlink/common/ark_network.c
Normal file
@ -0,0 +1,347 @@
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include "mmcsd_core.h"
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "iot_wifi.h"
|
||||
|
||||
const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
const uint8_t ucDNSServerAddress[4] = {8, 8, 8, 8};
|
||||
const uint8_t ucMACAddress[6] = {0x30, 0x4a, 0x26, 0x78, 0xfd, 0x12};
|
||||
|
||||
|
||||
#if !USE_LWIP
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "FreeRTOS_DHCP_Server.h"
|
||||
#include "iperf_task.h"
|
||||
|
||||
|
||||
|
||||
//static uint8_t ap_ssid[64] = {"ap63011"};
|
||||
//static uint8_t ap_passwd[16] = {"88888888"};
|
||||
|
||||
int vTestTCPClientSocket( void )
|
||||
{
|
||||
SocketSet_t xFD_Set = NULL;
|
||||
Socket_t xSocket = FREERTOS_INVALID_SOCKET;
|
||||
struct freertos_sockaddr xServerAddress;
|
||||
WinProperties_t xWinProps;
|
||||
BaseType_t ret;
|
||||
uint8_t wifi_data_buffer[2048] = {0};
|
||||
int xReturn = -1;
|
||||
|
||||
start_sta("AndroidAP", "12345678", 1);
|
||||
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
if (NULL == xFD_Set) {
|
||||
return xReturn;
|
||||
}
|
||||
/* Create a TCP socket. */
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
if( xSocket != FREERTOS_INVALID_SOCKET ) {
|
||||
printf( "Open socket failed\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
/* Set a time out so a missing reply does not cause the task to block indefinitely. */
|
||||
const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 );
|
||||
const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 );
|
||||
ret = FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
ret = FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );
|
||||
}
|
||||
|
||||
/* Set the window and buffer sizes. */
|
||||
xWinProps.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProps.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
|
||||
xWinProps.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProps.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
|
||||
|
||||
/* Connect to the echo server. */
|
||||
printf( "connecting to echo server....\r\n" );
|
||||
xServerAddress.sin_port = FreeRTOS_htons( 10010 );
|
||||
xServerAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 43, 1 );
|
||||
ret = FreeRTOS_connect( xSocket, &xServerAddress, sizeof( xServerAddress ) );
|
||||
if( ret != 0 ) {
|
||||
printf( "Could not connect to server %ld\r\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
ret = FreeRTOS_send( xSocket, (void*)wifi_data_buffer, sizeof wifi_data_buffer, 0 );
|
||||
if( ret < 0 ) {
|
||||
printf( "Could not send data to server %ld\r\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
while (1) {//waiting for data from server
|
||||
FreeRTOS_FD_CLR(xSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSocket, xFD_Set, eSELECT_READ);
|
||||
ret = FreeRTOS_select( xFD_Set, portMAX_DELAY );
|
||||
if (ret < 0) {
|
||||
printf("Select failed\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if( FreeRTOS_FD_ISSET ( xSocket, xFD_Set ) ) {
|
||||
ret = FreeRTOS_recv(xSocket, wifi_data_buffer, sizeof wifi_data_buffer, 0);
|
||||
if (ret > 0) {
|
||||
printf("recv buf size:%d\r\n", ret);
|
||||
} else {
|
||||
printf("FreeRTOS_recv err:%d\r\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
xReturn = 0;
|
||||
|
||||
exit:
|
||||
/* Close this socket before looping back to create another. */
|
||||
if ( xSocket != FREERTOS_INVALID_SOCKET)
|
||||
FreeRTOS_closesocket( xSocket );
|
||||
|
||||
if (NULL != xFD_Set)
|
||||
FreeRTOS_DeleteSocketSet(xFD_Set);
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
static int vTestTCPServerSocket( void )
|
||||
{
|
||||
SocketSet_t xFD_Set;
|
||||
struct freertos_sockaddr xAddress, xRemoteAddr;
|
||||
Socket_t xSockets = FREERTOS_INVALID_SOCKET, xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
socklen_t xClientLength = sizeof( xAddress );
|
||||
static const TickType_t xNoTimeOut = portMAX_DELAY;
|
||||
BaseType_t ret = -1;
|
||||
BaseType_t xResult;
|
||||
uint8_t wifi_data_buffer[2048] = {0};
|
||||
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
xSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
configASSERT( xSockets != FREERTOS_INVALID_SOCKET );
|
||||
FreeRTOS_setsockopt( xSockets,
|
||||
0,
|
||||
FREERTOS_SO_RCVTIMEO,
|
||||
&xNoTimeOut,
|
||||
sizeof( xNoTimeOut ) );
|
||||
xAddress.sin_port = ( uint16_t ) 11111;
|
||||
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
|
||||
FreeRTOS_bind( xSockets, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xSockets, 1 );
|
||||
|
||||
while (1) {
|
||||
FreeRTOS_FD_CLR(xSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSockets, xFD_Set, eSELECT_READ);
|
||||
if (xClientSocket && xClientSocket != FREERTOS_INVALID_SOCKET) {
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET( xClientSocket, xFD_Set, eSELECT_READ );
|
||||
}
|
||||
|
||||
xResult = FreeRTOS_select( xFD_Set, portMAX_DELAY );
|
||||
if (xResult < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if( FreeRTOS_FD_ISSET ( xSockets, xFD_Set ) ) {
|
||||
xClientSocket = FreeRTOS_accept( xSockets, &xRemoteAddr, &xClientLength);
|
||||
if( ( xClientSocket != NULL ) && ( xClientSocket != FREERTOS_INVALID_SOCKET ) ) {
|
||||
char pucBuffer[32] = {0};
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_GetRemoteAddress( xClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||||
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||||
printf("Carlink: Received a connection from %s:%u\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||||
}
|
||||
continue;
|
||||
} else if( FreeRTOS_FD_ISSET ( xClientSocket, xFD_Set ) ) {
|
||||
|
||||
ret = FreeRTOS_recv(xClientSocket, wifi_data_buffer, sizeof wifi_data_buffer, 0);
|
||||
if (ret > 0) {
|
||||
printf("recv buf size:%d\r\n", ret);
|
||||
} else {
|
||||
printf("FreeRTOS_recv err:%d\r\n", ret);
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket)
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
if (FREERTOS_INVALID_SOCKET != xSockets)
|
||||
FreeRTOS_closesocket(xSockets);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !CARLINK_EY && !CARLINK_EC
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
char ip_str[20] = {0};
|
||||
|
||||
sprintf(ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
static struct netif glwip_netif[4];
|
||||
|
||||
err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
|
||||
err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
extern err_t ncm_ethernetif_init(struct netif *netif);
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_SUPPORT
|
||||
void wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
//WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
}
|
||||
|
||||
static BaseType_t wifi_init()
|
||||
{
|
||||
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, wifi_event_handler);
|
||||
for (;;) {
|
||||
int status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int g_flag_init_finished = 0;
|
||||
static void ark_network_init_thread(void *param)
|
||||
{
|
||||
#ifdef WIFI_SUPPORT
|
||||
BaseType_t ret = 0;
|
||||
ret = wifi_init();
|
||||
#if !USE_LWIP
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
|
||||
start_ap(36, "arkn141m_ap_3ca8", "88888888", 1);
|
||||
vIPerfInstall();
|
||||
vTestTCPServerSocket();
|
||||
#else
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
//start_ap(36, "arkn141m_lwip_ap_3ca8", "88888888", 1);
|
||||
start_p2p("ark630hv100_p2p", "ark630hv100", "12345678");
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(NULL, NULL);
|
||||
netif_add(&glwip_netif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&glwip_netif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&glwip_netif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
netif_set_up(&glwip_netif[0]);
|
||||
|
||||
#endif
|
||||
#elif defined(CONFIG_USB_DEVICE_CDC_NCM)
|
||||
#if !USE_LWIP
|
||||
BaseType_t ret = 0;
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
#else
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
//ip4_addr_t dhcp_addr_start;
|
||||
//ip4_addr_t dhcp_addr_end;
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(NULL, NULL);
|
||||
netif_add(&glwip_netif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, ncm_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&glwip_netif[0]);
|
||||
|
||||
/*uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&glwip_netif[0], &dhcp_addr_start, &dhcp_addr_end);*/
|
||||
|
||||
netif_set_up(&glwip_netif[0]);
|
||||
#endif
|
||||
#endif
|
||||
g_flag_init_finished = 1;
|
||||
#ifdef WIFI_SUPPORT
|
||||
ret = ret;
|
||||
#endif
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int ark_network_init()
|
||||
{
|
||||
BaseType_t ret = 0;
|
||||
if (g_flag_init_finished)
|
||||
return 0;
|
||||
g_flag_init_finished = 0;
|
||||
ret = xTaskCreate(ark_network_init_thread, "ark_net_init", 1024, NULL, 8, NULL);
|
||||
|
||||
while(!g_flag_init_finished) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
|
8
MXC_A27-PCB4.5-270T/app/carlink/common/ark_network.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __ARK_NETWORK_H
|
||||
#define __ARK_NETWORK_H
|
||||
|
||||
int ark_network_init();
|
||||
|
||||
|
||||
|
||||
#endif
|
641
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_bt_wifi.c
Normal file
@ -0,0 +1,641 @@
|
||||
//#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "carlink_utils.h"
|
||||
#include "console.h"
|
||||
#include "fsc_bt.h"
|
||||
#include "iap.h"
|
||||
|
||||
#if !defined(USE_LWIP) || !USE_LWIP
|
||||
#error "Carlink need lwip!"
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
#include "carlink_video.h"
|
||||
#include "mycommon.h"
|
||||
#include "wifi_conf.h"
|
||||
#include "carlink_common.h"
|
||||
|
||||
#define DEV_NAME_PREFIX "AP630_CARLINK"
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t carlink_p2p_name[64] = {0};
|
||||
static uint8_t carlink_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t carlink_ap_passwd[16] = {"88888888"};
|
||||
static uint8_t carlink_wifi_mac[32] = {0};
|
||||
|
||||
extern int wps_connect_done;
|
||||
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
|
||||
static int lwip_tcpip_init_done_flag = 0;
|
||||
|
||||
static int g_bt_wifi_init_flag = 0;
|
||||
static pthread_mutex_t btwifiLocker =
|
||||
{
|
||||
.xIsInitialized = pdFALSE,
|
||||
.xMutex = { { 0 } },
|
||||
.xTaskOwner = NULL,
|
||||
.xAttr = { .iType = 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct netif gnetif[4];
|
||||
|
||||
extern int wifi_add_custom_ie(void *cus_ie, int ie_num);
|
||||
extern int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
|
||||
static void carlink_reset_wifi_ap_info(const char *prefex);
|
||||
static void carlink_start_wlan();
|
||||
extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
const char *carlink_get_bt_mac()
|
||||
{
|
||||
if (!g_cp_bt_mac_ready)
|
||||
return NULL;
|
||||
return (const char *)g_cp_bt_mac;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_p2p_name()
|
||||
{
|
||||
return (const char *)carlink_p2p_name;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_ssid()
|
||||
{
|
||||
return (const char *)carlink_ap_ssid;
|
||||
}
|
||||
|
||||
|
||||
const char *carlink_get_wifi_mac()
|
||||
{
|
||||
wifi_get_mac_address((char *)carlink_wifi_mac);
|
||||
return (const char *)carlink_wifi_mac;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_passwd()
|
||||
{
|
||||
return (const char *)carlink_ap_passwd;
|
||||
}
|
||||
|
||||
void carlink_get_ap_ip_addr(char ip[4])
|
||||
{
|
||||
memcpy((void*)ip, (void*)ucIPAddress, 4);
|
||||
}
|
||||
|
||||
|
||||
static void tcpip_init_done(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
}
|
||||
|
||||
static void carlink_lwiperf_report_cb_impl(void *arg, enum lwiperf_report_type report_type,
|
||||
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
printf("lwiperf_report_cb_impl bytes:%d %d ms \r\n", bytes_transferred, ms_duration);
|
||||
}
|
||||
|
||||
int carlink_wlan_tcp_ip_is_ready()
|
||||
{
|
||||
return lwip_tcpip_init_done_flag;
|
||||
}
|
||||
|
||||
//dd3000a0400000020022020961726B6D6963726F0003064C696E75780004030102030606ffffffffffff070666fadde250c0
|
||||
static u8 carplay_vendor_ie[] = {
|
||||
0xdd, 0x30, 0x00, 0xa0, 0x40, 0x00, 0x00, 0x02, 0x00, 0x22, 0x02, 0x09, 0x61, 0x72, 0x6B, 0x6D,
|
||||
0x69, 0x63, 0x72, 0x6F, 0x00, 0x03, 0x06, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x00, 0x04, 0x03, 0x01,
|
||||
0x02, 0x03, 0x06, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x06, 0x66, 0xfa, 0xdd, 0xe2,
|
||||
0x50, 0xc0
|
||||
};
|
||||
static rtw_custom_ie_t carplay_ie[1] = {{carplay_vendor_ie, PROBE_RSP | BEACON}};
|
||||
|
||||
void carlink_carplay_add_vendor_ie()
|
||||
{
|
||||
wifi_add_custom_ie((void *)carplay_ie, 1);
|
||||
}
|
||||
|
||||
void carlink_carplay_ie_replace_bt_mac(const char* btmac_str, int btmac_str_len)
|
||||
{
|
||||
char btmac[6] = {0};
|
||||
string2hex((char *)btmac_str, btmac_str_len, btmac, 6);
|
||||
//memcpy((void*)g_link_info->btmac, (void*)btmac, 6);
|
||||
//sscanf(btmac_str, "%02x%02x%02x%02x%02x%02x", btmac[0], btmac[1], btmac[2], btmac[3], btmac[4], btmac[5]);
|
||||
carplay_vendor_ie[36] = btmac[0];
|
||||
carplay_vendor_ie[37] = btmac[1];
|
||||
carplay_vendor_ie[38] = btmac[2];
|
||||
carplay_vendor_ie[39] = btmac[3];
|
||||
carplay_vendor_ie[40] = btmac[4];
|
||||
carplay_vendor_ie[41] = btmac[5];
|
||||
//memcpy((void*)(carplay_vendor_ie + 36), (void*)btmac, 6);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(carplay_vendor_ie); i++) {
|
||||
printf("0x%02x, ", carplay_vendor_ie[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
#define ENABLE_REBOOT_WIFI 0
|
||||
void carlink_restart_bt_wifi()
|
||||
{
|
||||
carlink_bt_close();
|
||||
#if ENABLE_REBOOT_WIFI
|
||||
netif_set_down(&gnetif[0]);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
WIFI_Off();
|
||||
#endif
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
#if ENABLE_REBOOT_WIFI
|
||||
//start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
#if (CARLINK_EC)
|
||||
start_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
#else
|
||||
start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
#endif
|
||||
carlink_carplay_add_vendor_ie();
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
#endif
|
||||
printf("reopen bt\r\n");
|
||||
carlink_bt_open();
|
||||
}
|
||||
|
||||
static void carlink_start_wlan()
|
||||
{
|
||||
char ap_prefix[5] = {0};
|
||||
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
while(!g_cp_bt_mac_ready) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
carlink_reset_wifi_ap_info(ap_prefix);
|
||||
#if (CARLINK_EC)
|
||||
start_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
#else
|
||||
start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
#endif
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(tcpip_init_done, NULL);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
|
||||
//netif_set_up(&gnetif[0]);
|
||||
lwiperf_start_tcp_server_default(carlink_lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
carlink_carplay_add_vendor_ie();
|
||||
}
|
||||
|
||||
void cp_wlan_start(void){
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
static void dump_ip_addr(const char *msg, const ip_addr_t *server_addr)
|
||||
{
|
||||
printf("%s %d.%d.%d.%d \r\n", msg,
|
||||
ip4_addr1_16(ip_2_ip4(server_addr)), ip4_addr2_16(ip_2_ip4(server_addr)), ip4_addr3_16(ip_2_ip4(server_addr)), ip4_addr4_16(ip_2_ip4(server_addr)));
|
||||
}
|
||||
|
||||
|
||||
static void dhcp_client_status_callback(struct netif *netif, int status, const ip_addr_t *server_addr)
|
||||
{
|
||||
if (&gnetif[0] == netif) {
|
||||
dump_ip_addr("dhcp server ip :", (const ip_addr_t *)server_addr);
|
||||
dump_ip_addr("dhcp client ip :", (const ip_addr_t *)&netif->ip_addr);
|
||||
dump_ip_addr("dhcp client netmask:", (const ip_addr_t *)&netif->netmask);
|
||||
dump_ip_addr("dhcp client gw :", (const ip_addr_t *)&netif->gw);
|
||||
}
|
||||
}
|
||||
|
||||
int start_sta_ext(const char* ssid, const char* passwd, char need_passwd)
|
||||
{
|
||||
int ret = -1;
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
|
||||
ret = start_sta(ssid, passwd, need_passwd);
|
||||
if (ret != 0) {
|
||||
printf("start wifi sta failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (lwip_tcpip_init_done_flag) {
|
||||
netif_remove(&gnetif[0]);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&gnetif[0]);
|
||||
dhcp_regisger_status_callback(dhcp_client_status_callback);
|
||||
netif_set_up(&gnetif[0]);
|
||||
dhcp_start(&gnetif[0]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __restart_p2p(const char *dev_name, const char *ssid, const char *passwd)
|
||||
{
|
||||
int ret = -1;
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
|
||||
ret = start_p2p(dev_name, ssid, passwd);
|
||||
if (ret != 0) {
|
||||
printf("restart wifi p2p failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
if (!lwip_tcpip_init_done_flag) {
|
||||
printf("lwip tcpip is not inited\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dhcp_stop(&gnetif[0]);
|
||||
netif_remove(&gnetif[0]);
|
||||
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int restart_p2p()
|
||||
{
|
||||
if (!g_cp_bt_mac_ready) {
|
||||
printf("bt is not ready at %s", __func__);
|
||||
return -1;
|
||||
}
|
||||
return __restart_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
}
|
||||
|
||||
static void carlink_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
if (prefex) {
|
||||
memset(carlink_ap_ssid, 0, sizeof(carlink_ap_ssid));
|
||||
sprintf((char *)carlink_ap_ssid, "%s_%s", DEV_NAME_PREFIX, prefex);
|
||||
memset(carlink_p2p_name, 0, sizeof(carlink_p2p_name));
|
||||
sprintf((char *)carlink_p2p_name, "DIRECT-%s_p2p_%s", DEV_NAME_PREFIX, prefex);//do not delete "DIRECT-" !!!
|
||||
}
|
||||
}
|
||||
|
||||
static void carlink_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd_para = NULL;
|
||||
//printf("\r\nfsc_bt_callback_ec %s %d\r\n", cAtStr, strlen(cAtStr));
|
||||
struct carlink_event ev;
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
ev.type = CARLINK_EVENT_NONE;
|
||||
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+IAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
//iap2_read_data_proc(ble_buf, data_len);
|
||||
carlink_rfcomm_data_read_hook(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+AAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
//iap2_read_data_proc(ble_buf, data_len);
|
||||
carlink_rfcomm_data_read_hook(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTDATA=", 10)) {
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=1",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_DISCONNECT\r\n",__func__ ,__LINE__);
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.disable_filter = true;
|
||||
carlink_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_CONNECT\r\n",__func__ ,__LINE__);
|
||||
|
||||
ev.type = CARLINK_EVENT_BT_CONNECT;
|
||||
ev.disable_filter = true;
|
||||
carlink_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=%s_%s\r\n", DEV_NAME_PREFIX, (cAtStr + 6 + 8));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=%s_%s\r\n", DEV_NAME_PREFIX, (cAtStr + 6 + 8));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
carlink_carplay_ie_replace_bt_mac(cAtStr + 6, 12);
|
||||
g_cp_bt_mac_ready = true;
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
char* cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
} else if (0 == strncmp(cAtStr, "+NAME=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+LEADDR\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get LE addr
|
||||
} else if (0 == strncmp(cAtStr, "+LEADDR=", 6)) {
|
||||
char hexMacAddr[6] = {0};
|
||||
char m_tmp_buf[64] = {0};
|
||||
string2hex(&cAtStr[8], 12, hexMacAddr, sizeof(hexMacAddr));
|
||||
sprintf(m_tmp_buf, "AT+ADVDATA=%s\r\n", hexMacAddr);
|
||||
console_send_atcmd(m_tmp_buf, 19);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSENT=", 10)) {
|
||||
return;
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=3", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_IAP_READY;
|
||||
ev.link_type = CARPLAY_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=1", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.link_type = CARPLAY_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+AAPSTAT=3", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_AA_RFCOMM_READY;
|
||||
ev.link_type = AUTO_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+AAPSTAT=1", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.link_type = AUTO_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
int carlink_iap_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+IAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
at_str = (uint8_t *)malloc(cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
free(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
int carlink_auto_rfcomm_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+AAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
if (0) {
|
||||
int i;
|
||||
printf("AAPSend: ");
|
||||
for (i = 0; i < len; i++) {
|
||||
printf("%02x ", data[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
|
||||
at_str = (uint8_t *)malloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
free(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
void carlink_bt_open_nolock()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=1\r\n"};
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
}
|
||||
|
||||
|
||||
void carlink_bt_open()
|
||||
{
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (0 == g_bt_wifi_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
carlink_bt_open_nolock();
|
||||
exit:
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
}
|
||||
|
||||
void carlink_bt_close()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=0\r\n"};
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (0 == g_bt_wifi_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
exit:
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void carlink_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
char mac_str[32] = {0};
|
||||
char *mac = NULL;
|
||||
struct carlink_event ev;
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
|
||||
if (xEvent) {
|
||||
mac = (char *)xEvent->xInfo.xAPStationConnected.ucMac;
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
wps_connect_done = 0;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", mac_str);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", mac_str);
|
||||
|
||||
ev.type = CARLINK_EVENT_WIFI_DISCONNECT;
|
||||
ev.disable_filter = true;
|
||||
memcpy((void*)ev.u.para, (void*)mac_str, strlen(mac_str));
|
||||
carlink_notify_event(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
#if ( ipconfigUSE_DHCP_HOOK != 0 )
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
char g_ip_str[32] = {0};
|
||||
|
||||
sprintf(g_ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, g_ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BaseType_t carlink_wifi_init()
|
||||
{
|
||||
int status;
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, carlink_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void bt_set_support_carplay() // cp
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=33962\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bt_set_support_carplay_android_auto()//auto + cp
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=50346\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
|
||||
int carlink_bt_wifi_init()
|
||||
{
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (g_bt_wifi_init_flag) {
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
return 0;
|
||||
}
|
||||
//carlink_ey_video_init();
|
||||
carlink_wifi_init();
|
||||
console_register_cb(NULL, carlink_bt_callback);
|
||||
fsc_bt_main();
|
||||
//bt_set_support_carplay();
|
||||
bt_set_support_carplay_android_auto();
|
||||
carlink_bt_open_nolock();
|
||||
carlink_start_wlan();
|
||||
g_bt_wifi_init_flag = 1;
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
printf("bt wlan init is ok\r\n");
|
||||
|
||||
// app_wifi_update_demo();
|
||||
wifi_update_init();
|
||||
printf("app wlan update init ok\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
140
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_common.c
Normal file
@ -0,0 +1,140 @@
|
||||
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ff_sfdisk.h"
|
||||
#include "carlink_video.h"
|
||||
#include "os_adapt.h"
|
||||
|
||||
#include "carlink_common.h"
|
||||
|
||||
static QueueHandle_t carlink_event_queue = NULL;
|
||||
static struct ICalinkEventCallbacks* gcarlink_event_cbs[8];
|
||||
static int gcarlink_event_cbs_count;
|
||||
static int g_comm_init_flag = 0;
|
||||
static pthread_mutex_t carlink_com_locker =
|
||||
{
|
||||
.xIsInitialized = pdFALSE,
|
||||
.xMutex = { { 0 } },
|
||||
.xTaskOwner = NULL,
|
||||
.xAttr = { .iType = 0 }
|
||||
};
|
||||
|
||||
void pthread_key_system_init();
|
||||
|
||||
void carlink_rfcomm_data_read_hook(void* buf, int len)
|
||||
{
|
||||
struct ICalinkEventCallbacks *pcb;
|
||||
int i;
|
||||
for (i = 0; i < gcarlink_event_cbs_count; i++) {
|
||||
pcb = gcarlink_event_cbs[i];
|
||||
if (pcb && pcb->onEvent) {
|
||||
pcb->rfcomm_data_read(pcb->cb_ctx, buf, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void carlink_notify_event(struct carlink_event *ev)
|
||||
{
|
||||
if (CARLINK_EVENT_NONE != ev->type && NULL != carlink_event_queue) {
|
||||
xQueueSend(carlink_event_queue, ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_notify_event_isr(struct carlink_event *ev)
|
||||
{
|
||||
if (CARLINK_EVENT_NONE != ev->type && NULL != carlink_event_queue) {
|
||||
xQueueSendFromISR(carlink_event_queue, ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_send_key_event(uint8_t key, bool pressed)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
ev.type = CARLINK_EVENT_KEY_EVENT;
|
||||
ev.disable_filter = true;
|
||||
ev.u.para[0] = key;
|
||||
ev.u.para[1] = (uint8_t)pressed;
|
||||
|
||||
carlink_notify_event_isr(&ev);
|
||||
}
|
||||
|
||||
|
||||
static void carlink_event_proc(void* param)
|
||||
{
|
||||
struct carlink_event ev;
|
||||
struct ICalinkEventCallbacks *pcb;
|
||||
int i;
|
||||
|
||||
(void)param;
|
||||
|
||||
if (NULL == carlink_event_queue)
|
||||
return;
|
||||
|
||||
while(1) {
|
||||
if (xQueueReceive(carlink_event_queue, &ev, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < gcarlink_event_cbs_count; i++) {
|
||||
pcb = gcarlink_event_cbs[i];
|
||||
if (pcb && pcb->onEvent) {
|
||||
pcb->onEvent(pcb->cb_ctx, &ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_register_event_callbacks(const struct ICalinkEventCallbacks *pcb)
|
||||
{
|
||||
if (gcarlink_event_cbs_count < 8) {
|
||||
gcarlink_event_cbs[gcarlink_event_cbs_count++] = (struct ICalinkEventCallbacks *)pcb;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int carlink_common_init()
|
||||
{
|
||||
FF_Disk_t *sfdisk = NULL;
|
||||
BaseType_t ret = -1;
|
||||
|
||||
pthread_mutex_lock(&carlink_com_locker);
|
||||
if (g_comm_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
carlink_ey_video_init();
|
||||
|
||||
carlink_event_queue = xQueueCreate(16, sizeof(struct carlink_event));
|
||||
if (NULL == carlink_event_queue) {
|
||||
printf("%s:%d failed\n", __func__, __LINE__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pthread_key_system_init();
|
||||
|
||||
sfdisk = FF_SFDiskInit("/sf");
|
||||
if (!sfdisk) {
|
||||
printf("FF_SFDiskInit fail.\r\n");
|
||||
//return;
|
||||
}
|
||||
|
||||
ret = xTaskCreate(carlink_event_proc, "cl_ev_proc", 2048, NULL, configMAX_PRIORITIES / 5, NULL);
|
||||
g_comm_init_flag = 1;
|
||||
|
||||
exit:
|
||||
if (ret == -1) {
|
||||
}
|
||||
pthread_mutex_unlock(&carlink_com_locker);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
93
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_common.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef __CARLINK_COMMON_H
|
||||
#define __CARLINK_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CARLINK_CARPLAY = 0x00,
|
||||
CARLINK_CARLIFE,
|
||||
CARLINK_ANDROID_CARLIFE,
|
||||
CARLINK_ANDROID_MIRROR = 3,
|
||||
CARLINK_IOS_CARLIFE,
|
||||
CARLINK_ANDROID_AUTO = 5,
|
||||
CARLINK_ECLINK = 0x06,
|
||||
CARLINK_CARPLAY_WIRELESS,
|
||||
CARLINK_AUTO_WIRELESS,
|
||||
CARLINK_ECLINK_WIRELESS,
|
||||
}CARLink_TYPE;
|
||||
|
||||
|
||||
|
||||
#define CARLINK_VIDEO_WIDTH 800
|
||||
#define CARLINK_VIDEO_HEIGHT 380
|
||||
|
||||
|
||||
|
||||
enum CARLINK_EVENT_TYPE
|
||||
{
|
||||
CARLINK_EVENT_NONE = 0,
|
||||
CARLINK_EVENT_BT_CONNECT,
|
||||
CARLINK_EVENT_BT_IAP_READY,
|
||||
CARLINK_EVENT_BT_AA_RFCOMM_READY,
|
||||
CARLINK_EVENT_BT_DISCONNECT,
|
||||
CARLINK_EVENT_WIFI_DISCONNECT,
|
||||
CARLINK_EVENT_WIFI_CONNECT,
|
||||
|
||||
CARLINK_EVENT_INIT_DONE,
|
||||
CARLINK_EVENT_MSG_SESSION_CONNECT,
|
||||
CARLINK_EVENT_MSG_SESSION_STOP,
|
||||
CARLINK_EVENT_MSG_DISABLE_BT,
|
||||
CARLINK_EVENT_KEY_EVENT
|
||||
};
|
||||
|
||||
struct carlink_event
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
CARLink_TYPE link_type;
|
||||
bool disable_filter;
|
||||
union {
|
||||
int len;
|
||||
void* data;
|
||||
uint8_t para[32];
|
||||
}u;
|
||||
};
|
||||
|
||||
struct ICalinkEventCallbacks
|
||||
{
|
||||
void (*onEvent)(void* ctx, const struct carlink_event *ev);
|
||||
void (*rfcomm_data_read)(void* ctx, const void* buf, int len);
|
||||
void* cb_ctx;
|
||||
};
|
||||
|
||||
|
||||
void carlink_notify_event(struct carlink_event *ev);
|
||||
void carlink_notify_event_isr(struct carlink_event *ev);
|
||||
|
||||
void carlink_register_event_callbacks(const struct ICalinkEventCallbacks *pcb);
|
||||
void carlink_rfcomm_data_read_hook(void* buf, int len);
|
||||
int carlink_iap_data_write(unsigned char *data, int len);
|
||||
int carlink_auto_rfcomm_data_write(unsigned char *data, int len);
|
||||
int carlink_bt_wifi_init();
|
||||
int carlink_wlan_tcp_ip_is_ready();
|
||||
void carlink_bt_open();
|
||||
void carlink_bt_close();
|
||||
void carlink_restart_bt_wifi();
|
||||
const char *carlink_get_bt_mac();
|
||||
const char *carlink_get_wifi_p2p_name();
|
||||
const char *carlink_get_wifi_ssid();
|
||||
const char *carlink_get_wifi_passwd();
|
||||
const char *carlink_get_wifi_mac();
|
||||
void carlink_get_ap_ip_addr(char ip[4]);
|
||||
|
||||
|
||||
int carlink_common_init();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
128
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_utils.c
Normal file
@ -0,0 +1,128 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "carlink_utils.h"
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
void hex2str(const uint8_t *input, uint16_t input_len, char *output)
|
||||
{
|
||||
char *hexEncode = "0123456789ABCDEF";
|
||||
int i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < input_len; i++) {
|
||||
output[j++] = hexEncode[(input[i] >> 4) & 0xf];
|
||||
output[j++] = hexEncode[(input[i]) & 0xf];
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
#define isDigit(c) (((c) <= '9' && (c) >= '0') ? (1) : (0))
|
||||
|
||||
static uint8_t hex2dec(char hex)
|
||||
{
|
||||
if (isDigit(hex)) {
|
||||
return (hex - '0');
|
||||
}
|
||||
if (hex >= 'a' && hex <= 'f') {
|
||||
return (hex - 'a' + 10);
|
||||
}
|
||||
if (hex >= 'A' && hex <= 'F') {
|
||||
return (hex - 'A' + 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string2hex(char *input, int input_len, char *output, int max_len)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t ch0, ch1;
|
||||
|
||||
if (input_len % 2 != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (i < input_len / 2 && i < max_len) {
|
||||
ch0 = hex2dec((char)input[2 * i]);
|
||||
ch1 = hex2dec((char)input[2 * i + 1]);
|
||||
output[i] = (ch0 << 4 | ch1);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
void str2asiistr(const char *input, int input_len, char *output, int max_len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (max_len < 2 *input_len)
|
||||
return;
|
||||
|
||||
while (i < input_len) {
|
||||
sprintf(output, "%02x", input[i]);
|
||||
output += 2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_power_of_2(uint32_t n)
|
||||
{
|
||||
return (n != 0 && ((n & (n -1)) == 0));
|
||||
}
|
||||
|
||||
// buffer_size musb be pow of 2
|
||||
int ring_buffer_init( ring_buffer_t *ctx, int buffer_size)
|
||||
{
|
||||
void *base = NULL;
|
||||
if (ctx == NULL || !is_power_of_2(buffer_size))
|
||||
return -1;
|
||||
base = pvPortMalloc(buffer_size);
|
||||
|
||||
ctx->buffer = (uint8_t *)base;
|
||||
//ctx->end = (uint8_t *)base + buffer_size;
|
||||
ctx->size = (uint32_t) buffer_size;
|
||||
ctx->mask = (uint32_t)( buffer_size - 1 );
|
||||
ctx->read_offset = 0;
|
||||
ctx->write_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ring_buffer_free( ring_buffer_t *ctx )
|
||||
{
|
||||
if (ctx == NULL || NULL == ctx->buffer)
|
||||
return;
|
||||
vPortFree(ctx->buffer);
|
||||
}
|
||||
|
||||
uint32_t ring_buffer_write(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
len = min(len, ctx->size - ctx->write_offset + ctx->read_offset);
|
||||
|
||||
l = min(len, ctx->size - (ctx->write_offset & (ctx->mask)));
|
||||
memcpy(ctx->buffer + (ctx->write_offset & (ctx->mask)), buffer, l);
|
||||
memcpy(ctx->buffer, buffer + l, len - l);
|
||||
ctx->write_offset += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ring_buffer_read(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
len = min(len, ctx->write_offset - ctx->read_offset);
|
||||
|
||||
l = min(len, ctx->size - (ctx->read_offset & (ctx->mask)));
|
||||
memcpy(buffer, ctx->buffer + (ctx->read_offset & (ctx->mask)), l);
|
||||
memcpy(buffer + l, ctx->buffer, len - l);
|
||||
ctx->read_offset += len;
|
||||
return len;
|
||||
}
|
||||
|
31
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_utils.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef __CARLINK_UTILS_H
|
||||
#define __CARLINK_UTILS_H
|
||||
|
||||
void hex2str(const uint8_t *input, uint16_t input_len, char *output);
|
||||
int string2hex(char *input, int input_len, char *output, int max_len);
|
||||
void str2asiistr(const char *input, int input_len, char *output, int max_len);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * buffer;
|
||||
//const uint8_t * end;
|
||||
uint32_t size;
|
||||
uint32_t mask;
|
||||
uint32_t read_offset;
|
||||
uint32_t write_offset;
|
||||
} ring_buffer_t;
|
||||
|
||||
int ring_buffer_init( ring_buffer_t *ctx, int buffer_size);
|
||||
void ring_buffer_free( ring_buffer_t *ctx );
|
||||
uint32_t ring_buffer_write(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len);
|
||||
uint32_t ring_buffer_read(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len);
|
||||
|
||||
/*#define ring_buffer_get_read_ptr( RING ) ( &(RING)->buffer[ (RING)->read_offset & (RING)->mask ] )
|
||||
#define ring_buffer_get_write_ptr( RING ) ( &(RING)->buffer[ (RING)->write_offset & (RING)->mask ] )
|
||||
#define ring_buffer_read_advance( RING, COUNT ) do { (RING)->read_offset += (COUNT); } while( 0 )
|
||||
#define ring_buffer_write_advance( RING, COUNT ) do { (RING)->write_offset += (COUNT); } while( 0 )
|
||||
#define ring_buffer_reset( RING ) do { (RING)->read_offset = (RING)->write_offset; } while( 0 )*/
|
||||
#define ring_buffer_get_bytes_used( RING ) ( (uint32_t)( (RING)->write_offset - (RING)->read_offset ) )
|
||||
#define ring_buffer_get_bytes_free( RING ) ( (RING)->size - ring_buffer_get_bytes_used( RING ) )
|
||||
|
||||
#endif
|
372
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_video.c
Normal file
@ -0,0 +1,372 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "carlink_video.h"
|
||||
#include "mfcapi.h"
|
||||
#include "lcd.h"
|
||||
#include "pxp.h"
|
||||
#include "cp15/cp15.h"
|
||||
#include "timer.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#include "os_adapt.h"
|
||||
#include "ff_stdio.h"
|
||||
|
||||
static List_t frame_free_list;
|
||||
static List_t frame_ready_list;
|
||||
static video_frame_s h264_frame_fifos[H264_FRAME_FIFO_COUNT];
|
||||
static char* h264_buf = NULL;
|
||||
static SemaphoreHandle_t frame_list_mutex = NULL;
|
||||
static TaskHandle_t dec_h264_handle;
|
||||
static QueueHandle_t h264_frame_queue;
|
||||
static uint8_t g_init_flag = 0;
|
||||
static uint8_t g_video_start = 0;
|
||||
static int g_disp_x = 0, g_disp_y = 0, g_disp_width = LCD_WIDTH, g_disp_height = LCD_HEIGHT;
|
||||
static int g_video_width = LCD_WIDTH, g_video_height = LCD_HEIGHT, g_video_fps = 30;
|
||||
static int g_hide_carlink_flag = 0;
|
||||
|
||||
static int g_active_video_x = 0, g_active_video_y = 0;
|
||||
|
||||
void set_carlink_active_video_info(int x, int y)//for android auto
|
||||
{
|
||||
g_active_video_x = x;
|
||||
g_active_video_y = y;
|
||||
}
|
||||
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps)
|
||||
{
|
||||
g_video_width = w;
|
||||
g_video_height = h;
|
||||
g_video_fps = fps;
|
||||
}
|
||||
|
||||
int get_carlink_video_width()
|
||||
{
|
||||
return g_video_width;
|
||||
}
|
||||
|
||||
int get_carlink_video_height()
|
||||
{
|
||||
return g_video_height;
|
||||
}
|
||||
|
||||
int get_carlink_video_fps()
|
||||
{
|
||||
return g_video_fps;
|
||||
}
|
||||
|
||||
void set_carlink_display_info(int x, int y, int w, int h)
|
||||
{
|
||||
g_disp_x = x;
|
||||
g_disp_y = y;
|
||||
g_disp_width = w;
|
||||
g_disp_height = h;
|
||||
}
|
||||
|
||||
static void h264_frame_list_reset()
|
||||
{
|
||||
video_frame_s *buffer;
|
||||
int i;
|
||||
|
||||
buffer = (video_frame_s *)h264_frame_fifos;
|
||||
vListInitialise(&frame_free_list);
|
||||
vListInitialise(&frame_ready_list);
|
||||
for(i = 0; i < H264_FRAME_FIFO_COUNT; i++) {
|
||||
buffer->buf = (char *)(((unsigned int)h264_buf + i * H264_FRAME_BUF_SIZE));
|
||||
buffer->cur = buffer->buf;
|
||||
buffer->frame_id = i;
|
||||
buffer->len = 0;
|
||||
vListInitialiseItem(&buffer->entry);
|
||||
vListInsertEnd(&frame_free_list, &buffer->entry);
|
||||
listSET_LIST_ITEM_OWNER(&buffer->entry, buffer);
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
static int h264_frame_buf_init(void)
|
||||
{
|
||||
h264_buf = pvPortMalloc(H264_FRAME_FIFO_COUNT * H264_FRAME_BUF_SIZE );
|
||||
if (h264_buf == NULL) {
|
||||
printf("malloc jpeg buf failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
h264_frame_list_reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h264_dec_ctx_init()
|
||||
{
|
||||
g_video_start = 0;
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
void set_carlink_display_state(int on)
|
||||
{
|
||||
g_hide_carlink_flag = on;
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
void set_carlink_display_state_irq(int on)
|
||||
{
|
||||
g_hide_carlink_flag = on;
|
||||
|
||||
xQueueSendFromISR(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
video_frame_s* get_h264_frame_buf()
|
||||
{
|
||||
video_frame_s* frame = NULL;
|
||||
ListItem_t* item = NULL;
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (g_video_start && !listLIST_IS_EMPTY(&frame_free_list)) {
|
||||
frame = list_first_entry(&frame_free_list);
|
||||
item = listGET_HEAD_ENTRY(&frame_free_list);
|
||||
uxListRemove(item);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
void notify_h264_frame_ready(video_frame_s** frame)
|
||||
{
|
||||
//ListItem_t* item = NULL;
|
||||
video_frame_s * tmp = *frame;
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (NULL != tmp) {
|
||||
vListInsertEnd(&frame_ready_list, &tmp->entry);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
void set_h264_frame_free(video_frame_s* frame)
|
||||
{
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (g_video_start) {
|
||||
frame->cur = frame->buf;
|
||||
frame->len = 0;
|
||||
vListInsertEnd(&frame_free_list, &frame->entry);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
}
|
||||
uint8_t map_flag = 0;
|
||||
static void h264_decode_proc(void *pvParameters)
|
||||
{
|
||||
MFCHandle *handle = NULL;
|
||||
DWLLinearMem_t inBuf;
|
||||
OutFrameBuffer outBuf = {0};
|
||||
int ret = -1, i;
|
||||
uint32_t align_width, align_height;
|
||||
uint32_t yaddr, uaddr, vaddr, dstaddr;
|
||||
video_frame_s* frame = NULL;
|
||||
uint32_t ts = get_timer(0), show_ts = 0, video_ts = 0;
|
||||
int32_t delta_ts = 0;;
|
||||
int carlink_lcd_take = 0;
|
||||
ListItem_t* item = NULL;
|
||||
//FF_FILE *fp = ff_fopen("/usb/ey.h264", "w+");
|
||||
|
||||
handle = mfc_init(RAW_STRM_TYPE_H264_NOREORDER);
|
||||
if(!handle) {
|
||||
printf("%s, mfc_init failed.\r\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
g_video_start = 1;
|
||||
while(1) {
|
||||
if (xQueueReceive(h264_frame_queue, NULL, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
if (g_video_start == 0) {
|
||||
printf("dec uninit\r\n");
|
||||
if (carlink_lcd_take) {
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
vVideoDisplayBufGive();
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
carlink_lcd_take = 0;
|
||||
}
|
||||
mfc_uninit(handle);
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
h264_frame_list_reset();
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
xQueueReset(h264_frame_queue);
|
||||
handle = mfc_init(RAW_STRM_TYPE_H264_NOREORDER);
|
||||
if(!handle) {
|
||||
printf("%s, mfc_reinit failed.\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
g_video_start = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_hide_carlink_flag == 0) {
|
||||
if(map_flag)
|
||||
map_flag = 0;
|
||||
printf("Exit navigation =========\r\n ");
|
||||
Set_sys_wifi_state(0);
|
||||
//printf("start carplay or andrord auto .\r\n");
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
}
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (!listLIST_IS_EMPTY(&frame_ready_list)) {
|
||||
frame = list_first_entry(&frame_ready_list);
|
||||
item = listGET_HEAD_ENTRY(&frame_ready_list);
|
||||
uxListRemove(item);
|
||||
} else {
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
continue;
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
memset(&outBuf, 0, sizeof(OutFrameBuffer));
|
||||
inBuf.busAddress = (u32)frame->cur;
|
||||
inBuf.virtualAddress = (u32 *)inBuf.busAddress;
|
||||
inBuf.size = frame->len;
|
||||
CP15_clean_dcache_for_dma(inBuf.busAddress, inBuf.busAddress + inBuf.size);
|
||||
ts = get_timer(0);
|
||||
//printf("start dec...\r\n");
|
||||
ret = mfc_decode(handle, &inBuf, &outBuf);
|
||||
//ret = 0;
|
||||
//if (NULL != fp)
|
||||
// ret = ff_fwrite((void*)inBuf.virtualAddress, 1, inBuf.size, fp);
|
||||
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
frame->cur = frame->buf;
|
||||
frame->len = 0;
|
||||
vListInsertEnd(&frame_free_list, &frame->entry);
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("h264 decode fail.\n");
|
||||
continue;
|
||||
}//printf("dec num:%d use:%d ms\r\n", outBuf.num, (get_timer(0) - ts) / 1000);
|
||||
//continue;
|
||||
|
||||
for(i = 0; i < outBuf.num; i++) {
|
||||
int active_offset = 0;
|
||||
align_width = outBuf.frameWidth;
|
||||
align_height = outBuf.frameHeight;
|
||||
|
||||
if(!(align_width && align_height))
|
||||
continue;
|
||||
active_offset = g_active_video_y * align_width;
|
||||
yaddr = outBuf.buffer[i].yBusAddress + active_offset + g_active_video_x;
|
||||
uaddr = outBuf.buffer[i].yBusAddress + align_width * align_height + active_offset / 2 + g_active_video_x;
|
||||
vaddr = 0;//yaddr + align_width * align_height * 5/4;
|
||||
|
||||
if (carlink_lcd_take == 0) {
|
||||
carlink_lcd_take = 1;
|
||||
xVideoDisplayBufTake(portMAX_DELAY);
|
||||
}
|
||||
if (carlink_lcd_take) {
|
||||
LcdOsdInfo info = {0};
|
||||
|
||||
if (0 == g_hide_carlink_flag)
|
||||
continue;
|
||||
|
||||
show_ts = get_timer(0);
|
||||
|
||||
info.format = LCD_OSD_FORAMT_YUV420; //set default format.
|
||||
if ((info.format == LCD_OSD_FORAMT_RGB565) || \
|
||||
(g_disp_width != g_video_width) || (g_disp_height != g_video_height)) {
|
||||
uint32_t pxp_width, pxp_height;
|
||||
int pxp_out_fmt = PXP_OUT_FMT_YUV2P420;
|
||||
|
||||
if(info.format == LCD_OSD_FORAMT_RGB565)
|
||||
pxp_out_fmt = PXP_OUT_FMT_RGB565;
|
||||
|
||||
//align_width = ((outBuf.frameWidth + 0xf) & (~0xf));
|
||||
if (outBuf.frameWidth != g_video_width)
|
||||
align_width = g_video_width;
|
||||
else
|
||||
align_width = outBuf.frameWidth ;
|
||||
if (outBuf.frameHeight != g_video_height)
|
||||
align_height = g_video_height;
|
||||
else
|
||||
align_height = outBuf.frameHeight;
|
||||
|
||||
pxp_width = g_disp_width;
|
||||
pxp_height = g_disp_height;
|
||||
dstaddr = ulVideoDisplayBufGet();
|
||||
|
||||
pxp_scaler_rotate(yaddr, uaddr, vaddr, PXP_SRC_FMT_YUV2P420, align_width, align_height,
|
||||
dstaddr, dstaddr + pxp_width * pxp_height, pxp_out_fmt, pxp_width, pxp_height, LCD_ROTATE_ANGLE);
|
||||
info.yaddr = dstaddr;
|
||||
info.uaddr = dstaddr + pxp_width * pxp_height;
|
||||
info.vaddr = 0;
|
||||
} else {
|
||||
info.yaddr = yaddr;
|
||||
info.uaddr = uaddr;
|
||||
info.vaddr = vaddr;
|
||||
}
|
||||
info.x = g_disp_x;
|
||||
info.y = g_disp_y;
|
||||
info.width = g_disp_width;
|
||||
info.height = g_disp_height;
|
||||
if (g_active_video_x != 0)
|
||||
info.stride = outBuf.frameWidth;
|
||||
|
||||
if (info.format == LCD_OSD_FORAMT_YUV420)
|
||||
ark_lcd_set_osd_yuv420_mode(LCD_VIDEO_LAYER, LCD_OSD_Y_UV420);
|
||||
|
||||
if (!ark_lcd_get_osd_info_atomic_isactive(LCD_VIDEO_LAYER)) {
|
||||
ark_lcd_wait_for_vsync();
|
||||
}
|
||||
|
||||
ark_lcd_set_osd_info_atomic(LCD_VIDEO_LAYER, &info);
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
Set_sys_wifi_state(1);
|
||||
// ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
vVideoDisplayBufRender(dstaddr);
|
||||
if (outBuf.num > 1) {// for apple h264
|
||||
video_ts = (1000 / g_video_fps);
|
||||
show_ts = (get_timer(0) - show_ts) / 1000;
|
||||
delta_ts = ((int32_t)video_ts - (int32_t)show_ts) -3;
|
||||
//printf("delay %d ms\r\n", delta_ts);
|
||||
if (delta_ts > 0)
|
||||
vTaskDelay(pdMS_TO_TICKS(delta_ts));
|
||||
}
|
||||
if(!map_flag){
|
||||
// printf("###############################################.\r\n");
|
||||
request_UI("maps:");
|
||||
map_flag = 1;
|
||||
// printf("###############################################.\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//printf("all use:%d ms dec:%ld ms all ts:%ld ms\r\n", (get_timer(0) - ts) / 1000, dec_ts, (get_timer(0) - all_ts) / 1000);
|
||||
//all_ts = get_timer(0);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (NULL != handle)
|
||||
mfc_uninit(handle);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int carlink_ey_video_init()
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (g_init_flag ==1) {
|
||||
return 0;
|
||||
}
|
||||
g_init_flag = 1;
|
||||
ret = h264_frame_buf_init();
|
||||
frame_list_mutex = xSemaphoreCreateMutex();
|
||||
//h264_frame_queue = xQueueCreate(H264_FRAME_FIFO_COUNT, sizeof(uint32_t));
|
||||
h264_frame_queue = xQueueCreate(1, 0);
|
||||
ret = xTaskCreate(h264_decode_proc, "h264_decode_proc", 2048 * 4, NULL, configMAX_PRIORITIES - 3, &dec_h264_handle);
|
||||
return ret;
|
||||
}
|
99
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_video.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef __CARLINK_VIDEO_H
|
||||
#define __CARLINK_VIDEO_H
|
||||
#include <FreeRTOS.h>
|
||||
#include "board.h"
|
||||
#include "list.h"
|
||||
|
||||
#define H264DEC_INBUF_SIZE (LCD_WIDTH * LCD_HEIGHT * 2)
|
||||
#define H264DEC_DISP_COUNTS (2)
|
||||
#define H264_FRAME_FIFO_COUNT (12)
|
||||
#define H264_FRAME_BUF_SIZE (0x80000)
|
||||
|
||||
typedef struct h264_frame_s {
|
||||
char* buf;
|
||||
char* cur;
|
||||
unsigned int len;
|
||||
unsigned int frame_id;
|
||||
ListItem_t entry;
|
||||
} video_frame_s;
|
||||
|
||||
video_frame_s* get_h264_frame_buf(void);
|
||||
void notify_h264_frame_ready(video_frame_s** frame);
|
||||
void set_h264_frame_free(video_frame_s* frame);
|
||||
void h264_dec_ctx_init();
|
||||
int carlink_ey_video_init();
|
||||
int get_carlink_video_width(void);
|
||||
int get_carlink_video_height(void);
|
||||
int get_carlink_video_fps(void);
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps);//set h264 video stream info from phone
|
||||
void set_carlink_display_info(int x, int y, int w, int h);//set carlink show area in lcd
|
||||
void set_carlink_display_state(int on); // on: 1.display carlink; 0. display native ui
|
||||
void set_carlink_active_video_info(int x, int y);//for android auto
|
||||
|
||||
#define WRITE_BE32(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) >> 24; \
|
||||
*__ptr++ = ((val) & 0x00FF0000) >> 16; \
|
||||
*__ptr++ = ((val) & 0x0000FF00) >> 8; \
|
||||
*__ptr = ((val) & 0x000000FF); \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_BE16(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) >> 8; \
|
||||
*__ptr = (val) & 0x00FF; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define READ_BE32(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = (*__ptr++) << 24; \
|
||||
(dest) |= (*__ptr++) << 16; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
(dest) |= *__ptr; \
|
||||
} while (0)
|
||||
|
||||
#define READ_BE16(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = (*__ptr++) << 8; \
|
||||
(dest) |= *__ptr; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_LE32(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = ((val) & 0x000000FF); \
|
||||
*__ptr++ = ((val) & 0x0000FF00) >> 8; \
|
||||
*__ptr++ = ((val) & 0x00FF0000) >> 16; \
|
||||
*__ptr = (val) >> 24; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_LE16(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) & 0x00FF; \
|
||||
*__ptr = (val) >> 8; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define READ_LE32(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = *__ptr; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
(dest) |= (*__ptr++) << 16; \
|
||||
(dest) |= (*__ptr++) << 24; \
|
||||
} while (0)
|
||||
|
||||
#define READ_LE16(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = *__ptr; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
} while (0)
|
||||
#endif
|
153
MXC_A27-PCB4.5-270T/app/carlink/common/mycommon.h
Normal file
@ -0,0 +1,153 @@
|
||||
#ifndef MYCOMMON_H_H
|
||||
#define MYCOMMON_H_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef CARLINK_LINK_TYPE
|
||||
#define CARLINK_LINK_TYPE
|
||||
typedef enum
|
||||
{
|
||||
CARPLAY = 0x00,
|
||||
CARLIFE,
|
||||
ANDROID_CARLIFE,
|
||||
ANDROID_MIRROR = 3,
|
||||
IOS_CARLIFE,
|
||||
ANDROID_AUTO = 5,
|
||||
ECLINK = 0x06,
|
||||
CARPLAY_WIRELESS,
|
||||
AUTO_WIRELESS
|
||||
}Link_TYPE;
|
||||
#endif
|
||||
|
||||
//general function
|
||||
typedef enum __USB_MODE
|
||||
{
|
||||
UNDEFINED = 0,
|
||||
HOST,
|
||||
PERIPHERAL,
|
||||
OTG
|
||||
}USB_MODE;
|
||||
|
||||
#define LOGV(...) printf(__VA_ARGS__); printf("\r\n");
|
||||
|
||||
struct view_area
|
||||
{
|
||||
short w;
|
||||
short h;
|
||||
short x;
|
||||
short y;
|
||||
};
|
||||
|
||||
typedef struct __carplay_cfg_info
|
||||
{
|
||||
char *iap2_name;
|
||||
char *iap2_modelIdentifier;
|
||||
char *iap2_manfacturer;
|
||||
char *iap2_serialnumber;
|
||||
char *iap2_sw_ver;
|
||||
char *iap2_hw_ver;
|
||||
char *iap2_vehicleInfo_name;
|
||||
char *iap2_product_uuid;
|
||||
char *iap2_usb_serial_num;
|
||||
|
||||
char *manfacturer;
|
||||
char *oem_icon_label;
|
||||
char *oem_icon_path;
|
||||
char *os_info;
|
||||
char *iOSVersionMin;
|
||||
char *limited_ui_elements;
|
||||
char *guuid;
|
||||
char *devid;
|
||||
char link_type;
|
||||
char btmac[6];
|
||||
bool oem_icon_visible;
|
||||
bool limited_ui;
|
||||
bool right_hand_driver;
|
||||
bool night_mode;
|
||||
bool has_knob;
|
||||
bool has_telbutton;
|
||||
bool has_mediabutton;
|
||||
bool has_proxsensor;
|
||||
bool has_EnhancedReqCarUI;
|
||||
bool has_ETCSupported;
|
||||
bool HiFiTouch;
|
||||
bool LoFiTouch;
|
||||
unsigned short usb_country_code;
|
||||
unsigned short tp_verndor_code;
|
||||
unsigned short tp_product_code;
|
||||
unsigned short tel_verndor_code;
|
||||
unsigned short tel_product_code;
|
||||
unsigned short knob_verndor_code;
|
||||
unsigned short knob_product_code;
|
||||
unsigned short proxsensor_verndor_code;
|
||||
unsigned short proxsensor_product_code;
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
short screen_width_phy;//mm
|
||||
short screen_height_phy;
|
||||
|
||||
char encrypt_ic_i2c_bus_num;
|
||||
char encrypt_ic_addr;
|
||||
char usb_idx;
|
||||
char need_sw_aec;
|
||||
char aec_delay;
|
||||
bool tvout_enable;
|
||||
|
||||
bool use_remote_audio;
|
||||
char video_type;
|
||||
short icurrent;
|
||||
int duck_vol;
|
||||
|
||||
char enable_iap_carplay_sess;
|
||||
char *keychain_path_dir;
|
||||
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char* public_key;
|
||||
char* src_version;
|
||||
char ip_v4_addr[4];
|
||||
char wifi_channel;
|
||||
short net_port;
|
||||
|
||||
char carplay_net_ready;
|
||||
char disable_bonjour;
|
||||
char iap_carplay_rej;
|
||||
|
||||
bool enable_enhanced_siri;
|
||||
bool enable_single_ui;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
short mfi_ic_i2c_bus_num;
|
||||
short mfi_ic_addr;
|
||||
|
||||
bool is_old_carplay_ver;
|
||||
|
||||
struct view_area area[3];
|
||||
char view_area_index;
|
||||
|
||||
}carplay_cfg_info;
|
||||
|
||||
typedef struct __auto_cfg_info
|
||||
{
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char wifi_channel;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
} auto_cfg_info;
|
||||
|
||||
|
||||
extern carplay_cfg_info *g_link_info;
|
||||
extern auto_cfg_info *g_auto_link_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
59
MXC_A27-PCB4.5-270T/app/double_pointer_halo/app.h
Normal file
@ -0,0 +1,59 @@
|
||||
//****************************************************************************
|
||||
//
|
||||
// Copyright (C) 2010 ShenZhen ExceedSpace
|
||||
//
|
||||
// Author ZhuoYongHong
|
||||
//
|
||||
// File name: app.h
|
||||
// D3<44>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD>
|
||||
//
|
||||
// Revision history
|
||||
//
|
||||
// 2010.09.06 ZhuoYongHong Initial version
|
||||
//
|
||||
//****************************************************************************
|
||||
|
||||
#ifndef _XSPACE_APP_H_
|
||||
#define _XSPACE_APP_H_
|
||||
|
||||
#include <xm_user.h>
|
||||
#include <xm_base.h>
|
||||
#include <xm_key.h>
|
||||
#include <xm_assert.h>
|
||||
#include <xm_printf.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
#define XMTIMER_DESKTOPVIEW 1 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>)<29>µĶ<C2B5>ʱ<EFBFBD><CAB1>, <20><><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD>ָ<EFBFBD><D6B8>ˢ<EFBFBD><CBA2>
|
||||
#define XMTIMER_CIRCULAR_POINTER_VIEW 2 // <20><>״ָ<D7B4><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µĶ<C2B5>ʱ<EFBFBD><CAB1>, <20><><EFBFBD>ڻ<EFBFBD>״ָ<D7B4><D6B8>ˢ<EFBFBD><CBA2>
|
||||
#define XMTIMER_CLOCK_VIEW 3 // ʱ<>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD>µĶ<C2B5>ʱ<EFBFBD><CAB1>
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>)<29><>ͼ
|
||||
XMHWND_DECLARE(Desktop)
|
||||
|
||||
// <20><>״ָ<D7B4><D6B8><EFBFBD><EFBFBD>ͼ
|
||||
XMHWND_DECLARE(CircularPointer)
|
||||
|
||||
// ʱ<><CAB1><EFBFBD><EFBFBD>ͼ
|
||||
XMHWND_DECLARE(ClockView)
|
||||
|
||||
|
||||
|
||||
|
||||
void AppInit (void);
|
||||
void AppExit (void);
|
||||
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif /* end of __cplusplus */
|
||||
|
||||
#endif // #ifndef _XSPACE_APP_H_w
|
1324
MXC_A27-PCB4.5-270T/app/double_pointer_halo/double_arial.c
Normal file
2269
MXC_A27-PCB4.5-270T/app/double_pointer_halo/double_pointer_demo.c
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef POINTER_DEMO_H
|
||||
#define POINTER_DEMO_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// <20><><EFBFBD>ε<EFBFBD>ͼaRGB8888
|
||||
extern unsigned int* get_halo_image(void);
|
||||
|
||||
extern unsigned short* get_bk_image(void);
|
||||
|
||||
int double_pointer_halo_draw (void);
|
||||
|
||||
int double_pointer_halo_init (int width, int height);
|
||||
|
||||
int double_pointer_halo_exit (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
204
MXC_A27-PCB4.5-270T/app/double_pointer_halo/double_vg_font.c
Normal file
@ -0,0 +1,204 @@
|
||||
#include "vg_font.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef DOUBLE_POINTER_HALO
|
||||
|
||||
#define MAX_TEXT_SIZE 64 // 定义显示支持的最大的字符长度
|
||||
|
||||
static VGuint tmpGlyphIndices[MAX_TEXT_SIZE];
|
||||
static VGfloat tmpAdjustmentsX[MAX_TEXT_SIZE];
|
||||
static VGfloat tmpAdjustmentsY[MAX_TEXT_SIZE];
|
||||
|
||||
// Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
|
||||
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
|
||||
|
||||
#define FONS_UTF8_ACCEPT 0
|
||||
#define FONS_UTF8_REJECT 12
|
||||
|
||||
static unsigned int fons__decutf8(unsigned int* state, unsigned int* codep, unsigned int byte)
|
||||
{
|
||||
static const unsigned char utf8d[] = {
|
||||
// The first part of the table maps bytes to character classes that
|
||||
// to reduce the size of the transition table and create bitmasks.
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
||||
|
||||
// The second part is a transition table that maps a combination
|
||||
// of a state of the automaton and a character class to a state.
|
||||
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
||||
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
||||
12,36,12,12,12,12,12,12,12,12,12,12,
|
||||
};
|
||||
|
||||
unsigned int type = utf8d[byte];
|
||||
|
||||
*codep = (*state != FONS_UTF8_ACCEPT) ?
|
||||
(byte & 0x3fu) | (*codep << 6) :
|
||||
(0xff >> type) & (byte);
|
||||
|
||||
*state = utf8d[256 + *state + type];
|
||||
return *state;
|
||||
}
|
||||
|
||||
// 将UTF8的字符串转换为UTF32编码的32位整数串
|
||||
int utf8_to_utf32 (const char* str, const char* end,
|
||||
unsigned int *unicode, int size)
|
||||
{
|
||||
unsigned int utf8state = 0;
|
||||
unsigned int codepoint;
|
||||
int count = 0;
|
||||
for (; str != end; ++str)
|
||||
{
|
||||
if (fons__decutf8(&utf8state, &codepoint, *(const unsigned char*)str))
|
||||
continue;
|
||||
*unicode ++ = codepoint;
|
||||
size --;
|
||||
count ++;
|
||||
if(size <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static VGint kerningsCompare(const void* arg0, const void* arg1)
|
||||
{
|
||||
const KerningEntry* krn0 = (const KerningEntry*)arg0;
|
||||
const KerningEntry* krn1 = (const KerningEntry*)arg1;
|
||||
|
||||
return (VGint)krn0->key - (VGint)krn1->key;
|
||||
}
|
||||
|
||||
const KerningEntry* kerningFromGlyphIndices(const Font* font,
|
||||
const VGint leftGlyphIndex,
|
||||
const VGint rightGlyphIndex)
|
||||
{
|
||||
const KerningEntry krn =
|
||||
{
|
||||
((VGuint)leftGlyphIndex << 16) + (VGuint)rightGlyphIndex,
|
||||
0.0f, 0.0f
|
||||
};
|
||||
|
||||
return (const KerningEntry*)bsearch(&krn, font->kerningTable, font->kerningTableSize, sizeof(KerningEntry), kerningsCompare);
|
||||
}
|
||||
|
||||
// given a couple of character codes, return the relative kerning (NULL if kerning is zero)
|
||||
const KerningEntry* kerningFromCharCodes(const Font* font,
|
||||
const VGint leftCharCode,
|
||||
const VGint rightCharCode)
|
||||
{
|
||||
return ((leftCharCode >= 0) && (rightCharCode >= 0)) ? kerningFromGlyphIndices(font, leftCharCode, rightCharCode) : NULL;
|
||||
}
|
||||
|
||||
static void TextInfoBuild(const Font* font, const unsigned int* str, const size_t strLen)
|
||||
{
|
||||
size_t i;
|
||||
VGint leftGlyphIndex = *str;
|
||||
|
||||
// first glyph index
|
||||
for (i = 1; i < strLen; ++i)
|
||||
{
|
||||
const VGint rightGlyphIndex = str[i];
|
||||
const KerningEntry* krn = kerningFromGlyphIndices(font, leftGlyphIndex, rightGlyphIndex);
|
||||
// append glyph index
|
||||
// initialize adjustment
|
||||
tmpAdjustmentsX[i - 1] = 0.0f;
|
||||
tmpAdjustmentsY[i - 1] = 0.0f;
|
||||
// add kerning info
|
||||
if (krn != NULL)
|
||||
{
|
||||
tmpAdjustmentsX[i - 1] += krn->x;
|
||||
tmpAdjustmentsY[i - 1] += krn->y;
|
||||
}
|
||||
leftGlyphIndex = rightGlyphIndex;
|
||||
}
|
||||
// last adjustment entry
|
||||
tmpAdjustmentsX[strLen - 1] = 0.0f;
|
||||
tmpAdjustmentsY[strLen - 1] = 0.0f;
|
||||
}
|
||||
|
||||
// 计算字符串尺寸
|
||||
// str UTF8编码的字符串, 字符串每个字符的字形数据需要添加到字库文件(如arial.c), 否则计算失败
|
||||
// cx 保存字符串的逻辑宽度
|
||||
// cy 保存字符串的逻辑高度(始终为1.0)
|
||||
int vgTextSize(const Font* font, const char* str, VGfloat *cx, VGfloat *cy)
|
||||
{
|
||||
VGfloat glyphOrigin[2] = { 0.0f, 0.0f };
|
||||
size_t strLen;
|
||||
|
||||
if(font == NULL || str == NULL)
|
||||
return -1;
|
||||
strLen = strlen(str);
|
||||
if(strLen == 0)
|
||||
return -1;
|
||||
|
||||
strLen = utf8_to_utf32 (str, str + strLen, tmpGlyphIndices, MAX_TEXT_SIZE);
|
||||
|
||||
// build the sequence of glyph indices and kerning data
|
||||
TextInfoBuild(font, tmpGlyphIndices, strLen);
|
||||
// calculate the metrics of the glyph sequence
|
||||
vgSetfv(VG_GLYPH_ORIGIN, 2, glyphOrigin); // 设置开始的画笔位置, 此处为(0,0), 用于字符串宽度计算
|
||||
vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
|
||||
vgLoadIdentity();
|
||||
vgDrawGlyphs(font->openvgHandle, (VGint)strLen, tmpGlyphIndices, tmpAdjustmentsX, tmpAdjustmentsY, 0, VG_FALSE);
|
||||
vgGetfv(VG_GLYPH_ORIGIN, 2, glyphOrigin); // 获取结束的画笔位置
|
||||
*cx = glyphOrigin[0];
|
||||
*cy = 1.0; // 高度为1.0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VGErrorCode arialFontInit(void);
|
||||
void arialFontDestroy(void);
|
||||
VGErrorCode courbdFontInit(void);
|
||||
void courbdFontDestroy(void);
|
||||
|
||||
int vgFontInit (void)
|
||||
{
|
||||
arialFontInit();
|
||||
//courbdFontInit ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vgFontExit (void)
|
||||
{
|
||||
arialFontDestroy();
|
||||
//courbdFontDestroy ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// draw a line of text
|
||||
// str UTF8编码的字符串, 字符串每个字符的字形数据需要添加到字库文件(如arial.c), 否则绘制失败
|
||||
int vgTextOut (const Font* font,
|
||||
const char* str,
|
||||
const VGbitfield paintModes)
|
||||
{
|
||||
size_t strLen;
|
||||
if(font == NULL || str == NULL)
|
||||
return -1;
|
||||
strLen = strlen(str);
|
||||
if(strLen == 0)
|
||||
return 0;
|
||||
if(strLen > MAX_TEXT_SIZE)
|
||||
strLen = MAX_TEXT_SIZE;
|
||||
|
||||
strLen = utf8_to_utf32 (str, str + strLen, tmpGlyphIndices, MAX_TEXT_SIZE);
|
||||
// build the sequence of glyph indices and kerning data
|
||||
TextInfoBuild (font, tmpGlyphIndices, strLen);
|
||||
// draw glyphs
|
||||
vgDrawGlyphs (font->openvgHandle, (VGint)strLen, tmpGlyphIndices, tmpAdjustmentsX, tmpAdjustmentsY, paintModes, VG_FALSE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,2 @@
|
||||
直接点击PNG2VG.exe, 将与PNG2VG.exe,在同一目录下的PNG文件转换为RGB565, ARGB888格式.
|
||||
|
@ -0,0 +1 @@
|
||||
PNG2VG.exe
|
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 540 B |
After Width: | Height: | Size: 540 B |