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 #include <ubixos/types.h>
00037 
00038 #include "net/debug.h"
00039 #include "net/arch.h"
00040 #include "net/api_msg.h"
00041 #include "net/memp.h"
00042 #include "net/sys.h"
00043 #include "net/tcpip.h"
00044 
00045 
00046 static err_t
00047 recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
00048 {
00049   struct netconn *conn;
00050 
00051   conn = arg;
00052 
00053   if(conn == NULL) {
00054     pbuf_free(p);
00055     return ERR_VAL;
00056   }
00057   
00058   if(conn->recvmbox != SYS_MBOX_NULL) {
00059     conn->err = err;
00060     sys_mbox_post(conn->recvmbox, p);
00061   }  
00062   return ERR_OK;
00063 }
00064 
00065 static void
00066 recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
00067          struct ip_addr *addr, uInt16 port)
00068 {
00069   struct netbuf *buf;
00070   struct netconn *conn;
00071 
00072   conn = arg;
00073   
00074   if(conn == NULL) {
00075     pbuf_free(p);
00076     return;
00077   }
00078 
00079   if(conn->recvmbox != SYS_MBOX_NULL) {
00080     buf = memp_mallocp(MEMP_NETBUF);
00081     if(buf == NULL) {
00082       pbuf_free(p);
00083       return;
00084     } else {
00085       buf->p = p;
00086       buf->ptr = p;
00087       buf->fromaddr = addr;
00088       buf->fromport = port;
00089     }
00090     
00091     sys_mbox_post(conn->recvmbox, buf);
00092   }
00093 }
00094 
00095 static err_t
00096 poll_tcp(void *arg, struct tcp_pcb *pcb)
00097 {
00098   struct netconn *conn;
00099 
00100   conn = arg;
00101   if(conn != NULL &&
00102      (conn->state == NETCONN_WRITE || conn->state == NETCONN_CLOSE) &&
00103      conn->sem != SYS_SEM_NULL) {
00104     sys_sem_signal(conn->sem);
00105   }
00106   return ERR_OK;
00107 }
00108 
00109 static err_t
00110 sent_tcp(void *arg, struct tcp_pcb *pcb, uInt16 len)
00111 {
00112   struct netconn *conn;
00113 
00114   conn = arg;
00115   if(conn != NULL && conn->sem != SYS_SEM_NULL) {
00116     sys_sem_signal(conn->sem);
00117   }
00118   return ERR_OK;
00119 }
00120 
00121 static void
00122 err_tcp(void *arg, err_t err)
00123 {
00124   struct netconn *conn;
00125 
00126   conn = arg;
00127 
00128   conn->pcb.tcp = NULL;
00129 
00130   
00131   conn->err = err;
00132   if(conn->recvmbox != SYS_MBOX_NULL) {
00133     sys_mbox_post(conn->recvmbox, NULL);
00134   }
00135   if(conn->mbox != SYS_MBOX_NULL) {
00136     sys_mbox_post(conn->mbox, NULL);
00137   }
00138   if(conn->acceptmbox != SYS_MBOX_NULL) {
00139     sys_mbox_post(conn->acceptmbox, NULL);
00140   }
00141   if(conn->sem != SYS_SEM_NULL) {
00142     sys_sem_signal(conn->sem);
00143   }
00144 }
00145 
00146 static void
00147 setup_tcp(struct netconn *conn)
00148 {
00149   struct tcp_pcb *pcb;
00150   
00151   pcb = conn->pcb.tcp;
00152   tcp_arg(pcb, conn);
00153   tcp_recv(pcb, recv_tcp);
00154   tcp_sent(pcb, sent_tcp);
00155   tcp_poll(pcb, poll_tcp, 4);
00156   tcp_err(pcb, err_tcp);
00157 }
00158 
00159 static err_t
00160 accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
00161 {
00162   sys_mbox_t *mbox;
00163   struct netconn *newconn;
00164   
00165 #if API_MSG_DEBUG
00166 #if TCP_DEBUG
00167   tcp_debug_print_state(newpcb->state);
00168 #endif 
00169 #endif 
00170   mbox = (sys_mbox_t *)arg;
00171   newconn = memp_mallocp(MEMP_NETCONN);
00172   if(newconn == NULL) {
00173     return ERR_MEM;
00174   }
00175   newconn->type = NETCONN_TCP;
00176   newconn->pcb.tcp = newpcb;
00177   setup_tcp(newconn);
00178   newconn->recvmbox = sys_mbox_new();
00179   if(newconn->recvmbox == SYS_MBOX_NULL) {
00180     memp_free(MEMP_NETCONN, newconn);
00181     return ERR_MEM;
00182   }
00183   newconn->mbox = sys_mbox_new();
00184   if(newconn->mbox == SYS_MBOX_NULL) {
00185     sys_mbox_free(newconn->recvmbox);
00186     memp_free(MEMP_NETCONN, newconn);
00187     return ERR_MEM;
00188   }
00189   newconn->sem = sys_sem_new(0);
00190   if(newconn->sem == SYS_SEM_NULL) {
00191     sys_mbox_free(newconn->recvmbox);
00192     sys_mbox_free(newconn->mbox);
00193     memp_free(MEMP_NETCONN, newconn);
00194     return ERR_MEM;
00195   }
00196   newconn->acceptmbox = SYS_MBOX_NULL;
00197   newconn->err = err;
00198   sys_mbox_post(*mbox, newconn);
00199   return ERR_OK;
00200 }
00201 
00202 static void
00203 do_newconn(struct api_msg_msg *msg)
00204 {
00205 }
00206 
00207 static void
00208 do_delconn(struct api_msg_msg *msg)
00209 {
00210   if(msg->conn->pcb.tcp != NULL) {
00211     switch(msg->conn->type) {
00212     case NETCONN_UDPLITE:
00213       
00214     case NETCONN_UDPNOCHKSUM:
00215       
00216     case NETCONN_UDP:
00217       msg->conn->pcb.udp->recv_arg = NULL;
00218       udp_remove(msg->conn->pcb.udp);
00219       break;
00220     case NETCONN_TCP:
00221       tcp_arg(msg->conn->pcb.tcp, NULL);
00222       tcp_sent(msg->conn->pcb.tcp, NULL);
00223       tcp_recv(msg->conn->pcb.tcp, NULL);
00224       tcp_accept(msg->conn->pcb.tcp, NULL);
00225       tcp_poll(msg->conn->pcb.tcp, NULL, 0);
00226       tcp_err(msg->conn->pcb.tcp, NULL);
00227       if(msg->conn->pcb.tcp->state == LISTEN) {
00228         tcp_close(msg->conn->pcb.tcp);
00229       } else {
00230         if(tcp_close(msg->conn->pcb.tcp) != ERR_OK) {
00231           tcp_abort(msg->conn->pcb.tcp);
00232         }
00233       }
00234     break;
00235     }
00236   }
00237   if(msg->conn->mbox != SYS_MBOX_NULL) {
00238     sys_mbox_post(msg->conn->mbox, NULL);
00239   }
00240 }
00241 
00242 static void
00243 do_bind(struct api_msg_msg *msg)
00244 {
00245   if(msg->conn->pcb.tcp == NULL) {
00246     switch(msg->conn->type) {
00247     case NETCONN_UDPLITE:
00248       msg->conn->pcb.udp = udp_new();
00249       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
00250       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
00251       break;
00252     case NETCONN_UDPNOCHKSUM:
00253       msg->conn->pcb.udp = udp_new();
00254       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
00255       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
00256       break;
00257     case NETCONN_UDP:
00258       msg->conn->pcb.udp = udp_new();
00259       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
00260       break;
00261     case NETCONN_TCP:
00262       msg->conn->pcb.tcp = tcp_new();
00263       setup_tcp(msg->conn);
00264       break;
00265     }
00266   }
00267   switch(msg->conn->type) {
00268   case NETCONN_UDPLITE:
00269     
00270   case NETCONN_UDPNOCHKSUM:
00271     
00272   case NETCONN_UDP:
00273     udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
00274     break;
00275   case NETCONN_TCP:
00276     msg->conn->err = tcp_bind(msg->conn->pcb.tcp,
00277                               msg->msg.bc.ipaddr, msg->msg.bc.port);
00278     break;
00279   }
00280   sys_mbox_post(msg->conn->mbox, NULL);
00281 }
00282 
00283 static err_t
00284 do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
00285 {
00286   struct netconn *conn;
00287 
00288   conn = arg;
00289 
00290   if(conn == NULL) {
00291     return ERR_VAL;
00292   }
00293   
00294   conn->err = err;
00295 
00296   if(conn->type == NETCONN_TCP && err == ERR_OK) {
00297     setup_tcp(conn);
00298   }    
00299   
00300   sys_mbox_post(conn->mbox, NULL);
00301   return ERR_OK;
00302 }
00303 
00304 static void
00305 do_connect(struct api_msg_msg *msg)
00306 {
00307   if(msg->conn->pcb.tcp == NULL) {
00308     switch(msg->conn->type) {
00309     case NETCONN_UDPLITE:
00310       msg->conn->pcb.udp = udp_new();
00311       if(msg->conn->pcb.udp == NULL) {
00312         msg->conn->err = ERR_MEM;
00313         sys_mbox_post(msg->conn->mbox, NULL);
00314         return;
00315       }
00316       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
00317       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
00318       break;
00319     case NETCONN_UDPNOCHKSUM:
00320       msg->conn->pcb.udp = udp_new();
00321       if(msg->conn->pcb.udp == NULL) {
00322         msg->conn->err = ERR_MEM;
00323         sys_mbox_post(msg->conn->mbox, NULL);
00324         return;
00325       }
00326       udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
00327       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
00328       break;
00329     case NETCONN_UDP:
00330       msg->conn->pcb.udp = udp_new();
00331       if(msg->conn->pcb.udp == NULL) {
00332         msg->conn->err = ERR_MEM;
00333         sys_mbox_post(msg->conn->mbox, NULL);
00334         return;
00335       }
00336       udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
00337       break;
00338     case NETCONN_TCP:
00339       msg->conn->pcb.tcp = tcp_new();      
00340       if(msg->conn->pcb.tcp == NULL) {
00341         msg->conn->err = ERR_MEM;
00342         sys_mbox_post(msg->conn->mbox, NULL);
00343         return;
00344       }
00345       break;
00346     }
00347   }
00348   switch(msg->conn->type) {
00349   case NETCONN_UDPLITE:
00350     
00351   case NETCONN_UDPNOCHKSUM:
00352     
00353   case NETCONN_UDP:
00354     udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
00355     sys_mbox_post(msg->conn->mbox, NULL);
00356     break;
00357   case NETCONN_TCP:
00358     
00359     setup_tcp(msg->conn);
00360     tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
00361                 do_connected);
00362     
00363     break;
00364   }
00365 }
00366 
00367 static void
00368 do_listen(struct api_msg_msg *msg)
00369 {
00370   if(msg->conn->pcb.tcp != NULL) {
00371     switch(msg->conn->type) {
00372     case NETCONN_UDPLITE:
00373       
00374     case NETCONN_UDPNOCHKSUM:
00375       
00376     case NETCONN_UDP:
00377       DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for UDP.\n"));
00378       break;
00379     case NETCONN_TCP:
00380       msg->conn->pcb.tcp = tcp_listen(msg->conn->pcb.tcp);
00381       if(msg->conn->pcb.tcp == NULL) {
00382         msg->conn->err = ERR_MEM;
00383       } else {
00384         if(msg->conn->acceptmbox == SYS_MBOX_NULL) {
00385           msg->conn->acceptmbox = sys_mbox_new();
00386           if(msg->conn->acceptmbox == SYS_MBOX_NULL) {
00387             msg->conn->err = ERR_MEM;
00388             break;
00389           }
00390         }
00391         tcp_arg(msg->conn->pcb.tcp, (void *)&(msg->conn->acceptmbox));
00392         tcp_accept(msg->conn->pcb.tcp, accept_function);
00393       }
00394       break;
00395     }
00396   }
00397   sys_mbox_post(msg->conn->mbox, NULL);
00398 }
00399 
00400 static void
00401 do_accept(struct api_msg_msg *msg)
00402 {
00403   if(msg->conn->pcb.tcp != NULL) {
00404     switch(msg->conn->type) {
00405     case NETCONN_UDPLITE:
00406       
00407     case NETCONN_UDPNOCHKSUM:
00408       
00409     case NETCONN_UDP:    
00410       DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for UDP.\n"));
00411       break;
00412     case NETCONN_TCP:
00413       break;
00414     }
00415   }
00416 }
00417 
00418 static void
00419 do_send(struct api_msg_msg *msg)
00420 {
00421   if(msg->conn->pcb.tcp != NULL) {
00422     switch(msg->conn->type) {
00423     case NETCONN_UDPLITE:
00424       
00425     case NETCONN_UDPNOCHKSUM:
00426       
00427     case NETCONN_UDP:
00428       udp_send(msg->conn->pcb.udp, msg->msg.p);
00429       break;
00430     case NETCONN_TCP:
00431       break;
00432     }
00433   }
00434   sys_mbox_post(msg->conn->mbox, NULL);
00435 }
00436 
00437 static void
00438 do_recv(struct api_msg_msg *msg)
00439 {
00440   if(msg->conn->pcb.tcp != NULL) {
00441     if(msg->conn->type == NETCONN_TCP) {
00442       tcp_recved(msg->conn->pcb.tcp, msg->msg.len);
00443     }
00444   }
00445   sys_mbox_post(msg->conn->mbox, NULL);
00446 }
00447 
00448 static void
00449 do_write(struct api_msg_msg *msg)
00450 {
00451   err_t err;
00452   if(msg->conn->pcb.tcp != NULL) {
00453     switch(msg->conn->type) {
00454     case NETCONN_UDPLITE:
00455       
00456     case NETCONN_UDPNOCHKSUM:
00457       
00458     case NETCONN_UDP:
00459       msg->conn->err = ERR_VAL;
00460       break;
00461     case NETCONN_TCP:      
00462       err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
00463                       msg->msg.w.len, msg->msg.w.copy);
00464       
00465 
00466 
00467 
00468       if(err == ERR_OK && msg->conn->pcb.tcp->unacked == NULL) {
00469         tcp_output(msg->conn->pcb.tcp);
00470       }
00471       msg->conn->err = err;
00472       break;
00473     }
00474   }
00475   sys_mbox_post(msg->conn->mbox, NULL);
00476 }
00477 
00478 static void
00479 do_close(struct api_msg_msg *msg)
00480 {
00481   err_t err;
00482   if(msg->conn->pcb.tcp != NULL) {
00483     switch(msg->conn->type) {
00484     case NETCONN_UDPLITE:
00485       
00486     case NETCONN_UDPNOCHKSUM:
00487       
00488     case NETCONN_UDP:
00489       break;
00490     case NETCONN_TCP:
00491       if(msg->conn->pcb.tcp->state == LISTEN) {
00492         err = tcp_close(msg->conn->pcb.tcp);
00493       } else {
00494         err = tcp_close(msg->conn->pcb.tcp);
00495       }
00496       msg->conn->err = err;      
00497       break;
00498     }
00499   }
00500   sys_mbox_post(msg->conn->mbox, NULL);
00501 }
00502 
00503 typedef void (* api_msg_decode)(struct api_msg_msg *msg);
00504 static api_msg_decode decode[API_MSG_MAX] = {
00505   do_newconn,
00506   do_delconn,
00507   do_bind,
00508   do_connect,
00509   do_listen,
00510   do_accept,
00511   do_send,
00512   do_recv,
00513   do_write,
00514   do_close
00515   };
00516 void
00517 api_msg_input(struct api_msg *msg)
00518 {  
00519   decode[msg->type](&(msg->msg));
00520 }
00521 
00522 void
00523 api_msg_post(struct api_msg *msg)
00524 {
00525   tcpip_apimsg(msg);
00526 }
00527 
00528 
00529