support adapter_ethernet and hfa21 device

This commit is contained in:
Liu_Weichao
2021-10-20 11:13:49 +08:00
parent 3f13410d96
commit 7b82f2a60b
11 changed files with 703 additions and 86 deletions
@@ -0,0 +1,9 @@
config ADAPTER_HFA21_ETHERNET
help
Please check HFA21 can only work for adapter_wifi or adapter_ethernet in the meantime!
bool "Using ethernet adapter device HFA21"
default n
if ADAPTER_HFA21_ETHERNET
source "$APP_DIR/Framework/connection/ethernet/hfa21_ethernet/Kconfig"
endif
@@ -1,3 +1,7 @@
SRC_FILES := adapter_ethernet.c
ifeq ($(CONFIG_ADAPTER_HFA21_ETHERNET),y)
SRC_DIR += hfa21_ethernet
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -15,5 +15,112 @@
* @brief Implement the connection ethernet adapter function
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021.06.25
* @date 2021.10.15
*/
#include <adapter.h>
#ifdef ADAPTER_HFA21_ETHERNET
extern AdapterProductInfoType Hfa21EthernetAttach(struct Adapter *adapter);
#endif
#define ADAPTER_ETHERNET_NAME "ethernet"
static int AdapterEthernetRegister(struct Adapter *adapter)
{
int ret = 0;
strncpy(adapter->name, ADAPTER_ETHERNET_NAME, NAME_NUM_MAX);
adapter->net_protocol = IP_PROTOCOL;
adapter->adapter_status = UNREGISTERED;
ret = AdapterDeviceRegister(adapter);
if (ret < 0) {
printf("AdapterEthernet register error\n");
return -1;
}
return ret;
}
int AdapterEthernetInit(void)
{
int ret = 0;
struct Adapter *adapter = PrivMalloc(sizeof(struct Adapter));
if (!adapter) {
printf("AdapterEthernetInit malloc error\n");
free(adapter);
return -1;
}
memset(adapter, 0, sizeof(struct Adapter));
ret = AdapterEthernetRegister(adapter);
if (ret < 0) {
printf("AdapterEthernetInit register ethernet adapter error\n");
free(adapter);
return -1;
}
#ifdef ADAPTER_HFA21_ETHERNET
AdapterProductInfoType product_info = Hfa21EthernetAttach(adapter);
if (!product_info) {
printf("AdapterEthernetInit hfa21 attach error\n");
free(adapter);
return -1;
}
adapter->product_info_flag = 1;
adapter->info = product_info;
adapter->done = product_info->model_done;
#endif
return ret;
}
/******************ethernet TEST*********************/
int AdapterEthernetTest(void)
{
int baud_rate = BAUD_RATE_57600;
struct Adapter *adapter = AdapterDeviceFindByName(ADAPTER_ETHERNET_NAME);
#ifdef ADAPTER_HFA21_ETHERNET
char ethernet_recv_msg[128] = {0};
int i, len = 0;
const char *ethernet_msg = "Adapter Ethernet Test";
AdapterDeviceOpen(adapter);
AdapterDeviceControl(adapter, OPE_INT, &baud_rate);
AdapterDeviceSetUp(adapter);
const char *ip = "10.10.100.50";
const char *port = "12345";
enum NetRoleType net_role = SERVER;//CLIENT
enum IpType ip_type = IPV4;
AdapterDeviceConnect(adapter, net_role, ip, port, ip_type);
printf("ready to test data transfer\n");
len = strlen(ethernet_msg);
for (i = 0;i < 10; i ++) {
printf("AdapterEthernetTest send %s\n", ethernet_msg);
AdapterDeviceSend(adapter, ethernet_msg, len);
PrivTaskDelay(4000);
}
while (1) {
AdapterDeviceRecv(adapter, ethernet_recv_msg, 128);
printf("AdapterEthernetTest recv %s\n", ethernet_recv_msg);
memset(ethernet_recv_msg, 0, 128);
}
#endif
return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, AdapterEthernetTest, AdapterEthernetTest, show adapter ethernet information);
@@ -0,0 +1,33 @@
config ADAPTER_ETHERNET_HFA21
string "HFA21 ETHERNET adapter name"
default "hfa21_ethernet"
if ADD_XIUOS_FETURES
config ADAPTER_HFA21_DRIVER_EXTUART
bool "Using extra uart to support ethernet"
default n
config ADAPTER_HFA21_DRIVER
string "HFA21 device uart driver path"
default "/dev/usart3_dev3"
depends on !ADAPTER_HFA21_DRIVER_EXTUART
if ADAPTER_HFA21_DRIVER_EXTUART
config ADAPTER_HFA21_DRIVER
string "HFA21 device extra uart driver path"
default "/dev/extuart_dev6"
config ADAPTER_HFA21_DRIVER_EXT_PORT
int "if HFA21 device using extuart, choose port"
default "6"
endif
endif
if ADD_NUTTX_FETURES
endif
if ADD_RTTHREAD_FETURES
endif
@@ -0,0 +1,3 @@
SRC_FILES := hfa21_ethernet.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,453 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file hfa21_ethernet.c
* @brief Implement the connection ethernet adapter function, using HFA21 device
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021.10.15
*/
#include <adapter.h>
#include <at_agent.h>
#define HFA21_ETHERNET_AT_CMD "+++"
#define HFA21_ETHERNET_AT_CONFIRM_CMD "a"
#define HFA21_ETHERNET_AT_FCLR_CMD "AT+FCLR\r"
#define HFA21_ETHERNET_AT_FEPHY_CMD "AT+FEPHY=on\r"
#define HFA21_ETHERNET_AT_ENABLE_WANN_CMD "AT+FVEW=enable\r"
#define HFA21_ETHERNET_AT_DISABLE_WANN_CMD "AT+FVEW=disable\r"
#define HFA21_ETHERNET_AT_RELD_CMD "AT+RELD\r"
#define HFA21_ETHERNET_AT_WMODE_CMD "AT+WMODE\r"
#define HFA21_ETHERNET_AT_WANN_CMD "AT+WANN\r"
#define HFA21_ETHERNET_AT_SET_WANN_CMD "AT+WANN=%s,%s,%s,%s\r"
#define HFA21_ETHERNET_AT_PING_CMD "AT+PING=%s\r"
#define HFA21_ETHERNET_AT_NETP_CMD "AT+NETP=%s,%s,%s,%s\r"
#define HFA21_ETHERNET_AT_REBOOT_CMD "AT+Z\r"
#define HFA21_ETHERNET_OK_REPLY "+ok"
static int Hfa21EthernetSetDown(struct Adapter *adapter_at);
/**
* @description: enter AT command mode
* @param at_agent - ethernet device agent pointer
* @return success: 0
*/
static int Hfa21EthernetInitAtCmd(ATAgentType at_agent)
{
ATOrderSend(at_agent, REPLY_TIME_OUT, NULL, HFA21_ETHERNET_AT_CMD);
PrivTaskDelay(100);
ATOrderSend(at_agent, REPLY_TIME_OUT, NULL, HFA21_ETHERNET_AT_CONFIRM_CMD);
PrivTaskDelay(500);
return 0;
}
/**
* @description: Open HFA21 uart function
* @param adapter - ethernet device pointer
* @return success: 0, failure: -1
*/
static int Hfa21EthernetOpen(struct Adapter *adapter)
{
/*step1: open hfa21 serial port*/
adapter->fd = PrivOpen(ADAPTER_HFA21_DRIVER, O_RDWR);
if (adapter->fd < 0) {
printf("Hfa21EthernetOpen get serial %s fd error\n", ADAPTER_HFA21_DRIVER);
return -1;
}
/*step2: init AT agent*/
if (!adapter->agent) {
char *agent_name = "ethernet_uart_client";
if (EOK != InitATAgent(agent_name, adapter->fd, 512)) {
printf("at agent init failed !\n");
return -1;
}
ATAgentType at_agent = GetATAgent(agent_name);
adapter->agent = at_agent;
}
ADAPTER_DEBUG("Hfa21Ethernet open done\n");
return 0;
}
/**
* @description: Close HFA21 ethernet and uart function
* @param adapter - ethernet device pointer
* @return success: 0
*/
static int Hfa21EthernetClose(struct Adapter *adapter)
{
return Hfa21EthernetSetDown(adapter);
}
/**
* @description: send data to adapter
* @param adapter - ethernet device pointer
* @param data - data buffer
* @param data - data length
* @return success: 0
*/
static int Hfa21EthernetSend(struct Adapter *adapter, const void *data, size_t len)
{
int result = 0;
if (adapter->agent) {
EntmSend(adapter->agent, (const char *)data, len);
}else {
printf("Hfa21EthernetSend can not find agent!\n");
}
__exit:
return result;
}
/**
* @description: receive data from adapter
* @param adapter - ethernet device pointer
* @param data - data buffer
* @param data - data length
* @return success: 0
*/
static int Hfa21EthernetReceive(struct Adapter *adapter, void *rev_buffer, size_t buffer_len)
{
int result = 0;
if (adapter->agent) {
return EntmRecv(adapter->agent, (char *)rev_buffer, buffer_len, 40000);
} else {
printf("Hfa21EthernetReceive can not find agent!\n");
}
__exit:
return result;
}
/**
* @description: connnect Ethernet to internet
* @param adapter - Ethernet device pointer
* @return success: 0
*/
static int Hfa21EthernetSetUp(struct Adapter *adapter)
{
int ret = 0;
AtSetReplyLrEnd(adapter->agent, 1);
/* wait hfa21 device startup finish */
PrivTaskDelay(5000);
/*Step1 : enter AT mode*/
Hfa21EthernetInitAtCmd(adapter->agent);
PrivTaskDelay(1000);
/*Step2 : FCLR reboot*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_FCLR_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
PrivTaskDelay(10000);
Hfa21EthernetInitAtCmd(adapter->agent);
/*Step3 : FEPHY enable phy function*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_FEPHY_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
/*Step4 : FVEW disable WANN function, ethernet work at LANN mode*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_DISABLE_WANN_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
/*Step5 : RELD enable F-AT cmd*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_RELD_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
PrivTaskDelay(10000);
Hfa21EthernetInitAtCmd(adapter->agent);
/*Step6 : AT+WMODE check work mode, AP or STA*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_WMODE_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
/*Step7 : AT+WANN check if get ip、netmask、gateway*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_WANN_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
/*Step8 : AT+Z reboot hfa21 device*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_REBOOT_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
PrivTaskDelay(10000);
return ret;
__exit:
Hfa21EthernetSetDown(adapter);
return -1;
}
/**
* @description: disconnnect ethernet from internet
* @param adapter - ethernet device pointer
* @return success: 0
*/
static int Hfa21EthernetSetDown(struct Adapter *adapter)
{
Hfa21EthernetInitAtCmd(adapter->agent);
ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, HFA21_ETHERNET_AT_FCLR_CMD);
PrivTaskDelay(20000);
return 0;
}
/**
* @description: set ethernet ip/gateway/netmask address(in sta mode) working at WANN mode
* @param adapter - ethernet device pointer
* @param ip - ip address
* @param gateway - gateway address
* @param netmask - netmask address
* @return success: 0, failure: -ENOMEMORY or -1
*/
static int Hfa21EthernetSetAddr(struct Adapter *adapter, const char *ip, const char *gateway, const char *netmask)
{
int ret = 0;
uint8_t hfa21_ethernet_cmd[64];
/*Step1 : enter AT mode*/
Hfa21EthernetInitAtCmd(adapter->agent);
/*Step2 : set mode、ip、netmask and gateway*/
memset(hfa21_ethernet_cmd, 0, sizeof(hfa21_ethernet_cmd));
sprintf(hfa21_ethernet_cmd, HFA21_ETHERNET_AT_SET_WANN_CMD, "DHCP", ip, netmask, gateway);
ret = AtCmdConfigAndCheck(adapter->agent, hfa21_ethernet_cmd, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
/*Step3 : AT+WANN check if set ip、netmask、gateway successfully*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_WANN_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
/*Step4 : AT+Z reboot hfa21 device*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_REBOOT_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
PrivTaskDelay(10000);
return ret;
__exit:
Hfa21EthernetSetDown(adapter);
return -1;
}
/**
* @description: ethernet ping function
* @param adapter - ethernet device pointer
* @param destination - domain name or ip address
* @return success: 0, failure: -1
*/
static int Hfa21EthernetPing(struct Adapter *adapter, const char *destination)
{
int ret = 0;
char *ping_result = (char *) PrivCalloc(1, 17);
char *dst = (char *) PrivCalloc(1, 17);
strcpy(dst, destination);
strcat(dst, "\r");
printf("Hfa21EthernetPing [%s]\n", dst);
/*Step1 : enter AT mode*/
Hfa21EthernetInitAtCmd(adapter->agent);
/*Step2 : ping dst ip address*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_PING_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
/*Step3 : AT+Z reboot hfa21 device*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_REBOOT_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
return ret;
__exit:
Hfa21EthernetSetDown(adapter);
return -1;
}
/**
* @description: ethernet connect function
* @param adapter - ethernet device pointer
* @param net_role - net role, CLIENT or SERVER
* @param ip - ip address
* @param port - port num
* @param ip_type - ip type, IPV4 or IPV6
* @return success: 0, failure: -1
*/
static int Hfa21EthernetConnect(struct Adapter *adapter, enum NetRoleType net_role, const char *ip, const char *port, enum IpType ip_type)
{
int ret = 0;
char hfa21_ethernet_cmd[128];
char net_role_string[6] = {0};
/*Step1 : enter AT mode*/
Hfa21EthernetInitAtCmd(adapter->agent);
if (CLIENT == net_role) {
strcpy(net_role_string, "CLIENT");
} else if (SERVER == net_role) {
strcpy(net_role_string, "SERVER");
} else {
printf("Hfa21EthernetConnect do not support %d net type\n", net_role);
return -1;
}
if (IPV4 == ip_type) {
/*to do*/
} else if (IPV6 == ip_type) {
/*to do*/
} else {
printf("Hfa21EthernetConnect do not support %d ip type\n", ip_type);
return -1;
}
/*Step2 : create tcp connect*/
memset(hfa21_ethernet_cmd, 0, sizeof(hfa21_ethernet_cmd));
sprintf(hfa21_ethernet_cmd, HFA21_ETHERNET_AT_NETP_CMD, "TCP", net_role_string, port, ip);
ret = AtCmdConfigAndCheck(adapter->agent, hfa21_ethernet_cmd, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
adapter->net_role = net_role;
/*Step3 : AT+Z reboot hfa21 device*/
ret = AtCmdConfigAndCheck(adapter->agent, HFA21_ETHERNET_AT_REBOOT_CMD, HFA21_ETHERNET_OK_REPLY);
if (ret < 0) {
goto __exit;
}
PrivTaskDelay(10000);
return ret;
__exit:
Hfa21EthernetSetDown(adapter);
return -1;
}
static int Hfa21EthernetIoctl(struct Adapter *adapter, int cmd, void *args)
{
if (OPE_INT != cmd) {
printf("Hfa21EthernetIoctl only support OPE_INT, do not support %d\n", cmd);
return -1;
}
uint32_t baud_rate = *((uint32_t *)args);
struct SerialDataCfg serial_cfg;
memset(&serial_cfg, 0 ,sizeof(struct SerialDataCfg));
serial_cfg.serial_baud_rate = baud_rate;
serial_cfg.serial_data_bits = DATA_BITS_8;
serial_cfg.serial_stop_bits = STOP_BITS_1;
serial_cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
serial_cfg.serial_parity_mode = PARITY_NONE;
serial_cfg.serial_bit_order = BIT_ORDER_LSB;
serial_cfg.serial_invert_mode = NRZ_NORMAL;
#ifdef ADAPTER_HFA21_DRIVER_EXT_PORT
serial_cfg.ext_uart_no = ADAPTER_HFA21_DRIVER_EXT_PORT;
serial_cfg.port_configure = PORT_CFG_INIT;
#endif
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = SERIAL_TYPE;
ioctl_cfg.args = &serial_cfg;
PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg);
printf("Hfa21EthernetIoctl success\n");
return 0;
}
static const struct IpProtocolDone hfa21_ethernet_done =
{
.open = Hfa21EthernetOpen,
.close = Hfa21EthernetClose,
.ioctl = Hfa21EthernetIoctl,
.setup = Hfa21EthernetSetUp,
.setdown = Hfa21EthernetSetDown,
.setaddr = Hfa21EthernetSetAddr,
.setdns = NULL,
.setdhcp = NULL,
.ping = Hfa21EthernetPing,
.netstat = NULL,
.connect = Hfa21EthernetConnect,
.send = Hfa21EthernetSend,
.recv = Hfa21EthernetReceive,
.disconnect = NULL,
};
/**
* @description: Register ethernet device hfa21
* @return success: product_info, failure: NULL
*/
AdapterProductInfoType Hfa21EthernetAttach(struct Adapter *adapter)
{
struct AdapterProductInfo *product_info = PrivMalloc(sizeof(struct AdapterProductInfo));
if (!product_info) {
printf("Hfa21EthernetAttach Attach malloc product_info error\n");
PrivFree(product_info);
return NULL;
}
strcpy(product_info->model_name, ADAPTER_ETHERNET_HFA21);
product_info->model_done = (void *)&hfa21_ethernet_done;
return product_info;
}