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
00040
00041
00042 #include "lwip/opt.h"
00043
00044 #if LWIP_NETCONN
00045
00046 #include "lwip/api.h"
00047 #include "lwip/tcpip.h"
00048 #include "lwip/memp.h"
00049
00050 #include "lwip/ip.h"
00051 #include "lwip/raw.h"
00052 #include "lwip/udp.h"
00053 #include "lwip/tcp.h"
00054
00055 #include <string.h>
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 struct netconn*
00068 netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
00069 {
00070 struct netconn *conn;
00071 struct api_msg msg;
00072
00073 conn = netconn_alloc(t, callback);
00074 if (conn != NULL) {
00075 msg.function = do_newconn;
00076 msg.msg.msg.n.proto = proto;
00077 msg.msg.conn = conn;
00078 if (TCPIP_APIMSG(&msg) != ERR_OK) {
00079 LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
00080 LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
00081 LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
00082 #if LWIP_TCP
00083 LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
00084 #endif
00085 sys_sem_free(&conn->op_completed);
00086 sys_mbox_free(&conn->recvmbox);
00087 memp_free(MEMP_NETCONN, conn);
00088 return NULL;
00089 }
00090 }
00091 return conn;
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 err_t
00103 netconn_delete(struct netconn *conn)
00104 {
00105 struct api_msg msg;
00106
00107
00108 if (conn == NULL) {
00109 return ERR_OK;
00110 }
00111
00112 msg.function = do_delconn;
00113 msg.msg.conn = conn;
00114 tcpip_apimsg(&msg);
00115
00116 netconn_free(conn);
00117
00118
00119
00120 return ERR_OK;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 err_t
00135 netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
00136 {
00137 struct api_msg msg;
00138 err_t err;
00139
00140 LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
00141 LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
00142 LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
00143
00144 msg.function = do_getaddr;
00145 msg.msg.conn = conn;
00146 msg.msg.msg.ad.ipaddr = addr;
00147 msg.msg.msg.ad.port = port;
00148 msg.msg.msg.ad.local = local;
00149 err = TCPIP_APIMSG(&msg);
00150
00151 NETCONN_SET_SAFE_ERR(conn, err);
00152 return err;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 err_t
00166 netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port)
00167 {
00168 struct api_msg msg;
00169 err_t err;
00170
00171 LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
00172
00173 msg.function = do_bind;
00174 msg.msg.conn = conn;
00175 msg.msg.msg.bc.ipaddr = addr;
00176 msg.msg.msg.bc.port = port;
00177 err = TCPIP_APIMSG(&msg);
00178
00179 NETCONN_SET_SAFE_ERR(conn, err);
00180 return err;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 err_t
00192 netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port)
00193 {
00194 struct api_msg msg;
00195 err_t err;
00196
00197 LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
00198
00199 msg.function = do_connect;
00200 msg.msg.conn = conn;
00201 msg.msg.msg.bc.ipaddr = addr;
00202 msg.msg.msg.bc.port = port;
00203
00204 err = tcpip_apimsg(&msg);
00205
00206 NETCONN_SET_SAFE_ERR(conn, err);
00207 return err;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216 err_t
00217 netconn_disconnect(struct netconn *conn)
00218 {
00219 struct api_msg msg;
00220 err_t err;
00221
00222 LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
00223
00224 msg.function = do_disconnect;
00225 msg.msg.conn = conn;
00226 err = TCPIP_APIMSG(&msg);
00227
00228 NETCONN_SET_SAFE_ERR(conn, err);
00229 return err;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 err_t
00241 netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
00242 {
00243 #if LWIP_TCP
00244 struct api_msg msg;
00245 err_t err;
00246
00247
00248 LWIP_UNUSED_ARG(backlog);
00249
00250 LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
00251
00252 msg.function = do_listen;
00253 msg.msg.conn = conn;
00254 #if TCP_LISTEN_BACKLOG
00255 msg.msg.msg.lb.backlog = backlog;
00256 #endif
00257 err = TCPIP_APIMSG(&msg);
00258
00259 NETCONN_SET_SAFE_ERR(conn, err);
00260 return err;
00261 #else
00262 LWIP_UNUSED_ARG(conn);
00263 LWIP_UNUSED_ARG(backlog);
00264 return ERR_ARG;
00265 #endif
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 err_t
00277 netconn_accept(struct netconn *conn, struct netconn **new_conn)
00278 {
00279 #if LWIP_TCP
00280 struct netconn *newconn;
00281 err_t err;
00282 #if TCP_LISTEN_BACKLOG
00283 struct api_msg msg;
00284 #endif
00285
00286 LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
00287 *new_conn = NULL;
00288 LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
00289 LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;);
00290
00291 err = conn->last_err;
00292 if (ERR_IS_FATAL(err)) {
00293
00294
00295 return err;
00296 }
00297
00298 #if LWIP_SO_RCVTIMEO
00299 if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
00300 NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
00301 return ERR_TIMEOUT;
00302 }
00303 #else
00304 sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0);
00305 #endif
00306
00307 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
00308
00309 if (newconn == NULL) {
00310
00311 NETCONN_SET_SAFE_ERR(conn, ERR_ABRT);
00312 return ERR_ABRT;
00313 }
00314 #if TCP_LISTEN_BACKLOG
00315
00316 msg.function = do_recv;
00317 msg.msg.conn = conn;
00318
00319 TCPIP_APIMSG(&msg);
00320 #endif
00321
00322 *new_conn = newconn;
00323
00324 return ERR_OK;
00325 #else
00326 LWIP_UNUSED_ARG(conn);
00327 LWIP_UNUSED_ARG(new_conn);
00328 return ERR_ARG;
00329 #endif
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 static err_t
00342 netconn_recv_data(struct netconn *conn, void **new_buf)
00343 {
00344 void *buf = NULL;
00345 u16_t len;
00346 err_t err;
00347 #if LWIP_TCP
00348 struct api_msg msg;
00349 #endif
00350
00351 LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
00352 *new_buf = NULL;
00353 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
00354 LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
00355
00356 err = conn->last_err;
00357 if (ERR_IS_FATAL(err)) {
00358
00359
00360
00361
00362 return err;
00363 }
00364
00365 #if LWIP_SO_RCVTIMEO
00366 if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
00367 NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
00368 return ERR_TIMEOUT;
00369 }
00370 #else
00371 sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
00372 #endif
00373
00374 #if LWIP_TCP
00375 #if (LWIP_UDP || LWIP_RAW)
00376 if (conn->type == NETCONN_TCP)
00377 #endif
00378 {
00379 if (!netconn_get_noautorecved(conn) || (buf == NULL)) {
00380
00381
00382
00383 msg.function = do_recv;
00384 msg.msg.conn = conn;
00385 if (buf != NULL) {
00386 msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len;
00387 } else {
00388 msg.msg.msg.r.len = 1;
00389 }
00390
00391 TCPIP_APIMSG(&msg);
00392 }
00393
00394
00395 if (buf == NULL) {
00396 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
00397
00398 NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
00399 return ERR_CLSD;
00400 }
00401 len = ((struct pbuf *)buf)->tot_len;
00402 }
00403 #endif
00404 #if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
00405 else
00406 #endif
00407 #if (LWIP_UDP || LWIP_RAW)
00408 {
00409 LWIP_ASSERT("buf != NULL", buf != NULL);
00410 len = netbuf_len((struct netbuf *)buf);
00411 }
00412 #endif
00413
00414 #if LWIP_SO_RCVBUF
00415 SYS_ARCH_DEC(conn->recv_avail, len);
00416 #endif
00417
00418 API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
00419
00420 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
00421
00422 *new_buf = buf;
00423
00424 return ERR_OK;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 err_t
00437 netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
00438 {
00439 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) &&
00440 netconn_type(conn) == NETCONN_TCP, return ERR_ARG;);
00441
00442 return netconn_recv_data(conn, (void **)new_buf);
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 err_t
00454 netconn_recv(struct netconn *conn, struct netbuf **new_buf)
00455 {
00456 #if LWIP_TCP
00457 struct netbuf *buf = NULL;
00458 err_t err;
00459 #endif
00460
00461 LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
00462 *new_buf = NULL;
00463 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
00464 LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
00465
00466 #if LWIP_TCP
00467 #if (LWIP_UDP || LWIP_RAW)
00468 if (conn->type == NETCONN_TCP)
00469 #endif
00470 {
00471 struct pbuf *p = NULL;
00472
00473
00474 buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
00475 if (buf == NULL) {
00476 NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
00477 return ERR_MEM;
00478 }
00479
00480 err = netconn_recv_data(conn, (void **)&p);
00481 if (err != ERR_OK) {
00482 memp_free(MEMP_NETBUF, buf);
00483 return err;
00484 }
00485 LWIP_ASSERT("p != NULL", p != NULL);
00486
00487 buf->p = p;
00488 buf->ptr = p;
00489 buf->port = 0;
00490 ip_addr_set_any(&buf->addr);
00491 *new_buf = buf;
00492
00493 return ERR_OK;
00494 }
00495 #endif
00496 #if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
00497 else
00498 #endif
00499 {
00500 #if (LWIP_UDP || LWIP_RAW)
00501 return netconn_recv_data(conn, (void **)new_buf);
00502 #endif
00503 }
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 void
00517 netconn_recved(struct netconn *conn, u32_t length)
00518 {
00519 #if LWIP_TCP
00520 if ((conn != NULL) && (conn->type == NETCONN_TCP) &&
00521 (netconn_get_noautorecved(conn))) {
00522 struct api_msg msg;
00523
00524
00525
00526 msg.function = do_recv;
00527 msg.msg.conn = conn;
00528 msg.msg.msg.r.len = length;
00529
00530 TCPIP_APIMSG(&msg);
00531 }
00532 #else
00533 LWIP_UNUSED_ARG(conn);
00534 LWIP_UNUSED_ARG(length);
00535 #endif
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 err_t
00549 netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port)
00550 {
00551 if (buf != NULL) {
00552 ip_addr_set(&buf->addr, addr);
00553 buf->port = port;
00554 return netconn_send(conn, buf);
00555 }
00556 return ERR_VAL;
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566 err_t
00567 netconn_send(struct netconn *conn, struct netbuf *buf)
00568 {
00569 struct api_msg msg;
00570 err_t err;
00571
00572 LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
00573
00574 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
00575 msg.function = do_send;
00576 msg.msg.conn = conn;
00577 msg.msg.msg.b = buf;
00578 err = TCPIP_APIMSG(&msg);
00579
00580 NETCONN_SET_SAFE_ERR(conn, err);
00581 return err;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 err_t
00598 netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
00599 u8_t apiflags, size_t *bytes_written)
00600 {
00601 struct api_msg msg;
00602 err_t err;
00603 u8_t dontblock;
00604
00605 LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
00606 LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;);
00607 if (size == 0) {
00608 return ERR_OK;
00609 }
00610 dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
00611 if (dontblock && !bytes_written) {
00612
00613
00614 return ERR_VAL;
00615 }
00616
00617
00618 msg.function = do_write;
00619 msg.msg.conn = conn;
00620 msg.msg.msg.w.dataptr = dataptr;
00621 msg.msg.msg.w.apiflags = apiflags;
00622 msg.msg.msg.w.len = size;
00623 #if LWIP_SO_SNDTIMEO
00624 if (conn->send_timeout != 0) {
00625
00626
00627 msg.msg.msg.w.time_started = sys_now();
00628 } else {
00629 msg.msg.msg.w.time_started = 0;
00630 }
00631 #endif
00632
00633
00634
00635
00636 err = TCPIP_APIMSG(&msg);
00637 if ((err == ERR_OK) && (bytes_written != NULL)) {
00638 if (dontblock
00639 #if LWIP_SO_SNDTIMEO
00640 || (conn->send_timeout != 0)
00641 #endif
00642 ) {
00643
00644 *bytes_written = msg.msg.msg.w.len;
00645 } else {
00646
00647 *bytes_written = size;
00648 }
00649 }
00650
00651 NETCONN_SET_SAFE_ERR(conn, err);
00652 return err;
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662 static err_t
00663 netconn_close_shutdown(struct netconn *conn, u8_t how)
00664 {
00665 struct api_msg msg;
00666 err_t err;
00667
00668 LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
00669
00670 msg.function = do_close;
00671 msg.msg.conn = conn;
00672
00673 msg.msg.msg.sd.shut = how;
00674
00675
00676 err = tcpip_apimsg(&msg);
00677
00678 NETCONN_SET_SAFE_ERR(conn, err);
00679 return err;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688 err_t
00689 netconn_close(struct netconn *conn)
00690 {
00691
00692 return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
00693 }
00694
00695
00696
00697
00698
00699
00700
00701 err_t
00702 netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
00703 {
00704 return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0));
00705 }
00706
00707 #if LWIP_IGMP
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 err_t
00719 netconn_join_leave_group(struct netconn *conn,
00720 ip_addr_t *multiaddr,
00721 ip_addr_t *netif_addr,
00722 enum netconn_igmp join_or_leave)
00723 {
00724 struct api_msg msg;
00725 err_t err;
00726
00727 LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
00728
00729 msg.function = do_join_leave_group;
00730 msg.msg.conn = conn;
00731 msg.msg.msg.jl.multiaddr = multiaddr;
00732 msg.msg.msg.jl.netif_addr = netif_addr;
00733 msg.msg.msg.jl.join_or_leave = join_or_leave;
00734 err = TCPIP_APIMSG(&msg);
00735
00736 NETCONN_SET_SAFE_ERR(conn, err);
00737 return err;
00738 }
00739 #endif
00740
00741 #if LWIP_DNS
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 err_t
00753 netconn_gethostbyname(const char *name, ip_addr_t *addr)
00754 {
00755 struct dns_api_msg msg;
00756 err_t err;
00757 sys_sem_t sem;
00758
00759 LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
00760 LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
00761
00762 err = sys_sem_new(&sem, 0);
00763 if (err != ERR_OK) {
00764 return err;
00765 }
00766
00767 msg.name = name;
00768 msg.addr = addr;
00769 msg.err = &err;
00770 msg.sem = &sem;
00771
00772 tcpip_callback(do_gethostbyname, &msg);
00773 sys_sem_wait(&sem);
00774 sys_sem_free(&sem);
00775
00776 return err;
00777 }
00778 #endif
00779
00780 #endif