CARPLAY版本整理
This commit is contained in:
347
MXC_A27-PCB4.5-270T/app/carlink/common/ark_network.c
Normal file
347
MXC_A27-PCB4.5-270T/app/carlink/common/ark_network.c
Normal file
@ -0,0 +1,347 @@
|
||||
#include <stdio.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include "mmcsd_core.h"
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "iot_wifi.h"
|
||||
|
||||
const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
const uint8_t ucDNSServerAddress[4] = {8, 8, 8, 8};
|
||||
const uint8_t ucMACAddress[6] = {0x30, 0x4a, 0x26, 0x78, 0xfd, 0x12};
|
||||
|
||||
|
||||
#if !USE_LWIP
|
||||
#include "FreeRTOS_IP.h"
|
||||
#include "FreeRTOS_IP_Private.h"
|
||||
#include "FreeRTOS_Sockets.h"
|
||||
#include "FreeRTOS_DHCP.h"
|
||||
#include "FreeRTOS_DHCP_Server.h"
|
||||
#include "iperf_task.h"
|
||||
|
||||
|
||||
|
||||
//static uint8_t ap_ssid[64] = {"ap63011"};
|
||||
//static uint8_t ap_passwd[16] = {"88888888"};
|
||||
|
||||
int vTestTCPClientSocket( void )
|
||||
{
|
||||
SocketSet_t xFD_Set = NULL;
|
||||
Socket_t xSocket = FREERTOS_INVALID_SOCKET;
|
||||
struct freertos_sockaddr xServerAddress;
|
||||
WinProperties_t xWinProps;
|
||||
BaseType_t ret;
|
||||
uint8_t wifi_data_buffer[2048] = {0};
|
||||
int xReturn = -1;
|
||||
|
||||
start_sta("AndroidAP", "12345678", 1);
|
||||
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
if (NULL == xFD_Set) {
|
||||
return xReturn;
|
||||
}
|
||||
/* Create a TCP socket. */
|
||||
xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
if( xSocket != FREERTOS_INVALID_SOCKET ) {
|
||||
printf( "Open socket failed\r\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
/* Set a time out so a missing reply does not cause the task to block indefinitely. */
|
||||
const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 4000 );
|
||||
const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 );
|
||||
ret = FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) );
|
||||
ret = FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );
|
||||
}
|
||||
|
||||
/* Set the window and buffer sizes. */
|
||||
xWinProps.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProps.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
|
||||
xWinProps.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
|
||||
xWinProps.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
|
||||
FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProps, sizeof( xWinProps ) );
|
||||
|
||||
/* Connect to the echo server. */
|
||||
printf( "connecting to echo server....\r\n" );
|
||||
xServerAddress.sin_port = FreeRTOS_htons( 10010 );
|
||||
xServerAddress.sin_addr = FreeRTOS_inet_addr_quick( 192, 168, 43, 1 );
|
||||
ret = FreeRTOS_connect( xSocket, &xServerAddress, sizeof( xServerAddress ) );
|
||||
if( ret != 0 ) {
|
||||
printf( "Could not connect to server %ld\r\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
ret = FreeRTOS_send( xSocket, (void*)wifi_data_buffer, sizeof wifi_data_buffer, 0 );
|
||||
if( ret < 0 ) {
|
||||
printf( "Could not send data to server %ld\r\n", ret );
|
||||
goto exit;
|
||||
}
|
||||
|
||||
while (1) {//waiting for data from server
|
||||
FreeRTOS_FD_CLR(xSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSocket, xFD_Set, eSELECT_READ);
|
||||
ret = FreeRTOS_select( xFD_Set, portMAX_DELAY );
|
||||
if (ret < 0) {
|
||||
printf("Select failed\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if( FreeRTOS_FD_ISSET ( xSocket, xFD_Set ) ) {
|
||||
ret = FreeRTOS_recv(xSocket, wifi_data_buffer, sizeof wifi_data_buffer, 0);
|
||||
if (ret > 0) {
|
||||
printf("recv buf size:%d\r\n", ret);
|
||||
} else {
|
||||
printf("FreeRTOS_recv err:%d\r\n", ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
xReturn = 0;
|
||||
|
||||
exit:
|
||||
/* Close this socket before looping back to create another. */
|
||||
if ( xSocket != FREERTOS_INVALID_SOCKET)
|
||||
FreeRTOS_closesocket( xSocket );
|
||||
|
||||
if (NULL != xFD_Set)
|
||||
FreeRTOS_DeleteSocketSet(xFD_Set);
|
||||
return xReturn;
|
||||
}
|
||||
|
||||
static int vTestTCPServerSocket( void )
|
||||
{
|
||||
SocketSet_t xFD_Set;
|
||||
struct freertos_sockaddr xAddress, xRemoteAddr;
|
||||
Socket_t xSockets = FREERTOS_INVALID_SOCKET, xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
socklen_t xClientLength = sizeof( xAddress );
|
||||
static const TickType_t xNoTimeOut = portMAX_DELAY;
|
||||
BaseType_t ret = -1;
|
||||
BaseType_t xResult;
|
||||
uint8_t wifi_data_buffer[2048] = {0};
|
||||
|
||||
xFD_Set = FreeRTOS_CreateSocketSet();
|
||||
xSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
|
||||
configASSERT( xSockets != FREERTOS_INVALID_SOCKET );
|
||||
FreeRTOS_setsockopt( xSockets,
|
||||
0,
|
||||
FREERTOS_SO_RCVTIMEO,
|
||||
&xNoTimeOut,
|
||||
sizeof( xNoTimeOut ) );
|
||||
xAddress.sin_port = ( uint16_t ) 11111;
|
||||
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
|
||||
FreeRTOS_bind( xSockets, &xAddress, sizeof( xAddress ) );
|
||||
FreeRTOS_listen( xSockets, 1 );
|
||||
|
||||
while (1) {
|
||||
FreeRTOS_FD_CLR(xSockets, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xSockets, xFD_Set, eSELECT_READ);
|
||||
if (xClientSocket && xClientSocket != FREERTOS_INVALID_SOCKET) {
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET( xClientSocket, xFD_Set, eSELECT_READ );
|
||||
}
|
||||
|
||||
xResult = FreeRTOS_select( xFD_Set, portMAX_DELAY );
|
||||
if (xResult < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if( FreeRTOS_FD_ISSET ( xSockets, xFD_Set ) ) {
|
||||
xClientSocket = FreeRTOS_accept( xSockets, &xRemoteAddr, &xClientLength);
|
||||
if( ( xClientSocket != NULL ) && ( xClientSocket != FREERTOS_INVALID_SOCKET ) ) {
|
||||
char pucBuffer[32] = {0};
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_GetRemoteAddress( xClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
|
||||
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
|
||||
printf("Carlink: Received a connection from %s:%u\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
|
||||
}
|
||||
continue;
|
||||
} else if( FreeRTOS_FD_ISSET ( xClientSocket, xFD_Set ) ) {
|
||||
|
||||
ret = FreeRTOS_recv(xClientSocket, wifi_data_buffer, sizeof wifi_data_buffer, 0);
|
||||
if (ret > 0) {
|
||||
printf("recv buf size:%d\r\n", ret);
|
||||
} else {
|
||||
printf("FreeRTOS_recv err:%d\r\n", ret);
|
||||
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
xClientSocket = FREERTOS_INVALID_SOCKET;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FREERTOS_INVALID_SOCKET != xClientSocket)
|
||||
FreeRTOS_closesocket(xClientSocket);
|
||||
if (FREERTOS_INVALID_SOCKET != xSockets)
|
||||
FreeRTOS_closesocket(xSockets);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !CARLINK_EY && !CARLINK_EC
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
char ip_str[20] = {0};
|
||||
|
||||
sprintf(ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
static struct netif glwip_netif[4];
|
||||
|
||||
err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
|
||||
err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
extern err_t ncm_ethernetif_init(struct netif *netif);
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_SUPPORT
|
||||
void wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
//WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
}
|
||||
|
||||
static BaseType_t wifi_init()
|
||||
{
|
||||
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, wifi_event_handler);
|
||||
for (;;) {
|
||||
int status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int g_flag_init_finished = 0;
|
||||
static void ark_network_init_thread(void *param)
|
||||
{
|
||||
#ifdef WIFI_SUPPORT
|
||||
BaseType_t ret = 0;
|
||||
ret = wifi_init();
|
||||
#if !USE_LWIP
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
|
||||
start_ap(36, "arkn141m_ap_3ca8", "88888888", 1);
|
||||
vIPerfInstall();
|
||||
vTestTCPServerSocket();
|
||||
#else
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
//start_ap(36, "arkn141m_lwip_ap_3ca8", "88888888", 1);
|
||||
start_p2p("ark630hv100_p2p", "ark630hv100", "12345678");
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(NULL, NULL);
|
||||
netif_add(&glwip_netif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&glwip_netif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&glwip_netif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
netif_set_up(&glwip_netif[0]);
|
||||
|
||||
#endif
|
||||
#elif defined(CONFIG_USB_DEVICE_CDC_NCM)
|
||||
#if !USE_LWIP
|
||||
BaseType_t ret = 0;
|
||||
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
|
||||
#else
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
//ip4_addr_t dhcp_addr_start;
|
||||
//ip4_addr_t dhcp_addr_end;
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(NULL, NULL);
|
||||
netif_add(&glwip_netif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, ncm_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&glwip_netif[0]);
|
||||
|
||||
/*uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&glwip_netif[0], &dhcp_addr_start, &dhcp_addr_end);*/
|
||||
|
||||
netif_set_up(&glwip_netif[0]);
|
||||
#endif
|
||||
#endif
|
||||
g_flag_init_finished = 1;
|
||||
#ifdef WIFI_SUPPORT
|
||||
ret = ret;
|
||||
#endif
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int ark_network_init()
|
||||
{
|
||||
BaseType_t ret = 0;
|
||||
if (g_flag_init_finished)
|
||||
return 0;
|
||||
g_flag_init_finished = 0;
|
||||
ret = xTaskCreate(ark_network_init_thread, "ark_net_init", 1024, NULL, 8, NULL);
|
||||
|
||||
while(!g_flag_init_finished) {
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
|
8
MXC_A27-PCB4.5-270T/app/carlink/common/ark_network.h
Normal file
8
MXC_A27-PCB4.5-270T/app/carlink/common/ark_network.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __ARK_NETWORK_H
|
||||
#define __ARK_NETWORK_H
|
||||
|
||||
int ark_network_init();
|
||||
|
||||
|
||||
|
||||
#endif
|
641
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_bt_wifi.c
Normal file
641
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_bt_wifi.c
Normal file
@ -0,0 +1,641 @@
|
||||
//#include "os_adapt.h"
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "timer.h"
|
||||
#include "iot_wifi.h"
|
||||
#include "mmcsd_core.h"
|
||||
#include "carlink_utils.h"
|
||||
#include "console.h"
|
||||
#include "fsc_bt.h"
|
||||
#include "iap.h"
|
||||
|
||||
#if !defined(USE_LWIP) || !USE_LWIP
|
||||
#error "Carlink need lwip!"
|
||||
#endif
|
||||
|
||||
#include "ethernet.h"
|
||||
#include "tcpip.h"
|
||||
#include "lwip/apps/lwiperf.h"
|
||||
#include "dhcp.h"
|
||||
|
||||
#include "carlink_video.h"
|
||||
#include "mycommon.h"
|
||||
#include "wifi_conf.h"
|
||||
#include "carlink_common.h"
|
||||
|
||||
#define DEV_NAME_PREFIX "AP630_CARLINK"
|
||||
|
||||
static char g_cp_bt_mac[13] = {0};
|
||||
static bool g_cp_bt_mac_ready = false;
|
||||
|
||||
static uint8_t carlink_p2p_name[64] = {0};
|
||||
static uint8_t carlink_ap_ssid[64] = {"ap63011"};
|
||||
static uint8_t carlink_ap_passwd[16] = {"88888888"};
|
||||
static uint8_t carlink_wifi_mac[32] = {0};
|
||||
|
||||
extern int wps_connect_done;
|
||||
|
||||
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
|
||||
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
|
||||
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
|
||||
|
||||
static int lwip_tcpip_init_done_flag = 0;
|
||||
|
||||
static int g_bt_wifi_init_flag = 0;
|
||||
static pthread_mutex_t btwifiLocker =
|
||||
{
|
||||
.xIsInitialized = pdFALSE,
|
||||
.xMutex = { { 0 } },
|
||||
.xTaskOwner = NULL,
|
||||
.xAttr = { .iType = 0 }
|
||||
};
|
||||
|
||||
|
||||
static struct netif gnetif[4];
|
||||
|
||||
extern int wifi_add_custom_ie(void *cus_ie, int ie_num);
|
||||
extern int mmcsd_wait_sdio_ready(int32_t timeout);
|
||||
|
||||
static void carlink_reset_wifi_ap_info(const char *prefex);
|
||||
static void carlink_start_wlan();
|
||||
extern err_t dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end);
|
||||
extern err_t wlan_ethernetif_init(struct netif *netif);
|
||||
#define lwip_ipv4_addr(addr) ((addr[0]) | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24))
|
||||
|
||||
const char *carlink_get_bt_mac()
|
||||
{
|
||||
if (!g_cp_bt_mac_ready)
|
||||
return NULL;
|
||||
return (const char *)g_cp_bt_mac;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_p2p_name()
|
||||
{
|
||||
return (const char *)carlink_p2p_name;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_ssid()
|
||||
{
|
||||
return (const char *)carlink_ap_ssid;
|
||||
}
|
||||
|
||||
|
||||
const char *carlink_get_wifi_mac()
|
||||
{
|
||||
wifi_get_mac_address((char *)carlink_wifi_mac);
|
||||
return (const char *)carlink_wifi_mac;
|
||||
}
|
||||
|
||||
const char *carlink_get_wifi_passwd()
|
||||
{
|
||||
return (const char *)carlink_ap_passwd;
|
||||
}
|
||||
|
||||
void carlink_get_ap_ip_addr(char ip[4])
|
||||
{
|
||||
memcpy((void*)ip, (void*)ucIPAddress, 4);
|
||||
}
|
||||
|
||||
|
||||
static void tcpip_init_done(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
}
|
||||
|
||||
static void carlink_lwiperf_report_cb_impl(void *arg, enum lwiperf_report_type report_type,
|
||||
const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
|
||||
u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
printf("lwiperf_report_cb_impl bytes:%d %d ms \r\n", bytes_transferred, ms_duration);
|
||||
}
|
||||
|
||||
int carlink_wlan_tcp_ip_is_ready()
|
||||
{
|
||||
return lwip_tcpip_init_done_flag;
|
||||
}
|
||||
|
||||
//dd3000a0400000020022020961726B6D6963726F0003064C696E75780004030102030606ffffffffffff070666fadde250c0
|
||||
static u8 carplay_vendor_ie[] = {
|
||||
0xdd, 0x30, 0x00, 0xa0, 0x40, 0x00, 0x00, 0x02, 0x00, 0x22, 0x02, 0x09, 0x61, 0x72, 0x6B, 0x6D,
|
||||
0x69, 0x63, 0x72, 0x6F, 0x00, 0x03, 0x06, 0x4C, 0x69, 0x6E, 0x75, 0x78, 0x00, 0x04, 0x03, 0x01,
|
||||
0x02, 0x03, 0x06, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x06, 0x66, 0xfa, 0xdd, 0xe2,
|
||||
0x50, 0xc0
|
||||
};
|
||||
static rtw_custom_ie_t carplay_ie[1] = {{carplay_vendor_ie, PROBE_RSP | BEACON}};
|
||||
|
||||
void carlink_carplay_add_vendor_ie()
|
||||
{
|
||||
wifi_add_custom_ie((void *)carplay_ie, 1);
|
||||
}
|
||||
|
||||
void carlink_carplay_ie_replace_bt_mac(const char* btmac_str, int btmac_str_len)
|
||||
{
|
||||
char btmac[6] = {0};
|
||||
string2hex((char *)btmac_str, btmac_str_len, btmac, 6);
|
||||
//memcpy((void*)g_link_info->btmac, (void*)btmac, 6);
|
||||
//sscanf(btmac_str, "%02x%02x%02x%02x%02x%02x", btmac[0], btmac[1], btmac[2], btmac[3], btmac[4], btmac[5]);
|
||||
carplay_vendor_ie[36] = btmac[0];
|
||||
carplay_vendor_ie[37] = btmac[1];
|
||||
carplay_vendor_ie[38] = btmac[2];
|
||||
carplay_vendor_ie[39] = btmac[3];
|
||||
carplay_vendor_ie[40] = btmac[4];
|
||||
carplay_vendor_ie[41] = btmac[5];
|
||||
//memcpy((void*)(carplay_vendor_ie + 36), (void*)btmac, 6);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(carplay_vendor_ie); i++) {
|
||||
printf("0x%02x, ", carplay_vendor_ie[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
#define ENABLE_REBOOT_WIFI 0
|
||||
void carlink_restart_bt_wifi()
|
||||
{
|
||||
carlink_bt_close();
|
||||
#if ENABLE_REBOOT_WIFI
|
||||
netif_set_down(&gnetif[0]);
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
WIFI_Off();
|
||||
#endif
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
#if ENABLE_REBOOT_WIFI
|
||||
//start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
#if (CARLINK_EC)
|
||||
start_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
#else
|
||||
start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
#endif
|
||||
carlink_carplay_add_vendor_ie();
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
#endif
|
||||
printf("reopen bt\r\n");
|
||||
carlink_bt_open();
|
||||
}
|
||||
|
||||
static void carlink_start_wlan()
|
||||
{
|
||||
char ap_prefix[5] = {0};
|
||||
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
ip4_addr_t dhcp_addr_start;
|
||||
ip4_addr_t dhcp_addr_end;
|
||||
|
||||
while(!g_cp_bt_mac_ready) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
memcpy(ap_prefix, g_cp_bt_mac + 8, 4);
|
||||
carlink_reset_wifi_ap_info(ap_prefix);
|
||||
#if (CARLINK_EC)
|
||||
start_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
#else
|
||||
start_ap(36, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd, 1);
|
||||
#endif
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
tcpip_init(tcpip_init_done, NULL);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_default(&gnetif[0]);
|
||||
|
||||
uint8_t addr_start[4] = {192, 168, 13, 20};
|
||||
uint8_t addr_end[4] = {192, 168, 13, 30};
|
||||
dhcp_addr_start.addr = lwip_ipv4_addr(addr_start);
|
||||
dhcp_addr_end.addr = lwip_ipv4_addr(addr_end);
|
||||
dhcp_server_start(&gnetif[0], &dhcp_addr_start, &dhcp_addr_end);
|
||||
|
||||
|
||||
//netif_set_up(&gnetif[0]);
|
||||
lwiperf_start_tcp_server_default(carlink_lwiperf_report_cb_impl, NULL);
|
||||
lwip_tcpip_init_done_flag = 1;
|
||||
carlink_carplay_add_vendor_ie();
|
||||
}
|
||||
|
||||
void cp_wlan_start(void){
|
||||
netif_set_up(&gnetif[0]);
|
||||
}
|
||||
|
||||
static void dump_ip_addr(const char *msg, const ip_addr_t *server_addr)
|
||||
{
|
||||
printf("%s %d.%d.%d.%d \r\n", msg,
|
||||
ip4_addr1_16(ip_2_ip4(server_addr)), ip4_addr2_16(ip_2_ip4(server_addr)), ip4_addr3_16(ip_2_ip4(server_addr)), ip4_addr4_16(ip_2_ip4(server_addr)));
|
||||
}
|
||||
|
||||
|
||||
static void dhcp_client_status_callback(struct netif *netif, int status, const ip_addr_t *server_addr)
|
||||
{
|
||||
if (&gnetif[0] == netif) {
|
||||
dump_ip_addr("dhcp server ip :", (const ip_addr_t *)server_addr);
|
||||
dump_ip_addr("dhcp client ip :", (const ip_addr_t *)&netif->ip_addr);
|
||||
dump_ip_addr("dhcp client netmask:", (const ip_addr_t *)&netif->netmask);
|
||||
dump_ip_addr("dhcp client gw :", (const ip_addr_t *)&netif->gw);
|
||||
}
|
||||
}
|
||||
|
||||
int start_sta_ext(const char* ssid, const char* passwd, char need_passwd)
|
||||
{
|
||||
int ret = -1;
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
|
||||
ret = start_sta(ssid, passwd, need_passwd);
|
||||
if (ret != 0) {
|
||||
printf("start wifi sta failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (lwip_tcpip_init_done_flag) {
|
||||
netif_remove(&gnetif[0]);
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
netif_set_default(&gnetif[0]);
|
||||
dhcp_regisger_status_callback(dhcp_client_status_callback);
|
||||
netif_set_up(&gnetif[0]);
|
||||
dhcp_start(&gnetif[0]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __restart_p2p(const char *dev_name, const char *ssid, const char *passwd)
|
||||
{
|
||||
int ret = -1;
|
||||
ip4_addr_t ip_addr;
|
||||
ip4_addr_t netmask;
|
||||
ip4_addr_t gw;
|
||||
|
||||
ip_addr.addr = lwip_ipv4_addr(ucIPAddress);
|
||||
netmask.addr = lwip_ipv4_addr(ucNetMask);
|
||||
gw.addr = lwip_ipv4_addr(ucGatewayAddress);
|
||||
|
||||
ret = start_p2p(dev_name, ssid, passwd);
|
||||
if (ret != 0) {
|
||||
printf("restart wifi p2p failed\r\n");
|
||||
return ret;
|
||||
}
|
||||
if (!lwip_tcpip_init_done_flag) {
|
||||
printf("lwip tcpip is not inited\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dhcp_stop(&gnetif[0]);
|
||||
netif_remove(&gnetif[0]);
|
||||
|
||||
netif_add(&gnetif[0],
|
||||
#if LWIP_IPV4
|
||||
&ip_addr, &netmask, &gw,
|
||||
#endif
|
||||
NULL, wlan_ethernetif_init, tcpip_input);
|
||||
|
||||
netif_set_up(&gnetif[0]);
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int restart_p2p()
|
||||
{
|
||||
if (!g_cp_bt_mac_ready) {
|
||||
printf("bt is not ready at %s", __func__);
|
||||
return -1;
|
||||
}
|
||||
return __restart_p2p((const char *)carlink_p2p_name, (const char *)carlink_ap_ssid, (const char *)carlink_ap_passwd);
|
||||
}
|
||||
|
||||
static void carlink_reset_wifi_ap_info(const char *prefex)
|
||||
{
|
||||
if (prefex) {
|
||||
memset(carlink_ap_ssid, 0, sizeof(carlink_ap_ssid));
|
||||
sprintf((char *)carlink_ap_ssid, "%s_%s", DEV_NAME_PREFIX, prefex);
|
||||
memset(carlink_p2p_name, 0, sizeof(carlink_p2p_name));
|
||||
sprintf((char *)carlink_p2p_name, "DIRECT-%s_p2p_%s", DEV_NAME_PREFIX, prefex);//do not delete "DIRECT-" !!!
|
||||
}
|
||||
}
|
||||
|
||||
static void carlink_bt_callback(char * cAtStr)
|
||||
{
|
||||
char* cmd_para = NULL;
|
||||
//printf("\r\nfsc_bt_callback_ec %s %d\r\n", cAtStr, strlen(cAtStr));
|
||||
struct carlink_event ev;
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
ev.type = CARLINK_EVENT_NONE;
|
||||
|
||||
if (0) {
|
||||
} else if (0 == strncmp(cAtStr, "+IAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
//iap2_read_data_proc(ble_buf, data_len);
|
||||
carlink_rfcomm_data_read_hook(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+AAPDATA=", 9)) {
|
||||
char ble_buf[256] = {0};
|
||||
int data_len, i;
|
||||
int data_str_len = (strlen(cAtStr) - 9);
|
||||
cmd_para = cAtStr + 9;
|
||||
data_len = data_str_len / 2;
|
||||
string2hex(cmd_para, data_str_len, ble_buf, data_len);
|
||||
for (i = 0; i < data_len; i++) {
|
||||
printf("%02x ", ble_buf[i]);
|
||||
}printf("\r\n");
|
||||
//iap2_read_data_proc(ble_buf, data_len);
|
||||
carlink_rfcomm_data_read_hook(ble_buf, data_len);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTDATA=", 10)) {
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=1",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_DISCONNECT\r\n",__func__ ,__LINE__);
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.disable_filter = true;
|
||||
carlink_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3",11)) {
|
||||
printf("TRACE[%s][%d]:EC_EVENT_BT_CONNECT\r\n",__func__ ,__LINE__);
|
||||
|
||||
ev.type = CARLINK_EVENT_BT_CONNECT;
|
||||
ev.disable_filter = true;
|
||||
carlink_notify_event(&ev);
|
||||
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+NAME=%s_%s\r\n", DEV_NAME_PREFIX, (cAtStr + 6 + 8));
|
||||
printf("ADDR:%s\r\n", cAtStr + 6);
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memset(cmd_str, 0, sizeof(cmd_str));
|
||||
sprintf(cmd_str, "AT+LENAME=%s_%s\r\n", DEV_NAME_PREFIX, (cAtStr + 6 + 8));
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
|
||||
memcpy(g_cp_bt_mac, (cAtStr + 6), 12);
|
||||
carlink_carplay_ie_replace_bt_mac(cAtStr + 6, 12);
|
||||
g_cp_bt_mac_ready = true;
|
||||
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
|
||||
char* cmd = "AT+ADDR\r\n";
|
||||
console_send_atcmd(cmd, strlen(cmd));//get mac addr
|
||||
} else if (0 == strncmp(cAtStr, "+NAME=", 6)) {
|
||||
char cmd_str[64] = {0};
|
||||
sprintf(cmd_str, "AT+LEADDR\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));//get LE addr
|
||||
} else if (0 == strncmp(cAtStr, "+LEADDR=", 6)) {
|
||||
char hexMacAddr[6] = {0};
|
||||
char m_tmp_buf[64] = {0};
|
||||
string2hex(&cAtStr[8], 12, hexMacAddr, sizeof(hexMacAddr));
|
||||
sprintf(m_tmp_buf, "AT+ADVDATA=%s\r\n", hexMacAddr);
|
||||
console_send_atcmd(m_tmp_buf, 19);
|
||||
} else if (0 == strncmp(cAtStr, "+GATTSENT=", 10)) {
|
||||
return;
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=3", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_IAP_READY;
|
||||
ev.link_type = CARPLAY_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+IAPSTAT=1", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.link_type = CARPLAY_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+AAPSTAT=3", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_AA_RFCOMM_READY;
|
||||
ev.link_type = AUTO_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
|
||||
} else if (0 == strncmp(cAtStr, "+AAPSTAT=1", 10)) {
|
||||
ev.type = CARLINK_EVENT_BT_DISCONNECT;
|
||||
ev.link_type = AUTO_WIRELESS;
|
||||
carlink_notify_event(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
int carlink_iap_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+IAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
at_str = (uint8_t *)malloc(cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
free(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
int carlink_auto_rfcomm_data_write(unsigned char *data, int len)
|
||||
{
|
||||
uint8_t *at_str = NULL, *at_str_ptr = NULL;
|
||||
uint8_t *at_prefix = "AT+AAPSEND=";
|
||||
int prefix_len = strlen((char *)at_prefix);
|
||||
int cmd_len = (len * 2 + prefix_len + 2);
|
||||
|
||||
if (0) {
|
||||
int i;
|
||||
printf("AAPSend: ");
|
||||
for (i = 0; i < len; i++) {
|
||||
printf("%02x ", data[i]);
|
||||
}printf("\r\n");
|
||||
}
|
||||
|
||||
at_str = (uint8_t *)malloc(cmd_len + 1);
|
||||
memset(at_str, 0, cmd_len + 1);
|
||||
if (NULL == at_str)
|
||||
return -1;
|
||||
at_str_ptr = at_str;
|
||||
sprintf((char*)at_str_ptr, "%s", (char*)at_prefix);
|
||||
at_str_ptr += prefix_len;
|
||||
hex2str(data, len, (char *)at_str_ptr);
|
||||
at_str_ptr += (len * 2);
|
||||
*at_str_ptr++ = '\r';
|
||||
*at_str_ptr++ = '\n';
|
||||
console_send_atcmd((char *)at_str, cmd_len);
|
||||
free(at_str);
|
||||
return len;
|
||||
}
|
||||
|
||||
void carlink_bt_open_nolock()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=1\r\n"};
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
}
|
||||
|
||||
|
||||
void carlink_bt_open()
|
||||
{
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (0 == g_bt_wifi_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
carlink_bt_open_nolock();
|
||||
exit:
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
}
|
||||
|
||||
void carlink_bt_close()
|
||||
{
|
||||
char at_str[] = {"AT+BTEN=0\r\n"};
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (0 == g_bt_wifi_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
console_send_atcmd((char *)at_str, strlen(at_str));
|
||||
exit:
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void carlink_wifi_event_handler( WIFIEvent_t * xEvent )
|
||||
{
|
||||
WIFIEventType_t xEventType = xEvent->xEventType;
|
||||
char mac_str[32] = {0};
|
||||
char *mac = NULL;
|
||||
struct carlink_event ev;
|
||||
memset((void*)&ev, 0, sizeof(ev));
|
||||
|
||||
if (xEvent) {
|
||||
mac = (char *)xEvent->xInfo.xAPStationConnected.ucMac;
|
||||
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
}
|
||||
|
||||
wps_connect_done = 0;
|
||||
|
||||
if (0) {
|
||||
} else if (eWiFiEventConnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is connected to ap \r\n");
|
||||
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
|
||||
printf("\r\n The meter is disconnected from ap \r\n");
|
||||
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
|
||||
printf("\r\n The meter in AP is connected by sta %s \r\n", mac_str);
|
||||
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
|
||||
printf("\r\n The sta %s is disconnected from the meter \r\n", mac_str);
|
||||
|
||||
ev.type = CARLINK_EVENT_WIFI_DISCONNECT;
|
||||
ev.disable_filter = true;
|
||||
memcpy((void*)ev.u.para, (void*)mac_str, strlen(mac_str));
|
||||
carlink_notify_event(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
#if ( ipconfigUSE_DHCP_HOOK != 0 )
|
||||
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
|
||||
uint32_t ulIPAddress )
|
||||
{
|
||||
eDHCPCallbackAnswer_t eReturn;
|
||||
char g_ip_str[32] = {0};
|
||||
|
||||
sprintf(g_ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
|
||||
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
|
||||
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, g_ip_str, getDhcpClientState());
|
||||
if (getDhcpClientState() == 0)
|
||||
return eDHCPStopNoChanges;
|
||||
|
||||
switch( eDHCPPhase )
|
||||
{
|
||||
case eDHCPPhaseFinished:
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
case eDHCPPhasePreDiscover :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
|
||||
case eDHCPPhasePreRequest :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
default :
|
||||
eReturn = eDHCPContinue;
|
||||
break;
|
||||
}
|
||||
|
||||
return eReturn;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BaseType_t carlink_wifi_init()
|
||||
{
|
||||
int status;
|
||||
WIFI_Context_init();
|
||||
WIFI_RegisterEvent(eWiFiEventMax, carlink_wifi_event_handler);
|
||||
for (;;) {
|
||||
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
|
||||
if (status == MMCSD_HOST_PLUGED) {
|
||||
printf("detect sdio device\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void bt_set_support_carplay() // cp
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=33962\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bt_set_support_carplay_android_auto()//auto + cp
|
||||
{
|
||||
char cmd_str[64] = {0};
|
||||
|
||||
sprintf(cmd_str, "AT+PROFILE=50346\r\n");
|
||||
console_send_atcmd(cmd_str, strlen(cmd_str));
|
||||
}
|
||||
|
||||
int carlink_bt_wifi_init()
|
||||
{
|
||||
pthread_mutex_lock(&btwifiLocker);
|
||||
if (g_bt_wifi_init_flag) {
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
return 0;
|
||||
}
|
||||
//carlink_ey_video_init();
|
||||
carlink_wifi_init();
|
||||
console_register_cb(NULL, carlink_bt_callback);
|
||||
fsc_bt_main();
|
||||
//bt_set_support_carplay();
|
||||
bt_set_support_carplay_android_auto();
|
||||
carlink_bt_open_nolock();
|
||||
carlink_start_wlan();
|
||||
g_bt_wifi_init_flag = 1;
|
||||
pthread_mutex_unlock(&btwifiLocker);
|
||||
printf("bt wlan init is ok\r\n");
|
||||
|
||||
// app_wifi_update_demo();
|
||||
wifi_update_init();
|
||||
printf("app wlan update init ok\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
140
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_common.c
Normal file
140
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_common.c
Normal file
@ -0,0 +1,140 @@
|
||||
|
||||
#include <FreeRTOS_POSIX.h>
|
||||
#include <task.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ff_sfdisk.h"
|
||||
#include "carlink_video.h"
|
||||
#include "os_adapt.h"
|
||||
|
||||
#include "carlink_common.h"
|
||||
|
||||
static QueueHandle_t carlink_event_queue = NULL;
|
||||
static struct ICalinkEventCallbacks* gcarlink_event_cbs[8];
|
||||
static int gcarlink_event_cbs_count;
|
||||
static int g_comm_init_flag = 0;
|
||||
static pthread_mutex_t carlink_com_locker =
|
||||
{
|
||||
.xIsInitialized = pdFALSE,
|
||||
.xMutex = { { 0 } },
|
||||
.xTaskOwner = NULL,
|
||||
.xAttr = { .iType = 0 }
|
||||
};
|
||||
|
||||
void pthread_key_system_init();
|
||||
|
||||
void carlink_rfcomm_data_read_hook(void* buf, int len)
|
||||
{
|
||||
struct ICalinkEventCallbacks *pcb;
|
||||
int i;
|
||||
for (i = 0; i < gcarlink_event_cbs_count; i++) {
|
||||
pcb = gcarlink_event_cbs[i];
|
||||
if (pcb && pcb->onEvent) {
|
||||
pcb->rfcomm_data_read(pcb->cb_ctx, buf, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void carlink_notify_event(struct carlink_event *ev)
|
||||
{
|
||||
if (CARLINK_EVENT_NONE != ev->type && NULL != carlink_event_queue) {
|
||||
xQueueSend(carlink_event_queue, ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_notify_event_isr(struct carlink_event *ev)
|
||||
{
|
||||
if (CARLINK_EVENT_NONE != ev->type && NULL != carlink_event_queue) {
|
||||
xQueueSendFromISR(carlink_event_queue, ev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_send_key_event(uint8_t key, bool pressed)
|
||||
{
|
||||
struct carlink_event ev = {0};
|
||||
ev.type = CARLINK_EVENT_KEY_EVENT;
|
||||
ev.disable_filter = true;
|
||||
ev.u.para[0] = key;
|
||||
ev.u.para[1] = (uint8_t)pressed;
|
||||
|
||||
carlink_notify_event_isr(&ev);
|
||||
}
|
||||
|
||||
|
||||
static void carlink_event_proc(void* param)
|
||||
{
|
||||
struct carlink_event ev;
|
||||
struct ICalinkEventCallbacks *pcb;
|
||||
int i;
|
||||
|
||||
(void)param;
|
||||
|
||||
if (NULL == carlink_event_queue)
|
||||
return;
|
||||
|
||||
while(1) {
|
||||
if (xQueueReceive(carlink_event_queue, &ev, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < gcarlink_event_cbs_count; i++) {
|
||||
pcb = gcarlink_event_cbs[i];
|
||||
if (pcb && pcb->onEvent) {
|
||||
pcb->onEvent(pcb->cb_ctx, &ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void carlink_register_event_callbacks(const struct ICalinkEventCallbacks *pcb)
|
||||
{
|
||||
if (gcarlink_event_cbs_count < 8) {
|
||||
gcarlink_event_cbs[gcarlink_event_cbs_count++] = (struct ICalinkEventCallbacks *)pcb;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int carlink_common_init()
|
||||
{
|
||||
FF_Disk_t *sfdisk = NULL;
|
||||
BaseType_t ret = -1;
|
||||
|
||||
pthread_mutex_lock(&carlink_com_locker);
|
||||
if (g_comm_init_flag) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
carlink_ey_video_init();
|
||||
|
||||
carlink_event_queue = xQueueCreate(16, sizeof(struct carlink_event));
|
||||
if (NULL == carlink_event_queue) {
|
||||
printf("%s:%d failed\n", __func__, __LINE__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
pthread_key_system_init();
|
||||
|
||||
sfdisk = FF_SFDiskInit("/sf");
|
||||
if (!sfdisk) {
|
||||
printf("FF_SFDiskInit fail.\r\n");
|
||||
//return;
|
||||
}
|
||||
|
||||
ret = xTaskCreate(carlink_event_proc, "cl_ev_proc", 2048, NULL, configMAX_PRIORITIES / 5, NULL);
|
||||
g_comm_init_flag = 1;
|
||||
|
||||
exit:
|
||||
if (ret == -1) {
|
||||
}
|
||||
pthread_mutex_unlock(&carlink_com_locker);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
93
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_common.h
Normal file
93
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_common.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef __CARLINK_COMMON_H
|
||||
#define __CARLINK_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CARLINK_CARPLAY = 0x00,
|
||||
CARLINK_CARLIFE,
|
||||
CARLINK_ANDROID_CARLIFE,
|
||||
CARLINK_ANDROID_MIRROR = 3,
|
||||
CARLINK_IOS_CARLIFE,
|
||||
CARLINK_ANDROID_AUTO = 5,
|
||||
CARLINK_ECLINK = 0x06,
|
||||
CARLINK_CARPLAY_WIRELESS,
|
||||
CARLINK_AUTO_WIRELESS,
|
||||
CARLINK_ECLINK_WIRELESS,
|
||||
}CARLink_TYPE;
|
||||
|
||||
|
||||
|
||||
#define CARLINK_VIDEO_WIDTH 800
|
||||
#define CARLINK_VIDEO_HEIGHT 380
|
||||
|
||||
|
||||
|
||||
enum CARLINK_EVENT_TYPE
|
||||
{
|
||||
CARLINK_EVENT_NONE = 0,
|
||||
CARLINK_EVENT_BT_CONNECT,
|
||||
CARLINK_EVENT_BT_IAP_READY,
|
||||
CARLINK_EVENT_BT_AA_RFCOMM_READY,
|
||||
CARLINK_EVENT_BT_DISCONNECT,
|
||||
CARLINK_EVENT_WIFI_DISCONNECT,
|
||||
CARLINK_EVENT_WIFI_CONNECT,
|
||||
|
||||
CARLINK_EVENT_INIT_DONE,
|
||||
CARLINK_EVENT_MSG_SESSION_CONNECT,
|
||||
CARLINK_EVENT_MSG_SESSION_STOP,
|
||||
CARLINK_EVENT_MSG_DISABLE_BT,
|
||||
CARLINK_EVENT_KEY_EVENT
|
||||
};
|
||||
|
||||
struct carlink_event
|
||||
{
|
||||
enum CARLINK_EVENT_TYPE type;
|
||||
CARLink_TYPE link_type;
|
||||
bool disable_filter;
|
||||
union {
|
||||
int len;
|
||||
void* data;
|
||||
uint8_t para[32];
|
||||
}u;
|
||||
};
|
||||
|
||||
struct ICalinkEventCallbacks
|
||||
{
|
||||
void (*onEvent)(void* ctx, const struct carlink_event *ev);
|
||||
void (*rfcomm_data_read)(void* ctx, const void* buf, int len);
|
||||
void* cb_ctx;
|
||||
};
|
||||
|
||||
|
||||
void carlink_notify_event(struct carlink_event *ev);
|
||||
void carlink_notify_event_isr(struct carlink_event *ev);
|
||||
|
||||
void carlink_register_event_callbacks(const struct ICalinkEventCallbacks *pcb);
|
||||
void carlink_rfcomm_data_read_hook(void* buf, int len);
|
||||
int carlink_iap_data_write(unsigned char *data, int len);
|
||||
int carlink_auto_rfcomm_data_write(unsigned char *data, int len);
|
||||
int carlink_bt_wifi_init();
|
||||
int carlink_wlan_tcp_ip_is_ready();
|
||||
void carlink_bt_open();
|
||||
void carlink_bt_close();
|
||||
void carlink_restart_bt_wifi();
|
||||
const char *carlink_get_bt_mac();
|
||||
const char *carlink_get_wifi_p2p_name();
|
||||
const char *carlink_get_wifi_ssid();
|
||||
const char *carlink_get_wifi_passwd();
|
||||
const char *carlink_get_wifi_mac();
|
||||
void carlink_get_ap_ip_addr(char ip[4]);
|
||||
|
||||
|
||||
int carlink_common_init();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
128
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_utils.c
Normal file
128
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_utils.c
Normal file
@ -0,0 +1,128 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "carlink_utils.h"
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
#ifndef min
|
||||
#define min(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
void hex2str(const uint8_t *input, uint16_t input_len, char *output)
|
||||
{
|
||||
char *hexEncode = "0123456789ABCDEF";
|
||||
int i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < input_len; i++) {
|
||||
output[j++] = hexEncode[(input[i] >> 4) & 0xf];
|
||||
output[j++] = hexEncode[(input[i]) & 0xf];
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
#define isDigit(c) (((c) <= '9' && (c) >= '0') ? (1) : (0))
|
||||
|
||||
static uint8_t hex2dec(char hex)
|
||||
{
|
||||
if (isDigit(hex)) {
|
||||
return (hex - '0');
|
||||
}
|
||||
if (hex >= 'a' && hex <= 'f') {
|
||||
return (hex - 'a' + 10);
|
||||
}
|
||||
if (hex >= 'A' && hex <= 'F') {
|
||||
return (hex - 'A' + 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string2hex(char *input, int input_len, char *output, int max_len)
|
||||
{
|
||||
int i = 0;
|
||||
uint8_t ch0, ch1;
|
||||
|
||||
if (input_len % 2 != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (i < input_len / 2 && i < max_len) {
|
||||
ch0 = hex2dec((char)input[2 * i]);
|
||||
ch1 = hex2dec((char)input[2 * i + 1]);
|
||||
output[i] = (ch0 << 4 | ch1);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
void str2asiistr(const char *input, int input_len, char *output, int max_len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (max_len < 2 *input_len)
|
||||
return;
|
||||
|
||||
while (i < input_len) {
|
||||
sprintf(output, "%02x", input[i]);
|
||||
output += 2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_power_of_2(uint32_t n)
|
||||
{
|
||||
return (n != 0 && ((n & (n -1)) == 0));
|
||||
}
|
||||
|
||||
// buffer_size musb be pow of 2
|
||||
int ring_buffer_init( ring_buffer_t *ctx, int buffer_size)
|
||||
{
|
||||
void *base = NULL;
|
||||
if (ctx == NULL || !is_power_of_2(buffer_size))
|
||||
return -1;
|
||||
base = pvPortMalloc(buffer_size);
|
||||
|
||||
ctx->buffer = (uint8_t *)base;
|
||||
//ctx->end = (uint8_t *)base + buffer_size;
|
||||
ctx->size = (uint32_t) buffer_size;
|
||||
ctx->mask = (uint32_t)( buffer_size - 1 );
|
||||
ctx->read_offset = 0;
|
||||
ctx->write_offset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ring_buffer_free( ring_buffer_t *ctx )
|
||||
{
|
||||
if (ctx == NULL || NULL == ctx->buffer)
|
||||
return;
|
||||
vPortFree(ctx->buffer);
|
||||
}
|
||||
|
||||
uint32_t ring_buffer_write(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
len = min(len, ctx->size - ctx->write_offset + ctx->read_offset);
|
||||
|
||||
l = min(len, ctx->size - (ctx->write_offset & (ctx->mask)));
|
||||
memcpy(ctx->buffer + (ctx->write_offset & (ctx->mask)), buffer, l);
|
||||
memcpy(ctx->buffer, buffer + l, len - l);
|
||||
ctx->write_offset += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ring_buffer_read(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
len = min(len, ctx->write_offset - ctx->read_offset);
|
||||
|
||||
l = min(len, ctx->size - (ctx->read_offset & (ctx->mask)));
|
||||
memcpy(buffer, ctx->buffer + (ctx->read_offset & (ctx->mask)), l);
|
||||
memcpy(buffer + l, ctx->buffer, len - l);
|
||||
ctx->read_offset += len;
|
||||
return len;
|
||||
}
|
||||
|
31
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_utils.h
Normal file
31
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_utils.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef __CARLINK_UTILS_H
|
||||
#define __CARLINK_UTILS_H
|
||||
|
||||
void hex2str(const uint8_t *input, uint16_t input_len, char *output);
|
||||
int string2hex(char *input, int input_len, char *output, int max_len);
|
||||
void str2asiistr(const char *input, int input_len, char *output, int max_len);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t * buffer;
|
||||
//const uint8_t * end;
|
||||
uint32_t size;
|
||||
uint32_t mask;
|
||||
uint32_t read_offset;
|
||||
uint32_t write_offset;
|
||||
} ring_buffer_t;
|
||||
|
||||
int ring_buffer_init( ring_buffer_t *ctx, int buffer_size);
|
||||
void ring_buffer_free( ring_buffer_t *ctx );
|
||||
uint32_t ring_buffer_write(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len);
|
||||
uint32_t ring_buffer_read(ring_buffer_t *ctx, uint8_t *buffer, uint32_t len);
|
||||
|
||||
/*#define ring_buffer_get_read_ptr( RING ) ( &(RING)->buffer[ (RING)->read_offset & (RING)->mask ] )
|
||||
#define ring_buffer_get_write_ptr( RING ) ( &(RING)->buffer[ (RING)->write_offset & (RING)->mask ] )
|
||||
#define ring_buffer_read_advance( RING, COUNT ) do { (RING)->read_offset += (COUNT); } while( 0 )
|
||||
#define ring_buffer_write_advance( RING, COUNT ) do { (RING)->write_offset += (COUNT); } while( 0 )
|
||||
#define ring_buffer_reset( RING ) do { (RING)->read_offset = (RING)->write_offset; } while( 0 )*/
|
||||
#define ring_buffer_get_bytes_used( RING ) ( (uint32_t)( (RING)->write_offset - (RING)->read_offset ) )
|
||||
#define ring_buffer_get_bytes_free( RING ) ( (RING)->size - ring_buffer_get_bytes_used( RING ) )
|
||||
|
||||
#endif
|
372
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_video.c
Normal file
372
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_video.c
Normal file
@ -0,0 +1,372 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "carlink_video.h"
|
||||
#include "mfcapi.h"
|
||||
#include "lcd.h"
|
||||
#include "pxp.h"
|
||||
#include "cp15/cp15.h"
|
||||
#include "timer.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
#include "os_adapt.h"
|
||||
#include "ff_stdio.h"
|
||||
|
||||
static List_t frame_free_list;
|
||||
static List_t frame_ready_list;
|
||||
static video_frame_s h264_frame_fifos[H264_FRAME_FIFO_COUNT];
|
||||
static char* h264_buf = NULL;
|
||||
static SemaphoreHandle_t frame_list_mutex = NULL;
|
||||
static TaskHandle_t dec_h264_handle;
|
||||
static QueueHandle_t h264_frame_queue;
|
||||
static uint8_t g_init_flag = 0;
|
||||
static uint8_t g_video_start = 0;
|
||||
static int g_disp_x = 0, g_disp_y = 0, g_disp_width = LCD_WIDTH, g_disp_height = LCD_HEIGHT;
|
||||
static int g_video_width = LCD_WIDTH, g_video_height = LCD_HEIGHT, g_video_fps = 30;
|
||||
static int g_hide_carlink_flag = 0;
|
||||
|
||||
static int g_active_video_x = 0, g_active_video_y = 0;
|
||||
|
||||
void set_carlink_active_video_info(int x, int y)//for android auto
|
||||
{
|
||||
g_active_video_x = x;
|
||||
g_active_video_y = y;
|
||||
}
|
||||
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps)
|
||||
{
|
||||
g_video_width = w;
|
||||
g_video_height = h;
|
||||
g_video_fps = fps;
|
||||
}
|
||||
|
||||
int get_carlink_video_width()
|
||||
{
|
||||
return g_video_width;
|
||||
}
|
||||
|
||||
int get_carlink_video_height()
|
||||
{
|
||||
return g_video_height;
|
||||
}
|
||||
|
||||
int get_carlink_video_fps()
|
||||
{
|
||||
return g_video_fps;
|
||||
}
|
||||
|
||||
void set_carlink_display_info(int x, int y, int w, int h)
|
||||
{
|
||||
g_disp_x = x;
|
||||
g_disp_y = y;
|
||||
g_disp_width = w;
|
||||
g_disp_height = h;
|
||||
}
|
||||
|
||||
static void h264_frame_list_reset()
|
||||
{
|
||||
video_frame_s *buffer;
|
||||
int i;
|
||||
|
||||
buffer = (video_frame_s *)h264_frame_fifos;
|
||||
vListInitialise(&frame_free_list);
|
||||
vListInitialise(&frame_ready_list);
|
||||
for(i = 0; i < H264_FRAME_FIFO_COUNT; i++) {
|
||||
buffer->buf = (char *)(((unsigned int)h264_buf + i * H264_FRAME_BUF_SIZE));
|
||||
buffer->cur = buffer->buf;
|
||||
buffer->frame_id = i;
|
||||
buffer->len = 0;
|
||||
vListInitialiseItem(&buffer->entry);
|
||||
vListInsertEnd(&frame_free_list, &buffer->entry);
|
||||
listSET_LIST_ITEM_OWNER(&buffer->entry, buffer);
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
static int h264_frame_buf_init(void)
|
||||
{
|
||||
h264_buf = pvPortMalloc(H264_FRAME_FIFO_COUNT * H264_FRAME_BUF_SIZE );
|
||||
if (h264_buf == NULL) {
|
||||
printf("malloc jpeg buf failed\r\n");
|
||||
return -1;
|
||||
}
|
||||
h264_frame_list_reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void h264_dec_ctx_init()
|
||||
{
|
||||
g_video_start = 0;
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
void set_carlink_display_state(int on)
|
||||
{
|
||||
g_hide_carlink_flag = on;
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
void set_carlink_display_state_irq(int on)
|
||||
{
|
||||
g_hide_carlink_flag = on;
|
||||
|
||||
xQueueSendFromISR(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
video_frame_s* get_h264_frame_buf()
|
||||
{
|
||||
video_frame_s* frame = NULL;
|
||||
ListItem_t* item = NULL;
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (g_video_start && !listLIST_IS_EMPTY(&frame_free_list)) {
|
||||
frame = list_first_entry(&frame_free_list);
|
||||
item = listGET_HEAD_ENTRY(&frame_free_list);
|
||||
uxListRemove(item);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
return frame;
|
||||
}
|
||||
|
||||
|
||||
void notify_h264_frame_ready(video_frame_s** frame)
|
||||
{
|
||||
//ListItem_t* item = NULL;
|
||||
video_frame_s * tmp = *frame;
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (NULL != tmp) {
|
||||
vListInsertEnd(&frame_ready_list, &tmp->entry);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
xQueueSend(h264_frame_queue, NULL, 0);
|
||||
}
|
||||
|
||||
void set_h264_frame_free(video_frame_s* frame)
|
||||
{
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (g_video_start) {
|
||||
frame->cur = frame->buf;
|
||||
frame->len = 0;
|
||||
vListInsertEnd(&frame_free_list, &frame->entry);
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
}
|
||||
uint8_t map_flag = 0;
|
||||
static void h264_decode_proc(void *pvParameters)
|
||||
{
|
||||
MFCHandle *handle = NULL;
|
||||
DWLLinearMem_t inBuf;
|
||||
OutFrameBuffer outBuf = {0};
|
||||
int ret = -1, i;
|
||||
uint32_t align_width, align_height;
|
||||
uint32_t yaddr, uaddr, vaddr, dstaddr;
|
||||
video_frame_s* frame = NULL;
|
||||
uint32_t ts = get_timer(0), show_ts = 0, video_ts = 0;
|
||||
int32_t delta_ts = 0;;
|
||||
int carlink_lcd_take = 0;
|
||||
ListItem_t* item = NULL;
|
||||
//FF_FILE *fp = ff_fopen("/usb/ey.h264", "w+");
|
||||
|
||||
handle = mfc_init(RAW_STRM_TYPE_H264_NOREORDER);
|
||||
if(!handle) {
|
||||
printf("%s, mfc_init failed.\r\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
g_video_start = 1;
|
||||
while(1) {
|
||||
if (xQueueReceive(h264_frame_queue, NULL, portMAX_DELAY) != pdPASS) {
|
||||
printf("%s xQueueReceive err!\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
if (g_video_start == 0) {
|
||||
printf("dec uninit\r\n");
|
||||
if (carlink_lcd_take) {
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
vVideoDisplayBufGive();
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
carlink_lcd_take = 0;
|
||||
}
|
||||
mfc_uninit(handle);
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
h264_frame_list_reset();
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
xQueueReset(h264_frame_queue);
|
||||
handle = mfc_init(RAW_STRM_TYPE_H264_NOREORDER);
|
||||
if(!handle) {
|
||||
printf("%s, mfc_reinit failed.\r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
g_video_start = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (g_hide_carlink_flag == 0) {
|
||||
if(map_flag)
|
||||
map_flag = 0;
|
||||
printf("Exit navigation =========\r\n ");
|
||||
Set_sys_wifi_state(0);
|
||||
//printf("start carplay or andrord auto .\r\n");
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 0);
|
||||
ark_lcd_osd_enable(LCD_UI_LAYER, 1);
|
||||
}
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
if (!listLIST_IS_EMPTY(&frame_ready_list)) {
|
||||
frame = list_first_entry(&frame_ready_list);
|
||||
item = listGET_HEAD_ENTRY(&frame_ready_list);
|
||||
uxListRemove(item);
|
||||
} else {
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
continue;
|
||||
}
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
memset(&outBuf, 0, sizeof(OutFrameBuffer));
|
||||
inBuf.busAddress = (u32)frame->cur;
|
||||
inBuf.virtualAddress = (u32 *)inBuf.busAddress;
|
||||
inBuf.size = frame->len;
|
||||
CP15_clean_dcache_for_dma(inBuf.busAddress, inBuf.busAddress + inBuf.size);
|
||||
ts = get_timer(0);
|
||||
//printf("start dec...\r\n");
|
||||
ret = mfc_decode(handle, &inBuf, &outBuf);
|
||||
//ret = 0;
|
||||
//if (NULL != fp)
|
||||
// ret = ff_fwrite((void*)inBuf.virtualAddress, 1, inBuf.size, fp);
|
||||
|
||||
xSemaphoreTake(frame_list_mutex, portMAX_DELAY);
|
||||
frame->cur = frame->buf;
|
||||
frame->len = 0;
|
||||
vListInsertEnd(&frame_free_list, &frame->entry);
|
||||
xSemaphoreGive(frame_list_mutex);
|
||||
|
||||
if (ret < 0) {
|
||||
printf("h264 decode fail.\n");
|
||||
continue;
|
||||
}//printf("dec num:%d use:%d ms\r\n", outBuf.num, (get_timer(0) - ts) / 1000);
|
||||
//continue;
|
||||
|
||||
for(i = 0; i < outBuf.num; i++) {
|
||||
int active_offset = 0;
|
||||
align_width = outBuf.frameWidth;
|
||||
align_height = outBuf.frameHeight;
|
||||
|
||||
if(!(align_width && align_height))
|
||||
continue;
|
||||
active_offset = g_active_video_y * align_width;
|
||||
yaddr = outBuf.buffer[i].yBusAddress + active_offset + g_active_video_x;
|
||||
uaddr = outBuf.buffer[i].yBusAddress + align_width * align_height + active_offset / 2 + g_active_video_x;
|
||||
vaddr = 0;//yaddr + align_width * align_height * 5/4;
|
||||
|
||||
if (carlink_lcd_take == 0) {
|
||||
carlink_lcd_take = 1;
|
||||
xVideoDisplayBufTake(portMAX_DELAY);
|
||||
}
|
||||
if (carlink_lcd_take) {
|
||||
LcdOsdInfo info = {0};
|
||||
|
||||
if (0 == g_hide_carlink_flag)
|
||||
continue;
|
||||
|
||||
show_ts = get_timer(0);
|
||||
|
||||
info.format = LCD_OSD_FORAMT_YUV420; //set default format.
|
||||
if ((info.format == LCD_OSD_FORAMT_RGB565) || \
|
||||
(g_disp_width != g_video_width) || (g_disp_height != g_video_height)) {
|
||||
uint32_t pxp_width, pxp_height;
|
||||
int pxp_out_fmt = PXP_OUT_FMT_YUV2P420;
|
||||
|
||||
if(info.format == LCD_OSD_FORAMT_RGB565)
|
||||
pxp_out_fmt = PXP_OUT_FMT_RGB565;
|
||||
|
||||
//align_width = ((outBuf.frameWidth + 0xf) & (~0xf));
|
||||
if (outBuf.frameWidth != g_video_width)
|
||||
align_width = g_video_width;
|
||||
else
|
||||
align_width = outBuf.frameWidth ;
|
||||
if (outBuf.frameHeight != g_video_height)
|
||||
align_height = g_video_height;
|
||||
else
|
||||
align_height = outBuf.frameHeight;
|
||||
|
||||
pxp_width = g_disp_width;
|
||||
pxp_height = g_disp_height;
|
||||
dstaddr = ulVideoDisplayBufGet();
|
||||
|
||||
pxp_scaler_rotate(yaddr, uaddr, vaddr, PXP_SRC_FMT_YUV2P420, align_width, align_height,
|
||||
dstaddr, dstaddr + pxp_width * pxp_height, pxp_out_fmt, pxp_width, pxp_height, LCD_ROTATE_ANGLE);
|
||||
info.yaddr = dstaddr;
|
||||
info.uaddr = dstaddr + pxp_width * pxp_height;
|
||||
info.vaddr = 0;
|
||||
} else {
|
||||
info.yaddr = yaddr;
|
||||
info.uaddr = uaddr;
|
||||
info.vaddr = vaddr;
|
||||
}
|
||||
info.x = g_disp_x;
|
||||
info.y = g_disp_y;
|
||||
info.width = g_disp_width;
|
||||
info.height = g_disp_height;
|
||||
if (g_active_video_x != 0)
|
||||
info.stride = outBuf.frameWidth;
|
||||
|
||||
if (info.format == LCD_OSD_FORAMT_YUV420)
|
||||
ark_lcd_set_osd_yuv420_mode(LCD_VIDEO_LAYER, LCD_OSD_Y_UV420);
|
||||
|
||||
if (!ark_lcd_get_osd_info_atomic_isactive(LCD_VIDEO_LAYER)) {
|
||||
ark_lcd_wait_for_vsync();
|
||||
}
|
||||
|
||||
ark_lcd_set_osd_info_atomic(LCD_VIDEO_LAYER, &info);
|
||||
ark_lcd_osd_enable(LCD_VIDEO_LAYER, 1);
|
||||
ark_lcd_set_osd_sync(LCD_VIDEO_LAYER);
|
||||
Set_sys_wifi_state(1);
|
||||
// ark_lcd_osd_enable(LCD_UI_LAYER, 0);
|
||||
ark_lcd_set_osd_sync(LCD_UI_LAYER);
|
||||
vVideoDisplayBufRender(dstaddr);
|
||||
if (outBuf.num > 1) {// for apple h264
|
||||
video_ts = (1000 / g_video_fps);
|
||||
show_ts = (get_timer(0) - show_ts) / 1000;
|
||||
delta_ts = ((int32_t)video_ts - (int32_t)show_ts) -3;
|
||||
//printf("delay %d ms\r\n", delta_ts);
|
||||
if (delta_ts > 0)
|
||||
vTaskDelay(pdMS_TO_TICKS(delta_ts));
|
||||
}
|
||||
if(!map_flag){
|
||||
// printf("###############################################.\r\n");
|
||||
request_UI("maps:");
|
||||
map_flag = 1;
|
||||
// printf("###############################################.\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//printf("all use:%d ms dec:%ld ms all ts:%ld ms\r\n", (get_timer(0) - ts) / 1000, dec_ts, (get_timer(0) - all_ts) / 1000);
|
||||
//all_ts = get_timer(0);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (NULL != handle)
|
||||
mfc_uninit(handle);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
int carlink_ey_video_init()
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (g_init_flag ==1) {
|
||||
return 0;
|
||||
}
|
||||
g_init_flag = 1;
|
||||
ret = h264_frame_buf_init();
|
||||
frame_list_mutex = xSemaphoreCreateMutex();
|
||||
//h264_frame_queue = xQueueCreate(H264_FRAME_FIFO_COUNT, sizeof(uint32_t));
|
||||
h264_frame_queue = xQueueCreate(1, 0);
|
||||
ret = xTaskCreate(h264_decode_proc, "h264_decode_proc", 2048 * 4, NULL, configMAX_PRIORITIES - 3, &dec_h264_handle);
|
||||
return ret;
|
||||
}
|
99
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_video.h
Normal file
99
MXC_A27-PCB4.5-270T/app/carlink/common/carlink_video.h
Normal file
@ -0,0 +1,99 @@
|
||||
#ifndef __CARLINK_VIDEO_H
|
||||
#define __CARLINK_VIDEO_H
|
||||
#include <FreeRTOS.h>
|
||||
#include "board.h"
|
||||
#include "list.h"
|
||||
|
||||
#define H264DEC_INBUF_SIZE (LCD_WIDTH * LCD_HEIGHT * 2)
|
||||
#define H264DEC_DISP_COUNTS (2)
|
||||
#define H264_FRAME_FIFO_COUNT (12)
|
||||
#define H264_FRAME_BUF_SIZE (0x80000)
|
||||
|
||||
typedef struct h264_frame_s {
|
||||
char* buf;
|
||||
char* cur;
|
||||
unsigned int len;
|
||||
unsigned int frame_id;
|
||||
ListItem_t entry;
|
||||
} video_frame_s;
|
||||
|
||||
video_frame_s* get_h264_frame_buf(void);
|
||||
void notify_h264_frame_ready(video_frame_s** frame);
|
||||
void set_h264_frame_free(video_frame_s* frame);
|
||||
void h264_dec_ctx_init();
|
||||
int carlink_ey_video_init();
|
||||
int get_carlink_video_width(void);
|
||||
int get_carlink_video_height(void);
|
||||
int get_carlink_video_fps(void);
|
||||
|
||||
void set_carlink_video_info(int w, int h, int fps);//set h264 video stream info from phone
|
||||
void set_carlink_display_info(int x, int y, int w, int h);//set carlink show area in lcd
|
||||
void set_carlink_display_state(int on); // on: 1.display carlink; 0. display native ui
|
||||
void set_carlink_active_video_info(int x, int y);//for android auto
|
||||
|
||||
#define WRITE_BE32(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) >> 24; \
|
||||
*__ptr++ = ((val) & 0x00FF0000) >> 16; \
|
||||
*__ptr++ = ((val) & 0x0000FF00) >> 8; \
|
||||
*__ptr = ((val) & 0x000000FF); \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_BE16(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) >> 8; \
|
||||
*__ptr = (val) & 0x00FF; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define READ_BE32(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = (*__ptr++) << 24; \
|
||||
(dest) |= (*__ptr++) << 16; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
(dest) |= *__ptr; \
|
||||
} while (0)
|
||||
|
||||
#define READ_BE16(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = (*__ptr++) << 8; \
|
||||
(dest) |= *__ptr; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_LE32(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = ((val) & 0x000000FF); \
|
||||
*__ptr++ = ((val) & 0x0000FF00) >> 8; \
|
||||
*__ptr++ = ((val) & 0x00FF0000) >> 16; \
|
||||
*__ptr = (val) >> 24; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_LE16(ptr, val) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
*__ptr++ = (val) & 0x00FF; \
|
||||
*__ptr = (val) >> 8; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define READ_LE32(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = *__ptr; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
(dest) |= (*__ptr++) << 16; \
|
||||
(dest) |= (*__ptr++) << 24; \
|
||||
} while (0)
|
||||
|
||||
#define READ_LE16(ptr, dest) \
|
||||
do { \
|
||||
uint8_t* __ptr = (uint8_t*)(ptr); \
|
||||
(dest) = *__ptr; \
|
||||
(dest) |= (*__ptr++) << 8; \
|
||||
} while (0)
|
||||
#endif
|
153
MXC_A27-PCB4.5-270T/app/carlink/common/mycommon.h
Normal file
153
MXC_A27-PCB4.5-270T/app/carlink/common/mycommon.h
Normal file
@ -0,0 +1,153 @@
|
||||
#ifndef MYCOMMON_H_H
|
||||
#define MYCOMMON_H_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef CARLINK_LINK_TYPE
|
||||
#define CARLINK_LINK_TYPE
|
||||
typedef enum
|
||||
{
|
||||
CARPLAY = 0x00,
|
||||
CARLIFE,
|
||||
ANDROID_CARLIFE,
|
||||
ANDROID_MIRROR = 3,
|
||||
IOS_CARLIFE,
|
||||
ANDROID_AUTO = 5,
|
||||
ECLINK = 0x06,
|
||||
CARPLAY_WIRELESS,
|
||||
AUTO_WIRELESS
|
||||
}Link_TYPE;
|
||||
#endif
|
||||
|
||||
//general function
|
||||
typedef enum __USB_MODE
|
||||
{
|
||||
UNDEFINED = 0,
|
||||
HOST,
|
||||
PERIPHERAL,
|
||||
OTG
|
||||
}USB_MODE;
|
||||
|
||||
#define LOGV(...) printf(__VA_ARGS__); printf("\r\n");
|
||||
|
||||
struct view_area
|
||||
{
|
||||
short w;
|
||||
short h;
|
||||
short x;
|
||||
short y;
|
||||
};
|
||||
|
||||
typedef struct __carplay_cfg_info
|
||||
{
|
||||
char *iap2_name;
|
||||
char *iap2_modelIdentifier;
|
||||
char *iap2_manfacturer;
|
||||
char *iap2_serialnumber;
|
||||
char *iap2_sw_ver;
|
||||
char *iap2_hw_ver;
|
||||
char *iap2_vehicleInfo_name;
|
||||
char *iap2_product_uuid;
|
||||
char *iap2_usb_serial_num;
|
||||
|
||||
char *manfacturer;
|
||||
char *oem_icon_label;
|
||||
char *oem_icon_path;
|
||||
char *os_info;
|
||||
char *iOSVersionMin;
|
||||
char *limited_ui_elements;
|
||||
char *guuid;
|
||||
char *devid;
|
||||
char link_type;
|
||||
char btmac[6];
|
||||
bool oem_icon_visible;
|
||||
bool limited_ui;
|
||||
bool right_hand_driver;
|
||||
bool night_mode;
|
||||
bool has_knob;
|
||||
bool has_telbutton;
|
||||
bool has_mediabutton;
|
||||
bool has_proxsensor;
|
||||
bool has_EnhancedReqCarUI;
|
||||
bool has_ETCSupported;
|
||||
bool HiFiTouch;
|
||||
bool LoFiTouch;
|
||||
unsigned short usb_country_code;
|
||||
unsigned short tp_verndor_code;
|
||||
unsigned short tp_product_code;
|
||||
unsigned short tel_verndor_code;
|
||||
unsigned short tel_product_code;
|
||||
unsigned short knob_verndor_code;
|
||||
unsigned short knob_product_code;
|
||||
unsigned short proxsensor_verndor_code;
|
||||
unsigned short proxsensor_product_code;
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
short screen_width_phy;//mm
|
||||
short screen_height_phy;
|
||||
|
||||
char encrypt_ic_i2c_bus_num;
|
||||
char encrypt_ic_addr;
|
||||
char usb_idx;
|
||||
char need_sw_aec;
|
||||
char aec_delay;
|
||||
bool tvout_enable;
|
||||
|
||||
bool use_remote_audio;
|
||||
char video_type;
|
||||
short icurrent;
|
||||
int duck_vol;
|
||||
|
||||
char enable_iap_carplay_sess;
|
||||
char *keychain_path_dir;
|
||||
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char* public_key;
|
||||
char* src_version;
|
||||
char ip_v4_addr[4];
|
||||
char wifi_channel;
|
||||
short net_port;
|
||||
|
||||
char carplay_net_ready;
|
||||
char disable_bonjour;
|
||||
char iap_carplay_rej;
|
||||
|
||||
bool enable_enhanced_siri;
|
||||
bool enable_single_ui;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
short mfi_ic_i2c_bus_num;
|
||||
short mfi_ic_addr;
|
||||
|
||||
bool is_old_carplay_ver;
|
||||
|
||||
struct view_area area[3];
|
||||
char view_area_index;
|
||||
|
||||
}carplay_cfg_info;
|
||||
|
||||
typedef struct __auto_cfg_info
|
||||
{
|
||||
short width;//pixel
|
||||
short height;
|
||||
short fps;
|
||||
char* wifi_ssid;
|
||||
char* wifi_passwd;
|
||||
char wifi_channel;
|
||||
bool disable_carplay_audio;
|
||||
|
||||
} auto_cfg_info;
|
||||
|
||||
|
||||
extern carplay_cfg_info *g_link_info;
|
||||
extern auto_cfg_info *g_auto_link_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
Reference in New Issue
Block a user