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
00041 #if LWIP_NETCONN
00042
00043 #include "lwip/api_msg.h"
00044
00045 #include "lwip/ip.h"
00046 #include "lwip/udp.h"
00047 #include "lwip/tcp.h"
00048 #include "lwip/raw.h"
00049
00050 #include "lwip/memp.h"
00051 #include "lwip/tcpip.h"
00052 #include "lwip/igmp.h"
00053 #include "lwip/dns.h"
00054
00055 #include <string.h>
00056
00057
00058 #if LWIP_TCP
00059 static err_t do_writemore(struct netconn *conn);
00060 static void do_close_internal(struct netconn *conn);
00061 #endif
00062
00063 #if LWIP_RAW
00064
00065
00066
00067
00068
00069
00070
00071 static u8_t
00072 recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
00073 struct ip_addr *addr)
00074 {
00075 struct pbuf *q;
00076 struct netbuf *buf;
00077 struct netconn *conn;
00078 #if LWIP_SO_RCVBUF
00079 int recv_avail;
00080 #endif
00081
00082 LWIP_UNUSED_ARG(addr);
00083 conn = arg;
00084
00085 #if LWIP_SO_RCVBUF
00086 SYS_ARCH_GET(conn->recv_avail, recv_avail);
00087 if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&
00088 ((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) {
00089 #else
00090 if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
00091 #endif
00092
00093 q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);
00094 if(q != NULL) {
00095 if (pbuf_copy(q, p) != ERR_OK) {
00096 pbuf_free(q);
00097 q = NULL;
00098 }
00099 }
00100
00101 if(q != NULL) {
00102 buf = memp_malloc(MEMP_NETBUF);
00103 if (buf == NULL) {
00104 pbuf_free(q);
00105 return 0;
00106 }
00107
00108 buf->p = q;
00109 buf->ptr = q;
00110 buf->addr = &(((struct ip_hdr*)(q->payload))->src);
00111 buf->port = pcb->protocol;
00112
00113 if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
00114 netbuf_delete(buf);
00115 return 0;
00116 } else {
00117 SYS_ARCH_INC(conn->recv_avail, q->tot_len);
00118
00119 API_EVENT(conn, NETCONN_EVT_RCVPLUS, q->tot_len);
00120 }
00121 }
00122 }
00123
00124 return 0;
00125 }
00126 #endif
00127
00128 #if LWIP_UDP
00129
00130
00131
00132
00133
00134
00135 static void
00136 recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
00137 struct ip_addr *addr, u16_t port)
00138 {
00139 struct netbuf *buf;
00140 struct netconn *conn;
00141 #if LWIP_SO_RCVBUF
00142 int recv_avail;
00143 #endif
00144
00145 LWIP_UNUSED_ARG(pcb);
00146 LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL);
00147 LWIP_ASSERT("recv_udp must have an argument", arg != NULL);
00148 conn = arg;
00149 LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
00150
00151 #if LWIP_SO_RCVBUF
00152 SYS_ARCH_GET(conn->recv_avail, recv_avail);
00153 if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||
00154 ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
00155 #else
00156 if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
00157 #endif
00158 pbuf_free(p);
00159 return;
00160 }
00161
00162 buf = memp_malloc(MEMP_NETBUF);
00163 if (buf == NULL) {
00164 pbuf_free(p);
00165 return;
00166 } else {
00167 buf->p = p;
00168 buf->ptr = p;
00169 buf->addr = addr;
00170 buf->port = port;
00171 #if LWIP_NETBUF_RECVINFO
00172 {
00173 const struct ip_hdr* iphdr = ip_current_header();
00174
00175 const struct udp_hdr* udphdr = (void*)(((char*)iphdr) + IPH_LEN(iphdr));
00176 buf->toaddr = (struct ip_addr*)&iphdr->dest;
00177 buf->toport = udphdr->dest;
00178 }
00179 #endif
00180 }
00181
00182 if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
00183 netbuf_delete(buf);
00184 return;
00185 } else {
00186 SYS_ARCH_INC(conn->recv_avail, p->tot_len);
00187
00188 API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
00189 }
00190 }
00191 #endif
00192
00193 #if LWIP_TCP
00194
00195
00196
00197
00198
00199
00200 static err_t
00201 recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
00202 {
00203 struct netconn *conn;
00204 u16_t len;
00205
00206 LWIP_UNUSED_ARG(pcb);
00207 LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL);
00208 LWIP_ASSERT("recv_tcp must have an argument", arg != NULL);
00209 conn = arg;
00210 LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
00211
00212 if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
00213 return ERR_VAL;
00214 }
00215
00216 conn->err = err;
00217 if (p != NULL) {
00218 len = p->tot_len;
00219 SYS_ARCH_INC(conn->recv_avail, len);
00220 } else {
00221 len = 0;
00222 }
00223
00224 if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {
00225 return ERR_MEM;
00226 } else {
00227
00228 API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
00229 }
00230
00231 return ERR_OK;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 static err_t
00246 poll_tcp(void *arg, struct tcp_pcb *pcb)
00247 {
00248 struct netconn *conn = arg;
00249
00250 LWIP_UNUSED_ARG(pcb);
00251 LWIP_ASSERT("conn != NULL", (conn != NULL));
00252
00253 if (conn->state == NETCONN_WRITE) {
00254 do_writemore(conn);
00255 } else if (conn->state == NETCONN_CLOSE) {
00256 do_close_internal(conn);
00257 }
00258
00259 return ERR_OK;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269 static err_t
00270 sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
00271 {
00272 struct netconn *conn = arg;
00273
00274 LWIP_UNUSED_ARG(pcb);
00275 LWIP_ASSERT("conn != NULL", (conn != NULL));
00276
00277 if (conn->state == NETCONN_WRITE) {
00278 LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
00279 do_writemore(conn);
00280 } else if (conn->state == NETCONN_CLOSE) {
00281 do_close_internal(conn);
00282 }
00283
00284 if (conn) {
00285 if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)) {
00286 API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
00287 }
00288 }
00289
00290 return ERR_OK;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300 static void
00301 err_tcp(void *arg, err_t err)
00302 {
00303 struct netconn *conn;
00304
00305 conn = arg;
00306 LWIP_ASSERT("conn != NULL", (conn != NULL));
00307
00308 conn->pcb.tcp = NULL;
00309
00310 conn->err = err;
00311 if (conn->recvmbox != SYS_MBOX_NULL) {
00312
00313 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
00314 sys_mbox_post(conn->recvmbox, NULL);
00315 }
00316 if (conn->op_completed != SYS_SEM_NULL && conn->state == NETCONN_CONNECT) {
00317 conn->state = NETCONN_NONE;
00318 sys_sem_signal(conn->op_completed);
00319 }
00320 if (conn->acceptmbox != SYS_MBOX_NULL) {
00321
00322 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
00323 sys_mbox_post(conn->acceptmbox, NULL);
00324 }
00325 if ((conn->state == NETCONN_WRITE) || (conn->state == NETCONN_CLOSE)) {
00326
00327
00328 conn->state = NETCONN_NONE;
00329
00330 sys_sem_signal(conn->op_completed);
00331 }
00332 }
00333
00334
00335
00336
00337
00338
00339
00340 static void
00341 setup_tcp(struct netconn *conn)
00342 {
00343 struct tcp_pcb *pcb;
00344
00345 pcb = conn->pcb.tcp;
00346 tcp_arg(pcb, conn);
00347 tcp_recv(pcb, recv_tcp);
00348 tcp_sent(pcb, sent_tcp);
00349 tcp_poll(pcb, poll_tcp, 4);
00350 tcp_err(pcb, err_tcp);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 static err_t
00360 accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
00361 {
00362 struct netconn *newconn;
00363 struct netconn *conn;
00364
00365 #if API_MSG_DEBUG
00366 #if TCP_DEBUG
00367 tcp_debug_print_state(newpcb->state);
00368 #endif
00369 #endif
00370 conn = (struct netconn *)arg;
00371
00372 LWIP_ERROR("accept_function: invalid conn->acceptmbox",
00373 conn->acceptmbox != SYS_MBOX_NULL, return ERR_VAL;);
00374
00375
00376
00377 newconn = netconn_alloc(conn->type, conn->callback);
00378 if (newconn == NULL) {
00379 return ERR_MEM;
00380 }
00381 newconn->pcb.tcp = newpcb;
00382 setup_tcp(newconn);
00383 newconn->err = err;
00384
00385 if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {
00386
00387
00388 newconn->pcb.tcp = NULL;
00389 netconn_free(newconn);
00390 return ERR_MEM;
00391 } else {
00392
00393 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
00394 }
00395
00396 return ERR_OK;
00397 }
00398 #endif
00399
00400
00401
00402
00403
00404
00405
00406
00407 static err_t
00408 pcb_new(struct api_msg_msg *msg)
00409 {
00410 msg->conn->err = ERR_OK;
00411
00412 LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
00413
00414
00415 switch(NETCONNTYPE_GROUP(msg->conn->type)) {
00416 #if LWIP_RAW
00417 case NETCONN_RAW:
00418 msg->conn->pcb.raw = raw_new(msg->msg.n.proto);
00419 if(msg->conn->pcb.raw == NULL) {
00420 msg->conn->err = ERR_MEM;
00421 break;
00422 }
00423 raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
00424 break;
00425 #endif
00426 #if LWIP_UDP
00427 case NETCONN_UDP:
00428 msg->conn->pcb.udp = udp_new();
00429 if(msg->conn->pcb.udp == NULL) {
00430 msg->conn->err = ERR_MEM;
00431 break;
00432 }
00433 #if LWIP_UDPLITE
00434 if (msg->conn->type==NETCONN_UDPLITE) {
00435 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
00436 }
00437 #endif
00438 if (msg->conn->type==NETCONN_UDPNOCHKSUM) {
00439 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
00440 }
00441 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
00442 break;
00443 #endif
00444 #if LWIP_TCP
00445 case NETCONN_TCP:
00446 msg->conn->pcb.tcp = tcp_new();
00447 if(msg->conn->pcb.tcp == NULL) {
00448 msg->conn->err = ERR_MEM;
00449 break;
00450 }
00451 setup_tcp(msg->conn);
00452 break;
00453 #endif
00454 default:
00455
00456 msg->conn->err = ERR_VAL;
00457 break;
00458 }
00459
00460 return msg->conn->err;
00461 }
00462
00463
00464
00465
00466
00467
00468
00469 void
00470 do_newconn(struct api_msg_msg *msg)
00471 {
00472 if(msg->conn->pcb.tcp == NULL) {
00473 pcb_new(msg);
00474 }
00475
00476
00477
00478
00479 TCPIP_APIMSG_ACK(msg);
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 struct netconn*
00493 netconn_alloc(enum netconn_type t, netconn_callback callback)
00494 {
00495 struct netconn *conn;
00496 int size;
00497
00498 conn = memp_malloc(MEMP_NETCONN);
00499 if (conn == NULL) {
00500 return NULL;
00501 }
00502
00503 conn->err = ERR_OK;
00504 conn->type = t;
00505 conn->pcb.tcp = NULL;
00506
00507 #if (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_UDP_RECVMBOX_SIZE) && \
00508 (DEFAULT_RAW_RECVMBOX_SIZE == DEFAULT_TCP_RECVMBOX_SIZE)
00509 size = DEFAULT_RAW_RECVMBOX_SIZE;
00510 #else
00511 switch(NETCONNTYPE_GROUP(t)) {
00512 #if LWIP_RAW
00513 case NETCONN_RAW:
00514 size = DEFAULT_RAW_RECVMBOX_SIZE;
00515 break;
00516 #endif
00517 #if LWIP_UDP
00518 case NETCONN_UDP:
00519 size = DEFAULT_UDP_RECVMBOX_SIZE;
00520 break;
00521 #endif
00522 #if LWIP_TCP
00523 case NETCONN_TCP:
00524 size = DEFAULT_TCP_RECVMBOX_SIZE;
00525 break;
00526 #endif
00527 default:
00528 LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0);
00529 break;
00530 }
00531 #endif
00532
00533 if ((conn->op_completed = sys_sem_new(0)) == SYS_SEM_NULL) {
00534 memp_free(MEMP_NETCONN, conn);
00535 return NULL;
00536 }
00537 if ((conn->recvmbox = sys_mbox_new(size)) == SYS_MBOX_NULL) {
00538 sys_sem_free(conn->op_completed);
00539 memp_free(MEMP_NETCONN, conn);
00540 return NULL;
00541 }
00542
00543 conn->acceptmbox = SYS_MBOX_NULL;
00544 conn->state = NETCONN_NONE;
00545
00546 conn->socket = -1;
00547 conn->callback = callback;
00548 conn->recv_avail = 0;
00549 #if LWIP_TCP
00550 conn->write_msg = NULL;
00551 conn->write_offset = 0;
00552 #if LWIP_TCPIP_CORE_LOCKING
00553 conn->write_delayed = 0;
00554 #endif
00555 #endif
00556 #if LWIP_SO_RCVTIMEO
00557 conn->recv_timeout = 0;
00558 #endif
00559 #if LWIP_SO_RCVBUF
00560 conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
00561 #endif
00562 return conn;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571 void
00572 netconn_free(struct netconn *conn)
00573 {
00574 void *mem;
00575 LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
00576
00577
00578 if (conn->recvmbox != SYS_MBOX_NULL) {
00579 while (sys_mbox_tryfetch(conn->recvmbox, &mem) != SYS_MBOX_EMPTY) {
00580 if (conn->type == NETCONN_TCP) {
00581 if(mem != NULL) {
00582 pbuf_free((struct pbuf *)mem);
00583 }
00584 } else {
00585 netbuf_delete((struct netbuf *)mem);
00586 }
00587 }
00588 sys_mbox_free(conn->recvmbox);
00589 conn->recvmbox = SYS_MBOX_NULL;
00590 }
00591
00592
00593 if (conn->acceptmbox != SYS_MBOX_NULL) {
00594 while (sys_mbox_tryfetch(conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) {
00595 netconn_delete((struct netconn *)mem);
00596 }
00597 sys_mbox_free(conn->acceptmbox);
00598 conn->acceptmbox = SYS_MBOX_NULL;
00599 }
00600
00601 sys_sem_free(conn->op_completed);
00602 conn->op_completed = SYS_SEM_NULL;
00603
00604 memp_free(MEMP_NETCONN, conn);
00605 }
00606
00607 #if LWIP_TCP
00608
00609
00610
00611
00612
00613
00614
00615 static void
00616 do_close_internal(struct netconn *conn)
00617 {
00618 err_t err;
00619
00620 LWIP_ASSERT("invalid conn", (conn != NULL));
00621 LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
00622 LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
00623 LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));
00624
00625
00626 tcp_arg(conn->pcb.tcp, NULL);
00627 if (conn->pcb.tcp->state == LISTEN) {
00628 tcp_accept(conn->pcb.tcp, NULL);
00629 } else {
00630 tcp_recv(conn->pcb.tcp, NULL);
00631 tcp_accept(conn->pcb.tcp, NULL);
00632
00633 tcp_sent(conn->pcb.tcp, NULL);
00634 tcp_poll(conn->pcb.tcp, NULL, 4);
00635 tcp_err(conn->pcb.tcp, NULL);
00636 }
00637
00638 err = tcp_close(conn->pcb.tcp);
00639 if (err == ERR_OK) {
00640
00641 conn->state = NETCONN_NONE;
00642
00643 conn->pcb.tcp = NULL;
00644 conn->err = ERR_OK;
00645
00646
00647 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
00648 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
00649
00650 sys_sem_signal(conn->op_completed);
00651 } else {
00652
00653
00654 LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN));
00655 tcp_sent(conn->pcb.tcp, sent_tcp);
00656 tcp_poll(conn->pcb.tcp, poll_tcp, 4);
00657 tcp_err(conn->pcb.tcp, err_tcp);
00658 tcp_arg(conn->pcb.tcp, conn);
00659 }
00660
00661
00662 }
00663 #endif
00664
00665
00666
00667
00668
00669
00670
00671 void
00672 do_delconn(struct api_msg_msg *msg)
00673 {
00674 if (msg->conn->pcb.tcp != NULL) {
00675 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
00676 #if LWIP_RAW
00677 case NETCONN_RAW:
00678 raw_remove(msg->conn->pcb.raw);
00679 break;
00680 #endif
00681 #if LWIP_UDP
00682 case NETCONN_UDP:
00683 msg->conn->pcb.udp->recv_arg = NULL;
00684 udp_remove(msg->conn->pcb.udp);
00685 break;
00686 #endif
00687 #if LWIP_TCP
00688 case NETCONN_TCP:
00689 msg->conn->state = NETCONN_CLOSE;
00690 do_close_internal(msg->conn);
00691
00692
00693 return;
00694 #endif
00695 default:
00696 break;
00697 }
00698 }
00699
00700
00701
00702
00703 API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
00704 API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
00705
00706 if (msg->conn->op_completed != SYS_SEM_NULL) {
00707 sys_sem_signal(msg->conn->op_completed);
00708 }
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718 void
00719 do_bind(struct api_msg_msg *msg)
00720 {
00721 if (!ERR_IS_FATAL(msg->conn->err)) {
00722 if (msg->conn->pcb.tcp != NULL) {
00723 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
00724 #if LWIP_RAW
00725 case NETCONN_RAW:
00726 msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
00727 break;
00728 #endif
00729 #if LWIP_UDP
00730 case NETCONN_UDP:
00731 msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
00732 break;
00733 #endif
00734 #if LWIP_TCP
00735 case NETCONN_TCP:
00736 msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port);
00737 break;
00738 #endif
00739 default:
00740 break;
00741 }
00742 } else {
00743
00744 msg->conn->err = ERR_VAL;
00745 }
00746 }
00747 TCPIP_APIMSG_ACK(msg);
00748 }
00749
00750 #if LWIP_TCP
00751
00752
00753
00754
00755
00756
00757 static err_t
00758 do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
00759 {
00760 struct netconn *conn;
00761
00762 LWIP_UNUSED_ARG(pcb);
00763
00764 conn = arg;
00765
00766 if (conn == NULL) {
00767 return ERR_VAL;
00768 }
00769
00770 conn->err = err;
00771 if ((conn->type == NETCONN_TCP) && (err == ERR_OK)) {
00772 setup_tcp(conn);
00773 }
00774 conn->state = NETCONN_NONE;
00775 sys_sem_signal(conn->op_completed);
00776 return ERR_OK;
00777 }
00778 #endif
00779
00780
00781
00782
00783
00784
00785
00786
00787 void
00788 do_connect(struct api_msg_msg *msg)
00789 {
00790 if (msg->conn->pcb.tcp == NULL) {
00791 sys_sem_signal(msg->conn->op_completed);
00792 return;
00793 }
00794
00795 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
00796 #if LWIP_RAW
00797 case NETCONN_RAW:
00798 msg->conn->err = raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
00799 sys_sem_signal(msg->conn->op_completed);
00800 break;
00801 #endif
00802 #if LWIP_UDP
00803 case NETCONN_UDP:
00804 msg->conn->err = udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
00805 sys_sem_signal(msg->conn->op_completed);
00806 break;
00807 #endif
00808 #if LWIP_TCP
00809 case NETCONN_TCP:
00810 msg->conn->state = NETCONN_CONNECT;
00811 setup_tcp(msg->conn);
00812 msg->conn->err = tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
00813 do_connected);
00814
00815
00816 break;
00817 #endif
00818 default:
00819 LWIP_ERROR("Invalid netconn type", 0, do{ msg->conn->err = ERR_VAL;
00820 sys_sem_signal(msg->conn->op_completed); }while(0));
00821 break;
00822 }
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832 void
00833 do_disconnect(struct api_msg_msg *msg)
00834 {
00835 #if LWIP_UDP
00836 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
00837 udp_disconnect(msg->conn->pcb.udp);
00838 }
00839 #endif
00840 TCPIP_APIMSG_ACK(msg);
00841 }
00842
00843
00844
00845
00846
00847
00848
00849 void
00850 do_listen(struct api_msg_msg *msg)
00851 {
00852 #if LWIP_TCP
00853 if (!ERR_IS_FATAL(msg->conn->err)) {
00854 if (msg->conn->pcb.tcp != NULL) {
00855 if (msg->conn->type == NETCONN_TCP) {
00856 if (msg->conn->pcb.tcp->state == CLOSED) {
00857 #if TCP_LISTEN_BACKLOG
00858 struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
00859 #else
00860 struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp);
00861 #endif
00862 if (lpcb == NULL) {
00863 msg->conn->err = ERR_MEM;
00864 } else {
00865
00866 if (msg->conn->recvmbox != SYS_MBOX_NULL) {
00867
00868 sys_mbox_free(msg->conn->recvmbox);
00869 msg->conn->recvmbox = SYS_MBOX_NULL;
00870 }
00871 if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
00872 if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) {
00873 msg->conn->err = ERR_MEM;
00874 }
00875 }
00876 if (msg->conn->err == ERR_OK) {
00877 msg->conn->state = NETCONN_LISTEN;
00878 msg->conn->pcb.tcp = lpcb;
00879 tcp_arg(msg->conn->pcb.tcp, msg->conn);
00880 tcp_accept(msg->conn->pcb.tcp, accept_function);
00881 }
00882 }
00883 } else {
00884 msg->conn->err = ERR_CONN;
00885 }
00886 }
00887 }
00888 }
00889 #endif
00890 TCPIP_APIMSG_ACK(msg);
00891 }
00892
00893
00894
00895
00896
00897
00898
00899 void
00900 do_send(struct api_msg_msg *msg)
00901 {
00902 if (!ERR_IS_FATAL(msg->conn->err)) {
00903 if (msg->conn->pcb.tcp != NULL) {
00904 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
00905 #if LWIP_RAW
00906 case NETCONN_RAW:
00907 if (msg->msg.b->addr == NULL) {
00908 msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
00909 } else {
00910 msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr);
00911 }
00912 break;
00913 #endif
00914 #if LWIP_UDP
00915 case NETCONN_UDP:
00916 if (msg->msg.b->addr == NULL) {
00917 msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
00918 } else {
00919 msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port);
00920 }
00921 break;
00922 #endif
00923 default:
00924 break;
00925 }
00926 }
00927 }
00928 TCPIP_APIMSG_ACK(msg);
00929 }
00930
00931
00932
00933
00934
00935
00936
00937 void
00938 do_recv(struct api_msg_msg *msg)
00939 {
00940 #if LWIP_TCP
00941 if (!ERR_IS_FATAL(msg->conn->err)) {
00942 if (msg->conn->pcb.tcp != NULL) {
00943 if (msg->conn->type == NETCONN_TCP) {
00944 #if TCP_LISTEN_BACKLOG
00945 if (msg->conn->pcb.tcp->state == LISTEN) {
00946 tcp_accepted(msg->conn->pcb.tcp);
00947 } else
00948 #endif
00949 {
00950 tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len);
00951 }
00952 }
00953 }
00954 }
00955 #endif
00956 TCPIP_APIMSG_ACK(msg);
00957 }
00958
00959 #if LWIP_TCP
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 static err_t
00972 do_writemore(struct netconn *conn)
00973 {
00974 err_t err;
00975 void *dataptr;
00976 u16_t len, available;
00977 u8_t write_finished = 0;
00978 size_t diff;
00979
00980 LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
00981
00982 dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset;
00983 diff = conn->write_msg->msg.w.len - conn->write_offset;
00984 if (diff > 0xffffUL) {
00985 len = 0xffff;
00986 #if LWIP_TCPIP_CORE_LOCKING
00987 conn->write_delayed = 1;
00988 #endif
00989 } else {
00990 len = (u16_t)diff;
00991 }
00992 available = tcp_sndbuf(conn->pcb.tcp);
00993 if (available < len) {
00994
00995 len = available;
00996 #if LWIP_TCPIP_CORE_LOCKING
00997 conn->write_delayed = 1;
00998 #endif
00999 }
01000
01001 err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags);
01002 LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len));
01003 if (err == ERR_OK) {
01004 conn->write_offset += len;
01005 if (conn->write_offset == conn->write_msg->msg.w.len) {
01006
01007 write_finished = 1;
01008 conn->write_msg = NULL;
01009 conn->write_offset = 0;
01010
01011 conn->state = NETCONN_NONE;
01012 }
01013 err = tcp_output_nagle(conn->pcb.tcp);
01014 conn->err = err;
01015 if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) {
01016 API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
01017 }
01018 } else if (err == ERR_MEM) {
01019
01020
01021
01022
01023
01024 err = tcp_output(conn->pcb.tcp);
01025
01026 #if LWIP_TCPIP_CORE_LOCKING
01027 conn->write_delayed = 1;
01028 #endif
01029 } else {
01030
01031
01032 conn->err = err;
01033 write_finished = 1;
01034 }
01035
01036 if (write_finished) {
01037
01038
01039 conn->state = NETCONN_NONE;
01040 #if LWIP_TCPIP_CORE_LOCKING
01041 if (conn->write_delayed != 0)
01042 #endif
01043 {
01044 sys_sem_signal(conn->op_completed);
01045 }
01046 }
01047 #if LWIP_TCPIP_CORE_LOCKING
01048 else
01049 return ERR_MEM;
01050 #endif
01051 return ERR_OK;
01052 }
01053 #endif
01054
01055
01056
01057
01058
01059
01060
01061 void
01062 do_write(struct api_msg_msg *msg)
01063 {
01064 if (!ERR_IS_FATAL(msg->conn->err)) {
01065 if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
01066 #if LWIP_TCP
01067 msg->conn->state = NETCONN_WRITE;
01068
01069 LWIP_ASSERT("already writing", msg->conn->write_msg == NULL &&
01070 msg->conn->write_offset == 0);
01071 msg->conn->write_msg = msg;
01072 msg->conn->write_offset = 0;
01073 #if LWIP_TCPIP_CORE_LOCKING
01074 msg->conn->write_delayed = 0;
01075 if (do_writemore(msg->conn) != ERR_OK) {
01076 LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
01077 UNLOCK_TCPIP_CORE();
01078 sys_arch_sem_wait(msg->conn->op_completed, 0);
01079 LOCK_TCPIP_CORE();
01080 LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
01081 }
01082 #else
01083 do_writemore(msg->conn);
01084 #endif
01085
01086 return;
01087 #endif
01088 #if (LWIP_UDP || LWIP_RAW)
01089 } else {
01090 msg->conn->err = ERR_VAL;
01091 #endif
01092 }
01093 }
01094 TCPIP_APIMSG_ACK(msg);
01095 }
01096
01097
01098
01099
01100
01101
01102
01103 void
01104 do_getaddr(struct api_msg_msg *msg)
01105 {
01106 if (msg->conn->pcb.ip != NULL) {
01107 *(msg->msg.ad.ipaddr) = (msg->msg.ad.local?msg->conn->pcb.ip->local_ip:msg->conn->pcb.ip->remote_ip);
01108
01109 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
01110 #if LWIP_RAW
01111 case NETCONN_RAW:
01112 if (msg->msg.ad.local) {
01113 *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
01114 } else {
01115
01116 msg->conn->err = ERR_CONN;
01117 }
01118 break;
01119 #endif
01120 #if LWIP_UDP
01121 case NETCONN_UDP:
01122 if (msg->msg.ad.local) {
01123 *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
01124 } else {
01125 if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
01126 msg->conn->err = ERR_CONN;
01127 } else {
01128 *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
01129 }
01130 }
01131 break;
01132 #endif
01133 #if LWIP_TCP
01134 case NETCONN_TCP:
01135 *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port);
01136 break;
01137 #endif
01138 }
01139 } else {
01140 msg->conn->err = ERR_CONN;
01141 }
01142 TCPIP_APIMSG_ACK(msg);
01143 }
01144
01145
01146
01147
01148
01149
01150
01151 void
01152 do_close(struct api_msg_msg *msg)
01153 {
01154 #if LWIP_TCP
01155 if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) {
01156 msg->conn->state = NETCONN_CLOSE;
01157 do_close_internal(msg->conn);
01158
01159 } else
01160 #endif
01161 {
01162 msg->conn->err = ERR_VAL;
01163 sys_sem_signal(msg->conn->op_completed);
01164 }
01165 }
01166
01167 #if LWIP_IGMP
01168
01169
01170
01171
01172
01173
01174 void
01175 do_join_leave_group(struct api_msg_msg *msg)
01176 {
01177 if (!ERR_IS_FATAL(msg->conn->err)) {
01178 if (msg->conn->pcb.tcp != NULL) {
01179 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
01180 #if LWIP_UDP
01181 if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
01182 msg->conn->err = igmp_joingroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
01183 } else {
01184 msg->conn->err = igmp_leavegroup(msg->msg.jl.interface, msg->msg.jl.multiaddr);
01185 }
01186 #endif
01187 #if (LWIP_TCP || LWIP_RAW)
01188 } else {
01189 msg->conn->err = ERR_VAL;
01190 #endif
01191 }
01192 }
01193 }
01194 TCPIP_APIMSG_ACK(msg);
01195 }
01196 #endif
01197
01198 #if LWIP_DNS
01199
01200
01201
01202
01203
01204 static void
01205 do_dns_found(const char *name, struct ip_addr *ipaddr, void *arg)
01206 {
01207 struct dns_api_msg *msg = (struct dns_api_msg*)arg;
01208
01209 LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0);
01210
01211 if (ipaddr == NULL) {
01212
01213 *msg->err = ERR_VAL;
01214 } else {
01215
01216 *msg->err = ERR_OK;
01217 *msg->addr = *ipaddr;
01218 }
01219
01220 sys_sem_signal(msg->sem);
01221 }
01222
01223
01224
01225
01226
01227
01228
01229 void
01230 do_gethostbyname(void *arg)
01231 {
01232 struct dns_api_msg *msg = (struct dns_api_msg*)arg;
01233
01234 *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg);
01235 if (*msg->err != ERR_INPROGRESS) {
01236
01237
01238 sys_sem_signal(msg->sem);
01239 }
01240 }
01241 #endif
01242
01243 #endif