更新硬件SDK

This commit is contained in:
kerwincui
2023-03-04 03:44:56 +08:00
parent dcdf6e1b7c
commit e39d3d2f03
1900 changed files with 663153 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
/*
* dns_def.h
*
* Created on: 2022年4月13日
* Author: Administrator
*/
#ifndef __ETHERNET_COMMON_DNS_DEF_H__
#define __ETHERNET_COMMON_DNS_DEF_H__
#define DNS_SERVER_PORT (53)
#define MAX_DNS_SERVER 4
#include "luat_network_adapter.h"
typedef struct
{
llist_head node;
Buffer_Struct uri; //动态需要释放
luat_dns_ip_result ip_result[MAX_DNS_IP];
void *param;
int result;
uint8_t adapter_index;
}luat_dns_require_t;
typedef struct
{
luat_ip_addr_t dns_server[MAX_DNS_SERVER];
llist_head process_head;
llist_head require_head;
uint16_t session_id;
uint8_t is_static_dns[MAX_DNS_SERVER];
uint8_t is_run;
}dns_client_t;
void dns_init_client(dns_client_t *client);
uint8_t dns_check_uri(const char *uri, uint32_t uri_len);
void dns_require(dns_client_t *client, const char *domain_name, uint32_t len, void *param);
void dns_require_ex(dns_client_t *client, const char *domain_name, void *param, uint8_t adapter_index);
void dns_clear(dns_client_t *client);
void dns_run(dns_client_t *client, Buffer_Struct *in, Buffer_Struct *out, int *server_cnt);
#endif /* __ETHERNET_COMMON_DNS_DEF_H__ */

View File

@@ -0,0 +1,483 @@
#ifndef __LUAT_NW_ADAPTER_H__
#define __LUAT_NW_ADAPTER_H__
#include "luat_base.h"
#define LUAT_USE_LWIP
#define LUAT_USE_TLS
#define LUAT_USE_DNS
#define LWIP_NUM_SOCKETS 8
// #ifdef LUAT_USE_NETWORK
#include "luat_rtos.h"
#include "bsp_common.h"
#ifdef LUAT_USE_TLS
#include "mbedtls/ssl.h"
#include "mbedtls/platform.h"
#include "mbedtls/debug.h"
#include "mbedtls/x509_crt.h"
#include "mbedtls/base64.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/sha1.h"
#endif
#ifdef LUAT_USE_LWIP
#include "lwip/opt.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/ip4_frag.h"
#include "lwip/etharp.h"
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/igmp.h"
#include "lwip/dns.h"
#include "lwip/nd6.h"
#include "lwip/ip6_frag.h"
#include "lwip/mld6.h"
#include "lwip/dhcp6.h"
#include "lwip/sys.h"
#include "lwip/pbuf.h"
#include "lwip/inet.h"
#endif
#ifndef __BSP_COMMON_H__
#include "c_common.h"
#endif
#define MAX_DNS_IP (4) //每个URL最多保留4个IP
enum
{
EV_NW_RESET = USER_EVENT_ID_START + 0x1000000,
EV_NW_STATE,
EV_NW_TIMEOUT,
EV_NW_DNS_RESULT,
EV_NW_SOCKET_TX_OK,
EV_NW_SOCKET_RX_NEW,
EV_NW_SOCKET_RX_FULL,
EV_NW_SOCKET_CLOSE_OK,
EV_NW_SOCKET_REMOTE_CLOSE,
EV_NW_SOCKET_CONNECT_OK,
EV_NW_SOCKET_ERROR,
EV_NW_SOCKET_LISTEN,
EV_NW_SOCKET_NEW_CONNECT, //作为server接收到新的connect只有允许accept操作的才有否则直接上报CONNECT_OK
EV_NW_BREAK_WAIT,
EV_NW_END,
NW_STATE_LINK_OFF = 0,
NW_STATE_OFF_LINE,
NW_STATE_WAIT_DNS,
NW_STATE_CONNECTING,
NW_STATE_SHAKEHAND,
NW_STATE_ONLINE,
NW_STATE_LISTEN,
NW_STATE_DISCONNECTING,
NW_WAIT_NONE = 0,
NW_WAIT_LINK_UP,
NW_WAIT_ON_LINE,
NW_WAIT_TX_OK,
NW_WAIT_OFF_LINE,
NW_WAIT_EVENT,
//一旦使用高级API回调会改为下面的param1 = 0成功其他失败
EV_NW_RESULT_BASE = EV_NW_END + 1,
EV_NW_RESULT_LINK = EV_NW_RESULT_BASE + NW_WAIT_LINK_UP,
EV_NW_RESULT_CONNECT = EV_NW_RESULT_BASE + NW_WAIT_ON_LINE,
EV_NW_RESULT_CLOSE = EV_NW_RESULT_BASE + NW_WAIT_OFF_LINE,
EV_NW_RESULT_TX = EV_NW_RESULT_BASE + NW_WAIT_TX_OK,
EV_NW_RESULT_EVENT = EV_NW_RESULT_BASE + NW_WAIT_EVENT,
NW_ADAPTER_INDEX_LWIP_NONE = 0,
NW_ADAPTER_INDEX_LWIP_GPRS, //蜂窝网络模块
NW_ADAPTER_INDEX_LWIP_WIFI_STA, //WIFI SOC
NW_ADAPTER_INDEX_LWIP_WIFI_AP, //WIFI SOC
NW_ADAPTER_INDEX_LWIP_ETH, //自带以太网控制器的SOC
NW_ADAPTER_INDEX_LWIP_NETIF_QTY,
NW_ADAPTER_INDEX_HW_PS_DEVICE = NW_ADAPTER_INDEX_LWIP_NETIF_QTY,
NW_ADAPTER_INDEX_ETH0 = NW_ADAPTER_INDEX_HW_PS_DEVICE, //外挂以太网+硬件协议栈
NW_ADAPTER_INDEX_USB, //USB网卡
NW_ADAPTER_QTY,
NW_CMD_AUTO_HEART_TIME = 0,
};
#ifdef LUAT_USE_LWIP
#define luat_ip_addr_t ip_addr_t
#else
typedef struct
{
union
{
uint32_t ipv4;
uint32_t ipv6_u32_addr[4];
uint8_t ipv6_u8_addr[16];
};
uint8_t is_ipv6;
}luat_ip_addr_t;
uint8_t network_string_is_ipv4(const char *string, uint32_t len);
uint32_t network_string_to_ipv4(const char *string, uint32_t len);
int network_string_to_ipv6(const char *string, luat_ip_addr_t *ip_addr);
#endif
typedef struct
{
uint64_t tag;
void *param;
}luat_network_cb_param_t;
typedef struct
{
uint32_t ttl_end;
luat_ip_addr_t ip;
}luat_dns_ip_result;
typedef struct
{
/* data */
llist_head node;
Buffer_Struct uri;
luat_dns_ip_result result[MAX_DNS_IP];
uint8_t ip_nums;
}luat_dns_cache_t;
typedef struct
{
uint64_t tx_size;
uint64_t ack_size;
uint64_t tag;
#ifdef LUAT_USE_TLS
//SSL相关数据均为动态生成的需要在close的时候释放
mbedtls_ssl_context *ssl; /**< mbed TLS control context. */
mbedtls_ssl_config *config; /**< mbed TLS configuration context. */
mbedtls_x509_crt *ca_cert;
#endif
CBFuncEx_t user_callback;
void *user_data; //传递给user_callback的pParam
void *socket_param; //一般用来存放network_ctrl本身用于快速查找
HANDLE task_handle;
HANDLE timer;
HANDLE tls_short_timer;
HANDLE tls_long_timer;
HANDLE mutex;
uint32_t tcp_keep_idle;
int socket_id;
char *domain_name; //动态生成的需要在close的时候释放
uint32_t domain_name_len;
luat_ip_addr_t remote_ip;
luat_dns_ip_result *dns_ip; //动态生成的需要在close的时候释放
luat_ip_addr_t *online_ip; //指向某个ip无需释放
uint16_t remote_port;
uint16_t local_port;
uint8_t *cache_data; //动态生成的需要在close的时候释放
uint32_t cache_len;
int tls_timer_state;
uint32_t tcp_timeout_ms;
uint8_t tls_mode;
uint8_t tls_need_reshakehand;
uint8_t need_close;
uint8_t new_rx_flag;
uint8_t dns_ip_cnt;
uint8_t dns_ip_nums;
uint8_t tcp_keep_alive;
uint8_t tcp_keep_interval;
uint8_t tcp_keep_cnt;
uint8_t adapter_index;
uint8_t is_tcp;
uint8_t is_server_mode;
uint8_t auto_mode;
uint8_t wait_target_state;
uint8_t state;
uint8_t is_debug;
}network_ctrl_t;
typedef struct
{
uint64_t tag;
#ifdef LUAT_USE_LWIP
llist_head wait_ack_head;
#endif
llist_head tx_head;
llist_head rx_head;
uint32_t rx_wait_size;
uint32_t tx_wait_size;
#ifdef LUAT_USE_LWIP
union {
struct ip_pcb *ip;
struct tcp_pcb *tcp;
struct udp_pcb *udp;
struct raw_pcb *raw;
} pcb;
HANDLE mutex;
uint16_t local_port;
uint16_t remote_port;
#endif
void *param;
uint8_t state;
uint8_t is_tcp;
uint8_t is_ipv6;
uint8_t in_use;
uint8_t rx_waiting;
}socket_ctrl_t; //推荐底层协议栈适配用的socket状态结构
/*
* info内的api必须全部是非阻塞的及任务的并且对socket_id和tag做合法性检查
* 目前只支持tcp和udp不支持raw
* 如果没有特殊说明,成功返回=0失败返回<0
*/
typedef struct
{
//检查网络是否准备好返回非0准备好user_data是注册时的user_data传入给底层api
uint8_t (*check_ready)(void *user_data);
//创建一个socket并设置成非阻塞模式user_data传入对应适配器, tag作为socket的合法依据给check_socket_vaild比对用
//成功返回socketid失败 < 0
int (*create_soceket)(uint8_t is_tcp, uint64_t *tag, void *param, uint8_t is_ipv6, void *user_data);
//作为client绑定一个port并连接remote_ip和remote_port对应的server
//成功返回0失败 < 0
int (*socket_connect)(int socket_id, uint64_t tag, uint16_t local_port, luat_ip_addr_t *remote_ip, uint16_t remote_port, void *user_data);
//作为server绑定一个port开始监听
//成功返回0失败 < 0
int (*socket_listen)(int socket_id, uint64_t tag, uint16_t local_port, void *user_data);
//作为server接受一个client
//成功返回0失败 < 0
int (*socket_accept)(int socket_id, uint64_t tag, luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data);
//主动断开一个tcp连接需要走完整个tcp流程用户需要接收到close ok回调才能确认彻底断开
//成功返回0失败 < 0
int (*socket_disconnect)(int socket_id, uint64_t tag, void *user_data);
//释放掉socket的控制权除了tag异常外必须立刻生效
//成功返回0失败 < 0
int (*socket_close)(int socket_id, uint64_t tag, void *user_data);
//强行释放掉socket的控制权必须立刻生效
//成功返回0失败 < 0
int (*socket_force_close)(int socket_id, void *user_data);
//tcp时不需要remote_ip和remote_port如果buf为NULL则返回当前缓存区的数据量当返回值小于len时说明已经读完了
//udp时只返回1个block数据需要多次读直到没有数据为止
//成功返回实际读取的值,失败 < 0
int (*socket_receive)(int socket_id, uint64_t tag, uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data);
//tcp时不需要remote_ip和remote_port
//成功返回>0的len缓冲区满了=0失败 < 0如果发送了len=0的空包也是返回0注意判断
int (*socket_send)(int socket_id, uint64_t tag, const uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t remote_port, void *user_data);
//检查socket合法性成功返回0失败 < 0
int (*socket_check)(int socket_id, uint64_t tag, void *user_data);
//保留有效的socket将无效的socket关闭
void (*socket_clean)(int *vaild_socket_list, uint32_t num, void *user_data);
int (*getsockopt)(int socket_id, uint64_t tag, int level, int optname, void *optval, uint32_t *optlen, void *user_data);
int (*setsockopt)(int socket_id, uint64_t tag, int level, int optname, const void *optval, uint32_t optlen, void *user_data);
//非posix的socket用这个根据实际硬件设置参数
int (*user_cmd)(int socket_id, uint64_t tag, uint32_t cmd, uint32_t value, void *user_data);
int (*dns)(const char *domain_name, uint32_t len, void *param, void *user_data);
int (*set_dns_server)(uint8_t server_index, luat_ip_addr_t *ip, void *user_data);
#ifdef LUAT_USE_LWIP
int (*set_mac)(uint8_t *mac, void *user_data);
int (*set_static_ip)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, luat_ip_addr_t *ipv6, void *user_data);
#endif
int (*get_local_ip_info)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, void *user_data);
//所有网络消息都是通过cb_fun回调
//cb_fun回调时第一个参数为OS_EVENT包含了socket的必要信息第二个是luat_network_cb_param_t其中的param是这里传入的param(就是适配器序号)
//OS_EVENT ID为EV_NW_XXXparam1是socket id param2是各自参数 param3是create_soceket传入的socket_param(就是network_ctrl *)
//dns结果是特别的ID为EV_NW_SOCKET_DNS_RESULTparam1是获取到的IP数据量0就是失败了param2是ip组动态分配的 param3是dns传入的param(就是network_ctrl *)
void (*socket_set_callback)(CBFuncEx_t cb_fun, void *param, void *user_data);
char *name;
int max_socket_num;//最大socket数量也是最大network_ctrl申请数量的基础值
uint8_t no_accept;
uint8_t is_posix;
}network_adapter_info;
/*
* api有可能涉及到任务安全要求不可以在中断里运行只能在task中运行
*/
//获取最后一个注册的适配器序号
int network_get_last_register_adapter(void);
/****************************以下是通用基础api********************************************************/
/*
* 在使用之后任意API前必须先注册相关的协议栈接口
* 没有可逆的api
*/
int network_register_adapter(uint8_t adapter_index, network_adapter_info *info, void *user_data);
void network_register_set_default(uint8_t adapter_index);
void network_set_dns_server(uint8_t adapter_index, uint8_t server_index, luat_ip_addr_t *ip);
/*
* 申请一个network_ctrl
*/
network_ctrl_t *network_alloc_ctrl(uint8_t adapter_index);
/*
* 归还一个network_ctrl
*/
void network_release_ctrl(network_ctrl_t *ctrl);
/*
* 在使用network_ctrl前必须先初始化
* lua调用c时必须使用非阻塞接口task_handlecallbackparam都不需要
* 在纯c调用时如果不需要则塞应用必须有callback和param
* 在纯c调用时如果需要阻塞应用则必须有task_handle建议有callbackparam可以等待消息时同时在callback中处理其他类型的消息
*/
void network_init_ctrl(network_ctrl_t *ctrl, HANDLE task_handle, CBFuncEx_t callback, void *param);
/*
* 设置是tcp还是udp模式及TCP自动保活相关参数也可以直接改network_ctrl_t中的is_tcp参数
* 设置必须在socket处于close状态在进行connect和tls初始之前
*/
void network_set_base_mode(network_ctrl_t *ctrl, uint8_t is_tcp, uint32_t tcp_timeout_ms, uint8_t keep_alive, uint32_t keep_idle, uint8_t keep_interval, uint8_t keep_cnt);
/*
* 检查网络是否已经连接注意不是socket
* 返回非0是已连接可以开始socket操作
*/
uint8_t network_check_ready(network_ctrl_t *ctrl);
/*
* 设置本地port注意不要用60000及以上如果local_port为0系统从60000开始随机抽一个
* 如果local_port不为0且重复了则返回-1其他返回0
*/
int network_set_local_port(network_ctrl_t *ctrl, uint16_t local_port);
//创建一个socket
//成功返回0失败 < 0
int network_create_soceket(network_ctrl_t *ctrl, uint8_t is_ipv6);
//作为client连接server
//成功返回0失败 < 0
int network_socket_connect(network_ctrl_t *ctrl, luat_ip_addr_t *remote_ip);
//作为server开始监听
//成功返回0失败 < 0
int network_socket_listen(network_ctrl_t *ctrl);
uint8_t network_accept_enable(network_ctrl_t *ctrl);
//作为server接受一个client
//成功返回0失败 < 0
int network_socket_accept(network_ctrl_t *ctrl, network_ctrl_t *accept_ctrl);
//主动断开一个tcp连接需要走完整个tcp流程用户需要接收到close ok回调才能确认彻底断开
//成功返回0失败 < 0
int network_socket_disconnect(network_ctrl_t *ctrl);
//释放掉socket的控制权
//成功返回0失败 < 0
int network_socket_close(network_ctrl_t *ctrl);
//强行释放掉socket的控制权
//成功返回0失败 < 0
int network_socket_force_close(network_ctrl_t *ctrl);
//tcp时不需要remote_ip和remote_port如果buf为NULL则返回当前缓存区的数据量当返回值小于len时说明已经读完了
//udp时只返回1个block数据需要多次读直到没有数据为止
//成功返回实际读取的值,失败 < 0
int network_socket_receive(network_ctrl_t *ctrl,uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t *remote_port);
//tcp时不需要remote_ip和remote_port
//成功返回0失败 < 0
int network_socket_send(network_ctrl_t *ctrl,const uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t remote_port);
int network_getsockopt(network_ctrl_t *ctrl, int level, int optname, void *optval, uint32_t *optlen);
int network_setsockopt(network_ctrl_t *ctrl, int level, int optname, const void *optval, uint32_t optlen);
//非posix的socket用这个根据实际硬件设置参数
int network_user_cmd(network_ctrl_t *ctrl, uint32_t cmd, uint32_t value);
#ifdef LUAT_USE_LWIP
int network_set_mac(uint8_t adapter_index, uint8_t *mac);
int network_set_static_ip_info(uint8_t adapter_index, luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, luat_ip_addr_t *ipv6);
#endif
int network_get_local_ip_info(network_ctrl_t *ctrl, luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway);
void network_force_close_socket(network_ctrl_t *ctrl);
//url已经是ip形式了返回1并且填充remote_ip
//成功返回0失败 < 0
int network_dns(network_ctrl_t *ctrl);
void network_clean_invaild_socket(uint8_t adapter_index);
const char *network_ctrl_state_string(uint8_t state);
const char *network_ctrl_wait_state_string(uint8_t state);
const char *network_ctrl_callback_event_string(uint32_t event);
/****************************通用基础api结束********************************************************/
/****************************tls相关api************************************************************/
/*
* 给DTLS设置PSK给UDP加密传输时用的
*/
int network_set_psk_info(network_ctrl_t *ctrl,
const unsigned char *psk, size_t psk_len,
const unsigned char *psk_identity, size_t psk_identity_len);
/*
* TLS设置验证服务器的证书可以不用
*/
int network_set_server_cert(network_ctrl_t *ctrl, const unsigned char *cert, size_t cert_len);
/*
* TLS设置验证客户端的证书只有双向认证才需要而且一般只有金融领域才需要
*/
int network_set_client_cert(network_ctrl_t *ctrl,
const unsigned char *cert, size_t certLen,
const unsigned char *key, size_t keylen,
const unsigned char *pwd, size_t pwdlen);
/*
* 获取证书验证结果
*/
int network_cert_verify_result(network_ctrl_t *ctrl);
/*
* 初始化加密传输
* verify_mode参考MBEDTLS_SSL_VERIFY_XXX
*/
void network_init_tls(network_ctrl_t *ctrl, int verify_mode);
/*
* 结束加密传输模式,恢复成正常模式
*/
void network_deinit_tls(network_ctrl_t *ctrl);
/*
* 加密传输其他非阻塞api和通用api共用阻塞api和rtos环境相关阻塞api通用均由api内部做相关处理
*/
/****************************tls相关api结束************************************************************/
/****************************高级api用于实现一个完整功能***********************/
//一旦使用下面的api将由network内部自动判断状态并进行下一步操作中间处理过程除了主动强制关闭socket其他用户不能干预直到达到目标状态即使非阻塞回调也只回调最终结果。
//所有阻塞状态接口一旦收到link downsocket close, error之类的消息就会返回错误如果是timeout只有wait event会返回成功其他返回失败
//以下api是阻塞和非则塞均可当network_ctrl中设置了task_handle 而且 timeout_ms > 0时为阻塞接口
//返回值统一成功返回0失败 < 0非阻塞需要等待返回1
int network_wait_link_up(network_ctrl_t *ctrl, uint32_t timeout_ms);
/*
* 1.进行ready检测和等待ready
* 2.有remote_ip则开始连接服务器并等待连接结果
* 3.没有remote_ip则开始对url进行dns解析解析完成后对所有ip进行尝试连接直到有个成功或者全部失败
* 4.如果是加密模式,还要走握手环节,等到握手环节完成后才能返回结果
* local_port如果为0则api内部自动生成一个
* 使用前必须确保是在close状态建议先用network_close
*/
int network_connect(network_ctrl_t *ctrl, const char *domain_name, uint32_t domain_name_len, luat_ip_addr_t *remote_ip, uint16_t remote_port, uint32_t timeout_ms);
int network_listen(network_ctrl_t *ctrl, uint32_t timeout_ms);
int network_close(network_ctrl_t *ctrl, uint32_t timeout_ms);
/*
* timeout_ms=0时为非阻塞接口
* UDP的时候remote_ip和remote_port和connect不一致的时候才需要remote_ip和remote_port
* TCP不看remote_ip和remote_port
* 则塞模式,*tx_len不需要看非则塞模式需要看*tx_len的实际长度是不是和len一致
*/
int network_tx(network_ctrl_t *ctrl, const uint8_t *data, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t remote_port, uint32_t *tx_len, uint32_t timeout_ms);
/*
* 实际读到的数据量在read_len里如果是UDP模式且为server时需要看remote_ip和remote_port
*/
int network_rx(network_ctrl_t *ctrl, uint8_t *data, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t *remote_port, uint32_t *rx_len);
/*
* 接收到socket异常消息均会返回
* timeout_ms=0时为非阻塞接口
* 如果为阻塞接口out_event保存消息拷贝非引用is_timeout保存是否超时
* 返回0表示有数据接收或者超时返回返回1表示切换到非阻塞等待其他为网络异常
*/
int network_wait_event(network_ctrl_t *ctrl, OS_EVENT *out_event, uint32_t timeout_ms, uint8_t *is_timeout);
/*
* 接收到socket异常用户发送EV_NW_BREAK_WAIT或者有新数据都会返回如果是其他消息通过network_init_ctrl里输入的回调函数使用如果没有回调函数就直接抛弃了
* timeout_ms=0时依然为阻塞接口而且是永远等待
* 返回0表示有数据接收用户打断或者超时返回其他为网络异常
* 用户打断is_break = 1超时 is_timeout = 1
*/
int network_wait_rx(network_ctrl_t *ctrl, uint32_t timeout_ms, uint8_t *is_break, uint8_t *is_timeout);
/****************************高级api结束********************************************************************/
#endif
// #endif

