mirror of
https://github.com/pvvx/rtl00TstMinAmebaV35a.git
synced 2024-11-23 18:04:16 +00:00
2225 lines
72 KiB
C
2225 lines
72 KiB
C
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "main.h"
|
|
#include <lwip/sockets.h>
|
|
#include <lwip_netconf.h>
|
|
#include <dhcp/dhcps.h>
|
|
#include "serial_api.h"
|
|
#include "serial_ex_api.h"
|
|
#include "uart_adapter.h"
|
|
#include "wifi_conf.h"
|
|
#include "gpio_api.h" // mbed
|
|
#include "gpio_irq_api.h" // mbed
|
|
#include "osdep_service.h"
|
|
#include "flash_api.h"
|
|
#include "device_lock.h"
|
|
#include <mDNS/mDNS.h>
|
|
#include <example_wlan_fast_connect.h>
|
|
#include <timer_api.h>
|
|
|
|
|
|
/***********************************************************************
|
|
* Macros *
|
|
***********************************************************************/
|
|
|
|
/***********************************************************************
|
|
* Variables Declarations *
|
|
***********************************************************************/
|
|
char ua_tcp_server_ip[16];
|
|
|
|
_Sema ua_exception_sema;
|
|
_Sema ua_print_sema;
|
|
|
|
int ua_gpio_irq_happen = 0;
|
|
int ua_debug_print_en = 0;
|
|
int ua_wifi_connected = 0;
|
|
int ua_reconnect_started = 0;
|
|
int ua_reconnect_ip_change = 0;
|
|
|
|
ua_socket_t *ua_global_socket = NULL;
|
|
gpio_irq_t gpio_rx_wake;
|
|
|
|
/************************************************************************
|
|
* extern variables *
|
|
************************************************************************/
|
|
extern struct netif xnetif[NET_IF_NUM];
|
|
|
|
extern unsigned char psk_essid[NET_IF_NUM][NDIS_802_11_LENGTH_SSID+4];
|
|
extern unsigned char psk_passphrase[NET_IF_NUM][IW_PASSPHRASE_MAX_SIZE + 1];
|
|
extern unsigned char wpa_global_PSK[NET_IF_NUM][A_SHA_DIGEST_LEN * 2];
|
|
|
|
extern wlan_init_done_ptr p_wlan_uart_adapter_callback;
|
|
/************************************************************************
|
|
* extern funtions *
|
|
************************************************************************/
|
|
#if CONFIG_INCLUDE_SIMPLE_CONFIG
|
|
extern enum sc_result simple_config_test(rtw_network_info_t *);
|
|
extern int init_test_data(char *custom_pin_code);
|
|
extern void deinit_test_data(void);
|
|
extern void filter_add_enable();
|
|
extern void remove_filter();
|
|
extern void wifi_enter_promisc_mode();
|
|
#endif
|
|
|
|
/*************************************************************************
|
|
* uart releated *
|
|
*************************************************************************/
|
|
#define ____________UART__RELATED____________________
|
|
static void uartadapter_uart_irq(uint32_t id, SerialIrq event)
|
|
{
|
|
ua_socket_t *ua_socket = (ua_socket_t *)id;
|
|
|
|
if(event == RxIrq) {
|
|
ua_socket->uart.recv_buf[ua_socket->uart.pwrite++] = serial_getc(&ua_socket->uart.uart_sobj);
|
|
RtlUpSemaFromISR(&ua_socket->uart.action_sema); //up action semaphore
|
|
|
|
if(ua_socket->uart.pwrite > (UA_UART_RECV_BUFFER_LEN -1)){ //restart from head if reach tail
|
|
ua_socket->uart.pwrite = 0;
|
|
ua_socket->uart.overlap = 1;
|
|
}
|
|
|
|
if(ua_socket->uart.overlap && (ua_socket->uart.pwrite > ua_socket->uart.pread) ){
|
|
ua_socket->uart.miss_cnt ++;
|
|
ua_socket->uart.pread = ua_socket->uart.pwrite; //if pwrite overhead pread ,pread is always flow rwrite
|
|
}
|
|
ua_socket->uart.tick_last_update = xTaskGetTickCountFromISR(); // update tick everytime recved data
|
|
ua_socket->uart.rx_cnt ++;
|
|
}
|
|
}
|
|
|
|
static int uartadapter_uart_recv_data(ua_socket_t *ua_socket)
|
|
{
|
|
int uart_recv_len = 0;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
ua_socket->uart.tick_current = xTaskGetTickCount();
|
|
while((ua_socket->uart.tick_current -ua_socket->uart.tick_last_update) < (UA_UART_MAX_DELAY_TIME/portTICK_RATE_MS)
|
|
|| ua_socket->uart.tick_current <= ua_socket->uart.tick_last_update){
|
|
if(!ua_socket->uart.overlap){
|
|
uart_recv_len = ua_socket->uart.pwrite - ua_socket->uart.pread;
|
|
}else{
|
|
uart_recv_len = (UA_UART_RECV_BUFFER_LEN - ua_socket->uart.pread) + ua_socket->uart.pwrite;
|
|
}
|
|
|
|
if(uart_recv_len >= UA_UART_FRAME_LEN){
|
|
return 2;
|
|
}
|
|
//vTaskDelay(10);
|
|
ua_socket->uart.tick_current = xTaskGetTickCount();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int uartadapter_uart_read(ua_socket_t *ua_socket, void *read_buf, size_t size)
|
|
{
|
|
int ret = 0;
|
|
int read_bytes;
|
|
int pread_local,pwrite_local;
|
|
char *ptr;
|
|
|
|
ua_printf(UA_DEBUG, "==>uart adapter read uart");
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
if(!size || !read_buf){
|
|
ua_printf(UA_ERROR, "inpua error,size should not be null");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
|
|
pread_local = ua_socket->uart.pread;
|
|
pwrite_local = ua_socket->uart.pwrite;
|
|
ptr = (char *)read_buf;
|
|
|
|
/*calculate how much data not read */
|
|
if(!ua_socket->uart.overlap){
|
|
ua_socket->uart.recv_bytes = pwrite_local - pread_local;
|
|
}else{
|
|
ua_socket->uart.recv_bytes = (UA_UART_RECV_BUFFER_LEN - pread_local) + pwrite_local;
|
|
}
|
|
|
|
/*decide how much data shoule copy to application*/
|
|
if(size >= ua_socket->uart.recv_bytes ){
|
|
read_bytes = ua_socket->uart.recv_bytes;
|
|
ret = ua_socket->uart.recv_bytes;
|
|
}else{
|
|
read_bytes = size;
|
|
ret = size;
|
|
}
|
|
|
|
if(!ua_socket->uart.overlap){
|
|
memcpy(ptr, (ua_socket->uart.recv_buf+ pread_local), read_bytes );
|
|
}else {
|
|
ua_printf(UA_DEBUG, "uart recv buf is write overlap!!");
|
|
if((pread_local + read_bytes) > UA_UART_RECV_BUFFER_LEN){
|
|
memcpy(ptr,(ua_socket->uart.recv_buf+ pread_local),(UA_UART_RECV_BUFFER_LEN-pread_local));
|
|
memcpy(ptr+(UA_UART_RECV_BUFFER_LEN-pread_local), ua_socket->uart.recv_buf,read_bytes-(UA_UART_RECV_BUFFER_LEN- pread_local));
|
|
}else{
|
|
memcpy(ptr,(ua_socket->uart.recv_buf+ pread_local),read_bytes);
|
|
}
|
|
}
|
|
|
|
ua_socket->uart.recv_bytes = 0;
|
|
if((pread_local + read_bytes) >= UA_UART_RECV_BUFFER_LEN){ //update pread
|
|
ua_socket->uart.pread = (pread_local + read_bytes) - UA_UART_RECV_BUFFER_LEN;
|
|
ua_socket->uart.overlap = 0; //clean overlap flags
|
|
}else{
|
|
ua_socket->uart.pread = pread_local + read_bytes;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int uartadapter_uart_write(ua_socket_t *ua_socket, char *pbuf, size_t size)
|
|
{
|
|
int ret = -1;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
if(!size || !pbuf){
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
|
|
while(RtlDownSema(&ua_socket->uart.dma_tx) == pdTRUE){
|
|
ret = serial_send_stream_dma(&ua_socket->uart.uart_sobj, pbuf, size);
|
|
if(ret != HAL_OK){
|
|
ua_printf(UA_ERROR, "uart dma tx error %d!!", ret);
|
|
RtlUpSema(&ua_socket->uart.dma_tx);
|
|
return -1;
|
|
}else{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void uartadapter_uart_send_stream_done(uint32_t id)
|
|
{
|
|
ua_socket_t *ua_socket = (ua_socket_t *)id;
|
|
|
|
RtlUpSemaFromISR(&ua_socket->uart.dma_tx);
|
|
}
|
|
|
|
static void uartadapter_uart_rx_thread(void* param)
|
|
{
|
|
ua_socket_t *ua_socket = (ua_socket_t *)param;
|
|
char *rxbuf = NULL;
|
|
int ret =0;
|
|
int read_len = 0;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
rxbuf = pvPortMalloc(UA_UART_FRAME_LEN);
|
|
if(NULL == rxbuf){
|
|
ua_printf(UA_ERROR, "TCP: Allocate rx buffer failed.\n");
|
|
return;
|
|
}
|
|
|
|
|
|
while(1){
|
|
if(RtlDownSemaWithTimeout(&ua_socket->uart.action_sema, 1000) == pdTRUE){
|
|
ret = uartadapter_uart_recv_data(ua_socket);
|
|
if(ret == -1){
|
|
ua_printf(UA_ERROR, "uart recv data error!");
|
|
}else{
|
|
read_len = uartadapter_uart_read(ua_socket, rxbuf, UA_UART_FRAME_LEN);
|
|
if(read_len > 0){
|
|
uartadapter_tcp_send_data(ua_socket, rxbuf, read_len);
|
|
}else if(read_len < 0){
|
|
ua_printf(UA_ERROR, "tcp send read_len = %d", read_len);
|
|
}
|
|
}
|
|
}
|
|
#if UA_PS_ENABLE
|
|
else{
|
|
ua_socket->uart.uart_ps_cnt++;
|
|
if(ua_socket->uart.uart_ps_cnt >5){
|
|
ua_socket->uart.uart_ps_cnt = 5;
|
|
ua_socket->uart.uart_ps = 1;
|
|
if(ua_socket->uart.uart_ps && ua_socket->tcp.tcp_ps){
|
|
release_wakelock(UA_WAKELOCK);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
}
|
|
|
|
void uartadapter_uart_gpio_wakeup_callback (uint32_t id, gpio_irq_event event) {
|
|
acquire_wakelock(UA_WAKELOCK);
|
|
ua_socket_t *ua_socket = (ua_socket_t *)id;
|
|
ua_socket->uart.uart_ps = 0;
|
|
ua_socket->uart.uart_ps_cnt = 0;
|
|
}
|
|
|
|
int uartadapter_uart_open(ua_socket_t *ua_socket, ua_uart_set_str *puartpara)
|
|
{
|
|
PinName uart_tx,uart_rx;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
uart_tx = UA_UART_TX_PIN;
|
|
uart_rx = UA_UART_RX_PIN;
|
|
ua_socket->uart.uart_param.BaudRate = puartpara->BaudRate;
|
|
ua_socket->uart.uart_param.FlowControl = puartpara->FlowControl;
|
|
ua_socket->uart.uart_param.WordLen = puartpara->number;
|
|
ua_socket->uart.uart_param.Parity = puartpara->parity;
|
|
ua_socket->uart.uart_param.StopBit = puartpara->StopBits;
|
|
|
|
/*initial uart */
|
|
serial_init(&ua_socket->uart.uart_sobj, uart_tx, uart_rx);
|
|
serial_baud(&ua_socket->uart.uart_sobj,puartpara->BaudRate);
|
|
serial_format(&ua_socket->uart.uart_sobj, puartpara->number, (SerialParity)puartpara->parity, puartpara->StopBits);
|
|
|
|
/*uart irq handle*/
|
|
serial_irq_handler(&ua_socket->uart.uart_sobj, uartadapter_uart_irq, (uint32_t)ua_socket);
|
|
serial_irq_set(&ua_socket->uart.uart_sobj, RxIrq, 1);
|
|
serial_irq_set(&ua_socket->uart.uart_sobj, TxIrq, 1);
|
|
|
|
serial_send_comp_handler(&ua_socket->uart.uart_sobj, (void*)uartadapter_uart_send_stream_done, (uint32_t)ua_socket);
|
|
|
|
#if UA_PS_ENABLE
|
|
//config uart rx as gpio wakeup pin
|
|
gpio_irq_t gpio_rx_wake;
|
|
gpio_irq_init(&gpio_rx_wake, UA_GPIO_WAKEUP_PIN, uartadapter_uart_gpio_wakeup_callback, (uint32_t)ua_socket);
|
|
gpio_irq_set(&gpio_rx_wake, IRQ_FALL, 1); // Falling Edge Trigger
|
|
gpio_irq_enable(&gpio_rx_wake);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
int uartadapter_uart_baud(ua_socket_t *ua_socket, int baud_rate)
|
|
{
|
|
int ret = 0;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
ua_socket->uart.uart_param.BaudRate = baud_rate;
|
|
|
|
serial_baud(&ua_socket->uart.uart_sobj, baud_rate);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int uartadapter_uart_para(ua_socket_t *ua_socket, int word_len, int parity, int stop_bits)
|
|
{
|
|
int ret = 0;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
ua_socket->uart.uart_param.WordLen = word_len;
|
|
ua_socket->uart.uart_param.Parity = parity;
|
|
ua_socket->uart.uart_param.StopBit = stop_bits;
|
|
|
|
serial_format(&ua_socket->uart.uart_sobj, word_len, (SerialParity)parity, stop_bits);
|
|
|
|
return ret;
|
|
}
|
|
|
|
int uartadapter_uart_getpara(ua_socket_t *ua_socket, ua_uart_get_str *uart_para)
|
|
{
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
uart_para->BaudRate = ua_socket->uart.uart_param.BaudRate;
|
|
uart_para->FlowControl = ua_socket->uart.uart_param.FlowControl;
|
|
uart_para->number = ua_socket->uart.uart_param.WordLen;
|
|
uart_para->parity = ua_socket->uart.uart_param.Parity;
|
|
uart_para->StopBits = ua_socket->uart.uart_param.StopBit;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void uartadapter_uart_init(ua_socket_t *ua_socket)
|
|
{
|
|
ua_uart_set_str uartset;
|
|
ua_uart_get_str uartget;
|
|
char uarttest[]="uart0";
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
uartset.BaudRate = 9600;
|
|
uartset.number = 8;
|
|
uartset.StopBits = 1;
|
|
uartset.FlowControl = 0;
|
|
uartset.parity = 0;
|
|
strcpy(uartset.UartName,uarttest);
|
|
|
|
uartadapter_uart_open(ua_socket, &uartset);
|
|
|
|
if(uartadapter_uart_getpara(ua_socket, &uartget))
|
|
ua_printf(UA_ERROR, "get uart failed!");
|
|
else
|
|
ua_printf(UA_DEBUG,"uart pata:\r\n"\
|
|
"uart->BaudRate = %d\r\n"\
|
|
"uart->number = %d\r\n"\
|
|
"uart->FlowControl = %d\r\n"\
|
|
"uart->parity = %d\r\n"\
|
|
"uart->StopBits = %d\r\n"\
|
|
"\r\n",\
|
|
uartget.BaudRate,\
|
|
uartget.number,\
|
|
uartget.FlowControl,\
|
|
uartget.parity,\
|
|
uartget.StopBits\
|
|
);
|
|
}
|
|
|
|
#define _________FLASH___RELATED________________________
|
|
int uartadapter_flashread(int flashadd, char *pbuf, int len)
|
|
{
|
|
int ret = 0;
|
|
flash_t flash;
|
|
|
|
if( len == 0){
|
|
ua_printf(UA_ERROR, "inpua error,data length should not be null!");
|
|
ret = -1;
|
|
return ret;
|
|
}else //as 8711am only canbe r/w in words.so make len is 4-bytes aligmented.
|
|
len += 4 - ((len%4)==0 ? 4 : (len%4));
|
|
|
|
while(len){
|
|
if(flash_read_word(&flash, flashadd, (unsigned int *)pbuf) !=1 ){
|
|
ua_printf(UA_ERROR, "read flash error!");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
len -= 4;
|
|
pbuf += 4;
|
|
flashadd += 4;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
int uartadapter_flashwrite(int flashadd, char *pbuf, int len)
|
|
{
|
|
int ret = 0;
|
|
flash_t flash;
|
|
|
|
if( len == 0){
|
|
ua_printf(UA_ERROR, "inpua error,data length should not be null!");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
else //as 8711am only canbe r/w in words.so make len is 4-bytes aligmented.
|
|
len += 4 - ((len%4)==0 ? 4 : (len%4));
|
|
|
|
while(len){
|
|
if(flash_write_word(&flash, flashadd, *(unsigned int *)pbuf) !=1 ){
|
|
ua_printf(UA_ERROR, "write flash error!");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
len -= 4;
|
|
pbuf += 4;
|
|
flashadd += 4;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int uartadapter_flasherase(int flashadd, int erase_bytelen)
|
|
{
|
|
int ret = 0;
|
|
flash_t flash;
|
|
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
|
flash_erase_sector(&flash, flashadd);
|
|
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
|
return ret;
|
|
}
|
|
|
|
#define _________GPIO___RELATED________________________
|
|
void uartadapter_systemreload(void)
|
|
{
|
|
// Cortex-M3 SCB->AIRCR
|
|
HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) | // VECTKEY
|
|
(HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) | // PRIGROUP
|
|
(1 << 2)); // SYSRESETREQ
|
|
}
|
|
|
|
void uartadapter_gpio_irq (uint32_t id, gpio_irq_event event)
|
|
{
|
|
ua_printf(UA_DEBUG, "GPIO push button!!");
|
|
|
|
ua_gpio_irq_happen = 1;
|
|
RtlUpSemaFromISR(&ua_exception_sema);
|
|
}
|
|
|
|
void uartadapter_gtimer_timeout_handler(uint32_t id)
|
|
{
|
|
gpio_t *gpio_led = (gpio_t *)id;
|
|
|
|
gpio_write(gpio_led, !gpio_read(gpio_led));
|
|
}
|
|
|
|
void uartadapter_gpio_init(ua_socket_t *ua_socket)
|
|
{
|
|
gpio_init(&ua_socket->gpio.gpio_led, UA_GPIO_LED_PIN);
|
|
gpio_dir(&ua_socket->gpio.gpio_led, PIN_OUTPUT); // Direction: Output
|
|
gpio_mode(&ua_socket->gpio.gpio_led, PullNone); // No pull
|
|
|
|
gpio_init(&ua_socket->gpio.gpio_btn, UA_GPIO_IRQ_PIN);
|
|
gpio_dir(&ua_socket->gpio.gpio_btn, PIN_INPUT); // Direction: Output
|
|
gpio_mode(&ua_socket->gpio.gpio_btn, PullNone); // No pull
|
|
|
|
gpio_irq_init(&ua_socket->gpio.gpio_btn_irq, UA_GPIO_IRQ_PIN, uartadapter_gpio_irq, (uint32_t)(&ua_socket->gpio.gpio_btn));
|
|
gpio_irq_set(&ua_socket->gpio.gpio_btn_irq, IRQ_FALL, 1); // Falling Edge Trigger
|
|
gpio_irq_enable(&ua_socket->gpio.gpio_btn_irq);
|
|
|
|
// Initial a periodical timer
|
|
gtimer_init(&ua_socket->gpio.gpio_timer, TIMER0);
|
|
//gtimer_start_periodical(&ua_socket->gpio.gpio_timer, 100000, (void*)timer_timeout_handler, (uint32_t)&ua_socket->gpio.gpio_led);
|
|
}
|
|
|
|
void uartadapter_gpio_led_mode(ua_socket_t *ua_socket, ua_led_mode_t mode)
|
|
{
|
|
gtimer_stop(&ua_socket->gpio.gpio_timer);
|
|
switch(mode){
|
|
case UART_ADAPTER_LED_ON:
|
|
gpio_write(&ua_socket->gpio.gpio_led, 1);
|
|
break;
|
|
case UART_ADAPTER_LED_OFF:
|
|
gpio_write(&ua_socket->gpio.gpio_led, 0);
|
|
break;
|
|
case UART_ADAPTER_LED_FAST_TWINKLE:
|
|
gtimer_start_periodical(&ua_socket->gpio.gpio_timer, 100000,
|
|
(void*)uartadapter_gtimer_timeout_handler, (uint32_t)&ua_socket->gpio.gpio_led);
|
|
break;
|
|
case UART_ADAPTER_LED_SLOW_TWINKLE:
|
|
gtimer_start_periodical(&ua_socket->gpio.gpio_timer, 2000000,
|
|
(void*)uartadapter_gtimer_timeout_handler, (uint32_t)&ua_socket->gpio.gpio_led);
|
|
break;
|
|
default:
|
|
ua_printf(UA_ERROR, "Unknown GPIO LED mode!!");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define _________CONTROL__DATA__RELATED________________________
|
|
int uartadapter_strncmp(char *cs, char *ct, size_t count)
|
|
{
|
|
unsigned char c1, c2;
|
|
|
|
while (count) {
|
|
c1 = *cs++;
|
|
c2 = *ct++;
|
|
if (c1 != c2)
|
|
return c1 < c2 ? -1 : 1;
|
|
if (!c1)
|
|
break;
|
|
count--;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int uartadapter_control_write_tcp_info_into_flash(ua_socket_t *ua_socket)
|
|
{
|
|
int ret;
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
ua_printf(UA_INFO, "\r\nWrite Uart Adapter tcp connection new profile to flash");
|
|
|
|
uartadapter_flasherase(UA_FAST_RECONNECT_TCP_DATA, 0x1000);
|
|
ret = uartadapter_flashwrite(UA_FAST_RECONNECT_TCP_DATA, (char *)&ua_socket->tcp, sizeof(ua_tcp_socket_t));
|
|
return ret;
|
|
}
|
|
|
|
int uartadapter_control_read_tcp_info_and_connect(ua_socket_t *ua_socket)
|
|
{
|
|
int ret = 0;
|
|
ua_tcp_socket_t tcp = {0};
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
ua_printf(UA_INFO, "\r\nRead Uart Adapter tcp connection profile from flash");
|
|
|
|
uartadapter_flashread(UA_FAST_RECONNECT_TCP_DATA, (u8*)&tcp, sizeof(ua_tcp_socket_t));
|
|
if(tcp.group_id != ~0x0){
|
|
if(tcp.group_id){
|
|
ua_socket->tcp.group_id = tcp.group_id;
|
|
ua_socket->tcp.server_port = tcp.server_port;
|
|
ua_socket->tcp.client_port = tcp.client_port;
|
|
memcpy(ua_socket->tcp.client_ip, tcp.client_ip, 16);
|
|
|
|
if(xTaskCreate(uartadapter_tcp_transmit_server_thread, ((const char*)"tserver"), 256, (void *)ua_socket->tcp.server_port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(tcp server) failed", __FUNCTION__);
|
|
|
|
strncpy(ua_tcp_server_ip, ua_socket->tcp.client_ip, 16);
|
|
if(xTaskCreate(uartadapter_tcp_transmit_client_forever_thread, ((const char*)"tclient"), 256, (void *)ua_socket->tcp.client_port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(tcp client) failed", __FUNCTION__);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int uartadapter_control_set_req_handle(ua_socket_t *ua_socket, u8 *pbuf, u32 sz)
|
|
{
|
|
u8 *p = pbuf;
|
|
u8 len = 0;
|
|
u16 type = 0;
|
|
u32 port = 0;
|
|
u32 server_ip = 0;
|
|
int ret = 0;
|
|
struct sockaddr_in server_addr;
|
|
int server_addr_len = sizeof(server_addr);
|
|
TXTRecordRef txtRecord;
|
|
unsigned char txt_buf[100] = {0}; // use fixed buffer for text record to prevent malloc/free
|
|
unsigned char txt_buf2[100] = {0}; // use fixed buffer for text record to prevent malloc/free
|
|
|
|
|
|
ua_printf(UA_DEBUG, "\n===>uartadapter_control_set_req_handle()");
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
UA_PRINT_DATA(pbuf, sz);
|
|
|
|
while(p < (pbuf+sz)){
|
|
type = (*p)<<8 | *(p+1);
|
|
p = p + 2;
|
|
len = *p++;
|
|
ua_printf(UA_DEBUG, "type=%d len=%d\n", type, len);
|
|
switch(type)
|
|
{
|
|
case UART_CTRL_TYPE_BAUD_RATE:
|
|
ua_socket->uart.uart_param.BaudRate = *(u32 *)p;
|
|
ua_printf(UA_INFO, "SET UART BAUD_RATE to %d.\n", ua_socket->uart.uart_param.BaudRate);
|
|
serial_baud(&ua_socket->uart.uart_sobj, ua_socket->uart.uart_param.BaudRate);
|
|
break;
|
|
case UART_CTRL_TYPE_WORD_LEN:
|
|
ua_socket->uart.uart_param.WordLen = *p;
|
|
ua_printf(UA_INFO, "SET UART WORD_LEN to %d.\n", ua_socket->uart.uart_param.WordLen);
|
|
serial_format(&ua_socket->uart.uart_sobj,
|
|
ua_socket->uart.uart_param.WordLen,
|
|
(SerialParity)ua_socket->uart.uart_param.Parity,
|
|
ua_socket->uart.uart_param.StopBit);
|
|
break;
|
|
case UART_CTRL_TYPE_PARITY:
|
|
ua_socket->uart.uart_param.Parity = *p;
|
|
ua_printf(UA_INFO, "SET UART PARITY to %d.\n", ua_socket->uart.uart_param.Parity);
|
|
serial_format(&ua_socket->uart.uart_sobj,
|
|
ua_socket->uart.uart_param.WordLen,
|
|
(SerialParity)ua_socket->uart.uart_param.Parity,
|
|
ua_socket->uart.uart_param.StopBit);
|
|
break;
|
|
case UART_CTRL_TYPE_STOP_BIT:
|
|
ua_socket->uart.uart_param.StopBit = *p;
|
|
ua_printf(UA_INFO, "SET UART STOP_BIT to %d.\n", ua_socket->uart.uart_param.StopBit);
|
|
serial_format(&ua_socket->uart.uart_sobj,
|
|
ua_socket->uart.uart_param.WordLen,
|
|
(SerialParity)ua_socket->uart.uart_param.Parity,
|
|
ua_socket->uart.uart_param.StopBit);
|
|
break;
|
|
case UART_CTRL_TYPE_TCP_SERVER_CREATE:
|
|
port = (*p)<<8 | *(p+1);
|
|
|
|
if(ua_socket->tcp.transmit_server_listen_socket != -1){
|
|
ua_printf(UA_INFO, "Close old transmit server socket %d", ua_socket->tcp.transmit_server_listen_socket);
|
|
close(ua_socket->tcp.transmit_server_listen_socket);
|
|
}
|
|
if(xTaskCreate(uartadapter_tcp_transmit_server_thread, ((const char*)"tserver"), 256, (void *)port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(tcp server) failed", __FUNCTION__);
|
|
ua_socket->tcp.server_port = port;
|
|
uartadapter_control_write_tcp_info_into_flash(ua_socket);
|
|
vTaskDelay(50);
|
|
ua_printf(UA_DEBUG, "CREATE TCP SERVER WITH PORT %d.\n", port);
|
|
//TODO
|
|
break;
|
|
case UART_CTRL_TYPE_TCP_SERVER_DELETE:
|
|
port = (*p)<<8 | *(p+1);
|
|
|
|
if(ua_socket->tcp.transmit_server_listen_socket != -1){
|
|
getsockname (ua_socket->tcp.transmit_server_listen_socket, (struct sockaddr *)&server_addr, &server_addr_len);
|
|
if(server_addr.sin_port == ntohs((u16)port)){
|
|
ua_printf(UA_INFO,"uart tcp transmit server socket %d closed by control socket!", ua_socket->tcp.transmit_server_listen_socket);
|
|
close(ua_socket->tcp.transmit_server_listen_socket);
|
|
ua_socket->tcp.transmit_server_listen_socket = -1;
|
|
if(ua_socket->tcp.transmit_recv_socket != -1){
|
|
ua_printf(UA_INFO,"uart tcp transmit receive socket %d closed by control socket!", ua_socket->tcp.transmit_recv_socket);
|
|
close(ua_socket->tcp.transmit_recv_socket);
|
|
ua_socket->tcp.transmit_recv_socket = -1;
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_send_socket != -1){
|
|
ua_printf(UA_INFO,"uart tcp transmit send socket %d closed by control socket!", ua_socket->tcp.transmit_send_socket);
|
|
close(ua_socket->tcp.transmit_send_socket);
|
|
ua_socket->tcp.transmit_send_socket = -1;
|
|
ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER.\n");
|
|
memset(ua_socket->tcp.client_ip, 0, 16);
|
|
ua_socket->tcp.client_port = 0;
|
|
}
|
|
ua_printf(UA_INFO, "DELETE TCP SERVER \n");
|
|
ua_socket->tcp.server_port = 0;
|
|
uartadapter_control_write_tcp_info_into_flash(ua_socket);
|
|
}else{
|
|
ua_printf(UA_INFO, "DELETE TCP SERVER FAILED: port not match\n");
|
|
return -1;
|
|
}
|
|
}else{
|
|
ua_printf(UA_INFO, "DELETE TCP SERVER FAILED: server not exist\n");
|
|
return -1;
|
|
}
|
|
|
|
break;
|
|
case UART_CTRL_TYPE_TCP_CLIENT_CONNECT:
|
|
server_ip = (*(p+3))<<24 | (*(p+2))<<16 | (*(p+1))<<8 | *p;
|
|
p = p + 4;
|
|
memcpy(ua_tcp_server_ip, inet_ntoa(server_ip), 16);
|
|
port = (*p)<<8 | *(p+1);
|
|
ret = uartadapter_tcpclient(ua_socket, ua_tcp_server_ip, (unsigned short)port);
|
|
if(ret == 0){
|
|
ua_printf(UA_INFO, "CONNECT TO TCP SERVER, IP %s PORT %d Success.\n", ua_tcp_server_ip, port);
|
|
}else{
|
|
ua_printf(UA_INFO, "CONNECT TO TCP SERVER, IP %s PORT %d Failed.\n", ua_tcp_server_ip, port);
|
|
return -1;
|
|
}
|
|
memcpy(ua_socket->tcp.client_ip, ua_tcp_server_ip, 16);
|
|
ua_socket->tcp.client_port = port;
|
|
uartadapter_control_write_tcp_info_into_flash(ua_socket);
|
|
break;
|
|
case UART_CTRL_TYPE_TCP_CLIENT_DISCONNECT:
|
|
server_ip = (*(p+3))<<24 | (*(p+2))<<16 | (*(p+1))<<8 | *p;
|
|
p = p + 4;
|
|
memcpy(ua_tcp_server_ip, inet_ntoa(server_ip), 16);
|
|
port = (*p)<<8 | *(p+1);
|
|
|
|
if(ua_socket->tcp.transmit_send_socket != -1){
|
|
getpeername(ua_socket->tcp.transmit_send_socket, (struct sockaddr *)&server_addr, &server_addr_len);
|
|
if(server_addr.sin_port == ntohs((u16)port) && server_addr.sin_addr.s_addr == server_ip){
|
|
ua_printf(UA_INFO,"uart tcp transmit send socket %d closed by control socket!", ua_socket->tcp.transmit_send_socket);
|
|
close(ua_socket->tcp.transmit_send_socket);
|
|
ua_socket->tcp.transmit_send_socket = -1;
|
|
ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER.\n");
|
|
memset(ua_socket->tcp.client_ip, 0, 16);
|
|
ua_socket->tcp.client_port = 0;
|
|
uartadapter_control_write_tcp_info_into_flash(ua_socket);
|
|
}else{
|
|
ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER FAILED: port or IP not match.\n");
|
|
return -1;
|
|
}
|
|
}else{
|
|
ua_printf(UA_INFO, "DISCONNECT FROM TCP SERVER FAILED: connection not exist\n");
|
|
return -1;
|
|
}
|
|
break;
|
|
case UART_CTRL_TYPE_TCP_GROUP_ID:
|
|
ua_socket->tcp.group_id = *p;
|
|
ua_printf(UA_INFO,"SET TCP GROUP ID to %d!", *p);
|
|
sprintf(txt_buf2, "groupid:%d, tcpserver:%d", ua_socket->tcp.group_id, ua_socket->tcp.server_port);
|
|
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
|
|
TXTRecordSetValue(&txtRecord, "groupid", strlen(txt_buf2), txt_buf2);
|
|
mDNSUpdateService(ua_socket->dnsServiceRef, &txtRecord, 0);
|
|
mDNSUpdateService(ua_socket->dnsServiceRef2, &txtRecord, 0);
|
|
|
|
uartadapter_control_write_tcp_info_into_flash(ua_socket);
|
|
|
|
break;
|
|
default:
|
|
ua_printf(UA_DEBUG, "Unknown Type, just skip\n");
|
|
break;
|
|
|
|
}
|
|
p += len;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int uartadapter_control_get_req_handle(ua_socket_t *ua_socket, u16 type, u8 *prsp, u32 *sz)
|
|
{
|
|
u8 *p = prsp;
|
|
|
|
ua_printf(UA_DEBUG, "===>uartadapter_control_get_req_handle()");
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
sprintf((char *)p, UA_CONTROL_PREFIX);
|
|
p += strlen(UA_CONTROL_PREFIX);
|
|
*p++ = UART_CTRL_MODE_GET_RSP;
|
|
|
|
if(type & UART_CTRL_TYPE_BAUD_RATE){
|
|
*p++ = 0;
|
|
*p++ = UART_CTRL_TYPE_BAUD_RATE;
|
|
*p++ = 4;
|
|
*(u32*)p = ua_socket->uart.uart_param.BaudRate;
|
|
p += 4;
|
|
}
|
|
if(type & UART_CTRL_TYPE_WORD_LEN){
|
|
*p++ = 0;
|
|
*p++ = UART_CTRL_TYPE_WORD_LEN;
|
|
*p++ = 1;
|
|
*p = ua_socket->uart.uart_param.WordLen;
|
|
p += 1;
|
|
}
|
|
if(type & UART_CTRL_TYPE_PARITY){
|
|
*p++ = 0;
|
|
*p++ = UART_CTRL_TYPE_PARITY;
|
|
*p++ = 1;
|
|
*p = ua_socket->uart.uart_param.Parity;
|
|
p += 1;
|
|
}
|
|
if(type & UART_CTRL_TYPE_STOP_BIT){
|
|
*p++ = 0;
|
|
*p++ = UART_CTRL_TYPE_STOP_BIT;
|
|
*p++ = 1;
|
|
*p = ua_socket->uart.uart_param.StopBit;
|
|
p += 1;
|
|
}
|
|
#if 0
|
|
if(type & UART_CTRL_TYPE_FLOW_CTRL){
|
|
*p++ = UART_CTRL_TYPE_FLOW_CTRL;
|
|
*p++ = 1;
|
|
*p = ua_socket->uart.uart_param.FlowControl;
|
|
p += 1;
|
|
}
|
|
#endif
|
|
*sz = p - prsp;
|
|
|
|
UA_PRINT_DATA(prsp, *sz);
|
|
return 0;
|
|
}
|
|
|
|
int uartadapter_control_process(ua_socket_t *ua_socket, char *pbuf, size_t size)
|
|
{
|
|
/*the same as socket*/
|
|
int ret = 0;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
if(!size || !pbuf){
|
|
//ua_printf(UA_ERROR, "control data input error,please check!");
|
|
ret = -1;
|
|
return ret;
|
|
}
|
|
|
|
UA_PRINT_DATA(pbuf, size);
|
|
|
|
if(uartadapter_strncmp(pbuf, UA_CONTROL_PREFIX, 10) != 0)
|
|
{
|
|
ua_printf(UA_ERROR, "control data prefix wrong!");
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
u8 *p = (u8*)pbuf + strlen(UA_CONTROL_PREFIX);
|
|
u8 mode = *p++;
|
|
switch(mode)
|
|
{
|
|
case UART_CTRL_MODE_SET_REQ: //AMEBA_UART-MODE-TYPE-LEN-VAL-TYPE-LEN-VAL...
|
|
{
|
|
char rsp[32] = {0}; //AMEBA_UART-MODE
|
|
u32 sz = strlen(UA_CONTROL_PREFIX);
|
|
ret = uartadapter_control_set_req_handle(ua_socket, p, (size - strlen(UA_CONTROL_PREFIX) - 1));
|
|
if(0 == ret){
|
|
sprintf(rsp, UA_CONTROL_PREFIX);
|
|
*(rsp + sz) = UART_CTRL_MODE_SET_RSP;
|
|
sz ++;
|
|
sprintf(rsp + sz, "\n");
|
|
sz ++;
|
|
vTaskDelay(100);
|
|
uartadapter_tcp_send_control(ua_socket, rsp, sz);
|
|
}
|
|
break;
|
|
}
|
|
case UART_CTRL_MODE_GET_REQ: //AMEBA_UART-MODE-TYPE
|
|
{
|
|
char rsp[128] = {0};
|
|
u32 sz = 0;
|
|
u16 type = (*p)<<8 | *(p+1);
|
|
uartadapter_control_get_req_handle(ua_socket, type, (u8*)rsp, &sz);
|
|
sprintf(rsp + sz, "\n");
|
|
sz ++;
|
|
vTaskDelay(100);
|
|
uartadapter_tcp_send_control(ua_socket, rsp, sz);
|
|
break;
|
|
}
|
|
default:
|
|
ua_printf(UA_ERROR, UA_CONTROL_PREFIX": Mode (%d) not support!", mode);
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#define _________TCP__RELATED________________________
|
|
int uartadapter_tcpclient(ua_socket_t *ua_socket, const char *host_ip, unsigned short usPort)
|
|
{
|
|
int iAddrSize;
|
|
int iSockFD = -1;
|
|
int iStatus;
|
|
int enable = 1;
|
|
struct sockaddr_in sAddr;
|
|
int send_timeout = 3000;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
FD_ZERO(&sAddr);
|
|
sAddr.sin_family = AF_INET;
|
|
sAddr.sin_port = htons(usPort);
|
|
sAddr.sin_addr.s_addr = inet_addr(host_ip);
|
|
|
|
iAddrSize = sizeof(struct sockaddr_in);
|
|
|
|
iSockFD = socket(AF_INET, SOCK_STREAM, 0);
|
|
if( iSockFD < 0 ) {
|
|
ua_printf(UA_ERROR, "TCP ERROR: create tcp client socket fd error!");
|
|
return -1;
|
|
}
|
|
|
|
ua_printf(UA_DEBUG, "TCP: ServerIP=%s port=%d.", host_ip, usPort);
|
|
ua_printf(UA_DEBUG, "TCP: Create socket %d.", iSockFD);
|
|
// connecting to TCP server
|
|
iStatus = connect(iSockFD, (struct sockaddr *)&sAddr, iAddrSize);
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client connect server error %d!", iStatus);
|
|
goto Exit;
|
|
}
|
|
|
|
iStatus = setsockopt(iSockFD, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set TCP_NODELAY error! ");
|
|
goto Exit;
|
|
}
|
|
|
|
iStatus = setsockopt(iSockFD, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set SO_KEEPALIVE error! ");
|
|
goto Exit;
|
|
}
|
|
|
|
#if LWIP_SO_SNDTIMEO
|
|
iStatus = setsockopt(iSockFD, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(int));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set SO_SNDTIMEO error! ");
|
|
goto Exit;
|
|
}
|
|
#endif
|
|
|
|
#if LWIP_SO_RCVTIMEO
|
|
iStatus = setsockopt(iSockFD, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(int));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set SO_RCVTIMEO error! ");
|
|
goto Exit;
|
|
}
|
|
#endif
|
|
|
|
if(ua_socket->tcp.transmit_send_socket != -1){
|
|
close(ua_socket->tcp.transmit_send_socket);
|
|
ua_printf(UA_INFO, "Close old transmit send socket %d.", ua_socket->tcp.transmit_send_socket);
|
|
}
|
|
|
|
ua_printf(UA_INFO, "Connect to transmit server successfully.");
|
|
ua_socket->tcp.transmit_send_socket = iSockFD;
|
|
|
|
return 0;
|
|
|
|
Exit:
|
|
close(iSockFD);
|
|
return -1;
|
|
}
|
|
|
|
int uartadapter_tcpserver(ua_socket_t *ua_socket, unsigned short usPort, u8 socket_type)
|
|
{
|
|
struct sockaddr_in sLocalAddr;
|
|
int iAddrSize;
|
|
int iSockFD;
|
|
int iStatus;
|
|
int enable = 1;
|
|
|
|
UA_SOCKET_CHECK_2(ua_socket);
|
|
|
|
iSockFD = socket(AF_INET, SOCK_STREAM, 0);
|
|
if( iSockFD < 0 ) {
|
|
ua_printf(UA_ERROR, "create server_socket error!");
|
|
goto Exit;
|
|
}
|
|
|
|
iStatus = setsockopt( iSockFD, SOL_SOCKET, SO_REUSEADDR,
|
|
(const char *) &enable, sizeof( enable ) );
|
|
if( iStatus < 0 ) {
|
|
ua_printf(UA_ERROR, "set tcp server socket SO_REUSEADDR error %d! ", iStatus);
|
|
goto Exit;
|
|
}
|
|
|
|
ua_printf(UA_DEBUG, "TCP: Create Tcp server socket %d", iSockFD);
|
|
|
|
//filling the TCP server socket address
|
|
memset((char *)&sLocalAddr, 0, sizeof(sLocalAddr));
|
|
sLocalAddr.sin_family = AF_INET;
|
|
sLocalAddr.sin_len = sizeof(sLocalAddr);
|
|
sLocalAddr.sin_port = htons(usPort);
|
|
sLocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
iAddrSize = sizeof(sLocalAddr);
|
|
|
|
iStatus = bind(iSockFD, (struct sockaddr *)&sLocalAddr, iAddrSize);
|
|
if( iStatus < 0 ) {
|
|
ua_printf(UA_ERROR, "bind tcp server socket fd error %d! ", iStatus);
|
|
goto Exit;
|
|
}
|
|
ua_printf(UA_DEBUG, "TCP: Bind successfully.");
|
|
|
|
iStatus = listen(iSockFD, 10);
|
|
if( iStatus != 0 ) {
|
|
ua_printf(UA_ERROR, "listen tcp server socket fd error %d!", iStatus);
|
|
goto Exit;
|
|
}
|
|
|
|
if(0 == socket_type){
|
|
ua_socket->tcp.chat_server_listen_socket = iSockFD;
|
|
ua_printf(UA_INFO, "TCP Chat Server: Listen on port %d", usPort);
|
|
}else if(1 == socket_type){
|
|
ua_socket->tcp.control_server_listen_socket = iSockFD;
|
|
ua_printf(UA_INFO, "TCP Control Server: Listen on port %d", usPort);
|
|
}else{
|
|
ua_socket->tcp.transmit_server_listen_socket = iSockFD;
|
|
ua_printf(UA_INFO, "TCP Transmit Server: Listen on port %d", usPort);
|
|
}
|
|
|
|
return 0;
|
|
|
|
Exit:
|
|
close(iSockFD);
|
|
ua_printf(UA_DEBUG, "Tcp server listen on port %d closed!", usPort);
|
|
return 0;
|
|
}
|
|
|
|
void uartadapter_tcp_chat_server_thread(void *param)
|
|
{
|
|
ua_socket_t *ua_socket = (ua_socket_t *)param;
|
|
unsigned short port = UA_CHAT_SOCKET_PORT;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Data Server!");
|
|
uartadapter_tcpserver(ua_socket, port, 0);
|
|
|
|
#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1)
|
|
ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE));
|
|
#endif
|
|
ua_printf(UA_DEBUG, "TCP: Tcp data server stopped!");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uartadapter_tcp_control_server_thread(void *param)
|
|
{
|
|
ua_socket_t *ua_socket = (ua_socket_t *)param;
|
|
unsigned short port = UA_CONTROL_SOCKET_PORT;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Control Server!");
|
|
uartadapter_tcpserver(ua_socket, port, 1);
|
|
|
|
#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1)
|
|
ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE));
|
|
#endif
|
|
ua_printf(UA_DEBUG, "TCP: Tcp control server stopped!");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uartadapter_tcp_transmit_server_thread(void *param)
|
|
{
|
|
ua_socket_t *ua_socket = ua_global_socket;
|
|
unsigned short port = (int)param;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Transmit Server!");
|
|
uartadapter_tcpserver(ua_socket, port, 2);
|
|
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_SLOW_TWINKLE);
|
|
|
|
#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1)
|
|
ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE));
|
|
#endif
|
|
ua_printf(UA_DEBUG, "TCP: Tcp transmit server thread delete!");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uartadapter_tcp_transmit_client_thread(void *param)
|
|
{
|
|
ua_socket_t *ua_socket = ua_global_socket;
|
|
unsigned short port = (int)param;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Data Client!");
|
|
uartadapter_tcpclient(ua_socket, ua_tcp_server_ip, port);
|
|
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_SLOW_TWINKLE);
|
|
|
|
#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1)
|
|
ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE));
|
|
#endif
|
|
ua_printf(UA_DEBUG, "TCP: Tcp transmit client thread delete!");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uartadapter_tcp_transmit_client_forever_thread(void *param)
|
|
{
|
|
ua_socket_t *ua_socket = ua_global_socket;
|
|
unsigned short port = (int)param;
|
|
int ret = 0;
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_printf(UA_DEBUG, "Uart Adapter: Start Tcp Transmit Client forever thread!");
|
|
|
|
do{
|
|
ret = uartadapter_tcpclient(ua_socket, ua_tcp_server_ip, port);
|
|
if(ret != 0){
|
|
ua_printf(UA_INFO, "Uart Adapter: Try to connect to TCP server again");
|
|
vTaskDelay(3000);
|
|
}
|
|
}while(ret != 0);
|
|
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_SLOW_TWINKLE);
|
|
|
|
#if defined(INCLUDE_uxTaskGetStackHighWaterMark) && (INCLUDE_uxTaskGetStackHighWaterMark == 1)
|
|
ua_printf(UA_DEBUG, "Min available stack size of %s = %d * %d bytes\n\r", __FUNCTION__, uxTaskGetStackHighWaterMark(NULL), sizeof(portBASE_TYPE));
|
|
#endif
|
|
ua_printf(UA_DEBUG, "TCP: Tcp transmit client thread delete!");
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uartadapter_tcp_send_data(ua_socket_t *ua_socket, char *buffer, int size)
|
|
{
|
|
int iStatus;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
if(ua_socket->tcp.chat_socket != -1){
|
|
ua_socket->tcp.send_flag = 1;
|
|
RtlDownSema(&ua_socket->uart.tcp_tx_rx_sema);
|
|
iStatus = send(ua_socket->tcp.chat_socket, buffer, size, 0 );
|
|
RtlUpSema(&ua_socket->uart.tcp_tx_rx_sema);
|
|
ua_socket->tcp.send_flag = 0;
|
|
if( iStatus <= 0 ){
|
|
ua_printf(UA_ERROR, "tcp chat socket send data error! iStatus:%d!", iStatus);
|
|
}else{
|
|
ua_socket->tcp.tx_cnt += iStatus;
|
|
}
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_send_socket != -1){
|
|
ua_socket->tcp.send_flag = 1;
|
|
iStatus = send(ua_socket->tcp.transmit_send_socket, buffer, size, 0 );
|
|
ua_socket->tcp.send_flag = 0;
|
|
if( iStatus <= 0 ){
|
|
ua_printf(UA_ERROR, "tcp transmit send socket send data error! iStatus:%d!", iStatus);
|
|
}else{
|
|
ua_socket->tcp.tx_cnt += iStatus;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void uartadapter_tcp_send_control(ua_socket_t *ua_socket, char *buffer, int size)
|
|
{
|
|
int iStatus;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
if(ua_socket->tcp.control_socket != -1){
|
|
ua_socket->tcp.send_flag = 1;
|
|
iStatus = send(ua_socket->tcp.control_socket, buffer, size, 0 );
|
|
ua_socket->tcp.send_flag = 0;
|
|
if( iStatus <= 0 ){
|
|
ua_printf(UA_ERROR,"tcp control socket send data error! iStatus:%d!", iStatus);
|
|
}
|
|
|
|
if(ua_debug_print_en){
|
|
ua_printf(UA_INFO,"uart tcp control socket send %d bytes, ret %d!", size, iStatus);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void uartadapter_tcp_except_handler(ua_socket_t *ua_socket, fd_set *exceptfds)
|
|
{
|
|
if(ua_socket->tcp.chat_socket != -1 && FD_ISSET(ua_socket->tcp.chat_socket, exceptfds)){
|
|
ua_printf(UA_INFO,"uart tcp chat socket %d exception happen, need to close!", ua_socket->tcp.chat_socket);
|
|
close(ua_socket->tcp.chat_socket);
|
|
ua_socket->tcp.chat_socket = -1;
|
|
}
|
|
|
|
if(ua_socket->tcp.control_socket != -1 && FD_ISSET(ua_socket->tcp.control_socket, exceptfds)){
|
|
ua_printf(UA_INFO,"uart tcp control socket %d exception happen, need to close!", ua_socket->tcp.control_socket);
|
|
close(ua_socket->tcp.control_socket);
|
|
ua_socket->tcp.control_socket = -1;
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_recv_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_recv_socket, exceptfds)){
|
|
ua_printf(UA_INFO,"uart tcp transmit recv socket %d exception happen, need to close!", ua_socket->tcp.transmit_recv_socket);
|
|
close(ua_socket->tcp.transmit_recv_socket);
|
|
ua_socket->tcp.transmit_recv_socket = -1;
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
#if 0
|
|
if(ua_socket->tcp.transmit_server_listen_socket != -1){
|
|
ua_printf(UA_INFO,"uart tcp transmit server socket %d exception happen, need to close!", ua_socket->tcp.transmit_server_listen_socket);
|
|
close(ua_socket->tcp.transmit_server_listen_socket);
|
|
ua_socket->tcp.transmit_server_listen_socket = -1;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_send_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_send_socket, exceptfds)){
|
|
ua_printf(UA_INFO,"uart tcp transmit send socket %d exception happen, need to close!", ua_socket->tcp.transmit_send_socket);
|
|
close(ua_socket->tcp.transmit_send_socket);
|
|
ua_socket->tcp.transmit_send_socket = -1;
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
|
|
strncpy(ua_tcp_server_ip, ua_socket->tcp.client_ip, 16);
|
|
if(xTaskCreate(uartadapter_tcp_transmit_client_forever_thread, ((const char*)"tclient"), 256, (void *)ua_socket->tcp.client_port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(tcp client) failed", __FUNCTION__);
|
|
}
|
|
|
|
if(ua_socket->tcp.chat_server_listen_socket != -1 && FD_ISSET(ua_socket->tcp.chat_server_listen_socket, exceptfds)){
|
|
ua_printf(UA_INFO,"uart tcp chat server socket %d exception happen, need to restart!", ua_socket->tcp.chat_server_listen_socket);
|
|
close(ua_socket->tcp.chat_server_listen_socket);
|
|
ua_socket->tcp.chat_server_listen_socket = -1;
|
|
uartadapter_tcpserver(ua_socket, UA_CHAT_SOCKET_PORT, 0);
|
|
}
|
|
|
|
if(ua_socket->tcp.control_server_listen_socket != -1 && FD_ISSET(ua_socket->tcp.control_server_listen_socket, exceptfds)){
|
|
ua_printf(UA_INFO,"uart tcp control server socket %d exception happen, need to restart!", ua_socket->tcp.control_server_listen_socket);
|
|
close(ua_socket->tcp.control_server_listen_socket);
|
|
ua_socket->tcp.control_server_listen_socket = -1;
|
|
uartadapter_tcpserver(ua_socket, UA_CONTROL_SOCKET_PORT, 1);
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_server_listen_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_server_listen_socket, exceptfds)){
|
|
ua_printf(UA_INFO,"uart tcp transmit server socket %d exception happen, need to close!", ua_socket->tcp.transmit_server_listen_socket);
|
|
close(ua_socket->tcp.transmit_server_listen_socket);
|
|
ua_socket->tcp.transmit_server_listen_socket = -1;
|
|
//uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
uartadapter_tcpserver(ua_socket, ua_socket->tcp.server_port, 2);
|
|
}
|
|
|
|
}
|
|
|
|
void uartadapter_tcp_chat_socket_handler(ua_socket_t *ua_socket, char *tcp_rxbuf)
|
|
{
|
|
int recv_len;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_socket->tcp.recv_flag = 1;
|
|
RtlDownSema(&ua_socket->uart.tcp_tx_rx_sema);
|
|
recv_len = recv(ua_socket->tcp.chat_socket, tcp_rxbuf, UA_UART_FRAME_LEN, MSG_DONTWAIT);
|
|
RtlUpSema(&ua_socket->uart.tcp_tx_rx_sema);
|
|
ua_socket->tcp.recv_flag = 0;
|
|
if(recv_len < 0){
|
|
ua_printf(UA_ERROR, "Tcp Chat Socket %d Recv Error, ret = %d", ua_socket->tcp.chat_socket, recv_len);
|
|
}else if(recv_len == 0){
|
|
ua_printf(UA_INFO, "Tcp Chat Socket %d closed", ua_socket->tcp.chat_socket);
|
|
close(ua_socket->tcp.chat_socket);
|
|
ua_socket->tcp.chat_socket = -1;
|
|
}else{
|
|
ua_printf(UA_DEBUG, "Tcp Chat Socket %d Recv %d Data", ua_socket->tcp.chat_socket, recv_len);
|
|
uartadapter_uart_write(ua_socket, tcp_rxbuf, recv_len);
|
|
ua_socket->tcp.rx_cnt += recv_len;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void uartadapter_tcp_control_socket_handler(ua_socket_t *ua_socket)
|
|
{
|
|
char tcp_rxbuf[UA_UART_FRAME_LEN];
|
|
int recv_len;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
recv_len = recv(ua_socket->tcp.control_socket, tcp_rxbuf, UA_UART_FRAME_LEN, MSG_DONTWAIT); //MSG_DONTWAIT MSG_WAITALL
|
|
if(recv_len<0){
|
|
ua_printf(UA_ERROR, "Tcp Control Socket %d Recv Error", ua_socket->tcp.control_socket);
|
|
}else if(recv_len == 0){
|
|
ua_printf(UA_INFO, "Tcp Control Socket %d closed", ua_socket->tcp.control_socket);
|
|
close(ua_socket->tcp.control_socket);
|
|
ua_socket->tcp.control_socket = -1;
|
|
}else{
|
|
ua_printf(UA_DEBUG, "Tcp Control Socket %d Recv %d Data", ua_socket->tcp.control_socket, recv_len);
|
|
uartadapter_control_process(ua_socket, (void*)tcp_rxbuf, recv_len);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void uartadapter_tcp_transmit_socket_handler(ua_socket_t *ua_socket, char *tcp_rxbuf)
|
|
{
|
|
int recv_len;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_socket->tcp.recv_flag = 1;
|
|
recv_len = recv(ua_socket->tcp.transmit_recv_socket, tcp_rxbuf, UA_UART_FRAME_LEN, MSG_DONTWAIT);
|
|
ua_socket->tcp.recv_flag = 0;
|
|
if(recv_len < 0){
|
|
ua_printf(UA_ERROR, "Tcp Transmit Recv Socket %d Recv Error, ret = %d", ua_socket->tcp.transmit_recv_socket, recv_len);
|
|
}else if(recv_len == 0){
|
|
ua_printf(UA_INFO, "Tcp Transmit Recv Socket %d closed", ua_socket->tcp.transmit_recv_socket);
|
|
close(ua_socket->tcp.transmit_recv_socket);
|
|
ua_socket->tcp.transmit_recv_socket = -1;
|
|
#if 0
|
|
if(ua_socket->tcp.transmit_server_listen_socket != -1){
|
|
ua_printf(UA_INFO, "Tcp Transmit Server Socket %d closed", ua_socket->tcp.transmit_server_listen_socket);
|
|
close(ua_socket->tcp.transmit_server_listen_socket);
|
|
ua_socket->tcp.transmit_server_listen_socket = -1;
|
|
}
|
|
#endif
|
|
}else{
|
|
uartadapter_uart_write(ua_socket, tcp_rxbuf, recv_len);
|
|
ua_socket->tcp.rx_cnt += recv_len;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void uartadapter_tcp_chat_listen_socket_handler(ua_socket_t *ua_socket)
|
|
{
|
|
int old_chat_socket;
|
|
struct sockaddr_in sAddr;
|
|
int addrlen = sizeof(sAddr);
|
|
int iStatus;
|
|
int enable = 1;
|
|
int send_timeout = 3000;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
old_chat_socket = ua_socket->tcp.chat_socket;
|
|
|
|
ua_socket->tcp.chat_socket = accept(ua_socket->tcp.chat_server_listen_socket, (struct sockaddr *)&sAddr, (socklen_t*)&addrlen);
|
|
if( ua_socket->tcp.chat_socket< 0 ) {
|
|
ua_printf(UA_ERROR, "Accept tcp chat socket error");
|
|
goto EXIT;
|
|
}
|
|
|
|
iStatus = setsockopt(ua_socket->tcp.chat_socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp chat socket set opt TCP_NODELAY error! ");
|
|
goto EXIT;
|
|
}
|
|
|
|
iStatus = setsockopt(ua_socket->tcp.chat_socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp chat socket set opt SO_KEEPALIVE error! ");
|
|
goto EXIT;
|
|
}
|
|
|
|
#if LWIP_SO_SNDTIMEO
|
|
iStatus = setsockopt(ua_socket->tcp.chat_socket, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(send_timeout));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set opt error! ");
|
|
goto EXIT;
|
|
}
|
|
#endif
|
|
|
|
#if LWIP_SO_RCVTIMEO
|
|
iStatus = setsockopt(ua_socket->tcp.chat_socket, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(send_timeout));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set opt error! ");
|
|
goto EXIT;
|
|
}
|
|
#endif
|
|
|
|
ua_printf(UA_INFO, "Accept new chat socket %d on port %d successfully.", ua_socket->tcp.chat_socket, htons(sAddr.sin_port));
|
|
if(old_chat_socket != -1)
|
|
{
|
|
close(old_chat_socket);
|
|
ua_printf(UA_INFO, "Close old chat socket %d.", old_chat_socket);
|
|
}
|
|
|
|
return;
|
|
|
|
EXIT:
|
|
if(ua_socket->tcp.chat_server_listen_socket != -1){
|
|
close(ua_socket->tcp.chat_server_listen_socket);
|
|
ua_socket->tcp.chat_server_listen_socket = -1;
|
|
}
|
|
}
|
|
|
|
void uartadapter_tcp_control_listen_socket_handler(ua_socket_t *ua_socket)
|
|
{
|
|
int old_control_socket;
|
|
struct sockaddr_in sAddr;
|
|
int addrlen = sizeof(sAddr);
|
|
int iStatus;
|
|
int enable = 1;
|
|
int send_timeout = 3000;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
old_control_socket = ua_socket->tcp.control_socket;
|
|
|
|
ua_socket->tcp.control_socket = accept(ua_socket->tcp.control_server_listen_socket, (struct sockaddr *)&sAddr, (socklen_t*)&addrlen);
|
|
if( ua_socket->tcp.control_socket< 0 ) {
|
|
ua_printf(UA_ERROR, "Accept tcp control socket error");
|
|
goto EXIT;
|
|
}
|
|
|
|
iStatus = setsockopt(ua_socket->tcp.control_socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp chat socket set opt TCP_NODELAY error! ");
|
|
goto EXIT;
|
|
}
|
|
|
|
iStatus = setsockopt(ua_socket->tcp.control_socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp chat socket set opt SO_KEEPALIVE error! ");
|
|
goto EXIT;
|
|
}
|
|
|
|
#if LWIP_SO_SNDTIMEO
|
|
iStatus = setsockopt(ua_socket->tcp.control_socket, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(send_timeout));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set opt error! ");
|
|
goto EXIT;
|
|
}
|
|
#endif
|
|
|
|
#if LWIP_SO_RCVTIMEO
|
|
iStatus = setsockopt(ua_socket->tcp.control_socket, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(send_timeout));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set opt error! ");
|
|
goto EXIT;
|
|
}
|
|
#endif
|
|
|
|
ua_printf(UA_INFO, "Accept new control socket %d on port %d successfully.", ua_socket->tcp.control_socket, htons(sAddr.sin_port));
|
|
if(old_control_socket != -1)
|
|
{
|
|
close(old_control_socket);
|
|
ua_printf(UA_INFO, "Close old control socket %d.", old_control_socket);
|
|
}
|
|
|
|
return;
|
|
|
|
EXIT:
|
|
if(ua_socket->tcp.control_server_listen_socket!= -1){
|
|
close(ua_socket->tcp.control_server_listen_socket);
|
|
ua_socket->tcp.control_server_listen_socket= -1;
|
|
}
|
|
}
|
|
|
|
void uartadapter_tcp_transmit_listen_socket_handler(ua_socket_t *ua_socket)
|
|
{
|
|
int old_transmit_recv_socket;
|
|
struct sockaddr_in sAddr;
|
|
int addrlen = sizeof(sAddr);
|
|
int iStatus;
|
|
int enable = 1;
|
|
int send_timeout = 3000;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
old_transmit_recv_socket = ua_socket->tcp.transmit_recv_socket;
|
|
|
|
ua_socket->tcp.transmit_recv_socket = accept(ua_socket->tcp.transmit_server_listen_socket, (struct sockaddr *)&sAddr, (socklen_t*)&addrlen);
|
|
if( ua_socket->tcp.transmit_recv_socket < 0 ) {
|
|
ua_printf(UA_ERROR, "Accept tcp control socket error");
|
|
goto EXIT;
|
|
}
|
|
|
|
iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp transmit recv socket set opt TCP_NODELAY error! ");
|
|
goto EXIT;
|
|
}
|
|
|
|
iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp transmit recv socket set opt SO_KEEPALIVE error! ");
|
|
goto EXIT;
|
|
}
|
|
|
|
#if LWIP_SO_SNDTIMEO
|
|
iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, SOL_SOCKET, SO_SNDTIMEO, &send_timeout, sizeof(send_timeout));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set opt error! ");
|
|
goto EXIT;
|
|
}
|
|
#endif
|
|
|
|
#if LWIP_SO_RCVTIMEO
|
|
iStatus = setsockopt(ua_socket->tcp.transmit_recv_socket, SOL_SOCKET, SO_RCVTIMEO, &send_timeout, sizeof(send_timeout));
|
|
if (iStatus < 0) {
|
|
ua_printf(UA_ERROR, "tcp client socket set opt error! ");
|
|
goto EXIT;
|
|
}
|
|
#endif
|
|
|
|
ua_printf(UA_INFO, "Accept new transmit recv socket %d on port %d successfully.", ua_socket->tcp.transmit_recv_socket, htons(sAddr.sin_port));
|
|
if(old_transmit_recv_socket != -1)
|
|
{
|
|
close(old_transmit_recv_socket);
|
|
ua_printf(UA_INFO, "Close old transmit recv socket %d.", old_transmit_recv_socket);
|
|
}
|
|
|
|
return;
|
|
|
|
EXIT:
|
|
if(ua_socket->tcp.transmit_server_listen_socket!= -1){
|
|
close(ua_socket->tcp.transmit_server_listen_socket);
|
|
ua_socket->tcp.transmit_server_listen_socket= -1;
|
|
}
|
|
}
|
|
|
|
void uartadapter_tcp_select_restart_handler(ua_socket_t *ua_socket)
|
|
{
|
|
if(ua_socket->tcp.chat_socket != -1){
|
|
ua_printf(UA_INFO,"IP changed, uart tcp chat socket %d need to close!", ua_socket->tcp.chat_socket);
|
|
close(ua_socket->tcp.chat_socket);
|
|
ua_socket->tcp.chat_socket = -1;
|
|
}
|
|
|
|
if(ua_socket->tcp.control_socket != -1){
|
|
ua_printf(UA_INFO,"IP changed, uart tcp control socket %d need to close!", ua_socket->tcp.control_socket);
|
|
close(ua_socket->tcp.control_socket);
|
|
ua_socket->tcp.control_socket = -1;
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_recv_socket != -1){
|
|
ua_printf(UA_INFO,"IP changed, uart tcp transmit recv socket %d need to close!", ua_socket->tcp.transmit_recv_socket);
|
|
close(ua_socket->tcp.transmit_recv_socket);
|
|
ua_socket->tcp.transmit_recv_socket = -1;
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_send_socket != -1){
|
|
ua_printf(UA_INFO,"IP changed, uart tcp transmit send socket %d need to close!", ua_socket->tcp.transmit_send_socket);
|
|
close(ua_socket->tcp.transmit_send_socket);
|
|
ua_socket->tcp.transmit_send_socket = -1;
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
}
|
|
|
|
if(ua_socket->tcp.chat_server_listen_socket!= -1){
|
|
ua_printf(UA_INFO,"IP changed, uart tcp chat server socket %d need to restart!", ua_socket->tcp.chat_server_listen_socket);
|
|
close(ua_socket->tcp.chat_server_listen_socket);
|
|
ua_socket->tcp.chat_server_listen_socket = -1;
|
|
uartadapter_tcpserver(ua_socket, UA_CHAT_SOCKET_PORT, 0);
|
|
}
|
|
|
|
if(ua_socket->tcp.control_server_listen_socket!= -1){
|
|
ua_printf(UA_INFO,"IP changed, uart tcp control server socket %d need to restart!", ua_socket->tcp.control_server_listen_socket);
|
|
close(ua_socket->tcp.control_server_listen_socket);
|
|
ua_socket->tcp.control_server_listen_socket = -1;
|
|
uartadapter_tcpserver(ua_socket, UA_CONTROL_SOCKET_PORT, 1);
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_server_listen_socket!= -1){
|
|
ua_printf(UA_INFO,"IP changed, uart tcp transmit server socket %d need to close!", ua_socket->tcp.transmit_server_listen_socket);
|
|
close(ua_socket->tcp.transmit_server_listen_socket);
|
|
ua_socket->tcp.transmit_server_listen_socket = -1;
|
|
uartadapter_gpio_led_mode(ua_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
}
|
|
|
|
}
|
|
|
|
void uartadapter_tcp_select_thread(void *param)
|
|
{
|
|
ua_socket_t *ua_socket = (ua_socket_t *)param;
|
|
int max_fd;
|
|
struct timeval tv;
|
|
fd_set readfds;
|
|
fd_set exceptfds;
|
|
int ret = 0;
|
|
char *tcp_rxbuf;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
tcp_rxbuf = pvPortMalloc(UA_UART_FRAME_LEN);
|
|
if(NULL == tcp_rxbuf){
|
|
ua_printf(UA_ERROR, "Allocate select buffer failed.\n");
|
|
return;
|
|
}
|
|
|
|
while(1){
|
|
if(ua_reconnect_ip_change){
|
|
uartadapter_tcp_select_restart_handler(ua_socket);
|
|
ua_reconnect_ip_change = 0;
|
|
}
|
|
|
|
FD_ZERO(&readfds);
|
|
FD_ZERO(&exceptfds);
|
|
max_fd = -1;
|
|
|
|
if(ua_socket->tcp.chat_socket != -1){
|
|
FD_SET(ua_socket->tcp.chat_socket, &readfds);
|
|
FD_SET(ua_socket->tcp.chat_socket, &exceptfds);
|
|
if(ua_socket->tcp.chat_socket > max_fd)
|
|
max_fd = ua_socket->tcp.chat_socket;
|
|
}
|
|
|
|
if(ua_socket->tcp.control_socket != -1){
|
|
FD_SET(ua_socket->tcp.control_socket, &readfds);
|
|
FD_SET(ua_socket->tcp.control_socket, &exceptfds);
|
|
if(ua_socket->tcp.control_socket > max_fd)
|
|
max_fd = ua_socket->tcp.control_socket;
|
|
}
|
|
|
|
if(ua_socket->tcp.control_server_listen_socket != -1){
|
|
FD_SET(ua_socket->tcp.control_server_listen_socket, &readfds);
|
|
FD_SET(ua_socket->tcp.control_server_listen_socket, &exceptfds);
|
|
if(ua_socket->tcp.control_server_listen_socket > max_fd)
|
|
max_fd = ua_socket->tcp.control_server_listen_socket;
|
|
}
|
|
|
|
if(ua_socket->tcp.chat_server_listen_socket != -1){
|
|
FD_SET(ua_socket->tcp.chat_server_listen_socket, &readfds);
|
|
FD_SET(ua_socket->tcp.chat_server_listen_socket, &exceptfds);
|
|
if(ua_socket->tcp.chat_server_listen_socket > max_fd)
|
|
max_fd = ua_socket->tcp.chat_server_listen_socket;
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_recv_socket != -1){
|
|
FD_SET(ua_socket->tcp.transmit_recv_socket, &readfds);
|
|
FD_SET(ua_socket->tcp.transmit_recv_socket, &exceptfds);
|
|
if(ua_socket->tcp.transmit_recv_socket > max_fd)
|
|
max_fd = ua_socket->tcp.transmit_recv_socket;
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_send_socket != -1){
|
|
FD_SET(ua_socket->tcp.transmit_send_socket, &exceptfds);
|
|
if(ua_socket->tcp.transmit_send_socket > max_fd)
|
|
max_fd = ua_socket->tcp.transmit_send_socket;
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_server_listen_socket != -1){
|
|
FD_SET(ua_socket->tcp.transmit_server_listen_socket, &readfds);
|
|
FD_SET(ua_socket->tcp.transmit_server_listen_socket, &exceptfds);
|
|
if(ua_socket->tcp.transmit_server_listen_socket> max_fd)
|
|
max_fd = ua_socket->tcp.transmit_server_listen_socket;
|
|
}
|
|
|
|
tv.tv_sec = 1;
|
|
tv.tv_usec = 0;
|
|
|
|
ret = select(max_fd + 1, &readfds, NULL, &exceptfds, &tv);
|
|
|
|
if(ua_debug_print_en){
|
|
ua_printf(UA_INFO, "uart adapter test select ret = %x",ret);
|
|
}
|
|
if(ret > 0){
|
|
#if UA_PS_ENABLE
|
|
//printf("select get lock \r\n");
|
|
acquire_wakelock(UA_WAKELOCK);
|
|
ua_socket->tcp.tcp_ps = 0;
|
|
ua_socket->tcp.tcp_ps_cnt = 0;
|
|
#endif
|
|
|
|
uartadapter_tcp_except_handler(ua_socket, &exceptfds);
|
|
|
|
if(ua_socket->tcp.chat_socket != -1 && FD_ISSET(ua_socket->tcp.chat_socket, &readfds)){
|
|
uartadapter_tcp_chat_socket_handler(ua_socket, tcp_rxbuf);
|
|
}
|
|
|
|
if(ua_socket->tcp.control_socket != -1 && FD_ISSET(ua_socket->tcp.control_socket, &readfds)){
|
|
uartadapter_tcp_control_socket_handler(ua_socket);
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_recv_socket != -1 && FD_ISSET(ua_socket->tcp.transmit_recv_socket, &readfds)){
|
|
uartadapter_tcp_transmit_socket_handler(ua_socket, tcp_rxbuf);
|
|
}
|
|
|
|
if(ua_socket->tcp.chat_server_listen_socket!= -1 && FD_ISSET(ua_socket->tcp.chat_server_listen_socket, &readfds)){
|
|
uartadapter_tcp_chat_listen_socket_handler(ua_socket);
|
|
}
|
|
|
|
if(ua_socket->tcp.control_server_listen_socket!= -1 && FD_ISSET(ua_socket->tcp.control_server_listen_socket, &readfds)){
|
|
uartadapter_tcp_control_listen_socket_handler(ua_socket);
|
|
}
|
|
|
|
if(ua_socket->tcp.transmit_server_listen_socket!= -1 && FD_ISSET(ua_socket->tcp.transmit_server_listen_socket, &readfds)){
|
|
uartadapter_tcp_transmit_listen_socket_handler(ua_socket);
|
|
}
|
|
|
|
|
|
}
|
|
#if UA_PS_ENABLE
|
|
else{
|
|
ua_socket->tcp.tcp_ps_cnt++;
|
|
if(ua_socket->tcp.tcp_ps_cnt > 5){
|
|
ua_socket->tcp.tcp_ps_cnt = 5;
|
|
ua_socket->tcp.tcp_ps = 1;
|
|
if(ua_socket->uart.uart_ps && ua_socket->tcp.tcp_ps){
|
|
release_wakelock(UA_WAKELOCK);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//vTaskDelete(NULL);
|
|
}
|
|
|
|
#define _________WIFI__RELATED________________________
|
|
|
|
int uartadapter_connect_wifi(rtw_network_info_t *p_wifi, uint32_t channel, uint8_t pscan_config)
|
|
{
|
|
int retry = 3;
|
|
rtw_wifi_setting_t setting;
|
|
int ret;
|
|
while (1) {
|
|
if(wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1) < 0){
|
|
ua_printf(UA_ERROR, "wifi set partial scan channel fail");
|
|
ret = SC_TARGET_CHANNEL_SCAN_FAIL;
|
|
return ret;
|
|
}
|
|
|
|
ret = wifi_connect((char*)p_wifi->ssid.val,
|
|
p_wifi->security_type,
|
|
(char*)p_wifi->password,
|
|
p_wifi->ssid.len,
|
|
p_wifi->password_len,
|
|
p_wifi->key_id,
|
|
NULL);
|
|
|
|
if (ret == RTW_SUCCESS) {
|
|
ret = LwIP_DHCP(0, DHCP_START);
|
|
wifi_get_setting(WLAN0_NAME, &setting);
|
|
wifi_show_setting(WLAN0_NAME, &setting);
|
|
if (ret == DHCP_ADDRESS_ASSIGNED)
|
|
return SC_SUCCESS;
|
|
else
|
|
return SC_DHCP_FAIL;
|
|
}
|
|
|
|
if (retry == 0) {
|
|
ret = SC_JOIN_BSS_FAIL;
|
|
break;
|
|
}
|
|
retry --;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static int uartadapter_load_wifi_config()
|
|
{
|
|
flash_t flash;
|
|
struct wlan_fast_reconnect *data;
|
|
uint32_t channel;
|
|
uint8_t pscan_config;
|
|
char key_id;
|
|
rtw_network_info_t wifi = {0};
|
|
int ret = SC_SUCCESS;
|
|
|
|
|
|
data = (struct wlan_fast_reconnect *)rtw_zmalloc(sizeof(struct wlan_fast_reconnect));
|
|
device_mutex_lock(RT_DEV_LOCK_FLASH);
|
|
flash_stream_read(&flash, FAST_RECONNECT_DATA, sizeof(struct wlan_fast_reconnect), (uint8_t *)data);
|
|
device_mutex_unlock(RT_DEV_LOCK_FLASH);
|
|
if(*((uint32_t *) data) != ~0x0){
|
|
memcpy(psk_essid, data->psk_essid, sizeof(data->psk_essid));
|
|
memcpy(psk_passphrase, data->psk_passphrase, sizeof(data->psk_passphrase));
|
|
memcpy(wpa_global_PSK, data->wpa_global_PSK, sizeof(data->wpa_global_PSK));
|
|
memcpy(&channel, &(data->channel), 4);
|
|
sprintf(&key_id,"%d",(channel >> 28));
|
|
channel &= 0xff;
|
|
pscan_config = PSCAN_ENABLE | PSCAN_FAST_SURVEY;
|
|
//set partial scan for entering to listen beacon quickly
|
|
//wifi_set_pscan_chan((uint8_t *)&channel, &pscan_config, 1);
|
|
|
|
//set wifi connect
|
|
wifi.ssid.len = (int)strlen((char*)psk_essid);
|
|
memcpy(wifi.ssid.val, psk_essid, wifi.ssid.len);
|
|
wifi.key_id = key_id;
|
|
|
|
//open mode
|
|
if(!strlen((char*)psk_passphrase)){
|
|
wifi.security_type = RTW_SECURITY_OPEN;
|
|
}
|
|
//wep mode
|
|
else if( strlen((char*)psk_passphrase) == 5 || strlen((char*)psk_passphrase) == 13){
|
|
wifi.security_type = RTW_SECURITY_WEP_PSK;
|
|
wifi.password = (unsigned char *)psk_passphrase;
|
|
wifi.password_len = (int)strlen((char const *)psk_passphrase);
|
|
}
|
|
//WPA/WPA2
|
|
else{
|
|
wifi.security_type = RTW_SECURITY_WPA2_AES_PSK;
|
|
wifi.password = (unsigned char *)psk_passphrase;
|
|
wifi.password_len = (int)strlen((char const *)psk_passphrase);
|
|
}
|
|
|
|
ret = uartadapter_connect_wifi(&wifi, channel, pscan_config);
|
|
|
|
//print_simple_config_result((enum ua_sc_result)ret);
|
|
|
|
if(data)
|
|
rtw_mfree((u8*)data, sizeof(sizeof(struct wlan_fast_reconnect)));
|
|
|
|
if(ret == SC_SUCCESS)
|
|
return RTW_SUCCESS;
|
|
else
|
|
return RTW_ERROR;
|
|
}else{
|
|
ua_printf(UA_INFO, "No AP Profile read from FLASH, start simple configure");
|
|
|
|
if(data)
|
|
rtw_mfree((u8*)data, sizeof(sizeof(struct wlan_fast_reconnect)));
|
|
|
|
return RTW_ERROR;
|
|
}
|
|
}
|
|
|
|
#if CONFIG_INCLUDE_SIMPLE_CONFIG
|
|
int uartadapter_simple_config(char *pin_code){
|
|
|
|
enum sc_result ret = SC_ERROR;
|
|
wifi_enter_promisc_mode();
|
|
if(init_test_data(pin_code) == 0){
|
|
filter_add_enable();
|
|
ret = simple_config_test(NULL);
|
|
//print_simple_config_result(ret);
|
|
remove_filter();
|
|
if(ret == SC_SUCCESS)
|
|
return RTW_SUCCESS;
|
|
else
|
|
return RTW_ERROR;
|
|
}else{
|
|
return RTW_ERROR;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define _________MDNS__RELATED________________________
|
|
static void uartadapter_mdns_start(ua_socket_t *ua_socket, int is_restart)
|
|
{
|
|
TXTRecordRef txtRecord;
|
|
unsigned char txt_buf[100] = {0}; // use fixed buffer for text record to prevent malloc/free
|
|
unsigned char txt_buf2[100] = {0}; // use fixed buffer for text record to prevent malloc/free
|
|
struct sockaddr_in server_addr;
|
|
int server_addr_len = sizeof(server_addr);
|
|
|
|
struct netif * pnetif = &xnetif[0];
|
|
|
|
if(is_restart){
|
|
ua_printf(UA_INFO, "Uart Adapter mDNS Restart");
|
|
mDNSResponderDeinit();
|
|
vTaskDelay(1000);
|
|
}
|
|
|
|
ua_printf(UA_DEBUG, "Uart Adapter mDNS Init");
|
|
|
|
if(mDNSResponderInit() == 0) {
|
|
ua_printf(UA_INFO, "mDNS Register service");
|
|
char hostname[32] = {0}; //AMEBA_UART-MODE
|
|
u32 prefix_len = strlen("AMEBA_");
|
|
sprintf(hostname, "AMEBA_");
|
|
sprintf(hostname+prefix_len, "%02x%02x%02x%02x%02x%02x",
|
|
pnetif->hwaddr[0], pnetif->hwaddr[1], pnetif->hwaddr[2],
|
|
pnetif->hwaddr[3], pnetif->hwaddr[4], pnetif->hwaddr[5]);
|
|
|
|
sprintf(txt_buf2, "groupid:%d, tcpserver:%d", ua_socket->tcp.group_id, ua_socket->tcp.server_port);
|
|
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
|
|
TXTRecordSetValue(&txtRecord, "groupid", strlen(txt_buf2), txt_buf2);
|
|
|
|
ua_socket->dnsServiceRef = mDNSRegisterService(hostname, "_uart_data._tcp", "local", 5001, &txtRecord);
|
|
if(ua_socket->dnsServiceRef == NULL)
|
|
ua_printf(UA_ERROR, "mdns data service register failed!");
|
|
ua_socket->dnsServiceRef2 = mDNSRegisterService(hostname, "_uart_control._tcp", "local", 6001, &txtRecord);
|
|
if(ua_socket->dnsServiceRef2 == NULL)
|
|
ua_printf(UA_ERROR, "mdns control service register failed!");
|
|
TXTRecordDeallocate(&txtRecord);
|
|
|
|
}else{
|
|
ua_printf(UA_INFO, "mDNS Init Failed");
|
|
}
|
|
|
|
//vTaskDelete(NULL);
|
|
}
|
|
|
|
|
|
|
|
#define _________INIT__RELATED________________________
|
|
static void uartadapter_auto_reconnect(void* param)
|
|
{
|
|
ua_socket_t *ua_socket = (ua_socket_t *)param;
|
|
uint32_t IPaddress, IPaddress2;
|
|
uint8_t iptab[4], iptab2[4];
|
|
//int ret = 0;
|
|
|
|
ua_reconnect_started = 1;
|
|
|
|
#if CONFIG_AUTO_RECONNECT
|
|
wifi_set_autoreconnect(0);
|
|
#endif
|
|
vTaskDelay(1000);
|
|
while(uartadapter_load_wifi_config() != RTW_SUCCESS){
|
|
vTaskDelay(2000);
|
|
}
|
|
#if CONFIG_AUTO_RECONNECT
|
|
wifi_set_autoreconnect(1);
|
|
#endif
|
|
|
|
ua_printf(UA_INFO, "uart adapter reconnect successful");
|
|
//uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_OFF);
|
|
|
|
if(0 == memcmp(&ua_socket->ip, &xnetif[0].ip_addr, sizeof(ip_addr_t))){
|
|
IPaddress = ua_socket->ip.addr;
|
|
iptab[0] = (uint8_t)(IPaddress >> 24);
|
|
iptab[1] = (uint8_t)(IPaddress >> 16);
|
|
iptab[2] = (uint8_t)(IPaddress >> 8);
|
|
iptab[3] = (uint8_t)(IPaddress);
|
|
ua_printf(UA_INFO, "reconnect IP address no change, %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0]);
|
|
}else{
|
|
IPaddress = ua_socket->ip.addr;
|
|
iptab[0] = (uint8_t)(IPaddress >> 24);
|
|
iptab[1] = (uint8_t)(IPaddress >> 16);
|
|
iptab[2] = (uint8_t)(IPaddress >> 8);
|
|
iptab[3] = (uint8_t)(IPaddress);
|
|
IPaddress2 = xnetif[0].ip_addr.addr;
|
|
iptab2[0] = (uint8_t)(IPaddress2 >> 24);
|
|
iptab2[1] = (uint8_t)(IPaddress2 >> 16);
|
|
iptab2[2] = (uint8_t)(IPaddress2 >> 8);
|
|
iptab2[3] = (uint8_t)(IPaddress2);
|
|
ua_printf(UA_INFO, "reconnect IP address changed from %d.%d.%d.%d to %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0], iptab2[3], iptab2[2], iptab2[1], iptab2[0]);
|
|
memcpy(&ua_socket->ip, &xnetif[0].ip_addr, sizeof(ip_addr_t));
|
|
ua_reconnect_ip_change = 1;
|
|
|
|
ua_printf(UA_INFO,"IP changed, remove TCP information in FLASH!");
|
|
ua_socket->tcp.group_id = 0;
|
|
ua_socket->tcp.client_port = 0;
|
|
ua_socket->tcp.server_port = 0;
|
|
memset(ua_socket->tcp.client_ip, 0, 16);
|
|
|
|
uartadapter_mdns_start(ua_socket, 1);
|
|
}
|
|
|
|
|
|
ua_reconnect_started = 0;
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uartadapter_auto_connect(void *param)
|
|
{
|
|
int ret = 0;
|
|
ua_socket_t *ua_socket = (ua_socket_t *)param;
|
|
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
if(wifi_is_ready_to_transceive(RTW_STA_INTERFACE) == RTW_SUCCESS) {
|
|
ua_printf(UA_INFO, "wifi connect successfully!");
|
|
}else{
|
|
#if CONFIG_AUTO_RECONNECT
|
|
wifi_set_autoreconnect(0);
|
|
#endif
|
|
RETRY:
|
|
vTaskDelay(2000);
|
|
ret = uartadapter_load_wifi_config();
|
|
if(ret != RTW_SUCCESS){
|
|
vTaskDelay(2000);
|
|
#if CONFIG_INCLUDE_SIMPLE_CONFIG
|
|
ret = uartadapter_simple_config(NULL);
|
|
if(ret != RTW_SUCCESS){
|
|
ua_printf(UA_INFO, "Simple configure connect failed, try again!");
|
|
goto RETRY;
|
|
}
|
|
#endif
|
|
}
|
|
#if CONFIG_AUTO_RECONNECT
|
|
wifi_set_autoreconnect(1);
|
|
#endif
|
|
}
|
|
|
|
ua_wifi_connected = 1;
|
|
//uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_OFF);
|
|
|
|
memcpy(&ua_socket->ip, &xnetif[0].ip_addr, sizeof(ip_addr_t));
|
|
|
|
if(!sys_thread_new("tcp data server", uartadapter_tcp_chat_server_thread, (void *)ua_socket, 256, UA_UART_THREAD_PRIORITY))
|
|
ua_printf(UA_ERROR, "%s sys_thread_new data server failed\n", __FUNCTION__);
|
|
|
|
vTaskDelay(50);
|
|
if(!sys_thread_new("tcp control server", uartadapter_tcp_control_server_thread, (void *)ua_socket, 256, UA_UART_THREAD_PRIORITY))
|
|
ua_printf(UA_ERROR, "%s sys_thread_new control server failed\n", __FUNCTION__);
|
|
|
|
vTaskDelay(50);
|
|
|
|
if(!sys_thread_new("tcp select", uartadapter_tcp_select_thread, (void *)ua_socket, 768, UA_UART_THREAD_PRIORITY))
|
|
ua_printf(UA_ERROR, "%s sys_thread_new tcp select failed\n", __FUNCTION__);
|
|
|
|
vTaskDelay(50);
|
|
|
|
uartadapter_control_read_tcp_info_and_connect(ua_socket);
|
|
|
|
vTaskDelay(50);
|
|
|
|
uartadapter_mdns_start(ua_socket, 0);
|
|
|
|
vTaskDelay(50);
|
|
|
|
ua_printf(UA_INFO, "[MEM] After auao connect, available heap %d", xPortGetFreeHeapSize());
|
|
|
|
/* Kill init thread after all init tasks done */
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uartadapter_exception_thread(void *param)
|
|
{
|
|
int ret = 0;
|
|
unsigned int tick_start;
|
|
unsigned int tick_current;
|
|
int pin_high = 0;
|
|
int address = FAST_RECONNECT_DATA;
|
|
|
|
ua_socket_t *ua_socket = (ua_socket_t *)param;
|
|
|
|
while(RtlDownSema(&ua_exception_sema) == pdTRUE){
|
|
if(ua_gpio_irq_happen){
|
|
pin_high = 0;
|
|
tick_start = xTaskGetTickCount();
|
|
tick_current = xTaskGetTickCount();
|
|
while(tick_current - tick_start < 3000){
|
|
if (gpio_read(&ua_socket->gpio.gpio_btn)){
|
|
pin_high = 1;
|
|
break;
|
|
}else{
|
|
tick_current = xTaskGetTickCount();
|
|
}
|
|
vTaskDelay(10);
|
|
}
|
|
|
|
ua_gpio_irq_happen = 0;
|
|
if(!pin_high){
|
|
ret = uartadapter_flasherase(address, sizeof(rtw_wifi_config_t));
|
|
if(ret < 0){
|
|
ua_printf(UA_ERROR, "flash erase error!");
|
|
}
|
|
|
|
ret = uartadapter_flasherase(UA_FAST_RECONNECT_TCP_DATA, sizeof(ua_tcp_socket_t));
|
|
if(ret < 0){
|
|
ua_printf(UA_ERROR, "flash erase error!");
|
|
}
|
|
|
|
uartadapter_systemreload();
|
|
}
|
|
}
|
|
}
|
|
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
ua_socket_t* uartadapter_socket_init()
|
|
{
|
|
ua_socket_t* ua_socket = NULL;
|
|
//int ret = 0;
|
|
|
|
ua_socket = pvPortMalloc(sizeof(ua_socket_t));
|
|
|
|
if(NULL == ua_socket){
|
|
ua_printf(UA_ERROR, "Allocate uart adapter socket failed.");
|
|
goto Exit2;
|
|
}
|
|
|
|
ua_socket->uart.rcv_ch = 0;
|
|
ua_socket->uart.overlap = 0;
|
|
ua_socket->uart.recv_bytes = 0;
|
|
ua_socket->uart.pread = 0;
|
|
ua_socket->uart.pwrite = 0;
|
|
ua_socket->uart.tick_last_update = 0;
|
|
ua_socket->uart.tick_current = 0;
|
|
ua_socket->uart.rx_cnt = 0;
|
|
ua_socket->uart.miss_cnt = 0;
|
|
ua_socket->uart.tx_busy = 0;
|
|
RtlInitSema(&ua_socket->uart.action_sema, 0);
|
|
RtlInitSema(&ua_socket->uart.tcp_tx_rx_sema, 1);
|
|
RtlInitSema(&ua_socket->uart.dma_tx, 1);
|
|
|
|
ua_socket->tcp.chat_socket= -1;
|
|
ua_socket->tcp.control_socket= -1;
|
|
ua_socket->tcp.chat_server_listen_socket= -1;
|
|
ua_socket->tcp.control_server_listen_socket= -1;
|
|
|
|
ua_socket->tcp.transmit_recv_socket = -1;
|
|
ua_socket->tcp.transmit_send_socket = -1;
|
|
ua_socket->tcp.transmit_server_listen_socket = -1;
|
|
|
|
ua_socket->tcp.group_id = 0;
|
|
ua_socket->tcp.server_port = 0;
|
|
ua_socket->tcp.client_port = 0;
|
|
memset(ua_socket->tcp.client_ip, 0, 16);
|
|
|
|
ua_socket->tcp.send_flag = 0;
|
|
ua_socket->tcp.recv_flag = 0;
|
|
ua_socket->tcp.rx_cnt = 0;
|
|
ua_socket->tcp.tx_cnt = 0;
|
|
|
|
ua_socket->uart.uart_ps = 0;
|
|
ua_socket->uart.uart_ps_cnt = 0;
|
|
ua_socket->tcp.tcp_ps = 0;
|
|
ua_socket->tcp.tcp_ps_cnt = 0;
|
|
|
|
ua_socket->dnsServiceRef = NULL;
|
|
ua_socket->dnsServiceRef2 = NULL;
|
|
|
|
return ua_socket;
|
|
|
|
Exit2:
|
|
return NULL;
|
|
|
|
}
|
|
|
|
void uartadapter_disconnect_handler(char *buf, int buf_len, int flags, void *userdata)
|
|
{
|
|
if(!ua_wifi_connected || ua_reconnect_started)
|
|
return;
|
|
|
|
ua_printf(UA_DEBUG, "start uart adapter reconnect thread\r\n");
|
|
//uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
|
|
if(xTaskCreate(uartadapter_auto_reconnect, ((const char*)"reconnect"), 512, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(uart_rx) failed", __FUNCTION__);
|
|
|
|
}
|
|
|
|
int uartadapter_init()
|
|
{
|
|
int ret = 0;
|
|
|
|
RtlInitSema(&ua_print_sema, 1);
|
|
|
|
ua_printf(UA_INFO, "==============>%s()\n", __func__);
|
|
|
|
ua_global_socket = uartadapter_socket_init();
|
|
if(ua_global_socket == NULL){
|
|
ua_printf(UA_ERROR, "ua_socket init failed");
|
|
ret = -1;
|
|
goto Exit;
|
|
}
|
|
|
|
#if !UA_PS_ENABLE
|
|
acquire_wakelock(UA_WAKELOCK);
|
|
#endif
|
|
|
|
RtlInitSema(&ua_exception_sema, 0);
|
|
|
|
uartadapter_uart_init(ua_global_socket);
|
|
|
|
uartadapter_gpio_init(ua_global_socket);
|
|
//uartadapter_gpio_led_mode(ua_global_socket, UART_ADAPTER_LED_FAST_TWINKLE);
|
|
|
|
wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, uartadapter_disconnect_handler, NULL);
|
|
|
|
if(xTaskCreate(uartadapter_uart_rx_thread, ((const char*)"uart_rx"), 256, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(uart_rx) failed", __FUNCTION__);
|
|
|
|
vTaskDelay(50);
|
|
|
|
if(xTaskCreate(uartadapter_auto_connect, ((const char*)"auto connnect"), 1024, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(auao connnect) failed", __FUNCTION__);
|
|
|
|
vTaskDelay(50);
|
|
|
|
if(xTaskCreate(uartadapter_exception_thread, ((const char*)"uart main"), 128, (void *)ua_global_socket, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(auao connnect) failed", __FUNCTION__);
|
|
|
|
return 0;
|
|
Exit:
|
|
ua_printf(UA_ERROR, "%s(): Initialization failed!", __func__);
|
|
return ret;
|
|
}
|
|
|
|
void example_uart_adapter_init()
|
|
{
|
|
// Call back from wlan driver after wlan init done
|
|
p_wlan_uart_adapter_callback = uartadapter_init;
|
|
}
|
|
|
|
#define _________CMD__RELATED________________________
|
|
void uartadapter_print_irq_rx_count(ua_socket_t *ua_socket)
|
|
{
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_printf(UA_INFO, "ua_tick_last_update: %d!\n", ua_socket->uart.tick_last_update);
|
|
ua_printf(UA_INFO, "ua_tick_current: %d!\n", ua_socket->uart.tick_current);
|
|
ua_printf(UA_INFO, "ua current tick: %d!\n", xTaskGetTickCount());
|
|
ua_printf(UA_INFO, "ua_pwrite: %d!\n", ua_socket->uart.pwrite);
|
|
ua_printf(UA_INFO, "ua_pread: %d!\n", ua_socket->uart.pread);
|
|
ua_printf(UA_INFO, "ua_overlap: %d!\n", ua_socket->uart.overlap);
|
|
ua_printf(UA_INFO, "ua_rcv_ch: %d!\n", ua_socket->uart.rcv_ch);
|
|
ua_printf(UA_INFO, "ua_uart_recv_bytes: %d!\n", ua_socket->uart.recv_bytes);
|
|
ua_printf(UA_INFO, "irq_rx_cnt: %d!\n", ua_socket->uart.rx_cnt);
|
|
ua_printf(UA_INFO, "irq_miss_cnt: %d!\n", ua_socket->uart.miss_cnt);
|
|
ua_printf(UA_INFO, "tcp_tx_cnt: %d!\n", ua_socket->tcp.tx_cnt);
|
|
ua_printf(UA_INFO, "tcp_rx_cnt: %d!\n", ua_socket->tcp.rx_cnt);
|
|
ua_printf(UA_INFO, "tcp_send_flag: %d!\n", ua_socket->tcp.send_flag);
|
|
ua_printf(UA_INFO, "tcp_recv_flag: %d!\n", ua_socket->tcp.recv_flag);
|
|
ua_printf(UA_INFO, "tcp_chat_socket: %d!\n", ua_socket->tcp.chat_socket);
|
|
ua_printf(UA_INFO, "tcp_control_socket: %d!\n", ua_socket->tcp.control_socket);
|
|
ua_printf(UA_INFO, "tcp_transmit_recv_socket: %d!\n", ua_socket->tcp.transmit_recv_socket);
|
|
ua_printf(UA_INFO, "tcp_transmit_send_socket: %d!\n", ua_socket->tcp.transmit_send_socket);
|
|
ua_printf(UA_INFO, "tcp_chat_server_listen_socket: %d!\n", ua_socket->tcp.chat_server_listen_socket);
|
|
ua_printf(UA_INFO, "tcp_control_server_listen_socket: %d!\n", ua_socket->tcp.control_server_listen_socket);
|
|
ua_printf(UA_INFO, "tcp_transmit_server_listen_socket: %d!\n", ua_socket->tcp.transmit_server_listen_socket);
|
|
|
|
}
|
|
|
|
void uartadapter_reset_irq_rx_count(ua_socket_t *ua_socket)
|
|
{
|
|
UA_SOCKET_CHECK(ua_socket);
|
|
|
|
ua_socket->uart.rx_cnt = 0;
|
|
ua_socket->uart.miss_cnt = 0;
|
|
ua_socket->tcp.rx_cnt = 0;
|
|
ua_socket->tcp.tx_cnt = 0;
|
|
}
|
|
|
|
void uartadapter_set_debug_print(bool enable)
|
|
{
|
|
ua_debug_print_en = enable;
|
|
}
|
|
|
|
void cmd_uart_adapter(int argc, char **argv)
|
|
{
|
|
if(argc < 2) {
|
|
printf("\n\r inpua error\n");
|
|
return;
|
|
}
|
|
|
|
if(strcmp(argv[1], "help") == 0){
|
|
printf("\r\nUART THROUGH COMMAND LIST:");
|
|
printf("\r\n==============================");
|
|
printf("\r\n\tuart_baud");
|
|
printf("\r\n");
|
|
}else if(strcmp(argv[1], "irq_rx_get") == 0){
|
|
uartadapter_print_irq_rx_count(ua_global_socket);
|
|
}else if(strcmp(argv[1], "debug_print_en") == 0){
|
|
uartadapter_set_debug_print(TRUE);
|
|
}else if(strcmp(argv[1], "debug_print_dis") == 0){
|
|
uartadapter_set_debug_print(FALSE);
|
|
}else if(strcmp(argv[1], "irq_rx_reset") == 0){
|
|
uartadapter_reset_irq_rx_count(ua_global_socket);
|
|
}else if(strcmp(argv[1], "tcp") == 0){
|
|
unsigned int port;
|
|
if(strcmp(argv[2], "-c") == 0 || strcmp(argv[2], "c") == 0){
|
|
strncpy(ua_tcp_server_ip, argv[3], (strlen(argv[3])>16)?16:strlen(argv[3]));
|
|
port = atoi(argv[4]);
|
|
if(xTaskCreate(uartadapter_tcp_transmit_client_thread, ((const char*)"tclient"), 256, (void *)port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(tcp client) failed", __FUNCTION__);
|
|
}else if(strcmp(argv[2], "-s") == 0 || strcmp(argv[2], "s") == 0){
|
|
port = atoi(argv[3]);
|
|
if(xTaskCreate(uartadapter_tcp_transmit_server_thread, ((const char*)"tserver"), 256, (void *)port, UA_UART_THREAD_PRIORITY, NULL) != pdPASS)
|
|
ua_printf(UA_ERROR, "%s xTaskCreate(tcp server) failed", __FUNCTION__);
|
|
}
|
|
}else if(strcmp(argv[1], "uart_baud") == 0){
|
|
uartadapter_uart_baud(ua_global_socket, atoi(argv[2]));
|
|
}else if(strcmp(argv[1], "uart_para") == 0){
|
|
uartadapter_uart_para(ua_global_socket, atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
|
|
}else if(strcmp(argv[1], "led") == 0){
|
|
//uartadapter_gpio_led_mode(ua_global_socket, atoi(argv[2]));
|
|
}else{
|
|
printf("\n\rCan not find the input commond!");
|
|
}
|
|
}
|
|
|