MAX_CARLINK_A270S/MXC_A27-PCB4.5-270T/app/carlink/EY/carlink_ey.c

838 lines
30 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <FreeRTOS.h>
#include <task.h>
#include "FreeRTOS_IP.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_Sockets.h"
#include "mmcsd_core.h"
#include "mfcapi.h"
#include "board.h"
#include "lcd.h"
#include "timer.h"
#include "FreeRTOS_DHCP.h"
#include "FreeRTOS_DHCP_Server.h"
#include "carlink_video.h"
#include "carlink_ey_audio.h"
#include "carlink_ey.h"
#include "console.h"
#include "iot_wifi.h"
#include "carlink_utils.h"
#if CARLINK_EY
#define EY_BT_EVENT_CONNECT 0
#define EY_BT_EVENT_DISCONNECT 1
#define EY_BT_EVENT_NOTIFY_PHONE_TYPE 2
#define EY_BT_EVENT_NOTIFY_SSID 3
#define EY_BT_EVENT_NOTIFY_PASSWD 4
#define EY_BT_EVENT_NOTIFY_CONNECT_STATUS 5
#define EY_BT_EVENT_NOTIFY_PHONE_AP_READY 6
#define EY_BT_EVENT_NOTIFY_USE_TCP 7
#define EY_BT_EVENT_BLE_CONNECT 8
#define EY_CARLINK_EVENT_CONNECT 9
#define EY_CARLINK_EVENT_DISCONNECT 10
struct bt_event
{
int type;
uint8_t para[32];
};
static uint8_t gbt_ready = 0;
static TaskHandle_t ey_bt_task = NULL;
static TaskHandle_t ey_network_task = NULL;
static QueueHandle_t ey_bt_event_queue = NULL;
static const uint8_t ucIPAddress[4] = {192, 168, 13, 1};
static const uint8_t ucNetMask[4] = {255, 255, 255, 0};
static const uint8_t ucGatewayAddress[4] = {0, 0, 0, 0};
static const uint8_t ucDNSServerAddress[4] = {8, 8, 8, 8};
static const uint8_t ucMACAddress[6] = {0x30, 0x4a, 0x26, 0x78, 0xfd, 0x12};
static uint8_t ap_ssid[64] = {"ap63011"};
static uint8_t ap_passwd[16] = {"88888888"};
static uint8_t gphone_type = 0;
//static uint8_t guse_tcp = 1;
static int gWifiOn = 0;
//static int gWIfiConnecting = 0;
static Socket_t gClientSocket = FREERTOS_INVALID_SOCKET, gXClientSocket = FREERTOS_INVALID_SOCKET;
static SemaphoreHandle_t gSocketMutex = NULL;
void cmd_test(const char* temp_uart_buf);
static void ey_reset_wifi_ap_info(const char *btmac)
{
sprintf((char *)ap_ssid, "AP630_%s", btmac);
}
static void notify_carlink_state(int state)
{
struct bt_event ev = {0};
ev.type = -1;
if (state == 0) {
ev.type = EY_CARLINK_EVENT_DISCONNECT;
} else {
ev.type = EY_CARLINK_EVENT_CONNECT;
}
if (0 != ev.type && NULL != ey_bt_event_queue) {
xQueueSend(ey_bt_event_queue, &ev, 0);
}
}
static void notify_phone_ip_addr(uint32_t ipAddr);
static void ey_wifi_start_ap(const uint8_t* ssid, const uint8_t* passwd, int channel)
{
char cmd[64] = {0};
uint32_t IPAddress = (32 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
if (gWifiOn == 0) {
printf("Turning on wifi ap...\r\n");
WIFI_SetMode(eWiFiModeAP);
gWifiOn = 1;
//WIFI_On();
sprintf(cmd, "wifi_ap %s %d %s", ssid, channel, passwd);
cmd_test(cmd);
IPAddress = (20 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
dhcpserver_start(ucIPAddress, IPAddress, 10);
}
}
#define ucNumNetworks 12
static int ey_wifi_connect_remote_ap(const char* ssid, const char* passwd)
{
WIFINetworkParams_t xNetworkParams = {0};
WIFIReturnCode_t xWifiStatus;
int retry = 0;
WIFI_Context_init();
if (gWifiOn == 0) {
WIFI_SetMode(eWiFiModeStation);
printf("Turning on wifi...\r\n");
xWifiStatus = WIFI_On();
printf("Checking status...\r\n");
if( xWifiStatus == eWiFiSuccess ) {
printf("WiFi module initialized.\r\n");
} else {
printf("WiFi module failed to initialize.\r\n" );
return -1;
}
gWifiOn = 1;
}
#if 0
while (1) {
printf("Starting scan\r\n");
WIFIScanResult_t xScanResults[ ucNumNetworks ] = {0};
xWifiStatus = WIFI_Scan( xScanResults, ucNumNetworks ); // Initiate scan
printf("Scan started\r\n");
// For each scan result, print out the SSID and RSSI
if ( xWifiStatus == eWiFiSuccess ) {
printf("Scan success\r\n");
for ( uint8_t i=0; i < ucNumNetworks; i++ ) {
printf("%s : %d \r\n", xScanResults[i].ucSSID, xScanResults[i].cRSSI);
}
break;
} else {
printf("Scan failed, status code: %d\n", (int)xWifiStatus);
goto exit;
//return -1;
}
vTaskDelay(200);
}
#endif
memset(&xNetworkParams, 0, sizeof(xNetworkParams));
xNetworkParams.ucSSIDLength = strlen( ssid );
memcpy(xNetworkParams.ucSSID, ssid, xNetworkParams.ucSSIDLength);
xNetworkParams.xPassword.xWPA.ucLength = strlen( passwd );
memcpy(xNetworkParams.xPassword.xWPA.cPassphrase, passwd, xNetworkParams.xPassword.xWPA.ucLength);
xNetworkParams.xSecurity = eWiFiSecurityWPA2;
wifi_conn_retry:
xWifiStatus = WIFI_ConnectAP( &( xNetworkParams ) );
if( xWifiStatus == eWiFiSuccess ) {
printf( "WiFi Connected to AP.\r\n" );
} else {
printf( "WiFi failed to connect to AP.\r\n" );
if (retry++ < 15) {vTaskDelay(pdMS_TO_TICKS(300));
goto wifi_conn_retry;}
return -1;
}
return 0;
}
#if ( ipconfigUSE_DHCP_HOOK != 0 )
eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase,
uint32_t ulIPAddress )
{
eDHCPCallbackAnswer_t eReturn;
//uint32_t ulStaticIPAddress, ulStaticNetMask;
char ip_str[20] = {0};
//const uint8_t ucIPAddressDef[4] = {192, 168, 13, 37};
sprintf(ip_str, "%d.%d.%d.%d\r\n", (ulIPAddress >> 0) & 0xFF,
(ulIPAddress >> 8) & 0xFF, (ulIPAddress >> 16) & 0xFF, (ulIPAddress >> 24) & 0xFF);
printf("\r\n eDHCPPhase:%d ulIPAddress:%s state:%d \r\n", eDHCPPhase, ip_str, getDhcpClientState());
if (getDhcpClientState() == 0)
return eDHCPStopNoChanges;
switch( eDHCPPhase )
{
case eDHCPPhaseFinished:
notify_phone_ip_addr(ulIPAddress);//FreeRTOS_GetIPAddress()
eReturn = eDHCPContinue;
break;
case eDHCPPhasePreDiscover :
eReturn = eDHCPContinue;
break;
case eDHCPPhasePreRequest :
eReturn = eDHCPContinue;
break;
default :
eReturn = eDHCPContinue;
break;
}
return eReturn;
}
#endif
static void notify_phone_ip_addr(uint32_t ipAddr)
{
char at_cmd[64] = {0};
if (!gbt_ready)
return;
memset(at_cmd, 0, sizeof(at_cmd));
//uint32_t IPAddress = (32 << 24) | (13 << 16) | (168 << 8) | (192 << 0);
sprintf(at_cmd, "AT+IPADDR=%d.%d.%d.%d\r\n", (ipAddr >> 0) & 0xFF,
(ipAddr >> 8) & 0xFF, (ipAddr >> 16) & 0xFF, (ipAddr >> 24) & 0xFF);
printf("at_cmd:%s\r\n", at_cmd);
console_send_atcmd(at_cmd, strlen(at_cmd));
}
static void notify_iphone_ssid_passwd()
{
char at_cmd[128] = {0};
char bt_ssid_hex_str[64] = {0};
char bt_passwd_hex_str[32] = {0};
if (!gbt_ready)
return;
memset(at_cmd, 0, sizeof(at_cmd));
str2asiistr((const char *)ap_ssid, strlen((const char *)ap_ssid), bt_ssid_hex_str, 2 * strlen((const char *)ap_ssid));
printf("bt_ssid_hex_str:%s\r\n", bt_ssid_hex_str);
sprintf(at_cmd, "AT+GATTSET=AAA2%s\r\n", bt_ssid_hex_str);
printf("ssid at:%s ||| \r\n", at_cmd);
console_send_atcmd(at_cmd, strlen(at_cmd));
memset(at_cmd, 0, sizeof(at_cmd));
str2asiistr((const char *)ap_passwd, strlen((const char *)ap_passwd), bt_passwd_hex_str, 2 * strlen((const char *)ap_passwd));
sprintf(at_cmd, "AT+GATTSET=AAA3%s\r\n", bt_passwd_hex_str);
printf("passwd at:%s\r\n", at_cmd);
console_send_atcmd(at_cmd, strlen(at_cmd));
}
static void notify_iphone_ap_connect_status(int status)
{
char at_cmd[128] = {0};
char json_str[64] = {0};
char json_hex_str[128] = {0};
if (!gbt_ready)
return;
sprintf(json_str, "{\"fun\": \"hotspot\",\"type\": \"%d\"}", status);
printf("\r\n%s \r\n", json_str);
str2asiistr(json_str, strlen(json_str), json_hex_str, 2 * strlen(json_str));
sprintf(at_cmd, "AT+GATTSET=AAA7%s\r\n", json_hex_str);
printf("ssid at:%s\r\n", at_cmd);
console_send_atcmd(at_cmd, strlen(at_cmd));
}
static int readn(Socket_t xSocket, uint8_t * pvBuffer, size_t uxBufferLength)
{
int totalLen = 0, lBytes, retry_count = 0;
while (uxBufferLength > 0) {
lBytes = FreeRTOS_recv( xSocket, (void *)pvBuffer, uxBufferLength, 0);
if (lBytes < 0) {
printf("FreeRTOS_recv err:%d\r\n", lBytes);
totalLen = -1;
break;
}
if (lBytes == 0) {
printf("FreeRTOS_recv lBytes:%d\r\n", lBytes);
if (retry_count++ > 1)
break;
}
pvBuffer += lBytes;
uxBufferLength -= lBytes;
totalLen += lBytes;
}
return totalLen;
}
static void set_socket_win(Socket_t xSockets)
{
WinProperties_t xWinProperties;
memset(&xWinProperties, '\0', sizeof xWinProperties);
xWinProperties.lTxBufSize = ipconfigIPERF_TX_BUFSIZE; /* Units of bytes. */
xWinProperties.lTxWinSize = ipconfigIPERF_TX_WINSIZE; /* Size in units of MSS */
xWinProperties.lRxBufSize = ipconfigIPERF_RX_BUFSIZE; /* Units of bytes. */
xWinProperties.lRxWinSize = ipconfigIPERF_RX_WINSIZE; /* Size in units of MSS */
FreeRTOS_setsockopt( xSockets, 0, FREERTOS_SO_WIN_PROPERTIES, ( void * ) &xWinProperties, sizeof( xWinProperties ) );
}
static void ey_send_hu_info(Socket_t xSockets)
{
uint8_t reply[13] = {0};
reply[0] = 'O'; reply[1] = 'K';
WRITE_LE16(reply + 2, get_carlink_video_width());
WRITE_LE16(reply + 4, get_carlink_video_height());
WRITE_LE16(reply + 6, get_carlink_video_width());
WRITE_LE16(reply + 8, get_carlink_video_height());
reply[10] = get_carlink_video_fps();
WRITE_LE16(reply + 11, 2000);
FreeRTOS_send(xSockets, reply, sizeof(reply), 0);
}
uint32_t gey_ts = 0;
#define EY_DEBUG 0
static void ey_network_task_proc(void* arg)
{
SocketSet_t xFD_Set;
BaseType_t xResult;
Socket_t xSockets = FREERTOS_INVALID_SOCKET;
Socket_t xClientSocket = FREERTOS_INVALID_SOCKET;
Socket_t xXSSockets = FREERTOS_INVALID_SOCKET;
Socket_t xXSClientSocket = FREERTOS_INVALID_SOCKET;
static const TickType_t xNoTimeOut = pdMS_TO_TICKS( 2000 );
struct freertos_sockaddr xAddress, xRemoteAddr;
uint32_t xClientLength = sizeof( struct freertos_sockaddr );
int32_t lBytes;
uint8_t *header_ptr;
msg_header header;
#if EY_DEBUG
void *h264SrcBuf = NULL;
#endif
uint8_t *h264SrcBufPtr = NULL;
int32_t h264SrcSize = 0;
int i;
video_frame_s* frame = NULL;
TickType_t xBlockingTime = pdMS_TO_TICKS( 2000 );uint32_t ts/*, r_ts*/;
int cur_data_size = 0, pre_data_size = 0, retry_count;
int err_flag = 0;
#if EY_DEBUG
h264SrcBuf = pvPortMalloc(H264DEC_INBUF_SIZE);
if(!h264SrcBuf) {
printf("%s, h264SrcBuf pvPortMalloc failed.\n", __func__);
return ;
}
#endif
xFD_Set = FreeRTOS_CreateSocketSet();
xSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
configASSERT( xSockets != FREERTOS_INVALID_SOCKET );
FreeRTOS_setsockopt(xSockets, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof(xNoTimeOut));
//FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, (void *)&option, sizeof(option));
set_socket_win(xSockets);
xAddress.sin_port = ( uint16_t ) 11111;
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
FreeRTOS_bind( xSockets, &xAddress, sizeof( xAddress ) );
FreeRTOS_listen( xSockets, 1 );
xXSSockets = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
configASSERT( xXSSockets != FREERTOS_INVALID_SOCKET );
FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_RCVTIMEO, &xNoTimeOut, sizeof(xNoTimeOut));
//FreeRTOS_setsockopt(xXSSockets, 0, FREERTOS_SO_REUSE_LISTEN_SOCKET, (void *)&option, sizeof(option));
set_socket_win(xXSSockets);
xAddress.sin_port = ( uint16_t ) 11113;
xAddress.sin_port = FreeRTOS_htons( xAddress.sin_port );
FreeRTOS_bind( xXSSockets, &xAddress, sizeof( xAddress ) );
FreeRTOS_listen( xXSSockets, 1 );
while(1) {
if (err_flag != 0) {
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
if (FREERTOS_INVALID_SOCKET != xClientSocket) {
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_closesocket(xClientSocket);
xClientSocket = FREERTOS_INVALID_SOCKET;
}
if (FREERTOS_INVALID_SOCKET != xXSClientSocket) {
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_closesocket(xXSClientSocket);
xXSClientSocket = FREERTOS_INVALID_SOCKET;
}
gClientSocket = FREERTOS_INVALID_SOCKET;
gXClientSocket = FREERTOS_INVALID_SOCKET;
xSemaphoreGive(gSocketMutex);
notify_carlink_state(0);
err_flag = 0;
}
FreeRTOS_FD_CLR(xSockets, xFD_Set, eSELECT_READ);
FreeRTOS_FD_SET(xSockets, xFD_Set, eSELECT_READ);
FreeRTOS_FD_CLR(xXSSockets, xFD_Set, eSELECT_READ);
FreeRTOS_FD_SET(xXSSockets, xFD_Set, eSELECT_READ);
if (xClientSocket && xClientSocket != FREERTOS_INVALID_SOCKET) {
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
}
if (xXSClientSocket && xXSClientSocket != FREERTOS_INVALID_SOCKET) {
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_FD_SET(xXSClientSocket, xFD_Set, eSELECT_READ);
}
xResult = FreeRTOS_select( xFD_Set, xBlockingTime );
if (xResult == 0) {//printf("select timeout\r\n");
if (FREERTOS_INVALID_SOCKET != xClientSocket) {//maybe socket don't recv close info;
if (cur_data_size == pre_data_size) {// no data recv
printf("no data, retry count:%d\r\n", retry_count);
if (retry_count++ >= 1) {// no data for 4s
err_flag = 1;
notify_carlink_state(0);
}
}
pre_data_size = cur_data_size;
}
xBlockingTime = pdMS_TO_TICKS( 2000 );
continue;
}
if (xResult < 0) {
break;
}
pre_data_size = cur_data_size;
if (0){
} else if(FreeRTOS_FD_ISSET ( xSockets, xFD_Set )) {
xClientSocket = FreeRTOS_accept( xSockets, &xRemoteAddr, &xClientLength);
if((xClientSocket != NULL) && (xClientSocket != FREERTOS_INVALID_SOCKET)) {
char pucBuffer[32] = {0};
FreeRTOS_FD_CLR(xClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_FD_SET(xClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_GetRemoteAddress( xClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
set_socket_win(xClientSocket);
printf("\r\nServer 11111: Received a connection from %s:%u\r\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
cur_data_size = 0;
pre_data_size = 0;
retry_count = 0;
h264_dec_ctx_init();
notify_carlink_state(1);
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
gClientSocket = xClientSocket;
xSemaphoreGive(gSocketMutex);
}
continue;
} else if (FreeRTOS_FD_ISSET ( xXSSockets, xFD_Set )) {
xXSClientSocket = FreeRTOS_accept( xXSSockets, &xRemoteAddr, &xClientLength);
if ((xXSClientSocket != NULL) && (xXSClientSocket != FREERTOS_INVALID_SOCKET)) {
char pucBuffer[32] = {0};
FreeRTOS_FD_CLR(xXSClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_FD_SET(xXSClientSocket, xFD_Set, eSELECT_READ);
FreeRTOS_GetRemoteAddress( xXSClientSocket, ( struct freertos_sockaddr * ) &xRemoteAddr );
FreeRTOS_inet_ntoa(xRemoteAddr.sin_addr, pucBuffer );
printf("\r\nServer 11113: Received a connection from %s:%u\r\n", pucBuffer, FreeRTOS_ntohs(xRemoteAddr.sin_port));
set_socket_win(xXSClientSocket);
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
gXClientSocket = xXSClientSocket;
xSemaphoreGive(gSocketMutex);
}
continue;
} else if (FreeRTOS_FD_ISSET ( xXSClientSocket, xFD_Set )) {
lBytes = FreeRTOS_recv( xXSClientSocket, (void*)&header, sizeof(header), 0);
if (lBytes < 0) {
printf("FreeRTOS_recv port 11113 err:%d\r\n", lBytes);
err_flag = 1;
} else {
cur_data_size += lBytes;
}
continue;
}
lBytes = FreeRTOS_recv( xClientSocket, (void*)&header, sizeof(header), 0);
if (lBytes < 0) {
printf("FreeRTOS_recv port 11111 err:%d\r\n", lBytes);
err_flag = 1;
continue;
}
cur_data_size += lBytes;
if (lBytes == 0)
continue;
if (!(header.sync_word[0] == 0xAA && header.sync_word[1] == 0xBB && header.sync_word[2] == 0xCC))
continue;
if (header.type == 4) {
uint16_t height, width;
header_ptr = (uint8_t *)&header;
for (i = 0; i < lBytes; i++) {
printf("%02x ", header_ptr[i]);
}printf("\r\n");
height = (header_ptr[12] | (header_ptr[13] << 8));
width = (header_ptr[14] | (header_ptr[15] << 8));
printf("#receive phone info width:%d height:%d\r\n", width, height);gey_ts = get_timer(0);//r_ts = header.ts;
ey_send_hu_info(xClientSocket);
continue;
} else if (header.type == 6) {
printf("heart beat\r\n");
continue;
} else if (header.type != 0) {
continue;
}
h264SrcSize = header.payload_size - 4;//skip timestamp
if (h264SrcSize <= 0 || h264SrcSize > H264_FRAME_BUF_SIZE) {
printf("h264 data len:%d err\r\n", h264SrcSize);
continue;
}
#if EY_DEBUG
h264SrcBufPtr = (uint8_t *)h264SrcBuf;
#else
get_retry:
frame = get_h264_frame_buf();
if (NULL == frame) {
printf("h264 frame is empty\r\n");
vTaskDelay(pdMS_TO_TICKS(20));
goto get_retry;
//continue;
}
h264SrcBufPtr = (uint8_t *)frame->cur;
frame->len = h264SrcSize;
#endif
//ts = get_timer(0);
//printf("Size:%05d lts:%03d rts:%06d\r\n", h264SrcSize, (ts - gey_ts) / 1000, header.ts - r_ts);
gey_ts = ts;//r_ts = header.ts;
lBytes = readn(xClientSocket, h264SrcBufPtr, h264SrcSize);
if (h264SrcSize != lBytes) {
set_h264_frame_free(frame);
if (lBytes == -1) {
printf("###FreeRTOS_recv port 11111 err:%d\r\n", lBytes);
err_flag = 1;
} else{
cur_data_size += lBytes;
}
} else {
cur_data_size += lBytes;
notify_h264_frame_ready(&frame);
}
}
printf("%s exit...\r\n", __func__);
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
if (FREERTOS_INVALID_SOCKET != xSockets)
FreeRTOS_closesocket(xSockets);
if (FREERTOS_INVALID_SOCKET != xXSSockets)
FreeRTOS_closesocket(xXSSockets);
if (FREERTOS_INVALID_SOCKET != xClientSocket)
FreeRTOS_closesocket(xClientSocket);
if (FREERTOS_INVALID_SOCKET != xXSClientSocket)
FreeRTOS_closesocket(xXSClientSocket);
gClientSocket = FREERTOS_INVALID_SOCKET;
gXClientSocket = FREERTOS_INVALID_SOCKET;
xSemaphoreGive(gSocketMutex);
vTaskDelete(NULL);
}
static int ey_start_network()
{
BaseType_t ret;
ret = xTaskCreate(ey_network_task_proc, "ey_network", 2048, NULL, configMAX_PRIORITIES - 3, &ey_network_task);
return ret;
}
void ey_wifi_event_handler( WIFIEvent_t * xEvent )
{
WIFIEventType_t xEventType = xEvent->xEventType;
if (0) {
} else if (eWiFiEventConnected == xEventType) {// meter is sta
notify_iphone_ap_connect_status(0);
printf("\r\n The meter is connected to ap \r\n");
} else if (eWiFiEventDisconnected == xEventType) {// meter is sta
printf("\r\n The meter is disconnected from ap \r\n");
xSemaphoreTake(gSocketMutex, portMAX_DELAY);
if (gClientSocket != FREERTOS_INVALID_SOCKET)
FreeRTOS_SignalSocket(gClientSocket);// wake up socket recv
if (gXClientSocket != FREERTOS_INVALID_SOCKET)
FreeRTOS_SignalSocket(gClientSocket);
xSemaphoreGive(gSocketMutex);
notify_phone_ip_addr(0);
notify_carlink_state(0);
} else if (eWiFiEventAPStationConnected == xEventType) {// meter is ap
printf("\r\n The meter in AP is connected by sta %s \r\n", xEvent->xInfo.xAPStationConnected.ucMac);
} else if (eWiFiEventAPStationDisconnected == xEventType) {// meter is ap
printf("\r\n The sta %s is disconnected from the meter \r\n", xEvent->xInfo.xAPStationDisconnected.ucMac);
//notify_phone_ip_addr(0);
}
}
int mmcsd_wait_sdio_ready(int32_t timeout);
static int carlink_ey_network_init()
{
BaseType_t ret;
unsigned int status;
gSocketMutex = xSemaphoreCreateMutex();
WIFI_Context_init();
WIFI_RegisterEvent(eWiFiEventMax, ey_wifi_event_handler);
for (;;) {
status = mmcsd_wait_sdio_ready((int32_t)portMAX_DELAY);
if (status == MMCSD_HOST_PLUGED) {
printf("detect sdio device\r\n");
break;
}
}
ret = FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress,ucDNSServerAddress, ucMACAddress);
ey_start_network();
return (int)ret;
}
static void carlink_ey_network_uninit()
{
}
static void ey_bt_callback(char * cAtStr)
{
char* cmd = NULL, *cmd_para = NULL;
struct bt_event ev = {0};
ev.type = -1;
printf("\r\nfsc_bt_callback %s\r\n", cAtStr);
if (0) {
} else if (0 == strncmp(cAtStr, "+WLCONN", 7)) {
ev.type = EY_BT_EVENT_NOTIFY_PHONE_AP_READY;
} else if (0 == strncmp(cAtStr, "+ADDR=", 6)) {
char cmd_str[64] = {0};
sprintf(cmd_str, "AT+NAME=EY_%s\r\n", (cAtStr + 6));
ey_reset_wifi_ap_info(cAtStr + 6);
printf("ADDR:%s\r\n", cAtStr + 6);
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
memset(cmd_str, 0, sizeof(cmd_str));
sprintf(cmd_str, "AT+LENAME=EY_%s\r\n", (cAtStr + 6));
console_send_atcmd(cmd_str, strlen(cmd_str));//get mac addr
gbt_ready = 1;
} else if (0 == strncmp(cAtStr, "+WLSSID=", 8)) {
ev.type = EY_BT_EVENT_NOTIFY_SSID;
cmd_para = cAtStr + 8;
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
} else if (0 == strncmp(cAtStr, "+WLPASSWD=", 10)) {
ev.type = EY_BT_EVENT_NOTIFY_PASSWD;
cmd_para = cAtStr + 10;
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
} else if (0 == strncmp(cAtStr, "+HFPSTAT=1", 10)) {
ev.type = EY_BT_EVENT_DISCONNECT;
} else if (0 == strncmp(cAtStr, "+HFPDEV=", 8)) {
ev.type = EY_BT_EVENT_CONNECT;
cmd_para = cAtStr + 8;
memcpy((void*)ev.para, (void*)cmd_para, 12);
} else if (0 == strncmp(cAtStr, "+AAA5=", 6)) {
ev.type = EY_BT_EVENT_NOTIFY_PHONE_TYPE;
cmd_para = cAtStr + 6;
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
} else if (0 == strncmp(cAtStr, "+AAA7=", 6)) {
ev.type = EY_BT_EVENT_NOTIFY_CONNECT_STATUS;
cmd_para = cAtStr + 7;
memcpy((void*)ev.para, (void*)cmd_para, strlen(cmd_para));
} else if (0 == strncmp(cAtStr, "+GATTSTAT=3", 11)) {
ev.type = EY_BT_EVENT_BLE_CONNECT;
} else if (0 == strncmp(cAtStr, "+AAA9", 5)) {
ev.type = EY_BT_EVENT_NOTIFY_USE_TCP;
} else if (0 == strncmp(cAtStr, "+VER", 4)) {
cmd = "AT+ADDR\r\n";
console_send_atcmd(cmd, strlen(cmd));//get mac addr
}
if (-1 != ev.type && NULL != ey_bt_event_queue) {
xQueueSend(ey_bt_event_queue, &ev, 0);
}
}
static void ey_bt_task_proc(void* arg)
{
struct bt_event ev;
char* cmd_para = NULL;
char at_cmd[128] = {0};
char phone_type = -1;
char ssid[32] = {0};
char passwd[32] = {0};
char bt_mac[12 + 1] = {0};
int ret = -1;
int carlink_ready_flag = 0;
for (;;) {
memset((void*)&ev, 0, sizeof(ev));
if (xQueueReceive(ey_bt_event_queue, &ev, portMAX_DELAY) != pdPASS) {
printf("%s xQueueReceive err!\r\n", __func__);
continue;
}
cmd_para = (char*)ev.para;
if (0) {
} else if (EY_BT_EVENT_NOTIFY_CONNECT_STATUS == ev.type) {
} else if (EY_BT_EVENT_CONNECT == ev.type) {
memcpy(bt_mac, cmd_para, 12);
bt_mac[12] = '0';
} else if (EY_BT_EVENT_DISCONNECT == ev.type) {
memset(ssid, 0, sizeof(ssid));
memset(passwd, 0, sizeof(passwd));
memset(bt_mac, 0, sizeof(bt_mac));
phone_type = -1;
notify_iphone_ssid_passwd();
notify_phone_ip_addr(0);
} else if (EY_BT_EVENT_NOTIFY_PHONE_TYPE == ev.type) {
string2hex(cmd_para, strlen(cmd_para), &phone_type, 2);
printf("\r\nphone type:%d\n", phone_type);
if (phone_type != gphone_type) {
gWifiOn = 0;// reboot wifi
WIFI_Off();
vTaskDelay(pdMS_TO_TICKS(2000));
}
gphone_type = phone_type;
if (0 == phone_type) {//android
char type_str[5] = {0};
char *tmp_buf = "-1";
str2asiistr(tmp_buf, strlen(tmp_buf), type_str, 2 * strlen(tmp_buf));
sprintf(at_cmd, "AT+GATTSET=AAA2%s\r\n", type_str);
printf("\r\nat:%s\r\n", at_cmd);
console_send_atcmd(at_cmd, strlen(at_cmd));
} else if (1 == phone_type) {//iphone
setDhcpClientState(0);
vDHCPProcess(1, eInitialWait);
xSendDHCPEvent();
notify_iphone_ssid_passwd();
ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
uint32_t ap_addr = (ucIPAddress[0]) | (ucIPAddress[1] << 8) | (ucIPAddress[2] << 16) | (ucIPAddress[3] << 24);
notify_phone_ip_addr(ap_addr);
}
} else if (EY_BT_EVENT_NOTIFY_SSID == ev.type) {
memcpy(ssid, cmd_para, strlen(cmd_para) + 1);
printf("\r\nssid:%s\r\n", ssid);
} else if (EY_BT_EVENT_NOTIFY_PASSWD == ev.type) {
memcpy(passwd, cmd_para, strlen(cmd_para) + 1);
printf("\r\npasswd:%s\r\n", passwd);
} else if (EY_BT_EVENT_NOTIFY_PHONE_AP_READY == ev.type) {
printf("\r\nssid:%s passwd:%s\r\n", ssid, passwd);
setDhcpClientState(1);
vDHCPProcess(1, eInitialWait);
xSendDHCPEvent();
notify_iphone_ap_connect_status(4);
ret = ey_wifi_connect_remote_ap(ssid, passwd);
if (ret == 0) {
vDHCPProcess(1, eWaitingSendFirstDiscover);
xSendDHCPEvent();
}
} else if (EY_BT_EVENT_NOTIFY_USE_TCP == ev.type) {
} else if (EY_BT_EVENT_BLE_CONNECT == ev.type) {
char bt_mac_hex_str[25] = {0};
str2asiistr(bt_mac, 12, bt_mac_hex_str, 24);
sprintf(at_cmd, "AT+GATTSEND=AAA5%s\r\n", bt_mac_hex_str);
printf("\r\nat:%s\r\n", at_cmd);
console_send_atcmd(at_cmd, strlen(at_cmd));
} else if (EY_CARLINK_EVENT_CONNECT == ev.type) {
carlink_ready_flag = 1;
printf("EY_CARLINK_EVENT_CONNECT\r\n");
set_carlink_display_state(1);
#if EY_CARLINK_NOTIFY_HOOK
carlink_ey_notify_state_hook(CARLINK_EY_READY);
#endif
} else if (EY_CARLINK_EVENT_DISCONNECT == ev.type) {
if (carlink_ready_flag == 1) {
printf("EY_CARLINK_EVENT_DISCONNECT\r\n");
carlink_ready_flag = 0;
set_carlink_display_state(0);
#if EY_CARLINK_NOTIFY_HOOK
carlink_ey_notify_state_hook(CARLINK_EY_EXIT);
#endif
}
}
}
vTaskDelete(NULL);
}
static int carlink_ey_bt_init()
{
int ret = -1;
ret = fsc_bt_main();
if (ret != 0)
return ret;
console_register_cb(NULL, ey_bt_callback);
ey_bt_event_queue = xQueueCreate(1, sizeof(struct bt_event));
ret = xTaskCreate(ey_bt_task_proc, "ey_bt", 2048, NULL, configMAX_PRIORITIES - 1, &ey_bt_task);
return ret;
}
static void carlink_ey_bt_uninit()
{
}
static void carlink_ey_init_thread(void *param)
{
carlink_ey_audio_init();
carlink_ey_video_init();
carlink_ey_network_init();
carlink_ey_bt_init();
//ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
vTaskDelete(NULL);
}
int carlink_ey_init()
{
#if 0
int ret = -1;
ret = carlink_ey_audio_init();
ret = carlink_ey_video_init();
ret = carlink_ey_network_init();
ret = carlink_ey_bt_init();
//ey_wifi_start_ap(ap_ssid, ap_passwd, 36);
return ret;
#else
//避免wifi模块异常后导致初始化接口阻塞影响机器正常启动。
xTaskCreate(carlink_ey_init_thread, "carlink_ey_init", 1024, NULL, 8, NULL);
return 0;
#endif
}
void carlink_ey_uninit()
{
carlink_ey_bt_uninit();
carlink_ey_network_uninit();
}
#else
int carlink_ey_init()
{
return 0;
}
void carlink_ey_uninit()
{
}
#endif