Warning, cross-references for /kernel/lwip/api/api_lib.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #include "lwip/opt.h"
0043
0044 #if LWIP_NETCONN
0045
0046 #include "lwip/api.h"
0047 #include "lwip/tcpip.h"
0048 #include "lwip/memp.h"
0049
0050 #include "lwip/ip.h"
0051 #include "lwip/raw.h"
0052 #include "lwip/udp.h"
0053 #include "lwip/tcp.h"
0054
0055 #include <string.h>
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 struct netconn*
0068 netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
0069 {
0070 struct netconn *conn;
0071 struct api_msg msg;
0072
0073 conn = netconn_alloc(t, callback);
0074 if (conn != NULL ) {
0075 msg.function = do_newconn;
0076 msg.msg.msg.n.proto = proto;
0077 msg.msg.conn = conn;
0078 TCPIP_APIMSG(&msg);
0079
0080 if (conn->err != ERR_OK) {
0081 LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
0082 LWIP_ASSERT("conn has no op_completed", conn->op_completed != SYS_SEM_NULL);
0083 LWIP_ASSERT("conn has no recvmbox", conn->recvmbox != SYS_MBOX_NULL);
0084 LWIP_ASSERT("conn->acceptmbox shouldn't exist", conn->acceptmbox == SYS_MBOX_NULL);
0085 sys_sem_free(conn->op_completed);
0086 sys_mbox_free(conn->recvmbox);
0087 memp_free(MEMP_NETCONN, conn);
0088 return NULL;
0089 }
0090 }
0091 return conn;
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 err_t
0103 netconn_delete(struct netconn *conn)
0104 {
0105 struct api_msg msg;
0106
0107
0108 if (conn == NULL) {
0109 return ERR_OK;
0110 }
0111
0112 msg.function = do_delconn;
0113 msg.msg.conn = conn;
0114 tcpip_apimsg(&msg);
0115
0116 conn->pcb.tcp = NULL;
0117 netconn_free(conn);
0118
0119 return ERR_OK;
0120 }
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 err_t
0134 netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local)
0135 {
0136 struct api_msg msg;
0137
0138 LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
0139 LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
0140 LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
0141
0142 msg.function = do_getaddr;
0143 msg.msg.conn = conn;
0144 msg.msg.msg.ad.ipaddr = addr;
0145 msg.msg.msg.ad.port = port;
0146 msg.msg.msg.ad.local = local;
0147 TCPIP_APIMSG(&msg);
0148
0149 return conn->err;
0150 }
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 err_t
0163 netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port)
0164 {
0165 struct api_msg msg;
0166
0167 LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
0168
0169 msg.function = do_bind;
0170 msg.msg.conn = conn;
0171 msg.msg.msg.bc.ipaddr = addr;
0172 msg.msg.msg.bc.port = port;
0173 TCPIP_APIMSG(&msg);
0174 return conn->err;
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 err_t
0186 netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port)
0187 {
0188 struct api_msg msg;
0189
0190 LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
0191
0192 msg.function = do_connect;
0193 msg.msg.conn = conn;
0194 msg.msg.msg.bc.ipaddr = addr;
0195 msg.msg.msg.bc.port = port;
0196
0197 tcpip_apimsg(&msg);
0198 return conn->err;
0199 }
0200
0201
0202
0203
0204
0205
0206
0207 err_t
0208 netconn_disconnect(struct netconn *conn)
0209 {
0210 struct api_msg msg;
0211
0212 LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
0213
0214 msg.function = do_disconnect;
0215 msg.msg.conn = conn;
0216 TCPIP_APIMSG(&msg);
0217 return conn->err;
0218 }
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 err_t
0229 netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
0230 {
0231 struct api_msg msg;
0232
0233
0234 LWIP_UNUSED_ARG(backlog);
0235
0236 LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
0237
0238 msg.function = do_listen;
0239 msg.msg.conn = conn;
0240 #if TCP_LISTEN_BACKLOG
0241 msg.msg.msg.lb.backlog = backlog;
0242 #endif
0243 TCPIP_APIMSG(&msg);
0244 return conn->err;
0245 }
0246
0247
0248
0249
0250
0251
0252
0253 struct netconn *
0254 netconn_accept(struct netconn *conn)
0255 {
0256 struct netconn *newconn;
0257
0258 LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return NULL;);
0259 LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return NULL;);
0260
0261 #if LWIP_SO_RCVTIMEO
0262 if (sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
0263 newconn = NULL;
0264 } else
0265 #else
0266 sys_arch_mbox_fetch(conn->acceptmbox, (void *)&newconn, 0);
0267 #endif
0268 {
0269
0270 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
0271
0272 #if TCP_LISTEN_BACKLOG
0273 if (newconn != NULL) {
0274
0275 struct api_msg msg;
0276 msg.function = do_recv;
0277 msg.msg.conn = conn;
0278 TCPIP_APIMSG(&msg);
0279 }
0280 #endif
0281 }
0282
0283 return newconn;
0284 }
0285
0286
0287
0288
0289
0290
0291
0292 struct netbuf *
0293 netconn_recv(struct netconn *conn)
0294 {
0295 struct api_msg msg;
0296 struct netbuf *buf = NULL;
0297 struct pbuf *p;
0298 u16_t len;
0299
0300 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return NULL;);
0301
0302 if (conn->recvmbox == SYS_MBOX_NULL) {
0303
0304
0305 conn->err = ERR_CONN;
0306 return NULL;
0307 }
0308
0309 if (ERR_IS_FATAL(conn->err)) {
0310 return NULL;
0311 }
0312
0313 if (conn->type == NETCONN_TCP) {
0314 #if LWIP_TCP
0315 if (conn->state == NETCONN_LISTEN) {
0316
0317 conn->err = ERR_CONN;
0318 return NULL;
0319 }
0320
0321 buf = memp_malloc(MEMP_NETBUF);
0322
0323 if (buf == NULL) {
0324 conn->err = ERR_MEM;
0325 return NULL;
0326 }
0327
0328 #if LWIP_SO_RCVTIMEO
0329 if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
0330 memp_free(MEMP_NETBUF, buf);
0331 conn->err = ERR_TIMEOUT;
0332 return NULL;
0333 }
0334 #else
0335 sys_arch_mbox_fetch(conn->recvmbox, (void *)&p, 0);
0336 #endif
0337
0338 if (p != NULL) {
0339 len = p->tot_len;
0340 SYS_ARCH_DEC(conn->recv_avail, len);
0341 } else {
0342 len = 0;
0343 }
0344
0345
0346 API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
0347
0348
0349 if (p == NULL) {
0350 memp_free(MEMP_NETBUF, buf);
0351
0352 if (conn->err == ERR_OK) {
0353 conn->err = ERR_CLSD;
0354 }
0355 return NULL;
0356 }
0357
0358 buf->p = p;
0359 buf->ptr = p;
0360 buf->port = 0;
0361 buf->addr = NULL;
0362
0363
0364 msg.function = do_recv;
0365 msg.msg.conn = conn;
0366 if (buf != NULL) {
0367 msg.msg.msg.r.len = buf->p->tot_len;
0368 } else {
0369 msg.msg.msg.r.len = 1;
0370 }
0371 TCPIP_APIMSG(&msg);
0372 #endif
0373 } else {
0374 #if (LWIP_UDP || LWIP_RAW)
0375 #if LWIP_SO_RCVTIMEO
0376 if (sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
0377 buf = NULL;
0378 }
0379 #else
0380 sys_arch_mbox_fetch(conn->recvmbox, (void *)&buf, 0);
0381 #endif
0382 if (buf!=NULL) {
0383 SYS_ARCH_DEC(conn->recv_avail, buf->p->tot_len);
0384
0385 API_EVENT(conn, NETCONN_EVT_RCVMINUS, buf->p->tot_len);
0386 }
0387 #endif
0388 }
0389
0390 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv: received %p (err %d)\n", (void *)buf, conn->err));
0391
0392 return buf;
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405 err_t
0406 netconn_sendto(struct netconn *conn, struct netbuf *buf, struct ip_addr *addr, u16_t port)
0407 {
0408 if (buf != NULL) {
0409 buf->addr = addr;
0410 buf->port = port;
0411 return netconn_send(conn, buf);
0412 }
0413 return ERR_VAL;
0414 }
0415
0416
0417
0418
0419
0420
0421
0422
0423 err_t
0424 netconn_send(struct netconn *conn, struct netbuf *buf)
0425 {
0426 struct api_msg msg;
0427
0428 LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
0429
0430 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
0431 msg.function = do_send;
0432 msg.msg.conn = conn;
0433 msg.msg.msg.b = buf;
0434 TCPIP_APIMSG(&msg);
0435 return conn->err;
0436 }
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 err_t
0450 netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags)
0451 {
0452 struct api_msg msg;
0453
0454 LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
0455 LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;);
0456
0457 msg.function = do_write;
0458 msg.msg.conn = conn;
0459 msg.msg.msg.w.dataptr = dataptr;
0460 msg.msg.msg.w.apiflags = apiflags;
0461 msg.msg.msg.w.len = size;
0462
0463
0464
0465 TCPIP_APIMSG(&msg);
0466 return conn->err;
0467 }
0468
0469
0470
0471
0472
0473
0474
0475 err_t
0476 netconn_close(struct netconn *conn)
0477 {
0478 struct api_msg msg;
0479
0480 LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
0481
0482 msg.function = do_close;
0483 msg.msg.conn = conn;
0484 tcpip_apimsg(&msg);
0485 return conn->err;
0486 }
0487
0488 #if LWIP_IGMP
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499 err_t
0500 netconn_join_leave_group(struct netconn *conn,
0501 struct ip_addr *multiaddr,
0502 struct ip_addr *interface,
0503 enum netconn_igmp join_or_leave)
0504 {
0505 struct api_msg msg;
0506
0507 LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
0508
0509 msg.function = do_join_leave_group;
0510 msg.msg.conn = conn;
0511 msg.msg.msg.jl.multiaddr = multiaddr;
0512 msg.msg.msg.jl.interface = interface;
0513 msg.msg.msg.jl.join_or_leave = join_or_leave;
0514 TCPIP_APIMSG(&msg);
0515 return conn->err;
0516 }
0517 #endif
0518
0519 #if LWIP_DNS
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530 err_t
0531 netconn_gethostbyname(const char *name, struct ip_addr *addr)
0532 {
0533 struct dns_api_msg msg;
0534 err_t err;
0535 sys_sem_t sem;
0536
0537 LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
0538 LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
0539
0540 sem = sys_sem_new(0);
0541 if (sem == SYS_SEM_NULL) {
0542 return ERR_MEM;
0543 }
0544
0545 msg.name = name;
0546 msg.addr = addr;
0547 msg.err = &err;
0548 msg.sem = sem;
0549
0550 tcpip_callback(do_gethostbyname, &msg);
0551 sys_sem_wait(sem);
0552 sys_sem_free(sem);
0553
0554 return err;
0555 }
0556 #endif
0557
0558 #endif