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,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