mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-07 06:01:35 +03:00
move lwIP source to sdk and add a build hook instead of variant
This commit is contained in:
1144
tools/sdk/lwip/src/app/dhcpserver.c
Normal file
1144
tools/sdk/lwip/src/app/dhcpserver.c
Normal file
File diff suppressed because it is too large
Load Diff
1303
tools/sdk/lwip/src/app/espconn.c
Normal file
1303
tools/sdk/lwip/src/app/espconn.c
Normal file
File diff suppressed because it is too large
Load Diff
134
tools/sdk/lwip/src/app/espconn_mdns.c
Normal file
134
tools/sdk/lwip/src/app/espconn_mdns.c
Normal file
@ -0,0 +1,134 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2013-2014 Espressif Systems (Wuxi)
|
||||
*
|
||||
* FileName: espconn_mdns.c
|
||||
*
|
||||
* Description: udp proto interface
|
||||
*
|
||||
* Modification history:
|
||||
* 2014/3/31, v1.0 create this file.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "ets_sys.h"
|
||||
#include "os_type.h"
|
||||
|
||||
#include "lwip/mdns.h"
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_enable
|
||||
* Description : join a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_enable(void)
|
||||
{
|
||||
mdns_enable();
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_disable
|
||||
* Description : join a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_disable(void)
|
||||
{
|
||||
mdns_disable();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_set_hostname
|
||||
* Description : join a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_set_hostname(char *name)
|
||||
{
|
||||
mdns_set_hostname(name);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_init
|
||||
* Description : join a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
char* ICACHE_FLASH_ATTR
|
||||
espconn_mdns_get_hostname(void)
|
||||
{
|
||||
return (char *)mdns_get_hostname();
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_get_servername
|
||||
* Description : join a multicast group
|
||||
* Parameters : info -- the info of mdns
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_set_servername(const char *name)
|
||||
{
|
||||
mdns_set_servername(name);
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_get_servername
|
||||
* Description : join a multicast group
|
||||
* Parameters : info -- the info of mdns
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
char* ICACHE_FLASH_ATTR
|
||||
espconn_mdns_get_servername(void)
|
||||
{
|
||||
return (char *)mdns_get_servername();
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : mdns_server_register
|
||||
* Description : join a multicast group
|
||||
* Parameters : info -- the info of mdns
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_server_register(void)
|
||||
{
|
||||
mdns_server_register();
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : mdns_server_register
|
||||
* Description : join a multicast group
|
||||
* Parameters : info -- the info of mdns
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_server_unregister(void)
|
||||
{
|
||||
mdns_server_unregister();
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_init
|
||||
* Description : join a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_close(void)
|
||||
{
|
||||
mdns_close();
|
||||
}
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_mdns_init
|
||||
* Description : join a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
espconn_mdns_init(struct mdns_info *info)
|
||||
{
|
||||
mdns_init(info);
|
||||
}
|
1390
tools/sdk/lwip/src/app/espconn_tcp.c
Normal file
1390
tools/sdk/lwip/src/app/espconn_tcp.c
Normal file
File diff suppressed because it is too large
Load Diff
423
tools/sdk/lwip/src/app/espconn_udp.c
Normal file
423
tools/sdk/lwip/src/app/espconn_udp.c
Normal file
@ -0,0 +1,423 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2013-2014 Espressif Systems (Wuxi)
|
||||
*
|
||||
* FileName: espconn_udp.c
|
||||
*
|
||||
* Description: udp proto interface
|
||||
*
|
||||
* Modification history:
|
||||
* 2014/3/31, v1.0 create this file.
|
||||
*******************************************************************************/
|
||||
|
||||
#include "ets_sys.h"
|
||||
#include "os_type.h"
|
||||
//#include "os.h"
|
||||
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "lwip/udp.h"
|
||||
|
||||
#include "lwip/app/espconn_udp.h"
|
||||
|
||||
#ifdef MEMLEAK_DEBUG
|
||||
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
|
||||
#endif
|
||||
|
||||
extern espconn_msg *plink_active;
|
||||
extern uint8 default_interface;
|
||||
|
||||
enum send_opt{
|
||||
ESPCONN_SENDTO,
|
||||
ESPCONN_SEND
|
||||
};
|
||||
static void ICACHE_FLASH_ATTR espconn_data_sentcb(struct espconn *pespconn)
|
||||
{
|
||||
if (pespconn == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pespconn->sent_callback != NULL) {
|
||||
pespconn->sent_callback(pespconn);
|
||||
}
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR espconn_data_sent(void *arg, enum send_opt opt)
|
||||
{
|
||||
espconn_msg *psent = arg;
|
||||
|
||||
if (psent == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (psent->pcommon.cntr == 0) {
|
||||
psent->pespconn->state = ESPCONN_CONNECT;
|
||||
if (psent->pcommon.err == 0)
|
||||
espconn_data_sentcb(psent->pespconn);
|
||||
} else {
|
||||
if (opt == ESPCONN_SEND){
|
||||
espconn_udp_sent(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr);
|
||||
} else {
|
||||
espconn_udp_sendto(arg, psent->pcommon.ptrbuf, psent->pcommon.cntr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_udp_sent
|
||||
* Description : sent data for client or server
|
||||
* Parameters : void *arg -- client or server to send
|
||||
* uint8* psent -- Data to send
|
||||
* uint16 length -- Length of data to send
|
||||
* Returns : return espconn error code.
|
||||
* - ESPCONN_OK. Successful. No error occured.
|
||||
* - ESPCONN_MEM. Out of memory.
|
||||
* - ESPCONN_RTE. Could not find route to destination address.
|
||||
* - More errors could be returned by lower protocol layers.
|
||||
*******************************************************************************/
|
||||
err_t ICACHE_FLASH_ATTR
|
||||
espconn_udp_sent(void *arg, uint8 *psent, uint16 length)
|
||||
{
|
||||
espconn_msg *pudp_sent = arg;
|
||||
struct udp_pcb *upcb = pudp_sent->pcommon.pcb;
|
||||
struct pbuf *p, *q ,*p_temp;
|
||||
u8_t *data = NULL;
|
||||
u16_t cnt = 0;
|
||||
u16_t datalen = 0;
|
||||
u16_t i = 0;
|
||||
err_t err;
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb));
|
||||
|
||||
if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) {
|
||||
return ESPCONN_ARG;
|
||||
}
|
||||
|
||||
if (1470 < length) {
|
||||
datalen = 1470;
|
||||
} else {
|
||||
datalen = length;
|
||||
}
|
||||
|
||||
p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
|
||||
|
||||
if (p != NULL) {
|
||||
q = p;
|
||||
|
||||
while (q != NULL) {
|
||||
data = (u8_t *)q->payload;
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data));
|
||||
|
||||
for (i = 0; i < q->len; i++) {
|
||||
data[i] = ((u8_t *) psent)[cnt++];
|
||||
}
|
||||
|
||||
q = q->next;
|
||||
}
|
||||
} else {
|
||||
return ESPCONN_MEM;
|
||||
}
|
||||
|
||||
upcb->remote_port = pudp_sent->pespconn->proto.udp->remote_port;
|
||||
IP4_ADDR(&upcb->remote_ip, pudp_sent->pespconn->proto.udp->remote_ip[0],
|
||||
pudp_sent->pespconn->proto.udp->remote_ip[1],
|
||||
pudp_sent->pespconn->proto.udp->remote_ip[2],
|
||||
pudp_sent->pespconn->proto.udp->remote_ip[3]);
|
||||
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip, upcb->remote_port));
|
||||
|
||||
struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00);
|
||||
struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01);
|
||||
|
||||
if(wifi_get_opmode() == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL)
|
||||
{
|
||||
if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \
|
||||
ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \
|
||||
ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) {
|
||||
|
||||
p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
|
||||
if (pbuf_copy (p_temp,p) != ERR_OK) {
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent: copying to new pbuf failed\n"));
|
||||
return ESPCONN_ARG;
|
||||
}
|
||||
netif_set_default(sta_netif);
|
||||
err = udp_send(upcb, p_temp);
|
||||
pbuf_free(p_temp);
|
||||
netif_set_default(ap_netif);
|
||||
}
|
||||
}
|
||||
err = udp_send(upcb, p);
|
||||
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d\n", __LINE__, err));
|
||||
|
||||
if (p->ref != 0) {
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
|
||||
pbuf_free(p);
|
||||
pudp_sent->pcommon.ptrbuf = psent + datalen;
|
||||
pudp_sent->pcommon.cntr = length - datalen;
|
||||
pudp_sent->pcommon.err = err;
|
||||
espconn_data_sent(pudp_sent, ESPCONN_SEND);
|
||||
if (err > 0)
|
||||
return ESPCONN_IF;
|
||||
return err;
|
||||
} else {
|
||||
pbuf_free(p);
|
||||
return ESPCONN_RTE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_udp_sendto
|
||||
* Description : sent data for UDP
|
||||
* Parameters : void *arg -- UDP to send
|
||||
* uint8* psent -- Data to send
|
||||
* uint16 length -- Length of data to send
|
||||
* Returns : return espconn error code.
|
||||
* - ESPCONN_OK. Successful. No error occured.
|
||||
* - ESPCONN_MEM. Out of memory.
|
||||
* - ESPCONN_RTE. Could not find route to destination address.
|
||||
* - More errors could be returned by lower protocol layers.
|
||||
*******************************************************************************/
|
||||
err_t ICACHE_FLASH_ATTR
|
||||
espconn_udp_sendto(void *arg, uint8 *psent, uint16 length)
|
||||
{
|
||||
espconn_msg *pudp_sent = arg;
|
||||
struct udp_pcb *upcb = pudp_sent->pcommon.pcb;
|
||||
struct espconn *pespconn = pudp_sent->pespconn;
|
||||
struct pbuf *p, *q ,*p_temp;
|
||||
struct ip_addr dst_ip;
|
||||
u16_t dst_port;
|
||||
u8_t *data = NULL;
|
||||
u16_t cnt = 0;
|
||||
u16_t datalen = 0;
|
||||
u16_t i = 0;
|
||||
err_t err;
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %d %p\n", __LINE__, length, upcb));
|
||||
|
||||
if (pudp_sent == NULL || upcb == NULL || psent == NULL || length == 0) {
|
||||
return ESPCONN_ARG;
|
||||
}
|
||||
|
||||
if (1470 < length) {
|
||||
datalen = 1470;
|
||||
} else {
|
||||
datalen = length;
|
||||
}
|
||||
|
||||
p = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, p));
|
||||
|
||||
if (p != NULL) {
|
||||
q = p;
|
||||
|
||||
while (q != NULL) {
|
||||
data = (u8_t *)q->payload;
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %p\n", __LINE__, data));
|
||||
|
||||
for (i = 0; i < q->len; i++) {
|
||||
data[i] = ((u8_t *) psent)[cnt++];
|
||||
}
|
||||
|
||||
q = q->next;
|
||||
}
|
||||
} else {
|
||||
return ESPCONN_MEM;
|
||||
}
|
||||
|
||||
dst_port = pespconn->proto.udp->remote_port;
|
||||
IP4_ADDR(&dst_ip, pespconn->proto.udp->remote_ip[0],
|
||||
pespconn->proto.udp->remote_ip[1], pespconn->proto.udp->remote_ip[2],
|
||||
pespconn->proto.udp->remote_ip[3]);
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sent %d %x %d\n", __LINE__, upcb->remote_ip, upcb->remote_port));
|
||||
|
||||
struct netif *sta_netif = (struct netif *)eagle_lwip_getif(0x00);
|
||||
struct netif *ap_netif = (struct netif *)eagle_lwip_getif(0x01);
|
||||
|
||||
if(wifi_get_opmode() == ESPCONN_AP_STA && default_interface == ESPCONN_AP_STA && sta_netif != NULL && ap_netif != NULL)
|
||||
{
|
||||
if(netif_is_up(sta_netif) && netif_is_up(ap_netif) && \
|
||||
ip_addr_isbroadcast(&upcb->remote_ip, sta_netif) && \
|
||||
ip_addr_isbroadcast(&upcb->remote_ip, ap_netif)) {
|
||||
|
||||
p_temp = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
|
||||
if (pbuf_copy (p_temp,p) != ERR_OK) {
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_sendto: copying to new pbuf failed\n"));
|
||||
return ESPCONN_ARG;
|
||||
}
|
||||
netif_set_default(sta_netif);
|
||||
err = udp_sendto(upcb, p_temp, &dst_ip, dst_port);
|
||||
pbuf_free(p_temp);
|
||||
netif_set_default(ap_netif);
|
||||
}
|
||||
}
|
||||
err = udp_sendto(upcb, p, &dst_ip, dst_port);
|
||||
|
||||
if (p->ref != 0) {
|
||||
pbuf_free(p);
|
||||
pudp_sent->pcommon.ptrbuf = psent + datalen;
|
||||
pudp_sent->pcommon.cntr = length - datalen;
|
||||
pudp_sent->pcommon.err = err;
|
||||
espconn_data_sent(pudp_sent, ESPCONN_SENDTO);
|
||||
|
||||
if (err > 0)
|
||||
return ESPCONN_IF;
|
||||
return err;
|
||||
} else {
|
||||
pbuf_free(p);
|
||||
return ESPCONN_RTE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_udp_server_recv
|
||||
* Description : This callback will be called when receiving a datagram.
|
||||
* Parameters : arg -- user supplied argument
|
||||
* upcb -- the udp_pcb which received data
|
||||
* p -- the packet buffer that was received
|
||||
* addr -- the remote IP address from which the packet was received
|
||||
* port -- the remote port from which the packet was received
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
static void ICACHE_FLASH_ATTR
|
||||
espconn_udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p,
|
||||
struct ip_addr *addr, u16_t port)
|
||||
{
|
||||
espconn_msg *precv = arg;
|
||||
u8_t *pdata = NULL;
|
||||
u16_t length = 0;
|
||||
struct ip_info ipconfig;
|
||||
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("espconn_udp_server_recv %d %p\n", __LINE__, upcb));
|
||||
|
||||
precv->pcommon.remote_ip[0] = ip4_addr1_16(addr);
|
||||
precv->pcommon.remote_ip[1] = ip4_addr2_16(addr);
|
||||
precv->pcommon.remote_ip[2] = ip4_addr3_16(addr);
|
||||
precv->pcommon.remote_ip[3] = ip4_addr4_16(addr);
|
||||
precv->pcommon.remote_port = port;
|
||||
precv->pcommon.pcb = upcb;
|
||||
|
||||
if (wifi_get_opmode() != 1) {
|
||||
wifi_get_ip_info(1, &ipconfig);
|
||||
|
||||
if (!ip_addr_netcmp(addr, &ipconfig.ip, &ipconfig.netmask)) {
|
||||
wifi_get_ip_info(0, &ipconfig);
|
||||
}
|
||||
} else {
|
||||
wifi_get_ip_info(0, &ipconfig);
|
||||
}
|
||||
|
||||
precv->pespconn->proto.udp->local_ip[0] = ip4_addr1_16(&ipconfig.ip);
|
||||
precv->pespconn->proto.udp->local_ip[1] = ip4_addr2_16(&ipconfig.ip);
|
||||
precv->pespconn->proto.udp->local_ip[2] = ip4_addr3_16(&ipconfig.ip);
|
||||
precv->pespconn->proto.udp->local_ip[3] = ip4_addr4_16(&ipconfig.ip);
|
||||
|
||||
if (p != NULL) {
|
||||
pdata = (u8_t *)os_zalloc(p ->tot_len + 1);
|
||||
length = pbuf_copy_partial(p, pdata, p ->tot_len, 0);
|
||||
precv->pcommon.pcb = upcb;
|
||||
pbuf_free(p);
|
||||
if (length != 0) {
|
||||
if (precv->pespconn->recv_callback != NULL) {
|
||||
precv->pespconn->recv_callback(precv->pespconn, (char *)pdata, length);
|
||||
}
|
||||
}
|
||||
os_free(pdata);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_udp_disconnect
|
||||
* Description : A new incoming connection has been disconnected.
|
||||
* Parameters : espconn -- the espconn used to disconnect with host
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon)
|
||||
{
|
||||
if (pdiscon == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct udp_pcb *upcb = pdiscon->pcommon.pcb;
|
||||
|
||||
udp_disconnect(upcb);
|
||||
|
||||
udp_remove(upcb);
|
||||
|
||||
espconn_list_delete(&plink_active, pdiscon);
|
||||
|
||||
os_free(pdiscon);
|
||||
pdiscon = NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_udp_server
|
||||
* Description : Initialize the server: set up a PCB and bind it to the port
|
||||
* Parameters : pespconn -- the espconn used to build server
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
sint8 ICACHE_FLASH_ATTR
|
||||
espconn_udp_server(struct espconn *pespconn)
|
||||
{
|
||||
struct udp_pcb *upcb = NULL;
|
||||
espconn_msg *pserver = NULL;
|
||||
upcb = udp_new();
|
||||
|
||||
if (upcb == NULL) {
|
||||
return ESPCONN_MEM;
|
||||
} else {
|
||||
pserver = (espconn_msg *)os_zalloc(sizeof(espconn_msg));
|
||||
|
||||
if (pserver == NULL) {
|
||||
udp_remove(upcb);
|
||||
return ESPCONN_MEM;
|
||||
}
|
||||
|
||||
pserver->pcommon.pcb = upcb;
|
||||
pserver->pespconn = pespconn;
|
||||
espconn_list_creat(&plink_active, pserver);
|
||||
udp_bind(upcb, IP_ADDR_ANY, pserver->pespconn->proto.udp->local_port);
|
||||
udp_recv(upcb, espconn_udp_recv, (void *)pserver);
|
||||
return ESPCONN_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_igmp_leave
|
||||
* Description : leave a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
sint8 ICACHE_FLASH_ATTR
|
||||
espconn_igmp_leave(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
|
||||
{
|
||||
if (igmp_leavegroup(host_ip, multicast_ip) != ERR_OK) {
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_leave_multigrup failed!\n"));
|
||||
return -1;
|
||||
};
|
||||
|
||||
return ESPCONN_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : espconn_igmp_join
|
||||
* Description : join a multicast group
|
||||
* Parameters : host_ip -- the ip address of udp server
|
||||
* multicast_ip -- multicast ip given by user
|
||||
* Returns : none
|
||||
*******************************************************************************/
|
||||
sint8 ICACHE_FLASH_ATTR
|
||||
espconn_igmp_join(ip_addr_t *host_ip, ip_addr_t *multicast_ip)
|
||||
{
|
||||
if (igmp_joingroup(host_ip, multicast_ip) != ERR_OK) {
|
||||
LWIP_DEBUGF(ESPCONN_UDP_DEBUG, ("udp_join_multigrup failed!\n"));
|
||||
return -1;
|
||||
};
|
||||
|
||||
/* join to any IP address at the port */
|
||||
return ESPCONN_OK;
|
||||
}
|
369
tools/sdk/lwip/src/app/netio.c
Normal file
369
tools/sdk/lwip/src/app/netio.c
Normal file
@ -0,0 +1,369 @@
|
||||
/**
|
||||
* @file
|
||||
* MetIO Server
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_TCP
|
||||
#include "lwip/tcp.h"
|
||||
|
||||
#ifdef MEMLEAK_DEBUG
|
||||
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This implements a netio server.
|
||||
* The client sends a command word (4 bytes) then a data length word (4 bytes).
|
||||
* If the command is "receive", the server is to consume "data length" bytes into
|
||||
* a circular buffer until the first byte is non-zero, then it is to consume
|
||||
* another command/data pair.
|
||||
* If the command is "send", the server is to send "data length" bytes from a circular
|
||||
* buffer with the first byte being zero, until "some time" (6 seconds in the
|
||||
* current netio126.zip download) has passed and then send one final buffer with
|
||||
* the first byte being non-zero. Then it is to consume another command/data pair.
|
||||
*/
|
||||
|
||||
/* See http://www.nwlab.net/art/netio/netio.html to get the netio tool */
|
||||
|
||||
/* implementation options */
|
||||
#define NETIO_BUF_SIZE (4 * 1024)
|
||||
#define NETIO_USE_STATIC_BUF 0
|
||||
|
||||
/* NetIO server state definition */
|
||||
#define NETIO_STATE_WAIT_FOR_CMD 0
|
||||
#define NETIO_STATE_RECV_DATA 1
|
||||
#define NETIO_STATE_SEND_DATA 2
|
||||
#define NETIO_STATE_SEND_DATA_LAST 3
|
||||
#define NETIO_STATE_DONE 4
|
||||
|
||||
struct netio_state {
|
||||
u32_t state;
|
||||
u32_t cmd;
|
||||
u32_t data_len;
|
||||
u32_t cntr;
|
||||
u8_t * buf_ptr;
|
||||
u32_t buf_pos;
|
||||
u32_t first_byte;
|
||||
u32_t time_stamp;
|
||||
};
|
||||
|
||||
/* NetIO command protocol definition */
|
||||
#define NETIO_CMD_QUIT 0
|
||||
#define NETIO_CMD_C2S 1
|
||||
#define NETIO_CMD_S2C 2
|
||||
#define NETIO_CMD_RES 3
|
||||
|
||||
static err_t netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err);
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
netio_close(void *arg, struct tcp_pcb *pcb)
|
||||
{
|
||||
err_t err;
|
||||
|
||||
struct netio_state *ns = arg;
|
||||
ns->state = NETIO_STATE_DONE;
|
||||
tcp_recv(pcb, NULL);
|
||||
err = tcp_close(pcb);
|
||||
|
||||
if (err != ERR_OK) {
|
||||
/* closing failed, try again later */
|
||||
tcp_recv(pcb, netio_recv);
|
||||
} else {
|
||||
/* closing succeeded */
|
||||
#if NETIO_USE_STATIC_BUF != 1
|
||||
if(ns->buf_ptr != NULL){
|
||||
mem_free(ns->buf_ptr);
|
||||
}
|
||||
#endif
|
||||
tcp_arg(pcb, NULL);
|
||||
tcp_poll(pcb, NULL, 0);
|
||||
tcp_sent(pcb, NULL);
|
||||
if (arg != NULL) {
|
||||
mem_free(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static err_t ICACHE_FLASH_ATTR
|
||||
netio_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||
{
|
||||
struct netio_state *ns = arg;
|
||||
u8_t * data_ptr;
|
||||
u32_t data_cntr;
|
||||
struct pbuf *q = p;
|
||||
u16_t len;
|
||||
|
||||
if (p != NULL) {
|
||||
tcp_recved(pcb, p->tot_len);
|
||||
}
|
||||
|
||||
if (err == ERR_OK && q != NULL) {
|
||||
|
||||
while (q != NULL) {
|
||||
data_cntr = q->len;
|
||||
data_ptr = q->payload;
|
||||
while (data_cntr--) {
|
||||
if (ns->state == NETIO_STATE_DONE){
|
||||
netio_close(ns, pcb);
|
||||
break;
|
||||
} else if (ns->state == NETIO_STATE_WAIT_FOR_CMD) {
|
||||
if (ns->cntr < 4) {
|
||||
/* build up the CMD field */
|
||||
ns->cmd <<= 8;
|
||||
ns->cmd |= *data_ptr++;
|
||||
ns->cntr++;
|
||||
} else if (ns->cntr < 8) {
|
||||
/* build up the DATA field */
|
||||
ns->data_len <<= 8;
|
||||
ns->data_len |= *data_ptr++;
|
||||
ns->cntr++;
|
||||
|
||||
if (ns->cntr == 8) {
|
||||
/* now we have full command and data words */
|
||||
ns->cntr = 0;
|
||||
ns->buf_pos = 0;
|
||||
ns->buf_ptr[0] = 0;
|
||||
if (ns->cmd == NETIO_CMD_C2S) {
|
||||
ns->state = NETIO_STATE_RECV_DATA;
|
||||
} else if (ns->cmd == NETIO_CMD_S2C) {
|
||||
ns->state = NETIO_STATE_SEND_DATA;
|
||||
/* start timer */
|
||||
ns->time_stamp = sys_now();
|
||||
/* send first round of data */
|
||||
|
||||
len = tcp_sndbuf(pcb);
|
||||
len = LWIP_MIN(len, ns->data_len - ns->cntr);
|
||||
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
|
||||
|
||||
do {
|
||||
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
|
||||
if (err == ERR_MEM) {
|
||||
len /= 2;
|
||||
}
|
||||
} while ((err == ERR_MEM) && (len > 1));
|
||||
|
||||
ns->buf_pos += len;
|
||||
ns->cntr += len;
|
||||
|
||||
} else {
|
||||
/* unrecognized command, punt */
|
||||
ns->cntr = 0;
|
||||
ns->buf_pos = 0;
|
||||
ns->buf_ptr[0] = 0;
|
||||
netio_close(ns, pcb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* in trouble... shouldn't be in this state! */
|
||||
}
|
||||
|
||||
} else if (ns->state == NETIO_STATE_RECV_DATA) {
|
||||
|
||||
if(ns->cntr == 0){
|
||||
/* save the first byte of this new round of data
|
||||
* this will not match ns->buf_ptr[0] in the case that
|
||||
* NETIO_BUF_SIZE is less than ns->data_len.
|
||||
*/
|
||||
ns->first_byte = *data_ptr;
|
||||
}
|
||||
|
||||
ns->buf_ptr[ns->buf_pos++] = *data_ptr++;
|
||||
ns->cntr++;
|
||||
|
||||
if (ns->buf_pos == NETIO_BUF_SIZE) {
|
||||
/* circularize the buffer */
|
||||
ns->buf_pos = 0;
|
||||
}
|
||||
|
||||
if(ns->cntr == ns->data_len){
|
||||
ns->cntr = 0;
|
||||
if (ns->first_byte != 0) {
|
||||
/* if this last round did not start with 0,
|
||||
* go look for another command */
|
||||
ns->state = NETIO_STATE_WAIT_FOR_CMD;
|
||||
ns->data_len = 0;
|
||||
ns->cmd = 0;
|
||||
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
|
||||
} else {
|
||||
/* stay here and wait on more data */
|
||||
}
|
||||
}
|
||||
|
||||
} else if (ns->state == NETIO_STATE_SEND_DATA
|
||||
|| ns->state == NETIO_STATE_SEND_DATA_LAST) {
|
||||
/* I don't think this should happen... */
|
||||
} else {
|
||||
/* done / quit */
|
||||
netio_close(ns, pcb);
|
||||
break;
|
||||
} /* end of ns->state condition */
|
||||
} /* end of while data still in this pbuf */
|
||||
|
||||
q = q->next;
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
|
||||
} else {
|
||||
|
||||
/* error or closed by other side */
|
||||
if (p != NULL) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
/* close the connection */
|
||||
netio_close(ns, pcb);
|
||||
|
||||
}
|
||||
return ERR_OK;
|
||||
|
||||
}
|
||||
|
||||
static err_t ICACHE_FLASH_ATTR
|
||||
netio_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
|
||||
{
|
||||
struct netio_state *ns = arg;
|
||||
err_t err = ERR_OK;
|
||||
|
||||
if (ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA) {
|
||||
/* done with this round of sending */
|
||||
ns->buf_pos = 0;
|
||||
ns->cntr = 0;
|
||||
|
||||
/* check if timer expired */
|
||||
if (sys_now() - ns->time_stamp > 600) {
|
||||
ns->buf_ptr[0] = 1;
|
||||
ns->state = NETIO_STATE_SEND_DATA_LAST;
|
||||
} else {
|
||||
ns->buf_ptr[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(ns->state == NETIO_STATE_SEND_DATA_LAST || ns->state == NETIO_STATE_SEND_DATA){
|
||||
len = tcp_sndbuf(pcb);
|
||||
len = LWIP_MIN(len, ns->data_len - ns->cntr);
|
||||
len = LWIP_MIN(len, NETIO_BUF_SIZE - ns->buf_pos);
|
||||
|
||||
if(ns->cntr < ns->data_len){
|
||||
do {
|
||||
err = tcp_write(pcb, ns->buf_ptr + ns->buf_pos, len, TCP_WRITE_FLAG_COPY);
|
||||
if (err == ERR_MEM) {
|
||||
len /= 2;
|
||||
}
|
||||
} while ((err == ERR_MEM) && (len > 1));
|
||||
|
||||
ns->buf_pos += len;
|
||||
if(ns->buf_pos >= NETIO_BUF_SIZE){
|
||||
ns->buf_pos = 0;
|
||||
}
|
||||
|
||||
ns->cntr += len;
|
||||
}
|
||||
}
|
||||
|
||||
if(ns->cntr >= ns->data_len && ns->state == NETIO_STATE_SEND_DATA_LAST){
|
||||
/* we have buffered up all our data to send this last round, go look for a command */
|
||||
ns->state = NETIO_STATE_WAIT_FOR_CMD;
|
||||
ns->cntr = 0;
|
||||
/* TODO LWIP_DEBUGF( print out some throughput calculation results... ); */
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static err_t ICACHE_FLASH_ATTR
|
||||
netio_poll(void *arg, struct tcp_pcb *pcb)
|
||||
{
|
||||
struct netio_state * ns = arg;
|
||||
if(ns->state == NETIO_STATE_SEND_DATA){
|
||||
|
||||
} else if(ns->state == NETIO_STATE_DONE){
|
||||
netio_close(ns, pcb);
|
||||
}
|
||||
|
||||
return ERR_OK;
|
||||
|
||||
}
|
||||
|
||||
#if NETIO_USE_STATIC_BUF == 1
|
||||
static u8_t netio_buf[NETIO_BUF_SIZE];
|
||||
#endif
|
||||
|
||||
static err_t ICACHE_FLASH_ATTR
|
||||
netio_accept(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||
{
|
||||
struct netio_state * ns;
|
||||
|
||||
LWIP_UNUSED_ARG(err);
|
||||
|
||||
ns = (struct netio_state *)mem_malloc(sizeof(struct netio_state));
|
||||
|
||||
if(ns == NULL){
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
ns->state = NETIO_STATE_WAIT_FOR_CMD;
|
||||
ns->data_len = 0;
|
||||
ns->cmd = 0;
|
||||
ns->cntr = 0;
|
||||
ns->buf_pos = 0;
|
||||
#if NETIO_USE_STATIC_BUF == 1
|
||||
ns->buf_ptr = netio_buf;
|
||||
#else
|
||||
ns->buf_ptr = (u8_t *)mem_malloc(NETIO_BUF_SIZE);
|
||||
|
||||
if(ns->buf_ptr == NULL){
|
||||
mem_free(ns);
|
||||
return ERR_MEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
ns->buf_ptr[0] = 0;
|
||||
|
||||
tcp_arg(pcb, ns);
|
||||
tcp_sent(pcb, netio_sent);
|
||||
tcp_recv(pcb, netio_recv);
|
||||
tcp_poll(pcb, netio_poll, 4); /* every 2 seconds */
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR netio_init(void)
|
||||
{
|
||||
struct tcp_pcb *pcb;
|
||||
|
||||
pcb = tcp_new();
|
||||
tcp_bind(pcb, IP_ADDR_ANY, 18767);
|
||||
pcb = tcp_listen(pcb);
|
||||
tcp_accept(pcb, netio_accept);
|
||||
}
|
||||
|
||||
#endif /* LWIP_TCP */
|
329
tools/sdk/lwip/src/app/ping.c
Normal file
329
tools/sdk/lwip/src/app/ping.c
Normal file
@ -0,0 +1,329 @@
|
||||
/**
|
||||
* @file
|
||||
* Ping sender module
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is an example of a "ping" sender (with raw API and socket API).
|
||||
* It can be used as a start point to maintain opened a network connection, or
|
||||
* like a network "watchdog" for your device.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* copyright (c) 2010 - 2011 Espressif System
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/raw.h"
|
||||
#include "lwip/icmp.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/timers.h"
|
||||
#include "lwip/inet_chksum.h"
|
||||
#include "os_type.h"
|
||||
#include "osapi.h"
|
||||
|
||||
#include "lwip/app/ping.h"
|
||||
|
||||
#if PING_USE_SOCKETS
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/inet.h"
|
||||
#endif /* PING_USE_SOCKETS */
|
||||
|
||||
#ifdef MEMLEAK_DEBUG
|
||||
static const char mem_debug_file[] ICACHE_RODATA_ATTR = __FILE__;
|
||||
#endif
|
||||
|
||||
/* ping variables */
|
||||
static u16_t ping_seq_num = 0;
|
||||
static u32_t ping_time;
|
||||
|
||||
static void ICACHE_FLASH_ATTR ping_timeout(void* arg)
|
||||
{
|
||||
struct ping_msg *pingmsg = (struct ping_msg *)arg;
|
||||
pingmsg->timeout_count ++;
|
||||
if (pingmsg->ping_opt->recv_function == NULL){
|
||||
os_printf("ping timeout\n");
|
||||
} else {
|
||||
struct ping_resp pingresp;
|
||||
os_bzero(&pingresp, sizeof(struct ping_resp));
|
||||
pingresp.ping_err = -1;
|
||||
pingmsg->ping_opt->recv_function(pingmsg->ping_opt, (void*)&pingresp);
|
||||
}
|
||||
}
|
||||
|
||||
/** Prepare a echo ICMP request */
|
||||
static void ICACHE_FLASH_ATTR
|
||||
ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
|
||||
{
|
||||
size_t i = 0;
|
||||
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;
|
||||
++ ping_seq_num;
|
||||
if (ping_seq_num == 0x7fff)
|
||||
ping_seq_num = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
iecho->chksum = inet_chksum(iecho, len);
|
||||
}
|
||||
/*
|
||||
static void ICACHE_FLASH_ATTR
|
||||
ping_prepare_er(struct icmp_echo_hdr *iecho, u16_t len)
|
||||
{
|
||||
|
||||
ICMPH_TYPE_SET(iecho, ICMP_ER);
|
||||
ICMPH_CODE_SET(iecho, 0);
|
||||
iecho->chksum = 0;
|
||||
|
||||
iecho->chksum = inet_chksum(iecho, len);
|
||||
}
|
||||
*/
|
||||
/* Ping using the raw ip */
|
||||
static u8_t ICACHE_FLASH_ATTR
|
||||
ping_recv(void *arg, struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *addr)
|
||||
{
|
||||
struct icmp_echo_hdr *iecho = NULL;
|
||||
static u16_t seqno = 0;
|
||||
struct ping_msg *pingmsg = (struct ping_msg*)arg;
|
||||
|
||||
LWIP_UNUSED_ARG(arg);
|
||||
LWIP_UNUSED_ARG(pcb);
|
||||
LWIP_UNUSED_ARG(addr);
|
||||
LWIP_ASSERT("p != NULL", p != NULL);
|
||||
|
||||
if (pbuf_header( p, -PBUF_IP_HLEN)==0) {
|
||||
iecho = (struct icmp_echo_hdr *)p->payload;
|
||||
|
||||
if ((iecho->id == PING_ID) && (iecho->seqno == htons(ping_seq_num)) && iecho->type == ICMP_ER) {
|
||||
LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
|
||||
ip_addr_debug_print(PING_DEBUG, addr);
|
||||
LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now()-ping_time)));
|
||||
if (iecho->seqno != seqno){
|
||||
/* do some ping result processing */
|
||||
{
|
||||
struct ip_hdr *iphdr = NULL;
|
||||
char ipaddrstr[16];
|
||||
ip_addr_t source_ip;
|
||||
sys_untimeout(ping_timeout, pingmsg);
|
||||
os_bzero(&source_ip, sizeof(ip_addr_t));
|
||||
os_bzero(ipaddrstr, sizeof(ipaddrstr));
|
||||
uint32 delay = system_relative_time(pingmsg->ping_sent);
|
||||
delay /= PING_COARSE;
|
||||
iphdr = (struct ip_hdr*)((u8*)iecho - PBUF_IP_HLEN);
|
||||
source_ip.addr = iphdr->src.addr;
|
||||
ipaddr_ntoa_r(&source_ip,ipaddrstr, sizeof(ipaddrstr));
|
||||
if (pingmsg->ping_opt->recv_function == NULL){
|
||||
os_printf("recv %s: byte = %d, time = %d ms, seq = %d\n",ipaddrstr, PING_DATA_SIZE, delay, ntohs(iecho->seqno));
|
||||
} else {
|
||||
struct ping_resp pingresp;
|
||||
os_bzero(&pingresp, sizeof(struct ping_resp));
|
||||
pingresp.bytes = PING_DATA_SIZE;
|
||||
pingresp.resp_time = delay;
|
||||
pingresp.seqno = ntohs(iecho->seqno);
|
||||
pingresp.ping_err = 0;
|
||||
pingmsg->ping_opt->recv_function(pingmsg->ping_opt,(void*) &pingresp);
|
||||
}
|
||||
}
|
||||
seqno = iecho->seqno;
|
||||
}
|
||||
|
||||
PING_RESULT(1);
|
||||
pbuf_free(p);
|
||||
return 1; /* eat the packet */
|
||||
}
|
||||
// } else if(iecho->type == ICMP_ECHO){
|
||||
// struct pbuf *q = NULL;
|
||||
// os_printf("receive ping request:seq=%d\n", ntohs(iecho->seqno));
|
||||
// q = pbuf_alloc(PBUF_IP, (u16_t)p->tot_len, PBUF_RAM);
|
||||
// if (q!=NULL) {
|
||||
// pbuf_copy(q, p);
|
||||
// iecho = (struct icmp_echo_hdr *)q->payload;
|
||||
// ping_prepare_er(iecho, q->tot_len);
|
||||
// raw_sendto(pcb, q, addr);
|
||||
// pbuf_free(q);
|
||||
// }
|
||||
// pbuf_free(p);
|
||||
// return 1;
|
||||
// }
|
||||
}
|
||||
|
||||
return 0; /* don't eat the packet */
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
ping_send(struct raw_pcb *raw, ip_addr_t *addr)
|
||||
{
|
||||
struct pbuf *p = NULL;
|
||||
struct icmp_echo_hdr *iecho = NULL;
|
||||
size_t ping_size = sizeof(struct icmp_echo_hdr) + PING_DATA_SIZE;
|
||||
|
||||
LWIP_DEBUGF( PING_DEBUG, ("ping: send "));
|
||||
ip_addr_debug_print(PING_DEBUG, addr);
|
||||
LWIP_DEBUGF( PING_DEBUG, ("\n"));
|
||||
LWIP_ASSERT("ping_size <= 0xffff", ping_size <= 0xffff);
|
||||
|
||||
p = pbuf_alloc(PBUF_IP, (u16_t)ping_size, PBUF_RAM);
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
if ((p->len == p->tot_len) && (p->next == NULL)) {
|
||||
iecho = (struct icmp_echo_hdr *)p->payload;
|
||||
|
||||
ping_prepare_echo(iecho, (u16_t)ping_size);
|
||||
|
||||
raw_sendto(raw, p, addr);
|
||||
ping_time = sys_now();
|
||||
}
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
static void ICACHE_FLASH_ATTR
|
||||
ping_coarse_tmr(void *arg)
|
||||
{
|
||||
struct ping_msg *pingmsg = (struct ping_msg*)arg;
|
||||
struct ping_option *ping_opt= NULL;
|
||||
struct ping_resp pingresp;
|
||||
ip_addr_t ping_target;
|
||||
|
||||
LWIP_ASSERT("ping_timeout: no pcb given!", pingmsg != NULL);
|
||||
ping_target.addr = pingmsg->ping_opt->ip;
|
||||
ping_opt = pingmsg->ping_opt;
|
||||
if (--pingmsg->sent_count != 0){
|
||||
pingmsg ->ping_sent = system_get_time();
|
||||
ping_send(pingmsg->ping_pcb, &ping_target);
|
||||
|
||||
sys_timeout(PING_TIMEOUT_MS, ping_timeout, pingmsg);
|
||||
sys_timeout(pingmsg->coarse_time, ping_coarse_tmr, pingmsg);
|
||||
} else {
|
||||
uint32 delay = system_relative_time(pingmsg->ping_start);
|
||||
delay /= PING_COARSE;
|
||||
// ping_seq_num = 0;
|
||||
if (ping_opt->sent_function == NULL){
|
||||
os_printf("ping %d, timeout %d, total payload %d bytes, %d ms\n",
|
||||
pingmsg->max_count, pingmsg->timeout_count, PING_DATA_SIZE*(pingmsg->max_count - pingmsg->timeout_count),delay);
|
||||
} else {
|
||||
os_bzero(&pingresp, sizeof(struct ping_resp));
|
||||
pingresp.total_count = pingmsg->max_count;
|
||||
pingresp.timeout_count = pingmsg->timeout_count;
|
||||
pingresp.total_bytes = PING_DATA_SIZE*(pingmsg->max_count - pingmsg->timeout_count);
|
||||
pingresp.total_time = delay;
|
||||
pingresp.ping_err = 0;
|
||||
}
|
||||
sys_untimeout(ping_coarse_tmr, pingmsg);
|
||||
raw_remove(pingmsg->ping_pcb);
|
||||
os_free(pingmsg);
|
||||
if (ping_opt->sent_function != NULL)
|
||||
ping_opt->sent_function(ping_opt,(uint8*)&pingresp);
|
||||
}
|
||||
}
|
||||
|
||||
static bool ICACHE_FLASH_ATTR
|
||||
ping_raw_init(struct ping_msg *pingmsg)
|
||||
{
|
||||
if (pingmsg == NULL)
|
||||
return false;
|
||||
|
||||
ip_addr_t ping_target;
|
||||
pingmsg->ping_pcb = raw_new(IP_PROTO_ICMP);
|
||||
LWIP_ASSERT("ping_pcb != NULL", pingmsg->ping_pcb != NULL);
|
||||
|
||||
raw_recv(pingmsg->ping_pcb, ping_recv, pingmsg);
|
||||
raw_bind(pingmsg->ping_pcb, IP_ADDR_ANY);
|
||||
|
||||
ping_target.addr = pingmsg->ping_opt->ip;
|
||||
pingmsg ->ping_sent = system_get_time();
|
||||
ping_send(pingmsg->ping_pcb, &ping_target);
|
||||
|
||||
sys_timeout(PING_TIMEOUT_MS, ping_timeout, pingmsg);
|
||||
sys_timeout(pingmsg->coarse_time, ping_coarse_tmr, pingmsg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
ping_start(struct ping_option *ping_opt)
|
||||
{
|
||||
struct ping_msg *pingmsg = NULL;
|
||||
pingmsg = (struct ping_msg *)os_zalloc(sizeof(struct ping_msg));
|
||||
if (pingmsg == NULL || ping_opt == NULL)
|
||||
return false;
|
||||
|
||||
pingmsg->ping_opt = ping_opt;
|
||||
if (ping_opt->count != 0)
|
||||
pingmsg->max_count = ping_opt->count;
|
||||
else
|
||||
pingmsg->max_count = DEFAULT_PING_MAX_COUNT;
|
||||
|
||||
if (ping_opt->coarse_time != 0)
|
||||
pingmsg->coarse_time = ping_opt->coarse_time * PING_COARSE;
|
||||
else
|
||||
pingmsg->coarse_time = PING_COARSE;
|
||||
|
||||
pingmsg->ping_start = system_get_time();
|
||||
pingmsg->sent_count = pingmsg->max_count;
|
||||
return ping_raw_init(pingmsg);
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
ping_regist_recv(struct ping_option *ping_opt, ping_recv_function ping_recv)
|
||||
{
|
||||
if (ping_opt == NULL)
|
||||
return false;
|
||||
|
||||
ping_opt ->recv_function = ping_recv;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
ping_regist_sent(struct ping_option *ping_opt, ping_sent_function ping_sent)
|
||||
{
|
||||
if (ping_opt == NULL)
|
||||
return false;
|
||||
|
||||
ping_opt ->sent_function = ping_sent;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* LWIP_RAW */
|
Reference in New Issue
Block a user