api_lib.c
ubixos/types.h
net/debug.h
net/api.h
net/api_msg.h
net/memp.h
lib/kprintf.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/api_msg.h
src/sys/net/api/api_lib.c
net/def.h
net/mem.h
net/memp.h
lib/kprintf.h
net/ipv4/ip_addr.h
net/err.h
net/api.h
net/opt.h
net/sys.h
net/pbuf.h
net/debug.h
net/ipv4/inet.h
arch/cc.h
void * void* netbuf_alloc (struct netbuf *buf, uInt16 size) netbuf_alloc struct netbuf * buf uInt16 size NULL netbuf::p pbuf::payload pbuf_alloc pbuf_free PBUF_RAM PBUF_TRANSPORT netbuf::ptr
void void netbuf_chain (struct netbuf *head, struct netbuf *tail) netbuf_chain struct netbuf * head struct netbuf * tail memp_freep MEMP_NETBUF netbuf::p pbuf_chain netbuf::ptr
void void netbuf_copy (struct netbuf *buf, void *dataptr, uInt16 len) netbuf_copy struct netbuf * buf void * dataptr uInt16 len netbuf_copy_partial bot_thread shell_main udpecho_thread
void void netbuf_copy_partial (struct netbuf *buf, void *dataptr, uInt16 len, uInt16 offset) netbuf_copy_partial struct netbuf * buf void * dataptr uInt16 len uInt16 offset pbuf::len pbuf::next NULL netbuf::p pbuf::payload lwip_recvfrom netbuf_copy
err_t err_t netbuf_data (struct netbuf *buf, void **dataptr, uInt16 *len) netbuf_data struct netbuf * buf void ** dataptr uInt16 * len ERR_BUF ERR_OK pbuf::len NULL pbuf::payload netbuf::ptr
void void netbuf_delete (struct netbuf *buf) netbuf_delete struct netbuf * buf memp_freep MEMP_NETBUF NULL netbuf::p pbuf_free netbuf::ptr bot_thread lwip_close lwip_recvfrom lwip_send netconn_delete shell_main udpecho_thread
void void netbuf_first (struct netbuf *buf) netbuf_first struct netbuf * buf netbuf::p netbuf::ptr
void void netbuf_free (struct netbuf *buf) netbuf_free struct netbuf * buf NULL netbuf::p pbuf_free netbuf::ptr
ip_addr * struct ip_addr* netbuf_fromaddr (struct netbuf *buf) netbuf_fromaddr struct netbuf * buf netbuf::fromaddr lwip_recvfrom udpecho_thread
uInt16 uInt16 netbuf_fromport (struct netbuf *buf) netbuf_fromport struct netbuf * buf netbuf::fromport lwip_recvfrom udpecho_thread
uInt16 uInt16 netbuf_len (struct netbuf *buf) netbuf_len struct netbuf * buf netbuf::p pbuf::tot_len bot_thread lwip_recvfrom shell_main
netbuf * struct netbuf* netbuf_new (void) netbuf_new void memp_mallocp MEMP_NETBUF NULL netbuf::p netbuf::ptr lwip_send
Int8 Int8 netbuf_next (struct netbuf *buf) netbuf_next struct netbuf * buf pbuf::next NULL netbuf::ptr
void void netbuf_ref (struct netbuf *buf, void *dataptr, uInt16 size) netbuf_ref struct netbuf * buf void * dataptr uInt16 size pbuf::len NULL netbuf::p pbuf::payload pbuf_alloc pbuf_free PBUF_ROM PBUF_TRANSPORT netbuf::ptr pbuf::tot_len lwip_send
netconn * struct netconn* netconn_accept (struct netconn *conn) netconn_accept struct netconn * conn netconn::acceptmbox NULL sys_mbox_fetch lwip_accept shell_thread
err_t err_t netconn_addr (struct netconn *conn, struct ip_addr **addr, uInt16 *port) netconn_addr struct netconn * conn struct ip_addr ** addr uInt16 * port netconn::err ERR_OK tcp_pcb::local_ip tcp_pcb::local_port udp_pcb::local_port NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM netconn::pcb netconn::tcp netconn::type netconn::udp
err_t err_t netconn_bind (struct netconn *conn, struct ip_addr *addr, uInt16 port) netconn_bind struct netconn * conn struct ip_addr * addr uInt16 port API_MSG_BIND api_msg_post api_msg_msg::bc api_msg_msg::conn netconn::err ERR_MEM ERR_VAL netconn::mbox MEMP_API_MSG memp_freep memp_mallocp api_msg_msg::msg api_msg::msg NETCONN_TCP NULL netconn::recvmbox sys_mbox_fetch sys_mbox_new SYS_MBOX_NULL netconn::type lwip_bind shell_thread udpecho_thread
err_t err_t netconn_close (struct netconn *conn) netconn_close struct netconn * conn API_MSG_CLOSE api_msg_post api_msg_msg::conn netconn::err ERR_MEM ERR_VAL netconn::mbox MEMP_API_MSG memp_freep memp_mallocp api_msg_msg::msg api_msg::msg NETCONN_CLOSE NETCONN_NONE NULL netconn::sem netconn::state sys_mbox_fetch SYS_SEM_NULL sys_sem_wait shell_main
err_t err_t netconn_connect (struct netconn *conn, struct ip_addr *addr, uInt16 port) netconn_connect struct netconn * conn struct ip_addr * addr uInt16 port API_MSG_CONNECT api_msg_post api_msg_msg::bc api_msg_msg::conn netconn::err ERR_MEM ERR_VAL kprintf netconn::mbox MEMP_API_MSG memp_freep memp_mallocp api_msg_msg::msg api_msg::msg NULL netconn::recvmbox sys_mbox_fetch sys_mbox_new SYS_MBOX_NULL bot_thread lwip_connect lwip_sendto udpecho_thread
err_t err_t netconn_delete (struct netconn *conn) netconn_delete struct netconn * conn netconn::acceptmbox API_MSG_DELCONN api_msg_post api_msg_msg::conn ERR_MEM ERR_OK netconn::mbox MEMP_API_MSG memp_free memp_freep memp_mallocp MEMP_NETCONN api_msg_msg::msg api_msg::msg netbuf_delete netconn_delete NETCONN_TCP NULL pbuf_free netconn::recvmbox netconn::sem sys_arch_mbox_fetch sys_mbox_fetch sys_mbox_free SYS_MBOX_NULL sys_sem_free SYS_SEM_NULL netconn::type lwip_accept lwip_close lwip_socket netconn_delete
err_t err_t netconn_err (struct netconn *conn) netconn_err struct netconn * conn netconn::err
err_t err_t netconn_listen (struct netconn *conn) netconn_listen struct netconn * conn netconn::acceptmbox API_MSG_LISTEN api_msg_post api_msg_msg::conn netconn::err ERR_MEM ERR_VAL netconn::mbox MEMP_API_MSG memp_freep memp_mallocp api_msg_msg::msg api_msg::msg NULL sys_mbox_fetch sys_mbox_new SYS_MBOX_NULL lwip_listen shell_thread
netconn * struct netconn* netconn_new (enum netconn_type t) netconn_new enum netconn_type t netconn::acceptmbox netconn::mbox memp_freep memp_mallocp MEMP_NETCONN NETCONN_NONE NULL netconn::pcb netconn::recvmbox netconn::sem netconn::state sys_mbox_new SYS_MBOX_NULL SYS_SEM_NULL netconn::tcp netconn::type bot_thread lwip_socket shell_thread udpecho_thread
err_t err_t netconn_peer (struct netconn *conn, struct ip_addr **addr, uInt16 *port) netconn_peer struct netconn * conn struct ip_addr ** addr uInt16 * port netconn::err ERR_OK NETCONN_TCP NETCONN_UDP NETCONN_UDPLITE NETCONN_UDPNOCHKSUM netconn::pcb tcp_pcb::remote_ip udp_pcb::remote_ip tcp_pcb::remote_port udp_pcb::remote_port netconn::tcp netconn::type netconn::udp lwip_accept lwip_sendto
netbuf * struct netbuf* netconn_recv (struct netconn *conn) netconn_recv struct netconn * conn API_LIB_DEBUG api_msg_post API_MSG_RECV api_msg_msg::conn DEBUGF netconn::err ERR_CONN ERR_MEM ERR_OK netbuf::fromaddr netbuf::fromport api_msg_msg::len LISTEN netconn::mbox MEMP_API_MSG memp_freep memp_mallocp MEMP_NETBUF api_msg_msg::msg api_msg::msg NETCONN_TCP NULL netbuf::p netconn::pcb netbuf::ptr netconn::recvmbox tcp_pcb::state sys_mbox_fetch sys_mbox_free SYS_MBOX_NULL netconn::tcp pbuf::tot_len api_msg::type netconn::type bot_thread lwip_recvfrom shell_main udpecho_thread
err_t err_t netconn_send (struct netconn *conn, struct netbuf *buf) netconn_send struct netconn * conn struct netbuf * buf API_LIB_DEBUG api_msg_post API_MSG_SEND api_msg_msg::conn DEBUGF netconn::err ERR_MEM ERR_OK ERR_VAL netconn::mbox MEMP_API_MSG memp_freep memp_mallocp api_msg_msg::msg api_msg::msg NULL api_msg_msg::p netbuf::p sys_mbox_fetch pbuf::tot_len lwip_send udpecho_thread
enum netconn_type enum netconn_type netconn_type (struct netconn *conn) netconn_type struct netconn * conn netconn::type lwip_recvfrom lwip_send lwip_write
err_t err_t netconn_write (struct netconn *conn, void *dataptr, uInt16 size, uInt8 copy) netconn_write struct netconn * conn void * dataptr uInt16 size uInt8 copy API_LIB_DEBUG api_msg_post API_MSG_WRITE api_msg_msg::conn DEBUGF netconn::err ERR_MEM ERR_OK ERR_VAL netconn::mbox MEMP_API_MSG memp_freep memp_mallocp api_msg_msg::msg api_msg::msg NETCONN_NONE NETCONN_TCP NETCONN_WRITE NULL netconn::pcb netconn::sem netconn::state sys_mbox_fetch sys_sem_free sys_sem_new SYS_SEM_NULL sys_sem_wait netconn::tcp tcp_sndbuf netconn::type api_msg_msg::w lwip_send lwip_write sendstr

    /*
    *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__lib_8c.xml 88 2016-01-12 00:11:29Z reddawg $
    */

    /*ThisisthepartoftheAPIthatislinkedwith
    theapplication*/

    #include<ubixos/types.h>

    #include"net/debug.h"
    #include"net/api.h"
    #include"net/api_msg.h"
    #include"net/memp.h"

    #include"net/debug.h"

    #include"lib/kprintf.h"
    /*-----------------------------------------------------------------------------------*/
    struct
    netbuf*netbuf_new(void)
    {
    structnetbuf*buf;

    buf=memp_mallocp(MEMP_NETBUF);
    if(buf!=NULL){
    buf->p=NULL;
    buf->ptr=NULL;
    returnbuf;
    }else{
    returnNULL;
    }
    }
    /*-----------------------------------------------------------------------------------*/
    void
    netbuf_delete(structnetbuf*buf)
    {
    if(buf!=NULL){
    if(buf->p!=NULL){
    pbuf_free(buf->p);
    buf->p=buf->ptr=NULL;
    }
    memp_freep(MEMP_NETBUF,buf);
    }
    }
    /*-----------------------------------------------------------------------------------*/
    void*
    netbuf_alloc(structnetbuf*buf,uInt16size)
    {
    /*Deallocateanypreviouslyallocatedmemory.*/
    if(buf->p!=NULL){
    pbuf_free(buf->p);
    }
    buf->p=pbuf_alloc(PBUF_TRANSPORT,size,PBUF_RAM);
    if(buf->p==NULL){
    returnNULL;
    }
    buf->ptr=buf->p;
    returnbuf->p->payload;
    }
    /*-----------------------------------------------------------------------------------*/
    void
    netbuf_free(structnetbuf*buf)
    {
    if(buf->p!=NULL){
    pbuf_free(buf->p);
    }
    buf->p=buf->ptr=NULL;
    }
    /*-----------------------------------------------------------------------------------*/
    void
    netbuf_ref(structnetbuf*buf,void*dataptr,uInt16size)
    {
    if(buf->p!=NULL){
    pbuf_free(buf->p);
    }
    buf->p=pbuf_alloc(PBUF_TRANSPORT,0,PBUF_ROM);
    buf->p->payload=dataptr;
    buf->p->len=buf->p->tot_len=size;
    buf->ptr=buf->p;
    }
    /*-----------------------------------------------------------------------------------*/
    void
    netbuf_chain(structnetbuf*head,structnetbuf*tail)
    {
    pbuf_chain(head->p,tail->p);
    head->ptr=head->p;
    memp_freep(MEMP_NETBUF,tail);
    }
    /*-----------------------------------------------------------------------------------*/
    uInt16
    netbuf_len(structnetbuf*buf)
    {
    returnbuf->p->tot_len;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netbuf_data(structnetbuf*buf,void**dataptr,uInt16*len)
    {
    if(buf->ptr==NULL){
    returnERR_BUF;
    }
    *dataptr=buf->ptr->payload;
    *len=buf->ptr->len;
    returnERR_OK;
    }
    /*-----------------------------------------------------------------------------------*/
    Int8
    netbuf_next(structnetbuf*buf)
    {
    if(buf->ptr->next==NULL){
    return-1;
    }
    buf->ptr=buf->ptr->next;
    if(buf->ptr->next==NULL){
    return1;
    }
    return0;
    }
    /*-----------------------------------------------------------------------------------*/
    void
    netbuf_first(structnetbuf*buf)
    {
    buf->ptr=buf->p;
    }
    /*-----------------------------------------------------------------------------------*/
    void
    netbuf_copy_partial(structnetbuf*buf,void*dataptr,uInt16len,uInt16offset)
    {
    structpbuf*p;
    uInt16i,left;

    left=0;

    if(buf==NULL){
    return;
    }

    /*Thisimplementationisbad.Itshouldusebcopy
    instead.*/
    for(p=buf->p;left<len&&p!=NULL;p=p->next){
    if(offset!=0&&offset>=p->len){
    offset-=p->len;
    }else{
    for(i=offset;i<p->len;++i){
    ((char*)dataptr)[left]=((char*)p->payload)[i];
    if(++left>=len){
    return;
    }
    }
    }
    }
    }
    /*-----------------------------------------------------------------------------------*/
    void
    netbuf_copy(structnetbuf*buf,void*dataptr,uInt16len)
    {
    netbuf_copy_partial(buf,dataptr,len,0);
    }
    /*-----------------------------------------------------------------------------------*/
    structip_addr*
    netbuf_fromaddr(structnetbuf*buf)
    {
    returnbuf->fromaddr;
    }
    /*-----------------------------------------------------------------------------------*/
    uInt16
    netbuf_fromport(structnetbuf*buf)
    {
    returnbuf->fromport;
    }
    /*-----------------------------------------------------------------------------------*/
    struct
    netconn*netconn_new(enumnetconn_typet)
    {
    structnetconn*conn;

    conn=memp_mallocp(MEMP_NETCONN);
    if(conn==NULL){
    returnNULL;
    }
    conn->type=t;
    conn->pcb.tcp=NULL;

    if((conn->mbox=sys_mbox_new())==SYS_MBOX_NULL){
    memp_freep(MEMP_NETCONN,conn);
    returnNULL;
    }
    conn->recvmbox=SYS_MBOX_NULL;
    conn->acceptmbox=SYS_MBOX_NULL;
    conn->sem=SYS_SEM_NULL;
    conn->state=NETCONN_NONE;
    returnconn;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_delete(structnetconn*conn)
    {
    structapi_msg*msg;
    void*mem;

    if(conn==NULL){
    returnERR_OK;
    }

    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    returnERR_MEM;
    }

    msg->type=API_MSG_DELCONN;
    msg->msg.conn=conn;
    api_msg_post(msg);
    sys_mbox_fetch(conn->mbox,NULL);
    memp_freep(MEMP_API_MSG,msg);

    /*Draintherecvmbox.*/
    if(conn->recvmbox!=SYS_MBOX_NULL){
    while(sys_arch_mbox_fetch(conn->recvmbox,&mem,1)!=0){
    if(conn->type==NETCONN_TCP){
    pbuf_free((structpbuf*)mem);
    }else{
    netbuf_delete((structnetbuf*)mem);
    }
    }
    sys_mbox_free(conn->recvmbox);
    conn->recvmbox=SYS_MBOX_NULL;
    }

    /*Draintheacceptmbox.*/
    if(conn->acceptmbox!=SYS_MBOX_NULL){
    while(sys_arch_mbox_fetch(conn->acceptmbox,&mem,1)!=0){
    netconn_delete((structnetconn*)mem);
    }

    sys_mbox_free(conn->acceptmbox);
    conn->acceptmbox=SYS_MBOX_NULL;
    }

    sys_mbox_free(conn->mbox);
    conn->mbox=SYS_MBOX_NULL;
    if(conn->sem!=SYS_SEM_NULL){
    sys_sem_free(conn->sem);
    }
    /*conn->sem=SYS_SEM_NULL;*/
    memp_free(MEMP_NETCONN,conn);
    returnERR_OK;
    }
    /*-----------------------------------------------------------------------------------*/
    enumnetconn_type
    netconn_type(structnetconn*conn)
    {
    returnconn->type;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_peer(structnetconn*conn,structip_addr**addr,
    uInt16*port)
    {
    switch(conn->type){
    caseNETCONN_UDPLITE:
    caseNETCONN_UDPNOCHKSUM:
    caseNETCONN_UDP:
    *addr=&(conn->pcb.udp->remote_ip);
    *port=conn->pcb.udp->remote_port;
    break;
    caseNETCONN_TCP:
    *addr=&(conn->pcb.tcp->remote_ip);
    *port=conn->pcb.tcp->remote_port;
    break;
    }
    return(conn->err=ERR_OK);
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_addr(structnetconn*conn,structip_addr**addr,
    uInt16*port)
    {
    switch(conn->type){
    caseNETCONN_UDPLITE:
    caseNETCONN_UDPNOCHKSUM:
    caseNETCONN_UDP:
    *addr=&(conn->pcb.udp->local_ip);
    *port=conn->pcb.udp->local_port;
    break;
    caseNETCONN_TCP:
    *addr=&(conn->pcb.tcp->local_ip);
    *port=conn->pcb.tcp->local_port;
    break;
    }
    return(conn->err=ERR_OK);
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_bind(structnetconn*conn,structip_addr*addr,
    uInt16port)
    {
    structapi_msg*msg;

    if(conn==NULL){
    returnERR_VAL;
    }

    if(conn->type!=NETCONN_TCP&&
    conn->recvmbox==SYS_MBOX_NULL){
    if((conn->recvmbox=sys_mbox_new())==SYS_MBOX_NULL){
    returnERR_MEM;
    }
    }

    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    return(conn->err=ERR_MEM);
    }
    msg->type=API_MSG_BIND;
    msg->msg.conn=conn;
    msg->msg.msg.bc.ipaddr=addr;
    msg->msg.msg.bc.port=port;
    api_msg_post(msg);
    sys_mbox_fetch(conn->mbox,NULL);
    memp_freep(MEMP_API_MSG,msg);
    returnconn->err;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_connect(structnetconn*conn,structip_addr*addr,
    uInt16port)
    {
    structapi_msg*msg;

    if(conn==NULL){
    returnERR_VAL;
    }

    if(conn->recvmbox==SYS_MBOX_NULL){
    if((conn->recvmbox=sys_mbox_new())==SYS_MBOX_NULL){
    returnERR_MEM;
    }
    }

    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    returnERR_MEM;
    }
    msg->type=API_MSG_CONNECT;
    msg->msg.conn=conn;
    msg->msg.msg.bc.ipaddr=addr;
    msg->msg.msg.bc.port=port;
    kprintf("1");
    api_msg_post(msg);
    kprintf("2:[0x%X]",conn->mbox);
    sys_mbox_fetch(conn->mbox,NULL);
    kprintf("3");
    memp_freep(MEMP_API_MSG,msg);
    kprintf("4");
    returnconn->err;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_listen(structnetconn*conn)
    {
    structapi_msg*msg;

    if(conn==NULL){
    returnERR_VAL;
    }

    if(conn->acceptmbox==SYS_MBOX_NULL){
    conn->acceptmbox=sys_mbox_new();
    if(conn->acceptmbox==SYS_MBOX_NULL){
    returnERR_MEM;
    }
    }

    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    return(conn->err=ERR_MEM);
    }
    msg->type=API_MSG_LISTEN;
    msg->msg.conn=conn;
    api_msg_post(msg);
    sys_mbox_fetch(conn->mbox,NULL);
    memp_freep(MEMP_API_MSG,msg);
    returnconn->err;
    }
    /*-----------------------------------------------------------------------------------*/
    structnetconn*
    netconn_accept(structnetconn*conn)
    {
    structnetconn*newconn;

    if(conn==NULL){
    returnNULL;
    }

    sys_mbox_fetch(conn->acceptmbox,(void**)&newconn);

    returnnewconn;
    }
    /*-----------------------------------------------------------------------------------*/
    structnetbuf*
    netconn_recv(structnetconn*conn)
    {
    structapi_msg*msg;
    structnetbuf*buf;
    structpbuf*p;

    if(conn==NULL){
    returnNULL;
    }

    if(conn->recvmbox==SYS_MBOX_NULL){
    conn->err=ERR_CONN;
    returnNULL;
    }

    if(conn->err!=ERR_OK){
    returnNULL;
    }

    if(conn->type==NETCONN_TCP){
    if(conn->pcb.tcp->state==LISTEN){
    conn->err=ERR_CONN;
    returnNULL;
    }

    buf=memp_mallocp(MEMP_NETBUF);

    if(buf==NULL){
    conn->err=ERR_MEM;
    returnNULL;
    }

    sys_mbox_fetch(conn->recvmbox,(void**)&p);

    /*Ifweareclosed,weindicatethatwenolongerwishtorecieve
    databysettingconn->recvmboxtoSYS_MBOX_NULL.*/
    if(p==NULL){
    memp_freep(MEMP_NETBUF,buf);
    sys_mbox_free(conn->recvmbox);
    conn->recvmbox=SYS_MBOX_NULL;
    returnNULL;
    }

    buf->p=p;
    buf->ptr=p;
    buf->fromport=0;
    buf->fromaddr=NULL;

    /*Letthestackknowthatwehavetakenthedata.*/
    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    conn->err=ERR_MEM;
    returnbuf;
    }
    msg->type=API_MSG_RECV;
    msg->msg.conn=conn;
    if(buf!=NULL){
    msg->msg.msg.len=buf->p->tot_len;
    }else{
    msg->msg.msg.len=1;
    }
    api_msg_post(msg);

    sys_mbox_fetch(conn->mbox,NULL);
    memp_freep(MEMP_API_MSG,msg);
    }else{
    sys_mbox_fetch(conn->recvmbox,(void**)&buf);
    }

    DEBUGF(API_LIB_DEBUG,("netconn_recv:received%p(err%d)\n",buf,conn->err));

    returnbuf;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_send(structnetconn*conn,structnetbuf*buf)
    {
    structapi_msg*msg;

    if(conn==NULL){
    returnERR_VAL;
    }

    if(conn->err!=ERR_OK){
    returnconn->err;
    }

    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    return(conn->err=ERR_MEM);
    }

    DEBUGF(API_LIB_DEBUG,("netconn_send:sending%dbytes\n",buf->p->tot_len));
    msg->type=API_MSG_SEND;
    msg->msg.conn=conn;
    msg->msg.msg.p=buf->p;
    api_msg_post(msg);

    sys_mbox_fetch(conn->mbox,NULL);
    memp_freep(MEMP_API_MSG,msg);
    returnconn->err;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_write(structnetconn*conn,void*dataptr,uInt16size,uInt8copy)
    {
    structapi_msg*msg;
    uInt16len;

    if(conn==NULL){
    returnERR_VAL;
    }

    if(conn->err!=ERR_OK){
    returnconn->err;
    }

    if(conn->sem==SYS_SEM_NULL){
    conn->sem=sys_sem_new(0);
    if(conn->sem==SYS_SEM_NULL){
    returnERR_MEM;
    }
    }

    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    return(conn->err=ERR_MEM);
    }
    msg->type=API_MSG_WRITE;
    msg->msg.conn=conn;

    conn->state=NETCONN_WRITE;
    while(conn->err==ERR_OK&&size>0){
    msg->msg.msg.w.dataptr=dataptr;
    msg->msg.msg.w.copy=copy;

    if(conn->type==NETCONN_TCP){
    if(tcp_sndbuf(conn->pcb.tcp)==0){
    sys_sem_wait(conn->sem);
    if(conn->err!=ERR_OK){
    gotoret;
    }
    }
    if(size>tcp_sndbuf(conn->pcb.tcp)){
    /*Wecannotsendmorethanonesendbuffer'sworthofdataata
    time.*/
    len=tcp_sndbuf(conn->pcb.tcp);
    }else{
    len=size;
    }
    }else{
    len=size;
    }

    DEBUGF(API_LIB_DEBUG,("netconn_write:writing%dbytes(%d)\n",len,copy));
    msg->msg.msg.w.len=len;
    api_msg_post(msg);
    sys_mbox_fetch(conn->mbox,NULL);
    if(conn->err==ERR_OK){
    dataptr=(void*)((char*)dataptr+len);
    size-=len;
    }elseif(conn->err==ERR_MEM){
    conn->err=ERR_OK;
    sys_sem_wait(conn->sem);
    }else{
    gotoret;
    }
    }
    ret:
    memp_freep(MEMP_API_MSG,msg);
    conn->state=NETCONN_NONE;
    if(conn->sem!=SYS_SEM_NULL){
    sys_sem_free(conn->sem);
    conn->sem=SYS_SEM_NULL;
    }
    returnconn->err;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_close(structnetconn*conn)
    {
    structapi_msg*msg;

    if(conn==NULL){
    returnERR_VAL;
    }
    if((msg=memp_mallocp(MEMP_API_MSG))==NULL){
    return(conn->err=ERR_MEM);
    }

    conn->state=NETCONN_CLOSE;
    again:
    msg->type=API_MSG_CLOSE;
    msg->msg.conn=conn;
    api_msg_post(msg);
    sys_mbox_fetch(conn->mbox,NULL);
    if(conn->err==ERR_MEM&&
    conn->sem!=SYS_SEM_NULL){
    sys_sem_wait(conn->sem);
    gotoagain;
    }
    conn->state=NETCONN_NONE;
    memp_freep(MEMP_API_MSG,msg);
    returnconn->err;
    }
    /*-----------------------------------------------------------------------------------*/
    err_t
    netconn_err(structnetconn*conn)
    {
    returnconn->err;
    }
    /*-----------------------------------------------------------------------------------*/