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