CARPLAY版本整理

This commit is contained in:
2025-01-21 16:49:37 +08:00
commit f0fb64e4e6
26542 changed files with 13719676 additions and 0 deletions

View 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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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

Binary file not shown.

View 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

View 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

View File

@ -0,0 +1,7 @@
#ifndef _CARLINK_AA_H_
#define _CARLINK_AA_H_
int carlink_aa_init();
void carlink_aa_enable(int enable);
#endif

View 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

View 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

View 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

View 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

View 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

Binary file not shown.

View 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

View File

@ -0,0 +1,7 @@
#ifndef _CARLINK_CP_H_
#define _CARLINK_CP_H_
int carlink_cp_init();
void carlink_cp_enable(int enable);
#endif

View 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);
}

View 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;
}

View 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;
}

View 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

View 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

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
#ifndef _CARLINK_EC_H_
#define _CARLINK_EC_H_
int carlink_ec_init(int argc,char ** argv);
#endif

View 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

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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;
}

View 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

View 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;
}

View File

@ -0,0 +1,8 @@
#ifndef __ARK_NETWORK_H
#define __ARK_NETWORK_H
int ark_network_init();
#endif

View 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;
}

View 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;
}

View 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

View 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;
}

View 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

View 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;
}

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,2 @@
直接点击PNG2VG.exe, 将与PNG2VG.exe,在同一目录下的PNG文件转换为RGB565, ARGB888格式.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Some files were not shown because too many files have changed in this diff Show More