From fffb54e2c648a50f5bf1ace6cae5cb8d0119da59 Mon Sep 17 00:00:00 2001 From: Marko Mikulicic Date: Tue, 8 Nov 2016 23:29:07 +0100 Subject: [PATCH] Implementing MG interfaces PUBLISHED_FROM=46496c2d5340a0bbe4fe1c6c9ff187bc65d2d35f --- docs/c-api/net.h/intro.md | 2 + docs/c-api/net.h/mg_event_handler_t.md | 3 +- docs/c-api/net.h/mg_mgr_init_opt.md | 14 + docs/c-api/net.h/struct_mg_connection.md | 1 + docs/c-api/net.h/struct_mg_mgr.md | 3 +- docs/c-api/net.h/struct_mg_mgr_init_opts.md | 26 + mongoose.c | 571 +++++++++++++++----- mongoose.h | 261 +++++---- 8 files changed, 646 insertions(+), 235 deletions(-) create mode 100644 docs/c-api/net.h/mg_mgr_init_opt.md create mode 100644 docs/c-api/net.h/struct_mg_mgr_init_opts.md diff --git a/docs/c-api/net.h/intro.md b/docs/c-api/net.h/intro.md index 89520db6..f0c93de1 100644 --- a/docs/c-api/net.h/intro.md +++ b/docs/c-api/net.h/intro.md @@ -15,6 +15,7 @@ items: - { name: mg_enable_multithreading.md } - { name: mg_mgr_free.md } - { name: mg_mgr_init.md } + - { name: mg_mgr_init_opt.md } - { name: mg_mgr_poll.md } - { name: mg_next.md } - { name: mg_printf.md } @@ -31,6 +32,7 @@ items: - { name: struct_mg_connect_opts.md } - { name: struct_mg_connection.md } - { name: struct_mg_mgr.md } + - { name: struct_mg_mgr_init_opts.md } - { name: struct_mg_multithreading_opts.md } --- diff --git a/docs/c-api/net.h/mg_event_handler_t.md b/docs/c-api/net.h/mg_event_handler_t.md index 2360b79e..191805c8 100644 --- a/docs/c-api/net.h/mg_event_handler_t.md +++ b/docs/c-api/net.h/mg_event_handler_t.md @@ -3,7 +3,8 @@ title: "mg_event_handler_t" decl_name: "mg_event_handler_t" symbol_kind: "typedef" signature: | - typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev, void *ev_data); + typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev, + void *ev_data); --- Callback function (event handler) prototype. Must be defined by the user. diff --git a/docs/c-api/net.h/mg_mgr_init_opt.md b/docs/c-api/net.h/mg_mgr_init_opt.md new file mode 100644 index 00000000..767fed2c --- /dev/null +++ b/docs/c-api/net.h/mg_mgr_init_opt.md @@ -0,0 +1,14 @@ +--- +title: "mg_mgr_init_opt()" +decl_name: "mg_mgr_init_opt" +symbol_kind: "func" +signature: | + void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data, + struct mg_mgr_init_opts opts); +--- + +Like `mg_mgr_init` but with more options. + +Notably, this allows you to create a manger and choose +dynamically which networking interface implementation to use. + diff --git a/docs/c-api/net.h/struct_mg_connection.md b/docs/c-api/net.h/struct_mg_connection.md index 805675c5..a554b26a 100644 --- a/docs/c-api/net.h/struct_mg_connection.md +++ b/docs/c-api/net.h/struct_mg_connection.md @@ -42,6 +42,7 @@ signature: | } priv_1; /* Used by mg_enable_multithreading() */ void *priv_2; /* Used by mg_enable_multithreading() */ void *mgr_data; /* Implementation-specific event manager's data. */ + struct mg_iface *iface; unsigned long flags; /* Flags set by Mongoose */ #define MG_F_LISTENING (1 << 0) /* This connection is listening */ diff --git a/docs/c-api/net.h/struct_mg_mgr.md b/docs/c-api/net.h/struct_mg_mgr.md index 384f15f6..dcc2b523 100644 --- a/docs/c-api/net.h/struct_mg_mgr.md +++ b/docs/c-api/net.h/struct_mg_mgr.md @@ -12,7 +12,8 @@ signature: | sock_t ctl[2]; /* Socketpair for mg_broadcast() */ #endif void *user_data; /* User data */ - void *mgr_data; /* Implementation-specific event manager's data. */ + int num_ifaces; + struct mg_iface **ifaces; /* network interfaces */ #if MG_ENABLE_JAVASCRIPT struct v7 *v7; #endif diff --git a/docs/c-api/net.h/struct_mg_mgr_init_opts.md b/docs/c-api/net.h/struct_mg_mgr_init_opts.md new file mode 100644 index 00000000..da3e4951 --- /dev/null +++ b/docs/c-api/net.h/struct_mg_mgr_init_opts.md @@ -0,0 +1,26 @@ +--- +title: "struct mg_mgr_init_opts" +decl_name: "struct mg_mgr_init_opts" +symbol_kind: "struct" +signature: | + struct mg_mgr_init_opts { + struct mg_iface_vtable *main_iface; + int num_ifaces; + struct mg_iface_vtable **ifaces; + }; +--- + +Optional parameters to `mg_mgr_init_opt()`. + +If `main_iface` is not NULL, it will be used as the main interface in the +default interface set. The pointer will be free'd by `mg_mgr_free`. +Otherwise, the main interface will be autodetected based on the current +platform. + +If `num_ifaces` is 0 and `ifaces` is NULL, the default interface set will be +used. +This is an advanced option, as it requires you to construct a full interface +set, including special networking interfaces required by some optional +features such as TCP tunneling. Memory backing `ifaces` and each of the +`num_ifaces` pointers it contains will be reclaimed by `mg_mgr_free`. + diff --git a/mongoose.c b/mongoose.c index 6a62949c..fd32a5a9 100644 --- a/mongoose.c +++ b/mongoose.c @@ -1832,11 +1832,6 @@ int64_t cs_to64(const char *s) { #define intptr_t long #endif -extern void mg_ev_mgr_init(struct mg_mgr *mgr); -extern void mg_ev_mgr_free(struct mg_mgr *mgr); -extern void mg_ev_mgr_add_conn(struct mg_connection *nc); -extern void mg_ev_mgr_remove_conn(struct mg_connection *nc); - MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c) { DBG(("%p %p", mgr, c)); c->mgr = mgr; @@ -1844,14 +1839,14 @@ MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c) { mgr->active_connections = c; c->prev = NULL; if (c->next != NULL) c->next->prev = c; - mg_ev_mgr_add_conn(c); + c->iface->vtable->add_conn(c); } MG_INTERNAL void mg_remove_conn(struct mg_connection *conn) { if (conn->prev == NULL) conn->mgr->active_connections = conn->next; if (conn->prev) conn->prev->next = conn->next; if (conn->next) conn->next->prev = conn->prev; - mg_ev_mgr_remove_conn(conn); + conn->iface->vtable->remove_conn(conn); } MG_INTERNAL void mg_call(struct mg_connection *nc, @@ -1893,7 +1888,7 @@ MG_INTERNAL void mg_call(struct mg_connection *nc, (nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK); } if (recved > 0 && !(nc->flags & MG_F_UDP)) { - mg_if_recved(nc, recved); + nc->iface->vtable->recved(nc, recved); } } if (ev != MG_EV_POLL) { @@ -1924,7 +1919,7 @@ void mg_if_poll(struct mg_connection *nc, time_t now) { } static void mg_destroy_conn(struct mg_connection *conn, int destroy_if) { - if (destroy_if) mg_if_destroy_conn(conn); + if (destroy_if) conn->iface->vtable->destroy_conn(conn); if (conn->proto_data != NULL && conn->proto_data_destructor != NULL) { conn->proto_data_destructor(conn->proto_data); } @@ -1942,12 +1937,19 @@ static void mg_destroy_conn(struct mg_connection *conn, int destroy_if) { void mg_close_conn(struct mg_connection *conn) { DBG(("%p %lu %d", conn, conn->flags, conn->sock)); mg_remove_conn(conn); - mg_if_destroy_conn(conn); + conn->iface->vtable->destroy_conn(conn); mg_call(conn, NULL, MG_EV_CLOSE, NULL); mg_destroy_conn(conn, 0 /* destroy_if */); } void mg_mgr_init(struct mg_mgr *m, void *user_data) { + struct mg_mgr_init_opts opts; + memset(&opts, 0, sizeof(opts)); + mg_mgr_init_opt(m, user_data, opts); +} + +void mg_mgr_init_opt(struct mg_mgr *m, void *user_data, + struct mg_mgr_init_opts opts) { memset(m, 0, sizeof(*m)); #if MG_ENABLE_BROADCAST m->ctl[0] = m->ctl[1] = INVALID_SOCKET; @@ -1974,8 +1976,23 @@ void mg_mgr_init(struct mg_mgr *m, void *user_data) { } } #endif - - mg_ev_mgr_init(m); + { + int i; + if (opts.num_ifaces == 0) { + opts.num_ifaces = MG_NUM_IFACES; + opts.ifaces = mg_ifaces; + } + if (opts.main_iface != NULL) { + opts.ifaces[MG_MAIN_IFACE] = opts.main_iface; + } + m->num_ifaces = opts.num_ifaces; + m->ifaces = + (struct mg_iface **) MG_MALLOC(sizeof(*m->ifaces) * opts.num_ifaces); + for (i = 0; i < MG_NUM_IFACES; i++) { + m->ifaces[i] = mg_if_create_iface(opts.ifaces[i], m); + m->ifaces[i]->vtable->init(m->ifaces[i]); + } + } DBG(("==================================")); DBG(("init mgr=%p", m)); } @@ -2025,7 +2042,29 @@ void mg_mgr_free(struct mg_mgr *m) { mg_close_conn(conn); } - mg_ev_mgr_free(m); + { + int i; + for (i = 0; i < m->num_ifaces; i++) { + m->ifaces[i]->vtable->free(m->ifaces[i]); + MG_FREE(m->ifaces[i]); + } + MG_FREE(m->ifaces); + } +} + +time_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms) { + int i; + time_t now = 0; /* oh GCC, seriously ? */ + + if (m->num_ifaces == 0) { + LOG(LL_ERROR, ("cannot poll: no interfaces")); + return 0; + } + + for (i = 0; i < m->num_ifaces; i++) { + now = m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms); + } + return now; } int mg_vprintf(struct mg_connection *nc, const char *fmt, va_list ap) { @@ -2099,6 +2138,7 @@ MG_INTERNAL struct mg_connection *mg_create_connection_base( conn->handler = callback; conn->mgr = mgr; conn->last_io_time = (time_t) mg_time(); + conn->iface = mgr->ifaces[MG_MAIN_IFACE]; conn->flags = opts.flags & _MG_ALLOWED_CONNECT_FLAGS_MASK; conn->user_data = opts.user_data; /* @@ -2119,9 +2159,11 @@ MG_INTERNAL struct mg_connection *mg_create_connection( struct mg_add_sock_opts opts) { struct mg_connection *conn = mg_create_connection_base(mgr, callback, opts); - if (!mg_if_create_conn(conn)) { + if (conn != NULL && !conn->iface->vtable->create_conn(conn)) { MG_FREE(conn); conn = NULL; + } + if (conn == NULL) { MG_SET_PTRPTR(opts.error_string, "failed to init connection"); } @@ -2435,9 +2477,9 @@ void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa, void mg_send(struct mg_connection *nc, const void *buf, int len) { nc->last_io_time = (time_t) mg_time(); if (nc->flags & MG_F_UDP) { - mg_if_udp_send(nc, buf, len); + nc->iface->vtable->udp_send(nc, buf, len); } else { - mg_if_tcp_send(nc, buf, len); + nc->iface->vtable->tcp_send(nc, buf, len); } #if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP if (nc->mgr && nc->mgr->hexdump_file != NULL) { @@ -2534,7 +2576,7 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, } else { /* Drop on the floor. */ MG_FREE(buf); - mg_if_recved(nc, len); + nc->iface->vtable->recved(nc, len); } } @@ -2552,9 +2594,9 @@ MG_INTERNAL struct mg_connection *mg_do_connect(struct mg_connection *nc, nc->flags |= MG_F_CONNECTING; if (proto == SOCK_DGRAM) { - mg_if_connect_udp(nc); + nc->iface->vtable->connect_udp(nc); } else { - mg_if_connect_tcp(nc, sa); + nc->iface->vtable->connect_tcp(nc, sa); } mg_add_conn(nc->mgr, nc); return nc; @@ -2770,9 +2812,9 @@ struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address, #endif /* MG_ENABLE_SSL */ if (nc->flags & MG_F_UDP) { - rc = mg_if_listen_udp(nc, &nc->sa); + rc = nc->iface->vtable->listen_udp(nc, &nc->sa); } else { - rc = mg_if_listen_tcp(nc, &nc->sa); + rc = nc->iface->vtable->listen_tcp(nc, &nc->sa); } if (rc != 0) { DBG(("Failed to open listener: %d", rc)); @@ -2881,6 +2923,15 @@ double mg_set_timer(struct mg_connection *c, double timestamp) { return result; } +void mg_sock_set(struct mg_connection *nc, sock_t sock) { + nc->iface->vtable->sock_set(nc, sock); +} + +void mg_if_get_conn_addr(struct mg_connection *nc, int remote, + union socket_address *sa) { + nc->iface->vtable->get_conn_addr(nc, remote, sa); +} + struct mg_connection *mg_add_sock_opt(struct mg_mgr *s, sock_t sock, mg_event_handler_t callback, struct mg_add_sock_opts opts) { @@ -2903,6 +2954,53 @@ double mg_time(void) { return cs_time(); } #ifdef MG_MODULE_LINES +#line 1 "mongoose/src/net_if_socket.h" +#endif +/* + * Copyright (c) 2014-2016 Cesanta Software Limited + * All rights reserved + */ + +#ifndef CS_MONGOOSE_SRC_NET_IF_SOCKET_H_ +#define CS_MONGOOSE_SRC_NET_IF_SOCKET_H_ + +/* Amalgamated: #include "mongoose/src/net_if.h" */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef MG_ENABLE_NET_IF_SOCKET +#define MG_ENABLE_NET_IF_SOCKET MG_NET_IF == MG_NET_IF_SOCKET +#endif + +extern struct mg_iface_vtable mg_socket_iface_vtable; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CS_MONGOOSE_SRC_NET_IF_SOCKET_H_ */ +#ifdef MG_MODULE_LINES +#line 1 "mongoose/src/net_if.c" +#endif +/* Amalgamated: #include "mongoose/src/net_if.h" */ +/* Amalgamated: #include "mongoose/src/internal.h" */ +/* Amalgamated: #include "mongoose/src/net_if_socket.h" */ + +extern struct mg_iface_vtable mg_default_iface_vtable; + +struct mg_iface_vtable *mg_ifaces[] = {&mg_default_iface_vtable}; + +struct mg_iface *mg_if_create_iface(struct mg_iface_vtable *vtable, + struct mg_mgr *mgr) { + struct mg_iface *iface = (struct mg_iface *) MG_CALLOC(1, sizeof(*iface)); + iface->mgr = mgr; + iface->data = NULL; + iface->vtable = vtable; + return iface; +} +#ifdef MG_MODULE_LINES #line 1 "mongoose/src/net_if_socket.c" #endif /* @@ -2910,8 +3008,9 @@ double mg_time(void) { * All rights reserved */ -#if MG_NET_IF == MG_NET_IF_SOCKET +#if MG_ENABLE_NET_IF_SOCKET +/* Amalgamated: #include "mongoose/src/net_if_socket.h" */ /* Amalgamated: #include "mongoose/src/internal.h" */ /* Amalgamated: #include "mongoose/src/util.h" */ @@ -2948,8 +3047,8 @@ static int mg_is_error(int n) { ); } -void mg_if_connect_tcp(struct mg_connection *nc, - const union socket_address *sa) { +void mg_socket_if_connect_tcp(struct mg_connection *nc, + const union socket_address *sa) { int rc, proto = 0; nc->sock = socket(AF_INET, SOCK_STREAM, proto); if (nc->sock == INVALID_SOCKET) { @@ -2964,7 +3063,7 @@ void mg_if_connect_tcp(struct mg_connection *nc, LOG(LL_INFO, ("%p sock %d err %d", nc, nc->sock, nc->err)); } -void mg_if_connect_udp(struct mg_connection *nc) { +void mg_socket_if_connect_udp(struct mg_connection *nc) { nc->sock = socket(AF_INET, SOCK_DGRAM, 0); if (nc->sock == INVALID_SOCKET) { nc->err = mg_get_errno() ? mg_get_errno() : 1; @@ -2978,7 +3077,8 @@ void mg_if_connect_udp(struct mg_connection *nc) { nc->err = 0; } -int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { +int mg_socket_if_listen_tcp(struct mg_connection *nc, + union socket_address *sa) { int proto = 0; sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto); if (sock == INVALID_SOCKET) { @@ -2988,32 +3088,35 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { return 0; } -int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { +int mg_socket_if_listen_udp(struct mg_connection *nc, + union socket_address *sa) { sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0); if (sock == INVALID_SOCKET) return (mg_get_errno() ? mg_get_errno() : 1); mg_sock_set(nc, sock); return 0; } -void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_socket_if_tcp_send(struct mg_connection *nc, const void *buf, + size_t len) { mbuf_append(&nc->send_mbuf, buf, len); } -void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_socket_if_udp_send(struct mg_connection *nc, const void *buf, + size_t len) { mbuf_append(&nc->send_mbuf, buf, len); } -void mg_if_recved(struct mg_connection *nc, size_t len) { +void mg_socket_if_recved(struct mg_connection *nc, size_t len) { (void) nc; (void) len; } -int mg_if_create_conn(struct mg_connection *nc) { +int mg_socket_if_create_conn(struct mg_connection *nc) { (void) nc; return 1; } -void mg_if_destroy_conn(struct mg_connection *nc) { +void mg_socket_if_destroy_conn(struct mg_connection *nc) { if (nc->sock == INVALID_SOCKET) return; if (!(nc->flags & MG_F_UDP)) { closesocket(nc->sock); @@ -3390,32 +3493,32 @@ static void mg_mgr_handle_ctl_sock(struct mg_mgr *mgr) { #endif /* Associate a socket to a connection. */ -void mg_sock_set(struct mg_connection *nc, sock_t sock) { +void mg_socket_if_sock_set(struct mg_connection *nc, sock_t sock) { mg_set_non_blocking_mode(sock); mg_set_close_on_exec(sock); nc->sock = sock; DBG(("%p %d", nc, sock)); } -void mg_ev_mgr_init(struct mg_mgr *mgr) { - (void) mgr; - DBG(("%p using select()", mgr)); +void mg_socket_if_init(struct mg_iface *iface) { + (void) iface; + DBG(("%p using select()", iface->mgr)); #if MG_ENABLE_BROADCAST do { - mg_socketpair(mgr->ctl, SOCK_DGRAM); - } while (mgr->ctl[0] == INVALID_SOCKET); + mg_socketpair(iface->mgr->ctl, SOCK_DGRAM); + } while (iface->mgr->ctl[0] == INVALID_SOCKET); #endif } -void mg_ev_mgr_free(struct mg_mgr *mgr) { - (void) mgr; +void mg_socket_if_free(struct mg_iface *iface) { + (void) iface; } -void mg_ev_mgr_add_conn(struct mg_connection *nc) { +void mg_socket_if_add_conn(struct mg_connection *nc) { (void) nc; } -void mg_ev_mgr_remove_conn(struct mg_connection *nc) { +void mg_socket_if_remove_conn(struct mg_connection *nc) { (void) nc; } @@ -3432,7 +3535,8 @@ void mg_add_to_set(sock_t sock, fd_set *set, sock_t *max_fd) { } } -time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { +time_t mg_socket_if_poll(struct mg_iface *iface, int timeout_ms) { + struct mg_mgr *mgr = iface->mgr; double now = mg_time(); double min_timer; struct mg_connection *nc, *tmp; @@ -3618,12 +3722,39 @@ void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags) { mg_sock_addr_to_str(&sa, buf, len, flags); } -void mg_if_get_conn_addr(struct mg_connection *nc, int remote, - union socket_address *sa) { +void mg_socket_if_get_conn_addr(struct mg_connection *nc, int remote, + union socket_address *sa) { mg_sock_get_addr(nc->sock, remote, sa); } -#endif /* MG_NET_IF == MG_NET_IF_SOCKET */ +/* clang-format off */ +#define MG_SOCKET_IFACE_VTABLE \ + { \ + mg_socket_if_init, \ + mg_socket_if_free, \ + mg_socket_if_add_conn, \ + mg_socket_if_remove_conn, \ + mg_socket_if_poll, \ + mg_socket_if_listen_tcp, \ + mg_socket_if_listen_udp, \ + mg_socket_if_connect_tcp, \ + mg_socket_if_connect_udp, \ + mg_socket_if_tcp_send, \ + mg_socket_if_udp_send, \ + mg_socket_if_recved, \ + mg_socket_if_create_conn, \ + mg_socket_if_destroy_conn, \ + mg_socket_if_sock_set, \ + mg_socket_if_get_conn_addr, \ + } +/* clang-format on */ + +struct mg_iface_vtable mg_socket_iface_vtable = MG_SOCKET_IFACE_VTABLE; +#if MG_NET_IF == MG_NET_IF_SOCKET +struct mg_iface_vtable mg_default_iface_vtable = MG_SOCKET_IFACE_VTABLE; +#endif + +#endif /* MG_ENABLE_NET_IF_SOCKET */ #ifdef MG_MODULE_LINES #line 1 "mongoose/src/multithreading.c" #endif @@ -10036,7 +10167,7 @@ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io) { } if (cm->payload.len != 0) { - *ptr = (char)-1; + *ptr = (char) -1; ptr++; memcpy(ptr, cm->payload.p, cm->payload.len); } @@ -11041,6 +11172,34 @@ void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg) { #endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK && !defined(MG_SIMPLELINK_NO_OSI) */ #ifdef MG_MODULE_LINES +#line 1 "common/platforms/simplelink/sl_net_if.h" +#endif +/* + * Copyright (c) 2014-2016 Cesanta Software Limited + * All rights reserved + */ + +#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_ +#define CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_ + +/* Amalgamated: #include "mongoose/src/net_if.h" */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef MG_ENABLE_NET_IF_SIMPLELINK +#define MG_ENABLE_NET_IF_SIMPLELINK MG_NET_IF == MG_NET_IF_SIMPLELINK +#endif + +extern struct mg_iface_vtable mg_simplelink_iface_vtable; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_ */ +#ifdef MG_MODULE_LINES #line 1 "common/platforms/simplelink/sl_net_if.c" #endif /* @@ -11048,7 +11207,9 @@ void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg) { * All rights reserved */ -#if MG_NET_IF == MG_NET_IF_SIMPLELINK +/* Amalgamated: #include "common/platforms/simplelink/sl_net_if.h" */ + +#if MG_ENABLE_NET_IF_SIMPLELINK /* Amalgamated: #include "mongoose/src/internal.h" */ /* Amalgamated: #include "mongoose/src/util.h" */ @@ -11137,8 +11298,8 @@ static int mg_is_error(int n) { return (n < 0 && n != SL_EALREADY && n != SL_EAGAIN); } -void mg_if_connect_tcp(struct mg_connection *nc, - const union socket_address *sa) { +void mg_sl_if_connect_tcp(struct mg_connection *nc, + const union socket_address *sa) { int proto = 0; if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET; sock_t sock = sl_Socket(AF_INET, SOCK_STREAM, proto); @@ -11157,7 +11318,7 @@ out: ntohs(sa->sin.sin_port), nc->sock, proto, nc->err)); } -void mg_if_connect_udp(struct mg_connection *nc) { +void mg_sl_if_connect_udp(struct mg_connection *nc) { sock_t sock = sl_Socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { nc->err = sock; @@ -11167,7 +11328,7 @@ void mg_if_connect_udp(struct mg_connection *nc) { nc->err = 0; } -int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { +int mg_sl_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { int proto = 0; if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET; sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto); @@ -11180,32 +11341,32 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { #endif } -int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { +int mg_sl_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0); if (sock == INVALID_SOCKET) return (errno ? errno : 1); mg_sock_set(nc, sock); return 0; } -void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_sl_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { mbuf_append(&nc->send_mbuf, buf, len); } -void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_sl_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { mbuf_append(&nc->send_mbuf, buf, len); } -void mg_if_recved(struct mg_connection *nc, size_t len) { +void mg_sl_if_recved(struct mg_connection *nc, size_t len) { (void) nc; (void) len; } -int mg_if_create_conn(struct mg_connection *nc) { +int mg_sl_if_create_conn(struct mg_connection *nc) { (void) nc; return 1; } -void mg_if_destroy_conn(struct mg_connection *nc) { +void mg_sl_if_destroy_conn(struct mg_connection *nc) { if (nc->sock == INVALID_SOCKET) return; /* For UDP, only close outgoing sockets or listeners. */ if (!(nc->flags & MG_F_UDP) || nc->listener == NULL) { @@ -11394,30 +11555,31 @@ void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) { } /* Associate a socket to a connection. */ -void mg_sock_set(struct mg_connection *nc, sock_t sock) { +void mg_sl_if_sock_set(struct mg_connection *nc, sock_t sock) { mg_set_non_blocking_mode(sock); nc->sock = sock; DBG(("%p %d", nc, sock)); } -void mg_ev_mgr_init(struct mg_mgr *mgr) { - (void) mgr; - DBG(("%p using sl_Select()", mgr)); +void mg_sl_if_init(struct mg_iface *iface) { + (void) iface; + DBG(("%p using sl_Select()", iface->mgr)); } -void mg_ev_mgr_free(struct mg_mgr *mgr) { - (void) mgr; +void mg_sl_if_free(struct mg_iface *iface) { + (void) iface; } -void mg_ev_mgr_add_conn(struct mg_connection *nc) { +void mg_sl_if_add_conn(struct mg_connection *nc) { (void) nc; } -void mg_ev_mgr_remove_conn(struct mg_connection *nc) { +void mg_sl_if_remove_conn(struct mg_connection *nc) { (void) nc; } -time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { +time_t mg_sl_if_poll(struct mg_iface *iface, int timeout_ms) { + struct mg_mgr *mgr = iface->mgr; double now = mg_time(); double min_timer; struct mg_connection *nc, *tmp; @@ -11516,8 +11678,8 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { return now; } -void mg_if_get_conn_addr(struct mg_connection *nc, int remote, - union socket_address *sa) { +void mg_sl_if_get_conn_addr(struct mg_connection *nc, int remote, + union socket_address *sa) { /* SimpleLink does not provide a way to get socket's peer address after * accept or connect. Address hould have been preserved in the connection, * so we do our best here by using it. */ @@ -11536,8 +11698,8 @@ void sl_restart_cb(struct mg_mgr *mgr) { if (nc->flags & MG_F_LISTENING) { DBG(("restarting %p %s:%d", nc, inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port))); - int res = (nc->flags & MG_F_UDP ? mg_if_listen_udp(nc, &nc->sa) - : mg_if_listen_tcp(nc, &nc->sa)); + int res = (nc->flags & MG_F_UDP ? mg_sl_if_listen_udp(nc, &nc->sa) + : mg_sl_if_listen_tcp(nc, &nc->sa)); if (res == 0) continue; /* Well, we tried and failed. Fall through to closing. */ } @@ -11549,7 +11711,34 @@ void sl_restart_cb(struct mg_mgr *mgr) { } } -#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */ +/* clang-format off */ +#define MG_SL_IFACE_VTABLE \ + { \ + mg_sl_if_init, \ + mg_sl_if_free, \ + mg_sl_if_add_conn, \ + mg_sl_if_remove_conn, \ + mg_sl_if_poll, \ + mg_sl_if_listen_tcp, \ + mg_sl_if_listen_udp, \ + mg_sl_if_connect_tcp, \ + mg_sl_if_connect_udp, \ + mg_sl_if_tcp_send, \ + mg_sl_if_udp_send, \ + mg_sl_if_recved, \ + mg_sl_if_create_conn, \ + mg_sl_if_destroy_conn, \ + mg_sl_if_sock_set, \ + mg_sl_if_get_conn_addr, \ + } +/* clang-format on */ + +struct mg_iface_vtable mg_simplelink_iface_vtable = MG_SL_IFACE_VTABLE; +#if MG_NET_IF == MG_NET_IF_SIMPLELINK +struct mg_iface_vtable mg_default_iface_vtable = MG_SL_IFACE_VTABLE; +#endif + +#endif /* MG_ENABLE_NET_IF_SIMPLELINK */ #ifdef MG_MODULE_LINES #line 1 "common/platforms/lwip/mg_lwip_net_if.h" #endif @@ -11561,10 +11750,16 @@ void sl_restart_cb(struct mg_mgr *mgr) { #ifndef CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_ #define CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_ -#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL +#ifndef MG_ENABLE_NET_IF_LWIP_LOW_LEVEL +#define MG_ENABLE_NET_IF_LWIP_LOW_LEVEL MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL +#endif + +#if MG_ENABLE_NET_IF_LWIP_LOW_LEVEL #include +extern struct mg_iface_vtable mg_lwip_iface_vtable; + struct mg_lwip_conn_state { union { struct tcp_pcb *tcp; @@ -11591,7 +11786,7 @@ void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc); /* To be implemented by the platform. */ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); -#endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */ +#endif /* MG_ENABLE_NET_IF_LWIP_LOW_LEVEL */ #endif /* CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_ */ #ifdef MG_MODULE_LINES @@ -11602,7 +11797,7 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); * All rights reserved */ -#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL +#if MG_ENABLE_NET_IF_LWIP_LOW_LEVEL #include #include @@ -11616,34 +11811,40 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); * lwip functions */ #if MG_ENABLE_IPV6 -# define TCP_NEW tcp_new_ip6 -# define TCP_BIND tcp_bind_ip6 -# define UDP_BIND udp_bind_ip6 -# define IPADDR_NTOA(x) ip6addr_ntoa((const ip6_addr_t *)(x)) -# define SET_ADDR(dst, src) \ - memcpy((dst)->sin6.sin6_addr.s6_addr, (src)->ip6.addr, \ - sizeof((dst)->sin6.sin6_addr.s6_addr)) +#define TCP_NEW tcp_new_ip6 +#define TCP_BIND tcp_bind_ip6 +#define UDP_BIND udp_bind_ip6 +#define IPADDR_NTOA(x) ip6addr_ntoa((const ip6_addr_t *)(x)) +#define SET_ADDR(dst, src) \ + memcpy((dst)->sin6.sin6_addr.s6_addr, (src)->ip6.addr, \ + sizeof((dst)->sin6.sin6_addr.s6_addr)) #else -# define TCP_NEW tcp_new -# define TCP_BIND tcp_bind -# define UDP_BIND udp_bind -# define IPADDR_NTOA ipaddr_ntoa -# define SET_ADDR(dst, src) (dst)->sin.sin_addr.s_addr = GET_IPV4(src) +#define TCP_NEW tcp_new +#define TCP_BIND tcp_bind +#define UDP_BIND udp_bind +#define IPADDR_NTOA ipaddr_ntoa +#define SET_ADDR(dst, src) (dst)->sin.sin_addr.s_addr = GET_IPV4(src) #endif /* * If lwip is compiled with ipv6 support, then API changes even for ipv4 */ #if !defined(LWIP_IPV6) || !LWIP_IPV6 -# define GET_IPV4(ipX_addr) ((ipX_addr)->addr) +#define GET_IPV4(ipX_addr) ((ipX_addr)->addr) #else -# define GET_IPV4(ipX_addr) ((ipX_addr)->ip4.addr) +#define GET_IPV4(ipX_addr) ((ipX_addr)->ip4.addr) #endif void mg_lwip_ssl_do_hs(struct mg_connection *nc); void mg_lwip_ssl_send(struct mg_connection *nc); void mg_lwip_ssl_recv(struct mg_connection *nc); +void mg_lwip_if_init(struct mg_iface *iface); +void mg_lwip_if_free(struct mg_iface *iface); +void mg_lwip_if_add_conn(struct mg_connection *nc); +void mg_lwip_if_remove_conn(struct mg_connection *nc); +time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms); + #if LWIP_TCP_KEEPALIVE void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle, int interval, int count) { @@ -11793,8 +11994,8 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, return ERR_OK; } -void mg_if_connect_tcp(struct mg_connection *nc, - const union socket_address *sa) { +void mg_lwip_if_connect_tcp(struct mg_connection *nc, + const union socket_address *sa) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct tcp_pcb *tpcb = TCP_NEW(); cs->pcb.tcp = tpcb; @@ -11848,7 +12049,7 @@ static void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, mg_if_recv_udp_cb(nc, data, len, &sa, sizeof(sa.sin)); } -void mg_if_connect_udp(struct mg_connection *nc) { +void mg_lwip_if_connect_udp(struct mg_connection *nc) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct udp_pcb *upcb = udp_new(); cs->err = UDP_BIND(upcb, IP_ADDR_ANY, 0 /* any port */); @@ -11903,7 +12104,7 @@ static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) { return ERR_OK; } -int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { +int mg_lwip_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct tcp_pcb *tpcb = TCP_NEW(); ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr; @@ -11921,7 +12122,7 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { return 0; } -int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { +int mg_lwip_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct udp_pcb *upcb = udp_new(); ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr; @@ -11977,12 +12178,14 @@ static void mg_lwip_send_more(struct mg_connection *nc) { mbuf_trim(&nc->send_mbuf); } -void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_lwip_if_tcp_send(struct mg_connection *nc, const void *buf, + size_t len) { mbuf_append(&nc->send_mbuf, buf, len); mg_lwip_mgr_schedule_poll(nc->mgr); } -void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf, + size_t len) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; if (nc->sock == INVALID_SOCKET || cs->pcb.udp == NULL) { /* @@ -12009,7 +12212,7 @@ void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { } } -void mg_if_recved(struct mg_connection *nc, size_t len) { +void mg_lwip_if_recved(struct mg_connection *nc, size_t len) { if (nc->flags & MG_F_UDP) return; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL) { @@ -12017,8 +12220,8 @@ void mg_if_recved(struct mg_connection *nc, size_t len) { return; } DBG(("%p %p %u", nc, cs->pcb.tcp, len)); - /* Currently SSL acknowledges data immediately. - * TODO(rojer): Find a way to propagate mg_if_recved. */ +/* Currently SSL acknowledges data immediately. + * TODO(rojer): Find a way to propagate mg_lwip_if_recved. */ #if MG_ENABLE_SSL if (nc->ssl == NULL) { tcp_recved(cs->pcb.tcp, len); @@ -12029,7 +12232,7 @@ void mg_if_recved(struct mg_connection *nc, size_t len) { mbuf_trim(&nc->recv_mbuf); } -int mg_if_create_conn(struct mg_connection *nc) { +int mg_lwip_if_create_conn(struct mg_connection *nc) { struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) calloc(1, sizeof(*cs)); if (cs == NULL) return 0; @@ -12037,7 +12240,7 @@ int mg_if_create_conn(struct mg_connection *nc) { return 1; } -void mg_if_destroy_conn(struct mg_connection *nc) { +void mg_lwip_if_destroy_conn(struct mg_connection *nc) { if (nc->sock == INVALID_SOCKET) return; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; if (!(nc->flags & MG_F_UDP)) { @@ -12068,8 +12271,8 @@ void mg_if_destroy_conn(struct mg_connection *nc) { nc->sock = INVALID_SOCKET; } -void mg_if_get_conn_addr(struct mg_connection *nc, int remote, - union socket_address *sa) { +void mg_lwip_if_get_conn_addr(struct mg_connection *nc, int remote, + union socket_address *sa) { memset(sa, 0, sizeof(*sa)); if (nc->sock == INVALID_SOCKET) return; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; @@ -12093,11 +12296,38 @@ void mg_if_get_conn_addr(struct mg_connection *nc, int remote, } } -void mg_sock_set(struct mg_connection *nc, sock_t sock) { +void mg_lwip_if_sock_set(struct mg_connection *nc, sock_t sock) { nc->sock = sock; } -#endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */ +/* clang-format off */ +#define MG_LWIP_IFACE_VTABLE \ + { \ + mg_lwip_if_init, \ + mg_lwip_if_free, \ + mg_lwip_if_add_conn, \ + mg_lwip_if_remove_conn, \ + mg_lwip_if_poll, \ + mg_lwip_if_listen_tcp, \ + mg_lwip_if_listen_udp, \ + mg_lwip_if_connect_tcp, \ + mg_lwip_if_connect_udp, \ + mg_lwip_if_tcp_send, \ + mg_lwip_if_udp_send, \ + mg_lwip_if_recved, \ + mg_lwip_if_create_conn, \ + mg_lwip_if_destroy_conn, \ + mg_lwip_if_sock_set, \ + mg_lwip_if_get_conn_addr, \ + } +/* clang-format on */ + +struct mg_iface_vtable mg_lwip_iface_vtable = MG_LWIP_IFACE_VTABLE; +#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL +struct mg_iface_vtable mg_default_iface_vtable = MG_LWIP_IFACE_VTABLE; +#endif + +#endif /* MG_ENABLE_NET_IF_LWIP_LOW_LEVEL */ #ifdef MG_MODULE_LINES #line 1 "common/platforms/lwip/mg_lwip_ev_mgr.c" #endif @@ -12125,7 +12355,7 @@ struct mg_ev_mgr_lwip_data { void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc) { struct mg_ev_mgr_lwip_data *md = - (struct mg_ev_mgr_lwip_data *) nc->mgr->mgr_data; + (struct mg_ev_mgr_lwip_data *) nc->iface->data; if (md->sig_queue_len >= MG_SIG_QUEUE_LEN) return; int end_index = (md->start_index + md->sig_queue_len) % MG_SIG_QUEUE_LEN; md->sig_queue[end_index].sig = sig; @@ -12134,14 +12364,16 @@ void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc) { } void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) { - struct mg_ev_mgr_lwip_data *md = (struct mg_ev_mgr_lwip_data *) mgr->mgr_data; + struct mg_ev_mgr_lwip_data *md = + (struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data; while (md->sig_queue_len > 0) { struct mg_connection *nc = md->sig_queue[md->start_index].nc; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; switch (md->sig_queue[md->start_index].sig) { case MG_SIG_CONNECT_RESULT: { #ifdef SSL_KRYPTON - if (cs->err == 0 && nc->flags & MG_F_SSL && !(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) { + if (cs->err == 0 && nc->flags & MG_F_SSL && + !(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) { SSL_set_fd(nc->ssl, (intptr_t) nc); mg_lwip_ssl_do_hs(nc); } else @@ -12174,23 +12406,23 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) { } } -void mg_ev_mgr_init(struct mg_mgr *mgr) { +void mg_lwip_if_init(struct mg_iface *iface) { LOG(LL_INFO, ("%p Mongoose init")); - mgr->mgr_data = MG_CALLOC(1, sizeof(struct mg_ev_mgr_lwip_data)); + iface->data = MG_CALLOC(1, sizeof(struct mg_ev_mgr_lwip_data)); } -void mg_ev_mgr_free(struct mg_mgr *mgr) { - MG_FREE(mgr->mgr_data); - mgr->mgr_data = NULL; +void mg_lwip_if_free(struct mg_iface *iface) { + MG_FREE(iface->data); + iface->data = NULL; } -void mg_ev_mgr_add_conn(struct mg_connection *nc) { +void mg_lwip_if_add_conn(struct mg_connection *nc) { (void) nc; } -void mg_ev_mgr_remove_conn(struct mg_connection *nc) { +void mg_lwip_if_remove_conn(struct mg_connection *nc) { struct mg_ev_mgr_lwip_data *md = - (struct mg_ev_mgr_lwip_data *) nc->mgr->mgr_data; + (struct mg_ev_mgr_lwip_data *) nc->iface->data; /* Walk the queue and null-out further signals for this conn. */ for (int i = 0; i < MG_SIG_QUEUE_LEN; i++) { if (md->sig_queue[i].nc == nc) { @@ -12199,7 +12431,8 @@ void mg_ev_mgr_remove_conn(struct mg_connection *nc) { } } -time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { +time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) { + struct mg_mgr *mgr = iface->mgr; int n = 0; double now = mg_time(); struct mg_connection *nc, *tmp; @@ -12536,6 +12769,34 @@ static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t) { #endif #ifdef MG_MODULE_LINES +#line 1 "common/platforms/pic32_harmony/pic32_harmony_net_if.h" +#endif +/* + * Copyright (c) 2014-2016 Cesanta Software Limited + * All rights reserved + */ + +#ifndef CS_COMMON_PLATFORMS_PIC32_HARMONY_NET_IF_H_ +#define CS_COMMON_PLATFORMS_PIC32_HARMONY_NET_IF_H_ + +/* Amalgamated: #include "mongoose/src/net_if.h" */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef MG_ENABLE_NET_IF_PIC32_HARMONY +#define MG_ENABLE_NET_IF_PIC32_HARMONY MG_NET_IF == MG_NET_IF_PIC32_HARMONY +#endif + +extern struct mg_iface_vtable mg_pic32_harmony_iface_vtable; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CS_COMMON_PLATFORMS_PIC32_HARMONY_NET_IF_H_ */ +#ifdef MG_MODULE_LINES #line 1 "common/platforms/pic32_harmony/pic32_harmony_net_if.c" #endif /* @@ -12543,36 +12804,36 @@ static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t) { * All rights reserved */ -#if CS_PLATFORM == CS_P_PIC32_HARMONY +#if MG_ENABLE_NET_IF_PIC32_HARMONY -int mg_if_create_conn(struct mg_connection *nc) { +int mg_pic32_harmony_if_create_conn(struct mg_connection *nc) { (void) nc; return 1; } -void mg_if_recved(struct mg_connection *nc, size_t len) { +void mg_pic32_harmony_if_recved(struct mg_connection *nc, size_t len) { (void) nc; (void) len; } -void mg_ev_mgr_add_conn(struct mg_connection *nc) { +void mg_pic32_harmony_if_add_conn(struct mg_connection *nc) { (void) nc; } -void mg_ev_mgr_init(struct mg_mgr *mgr) { - (void) mgr; +void mg_pic32_harmony_if_init(struct mg_iface *iface) { + (void) iface; (void) mg_get_errno(); /* Shutup compiler */ } -void mg_ev_mgr_free(struct mg_mgr *mgr) { - (void) mgr; +void mg_pic32_harmony_if_free(struct mg_iface *iface) { + (void) iface; } -void mg_ev_mgr_remove_conn(struct mg_connection *nc) { +void mg_pic32_harmony_if_remove_conn(struct mg_connection *nc) { (void) nc; } -void mg_if_destroy_conn(struct mg_connection *nc) { +void mg_pic32_harmony_if_destroy_conn(struct mg_connection *nc) { if (nc->sock == INVALID_SOCKET) return; /* For UDP, only close outgoing sockets or listeners. */ if (!(nc->flags & MG_F_UDP)) { @@ -12586,7 +12847,8 @@ void mg_if_destroy_conn(struct mg_connection *nc) { nc->sock = INVALID_SOCKET; } -int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { +int mg_pic32_harmony_if_listen_udp(struct mg_connection *nc, + union socket_address *sa) { nc->sock = TCPIP_UDP_ServerOpen( sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4 : IP_ADDRESS_TYPE_IPV6, @@ -12598,15 +12860,18 @@ int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { return 0; } -void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_pic32_harmony_if_udp_send(struct mg_connection *nc, const void *buf, + size_t len) { mbuf_append(&nc->send_mbuf, buf, len); } -void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { +void mg_pic32_harmony_if_tcp_send(struct mg_connection *nc, const void *buf, + size_t len) { mbuf_append(&nc->send_mbuf, buf, len); } -int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { +int mg_pic32_harmony_if_listen_tcp(struct mg_connection *nc, + union socket_address *sa) { nc->sock = TCPIP_TCP_ServerOpen( sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4 : IP_ADDRESS_TYPE_IPV6, @@ -12648,7 +12913,7 @@ static int mg_accept_conn(struct mg_connection *lc) { mg_if_accept_tcp_cb(nc, (union socket_address *) &sa, sizeof(sa)); - return mg_if_listen_tcp(lc, &lc->sa) >= 0; + return mg_pic32_harmony_if_listen_tcp(lc, &lc->sa) >= 0; } char *inet_ntoa(struct in_addr in) { @@ -12730,7 +12995,8 @@ static void mg_handle_recv(struct mg_connection *nc) { } } -time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { +time_t mg_pic32_harmony_if_poll(struct mg_iface *iface, int timeout_ms) { + struct mg_mgr *mgr = iface->mgr; double now = mg_time(); struct mg_connection *nc, *tmp; @@ -12771,4 +13037,41 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { return now; } -#endif /* CS_PLATFORM == CS_P_PIC32_HARMONY */ +void mg_pic32_harmony_if_sock_set(struct mg_connection *nc, sock_t sock) { + nc->sock = sock; +} + +void mg_pic32_harmony_if_get_conn_addr(struct mg_connection *nc, int remote, + union socket_address *sa) { + /* TODO(alaskin): not implemented yet */ +} + +/* clang-format off */ +#define MG_PIC32_HARMONY_IFACE_VTABLE \ + { \ + mg_pic32_harmony_if_init, \ + mg_pic32_harmony_if_free, \ + mg_pic32_harmony_if_add_conn, \ + mg_pic32_harmony_if_remove_conn, \ + mg_pic32_harmony_if_poll, \ + mg_pic32_harmony_if_listen_tcp, \ + mg_pic32_harmony_if_listen_udp, \ + mg_pic32_harmony_if_connect_tcp, \ + mg_pic32_harmony_if_connect_udp, \ + mg_pic32_harmony_if_tcp_send, \ + mg_pic32_harmony_if_udp_send, \ + mg_pic32_harmony_if_recved, \ + mg_pic32_harmony_if_create_conn, \ + mg_pic32_harmony_if_destroy_conn, \ + mg_pic32_harmony_if_sock_set, \ + mg_pic32_harmony_if_get_conn_addr, \ + } +/* clang-format on */ + +struct mg_iface_vtable mg_pic32_harmony_iface_vtable = + MG_PIC32_HARMONY_IFACE_VTABLE; +#if MG_NET_IF == MG_NET_IF_PIC32_HARMONY_LOW_LEVEL +struct mg_iface_vtable mg_default_iface_vtable = MG_PIC32_HARMONY_IFACE_VTABLE; +#endif + +#endif /* MG_ENABLE_NET_IF_PIC32_HARMONY */ diff --git a/mongoose.h b/mongoose.h index 1d50e7ad..71aaedda 100644 --- a/mongoose.h +++ b/mongoose.h @@ -2769,6 +2769,126 @@ struct { \ #endif /* CS_MONGOOSE_SRC_FEATURES_H_ */ #ifdef MG_MODULE_LINES +#line 1 "mongoose/src/net_if.h" +#endif +/* + * Copyright (c) 2014-2016 Cesanta Software Limited + * All rights reserved + */ + +#ifndef CS_MONGOOSE_SRC_NET_IF_H_ +#define CS_MONGOOSE_SRC_NET_IF_H_ + +/* Amalgamated: #include "common/platform.h" */ + +/* + * Internal async networking core interface. + * Consists of calls made by the core, which should not block, + * and callbacks back into the core ("..._cb"). + * Callbacks may (will) cause methods to be invoked from within, + * but methods are not allowed to invoke callbacks inline. + * + * Implementation must ensure that only one callback is invoked at any time. + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define MG_MAIN_IFACE 0 +#define MG_NUM_IFACES 1 + +struct mg_mgr; +struct mg_connection; +union socket_address; + +struct mg_iface_vtable; + +struct mg_iface { + struct mg_mgr *mgr; + void *data; /* Implementation-specific data */ + struct mg_iface_vtable *vtable; +}; + +struct mg_iface_vtable { + void (*init)(struct mg_iface *iface); + void (*free)(struct mg_iface *iface); + void (*add_conn)(struct mg_connection *nc); + void (*remove_conn)(struct mg_connection *nc); + time_t (*poll)(struct mg_iface *iface, int timeout_ms); + + /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */ + int (*listen_tcp)(struct mg_connection *nc, union socket_address *sa); + /* Request that a "listening" UDP socket be created. */ + int (*listen_udp)(struct mg_connection *nc, union socket_address *sa); + + /* Request that a TCP connection is made to the specified address. */ + void (*connect_tcp)(struct mg_connection *nc, const union socket_address *sa); + /* Open a UDP socket. Doesn't actually connect anything. */ + void (*connect_udp)(struct mg_connection *nc); + + /* Send functions for TCP and UDP. Sent data is copied before return. */ + void (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len); + void (*udp_send)(struct mg_connection *nc, const void *buf, size_t len); + + void (*recved)(struct mg_connection *nc, size_t len); + + /* Perform interface-related connection initialization. Return 1 on ok. */ + int (*create_conn)(struct mg_connection *nc); + /* Perform interface-related cleanup on connection before destruction. */ + void (*destroy_conn)(struct mg_connection *nc); + + /* Associate a socket to a connection. */ + void (*sock_set)(struct mg_connection *nc, sock_t sock); + + /* Put connection's address into *sa, local (remote = 0) or remote. */ + void (*get_conn_addr)(struct mg_connection *nc, int remote, + union socket_address *sa); +}; + +extern struct mg_iface_vtable *mg_ifaces[]; + +/* Creates a new interface instance. */ +struct mg_iface *mg_if_create_iface(struct mg_iface_vtable *vtable, + struct mg_mgr *mgr); + +/* + * Deliver a new TCP connection. Returns NULL in case on error (unable to + * create connection, in which case interface state should be discarded. + * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered + * when mg_if_accept_tcp_cb is invoked. + */ +struct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc); +void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa, + size_t sa_len); + +/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */ +void mg_if_connect_cb(struct mg_connection *nc, int err); +/* Callback that reports that data has been put on the wire. */ +void mg_if_sent_cb(struct mg_connection *nc, int num_sent); +/* + * Receive callback. + * buf must be heap-allocated and ownership is transferred to the core. + * Core will acknowledge consumption by calling iface::recved. + */ +void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len); +void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, + union socket_address *sa, size_t sa_len); + +/* void mg_if_close_conn(struct mg_connection *nc); */ + +/* Deliver a POLL event to the connection. */ +void mg_if_poll(struct mg_connection *nc, time_t now); + +/* Deliver a TIMER event to the connection. */ +void mg_if_timer(struct mg_connection *c, double now); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CS_MONGOOSE_SRC_NET_IF_H_ */ +#ifdef MG_MODULE_LINES #line 1 "mongoose/src/net.h" #endif /* @@ -2807,6 +2927,7 @@ struct { \ #endif /* Amalgamated: #include "mongoose/src/common.h" */ +/* Amalgamated: #include "mongoose/src/net_if.h" */ /* Amalgamated: #include "common/mbuf.h" */ #if MG_ENABLE_SSL @@ -2850,7 +2971,8 @@ struct mg_connection; * Callback function (event handler) prototype. Must be defined by the user. * Mongoose calls the event handler, passing the events defined below. */ -typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev, void *ev_data); +typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev, + void *ev_data); /* Events. Meaning of event parameter (evp) is given in the comment. */ #define MG_EV_POLL 0 /* Sent to each connection on each mg_mgr_poll() call */ @@ -2873,7 +2995,8 @@ struct mg_mgr { sock_t ctl[2]; /* Socketpair for mg_broadcast() */ #endif void *user_data; /* User data */ - void *mgr_data; /* Implementation-specific event manager's data. */ + int num_ifaces; + struct mg_iface **ifaces; /* network interfaces */ #if MG_ENABLE_JAVASCRIPT struct v7 *v7; #endif @@ -2921,6 +3044,7 @@ struct mg_connection { } priv_1; /* Used by mg_enable_multithreading() */ void *priv_2; /* Used by mg_enable_multithreading() */ void *mgr_data; /* Implementation-specific event manager's data. */ + struct mg_iface *iface; unsigned long flags; /* Flags set by Mongoose */ #define MG_F_LISTENING (1 << 0) /* This connection is listening */ @@ -2958,6 +3082,36 @@ struct mg_connection { */ void mg_mgr_init(struct mg_mgr *mgr, void *user_data); +/* + * Optional parameters to `mg_mgr_init_opt()`. + * + * If `main_iface` is not NULL, it will be used as the main interface in the + * default interface set. The pointer will be free'd by `mg_mgr_free`. + * Otherwise, the main interface will be autodetected based on the current + * platform. + * + * If `num_ifaces` is 0 and `ifaces` is NULL, the default interface set will be + * used. + * This is an advanced option, as it requires you to construct a full interface + * set, including special networking interfaces required by some optional + * features such as TCP tunneling. Memory backing `ifaces` and each of the + * `num_ifaces` pointers it contains will be reclaimed by `mg_mgr_free`. + */ +struct mg_mgr_init_opts { + struct mg_iface_vtable *main_iface; + int num_ifaces; + struct mg_iface_vtable **ifaces; +}; + +/* + * Like `mg_mgr_init` but with more options. + * + * Notably, this allows you to create a manger and choose + * dynamically which networking interface implementation to use. + */ +void mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data, + struct mg_mgr_init_opts opts); + /* * De-initialises Mongoose manager. * @@ -3324,97 +3478,6 @@ double mg_time(void); #endif /* CS_MONGOOSE_SRC_NET_H_ */ #ifdef MG_MODULE_LINES -#line 1 "mongoose/src/net_if.h" -#endif -/* - * Copyright (c) 2014-2016 Cesanta Software Limited - * All rights reserved - */ - -#ifndef CS_MONGOOSE_SRC_NET_IF_H_ -#define CS_MONGOOSE_SRC_NET_IF_H_ - -/* - * Internal async networking core interface. - * Consists of calls made by the core, which should not block, - * and callbacks back into the core ("..._cb"). - * Callbacks may (will) cause methods to be invoked from within, - * but methods are not allowed to invoke callbacks inline. - * - * Implementation must ensure that only one callback is invoked at any time. - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Request that a TCP connection is made to the specified address. */ -void mg_if_connect_tcp(struct mg_connection *nc, - const union socket_address *sa); -/* Open a UDP socket. Doesn't actually connect anything. */ -void mg_if_connect_udp(struct mg_connection *nc); -/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */ -void mg_if_connect_cb(struct mg_connection *nc, int err); - -/* Set up a listening TCP socket on a given address. rv = 0 -> ok. */ -int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa); - -/* - * Deliver a new TCP connection. Returns NULL in case on error (unable to - * create connection, in which case interface state should be discarded. - * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered - * when mg_if_accept_tcp_cb is invoked. - */ -struct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc); -void mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa, - size_t sa_len); - -/* Request that a "listening" UDP socket be created. */ -int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa); - -/* Send functions for TCP and UDP. Sent data is copied before return. */ -void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len); -void mg_if_udp_send(struct mg_connection *nc, const void *buf, size_t len); -/* Callback that reports that data has been put on the wire. */ -void mg_if_sent_cb(struct mg_connection *nc, int num_sent); - -/* - * Receive callback. - * buf must be heap-allocated and ownership is transferred to the core. - * Core will acknowledge consumption by calling mg_if_recved. - */ -void mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len); -void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len, - union socket_address *sa, size_t sa_len); -void mg_if_recved(struct mg_connection *nc, size_t len); - -/* Deliver a POLL event to the connection. */ -void mg_if_poll(struct mg_connection *nc, time_t now); - -/* Deliver a TIMER event to the connection. */ -void mg_if_timer(struct mg_connection *c, double now); - -/* Perform interface-related connection initialization. Return 1 on success. */ -int mg_if_create_conn(struct mg_connection *nc); - -/* Perform interface-related cleanup on connection before destruction. */ -void mg_if_destroy_conn(struct mg_connection *nc); - -void mg_close_conn(struct mg_connection *nc); - -/* Put connection's address into *sa, local (remote = 0) or remote. */ -void mg_if_get_conn_addr(struct mg_connection *nc, int remote, - union socket_address *sa); - -/* Associate a socket to a connection. */ -void mg_sock_set(struct mg_connection *nc, sock_t sock); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* CS_MONGOOSE_SRC_NET_IF_H_ */ -#ifdef MG_MODULE_LINES #line 1 "mongoose/src/uri.h" #endif /* @@ -3805,12 +3868,12 @@ struct mg_ssi_call_ctx { #endif #if MG_ENABLE_HTTP_STREAMING_MULTIPART -#define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */ -#define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */ -#define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */ -#define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */ -#define MG_EV_HTTP_MULTIPART_REQUEST_END 125 /* struct mg_http_multipart_part \ - */ +#define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */ +#define MG_EV_HTTP_PART_BEGIN 122 /* struct mg_http_multipart_part */ +#define MG_EV_HTTP_PART_DATA 123 /* struct mg_http_multipart_part */ +#define MG_EV_HTTP_PART_END 124 /* struct mg_http_multipart_part */ +/* struct mg_http_multipart_part */ +#define MG_EV_HTTP_MULTIPART_REQUEST_END 125 #endif /*