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 "lwip/opt.h"
00040 #include "lwip/api.h"
00041 #include "lwip/api_msg.h"
00042 #include "lwip/memp.h"
00043
00044
00045 struct
00046 netbuf *netbuf_new(void)
00047 {
00048 struct netbuf *buf;
00049
00050 buf = memp_mallocp(MEMP_NETBUF);
00051 if(buf != NULL) {
00052 buf->p = NULL;
00053 buf->ptr = NULL;
00054 return buf;
00055 } else {
00056 return NULL;
00057 }
00058 }
00059
00060 void
00061 netbuf_delete(struct netbuf *buf)
00062 {
00063 if(buf != NULL) {
00064 if(buf->p != NULL) {
00065 pbuf_free(buf->p);
00066 buf->p = buf->ptr = NULL;
00067 }
00068 memp_freep(MEMP_NETBUF, buf);
00069 }
00070 }
00071
00072 void *
00073 netbuf_alloc(struct netbuf *buf, u16_t size)
00074 {
00075
00076 if(buf->p != NULL) {
00077 pbuf_free(buf->p);
00078 }
00079 buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM);
00080 if(buf->p == NULL) {
00081 return NULL;
00082 }
00083 buf->ptr = buf->p;
00084 return buf->p->payload;
00085 }
00086
00087 void
00088 netbuf_free(struct netbuf *buf)
00089 {
00090 if(buf->p != NULL) {
00091 pbuf_free(buf->p);
00092 }
00093 buf->p = buf->ptr = NULL;
00094 }
00095
00096 void
00097 netbuf_ref(struct netbuf *buf, void *dataptr, u16_t size)
00098 {
00099 if(buf->p != NULL) {
00100 pbuf_free(buf->p);
00101 }
00102 buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF);
00103 buf->p->payload = dataptr;
00104 buf->p->len = buf->p->tot_len = size;
00105 buf->ptr = buf->p;
00106 }
00107
00108 void
00109 netbuf_chain(struct netbuf *head, struct netbuf *tail)
00110 {
00111 pbuf_chain(head->p, tail->p);
00112 head->ptr = head->p;
00113 memp_freep(MEMP_NETBUF, tail);
00114 }
00115
00116 u16_t
00117 netbuf_len(struct netbuf *buf)
00118 {
00119 return buf->p->tot_len;
00120 }
00121
00122 err_t
00123 netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len)
00124 {
00125 if(buf->ptr == NULL) {
00126 return ERR_BUF;
00127 }
00128 *dataptr = buf->ptr->payload;
00129 *len = buf->ptr->len;
00130 return ERR_OK;
00131 }
00132
00133 s8_t
00134 netbuf_next(struct netbuf *buf)
00135 {
00136 if(buf->ptr->next == NULL) {
00137 return -1;
00138 }
00139 buf->ptr = buf->ptr->next;
00140 if(buf->ptr->next == NULL) {
00141 return 1;
00142 }
00143 return 0;
00144 }
00145
00146 void
00147 netbuf_first(struct netbuf *buf)
00148 {
00149 buf->ptr = buf->p;
00150 }
00151
00152 void
00153 netbuf_copy_partial(struct netbuf *buf, void *dataptr, u16_t len, u16_t offset)
00154 {
00155 struct pbuf *p;
00156 u16_t i, left;
00157
00158 left = 0;
00159
00160 if(buf == NULL) {
00161 return;
00162 }
00163
00164
00165
00166 for(p = buf->p; left < len && p != NULL; p = p->next) {
00167 if(offset != 0 && offset >= p->len) {
00168 offset -= p->len;
00169 } else {
00170 for(i = offset; i < p->len; ++i) {
00171 ((char *)dataptr)[left] = ((char *)p->payload)[i];
00172 if(++left >= len) {
00173 return;
00174 }
00175 }
00176 offset = 0;
00177 }
00178 }
00179 }
00180
00181 void
00182 netbuf_copy(struct netbuf *buf, void *dataptr, u16_t len)
00183 {
00184 netbuf_copy_partial(buf, dataptr, len, 0);
00185 }
00186
00187 struct ip_addr *
00188 netbuf_fromaddr(struct netbuf *buf)
00189 {
00190 return buf->fromaddr;
00191 }
00192
00193 u16_t
00194 netbuf_fromport(struct netbuf *buf)
00195 {
00196 return buf->fromport;
00197 }
00198
00199 struct
00200 netconn *netconn_new(enum netconn_type t)
00201 {
00202 struct netconn *conn;
00203
00204 conn = memp_mallocp(MEMP_NETCONN);
00205 if(conn == NULL) {
00206 return NULL;
00207 }
00208 conn->type = t;
00209 conn->pcb.tcp = NULL;
00210
00211 if((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) {
00212 memp_freep(MEMP_NETCONN, conn);
00213 return NULL;
00214 }
00215 conn->recvmbox = SYS_MBOX_NULL;
00216 conn->acceptmbox = SYS_MBOX_NULL;
00217 conn->sem = SYS_SEM_NULL;
00218 conn->state = NETCONN_NONE;
00219 conn->socket = 0;
00220 conn->callback = 0;
00221 conn->recv_avail = 0;
00222 return conn;
00223 }
00224
00225 struct
00226 netconn *netconn_new_with_callback(enum netconn_type t,
00227 void (*callback)(struct netconn *, enum netconn_evt, u16_t len))
00228 {
00229 struct netconn *conn;
00230
00231
00232 conn = netconn_new(t);
00233 if (conn)
00234 conn->callback = callback;
00235 return conn;
00236 }
00237
00238
00239 err_t
00240 netconn_delete(struct netconn *conn)
00241 {
00242 struct api_msg *msg;
00243 void *mem;
00244
00245 if(conn == NULL) {
00246 return ERR_OK;
00247 }
00248
00249 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00250 return ERR_MEM;
00251 }
00252
00253 msg->type = API_MSG_DELCONN;
00254 msg->msg.conn = conn;
00255 api_msg_post(msg);
00256 sys_mbox_fetch(conn->mbox, NULL);
00257 memp_freep(MEMP_API_MSG, msg);
00258
00259
00260 if(conn->recvmbox != SYS_MBOX_NULL) {
00261 while(sys_arch_mbox_fetch(conn->recvmbox, &mem, 1) != 0) {
00262 if(conn->type == NETCONN_TCP) {
00263 pbuf_free((struct pbuf *)mem);
00264 } else {
00265 netbuf_delete((struct netbuf *)mem);
00266 }
00267 }
00268 sys_mbox_free(conn->recvmbox);
00269 conn->recvmbox = SYS_MBOX_NULL;
00270 }
00271
00272
00273
00274 if(conn->acceptmbox != SYS_MBOX_NULL) {
00275 while(sys_arch_mbox_fetch(conn->acceptmbox, &mem, 1) != 0) {
00276 netconn_delete((struct netconn *)mem);
00277 }
00278
00279 sys_mbox_free(conn->acceptmbox);
00280 conn->acceptmbox = SYS_MBOX_NULL;
00281 }
00282
00283 sys_mbox_free(conn->mbox);
00284 conn->mbox = SYS_MBOX_NULL;
00285 if(conn->sem != SYS_SEM_NULL) {
00286 sys_sem_free(conn->sem);
00287 }
00288
00289 memp_free(MEMP_NETCONN, conn);
00290 return ERR_OK;
00291 }
00292
00293 enum netconn_type
00294 netconn_type(struct netconn *conn)
00295 {
00296 return conn->type;
00297 }
00298
00299 err_t
00300 netconn_peer(struct netconn *conn, struct ip_addr *addr,
00301 u16_t *port)
00302 {
00303 switch(conn->type) {
00304 case NETCONN_UDPLITE:
00305 case NETCONN_UDPNOCHKSUM:
00306 case NETCONN_UDP:
00307 if (conn->pcb.udp == NULL ||
00308 ((conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0))
00309 return ERR_CONN;
00310 *addr = (conn->pcb.udp->remote_ip);
00311 *port = conn->pcb.udp->remote_port;
00312 break;
00313 case NETCONN_TCP:
00314 if(conn->pcb.tcp == NULL)
00315 return ERR_CONN;
00316 *addr = (conn->pcb.tcp->remote_ip);
00317 *port = conn->pcb.tcp->remote_port;
00318 break;
00319 }
00320 return (conn->err = ERR_OK);
00321 }
00322
00323 err_t
00324 netconn_addr(struct netconn *conn, struct ip_addr **addr,
00325 u16_t *port)
00326 {
00327 switch(conn->type) {
00328 case NETCONN_UDPLITE:
00329 case NETCONN_UDPNOCHKSUM:
00330 case NETCONN_UDP:
00331 *addr = &(conn->pcb.udp->local_ip);
00332 *port = conn->pcb.udp->local_port;
00333 break;
00334 case NETCONN_TCP:
00335 *addr = &(conn->pcb.tcp->local_ip);
00336 *port = conn->pcb.tcp->local_port;
00337 break;
00338 }
00339 return (conn->err = ERR_OK);
00340 }
00341
00342 err_t
00343 netconn_bind(struct netconn *conn, struct ip_addr *addr,
00344 u16_t port)
00345 {
00346 struct api_msg *msg;
00347
00348 if(conn == NULL) {
00349 return ERR_VAL;
00350 }
00351
00352 if(conn->type != NETCONN_TCP &&
00353 conn->recvmbox == SYS_MBOX_NULL) {
00354 if((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
00355 return ERR_MEM;
00356 }
00357 }
00358
00359 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00360 return (conn->err = ERR_MEM);
00361 }
00362 msg->type = API_MSG_BIND;
00363 msg->msg.conn = conn;
00364 msg->msg.msg.bc.ipaddr = addr;
00365 msg->msg.msg.bc.port = port;
00366 api_msg_post(msg);
00367 sys_mbox_fetch(conn->mbox, NULL);
00368 memp_freep(MEMP_API_MSG, msg);
00369 return conn->err;
00370 }
00371
00372
00373 err_t
00374 netconn_connect(struct netconn *conn, struct ip_addr *addr,
00375 u16_t port)
00376 {
00377 struct api_msg *msg;
00378
00379 if(conn == NULL) {
00380 return ERR_VAL;
00381 }
00382
00383
00384 if(conn->recvmbox == SYS_MBOX_NULL) {
00385 if((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) {
00386 return ERR_MEM;
00387 }
00388 }
00389
00390 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00391 return ERR_MEM;
00392 }
00393 msg->type = API_MSG_CONNECT;
00394 msg->msg.conn = conn;
00395 msg->msg.msg.bc.ipaddr = addr;
00396 msg->msg.msg.bc.port = port;
00397 api_msg_post(msg);
00398 sys_mbox_fetch(conn->mbox, NULL);
00399 memp_freep(MEMP_API_MSG, msg);
00400 return conn->err;
00401 }
00402
00403 err_t
00404 netconn_disconnect(struct netconn *conn)
00405 {
00406 struct api_msg *msg;
00407
00408 if(conn == NULL) {
00409 return ERR_VAL;
00410 }
00411
00412 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00413 return ERR_MEM;
00414 }
00415 msg->type = API_MSG_DISCONNECT;
00416 msg->msg.conn = conn;
00417 api_msg_post(msg);
00418 sys_mbox_fetch(conn->mbox, NULL);
00419 memp_freep(MEMP_API_MSG, msg);
00420 return conn->err;
00421
00422 }
00423
00424 err_t
00425 netconn_listen(struct netconn *conn)
00426 {
00427 struct api_msg *msg;
00428
00429 if(conn == NULL) {
00430 return ERR_VAL;
00431 }
00432
00433 if(conn->acceptmbox == SYS_MBOX_NULL) {
00434 conn->acceptmbox = sys_mbox_new();
00435 if(conn->acceptmbox == SYS_MBOX_NULL) {
00436 return ERR_MEM;
00437 }
00438 }
00439
00440 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00441 return (conn->err = ERR_MEM);
00442 }
00443 msg->type = API_MSG_LISTEN;
00444 msg->msg.conn = conn;
00445 api_msg_post(msg);
00446 sys_mbox_fetch(conn->mbox, NULL);
00447 memp_freep(MEMP_API_MSG, msg);
00448 return conn->err;
00449 }
00450
00451 struct netconn *
00452 netconn_accept(struct netconn *conn)
00453 {
00454 struct netconn *newconn;
00455
00456 if(conn == NULL) {
00457 return NULL;
00458 }
00459
00460 sys_mbox_fetch(conn->acceptmbox, (void **)&newconn);
00461
00462 if (conn->callback)
00463 (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, 0);
00464
00465 return newconn;
00466 }
00467
00468 struct netbuf *
00469 netconn_recv(struct netconn *conn)
00470 {
00471 struct api_msg *msg;
00472 struct netbuf *buf;
00473 struct pbuf *p;
00474 u16_t len;
00475
00476 if(conn == NULL) {
00477 return NULL;
00478 }
00479
00480 if(conn->recvmbox == SYS_MBOX_NULL) {
00481 conn->err = ERR_CONN;
00482 return NULL;
00483 }
00484
00485 if(conn->err != ERR_OK) {
00486 return NULL;
00487 }
00488
00489 if(conn->type == NETCONN_TCP) {
00490 if(conn->pcb.tcp->state == LISTEN) {
00491 conn->err = ERR_CONN;
00492 return NULL;
00493 }
00494
00495
00496 buf = memp_mallocp(MEMP_NETBUF);
00497
00498 if(buf == NULL) {
00499 conn->err = ERR_MEM;
00500 return NULL;
00501 }
00502
00503 sys_mbox_fetch(conn->recvmbox, (void **)&p);
00504
00505 if (p != NULL)
00506 {
00507 len = p->tot_len;
00508 conn->recv_avail -= len;
00509 }
00510 else
00511 len = 0;
00512
00513
00514 if (conn->callback)
00515 (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, len);
00516
00517
00518
00519 if(p == NULL) {
00520 memp_freep(MEMP_NETBUF, buf);
00521 sys_mbox_free(conn->recvmbox);
00522 conn->recvmbox = SYS_MBOX_NULL;
00523 return NULL;
00524 }
00525
00526 buf->p = p;
00527 buf->ptr = p;
00528 buf->fromport = 0;
00529 buf->fromaddr = NULL;
00530
00531
00532 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00533 conn->err = ERR_MEM;
00534 return buf;
00535 }
00536 msg->type = API_MSG_RECV;
00537 msg->msg.conn = conn;
00538 if(buf != NULL) {
00539 msg->msg.msg.len = buf->p->tot_len;
00540 } else {
00541 msg->msg.msg.len = 1;
00542 }
00543 api_msg_post(msg);
00544
00545 sys_mbox_fetch(conn->mbox, NULL);
00546 memp_freep(MEMP_API_MSG, msg);
00547 } else {
00548 sys_mbox_fetch(conn->recvmbox, (void **)&buf);
00549 conn->recv_avail -= buf->p->tot_len;
00550
00551 if (conn->callback)
00552 (*conn->callback)(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
00553 }
00554
00555
00556
00557
00558 DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));
00559
00560
00561 return buf;
00562 }
00563
00564 err_t
00565 netconn_send(struct netconn *conn, struct netbuf *buf)
00566 {
00567 struct api_msg *msg;
00568
00569 if(conn == NULL) {
00570 return ERR_VAL;
00571 }
00572
00573 if(conn->err != ERR_OK) {
00574 return conn->err;
00575 }
00576
00577 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00578 return (conn->err = ERR_MEM);
00579 }
00580
00581 DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %d bytes\n", buf->p->tot_len));
00582 msg->type = API_MSG_SEND;
00583 msg->msg.conn = conn;
00584 msg->msg.msg.p = buf->p;
00585 api_msg_post(msg);
00586
00587 sys_mbox_fetch(conn->mbox, NULL);
00588 memp_freep(MEMP_API_MSG, msg);
00589 return conn->err;
00590 }
00591
00592 err_t
00593 netconn_write(struct netconn *conn, void *dataptr, u16_t size, u8_t copy)
00594 {
00595 struct api_msg *msg;
00596 u16_t len;
00597
00598 if(conn == NULL) {
00599 return ERR_VAL;
00600 }
00601
00602 if(conn->err != ERR_OK) {
00603 return conn->err;
00604 }
00605
00606 if(conn->sem == SYS_SEM_NULL) {
00607 conn->sem = sys_sem_new(0);
00608 if(conn->sem == SYS_SEM_NULL) {
00609 return ERR_MEM;
00610 }
00611 }
00612
00613 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00614 return (conn->err = ERR_MEM);
00615 }
00616 msg->type = API_MSG_WRITE;
00617 msg->msg.conn = conn;
00618
00619
00620 conn->state = NETCONN_WRITE;
00621 while(conn->err == ERR_OK && size > 0) {
00622 msg->msg.msg.w.dataptr = dataptr;
00623 msg->msg.msg.w.copy = copy;
00624
00625 if(conn->type == NETCONN_TCP) {
00626 if(tcp_sndbuf(conn->pcb.tcp) == 0) {
00627 sys_sem_wait(conn->sem);
00628 if(conn->err != ERR_OK) {
00629 goto ret;
00630 }
00631 }
00632 if(size > tcp_sndbuf(conn->pcb.tcp)) {
00633
00634
00635 len = tcp_sndbuf(conn->pcb.tcp);
00636 } else {
00637 len = size;
00638 }
00639 } else {
00640 len = size;
00641 }
00642
00643 DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy));
00644 msg->msg.msg.w.len = len;
00645 api_msg_post(msg);
00646 sys_mbox_fetch(conn->mbox, NULL);
00647 if(conn->err == ERR_OK) {
00648 dataptr = (void *)((char *)dataptr + len);
00649 size -= len;
00650 } else if(conn->err == ERR_MEM) {
00651 conn->err = ERR_OK;
00652 sys_sem_wait(conn->sem);
00653 } else {
00654 goto ret;
00655 }
00656 }
00657 ret:
00658 memp_freep(MEMP_API_MSG, msg);
00659 conn->state = NETCONN_NONE;
00660 if(conn->sem != SYS_SEM_NULL) {
00661 sys_sem_free(conn->sem);
00662 conn->sem = SYS_SEM_NULL;
00663 }
00664
00665 return conn->err;
00666 }
00667
00668 err_t
00669 netconn_close(struct netconn *conn)
00670 {
00671 struct api_msg *msg;
00672
00673 if(conn == NULL) {
00674 return ERR_VAL;
00675 }
00676 if((msg = memp_mallocp(MEMP_API_MSG)) == NULL) {
00677 return (conn->err = ERR_MEM);
00678 }
00679
00680 conn->state = NETCONN_CLOSE;
00681 again:
00682 msg->type = API_MSG_CLOSE;
00683 msg->msg.conn = conn;
00684 api_msg_post(msg);
00685 sys_mbox_fetch(conn->mbox, NULL);
00686 if(conn->err == ERR_MEM &&
00687 conn->sem != SYS_SEM_NULL) {
00688 sys_sem_wait(conn->sem);
00689 goto again;
00690 }
00691 conn->state = NETCONN_NONE;
00692 memp_freep(MEMP_API_MSG, msg);
00693 return conn->err;
00694 }
00695
00696 err_t
00697 netconn_err(struct netconn *conn)
00698 {
00699 return conn->err;
00700 }
00701