Commit fffb54e2 authored by Marko Mikulicic's avatar Marko Mikulicic Committed by Cesanta Bot

Implementing MG interfaces

PUBLISHED_FROM=46496c2d5340a0bbe4fe1c6c9ff187bc65d2d35f
parent 8bf3bd48
...@@ -15,6 +15,7 @@ items: ...@@ -15,6 +15,7 @@ items:
- { name: mg_enable_multithreading.md } - { name: mg_enable_multithreading.md }
- { name: mg_mgr_free.md } - { name: mg_mgr_free.md }
- { name: mg_mgr_init.md } - { name: mg_mgr_init.md }
- { name: mg_mgr_init_opt.md }
- { name: mg_mgr_poll.md } - { name: mg_mgr_poll.md }
- { name: mg_next.md } - { name: mg_next.md }
- { name: mg_printf.md } - { name: mg_printf.md }
...@@ -31,6 +32,7 @@ items: ...@@ -31,6 +32,7 @@ items:
- { name: struct_mg_connect_opts.md } - { name: struct_mg_connect_opts.md }
- { name: struct_mg_connection.md } - { name: struct_mg_connection.md }
- { name: struct_mg_mgr.md } - { name: struct_mg_mgr.md }
- { name: struct_mg_mgr_init_opts.md }
- { name: struct_mg_multithreading_opts.md } - { name: struct_mg_multithreading_opts.md }
--- ---
......
...@@ -3,7 +3,8 @@ title: "mg_event_handler_t" ...@@ -3,7 +3,8 @@ title: "mg_event_handler_t"
decl_name: "mg_event_handler_t" decl_name: "mg_event_handler_t"
symbol_kind: "typedef" symbol_kind: "typedef"
signature: | 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. Callback function (event handler) prototype. Must be defined by the user.
......
---
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.
...@@ -42,6 +42,7 @@ signature: | ...@@ -42,6 +42,7 @@ signature: |
} priv_1; /* Used by mg_enable_multithreading() */ } priv_1; /* Used by mg_enable_multithreading() */
void *priv_2; /* Used by mg_enable_multithreading() */ void *priv_2; /* Used by mg_enable_multithreading() */
void *mgr_data; /* Implementation-specific event manager's data. */ void *mgr_data; /* Implementation-specific event manager's data. */
struct mg_iface *iface;
unsigned long flags; unsigned long flags;
/* Flags set by Mongoose */ /* Flags set by Mongoose */
#define MG_F_LISTENING (1 << 0) /* This connection is listening */ #define MG_F_LISTENING (1 << 0) /* This connection is listening */
......
...@@ -12,7 +12,8 @@ signature: | ...@@ -12,7 +12,8 @@ signature: |
sock_t ctl[2]; /* Socketpair for mg_broadcast() */ sock_t ctl[2]; /* Socketpair for mg_broadcast() */
#endif #endif
void *user_data; /* User data */ 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 #if MG_ENABLE_JAVASCRIPT
struct v7 *v7; struct v7 *v7;
#endif #endif
......
---
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`.
...@@ -1832,11 +1832,6 @@ int64_t cs_to64(const char *s) { ...@@ -1832,11 +1832,6 @@ int64_t cs_to64(const char *s) {
#define intptr_t long #define intptr_t long
#endif #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) { MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c) {
DBG(("%p %p", mgr, c)); DBG(("%p %p", mgr, c));
c->mgr = mgr; c->mgr = mgr;
...@@ -1844,14 +1839,14 @@ MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c) { ...@@ -1844,14 +1839,14 @@ MG_INTERNAL void mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c) {
mgr->active_connections = c; mgr->active_connections = c;
c->prev = NULL; c->prev = NULL;
if (c->next != NULL) c->next->prev = c; 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) { MG_INTERNAL void mg_remove_conn(struct mg_connection *conn) {
if (conn->prev == NULL) conn->mgr->active_connections = conn->next; if (conn->prev == NULL) conn->mgr->active_connections = conn->next;
if (conn->prev) conn->prev->next = conn->next; if (conn->prev) conn->prev->next = conn->next;
if (conn->next) conn->next->prev = conn->prev; 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, MG_INTERNAL void mg_call(struct mg_connection *nc,
...@@ -1893,7 +1888,7 @@ 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); (nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);
} }
if (recved > 0 && !(nc->flags & MG_F_UDP)) { if (recved > 0 && !(nc->flags & MG_F_UDP)) {
mg_if_recved(nc, recved); nc->iface->vtable->recved(nc, recved);
} }
} }
if (ev != MG_EV_POLL) { if (ev != MG_EV_POLL) {
...@@ -1924,7 +1919,7 @@ void mg_if_poll(struct mg_connection *nc, time_t now) { ...@@ -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) { 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) { if (conn->proto_data != NULL && conn->proto_data_destructor != NULL) {
conn->proto_data_destructor(conn->proto_data); conn->proto_data_destructor(conn->proto_data);
} }
...@@ -1942,12 +1937,19 @@ static void mg_destroy_conn(struct mg_connection *conn, int destroy_if) { ...@@ -1942,12 +1937,19 @@ static void mg_destroy_conn(struct mg_connection *conn, int destroy_if) {
void mg_close_conn(struct mg_connection *conn) { void mg_close_conn(struct mg_connection *conn) {
DBG(("%p %lu %d", conn, conn->flags, conn->sock)); DBG(("%p %lu %d", conn, conn->flags, conn->sock));
mg_remove_conn(conn); mg_remove_conn(conn);
mg_if_destroy_conn(conn); conn->iface->vtable->destroy_conn(conn);
mg_call(conn, NULL, MG_EV_CLOSE, NULL); mg_call(conn, NULL, MG_EV_CLOSE, NULL);
mg_destroy_conn(conn, 0 /* destroy_if */); mg_destroy_conn(conn, 0 /* destroy_if */);
} }
void mg_mgr_init(struct mg_mgr *m, void *user_data) { 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)); memset(m, 0, sizeof(*m));
#if MG_ENABLE_BROADCAST #if MG_ENABLE_BROADCAST
m->ctl[0] = m->ctl[1] = INVALID_SOCKET; m->ctl[0] = m->ctl[1] = INVALID_SOCKET;
...@@ -1974,8 +1976,23 @@ void mg_mgr_init(struct mg_mgr *m, void *user_data) { ...@@ -1974,8 +1976,23 @@ void mg_mgr_init(struct mg_mgr *m, void *user_data) {
} }
} }
#endif #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(("=================================="));
DBG(("init mgr=%p", m)); DBG(("init mgr=%p", m));
} }
...@@ -2025,7 +2042,29 @@ void mg_mgr_free(struct mg_mgr *m) { ...@@ -2025,7 +2042,29 @@ void mg_mgr_free(struct mg_mgr *m) {
mg_close_conn(conn); 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) { 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( ...@@ -2099,6 +2138,7 @@ MG_INTERNAL struct mg_connection *mg_create_connection_base(
conn->handler = callback; conn->handler = callback;
conn->mgr = mgr; conn->mgr = mgr;
conn->last_io_time = (time_t) mg_time(); 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->flags = opts.flags & _MG_ALLOWED_CONNECT_FLAGS_MASK;
conn->user_data = opts.user_data; conn->user_data = opts.user_data;
/* /*
...@@ -2119,9 +2159,11 @@ MG_INTERNAL struct mg_connection *mg_create_connection( ...@@ -2119,9 +2159,11 @@ MG_INTERNAL struct mg_connection *mg_create_connection(
struct mg_add_sock_opts opts) { struct mg_add_sock_opts opts) {
struct mg_connection *conn = mg_create_connection_base(mgr, callback, 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); MG_FREE(conn);
conn = NULL; conn = NULL;
}
if (conn == NULL) {
MG_SET_PTRPTR(opts.error_string, "failed to init connection"); 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, ...@@ -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) { void mg_send(struct mg_connection *nc, const void *buf, int len) {
nc->last_io_time = (time_t) mg_time(); nc->last_io_time = (time_t) mg_time();
if (nc->flags & MG_F_UDP) { if (nc->flags & MG_F_UDP) {
mg_if_udp_send(nc, buf, len); nc->iface->vtable->udp_send(nc, buf, len);
} else { } else {
mg_if_tcp_send(nc, buf, len); nc->iface->vtable->tcp_send(nc, buf, len);
} }
#if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP #if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP
if (nc->mgr && nc->mgr->hexdump_file != NULL) { 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, ...@@ -2534,7 +2576,7 @@ void mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,
} else { } else {
/* Drop on the floor. */ /* Drop on the floor. */
MG_FREE(buf); 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, ...@@ -2552,9 +2594,9 @@ MG_INTERNAL struct mg_connection *mg_do_connect(struct mg_connection *nc,
nc->flags |= MG_F_CONNECTING; nc->flags |= MG_F_CONNECTING;
if (proto == SOCK_DGRAM) { if (proto == SOCK_DGRAM) {
mg_if_connect_udp(nc); nc->iface->vtable->connect_udp(nc);
} else { } else {
mg_if_connect_tcp(nc, sa); nc->iface->vtable->connect_tcp(nc, sa);
} }
mg_add_conn(nc->mgr, nc); mg_add_conn(nc->mgr, nc);
return nc; return nc;
...@@ -2770,9 +2812,9 @@ struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address, ...@@ -2770,9 +2812,9 @@ struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
#endif /* MG_ENABLE_SSL */ #endif /* MG_ENABLE_SSL */
if (nc->flags & MG_F_UDP) { if (nc->flags & MG_F_UDP) {
rc = mg_if_listen_udp(nc, &nc->sa); rc = nc->iface->vtable->listen_udp(nc, &nc->sa);
} else { } else {
rc = mg_if_listen_tcp(nc, &nc->sa); rc = nc->iface->vtable->listen_tcp(nc, &nc->sa);
} }
if (rc != 0) { if (rc != 0) {
DBG(("Failed to open listener: %d", rc)); DBG(("Failed to open listener: %d", rc));
...@@ -2881,6 +2923,15 @@ double mg_set_timer(struct mg_connection *c, double timestamp) { ...@@ -2881,6 +2923,15 @@ double mg_set_timer(struct mg_connection *c, double timestamp) {
return result; 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, struct mg_connection *mg_add_sock_opt(struct mg_mgr *s, sock_t sock,
mg_event_handler_t callback, mg_event_handler_t callback,
struct mg_add_sock_opts opts) { struct mg_add_sock_opts opts) {
...@@ -2903,6 +2954,53 @@ double mg_time(void) { ...@@ -2903,6 +2954,53 @@ double mg_time(void) {
return cs_time(); return cs_time();
} }
#ifdef MG_MODULE_LINES #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" #line 1 "mongoose/src/net_if_socket.c"
#endif #endif
/* /*
...@@ -2910,8 +3008,9 @@ double mg_time(void) { ...@@ -2910,8 +3008,9 @@ double mg_time(void) {
* All rights reserved * 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/internal.h" */
/* Amalgamated: #include "mongoose/src/util.h" */ /* Amalgamated: #include "mongoose/src/util.h" */
...@@ -2948,8 +3047,8 @@ static int mg_is_error(int n) { ...@@ -2948,8 +3047,8 @@ static int mg_is_error(int n) {
); );
} }
void mg_if_connect_tcp(struct mg_connection *nc, void mg_socket_if_connect_tcp(struct mg_connection *nc,
const union socket_address *sa) { const union socket_address *sa) {
int rc, proto = 0; int rc, proto = 0;
nc->sock = socket(AF_INET, SOCK_STREAM, proto); nc->sock = socket(AF_INET, SOCK_STREAM, proto);
if (nc->sock == INVALID_SOCKET) { if (nc->sock == INVALID_SOCKET) {
...@@ -2964,7 +3063,7 @@ void mg_if_connect_tcp(struct mg_connection *nc, ...@@ -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)); 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); nc->sock = socket(AF_INET, SOCK_DGRAM, 0);
if (nc->sock == INVALID_SOCKET) { if (nc->sock == INVALID_SOCKET) {
nc->err = mg_get_errno() ? mg_get_errno() : 1; nc->err = mg_get_errno() ? mg_get_errno() : 1;
...@@ -2978,7 +3077,8 @@ void mg_if_connect_udp(struct mg_connection *nc) { ...@@ -2978,7 +3077,8 @@ void mg_if_connect_udp(struct mg_connection *nc) {
nc->err = 0; 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; int proto = 0;
sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto); sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto);
if (sock == INVALID_SOCKET) { if (sock == INVALID_SOCKET) {
...@@ -2988,32 +3088,35 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) { ...@@ -2988,32 +3088,35 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
return 0; 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); sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) return (mg_get_errno() ? mg_get_errno() : 1); if (sock == INVALID_SOCKET) return (mg_get_errno() ? mg_get_errno() : 1);
mg_sock_set(nc, sock); mg_sock_set(nc, sock);
return 0; 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); 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); 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) nc;
(void) len; (void) len;
} }
int mg_if_create_conn(struct mg_connection *nc) { int mg_socket_if_create_conn(struct mg_connection *nc) {
(void) nc; (void) nc;
return 1; 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->sock == INVALID_SOCKET) return;
if (!(nc->flags & MG_F_UDP)) { if (!(nc->flags & MG_F_UDP)) {
closesocket(nc->sock); closesocket(nc->sock);
...@@ -3390,32 +3493,32 @@ static void mg_mgr_handle_ctl_sock(struct mg_mgr *mgr) { ...@@ -3390,32 +3493,32 @@ static void mg_mgr_handle_ctl_sock(struct mg_mgr *mgr) {
#endif #endif
/* Associate a socket to a connection. */ /* 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_non_blocking_mode(sock);
mg_set_close_on_exec(sock); mg_set_close_on_exec(sock);
nc->sock = sock; nc->sock = sock;
DBG(("%p %d", nc, sock)); DBG(("%p %d", nc, sock));
} }
void mg_ev_mgr_init(struct mg_mgr *mgr) { void mg_socket_if_init(struct mg_iface *iface) {
(void) mgr; (void) iface;
DBG(("%p using select()", mgr)); DBG(("%p using select()", iface->mgr));
#if MG_ENABLE_BROADCAST #if MG_ENABLE_BROADCAST
do { do {
mg_socketpair(mgr->ctl, SOCK_DGRAM); mg_socketpair(iface->mgr->ctl, SOCK_DGRAM);
} while (mgr->ctl[0] == INVALID_SOCKET); } while (iface->mgr->ctl[0] == INVALID_SOCKET);
#endif #endif
} }
void mg_ev_mgr_free(struct mg_mgr *mgr) { void mg_socket_if_free(struct mg_iface *iface) {
(void) mgr; (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) nc;
} }
void mg_ev_mgr_remove_conn(struct mg_connection *nc) { void mg_socket_if_remove_conn(struct mg_connection *nc) {
(void) nc; (void) nc;
} }
...@@ -3432,7 +3535,8 @@ void mg_add_to_set(sock_t sock, fd_set *set, sock_t *max_fd) { ...@@ -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 now = mg_time();
double min_timer; double min_timer;
struct mg_connection *nc, *tmp; struct mg_connection *nc, *tmp;
...@@ -3618,12 +3722,39 @@ void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags) { ...@@ -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); mg_sock_addr_to_str(&sa, buf, len, flags);
} }
void mg_if_get_conn_addr(struct mg_connection *nc, int remote, void mg_socket_if_get_conn_addr(struct mg_connection *nc, int remote,
union socket_address *sa) { union socket_address *sa) {
mg_sock_get_addr(nc->sock, remote, 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 #ifdef MG_MODULE_LINES
#line 1 "mongoose/src/multithreading.c" #line 1 "mongoose/src/multithreading.c"
#endif #endif
...@@ -10036,7 +10167,7 @@ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io) { ...@@ -10036,7 +10167,7 @@ uint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io) {
} }
if (cm->payload.len != 0) { if (cm->payload.len != 0) {
*ptr = (char)-1; *ptr = (char) -1;
ptr++; ptr++;
memcpy(ptr, cm->payload.p, cm->payload.len); 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) { ...@@ -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) */ #endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK && !defined(MG_SIMPLELINK_NO_OSI) */
#ifdef MG_MODULE_LINES #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" #line 1 "common/platforms/simplelink/sl_net_if.c"
#endif #endif
/* /*
...@@ -11048,7 +11207,9 @@ void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg) { ...@@ -11048,7 +11207,9 @@ void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg) {
* All rights reserved * 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/internal.h" */
/* Amalgamated: #include "mongoose/src/util.h" */ /* Amalgamated: #include "mongoose/src/util.h" */
...@@ -11137,8 +11298,8 @@ static int mg_is_error(int n) { ...@@ -11137,8 +11298,8 @@ static int mg_is_error(int n) {
return (n < 0 && n != SL_EALREADY && n != SL_EAGAIN); return (n < 0 && n != SL_EALREADY && n != SL_EAGAIN);
} }
void mg_if_connect_tcp(struct mg_connection *nc, void mg_sl_if_connect_tcp(struct mg_connection *nc,
const union socket_address *sa) { const union socket_address *sa) {
int proto = 0; int proto = 0;
if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET; if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET;
sock_t sock = sl_Socket(AF_INET, SOCK_STREAM, proto); sock_t sock = sl_Socket(AF_INET, SOCK_STREAM, proto);
...@@ -11157,7 +11318,7 @@ out: ...@@ -11157,7 +11318,7 @@ out:
ntohs(sa->sin.sin_port), nc->sock, proto, nc->err)); 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); sock_t sock = sl_Socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) { if (sock < 0) {
nc->err = sock; nc->err = sock;
...@@ -11167,7 +11328,7 @@ void mg_if_connect_udp(struct mg_connection *nc) { ...@@ -11167,7 +11328,7 @@ void mg_if_connect_udp(struct mg_connection *nc) {
nc->err = 0; 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; int proto = 0;
if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET; if (nc->flags & MG_F_SSL) proto = SL_SEC_SOCKET;
sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto); 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) { ...@@ -11180,32 +11341,32 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
#endif #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); sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) return (errno ? errno : 1); if (sock == INVALID_SOCKET) return (errno ? errno : 1);
mg_sock_set(nc, sock); mg_sock_set(nc, sock);
return 0; 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); 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); 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) nc;
(void) len; (void) len;
} }
int mg_if_create_conn(struct mg_connection *nc) { int mg_sl_if_create_conn(struct mg_connection *nc) {
(void) nc; (void) nc;
return 1; 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; if (nc->sock == INVALID_SOCKET) return;
/* For UDP, only close outgoing sockets or listeners. */ /* For UDP, only close outgoing sockets or listeners. */
if (!(nc->flags & MG_F_UDP) || nc->listener == NULL) { 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) { ...@@ -11394,30 +11555,31 @@ void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) {
} }
/* Associate a socket to a connection. */ /* 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); mg_set_non_blocking_mode(sock);
nc->sock = sock; nc->sock = sock;
DBG(("%p %d", nc, sock)); DBG(("%p %d", nc, sock));
} }
void mg_ev_mgr_init(struct mg_mgr *mgr) { void mg_sl_if_init(struct mg_iface *iface) {
(void) mgr; (void) iface;
DBG(("%p using sl_Select()", mgr)); DBG(("%p using sl_Select()", iface->mgr));
} }
void mg_ev_mgr_free(struct mg_mgr *mgr) { void mg_sl_if_free(struct mg_iface *iface) {
(void) mgr; (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) nc;
} }
void mg_ev_mgr_remove_conn(struct mg_connection *nc) { void mg_sl_if_remove_conn(struct mg_connection *nc) {
(void) 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 now = mg_time();
double min_timer; double min_timer;
struct mg_connection *nc, *tmp; struct mg_connection *nc, *tmp;
...@@ -11516,8 +11678,8 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { ...@@ -11516,8 +11678,8 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) {
return now; return now;
} }
void mg_if_get_conn_addr(struct mg_connection *nc, int remote, void mg_sl_if_get_conn_addr(struct mg_connection *nc, int remote,
union socket_address *sa) { union socket_address *sa) {
/* SimpleLink does not provide a way to get socket's peer address after /* SimpleLink does not provide a way to get socket's peer address after
* accept or connect. Address hould have been preserved in the connection, * accept or connect. Address hould have been preserved in the connection,
* so we do our best here by using it. */ * so we do our best here by using it. */
...@@ -11536,8 +11698,8 @@ void sl_restart_cb(struct mg_mgr *mgr) { ...@@ -11536,8 +11698,8 @@ void sl_restart_cb(struct mg_mgr *mgr) {
if (nc->flags & MG_F_LISTENING) { if (nc->flags & MG_F_LISTENING) {
DBG(("restarting %p %s:%d", nc, inet_ntoa(nc->sa.sin.sin_addr), DBG(("restarting %p %s:%d", nc, inet_ntoa(nc->sa.sin.sin_addr),
ntohs(nc->sa.sin.sin_port))); ntohs(nc->sa.sin.sin_port)));
int res = (nc->flags & MG_F_UDP ? mg_if_listen_udp(nc, &nc->sa) int res = (nc->flags & MG_F_UDP ? mg_sl_if_listen_udp(nc, &nc->sa)
: mg_if_listen_tcp(nc, &nc->sa)); : mg_sl_if_listen_tcp(nc, &nc->sa));
if (res == 0) continue; if (res == 0) continue;
/* Well, we tried and failed. Fall through to closing. */ /* Well, we tried and failed. Fall through to closing. */
} }
...@@ -11549,7 +11711,34 @@ void sl_restart_cb(struct mg_mgr *mgr) { ...@@ -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 #ifdef MG_MODULE_LINES
#line 1 "common/platforms/lwip/mg_lwip_net_if.h" #line 1 "common/platforms/lwip/mg_lwip_net_if.h"
#endif #endif
...@@ -11561,10 +11750,16 @@ void sl_restart_cb(struct mg_mgr *mgr) { ...@@ -11561,10 +11750,16 @@ void sl_restart_cb(struct mg_mgr *mgr) {
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_ #ifndef CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_
#define 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 <stdint.h> #include <stdint.h>
extern struct mg_iface_vtable mg_lwip_iface_vtable;
struct mg_lwip_conn_state { struct mg_lwip_conn_state {
union { union {
struct tcp_pcb *tcp; struct tcp_pcb *tcp;
...@@ -11591,7 +11786,7 @@ void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc); ...@@ -11591,7 +11786,7 @@ void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc);
/* To be implemented by the platform. */ /* To be implemented by the platform. */
void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); 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_ */ #endif /* CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_ */
#ifdef MG_MODULE_LINES #ifdef MG_MODULE_LINES
...@@ -11602,7 +11797,7 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); ...@@ -11602,7 +11797,7 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr);
* All rights reserved * All rights reserved
*/ */
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL #if MG_ENABLE_NET_IF_LWIP_LOW_LEVEL
#include <lwip/pbuf.h> #include <lwip/pbuf.h>
#include <lwip/tcp.h> #include <lwip/tcp.h>
...@@ -11616,34 +11811,40 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr); ...@@ -11616,34 +11811,40 @@ void mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr);
* lwip functions * lwip functions
*/ */
#if MG_ENABLE_IPV6 #if MG_ENABLE_IPV6
# define TCP_NEW tcp_new_ip6 #define TCP_NEW tcp_new_ip6
# define TCP_BIND tcp_bind_ip6 #define TCP_BIND tcp_bind_ip6
# define UDP_BIND udp_bind_ip6 #define UDP_BIND udp_bind_ip6
# define IPADDR_NTOA(x) ip6addr_ntoa((const ip6_addr_t *)(x)) #define IPADDR_NTOA(x) ip6addr_ntoa((const ip6_addr_t *)(x))
# define SET_ADDR(dst, src) \ #define SET_ADDR(dst, src) \
memcpy((dst)->sin6.sin6_addr.s6_addr, (src)->ip6.addr, \ memcpy((dst)->sin6.sin6_addr.s6_addr, (src)->ip6.addr, \
sizeof((dst)->sin6.sin6_addr.s6_addr)) sizeof((dst)->sin6.sin6_addr.s6_addr))
#else #else
# define TCP_NEW tcp_new #define TCP_NEW tcp_new
# define TCP_BIND tcp_bind #define TCP_BIND tcp_bind
# define UDP_BIND udp_bind #define UDP_BIND udp_bind
# define IPADDR_NTOA ipaddr_ntoa #define IPADDR_NTOA ipaddr_ntoa
# define SET_ADDR(dst, src) (dst)->sin.sin_addr.s_addr = GET_IPV4(src) #define SET_ADDR(dst, src) (dst)->sin.sin_addr.s_addr = GET_IPV4(src)
#endif #endif
/* /*
* If lwip is compiled with ipv6 support, then API changes even for ipv4 * If lwip is compiled with ipv6 support, then API changes even for ipv4
*/ */
#if !defined(LWIP_IPV6) || !LWIP_IPV6 #if !defined(LWIP_IPV6) || !LWIP_IPV6
# define GET_IPV4(ipX_addr) ((ipX_addr)->addr) #define GET_IPV4(ipX_addr) ((ipX_addr)->addr)
#else #else
# define GET_IPV4(ipX_addr) ((ipX_addr)->ip4.addr) #define GET_IPV4(ipX_addr) ((ipX_addr)->ip4.addr)
#endif #endif
void mg_lwip_ssl_do_hs(struct mg_connection *nc); void mg_lwip_ssl_do_hs(struct mg_connection *nc);
void mg_lwip_ssl_send(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_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 #if LWIP_TCP_KEEPALIVE
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle, void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
int interval, int count) { int interval, int count) {
...@@ -11793,8 +11994,8 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, ...@@ -11793,8 +11994,8 @@ static err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,
return ERR_OK; return ERR_OK;
} }
void mg_if_connect_tcp(struct mg_connection *nc, void mg_lwip_if_connect_tcp(struct mg_connection *nc,
const union socket_address *sa) { const union socket_address *sa) {
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct tcp_pcb *tpcb = TCP_NEW(); struct tcp_pcb *tpcb = TCP_NEW();
cs->pcb.tcp = tpcb; cs->pcb.tcp = tpcb;
...@@ -11848,7 +12049,7 @@ static void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p, ...@@ -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)); 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 mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct udp_pcb *upcb = udp_new(); struct udp_pcb *upcb = udp_new();
cs->err = UDP_BIND(upcb, IP_ADDR_ANY, 0 /* any port */); 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) { ...@@ -11903,7 +12104,7 @@ static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) {
return ERR_OK; 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 mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct tcp_pcb *tpcb = TCP_NEW(); struct tcp_pcb *tpcb = TCP_NEW();
ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr; 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) { ...@@ -11921,7 +12122,7 @@ int mg_if_listen_tcp(struct mg_connection *nc, union socket_address *sa) {
return 0; 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 mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
struct udp_pcb *upcb = udp_new(); struct udp_pcb *upcb = udp_new();
ip_addr_t *ip = (ip_addr_t *) &sa->sin.sin_addr.s_addr; 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) { ...@@ -11977,12 +12178,14 @@ static void mg_lwip_send_more(struct mg_connection *nc) {
mbuf_trim(&nc->send_mbuf); 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); mbuf_append(&nc->send_mbuf, buf, len);
mg_lwip_mgr_schedule_poll(nc->mgr); 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; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (nc->sock == INVALID_SOCKET || cs->pcb.udp == NULL) { 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) { ...@@ -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; if (nc->flags & MG_F_UDP) return;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL) { if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL) {
...@@ -12017,8 +12220,8 @@ void mg_if_recved(struct mg_connection *nc, size_t len) { ...@@ -12017,8 +12220,8 @@ void mg_if_recved(struct mg_connection *nc, size_t len) {
return; return;
} }
DBG(("%p %p %u", nc, cs->pcb.tcp, len)); DBG(("%p %p %u", nc, cs->pcb.tcp, len));
/* Currently SSL acknowledges data immediately. /* Currently SSL acknowledges data immediately.
* TODO(rojer): Find a way to propagate mg_if_recved. */ * TODO(rojer): Find a way to propagate mg_lwip_if_recved. */
#if MG_ENABLE_SSL #if MG_ENABLE_SSL
if (nc->ssl == NULL) { if (nc->ssl == NULL) {
tcp_recved(cs->pcb.tcp, len); tcp_recved(cs->pcb.tcp, len);
...@@ -12029,7 +12232,7 @@ void mg_if_recved(struct mg_connection *nc, size_t len) { ...@@ -12029,7 +12232,7 @@ void mg_if_recved(struct mg_connection *nc, size_t len) {
mbuf_trim(&nc->recv_mbuf); 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 *cs =
(struct mg_lwip_conn_state *) calloc(1, sizeof(*cs)); (struct mg_lwip_conn_state *) calloc(1, sizeof(*cs));
if (cs == NULL) return 0; if (cs == NULL) return 0;
...@@ -12037,7 +12240,7 @@ int mg_if_create_conn(struct mg_connection *nc) { ...@@ -12037,7 +12240,7 @@ int mg_if_create_conn(struct mg_connection *nc) {
return 1; 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; if (nc->sock == INVALID_SOCKET) return;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
if (!(nc->flags & MG_F_UDP)) { if (!(nc->flags & MG_F_UDP)) {
...@@ -12068,8 +12271,8 @@ void mg_if_destroy_conn(struct mg_connection *nc) { ...@@ -12068,8 +12271,8 @@ void mg_if_destroy_conn(struct mg_connection *nc) {
nc->sock = INVALID_SOCKET; nc->sock = INVALID_SOCKET;
} }
void mg_if_get_conn_addr(struct mg_connection *nc, int remote, void mg_lwip_if_get_conn_addr(struct mg_connection *nc, int remote,
union socket_address *sa) { union socket_address *sa) {
memset(sa, 0, sizeof(*sa)); memset(sa, 0, sizeof(*sa));
if (nc->sock == INVALID_SOCKET) return; if (nc->sock == INVALID_SOCKET) return;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; 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, ...@@ -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; 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 #ifdef MG_MODULE_LINES
#line 1 "common/platforms/lwip/mg_lwip_ev_mgr.c" #line 1 "common/platforms/lwip/mg_lwip_ev_mgr.c"
#endif #endif
...@@ -12125,7 +12355,7 @@ struct mg_ev_mgr_lwip_data { ...@@ -12125,7 +12355,7 @@ struct mg_ev_mgr_lwip_data {
void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc) { 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 *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; if (md->sig_queue_len >= MG_SIG_QUEUE_LEN) return;
int end_index = (md->start_index + md->sig_queue_len) % MG_SIG_QUEUE_LEN; int end_index = (md->start_index + md->sig_queue_len) % MG_SIG_QUEUE_LEN;
md->sig_queue[end_index].sig = sig; 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) { ...@@ -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) { 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) { while (md->sig_queue_len > 0) {
struct mg_connection *nc = md->sig_queue[md->start_index].nc; struct mg_connection *nc = md->sig_queue[md->start_index].nc;
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
switch (md->sig_queue[md->start_index].sig) { switch (md->sig_queue[md->start_index].sig) {
case MG_SIG_CONNECT_RESULT: { case MG_SIG_CONNECT_RESULT: {
#ifdef SSL_KRYPTON #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); SSL_set_fd(nc->ssl, (intptr_t) nc);
mg_lwip_ssl_do_hs(nc); mg_lwip_ssl_do_hs(nc);
} else } else
...@@ -12174,23 +12406,23 @@ void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) { ...@@ -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")); 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) { void mg_lwip_if_free(struct mg_iface *iface) {
MG_FREE(mgr->mgr_data); MG_FREE(iface->data);
mgr->mgr_data = NULL; 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) 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 *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. */ /* Walk the queue and null-out further signals for this conn. */
for (int i = 0; i < MG_SIG_QUEUE_LEN; i++) { for (int i = 0; i < MG_SIG_QUEUE_LEN; i++) {
if (md->sig_queue[i].nc == nc) { if (md->sig_queue[i].nc == nc) {
...@@ -12199,7 +12431,8 @@ void mg_ev_mgr_remove_conn(struct mg_connection *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; int n = 0;
double now = mg_time(); double now = mg_time();
struct mg_connection *nc, *tmp; struct mg_connection *nc, *tmp;
...@@ -12536,6 +12769,34 @@ static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t) { ...@@ -12536,6 +12769,34 @@ static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t) {
#endif #endif
#ifdef MG_MODULE_LINES #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" #line 1 "common/platforms/pic32_harmony/pic32_harmony_net_if.c"
#endif #endif
/* /*
...@@ -12543,36 +12804,36 @@ static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t) { ...@@ -12543,36 +12804,36 @@ static void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t) {
* All rights reserved * 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; (void) nc;
return 1; 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) nc;
(void) len; (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) nc;
} }
void mg_ev_mgr_init(struct mg_mgr *mgr) { void mg_pic32_harmony_if_init(struct mg_iface *iface) {
(void) mgr; (void) iface;
(void) mg_get_errno(); /* Shutup compiler */ (void) mg_get_errno(); /* Shutup compiler */
} }
void mg_ev_mgr_free(struct mg_mgr *mgr) { void mg_pic32_harmony_if_free(struct mg_iface *iface) {
(void) mgr; (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) 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; if (nc->sock == INVALID_SOCKET) return;
/* For UDP, only close outgoing sockets or listeners. */ /* For UDP, only close outgoing sockets or listeners. */
if (!(nc->flags & MG_F_UDP)) { if (!(nc->flags & MG_F_UDP)) {
...@@ -12586,7 +12847,8 @@ void mg_if_destroy_conn(struct mg_connection *nc) { ...@@ -12586,7 +12847,8 @@ void mg_if_destroy_conn(struct mg_connection *nc) {
nc->sock = INVALID_SOCKET; 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( nc->sock = TCPIP_UDP_ServerOpen(
sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4 sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4
: IP_ADDRESS_TYPE_IPV6, : IP_ADDRESS_TYPE_IPV6,
...@@ -12598,15 +12860,18 @@ int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) { ...@@ -12598,15 +12860,18 @@ int mg_if_listen_udp(struct mg_connection *nc, union socket_address *sa) {
return 0; 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); 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); 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( nc->sock = TCPIP_TCP_ServerOpen(
sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4 sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4
: IP_ADDRESS_TYPE_IPV6, : IP_ADDRESS_TYPE_IPV6,
...@@ -12648,7 +12913,7 @@ static int mg_accept_conn(struct mg_connection *lc) { ...@@ -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)); 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) { char *inet_ntoa(struct in_addr in) {
...@@ -12730,7 +12995,8 @@ static void mg_handle_recv(struct mg_connection *nc) { ...@@ -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(); double now = mg_time();
struct mg_connection *nc, *tmp; struct mg_connection *nc, *tmp;
...@@ -12771,4 +13037,41 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) { ...@@ -12771,4 +13037,41 @@ time_t mg_mgr_poll(struct mg_mgr *mgr, int timeout_ms) {
return now; 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 */
...@@ -2769,6 +2769,126 @@ struct { \ ...@@ -2769,6 +2769,126 @@ struct { \
#endif /* CS_MONGOOSE_SRC_FEATURES_H_ */ #endif /* CS_MONGOOSE_SRC_FEATURES_H_ */
#ifdef MG_MODULE_LINES #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" #line 1 "mongoose/src/net.h"
#endif #endif
/* /*
...@@ -2807,6 +2927,7 @@ struct { \ ...@@ -2807,6 +2927,7 @@ struct { \
#endif #endif
/* Amalgamated: #include "mongoose/src/common.h" */ /* Amalgamated: #include "mongoose/src/common.h" */
/* Amalgamated: #include "mongoose/src/net_if.h" */
/* Amalgamated: #include "common/mbuf.h" */ /* Amalgamated: #include "common/mbuf.h" */
#if MG_ENABLE_SSL #if MG_ENABLE_SSL
...@@ -2850,7 +2971,8 @@ struct mg_connection; ...@@ -2850,7 +2971,8 @@ struct mg_connection;
* Callback function (event handler) prototype. Must be defined by the user. * Callback function (event handler) prototype. Must be defined by the user.
* Mongoose calls the event handler, passing the events defined below. * 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. */ /* 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 */ #define MG_EV_POLL 0 /* Sent to each connection on each mg_mgr_poll() call */
...@@ -2873,7 +2995,8 @@ struct mg_mgr { ...@@ -2873,7 +2995,8 @@ struct mg_mgr {
sock_t ctl[2]; /* Socketpair for mg_broadcast() */ sock_t ctl[2]; /* Socketpair for mg_broadcast() */
#endif #endif
void *user_data; /* User data */ 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 #if MG_ENABLE_JAVASCRIPT
struct v7 *v7; struct v7 *v7;
#endif #endif
...@@ -2921,6 +3044,7 @@ struct mg_connection { ...@@ -2921,6 +3044,7 @@ struct mg_connection {
} priv_1; /* Used by mg_enable_multithreading() */ } priv_1; /* Used by mg_enable_multithreading() */
void *priv_2; /* Used by mg_enable_multithreading() */ void *priv_2; /* Used by mg_enable_multithreading() */
void *mgr_data; /* Implementation-specific event manager's data. */ void *mgr_data; /* Implementation-specific event manager's data. */
struct mg_iface *iface;
unsigned long flags; unsigned long flags;
/* Flags set by Mongoose */ /* Flags set by Mongoose */
#define MG_F_LISTENING (1 << 0) /* This connection is listening */ #define MG_F_LISTENING (1 << 0) /* This connection is listening */
...@@ -2958,6 +3082,36 @@ struct mg_connection { ...@@ -2958,6 +3082,36 @@ struct mg_connection {
*/ */
void mg_mgr_init(struct mg_mgr *mgr, void *user_data); 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. * De-initialises Mongoose manager.
* *
...@@ -3324,97 +3478,6 @@ double mg_time(void); ...@@ -3324,97 +3478,6 @@ double mg_time(void);
#endif /* CS_MONGOOSE_SRC_NET_H_ */ #endif /* CS_MONGOOSE_SRC_NET_H_ */
#ifdef MG_MODULE_LINES #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" #line 1 "mongoose/src/uri.h"
#endif #endif
/* /*
...@@ -3805,12 +3868,12 @@ struct mg_ssi_call_ctx { ...@@ -3805,12 +3868,12 @@ struct mg_ssi_call_ctx {
#endif #endif
#if MG_ENABLE_HTTP_STREAMING_MULTIPART #if MG_ENABLE_HTTP_STREAMING_MULTIPART
#define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */ #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_BEGIN 122 /* struct mg_http_multipart_part */
#define MG_EV_HTTP_PART_DATA 123 /* 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_PART_END 124 /* struct mg_http_multipart_part */
#define MG_EV_HTTP_MULTIPART_REQUEST_END 125 /* struct mg_http_multipart_part \ /* struct mg_http_multipart_part */
*/ #define MG_EV_HTTP_MULTIPART_REQUEST_END 125
#endif #endif
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment