api_msg.c
ubixos/types.h
net/debug.h
net/arch.h
net/api_msg.h
net/memp.h
net/sys.h
net/tcpip.h
net/ipv4/ip.h
arch/lib.h
net/netif.h
net/udp.h
arch/cpu.h
arch/sys_arch.h
net/tcp.h
ubixos/types.h
sys/_types.h
net/arch.h
net/ipv4/icmp.h
net/lwipopts.h
net/tcpip.h
net/api_msg.h
net/def.h
net/mem.h
net/memp.h
net/ipv4/ip_addr.h
net/err.h
net/api.h
net/opt.h
net/sys.h
src/sys/net/api/api_msg.c
net/pbuf.h
net/debug.h
net/ipv4/inet.h
arch/cc.h
void(*) typedef void(* ) api_msg_decode(struct api_msg_msg *msg) (struct api_msg_msg *msg) api_msg_decode
err_t static err_t accept_function (void *arg, struct tcp_pcb *newpcb, err_t err) accept_function void * arg struct tcp_pcb * newpcb err_t err netconn::acceptmbox netconn::err ERR_MEM ERR_OK netconn::mbox mbox memp_free memp_mallocp MEMP_NETCONN NETCONN_TCP NULL netconn::pcb netconn::recvmbox netconn::sem setup_tcp tcp_pcb::state sys_mbox_free sys_mbox_new SYS_MBOX_NULL sys_mbox_post sys_sem_new SYS_SEM_NULL netconn::tcp netconn::type do_listen
void void api_msg_input (struct api_msg *msg) api_msg_input struct api_msg * msg decode api_msg_msg::msg tcpip_thread
void void api_msg_post (struct api_msg *msg) api_msg_post struct api_msg * msg api_msg_msg::msg tcpip_apimsg netconn_bind netconn_close netconn_connect netconn_delete netconn_listen netconn_recv netconn_send netconn_write
void static void do_accept (struct api_msg_msg *msg) do_accept struct api_msg_msg * msg API_MSG_DEBUG api_msg_msg::conn DEBUGF NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL netconn::pcb netconn::tcp netconn::type
void static void do_bind (struct api_msg_msg *msg) do_bind struct api_msg_msg * msg api_msg_msg::bc api_msg_msg::conn netconn::err netconn::mbox api_msg_msg::msg NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL netconn::pcb recv_udp setup_tcp sys_mbox_post netconn::tcp tcp_bind tcp_new netconn::type netconn::udp udp_bind UDP_FLAGS_NOCHKSUM UDP_FLAGS_UDPLITE udp_new udp_recv udp_setflags
void static void do_close (struct api_msg_msg *msg) do_close struct api_msg_msg * msg api_msg_msg::conn netconn::err LISTEN netconn::mbox NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL netconn::pcb tcp_pcb::state sys_mbox_post netconn::tcp tcp_close netconn::type
void static void do_connect (struct api_msg_msg *msg) do_connect struct api_msg_msg * msg api_msg_msg::bc api_msg_msg::conn do_connected netconn::err ERR_MEM netconn::mbox api_msg_msg::msg NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL netconn::pcb recv_udp setup_tcp sys_mbox_post netconn::tcp tcp_connect tcp_new netconn::type netconn::udp udp_connect UDP_FLAGS_NOCHKSUM UDP_FLAGS_UDPLITE udp_new udp_recv udp_setflags
err_t static err_t do_connected (void *arg, struct tcp_pcb *pcb, err_t err) do_connected void * arg struct tcp_pcb * pcb err_t err netconn::err ERR_OK ERR_VAL netconn::mbox NETCONN_TCP NULL setup_tcp sys_mbox_post netconn::type do_connect
void static void do_delconn (struct api_msg_msg *msg) do_delconn struct api_msg_msg * msg api_msg_msg::conn ERR_OK LISTEN netconn::mbox NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL netconn::pcb udp_pcb::recv_arg tcp_pcb::state SYS_MBOX_NULL sys_mbox_post netconn::tcp tcp_abort tcp_accept tcp_arg tcp_close tcp_err tcp_poll tcp_recv tcp_sent netconn::type netconn::udp udp_remove
void static void do_listen (struct api_msg_msg *msg) do_listen struct api_msg_msg * msg accept_function netconn::acceptmbox API_MSG_DEBUG api_msg_msg::conn DEBUGF netconn::err ERR_MEM netconn::mbox NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL netconn::pcb sys_mbox_new SYS_MBOX_NULL sys_mbox_post netconn::tcp tcp_accept tcp_arg tcp_listen netconn::type
void static void do_newconn (struct api_msg_msg *msg) do_newconn struct api_msg_msg * msg
void static void do_recv (struct api_msg_msg *msg) do_recv struct api_msg_msg * msg api_msg_msg::conn api_msg_msg::len netconn::mbox api_msg_msg::msg NETCONN_TCP NULL netconn::pcb sys_mbox_post netconn::tcp tcp_recved netconn::type
void static void do_send (struct api_msg_msg *msg) do_send struct api_msg_msg * msg api_msg_msg::conn netconn::mbox api_msg_msg::msg NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL api_msg_msg::p netconn::pcb sys_mbox_post netconn::tcp netconn::type netconn::udp udp_send
void static void do_write (struct api_msg_msg *msg) do_write struct api_msg_msg * msg api_msg_msg::conn netconn::err ERR_OK ERR_VAL netconn::mbox api_msg_msg::msg NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM NULL netconn::pcb sys_mbox_post netconn::tcp tcp_output tcp_write netconn::type tcp_pcb::unacked api_msg_msg::w
void static void err_tcp (void *arg, err_t err) err_tcp void * arg err_t err netconn::acceptmbox netconn::err netconn::mbox NULL netconn::pcb netconn::recvmbox netconn::sem SYS_MBOX_NULL sys_mbox_post SYS_SEM_NULL sys_sem_signal netconn::tcp setup_tcp
err_t static err_t poll_tcp (void *arg, struct tcp_pcb *pcb) poll_tcp void * arg struct tcp_pcb * pcb ERR_OK NETCONN_CLOSE NETCONN_WRITE NULL netconn::sem netconn::state SYS_SEM_NULL sys_sem_signal setup_tcp
err_t static err_t recv_tcp (void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) recv_tcp void * arg struct tcp_pcb * pcb struct pbuf * p err_t err netconn::err ERR_OK ERR_VAL NULL pbuf_free netconn::recvmbox SYS_MBOX_NULL sys_mbox_post setup_tcp
void static void recv_udp (void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, uInt16 port) recv_udp void * arg struct udp_pcb * pcb struct pbuf * p struct ip_addr * addr uInt16 port netbuf::fromaddr netbuf::fromport memp_mallocp MEMP_NETBUF NULL netbuf::p pbuf_free netbuf::ptr netconn::recvmbox SYS_MBOX_NULL sys_mbox_post do_bind do_connect
err_t static err_t sent_tcp (void *arg, struct tcp_pcb *pcb, uInt16 len) sent_tcp void * arg struct tcp_pcb * pcb uInt16 len ERR_OK NULL netconn::sem SYS_SEM_NULL sys_sem_signal setup_tcp
void static void setup_tcp (struct netconn *conn) setup_tcp struct netconn * conn err_tcp netconn::pcb poll_tcp recv_tcp sent_tcp netconn::tcp tcp_arg tcp_err tcp_poll tcp_recv tcp_sent accept_function do_bind do_connect do_connected
api_msg_decode api_msg_decode decode[API_MSG_MAX] [API_MSG_MAX] decode { do_newconn, do_delconn, do_bind, do_connect, do_listen, do_accept, do_send, do_recv, do_write, do_close } api_msg_input

    /*
    *Copyright(c)2001,SwedishInstituteofComputerScience.
    *Allrightsreserved.
    *
    *Redistributionanduseinsourceandbinaryforms,withorwithout
    *modification,arepermittedprovidedthatthefollowingconditions
    *aremet:
    *1.Redistributionsofsourcecodemustretaintheabovecopyright
    *notice,thislistofconditionsandthefollowingdisclaimer.
    *2.Redistributionsinbinaryformmustreproducetheabovecopyright
    *notice,thislistofconditionsandthefollowingdisclaimerinthe
    *documentationand/orothermaterialsprovidedwiththedistribution.
    *3.NeitherthenameoftheInstitutenorthenamesofitscontributors
    *maybeusedtoendorseorpromoteproductsderivedfromthissoftware
    *withoutspecificpriorwrittenpermission.
    *
    *THISSOFTWAREISPROVIDEDBYTHEINSTITUTEANDCONTRIBUTORS``ASIS''AND
    *ANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THE
    *IMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSE
    *AREDISCLAIMED.INNOEVENTSHALLTHEINSTITUTEORCONTRIBUTORSBELIABLE
    *FORANYDIRECT,INDIRECT,INCIDENTAL,SPECIAL,EXEMPLARY,ORCONSEQUENTIAL
    *DAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODS
    *ORSERVICES;LOSSOFUSE,DATA,ORPROFITS;ORBUSINESSINTERRUPTION)
    *HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICT
    *LIABILITY,ORTORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAY
    *OUTOFTHEUSEOFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOF
    *SUCHDAMAGE.
    *
    *ThisfileispartofthelwIPTCP/IPstack.
    *
    *Author:AdamDunkels<adam@sics.se>
    *
    *$Id: api__msg_8c.xml 88 2016-01-12 00:11:29Z reddawg $
    */

    #include<ubixos/types.h>

    #include"net/debug.h"
    #include"net/arch.h"
    #include"net/api_msg.h"
    #include"net/memp.h"
    #include"net/sys.h"
    #include"net/tcpip.h"

    /*-----------------------------------------------------------------------------------*/
    staticerr_t
    recv_tcp(void*arg,structtcp_pcb*pcb,structpbuf*p,err_terr)
    {
    structnetconn*conn;

    conn=arg;

    if(conn==NULL){
    pbuf_free(p);
    returnERR_VAL;
    }

    if(conn->recvmbox!=SYS_MBOX_NULL){
    conn->err=err;
    sys_mbox_post(conn->recvmbox,p);
    }
    returnERR_OK;
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    recv_udp(void*arg,structudp_pcb*pcb,structpbuf*p,
    structip_addr*addr,uInt16port)
    {
    structnetbuf*buf;
    structnetconn*conn;

    conn=arg;

    if(conn==NULL){
    pbuf_free(p);
    return;
    }

    if(conn->recvmbox!=SYS_MBOX_NULL){
    buf=memp_mallocp(MEMP_NETBUF);
    if(buf==NULL){
    pbuf_free(p);
    return;
    }else{
    buf->p=p;
    buf->ptr=p;
    buf->fromaddr=addr;
    buf->fromport=port;
    }

    sys_mbox_post(conn->recvmbox,buf);
    }
    }
    /*-----------------------------------------------------------------------------------*/
    staticerr_t
    poll_tcp(void*arg,structtcp_pcb*pcb)
    {
    structnetconn*conn;

    conn=arg;
    if(conn!=NULL&&
    (conn->state==NETCONN_WRITE||conn->state==NETCONN_CLOSE)&&
    conn->sem!=SYS_SEM_NULL){
    sys_sem_signal(conn->sem);
    }
    returnERR_OK;
    }
    /*-----------------------------------------------------------------------------------*/
    staticerr_t
    sent_tcp(void*arg,structtcp_pcb*pcb,uInt16len)
    {
    structnetconn*conn;

    conn=arg;
    if(conn!=NULL&&conn->sem!=SYS_SEM_NULL){
    sys_sem_signal(conn->sem);
    }
    returnERR_OK;
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    err_tcp(void*arg,err_terr)
    {
    structnetconn*conn;

    conn=arg;

    conn->pcb.tcp=NULL;

    conn->err=err;
    if(conn->recvmbox!=SYS_MBOX_NULL){
    sys_mbox_post(conn->recvmbox,NULL);
    }
    if(conn->mbox!=SYS_MBOX_NULL){
    sys_mbox_post(conn->mbox,NULL);
    }
    if(conn->acceptmbox!=SYS_MBOX_NULL){
    sys_mbox_post(conn->acceptmbox,NULL);
    }
    if(conn->sem!=SYS_SEM_NULL){
    sys_sem_signal(conn->sem);
    }
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    setup_tcp(structnetconn*conn)
    {
    structtcp_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);
    }
    /*-----------------------------------------------------------------------------------*/
    staticerr_t
    accept_function(void*arg,structtcp_pcb*newpcb,err_terr)
    {
    sys_mbox_t*mbox;
    structnetconn*newconn;

    #ifAPI_MSG_DEBUG
    #ifTCP_DEBUG
    tcp_debug_print_state(newpcb->state);
    #endif/*TCP_DEBUG*/
    #endif/*API_MSG_DEBUG*/
    mbox=(sys_mbox_t*)arg;
    newconn=memp_mallocp(MEMP_NETCONN);
    if(newconn==NULL){
    returnERR_MEM;
    }
    newconn->type=NETCONN_TCP;
    newconn->pcb.tcp=newpcb;
    setup_tcp(newconn);
    newconn->recvmbox=sys_mbox_new();
    if(newconn->recvmbox==SYS_MBOX_NULL){
    memp_free(MEMP_NETCONN,newconn);
    returnERR_MEM;
    }
    newconn->mbox=sys_mbox_new();
    if(newconn->mbox==SYS_MBOX_NULL){
    sys_mbox_free(newconn->recvmbox);
    memp_free(MEMP_NETCONN,newconn);
    returnERR_MEM;
    }
    newconn->sem=sys_sem_new(0);
    if(newconn->sem==SYS_SEM_NULL){
    sys_mbox_free(newconn->recvmbox);
    sys_mbox_free(newconn->mbox);
    memp_free(MEMP_NETCONN,newconn);
    returnERR_MEM;
    }
    newconn->acceptmbox=SYS_MBOX_NULL;
    newconn->err=err;
    sys_mbox_post(*mbox,newconn);
    returnERR_OK;
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_newconn(structapi_msg_msg*msg)
    {
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_delconn(structapi_msg_msg*msg)
    {
    if(msg->conn->pcb.tcp!=NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    msg->conn->pcb.udp->recv_arg=NULL;
    udp_remove(msg->conn->pcb.udp);
    break;
    caseNETCONN_TCP:
    tcp_arg(msg->conn->pcb.tcp,NULL);
    tcp_sent(msg->conn->pcb.tcp,NULL);
    tcp_recv(msg->conn->pcb.tcp,NULL);
    tcp_accept(msg->conn->pcb.tcp,NULL);
    tcp_poll(msg->conn->pcb.tcp,NULL,0);
    tcp_err(msg->conn->pcb.tcp,NULL);
    if(msg->conn->pcb.tcp->state==LISTEN){
    tcp_close(msg->conn->pcb.tcp);
    }else{
    if(tcp_close(msg->conn->pcb.tcp)!=ERR_OK){
    tcp_abort(msg->conn->pcb.tcp);
    }
    }
    break;
    }
    }
    if(msg->conn->mbox!=SYS_MBOX_NULL){
    sys_mbox_post(msg->conn->mbox,NULL);
    }
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_bind(structapi_msg_msg*msg)
    {
    if(msg->conn->pcb.tcp==NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    msg->conn->pcb.udp=udp_new();
    udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_UDPLITE);
    udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
    break;
    caseNETCONN_UDPNOCHKSUM:
    msg->conn->pcb.udp=udp_new();
    udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_NOCHKSUM);
    udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
    break;
    caseNETCONN_UDP:
    msg->conn->pcb.udp=udp_new();
    udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
    break;
    caseNETCONN_TCP:
    msg->conn->pcb.tcp=tcp_new();
    setup_tcp(msg->conn);
    break;
    }
    }
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    udp_bind(msg->conn->pcb.udp,msg->msg.bc.ipaddr,msg->msg.bc.port);
    break;
    caseNETCONN_TCP:
    msg->conn->err=tcp_bind(msg->conn->pcb.tcp,
    msg->msg.bc.ipaddr,msg->msg.bc.port);
    break;
    }
    sys_mbox_post(msg->conn->mbox,NULL);
    }
    /*-----------------------------------------------------------------------------------*/
    staticerr_t
    do_connected(void*arg,structtcp_pcb*pcb,err_terr)
    {
    structnetconn*conn;

    conn=arg;

    if(conn==NULL){
    returnERR_VAL;
    }

    conn->err=err;

    if(conn->type==NETCONN_TCP&&err==ERR_OK){
    setup_tcp(conn);
    }

    sys_mbox_post(conn->mbox,NULL);
    returnERR_OK;
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_connect(structapi_msg_msg*msg)
    {
    if(msg->conn->pcb.tcp==NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    msg->conn->pcb.udp=udp_new();
    if(msg->conn->pcb.udp==NULL){
    msg->conn->err=ERR_MEM;
    sys_mbox_post(msg->conn->mbox,NULL);
    return;
    }
    udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_UDPLITE);
    udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
    break;
    caseNETCONN_UDPNOCHKSUM:
    msg->conn->pcb.udp=udp_new();
    if(msg->conn->pcb.udp==NULL){
    msg->conn->err=ERR_MEM;
    sys_mbox_post(msg->conn->mbox,NULL);
    return;
    }
    udp_setflags(msg->conn->pcb.udp,UDP_FLAGS_NOCHKSUM);
    udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
    break;
    caseNETCONN_UDP:
    msg->conn->pcb.udp=udp_new();
    if(msg->conn->pcb.udp==NULL){
    msg->conn->err=ERR_MEM;
    sys_mbox_post(msg->conn->mbox,NULL);
    return;
    }
    udp_recv(msg->conn->pcb.udp,recv_udp,msg->conn);
    break;
    caseNETCONN_TCP:
    msg->conn->pcb.tcp=tcp_new();
    if(msg->conn->pcb.tcp==NULL){
    msg->conn->err=ERR_MEM;
    sys_mbox_post(msg->conn->mbox,NULL);
    return;
    }
    break;
    }
    }
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    udp_connect(msg->conn->pcb.udp,msg->msg.bc.ipaddr,msg->msg.bc.port);
    sys_mbox_post(msg->conn->mbox,NULL);
    break;
    caseNETCONN_TCP:
    /*tcp_arg(msg->conn->pcb.tcp,msg->conn);*/
    setup_tcp(msg->conn);
    tcp_connect(msg->conn->pcb.tcp,msg->msg.bc.ipaddr,msg->msg.bc.port,
    do_connected);
    /*tcp_output(msg->conn->pcb.tcp);*/
    break;
    }
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_listen(structapi_msg_msg*msg)
    {
    if(msg->conn->pcb.tcp!=NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    DEBUGF(API_MSG_DEBUG,("api_msg:listenUDP:cannotlistenforUDP.\n"));
    break;
    caseNETCONN_TCP:
    msg->conn->pcb.tcp=tcp_listen(msg->conn->pcb.tcp);
    if(msg->conn->pcb.tcp==NULL){
    msg->conn->err=ERR_MEM;
    }else{
    if(msg->conn->acceptmbox==SYS_MBOX_NULL){
    msg->conn->acceptmbox=sys_mbox_new();
    if(msg->conn->acceptmbox==SYS_MBOX_NULL){
    msg->conn->err=ERR_MEM;
    break;
    }
    }
    tcp_arg(msg->conn->pcb.tcp,(void*)&(msg->conn->acceptmbox));
    tcp_accept(msg->conn->pcb.tcp,accept_function);
    }
    break;
    }
    }
    sys_mbox_post(msg->conn->mbox,NULL);
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_accept(structapi_msg_msg*msg)
    {
    if(msg->conn->pcb.tcp!=NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    DEBUGF(API_MSG_DEBUG,("api_msg:acceptUDP:cannotacceptforUDP.\n"));
    break;
    caseNETCONN_TCP:
    break;
    }
    }
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_send(structapi_msg_msg*msg)
    {
    if(msg->conn->pcb.tcp!=NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    udp_send(msg->conn->pcb.udp,msg->msg.p);
    break;
    caseNETCONN_TCP:
    break;
    }
    }
    sys_mbox_post(msg->conn->mbox,NULL);
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_recv(structapi_msg_msg*msg)
    {
    if(msg->conn->pcb.tcp!=NULL){
    if(msg->conn->type==NETCONN_TCP){
    tcp_recved(msg->conn->pcb.tcp,msg->msg.len);
    }
    }
    sys_mbox_post(msg->conn->mbox,NULL);
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_write(structapi_msg_msg*msg)
    {
    err_terr;
    if(msg->conn->pcb.tcp!=NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    msg->conn->err=ERR_VAL;
    break;
    caseNETCONN_TCP:
    err=tcp_write(msg->conn->pcb.tcp,msg->msg.w.dataptr,
    msg->msg.w.len,msg->msg.w.copy);
    /*ThisistheNaglealgorithm:inhibitthesendingofnewTCP
    segmentswhennewoutgoingdataarrivesfromtheuserifany
    previouslytransmitteddataontheconnectionremains
    unacknowledged.*/
    if(err==ERR_OK&&msg->conn->pcb.tcp->unacked==NULL){
    tcp_output(msg->conn->pcb.tcp);
    }
    msg->conn->err=err;
    break;
    }
    }
    sys_mbox_post(msg->conn->mbox,NULL);
    }
    /*-----------------------------------------------------------------------------------*/
    staticvoid
    do_close(structapi_msg_msg*msg)
    {
    err_terr;
    if(msg->conn->pcb.tcp!=NULL){
    switch(msg->conn->type){
    caseNETCONN_UDPLITE:
    /*FALLTHROUGH*/
    caseNETCONN_UDPNOCHKSUM:
    /*FALLTHROUGH*/
    caseNETCONN_UDP:
    break;
    caseNETCONN_TCP:
    if(msg->conn->pcb.tcp->state==LISTEN){
    err=tcp_close(msg->conn->pcb.tcp);
    }else{
    err=tcp_close(msg->conn->pcb.tcp);
    }
    msg->conn->err=err;
    break;
    }
    }
    sys_mbox_post(msg->conn->mbox,NULL);
    }
    /*-----------------------------------------------------------------------------------*/
    typedefvoid(*api_msg_decode)(structapi_msg_msg*msg);
    staticapi_msg_decodedecode[API_MSG_MAX]={
    do_newconn,
    do_delconn,
    do_bind,
    do_connect,
    do_listen,
    do_accept,
    do_send,
    do_recv,
    do_write,
    do_close
    };
    void
    api_msg_input(structapi_msg*msg)
    {
    decode[msg->type](&(msg->msg));
    }
    /*-----------------------------------------------------------------------------------*/
    void
    api_msg_post(structapi_msg*msg)
    {
    tcpip_apimsg(msg);
    }
    /*-----------------------------------------------------------------------------------*/