示例#1
0
/**
 * 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
 */
void
do_write(struct api_msg_msg *msg)
{
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
#if LWIP_TCP
      msg->conn->state = NETCONN_WRITE;
      /* set all the variables used by do_writemore */
      LWIP_ASSERT("already writing", msg->conn->write_msg == NULL &&
        msg->conn->write_offset == 0);
      msg->conn->write_msg = msg;
      msg->conn->write_offset = 0;
#if LWIP_TCPIP_CORE_LOCKING
      msg->conn->write_delayed = 0;
      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
      do_writemore(msg->conn);
#endif
      /* for both cases: if do_writemore was called, don't ACK the APIMSG! */
      return;
#endif /* LWIP_TCP */
#if (LWIP_UDP || LWIP_RAW)
    } else {
      msg->conn->err = ERR_VAL;
#endif /* (LWIP_UDP || LWIP_RAW) */
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
示例#2
0
/**
 * Bind a pcb contained in a netconn
 * Called from netconn_bind.
 *
 * @param msg the api_msg_msg pointing to the connection and containing
 *            the IP address and port to bind to
 */
void
do_bind(struct api_msg_msg *msg)
{
    if (ERR_IS_FATAL(msg->conn->last_err)) {
        msg->err = msg->conn->last_err;
    } else {
        msg->err = ERR_VAL;
        if (msg->conn->pcb.tcp != NULL) {
            switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
            case NETCONN_RAW:
                msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
                break;
#endif /* LWIP_RAW */
#if LWIP_UDP
            case NETCONN_UDP:
                msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
                break;
#endif /* LWIP_UDP */
#if LWIP_TCP
            case NETCONN_TCP:
                msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
                break;
#endif /* LWIP_TCP */
            default:
                break;
            }
        }
    }
    TCPIP_APIMSG_ACK(msg);
}
示例#3
0
文件: api_msg.c 项目: Akagi201/lwip
/**
 * 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
 */
void
lwip_netconn_do_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 (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
        if (msg->conn->state == NETCONN_NONE) {
          struct tcp_pcb* lpcb;
#if LWIP_IPV6
          if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) {
#if TCP_LISTEN_BACKLOG
            lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
#else  /* TCP_LISTEN_BACKLOG */
            lpcb = tcp_listen_dual(msg->conn->pcb.tcp);
#endif /* TCP_LISTEN_BACKLOG */
          } else
#endif /* LWIP_IPV6 */
          {
#if TCP_LISTEN_BACKLOG
            lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
#else  /* TCP_LISTEN_BACKLOG */
            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;
            }
          }
        }
      } else {
        msg->err = ERR_ARG;
      }
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
示例#4
0
/**
 * 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
 */
void
do_send(struct api_msg_msg *msg)
{
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if (msg->conn->pcb.tcp != NULL) {
      switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
      case NETCONN_RAW:
        if (msg->msg.b->addr == NULL) {
          msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
        } else {
          msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr);
        }
        break;
#endif
#if LWIP_UDP
      case NETCONN_UDP:
        if (msg->msg.b->addr == NULL) {
          msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
        } else {
          msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port);
        }
        break;
#endif /* LWIP_UDP */
      default:
        break;
      }
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
示例#5
0
/**
 * Join multicast groups for UDP netconns.
 * Called from netconn_join_leave_group
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_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);
}
示例#6
0
文件: api_msg.c 项目: mtharp/lwip
/**
 * Connect a pcb contained inside a netconn
 * Called from netconn_connect.
 *
 * @param msg the api_msg_msg pointing to the connection and containing
 *            the IP address and port to connect to
 */
void
lwip_netconn_do_connect(struct api_msg_msg *msg)
{
  if (msg->conn->pcb.tcp == NULL) {
    /* This may happen when calling netconn_connect() a second time */
    msg->err = ERR_CLSD;
    if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
      /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */
      sys_sem_signal(&msg->conn->op_completed);
      return;
    }
  } else {
    switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW
    case NETCONN_RAW:
      msg->err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr));
      break;
