diff --git a/components/net/at/at_socket/at_socket.c b/components/net/at/at_socket/at_socket.c index 054c5508c9b70cbbdb462a0282ad68cc937e7d56..f08a374bf05ed1037f573d36271193f1a606b963 100644 --- a/components/net/at/at_socket/at_socket.c +++ b/components/net/at/at_socket/at_socket.c @@ -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 */ diff --git a/components/net/at/include/at.h b/components/net/at/include/at.h index 9a2630203f2f3454bb2f882e056dc31323015b89..10e4c8833b5a711f8bf256ec2bb4e36530408989 100644 --- a/components/net/at/include/at.h +++ b/components/net/at/include/at.h @@ -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; diff --git a/components/net/at/src/at_cli.c b/components/net/at/src/at_cli.c index 60e3b4d86807762e2db854470aebaacccf58403d..80af613fa6d96db240c6b3a96299c8681e85713d 100644 --- a/components/net/at/src/at_cli.c +++ b/components/net/at/src/at_cli.c @@ -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(); diff --git a/components/net/at/src/at_client.c b/components/net/at/src/at_client.c index 1f6ed66743fde5236b4ed08e3444d053d274dea4..4020d80165dd5eceb956ca75259803184457be8b 100644 --- a/components/net/at/src/at_client.c +++ b/components/net/at/src/at_client.c @@ -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) { diff --git a/components/net/lwip-1.4.1/READTEST.md b/components/net/lwip-1.4.1/READTEST.md new file mode 100644 index 0000000000000000000000000000000000000000..05f10dc780abd5ced038d1fcf05e5db0ddb2a6e2 --- /dev/null +++ b/components/net/lwip-1.4.1/READTEST.md @@ -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 diff --git a/components/net/lwip-1.4.1/SConscript b/components/net/lwip-1.4.1/SConscript index 3ba2bcd4c8ef90dd64722cb8c094267416ae99e2..8e3a4cb9d4c28268758b89e1ecc648d39bb67b38 100644 --- a/components/net/lwip-1.4.1/SConscript +++ b/components/net/lwip-1.4.1/SConscript @@ -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) diff --git a/components/net/lwip-1.4.1/src/apps/ping/ping.c b/components/net/lwip-1.4.1/src/apps/ping/ping.c new file mode 100644 index 0000000000000000000000000000000000000000..1075e2ddfd25108ffa217682db972ecaa9762066 --- /dev/null +++ b/components/net/lwip-1.4.1/src/apps/ping/ping.c @@ -0,0 +1,245 @@ +/* + * netutils: ping implementation + */ + +#include + +#ifdef RT_LWIP_ICMP /* don't build if not configured for use in rtconfig.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * 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_FUNCTION_EXPORT(ping, ping network host); + +int cmd_ping(int argc, char **argv) +{ + if (argc == 1) + { + rt_kprintf("Please input: ping \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 */ + diff --git a/components/net/lwip-1.4.1/src/core/dns.c b/components/net/lwip-1.4.1/src/core/dns.c index d63361226f2e793478f71798bbc6bf7aa074a1a4..20398ae6099444a166e143d24924bb3b985b56ac 100644 --- a/components/net/lwip-1.4.1/src/core/dns.c +++ b/components/net/lwip-1.4.1/src/core/dns.c @@ -83,6 +83,8 @@ #include +#include + /** 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 */ } } diff --git a/components/net/lwip-1.4.1/src/core/netif.c b/components/net/lwip-1.4.1/src/core/netif.c index 4a02e77f31f24ec0cf470631f79879ad171cf5ce..9c3e32b33f5f83e759d4cc8fe1b8d578e598b302 100644 --- a/components/net/lwip-1.4.1/src/core/netif.c +++ b/components/net/lwip-1.4.1/src/core/netif.c @@ -60,6 +60,13 @@ #include "lwip/dhcp.h" #endif /* LWIP_DHCP */ +#include + +#ifdef RT_USING_NETDEV +#include "lwip/netdb.h" +#include +#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 */ } } diff --git a/components/net/lwip-1.4.1/src/netif/ethernetif.c b/components/net/lwip-1.4.1/src/netif/ethernetif.c index 31aeaf6dfff261f009046d75b14e10453dd90cb0..dfe304f91db334b8ec0911563d8f10c15ef3ef5b 100644 --- a/components/net/lwip-1.4.1/src/netif/ethernetif.c +++ b/components/net/lwip-1.4.1/src/netif/ethernetif.c @@ -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 + +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; } diff --git a/components/net/lwip-2.0.2/READTEST.md b/components/net/lwip-2.0.2/READTEST.md index b67f2afdf4e4d425685ea1decb1dcd83181bb99e..dbc2a2bf4d1c6fcb2691a6d953637be65d23a447 100644 --- a/components/net/lwip-2.0.2/READTEST.md +++ b/components/net/lwip-2.0.2/READTEST.md @@ -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 diff --git a/components/net/lwip-2.0.2/SConscript b/components/net/lwip-2.0.2/SConscript index d99556af90a10e4b0a7009495d79dbde640b4e44..df04b42324ab8519c5bd645c37078937d04e7203 100644 --- a/components/net/lwip-2.0.2/SConscript +++ b/components/net/lwip-2.0.2/SConscript @@ -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) diff --git a/components/net/lwip-2.0.2/src/apps/ping/ping.c b/components/net/lwip-2.0.2/src/apps/ping/ping.c index 4b934f0cacccc43e56ef080e94d7299d95bde036..1075e2ddfd25108ffa217682db972ecaa9762066 100644 --- a/components/net/lwip-2.0.2/src/apps/ping/ping.c +++ b/components/net/lwip-2.0.2/src/apps/ping/ping.c @@ -2,16 +2,20 @@ * netutils: ping implementation */ -#include "lwip/opt.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" +#include + +#ifdef RT_LWIP_ICMP /* don't build if not configured for use in rtconfig.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /** * 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) + if (size == 0) + { size = PING_DATA_SIZE; + } - if (inet_aton(target, &ping_target) == 0) + 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); + 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 */ + diff --git a/components/net/lwip-2.0.2/src/core/dns.c b/components/net/lwip-2.0.2/src/core/dns.c index 12c6f16fe3508ffab5a0b5237b93d8b2a810c16a..5f8c3e52e333a6ffba6d1f42099cbbc8b2929942 100644 --- a/components/net/lwip-2.0.2/src/core/dns.c +++ b/components/net/lwip-2.0.2/src/core/dns.c @@ -95,6 +95,8 @@ #include +#include + /** 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; } diff --git a/components/net/lwip-2.0.2/src/core/netif.c b/components/net/lwip-2.0.2/src/core/netif.c index 428b148421461ca00d0f2bc120934b66294031dc..01e83676da52434b98cb3e1d93b12980d640324f 100644 --- a/components/net/lwip-2.0.2/src/core/netif.c +++ b/components/net/lwip-2.0.2/src/core/netif.c @@ -89,6 +89,13 @@ #include "lwip/nd6.h" #endif +#include + +#ifdef RT_USING_NETDEV +#include "lwip/netdb.h" +#include +#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 */ } } diff --git a/components/net/lwip-2.0.2/src/netif/ethernetif.c b/components/net/lwip-2.0.2/src/netif/ethernetif.c index 8d53f0f4edd084a41172459bd405ee0e3eb0f9c5..6e0eb1eed762d70c36d7a9cf450a75ba22396b63 100644 --- a/components/net/lwip-2.0.2/src/netif/ethernetif.c +++ b/components/net/lwip-2.0.2/src/netif/ethernetif.c @@ -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 + +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; } diff --git a/components/net/lwip-2.1.0/READTEST.md b/components/net/lwip-2.1.0/READTEST.md new file mode 100644 index 0000000000000000000000000000000000000000..6bdebeb1125c8d014091674b5cfcb6cb5542aa7e --- /dev/null +++ b/components/net/lwip-2.1.0/READTEST.md @@ -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 diff --git a/components/net/lwip-2.1.0/SConscript b/components/net/lwip-2.1.0/SConscript index 22c56be1b90d38ef42193c168c97b514fbba5d06..36baf9418bea21330070bbd1371639e4217549e2 100644 --- a/components/net/lwip-2.1.0/SConscript +++ b/components/net/lwip-2.1.0/SConscript @@ -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) diff --git a/components/net/lwip-2.1.0/src/apps/ping/ping.c b/components/net/lwip-2.1.0/src/apps/ping/ping.c index 4b934f0cacccc43e56ef080e94d7299d95bde036..1075e2ddfd25108ffa217682db972ecaa9762066 100644 --- a/components/net/lwip-2.1.0/src/apps/ping/ping.c +++ b/components/net/lwip-2.1.0/src/apps/ping/ping.c @@ -2,16 +2,20 @@ * netutils: ping implementation */ -#include "lwip/opt.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" +#include + +#ifdef RT_LWIP_ICMP /* don't build if not configured for use in rtconfig.h */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /** * 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) + if (size == 0) + { size = PING_DATA_SIZE; + } - if (inet_aton(target, &ping_target) == 0) + 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); + 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 */ + diff --git a/components/net/lwip-2.1.0/src/core/dns.c b/components/net/lwip-2.1.0/src/core/dns.c index 9d2f61ed86ba71b2b236eb3b6acf2650ac3b3864..831956f7116b6941050e7cf33b08a94fe5960180 100644 --- a/components/net/lwip-2.1.0/src/core/dns.c +++ b/components/net/lwip-2.1.0/src/core/dns.c @@ -97,6 +97,8 @@ #include +#include + /** 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; } diff --git a/components/net/lwip-2.1.0/src/core/netif.c b/components/net/lwip-2.1.0/src/core/netif.c index 15200a27409df70f6018fbb6f792cecfcf18b279..5b31c627e979f066bfca25aeda9765aecb499c9f 100644 --- a/components/net/lwip-2.1.0/src/core/netif.c +++ b/components/net/lwip-2.1.0/src/core/netif.c @@ -90,6 +90,13 @@ #include "lwip/nd6.h" #endif +#include + +#ifdef RT_USING_NETDEV +#include "lwip/netdb.h" +#include +#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 */ } } diff --git a/components/net/lwip-2.1.0/src/netif/ethernetif.c b/components/net/lwip-2.1.0/src/netif/ethernetif.c index f0defe5b258e6f1ddf06d24e9a2e4977d7a60fc9..655f2864befa08be956504685d7c26e278219606 100755 --- a/components/net/lwip-2.1.0/src/netif/ethernetif.c +++ b/components/net/lwip-2.1.0/src/netif/ethernetif.c @@ -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 + +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; }