View File

@@ -0,0 +1,21 @@
#ifndef __NET_LWIP_H__
#define __NET_LWIP_H__
void net_lwip_register_adapter(uint8_t adapter_index);
void net_lwip_init(void);
int net_lwip_check_all_ack(int socket_id);
void net_lwip_set_netif(uint8_t adapter_index, struct netif *netif, void *init, uint8_t is_default);
struct netif * net_lwip_get_netif(uint8_t adapter_index);
void net_lwip_input_packets(struct netif *netif, struct pbuf *p);
/*
* 如果是需要使用静态IP则需要先设置好IP再设置linkup
* 如果之前设置了静态IP现在想用动态IP需要先删掉静态IP再linkup
* 一旦linkup如果没有使用静态IP就会启动DHCP
* 不能用过DHCP获取IP的网卡必须先设置静态IP比如GPRS
*/
void net_lwip_set_link_state(uint8_t adapter_index, uint8_t updown);
/*
* GPRS网卡专用user_data填adapter_index不从network_adapter走
*/
int net_lwip_set_static_ip(ip_addr_t *ip, ip_addr_t *submask, ip_addr_t *gateway, ip_addr_t *ipv6, void *user_data);
#endif

View File

@@ -0,0 +1,26 @@
#ifndef ETHERNET_COMMON_PLATFORM_DEF_H_
#define ETHERNET_COMMON_PLATFORM_DEF_H_
#define platform_random luat_crypto_trng
#define platform_send_event luat_send_event_to_task
#define platform_wait_event luat_wait_event_from_task
#define platform_create_task luat_rtos_task_create
#define platform_get_current_task luat_get_current_task
#define platform_task_sleep luat_timer_mdelay
#define platform_create_timer luat_create_rtos_timer
#define platform_start_timer luat_start_rtos_timer
#define platform_stop_timer luat_stop_rtos_timer
#define platform_release_timer luat_release_rtos_timer
#define platform_create_mutex luat_mutex_create
#define platform_lock_mutex luat_mutex_lock
#define platform_unlock_mutex luat_mutex_unlock
#define platform_release_mutex luat_mutex_release
#define msleep luat_timer_mdelay
#define OS_LOCK luat_task_suspend_all()
#define OS_UNLOCK luat_task_resume_all()
#endif /* ETHERNET_COMMON_PLATFORM_DEF_H_ */

