⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 api_msg.c

📁 freescale k40/k60 freertos-lwip例程
💻 C
📖 第 1 页 / 共 3 页
字号:
/** * @file * Sequential API Internal module * *//* * Copyright (c) 2001-2004 Swedish Institute of Computer Science. * All rights reserved.  *  * 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. *  * Author: Adam Dunkels <adam@sics.se> * */#include "lwip/opt.h"#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */#include "lwip/api_msg.h"#include "lwip/ip.h"#include "lwip/udp.h"#include "lwip/tcp.h"#include "lwip/raw.h"#include "lwip/memp.h"#include "lwip/tcpip.h"#include "lwip/igmp.h"#include "lwip/dns.h"#include <string.h>/* forward declarations */#if LWIP_TCPstatic err_t do_writemore(struct netconn *conn);static void do_close_internal(struct netconn *conn);#endif#if LWIP_RAW/** * Receive callback function for RAW netconns. * Doesn't 'eat' the packet, only references it and sends it to * conn->recvmbox * * @see raw.h (struct raw_pcb.recv) for parameters and return value */static u8_trecv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,    struct ip_addr *addr){  struct pbuf *q;  struct netbuf *buf;  struct netconn *conn;#if LWIP_SO_RCVBUF  int recv_avail;#endif /* LWIP_SO_RCVBUF */  LWIP_UNUSED_ARG(addr);  conn = arg;#if LWIP_SO_RCVBUF  SYS_ARCH_GET(conn->recv_avail, recv_avail);  if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&      ((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) {#else  /* LWIP_SO_RCVBUF */  if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {#endif /* LWIP_SO_RCVBUF */    /* copy the whole packet into new pbufs */    q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);    if(q != NULL) {      if (pbuf_copy(q, p) != ERR_OK) {        pbuf_free(q);        q = NULL;      }    }    if(q != NULL) {      buf = memp_malloc(MEMP_NETBUF);      if (buf == NULL) {        pbuf_free(q);        return 0;      }      buf->p = q;      buf->ptr = q;      buf->addr = &(((struct ip_hdr*)(q->payload))->src);      buf->port = pcb->protocol;      if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {        netbuf_delete(buf);        return 0;      } else {        SYS_ARCH_INC(conn->recv_avail, q->tot_len);        /* Register event with callback */        API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len);      }    }  }  return 0; /* do not eat the packet */}#endif /* LWIP_RAW*/#if LWIP_UDP/** * Receive callback function for UDP netconns. * Posts the packet to conn->recvmbox or deletes it on memory error. * * @see udp.h (struct udp_pcb.recv) for parameters */static voidrecv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,   struct ip_addr *addr, u16_t port){  struct netbuf *buf;  struct netconn *conn;#if LWIP_SO_RCVBUF  int recv_avail;#endif /* LWIP_SO_RCVBUF */  LWIP_UNUSED_ARG(pcb); /* only used for asserts... */  LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);  LWIP_ASSERT("recv_udp must have an argument", arg != NULL);  conn = arg;  LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);#if LWIP_SO_RCVBUF  SYS_ARCH_GET(conn->recv_avail, recv_avail);  if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||      ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {#else  /* LWIP_SO_RCVBUF */  if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {#endif /* LWIP_SO_RCVBUF */    pbuf_free(p);    return;  }  buf = memp_malloc(MEMP_NETBUF);  if (buf == NULL) {    pbuf_free(p);    return;  } else {    buf->p = p;    buf->ptr = p;    buf->addr = addr;    buf->port = port;#if LWIP_NETBUF_RECVINFO    {      const struct ip_hdr* iphdr = ip_current_header();      /* get the UDP header - always in the first pbuf, ensured by udp_input */      const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));      buf->toaddr = (struct ip_addr*)&iphdr->dest;      buf->toport = udphdr->dest;    }#endif /* LWIP_NETBUF_RECVINFO */  }  if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {    netbuf_delete(buf);    return;  } else {    SYS_ARCH_INC(conn->recv_avail, p->tot_len);    /* Register event with callback */    API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);  }}#endif /* LWIP_UDP */#if LWIP_TCP/** * Receive callback function for TCP netconns. * Posts the packet to conn->recvmbox, but doesn't delete it on errors. * * @see tcp.h (struct tcp_pcb.recv) for parameters and return value */static err_trecv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err){  struct netconn *conn;  u16_t len;  LWIP_UNUSED_ARG(pcb);  LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);  LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);  conn = arg;  LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);  if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {    return ERR_VAL;  }  conn->err = err;  if (p != NULL) {    len = p->tot_len;    SYS_ARCH_INC(conn->recv_avail, len);  } else {    len = 0;  }  if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {    return ERR_MEM;  } else {    /* Register event with callback */    API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);  }  return ERR_OK;}/** * Poll callback function for TCP netconns. * Wakes up an application thread that waits for a connection to close * or data to be sent. The application thread then takes the * appropriate action to go on. * * Signals the conn->sem. * netconn_close waits for conn->sem if closing failed. * * @see tcp.h (struct tcp_pcb.poll) for parameters and return value */static err_tpoll_tcp(void *arg, struct tcp_pcb *pcb){  struct netconn *conn = arg;  LWIP_UNUSED_ARG(pcb);  LWIP_ASSERT("conn != NULL", (conn != NULL));  if (conn->state == NETCONN_WRITE) {    do_writemore(conn);  } else if (conn->state == NETCONN_CLOSE) {    do_close_internal(conn);  }  return ERR_OK;}/** * Sent callback function for TCP netconns. * Signals the conn->sem and calls API_EVENT. * netconn_write waits for conn->sem if send buffer is low. * * @see tcp.h (struct tcp_pcb.sent) for parameters and return value */static err_tsent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len){  struct netconn *conn = arg;  LWIP_UNUSED_ARG(pcb);  LWIP_ASSERT("conn != NULL", (conn != NULL));  if (conn->state == NETCONN_WRITE) {    LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);    do_writemore(conn);  } else if (conn->state == NETCONN_CLOSE) {    do_close_internal(conn);  }  if (conn) {    if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)) {      API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);    }  }    return ERR_OK;}/** * Error callback function for TCP netconns. * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. * The application thread has then to decide what to do. * * @see tcp.h (struct tcp_pcb.err) for parameters */static voiderr_tcp(void *arg, err_t err){  struct netconn *conn;  conn = arg;  LWIP_ASSERT("conn != NULL", (conn != NULL));  conn->pcb.tcp = NULL;  conn->err = err;  if (conn->recvmbox != SYS_MBOX_NULL) {    /* Register event with callback */    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);    sys_mbox_post(conn->recvmbox, NULL);  }  if (conn->op_completed != SYS_SEM_NULL && conn->state == NETCONN_CONNECT) {    conn->state = NETCONN_NONE;    sys_sem_signal(conn->op_completed);  }  if (conn->acceptmbox != SYS_MBOX_NULL) {    /* Register event with callback */    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);    sys_mbox_post(conn->acceptmbox, NULL);  }  if ((conn->state == NETCONN_WRITE) || (conn->state == NETCONN_CLOSE)) {    /* calling do_writemore/do_close_internal is not necessary       since the pcb has already been deleted! */    conn->state = NETCONN_NONE;    /* wake up the waiting task */    sys_sem_signal(conn->op_completed);  }}/** * Setup a tcp_pcb with the correct callback function pointers * and their arguments. * * @param conn the TCP netconn to setup */static voidsetup_tcp(struct netconn *conn){  struct tcp_pcb *pcb;  pcb = conn->pcb.tcp;  tcp_arg(pcb, conn);  tcp_recv(pcb, recv_tcp);  tcp_sent(pcb, sent_tcp);  tcp_poll(pcb, poll_tcp, 4);  tcp_err(pcb, err_tcp);}/** * Accept callback function for TCP netconns. * Allocates a new netconn and posts that to conn->acceptmbox. * * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value */static err_taccept_function(void *arg, struct tcp_pcb *newpcb, err_t err){  struct netconn *newconn;  struct netconn *conn;#if API_MSG_DEBUG#if TCP_DEBUG  tcp_debug_print_state(newpcb->state);#endif /* TCP_DEBUG */#endif /* API_MSG_DEBUG */  conn = (struct netconn *)arg;  LWIP_ERROR("accept_function: invalid conn->acceptmbox",             conn->acceptmbox != SYS_MBOX_NULL, return ERR_VAL;);  /* We have to set the callback here even though   * the new socket is unknown. conn->socket is marked as -1. */  newconn = netconn_alloc(conn->type, conn->callback);  if (newconn == NULL) {    return ERR_MEM;  }  newconn->pcb.tcp = newpcb;  setup_tcp(newconn);  newconn->err = err;  if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {    /* When returning != ERR_OK, the connection is aborted in tcp_process(),       so do nothing here! */    newconn->pcb.tcp = NULL;    netconn_free(newconn);    return ERR_MEM;  } else {    /* Register event with callback */    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);  }  return ERR_OK;}#endif /* LWIP_TCP *//** * Create a new pcb of a specific type. * Called from do_newconn(). * * @param msg the api_msg_msg describing the connection type * @return msg->conn->err, but the return value is currently ignored */static err_tpcb_new(struct api_msg_msg *msg){   msg->conn->err = ERR_OK;   LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);   /* Allocate a PCB for this connection */   switch(NETCONNTYPE_GROUP(msg->conn->type)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -