本文整理汇总了C++中pbuf_chain函数的典型用法代码示例。如果您正苦于以下问题:C++ pbuf_chain函数的具体用法?C++ pbuf_chain怎么用?C++ pbuf_chain使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了pbuf_chain函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: client_recv
// on data received
err_t client_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
struct client *c = arg;
if (err!=ERR_OK) {
pbuf_free(p);
return client_kill(c);
}
// no buffer
if (!p) {
c->st = TERMINATED;
// and no queued data -> close
if (!c->p)
return client_kill(c);
return flushq(c);
}
switch (c->st) {
case ACCEPTED: {
c->st++;
}
case RECEIVED: {
// this is a hack - we assume each line fits into a single packet
// this could be done properly using pbuf header magic and keeping line state
u8_t *dst = p->payload;
u8_t *res = memchr(dst, '\n', p->len);
// invalid data or exit requested
if (!res || !memcmp(dst,"exit",4)) {
pbuf_free(p);
return client_kill(c);
}
// reverse the line
if (res[-1] == '\r') res--;
u32_t len = res-dst;
for (int i = 0; i < (len)/2;i++) {
u8_t t = dst[i];
dst[i] = dst[len-i-1];
dst[len-i-1] = t;
}
dst[len] = '\n';
pbuf_realloc(p, len+1);
// and enqueue it
if (c->p) {
pbuf_chain(c->p, p);
return ERR_OK;
}
c->p = p;
return flushq(c);
}
// unknown state
default: {
tcp_recved(pcb, p->tot_len);
c->p = NULL; // XXX leaky?
pbuf_free(p);
}
}
return ERR_OK;
}
示例2: recv_data
// This works for both UDP and TCP.
static err_t recv_data(int s, struct pbuf * p) {
sockfd_t * fd;
// Get our socket.
if (sock_verify(s) < 0)
return ERR_CONN;
fd = fds + s;
// Get access.
mutex_lock(fd->mutex);
// Do we already have some data chained up in pbufs?
if (fd->recv_buf) {
pbuf_chain(fd->recv_buf, p);
pbuf_free(p);
} else
fd->recv_buf = p;
// Set a new receive count
fd->recv = fd->recv_buf->tot_len;
// Here would be the place we'd want to implement TCP_NODELAY (or the lack
// thereof) but for now we'll just send it all through...
cond_signal(fd->recv_avail);
// Note that we DON'T ACK the data until after a client has received
// it using recv(). Otherwise the peer could send and send and send...
mutex_unlock(fd->mutex);
genwait_wake_all(&select_wait);
return ERR_OK;
}
示例3: netbuf_chain
void
netbuf_chain(struct netbuf *head, struct netbuf *tail)
{
pbuf_chain(head->p, tail->p);
head->ptr = head->p;
memp_free(MEMP_NETBUF, tail);
}
示例4: raw_send_to
/**
* Send the raw IP packet to the given address. Note that actually you cannot
* modify the IP headers (this is inconsitent with the receive callback where
* you actually get the IP headers), you can only specifiy the ip payload here.
* It requires some more changes in LWIP. (there will be a raw_send() function
* then)
*
* @param pcb the raw pcb which to send
* @param p the ip payload to send
* @param ipaddr the destination address of the whole IP packet
*
*/
err_t
raw_send_to(struct raw_pcb *pcb, struct pbuf *p, struct ip_addr *ipaddr)
{
err_t err;
struct netif *netif;
struct ip_addr *src_ip;
struct pbuf *q; /* q will be sent down the stack */
LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 3, ("raw_send_to\n"));
/* not enough space to add an IP header to first pbuf in given p chain? */
if (pbuf_header(p, IP_HLEN)) {
/* allocate header in new pbuf */
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(RAW_DEBUG | DBG_TRACE | 2, ("raw_send_to: could not allocate header\n"));
return ERR_MEM;
}
/* chain header q in front of given pbuf p */
pbuf_chain(q, p);
/* { first pbuf q points to header pbuf } */
LWIP_DEBUGF(RAW_DEBUG, ("raw_send_to: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
} else {
/* first pbuf q equals given pbuf */
q = p;
pbuf_header(q, -IP_HLEN);
}
if ((netif = ip_route(ipaddr)) == NULL) {
LWIP_DEBUGF(RAW_DEBUG | 1, ("raw_send_to: No route to 0x%lx\n", ipaddr->addr));
#if RAW_STATS
/* ++lwip_stats.raw.rterr;*/
#endif /* RAW_STATS */
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
if (ip_addr_isany(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = &(netif->ip_addr);
} else {
/* use RAW PCB local IP address as source address */
src_ip = &(pcb->local_ip);
}
err = ip_output_if (q, src_ip, ipaddr, pcb->ttl, pcb->tos, pcb->protocol, netif);
/* did we chain a header earlier? */
if (q != p) {
/* free the header */
pbuf_free(q);
}
return err;
}
示例5: l2cap_input
void
l2cap_input(struct pbuf *p, struct bd_addr *bdaddr)
{
struct l2cap_seg *inseg;
struct hci_acl_hdr *aclhdr;
struct pbuf *data;
err_t ret;
pbuf_header(p, HCI_ACL_HDR_LEN);
aclhdr = p->payload;
pbuf_header(p, -HCI_ACL_HDR_LEN);
pbuf_realloc(p, aclhdr->len);
for(inseg = l2cap_insegs; inseg != NULL; inseg = inseg->next) {
if(bd_addr_cmp(bdaddr, &(inseg->bdaddr))) {
break;
}
}
/* Reassembly procedures */
/* Check if continuing fragment or start of L2CAP packet */
if(((aclhdr->conhdl_pb_bc >> 12) & 0x03)== L2CAP_ACL_CONT) { /* Continuing fragment */
if(inseg == NULL) {
/* Discard packet */
LWIP_DEBUGF(L2CAP_DEBUG, ("l2cap_input: Continuing fragment. Discard packet\n"));
pbuf_free(p);
return;
} else if(inseg->p->tot_len + p->tot_len > inseg->len) { /* Check if length of
segment exceeds
l2cap header length */
/* Discard packet */
LWIP_DEBUGF(L2CAP_DEBUG, ("l2cap_input: Continuing fragment. Length exceeds L2CAP hdr length. Discard packet\n"));
pbuf_free(inseg->p);
L2CAP_SEG_RMV(&(l2cap_insegs), inseg);
lwbt_memp_free(MEMP_L2CAP_SEG, inseg);
pbuf_free(p);
return;
}
/* Add pbuf to segement */
pbuf_chain(inseg->p, p);
pbuf_free(p);
} else if(((aclhdr->conhdl_pb_bc >> 12) & 0x03) == L2CAP_ACL_START) { /* Start of L2CAP packet */
示例6: _tcp_flush
void _tcp_flush(void *v) {
TCP *es=v;
if(es->pcb->snd_queuelen > TCP_SND_QUEUELEN-1) // !!!! pred vpisom preveri, ce ni queue ze poln
tcp_output(es->pcb); // kratkih blokov (Nagle algoritem bo javil MEM error....)
else if(es->io) { // sicer nadaljevanje...
char c[256];
int k,n=0;
if(es->rx) { // a je kaj za sprejem ???
struct pbuf *q;
for(q=es->rx; q != NULL; q=es->rx) { // preskanirat je treba celo verigo pbuf
n+=k=_buffer_push(es->io[0],q->payload, q->len); // push v io
if(k < q->len) {
pbuf_header(q,-k); // skrajsaj header
break;
}
es->rx = es->rx->next;
if (es->rx != NULL)
pbuf_ref(es->rx);
pbuf_free(q);
}
tcp_recved(es->pcb,n); // free raw input
}
n=_buffer_count(es->io[1]); // koliko je v buferju za izpis ...
if(n > tcp_sndbuf(es->pcb)) // ne sme biti vec kot je placa na raw output ....
n = tcp_sndbuf(es->pcb);
if(n > 256) // ne sme bit vec kot 1024.... glej c[1024]
n=256;
if(n) { // ce je sploh kej ...
struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, n , PBUF_POOL);
if(p != NULL) { // ce je alokacija pbuf uspela
n=_buffer_pull(es->io[1],c,n); // kopiraj pull vsebino v vmesni buffer
pbuf_take(p,c,n); // formiraj pbuf
if(es->tx) // verizi, ce je se kaj od prej..
pbuf_chain(es->tx,p); //
else
es->tx = p; // sicer nastavi nov pointer
tcp_sent(es->pcb, TCP_sent); // set callback & send..
TCP_send(es->pcb, es);
tcp_output(es->pcb);
}
}
}
}
示例7: TCP_recv
/**
* @brief This function is the implementation for tcp_recv LwIP callback
* @param arg: pointer on a argument for the tcp_pcb connection
* @param tpcb: pointer on the tcp_pcb connection
* @param pbuf: pointer on the received pbuf
* @param err: error information regarding the reveived pbuf
* @retval err_t: error code
*/
static err_t
TCP_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
err_t ret_err;
TCP *es;
LWIP_ASSERT("arg != NULL",arg != NULL);
es = (TCP *)arg;
if (p == NULL) { /* if we receive an empty tcp frame from client => close connection */
es->state = ES_CLOSING; /* remote host closed connection */
if (es->tx == NULL) {
TCP_close(tpcb, es); /* we're done sending, close connection */
} else { /* we're not done yet */
tcp_sent(tpcb, TCP_sent); /* send remaining data*/
TCP_send(tpcb, es); /* acknowledge received packet */
}
ret_err = ERR_OK;
} else if(err != ERR_OK) { /* else : a non empty frame was received from client but for some reason err != ERR_OK */
if (p != NULL) {
es->tx = NULL;
pbuf_free(p); /* free received pbuf*/
}
ret_err = err;
} else if(es->state == ES_ACCEPTED) { /* first data chunk in p->payload */
es->state = ES_RECEIVED;
es->rx = p; /* store reference to incoming pbuf (chain) */
ret_err = ERR_OK;
} else if (es->state == ES_RECEIVED) {
if (es->rx)
pbuf_chain(es->rx,p);
else
es->rx = p;
ret_err = ERR_OK;
} else { /* data received when connection already closed */
tcp_recved(tpcb, p->tot_len); /* Acknowledge data reception */
es->tx = NULL;
pbuf_free(p); /* free pbuf and do nothing */
ret_err = ERR_OK;
}
return ret_err;
}
示例8: mg_lwip_tcp_recv_cb
static err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err) {
struct mg_connection *nc = (struct mg_connection *) arg;
DBG(("%p %p %u %d", nc, tpcb, (p != NULL ? p->tot_len : 0), err));
if (p == NULL) {
if (nc != NULL) {
system_os_post(MG_TASK_PRIORITY, MG_SIG_CLOSE_CONN, (uint32_t) nc);
} else {
/* Tombstoned connection, do nothing. */
}
return ERR_OK;
} else if (nc == NULL) {
tcp_abort(tpcb);
return ERR_ARG;
}
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
/*
* If we get a chain of more than one segment at once, we need to bump
* refcount on the subsequent bufs to make them independent.
*/
if (p->next != NULL) {
struct pbuf *q = p->next;
for (; q != NULL; q = q->next) pbuf_ref(q);
}
if (cs->rx_chain == NULL) {
cs->rx_chain = p;
cs->rx_offset = 0;
} else {
pbuf_chain(cs->rx_chain, p);
}
#ifdef SSL_KRYPTON
if (nc->ssl != NULL) {
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
mg_lwip_ssl_recv(nc);
} else {
mg_lwip_ssl_do_hs(nc);
}
return ERR_OK;
}
#endif
while (cs->rx_chain != NULL) {
struct pbuf *seg = cs->rx_chain;
size_t len = (seg->len - cs->rx_offset);
char *data = (char *) malloc(len);
if (data == NULL) {
DBG(("OOM"));
return ERR_MEM;
}
pbuf_copy_partial(seg, data, len, cs->rx_offset);
mg_if_recv_tcp_cb(nc, data, len); /* callee takes over data */
cs->rx_offset += len;
if (cs->rx_offset == cs->rx_chain->len) {
cs->rx_chain = pbuf_dechain(cs->rx_chain);
pbuf_free(seg);
cs->rx_offset = 0;
}
}
if (nc->send_mbuf.len > 0) {
mg_lwip_mgr_schedule_poll(nc->mgr);
}
return ERR_OK;
}
示例9: echo_recv
err_t
echo_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
struct echo_state *es;
err_t ret_err;
LWIP_ASSERT("arg != NULL",arg != NULL);
es = arg;
if (p == NULL)
{
/* remote host closed connection */
es->state = ES_CLOSING;
if(es->p == NULL)
{
/* we're done sending, close it */
echo_close(tpcb, es);
}
else
{
/* we're not done yet */
tcp_sent(tpcb, echo_sent);
echo_send(tpcb, es);
}
ret_err = ERR_OK;
}
else if(err != ERR_OK)
{
/* cleanup, for unkown reason */
if (p != NULL)
{
es->p = NULL;
pbuf_free(p);
}
ret_err = err;
}
else if(es->state == ES_ACCEPTED)
{
/* first data chunk in p->payload */
es->state = ES_RECEIVED;
/* store reference to incoming pbuf (chain) */
es->p = p;
/* install send completion notifier */
tcp_sent(tpcb, echo_sent);
echo_send(tpcb, es);
ret_err = ERR_OK;
}
else if (es->state == ES_RECEIVED)
{
/* read some more data */
if(es->p == NULL)
{
es->p = p;
tcp_sent(tpcb, echo_sent);
echo_send(tpcb, es);
}
else
{
struct pbuf *ptr;
/* chain pbufs to the end of what we recv'ed previously */
ptr = es->p;
pbuf_chain(ptr,p);
}
ret_err = ERR_OK;
}
else if(es->state == ES_CLOSING)
{
/* odd case, remote side closing twice, trash data */
tcp_recved(tpcb, p->tot_len);
es->p = NULL;
pbuf_free(p);
ret_err = ERR_OK;
}
else
{
/* unkown es->state, trash data */
tcp_recved(tpcb, p->tot_len);
es->p = NULL;
pbuf_free(p);
ret_err = ERR_OK;
}
return ret_err;
}
示例10: raw_sendto
/**
* Send the raw IP packet to the given address. Note that actually you cannot
* modify the IP headers (this is inconsistent with the receive callback where
* you actually get the IP headers), you can only specify the IP payload here.
* It requires some more changes in lwIP. (there will be a raw_send() function
* then.)
*
* @param pcb the raw pcb which to send
* @param p the IP payload to send
* @param ipaddr the destination address of the IP packet
*
*/
err_t ICACHE_FLASH_ATTR
raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
{
err_t err;
struct netif *netif;
ipX_addr_t *src_ip;
struct pbuf *q; /* q will be sent down the stack */
s16_t header_size;
ipX_addr_t *dst_ip = ip_2_ipX(ipaddr);
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
header_size = (
#if LWIP_IPV6
PCB_ISIPV6(pcb) ? IP6_HLEN :
#endif /* LWIP_IPV6 */
IP_HLEN);
/* not enough space to add an IP header to first pbuf in given p chain? */
if (pbuf_header(p, header_size)) {
/* allocate header in new pbuf */
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
return ERR_MEM;
}
if (p->tot_len != 0) {
/* chain header q in front of given pbuf p */
pbuf_chain(q, p);
}
/* { first pbuf q points to header pbuf } */
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
} else {
/* first pbuf q equals given pbuf */
q = p;
if(pbuf_header(q, -header_size)) {
LWIP_ASSERT("Can't restore header we just removed!", 0);
return ERR_MEM;
}
}
netif = ipX_route(PCB_ISIPV6(pcb), &pcb->local_ip, dst_ip);
if (netif == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
ipX_addr_debug_print(PCB_ISIPV6(pcb), RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, dst_ip);
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
#if IP_SOF_BROADCAST
#if LWIP_IPV6
/* @todo: why does IPv6 not filter broadcast with SOF_BROADCAST enabled? */
if (!PCB_ISIPV6(pcb))
#endif /* LWIP_IPV6 */
{
/* broadcast filter? */
if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_VAL;
}
}
#endif /* IP_SOF_BROADCAST */
if (ipX_addr_isany(PCB_ISIPV6(pcb), &pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = ipX_netif_get_local_ipX(PCB_ISIPV6(pcb), netif, dst_ip);
#if LWIP_IPV6
if (src_ip == NULL) {
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
#endif /* LWIP_IPV6 */
} else {
/* use RAW PCB local IP address as source address */
src_ip = &pcb->local_ip;
}
NETIF_SET_HWADDRHINT(netif, &pcb->addr_hint);
//.........这里部分代码省略.........
示例11: tcp_echoserver_recv
/**
* @brief This function is the implementation for tcp_recv LwIP callback
* @param arg: pointer on a argument for the tcp_pcb connection
* @param tpcb: pointer on the tcp_pcb connection
* @param pbuf: pointer on the received pbuf
* @param err: error information regarding the reveived pbuf
* @retval err_t: error code
*/
static err_t tcp_echoserver_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
struct tcp_echoserver_struct *es;
err_t ret_err;
LWIP_ASSERT("arg != NULL",arg != NULL);
es = (struct tcp_echoserver_struct *)arg;
/* if we receive an empty tcp frame from client => close connection */
if (p == NULL)
{
/* remote host closed connection */
es->state = ES_CLOSING;
if(es->p == NULL)
{
/* we're done sending, close connection */
tcp_echoserver_connection_close(tpcb, es);
}
else
{
/* we're not done yet */
/* acknowledge received packet */
tcp_sent(tpcb, tcp_echoserver_sent);
/* send remaining data*/
tcp_echoserver_send(tpcb, es);
}
ret_err = ERR_OK;
}
/* else : a non empty frame was received from client but for some reason err != ERR_OK */
else if(err != ERR_OK)
{
/* free received pbuf*/
es->p = NULL;
pbuf_free(p);
ret_err = err;
}
else if(es->state == ES_ACCEPTED)
{
/* first data chunk in p->payload */
es->state = ES_RECEIVED;
/* store reference to incoming pbuf (chain) */
es->p = p;
/* initialize LwIP tcp_sent callback function */
tcp_sent(tpcb, tcp_echoserver_sent);
/* send back the received data (echo) */
tcp_echoserver_send(tpcb, es);
ret_err = ERR_OK;
}
else if (es->state == ES_RECEIVED)
{
/* more data received from client and previous data has been already sent*/
if(es->p == NULL)
{
es->p = p;
/* send back received data */
tcp_echoserver_send(tpcb, es);
}
else
{
struct pbuf *ptr;
/* chain pbufs to the end of what we recv'ed previously */
ptr = es->p;
pbuf_chain(ptr,p);
}
ret_err = ERR_OK;
}
/* data received when connection already closed */
else
{
/* Acknowledge data reception */
tcp_recved(tpcb, p->tot_len);
/* free pbuf and do nothing */
es->p = NULL;
pbuf_free(p);
ret_err = ERR_OK;
}
return ret_err;
}
示例12: CallbackOnRecieve
//------------------------------------------------------------------------------------------------------------------------------------------------------
err_t CallbackOnRecieve(void *_arg, struct tcp_pcb *_tpcb, struct pbuf *_p, err_t _err)
{
err_t ret_err;
LWIP_ASSERT("arg != NULL", _arg != NULL);
struct State *ss = (struct State*)_arg;
if (_p == NULL)
{
// remote host closed connection
ss->state = S_CLOSING;
if (ss->p == NULL)
{
// we're done sending, close it
CloseConnection(_tpcb, ss);
}
else
{
// we're not done yet
//tcp_sent(_tpcb, CallbackOnSent);
}
ret_err = ERR_OK;
}
else if (_err != ERR_OK)
{
// cleanup, for unkown reason
if (_p != NULL)
{
ss->p = NULL;
pbuf_free(_p);
}
ret_err = _err;
}
else if (ss->state == S_ACCEPTED)
{
if (ss->numPort == POLICY_PORT)
{
pbuf_free(_p);
ss->state = S_RECIEVED;
SendAnswer(ss, _tpcb);
ss->state = S_CLOSING;
ret_err = ERR_OK;
}
else
{
// first data chunk in _p->payload
ss->state = S_RECIEVED;
// store reference to incoming pbuf (chain)
ss->p = _p;
Send(_tpcb, ss);
ret_err = ERR_OK;
}
}
else if (ss->state == S_RECIEVED)
{
// read some more data
if (ss->p == NULL)
{
//ss->p = _p;
//tcp_sent(_tpcb, CallbackOnSent);
//Send(_tpcb, ss);
SocketFuncReciever((char*)_p->payload, _p->len);
u8_t freed = 0;
do
{
// try hard to free pbuf
freed = pbuf_free(_p);
} while (freed == 0);
}
else
{
struct pbuf *ptr;
// chain pbufs to the end of what we recv'ed previously
ptr = ss->p;
pbuf_chain(ptr, _p);
}
ret_err = ERR_OK;
}
else if (ss->state == S_CLOSING)
{
// odd case, remote side closing twice, trash data
tcp_recved(_tpcb, _p->tot_len);
ss->p = NULL;
pbuf_free(_p);
ret_err = ERR_OK;
}
else
{
// unknown ss->state, trash data
tcp_recved(_tpcb, _p->tot_len);
ss->p = NULL;
pbuf_free(_p);
ret_err = ERR_OK;
}
return ret_err;
}
示例13: recv_tcp
static err_t recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) {
struct socket *s = arg;
struct sockreq *req;
struct sockreq *next;
int bytes;
int waitrecv;
int bytesrecv = 0;
if (p) {
if (s->tcp.recvtail) {
pbuf_chain(s->tcp.recvtail, p);
s->tcp.recvtail = p;
} else {
s->tcp.recvhead = p;
s->tcp.recvtail = p;
}
} else {
s->state = SOCKSTATE_CLOSING;
set_io_event(&s->iob, IOEVT_CLOSE);
}
if (s->state == SOCKSTATE_CLOSING && s->tcp.recvhead == NULL) {
req = s->waithead;
while (req) {
next = req->next;
if (req->type == SOCKREQ_RECV || req->type == SOCKREQ_WAITRECV) release_socket_request(req, 0);
req = next;
}
return 0;
}
while (1) {
if (!s->tcp.recvhead) break;
req = s->waithead;
waitrecv = 0;
while (req) {
if (req->type == SOCKREQ_RECV) break;
if (req->type == SOCKREQ_WAITRECV) waitrecv++;
req = req->next;
}
if (!req) {
if (waitrecv) {
req = s->waithead;
while (req) {
next = req->next;
if (req->type == SOCKREQ_WAITRECV) release_socket_request(req, 0);
req = next;
}
}
break;
}
bytes = fetch_rcvbuf(s, req->msg->msg_iov, req->msg->msg_iovlen);
if (bytes > 0) {
bytesrecv += bytes;
req->rc += bytes;
release_socket_request(req, req->rc);
}
}
if (bytesrecv) tcp_recved(pcb, bytesrecv);
if (s->tcp.recvhead) {
set_io_event(&s->iob, IOEVT_READ);
} else {
clear_io_event(&s->iob, IOEVT_READ);
}
return 0;
}
示例14: raw_sendto
/**
* Send the raw IP packet to the given address. Note that actually you cannot
* modify the IP headers (this is inconsistent with the receive callback where
* you actually get the IP headers), you can only specify the IP payload here.
* It requires some more changes in lwIP. (there will be a raw_send() function
* then.)
*
* @param pcb the raw pcb which to send
* @param p the IP payload to send
* @param ipaddr the destination address of the IP packet
*
*/
err_t
raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr)
{
err_t err;
struct netif *netif;
const ip_addr_t *src_ip;
struct pbuf *q; /* q will be sent down the stack */
s16_t header_size;
const ip_addr_t *dst_ip = ipaddr;
if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) {
return ERR_VAL;
}
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n"));
header_size = (
#if LWIP_IPV4 && LWIP_IPV6
IP_IS_V6(ipaddr) ? IP6_HLEN : IP_HLEN);
#elif LWIP_IPV4
IP_HLEN);
#else
IP6_HLEN);
#endif
/* not enough space to add an IP header to first pbuf in given p chain? */
if (pbuf_header(p, header_size)) {
/* allocate header in new pbuf */
q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
return ERR_MEM;
}
if (p->tot_len != 0) {
/* chain header q in front of given pbuf p */
pbuf_chain(q, p);
}
/* { first pbuf q points to header pbuf } */
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
} else {
/* first pbuf q equals given pbuf */
q = p;
if (pbuf_header(q, -header_size)) {
LWIP_ASSERT("Can't restore header we just removed!", 0);
return ERR_MEM;
}
}
netif = ip_route(&pcb->local_ip, dst_ip);
if (netif == NULL) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to "));
ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, dst_ip);
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
#if IP_SOF_BROADCAST
if (IP_IS_V4(ipaddr))
{
/* broadcast filter? */
if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(ipaddr, netif)) {
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
/* free any temporary header pbuf allocated by pbuf_header() */
if (q != p) {
pbuf_free(q);
}
return ERR_VAL;
}
}
#endif /* IP_SOF_BROADCAST */
if (ip_addr_isany(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = ip_netif_get_local_ip(netif, dst_ip);
#if LWIP_IPV6
if (src_ip == NULL) {
if (q != p) {
pbuf_free(q);
}
return ERR_RTE;
}
#endif /* LWIP_IPV6 */
} else {
/* use RAW PCB local IP address as source address */
//.........这里部分代码省略.........
示例15: udp_sendto_if
/**
* Send data to a specified address using UDP.
* The netif used for sending can be specified.
*
* This function exists mainly for DHCP, to be able to send UDP packets
* on a netif that is still down.
*
* @param pcb UDP PCB used to send the data.
* @param p chain of pbuf's to be sent.
* @param dst_ip Destination IP address.
* @param dst_port Destination UDP port.
* @param netif the netif used for sending.
*
* dst_ip & dst_port are expected to be in the same byte order as in the pcb.
*
* @return lwIP error code (@see udp_send for possible error codes)
*
* @see udp_disconnect() udp_send()
*/
err_t
udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p,
struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif)
{
struct udp_hdr *udphdr;
struct ip_addr *src_ip;
err_t err;
struct pbuf *q; /* q will be sent down the stack */
#if IP_SOF_BROADCAST
/* broadcast filter? */
if ( ((pcb->so_options & SOF_BROADCAST) == 0) && ip_addr_isbroadcast(dst_ip, netif) ) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb));
return ERR_VAL;
}
#endif /* IP_SOF_BROADCAST */
/* if the PCB is not yet bound to a port, bind it here */
if (pcb->local_port == 0) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n"));
err = udp_bind(pcb, &pcb->local_ip, pcb->local_port);
if (err != ERR_OK) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n"));
return err;
}
}
/* not enough space to add an UDP header to first pbuf in given p chain? */
if (pbuf_header(p, UDP_HLEN)) {
/* allocate header in a separate new pbuf */
q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
return ERR_MEM;
}
/* chain header q in front of given pbuf p */
pbuf_chain(q, p);
/* first pbuf q points to header pbuf */
LWIP_DEBUGF(UDP_DEBUG,
("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
} else {
/* adding space for header within p succeeded */
/* first pbuf q equals given pbuf */
q = p;
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
}
LWIP_ASSERT("check that first pbuf can hold struct udp_hdr",
(q->len >= sizeof(struct udp_hdr)));
/* q now represents the packet to be sent */
udphdr = q->payload;
udphdr->src = htons(pcb->local_port);
udphdr->dest = htons(dst_port);
/* in UDP, 0 checksum means 'no checksum' */
udphdr->chksum = 0x0000;
/* PCB local address is IP_ANY_ADDR? */
if (ip_addr_isany(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = &(netif->ip_addr);
} else {
/* check if UDP PCB local IP address is correct
* this could be an old address if netif->ip_addr has changed */
if (!ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
/* local_ip doesn't match, drop the packet */
if (q != p) {
/* free the header pbuf */
pbuf_free(q);
q = NULL;
/* p is still referenced by the caller, and will live on */
}
return ERR_VAL;
}
/* use UDP PCB local IP address as source address */
src_ip = &(pcb->local_ip);
}
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len));
#if LWIP_UDPLITE
//.........这里部分代码省略.........