api_lib.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2001, Swedish Institute of Computer Science.
00003  * All rights reserved. 
00004  *
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions 
00007  * are met: 
00008  * 1. Redistributions of source code must retain the above copyright 
00009  *    notice, this list of conditions and the following disclaimer. 
00010  * 2. Redistributions in binary form must reproduce the above copyright 
00011  *    notice, this list of conditions and the following disclaimer in the 
00012  *    documentation and/or other materials provided with the distribution. 
00013  * 3. Neither the name of the Institute nor the names of its contributors 
00014  *    may be used to endorse or promote products derived from this software 
00015  *    without specific prior written permission. 
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
00027  * SUCH DAMAGE. 
00028  *
00029  * This file is part of the lwIP TCP/IP stack.
00030  * 
00031  * Author: Adam Dunkels <adam@sics.se>
00032  *
00033  * $Id: api__lib_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
00034  */
00035 
00036 /* This is the part of the API that is linked with
00037    the application */
00038 
00039 #include <ubixos/types.h>
00040 
00041 #include "net/debug.h"
00042 #include "net/api.h"
00043 #include "net/api_msg.h"
00044 #include "net/memp.h"
00045 
00046 #include "net/debug.h"
00047 
00048 #include "lib/kprintf.h"
00049 /*-----------------------------------------------------------------------------------*/
00050 struct
00051 netbuf *netbuf_new(void)
00052 {
00053   struct netbuf *buf;
00054 
00055   buf = memp_mallocp(MEMP_NETBUF);
00056   if(buf != NULL) {
00057     buf->p = NULL;
00058     buf->ptr = NULL;
00059     return buf;
00060   } else {
00061     return NULL;
00062   }
00063 }
00064 /*-----------------------------------------------------------------------------------*/
00065 void
00066 netbuf_delete(struct netbuf *buf)
00067 {
00068   if(buf != NULL) {
00069     if(buf->p != NULL) {
00070       pbuf_free(buf->p);
00071       buf->p = buf->ptr = NULL;
00072     }
00073     memp_freep(MEMP_NETBUF, buf);
00074   }
00075 }
00076 /*-----------------------------------------------------------------------------------*/
00077 void *
00078 netbuf_alloc(struct netbuf *buf, uInt16 size)
00079 {
00080   /* Deallocate any previously allocated memory. */
00081   if(buf->p != NULL) {
00082     pbuf_free(buf->p);
00083   }
00084   buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
00085   if(buf->p == NULL) {
00086      return NULL;
00087   }
00088   buf->ptr = buf->p;
00089   return buf->p->payload;
00090 }
00091 /*-----------------------------------------------------------------------------------*/
00092 void
00093 netbuf_free(struct netbuf *buf)
00094 {
00095   if(buf->p != NULL) {
00096     pbuf_free(buf->p);
00097   }
00098   buf->p = buf->ptr = NULL;
00099 }
00100 /*-----------------------------------------------------------------------------------*/
00101 void
00102 netbuf_ref(struct netbuf *buf, void *dataptr, uInt16 size)
00103 {
00104   if(buf->p != NULL) {
00105     pbuf_free(buf->p);
00106   }
00107   buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_ROM);
00108   buf->p->payload = dataptr;
00109   buf->p->len = buf->p->tot_len = size;
00110   buf->ptr = buf->p;
00111 }
00112 /*-----------------------------------------------------------------------------------*/
00113 void
00114 netbuf_chain(struct netbuf *head, struct netbuf *tail)
00115 {
00116   pbuf_chain(head->p, tail->p);
00117   head->ptr = head->p;
00118   memp_freep(MEMP_NETBUF, tail);
00119 }
00120 /*-----------------------------------------------------------------------------------*/
00121 uInt16
00122 netbuf_len(struct netbuf *buf)
00123 {
00124   return buf->p->tot_len;
00125 }
00126 /*-----------------------------------------------------------------------------------*/
00127 err_t
00128 netbuf_data(struct netbuf *buf, void **dataptr, uInt16 *len)
00129 {
00130   if(buf->ptr == NULL) {
00131     return ERR_BUF;
00132   }
00133   *dataptr = buf->ptr->payload;
00134   *len = buf->ptr->len;
00135   return ERR_OK;
00136 }
00137 /*-----------------------------------------------------------------------------------*/
00138 Int8
00139 netbuf_next(struct netbuf *buf)
00140 {
00141   if(buf->ptr->next == NULL) {
00142     return -1;
00143   }
00144   buf->ptr = buf->ptr->next;
00145   if(buf->ptr->next == NULL) {
00146     return 1;
00147   }
00148   return 0;
00149 }
00150 /*-----------------------------------------------------------------------------------*/
00151 void
00152 netbuf_first(struct netbuf *buf)
00153 {
00154   buf->ptr = buf->p;
00155 }
00156 /*-----------------------------------------------------------------------------------*/
00157 void
00158 netbuf_copy_partial(struct netbuf *buf, void *dataptr, uInt16 len, uInt16 offset)
00159 {
00160   struct pbuf *p;
00161   uInt16 i, left;
00162 
00163   left = 0;
00164 
00165   if(buf == NULL) {
00166     return;
00167   }
00168   
00169   /* This implementation is bad. It should use bcopy
00170      instead. */
00171   for(p = buf->p; left < len && p != NULL; p = p->next) {
00172     if(offset != 0 && offset >= p->len) {
00173       offset -= p->len;
00174     } else {    
00175       for(i = offset; i < p->len; ++i) {
00176         ((char *)dataptr)[left] = ((char *)p->payload)[i];
00177         if(++left >= len) {
00178           return;
00179         }
00180       }
00181     }
00182   }
00183 }
00184 /*-----------------------------------------------------------------------------------*/
00185 void
00186 netbuf_copy(struct netbuf *buf, void *dataptr, uInt16 len)
00187 {
00188   netbuf_copy_partial(buf, dataptr, len, 0);
00189 }
00190 /*-----------------------------------------------------------------------------------*/
00191 struct ip_addr *
00192 netbuf_fromaddr(struct netbuf *buf)
00193 {
00194   return buf->fromaddr;
00195 }
00196 /*-----------------------------------------------------------------------------------*/
00197 uInt16
00198 netbuf_fromport(struct netbuf *buf)
00199 {
00200   return buf->fromport;
00201 }
00202 /*-----------------------------------------------------------------------------------*/
00203 struct
00204 netconn *netconn_new(enum netconn_type t)
00205 {
00206   struct netconn *conn;
00207 
00208   conn = memp_mallocp(MEMP_NETCONN);
00209   if(conn == NULL) {
00210     return NULL;
00211   }
00212   conn->type = t;
00213   conn->pcb.tcp = NULL;
00214 
00215   if((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {
00216     memp_freep(MEMP_NETCONN, conn);
00217     return NULL;
00218   }
00219   conn->recvmbox = SYS_MBOX_NULL;
00220   conn->acceptmbox = SYS_MBOX_NULL;
00221   conn->sem = SYS_SEM_NULL;
00222   conn->state = NETCONN_NONE;
00223   return conn;
00224 }
00225 /*-----------------------------------------------------------------------------------*/
00226 err_t
00227 netconn_delete(struct netconn *conn)
00228 {
00229   struct api_msg *msg;
00230   void *mem;
00231   
00232   if(conn == NULL) {
00233     return ERR_OK;
00234   }
00235   
00236   if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00237     return ERR_MEM;
00238   }
00239   
00240   msg->type = API_MSG_DELCONN;
00241   msg->msg.conn = conn;
00242   api_msg_post(msg);  
00243   sys_mbox_fetch(conn->mbox, NULL);
00244   memp_freep(MEMP_API_MSG, msg);
00245 
00246   /* Drain the recvmbox. */
00247   if(conn->recvmbox != SYS_MBOX_NULL) {
00248     while(sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != 0) {
00249       if(conn->type == NETCONN_TCP) {
00250         pbuf_free((struct pbuf *)mem);
00251       } else {
00252         netbuf_delete((struct netbuf *)mem);
00253       }
00254     }
00255     sys_mbox_free(conn->recvmbox);
00256     conn->recvmbox = SYS_MBOX_NULL;
00257   }
00258  
00259 
00260   /* Drain the acceptmbox. */
00261   if(conn->acceptmbox != SYS_MBOX_NULL) {
00262     while(sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != 0) {
00263       netconn_delete((struct netconn *)mem);
00264     }
00265     
00266     sys_mbox_free(conn->acceptmbox);
00267     conn->acceptmbox = SYS_MBOX_NULL;
00268   }
00269 
00270   sys_mbox_free(conn->mbox);
00271   conn->mbox = SYS_MBOX_NULL;
00272   if(conn->sem != SYS_SEM_NULL) {
00273     sys_sem_free(conn->sem);
00274   }
00275   /*  conn->sem = SYS_SEM_NULL;*/
00276   memp_free(MEMP_NETCONN, conn);
00277   return ERR_OK;
00278 }
00279 /*-----------------------------------------------------------------------------------*/
00280 enum netconn_type
00281 netconn_type(struct netconn *conn)
00282 {
00283   return conn->type;
00284 }
00285 /*-----------------------------------------------------------------------------------*/
00286 err_t
00287 netconn_peer(struct netconn *conn, struct ip_addr **addr,
00288              uInt16 *port)
00289 {
00290   switch(conn->type) {
00291   case NETCONN_UDPLITE:
00292   case NETCONN_UDPNOCHKSUM:
00293   case NETCONN_UDP:
00294     *addr = &(conn->pcb.udp->remote_ip);
00295     *port = conn->pcb.udp->remote_port;
00296     break;
00297   case NETCONN_TCP:
00298     *addr = &(conn->pcb.tcp->remote_ip);
00299     *port = conn->pcb.tcp->remote_port;
00300     break;
00301   }
00302   return (conn->err = ERR_OK);
00303 }
00304 /*-----------------------------------------------------------------------------------*/
00305 err_t
00306 netconn_addr(struct netconn *conn, struct ip_addr **addr,
00307              uInt16 *port)
00308 {
00309   switch(conn->type) {
00310   case NETCONN_UDPLITE:
00311   case NETCONN_UDPNOCHKSUM:
00312   case NETCONN_UDP:
00313     *addr = &(conn->pcb.udp->local_ip);
00314     *port = conn->pcb.udp->local_port;
00315     break;
00316   case NETCONN_TCP:
00317     *addr = &(conn->pcb.tcp->local_ip);
00318     *port = conn->pcb.tcp->local_port;
00319     break;
00320   }
00321   return (conn->err = ERR_OK);
00322 }
00323 /*-----------------------------------------------------------------------------------*/
00324 err_t
00325 netconn_bind(struct netconn *conn, struct ip_addr *addr,
00326             uInt16 port)
00327 {
00328   struct api_msg *msg;
00329 
00330   if(conn == NULL) {
00331     return ERR_VAL;
00332   }
00333 
00334   if(conn->type != NETCONN_TCP &&
00335      conn->recvmbox == SYS_MBOX_NULL) {
00336     if((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
00337       return ERR_MEM;
00338     }
00339   }
00340   
00341   if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00342     return (conn->err = ERR_MEM);
00343   }
00344   msg->type = API_MSG_BIND;
00345   msg->msg.conn = conn;
00346   msg->msg.msg.bc.ipaddr = addr;
00347   msg->msg.msg.bc.port = port;
00348   api_msg_post(msg);
00349   sys_mbox_fetch(conn->mbox, NULL);
00350   memp_freep(MEMP_API_MSG, msg);
00351   return conn->err;
00352 }
00353 /*-----------------------------------------------------------------------------------*/
00354 err_t
00355 netconn_connect(struct netconn *conn, struct ip_addr *addr,
00356                    uInt16 port)
00357 {
00358   struct api_msg *msg;
00359   
00360   if(conn == NULL) {
00361     return ERR_VAL;
00362   }
00363 
00364 
00365   if(conn->recvmbox == SYS_MBOX_NULL) {
00366     if((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
00367       return ERR_MEM;
00368     }
00369   }
00370   
00371   if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00372     return ERR_MEM;
00373   }
00374   msg->type = API_MSG_CONNECT;
00375   msg->msg.conn = conn;  
00376   msg->msg.msg.bc.ipaddr = addr;
00377   msg->msg.msg.bc.port = port;
00378   kprintf("1");
00379   api_msg_post(msg);
00380   kprintf("2: [0x%X]",conn->mbox);
00381   sys_mbox_fetch(conn->mbox, NULL);
00382   kprintf("3");
00383   memp_freep(MEMP_API_MSG, msg);
00384   kprintf("4");
00385   return conn->err;
00386 }
00387 /*-----------------------------------------------------------------------------------*/
00388 err_t
00389 netconn_listen(struct netconn *conn)
00390 {
00391   struct api_msg *msg;
00392 
00393   if(conn == NULL) {
00394     return ERR_VAL;
00395   }
00396 
00397   if(conn->acceptmbox == SYS_MBOX_NULL) {
00398     conn->acceptmbox = sys_mbox_new();
00399     if(conn->acceptmbox == SYS_MBOX_NULL) {
00400       return ERR_MEM;
00401     }
00402   }
00403   
00404   if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00405     return (conn->err = ERR_MEM);
00406   }
00407   msg->type = API_MSG_LISTEN;
00408   msg->msg.conn = conn;
00409   api_msg_post(msg);
00410   sys_mbox_fetch(conn->mbox, NULL);
00411   memp_freep(MEMP_API_MSG, msg);
00412   return conn->err;
00413 }
00414 /*-----------------------------------------------------------------------------------*/
00415 struct netconn *
00416 netconn_accept(struct netconn *conn)
00417 {
00418   struct netconn *newconn;
00419   
00420   if(conn == NULL) {
00421     return NULL;
00422   }
00423   
00424   sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
00425 
00426   return newconn;
00427 }
00428 /*-----------------------------------------------------------------------------------*/
00429 struct netbuf *
00430 netconn_recv(struct netconn *conn)
00431 {
00432   struct api_msg *msg;
00433   struct netbuf *buf;
00434   struct pbuf *p;
00435     
00436   if(conn == NULL) {
00437     return NULL;
00438   }
00439   
00440   if(conn->recvmbox == SYS_MBOX_NULL) {
00441     conn->err = ERR_CONN;
00442     return NULL;
00443   }
00444 
00445   if(conn->err != ERR_OK) {
00446     return NULL;
00447   }
00448 
00449   if(conn->type == NETCONN_TCP) {
00450     if(conn->pcb.tcp->state == LISTEN) {
00451       conn->err = ERR_CONN;
00452       return NULL;
00453     }
00454 
00455 
00456     buf = memp_mallocp(MEMP_NETBUF);
00457 
00458     if(buf == NULL) {
00459       conn->err = ERR_MEM;
00460       return NULL;
00461     }
00462     
00463     sys_mbox_fetch(conn->recvmbox, (void **)&p);
00464     
00465     /* If we are closed, we indicate that we no longer wish to recieve
00466        data by setting conn->recvmbox to SYS_MBOX_NULL. */
00467     if(p == NULL) {
00468       memp_freep(MEMP_NETBUF, buf);
00469       sys_mbox_free(conn->recvmbox);
00470       conn->recvmbox = SYS_MBOX_NULL;
00471       return NULL;
00472     }
00473 
00474     buf->p = p;
00475     buf->ptr = p;
00476     buf->fromport = 0;
00477     buf->fromaddr = NULL;
00478 
00479     /* Let the stack know that we have taken the data. */
00480     if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00481       conn->err = ERR_MEM;
00482       return buf;
00483     }
00484     msg->type = API_MSG_RECV;
00485     msg->msg.conn = conn;
00486     if(buf != NULL) {
00487       msg->msg.msg.len = buf->p->tot_len;
00488     } else {
00489       msg->msg.msg.len = 1;
00490     }
00491     api_msg_post(msg);
00492 
00493     sys_mbox_fetch(conn->mbox, NULL);
00494     memp_freep(MEMP_API_MSG, msg);
00495   } else {
00496     sys_mbox_fetch(conn->recvmbox, (void **)&buf);
00497   }
00498 
00499   
00500 
00501     
00502   DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", buf, conn->err));
00503 
00504 
00505   return buf;
00506 }
00507 /*-----------------------------------------------------------------------------------*/
00508 err_t
00509 netconn_send(struct netconn *conn, struct netbuf *buf)
00510 {
00511   struct api_msg *msg;
00512 
00513   if(conn == NULL) {
00514     return ERR_VAL;
00515   }
00516 
00517   if(conn->err != ERR_OK) {
00518     return conn->err;
00519   }
00520 
00521   if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00522     return (conn->err = ERR_MEM);
00523   }
00524 
00525   DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
00526   msg->type = API_MSG_SEND;
00527   msg->msg.conn = conn;
00528   msg->msg.msg.p = buf->p;
00529   api_msg_post(msg);
00530 
00531   sys_mbox_fetch(conn->mbox, NULL);
00532   memp_freep(MEMP_API_MSG, msg);
00533   return conn->err;
00534 }
00535 /*-----------------------------------------------------------------------------------*/
00536 err_t
00537 netconn_write(struct netconn *conn, void *dataptr, uInt16 size, uInt8 copy)
00538 {
00539   struct api_msg *msg;
00540   uInt16 len;
00541   
00542   if(conn == NULL) {
00543     return ERR_VAL;
00544   }
00545 
00546   if(conn->err != ERR_OK) {
00547     return conn->err;
00548   }
00549   
00550   if(conn->sem == SYS_SEM_NULL) {
00551     conn->sem = sys_sem_new(0);
00552     if(conn->sem == SYS_SEM_NULL) {
00553       return ERR_MEM;
00554     }
00555   }
00556 
00557   if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00558     return (conn->err = ERR_MEM);
00559   }
00560   msg->type = API_MSG_WRITE;
00561   msg->msg.conn = conn;
00562         
00563 
00564   conn->state = NETCONN_WRITE;
00565   while(conn->err == ERR_OK && size > 0) {
00566     msg->msg.msg.w.dataptr = dataptr;
00567     msg->msg.msg.w.copy = copy;
00568     
00569     if(conn->type == NETCONN_TCP) {
00570       if(tcp_sndbuf(conn->pcb.tcp) == 0) {
00571         sys_sem_wait(conn->sem);
00572         if(conn->err != ERR_OK) {
00573           goto ret;
00574         }
00575       }
00576       if(size > tcp_sndbuf(conn->pcb.tcp)) {
00577         /* We cannot send more than one send buffer's worth of data at a
00578            time. */
00579         len = tcp_sndbuf(conn->pcb.tcp);
00580       } else {
00581         len = size;
00582       }
00583     } else {
00584       len = size;
00585     }
00586     
00587     DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
00588     msg->msg.msg.w.len = len;
00589     api_msg_post(msg);
00590     sys_mbox_fetch(conn->mbox, NULL);    
00591     if(conn->err == ERR_OK) {
00592       dataptr = (void *)((char *)dataptr + len);
00593       size -= len;
00594     } else if(conn->err == ERR_MEM) {
00595       conn->err = ERR_OK;
00596       sys_sem_wait(conn->sem);
00597     } else {
00598       goto ret;
00599     }
00600   }
00601  ret:
00602   memp_freep(MEMP_API_MSG, msg);
00603   conn->state = NETCONN_NONE;
00604   if(conn->sem != SYS_SEM_NULL) {
00605     sys_sem_free(conn->sem);
00606     conn->sem = SYS_SEM_NULL;
00607   }
00608   return conn->err;
00609 }
00610 /*-----------------------------------------------------------------------------------*/
00611 err_t
00612 netconn_close(struct netconn *conn)
00613 {
00614   struct api_msg *msg;
00615 
00616   if(conn == NULL) {
00617     return ERR_VAL;
00618   }
00619   if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00620     return (conn->err = ERR_MEM);
00621   }
00622 
00623   conn->state = NETCONN_CLOSE;
00624  again:
00625   msg->type = API_MSG_CLOSE;
00626   msg->msg.conn = conn;
00627   api_msg_post(msg);
00628   sys_mbox_fetch(conn->mbox, NULL);
00629   if(conn->err == ERR_MEM &&
00630      conn->sem != SYS_SEM_NULL) {
00631     sys_sem_wait(conn->sem);
00632     goto again;
00633   }
00634   conn->state = NETCONN_NONE;
00635   memp_freep(MEMP_API_MSG, msg);
00636   return conn->err;
00637 }
00638 /*-----------------------------------------------------------------------------------*/
00639 err_t
00640 netconn_err(struct netconn *conn)
00641 {
00642   return conn->err;
00643 }
00644 /*-----------------------------------------------------------------------------------*/
00645 
00646 
00647 
00648 

Generated on Tue Dec 12 08:52:07 2006 for UbixOS V2 by  doxygen 1.4.7