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

📄 api_msg.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Called from netconn_disconnect. * * @param msg the api_msg_msg pointing to the connection to disconnect */voiddo_disconnect(struct api_msg_msg *msg){#if LWIP_UDP  if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {    udp_disconnect(msg->conn->pcb.udp);    msg->err = ERR_OK;  } else#endif /* LWIP_UDP */  {    msg->err = ERR_VAL;  }  TCPIP_APIMSG_ACK(msg);}#if LWIP_TCP/** * Set a TCP pcb contained in a netconn into listen mode * Called from netconn_listen. * * @param msg the api_msg_msg pointing to the connection */voiddo_listen(struct api_msg_msg *msg){  if (ERR_IS_FATAL(msg->conn->last_err)) {    msg->err = msg->conn->last_err;  } else {    msg->err = ERR_CONN;    if (msg->conn->pcb.tcp != NULL) {      if (msg->conn->type == NETCONN_TCP) {        if (msg->conn->state == NETCONN_NONE) {#if TCP_LISTEN_BACKLOG          struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);#else  /* TCP_LISTEN_BACKLOG */          struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);#endif /* TCP_LISTEN_BACKLOG */          if (lpcb == NULL) {            /* in this case, the old pcb is still allocated */            msg->err = ERR_MEM;          } else {            /* delete the recvmbox and allocate the acceptmbox */            if (sys_mbox_valid(&msg->conn->recvmbox)) {              /** @todo: should we drain the recvmbox here? */              sys_mbox_free(&msg->conn->recvmbox);              sys_mbox_set_invalid(&msg->conn->recvmbox);            }            msg->err = ERR_OK;            if (!sys_mbox_valid(&msg->conn->acceptmbox)) {              msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE);            }            if (msg->err == ERR_OK) {              msg->conn->state = NETCONN_LISTEN;              msg->conn->pcb.tcp = lpcb;              tcp_arg(msg->conn->pcb.tcp, msg->conn);              tcp_accept(msg->conn->pcb.tcp, accept_function);            } else {              /* since the old pcb is already deallocated, free lpcb now */              tcp_close(lpcb);              msg->conn->pcb.tcp = NULL;            }          }        }      }    }  }  TCPIP_APIMSG_ACK(msg);}#endif /* LWIP_TCP *//** * Send some data on a RAW or UDP pcb contained in a netconn * Called from netconn_send * * @param msg the api_msg_msg pointing to the connection */voiddo_send(struct api_msg_msg *msg){  if (ERR_IS_FATAL(msg->conn->last_err)) {    msg->err = msg->conn->last_err;  } else {    msg->err = ERR_CONN;    if (msg->conn->pcb.tcp != NULL) {      switch (NETCONNTYPE_GROUP(msg->conn->type)) {#if LWIP_RAW      case NETCONN_RAW:        if (ip_addr_isany(&msg->msg.b->addr)) {          msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);        } else {          msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr);        }        break;#endif#if LWIP_UDP      case NETCONN_UDP:#if LWIP_CHECKSUM_ON_COPY        if (ip_addr_isany(&msg->msg.b->addr)) {          msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p,            msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);        } else {          msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,            &msg->msg.b->addr, msg->msg.b->port,            msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);        }#else /* LWIP_CHECKSUM_ON_COPY */        if (ip_addr_isany(&msg->msg.b->addr)) {          msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);        } else {          msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port);        }#endif /* LWIP_CHECKSUM_ON_COPY */        break;#endif /* LWIP_UDP */      default:        break;      }    }  }  TCPIP_APIMSG_ACK(msg);}#if LWIP_TCP/** * Indicate data has been received from a TCP pcb contained in a netconn * Called from netconn_recv * * @param msg the api_msg_msg pointing to the connection */voiddo_recv(struct api_msg_msg *msg){  msg->err = ERR_OK;  if (msg->conn->pcb.tcp != NULL) {    if (msg->conn->type == NETCONN_TCP) {#if TCP_LISTEN_BACKLOG      if (msg->conn->pcb.tcp->state == LISTEN) {        tcp_accepted(msg->conn->pcb.tcp);      } else#endif /* TCP_LISTEN_BACKLOG */      {        u32_t remaining = msg->msg.r.len;        do {          u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining;          tcp_recved(msg->conn->pcb.tcp, recved);          remaining -= recved;        }while(remaining != 0);      }    }  }  TCPIP_APIMSG_ACK(msg);}/** * See if more data needs to be written from a previous call to netconn_write. * Called initially from do_write. If the first call can't send all data * (because of low memory or empty send-buffer), this function is called again * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the * blocking application thread (waiting in netconn_write) is released. * * @param conn netconn (that is currently in state NETCONN_WRITE) to process * @return ERR_OK *         ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished */static err_tdo_writemore(struct netconn *conn){  err_t err = ERR_OK;  void *dataptr;  u16_t len, available;  u8_t write_finished = 0;  size_t diff;  u8_t dontblock = netconn_is_nonblocking(conn) ||       (conn->current_msg->msg.w.apiflags & NETCONN_DONTBLOCK);  u8_t apiflags = conn->current_msg->msg.w.apiflags;  LWIP_ASSERT("conn != NULL", conn != NULL);  LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);  LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);  LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len",    conn->write_offset < conn->current_msg->msg.w.len);  dataptr = (u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;  diff = conn->current_msg->msg.w.len - conn->write_offset;  if (diff > 0xffffUL) { /* max_u16_t */    len = 0xffff;#if LWIP_TCPIP_CORE_LOCKING    conn->flags |= NETCONN_FLAG_WRITE_DELAYED;#endif    apiflags |= TCP_WRITE_FLAG_MORE;  } else {    len = (u16_t)diff;  }  available = tcp_sndbuf(conn->pcb.tcp);  if (available < len) {    /* don't try to write more than sendbuf */    len = available;#if LWIP_TCPIP_CORE_LOCKING    conn->flags |= NETCONN_FLAG_WRITE_DELAYED;#endif    apiflags |= TCP_WRITE_FLAG_MORE;  }  if (dontblock && (len < conn->current_msg->msg.w.len)) {    /* failed to send all data at once -> nonblocking write not possible */    err = ERR_MEM;  }  if (err == ERR_OK) {    LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));    err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);  }  if (dontblock && (err == ERR_MEM)) {    /* nonblocking write failed */    write_finished = 1;    err = ERR_WOULDBLOCK;    /* let poll_tcp check writable space to mark the pcb       writable again */    conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;    /* let select mark this pcb as non-writable. */    API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);  } else {    /* if OK or memory error, check available space */    if (((err == ERR_OK) || (err == ERR_MEM)) &&        ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) ||         (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT))) {      /* The queued byte- or pbuf-count exceeds the configured low-water limit,         let select mark this pcb as non-writable. */      API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);    }    if (err == ERR_OK) {      conn->write_offset += len;      if (conn->write_offset == conn->current_msg->msg.w.len) {        /* everything was written */        write_finished = 1;        conn->write_offset = 0;      }      tcp_output(conn->pcb.tcp);    } else if (err == ERR_MEM) {      /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called         we do NOT return to the application thread, since ERR_MEM is         only a temporary error! */      /* tcp_write returned ERR_MEM, try tcp_output anyway */      tcp_output(conn->pcb.tcp);  #if LWIP_TCPIP_CORE_LOCKING      conn->flags |= NETCONN_FLAG_WRITE_DELAYED;  #endif    } else {      /* On errors != ERR_MEM, we don't try writing any more but return         the error to the application thread. */      write_finished = 1;    }  }  if (write_finished) {    /* everything was written: set back connection state       and back to application task */    conn->current_msg->err = err;    conn->current_msg = NULL;    conn->state = NETCONN_NONE;#if LWIP_TCPIP_CORE_LOCKING    if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0)#endif    {      sys_sem_signal(&conn->op_completed);    }  }#if LWIP_TCPIP_CORE_LOCKING  else    return ERR_MEM;#endif  return ERR_OK;}#endif /* LWIP_TCP *//** * Send some data on a TCP pcb contained in a netconn * Called from netconn_write * * @param msg the api_msg_msg pointing to the connection */voiddo_write(struct api_msg_msg *msg){  if (ERR_IS_FATAL(msg->conn->last_err)) {    msg->err = msg->conn->last_err;  } else {    if (msg->conn->type == NETCONN_TCP) {#if LWIP_TCP      if (msg->conn->state != NETCONN_NONE) {        /* netconn is connecting, closing or in blocking write */        msg->err = ERR_INPROGRESS;      } else if (msg->conn->pcb.tcp != NULL) {        msg->conn->state = NETCONN_WRITE;        /* set all the variables used by do_writemore */        LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&          msg->conn->write_offset == 0);        LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0);        msg->conn->current_msg = msg;        msg->conn->write_offset = 0;#if LWIP_TCPIP_CORE_LOCKING        msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;        if (do_writemore(msg->conn) != ERR_OK) {          LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);          UNLOCK_TCPIP_CORE();          sys_arch_sem_wait(&msg->conn->op_completed, 0);          LOCK_TCPIP_CORE();          LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);        }#else /* LWIP_TCPIP_CORE_LOCKING */        do_writemore(msg->conn);#endif /* LWIP_TCPIP_CORE_LOCKING */        /* for both cases: if do_writemore was called, don't ACK the APIMSG           since do_writemore ACKs it! */        return;      } else {        msg->err = ERR_CONN;      }#else /* LWIP_TCP */      msg->err = ERR_VAL;#endif /* LWIP_TCP */#if (LWIP_UDP || LWIP_RAW)    } else {      msg->err = ERR_VAL;#endif /* (LWIP_UDP || LWIP_RAW) */    }  }  TCPIP_APIMSG_ACK(msg);}/** * Return a connection's local or remote address * Called from netconn_getaddr * * @param msg the api_msg_msg pointing to the connection */voiddo_getaddr(struct api_msg_msg *msg){  if (msg->conn->pcb.ip != NULL) {    *(msg->msg.ad.ipaddr) = (msg->msg.ad.local ? msg->conn->pcb.ip->local_ip :                             msg->conn->pcb.ip->remote_ip);    msg->err = ERR_OK;    switch (NETCONNTYPE_GROUP(msg->conn->type)) {#if LWIP_RAW    case NETCONN_RAW:      if (msg->msg.ad.local) {        *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;      } else {        /* return an error as connecting is only a helper for upper layers */        msg->err = ERR_CONN;      }      break;#endif /* LWIP_RAW */#if LWIP_UDP    case NETCONN_UDP:      if (msg->msg.ad.local) {        *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;      } else {        if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {          msg->err = ERR_CONN;        } else {          *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;        }      }      break;#endif /* LWIP_UDP */#if LWIP_TCP    case NETCONN_TCP:      *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port);      break;#endif /* LWIP_TCP */    default:      LWIP_ASSERT("invalid netconn_type", 0);      break;    }  } else {    msg->err = ERR_CONN;  }  TCPIP_APIMSG_ACK(msg);}/** * Close a TCP pcb contained in a netconn * Called from netconn_close * * @param msg the api_msg_msg pointing to the connection */voiddo_close(struct api_msg_msg *msg){#if LWIP_TCP  /* @todo: abort running write/connect? */  if ((msg->conn->state != NETCONN_NONE) && (msg->conn->state != NETCONN_LISTEN)) {    /* this only happens for TCP netconns */    LWIP_ASSERT("msg->conn->type == NETCONN_TCP", msg->conn->type == NETCONN_TCP);    msg->err = ERR_INPROGRESS;  } else if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {    if ((msg->msg.sd.shut != NETCONN_SHUT_RDWR) && (msg->conn->state == NETCONN_LISTEN)) {      /* LISTEN doesn't support half shutdown */      msg->err = ERR_CONN;    } else {      if (msg->msg.sd.shut & NETCONN_SHUT_RD) {        /* Drain and delete mboxes */        netconn_drain(msg->conn);      }      LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL &&        msg->conn->write_offset == 0);      msg->conn->state = NETCONN_CLOSE;      msg->conn->current_msg = msg;      do_close_internal(msg->conn);      /* for tcp netconns, do_close_internal ACKs the message */      return;    }  } else#endif /* LWIP_TCP */  {    msg->err = ERR_VAL;  }  sys_sem_signal(&msg->conn->op_completed);}#if LWIP_IGMP/** * Join multicast groups for UDP netconns. * Called from netconn_join_leave_group * * @param msg the api_msg_msg pointing to the connection */voiddo_join_leave_group(struct api_msg_msg *msg){   if (ERR_IS_FATAL(msg->conn->last_err)) {    msg->err = msg->conn->last_err;  } else {    if (msg->conn->pcb.tcp != NULL) {      if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {#if LWIP_UDP        if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {          msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr);        } else {          msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr);        }#endif /* LWIP_UDP */#if (LWIP_TCP || LWIP_RAW)      } else {        msg->err = ERR_VAL;#endif /* (LWIP_TCP || LWIP_RAW) */      }    } else {      msg->err = ERR_CONN;    }  }  TCPIP_APIMSG_ACK(msg);}#endif /* LWIP_IGMP */#if LWIP_DNS/** * Callback function that is called when DNS name is resolved * (or on timeout). A waiting application thread is waked up by * signaling the semaphore. */static voiddo_dns_found(const char *name, ip_addr_t *ipaddr, void *arg){  struct dns_api_msg *msg = (struct dns_api_msg*)arg;  LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0);  LWIP_UNUSED_ARG(name);  if (ipaddr == NULL) {    /* timeout or memory error */    *msg->err = ERR_VAL;  } else {    /* address was resolved */    *msg->err = ERR_OK;    *msg->addr = *ipaddr;  }  /* wake up the application task waiting in netconn_gethostbyname */  sys_sem_signal(msg->sem);}/** * Execute a DNS query * Called from netconn_gethostbyname * * @param arg the dns_api_msg pointing to the query */voiddo_gethostbyname(void *arg){  struct dns_api_msg *msg = (struct dns_api_msg*)arg;  *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg);  if (*msg->err != ERR_INPROGRESS) {    /* on error or immediate success, wake up the application     * task waiting in netconn_gethostbyname */    sys_sem_signal(msg->sem);  }}#endif /* LWIP_DNS */#endif /* LWIP_NETCONN */

⌨️ 快捷键说明

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