Commit 34eb3f1e authored by Sergey Lyubka's avatar Sergey Lyubka Committed by GitHub

Merge pull request #855 from cesanta/dev

Mongoose 6.8
parents 7c049307 9d30e892
...@@ -8,7 +8,7 @@ used by vast number of open source and ...@@ -8,7 +8,7 @@ used by vast number of open source and
commercial products - it even runs on the International Space station! commercial products - it even runs on the International Space station!
Mongoose makes embedded network programming fast, robust, and easy. Mongoose makes embedded network programming fast, robust, and easy.
- [Download Mongoose Source Code here](https://www.cesanta.com) - [Download Mongoose Source Code here](https://www.cesanta.com/download.html)
Looking for a complete IoT firmware solution? Looking for a complete IoT firmware solution?
...@@ -17,9 +17,9 @@ Check out [Mongoose OS](https://mongoose-os.com) - open source embedded operatin ...@@ -17,9 +17,9 @@ Check out [Mongoose OS](https://mongoose-os.com) - open source embedded operatin
# Support # Support
- [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples) - [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples)
- [Read User Guide and API reference](https://docs.cesanta.com/mongoose) - [Read User Guide and API reference](https://docs.cesanta.com/mongoose)
- [Support Forum - ask your technical questions here] (http://forum.cesanta.com/index.php?p=/categories/mongoose) - [Support Forum - ask your technical questions here](https://forum.mongoose-os.com/categories/mongoose)
- [Commercial licensing and support available] (https://www.cesanta.com/services-support) - [Commercial licensing and support available](https://www.cesanta.com/licensing.html)
- [Check our latest releases] (https://github.com/cesanta/mongoose/releases) - [Check our latest releases](https://github.com/cesanta/mongoose/releases)
# Features # Features
...@@ -47,7 +47,7 @@ Check out [Mongoose OS](https://mongoose-os.com) - open source embedded operatin ...@@ -47,7 +47,7 @@ Check out [Mongoose OS](https://mongoose-os.com) - open source embedded operatin
Mongoose is released under Commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses. Mongoose is released under Commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses.
Commercial Projects: [Contact us for commercial license.] (https://www.cesanta.com/contact) Commercial Projects: [Contact us for commercial license.](https://www.cesanta.com/contact.html)
# Dashboard Example # Dashboard Example
...@@ -55,18 +55,14 @@ Mongoose is often used to implement device dashboards and real-time ...@@ -55,18 +55,14 @@ Mongoose is often used to implement device dashboards and real-time
data exchange over Websocket. Here is a dashboard example that illustrates data exchange over Websocket. Here is a dashboard example that illustrates
the functionality: the functionality:
![](http://www.cesanta.com/hubfs/www.cesanta.com/diagrams/dash_mongoose_diagram.png) ![](http://www.cesanta.com/images/dashboard.png)
[Developing a new product? Contact us today to discuss how Mongoose can help. [Developing a new product? Contact us today to discuss how Mongoose can help.](https://www.cesanta.com/contact.html)
](https://www.cesanta.com/contact)
# Contributions # Contributions
To submit contributions, sign To submit contributions, sign [Cesanta CLA](https://cesanta.com/cla.html)
[Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml)
and send GitHub pull request. You retain the copyright on your contributions. and send GitHub pull request. You retain the copyright on your contributions.
# Looking for a pre-compiled Mongoose web server Windows or Mac binary? # Looking for a pre-compiled Mongoose web server Windows or Mac binary?
- [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/products/binary) - [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/binary.html)
[![Analytics](https://ga-beacon.appspot.com/UA-42732794-5/project-page)](https://github.com/cesanta/mongoose)
...@@ -7,5 +7,5 @@ signature: | ...@@ -7,5 +7,5 @@ signature: |
--- ---
Frees the memory allocated for options. Frees the memory allocated for options.
If the cm paramater doesn't contain any option it does nothing. If the cm parameter doesn't contain any option it does nothing.
...@@ -21,5 +21,5 @@ This function doesn't update the `name` and `rdata` pointers in the `rr` ...@@ -21,5 +21,5 @@ This function doesn't update the `name` and `rdata` pointers in the `rr`
struct because they might be invalidated as soon as the IO buffer grows struct because they might be invalidated as soon as the IO buffer grows
again. again.
Returns the number of bytes appened or -1 in case of error. Returns the number of bytes appended or -1 in case of error.
...@@ -11,6 +11,7 @@ items: ...@@ -11,6 +11,7 @@ items:
- { name: mg_send_websocket_handshake.md } - { name: mg_send_websocket_handshake.md }
- { name: mg_send_websocket_handshake2.md } - { name: mg_send_websocket_handshake2.md }
- { name: mg_send_websocket_handshake3.md } - { name: mg_send_websocket_handshake3.md }
- { name: mg_send_websocket_handshake3v.md }
- { name: mg_set_protocol_http_websocket.md } - { name: mg_set_protocol_http_websocket.md }
- { name: mg_url_decode.md } - { name: mg_url_decode.md }
- { name: struct_http_message.md } - { name: struct_http_message.md }
......
...@@ -4,9 +4,8 @@ decl_name: "mg_connect_ws" ...@@ -4,9 +4,8 @@ decl_name: "mg_connect_ws"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_connect_ws(struct mg_mgr *mgr, struct mg_connection *mg_connect_ws(struct mg_mgr *mgr,
mg_event_handler_t event_handler, MG_CB(mg_event_handler_t event_handler,
const char *url, const char *protocol, void *user_data);
const char *extra_headers);
--- ---
Helper function that creates an outbound WebSocket connection. Helper function that creates an outbound WebSocket connection.
......
...@@ -3,11 +3,8 @@ title: "mg_connect_ws_opt()" ...@@ -3,11 +3,8 @@ title: "mg_connect_ws_opt()"
decl_name: "mg_connect_ws_opt" decl_name: "mg_connect_ws_opt"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr, struct mg_connection *mg_connect_ws_opt(
mg_event_handler_t ev_handler, struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data);
struct mg_connect_opts opts,
const char *url, const char *protocol,
const char *extra_headers);
--- ---
Helper function that creates an outbound WebSocket connection Helper function that creates an outbound WebSocket connection
......
...@@ -9,5 +9,6 @@ signature: | ...@@ -9,5 +9,6 @@ signature: |
Sends multiple websocket frames. Sends multiple websocket frames.
Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers. Like `mg_send_websocket_frame()`, but composes a frame from multiple
*buffers.
---
title: "mg_send_websocket_handshake3v()"
decl_name: "mg_send_websocket_handshake3v"
symbol_kind: "func"
signature: |
void mg_send_websocket_handshake3v(struct mg_connection *nc,
const struct mg_str path,
const struct mg_str host,
const struct mg_str protocol,
const struct mg_str extra_headers,
const struct mg_str user,
const struct mg_str pass);
---
Same as mg_send_websocket_handshake3 but with strings not necessarily
NUL-temrinated
...@@ -13,6 +13,7 @@ Source string is specified by (`src`, `src_len`), and destination is ...@@ -13,6 +13,7 @@ Source string is specified by (`src`, `src_len`), and destination is
(`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then
`+` character is decoded as a blank space character. This function `+` character is decoded as a blank space character. This function
guarantees to NUL-terminate the destination. If destination is too small, guarantees to NUL-terminate the destination. If destination is too small,
then the source string is partially decoded and `-1` is returned. Otherwise, then the source string is partially decoded and `-1` is returned.
*Otherwise,
a length of the decoded string is returned, not counting final NUL. a length of the decoded string is returned, not counting final NUL.
...@@ -5,6 +5,7 @@ symbol_kind: "struct" ...@@ -5,6 +5,7 @@ symbol_kind: "struct"
signature: | signature: |
struct http_message { struct http_message {
struct mg_str message; /* Whole message: request line + headers + body */ struct mg_str message; /* Whole message: request line + headers + body */
struct mg_str body; /* Message body. 0-length for requests with no body */
/* HTTP Request line (or HTTP response line) */ /* HTTP Request line (or HTTP response line) */
struct mg_str method; /* "GET" */ struct mg_str method; /* "GET" */
...@@ -28,9 +29,6 @@ signature: | ...@@ -28,9 +29,6 @@ signature: |
/* Headers */ /* Headers */
struct mg_str header_names[MG_MAX_HTTP_HEADERS]; struct mg_str header_names[MG_MAX_HTTP_HEADERS];
struct mg_str header_values[MG_MAX_HTTP_HEADERS]; struct mg_str header_values[MG_MAX_HTTP_HEADERS];
/* Message body */
struct mg_str body; /* Zero-length for requests with no body */
}; };
--- ---
......
...@@ -3,11 +3,9 @@ title: "mg_connect_http()" ...@@ -3,11 +3,9 @@ title: "mg_connect_http()"
decl_name: "mg_connect_http" decl_name: "mg_connect_http"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_connect_http(struct mg_mgr *mgr, struct mg_connection *mg_connect_http(
mg_event_handler_t event_handler, struct mg_mgr *mgr,
const char *url, MG_CB(mg_event_handler_t event_handler, void *user_data);
const char *extra_headers,
const char *post_data);
--- ---
Helper function that creates an outbound HTTP connection. Helper function that creates an outbound HTTP connection.
......
...@@ -3,12 +3,8 @@ title: "mg_connect_http_opt()" ...@@ -3,12 +3,8 @@ title: "mg_connect_http_opt()"
decl_name: "mg_connect_http_opt" decl_name: "mg_connect_http_opt"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_connect_http_opt(struct mg_mgr *mgr, struct mg_connection *mg_connect_http_opt(
mg_event_handler_t ev_handler, struct mg_mgr *mgr, MG_CB(mg_event_handler_t ev_handler, void *user_data);
struct mg_connect_opts opts,
const char *url,
const char *extra_headers,
const char *post_data);
--- ---
Helper function that creates an outbound HTTP connection. Helper function that creates an outbound HTTP connection.
......
...@@ -3,6 +3,7 @@ title: "Server API reference" ...@@ -3,6 +3,7 @@ title: "Server API reference"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "http_server.h" decl_name: "http_server.h"
items: items:
- { name: mg_check_digest_auth.md }
- { name: mg_file_upload_handler.md } - { name: mg_file_upload_handler.md }
- { name: mg_get_http_basic_auth.md } - { name: mg_get_http_basic_auth.md }
- { name: mg_get_http_header.md } - { name: mg_get_http_header.md }
......
---
title: "mg_check_digest_auth()"
decl_name: "mg_check_digest_auth"
symbol_kind: "func"
signature: |
int mg_check_digest_auth(struct mg_str method, struct mg_str uri,
struct mg_str username, struct mg_str cnonce,
struct mg_str response, struct mg_str qop,
struct mg_str nc, struct mg_str nonce,
struct mg_str auth_domain, FILE *fp);
---
Authenticates given response params against an opened password file.
Returns 1 if authenticated, 0 otherwise.
It's used by mg_http_check_digest_auth().
...@@ -4,7 +4,8 @@ decl_name: "mg_file_upload_handler" ...@@ -4,7 +4,8 @@ decl_name: "mg_file_upload_handler"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data, void mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,
mg_fu_fname_fn local_name_fn); mg_fu_fname_fn local_name_fn
MG_UD_ARG(void *user_data);
--- ---
File upload handler. File upload handler.
......
...@@ -12,5 +12,6 @@ Fetches a HTTP form variable. ...@@ -12,5 +12,6 @@ Fetches a HTTP form variable.
Fetches a variable `name` from a `buf` into a buffer specified by `dst`, Fetches a variable `name` from a `buf` into a buffer specified by `dst`,
`dst_len`. The destination is always zero-terminated. Returns the length of `dst_len`. The destination is always zero-terminated. Returns the length of
a fetched variable. If not found, 0 is returned. `buf` must be valid a fetched variable. If not found, 0 is returned. `buf` must be valid
url-encoded buffer. If destination is too small, `-1` is returned. url-encoded buffer. If destination is too small or an error occured,
negative number is returned.
...@@ -12,7 +12,7 @@ Sends a redirect response. ...@@ -12,7 +12,7 @@ Sends a redirect response.
`status_code` should be either 301 or 302 and `location` point to the `status_code` should be either 301 or 302 and `location` point to the
new location. new location.
If `extra_headers` is not empty, then `extra_headers` are also sent If `extra_headers` is not empty, then `extra_headers` are also sent
after the reponse line. `extra_headers` must NOT end end with new line. after the response line. `extra_headers` must NOT end end with new line.
Example: Example:
......
...@@ -4,7 +4,8 @@ decl_name: "mg_register_http_endpoint" ...@@ -4,7 +4,8 @@ decl_name: "mg_register_http_endpoint"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path, void mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,
mg_event_handler_t handler); MG_CB(mg_event_handler_t handler,
void *user_data);
--- ---
Registers a callback for a specified http endpoint Registers a callback for a specified http endpoint
...@@ -20,7 +21,7 @@ static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) { ...@@ -20,7 +21,7 @@ static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {
nc->flags |= MG_F_SEND_AND_CLOSE; nc->flags |= MG_F_SEND_AND_CLOSE;
} }
static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) { static void handle_hello2(struct mg_connection *nc, int ev, void *ev_data) {
(void) ev; (void) ev_data; (void) ev; (void) ev_data;
mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]"); mg_printf(nc, "HTTP/1.0 200 OK\r\n\r\n[I am Hello2]");
nc->flags |= MG_F_SEND_AND_CLOSE; nc->flags |= MG_F_SEND_AND_CLOSE;
......
...@@ -9,7 +9,7 @@ signature: | ...@@ -9,7 +9,7 @@ signature: |
Sends buffer `buf` of size `len` to the client using chunked HTTP encoding. Sends buffer `buf` of size `len` to the client using chunked HTTP encoding.
This function sends the buffer size as hex number + newline first, then This function sends the buffer size as hex number + newline first, then
the buffer itself, then the newline. For example, the buffer itself, then the newline. For example,
`mg_send_http_chunk(nc, "foo", 3)` whill append the `3\r\nfoo\r\n` string `mg_send_http_chunk(nc, "foo", 3)` will append the `3\r\nfoo\r\n` string
to the `nc->send_mbuf` output IO buffer. to the `nc->send_mbuf` output IO buffer.
NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to NOTE: The HTTP header "Transfer-Encoding: chunked" should be sent prior to
......
...@@ -9,7 +9,7 @@ signature: | ...@@ -9,7 +9,7 @@ signature: |
Sends the response status line. Sends the response status line.
If `extra_headers` is not NULL, then `extra_headers` are also sent If `extra_headers` is not NULL, then `extra_headers` are also sent
after the reponse line. `extra_headers` must NOT end end with new line. after the response line. `extra_headers` must NOT end end with new line.
Example: Example:
mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *"); mg_send_response_line(nc, 200, "Access-Control-Allow-Origin: *");
......
...@@ -5,6 +5,7 @@ decl_name: "mqtt.h" ...@@ -5,6 +5,7 @@ decl_name: "mqtt.h"
items: items:
- { name: mg_mqtt_connack.md } - { name: mg_mqtt_connack.md }
- { name: mg_mqtt_disconnect.md } - { name: mg_mqtt_disconnect.md }
- { name: mg_mqtt_match_topic_expression.md }
- { name: mg_mqtt_next_subscribe_topic.md } - { name: mg_mqtt_next_subscribe_topic.md }
- { name: mg_mqtt_ping.md } - { name: mg_mqtt_ping.md }
- { name: mg_mqtt_pong.md } - { name: mg_mqtt_pong.md }
...@@ -17,6 +18,7 @@ items: ...@@ -17,6 +18,7 @@ items:
- { name: mg_mqtt_subscribe.md } - { name: mg_mqtt_subscribe.md }
- { name: mg_mqtt_unsuback.md } - { name: mg_mqtt_unsuback.md }
- { name: mg_mqtt_unsubscribe.md } - { name: mg_mqtt_unsubscribe.md }
- { name: mg_mqtt_vmatch_topic_expression.md }
- { name: mg_send_mqtt_handshake.md } - { name: mg_send_mqtt_handshake.md }
- { name: mg_send_mqtt_handshake_opt.md } - { name: mg_send_mqtt_handshake_opt.md }
- { name: mg_set_protocol_mqtt.md } - { name: mg_set_protocol_mqtt.md }
......
---
title: "mg_mqtt_match_topic_expression()"
decl_name: "mg_mqtt_match_topic_expression"
symbol_kind: "func"
signature: |
int mg_mqtt_match_topic_expression(struct mg_str exp, struct mg_str topic);
---
Matches a topic against a topic expression
Returns 1 if it matches; 0 otherwise.
---
title: "mg_mqtt_vmatch_topic_expression()"
decl_name: "mg_mqtt_vmatch_topic_expression"
symbol_kind: "func"
signature: |
int mg_mqtt_vmatch_topic_expression(const char *exp, struct mg_str topic);
---
Same as `mg_mqtt_match_topic_expression()`, but takes `exp` as a
NULL-terminated string.
...@@ -5,6 +5,7 @@ symbol_kind: "struct" ...@@ -5,6 +5,7 @@ symbol_kind: "struct"
signature: | signature: |
struct mg_mqtt_proto_data { struct mg_mqtt_proto_data {
uint16_t keep_alive; uint16_t keep_alive;
double last_control_time;
}; };
--- ---
......
...@@ -11,7 +11,6 @@ items: ...@@ -11,7 +11,6 @@ items:
- { name: mg_check_ip_acl.md } - { name: mg_check_ip_acl.md }
- { name: mg_connect.md } - { name: mg_connect.md }
- { name: mg_connect_opt.md } - { name: mg_connect_opt.md }
- { name: mg_enable_javascript.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_init_opt.md }
......
...@@ -3,7 +3,9 @@ title: "mg_add_sock()" ...@@ -3,7 +3,9 @@ title: "mg_add_sock()"
decl_name: "mg_add_sock" decl_name: "mg_add_sock"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t); struct mg_connection *mg_add_sock(struct mg_mgr *mgr, sock_t sock,
MG_CB(mg_event_handler_t handler,
void *user_data);
--- ---
Creates a connection, associates it with the given socket and event handler Creates a connection, associates it with the given socket and event handler
......
...@@ -3,9 +3,9 @@ title: "mg_add_sock_opt()" ...@@ -3,9 +3,9 @@ title: "mg_add_sock_opt()"
decl_name: "mg_add_sock_opt" decl_name: "mg_add_sock_opt"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t, struct mg_connection *mg_add_sock_opt(struct mg_mgr *mgr, sock_t sock,
mg_event_handler_t, MG_CB(mg_event_handler_t handler,
struct mg_add_sock_opts); void *user_data);
--- ---
Creates a connection, associates it with the given socket and event handler Creates a connection, associates it with the given socket and event handler
......
...@@ -3,8 +3,9 @@ title: "mg_bind()" ...@@ -3,8 +3,9 @@ title: "mg_bind()"
decl_name: "mg_bind" decl_name: "mg_bind"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_bind(struct mg_mgr *, const char *, struct mg_connection *mg_bind(struct mg_mgr *mgr, const char *address,
mg_event_handler_t); MG_CB(mg_event_handler_t handler,
void *user_data);
--- ---
Creates a listening connection. Creates a listening connection.
......
...@@ -4,8 +4,8 @@ decl_name: "mg_bind_opt" ...@@ -4,8 +4,8 @@ decl_name: "mg_bind_opt"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address, struct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,
mg_event_handler_t handler, MG_CB(mg_event_handler_t handler,
struct mg_bind_opts opts); void *user_data);
--- ---
Creates a listening connection. Creates a listening connection.
...@@ -15,7 +15,7 @@ the same as for the `mg_connect()` call, where `HOST` part is optional. ...@@ -15,7 +15,7 @@ the same as for the `mg_connect()` call, where `HOST` part is optional.
`address` can be just a port number, e.g. `:8000`. To bind to a specific `address` can be just a port number, e.g. `:8000`. To bind to a specific
interface, an IP address can be specified, e.g. `1.2.3.4:8000`. By default, interface, an IP address can be specified, e.g. `1.2.3.4:8000`. By default,
a TCP connection is created. To create UDP connection, prepend `udp://` a TCP connection is created. To create UDP connection, prepend `udp://`
prefix, e.g. `udp://:8000`. To summarize, `address` paramer has following prefix, e.g. `udp://:8000`. To summarize, `address` parameter has following
format: `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or format: `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or
`udp`. `udp`.
......
...@@ -3,7 +3,8 @@ title: "mg_broadcast()" ...@@ -3,7 +3,8 @@ title: "mg_broadcast()"
decl_name: "mg_broadcast" decl_name: "mg_broadcast"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
void mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t); void mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,
size_t len);
--- ---
Passes a message of a given length to all connections. Passes a message of a given length to all connections.
......
...@@ -18,7 +18,7 @@ Subnet masks may vary from 0 to 32, inclusive. The default setting ...@@ -18,7 +18,7 @@ Subnet masks may vary from 0 to 32, inclusive. The default setting
is to allow all access. On each request the full list is traversed, is to allow all access. On each request the full list is traversed,
and the last match wins. Example: and the last match wins. Example:
`-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet `-0.0.0.0/0,+192.168/16` - deny all accesses, only allow 192.168/16 subnet
To learn more about subnet masks, see this To learn more about subnet masks, see this
link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork]. link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork].
......
...@@ -4,7 +4,8 @@ decl_name: "mg_connect" ...@@ -4,7 +4,8 @@ decl_name: "mg_connect"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address, struct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,
mg_event_handler_t handler); MG_CB(mg_event_handler_t handler,
void *user_data);
--- ---
Connects to a remote host. Connects to a remote host.
......
...@@ -4,8 +4,8 @@ decl_name: "mg_connect_opt" ...@@ -4,8 +4,8 @@ decl_name: "mg_connect_opt"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address, struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
mg_event_handler_t handler, MG_CB(mg_event_handler_t handler,
struct mg_connect_opts opts); void *user_data);
--- ---
Connects to a remote host. Connects to a remote host.
......
---
title: "mg_enable_javascript()"
decl_name: "mg_enable_javascript"
symbol_kind: "func"
signature: |
enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
const char *init_js_file_name);
---
Enables server-side JavaScript scripting.
Requires a `-DMG_ENABLE_JAVASCRIPT` compilation flag and V7 engine sources.
V7 instance must not be destroyed during manager's lifetime.
Returns a V7 error.
...@@ -4,7 +4,7 @@ decl_name: "mg_event_handler_t" ...@@ -4,7 +4,7 @@ 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, typedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev,
void *ev_data); void *ev_data MG_UD_ARG(void *user_data));
--- ---
Callback function (event handler) prototype. Must be defined by the user. Callback function (event handler) prototype. Must be defined by the user.
......
...@@ -3,7 +3,7 @@ title: "mg_next()" ...@@ -3,7 +3,7 @@ title: "mg_next()"
decl_name: "mg_next" decl_name: "mg_next"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
struct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *); struct mg_connection *mg_next(struct mg_mgr *mgr, struct mg_connection *c);
--- ---
Iterates over all active connections. Iterates over all active connections.
......
...@@ -8,6 +8,7 @@ signature: | ...@@ -8,6 +8,7 @@ signature: |
unsigned int flags; /* Extra connection flags */ unsigned int flags; /* Extra connection flags */
const char **error_string; /* Placeholder for the error string */ const char **error_string; /* Placeholder for the error string */
struct mg_iface *iface; /* Interface instance */ struct mg_iface *iface; /* Interface instance */
const char *nameserver; /* DNS server to use, NULL for default */
#if MG_ENABLE_SSL #if MG_ENABLE_SSL
/* /*
* SSL settings. * SSL settings.
......
...@@ -14,9 +14,7 @@ signature: | ...@@ -14,9 +14,7 @@ signature: |
void *user_data; /* User data */ void *user_data; /* User data */
int num_ifaces; int num_ifaces;
struct mg_iface **ifaces; /* network interfaces */ struct mg_iface **ifaces; /* network interfaces */
#if MG_ENABLE_JAVASCRIPT const char *nameserver; /* DNS server to use */
struct v7 *v7;
#endif
}; };
--- ---
......
...@@ -4,9 +4,10 @@ decl_name: "struct mg_mgr_init_opts" ...@@ -4,9 +4,10 @@ decl_name: "struct mg_mgr_init_opts"
symbol_kind: "struct" symbol_kind: "struct"
signature: | signature: |
struct mg_mgr_init_opts { struct mg_mgr_init_opts {
struct mg_iface_vtable *main_iface; const struct mg_iface_vtable *main_iface;
int num_ifaces; int num_ifaces;
struct mg_iface_vtable **ifaces; const struct mg_iface_vtable **ifaces;
const char *nameserver;
}; };
--- ---
......
...@@ -6,6 +6,7 @@ items: ...@@ -6,6 +6,7 @@ items:
- { name: mg_resolve_async.md } - { name: mg_resolve_async.md }
- { name: mg_resolve_async_opt.md } - { name: mg_resolve_async_opt.md }
- { name: mg_resolve_from_hosts_file.md } - { name: mg_resolve_from_hosts_file.md }
- { name: mg_set_nameserver.md }
- { name: struct_mg_resolve_async_opts.md } - { name: struct_mg_resolve_async_opts.md }
--- ---
......
---
title: "mg_set_nameserver()"
decl_name: "mg_set_nameserver"
symbol_kind: "func"
signature: |
void mg_set_nameserver(struct mg_mgr *mgr, const char *nameserver);
---
Set default DNS server
...@@ -4,7 +4,7 @@ decl_name: "struct mg_resolve_async_opts" ...@@ -4,7 +4,7 @@ decl_name: "struct mg_resolve_async_opts"
symbol_kind: "struct" symbol_kind: "struct"
signature: | signature: |
struct mg_resolve_async_opts { struct mg_resolve_async_opts {
const char *nameserver_url; const char *nameserver;
int max_retries; /* defaults to 2 if zero */ int max_retries; /* defaults to 2 if zero */
int timeout; /* in seconds; defaults to 5 if zero */ int timeout; /* in seconds; defaults to 5 if zero */
int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */ int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
......
...@@ -3,6 +3,7 @@ title: "URI" ...@@ -3,6 +3,7 @@ title: "URI"
symbol_kind: "intro" symbol_kind: "intro"
decl_name: "uri.h" decl_name: "uri.h"
items: items:
- { name: mg_assemble_uri.md }
- { name: mg_parse_uri.md } - { name: mg_parse_uri.md }
--- ---
......
---
title: "mg_assemble_uri()"
decl_name: "mg_assemble_uri"
symbol_kind: "func"
signature: |
int mg_assemble_uri(const struct mg_str *scheme, const struct mg_str *user_info,
const struct mg_str *host, unsigned int port,
const struct mg_str *path, const struct mg_str *query,
const struct mg_str *fragment, int normalize_path,
struct mg_str *uri);
---
Assemble URI from parts. Any of the inputs can be NULL or zero-length mg_str.
If normalize_path is true, path is normalized by resolving relative refs.
Result is a heap-allocated string (uri->p must be free()d after use).
Returns 0 on success, -1 on error.
...@@ -3,7 +3,7 @@ title: "mg_parse_uri()" ...@@ -3,7 +3,7 @@ title: "mg_parse_uri()"
decl_name: "mg_parse_uri" decl_name: "mg_parse_uri"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
int mg_parse_uri(struct mg_str uri, struct mg_str *scheme, int mg_parse_uri(const struct mg_str uri, struct mg_str *scheme,
struct mg_str *user_info, struct mg_str *host, struct mg_str *user_info, struct mg_str *host,
unsigned int *port, struct mg_str *path, struct mg_str *query, unsigned int *port, struct mg_str *path, struct mg_str *query,
struct mg_str *fragment); struct mg_str *fragment);
......
...@@ -8,20 +8,21 @@ items: ...@@ -8,20 +8,21 @@ items:
- { name: mg_basic_auth_header.md } - { name: mg_basic_auth_header.md }
- { name: mg_conn_addr_to_str.md } - { name: mg_conn_addr_to_str.md }
- { name: mg_fopen.md } - { name: mg_fopen.md }
- { name: mg_fread.md }
- { name: mg_fwrite.md }
- { name: mg_hexdump.md } - { name: mg_hexdump.md }
- { name: mg_hexdump_connection.md } - { name: mg_hexdump_connection.md }
- { name: mg_hexdumpf.md } - { name: mg_hexdumpf.md }
- { name: mg_is_big_endian.md } - { name: mg_is_big_endian.md }
- { name: mg_match_prefix.md }
- { name: mg_mbuf_append_base64.md } - { name: mg_mbuf_append_base64.md }
- { name: mg_mbuf_append_base64_putc.md } - { name: mg_mbuf_append_base64_putc.md }
- { name: mg_next_comma_list_entry.md }
- { name: mg_open.md } - { name: mg_open.md }
- { name: mg_skip.md } - { name: mg_skip.md }
- { name: mg_sock_addr_to_str.md } - { name: mg_sock_addr_to_str.md }
- { name: mg_sock_to_str.md } - { name: mg_sock_to_str.md }
- { name: mg_start_thread.md } - { name: mg_start_thread.md }
- { name: mg_stat.md } - { name: mg_stat.md }
- { name: mg_url_encode.md }
--- ---
......
...@@ -3,7 +3,8 @@ title: "mg_basic_auth_header()" ...@@ -3,7 +3,8 @@ title: "mg_basic_auth_header()"
decl_name: "mg_basic_auth_header" decl_name: "mg_basic_auth_header"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
void mg_basic_auth_header(const char *user, const char *pass, struct mbuf *buf); void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass,
struct mbuf *buf);
--- ---
Generate a Basic Auth header and appends it to buf. Generate a Basic Auth header and appends it to buf.
......
...@@ -3,8 +3,8 @@ title: "mg_conn_addr_to_str()" ...@@ -3,8 +3,8 @@ title: "mg_conn_addr_to_str()"
decl_name: "mg_conn_addr_to_str" decl_name: "mg_conn_addr_to_str"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len, int mg_conn_addr_to_str(struct mg_connection *c, char *buf, size_t len,
int flags); int flags);
--- ---
Converts a connection's local or remote address into string. Converts a connection's local or remote address into string.
...@@ -17,5 +17,6 @@ see `MG_SOCK_STRINGIFY_*` definitions. ...@@ -17,5 +17,6 @@ see `MG_SOCK_STRINGIFY_*` definitions.
- MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address
If both port number and IP address are printed, they are separated by `:`. If both port number and IP address are printed, they are separated by `:`.
If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported. If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.
Return length of the stringified address.
---
title: "mg_fread()"
decl_name: "mg_fread"
symbol_kind: "func"
signature: |
size_t mg_fread(void *ptr, size_t size, size_t count, FILE *f);
---
Reads data from the given file stream.
Return value is a number of bytes readen.
---
title: "mg_fwrite()"
decl_name: "mg_fwrite"
symbol_kind: "func"
signature: |
size_t mg_fwrite(const void *ptr, size_t size, size_t count, FILE *f);
---
Writes data to the given file stream.
Return value is a number of bytes wtitten.
---
title: "mg_match_prefix()"
decl_name: "mg_match_prefix"
symbol_kind: "func"
signature: |
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
---
Matches 0-terminated string (mg_match_prefix) or string with given length
mg_match_prefix_n against a glob pattern.
Match is case-insensitive. Returns number of bytes matched, or -1 if no
match.
---
title: "mg_next_comma_list_entry()"
decl_name: "mg_next_comma_list_entry"
symbol_kind: "func"
signature: |
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
struct mg_str *eq_val);
---
A helper function for traversing a comma separated list of values.
It returns a list pointer shifted to the next value or NULL if the end
of the list found.
The value is stored in a val vector. If the value has a form "x=y", then
eq_val vector is initialised to point to the "y" part, and val vector length
is adjusted to point only to "x".
If the list is just a comma separated list of entries, like "aa,bb,cc" then
`eq_val` will contain zero-length string.
The purpose of this function is to parse comma separated string without
any copying/memory allocation.
...@@ -3,8 +3,8 @@ title: "mg_sock_addr_to_str()" ...@@ -3,8 +3,8 @@ title: "mg_sock_addr_to_str()"
decl_name: "mg_sock_addr_to_str" decl_name: "mg_sock_addr_to_str"
symbol_kind: "func" symbol_kind: "func"
signature: | signature: |
void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len, int mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
int flags); int flags);
--- ---
Convert the socket's address into string. Convert the socket's address into string.
......
---
title: "mg_url_encode()"
decl_name: "mg_url_encode"
symbol_kind: "func"
signature: |
struct mg_str mg_url_encode(const struct mg_str src);
---
URL-escape the specified string.
All non-printable characters are escaped, plus `._-$,;~()/`.
Input need not be NUL-terminated, but the returned string is.
Returned string is heap-allocated and must be free()'d.
...@@ -16,7 +16,7 @@ CGI file must be executable. Mongoose honours the shebang line - see ...@@ -16,7 +16,7 @@ CGI file must be executable. Mongoose honours the shebang line - see
http://en.wikipedia.org/wiki/Shebang_(Unix). http://en.wikipedia.org/wiki/Shebang_(Unix).
For example, if both PHP and Perl CGIs are used, then For example, if both PHP and Perl CGIs are used, then
``#!/path/to/php-cgi.exe` and ``#!/path/to/perl.exe` must be the first lines `#!/path/to/php-cgi.exe` and `#!/path/to/perl.exe` must be the first lines
of the respective CGI scripts. of the respective CGI scripts.
It is possible to hardcode the path to the CGI interpreter for all It is possible to hardcode the path to the CGI interpreter for all
...@@ -29,3 +29,7 @@ Example: ...@@ -29,3 +29,7 @@ Example:
```c ```c
opts.cgi_interpreter = "C:\\ruby\\ruby.exe"; opts.cgi_interpreter = "C:\\ruby\\ruby.exe";
``` ```
NOTE: In the CGI handler we don't use explicitly a system call waitpid() for
reaping zombie processes. Instead, we set the SIGCHLD handler to SIG_IGN.
It will cause zombie processes to be reaped automatically.
CAUTION: not all OSes (e.g. QNX) reap zombies if SIGCHLD is ignored.
\ No newline at end of file
...@@ -18,8 +18,9 @@ static int exit_flag = 0; ...@@ -18,8 +18,9 @@ static int exit_flag = 0;
static void ev_handler(struct mg_connection *c, int ev, void *p) { static void ev_handler(struct mg_connection *c, int ev, void *p) {
if (ev == MG_EV_HTTP_REPLY) { if (ev == MG_EV_HTTP_REPLY) {
struct http_message *hm = (struct http_message *)p;
c->flags |= MG_F_CLOSE_IMMEDIATELY; c->flags |= MG_F_CLOSE_IMMEDIATELY;
fwrite(hm->message.p, 1, hm->message.len, stdout); fwrite(hm->message.p, 1, (int)hm->message.len, stdout);
putchar('\n'); putchar('\n');
exit_flag = 1; exit_flag = 1;
} else if (ev == MG_EV_CLOSE) { } else if (ev == MG_EV_CLOSE) {
...@@ -31,7 +32,7 @@ int main(void) { ...@@ -31,7 +32,7 @@ int main(void) {
struct mg_mgr mgr; struct mg_mgr mgr;
mg_mgr_init(&mgr, NULL); mg_mgr_init(&mgr, NULL);
mg_connect_http(mgr, ev_handler, url, NULL, NULL); mg_connect_http(&mgr, ev_handler, url, NULL, NULL);
while (exit_flag == 0) { while (exit_flag == 0) {
......
...@@ -30,8 +30,8 @@ static void ev_handler(struct mg_connection *c, int ev, void *p) { ...@@ -30,8 +30,8 @@ static void ev_handler(struct mg_connection *c, int ev, void *p) {
// We have received an HTTP request. Parsed request is contained in `hm`. // We have received an HTTP request. Parsed request is contained in `hm`.
// Send HTTP reply to the client which shows full original request. // Send HTTP reply to the client which shows full original request.
mg_send_head(c, 200, hm.message.len, "Content-Type: text/plain"); mg_send_head(c, 200, hm->message.len, "Content-Type: text/plain");
mg_printf(c, "%.*s", hm.message.len, hm.message.p); mg_printf(c, "%.*s", (int)hm->message.len, hm->message.p);
} }
} }
......
...@@ -35,7 +35,7 @@ The exec directive is used to execute a command on a server, ...@@ -35,7 +35,7 @@ The exec directive is used to execute a command on a server,
and show command's output. Example: `<!--#exec "ls -l" -->` and show command's output. Example: `<!--#exec "ls -l" -->`
The call directive is a way to invoke a C handler from the HTML page. The call directive is a way to invoke a C handler from the HTML page.
On each occurence of `<!--#call PARAMS -->` directive, On each occurrence of `<!--#call PARAMS -->` directive,
Mongoose calls a registered event handler with `MG_EV_SSI_CALL` event. Mongoose calls a registered event handler with `MG_EV_SSI_CALL` event.
Event parameter will point to the `PARAMS` string. Event parameter will point to the `PARAMS` string.
An event handler can output any text, for example by calling An event handler can output any text, for example by calling
......
...@@ -30,4 +30,4 @@ int main(void) { ...@@ -30,4 +30,4 @@ int main(void) {
} }
``` ```
For the full example, please see the [Simplest HTTPS server example](https://github.com/cesanta/dev/tree/master/mongoose/examples/simplest_web_server_ssl). For the full example, please see the [Simplest HTTPS server example](https://github.com/cesanta/mongoose/tree/master/examples/simplest_web_server_ssl).
...@@ -3,6 +3,6 @@ title: Disabling flags ...@@ -3,6 +3,6 @@ title: Disabling flags
--- ---
- `MG_DISABLE_HTTP_DIGEST_AUTH` disable HTTP Digest (MD5) authorisation support - `MG_DISABLE_HTTP_DIGEST_AUTH` disable HTTP Digest (MD5) authorisation support
- `MG_DISABLE_SHA1` disable SHA1 support (used by WebSocket) - `CS_DISABLE_SHA1` disable SHA1 support (used by WebSocket)
- `MG_DISABLE_MD5` disable MD5 support (used by HTTP auth) - `CS_DISABLE_MD5` disable MD5 support (used by HTTP auth)
- `MG_DISABLE_HTTP_KEEP_ALIVE` useful for embedded systems to save resources - `MG_DISABLE_HTTP_KEEP_ALIVE` useful for embedded systems to save resources
...@@ -9,3 +9,4 @@ title: Tunables ...@@ -9,3 +9,4 @@ title: Tunables
- `MG_SSL_CRYPTO_MODERN`, `MG_SSL_CRYPTO_OLD` - choose either "Modern" or "Old" ciphers - `MG_SSL_CRYPTO_MODERN`, `MG_SSL_CRYPTO_OLD` - choose either "Modern" or "Old" ciphers
instead of the default "Intermediate" setting. instead of the default "Intermediate" setting.
See [this article](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations) for details. See [this article](https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations) for details.
- `MG_USER_FILE_FUNCTIONS` allow you to use custom file operation, by defining you own `mg_stat`, `mg_fopen`, `mg_open`, `mg_fread` and `mg_fwrite` functions
\ No newline at end of file
...@@ -22,7 +22,7 @@ IPATH = . ../.. $(REPO_PATH) ...@@ -22,7 +22,7 @@ IPATH = . ../.. $(REPO_PATH)
VPATH = ../.. VPATH = ../..
MONGOOSE_FEATURES = -DMG_ENABLE_SSL -DMG_ENABLE_HTTP_STREAMING_MULTIPART MONGOOSE_FEATURES = -DMG_ENABLE_SSL -DMG_ENABLE_HTTP_STREAMING_MULTIPART -DMG_MODULE_LINES
SDK_FLAGS = -DUSE_FREERTOS -DSL_PLATFORM_MULTI_THREADED SDK_FLAGS = -DUSE_FREERTOS -DSL_PLATFORM_MULTI_THREADED
# -DTARGET_IS_CC3200 would reduce code size by using functions in ROM # -DTARGET_IS_CC3200 would reduce code size by using functions in ROM
...@@ -58,11 +58,11 @@ $(FW_DIR): ...@@ -58,11 +58,11 @@ $(FW_DIR):
$(FW_ZIP): $(FW_ELF) $(FW_BIN) $(SLFS_FILES) $(FW_ZIP): $(FW_ELF) $(FW_BIN) $(SLFS_FILES)
@echo " Code size: $(shell ls -l $(FW_BIN) | awk '{print $$5}')" @echo " Code size: $(shell ls -l $(FW_BIN) | awk '{print $$5}')"
@echo " GEN $(FW_MANIFEST)" @echo " GEN $(FW_MANIFEST)"
@fw_meta gen_build_info \ @fw_meta.py gen_build_info \
--json_output=$(BUILD_INFO_JSON) --json_output=$(BUILD_INFO_JSON)
@cp -v $(SLFS_FILES) out/ @cp -v $(SLFS_FILES) out/
@cp $(CC3200_SP_FILE)* $(FW_DIR) @cp $(CC3200_SP_FILE)* $(FW_DIR)
@fw_meta create_manifest \ @fw_meta.py create_manifest \
--name=$(PROG) --platform=$(PLATFORM) \ --name=$(PROG) --platform=$(PLATFORM) \
--build_info=$(BUILD_INFO_JSON) \ --build_info=$(BUILD_INFO_JSON) \
--output=$(FW_MANIFEST) \ --output=$(FW_MANIFEST) \
...@@ -72,14 +72,14 @@ $(FW_ZIP): $(FW_ELF) $(FW_BIN) $(SLFS_FILES) ...@@ -72,14 +72,14 @@ $(FW_ZIP): $(FW_ELF) $(FW_BIN) $(SLFS_FILES)
/sys/mcuimg.bin:type=app,src=$(notdir $(FW_BIN)) \ /sys/mcuimg.bin:type=app,src=$(notdir $(FW_BIN)) \
$(foreach f,$(SLFS_FILES), $(notdir $(f)):type=slfile,src=$(notdir $(f))) $(foreach f,$(SLFS_FILES), $(notdir $(f)):type=slfile,src=$(notdir $(f)))
@echo " ZIP $@" @echo " ZIP $@"
@fw_meta create_fw \ @fw_meta.py create_fw \
--manifest=$(FW_MANIFEST) \ --manifest=$(FW_MANIFEST) \
--src_dir=$(FW_DIR) \ --src_dir=$(FW_DIR) \
--output=$@ --output=$@
FREERTOS_SRCS = timers.c list.c queue.c tasks.c port.c heap_3.c osi_freertos.c FREERTOS_SRCS = timers.c list.c queue.c tasks.c port.c heap_3.c osi_freertos.c
DRIVER_SRCS = cpu.c gpio.c gpio_if.c i2c.c i2c_if.c interrupt.c pin.c prcm.c spi.c uart.c udma.c utils.c DRIVER_SRCS = cpu.c gpio.c gpio_if.c i2c.c i2c_if.c interrupt.c pin.c prcm.c spi.c uart.c udma.c utils.c
SL_SRCS = socket.c wlan.c driver.c device.c netapp.c netcfg.c network_common.c cc_pal.c fs.c SL_SRCS = socket.c wlan.c driver.c device.c netapp.c netcfg.c network_common.c timer.c cc_pal.c fs.c
SDK_SRCS = startup_gcc.c $(FREERTOS_SRCS) $(DRIVER_SRCS) $(SL_SRCS) SDK_SRCS = startup_gcc.c $(FREERTOS_SRCS) $(DRIVER_SRCS) $(SL_SRCS)
IPATH += $(SDK_PATH) $(SDK_PATH)/inc $(SDK_PATH)/driverlib \ IPATH += $(SDK_PATH) $(SDK_PATH)/inc $(SDK_PATH)/driverlib \
$(SDK_PATH)/example/common $(SDK_PATH)/oslib \ $(SDK_PATH)/example/common $(SDK_PATH)/oslib \
......
...@@ -40,22 +40,22 @@ void cs_log_set_level(enum cs_log_level level); ...@@ -40,22 +40,22 @@ void cs_log_set_level(enum cs_log_level level);
void cs_log_set_file(FILE *file); void cs_log_set_file(FILE *file);
extern enum cs_log_level cs_log_level; extern enum cs_log_level cs_log_threshold;
void cs_log_print_prefix(const char *func); void cs_log_print_prefix(const char *func);
void cs_log_printf(const char *fmt, ...); void cs_log_printf(const char *fmt, ...);
#define LOG(l, x) \ #define LOG(l, x) \
if (cs_log_level >= l) { \ if (cs_log_threshold >= l) { \
cs_log_print_prefix(__func__); \ cs_log_print_prefix(__func__); \
cs_log_printf x; \ cs_log_printf x; \
} }
#ifndef CS_NDEBUG #ifndef CS_NDEBUG
#define DBG(x) \ #define DBG(x) \
if (cs_log_level >= LL_VERBOSE_DEBUG) { \ if (cs_log_threshold >= LL_VERBOSE_DEBUG) { \
cs_log_print_prefix(__func__); \ cs_log_print_prefix(__func__); \
cs_log_printf x; \ cs_log_printf x; \
} }
#else /* NDEBUG */ #else /* NDEBUG */
......
...@@ -294,3 +294,16 @@ void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *e) { ...@@ -294,3 +294,16 @@ void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *e) {
LOG(LL_ERROR, ("status %d sender %d", e->EventData.deviceEvent.status, LOG(LL_ERROR, ("status %d sender %d", e->EventData.deviceEvent.status,
e->EventData.deviceEvent.sender)); e->EventData.deviceEvent.sender));
} }
#ifndef __TI_COMPILER_VERSION__
int _gettimeofday_r(struct _reent *r, struct timeval *tp, void *tz) {
#else
int gettimeofday(struct timeval *tp, void *tz) {
#endif
unsigned long sec;
unsigned short msec;
MAP_PRCMRTCGet(&sec, &msec);
tp->tv_sec = sec;
tp->tv_usec = ((unsigned long) msec) * 1000;
return 0;
}
docker.cesanta.com/cc3200-build:1.2.0-r8 docker.cesanta.com/cc3200-build:1.3.0-r2
SDK_VER=$(shell cat sdk.version)
.PHONY: all
MG_PATH = $(realpath $(PWD)/../../)
all:
docker run --rm -it -v $(MG_PATH):/esp32_idf \
$(SDK_VER) \
bash -c "cd esp32_idf/examples/ESP32_IDF && \
make -f Makefile.build defconfig && make -f Makefile.build"
clean:
docker run --rm -it -v $(MG_PATH):/esp32_idf \
$(SDK_VER) \
bash -c "rm -rf esp32_idf/examples/ESP32_IDF/build"
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := esp32_idf
include $(IDF_PATH)/make/project.mk
This is a Mongoose "Hello, world" that can be compiled under Espressif IoT Development Framework for ESP32
It connects to WiFi network and serves a "hello world" page.
Most of the the boilerplate comes from [project_template](https://github.com/espressif/esp-idf-template) with minimal changes.
For building the example, you need to have [Docker](https://www.docker.com/products/docker) and use our pre-built SDK container.
To build just run in the example directory
```
$ make
```
Note: before building, change `WIFI_SSID` and `WIFI_PASS` macros in main/main.c file
Once built, use [esptool](https://github.com/espressif/esptool) for flashing
```
$ python esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 115200 --before default_reset --after hard_reset write_flash -u --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 build/bootloader/bootloader.bin 0x10000 build/esp32_idf.bin 0x8000 build/partitions_singleapp.bin
```
#
# Main component makefile.
#
# This Makefile can be left empty. By default, it will take the sources in the
# src/ directory, compile them and link them into lib(subdirectory_name).a
# in the build directory. This behaviour is entirely configurable,
# please read the ESP-IDF documents if you need to do this.
#
COMPONENT_OBJS = main.o mongoose.o
mongoose.o: ../../../../mongoose.c
$(summary) "CC $@"
$(CC) $(CFLAGS) $(CPPFLAGS) \
$(addprefix -I ,$(COMPONENT_INCLUDES)) \
$(addprefix -I ,$(COMPONENT_EXTRA_INCLUDES)) \
-c $< -o $@
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "./../../../mongoose.h"
#define WIFI_SSID "ssid"
#define WIFI_PASS "pass"
#define MG_LISTEN_ADDR "80"
static esp_err_t event_handler(void *ctx, system_event_t *event) {
(void) ctx;
(void) event;
return ESP_OK;
}
static void mg_ev_handler(struct mg_connection *nc, int ev, void *p) {
static const char *reply_fmt =
"HTTP/1.0 200 OK\r\n"
"Connection: close\r\n"
"Content-Type: text/plain\r\n"
"\r\n"
"Hello %s\n";
switch (ev) {
case MG_EV_ACCEPT: {
char addr[32];
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
printf("Connection %p from %s\n", nc, addr);
break;
}
case MG_EV_HTTP_REQUEST: {
char addr[32];
struct http_message *hm = (struct http_message *) p;
mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr),
MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
printf("HTTP request from %s: %.*s %.*s\n", addr, (int) hm->method.len,
hm->method.p, (int) hm->uri.len, hm->uri.p);
mg_printf(nc, reply_fmt, addr);
nc->flags |= MG_F_SEND_AND_CLOSE;
break;
}
case MG_EV_CLOSE: {
printf("Connection %p closed\n", nc);
break;
}
}
}
void app_main(void) {
nvs_flash_init();
tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
/* Initializing WiFi */
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
wifi_config_t sta_config = {
.sta = {.ssid = WIFI_SSID, .password = WIFI_PASS, .bssid_set = false}};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config));
ESP_ERROR_CHECK(esp_wifi_start());
ESP_ERROR_CHECK(esp_wifi_connect());
/* Starting Mongoose */
struct mg_mgr mgr;
struct mg_connection *nc;
printf("Starting web-server on port %s\n", MG_LISTEN_ADDR);
mg_mgr_init(&mgr, NULL);
nc = mg_bind(&mgr, MG_LISTEN_ADDR, mg_ev_handler);
if (nc == NULL) {
printf("Error setting up listener!\n");
return;
}
mg_set_protocol_http_websocket(nc);
/* Processing events */
while (1) {
mg_mgr_poll(&mgr, 1000);
}
}
docker.cesanta.com/esp32-build:1.0-r13
#!/bin/bash #!/bin/bash
REPO=$(cd ../.. && pwd)
docker run \ docker run \
--rm -i -v $(realpath ${PWD}/../..):/src \ --rm -i -v $REPO:/src \
--entrypoint=/bin/bash $(cat sdk.version) -l -c -x ' --entrypoint=/bin/bash $(cat sdk.version) -l -c -x '
export SDK_PATH=/opt/Espressif/ESP8266_RTOS_SDK; export SDK_PATH=/opt/Espressif/ESP8266_RTOS_SDK;
export BIN_PATH=./bin; export BIN_PATH=./bin;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# `wildcard ./*/` works in both linux and linux/wine, while `wildcard */` enumerates nothing under wine # `wildcard ./*/` works in both linux and linux/wine, while `wildcard */` enumerates nothing under wine
SUBDIRS = $(sort $(dir $(wildcard ./*/))) SUBDIRS = $(sort $(dir $(wildcard ./*/)))
SUBDIRS:=$(filter-out ./ ./CC3200/ ./ESP8266_RTOS/ ./mbed/ ./MSP432/ ./nRF51/ ./nRF52/ ./NXP_K64/ ./NXP_LPC4088/ ./PIC32/ ./STM32F4_CC3100/ ./TM4C129/ ./WinCE/, $(SUBDIRS)) SUBDIRS:=$(filter-out ./ ./CC3200/ ./ESP32_IDF/ ./ESP8266_RTOS/ ./mbed/ ./MSP432/ ./nRF51/ ./nRF52/ ./NXP_K64/ ./NXP_LPC4088/ ./PIC32/ ./STM32F4_CC3100/ ./TM4C129/ ./WinCE/, $(SUBDIRS))
ifeq ($(OS), Windows_NT) ifeq ($(OS), Windows_NT)
SUBDIRS:=$(filter-out ./netcat/ ./raspberry_pi_mjpeg_led/ ./captive_dns_server/, $(SUBDIRS)) SUBDIRS:=$(filter-out ./netcat/ ./raspberry_pi_mjpeg_led/ ./captive_dns_server/, $(SUBDIRS))
......
...@@ -10,28 +10,13 @@ ...@@ -10,28 +10,13 @@
#include "mongoose.h" #include "mongoose.h"
static const char *s_http_port = "8000"; static const char *s_http_port = "8000";
static struct mg_serve_http_opts s_http_server_opts;
struct file_writer_data { struct file_writer_data {
FILE *fp; FILE *fp;
size_t bytes_written; size_t bytes_written;
}; };
static void handle_request(struct mg_connection *nc) {
// This handler gets for all endpoints but /upload
mg_printf(nc, "%s",
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n"
"\r\n"
"<html><body>Upload example."
"<form method=\"POST\" action=\"/upload\" "
" enctype=\"multipart/form-data\">"
"<input type=\"file\" name=\"file\" /> <br/>"
"<input type=\"submit\" value=\"Upload\" />"
"</form></body></html>");
nc->flags |= MG_F_SEND_AND_CLOSE;
}
static void handle_upload(struct mg_connection *nc, int ev, void *p) { static void handle_upload(struct mg_connection *nc, int ev, void *p) {
struct file_writer_data *data = (struct file_writer_data *) nc->user_data; struct file_writer_data *data = (struct file_writer_data *) nc->user_data;
struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *) p; struct mg_http_multipart_part *mp = (struct mg_http_multipart_part *) p;
...@@ -82,25 +67,27 @@ static void handle_upload(struct mg_connection *nc, int ev, void *p) { ...@@ -82,25 +67,27 @@ static void handle_upload(struct mg_connection *nc, int ev, void *p) {
} }
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
(void) ev_data; if (ev == MG_EV_HTTP_REQUEST) {
switch (ev) { mg_serve_http(nc, ev_data, s_http_server_opts);
case MG_EV_HTTP_REQUEST:
// Invoked when the full HTTP request is in the buffer (including body).
handle_request(nc);
break;
} }
} }
int main(void) { int main(void) {
struct mg_mgr mgr; struct mg_mgr mgr;
struct mg_connection *nc; struct mg_connection *c;
mg_mgr_init(&mgr, NULL); mg_mgr_init(&mgr, NULL);
nc = mg_bind(&mgr, s_http_port, ev_handler); c = mg_bind(&mgr, s_http_port, ev_handler);
if (c == NULL) {
fprintf(stderr, "Cannot start server on port %s\n", s_http_port);
exit(EXIT_FAILURE);
}
s_http_server_opts.document_root = "."; // Serve current directory
mg_register_http_endpoint(c, "/upload", handle_upload MG_UD_ARG(NULL));
mg_register_http_endpoint(nc, "/upload", handle_upload);
// Set up HTTP server parameters // Set up HTTP server parameters
mg_set_protocol_http_websocket(nc); mg_set_protocol_http_websocket(c);
printf("Starting web server on port %s\n", s_http_port); printf("Starting web server on port %s\n", s_http_port);
for (;;) { for (;;) {
......
<!DOCTYPE html>
<html>
<head>
<title>AJAX Upload Example</title>
<script src="//code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
function updateProgress(evt) {
if (evt.lengthComputable) {
document.getElementById("output").textContent =
"Uploaded " + evt.loaded + " of " + evt.total + " bytes";
}
}
function uploadFile() {
var file_data = new FormData(document.getElementById('filename'));
$.ajax({
url: "/upload",
type: "POST",
data: file_data,
processData: false,
contentType: false,
cache: false,
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',updateProgress, false); // for handling the progress of the upload
}
return myXhr;
},
}).done(function(data) {
document.getElementById("output").textContent = "Result: " + data;
});
return false;
}
</script>
</head>
<body>
<h1>Upload file using standard form upload</h1>
<form method="POST" action="/upload" enctype="multipart/form-data">
<label>Select a file:</label><br>
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
<h1>Upload file using Ajax - that also gives progress report</h1>
<form method="post" id="filename" name="filename" onsubmit="return uploadFile();">
<label>Select a file:</label><br>
<input type="file" id="file" name="file" required />
<input type="submit" value="Upload" />
</form>
<br><br><div id="output"></div>
</body>
</html>
PROG = mqtt_broker PROG = mqtt_broker
MODULE_CFLAGS = -DMG_ENABLE_MQTT_BROKER -DMG_ENABLE_HTTP=0 MODULE_CFLAGS = -DMG_ENABLE_MQTT_BROKER -DMG_ENABLE_HTTP=0
SSL_LIB=openssl #SSL_LIB=openssl
include ../examples.mk include ../examples.mk
...@@ -17,22 +17,31 @@ ...@@ -17,22 +17,31 @@
#include "../../mongoose.h" #include "../../mongoose.h"
static const char *s_listening_address = "0.0.0.0:1883";
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev != MG_EV_POLL) printf("USER HANDLER GOT EVENT %d\n", ev);
/* Do your custom event processing here */
mg_mqtt_broker(c, ev, ev_data);
}
int main(void) { int main(void) {
struct mg_mgr mgr; struct mg_mgr mgr;
const char *address = "0.0.0.0:1883"; struct mg_connection *c;
struct mg_connection *nc;
struct mg_mqtt_broker brk; struct mg_mqtt_broker brk;
mg_mgr_init(&mgr, NULL); mg_mgr_init(&mgr, NULL);
mg_mqtt_broker_init(&brk, NULL); mg_mqtt_broker_init(&brk, NULL);
if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) { if ((c = mg_bind(&mgr, s_listening_address, ev_handler)) == NULL) {
fprintf(stderr, "mg_bind(%s) failed\n", address); fprintf(stderr, "mg_bind(%s) failed\n", s_listening_address);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
nc->user_data = &brk; mg_mqtt_broker_init(&brk, NULL);
c->user_data = &brk;
mg_set_protocol_mqtt(c);
printf("MQTT broker started on %s\n", address); printf("MQTT broker started on %s\n", s_listening_address);
/* /*
* TODO: Add a HTTP status page that shows current sessions * TODO: Add a HTTP status page that shows current sessions
......
...@@ -27,10 +27,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *p) { ...@@ -27,10 +27,7 @@ static void ev_handler(struct mg_connection *nc, int ev, void *p) {
struct mg_mqtt_message *msg = (struct mg_mqtt_message *) p; struct mg_mqtt_message *msg = (struct mg_mqtt_message *) p;
(void) nc; (void) nc;
#if 0 if (ev != MG_EV_POLL) printf("USER HANDLER GOT EVENT %d\n", ev);
if (ev != MG_EV_POLL)
printf("USER HANDLER GOT %d\n", ev);
#endif
switch (ev) { switch (ev) {
case MG_EV_CONNECT: { case MG_EV_CONNECT: {
......
PROG = mqtt_over_websocket_server
MODULE_CFLAGS = -DMG_ENABLE_MQTT_BROKER=1
#SSL_LIB=mbedtls
include ../examples.mk
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
* This software is dual-licensed: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. For the terms of this
* license, see <http://www.gnu.org/licenses/>.
*
* You are free to use this software under the terms of the GNU General
* Public License, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* Alternatively, you can license this software under a commercial
* license, as set out in <https://www.cesanta.com/license>.
*/
#include "mongoose.h"
static const char *s_mqtt_address = "0.0.0.0:1883";
static const char *s_http_address = "0.0.0.0:8080";
static void unproxy(struct mg_connection *c) {
struct mg_connection *pc = (struct mg_connection *) c->user_data;
if (pc != NULL) {
pc->flags |= MG_F_CLOSE_IMMEDIATELY;
pc->user_data = NULL;
c->user_data = NULL;
}
printf("Closing connection %p\n", c);
}
static void proxy_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_POLL) return;
printf("%p %s EVENT %d %p\n", c, __func__, ev, ev_data);
switch (ev) {
case MG_EV_CLOSE: {
unproxy(c);
break;
}
case MG_EV_RECV: {
struct mg_connection *pc = (struct mg_connection *) c->user_data;
if (pc != NULL) {
mg_send_websocket_frame(pc, WEBSOCKET_OP_BINARY, c->recv_mbuf.buf,
c->recv_mbuf.len);
mbuf_remove(&c->recv_mbuf, c->recv_mbuf.len);
}
break;
}
}
}
static void http_handler(struct mg_connection *c, int ev, void *ev_data) {
struct mg_connection *pc = (struct mg_connection *) c->user_data;
if (ev == MG_EV_POLL) return;
printf("%p %s EVENT %d %p\n", c, __func__, ev, ev_data);
/* Do your custom event processing here */
switch (ev) {
case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
pc = mg_connect(c->mgr, s_mqtt_address, proxy_handler);
pc->user_data = c;
c->user_data = pc;
printf("Created proxy connection %p\n", pc);
break;
}
case MG_EV_WEBSOCKET_FRAME: {
struct websocket_message *wm = (struct websocket_message *) ev_data;
if (pc != NULL) {
printf("Forwarding %d bytes\n", (int) wm->size);
mg_send(pc, wm->data, wm->size);
}
break;
}
case MG_EV_CLOSE: {
unproxy(c);
break;
}
}
}
static void mqtt_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_POLL) return;
printf("%p %s EVENT %d %p\n", c, __func__, ev, ev_data);
/* Do your custom event processing here */
switch (ev) {
case MG_EV_CLOSE:
printf("Closing MQTT connection %p\n", c);
break;
}
mg_mqtt_broker(c, ev, ev_data);
}
static void start_mqtt_server(struct mg_mgr *mgr, const char *addr) {
struct mg_connection *c;
static struct mg_mqtt_broker brk; // static is important - must not perish
if ((c = mg_bind(mgr, addr, mqtt_handler)) == NULL) {
fprintf(stderr, "Cannot start MQTT server on port [%s]\n", addr);
exit(EXIT_FAILURE);
}
mg_mqtt_broker_init(&brk, NULL);
c->user_data = &brk;
mg_set_protocol_mqtt(c);
printf("MQTT server started on %s\n", addr);
}
static void start_http_server(struct mg_mgr *mgr, const char *addr) {
struct mg_connection *c;
if ((c = mg_bind(mgr, addr, http_handler)) == NULL) {
fprintf(stderr, "Cannot start HTTP server on port [%s]\n", addr);
exit(EXIT_FAILURE);
}
mg_set_protocol_http_websocket(c);
printf("HTTP server started on %s\n", addr);
}
int main(void) {
struct mg_mgr mgr;
mg_mgr_init(&mgr, NULL);
start_http_server(&mgr, s_http_address);
start_mqtt_server(&mgr, s_mqtt_address);
for (;;) {
mg_mgr_poll(&mgr, 1000);
}
}
PROG = multithreaded
MODULE_CFLAGS=-DMG_ENABLE_THREADS
include ../examples.mk
/*
* Copyright (c) 2014-2017 Cesanta Software Limited
* All rights reserved
*/
#include "mongoose.h"
static sig_atomic_t s_received_signal = 0;
static const char *s_http_port = "8000";
static const int s_num_worker_threads = 5;
static unsigned long s_next_id = 0;
static void signal_handler(int sig_num) {
signal(sig_num, signal_handler);
s_received_signal = sig_num;
}
static struct mg_serve_http_opts s_http_server_opts;
static sock_t sock[2];
// This info is passed to the worker thread
struct work_request {
unsigned long conn_id; // needed to identify the connection where to send the reply
// optionally, more data that could be required by worker
};
// This info is passed by the worker thread to mg_broadcast
struct work_result {
unsigned long conn_id;
int sleep_time;
};
static void on_work_complete(struct mg_connection *nc, int ev, void *ev_data) {
(void) ev;
char s[32];
struct mg_connection *c;
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
if (c->user_data != NULL) {
struct work_result *res = (struct work_result *)ev_data;
if ((unsigned long)c->user_data == res->conn_id) {
sprintf(s, "conn_id:%lu sleep:%d", res->conn_id, res->sleep_time);
mg_send_head(c, 200, strlen(s), "Content-Type: text/plain");
mg_printf(c, "%s", s);
}
}
}
}
void *worker_thread_proc(void *param) {
struct mg_mgr *mgr = (struct mg_mgr *) param;
struct work_request req = {0};
while (s_received_signal == 0) {
if (read(sock[1], &req, sizeof(req)) < 0)
perror("Reading worker sock");
int r = rand() % 10;
sleep(r);
struct work_result res = {req.conn_id, r};
mg_broadcast(mgr, on_work_complete, (void *)&res, sizeof(res));
}
return NULL;
}
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
(void) nc;
(void) ev_data;
switch (ev) {
case MG_EV_ACCEPT:
nc->user_data = (void *)++s_next_id;
break;
case MG_EV_HTTP_REQUEST: {
struct work_request req = {(unsigned long)nc->user_data};
if (write(sock[0], &req, sizeof(req)) < 0)
perror("Writing worker sock");
break;
}
case MG_EV_CLOSE: {
if (nc->user_data) nc->user_data = NULL;
}
}
}
int main(void) {
struct mg_mgr mgr;
struct mg_connection *nc;
int i;
if (mg_socketpair(sock, SOCK_STREAM) == 0) {
perror("Opening socket pair");
exit(1);
}
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
mg_mgr_init(&mgr, NULL);
nc = mg_bind(&mgr, s_http_port, ev_handler);
if (nc == NULL) {
printf("Failed to create listener\n");
return 1;
}
mg_set_protocol_http_websocket(nc);
s_http_server_opts.document_root = "."; // Serve current directory
s_http_server_opts.enable_directory_listing = "no";
for (i = 0; i < s_num_worker_threads; i++) {
mg_start_thread(worker_thread_proc, &mgr);
}
printf("Started on port %s\n", s_http_port);
while (s_received_signal == 0) {
mg_mgr_poll(&mgr, 200);
}
mg_mgr_free(&mgr);
closesocket(sock[0]);
closesocket(sock[1]);
return 0;
}
...@@ -3,7 +3,7 @@ PROJECT_NAME := iot_lwip_tcp_server_pca10028 ...@@ -3,7 +3,7 @@ PROJECT_NAME := iot_lwip_tcp_server_pca10028
export OUTPUT_FILENAME export OUTPUT_FILENAME
#MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) #MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
MAKEFILE_NAME := $(MAKEFILE_LIST) MAKEFILE_NAME := $(MAKEFILE_LIST)
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) ) MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
TEMPLATE_PATH = ../../../../nrf51_iot_sdk/components/toolchain/gcc TEMPLATE_PATH = ../../../../nrf51_iot_sdk/components/toolchain/gcc
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
...@@ -17,7 +17,7 @@ RM := rm -rf ...@@ -17,7 +17,7 @@ RM := rm -rf
#echo suspend #echo suspend
ifeq ("$(VERBOSE)","1") ifeq ("$(VERBOSE)","1")
NO_ECHO := NO_ECHO :=
else else
NO_ECHO := @ NO_ECHO := @
endif endif
...@@ -118,7 +118,7 @@ BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LIS ...@@ -118,7 +118,7 @@ BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LIS
# Mongoose features # Mongoose features
MG_FEATURES_TINY = \ MG_FEATURES_TINY = \
-DMG_DISABLE_HTTP_DIGEST_AUTH \ -DMG_DISABLE_HTTP_DIGEST_AUTH \
-DMG_DISABLE_MD5 \ -DCS_DISABLE_MD5 \
-DMG_DISABLE_HTTP_KEEP_ALIVE \ -DMG_DISABLE_HTTP_KEEP_ALIVE \
-DMG_ENABLE_HTTP_SSI=0 \ -DMG_ENABLE_HTTP_SSI=0 \
-DMG_ENABLE_HTTP_STREAMING_MULTIPART -DMG_ENABLE_HTTP_STREAMING_MULTIPART
...@@ -251,7 +251,7 @@ genbin: ...@@ -251,7 +251,7 @@ genbin:
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
## Create binary .hex file from the .out file ## Create binary .hex file from the .out file
genhex: genhex:
@echo Preparing: $(OUTPUT_FILENAME).hex @echo Preparing: $(OUTPUT_FILENAME).hex
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex $(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
......
...@@ -3,7 +3,7 @@ PROJECT_NAME := iot_lwip_tcp_server_pca10040 ...@@ -3,7 +3,7 @@ PROJECT_NAME := iot_lwip_tcp_server_pca10040
export OUTPUT_FILENAME export OUTPUT_FILENAME
#MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) #MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
MAKEFILE_NAME := $(MAKEFILE_LIST) MAKEFILE_NAME := $(MAKEFILE_LIST)
MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) ) MAKEFILE_DIR := $(dir $(MAKEFILE_NAME) )
TEMPLATE_PATH = ../../../../nrf5_iot_sdk/components/toolchain/gcc TEMPLATE_PATH = ../../../../nrf5_iot_sdk/components/toolchain/gcc
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
...@@ -17,7 +17,7 @@ RM := rm -rf ...@@ -17,7 +17,7 @@ RM := rm -rf
#echo suspend #echo suspend
ifeq ("$(VERBOSE)","1") ifeq ("$(VERBOSE)","1")
NO_ECHO := NO_ECHO :=
else else
NO_ECHO := @ NO_ECHO := @
endif endif
...@@ -165,7 +165,7 @@ BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LIS ...@@ -165,7 +165,7 @@ BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LIS
# Mongoose features # Mongoose features
MG_FEATURES_TINY = \ MG_FEATURES_TINY = \
-DMG_DISABLE_HTTP_DIGEST_AUTH \ -DMG_DISABLE_HTTP_DIGEST_AUTH \
-DMG_DISABLE_MD5 \ -DCS_DISABLE_MD5 \
-DMG_DISABLE_HTTP_KEEP_ALIVE \ -DMG_DISABLE_HTTP_KEEP_ALIVE \
-DMG_ENABLE_HTTP_SSI=0 \ -DMG_ENABLE_HTTP_SSI=0 \
-DMG_ENABLE_HTTP_STREAMING_MULTIPART -DMG_ENABLE_HTTP_STREAMING_MULTIPART
...@@ -297,7 +297,7 @@ genbin: ...@@ -297,7 +297,7 @@ genbin:
$(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(NO_ECHO)$(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin
## Create binary .hex file from the .out file ## Create binary .hex file from the .out file
genhex: genhex:
@echo Preparing: $(OUTPUT_FILENAME).hex @echo Preparing: $(OUTPUT_FILENAME).hex
$(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex $(NO_ECHO)$(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex
echosize: echosize:
......
PROG = websocket_chat PROG = websocket_chat
MODULE_CFLAGS = -DMG_ENABLE_FILESYSTEM=0 MODULE_CFLAGS = -DMG_ENABLE_FILESYSTEM=1
include ../examples.mk include ../examples.mk
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
static sig_atomic_t s_signal_received = 0; static sig_atomic_t s_signal_received = 0;
static const char *s_http_port = "8000"; static const char *s_http_port = "8000";
static struct mg_serve_http_opts s_http_server_opts;
static void signal_handler(int sig_num) { static void signal_handler(int sig_num) {
signal(sig_num, signal_handler); // Reinstantiate signal handler signal(sig_num, signal_handler); // Reinstantiate signal handler
...@@ -46,6 +47,10 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) { ...@@ -46,6 +47,10 @@ static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
broadcast(nc, d); broadcast(nc, d);
break; break;
} }
case MG_EV_HTTP_REQUEST: {
mg_serve_http(nc, (struct http_message *) ev_data, s_http_server_opts);
break;
}
case MG_EV_CLOSE: { case MG_EV_CLOSE: {
/* Disconnect. Tell everybody. */ /* Disconnect. Tell everybody. */
if (is_websocket(nc)) { if (is_websocket(nc)) {
...@@ -69,6 +74,8 @@ int main(void) { ...@@ -69,6 +74,8 @@ int main(void) {
nc = mg_bind(&mgr, s_http_port, ev_handler); nc = mg_bind(&mgr, s_http_port, ev_handler);
mg_set_protocol_http_websocket(nc); mg_set_protocol_http_websocket(nc);
s_http_server_opts.document_root = "."; // Serve current directory
s_http_server_opts.enable_directory_listing = "yes";
printf("Started on port %s\n", s_http_port); printf("Started on port %s\n", s_http_port);
while (s_signal_received == 0) { while (s_signal_received == 0) {
......
This diff is collapsed.
This diff is collapsed.
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