Merge pull request #2590 from Lawlieta/develop

[net] [netdev] Add network interface device(netdev) components
This commit is contained in:
Bernard Xiong
2019-04-18 23:26:34 +08:00
committed by GitHub
66 changed files with 16923 additions and 11902 deletions
-91
View File
@@ -291,97 +291,6 @@ int cmd_echo(int argc, char** argv)
FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file);
#endif
#ifdef RT_USING_LWIP
int cmd_ifconfig(int argc, char **argv)
{
extern void list_if(void);
extern void set_if(char *netif_name, char *ip_addr, char *gw_addr, char *nm_addr);
if (argc == 1)
{
list_if();
}
else if (argc == 5)
{
rt_kprintf("config : %s\n", argv[1]);
rt_kprintf("IP addr: %s\n", argv[2]);
rt_kprintf("Gateway: %s\n", argv[3]);
rt_kprintf("netmask: %s\n", argv[4]);
set_if(argv[1], argv[2], argv[3], argv[4]);
}
else
{
rt_kprintf("bad parameter! e.g: ifconfig e0 192.168.1.30 192.168.1.1 255.255.255.0\n");
}
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ifconfig, __cmd_ifconfig, list the information of network interfaces);
#ifdef RT_LWIP_DNS
#include <lwip/api.h>
#include <lwip/dns.h>
#include <lwip/ip_addr.h>
#include <lwip/init.h>
int cmd_dns(int argc, char **argv)
{
extern void set_dns(char* dns_server);
if (argc == 1)
{
int index;
#if (LWIP_VERSION) < 0x02000000U
ip_addr_t ip_addr;
for(index=0; index<DNS_MAX_SERVERS; index++)
{
ip_addr = dns_getserver(index);
rt_kprintf("dns server #%d: %s\n", index, ipaddr_ntoa(&ip_addr));
}
#else
const ip_addr_t *ip_addr;
for(index=0; index<DNS_MAX_SERVERS; index++)
{
ip_addr = dns_getserver(index);
rt_kprintf("dns server #%d: %s\n", index, ipaddr_ntoa(ip_addr));
}
#endif
}
else if (argc == 2)
{
rt_kprintf("dns : %s\n", argv[1]);
set_dns(argv[1]);
}
else
{
rt_kprintf("bad parameter! e.g: dns 114.114.114.114\n");
}
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_dns, __cmd_dns, list the information of dns);
#endif
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
int cmd_netstat(int argc, char **argv)
{
extern void list_tcps(void);
extern void list_udps(void);
#ifdef RT_LWIP_TCP
list_tcps();
#endif
#ifdef RT_LWIP_UDP
list_udps();
#endif
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_netstat, __cmd_netstat, list the information of TCP / IP);
#endif
#endif /* RT_USING_LWIP */
int cmd_ps(int argc, char **argv)
{
extern long list_thread(void);
+42 -7
View File
@@ -4,6 +4,8 @@ menu "Socket abstraction layer"
config RT_USING_SAL
bool "Enable socket abstraction layer"
select RT_USING_NETDEV
select RT_USING_SYSTEM_WORKQUEUE
default n
if RT_USING_SAL
@@ -46,10 +48,30 @@ config RT_USING_SAL
default 16
endif
endif
endmenu
menu "Network interface device"
config RT_USING_NETDEV
bool "Enable network interface device"
default n
if RT_USING_NETDEV
config NETDEV_USING_IFCONFIG
bool "Enable ifconfig features"
default y
config NETDEV_USING_PING
bool "Enable ping features"
default y
config SAL_PROTO_FAMILIES_NUM
int "the maximum number of protocol families"
default 4
config NETDEV_USING_NETSTAT
bool "Enable netstat features"
default y
endif
@@ -79,9 +101,11 @@ config RT_USING_LWIP
endchoice
if (RT_USING_LWIP210 || RT_USING_LWIP202)
config RT_USING_LWIP_IPV6
bool "IPV6 protocol"
default n
if (!RT_USING_NETDEV || (RT_USING_NETDEV && NETDEV_IPV6))
config RT_USING_LWIP_IPV6
bool "IPV6 protocol"
default n
endif
endif
config RT_LWIP_IGMP
@@ -229,7 +253,11 @@ config RT_USING_LWIP
default n
config LWIP_NETIF_STATUS_CALLBACK
int "netif status callback"
int "Enable netif status callback"
default 1
config LWIP_NETIF_LINK_CALLBACK
int "Enable netif link status callback"
default 1
config SO_REUSE
@@ -264,6 +292,13 @@ config RT_USING_LWIP
config RT_LWIP_USING_HW_CHECKSUM
bool "Enable hardware checksum"
default n
config RT_LWIP_USING_PING
bool "Enable ping features"
default y
select NETDEV_USING_PING
select RT_LWIP_ICMP
select RT_LWIP_RAW
menuconfig RT_LWIP_DEBUG
bool "Enable lwIP Debugging Options"
+29 -11
View File
@@ -413,7 +413,6 @@ int at_closesocket(int socket)
{
if (at_dev_ops->at_closesocket(socket) != 0)
{
LOG_E("AT socket (%d) closesocket failed!", socket);
free_socket(sock);
return -1;
}
@@ -442,7 +441,6 @@ int at_shutdown(int socket, int how)
{
if (at_dev_ops->at_closesocket(socket) != 0)
{
LOG_E("AT socket (%d) shutdown failed!", socket);
free_socket(sock);
return -1;
}
@@ -468,7 +466,13 @@ static int socketaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t
{
const struct sockaddr_in* sin = (const struct sockaddr_in*) (const void *) sockaddr;
#if NETDEV_IPV4 && NETDEV_IPV6
(*addr).u_addr.ip4.addr = sin->sin_addr.s_addr;
#elif NETDEV_IPV4
(*addr).addr = sin->sin_addr.s_addr;
#elif NETDEV_IPV6
LOG_E("not support IPV6.");
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
*port = (uint16_t) HTONS_PORT(sin->sin_port);
@@ -546,7 +550,7 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
if (sock->state != AT_SOCKET_NONE)
{
LOG_E("Socket %d connect state is %d.", sock->socket, sock->state);
LOG_E("Socket(%d) connect state is %d.", sock->socket, sock->state);
result = -1;
goto __exit;
}
@@ -557,7 +561,6 @@ int at_connect(int socket, const struct sockaddr *name, socklen_t namelen)
if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
{
LOG_E("AT socket(%d) connect failed!", socket);
result = -1;
goto __exit;
}
@@ -623,7 +626,6 @@ int at_recvfrom(int socket, void *mem, size_t len, int flags, struct sockaddr *f
if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
{
LOG_E("AT socket UDP connect failed!");
result = -1;
goto __exit;
}
@@ -737,7 +739,7 @@ int at_recv(int s, void *mem, size_t len, int flags)
int at_sendto(int socket, const void *data, size_t size, int flags, const struct sockaddr *to, socklen_t tolen)
{
struct at_socket *sock = RT_NULL;
struct at_socket *sock;
int len, result = 0;
if (at_dev_ops == RT_NULL)
@@ -789,7 +791,6 @@ int at_sendto(int socket, const void *data, size_t size, int flags, const struct
if (at_dev_ops->at_connect(socket, ipstr, remote_port, sock->type, RT_TRUE) < 0)
{
LOG_E("AT socket (%d) UDP connect failed!", socket);
result = -1;
goto __exit;
}
@@ -999,7 +1000,6 @@ struct hostent *at_gethostbyname(const char *name)
{
if (at_dev_ops->at_domain_resolve(name, ipstr) < 0)
{
LOG_E("AT domain (%s) resolve error!", name);
return RT_NULL;
}
}
@@ -1008,8 +1008,14 @@ struct hostent *at_gethostbyname(const char *name)
strncpy(ipstr, name, strlen(name));
}
#if NETDEV_IPV4 && NETDEV_IPV6
addr.u_addr.ip4.addr = ipstr_to_u32(ipstr);
#elif NETDEV_IPV4
addr.addr = ipstr_to_u32(ipstr);
#elif NETDEV_IPV6
LOG_E("not support IPV6.");
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
/* fill hostent structure */
s_hostent_addr = addr;
s_phostent_addr[0] = &s_hostent_addr;
@@ -1106,12 +1112,18 @@ int at_getaddrinfo(const char *nodename, const char *servname,
{
strncpy(ip_str, nodename, strlen(nodename));
}
#if NETDEV_IPV4 && NETDEV_IPV6
addr.type = IPADDR_TYPE_V4;
if ((addr.u_addr.ip4.addr = ipstr_to_u32(ip_str)) == 0)
{
return EAI_FAIL;
}
#elif NETDEV_IPV4
addr.addr = ipstr_to_u32(ip_str);
#elif NETDEV_IPV6
LOG_E("not support IPV6.");
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
}
}
else
@@ -1143,10 +1155,16 @@ int at_getaddrinfo(const char *nodename, const char *servname,
sa = (struct sockaddr_storage *) (void *) ((uint8_t *) ai + sizeof(struct addrinfo));
struct sockaddr_in *sa4 = (struct sockaddr_in *) sa;
/* set up sockaddr */
#if NETDEV_IPV4 && NETDEV_IPV6
sa4->sin_addr.s_addr = addr.u_addr.ip4.addr;
#elif NETDEV_IPV4
sa4->sin_addr.s_addr = addr.addr;
#elif NETDEV_IPV6
LOG_E("not support IPV6.");
#endif /* NETDEV_IPV4 && NETDEV_IPV6 */
sa4->sin_family = AF_INET;
sa4->sin_len = sizeof(struct sockaddr_in);
sa4->sin_port = htons((u16_t )port_nr);
sa4->sin_port = htons((uint16_t)port_nr);
ai->ai_family = AF_INET;
/* set up addrinfo */
+1 -1
View File
@@ -64,7 +64,7 @@ enum at_status
{
AT_STATUS_UNINITIALIZED = 0,
AT_STATUS_INITIALIZED,
AT_STATUS_BUSY,
AT_STATUS_CLI,
};
typedef enum at_status at_status_t;
+10
View File
@@ -207,9 +207,16 @@ static void client_cli_parser(at_client_t client)
static rt_err_t (*client_odev_rx_ind)(rt_device_t dev, rt_size_t size) = RT_NULL;
rt_base_t int_lvl;
rt_thread_t at_client;
at_status_t client_odev_status;
if (client)
{
/* backup client status */
{
client_odev_status = client->status;
client->status = AT_STATUS_CLI;
}
/* backup client device RX indicate */
{
int_lvl = rt_hw_interrupt_disable();
@@ -256,6 +263,9 @@ static void client_cli_parser(at_client_t client)
}
}
/* restore client status */
client->status = client_odev_status;
/* restore client device RX indicate */
{
int_lvl = rt_hw_interrupt_disable();
+13 -6
View File
@@ -273,6 +273,7 @@ int at_resp_parse_line_args_by_kw(at_response_t resp, const char *keyword, const
* @return 0 : success
* -1 : response status error
* -2 : wait timeout
* -7 : enter AT CLI mode
*/
int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr, ...)
{
@@ -289,6 +290,12 @@ int at_obj_exec_cmd(at_client_t client, at_response_t resp, const char *cmd_expr
return -RT_ERROR;
}
/* check AT CLI mode */
if (client->status == AT_STATUS_CLI && resp)
{
return -RT_EBUSY;
}
rt_mutex_take(client->lock, RT_WAITING_FOREVER);
client->resp_status = AT_RESP_OK;
@@ -869,6 +876,12 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz)
client = &at_client_table[idx];
client->recv_bufsz = recv_bufsz;
result = at_client_para_init(client);
if (result != RT_EOK)
{
goto __exit;
}
/* find and open command device */
client->device = rt_device_find(dev_name);
if (client->device)
@@ -893,12 +906,6 @@ int at_client_init(const char *dev_name, rt_size_t recv_bufsz)
goto __exit;
}
result = at_client_para_init(client);
if (result != RT_EOK)
{
goto __exit;
}
__exit:
if (result == RT_EOK)
{
+12
View File
@@ -0,0 +1,12 @@
Porting network interface device for RT-Thread in lwIP.
The major jobs following RT-Thread Team. The RT-Thread network interface device need to synchronize some network status and address information in lwIP, so it need to make some changes in the lwIP netwrok status and address operations function.
The specific changes are as follows:
- netif.c: add RT-Thread netdev header file , status synchronize(UP, LINK_UP), address synchronize(IP, netmask, gateway);
- dns.c: add RT-Thread header file, dns servers synchronize;
- sockets.c: custom 'select' function implementation in RT-Thread by the wait queue mode.
by ChenYong 2019/3/26 10:00 AM
chenyong@rt-thread.com
+2 -2
View File
@@ -79,8 +79,8 @@ if GetDepend(['RT_LWIP_PPP']):
path += [GetCurrentDir() + '/src/netif/ppp']
# For testing apps
if GetDepend(['RT_USING_NETUTILS']):
src += Glob('./apps/*.c')
if GetDepend(['RT_LWIP_USING_PING']):
src += Glob('src/apps/ping/ping.c')
group = DefineGroup('LwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP141'], CPPPATH = path)
@@ -0,0 +1,245 @@
/*
* netutils: ping implementation
*/
#include <rtthread.h>
#ifdef RT_LWIP_ICMP /* don't build if not configured for use in rtconfig.h */
#include <lwip/opt.h>
#include <lwip/init.h>
#include <lwip/mem.h>
#include <lwip/icmp.h>
#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/inet.h>
#include <lwip/inet_chksum.h>
#include <lwip/ip.h>
#include <lwip/netdb.h>
#include <lwip/sockets.h>
/**
* PING_DEBUG: Enable debugging for PING.
*/
#ifndef PING_DEBUG
#define PING_DEBUG LWIP_DBG_ON
#endif
/** ping receive timeout - in milliseconds */
#define PING_RCV_TIMEO (2 * RT_TICK_PER_SECOND)
/** ping delay - in milliseconds */
#define PING_DELAY (1 * RT_TICK_PER_SECOND)
/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
#define PING_ID 0xAFAF
#endif
/** ping additional data size to include in the packet */
#ifndef PING_DATA_SIZE
#define PING_DATA_SIZE 32
#endif
/* ping variables */
static u16_t ping_seq_num;
struct _ip_addr
{
rt_uint8_t addr0, addr1, addr2, addr3;
};
/** Prepare a echo ICMP request */
static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
{
size_t i;
size_t data_len = len - sizeof(struct icmp_echo_hdr);
ICMPH_TYPE_SET(iecho, ICMP_ECHO);
ICMPH_CODE_SET(iecho, 0);
iecho->chksum = 0;
iecho->id = PING_ID;
iecho->seqno = htons(++ping_seq_num);
/* fill the additional data buffer with some data */
for (i = 0; i < data_len; i++)
{
((char*) iecho)[sizeof(struct icmp_echo_hdr) + i] = (char) i;
}
#ifdef RT_LWIP_USING_HW_CHECKSUM
iecho->chksum = 0;
#else
iecho->chksum = inet_chksum(iecho, len);
#endif
}
/* Ping using the socket ip */
err_t lwip_ping_send(int s, ip_addr_t *addr, int size)
{
int err;
struct icmp_echo_hdr *iecho;
struct sockaddr_in to;
int ping_size = sizeof(struct icmp_echo_hdr) + size;
LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
iecho = rt_malloc(ping_size);
if (iecho == RT_NULL)
{
return ERR_MEM;
}
ping_prepare_echo(iecho, (u16_t) ping_size);
to.sin_len = sizeof(to);
to.sin_family = AF_INET;
#if LWIP_IPV4 && LWIP_IPV6
to.sin_addr.s_addr = addr->u_addr.ip4.addr;
#elif LWIP_IPV4
to.sin_addr.s_addr = addr->addr;
#elif LWIP_IPV6
#error Not supported IPv6.
#endif
err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*) &to, sizeof(to));
rt_free(iecho);
return (err == ping_size ? ERR_OK : ERR_VAL);
}
int lwip_ping_recv(int s, int *ttl)
{
char buf[64];
int fromlen = sizeof(struct sockaddr_in), len;
struct sockaddr_in from;
struct ip_hdr *iphdr;
struct icmp_echo_hdr *iecho;
while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*) &from, (socklen_t*) &fromlen)) > 0)
{
if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)))
{
iphdr = (struct ip_hdr *) buf;
iecho = (struct icmp_echo_hdr *) (buf + (IPH_HL(iphdr) * 4));
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)))
{
*ttl = iphdr->_ttl;
return len;
}
}
}
return len;
}
#ifndef RT_USING_SAL
/* using the lwIP custom ping */
rt_err_t ping(char* target_name, rt_uint32_t times, rt_size_t size)
{
#if LWIP_VERSION_MAJOR >= 2U
struct timeval timeout = { PING_RCV_TIMEO / RT_TICK_PER_SECOND, PING_RCV_TIMEO % RT_TICK_PER_SECOND };
#else
int timeout = PING_RCV_TIMEO * 1000UL / RT_TICK_PER_SECOND;
#endif
int s, ttl, recv_len;
ip_addr_t target_addr;
rt_uint32_t send_times;
rt_tick_t recv_start_tick;
struct addrinfo hint, *res = NULL;
struct sockaddr_in *h = NULL;
struct in_addr ina;
send_times = 0;
ping_seq_num = 0;
if (size == 0)
{
size = PING_DATA_SIZE;
}
memset(&hint, 0, sizeof(hint));
/* convert URL to IP */
if (lwip_getaddrinfo(target_name, NULL, &hint, &res) != 0)
{
rt_kprintf("ping: unknown host %s\n", target_name);
return -RT_ERROR;
}
memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
memcpy(&ina, &h->sin_addr, sizeof(ina));
lwip_freeaddrinfo(res);
if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
{
rt_kprintf("ping: unknown host %s\n", target_name);
return -RT_ERROR;
}
/* new a socket */
if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
{
rt_kprintf("ping: create socket failed\n");
return -RT_ERROR;
}
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
while (1)
{
int elapsed_time;
if (lwip_ping_send(s, &target_addr, size) == ERR_OK)
{
recv_start_tick = rt_tick_get();
if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
{
elapsed_time = (rt_tick_get() - recv_start_tick) * 1000UL / RT_TICK_PER_SECOND;
rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", recv_len, inet_ntoa(ina), send_times,
ttl, elapsed_time);
}
else
{
rt_kprintf("From %s icmp_seq=%d timeout\n", inet_ntoa(ina), send_times);
}
}
else
{
rt_kprintf("Send %s - error\n", inet_ntoa(ina));
}
send_times++;
if (send_times >= times)
{
/* send ping times reached, stop */
break;
}
rt_thread_delay(PING_DELAY); /* take a delay */
}
lwip_close(s);
return RT_EOK;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(ping, ping network host);
int cmd_ping(int argc, char **argv)
{
if (argc == 1)
{
rt_kprintf("Please input: ping <host address>\n");
}
else
{
ping(argv[1], 4, 0);
}
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ping, __cmd_ping, ping network host);
#endif /* RT_USING_FINSH */
#endif /* RT_USING_SAL */
#endif /* RT_LWIP_ICMP */
+10
View File
@@ -83,6 +83,8 @@
#include <string.h>
#include <rtthread.h>
/** DNS server IP address */
#ifndef DNS_SERVER_ADDRESS
#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */
@@ -275,6 +277,14 @@ dns_setserver(u8_t numdns, ip_addr_t *dnsserver)
if ((numdns < DNS_MAX_SERVERS) && (dns_pcb != NULL) &&
(dnsserver != NULL) && !ip_addr_isany(dnsserver)) {
dns_servers[numdns] = (*dnsserver);
#ifdef RT_USING_NETDEV
extern struct netdev *netdev_default;
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
/* set network interface device DNS server address */
netdev_low_level_set_dns_server(netdev_default, numdns, dnsserver);
#endif /* RT_USING_NETDEV */
}
}
@@ -60,6 +60,13 @@
#include "lwip/dhcp.h"
#endif /* LWIP_DHCP */
#include <rtthread.h>
#ifdef RT_USING_NETDEV
#include "lwip/netdb.h"
#include <netdev.h>
#endif /* RT_USING_NETDEV */
#if LWIP_NETIF_STATUS_CALLBACK
#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
#else
@@ -374,6 +381,11 @@ netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr)
ip4_addr2_16(&netif->ip_addr),
ip4_addr3_16(&netif->ip_addr),
ip4_addr4_16(&netif->ip_addr)));
#ifdef RT_USING_NETDEV
/* rt-thread sal network interface device set IP address operations */
netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), (ip_addr_t *)ipaddr);
#endif /* RT_USING_NETDEV */
}
/**
@@ -394,6 +406,11 @@ netif_set_gw(struct netif *netif, ip_addr_t *gw)
ip4_addr2_16(&netif->gw),
ip4_addr3_16(&netif->gw),
ip4_addr4_16(&netif->gw)));
#ifdef RT_USING_NETDEV
/* rt_thread network interface device set gateway address */
netdev_low_level_set_gw(netdev_get_by_name(netif->name), (ip_addr_t *)gw);
#endif /* RT_USING_NETDEV */
}
/**
@@ -418,6 +435,11 @@ netif_set_netmask(struct netif *netif, ip_addr_t *netmask)
ip4_addr2_16(&netif->netmask),
ip4_addr3_16(&netif->netmask),
ip4_addr4_16(&netif->netmask)));
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set netmask address */
netdev_low_level_set_netmask(netdev_get_by_name(netif->name), (ip_addr_t *)netmask);
#endif /* RT_USING_NETDEV */
}
/**
@@ -476,6 +498,11 @@ void netif_set_up(struct netif *netif)
}
#endif /* LWIP_IGMP */
}
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set up status */
netdev_low_level_set_status(netdev_get_by_name(netif->name), RT_TRUE);
#endif /* RT_USING_NETDEV */
}
}
@@ -501,6 +528,11 @@ void netif_set_down(struct netif *netif)
}
#endif /* LWIP_ARP */
NETIF_STATUS_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set down status */
netdev_low_level_set_status(netdev_get_by_name(netif->name), RT_FALSE);
#endif /* RT_USING_NETDEV */
}
}
@@ -565,6 +597,11 @@ void netif_set_link_up(struct netif *netif )
#endif /* LWIP_IGMP */
}
NETIF_LINK_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set link up status */
netdev_low_level_set_link_status(netdev_get_by_name(netif->name), RT_TRUE);
#endif /* RT_USING_NETDEV */
}
}
@@ -576,6 +613,11 @@ void netif_set_link_down(struct netif *netif )
if (netif->flags & NETIF_FLAG_LINK_UP) {
netif->flags &= ~NETIF_FLAG_LINK_UP;
NETIF_LINK_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set link down status */
netdev_low_level_set_link_status(netdev_get_by_name(netif->name), RT_FALSE);
#endif /* RT_USING_NETDEV */
}
}
@@ -97,6 +97,244 @@ static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
#endif
#endif
#ifdef RT_USING_NETDEV
#include "lwip/init.h"
#include "lwip/netdb.h"
#include <netdev.h>
static int lwip_netdev_set_up(struct netdev *netif)
{
netif_set_up((struct netif *)netif->user_data);
return ERR_OK;
}
static int lwip_netdev_set_down(struct netdev *netif)
{
netif_set_down((struct netif *)netif->user_data);
return ERR_OK;
}
static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw)
{
if (ip_addr && netmask && gw)
{
netif_set_addr((struct netif *)netif->user_data, ip_addr, netmask, gw);
}
else
{
if (ip_addr)
{
netif_set_ipaddr((struct netif *)netif->user_data, ip_addr);
}
if (netmask)
{
netif_set_netmask((struct netif *)netif->user_data, netmask);
}
if (gw)
{
netif_set_gw((struct netif *)netif->user_data, gw);
}
}
return ERR_OK;
}
#ifdef RT_LWIP_DNS
static int lwip_netdev_set_dns_server(struct netdev *netif, ip_addr_t *dns_server)
{
extern void set_dns(char* dns_server);
set_dns(ipaddr_ntoa(dns_server));
return ERR_OK;
}
#endif /* RT_LWIP_DNS */
#ifdef RT_LWIP_DHCP
static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
{
netdev_low_level_set_dhcp_status(netif, is_enabled);
return ERR_OK;
}
#endif /* RT_LWIP_DHCP */
#ifdef RT_LWIP_USING_PING
extern int lwip_ping_recv(int s, int *ttl);
extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size);
int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len,
uint32_t timeout, struct netdev_ping_resp *ping_resp)
{
int s, ttl, recv_len, result = 0;
int elapsed_time;
rt_tick_t recv_start_tick;
#if LWIP_VERSION_MAJOR >= 2U
struct timeval recv_timeout = { timeout / RT_TICK_PER_SECOND, timeout % RT_TICK_PER_SECOND };
#else
int recv_timeout = timeout * 1000UL / RT_TICK_PER_SECOND;
#endif
ip_addr_t target_addr;
struct addrinfo hint, *res = RT_NULL;
struct sockaddr_in *h = RT_NULL;
struct in_addr ina;
RT_ASSERT(netif);
RT_ASSERT(host);
RT_ASSERT(ping_resp);
rt_memset(&hint, 0x00, sizeof(hint));
/* convert URL to IP */
if (lwip_getaddrinfo(host, RT_NULL, &hint, &res) != 0)
{
return -RT_ERROR;
}
rt_memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
rt_memcpy(&ina, &h->sin_addr, sizeof(ina));
lwip_freeaddrinfo(res);
if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
{
return -RT_ERROR;
}
rt_memcpy(&(ping_resp->ip_addr), &target_addr, sizeof(ip_addr_t));
/* new a socket */
if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
{
return -RT_ERROR;
}
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout));
if (lwip_ping_send(s, &target_addr, data_len) == ERR_OK)
{
recv_start_tick = rt_tick_get();
if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
{
elapsed_time = (rt_tick_get() - recv_start_tick) * 1000UL / RT_TICK_PER_SECOND;
ping_resp->data_len = recv_len;
ping_resp->ttl = ttl;
ping_resp->ticks = elapsed_time;
}
else
{
result = -RT_ETIMEOUT;
goto __exit;
}
}
else
{
result = -RT_ETIMEOUT;
goto __exit;
}
__exit:
lwip_close(s);
return result;
}
#endif /* RT_LWIP_USING_PING */
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
void lwip_netdev_netstat(struct netdev *netif)
{
extern void list_tcps(void);
extern void list_udps(void);
#ifdef RT_LWIP_TCP
list_tcps();
#endif
#ifdef RT_LWIP_UDP
list_udps();
#endif
}
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
const struct netdev_ops lwip_netdev_ops =
{
lwip_netdev_set_up,
lwip_netdev_set_down,
lwip_netdev_set_addr_info,
#ifdef RT_LWIP_DNS
lwip_netdev_set_dns_server,
#else
NULL,
#endif /* RT_LWIP_DNS */
#ifdef RT_LWIP_DHCP
lwip_netdev_set_dhcp,
#else
NULL,
#endif /* RT_LWIP_DHCP */
#ifdef RT_LWIP_USING_PING
lwip_netdev_ping,
#else
NULL,
#endif /* RT_LWIP_USING_PING */
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
lwip_netdev_netstat,
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
};
static int netdev_add(struct netif *lwip_netif)
{
#define LWIP_NETIF_NAME_LEN 2
int result = 0;
struct netdev *netdev = RT_NULL;
char name[LWIP_NETIF_NAME_LEN + 1] = {0};
RT_ASSERT(lwip_netif);
netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
if (netdev == RT_NULL)
{
return -ERR_IF;
}
netdev->flags = lwip_netif->flags;
netdev->mtu = lwip_netif->mtu;
netdev->ops = &lwip_netdev_ops;
netdev->hwaddr_len = lwip_netif->hwaddr_len;
rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
#ifdef SAL_USING_LWIP
extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
/* set the lwIP network interface device protocol family information */
sal_lwip_netdev_set_pf_info(netdev);
#endif /* SAL_USING_LWIP */
rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
result = netdev_register(netdev, name, (void *)lwip_netif);
#ifdef RT_LWIP_DHCP
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
#endif
return result;
}
/* synchronize lwIP network interface device and network interface device flags */
static int netdev_flags_sync(struct netif *lwip_netif)
{
struct netdev *netdev = NULL;
RT_ASSERT(lwip_netif);
netdev = netdev_get_by_name(lwip_netif->name);
if (netdev == RT_NULL)
{
return -ERR_IF;
}
netdev->flags |= lwip_netif->flags;
return ERR_OK;
}
#endif /* RT_USING_NETDEV */
static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{
#ifndef LWIP_NO_TX_THREAD
@@ -137,6 +375,11 @@ static err_t eth_netif_device_init(struct netif *netif)
{
rt_device_t device;
#ifdef RT_USING_NETDEV
/* network interface device register */
netdev_add(netif);
#endif /* RT_USING_NETDEV */
/* get device object */
device = (rt_device_t) ethif;
if (rt_device_init(device) != RT_EOK)
@@ -239,6 +482,12 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_
netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, eth_netif_device_init, tcpip_input);
}
#ifdef RT_USING_NETDEV
/* network interface device flags synchronize */
netdev_flags_sync(netif);
#endif /* RT_USING_NETDEV */
return RT_EOK;
}
+15 -1
View File
@@ -1,8 +1,22 @@
Porting network interface device for RT-Thread in lwIP.
The major jobs following RT-Thread Team. The RT-Thread network interface device need to synchronize some network status and address information in lwIP, so it need to make some changes in the lwIP netwrok status and address operations function.
The specific changes are as follows:
- netif.c: add RT-Thread netdev header file , status synchronize(UP, LINK_UP), address synchronize(IP, netmask, gateway);
- dns.c: add RT-Thread header file, dns servers synchronize;
- sockets.c: custom 'select' function implementation in RT-Thread by the wait queue mode.
by ChenYong 2019/3/26 10:00 AM
chenyong@rt-thread.com
Porting lwip 2.0.2 running on RT-Thread.
The major jobs following RT-Thread Team. The RT-Thread team already port the lwip 2.0.0, so I only do some move code and test jobs.
I use the memory pools to test lwip 2.0.2, I use the iperf tool to test it about more than 20 hours, It is running normal.
I don't test it working on memory heap.
...
Good Luck.
by Hans.Huang 3/27/17 10:52 AM
by Hans.Huang 2017/3/27 10:52 AM
huangxi_hans@163.com
+2 -5
View File
@@ -81,11 +81,8 @@ if GetDepend(['RT_LWIP_PPP']):
if GetDepend(['RT_USING_LWIP_IPV6']):
src += ipv6_src
if GetDepend(['RT_USING_NETUTILS']):
if GetDepend(['RT_NETUTILS_USING_TFTP']):
src += Glob('src/apps/tftp/*.c')
if GetDepend(['RT_NETUTILS_USING_PING']):
src += Glob('src/apps/ping/*.c')
if GetDepend(['RT_LWIP_USING_PING']):
src += Glob('src/apps/ping/ping.c')
group = DefineGroup('lwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP202'], CPPPATH = path)
+93 -49
View File
@@ -2,16 +2,20 @@
* netutils: ping implementation
*/
#include "lwip/opt.h"
#include <rtthread.h>
#include "lwip/mem.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#ifdef RT_LWIP_ICMP /* don't build if not configured for use in rtconfig.h */
#include <lwip/opt.h>
#include <lwip/init.h>
#include <lwip/mem.h>
#include <lwip/icmp.h>
#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/inet.h>
#include <lwip/inet_chksum.h>
#include <lwip/ip.h>
#include <lwip/netdb.h>
#include <lwip/sockets.h>
/**
* PING_DEBUG: Enable debugging for PING.
@@ -21,9 +25,9 @@
#endif
/** ping receive timeout - in milliseconds */
#define PING_RCV_TIMEO rt_tick_from_millisecond(2000)
#define PING_RCV_TIMEO (2 * RT_TICK_PER_SECOND)
/** ping delay - in milliseconds */
#define PING_DELAY rt_tick_from_millisecond(1000)
#define PING_DELAY (1 * RT_TICK_PER_SECOND)
/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
@@ -55,21 +59,26 @@ static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
iecho->seqno = htons(++ping_seq_num);
/* fill the additional data buffer with some data */
for(i = 0; i < data_len; i++)
for (i = 0; i < data_len; i++)
{
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
((char*) iecho)[sizeof(struct icmp_echo_hdr) + i] = (char) i;
}
iecho->chksum = inet_chksum(iecho, len);
#ifdef RT_LWIP_USING_HW_CHECKSUM
iecho->chksum = 0;
#else
iecho->chksum = inet_chksum(iecho, len);
#endif
}
/* Ping using the socket ip */
static err_t ping_send(int s, ip_addr_t *addr, int size)
err_t lwip_ping_send(int s, ip_addr_t *addr, int size)
{
int err;
struct icmp_echo_hdr *iecho;
struct sockaddr_in to;
size_t ping_size = sizeof(struct icmp_echo_hdr) + size;
int ping_size = sizeof(struct icmp_echo_hdr) + size;
LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
iecho = rt_malloc(ping_size);
@@ -78,19 +87,25 @@ static err_t ping_send(int s, ip_addr_t *addr, int size)
return ERR_MEM;
}
ping_prepare_echo(iecho, (u16_t)ping_size);
ping_prepare_echo(iecho, (u16_t) ping_size);
to.sin_len = sizeof(to);
to.sin_family = AF_INET;
#if LWIP_IPV4 && LWIP_IPV6
to.sin_addr.s_addr = addr->u_addr.ip4.addr;
#elif LWIP_IPV4
to.sin_addr.s_addr = addr->addr;
#elif LWIP_IPV6
#error Not supported IPv6.
#endif
err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*) &to, sizeof(to));
rt_free(iecho);
return (err == ping_size ? ERR_OK : ERR_VAL);
}
static int ping_recv(int s, int *ttl)
int lwip_ping_recv(int s, int *ttl)
{
char buf[64];
int fromlen = sizeof(struct sockaddr_in), len;
@@ -98,12 +113,12 @@ static int ping_recv(int s, int *ttl)
struct ip_hdr *iphdr;
struct icmp_echo_hdr *iecho;
while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0)
while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*) &from, (socklen_t*) &fromlen)) > 0)
{
if (len >= (sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr)))
if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)))
{
iphdr = (struct ip_hdr *)buf;
iecho = (struct icmp_echo_hdr *)(buf+(IPH_HL(iphdr) * 4));
iphdr = (struct ip_hdr *) buf;
iecho = (struct icmp_echo_hdr *) (buf + (IPH_HL(iphdr) * 4));
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)))
{
*ttl = iphdr->_ttl;
@@ -115,62 +130,86 @@ static int ping_recv(int s, int *ttl)
return len;
}
rt_err_t ping(char* target, rt_uint32_t times, rt_size_t size)
#ifndef RT_USING_SAL
/* using the lwIP custom ping */
rt_err_t ping(char* target_name, rt_uint32_t times, rt_size_t size)
{
int s, ttl, recv_len;
#if LWIP_VERSION_MAJOR >= 2U
struct timeval timeout = { PING_RCV_TIMEO / RT_TICK_PER_SECOND, PING_RCV_TIMEO % RT_TICK_PER_SECOND };
ip_addr_t ping_target;
#else
int timeout = PING_RCV_TIMEO * 1000UL / RT_TICK_PER_SECOND;
#endif
int s, ttl, recv_len;
ip_addr_t target_addr;
rt_uint32_t send_times;
rt_tick_t recv_start_tick;
struct _ip_addr
{
rt_uint8_t addr0, addr1, addr2, addr3;
} *addr;
struct addrinfo hint, *res = NULL;
struct sockaddr_in *h = NULL;
struct in_addr ina;
send_times = 0;
ping_seq_num = 0;
if(size == 0)
size = PING_DATA_SIZE;
if (inet_aton(target, &ping_target) == 0)
if (size == 0)
{
rt_kprintf("ping: unknown host %s\n", target);
size = PING_DATA_SIZE;
}
memset(&hint, 0, sizeof(hint));
/* convert URL to IP */
if (lwip_getaddrinfo(target_name, NULL, &hint, &res) != 0)
{
rt_kprintf("ping: unknown host %s\n", target_name);
return -RT_ERROR;
}
addr = (struct _ip_addr*)&ping_target;
memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
memcpy(&ina, &h->sin_addr, sizeof(ina));
lwip_freeaddrinfo(res);
if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
{
rt_kprintf("ping: unknown host %s\n", target_name);
return -RT_ERROR;
}
/* new a socket */
if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
{
rt_kprintf("ping: create socket failled\n");
rt_kprintf("ping: create socket failed\n");
return -RT_ERROR;
}
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
while (1)
{
if (ping_send(s, &ping_target, size) == ERR_OK)
int elapsed_time;
if (lwip_ping_send(s, &target_addr, size) == ERR_OK)
{
recv_start_tick = rt_tick_get();
if ((recv_len = ping_recv(s, &ttl)) >= 0)
if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
{
rt_kprintf("%d bytes from %d.%d.%d.%d icmp_seq=%d ttl=%d time=%d ticks\n", recv_len, addr->addr0,
addr->addr1, addr->addr2, addr->addr3, send_times, ttl, rt_tick_get() - recv_start_tick);
elapsed_time = (rt_tick_get() - recv_start_tick) * 1000UL / RT_TICK_PER_SECOND;
rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", recv_len, inet_ntoa(ina), send_times,
ttl, elapsed_time);
}
else
{
rt_kprintf("From %d.%d.%d.%d icmp_seq=%d timeout\n", addr->addr0, addr->addr1, addr->addr2,
addr->addr3, send_times);
rt_kprintf("From %s icmp_seq=%d timeout\n", inet_ntoa(ina), send_times);
}
}
else
{
rt_kprintf("Send %d.%d.%d.%d - error\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
rt_kprintf("Send %s - error\n", inet_ntoa(ina));
}
send_times ++;
if (send_times >= times) break; /* send ping times reached, stop */
send_times++;
if (send_times >= times)
{
/* send ping times reached, stop */
break;
}
rt_thread_delay(PING_DELAY); /* take a delay */
}
@@ -198,4 +237,9 @@ int cmd_ping(int argc, char **argv)
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ping, __cmd_ping, ping network host);
#endif
#endif /* RT_USING_FINSH */
#endif /* RT_USING_SAL */
#endif /* RT_LWIP_ICMP */
+10
View File
@@ -95,6 +95,8 @@
#include <string.h>
#include <rtthread.h>
/** Random generator function to create random TXIDs and source ports for queries */
#ifndef DNS_RAND_TXID
#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0)
@@ -366,6 +368,14 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver)
if (numdns < DNS_MAX_SERVERS) {
if (dnsserver != NULL) {
dns_servers[numdns] = (*dnsserver);
#ifdef RT_USING_NETDEV
extern struct netdev *netdev_default;
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
/* set network interface device DNS server address */
netdev_low_level_set_dns_server(netdev_default, numdns, dnsserver);
#endif /* RT_USING_NETDEV */
} else {
dns_servers[numdns] = *IP_ADDR_ANY;
}
@@ -89,6 +89,13 @@
#include "lwip/nd6.h"
#endif
#include <rtthread.h>
#ifdef RT_USING_NETDEV
#include "lwip/netdb.h"
#include <netdev.h>
#endif /* RT_USING_NETDEV */
#if LWIP_NETIF_STATUS_CALLBACK
#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
#else
@@ -534,6 +541,11 @@ netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr)
netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4);
NETIF_STATUS_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread sal network interface device set IP address operations */
netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), (ip_addr_t *)ipaddr);
#endif /* RT_USING_NETDEV */
}
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
@@ -564,6 +576,11 @@ netif_set_gw(struct netif *netif, const ip4_addr_t *gw)
ip4_addr2_16(netif_ip4_gw(netif)),
ip4_addr3_16(netif_ip4_gw(netif)),
ip4_addr4_16(netif_ip4_gw(netif))));
#ifdef RT_USING_NETDEV
/* rt_thread network interface device set gateway address */
netdev_low_level_set_gw(netdev_get_by_name(netif->name), (ip_addr_t *)gw);
#endif /* RT_USING_NETDEV */
}
/**
@@ -590,6 +607,11 @@ netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask)
ip4_addr2_16(netif_ip4_netmask(netif)),
ip4_addr3_16(netif_ip4_netmask(netif)),
ip4_addr4_16(netif_ip4_netmask(netif))));
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set netmask address */
netdev_low_level_set_netmask(netdev_get_by_name(netif->name), (ip_addr_t *)netmask);
#endif /* RT_USING_NETDEV */
}
#endif /* LWIP_IPV4 */
@@ -633,6 +655,11 @@ netif_set_up(struct netif *netif)
if (netif->flags & NETIF_FLAG_LINK_UP) {
netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6);
}
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set up status */
netdev_low_level_set_status(netdev_get_by_name(netif->name), RT_TRUE);
#endif /* RT_USING_NETDEV */
}
}
@@ -696,6 +723,11 @@ netif_set_down(struct netif *netif)
#endif /* LWIP_IPV6 */
NETIF_STATUS_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set down status */
netdev_low_level_set_status(netdev_get_by_name(netif->name), RT_FALSE);
#endif /* RT_USING_NETDEV */
}
}
@@ -749,6 +781,11 @@ netif_set_link_up(struct netif *netif)
netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6);
}
NETIF_LINK_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set link up status */
netdev_low_level_set_link_status(netdev_get_by_name(netif->name), RT_TRUE);
#endif /* RT_USING_NETDEV */
}
}
@@ -762,6 +799,11 @@ netif_set_link_down(struct netif *netif )
if (netif->flags & NETIF_FLAG_LINK_UP) {
netif->flags &= ~NETIF_FLAG_LINK_UP;
NETIF_LINK_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set link down status */
netdev_low_level_set_link_status(netdev_get_by_name(netif->name), RT_FALSE);
#endif /* RT_USING_NETDEV */
}
}
@@ -105,6 +105,244 @@ static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
#endif
#endif
#ifdef RT_USING_NETDEV
#include "lwip/init.h"
#include "lwip/netdb.h"
#include <netdev.h>
static int lwip_netdev_set_up(struct netdev *netif)
{
netif_set_up((struct netif *)netif->user_data);
return ERR_OK;
}
static int lwip_netdev_set_down(struct netdev *netif)
{
netif_set_down((struct netif *)netif->user_data);
return ERR_OK;
}
static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw)
{
if (ip_addr && netmask && gw)
{
netif_set_addr((struct netif *)netif->user_data, ip_addr, netmask, gw);
}
else
{
if (ip_addr)
{
netif_set_ipaddr((struct netif *)netif->user_data, ip_addr);
}
if (netmask)
{
netif_set_netmask((struct netif *)netif->user_data, netmask);
}
if (gw)
{
netif_set_gw((struct netif *)netif->user_data, gw);
}
}
return ERR_OK;
}
#ifdef RT_LWIP_DNS
static int lwip_netdev_set_dns_server(struct netdev *netif, ip_addr_t *dns_server)
{
extern void set_dns(char* dns_server);
set_dns(ipaddr_ntoa(dns_server));
return ERR_OK;
}
#endif /* RT_LWIP_DNS */
#ifdef RT_LWIP_DHCP
static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
{
netdev_low_level_set_dhcp_status(netif, is_enabled);
return ERR_OK;
}
#endif /* RT_LWIP_DHCP */
#ifdef RT_LWIP_USING_PING
extern int lwip_ping_recv(int s, int *ttl);
extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size);
int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len,
uint32_t timeout, struct netdev_ping_resp *ping_resp)
{
int s, ttl, recv_len, result = 0;
int elapsed_time;
rt_tick_t recv_start_tick;
#if LWIP_VERSION_MAJOR >= 2U
struct timeval recv_timeout = { timeout / RT_TICK_PER_SECOND, timeout % RT_TICK_PER_SECOND };
#else
int recv_timeout = timeout * 1000UL / RT_TICK_PER_SECOND;
#endif
ip_addr_t target_addr;
struct addrinfo hint, *res = RT_NULL;
struct sockaddr_in *h = RT_NULL;
struct in_addr ina;
RT_ASSERT(netif);
RT_ASSERT(host);
RT_ASSERT(ping_resp);
rt_memset(&hint, 0x00, sizeof(hint));
/* convert URL to IP */
if (lwip_getaddrinfo(host, RT_NULL, &hint, &res) != 0)
{
return -RT_ERROR;
}
rt_memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
rt_memcpy(&ina, &h->sin_addr, sizeof(ina));
lwip_freeaddrinfo(res);
if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
{
return -RT_ERROR;
}
rt_memcpy(&(ping_resp->ip_addr), &target_addr, sizeof(ip_addr_t));
/* new a socket */
if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
{
return -RT_ERROR;
}
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout));
if (lwip_ping_send(s, &target_addr, data_len) == ERR_OK)
{
recv_start_tick = rt_tick_get();
if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
{
elapsed_time = (rt_tick_get() - recv_start_tick) * 1000UL / RT_TICK_PER_SECOND;
ping_resp->data_len = recv_len;
ping_resp->ttl = ttl;
ping_resp->ticks = elapsed_time;
}
else
{
result = -RT_ETIMEOUT;
goto __exit;
}
}
else
{
result = -RT_ETIMEOUT;
goto __exit;
}
__exit:
lwip_close(s);
return result;
}
#endif /* RT_LWIP_USING_PING */
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
void lwip_netdev_netstat(struct netdev *netif)
{
extern void list_tcps(void);
extern void list_udps(void);
#ifdef RT_LWIP_TCP
list_tcps();
#endif
#ifdef RT_LWIP_UDP
list_udps();
#endif
}
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
const struct netdev_ops lwip_netdev_ops =
{
lwip_netdev_set_up,
lwip_netdev_set_down,
lwip_netdev_set_addr_info,
#ifdef RT_LWIP_DNS
lwip_netdev_set_dns_server,
#else
NULL,
#endif /* RT_LWIP_DNS */
#ifdef RT_LWIP_DHCP
lwip_netdev_set_dhcp,
#else
NULL,
#endif /* RT_LWIP_DHCP */
#ifdef RT_LWIP_USING_PING
lwip_netdev_ping,
#else
NULL,
#endif /* RT_LWIP_USING_PING */
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
lwip_netdev_netstat,
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
};
static int netdev_add(struct netif *lwip_netif)
{
#define LWIP_NETIF_NAME_LEN 2
int result = 0;
struct netdev *netdev = RT_NULL;
char name[LWIP_NETIF_NAME_LEN + 1] = {0};
RT_ASSERT(lwip_netif);
netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
if (netdev == RT_NULL)
{
return -ERR_IF;
}
netdev->flags = lwip_netif->flags;
netdev->mtu = lwip_netif->mtu;
netdev->ops = &lwip_netdev_ops;
netdev->hwaddr_len = lwip_netif->hwaddr_len;
rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
#ifdef SAL_USING_LWIP
extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
/* set the lwIP network interface device protocol family information */
sal_lwip_netdev_set_pf_info(netdev);
#endif /* SAL_USING_LWIP */
rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
result = netdev_register(netdev, name, (void *)lwip_netif);
#ifdef RT_LWIP_DHCP
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
#endif
return result;
}
/* synchronize lwIP network interface device and network interface device flags */
static int netdev_flags_sync(struct netif *lwip_netif)
{
struct netdev *netdev = NULL;
RT_ASSERT(lwip_netif);
netdev = netdev_get_by_name(lwip_netif->name);
if (netdev == RT_NULL)
{
return -ERR_IF;
}
netdev->flags |= lwip_netif->flags;
return ERR_OK;
}
#endif /* RT_USING_NETDEV */
static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{
#ifndef LWIP_NO_TX_THREAD
@@ -140,6 +378,11 @@ static err_t eth_netif_device_init(struct netif *netif)
{
struct eth_device *ethif;
#ifdef RT_USING_NETDEV
/* network interface device register */
netdev_add(netif);
#endif /* RT_USING_NETDEV */
ethif = (struct eth_device*)netif->state;
if (ethif != RT_NULL)
{
@@ -266,6 +509,11 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_
netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, eth_netif_device_init, tcpip_input);
}
#ifdef RT_USING_NETDEV
/* network interface device flags synchronize */
netdev_flags_sync(netif);
#endif /* RT_USING_NETDEV */
return RT_EOK;
}
+12
View File
@@ -0,0 +1,12 @@
Porting network interface device for RT-Thread in lwIP.
The major jobs following RT-Thread Team. The RT-Thread network interface device need to synchronize some network status and address information in lwIP, so it need to make some changes in the lwIP netwrok status and address operations function.
The specific changes are as follows:
- netif.c: add RT-Thread netdev header file , status synchronize(UP, LINK_UP), address synchronize(IP, netmask, gateway);
- dns.c: add RT-Thread header file, dns servers synchronize;
- sockets.c: custom 'select' function implementation in RT-Thread by the wait queue mode.
by ChenYong 2019/3/26 10:00 AM
chenyong@rt-thread.com
+2 -5
View File
@@ -257,11 +257,8 @@ if GetDepend(['RT_LWIP_PPP']):
if GetDepend(['RT_USING_LWIP_IPV6']):
src += lwipcore6_SRCS
if GetDepend(['RT_USING_NETUTILS']):
if GetDepend(['RT_NETUTILS_USING_TFTP']):
src += lwiptftp_SRCS
if GetDepend(['RT_NETUTILS_USING_PING']):
src += lwipping_SRCS
if GetDepend(['RT_LWIP_USING_PING']):
src += lwipping_SRCS
group = DefineGroup('lwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP210'], CPPPATH = path)
+93 -49
View File
@@ -2,16 +2,20 @@
* netutils: ping implementation
*/
#include "lwip/opt.h"
#include <rtthread.h>
#include "lwip/mem.h"
#include "lwip/icmp.h"
#include "lwip/netif.h"
#include "lwip/sys.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "lwip/inet_chksum.h"
#include "lwip/ip.h"
#ifdef RT_LWIP_ICMP /* don't build if not configured for use in rtconfig.h */
#include <lwip/opt.h>
#include <lwip/init.h>
#include <lwip/mem.h>
#include <lwip/icmp.h>
#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/inet.h>
#include <lwip/inet_chksum.h>
#include <lwip/ip.h>
#include <lwip/netdb.h>
#include <lwip/sockets.h>
/**
* PING_DEBUG: Enable debugging for PING.
@@ -21,9 +25,9 @@
#endif
/** ping receive timeout - in milliseconds */
#define PING_RCV_TIMEO rt_tick_from_millisecond(2000)
#define PING_RCV_TIMEO (2 * RT_TICK_PER_SECOND)
/** ping delay - in milliseconds */
#define PING_DELAY rt_tick_from_millisecond(1000)
#define PING_DELAY (1 * RT_TICK_PER_SECOND)
/** ping identifier - must fit on a u16_t */
#ifndef PING_ID
@@ -55,21 +59,26 @@ static void ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
iecho->seqno = htons(++ping_seq_num);
/* fill the additional data buffer with some data */
for(i = 0; i < data_len; i++)
for (i = 0; i < data_len; i++)
{
((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
((char*) iecho)[sizeof(struct icmp_echo_hdr) + i] = (char) i;
}
iecho->chksum = inet_chksum(iecho, len);
#ifdef RT_LWIP_USING_HW_CHECKSUM
iecho->chksum = 0;
#else
iecho->chksum = inet_chksum(iecho, len);
#endif
}
/* Ping using the socket ip */
static err_t ping_send(int s, ip_addr_t *addr, int size)
err_t lwip_ping_send(int s, ip_addr_t *addr, int size)
{
int err;
struct icmp_echo_hdr *iecho;
struct sockaddr_in to;
size_t ping_size = sizeof(struct icmp_echo_hdr) + size;
int ping_size = sizeof(struct icmp_echo_hdr) + size;
LWIP_ASSERT("ping_size is too big", ping_size <= 0xffff);
iecho = rt_malloc(ping_size);
@@ -78,19 +87,25 @@ static err_t ping_send(int s, ip_addr_t *addr, int size)
return ERR_MEM;
}
ping_prepare_echo(iecho, (u16_t)ping_size);
ping_prepare_echo(iecho, (u16_t) ping_size);
to.sin_len = sizeof(to);
to.sin_family = AF_INET;
#if LWIP_IPV4 && LWIP_IPV6
to.sin_addr.s_addr = addr->u_addr.ip4.addr;
#elif LWIP_IPV4
to.sin_addr.s_addr = addr->addr;
#elif LWIP_IPV6
#error Not supported IPv6.
#endif
err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*)&to, sizeof(to));
err = lwip_sendto(s, iecho, ping_size, 0, (struct sockaddr*) &to, sizeof(to));
rt_free(iecho);
return (err == ping_size ? ERR_OK : ERR_VAL);
}
static int ping_recv(int s, int *ttl)
int lwip_ping_recv(int s, int *ttl)
{
char buf[64];
int fromlen = sizeof(struct sockaddr_in), len;
@@ -98,12 +113,12 @@ static int ping_recv(int s, int *ttl)
struct ip_hdr *iphdr;
struct icmp_echo_hdr *iecho;
while((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) > 0)
while ((len = lwip_recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*) &from, (socklen_t*) &fromlen)) > 0)
{
if (len >= (sizeof(struct ip_hdr)+sizeof(struct icmp_echo_hdr)))
if (len >= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)))
{
iphdr = (struct ip_hdr *)buf;
iecho = (struct icmp_echo_hdr *)(buf+(IPH_HL(iphdr) * 4));
iphdr = (struct ip_hdr *) buf;
iecho = (struct icmp_echo_hdr *) (buf + (IPH_HL(iphdr) * 4));
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)))
{
*ttl = iphdr->_ttl;
@@ -115,62 +130,86 @@ static int ping_recv(int s, int *ttl)
return len;
}
rt_err_t ping(char* target, rt_uint32_t times, rt_size_t size)
#ifndef RT_USING_SAL
/* using the lwIP custom ping */
rt_err_t ping(char* target_name, rt_uint32_t times, rt_size_t size)
{
int s, ttl, recv_len;
#if LWIP_VERSION_MAJOR >= 2U
struct timeval timeout = { PING_RCV_TIMEO / RT_TICK_PER_SECOND, PING_RCV_TIMEO % RT_TICK_PER_SECOND };
ip_addr_t ping_target;
#else
int timeout = PING_RCV_TIMEO * 1000UL / RT_TICK_PER_SECOND;
#endif
int s, ttl, recv_len;
ip_addr_t target_addr;
rt_uint32_t send_times;
rt_tick_t recv_start_tick;
struct _ip_addr
{
rt_uint8_t addr0, addr1, addr2, addr3;
} *addr;
struct addrinfo hint, *res = NULL;
struct sockaddr_in *h = NULL;
struct in_addr ina;
send_times = 0;
ping_seq_num = 0;
if(size == 0)
size = PING_DATA_SIZE;
if (inet_aton(target, &ping_target) == 0)
if (size == 0)
{
rt_kprintf("ping: unknown host %s\n", target);
size = PING_DATA_SIZE;
}
memset(&hint, 0, sizeof(hint));
/* convert URL to IP */
if (lwip_getaddrinfo(target_name, NULL, &hint, &res) != 0)
{
rt_kprintf("ping: unknown host %s\n", target_name);
return -RT_ERROR;
}
addr = (struct _ip_addr*)&ping_target;
memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
memcpy(&ina, &h->sin_addr, sizeof(ina));
lwip_freeaddrinfo(res);
if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
{
rt_kprintf("ping: unknown host %s\n", target_name);
return -RT_ERROR;
}
/* new a socket */
if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
{
rt_kprintf("ping: create socket failled\n");
rt_kprintf("ping: create socket failed\n");
return -RT_ERROR;
}
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
while (1)
{
if (ping_send(s, &ping_target, size) == ERR_OK)
int elapsed_time;
if (lwip_ping_send(s, &target_addr, size) == ERR_OK)
{
recv_start_tick = rt_tick_get();
if ((recv_len = ping_recv(s, &ttl)) >= 0)
if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
{
rt_kprintf("%d bytes from %d.%d.%d.%d icmp_seq=%d ttl=%d time=%d ticks\n", recv_len, addr->addr0,
addr->addr1, addr->addr2, addr->addr3, send_times, ttl, rt_tick_get() - recv_start_tick);
elapsed_time = (rt_tick_get() - recv_start_tick) * 1000UL / RT_TICK_PER_SECOND;
rt_kprintf("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", recv_len, inet_ntoa(ina), send_times,
ttl, elapsed_time);
}
else
{
rt_kprintf("From %d.%d.%d.%d icmp_seq=%d timeout\n", addr->addr0, addr->addr1, addr->addr2,
addr->addr3, send_times);
rt_kprintf("From %s icmp_seq=%d timeout\n", inet_ntoa(ina), send_times);
}
}
else
{
rt_kprintf("Send %d.%d.%d.%d - error\n", addr->addr0, addr->addr1, addr->addr2, addr->addr3);
rt_kprintf("Send %s - error\n", inet_ntoa(ina));
}
send_times ++;
if (send_times >= times) break; /* send ping times reached, stop */
send_times++;
if (send_times >= times)
{
/* send ping times reached, stop */
break;
}
rt_thread_delay(PING_DELAY); /* take a delay */
}
@@ -198,4 +237,9 @@ int cmd_ping(int argc, char **argv)
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ping, __cmd_ping, ping network host);
#endif
#endif /* RT_USING_FINSH */
#endif /* RT_USING_SAL */
#endif /* RT_LWIP_ICMP */
+10
View File
@@ -97,6 +97,8 @@
#include <string.h>
#include <rtthread.h>
/** Random generator function to create random TXIDs and source ports for queries */
#ifndef DNS_RAND_TXID
#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0)
@@ -363,6 +365,14 @@ dns_setserver(u8_t numdns, const ip_addr_t *dnsserver)
if (numdns < DNS_MAX_SERVERS) {
if (dnsserver != NULL) {
dns_servers[numdns] = (*dnsserver);
#ifdef RT_USING_NETDEV
extern struct netdev *netdev_default;
extern void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
/* set network interface device DNS server address */
netdev_low_level_set_dns_server(netdev_default, numdns, dnsserver);
#endif /* RT_USING_NETDEV */
} else {
dns_servers[numdns] = *IP_ADDR_ANY;
}
@@ -90,6 +90,13 @@
#include "lwip/nd6.h"
#endif
#include <rtthread.h>
#ifdef RT_USING_NETDEV
#include "lwip/netdb.h"
#include <netdev.h>
#endif /* RT_USING_NETDEV */
#if LWIP_NETIF_STATUS_CALLBACK
#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0)
#else
@@ -481,6 +488,12 @@ netif_do_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr, ip_addr_t *ol
netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4);
NETIF_STATUS_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread sal network interface device set IP address operations */
netdev_low_level_set_ipaddr(netdev_get_by_name(netif->name), (ip_addr_t *)ipaddr);
#endif /* RT_USING_NETDEV */
return 1; /* address changed */
}
return 0; /* address unchanged */
@@ -541,6 +554,12 @@ netif_do_set_netmask(struct netif *netif, const ip4_addr_t *netmask, ip_addr_t *
ip4_addr2_16(netif_ip4_netmask(netif)),
ip4_addr3_16(netif_ip4_netmask(netif)),
ip4_addr4_16(netif_ip4_netmask(netif))));
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set netmask address */
netdev_low_level_set_netmask(netdev_get_by_name(netif->name), (ip_addr_t *)netmask);
#endif /* RT_USING_NETDEV */
return 1; /* netmask changed */
}
return 0; /* netmask unchanged */
@@ -603,6 +622,12 @@ netif_do_set_gw(struct netif *netif, const ip4_addr_t *gw, ip_addr_t *old_gw)
ip4_addr2_16(netif_ip4_gw(netif)),
ip4_addr3_16(netif_ip4_gw(netif)),
ip4_addr4_16(netif_ip4_gw(netif))));
#ifdef RT_USING_NETDEV
/* rt_thread network interface device set gateway address */
netdev_low_level_set_gw(netdev_get_by_name(netif->name), (ip_addr_t *)gw);
#endif /* RT_USING_NETDEV */
return 1; /* gateway changed */
}
return 0; /* gateway unchanged */
@@ -866,6 +891,11 @@ netif_set_up(struct netif *netif)
#if LWIP_IPV6
nd6_restart_netif(netif);
#endif /* LWIP_IPV6 */
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set up status */
netdev_low_level_set_status(netdev_get_by_name(netif->name), RT_TRUE);
#endif /* RT_USING_NETDEV */
}
}
@@ -945,6 +975,11 @@ netif_set_down(struct netif *netif)
#endif /* LWIP_IPV6 */
NETIF_STATUS_CALLBACK(netif);
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set down status */
netdev_low_level_set_status(netdev_get_by_name(netif->name), RT_FALSE);
#endif /* RT_USING_NETDEV */
}
}
@@ -1015,6 +1050,11 @@ netif_set_link_up(struct netif *netif)
netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args);
}
#endif
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set link up status */
netdev_low_level_set_link_status(netdev_get_by_name(netif->name), RT_TRUE);
#endif /* RT_USING_NETDEV */
}
}
@@ -1039,6 +1079,11 @@ netif_set_link_down(struct netif *netif)
netif_invoke_ext_callback(netif, LWIP_NSC_LINK_CHANGED, &args);
}
#endif
#ifdef RT_USING_NETDEV
/* rt-thread network interface device set link down status */
netdev_low_level_set_link_status(netdev_get_by_name(netif->name), RT_FALSE);
#endif /* RT_USING_NETDEV */
}
}
@@ -106,6 +106,244 @@ static char eth_rx_thread_stack[RT_LWIP_ETHTHREAD_STACKSIZE];
#endif
#endif
#ifdef RT_USING_NETDEV
#include "lwip/init.h"
#include "lwip/netdb.h"
#include <netdev.h>
static int lwip_netdev_set_up(struct netdev *netif)
{
netif_set_up((struct netif *)netif->user_data);
return ERR_OK;
}
static int lwip_netdev_set_down(struct netdev *netif)
{
netif_set_down((struct netif *)netif->user_data);
return ERR_OK;
}
static int lwip_netdev_set_addr_info(struct netdev *netif, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw)
{
if (ip_addr && netmask && gw)
{
netif_set_addr((struct netif *)netif->user_data, ip_addr, netmask, gw);
}
else
{
if (ip_addr)
{
netif_set_ipaddr((struct netif *)netif->user_data, ip_addr);
}
if (netmask)
{
netif_set_netmask((struct netif *)netif->user_data, netmask);
}
if (gw)
{
netif_set_gw((struct netif *)netif->user_data, gw);
}
}
return ERR_OK;
}
#ifdef RT_LWIP_DNS
static int lwip_netdev_set_dns_server(struct netdev *netif, ip_addr_t *dns_server)
{
extern void set_dns(char* dns_server);
set_dns(ipaddr_ntoa(dns_server));
return ERR_OK;
}
#endif /* RT_LWIP_DNS */
#ifdef RT_LWIP_DHCP
static int lwip_netdev_set_dhcp(struct netdev *netif, rt_bool_t is_enabled)
{
netdev_low_level_set_dhcp_status(netif, is_enabled);
return ERR_OK;
}
#endif /* RT_LWIP_DHCP */
#ifdef RT_LWIP_USING_PING
extern int lwip_ping_recv(int s, int *ttl);
extern err_t lwip_ping_send(int s, ip_addr_t *addr, int size);
int lwip_netdev_ping(struct netdev *netif, const char *host, size_t data_len,
uint32_t timeout, struct netdev_ping_resp *ping_resp)
{
int s, ttl, recv_len, result = 0;
int elapsed_time;
rt_tick_t recv_start_tick;
#if LWIP_VERSION_MAJOR >= 2U
struct timeval recv_timeout = { timeout / RT_TICK_PER_SECOND, timeout % RT_TICK_PER_SECOND };
#else
int recv_timeout = timeout * 1000UL / RT_TICK_PER_SECOND;
#endif
ip_addr_t target_addr;
struct addrinfo hint, *res = RT_NULL;
struct sockaddr_in *h = RT_NULL;
struct in_addr ina;
RT_ASSERT(netif);
RT_ASSERT(host);
RT_ASSERT(ping_resp);
rt_memset(&hint, 0x00, sizeof(hint));
/* convert URL to IP */
if (lwip_getaddrinfo(host, RT_NULL, &hint, &res) != 0)
{
return -RT_ERROR;
}
rt_memcpy(&h, &res->ai_addr, sizeof(struct sockaddr_in *));
rt_memcpy(&ina, &h->sin_addr, sizeof(ina));
lwip_freeaddrinfo(res);
if (inet_aton(inet_ntoa(ina), &target_addr) == 0)
{
return -RT_ERROR;
}
rt_memcpy(&(ping_resp->ip_addr), &target_addr, sizeof(ip_addr_t));
/* new a socket */
if ((s = lwip_socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP)) < 0)
{
return -RT_ERROR;
}
lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &recv_timeout, sizeof(recv_timeout));
if (lwip_ping_send(s, &target_addr, data_len) == ERR_OK)
{
recv_start_tick = rt_tick_get();
if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
{
elapsed_time = (rt_tick_get() - recv_start_tick) * 1000UL / RT_TICK_PER_SECOND;
ping_resp->data_len = recv_len;
ping_resp->ttl = ttl;
ping_resp->ticks = elapsed_time;
}
else
{
result = -RT_ETIMEOUT;
goto __exit;
}
}
else
{
result = -RT_ETIMEOUT;
goto __exit;
}
__exit:
lwip_close(s);
return result;
}
#endif /* RT_LWIP_USING_PING */
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
void lwip_netdev_netstat(struct netdev *netif)
{
extern void list_tcps(void);
extern void list_udps(void);
#ifdef RT_LWIP_TCP
list_tcps();
#endif
#ifdef RT_LWIP_UDP
list_udps();
#endif
}
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
const struct netdev_ops lwip_netdev_ops =
{
lwip_netdev_set_up,
lwip_netdev_set_down,
lwip_netdev_set_addr_info,
#ifdef RT_LWIP_DNS
lwip_netdev_set_dns_server,
#else
NULL,
#endif /* RT_LWIP_DNS */
#ifdef RT_LWIP_DHCP
lwip_netdev_set_dhcp,
#else
NULL,
#endif /* RT_LWIP_DHCP */
#ifdef RT_LWIP_USING_PING
lwip_netdev_ping,
#else
NULL,
#endif /* RT_LWIP_USING_PING */
#if defined (RT_LWIP_TCP) || defined (RT_LWIP_UDP)
lwip_netdev_netstat,
#endif /* RT_LWIP_TCP || RT_LWIP_UDP */
};
static int netdev_add(struct netif *lwip_netif)
{
#define LWIP_NETIF_NAME_LEN 2
int result = 0;
struct netdev *netdev = RT_NULL;
char name[LWIP_NETIF_NAME_LEN + 1] = {0};
RT_ASSERT(lwip_netif);
netdev = (struct netdev *)rt_calloc(1, sizeof(struct netdev));
if (netdev == RT_NULL)
{
return -ERR_IF;
}
netdev->flags = lwip_netif->flags;
netdev->ops = &lwip_netdev_ops;
netdev->hwaddr_len = lwip_netif->hwaddr_len;
rt_memcpy(netdev->hwaddr, lwip_netif->hwaddr, lwip_netif->hwaddr_len);
#ifdef SAL_USING_LWIP
extern int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
/* set the lwIP network interface device protocol family information */
sal_lwip_netdev_set_pf_info(netdev);
#endif /* SAL_USING_LWIP */
rt_strncpy(name, lwip_netif->name, LWIP_NETIF_NAME_LEN);
result = netdev_register(netdev, name, (void *)lwip_netif);
#ifdef RT_LWIP_DHCP
netdev_low_level_set_dhcp_status(netdev, RT_TRUE);
#endif
return result;
}
/* synchronize lwIP network interface device and network interface device flags */
static int netdev_flags_sync(struct netif *lwip_netif)
{
struct netdev *netdev = NULL;
RT_ASSERT(lwip_netif);
netdev = netdev_get_by_name(lwip_netif->name);
if (netdev == RT_NULL)
{
return -ERR_IF;
}
netdev->mtu = lwip_netif->mtu;
netdev->flags |= lwip_netif->flags;
return ERR_OK;
}
#endif /* RT_USING_NETDEV */
static err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{
#ifndef LWIP_NO_TX_THREAD
@@ -146,6 +384,11 @@ static err_t eth_netif_device_init(struct netif *netif)
{
rt_device_t device;
#ifdef RT_USING_NETDEV
/* network interface device register */
netdev_add(netif);
#endif /* RT_USING_NETDEV */
/* get device object */
device = (rt_device_t) ethif;
if (rt_device_init(device) != RT_EOK)
@@ -270,6 +513,11 @@ rt_err_t eth_device_init_with_flag(struct eth_device *dev, const char *name, rt_
netifapi_netif_add(netif, &ipaddr, &netmask, &gw, dev, eth_netif_device_init, tcpip_input);
}
#ifdef RT_USING_NETDEV
/* network interface device flags synchronize */
netdev_flags_sync(netif);
#endif /* RT_USING_NETDEV */
return RT_EOK;
}
+13
View File
@@ -0,0 +1,13 @@
# RT-Thread building script for component
from building import *
cwd = GetCurrentDir()
src = Glob('src/*.c')
CPPPATH = [cwd + '/include']
group = DefineGroup('netdev', src, depend = ['RT_USING_NETDEV'], CPPPATH = CPPPATH)
Return('group')
@@ -8,9 +8,9 @@
* 2015-02-17 Bernard First version
*/
#ifndef INET_H__
#define INET_H__
#ifndef __INET_H__
#define __INET_H__
#include <sal_ipaddr.h>
#include <netdev_ipaddr.h>
#endif
+179
View File
@@ -0,0 +1,179 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-18 ChenYong First version
*/
#ifndef __NETDEV_H__
#define __NETDEV_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* the maximum of all used hardware address lengths */
#ifndef NETDEV_HWADDR_MAX_LEN
#define NETDEV_HWADDR_MAX_LEN 8U
#endif
/* the maximum of dns server number supported */
#ifndef NETDEV_DNS_SERVERS_NUM
#define NETDEV_DNS_SERVERS_NUM 2U
#endif
/* whether the network interface device is 'up' (set by the network interface driver or application) */
#define NETDEV_FLAG_UP 0x01U
/* if set, the network interface device has broadcast capability, only supported in the 'lwIP' stack */
#define NETDEV_FLAG_BROADCAST 0x02U
/* if set, the network interface device has an active link (set by the network interface driver) */
#define NETDEV_FLAG_LINK_UP 0x04U
/* if set, the network interface device is an ethernet device using ARP, only supported in the 'lwIP' stack */
#define NETDEV_FLAG_ETHARP 0x08U
/* if set, the network interface device is an ethernet device, only supported in the 'lwIP' stack */
#define NETDEV_FLAG_ETHERNET 0x10U
/* if set, the network interface device has IGMP capability, only supported in the 'lwIP' stack */
#define NETDEV_FLAG_IGMP 0x20U
/* if set, the network interface device has MLD6 capability, only supported in the 'lwIP' stack */
#define NETDEV_FLAG_MLD6 0x40U
/* if set, the network interface device connected to internet successfully (set by the network interface driver) */
#define NETDEV_FLAG_INTERNET_UP 0x80U
/* if set, the network interface device has DHCP capability (set by the network interface device driver or application) */
#define NETDEV_FLAG_DHCP 0x100U
enum netdev_cb_type
{
NETDEV_CB_ADDR_IP, /* IP address */
NETDEV_CB_ADDR_NETMASK, /* subnet mask */
NETDEV_CB_ADDR_GATEWAY, /* netmask */
NETDEV_CB_ADDR_DNS_SERVER, /* dns server */
NETDEV_CB_STATUS_UP, /* changed to 'up' */
NETDEV_CB_STATUS_DOWN, /* changed to 'down' */
NETDEV_CB_STATUS_LINK_UP, /* changed to 'link up' */
NETDEV_CB_STATUS_LINK_DOWN, /* changed to 'link down' */
NETDEV_CB_STATUS_INTERNET_UP, /* changed to 'internet up' */
NETDEV_CB_STATUS_INTERNET_DOWN, /* changed to 'internet down' */
NETDEV_CB_STATUS_DHCP_ENABLE, /* enable DHCP capability */
NETDEV_CB_STATUS_DHCP_DISABLE, /* disable DHCP capability */
};
struct netdev;
/* function prototype for network interface device status or address change callback functions */
typedef void (*netdev_callback_fn )(struct netdev *netdev, enum netdev_cb_type type);
struct netdev_ops;
/* network interface device object */
struct netdev
{
rt_slist_t list;
char name[RT_NAME_MAX]; /* network interface device name */
ip_addr_t ip_addr; /* IP address */
ip_addr_t netmask; /* subnet mask */
ip_addr_t gw; /* gateway */
ip_addr_t dns_servers[NETDEV_DNS_SERVERS_NUM]; /* DNS server */
uint8_t hwaddr_len; /* hardware address length */
uint8_t hwaddr[NETDEV_HWADDR_MAX_LEN]; /* hardware address */
uint16_t flags; /* network interface device status flag */
uint16_t mtu; /* maximum transfer unit (in bytes) */
const struct netdev_ops *ops; /* network interface device operations */
netdev_callback_fn status_callback; /* network interface device flags change callback */
netdev_callback_fn addr_callback; /* network interface device address information change callback */
#ifdef RT_USING_SAL
void *sal_user_data; /* user-specific data for SAL */
#endif /* RT_USING_SAL */
void *user_data; /* user-specific data */
};
/* The list of network interface device */
extern struct netdev *netdev_list;
/* The default network interface device */
extern struct netdev *netdev_default;
/* The network interface device ping response object */
struct netdev_ping_resp
{
ip_addr_t ip_addr; /* response IP address */
uint16_t data_len; /* response data length */
uint16_t ttl; /* time to live */
uint32_t ticks; /* response time, unit tick */
void *user_data; /* user-specific data */
};
/* The network interface device operations */
struct netdev_ops
{
/* set network interface device hardware status operations */
int (*set_up)(struct netdev *netdev);
int (*set_down)(struct netdev *netdev);
/* set network interface device address information operations */
int (*set_addr_info)(struct netdev *netdev, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw);
int (*set_dns_server)(struct netdev *netdev, ip_addr_t *dns_server);
int (*set_dhcp)(struct netdev *netdev, rt_bool_t is_enabled);
/* set network interface device common network interface device operations */
int (*ping)(struct netdev *netdev, const char *host, size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp);
void (*netstat)(struct netdev *netdev);
};
/* The network interface device registered and unregistered*/
int netdev_register(struct netdev *netdev, const char *name, void *user_data);
int netdev_unregister(struct netdev *netdev);
/* Get network interface device object */
struct netdev *netdev_get_first_link_up(void);
struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr);
struct netdev *netdev_get_by_name(const char *name);
#ifdef RT_USING_SAL
struct netdev *netdev_get_by_family(int family);
#endif /* RT_USING_SAL */
/* Set default network interface device in list */
void netdev_set_default(struct netdev *netdev);
/* Set network interface device status */
int netdev_set_up(struct netdev *netdev);
int netdev_set_down(struct netdev *netdev);
int netdev_dhcp_enabled(struct netdev *netdev, rt_bool_t is_enabled);
/* Get network interface device status */
#define netdev_is_up(netdev) (((netdev)->flags & NETDEV_FLAG_UP) ? (uint8_t)1 : (uint8_t)0)
#define netdev_is_link_up(netdev) (((netdev)->flags & NETDEV_FLAG_LINK_UP) ? (uint8_t)1 : (uint8_t)0)
#define netdev_is_internet_up(netdev) (((netdev)->flags & NETDEV_FLAG_INTERNET_UP) ? (uint8_t)1 : (uint8_t)0)
#define netdev_is_dhcp_enabled(netdev) (((netdev)->flags & NETDEV_FLAG_DHCP) ? (uint8_t)1 : (uint8_t)0)
/* Set network interface device address */
int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ipaddr);
int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask);
int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw);
int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
/* Set network interface device callback, it can be called when the status or address changed */
void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback);
/* Set network interface device status and address, this function can only be called in the network interface device driver */
void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ipaddr);
void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask);
void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw);
void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server);
void netdev_low_level_set_status(struct netdev *netdev, rt_bool_t is_up);
void netdev_low_level_set_link_status(struct netdev *netdev, rt_bool_t is_up);
void netdev_low_level_set_dhcp_status(struct netdev *netdev, rt_bool_t is_enable);
#ifdef __cplusplus
}
#endif
#endif /* __NETDEV_H__ */
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-18 ChenYong First version
*/
#ifndef __NETDEV_IPADDR_H__
#define __NETDEV_IPADDR_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Only supports the IPV4 protocol */
#ifndef NETDEV_IPV4
#define NETDEV_IPV4 1
#endif
#ifndef NETDEV_IPV6
#define NETDEV_IPV6 0
#endif
#ifdef NETDEV_IPV4
/** IPv4 only: set the IP address given as an u32_t */
#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
/** IPv4 only: get the IP address as an u32_t */
#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
#define IP4ADDR_STRLEN_MAX 16
#endif /* NETIF_IPV4 */
/* These macros should be calculated by the preprocessor and are used
with compile-time constants only (so that there is no little-endian
overhead at runtime). */
#define PP_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
(((x) & 0x0000ff00UL) << 8) | \
(((x) & 0x00ff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#define htons(x) (uint16_t)PP_HTONS(x)
#define ntohs(x) (uint16_t)PP_NTOHS(x)
#define htonl(x) (uint32_t)PP_HTONL(x)
#define ntohl(x) (uint32_t)PP_NTOHL(x)
/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
to prevent this code from redefining it. */
#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
typedef uint32_t in_addr_t;
#endif
#if NETDEV_IPV4
struct in_addr
{
in_addr_t s_addr;
};
typedef struct ip4_addr
{
uint32_t addr;
} ip4_addr_t;
typedef ip4_addr_t ip_addr_t;
#endif /* NETIF_IPV4 */
#if NETDEV_IPV6
struct in6_addr
{
union
{
uint32_t u32_addr[4];
uint8_t u8_addr[16];
} un;
#define s6_addr un.u8_addr
};
typedef struct ip6_addr
{
uint32_t addr[4];
} ip6_addr_t;
typedef ip6_addr ip_addr_t
#endif /* NETIF_IPV6 */
#if NETDEV_IPV4 && NETDEV_IPV6
/* IP address types for use in ip_addr_t.type member */
enum netdev_ip_addr_type
{
/** IPv4 */
IPADDR_TYPE_V4 = 0U,
/** IPv6 */
IPADDR_TYPE_V6 = 6U,
/** IPv4+IPv6 ("dual-stack") */
IPADDR_TYPE_ANY = 46U
};
/* A union struct for both IP version's addresses */
typedef struct _ip_addr
{
union
{
ip6_addr_t ip6;
ip4_addr_t ip4;
} u_addr;
/** @ref netdev_ip_addr_type */
uint8_t type;
} ip_addr_t;
#endif /* NETIF_IPV4 && NETIF_IPV6 */
/** 255.255.255.255 */
#define IPADDR_NONE ((uint32_t)0xffffffffUL)
/** 127.0.0.1 */
#define IPADDR_LOOPBACK ((uint32_t)0x7f000001UL)
/** 0.0.0.0 */
#define IPADDR_ANY ((uint32_t)0x00000000UL)
/** 255.255.255.255 */
#define IPADDR_BROADCAST ((uint32_t)0xffffffffUL)
/** 255.255.255.255 */
#define INADDR_NONE IPADDR_NONE
/** 127.0.0.1 */
#define INADDR_LOOPBACK IPADDR_LOOPBACK
/** 0.0.0.0 */
#define INADDR_ANY IPADDR_ANY
/** 255.255.255.255 */
#define INADDR_BROADCAST IPADDR_BROADCAST
#define IPADDR_BROADCAST_STRING "255.255.255.255"
#ifdef NETDEV_IPV4
/** Copy IP address - faster than ip4_addr_set: no NULL check */
#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr)
#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr)
/** Set complete address to zero */
#define ip4_addr_set_zero(ipaddr) ((ipaddr)->addr = 0)
#define ip4_addr_isany_val(ipaddr) ((ipaddr).addr == IPADDR_ANY)
#define ip4_addr_isany(ipaddr) ((ipaddr) == NULL || ip4_addr_isany_val(*(ipaddr)))
#define ip_addr_copy(dest, src) ip4_addr_copy(dest, src)
#define ip_addr_cmp(addr1, addr2) ip4_addr_cmp(addr1, addr2)
#define ip_addr_set_zero(ipaddr) ip4_addr_set_zero(ipaddr)
#define ip_addr_isany(ipaddr) ip4_addr_isany(ipaddr)
in_addr_t netdev_ipaddr_addr(const char *cp);
int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr);
char *netdev_ip4addr_ntoa(const ip4_addr_t *addr);
char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
#define inet_addr(cp) netdev_ipaddr_addr(cp)
#define inet_aton(cp, addr) netdev_ip4addr_aton(cp,(ip4_addr_t*)addr)
#define inet_ntoa(addr) netdev_ip4addr_ntoa((const ip4_addr_t*)&(addr))
#define inet_ntoa_r(addr, buf, buflen) netdev_ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
#endif /* NETDEV_IPV4 */
#ifdef __cplusplus
}
#endif
#endif /* __NETDEV_IPADDR_H__ */
File diff suppressed because it is too large Load Diff
@@ -8,12 +8,12 @@
* 2018-05-18 ChenYong First version
*/
#include <sal_ipaddr.h>
#include <rtthread.h>
#include <netdev_ipaddr.h>
/* Here for now until needed in other places in lwIP */
#ifndef isprint
#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up)
#define in_range(c, lo, up) ((uint8_t)c >= lo && (uint8_t)c <= up)
#define isprint(c) in_range(c, 0x20, 0x7f)
#define isdigit(c) in_range(c, '0', '9')
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
@@ -33,13 +33,13 @@
* @param addr pointer to which to save the ip address in network order
* @return 1 if cp could be converted to addr, 0 on failure
*/
int sal_ip4addr_aton(const char *cp, ip4_addr_t *addr)
int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr)
{
u32_t val;
u8_t base;
uint32_t val;
uint8_t base;
char c;
u32_t parts[4];
u32_t *pp = parts;
uint32_t parts[4];
uint32_t *pp = parts;
c = *cp;
for (;;)
@@ -72,12 +72,12 @@ int sal_ip4addr_aton(const char *cp, ip4_addr_t *addr)
{
if (isdigit(c))
{
val = (val * base) + (u32_t) (c - '0');
val = (val * base) + (uint32_t) (c - '0');
c = *++cp;
}
else if (base == 16 && isxdigit(c))
{
val = (val << 4) | (u32_t) (c + 10 - (islower(c) ? 'a' : 'A'));
val = (val << 4) | (uint32_t) (c + 10 - (islower(c) ? 'a' : 'A'));
c = *++cp;
}
else
@@ -180,28 +180,28 @@ int sal_ip4addr_aton(const char *cp, ip4_addr_t *addr)
* @return either pointer to buf which now holds the ASCII
* representation of addr or NULL if buf was too small
*/
char *sal_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
{
u32_t s_addr;
uint32_t s_addr;
char inv[3];
char *rp;
u8_t *ap;
u8_t rem;
u8_t n;
u8_t i;
uint8_t *ap;
uint8_t rem;
uint8_t n;
uint8_t i;
int len = 0;
s_addr = ip4_addr_get_u32(addr);
rp = buf;
ap = (u8_t *) &s_addr;
ap = (uint8_t *) &s_addr;
for (n = 0; n < 4; n++)
{
i = 0;
do
{
rem = *ap % (u8_t) 10;
*ap /= (u8_t) 10;
rem = *ap % (uint8_t) 10;
*ap /= (uint8_t) 10;
inv[i++] = (char) ('0' + rem);
} while (*ap);
while (i--)
@@ -232,10 +232,10 @@ char *sal_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen)
* @return pointer to a global static (!) buffer that holds the ASCII
* representation of addr
*/
char *sal_ip4addr_ntoa(const ip4_addr_t *addr)
char *netdev_ip4addr_ntoa(const ip4_addr_t *addr)
{
static char str[IP4ADDR_STRLEN_MAX];
return sal_ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX);
return netdev_ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX);
}
@@ -246,11 +246,11 @@ char *sal_ip4addr_ntoa(const ip4_addr_t *addr)
* @param cp IP address in ascii representation (e.g. "127.0.0.1")
* @return ip address in network order
*/
in_addr_t sal_ipaddr_addr(const char *cp)
in_addr_t netdev_ipaddr_addr(const char *cp)
{
ip4_addr_t val;
if (sal_ip4addr_aton(cp, &val)) {
if (netdev_ip4addr_aton(cp, &val)) {
return ip4_addr_get_u32(&val);
}
return (IPADDR_NONE);
+10 -6
View File
@@ -18,14 +18,18 @@ extern "C" {
#endif
#ifdef SAL_USING_LWIP
/* lwIP protocol family register */
int lwip_inet_init(void);
#endif
/* Set lwIP network interface device protocol family information */
int sal_lwip_netdev_set_pf_info(struct netdev *netdev);
#endif /* SAL_USING_LWIP */
#ifdef SAL_USING_AT
/* AT protocol family register */
int at_inet_init(void);
#endif
/* Set AT network interface device protocol family information */
int sal_at_netdev_set_pf_info(struct netdev *netdev);
#endif /* SAL_USING_AT */
#ifdef __cplusplus
}
+11 -19
View File
@@ -16,6 +16,8 @@
#include <at_socket.h>
#include <af_inet.h>
#include <netdev.h>
#ifdef SAL_USING_POSIX
#include <dfs_poll.h>
#endif
@@ -78,24 +80,12 @@ static const struct sal_socket_ops at_socket_ops =
NULL,
NULL,
NULL,
#ifdef SAL_USING_POSIX
at_poll,
#endif /* SAL_USING_POSIX */
};
static int at_create(struct sal_socket *socket, int type, int protocol)
{
RT_ASSERT(socket);
//TODO Check type & protocol
socket->ops = &at_socket_ops;
return 0;
}
static struct sal_proto_ops at_proto_ops =
static const struct sal_netdb_ops at_netdb_ops =
{
at_gethostbyname,
NULL,
@@ -107,16 +97,18 @@ static const struct sal_proto_family at_inet_family =
{
AF_AT,
AF_INET,
at_create,
&at_proto_ops,
&at_socket_ops,
&at_netdb_ops,
};
int at_inet_init(void)
{
sal_proto_family_register(&at_inet_family);
/* Set AT network interface device protocol family information */
int sal_at_netdev_set_pf_info(struct netdev *netdev)
{
RT_ASSERT(netdev);
netdev->sal_user_data = (void *) &at_inet_family;
return 0;
}
INIT_COMPONENT_EXPORT(at_inet_init);
#endif /* SAL_USING_AT */
+11 -18
View File
@@ -14,6 +14,7 @@
#include <lwip/netdb.h>
#include <lwip/api.h>
#include <lwip/init.h>
#include <lwip/netif.h>
#ifdef SAL_USING_POSIX
#include <dfs_poll.h>
@@ -22,6 +23,8 @@
#include <sal.h>
#include <af_inet.h>
#include <netdev.h>
#if LWIP_VERSION < 0x2000000
#define SELWAIT_T int
#else
@@ -281,18 +284,7 @@ static const struct sal_socket_ops lwip_socket_ops =
#endif
};
static int inet_create(struct sal_socket *socket, int type, int protocol)
{
RT_ASSERT(socket);
//TODO Check type & protocol
socket->ops = &lwip_socket_ops;
return 0;
}
static struct sal_proto_ops lwip_proto_ops =
static const struct sal_netdb_ops lwip_netdb_ops =
{
lwip_gethostbyname,
lwip_gethostbyname_r,
@@ -304,16 +296,17 @@ static const struct sal_proto_family lwip_inet_family =
{
AF_INET,
AF_INET,
inet_create,
&lwip_proto_ops,
&lwip_socket_ops,
&lwip_netdb_ops,
};
int lwip_inet_init(void)
/* Set lwIP network interface device protocol family information */
int sal_lwip_netdev_set_pf_info(struct netdev *netdev)
{
sal_proto_family_register(&lwip_inet_family);
RT_ASSERT(netdev);
netdev->sal_user_data = (void *) &lwip_inet_family;
return 0;
}
INIT_COMPONENT_EXPORT(lwip_inet_init);
#endif /* SAL_USING_LWIP */
+10 -2
View File
@@ -20,6 +20,8 @@
#include <netdb.h>
#include <sal.h>
#include <netdev.h>
#ifdef SAL_USING_TLS
#if !defined(MBEDTLS_CONFIG_FILE)
@@ -76,6 +78,7 @@ int mbedtls_net_send_cb(void *ctx, const unsigned char *buf, size_t len)
{
struct sal_socket *sock;
int socket, ret;
struct sal_proto_family *pf;
RT_ASSERT(ctx);
RT_ASSERT(buf);
@@ -86,9 +89,11 @@ int mbedtls_net_send_cb(void *ctx, const unsigned char *buf, size_t len)
{
return -1;
}
pf = (struct sal_proto_family *)sock->netdev->sal_user_data;
/* Register scoket sendto option to TLS send data callback */
ret = sock->ops->sendto((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
ret = pf->skt_ops->sendto((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
if (ret < 0)
{
#ifdef RT_USING_DFS
@@ -109,6 +114,7 @@ int mbedtls_net_send_cb(void *ctx, const unsigned char *buf, size_t len)
int mbedtls_net_recv_cb( void *ctx, unsigned char *buf, size_t len)
{
struct sal_socket *sock;
struct sal_proto_family *pf;
int socket, ret;
RT_ASSERT(ctx);
@@ -121,8 +127,10 @@ int mbedtls_net_recv_cb( void *ctx, unsigned char *buf, size_t len)
return -1;
}
pf = (struct sal_proto_family *)sock->netdev->sal_user_data;
/* Register scoket recvfrom option to TLS recv data callback */
ret = sock->ops->recvfrom((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
ret = pf->skt_ops->recvfrom((int) sock->user_data, (void *)buf, len, 0, RT_NULL, RT_NULL);
if (ret < 0)
{
#ifdef RT_USING_DFS
+27 -29
View File
@@ -43,6 +43,24 @@ typedef uint32_t socklen_t;
#define SAL_SOCKET_OFFSET 0
#endif
struct sal_socket
{
uint32_t magic; /* SAL socket magic word */
int socket; /* SAL socket descriptor */
int domain;
int type;
int protocol;
struct netdev *netdev; /* SAL network interface device */
void *user_data; /* user-specific data */
#ifdef SAL_USING_TLS
void *user_data_tls; /* user-specific TLS data */
#endif
};
/* network interface socket opreations */
struct sal_socket_ops
{
int (*socket) (int domain, int type, int protocol);
@@ -64,7 +82,8 @@ struct sal_socket_ops
#endif
};
struct sal_proto_ops
/* sal network database name resolving */
struct sal_netdb_ops
{
struct hostent* (*gethostbyname) (const char *name);
int (*gethostbyname_r)(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop);
@@ -72,42 +91,21 @@ struct sal_proto_ops
void (*freeaddrinfo) (struct addrinfo *ai);
};
struct sal_socket
{
uint32_t magic; /* SAL socket magic word */
int socket; /* SAL socket descriptor */
int domain;
int type;
int protocol;
const struct sal_socket_ops *ops; /* socket options */
void *user_data; /* user-specific data */
#ifdef SAL_USING_TLS
void *user_data_tls; /* user-specific TLS data */
#endif
};
struct sal_proto_family
{
int family; /* primary protocol families type */
int sec_family; /* secondary protocol families type */
int (*create)(struct sal_socket *sal_socket, int type, int protocol); /* register socket options */
struct sal_proto_ops *ops; /* protocol family options */
int family; /* primary protocol families type */
int sec_family; /* secondary protocol families type */
const struct sal_socket_ops *skt_ops; /* socket opreations */
const struct sal_netdb_ops *netdb_ops; /* network database opreations */
};
/* SAL(Socket Abstraction Layer) initialize */
int sal_init(void);
/* Get SAL socket object by socket descriptor */
struct sal_socket *sal_get_socket(int sock);
/* SAL protocol family register and unregister operate */
int sal_proto_family_register(const struct sal_proto_family *pf);
int sal_proto_family_unregister(int family);
rt_bool_t sal_proto_family_is_registered(int family);
struct sal_proto_family *sal_proto_family_find(int family);
/* check SAL socket netweork interface device internet status */
int sal_check_netdev_internet_up(struct netdev *netdev);
#ifdef __cplusplus
}
@@ -1,128 +0,0 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-18 ChenYong First version
*/
#ifndef SAL_IPADDR_H__
#define SAL_IPADDR_H__
#include "sal_type.h"
#ifdef __cplusplus
extern "C" {
#endif
/** IPv4 only: set the IP address given as an u32_t */
#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32))
/** IPv4 only: get the IP address as an u32_t */
#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr)
#define IP4ADDR_STRLEN_MAX 16
/* These macros should be calculated by the preprocessor and are used
with compile-time constants only (so that there is no little-endian
overhead at runtime). */
#define PP_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
#define PP_NTOHS(x) PP_HTONS(x)
#define PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
(((x) & 0x0000ff00UL) << 8) | \
(((x) & 0x00ff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define PP_NTOHL(x) PP_HTONL(x)
#define htons(x) (u16_t)PP_HTONS(x)
#define ntohs(x) (u16_t)PP_NTOHS(x)
#define htonl(x) (u32_t)PP_HTONL(x)
#define ntohl(x) (u32_t)PP_NTOHL(x)
/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED
to prevent this code from redefining it. */
#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED)
typedef u32_t in_addr_t;
#endif
struct in_addr
{
in_addr_t s_addr;
};
struct in6_addr
{
union
{
u32_t u32_addr[4];
u8_t u8_addr[16];
} un;
#define s6_addr un.u8_addr
};
enum sal_ip_addr_type
{
/** IPv4 */
IPADDR_TYPE_V4 = 0U,
/** IPv6 */
IPADDR_TYPE_V6 = 6U,
/** IPv4+IPv6 ("dual-stack") */
IPADDR_TYPE_ANY = 46U
};
typedef struct ip4_addr
{
u32_t addr;
} ip4_addr_t;
typedef struct ip6_addr
{
u32_t addr[4];
} ip6_addr_t;
typedef struct _ip_addr
{
union
{
ip6_addr_t ip6;
ip4_addr_t ip4;
} u_addr;
/** @ref sal_ip_addr_type */
u8_t type;
} ip_addr_t;
/** 255.255.255.255 */
#define IPADDR_NONE ((u32_t)0xffffffffUL)
/** 127.0.0.1 */
#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
/** 0.0.0.0 */
#define IPADDR_ANY ((u32_t)0x00000000UL)
/** 255.255.255.255 */
#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
/** 255.255.255.255 */
#define INADDR_NONE IPADDR_NONE
/** 127.0.0.1 */
#define INADDR_LOOPBACK IPADDR_LOOPBACK
/** 0.0.0.0 */
#define INADDR_ANY IPADDR_ANY
/** 255.255.255.255 */
#define INADDR_BROADCAST IPADDR_BROADCAST
#define IPADDR_BROADCAST_STRING "255.255.255.255"
in_addr_t sal_ipaddr_addr(const char *cp);
int sal_ip4addr_aton(const char *cp, ip4_addr_t *addr);
char *sal_ip4addr_ntoa(const ip4_addr_t *addr);
char *sal_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen);
#define inet_addr(cp) sal_ipaddr_addr(cp)
#define inet_aton(cp,addr) sal_ip4addr_aton(cp,(ip4_addr_t*)addr)
#define inet_ntoa(addr) sal_ip4addr_ntoa((const ip4_addr_t*)&(addr))
#define inet_ntoa_r(addr, buf, buflen) sal_ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen)
#ifdef __cplusplus
}
#endif
#endif /* SAL_IPADDR_H__ */
@@ -10,7 +10,7 @@
#ifndef SAL_NETDB_H__
#define SAL_NETDB_H__
#include <sal_socket.h>
#include "sal_socket.h"
#ifdef __cplusplus
extern "C" {
@@ -11,7 +11,7 @@
#ifndef SAL_SOCKET_H__
#define SAL_SOCKET_H__
#include "sal_ipaddr.h"
#include <arpa/inet.h>
#ifdef __cplusplus
extern "C" {
@@ -1,34 +0,0 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-17 ChenYong First version
*/
#ifndef SAL_TYPE_H__
#define SAL_TYPE_H__
#include <stdlib.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int8_t err_t;
typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
typedef uintptr_t mem_ptr_t;
#ifdef __cplusplus
}
#endif
#endif /* SAL_TYPE_H__ */
File diff suppressed because it is too large Load Diff