00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
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   
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   
00170 
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   
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   
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   
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     
00466 
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     
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         
00578 
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