#endif /* LWIP_RAW */
#if LWIP_UDP
    case NETCONN_UDP:
      msg->err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
      break;
#endif /* LWIP_UDP */
#if LWIP_TCP
    case NETCONN_TCP:
      /* Prevent connect while doing any other action. */
      if (msg->conn->state != NETCONN_NONE) {
        msg->err = ERR_ISCONN;
      } else {
        setup_tcp(msg->conn);
        msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr),
          msg->msg.bc.port, lwip_netconn_do_connected);
        if (msg->err == ERR_OK) {
          u8_t non_blocking = netconn_is_nonblocking(msg->conn);
          msg->conn->state = NETCONN_CONNECT;
          SET_NONBLOCKING_CONNECT(msg->conn, non_blocking);
          if (non_blocking) {
            msg->err = ERR_INPROGRESS;
          } else {
            msg->conn->current_msg = msg;
            /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()),
            * when the connection is established! */
            return;
          }
        }
      }
      /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */
      sys_sem_signal(&msg->conn->op_completed);
      return;
#endif /* LWIP_TCP */
    default:
      LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0));
      break;
    }
  }
  /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(),
     so use TCPIP_APIMSG_ACK() here. */
  TCPIP_APIMSG_ACK(msg);
}
示例#7
0
文件: api_msg.c 项目: mtharp/lwip
/**
 * Return a connection's local or remote address
 * Called from netconn_getaddr
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
lwip_netconn_do_getaddr(struct api_msg_msg *msg)
{
  if (msg->conn->pcb.ip != NULL) {
    if (msg->msg.ad.local) {
      ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr),
        msg->conn->pcb.ip->local_ip);
    } else {
      ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr),
        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) {
        API_EXPR_DEREF(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) {
        API_EXPR_DEREF(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 {
          API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
        }
      }
      break;
#endif /* LWIP_UDP */
#if LWIP_TCP
    case NETCONN_TCP:
      if ((msg->msg.ad.local == 0) &&
          ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) {
        /* pcb is not connected and remote name is requested */
        msg->err = ERR_CONN;
      } else {
        API_EXPR_DEREF(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);
}
示例#8
0
/**
 * Connect a pcb contained inside a netconn
 * Only used for UDP netconns.
 * Called from netconn_disconnect.
 *
 * @param msg the api_msg_msg pointing to the connection to disconnect
 */
void
do_disconnect(struct api_msg_msg *msg)
{
#if LWIP_UDP
  if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
    udp_disconnect(msg->conn->pcb.udp);
  }
#endif /* LWIP_UDP */
  TCPIP_APIMSG_ACK(msg);
}
示例#9
0
/**
 * Bind a pcb contained in a netconn
 * Called from netconn_bind.
 *
 * @param msg the api_msg_msg pointing to the connection and containing
 *            the IP address and port to bind to
 */
void
do_bind(struct api_msg_msg *msg)
{
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if (msg->conn->pcb.tcp != NULL) {
      //[MS_CHANGE] - make sure we are binding to a valid address
      u8_t validAddr = ip_addr_isany(msg->msg.bc.ipaddr);

      if(!validAddr) {
        struct netif *netif;
        for(netif = netif_list; netif != NULL; netif = netif->next) {
          /* network mask matches? */
          if (netif_is_up(netif)) {
            if(ip_addr_cmp(msg->msg.bc.ipaddr, &netif->ip_addr)) {
                validAddr = 1;
                break;
            }
          }
        }
      }

      //[MS_CHANGE] - make sure we are binding to a valid address
      if(validAddr) 
      {
        switch (NETCONNTYPE_GROUP(msg->conn->type)) {
  #if LWIP_RAW
        case NETCONN_RAW:
          msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
          break;
  #endif /* LWIP_RAW */
  #if LWIP_UDP
        case NETCONN_UDP:
          msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
          break;
  #endif /* LWIP_UDP */
  #if LWIP_TCP
        case NETCONN_TCP:
          msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
          break;
  #endif /* LWIP_TCP */
        default:
          break;
        }
      }
      else {
          msg->conn->err = ERR_VAL;        
      }
    } else {
      /* msg->conn->pcb is NULL */
      msg->conn->err = ERR_VAL;
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
示例#10
0
/**
 * Create a new pcb of a specific type inside a netconn.
 * Called from netconn_new_with_proto_and_callback.
 *
 * @param msg the api_msg_msg describing the connection type
 */
void
do_newconn(struct api_msg_msg *msg)
{
   if(msg->conn->pcb.tcp == NULL) {
     pcb_new(msg);
   }
   /* Else? This "new" connection already has a PCB allocated. */
   /* Is this an error condition? Should it be deleted? */
   /* We currently just are happy and return. */

   TCPIP_APIMSG_ACK(msg);
}
示例#11
0
/**
 * Connect a pcb contained inside a netconn
 * Only used for UDP netconns.
 * Called from netconn_disconnect.
 *
 * @param msg the api_msg_msg pointing to the connection to disconnect
 */
void
do_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);
}
示例#12
0
/**
 * Close a TCP pcb contained in a netconn
 * Called from netconn_close
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_close(struct api_msg_msg *msg)
{
#if LWIP_TCP
  if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
      msg->conn->state = NETCONN_CLOSE;
      do_close_internal(msg->conn);
      /* for tcp netconns, do_close_internal ACKs the message */
  } else
#endif /* LWIP_TCP */
  {
    msg->conn->err = ERR_VAL;
    TCPIP_APIMSG_ACK(msg);
  }
}
示例#13
0
/**
 * 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
 */
void
do_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);
}
示例#14
0
/**
 * Return a connection's local or remote address
 * Called from netconn_getaddr
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
do_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);
}
示例#15
0
/**
 * 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
 */
void
do_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);
}
示例#16
0
文件: api_msg.c 项目: mtharp/lwip
/**
 * Join multicast groups for UDP netconns.
 * Called from netconn_join_leave_group
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
lwip_netconn_do_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 LWIP_IPV6 && LWIP_IPV6_MLD
        if (PCB_ISIPV6(msg->conn->pcb.udp)) {
          if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
            msg->err = mld6_joingroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)),
              ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
          } else {
            msg->err = mld6_leavegroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)),
              ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
          }
        }
        else
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
        {
#if LWIP_IGMP
          if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
            msg->err = igmp_joingroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)),
              ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr)));
          } else {
            msg->err = igmp_leavegroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)),
              ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr)));
          }
#endif /* LWIP_IGMP */
        }
#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);
}
示例#17
0
/**
 * 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
 */
void
do_listen(struct api_msg_msg *msg)
{
#if LWIP_TCP
  if (!ERR_IS_FATAL(msg->conn->err)) {
    if (msg->conn->pcb.tcp != NULL) {
      if (msg->conn->type == NETCONN_TCP) {
        if (msg->conn->pcb.tcp->state == CLOSED) {
#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) {
            msg->conn->err = ERR_MEM;
          } else {
            /* delete the recvmbox and allocate the acceptmbox */
            if (msg->conn->recvmbox != SYS_MBOX_NULL) {
              /** @todo: should we drain the recvmbox here? */
              sys_mbox_free(msg->conn->recvmbox);
              msg->conn->recvmbox = SYS_MBOX_NULL;
            }
            if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
              if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) {
                msg->conn->err = ERR_MEM;
              }
            }
            if (msg->conn->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 {
          msg->conn->err = ERR_CONN;
        }
      }
    }
  }
#endif /* LWIP_TCP */
  TCPIP_APIMSG_ACK(msg);
}
示例#18
0
/**
 * 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
 */
void
do_recv(struct api_msg_msg *msg)
{
#if LWIP_TCP
  if (!ERR_IS_FATAL(msg->conn->err)) {
    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 */
        {
          tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
        }
      }
    }
  }
#endif /* LWIP_TCP */
  TCPIP_APIMSG_ACK(msg);
}
示例#19
0
/**
 * 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
 */
void
do_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);
}