Refactor Mongoose documentation

PUBLISHED_FROM=e9a4e5c7b4a1d03b93a2a79e29de19e60e919929
This commit is contained in:
Sergey Lyubka authored and Cesanta Bot committed 2016-09-01 14:35:02 +00:00
1 parent 4120f953c7
commit 12437fd7fe
87 files changed
+977 -332

No files matched your search

@@ -0,0 +1,11 @@
---
title: Disabling flags
---
- `MG_DISABLE_HTTP_WEBSOCKET` disable HTTP + WebSocket protocol support
- `MG_DISABLE_HTTP_DIGEST_AUTH` disable HTTP Digest (MD5) authorisation support
- `MG_DISABLE_MQTT` disable MQTT support
- `MG_DISABLE_SHA1` disable SHA1 support (used by WebSocket)
- `MG_DISABLE_MD5` disable MD5 support (used by HTTP auth)
- `MG_DISABLE_SOCKETPAIR` disable `mg_broadcast()` API
- `MG_DISABLE_HTTP_KEEP_ALIVE` useful for embedded systems to save resources
@@ -0,0 +1,11 @@
---
title: Enabling flags
---
- `MG_ENABLE_SSL` Enable OpenSSL support
- `MG_ENABLE_IPV6` Enable IPV6 support
- `MG_ENABLE_THREADS` enable `mg_start_thread()` API
- `MG_ENABLE_MQTT_BROKER` enable MQTT broker
- `MG_ENABLE_DNS_SERVER` enable DNS server
- `MG_ENABLE_COAP` enable CoAP protocol
- `MG_ENABLE_GETADDRINFO` enable `getaddrinfo()` in `mg_resolve2()`
+22
View File
@@ -0,0 +1,22 @@
---
title: Build Options
items:
- { type: file, name: enabling-flags.md }
- { type: file, name: disabling-flags.md }
- { type: file, name: platform-spec.md }
- { type: file, name: tunables.md }
---
Mongoose source code ships in a single .c file that contains functionality
for all supported protocols (modules). Modules can be disabled at compile
time which reduces the executable's size. That can be done by setting preprocessor
flags. Also, some preprocessor flags can be used to tune internal Mongoose
parameters.
To set a preprocessor flag during compile time, use the `-D <PREPROCESSOR_FLAG>`
compiler option. For example, to disable both MQTT and CoAP,
compile the application `my_app.c` like this (assumed UNIX system):
```
$ cc my_app.c mongoose.c -D MG_DISABLE_MQTT -D MG_DISABLE_COAP
```
@@ -0,0 +1,10 @@
---
title: Platform specific
---
Mongoose tries to detect the target platform whenever possible, but in some cases you have
to explicitly declare some peculiarities of your target, such as:
- `MG_LWIP`: use LWIP networking stack
- `MG_CC3200`: enable workarounds for the TI CC3200 target.
- `MG_ESP8266`: enable workarounds for the ESP8266 target, add `RTOS_SDK` to specify the RTOS SDK flavour.
+11
View File
@@ -0,0 +1,11 @@
---
title: Tunables
---
- `MG_MALLOC`, `MG_CALLOC`, `MG_REALLOC`, `MG_FREE` allow you to a use custom
memory allocator, e.g. `-DMG_MALLOC=my_malloc`
- `MG_USE_READ_WRITE` when set replaces calls to `recv` with `read` and `send` with `write`,
thus enabling to add any kind of file descriptor (files, serial devices) to an event manager.
- `MG_SSL_CRYPTO_MODERN`, `MG_SSL_CRYPTO_OLD` - choose either "Modern" or "Old" ciphers
instead of the default "Intermediate" setting.
See [this article](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations) for details.
+47
View File
@@ -0,0 +1,47 @@
---
title: Design Concept
---
Mongoose has three basic data structures:
- `struct mg_mgr` is an event manager that holds all active connections
- `struct mg_connection` describes a connection
- `struct mbuf` describes data buffer (received or sent data)
Connections could be either *listening*, *outbound* or *inbound*. Outbound
connections are created by the `mg_connect()` call. Listening connections are
created by the `mg_bind()` call. Inbound connections are those accepted by a
listening connection. Each connection is described by the `struct mg_connection`
structure, which has a number of fields like socket, event handler function,
send/receive buffer, flags, etc.
An application that uses mongoose should follow a standard pattern of
event-driven application:
1. declare and initialise event manager:
```c
struct mg_mgr mgr;
mg_mgr_init(&mgr, NULL);
```
2. Create connections. For example, a server application should create
listening connections:
```c
struct mg_connection *c = mg_bind(&mgr, "80", ev_handler_function);
mg_set_protocol_http_websocket(c);
```
3. create an event loop by calling `mg_mgr_poll()` in a loop:
```c
for (;;) {
mg_mgr_poll(&mgr, 1000);
}
```
`mg_mgr_poll()` iterates over all sockets, accepts new connections, sends and
receives data, closes connections and calls event handler functions for the
respective events. For the full example, see
[Usage Example](#/overview/usage-example.md/)
which implements TCP echo server.
+32
View File
@@ -0,0 +1,32 @@
---
title: Connection flags
---
Each connection has a `flags` bit field. Some flags are set by Mongoose, for
example if a user creates an outbound UDP connection using a `udp://1.2.3.4:5678`
address, Mongoose is going to set a `MG_F_UDP` flag for that connection. Other
flags are meant to be set only by the user event handler to tell Mongoose how to
behave. Below is a list of connection flags that are meant to be set by event
handlers:
* `MG_F_FINISHED_SENDING_DATA` tells Mongoose that all data has been appended
to the `send_mbuf`. As soon as Mongoose sends it to the socket, the
connection will be closed.
* `MG_F_BUFFER_BUT_DONT_SEND` tells Mongoose to append data to the `send_mbuf`
but hold on sending it, because the data will be modified later and then will
be sent by clearing the `MG_F_BUFFER_BUT_DONT_SEND` flag.
* `MG_F_CLOSE_IMMEDIATELY` tells Mongoose to close the connection immediately,
usually after an error.
* `MG_F_USER_1`, `MG_F_USER_2`, `MG_F_USER_3`, `MG_F_USER_4` could be used by a
developer to store an application-specific state.
Flags below are set by Mongoose:
* `MG_F_SSL_HANDSHAKE_DONE` SSL only, set when SSL handshake is done.
* `MG_F_CONNECTING` set when the connection is in connecting state after
`mg_connect()` call but connect did not finish yet.
* `MG_F_LISTENING` set for all listening connections.
* `MG_F_UDP` set if the connection is UDP.
* `MG_F_IS_WEBSOCKET` set if the connection is a WebSocket connection.
* `MG_F_WEBSOCKET_NO_DEFRAG` should be set by a user if the user wants to switch
off automatic WebSocket frame defragmentation.
+31
View File
@@ -0,0 +1,31 @@
---
title: Event handler function
---
Each connection has an event handler function associated with it. That function
must be implemented by the user. Event handler is the key element of the Mongoose
application, since it defines the application's behaviour. This is what an event
handler function looks like:
```c
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
switch (ev) {
/* Event handler code that defines behavior of the connection */
...
}
}
```
- `struct mg_connection *nc`: Connection that has received an event.
- `int ev`: Event number, defined in `mongoose.h`. For example, when data
arrives on an inbound connection, `ev` would be `MG_EV_RECV`.
- `void *ev_data`: This pointer points to the event-specific data, and it has
a different meaning for different events. For example, for an `MG_EV_RECV` event,
`ev_data` is an `int *` pointer, pointing to the number of bytes received
from the remote peer and saved into the receive IO buffer. The exact meaning of
`ev_data` is described for each event. Protocol-specific events usually have
`ev_data` pointing to structures that hold protocol-specific information.
NOTE: `struct mg_connection` has `void *user_data` which is a placeholder for
application-specific data. Mongoose does not use that pointer. Event handler
can store any kind of information there.
+52
View File
@@ -0,0 +1,52 @@
---
title: Events
---
Mongoose accepts incoming connections, reads and writes data and calls
specified event handlers for each connection when appropriate. A typical event
sequence is this:
- For an outbound connection: `MG_EV_CONNECT` -> (`MG_EV_RECV`, `MG_EV_SEND`,
`MG_EV_POLL` ...) -> `MG_EV_CLOSE`
- For an inbound connection: `MG_EV_ACCEPT` -> (`MG_EV_RECV`, `MG_EV_SEND`,
`MG_EV_POLL` ...) -> `MG_EV_CLOSE`
Below is a list of core events triggered by Mongoose (note that each protocol
triggers protocol-specific events in addition to the core ones):
- `MG_EV_ACCEPT`: sent when a new server connection is accepted by a listening
connection. `void *ev_data` is `union socket_address` of the remote peer.
- `MG_EV_CONNECT`: sent when a new outbound connection created by `mg_connect()`
either failed or succeeded. `void *ev_data` is `int *success`. If `success`
is 0, then the connection has been established, otherwise it contains an error code.
See `mg_connect_opt()` function for code example.
- `MG_EV_RECV`: New data is received and appended to the end of `recv_mbuf`.
`void *ev_data` is `int *num_received_bytes`. Typically, event handler should
check received data in `nc->recv_mbuf`, discard processed data by calling
`mbuf_remove()`, set connection flags `nc->flags` if necessary (see `struct
mg_connection`) and write data the remote peer by output functions like
`mg_send()`.
**WARNING**: Mongoose uses `realloc()` to expand the receive buffer. It is
the user's responsibility to discard processed data from the beginning of the receive
buffer, note the `mbuf_remove()` call in the example above.
- `MG_EV_SEND`: Mongoose has written data to the remote peer and discarded
written data from the `mg_connection::send_mbuf`. `void *ev_data` is `int
*num_sent_bytes`.
**NOTE**: Mongoose output functions only append data to the
`mg_connection::send_mbuf`. They do not do any socket writes. An actual IO
is done by `mg_mgr_poll()`. An `MG_EV_SEND` event is just a notification about
an IO has been done.
- `MG_EV_POLL`: Sent to all connections on each invocation of `mg_mgr_poll()`.
This event could be used to do any housekeeping, for example check whether a
certain timeout has expired and closes the connection or send heartbeat
message, etc.
- `MG_EV_TIMER`: Sent to the connection if `mg_set_timer()` was called.
+40
View File
@@ -0,0 +1,40 @@
---
title: Overview
items:
# - { name: usage-example.md }
- { name: concept.md }
- { name: mbufs.md }
- { name: event-handler.md }
- { name: events.md }
- { name: conn-flags.md }
- { name: build-options }
- { name: usage-example.md }
---
Mongoose is a networking library written in C.
It is a swiss army knife for embedded network programming.
It implements event-driven non-blocking APIs for TCP, UDP, HTTP,
WebSocket, CoAP, MQTT for client and server mode.
Features include:
- Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
iPhone, FreeRTOS
- Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com),
[LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
- Works on a variety of embedded boards: TI CC3200, TI MSP430, STM32, ESP8266;
on all Linux-based boards like Raspberry PI, BeagleBone, etc
- Single-threaded, asynchronous, non-blocking core with simple event-based API
- Built-in protocols:
- plain TCP, plain UDP, SSL/TLS (one-way or two-way), client and server
- HTTP client and server
- WebSocket client and server
- MQTT client and server
- CoAP client and server
- DNS client and server
- asynchronous DNS resolver
- Tiny static and run-time footprint
- Source code is both ISO C and ISO C++ compliant
- Very easy to integrate: just copy
[mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and
[mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h)
files to your build tree
+14
View File
@@ -0,0 +1,14 @@
---
title: Memory buffers
---
Each connection has a send and receive buffer, `struct mg_connection::send_mbuf`
and `struct mg_connection::recv_mbuf` respectively. When data arrives,
Mongoose appends received data to the `recv_mbuf` and triggers an `MG_EV_RECV`
event. The user may send data back by calling one of the output functions, like
`mg_send()` or `mg_printf()`. Output functions append data to the `send_mbuf`.
When Mongoose successfully writes data to the socket, it discards data from
`struct mg_connection::send_mbuf` and sends an `MG_EV_SEND` event. When the connection
is closed, an `MG_EV_CLOSE` event is sent.
![](media/mbuf.png)
+44
View File
@@ -0,0 +1,44 @@
---
title: Example - TCP echo server
---
- Copy `mongoose.c` and `mongoose.h` to your build tree
- Write code that uses the Mongoose API, e.g. in `my_app.c`
- Compile application: `$ cc my_app.c mongoose.c`
```c
#include "mongoose.h" // Include Mongoose API definitions
// Define an event handler function
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
struct mbuf *io = &nc->recv_mbuf;
switch (ev) {
case MG_EV_RECV:
// This event handler implements simple TCP echo server
mg_send(nc, io->buf, io->len); // Echo received data back
mbuf_remove(io, io->len); // Discard data from recv buffer
break;
default:
break;
}
}
int main(void) {
struct mg_mgr mgr;
mg_mgr_init(&mgr, NULL); // Initialize event manager object
// Note that many connections can be added to a single event manager
// Connections can be created at any point, e.g. in event handler function
mg_bind(&mgr, "1234", ev_handler); // Create listening connection and add it to the event manager
for (;;) { // Start infinite event loop
mg_mgr_poll(&mgr, 1000);
}
mg_mgr_free(&mgr);
return 0;
}
```