fix for corrupted graphics when manipulating config files
[open-ps2-loader.git] / modules / network / SMSTCPIP / api_msg.c
blob729f93f2faf36266388bc33ef1f42c589167cd87
1 /*
2 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25 * OF SUCH DAMAGE.
27 * This file is part of the lwIP TCP/IP stack.
29 * Author: Adam Dunkels <adam@sics.se>
33 #include "lwip/opt.h"
34 #include "lwip/arch.h"
35 #include "lwip/api_msg.h"
36 #include "lwip/memp.h"
37 #include "lwip/sys.h"
38 #include "lwip/tcpip.h"
40 #include <thsemap.h>
42 #if LWIP_RAW
43 static int
44 recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
45 struct ip_addr *addr)
47 struct netbuf *buf;
48 struct netconn *conn;
50 conn = arg;
51 if (!conn) return 0;
53 if (conn->recvmbox != SYS_MBOX_NULL) {
54 if (!(buf = memp_malloc(MEMP_NETBUF))) {
55 return 0;
57 pbuf_ref(p);
58 buf->p = p;
59 buf->ptr = p;
60 buf->fromaddr = addr;
61 buf->fromport = pcb->protocol;
63 conn->recv_avail += p->tot_len;
64 /* Register event with callback */
65 if (conn->callback)
66 (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
67 sys_mbox_post(conn->recvmbox, buf);
70 return 0; /* do not eat the packet */
72 #endif
73 #if LWIP_UDP
74 static void
75 recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
76 struct ip_addr *addr, u16_t port)
78 struct netbuf *buf;
79 struct netconn *conn;
81 conn = arg;
83 if (conn == NULL) {
84 pbuf_free(p);
85 return;
87 if (conn->recvmbox != SYS_MBOX_NULL) {
88 buf = memp_malloc(MEMP_NETBUF);
89 if (buf == NULL) {
90 pbuf_free(p);
91 return;
92 } else {
93 buf->p = p;
94 buf->ptr = p;
95 buf->fromaddr = addr;
96 buf->fromport = port;
99 conn->recv_avail += p->tot_len;
100 /* Register event with callback */
101 if (conn->callback)
102 (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, p->tot_len);
103 sys_mbox_post(conn->recvmbox, buf);
106 #endif /* LWIP_UDP */
107 #if LWIP_TCP
108 static err_t recv_tcp ( void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err ) {
110 struct netconn* conn = arg;
111 u16_t len;
112 sys_mbox_t recvmbox;
114 if ( conn ) {
116 if ( ( recvmbox = conn -> recvmbox ) != SYS_MBOX_NULL ) {
118 void ( *callback )( struct netconn*, enum netconn_evt, u16_t len ) = conn -> callback;
120 conn -> err = err;
122 if ( p ) {
123 len = p -> tot_len;
124 conn -> recv_avail += len;
125 } else len = 0;
127 if ( callback ) callback ( conn, NETCONN_EVT_RCVPLUS, len );
129 sys_mbox_post ( recvmbox, p );
131 } /* end if */
133 return ERR_OK;
135 } else {
137 pbuf_free(p);
139 return ERR_VAL;
141 } /* end else */
143 } /* end recv_tcp */
145 static err_t
146 poll_tcp(void *arg, struct tcp_pcb *pcb)
148 struct netconn *conn;
150 conn = arg;
151 if (conn != NULL &&
152 (conn->state == NETCONN_WRITE || conn->state == NETCONN_CLOSE) &&
153 conn->sem != SYS_SEM_NULL) {
154 sys_sem_signal(conn->sem);
156 return ERR_OK;
159 static err_t
160 sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
162 struct netconn *conn;
164 conn = arg;
165 if (conn != NULL && conn->sem != SYS_SEM_NULL) {
166 sys_sem_signal(conn->sem);
169 if (conn && conn->callback)
170 if (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT)
171 (*conn->callback)(conn, NETCONN_EVT_SENDPLUS, len);
173 return ERR_OK;
176 static void
177 err_tcp(void *arg, err_t err)
179 struct netconn *conn;
181 conn = arg;
183 conn->pcb.tcp = NULL;
186 conn->err = err;
187 if (conn->recvmbox != SYS_MBOX_NULL) {
188 /* Register event with callback */
189 if (conn->callback)
190 (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
191 sys_mbox_post(conn->recvmbox, NULL);
193 if (conn->mbox != SYS_MBOX_NULL) {
194 sys_mbox_post(conn->mbox, NULL);
196 if (conn->acceptmbox != SYS_MBOX_NULL) {
197 /* Register event with callback */
198 if (conn->callback)
199 (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
200 sys_mbox_post(conn->acceptmbox, NULL);
202 if (conn->sem != SYS_SEM_NULL) {
203 sys_sem_signal(conn->sem);
207 static void
208 setup_tcp(struct netconn *conn)
210 struct tcp_pcb *pcb;
212 pcb = conn->pcb.tcp;
213 tcp_arg(pcb, conn);
214 tcp_recv(pcb, recv_tcp);
215 tcp_sent(pcb, sent_tcp);
216 tcp_poll(pcb, poll_tcp, 4);
217 tcp_err(pcb, err_tcp);
220 static err_t
221 accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
223 sys_mbox_t mbox;
224 struct netconn *newconn;
225 struct netconn *conn;
227 #if API_MSG_DEBUG
228 #if TCP_DEBUG
229 tcp_debug_print_state(newpcb->state);
230 #endif /* TCP_DEBUG */
231 #endif /* API_MSG_DEBUG */
232 conn = (struct netconn *)arg;
233 mbox = conn->acceptmbox;
234 newconn = memp_malloc(MEMP_NETCONN);
235 if (newconn == NULL) {
236 return ERR_MEM;
238 newconn->type = NETCONN_TCP;
239 newconn->pcb.tcp = newpcb;
240 setup_tcp(newconn);
241 newconn->recvmbox = sys_mbox_new();
242 if (newconn->recvmbox == SYS_MBOX_NULL) {
243 memp_free(MEMP_NETCONN, newconn);
244 return ERR_MEM;
246 newconn->mbox = sys_mbox_new();
247 if (newconn->mbox == SYS_MBOX_NULL) {
248 sys_mbox_free(newconn->recvmbox);
249 memp_free(MEMP_NETCONN, newconn);
250 return ERR_MEM;
252 newconn->sem = sys_sem_new(0);
253 if (newconn->sem == SYS_SEM_NULL) {
254 sys_mbox_free(newconn->recvmbox);
255 sys_mbox_free(newconn->mbox);
256 memp_free(MEMP_NETCONN, newconn);
257 return ERR_MEM;
259 newconn->acceptmbox = SYS_MBOX_NULL;
260 newconn->err = err;
261 /* Register event with callback */
262 if (conn->callback)
264 (*conn->callback)(conn, NETCONN_EVT_RCVPLUS, 0);
265 /* We have to set the callback here even though
266 * the new socket is unknown. Mark the socket as -1. */
267 newconn->callback = conn->callback;
268 newconn->socket = -1;
271 sys_mbox_post(mbox, newconn);
272 return ERR_OK;
274 #endif /* LWIP_TCP */
276 static void
277 do_newconn(struct api_msg_msg *msg)
279 if(msg->conn->pcb.tcp != NULL) {
280 /* This "new" connection already has a PCB allocated. */
281 /* Is this an error condition? Should it be deleted?
282 We currently just are happy and return. */
283 sys_mbox_post(msg->conn->mbox, NULL);
284 return;
287 msg->conn->err = ERR_OK;
289 /* Allocate a PCB for this connection */
290 switch(msg->conn->type) {
291 #if LWIP_RAW
292 case NETCONN_RAW:
293 msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field */
294 raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
295 break;
296 #endif
297 #if LWIP_UDP
298 case NETCONN_UDPLITE:
299 msg->conn->pcb.udp = udp_new();
300 if(msg->conn->pcb.udp == NULL) {
301 msg->conn->err = ERR_MEM;
302 break;
304 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
305 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
306 break;
307 case NETCONN_UDPNOCHKSUM:
308 msg->conn->pcb.udp = udp_new();
309 if(msg->conn->pcb.udp == NULL) {
310 msg->conn->err = ERR_MEM;
311 break;
313 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
314 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
315 break;
316 case NETCONN_UDP:
317 msg->conn->pcb.udp = udp_new();
318 if(msg->conn->pcb.udp == NULL) {
319 msg->conn->err = ERR_MEM;
320 break;
322 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
323 break;
324 #endif /* LWIP_UDP */
325 #if LWIP_TCP
326 case NETCONN_TCP:
327 msg->conn->pcb.tcp = tcp_new();
328 if(msg->conn->pcb.tcp == NULL) {
329 msg->conn->err = ERR_MEM;
330 break;
332 setup_tcp(msg->conn);
333 break;
334 #endif
335 default:
336 break;
340 sys_mbox_post(msg->conn->mbox, NULL);
344 static void
345 do_delconn(struct api_msg_msg *msg)
347 if (msg->conn->pcb.tcp != NULL) {
348 switch (msg->conn->type) {
349 #if LWIP_RAW
350 case NETCONN_RAW:
351 raw_remove(msg->conn->pcb.raw);
352 break;
353 #endif
354 #if LWIP_UDP
355 case NETCONN_UDPLITE:
356 /* FALLTHROUGH */
357 case NETCONN_UDPNOCHKSUM:
358 /* FALLTHROUGH */
359 case NETCONN_UDP:
360 msg->conn->pcb.udp->recv_arg = NULL;
361 udp_remove(msg->conn->pcb.udp);
362 break;
363 #endif /* LWIP_UDP */
364 #if LWIP_TCP
365 case NETCONN_TCP:
366 if (msg->conn->pcb.tcp->state == LISTEN) {
367 tcp_arg(msg->conn->pcb.tcp, NULL);
368 tcp_accept(msg->conn->pcb.tcp, NULL);
369 tcp_close(msg->conn->pcb.tcp);
370 } else {
371 tcp_arg(msg->conn->pcb.tcp, NULL);
372 tcp_sent(msg->conn->pcb.tcp, NULL);
373 tcp_recv(msg->conn->pcb.tcp, NULL);
374 tcp_poll(msg->conn->pcb.tcp, NULL, 0);
375 tcp_err(msg->conn->pcb.tcp, NULL);
376 if (tcp_close(msg->conn->pcb.tcp) != ERR_OK) {
377 tcp_abort(msg->conn->pcb.tcp);
380 #endif
381 default:
382 break;
385 /* Trigger select() in socket layer */
386 if (msg->conn->callback)
388 (*msg->conn->callback)(msg->conn, NETCONN_EVT_RCVPLUS, 0);
389 (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDPLUS, 0);
392 if (msg->conn->mbox != SYS_MBOX_NULL) {
393 sys_mbox_post(msg->conn->mbox, NULL);
397 static void
398 do_bind(struct api_msg_msg *msg)
400 if (msg->conn->pcb.tcp == NULL) {
401 switch (msg->conn->type) {
402 #if LWIP_RAW
403 case NETCONN_RAW:
404 msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field as protocol */
405 raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
406 break;
407 #endif
408 #if LWIP_UDP
409 case NETCONN_UDPLITE:
410 msg->conn->pcb.udp = udp_new();
411 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
412 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
413 break;
414 case NETCONN_UDPNOCHKSUM:
415 msg->conn->pcb.udp = udp_new();
416 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
417 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
418 break;
419 case NETCONN_UDP:
420 msg->conn->pcb.udp = udp_new();
421 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
422 break;
423 #endif /* LWIP_UDP */
424 #if LWIP_TCP
425 case NETCONN_TCP:
426 msg->conn->pcb.tcp = tcp_new();
427 setup_tcp(msg->conn);
428 #endif /* LWIP_TCP */
429 default:
430 break;
433 switch (msg->conn->type) {
434 #if LWIP_RAW
435 case NETCONN_RAW:
436 msg->conn->err = raw_bind(msg->conn->pcb.raw,msg->msg.bc.ipaddr);
437 break;
438 #endif
439 #if LWIP_UDP
440 case NETCONN_UDPLITE:
441 /* FALLTHROUGH */
442 case NETCONN_UDPNOCHKSUM:
443 /* FALLTHROUGH */
444 case NETCONN_UDP:
445 msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
446 break;
447 #endif /* LWIP_UDP */
448 #if LWIP_TCP
449 case NETCONN_TCP:
450 msg->conn->err = tcp_bind(msg->conn->pcb.tcp,
451 msg->msg.bc.ipaddr, msg->msg.bc.port);
452 #endif /* LWIP_TCP */
453 default:
454 break;
456 sys_mbox_post(msg->conn->mbox, NULL);
458 #if LWIP_TCP
460 static err_t
461 do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
463 struct netconn *conn;
465 conn = arg;
467 if (conn == NULL) {
468 return ERR_VAL;
471 conn->err = err;
472 if (conn->type == NETCONN_TCP && err == ERR_OK) {
473 setup_tcp(conn);
475 sys_mbox_post(conn->mbox, NULL);
476 return ERR_OK;
478 #endif
480 static void
481 do_connect(struct api_msg_msg *msg)
483 if (msg->conn->pcb.tcp == NULL) {
484 switch (msg->conn->type) {
485 #if LWIP_RAW
486 case NETCONN_RAW:
487 msg->conn->pcb.raw = raw_new(msg->msg.bc.port); /* misusing the port field as protocol */
488 raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
489 break;
490 #endif
491 #if LWIP_UDP
492 case NETCONN_UDPLITE:
493 msg->conn->pcb.udp = udp_new();
494 if (msg->conn->pcb.udp == NULL) {
495 msg->conn->err = ERR_MEM;
496 sys_mbox_post(msg->conn->mbox, NULL);
497 return;
499 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
500 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
501 break;
502 case NETCONN_UDPNOCHKSUM:
503 msg->conn->pcb.udp = udp_new();
504 if (msg->conn->pcb.udp == NULL) {
505 msg->conn->err = ERR_MEM;
506 sys_mbox_post(msg->conn->mbox, NULL);
507 return;
509 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
510 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
511 break;
512 case NETCONN_UDP:
513 msg->conn->pcb.udp = udp_new();
514 if (msg->conn->pcb.udp == NULL) {
515 msg->conn->err = ERR_MEM;
516 sys_mbox_post(msg->conn->mbox, NULL);
517 return;
519 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
520 break;
521 #endif /* LWIP_UDP */
522 #if LWIP_TCP
523 case NETCONN_TCP:
524 msg->conn->pcb.tcp = tcp_new();
525 if (msg->conn->pcb.tcp == NULL) {
526 msg->conn->err = ERR_MEM;
527 sys_mbox_post(msg->conn->mbox, NULL);
528 return;
530 #endif
531 default:
532 break;
535 switch (msg->conn->type) {
536 #if LWIP_RAW
537 case NETCONN_RAW:
538 raw_connect(msg->conn->pcb.raw, msg->msg.bc.ipaddr);
539 sys_mbox_post(msg->conn->mbox, NULL);
540 break;
541 #endif
542 #if LWIP_UDP
543 case NETCONN_UDPLITE:
544 /* FALLTHROUGH */
545 case NETCONN_UDPNOCHKSUM:
546 /* FALLTHROUGH */
547 case NETCONN_UDP:
548 udp_connect(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port);
549 sys_mbox_post(msg->conn->mbox, NULL);
550 break;
551 #endif
552 #if LWIP_TCP
553 case NETCONN_TCP:
554 /* tcp_arg(msg->conn->pcb.tcp, msg->conn);*/
555 setup_tcp(msg->conn);
556 tcp_connect(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port,
557 do_connected);
558 /*tcp_output(msg->conn->pcb.tcp);*/
559 #endif
561 default:
562 break;
566 static void
567 do_disconnect(struct api_msg_msg *msg)
570 switch (msg->conn->type) {
571 #if LWIP_RAW
572 case NETCONN_RAW:
573 /* Do nothing as connecting is only a helper for upper lwip layers */
574 break;
575 #endif
576 #if LWIP_UDP
577 case NETCONN_UDPLITE:
578 /* FALLTHROUGH */
579 case NETCONN_UDPNOCHKSUM:
580 /* FALLTHROUGH */
581 case NETCONN_UDP:
582 udp_disconnect(msg->conn->pcb.udp);
583 break;
584 #endif
585 case NETCONN_TCP:
586 break;
587 default:
588 break;
590 sys_mbox_post(msg->conn->mbox, NULL);
594 static void
595 do_listen(struct api_msg_msg *msg)
597 if (msg->conn->pcb.tcp != NULL) {
598 switch (msg->conn->type) {
599 #if LWIP_RAW
600 case NETCONN_RAW:
601 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen RAW: cannot listen for RAW.\n"));
602 break;
603 #endif
604 #if LWIP_UDP
605 case NETCONN_UDPLITE:
606 /* FALLTHROUGH */
607 case NETCONN_UDPNOCHKSUM:
608 /* FALLTHROUGH */
609 case NETCONN_UDP:
610 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: listen UDP: cannot listen for UDP.\n"));
611 break;
612 #endif /* LWIP_UDP */
613 #if LWIP_TCP
614 case NETCONN_TCP:
615 msg->conn->pcb.tcp = tcp_listen(msg->conn->pcb.tcp);
616 if (msg->conn->pcb.tcp == NULL) {
617 msg->conn->err = ERR_MEM;
618 } else {
619 if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
620 msg->conn->acceptmbox = sys_mbox_new();
621 if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
622 msg->conn->err = ERR_MEM;
623 break;
626 tcp_arg(msg->conn->pcb.tcp, msg->conn);
627 tcp_accept(msg->conn->pcb.tcp, accept_function);
629 #endif
630 default:
631 break;
634 sys_mbox_post(msg->conn->mbox, NULL);
637 static void
638 do_accept(struct api_msg_msg *msg)
640 if (msg->conn->pcb.tcp != NULL) {
641 switch (msg->conn->type) {
642 #if LWIP_RAW
643 case NETCONN_RAW:
644 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept RAW: cannot accept for RAW.\n"));
645 break;
646 #endif
647 #if LWIP_UDP
648 case NETCONN_UDPLITE:
649 /* FALLTHROUGH */
650 case NETCONN_UDPNOCHKSUM:
651 /* FALLTHROUGH */
652 case NETCONN_UDP:
653 LWIP_DEBUGF(API_MSG_DEBUG, ("api_msg: accept UDP: cannot accept for UDP.\n"));
654 break;
655 #endif /* LWIP_UDP */
656 case NETCONN_TCP:
657 break;
658 default:
659 break;
664 static void
665 do_send(struct api_msg_msg *msg)
667 if (msg->conn->pcb.tcp != NULL) {
668 switch (msg->conn->type) {
669 #if LWIP_RAW
670 case NETCONN_RAW:
671 raw_send(msg->conn->pcb.raw, msg->msg.p);
672 break;
673 #endif
674 #if LWIP_UDP
675 case NETCONN_UDPLITE:
676 /* FALLTHROUGH */
677 case NETCONN_UDPNOCHKSUM:
678 /* FALLTHROUGH */
679 case NETCONN_UDP:
680 udp_send(msg->conn->pcb.udp, msg->msg.p);
681 break;
682 #endif /* LWIP_UDP */
683 case NETCONN_TCP:
684 break;
685 default:
686 break;
689 sys_mbox_post(msg->conn->mbox, NULL);
692 static void do_recv ( struct api_msg_msg* msg ) {
694 struct netconn* conn = msg -> conn;
695 #if LWIP_TCP
696 if ( conn -> pcb.tcp && conn -> type == NETCONN_TCP )
697 tcp_recved ( conn -> pcb.tcp, msg -> msg.len );
698 #endif
699 sys_mbox_post ( conn -> mbox, NULL );
701 } /* end do_recv */
703 static void
704 do_write(struct api_msg_msg *msg)
706 #if LWIP_TCP
707 err_t err;
708 #endif
709 if (msg->conn->pcb.tcp != NULL) {
710 switch (msg->conn->type) {
711 #if LWIP_RAW
712 case NETCONN_RAW:
713 msg->conn->err = ERR_VAL;
714 break;
715 #endif
716 #if LWIP_UDP
717 case NETCONN_UDPLITE:
718 /* FALLTHROUGH */
719 case NETCONN_UDPNOCHKSUM:
720 /* FALLTHROUGH */
721 case NETCONN_UDP:
722 msg->conn->err = ERR_VAL;
723 break;
724 #endif /* LWIP_UDP */
725 #if LWIP_TCP
726 case NETCONN_TCP:
727 err = tcp_write(msg->conn->pcb.tcp, msg->msg.w.dataptr,
728 msg->msg.w.len, msg->msg.w.copy);
729 /* This is the Nagle algorithm: inhibit the sending of new TCP
730 segments when new outgoing data arrives from the user if any
731 previously transmitted data on the connection remains
732 unacknowledged. */
733 if(err == ERR_OK && (msg->conn->pcb.tcp->unacked == NULL || (msg->conn->pcb.tcp->flags & TF_NODELAY)) ) {
734 tcp_output(msg->conn->pcb.tcp);
736 msg->conn->err = err;
737 if (msg->conn->callback)
738 if (err == ERR_OK)
740 if (tcp_sndbuf(msg->conn->pcb.tcp) <= TCP_SNDLOWAT)
741 (*msg->conn->callback)(msg->conn, NETCONN_EVT_SENDMINUS, msg->msg.w.len);
743 #endif
744 default:
745 break;
748 sys_mbox_post(msg->conn->mbox, NULL);
751 static void
752 do_close(struct api_msg_msg *msg)
754 err_t err;
756 err = ERR_OK;
758 if (msg->conn->pcb.tcp != NULL) {
759 switch (msg->conn->type) {
760 #if LWIP_RAW
761 case NETCONN_RAW:
762 break;
763 #endif
764 #if LWIP_UDP
765 case NETCONN_UDPLITE:
766 /* FALLTHROUGH */
767 case NETCONN_UDPNOCHKSUM:
768 /* FALLTHROUGH */
769 case NETCONN_UDP:
770 break;
771 #endif /* LWIP_UDP */
772 #if LWIP_TCP
773 case NETCONN_TCP:
774 if (msg->conn->pcb.tcp->state == LISTEN) {
775 err = tcp_close(msg->conn->pcb.tcp);
777 msg->conn->err = err;
778 #endif
779 default:
780 break;
783 sys_mbox_post(msg->conn->mbox, NULL);
786 api_msg_decode __decode__[ API_MSG_MAX ] = {
787 do_newconn,
788 do_delconn,
789 do_bind,
790 do_connect,
791 do_disconnect,
792 do_listen,
793 do_accept,
794 do_send,
795 do_recv,
796 do_write,
797 do_close