View File

@@ -0,0 +1,646 @@
#include "luat_mcu.h"
#include "common_api.h"
#include "platform_def.h"
#include "dns_def.h"
#include "ctype.h"
#include "luat_network_adapter.h"
#define dnsONE_QUESTION 0x0001
#define dnsFLAG_QUERY_RESPONSE_BIT 0x8000
#define dnsFLAG_OPERATION_CODE_BITS 0x7800
#define dnsFLAG_TRUNCATION_BIT 0x0200
#define dnsFLAG_RESPONSE_CODE_BITS 0x000f
#define dnsOUTGOING_FLAGS 0x0100 /* Standard query. */
#define dnsTYPE_IPV4 0x0001 /* A record (host address. */
#define dnsCLASS 0x0001 /* IN */
#define dnsRX_FLAGS_MASK 0x800f /* The bits of interest in the flags field of incoming DNS messages. */
#define dnsEXPECTED_RX_FLAGS 0x8000 /* Should be a response, without any errors. */
#define dnsTYPE_IPV6 0x001C
#define dnsNAME_IS_OFFSET ( ( uint8_t ) 0xc0 )
#define MAX_DOMAIN_LEN 255
#define MAX_CHARACTER_NUM_PER_LABEL 63
#define DNS_TO_BASE (900)
#define DNS_TRY_MAX (3)
#ifdef LUAT_USE_LWIP
#define GetSysTickMS luat_mcu_tick64_ms
#endif
//extern void DBG_Printf(const char* format, ...);
//extern void DBG_HexPrintf(void *Data, unsigned int len);
//#ifdef LUAT_LOG_NO_NEWLINE
//#define DBG(x,y...) DBG_Printf("%s %d:"x, __FUNCTION__,__LINE__,##y)
//#define DBG_ERR(x,y...) DBG_Printf("%s %d:"x, __FUNCTION__,__LINE__,##y)
//#else
//#define DBG(x,y...) DBG_Printf("%s %d:"x"\r\n", __FUNCTION__,__LINE__,##y)
//#define DBG_ERR(x,y...) DBG_Printf("%s %d:"x"\r\n", __FUNCTION__,__LINE__,##y)
//#endif
typedef struct
{
llist_head node;
Buffer_Struct uri_buf; //静态不用释放
luat_dns_ip_result ip_result[MAX_DNS_IP];
uint64_t timeout_ms;
uint16_t session_id;
uint8_t retry_cnt;
uint8_t dns_cnt;
uint8_t ip_nums;
uint8_t is_done;
uint8_t is_ipv6;
}dns_process_t;
typedef struct xDNSMessage
{
uint16_t usIdentifier;
uint16_t usFlags;
uint16_t usQuestions;
uint16_t usAnswers;
uint16_t usAuthorityRRs;
uint16_t usAdditionalRRs;
}xDNSMessage_t;
static int32_t dns_find_process(void *pData, void *pParam)
{
uint16_t session_id = (uint32_t)pParam;
dns_process_t *process = (dns_process_t *)pData;
if (process->session_id == session_id)
{
return LIST_FIND;
}
return LIST_PASS;
}
static int32_t dns_skip_name_field(Buffer_Struct *buf)
{
if( ( buf->Data[buf->Pos] & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
{
/* Jump over the two byte offset. */
buf->Pos += sizeof( uint16_t );
}
else
{
/* pucByte points to the full name. Walk over the string. */
while( buf->Data[buf->Pos] != 0x00 )
{
/* The number of bytes to jump for each name section is stored in the byte
before the name section. */
buf->Pos += ( buf->Data[buf->Pos] + 1 );
if (buf->Pos >= buf->MaxLen)
{
return -1;
}
}
buf->Pos++;
}
if (buf->Pos >= buf->MaxLen)
{
return -1;
}
return 0;
}
static int32_t dns_set_result(void *pData, void *pParam)
{
int i;
dns_process_t *process = (dns_process_t *)pParam;
luat_dns_require_t *require = (luat_dns_require_t *)pData;
if (!require->result)
{
if (process->uri_buf.Pos == require->uri.Pos)
{
if (!memcmp(process->uri_buf.Data, require->uri.Data, require->uri.Pos))
{
require->result = -1;
if (process->ip_nums)
{
for(i = 0; i < process->ip_nums; i++)
{
require->ip_result[i] = process->ip_result[i];
}
require->result = process->ip_nums;
}
}
}
}
return LIST_PASS;
}
int32_t dns_get_ip(dns_client_t *client, Buffer_Struct *buf, uint16_t answer_num, dns_process_t *process)
{
uint16_t i, usTemp;
luat_ip_addr_t ip_addr = {0};
uint32_t ttl;
uint8_t error = 0;
if (process)
{
process->ip_nums = 0;
}
for(i = 0; i < answer_num; i++)
{
if (dns_skip_name_field(buf) != ERROR_NONE)
{
error = 1;
goto NET_DNSGETIP_DONE;
}
usTemp = BytesGetBe16(buf->Data + buf->Pos);
switch (usTemp)
{
case dnsTYPE_IPV4:
if ( (buf->Pos + 14) > buf->MaxLen)
{
error = 1;
goto NET_DNSGETIP_DONE;
}
buf->Pos += 4;
ttl = BytesGetBe32FromBuf(buf);
usTemp = BytesGetBe16FromBuf(buf);
if ( (buf->Pos + usTemp) > buf->MaxLen)
{
error = 1;
goto NET_DNSGETIP_DONE;
}
#ifdef LUAT_USE_LWIP
ip_addr.type = IPADDR_TYPE_V4;
ip_addr.u_addr.ip4.addr = BytesGetLe32(buf->Data + buf->Pos);
#else
ip_addr.ipv4 = BytesGetLe32(buf->Data + buf->Pos);
ip_addr.is_ipv6 = 0;
#endif
buf->Pos += usTemp;
if (ttl > 0)
{
if (process && (process->ip_nums < MAX_DNS_IP))
{
process->ip_result[process->ip_nums].ip = ip_addr;
process->ip_result[process->ip_nums].ttl_end = ttl + ((uint32_t)(GetSysTickMS()/1000));
process->ip_nums++;
}
}
break;
case dnsTYPE_IPV6:
if ( (buf->Pos + 14) > buf->MaxLen)
{
error = 1;
goto NET_DNSGETIP_DONE;
}
buf->Pos += 4;
ttl = BytesGetBe32FromBuf(buf);
usTemp = BytesGetBe16FromBuf(buf);
if ( (buf->Pos + usTemp) > buf->MaxLen)
{
error = 1;
goto NET_DNSGETIP_DONE;
}
#ifdef LUAT_USE_LWIP
memcpy(ip_addr.u_addr.ip6.addr, buf->Data + buf->Pos, sizeof( uint32_t ) * 4);
// ip_addr.u_addr.ip6.zone = 0;
ip_addr.type = IPADDR_TYPE_V6;
#else
memcpy(ip_addr.ipv6_u8_addr, buf->Data + buf->Pos, sizeof( uint32_t ) * 4);
ip_addr.is_ipv6 = 1;
#endif
if (ttl > 0)
{
if (process && (process->ip_nums < MAX_DNS_IP))
{
process->ip_result[process->ip_nums].ip = ip_addr;
process->ip_result[process->ip_nums].ttl_end = ttl + ((uint32_t)(GetSysTickMS()/1000));
process->ip_nums++;
}
}
buf->Pos += usTemp;
break;
default:
//DBG("%04x",usTemp);
buf->Pos += 8;
usTemp = BytesGetBe16FromBuf(buf);
buf->Pos += usTemp;
//OS(Dump)(buf->Data + buf->Pos, usTemp);
break;
}
}
NET_DNSGETIP_DONE:
if (error)
{
return -1;
}
else
{
if (process)
{
process->is_done = 1;
llist_traversal(&client->require_head, dns_set_result, process);
}
return 0;
}
}
uint8_t dns_check_uri(const char *uri, uint32_t uri_len)
{
uint32_t dot_num = 0;
uint32_t i = 0;
uint32_t label_len = 0;
char uri_last = 0;
if(uri ==NULL)
{
return 0;
}
if(uri_len == 0 || uri_len > MAX_DOMAIN_LEN) //domain must less than 255
{
return 0;
}
if (!isalpha((int)uri[0])) // domain must start with a letter
{
return 0;
}
uri_last = uri[uri_len - 1];
if (!isalnum((int)uri_last))//end with a letter or digit
{
return 0;
}
for(i = 0; i < uri_len ; i++)
{
if(!(isalnum((int)uri[i]) || uri[i]== '.' || uri[i] == '-'))//must a~z or A~Z or 0~9 or . or -
{
return 0;
}
if( uri [i] == '.')
{
dot_num++;
if((label_len > MAX_CHARACTER_NUM_PER_LABEL) || (0 == label_len)) //Label must be 63 characters or less
return 0;
label_len = 0;
}
else
{
label_len++;
}
}
if((label_len > MAX_CHARACTER_NUM_PER_LABEL) || (0 == dot_num))//the last label must be 63 characters or less
return 0;
return 1;
}
int32_t dns_make(dns_client_t *client, dns_process_t *process, Buffer_Struct *out)
{
int Result;
xDNSMessage_t MsgHead;
uint8_t *pucStart, *pucByte;
// uint16_t usRecordType;
// uint16_t usClass = BSP_Swap16(dnsCLASS);
if (process->dns_cnt >= MAX_DNS_SERVER)
{
return -ERROR_PERMISSION_DENIED;
}
out->Pos = sizeof(xDNSMessage_t) + 6 + process->uri_buf.Pos;
memset(&MsgHead, 0, sizeof(MsgHead));
MsgHead.usIdentifier = BSP_Swap16(process->session_id);
MsgHead.usFlags = BSP_Swap16(dnsOUTGOING_FLAGS);
MsgHead.usQuestions = BSP_Swap16(dnsONE_QUESTION);
memcpy(out->Data, &MsgHead, sizeof(MsgHead));
pucStart = out->Data + sizeof( MsgHead );
/* Leave a gap for the first length bytes. */
pucByte = pucStart + 1;
/* Copy in the host name. */
memcpy( ( char * ) pucByte, process->uri_buf.Data, process->uri_buf.Pos );
/* Mark the end of the string. */
pucByte += process->uri_buf.Pos;
*pucByte = 0x00;
/* Walk the string to replace the '.' characters with byte counts.
pucStart holds the address of the byte count. Walking the string
starts after the byte count position. */
pucByte = pucStart;
do
{
pucByte++;
while( ( *pucByte != 0x00 ) && ( *pucByte != '.' ) )
{
pucByte++;
}
/* Fill in the byte count, then move the pucStart pointer up to
the found byte position. */
*pucStart = ( uint8_t ) ( ( uint32_t ) pucByte - ( uint32_t ) pucStart );
( *pucStart )--;
pucStart = pucByte;
} while( *pucByte != 0x00 );
pucByte++;
/* Finish off the record. */
if (process->is_ipv6)
{
BytesPutBe16(pucByte, dnsTYPE_IPV6);
}
else
{
BytesPutBe16(pucByte, dnsTYPE_IPV4);
}
pucByte += sizeof( uint16_t );
BytesPutBe16(pucByte, dnsCLASS);
process->timeout_ms = GetSysTickMS() + DNS_TO_BASE * (process->retry_cnt + 1);
return ERROR_NONE;
}
static int32_t dns_check_process(void *pData, void *pParam)
{
dns_process_t *process = (dns_process_t *)pData;
Buffer_Struct *uri_buf = (Buffer_Struct *)pParam;
if (uri_buf->Pos == process->uri_buf.Pos)
{
if (!memcmp(uri_buf->Data, process->uri_buf.Data, uri_buf->Pos))
{
return LIST_FIND;
}
}
return LIST_PASS;
}
void dns_require(dns_client_t *client, const char *domain_name, uint32_t len, void *param)
{
luat_dns_require_t *require = zalloc(sizeof(luat_dns_require_t));
require->uri.Data = domain_name;
require->uri.Pos = len;
require->uri.MaxLen = len;
require->param = param;
dns_process_t *process = llist_traversal(&client->process_head, dns_check_process, &require->uri);
// if no same proc
if (!process)
{
process = zalloc(sizeof(dns_process_t));
Buffer_StaticInit(&process->uri_buf, require->uri.Data, require->uri.Pos);
process->uri_buf.Pos = require->uri.Pos;
client->session_id++;
if (!client->session_id)
{
client->session_id++;
}
process->session_id = client->session_id;
llist_add_tail(&process->node, &client->process_head);
}
llist_add_tail(&require->node, &client->require_head);
}
void dns_require_ex(dns_client_t *client, const char *domain_name, void *param, uint8_t adapter_index)
{
luat_dns_require_t *require = zalloc(sizeof(luat_dns_require_t));
require->uri.Data = domain_name;
require->uri.Pos = strlen(domain_name);
require->uri.MaxLen = strlen(domain_name);
require->param = param;
require->adapter_index = adapter_index;
dns_process_t *process = llist_traversal(&client->process_head, dns_check_process, &require->uri);
// if no same proc
if (!process)
{
process = zalloc(sizeof(dns_process_t));
Buffer_StaticInit(&process->uri_buf, require->uri.Data, require->uri.Pos);
process->uri_buf.Pos = require->uri.Pos;
client->session_id++;
if (!client->session_id)
{
client->session_id++;
}
process->session_id = client->session_id;
llist_add_tail(&process->node, &client->process_head);
}
llist_add_tail(&require->node, &client->require_head);
}
static int32_t dns_clear_require(void *pData, void *pParam)
{
luat_dns_require_t *require = (luat_dns_require_t *)pData;
free(require->uri.Data);
return LIST_DEL;
}
static int32_t dns_clear_process(void *pData, void *pParam)
{
dns_process_t *process = (dns_process_t *)pData;
if (pParam)
{
return process->is_done?LIST_DEL:LIST_PASS;
}
return LIST_DEL;
}
void dns_clear(dns_client_t *client)
{
// uint64_t now_time = GetSysTickMS();
llist_traversal(&client->process_head, dns_clear_process, NULL);
llist_traversal(&client->require_head, dns_clear_require, NULL);
}
static int32_t dns_find_need_tx_process(void *pData, void *pParam)
{
dns_process_t *process = (dns_process_t *)pData;
if (!process->is_done && (process->timeout_ms < GetSysTickMS()))
{
return LIST_FIND;
}
return LIST_PASS;
}
void dns_run(dns_client_t *client, Buffer_Struct *in, Buffer_Struct *out, int *server_cnt)
{
dns_process_t *process;
int i;
if (llist_empty(&client->process_head) && !llist_empty(&client->require_head))
{
dns_clear(client);
if (client->is_run)
{
DBG("dns stop");
}
client->is_run = 0;
return;
}
if (in)
{
xDNSMessage_t MsgHead;
while ( (in->Pos + sizeof(MsgHead)) < in->MaxLen)
{
memcpy(&MsgHead, in->Data + in->Pos, sizeof(MsgHead));
MsgHead.usIdentifier = BSP_Swap16(MsgHead.usIdentifier);
MsgHead.usFlags = BSP_Swap16(MsgHead.usFlags);
in->Pos += sizeof(MsgHead);
process = llist_traversal(&client->process_head, dns_find_process, MsgHead.usIdentifier);
if (process)
{
if ( MsgHead.usFlags & 0x8000)
{
MsgHead.usQuestions = BSP_Swap16(MsgHead.usQuestions);
MsgHead.usAnswers = BSP_Swap16(MsgHead.usAnswers);
MsgHead.usAuthorityRRs = BSP_Swap16(MsgHead.usAuthorityRRs);
MsgHead.usAdditionalRRs = BSP_Swap16(MsgHead.usAdditionalRRs);
for(i = 0; i < MsgHead.usQuestions; i++)
{
if (dns_skip_name_field(in) != ERROR_NONE)
{
goto NET_DNS_RX_OUT;
}
in->Pos += 4;
if (in->Pos >= in->MaxLen)
{
goto NET_DNS_RX_OUT;
}
}
if (!(MsgHead.usFlags & 0x000f))
{
if (dns_get_ip(client, in, MsgHead.usAnswers, process))
{
goto NET_DNS_RX_OUT;
}
}
else
{
if (dns_get_ip(client, in, MsgHead.usAnswers, NULL))
{
goto NET_DNS_RX_OUT;
}
}
if (dns_get_ip(client, in, MsgHead.usAuthorityRRs, NULL))
{
goto NET_DNS_RX_OUT;
}
if (dns_get_ip(client, in, MsgHead.usAdditionalRRs, NULL))
{
goto NET_DNS_RX_OUT;
}
}
else
{
goto NET_DNS_RX_OUT;
}
}
}
}
else if (out)
{
NET_DNS_TX:
process = llist_traversal(&client->process_head, dns_find_need_tx_process, NULL);
if (!process)
{
goto NET_DNS_RX_OUT;
}
if (process->timeout_ms)
{
process->retry_cnt++;
if (process->retry_cnt >= DNS_TRY_MAX)
{
process->retry_cnt = 0;
process->dns_cnt++;
if (process->dns_cnt >= MAX_DNS_SERVER)
{
process->ip_nums = 0;
process->is_done = 1;
llist_traversal(&client->require_head, dns_set_result, process);
llist_del(&process->node);
free(process);
goto NET_DNS_TX;
}
}
}
#ifdef LUAT_USE_LWIP
while(0xff == client->dns_server[process->dns_cnt].type)
#else
while(0xff == client->dns_server[process->dns_cnt].is_ipv6)
#endif
{
process->dns_cnt++;
if (process->dns_cnt >= MAX_DNS_SERVER)
{
process->ip_nums = 0;
llist_traversal(&client->require_head, dns_set_result, process);
llist_del(&process->node);
free(process);
goto NET_DNS_TX;
}
}
DBG("%.*s state %d use dns server%d, try %d", process->uri_buf.Pos, process->uri_buf.Data, process->is_done, process->dns_cnt, process->retry_cnt);
process->is_done = 0;
OS_InitBuffer(out, 512);
dns_make(client, process, out);
*server_cnt = process->dns_cnt;
}
NET_DNS_RX_OUT:
if (!llist_empty(&client->process_head))
{
llist_traversal(&client->process_head, dns_clear_process, 1);
}
if (llist_empty(&client->process_head) && llist_empty(&client->require_head))
{
if (client->is_run)
{
DBG("dns stop");
}
client->is_run = 0;
return;
}
else
{
client->is_run = 1;
}
return ;
}
void dns_init_client(dns_client_t *client)
{
int i;
INIT_LLIST_HEAD(&client->process_head);
INIT_LLIST_HEAD(&client->require_head);
for(i = 0; i < MAX_DNS_SERVER; i++)
{
if (!client->is_static_dns[i])
{
#ifdef LUAT_USE_LWIP
client->dns_server[i].type = 0xff;
#else
client->dns_server[i].is_ipv6 = 0xff;
#endif
}
}
}

View File

@@ -0,0 +1,101 @@
#include "common_api.h"
#include "luat_base.h"
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "mbedtls/cipher.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/sha512.h"
#include "mbedtls/md5.h"
uint32_t luat_get_utc(uint32_t *tamp)
{
uint32_t sec = soc_get_utc();
if (tamp)
{
*tamp = sec;
}
return sec;
}
void luat_os_entry_cri(void) {
portENTER_CRITICAL();
}
void luat_os_exit_cri(void) {
portEXIT_CRITICAL();
}
// delay_us 是系统函数
extern void delay_us(uint32_t us);
void luat_timer_us_delay(size_t us) {
if (us > 0)
delay_us(us);
}
extern void soc_vsprintf(uint8_t no_print, const char *fmt, va_list ap);
extern void soc_debug_out(char *string, uint32_t size);
void DBG_Printf(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
soc_vsprintf(0, fmt, ap);
va_end(ap);
}
extern const uint8_t ByteToAsciiTable[16];
void DBG_HexPrintf(void *Data, unsigned int len)
{
uint8_t *data = (uint8_t *)Data;
uint8_t *uart_buf;
uint32_t i,j;
j = 0;
if (!len) return;
uart_buf = malloc(len * 3 + 2);
if (!uart_buf) return;
memset(uart_buf, 0, len * 3 + 2);
for (i = 0; i < len; i++){
uart_buf[j++] = ByteToAsciiTable[(data[i] & 0xf0) >> 4];
uart_buf[j++] = ByteToAsciiTable[data[i] & 0x0f];
uart_buf[j++] = ' ';
}
uart_buf[j++] = '\r';
uart_buf[j++] = '\n';
soc_debug_out((char*)uart_buf, len * 3 + 2);
free(uart_buf);
}
//struct tm *mbedtls_platform_gmtime_r( const mbedtls_time_t *tt,
// struct tm *tm_buf )
//{
// Date_UserDataStruct Date;
// Time_UserDataStruct Time;
// Tamp2UTC(*tt, &Date, &Time, 0);
// tm_buf->tm_year = Date.Year - 1900;
// tm_buf->tm_mon = Date.Mon - 1;
// tm_buf->tm_mday = Date.Day;
// tm_buf->tm_hour = Time.Hour;
// tm_buf->tm_min = Time.Min;
// tm_buf->tm_sec = Time.Sec;
// return tm_buf;
//
//}
#include "osasys.h"
time_t luat_time(time_t *_Time) {
utc_timer_value_t *timeUtc = OsaSystemTimeReadUtc();
if (_Time != NULL) {
*_Time = timeUtc->UTCsecs;
}
return timeUtc->UTCsecs;
}
int luat_timer_mdelay(size_t ms) {
if (ms > 0) {
vTaskDelay(ms);
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
target("luatos_lwip_socket")
local LIB_DIR = "$(buildir)/luatos_lwip_socket/"
set_kind("static")
set_targetdir(LIB_DIR)
--加入代码和头文件
add_includedirs("./include",{public = true})
add_files("./**.c",{public = true})
LIB_USER = LIB_USER .. SDK_TOP .. LIB_DIR .. "libluatos_lwip_socket.a "
target_end()