51 | This page demonstrates how Fossa could be used to implement
52 | RESTful APIs. Start typing numbers into the text fields below.
53 | Browser sends two numbers to /api/v1/sum URI.
54 | Web server calclulates the sum and returns the result.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/examples/restful_server/restful_server.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #include "fossa.h"
7 |
8 | static const char *s_http_port = "8000";
9 | static struct ns_serve_http_opts s_http_server_opts;
10 |
11 | static void handle_sum_call(struct ns_connection *nc, struct http_message *hm) {
12 | char n1[100], n2[100];
13 | double result;
14 |
15 | /* Get form variables */
16 | ns_get_http_var(&hm->body, "n1", n1, sizeof(n1));
17 | ns_get_http_var(&hm->body, "n2", n2, sizeof(n2));
18 |
19 | /* Send headers */
20 | ns_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
21 |
22 | /* Compute the result and send it back as a JSON object */
23 | result = strtod(n1, NULL) + strtod(n2, NULL);
24 | ns_printf_http_chunk(nc, "{ \"result\": %lf }", result);
25 | ns_send_http_chunk(nc, "", 0); /* Send empty chunk, the end of response */
26 | }
27 |
28 | static void ev_handler(struct ns_connection *nc, int ev, void *ev_data) {
29 | struct http_message *hm = (struct http_message *) ev_data;
30 |
31 | switch (ev) {
32 | case NS_HTTP_REQUEST:
33 | if (ns_vcmp(&hm->uri, "/api/v1/sum") == 0) {
34 | handle_sum_call(nc, hm); /* Handle RESTful call */
35 | } else if (ns_vcmp(&hm->uri, "/printcontent") == 0) {
36 | char buf[100] = {0};
37 | memcpy(buf, hm->body.p,
38 | sizeof(buf) - 1 < hm->body.len? sizeof(buf) - 1 : hm->body.len);
39 | printf("%s\n", buf);
40 | } else {
41 | ns_serve_http(nc, hm, s_http_server_opts); /* Serve static content */
42 | }
43 | break;
44 | default:
45 | break;
46 | }
47 | }
48 |
49 | int main(int argc, char *argv[]) {
50 | struct ns_mgr mgr;
51 | struct ns_connection *nc;
52 | int i;
53 | char *cp;
54 |
55 | ns_mgr_init(&mgr, NULL);
56 |
57 | /* Process command line options to customize HTTP server */
58 | for (i = 1; i < argc; i++) {
59 | if (strcmp(argv[i], "-D") == 0 && i + 1 < argc) {
60 | mgr.hexdump_file = argv[++i];
61 | } else if (strcmp(argv[i], "-d") == 0 && i + 1 < argc) {
62 | s_http_server_opts.document_root = argv[++i];
63 | } else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
64 | s_http_port = argv[++i];
65 | } else if (strcmp(argv[i], "-a") == 0 && i + 1 < argc) {
66 | s_http_server_opts.auth_domain = argv[++i];
67 | } else if (strcmp(argv[i], "-P") == 0 && i + 1 < argc) {
68 | s_http_server_opts.global_auth_file = argv[++i];
69 | } else if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
70 | s_http_server_opts.per_directory_auth_file = argv[++i];
71 | } else if (strcmp(argv[i], "-r") == 0 && i + 1 < argc) {
72 | s_http_server_opts.url_rewrites = argv[++i];
73 | #ifndef NS_DISABLE_CGI
74 | } else if (strcmp(argv[i], "-i") == 0 && i + 1 < argc) {
75 | s_http_server_opts.cgi_interpreter = argv[++i];
76 | #endif
77 | #ifdef NS_ENABLE_SSL
78 | } else if (strcmp(argv[i], "-s") == 0 && i + 1 < argc) {
79 | const char *ssl_cert = argv[++i];
80 | const char *err_str = ns_set_ssl(nc, ssl_cert, NULL);
81 | if (err_str != NULL) {
82 | fprintf(stderr, "Error loading SSL cert: %s\n", err_str);
83 | exit(1);
84 | }
85 | #endif
86 | }
87 | }
88 |
89 | /* Set HTTP server options */
90 | nc = ns_bind(&mgr, s_http_port, ev_handler);
91 | if (nc == NULL) {
92 | fprintf(stderr, "Error starting server on port %s\n", s_http_port);
93 | exit(1);
94 | }
95 |
96 | ns_set_protocol_http_websocket(nc);
97 | s_http_server_opts.document_root = ".";
98 | s_http_server_opts.enable_directory_listing = "yes";
99 |
100 | /* Use current binary directory as document root */
101 | if (argc > 0 && ((cp = strrchr(argv[0], '/')) != NULL ||
102 | (cp = strrchr(argv[0], '/')) != NULL)) {
103 | *cp = '\0';
104 | s_http_server_opts.document_root = argv[0];
105 | }
106 |
107 | printf("Starting RESTful server on port %s\n", s_http_port);
108 | for (;;) {
109 | ns_mgr_poll(&mgr, 1000);
110 | }
111 | ns_mgr_free(&mgr);
112 |
113 | return 0;
114 | }
115 |
--------------------------------------------------------------------------------
/examples/restful_server_s3/Makefile:
--------------------------------------------------------------------------------
1 | PROG = restful_server_s3
2 | SOURCES = $(PROG).c ../../fossa.c
3 | CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA)
4 |
5 | ifeq ($(SSL), openssl)
6 | CFLAGS += -DNS_ENABLE_SSL -lssl -lcrypto -lcrypto
7 | else ifeq ($(SSL), krypton)
8 | CFLAGS += -DNS_ENABLE_SSL ../../../krypton/krypton.c
9 | endif
10 |
11 | all: $(PROG)
12 |
13 | $(PROG): $(SOURCES)
14 | $(CC) $(SOURCES) -o $@ $(CFLAGS)
15 |
16 | $(PROG).exe: $(SOURCES)
17 | cl $(SOURCES) /I../.. /MD /DNS_ENABLE_THREADS /Fe$@ advapi32.lib
18 |
19 | clean:
20 | rm -rf *.gc* *.dSYM *.exe *.obj *.o a.out $(PROG)
21 |
--------------------------------------------------------------------------------
/examples/restful_server_s3/README.md:
--------------------------------------------------------------------------------
1 | RESTful server with Amazon S3 upload example
2 | ============================================
3 |
4 | This example demonstrates how Fossa could be used to implement a RESTful
5 | service that uses another RESTful service to handle it's own API call.
6 | This example takes form data and uploads it as a file to Amazon S3.
7 |
8 | ## Prerequisites
9 |
10 | - Amazon S3 account security credentials: Access Key ID and Secret Access
11 | Key ID. Get them from the Amazon IAM console.
12 | - Amazon S3 bucket.
13 |
14 | ## Building and running the example
15 |
16 | $ git clone https://github.com/cesanta/fossa.git
17 | $ cd fossa/examples/restful_server_s3
18 | $ make
19 | $ ./restful_server_s3 -a ACCESS_KEY_ID -s SECRET_ACCESS_KEY_ID
20 | Starting RESTful server on port 8000
21 |
22 | Then, open a browser on `http://localhost:8000`
23 |
24 | Note: If you're getting a *Temporary Redirect* error, look what is the
25 | Endpoint value is. It's likely that you have something like
26 | `BUCKET_NAME.S3_ZONE.amazonaws.com`.
27 | Change the *Host* field to `S3_ZONE.amazonaws.com and retry`.
28 |
29 | ## Screenshot
30 |
31 | 
32 |
--------------------------------------------------------------------------------
/examples/restful_server_s3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | RESTful API demo
6 |
7 |
30 |
31 |
32 |
54 |
55 |
56 |
57 |
RESTful server with Amazon S3 integration demo.
58 |
59 |
60 | This page demonstrates how Fossa could be used to implement
61 | a RESTful service that uses another RESTful service to handle
62 | it's own API call. This example takes form data and uploads it as a file
63 | to Amazon S3.
64 | Open S3 console and create a bucket for testing. Fill out correct
65 | bucket name in the fields below.
66 |
67 |
68 |
If you're getting a "Temporary Redirect" error, look what is the
69 | Endpoint value is. It's likely that you have something like
70 | BUCKET_NAME.S3_ZONE.amazonaws.com. Change
71 | the Host field to S3_ZONE.amazonaws.com and retry.
72 |
64 | This page demonstrates how Fossa could be used to implement
65 | device settings page.
66 |
67 |
How to show device parameters on the page
68 |
This page has embedded
69 | <!--#call parameter_name --> blocks. For each such
70 | block, fossa triggers NS_SSI_CALL event, passing
71 | parameter_name string as an event parameter. A callback
72 | then can print some content, which will replace the
73 | <!--#call parameter_name --> block.
74 | Take a look at handle_ssi_call() to see how that is done.
75 |
76 |
77 |
How to save updated values
78 |
When Save button is clicked, this page makes Ajax call and passes
79 | values to the backend in a POST request. Backend extracts values from
80 | the POST request and updates the configuration. Take a look at
81 | handle_save() to see how that is done.
82 |
83 |
84 |
You can change values, click Save button, refresh this page - make sure
85 | settings values stay intact between refreshes.
86 |
87 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/examples/simplest_web_server/Makefile:
--------------------------------------------------------------------------------
1 | PROG = simplest_web_server
2 | SOURCES = $(PROG).c ../../fossa.c
3 | CFLAGS = -W -Wall -I../.. $(CFLAGS_EXTRA)
4 |
5 | all: $(PROG)
6 |
7 | $(PROG): $(SOURCES)
8 | $(CC) $(SOURCES) -o $@ $(CFLAGS)
9 |
10 | $(PROG).exe: $(SOURCES)
11 | cl $(SOURCES) /I../.. /MD /Fe$@
12 |
13 | clean:
14 | rm -rf *.gc* *.dSYM *.exe *.obj *.o a.out $(PROG)
15 |
--------------------------------------------------------------------------------
/examples/simplest_web_server/simplest_web_server.c:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2015 Cesanta Software Limited
2 | // All rights reserved
3 |
4 | #include "fossa.h"
5 |
6 | static const char *s_http_port = "8000";
7 | static struct ns_serve_http_opts s_http_server_opts;
8 |
9 | static void ev_handler(struct ns_connection *nc, int ev, void *p) {
10 | if (ev == NS_HTTP_REQUEST) {
11 | ns_serve_http(nc, p, s_http_server_opts);
12 | }
13 | }
14 |
15 | int main(void) {
16 | struct ns_mgr mgr;
17 | struct ns_connection *nc;
18 |
19 | ns_mgr_init(&mgr, NULL);
20 | nc = ns_bind(&mgr, s_http_port, ev_handler);
21 |
22 | // Set up HTTP server parameters
23 | ns_set_protocol_http_websocket(nc);
24 | s_http_server_opts.document_root = "."; // Serve current directory
25 | s_http_server_opts.enable_directory_listing = "yes";
26 |
27 | printf("Starting web server on port %s\n", s_http_port);
28 | for (;;) {
29 | ns_mgr_poll(&mgr, 1000);
30 | }
31 | ns_mgr_free(&mgr);
32 |
33 | return 0;
34 | }
35 |
--------------------------------------------------------------------------------
/examples/tcp_echo_server/Makefile:
--------------------------------------------------------------------------------
1 | PROG = echo_server
2 | SOURCES = $(PROG).c ../../fossa.c
3 | CFLAGS = -W -Wall -I../.. -pthread $(CFLAGS_EXTRA)
4 |
5 | all: $(PROG)
6 |
7 | $(PROG): $(SOURCES)
8 | $(CC) $(SOURCES) -o $@ $(CFLAGS)
9 |
10 | $(PROG).exe: $(SOURCES)
11 | cl $(SOURCES) /I../.. /MD /Fe$@
12 |
13 | clean:
14 | rm -rf *.gc* *.dSYM *.exe *.obj *.o a.out $(PROG)
15 |
--------------------------------------------------------------------------------
/examples/tcp_echo_server/echo_server.c:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2014 Cesanta Software Limited
2 | // All rights reserved
3 | //
4 | // This software is dual-licensed: you can redistribute it and/or modify
5 | // it under the terms of the GNU General Public License version 2 as
6 | // published by the Free Software Foundation. For the terms of this
7 | // license, see .
8 | //
9 | // You are free to use this software under the terms of the GNU General
10 | // Public License, but WITHOUT ANY WARRANTY; without even the implied
11 | // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | // See the GNU General Public License for more details.
13 | //
14 | // Alternatively, you can license this software under a commercial
15 | // license, as set out in .
16 | //
17 | // $Date: 2014-09-28 05:04:41 UTC $
18 |
19 | #include "fossa.h"
20 |
21 | static void ev_handler(struct ns_connection *nc, int ev, void *p) {
22 | struct mbuf *io = &nc->recv_mbuf;
23 | (void) p;
24 |
25 | switch (ev) {
26 | case NS_RECV:
27 | ns_send(nc, io->buf, io->len); // Echo message back
28 | mbuf_remove(io, io->len); // Discard message from recv buffer
29 | break;
30 | default:
31 | break;
32 | }
33 | }
34 |
35 | int main(void) {
36 | struct ns_mgr mgr;
37 | const char *port1 = "1234", *port2 = "127.0.0.1:17000";
38 |
39 | ns_mgr_init(&mgr, NULL);
40 | ns_bind(&mgr, port1, ev_handler);
41 | ns_bind(&mgr, port2, ev_handler);
42 |
43 | printf("Starting echo mgr on ports %s, %s\n", port1, port2);
44 | for (;;) {
45 | ns_mgr_poll(&mgr, 1000);
46 | }
47 | ns_mgr_free(&mgr);
48 |
49 | return 0;
50 | }
51 |
--------------------------------------------------------------------------------
/examples/websocket_chat/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2014 Cesanta Software
2 | # All rights reserved
3 |
4 | PROG = websocket_chat
5 | CFLAGS = -W -Wall -I../.. -pthread -g -O0 $(CFLAGS_EXTRA)
6 | SOURCES = $(PROG).c ../../fossa.c
7 |
8 | $(PROG): $(SOURCES)
9 | $(CC) -o $(PROG) $(SOURCES) $(CFLAGS)
10 |
11 | clean:
12 | rm -rf $(PROG) *.exe *.dSYM *.obj *.exp .*o *.lib
13 |
--------------------------------------------------------------------------------
/examples/websocket_chat/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | WebSocket Test
6 |
7 |
29 |
30 |
61 |
62 |
63 |
64 |
Websocket PubSub Demonstration
65 |
66 |
67 | This page demonstrates how Fossa could be used to implement
68 |
69 | publish–subscribe pattern. Open this page in several browser
70 | windows. Each window initiates persistent
71 | WebSocket
72 | connection with the server, making each browser window a websocket client.
73 | Send messages, and see messages sent by other clients.
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/examples/websocket_chat/websocket_chat.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #include "fossa.h"
7 |
8 | static sig_atomic_t s_signal_received = 0;
9 | static const char *s_http_port = "8000";
10 | static struct ns_serve_http_opts s_http_server_opts;
11 |
12 | static void signal_handler(int sig_num) {
13 | signal(sig_num, signal_handler); // Reinstantiate signal handler
14 | s_signal_received = sig_num;
15 | }
16 |
17 | static int is_websocket(const struct ns_connection *nc) {
18 | return nc->flags & NSF_IS_WEBSOCKET;
19 | }
20 |
21 | static void broadcast(struct ns_connection *nc, const char *msg, size_t len) {
22 | struct ns_connection *c;
23 | char buf[500];
24 |
25 | snprintf(buf, sizeof(buf), "%p %.*s", nc, (int) len, msg);
26 | for (c = ns_next(nc->mgr, NULL); c != NULL; c = ns_next(nc->mgr, c)) {
27 | ns_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, strlen(buf));
28 | }
29 | }
30 |
31 | static void ev_handler(struct ns_connection *nc, int ev, void *ev_data) {
32 | struct http_message *hm = (struct http_message *) ev_data;
33 | struct websocket_message *wm = (struct websocket_message *) ev_data;
34 |
35 | switch (ev) {
36 | case NS_HTTP_REQUEST:
37 | /* Usual HTTP request - serve static files */
38 | ns_serve_http(nc, hm, s_http_server_opts);
39 | nc->flags |= NSF_SEND_AND_CLOSE;
40 | break;
41 | case NS_WEBSOCKET_HANDSHAKE_DONE:
42 | /* New websocket connection. Tell everybody. */
43 | broadcast(nc, "joined", 6);
44 | break;
45 | case NS_WEBSOCKET_FRAME:
46 | /* New websocket message. Tell everybody. */
47 | broadcast(nc, (char *) wm->data, wm->size);
48 | break;
49 | case NS_CLOSE:
50 | /* Disconnect. Tell everybody. */
51 | if (is_websocket(nc)) {
52 | broadcast(nc, "left", 4);
53 | }
54 | break;
55 | default:
56 | break;
57 | }
58 | }
59 |
60 | int main(void) {
61 | struct ns_mgr mgr;
62 | struct ns_connection *nc;
63 |
64 | signal(SIGTERM, signal_handler);
65 | signal(SIGINT, signal_handler);
66 |
67 | ns_mgr_init(&mgr, NULL);
68 |
69 | nc = ns_bind(&mgr, s_http_port, ev_handler);
70 | s_http_server_opts.document_root = ".";
71 | ns_set_protocol_http_websocket(nc);
72 |
73 | printf("Started on port %s\n", s_http_port);
74 | while (s_signal_received == 0) {
75 | ns_mgr_poll(&mgr, 200);
76 | }
77 | ns_mgr_free(&mgr);
78 |
79 | return 0;
80 | }
81 |
--------------------------------------------------------------------------------
/platforms/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | @make -C arduino_ethernet_W5100/
3 | @make -C arduino_wifi_CC3000/
4 |
--------------------------------------------------------------------------------
/platforms/arduino_common/avrdebug.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 | #include
6 |
7 | void blink(int times, int ms) {
8 | static int inited = 0;
9 | int i;
10 |
11 | if (!inited) {
12 | DDRB |= 0x80;
13 | inited = 1;
14 | }
15 |
16 | for (i = 0; i < times; i++) {
17 | PORTB |= 0x80;
18 | delay(ms);
19 | PORTB &= 0x7F;
20 | delay(ms);
21 | }
22 | }
23 |
24 | extern unsigned int __heap_start;
25 | extern void *__brkval;
26 |
27 | struct __freelist {
28 | size_t sz;
29 | struct __freelist *nx;
30 | };
31 |
32 | extern struct __freelist *__flp;
33 |
34 | int get_freelistsize() {
35 | struct __freelist *current;
36 | int total = 0;
37 | for (current = __flp; current; current = current->nx) {
38 | total += 2;
39 | total += (int) current->sz;
40 | }
41 | return total;
42 | }
43 |
44 | int get_freememsize() {
45 | int free_memory;
46 | if ((int) __brkval == 0) {
47 | free_memory = ((int) &free_memory) - ((int) &__heap_start);
48 | } else {
49 | free_memory = ((int) &free_memory) - ((int) __brkval);
50 | free_memory += get_freelistsize();
51 | }
52 | return free_memory;
53 | }
54 |
--------------------------------------------------------------------------------
/platforms/arduino_common/avrdebug.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #ifndef AVRDEBUG_HEADER_INCLUDED
7 | #define AVRDEBUG_HEADER_INCLUDED
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 | /* Blinks ($times) times with ($ms) delay */
13 | void blink(int times, int ms);
14 |
15 | /* Returns free memory size */
16 | int get_freememsize();
17 |
18 | #if defined(AVR_ENABLE_DEBUG)
19 |
20 | #define DUMPINIT() Serial.begin(9600)
21 | #define DUMPSTR(msg) Serial.println(msg)
22 | #define DUMPDEC(num) Serial.println(num, DEC)
23 | #define DUMPFREEMEM() \
24 | Serial.print("Free mem: "); \
25 | Serial.println(get_freememsize())
26 |
27 | #define DUMPFUNCNAME() Serial.println(__func__)
28 |
29 | #define BLINK(t, m) blink(t, m);
30 |
31 | #else
32 |
33 | #define DUMPINIT()
34 | #define DUMPFUNCNAME()
35 | #define DUMPFREEMEM()
36 | #define BLINK(t, m)
37 | #define DUMPSTR(msg)
38 | #define DUMPDEC(num)
39 |
40 | #endif
41 |
42 | #ifdef __cplusplus
43 | }
44 | #endif
45 |
46 | #endif /* NS_AVRDEBUG_HEADER_INCLUDED */
47 |
--------------------------------------------------------------------------------
/platforms/arduino_common/avrlibc_compat.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #include
7 | #include
8 |
9 | long long int to64(const char* str) {
10 | long long int res = 0;
11 | char negative = 0;
12 |
13 | while (isspace(*str)) str++;
14 |
15 | if (*str == '+') {
16 | str++;
17 | } else if (*str == '-') {
18 | negative = 1;
19 | str++;
20 | }
21 |
22 | while (*str >= '0' && *str <= '9') {
23 | res = res * 10 + (*str - '0');
24 | str++;
25 | }
26 |
27 | return negative ? -res : res;
28 | }
29 |
30 | char* strerror(int errnum) {
31 | /* TODO(alashkin): show real error message */
32 | const char frmstr[] = "Error: %d";
33 | static char retbuf[sizeof(frmstr) + 11];
34 |
35 | snprintf(retbuf, sizeof(retbuf), frmstr, errnum);
36 | return retbuf;
37 | }
38 |
39 | /*
40 | * Returns the number of seconds since the Arduino board
41 | * began running the current program.
42 | * So, this function
43 | * 1. doesn't support anything but NULL as a parameter
44 | * 2. suitable only to detect timeouts etc.
45 | * If time(NULL) is logged, result would be something
46 | * like "1970-01-01..." etc)
47 | */
48 |
49 | time_t time(time_t* timer) {
50 | return millis() / 1000;
51 | }
52 |
--------------------------------------------------------------------------------
/platforms/arduino_common/avrlibc_compat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #ifndef AVRLIBC_COMPAT_HEADER_INCLUDED
7 | #define AVRLIBC_COMPAT_HEADER_INCLUDED
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | /*
14 | * Some of this stuff breaks
15 | * Fossa o Arduino
16 | * TODO(alashkin): remove these defines when
17 | * some kind of AVR-build-test will be ready
18 | */
19 | #define NS_DISABLE_HTTP_DIGEST_AUTH
20 | #define NS_DISABLE_MQTT
21 | #define NS_DISABLE_MD5
22 | #define NS_DISABLE_JSON_RPC
23 | #define NS_DISABLE_SOCKETPAIR
24 | #define NS_DISABLE_SSI
25 | #define NS_DISABLE_POPEN
26 | #define NS_DISABLE_DIRECTORY_LISTING
27 | #define NS_DISABLE_DAV
28 | #define NS_DISABLE_DNS
29 | #define NS_DISABLE_RESOLVER
30 | #define NS_DISABLE_CGI
31 |
32 | #ifdef __cplusplus
33 | extern "C" {
34 | #endif
35 |
36 | /* fossa requires to64, so define it' instead of strtol & co */
37 | long long int to64(const char* str);
38 |
39 | char* strerror(int errnum);
40 |
41 | /* Time declaration & functions */
42 | typedef unsigned long time_t;
43 |
44 | #ifndef TIMEVAL
45 | struct timeval {
46 | uint32_t tv_sec;
47 | uint32_t tv_usec;
48 | };
49 | #define TIMEVAL
50 | #endif
51 |
52 | time_t time(time_t* timer);
53 |
54 | /* TODO(alashkin): add (at least) in-flash "files" operations */
55 |
56 | #define AVR_NOFS
57 | #define AVR_LIBC
58 |
59 | #ifdef __cplusplus
60 | }
61 | #endif
62 |
63 | #endif
64 |
--------------------------------------------------------------------------------
/platforms/arduino_ethernet_W5100/Makefile:
--------------------------------------------------------------------------------
1 | AVRCOMMON = ./../arduino_common/
2 | SOURCES = $(AVRCOMMON)/avrdebug.cpp $(AVRCOMMON)/avrlibc_compat.cpp src/W5100_sockets.cpp
3 | HEADERS = $(SOURCES:.cpp=.h)
4 |
5 | all: avrsupport.h avrsupport.cpp
6 |
7 | avrsupport.h: $(HEADERS)
8 | @cat $(HEADERS) > avrsupport.h
9 |
10 | avrsupport.cpp: $(SOURCES)
11 | @echo "#include \"avrsupport.h\"" > avrsupport.cpp
12 | @cat $(SOURCES) >> avrsupport.cpp
13 |
--------------------------------------------------------------------------------
/platforms/arduino_ethernet_W5100/src/W5100_sockets.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | *
5 | * Partially BSD-compatible sockets for Wiznet W5100.
6 | *
7 | * Note: this implementation is intended for Fossa network library only.
8 | * It supports only non-blocking mode and contains some
9 | * simplifications.
10 | */
11 |
12 | #ifndef W5100_SOCKETS_HEADER_INCLUDED
13 | #define W5100_SOCKETS_HEADER_INCLUDED
14 |
15 | #define ETHERNET_W5100
16 |
17 | #ifdef __cplusplus
18 | extern "C" {
19 | #endif
20 |
21 | typedef void* sock_t;
22 |
23 | #define INVALID_SOCKET NULL
24 |
25 | #define SOCKET_ERROR -1
26 | #define INADDR_ANY 0
27 | #define AF_INET 2
28 |
29 | #define SOCK_STREAM 0
30 | #define SOCK_DGRAM 1
31 |
32 | #define SOMAXCONN 0 /* use hardware-specific maxconn */
33 |
34 | #define SOL_SOCKET 1
35 | #define SO_ERROR 1
36 | #define SO_REUSEADDR 2
37 |
38 | #define FD_CLOEXEC 1
39 |
40 | #define F_GETFL 1
41 | #define F_SETFL 2
42 | #define F_SETFD 3
43 |
44 | #define O_NONBLOCK 1
45 |
46 | /* errors */
47 | #define ENOENT 2
48 | #define EINTR 4
49 | #define EINPROGRESS 115
50 | #define EAGAIN 11
51 | #define EWOULDBLOCK EAGAIN
52 | /* TODO(alashkin): change to darwin values */
53 | #define ENOTCONN 10057
54 | #define EMSGSIZE 10040
55 | #define EINVAL 10022
56 |
57 | #define BUFSIZ 128
58 |
59 | typedef int16_t socklen_t;
60 | typedef uint8_t sa_family_t;
61 | typedef uint16_t in_port_t;
62 | typedef uint8_t ushort_t;
63 | typedef uint32_t ulong_t;
64 |
65 | typedef uint32_t in_addr_t;
66 |
67 | struct in_addr {
68 | in_addr_t s_addr;
69 | };
70 |
71 | struct sockaddr_in {
72 | sa_family_t sin_family;
73 | in_port_t sin_port;
74 | struct in_addr sin_addr;
75 | };
76 |
77 | struct sockaddr {
78 | union {
79 | sa_family_t sa_family;
80 | struct sockaddr_in sin;
81 | };
82 | };
83 |
84 | struct hostent {
85 | /*
86 | * 1. only one ip address is supported
87 | * 2. fossa uses only one field, so, gethostbyname fills only it
88 | */
89 | char* h_addr_list[1][sizeof(uint32_t)];
90 | };
91 |
92 | #define FD_SETSIZE 4 /* W5100 has four sockets only */
93 |
94 | typedef struct _fd_set {
95 | uint8_t fd_count;
96 | sock_t fd_array[FD_SETSIZE];
97 | } fd_set;
98 |
99 | /*
100 | * Usually, FD_XXX and xtoy are macroses,
101 | * here use funtions
102 | * coz size warnings with functions are
103 | * more clear in avr-gcc
104 | */
105 | void FD_ZERO(fd_set* s);
106 | int FD_ISSET(sock_t fd, fd_set* set);
107 | void FD_SET(sock_t fd, fd_set* set);
108 |
109 | uint16_t htons(uint16_t hostshort);
110 | uint32_t htonl(uint32_t hostlong);
111 | uint16_t ntohs(uint16_t netshort);
112 | uint32_t ntohl(uint32_t netlong);
113 |
114 | sock_t socket(int af, int type, int protocol);
115 | int closesocket(sock_t s);
116 | /* fossa uses BSD-style, so define close() */
117 | #define close(x) closesocket(x)
118 |
119 | int sendto(sock_t s, const void* buf, size_t len, int flags,
120 | const struct sockaddr* addr, socklen_t addr_len);
121 | int recvfrom(sock_t s, char* buf, int len, int flags, struct sockaddr* from,
122 | int* fromlen);
123 | int bind(sock_t s, const struct sockaddr* name, int namelen);
124 | int getsockname(sock_t s, struct sockaddr* name, int* namelen);
125 | struct hostent* gethostbyname(const char* name);
126 | char* inet_ntoa(struct in_addr in);
127 | const char* inet_ntop(int af, const void* src, char* dst, socklen_t size);
128 | int listen(sock_t s, int backlog);
129 | sock_t accept(sock_t s, struct sockaddr* addr, int* addrlen);
130 | int recv(sock_t s, char* buf, int len, int flags);
131 | int send(sock_t s, const char* buf, int len, int flags);
132 | int connect(sock_t s, const struct sockaddr* name, int namelen);
133 | int getpeername(sock_t s, struct sockaddr* name, int* namelen);
134 | int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
135 | const struct timeval* timeout);
136 | int getsockopt(sock_t s, int level, int optname, char* optval, int* optlen);
137 | int fcntl(sock_t s, int cmd, uint32_t arg);
138 | int setsockopt(sock_t s, int level, int optname, void* optval, int optlen);
139 |
140 | int ns_avr_get_dns_name(char* name, size_t namelen);
141 | int avr_netinit(uint8_t* mac, uint8_t* ip);
142 |
143 | #ifdef __cplusplus
144 | }
145 | #endif
146 |
147 | #endif /* W5100_SOCKETS_HEADER_INCLUDED */
148 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/Makefile:
--------------------------------------------------------------------------------
1 | AVRCOMMON = ./../arduino_common/
2 | SOURCES = $(AVRCOMMON)/avrdebug.cpp $(AVRCOMMON)/avrlibc_compat.cpp src/CC3000_utils.cpp
3 | HEADERS = $(SOURCES:.cpp=.h)
4 |
5 | all: avrsupport.h avrsupport.cpp
6 |
7 | avrsupport.h: $(HEADERS)
8 | @cat $(HEADERS) > avrsupport.h
9 |
10 | avrsupport.cpp: $(SOURCES)
11 | @echo "#include \"avrsupport.h\"" > avrsupport.cpp
12 | @cat $(SOURCES) >> avrsupport.cpp
13 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/Adafruit_CC3000_Server.h:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file Adafruit_CC3000_Server.h
4 | @author Tony DiCola (tony@tonydicola.com)
5 | @license BSD (see license.txt)
6 |
7 | Adafruit CC3000 TCP server implementation based on the same interface as
8 | the Arduino Ethernet library server class.
9 |
10 | See http://arduino.cc/en/Reference/Ethernet for documentation on the
11 | Arduino Ethernet library and its server interface.
12 |
13 | The only difference between this implementation and the Ethernet library
14 | is that a special client reference facade is returned by the available()
15 | function, instead of a copy of a client like in the Ethernet library. This
16 | is necessary to ensure the buffers that client instances contain aren't
17 | copied and get out of sync.
18 |
19 | */
20 | /**************************************************************************/
21 |
22 | #ifndef ADAFRUIT_CC3000_SERVER_H
23 | #define ADAFRUIT_CC3000_SERVER_H
24 |
25 | #include "Adafruit_CC3000.h"
26 |
27 | #include "Client.h"
28 | #include "Server.h"
29 |
30 | // Assume 4 sockets available, 1 of which is used for listening, so at most 3
31 | // clients can be connected at once.
32 | #define MAX_SERVER_CLIENTS 3
33 |
34 | // Facade that wraps a reference to a client instance into something that looks
35 | // and acts like a client instance value. This is done to mimic the semantics
36 | // of the Ethernet library, without running into problems allowing client
37 | // buffers
38 | // to be copied and get out of sync.
39 | class Adafruit_CC3000_ClientRef : public Client {
40 | public:
41 | Adafruit_CC3000_ClientRef(Adafruit_CC3000_Client *client);
42 | // Return true if the referenced client is connected. This is provided for
43 | // compatibility with Ethernet library code.
44 | operator bool();
45 | // Below are all the public methods of the client class:
46 | int connect(IPAddress ip, uint16_t port);
47 | int connect(const char *host, uint16_t port);
48 |
49 | uint8_t connected(void);
50 | size_t write(uint8_t c);
51 |
52 | size_t fastrprint(const char *str);
53 | size_t fastrprintln(const char *str);
54 | size_t fastrprint(char *str);
55 | size_t fastrprintln(char *str);
56 | size_t fastrprint(const __FlashStringHelper *ifsh);
57 | size_t fastrprintln(const __FlashStringHelper *ifsh);
58 |
59 | size_t write(const void *buf, uint16_t len, uint32_t flags = 0);
60 | int read(void *buf, uint16_t len, uint32_t flags = 0);
61 | int read(void);
62 | int32_t close(void);
63 | int available(void);
64 |
65 | int read(uint8_t *buf, size_t size);
66 | size_t write(const uint8_t *buf, size_t size);
67 | int peek();
68 | void flush();
69 | void stop();
70 |
71 | private:
72 | // Hide the fact that users are really dealing with a pointer to a client
73 | // instance. Note: this class does not own the contents of the client
74 | // pointer and should NEVER attempt to free/delete this pointer.
75 | Adafruit_CC3000_Client *_client;
76 | };
77 |
78 | class Adafruit_CC3000_Server : public Server {
79 | public:
80 | // Construct a TCP server to listen on the specified port.
81 | Adafruit_CC3000_Server(uint16_t port);
82 | // Return the index of a client instance with data available to read.
83 | // This is useful if you need to keep track of your own client state, you can
84 | // index into an array of client state based on the available index returned
85 | // from this function. Optional boolean parameter returns by reference true
86 | // if the available client is connecting for the first time.
87 | int8_t availableIndex(bool *newClient = NULL);
88 | // Get a client instance from a given index.
89 | Adafruit_CC3000_ClientRef getClientRef(int8_t clientIndex);
90 | // Return a reference to a client instance which has data available to read.
91 | Adafruit_CC3000_ClientRef available();
92 | // Initialize the server and start listening for connections.
93 | virtual void begin();
94 | // Write data to all connected clients. Buffer is a pointer to an array
95 | // of bytes, and size specifies how many bytes to write from the buffer.
96 | // Return the sum of bytes written to all clients.
97 | virtual size_t write(const uint8_t *buffer, size_t size);
98 | // Write a byte value to all connected clients.
99 | // Return the sum of bytes written to all clients.
100 | virtual size_t write(uint8_t value);
101 | // Make the overloads of write from the Print base class available.
102 | using Print::write;
103 |
104 | private:
105 | // Store the clients in a simple array.
106 | Adafruit_CC3000_Client _clients[MAX_SERVER_CLIENTS];
107 | // The port this server will listen for connections on.
108 | uint16_t _port;
109 | // The id of the listening socket.
110 | uint32_t _listenSocket;
111 |
112 | // Accept new connections and update the connected clients.
113 | bool acceptNewConnections();
114 | };
115 |
116 | #endif
117 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/README.md:
--------------------------------------------------------------------------------
1 | # Adafruit CC3000 Library
2 |
3 | This is a library for the Adafruit CC3000 WiFi Breakouts etc
4 |
5 | Designed specifically to work with the Adafruit CC3000 Breakout
6 | ----> https://www.adafruit.com/products/1469
7 |
8 | These modules use SPI to communicate, 6 pins are required to interface
9 |
10 | Adafruit invests time and resources providing this open source code,
11 | please support Adafruit and open-source hardware by purchasing
12 | products from Adafruit!
13 |
14 | Check out the links above for our tutorials and wiring diagrams
15 |
16 | Arduino library Written by Limor Fried & Kevin Townsend for Adafruit Industries.
17 | CC3000 host core written by TI
18 |
19 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder Adafruit_CC3000
20 | Check that the Adafruit_CC3000 folder contains Adafruit_CC3000.cpp and Adafruit_CC3000.h
21 |
22 | Place the Adafruit_CC3000 library folder your *arduinosketchfolder*/libraries/ folder.
23 | You may need to create the libraries subfolder if its your first library. Restart the IDE.
24 |
25 | NOTE: the 'SendTweet' example currently DOES NOT WORK due to Twitter API changes. The code is being kept for posterity in case a workaround can be developed.
26 |
27 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/ccspi.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | *
3 | * spi.h - CC3000 Host Driver Implementation.
4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 | *
6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
7 | * & Limor Fried for Adafruit Industries
8 | * This library works with the Adafruit CC3000 breakout
9 | * ----> https://www.adafruit.com/products/1469
10 | * Adafruit invests time and resources providing this open source code,
11 | * please support Adafruit and open-source hardware by purchasing
12 | * products from Adafruit!
13 | *
14 | * Redistribution and use in source and binary forms, with or without
15 | * modification, are permitted provided that the following conditions
16 | * are met:
17 | *
18 | * Redistributions of source code must retain the above copyright
19 | * notice, this list of conditions and the following disclaimer.
20 | *
21 | * Redistributions in binary form must reproduce the above copyright
22 | * notice, this list of conditions and the following disclaimer in the
23 | * documentation and/or other materials provided with the
24 | * distribution.
25 | *
26 | * Neither the name of Texas Instruments Incorporated nor the names of
27 | * its contributors may be used to endorse or promote products derived
28 | * from this software without specific prior written permission.
29 | *
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 | *
42 | *****************************************************************************/
43 |
44 | #ifndef __SPI_H__
45 | #define __SPI_H__
46 |
47 | // Adafruit CC3k Host Driver Difference
48 | // Include necessary Arduino headers.
49 | // Noted 12-12-2014 by tdicola
50 | #if ARDUINO >= 100
51 | #include "Arduino.h"
52 | #else
53 | #include "WProgram.h"
54 | #endif
55 |
56 | #include
57 | #include
58 | #include
59 | #include
60 |
61 | #include "utility/wlan.h"
62 |
63 | typedef void (*gcSpiHandleRx)(void *p);
64 | typedef void (*gcSpiHandleTx)(void);
65 |
66 | extern unsigned char wlan_tx_buffer[];
67 |
68 | //*****************************************************************************
69 | //
70 | // Prototypes for the APIs.
71 | //
72 | //*****************************************************************************
73 | extern void SpiOpen(gcSpiHandleRx pfRxHandler);
74 | extern void SpiClose(void);
75 | extern long SpiWrite(unsigned char *pUserBuffer, unsigned short usLength);
76 | extern void SpiResumeSpi(void);
77 | extern void SpiCleanGPIOISR(void);
78 | extern int init_spi(void);
79 | extern long TXBufferIsEmpty(void);
80 | extern long RXBufferIsEmpty(void);
81 | extern void CC3000_UsynchCallback(long lEventType, char *data,
82 | unsigned char length);
83 | extern void WriteWlanPin(unsigned char val);
84 | extern long ReadWlanInterruptPin(void);
85 | extern void WlanInterruptEnable();
86 | extern void WlanInterruptDisable();
87 | extern char *sendDriverPatch(unsigned long *Length);
88 | extern char *sendBootLoaderPatch(unsigned long *Length);
89 | extern char *sendWLFWPatch(unsigned long *Length);
90 | extern void SPI_IRQ(void);
91 |
92 | #endif
93 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/library.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Adafruit-CC3000",
3 | "keywords": "wifi, wi-fi, http, web, server, json, rest, spi",
4 | "description": "Library code for Adafruit's CC3000 Wi-Fi/WiFi breakouts",
5 | "repository":
6 | {
7 | "type": "git",
8 | "url": "https://github.com/adafruit/Adafruit_CC3000_Library.git"
9 | },
10 | "frameworks": "arduino",
11 | "platforms": "atmelavr"
12 | }
13 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/library.properties:
--------------------------------------------------------------------------------
1 | name=Adafruit CC3000 Library (for fossa)
2 | version=1.0.0
3 | author=Adafruit
4 | maintainer=Adafruit
5 | sentence=Library code for Adafruit's CC3000 WiFi breakouts.
6 | paragraph=The CC3000 allows an Arduino to connect to a WiFi network and access the internet. See more at: https://learn.adafruit.com/adafruit-cc3000-wifi/
7 | category=Communication
8 | url=https://github.com/adafruit/Adafruit_CC3000_Library
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/license.txt:
--------------------------------------------------------------------------------
1 | =====
2 |
3 | Copyright (c) 2013-2014
4 | Limor Fried, Kevin Townsend for Adafruit Industries & Tony DiCola (tony@tonydicola.com)
5 |
6 | Adafruit invests time and resources providing this open source code,
7 | please support Adafruit and open-source hardware by purchasing
8 | products from Adafruit!
9 |
10 | All rights reserved.
11 |
12 | =====
13 |
14 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
15 |
16 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
17 |
18 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/utility/data_types.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | *
3 | * data_types.h - CC3000 Host Driver Implementation.
4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 | *
6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
7 | * & Limor Fried for Adafruit Industries
8 | * This library works with the Adafruit CC3000 breakout
9 | * ----> https://www.adafruit.com/products/1469
10 | * Adafruit invests time and resources providing this open source code,
11 | * please support Adafruit and open-source hardware by purchasing
12 | * products from Adafruit!
13 | *
14 | * Redistribution and use in source and binary forms, with or without
15 | * modification, are permitted provided that the following conditions
16 | * are met:
17 | *
18 | * Redistributions of source code must retain the above copyright
19 | * notice, this list of conditions and the following disclaimer.
20 | *
21 | * Redistributions in binary form must reproduce the above copyright
22 | * notice, this list of conditions and the following disclaimer in the
23 | * documentation and/or other materials provided with the
24 | * distribution.
25 | *
26 | * Neither the name of Texas Instruments Incorporated nor the names of
27 | * its contributors may be used to endorse or promote products derived
28 | * from this software without specific prior written permission.
29 | *
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 | *
42 | *****************************************************************************/
43 | #ifndef __DATA_TYPES__
44 | #define __DATA_TYPES__
45 |
46 | //*****************************************************************************
47 | //
48 | // If building with a C++ compiler, make all of the definitions in this header
49 | // have a C binding.
50 | //
51 | //*****************************************************************************
52 | #ifdef __cplusplus
53 | extern "C" {
54 | #endif
55 |
56 | #ifndef NULL
57 | #define NULL (0)
58 | #endif
59 |
60 | #ifndef FALSE
61 | #define FALSE (0)
62 | #endif
63 |
64 | #ifndef TRUE
65 | #define TRUE (!FALSE)
66 | #endif
67 |
68 | #ifndef OK
69 | #define OK (0)
70 | #endif
71 |
72 | #ifndef _INT8
73 | #define _INT8
74 | typedef signed char INT8;
75 | #endif
76 |
77 | #ifndef _UINT8
78 | #define _UINT8
79 | typedef unsigned char UINT8;
80 | #endif
81 |
82 | #ifndef _INT16
83 | #define _INT16
84 | typedef signed short INT16;
85 | #endif
86 |
87 | #ifndef _UINT16
88 | #define _UINT16
89 | typedef unsigned short UINT16;
90 | #endif
91 |
92 | #ifndef _BOOLEAN
93 | #define _BOOLEAN
94 | typedef unsigned char BOOLEAN;
95 | #endif
96 |
97 | #ifndef _INT32
98 | #define _INT32
99 | typedef signed long INT32;
100 | #endif
101 |
102 | #ifndef _UINT32
103 | #define _UINT32
104 | typedef unsigned long UINT32;
105 | #endif
106 |
107 | typedef int INT;
108 | typedef char CHAR;
109 |
110 | #ifdef __cplusplus
111 | }
112 | #endif /* __cplusplus */
113 |
114 | #endif /* __DATA_TYPE__ */
115 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/utility/debug.cpp:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file Adafruit_CC3000.cpp
4 | @author KTOWN (Kevin Townsend Adafruit Industries)
5 | @license BSD (see license.txt)
6 |
7 | This is a library for the Adafruit CC3000 WiFi breakout board
8 | This library works with the Adafruit CC3000 breakout
9 | ----> https://www.adafruit.com/products/1469
10 |
11 | Check out the links above for our tutorials and wiring diagrams
12 | These chips use SPI to communicate.
13 |
14 | Adafruit invests time and resources providing this open source code,
15 | please support Adafruit and open-source hardware by purchasing
16 | products from Adafruit!
17 |
18 | @section HISTORY
19 |
20 | v1.0 - Initial release
21 | */
22 | /**************************************************************************/
23 |
24 | #include "debug.h"
25 |
26 | /**************************************************************************/
27 | /*!
28 | @brief This function will display the number of bytes currently free
29 | in RAM ... useful for debugging!
30 | */
31 | /**************************************************************************/
32 |
33 | #if defined(__arm__) && defined(__SAM3X8E__) // Arduino Due
34 | // should use uinstd.h to define sbrk but on Arduino Due this causes a conflict
35 | extern "C" char* sbrk(int incr);
36 | int getFreeRam(void) {
37 | char top;
38 | return &top - reinterpret_cast(sbrk(0));
39 | }
40 | #else // AVR
41 | int getFreeRam(void) {
42 | extern int __bss_end;
43 | extern int* __brkval;
44 | int free_memory;
45 | if ((int) __brkval == 0) {
46 | free_memory = ((int) &free_memory) - ((int) &__bss_end);
47 | } else {
48 | free_memory = ((int) &free_memory) - ((int) __brkval);
49 | }
50 |
51 | return free_memory;
52 | }
53 | #endif
54 |
55 | void displayFreeRam(void) {
56 | if (CC3KPrinter == 0) {
57 | return;
58 | }
59 | CC3KPrinter->print(F("Free RAM: "));
60 | CC3KPrinter->print(getFreeRam());
61 | CC3KPrinter->println(F(" bytes"));
62 | }
63 |
64 | void uart_putchar(char c) {
65 | if (CC3KPrinter != 0) {
66 | CC3KPrinter->write(c);
67 | }
68 | }
69 |
70 | void printDec(uint8_t h) {
71 | uart_putchar((h / 100) + '0');
72 | h %= 100;
73 | uart_putchar((h / 10) + '0');
74 | h %= 10;
75 | uart_putchar(h + '0');
76 | }
77 |
78 | void printHex(uint8_t h) {
79 | uint8_t d = h >> 4;
80 | if (d >= 10) {
81 | uart_putchar(d - 10 + 'A');
82 | } else {
83 | uart_putchar(d + '0');
84 | }
85 | h &= 0xF;
86 | if (h >= 10) {
87 | uart_putchar(h - 10 + 'A');
88 | } else {
89 | uart_putchar(h + '0');
90 | }
91 | }
92 |
93 | void printHex16(uint16_t h) {
94 | uart_putchar('0');
95 | uart_putchar('x');
96 | DEBUGPRINT_HEX(h >> 8);
97 | DEBUGPRINT_HEX(h);
98 | }
99 |
100 | void printDec16(uint16_t h) {
101 | uart_putchar((h / 10000) + '0');
102 | h %= 10000;
103 | uart_putchar((h / 1000) + '0');
104 | h %= 1000;
105 | uart_putchar((h / 100) + '0');
106 | h %= 100;
107 | uart_putchar((h / 10) + '0');
108 | h %= 10;
109 | uart_putchar(h + '0');
110 | }
111 |
112 | void DEBUGPRINT(const prog_char* fstr) {
113 | char c;
114 | if (!fstr) return;
115 | while ((c = pgm_read_byte(fstr++))) uart_putchar(c);
116 | }
117 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/utility/debug.h:
--------------------------------------------------------------------------------
1 | /**************************************************************************/
2 | /*!
3 | @file Adafruit_CC3000.cpp
4 | @author KTOWN (Kevin Townsend for Adafruit Industries)
5 | @license BSD (see license.txt)
6 |
7 | This is a library for the Adafruit CC3000 WiFi breakout board
8 | This library works with the Adafruit CC3000 breakout
9 | ----> https://www.adafruit.com/products/1469
10 |
11 | Check out the links above for our tutorials and wiring diagrams
12 | These chips use SPI to communicate.
13 |
14 | Adafruit invests time and resources providing this open source code,
15 | please support Adafruit and open-source hardware by purchasing
16 | products from Adafruit!
17 |
18 | @section HISTORY
19 |
20 | v1.0 - Initial release
21 | */
22 | /**************************************************************************/
23 |
24 | #include
25 |
26 | #define GCC_VERSION \
27 | (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
28 | #if (GCC_VERSION >= 40702) || !defined(prog_char)
29 | typedef char PROGMEM prog_char;
30 | #endif
31 |
32 | #ifndef _CC3000_DEBUG
33 | #define _CC3000_DEBUG
34 |
35 | #define DEBUG_MODE (0)
36 |
37 | int getFreeRam(void);
38 | void displayFreeRam(void);
39 | void uart_putchar(char c);
40 | void printHex(uint8_t h);
41 | void printHex16(uint16_t h);
42 | void DEBUGPRINT(const prog_char* fstr);
43 | void printDec(uint8_t h);
44 | void printDec16(uint16_t h);
45 |
46 | #ifndef FLASHIFY
47 | #define FLASHIFY(s) \
48 | ({ \
49 | static const char c[] __attribute__((progmem)) = s; \
50 | c; \
51 | })
52 | #endif
53 |
54 | #define PRINT_F(__s) DEBUGPRINT(FLASHIFY(__s))
55 |
56 | #if (DEBUG_MODE != 0)
57 | #define DEBUGPRINT_F(__s) DEBUGPRINT(FLASHIFY(__s))
58 | #define DEBUGPRINT_DEC(x) printDec(x)
59 | #define DEBUGPRINT_DEC16(x) printDec16(x)
60 | #define DEBUGPRINT_HEX(x) printHex(x)
61 | #define DEBUGPRINT_HEX16(x) printHex16(x)
62 | #else
63 | #define DEBUGPRINT_F(__s) /* do nothing! */
64 | #define DEBUGPRINT_DEC(x)
65 | #define DEBUGPRINT_DEC16(x)
66 | #define DEBUGPRINT_HEX(x)
67 | #define DEBUGPRINT_HEX16(x)
68 | #endif
69 |
70 | extern Print* CC3KPrinter;
71 |
72 | #endif
73 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/utility/error_codes.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | *
3 | * error_codes.h - CC3000 Host Driver Implementation.
4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 | *
6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
7 | * & Limor Fried for Adafruit Industries
8 | * This library works with the Adafruit CC3000 breakout
9 | * ----> https://www.adafruit.com/products/1469
10 | * Adafruit invests time and resources providing this open source code,
11 | * please support Adafruit and open-source hardware by purchasing
12 | * products from Adafruit!
13 | *
14 | * Redistribution and use in source and binary forms, with or without
15 | * modification, are permitted provided that the following conditions
16 | * are met:
17 | *
18 | * Redistributions of source code must retain the above copyright
19 | * notice, this list of conditions and the following disclaimer.
20 | *
21 | * Redistributions in binary form must reproduce the above copyright
22 | * notice, this list of conditions and the following disclaimer in the
23 | * documentation and/or other materials provided with the
24 | * distribution.
25 | *
26 | * Neither the name of Texas Instruments Incorporated nor the names of
27 | * its contributors may be used to endorse or promote products derived
28 | * from this software without specific prior written permission.
29 | *
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 | *
42 | *****************************************************************************/
43 | #ifndef __ERROR_CODES__
44 | #define __ERROR_CODES__
45 |
46 | //*****************************************************************************
47 | //
48 | // If building with a C++ compiler, make all of the definitions in this header
49 | // have a C binding.
50 | //
51 | //*****************************************************************************
52 | #ifdef __cplusplus
53 | extern "C" {
54 | #endif
55 |
56 | //
57 | // Error numbers
58 | //
59 | #define ERROR_WIFI_ALREADY_DISCONNECTED -129
60 | #define NOT_ENOUGH_SOCKETS -128
61 | #define SOCKET_ALREADY_EXISTS -127
62 | #define NOT_SUPPORTED -126
63 | #define TCP_OPEN_FAILED -124
64 | #define BAD_SOCKET_DATA -123
65 | #define SOCKET_NOT_FOUND -122
66 | #define SOCKET_TIMED_OUT -121
67 | #define BAD_IP_HEADER -120
68 | #define NEED_TO_LISTEN -119
69 | #define RECV_TIMED_OUT -118
70 | #define NEED_TO_SEND -114
71 | #define UNABLE_TO_SEND -113
72 | #define DHCP_ERROR -100
73 | #define DHCP_LEASE_EXPIRED -99
74 | #define ARP_REQUEST_FAILED -95
75 | #define DHCP_LEASE_RENEWING -92
76 | #define IGMP_ERROR -91
77 | #define INVALID_VALUE -85
78 | #define DNS_ID_ERROR -75
79 | #define DNS_OPCODE_ERROR -74
80 | #define DNS_RCODE_ERROR -73
81 | #define DNS_COUNT_ERROR -72
82 | #define DNS_TYPE_ERROR -71
83 | #define DNS_CLASS_ERROR -70
84 | #define DNS_NOT_FOUND -69
85 | #define SOCKET_BUFFER_TOO_SMALL -68
86 | #define REASSEMBLY_ERROR -64
87 | #define REASSEMBLY_TIMED_OUT -63
88 | #define BAD_REASSEMBLY_DATA -62
89 | #define UNABLE_TO_TCP_SEND -60
90 | #define ERROR_WIFI_NOT_CONNECTED -59
91 | #define SEND_FAILED_ARP_IN_PROCESS -58
92 | #define RECV_FAILED_SOCKET_INACTIVE -57
93 |
94 | //
95 | // Return the same error code to all socket
96 | // calls which fail due to socket's inactivity
97 | //
98 | #define ERROR_SOCKET_INACTIVE RECV_FAILED_SOCKET_INACTIVE
99 |
100 | //
101 | // TCP function error codes
102 | //
103 | #define TCP_ERROR -1
104 | #define TCP_TOO_LONG -2
105 | #define TCP_BAD_HEADER -3
106 | #define TCP_BAD_CSUM -4
107 | #define TCP_BAD_FCS -5
108 | #define TCP_NO_CONNECT -6
109 |
110 | //
111 | // UDP function error codes
112 | //
113 | #define UDP_ERROR -1
114 | #define UDP_TOO_LONG -2
115 | #define UDP_BAD_CSUM -4
116 | #define UDP_BAD_FCS -5
117 |
118 | //
119 | // Raw error codes
120 | //
121 | #define RAW_ERROR -1
122 | #define RAW_TOO_LONG -2
123 |
124 | //
125 | // SimpleLink error codes
126 | //
127 | #define SL_INVALID_INTERFACE -1
128 | #define SL_NO_MORE_DATA_TO_READ -2
129 | #define SL_OUT_OF_RESOURCES (-150)
130 | #define SL_NOT_ENOUGH_SPACE (-151)
131 | #define SL_INCORRECT_IF (-152)
132 | #define SL_NOTHING_TO_SEND (-153)
133 | #define SL_WILL_SEND_LATER \
134 | (100) // This is not an error - just an indication that we can't send data
135 | // now
136 | #define SL_TX_ALLOC_FAILED (-161)
137 |
138 | #define SL_INVALID_COMMAND_ARGUMENTS (-170)
139 |
140 | #ifdef __cplusplus
141 | }
142 | #endif /* __cplusplus */
143 |
144 | #endif /* __ERROR_CODES__ */
145 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/utility/host_driver_version.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | *
3 | * host_driver_version.h - CC3000 Host Driver Implementation.
4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 | *
6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
7 | * & Limor Fried for Adafruit Industries
8 | * This library works with the Adafruit CC3000 breakout
9 | * ----> https://www.adafruit.com/products/1469
10 | * Adafruit invests time and resources providing this open source code,
11 | * please support Adafruit and open-source hardware by purchasing
12 | * products from Adafruit!
13 | *
14 | * Redistribution and use in source and binary forms, with or without
15 | * modification, are permitted provided that the following conditions
16 | * are met:
17 | *
18 | * Redistributions of source code must retain the above copyright
19 | * notice, this list of conditions and the following disclaimer.
20 | *
21 | * Redistributions in binary form must reproduce the above copyright
22 | * notice, this list of conditions and the following disclaimer in the
23 | * documentation and/or other materials provided with the
24 | * distribution.
25 | *
26 | * Neither the name of Texas Instruments Incorporated nor the names of
27 | * its contributors may be used to endorse or promote products derived
28 | * from this software without specific prior written permission.
29 | *
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 | *
42 | *****************************************************************************/
43 | #ifndef __HOST_DRIVER_VERSION_H__
44 | #define __HOST_DRIVER_VERSION_H__
45 |
46 | #define DRIVER_VERSION_NUMBER 16
47 |
48 | #endif // __VERSION_H__
49 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/adafruit_CC3000_lib_fossa/utility/security.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | *
3 | * security.h - CC3000 Host Driver Implementation.
4 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 | *
6 | * Adapted for use with the Arduino/AVR by KTOWN (Kevin Townsend)
7 | * & Limor Fried for Adafruit Industries
8 | * This library works with the Adafruit CC3000 breakout
9 | * ----> https://www.adafruit.com/products/1469
10 | * Adafruit invests time and resources providing this open source code,
11 | * please support Adafruit and open-source hardware by purchasing
12 | * products from Adafruit!
13 | *
14 | * Redistribution and use in source and binary forms, with or without
15 | * modification, are permitted provided that the following conditions
16 | * are met:
17 | *
18 | * Redistributions of source code must retain the above copyright
19 | * notice, this list of conditions and the following disclaimer.
20 | *
21 | * Redistributions in binary form must reproduce the above copyright
22 | * notice, this list of conditions and the following disclaimer in the
23 | * documentation and/or other materials provided with the
24 | * distribution.
25 | *
26 | * Neither the name of Texas Instruments Incorporated nor the names of
27 | * its contributors may be used to endorse or promote products derived
28 | * from this software without specific prior written permission.
29 | *
30 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 | *
42 | *****************************************************************************/
43 | #ifndef __SECURITY__
44 | #define __SECURITY__
45 |
46 | #include "nvmem.h"
47 |
48 | //*****************************************************************************
49 | //
50 | // If building with a C++ compiler, make all of the definitions in this header
51 | // have a C binding.
52 | //
53 | //*****************************************************************************
54 | #ifdef __cplusplus
55 | extern "C" {
56 | #endif
57 |
58 | #define AES128_KEY_SIZE 16
59 |
60 | #ifndef CC3000_UNENCRYPTED_SMART_CONFIG
61 |
62 | //*****************************************************************************
63 | //
64 | //! aes_encrypt
65 | //!
66 | //! @param[in] key AES128 key of size 16 bytes
67 | //! @param[in\out] state 16 bytes of plain text and cipher text
68 | //!
69 | //! @return none
70 | //!
71 | //! @brief AES128 encryption:
72 | //! Given AES128 key and 16 bytes plain text, cipher text of 16 bytes
73 | //! is computed. The AES implementation is in mode ECB (Electronic
74 | //! Code Book).
75 | //!
76 | //!
77 | //*****************************************************************************
78 | extern void aes_encrypt(UINT8 *state, UINT8 *key);
79 |
80 | //*****************************************************************************
81 | //
82 | //! aes_decrypt
83 | //!
84 | //! @param[in] key AES128 key of size 16 bytes
85 | //! @param[in\out] state 16 bytes of cipher text and plain text
86 | //!
87 | //! @return none
88 | //!
89 | //! @brief AES128 decryption:
90 | //! Given AES128 key and 16 bytes cipher text, plain text of 16 bytes
91 | //! is computed The AES implementation is in mode ECB
92 | //! (Electronic Code Book).
93 | //!
94 | //!
95 | //*****************************************************************************
96 | extern void aes_decrypt(UINT8 *state, UINT8 *key);
97 |
98 | //*****************************************************************************
99 | //
100 | //! aes_read_key
101 | //!
102 | //! @param[out] key AES128 key of size 16 bytes
103 | //!
104 | //! @return on success 0, error otherwise.
105 | //!
106 | //! @brief Reads AES128 key from EEPROM
107 | //! Reads the AES128 key from fileID #12 in EEPROM
108 | //! returns an error if the key does not exist.
109 | //!
110 | //!
111 | //*****************************************************************************
112 | extern INT32 aes_read_key(UINT8 *key);
113 |
114 | //*****************************************************************************
115 | //
116 | //! aes_write_key
117 | //!
118 | //! @param[out] key AES128 key of size 16 bytes
119 | //!
120 | //! @return on success 0, error otherwise.
121 | //!
122 | //! @brief writes AES128 key from EEPROM
123 | //! Writes the AES128 key to fileID #12 in EEPROM
124 | //!
125 | //!
126 | //*****************************************************************************
127 | extern INT32 aes_write_key(UINT8 *key);
128 |
129 | #endif // CC3000_UNENCRYPTED_SMART_CONFIG
130 |
131 | #ifdef __cplusplus
132 | }
133 | #endif // __cplusplus
134 |
135 | #endif
136 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/avrsupport.cpp:
--------------------------------------------------------------------------------
1 | #include "avrsupport.h"
2 | /*
3 | * Copyright (c) 2015 Cesanta Software Limited
4 | * All rights reserved
5 | */
6 | #include
7 |
8 | void blink(int times, int ms) {
9 | static int inited = 0;
10 | int i;
11 |
12 | if (!inited) {
13 | DDRB |= 0x80;
14 | inited = 1;
15 | }
16 |
17 | for (i = 0; i < times; i++) {
18 | PORTB |= 0x80;
19 | delay(ms);
20 | PORTB &= 0x7F;
21 | delay(ms);
22 | }
23 | }
24 |
25 | extern unsigned int __heap_start;
26 | extern void* __brkval;
27 |
28 | struct __freelist {
29 | size_t sz;
30 | struct __freelist* nx;
31 | };
32 |
33 | extern struct __freelist* __flp;
34 |
35 | int get_freelistsize() {
36 | struct __freelist* current;
37 | int total = 0;
38 | for (current = __flp; current; current = current->nx) {
39 | total += 2;
40 | total += (int) current->sz;
41 | }
42 | return total;
43 | }
44 |
45 | int get_freememsize() {
46 | int free_memory;
47 | if ((int) __brkval == 0) {
48 | free_memory = ((int) &free_memory) - ((int) &__heap_start);
49 | } else {
50 | free_memory = ((int) &free_memory) - ((int) __brkval);
51 | free_memory += get_freelistsize();
52 | }
53 | return free_memory;
54 | }
55 | /*
56 | * Copyright (c) 2015 Cesanta Software Limited
57 | * All rights reserved
58 | */
59 |
60 | #include
61 | #include
62 |
63 | long long int to64(const char* str) {
64 | long long int res = 0;
65 | char negative = 0;
66 |
67 | while (isspace(*str)) str++;
68 |
69 | if (*str == '+') {
70 | str++;
71 | } else if (*str == '-') {
72 | negative = 1;
73 | str++;
74 | }
75 |
76 | while (*str >= '0' && *str <= '9') {
77 | res = res * 10 + (*str - '0');
78 | str++;
79 | }
80 |
81 | return negative ? -res : res;
82 | }
83 |
84 | char* strerror(int errnum) {
85 | /* TODO(alashkin): show real error message */
86 | const char frmstr[] = "Error: %d";
87 | static char retbuf[sizeof(frmstr) + 11];
88 |
89 | snprintf(retbuf, sizeof(retbuf), frmstr, errnum);
90 | return retbuf;
91 | }
92 |
93 | /*
94 | * Returns the number of seconds since the Arduino board
95 | * began running the current program.
96 | * So, this function
97 | * 1. doesn't support anything but NULL as a parameter
98 | * 2. suitable only to detect timeouts etc.
99 | * If time(NULL) is logged, result would be something
100 | * like "1970-01-01..." etc)
101 | */
102 |
103 | time_t time(time_t* timer) {
104 | return millis() / 1000;
105 | }
106 | /*
107 | * Copyright (c) 2015 Cesanta Software Limited
108 | * All rights reserved
109 | */
110 |
111 | #include
112 | #include
113 | #include
114 |
115 | #include
116 | #include
117 |
118 | #define ADAFRUIT_CC3000_IRQ 3
119 | #define ADAFRUIT_CC3000_VBAT 5
120 | #define ADAFRUIT_CC3000_CS 10
121 | #define DHCP_TIMEOUT 30
122 |
123 | static unsigned long aucDHCP = 14400;
124 | static unsigned long aucARP = 3600;
125 | static unsigned long aucKeepalive = 30;
126 | static unsigned long aucInactivity = 0;
127 |
128 | Adafruit_CC3000 cc3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ,
129 | ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER);
130 |
131 | int check_dhcp() {
132 | time_t finish_time = millis() + DHCP_TIMEOUT * 1000;
133 | while (!cc3000.checkDHCP() && millis() < finish_time) {
134 | delay(100);
135 | yield();
136 | }
137 |
138 | return cc3000.checkDHCP();
139 | }
140 |
141 | int avr_netinit(const char* wlan_ssid, const char* wlan_pwd, int wlan_security,
142 | uint32_t ip, uint32_t subnet_mask, uint32_t gateway,
143 | uint32_t dns) {
144 | init_sockets_buffer();
145 |
146 | if (!cc3000.begin()) {
147 | return -1;
148 | }
149 |
150 | if (!cc3000.connectToAP(wlan_ssid, wlan_pwd, wlan_security)) {
151 | return -1;
152 | }
153 |
154 | if (!check_dhcp()) {
155 | return -1;
156 | }
157 |
158 | uint32_t current_ip = 0, current_subnet_mask = 0, current_gw = 0,
159 | currend_dhcp = 0, current_dns = 0;
160 |
161 | if (!cc3000.getIPAddress(¤t_ip, ¤t_subnet_mask, ¤t_gw,
162 | ¤d_dhcp, ¤t_dns)) {
163 | return -1;
164 | }
165 |
166 | if (current_ip != ip || current_subnet_mask != subnet_mask ||
167 | current_gw != gateway || current_dns != dns) {
168 | if (!cc3000.setStaticIPAddress(ip, subnet_mask, gateway, dns)) {
169 | return -1;
170 | }
171 |
172 | /* Waiting while new address is really assigned */
173 | if (!check_dhcp()) {
174 | return -1;
175 | }
176 | }
177 |
178 | if (netapp_timeout_values(&aucDHCP, &aucARP, &aucKeepalive, &aucInactivity) !=
179 | 0) {
180 | return -1;
181 | }
182 |
183 | /* TODO(alashkin): power fix */
184 | delay(5000);
185 |
186 | return 0;
187 | }
188 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/avrsupport.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #ifndef AVRDEBUG_HEADER_INCLUDED
7 | #define AVRDEBUG_HEADER_INCLUDED
8 |
9 | #ifdef __cplusplus
10 | extern "C" {
11 | #endif
12 | /* Blinks ($times) times with ($ms) delay */
13 | void blink(int times, int ms);
14 |
15 | /* Returns free memory size */
16 | int get_freememsize();
17 |
18 | #if defined(AVR_ENABLE_DEBUG)
19 |
20 | #define DUMPINIT() Serial.begin(9600)
21 | #define DUMPSTR(msg) Serial.println(msg)
22 | #define DUMPDEC(num) Serial.println(num, DEC)
23 | #define DUMPFREEMEM() \
24 | Serial.print("Free mem: "); \
25 | Serial.println(get_freememsize())
26 |
27 | #define DUMPFUNCNAME() Serial.println(__func__)
28 |
29 | #define BLINK(t, m) blink(t, m);
30 |
31 | #else
32 |
33 | #define DUMPINIT()
34 | #define DUMPFUNCNAME()
35 | #define DUMPFREEMEM()
36 | #define BLINK(t, m)
37 | #define DUMPSTR(msg)
38 | #define DUMPDEC(num)
39 |
40 | #endif
41 |
42 | #ifdef __cplusplus
43 | }
44 | #endif
45 |
46 | #endif /* NS_AVRDEBUG_HEADER_INCLUDED */
47 | /*
48 | * Copyright (c) 2015 Cesanta Software Limited
49 | * All rights reserved
50 | */
51 |
52 | #ifndef AVRLIBC_COMPAT_HEADER_INCLUDED
53 | #define AVRLIBC_COMPAT_HEADER_INCLUDED
54 |
55 | #include
56 | #include
57 | #include
58 |
59 | /*
60 | * Some of this stuff breaks
61 | * Fossa o Arduino
62 | * TODO(alashkin): remove these defines when
63 | * some kind of AVR-build-test will be ready
64 | */
65 | #define NS_DISABLE_HTTP_DIGEST_AUTH
66 | #define NS_DISABLE_MQTT
67 | #define NS_DISABLE_MD5
68 | #define NS_DISABLE_JSON_RPC
69 | #define NS_DISABLE_SOCKETPAIR
70 | #define NS_DISABLE_SSI
71 | #define NS_DISABLE_POPEN
72 | #define NS_DISABLE_DIRECTORY_LISTING
73 | #define NS_DISABLE_DAV
74 | #define NS_DISABLE_DNS
75 | #define NS_DISABLE_RESOLVER
76 | #define NS_DISABLE_CGI
77 |
78 | #ifdef __cplusplus
79 | extern "C" {
80 | #endif
81 |
82 | /* fossa requires to64, so define it' instead of strtol & co */
83 | long long int to64(const char* str);
84 |
85 | char* strerror(int errnum);
86 |
87 | /* Time declaration & functions */
88 | typedef unsigned long time_t;
89 |
90 | #ifndef TIMEVAL
91 | struct timeval {
92 | uint32_t tv_sec;
93 | uint32_t tv_usec;
94 | };
95 | #define TIMEVAL
96 | #endif
97 |
98 | time_t time(time_t* timer);
99 |
100 | /* TODO(alashkin): add (at least) in-flash "files" operations */
101 |
102 | #define AVR_NOFS
103 | #define AVR_LIBC
104 |
105 | #ifdef __cplusplus
106 | }
107 | #endif
108 |
109 | #endif
110 |
111 | /*
112 | * Copyright (c) 2015 Cesanta Software Limited
113 | * All rights reserved
114 | */
115 |
116 | #ifndef CC3000UTILS_HEADER_INCLUDED
117 | #define CC3000UTILS_HEADER_INCLUDED
118 |
119 | #define WIFI_CC3000
120 |
121 | #ifdef __cplusplus
122 | extern "C" {
123 | #endif
124 |
125 | int avr_netinit(const char* wlan_ssid, const char* wlan_pwd, int wlan_security,
126 | uint32_t ip, uint32_t subnet_mask, uint32_t gateway,
127 | uint32_t dns);
128 |
129 | #include
130 | #include
131 |
132 | #define close(x) closesocket(x)
133 |
134 | #ifdef __cplusplus
135 | }
136 | #endif
137 |
138 | #endif
139 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/src/CC3000_utils.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include
11 | #include
12 |
13 | #define ADAFRUIT_CC3000_IRQ 3
14 | #define ADAFRUIT_CC3000_VBAT 5
15 | #define ADAFRUIT_CC3000_CS 10
16 | #define DHCP_TIMEOUT 30
17 |
18 | static unsigned long aucDHCP = 14400;
19 | static unsigned long aucARP = 3600;
20 | static unsigned long aucKeepalive = 30;
21 | static unsigned long aucInactivity = 0;
22 |
23 | Adafruit_CC3000 cc3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ,
24 | ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER);
25 |
26 | int check_dhcp() {
27 | time_t finish_time = millis() + DHCP_TIMEOUT * 1000;
28 | while (!cc3000.checkDHCP() && millis() < finish_time) {
29 | delay(100);
30 | yield();
31 | }
32 |
33 | return cc3000.checkDHCP();
34 | }
35 |
36 | int avr_netinit(const char* wlan_ssid, const char* wlan_pwd, int wlan_security,
37 | uint32_t ip, uint32_t subnet_mask, uint32_t gateway,
38 | uint32_t dns) {
39 | init_sockets_buffer();
40 |
41 | if (!cc3000.begin()) {
42 | return -1;
43 | }
44 |
45 | if (!cc3000.connectToAP(wlan_ssid, wlan_pwd, wlan_security)) {
46 | return -1;
47 | }
48 |
49 | if (!check_dhcp()) {
50 | return -1;
51 | }
52 |
53 | uint32_t current_ip = 0, current_subnet_mask = 0, current_gw = 0,
54 | currend_dhcp = 0, current_dns = 0;
55 |
56 | if (!cc3000.getIPAddress(¤t_ip, ¤t_subnet_mask, ¤t_gw,
57 | ¤d_dhcp, ¤t_dns)) {
58 | return -1;
59 | }
60 |
61 | if (current_ip != ip || current_subnet_mask != subnet_mask ||
62 | current_gw != gateway || current_dns != dns) {
63 | if (!cc3000.setStaticIPAddress(ip, subnet_mask, gateway, dns)) {
64 | return -1;
65 | }
66 |
67 | /* Waiting while new address is really assigned */
68 | if (!check_dhcp()) {
69 | return -1;
70 | }
71 | }
72 |
73 | if (netapp_timeout_values(&aucDHCP, &aucARP, &aucKeepalive, &aucInactivity) !=
74 | 0) {
75 | return -1;
76 | }
77 |
78 | /* TODO(alashkin): power fix */
79 | delay(5000);
80 |
81 | return 0;
82 | }
83 |
--------------------------------------------------------------------------------
/platforms/arduino_wifi_CC3000/src/CC3000_utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2015 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 | #ifndef CC3000UTILS_HEADER_INCLUDED
6 | #define CC3000UTILS_HEADER_INCLUDED
7 |
8 | #define WIFI_CC3000
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | int avr_netinit(const char* wlan_ssid, const char* wlan_pwd, int wlan_security,
15 | uint32_t ip, uint32_t subnet_mask, uint32_t gateway,
16 | uint32_t dns);
17 |
18 | #include
19 | #include
20 |
21 | #define close(x) closesocket(x)
22 |
23 | #ifdef __cplusplus
24 | }
25 | #endif
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/src/CPPLINT.cfg:
--------------------------------------------------------------------------------
1 | exclude_files=sha1\.c
2 |
--------------------------------------------------------------------------------
/src/Makefile:
--------------------------------------------------------------------------------
1 | include modules.mk
2 |
3 | all: ../fossa.c ../fossa.h
4 |
5 | ../fossa.h: Makefile modules.mk $(HEADERS)
6 | @echo "AMALGAMATING\tfossa.h"
7 | @echo "#ifdef __AVR__\n#include \"avrsupport.h\"\n#endif" > $@
8 | @cat $(HEADERS) | sed '/^#include "/d' >>$@
9 |
10 | ../fossa.c: Makefile internal.h modules.mk $(SOURCES)
11 | @echo "AMALGAMATING\tfossa.c"
12 | @(echo '#include "fossa.h"'; ../../tools/amalgam --srcdir src internal.h $(SOURCES)) >$@
13 |
--------------------------------------------------------------------------------
/src/common.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | * This software is dual-licensed: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License version 2 as
6 | * published by the Free Software Foundation. For the terms of this
7 | * license, see .
8 | *
9 | * You are free to use this software under the terms of the GNU General
10 | * Public License, but WITHOUT ANY WARRANTY; without even the implied
11 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | * See the GNU General Public License for more details.
13 | *
14 | * Alternatively, you can license this software under a commercial
15 | * license, as set out in .
16 | */
17 |
18 | #define NS_FOSSA_VERSION "2.0.0"
19 |
--------------------------------------------------------------------------------
/src/dns-server.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #ifdef NS_ENABLE_DNS_SERVER
7 |
8 | #include "internal.h"
9 |
10 | struct ns_dns_reply ns_dns_create_reply(struct mbuf *io,
11 | struct ns_dns_message *msg) {
12 | struct ns_dns_reply rep;
13 | rep.msg = msg;
14 | rep.io = io;
15 | rep.start = io->len;
16 |
17 | /* reply + recursion allowed */
18 | msg->flags |= 0x8080;
19 | ns_dns_copy_body(io, msg);
20 |
21 | msg->num_answers = 0;
22 | return rep;
23 | }
24 |
25 | int ns_dns_send_reply(struct ns_connection *nc, struct ns_dns_reply *r) {
26 | size_t sent = r->io->len - r->start;
27 | ns_dns_insert_header(r->io, r->start, r->msg);
28 | if (!(nc->flags & NSF_UDP)) {
29 | uint16_t len = htons(sent);
30 | mbuf_insert(r->io, r->start, &len, 2);
31 | }
32 |
33 | if (&nc->send_mbuf != r->io || nc->flags & NSF_UDP) {
34 | sent = ns_send(nc, r->io->buf + r->start, r->io->len - r->start);
35 | r->io->len = r->start;
36 | }
37 | return sent;
38 | }
39 |
40 | int ns_dns_reply_record(struct ns_dns_reply *reply,
41 | struct ns_dns_resource_record *question,
42 | const char *name, int rtype, int ttl, const void *rdata,
43 | size_t rdata_len) {
44 | struct ns_dns_message *msg = (struct ns_dns_message *) reply->msg;
45 | char rname[512];
46 | struct ns_dns_resource_record *ans = &msg->answers[msg->num_answers];
47 | if (msg->num_answers >= NS_MAX_DNS_ANSWERS) {
48 | return -1; /* LCOV_EXCL_LINE */
49 | }
50 |
51 | if (name == NULL) {
52 | name = rname;
53 | rname[511] = 0;
54 | ns_dns_uncompress_name(msg, &question->name, rname, sizeof(rname) - 1);
55 | }
56 |
57 | *ans = *question;
58 | ans->kind = NS_DNS_ANSWER;
59 | ans->rtype = rtype;
60 | ans->ttl = ttl;
61 |
62 | if (ns_dns_encode_record(reply->io, ans, name, strlen(name), rdata,
63 | rdata_len) == -1) {
64 | return -1; /* LCOV_EXCL_LINE */
65 | };
66 |
67 | msg->num_answers++;
68 | return 0;
69 | }
70 |
71 | #endif /* NS_ENABLE_DNS_SERVER */
72 |
--------------------------------------------------------------------------------
/src/dns-server.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | /*
7 | * === DNS server
8 | *
9 | * Disabled by default; enable with `-DNS_ENABLE_DNS_SERVER`.
10 | */
11 |
12 | #ifndef NS_DNS_SERVER_HEADER_DEFINED
13 | #define NS_DNS_SERVER_HEADER_DEFINED
14 |
15 | #ifdef NS_ENABLE_DNS_SERVER
16 |
17 | #include "dns.h"
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif /* __cplusplus */
22 |
23 | #define NS_DNS_SERVER_DEFAULT_TTL 3600
24 |
25 | struct ns_dns_reply {
26 | struct ns_dns_message *msg;
27 | struct mbuf *io;
28 | size_t start;
29 | };
30 |
31 | /*
32 | * Create a DNS reply.
33 | *
34 | * The reply will be based on an existing query message `msg`.
35 | * The query body will be appended to the output buffer.
36 | * "reply + recursion allowed" will be added to the message flags and
37 | * message's num_answers will be set to 0.
38 | *
39 | * Answer records can be appended with `ns_dns_send_reply` or by lower
40 | * level function defined in the DNS API.
41 | *
42 | * In order to send the reply use `ns_dns_send_reply`.
43 | * It's possible to use a connection's send buffer as reply buffers,
44 | * and it will work for both UDP and TCP connections.
45 | *
46 | * Example:
47 | *
48 | * [source,c]
49 | * -----
50 | * reply = ns_dns_create_reply(&nc->send_mbuf, msg);
51 | * for (i = 0; i < msg->num_questions; i++) {
52 | * rr = &msg->questions[i];
53 | * if (rr->rtype == NS_DNS_A_RECORD) {
54 | * ns_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);
55 | * }
56 | * }
57 | * ns_dns_send_reply(nc, &reply);
58 | * -----
59 | */
60 | struct ns_dns_reply ns_dns_create_reply(struct mbuf *, struct ns_dns_message *);
61 |
62 | /*
63 | * Append a DNS reply record to the IO buffer and to the DNS message.
64 | *
65 | * The message num_answers field will be incremented. It's caller's duty
66 | * to ensure num_answers is propertly initialized.
67 | *
68 | * Returns -1 on error.
69 | */
70 | int ns_dns_reply_record(struct ns_dns_reply *, struct ns_dns_resource_record *,
71 | const char *, int, int, const void *, size_t);
72 |
73 | /*
74 | * Send a DNS reply through a connection.
75 | *
76 | * The DNS data is stored in an IO buffer pointed by reply structure in `r`.
77 | * This function mutates the content of that buffer in order to ensure that
78 | * the DNS header reflects size and flags of the mssage, that might have been
79 | * updated either with `ns_dns_reply_record` or by direct manipulation of
80 | * `r->message`.
81 | *
82 | * Once sent, the IO buffer will be trimmed unless the reply IO buffer
83 | * is the connection's send buffer and the connection is not in UDP mode.
84 | */
85 | int ns_dns_send_reply(struct ns_connection *, struct ns_dns_reply *);
86 |
87 | #ifdef __cplusplus
88 | }
89 | #endif /* __cplusplus */
90 |
91 | #endif /* NS_ENABLE_DNS_SERVER */
92 | #endif /* NS_HTTP_HEADER_DEFINED */
93 |
--------------------------------------------------------------------------------
/src/dns.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | /*
7 | * === DNS
8 | */
9 |
10 | #ifndef NS_DNS_HEADER_DEFINED
11 | #define NS_DNS_HEADER_DEFINED
12 |
13 | #include "net.h"
14 |
15 | #ifdef __cplusplus
16 | extern "C" {
17 | #endif /* __cplusplus */
18 |
19 | #define NS_DNS_A_RECORD 0x01 /* Lookup IP address */
20 | #define NS_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */
21 | #define NS_DNS_AAAA_RECORD 0x1c /* Lookup IPv6 address */
22 | #define NS_DNS_MX_RECORD 0x0f /* Lookup mail server for domain */
23 |
24 | #define NS_MAX_DNS_QUESTIONS 32
25 | #define NS_MAX_DNS_ANSWERS 32
26 |
27 | #define NS_DNS_MESSAGE 100 /* High-level DNS message event */
28 |
29 | enum ns_dns_resource_record_kind {
30 | NS_DNS_INVALID_RECORD = 0,
31 | NS_DNS_QUESTION,
32 | NS_DNS_ANSWER
33 | };
34 |
35 | /* DNS resource record. */
36 | struct ns_dns_resource_record {
37 | struct ns_str name; /* buffer with compressed name */
38 | int rtype;
39 | int rclass;
40 | int ttl;
41 | enum ns_dns_resource_record_kind kind;
42 | struct ns_str rdata; /* protocol data (can be a compressed name) */
43 | };
44 |
45 | /* DNS message (request and response). */
46 | struct ns_dns_message {
47 | struct ns_str pkt; /* packet body */
48 | uint16_t flags;
49 | uint16_t transaction_id;
50 | int num_questions;
51 | int num_answers;
52 | struct ns_dns_resource_record questions[NS_MAX_DNS_QUESTIONS];
53 | struct ns_dns_resource_record answers[NS_MAX_DNS_ANSWERS];
54 | };
55 |
56 | struct ns_dns_resource_record *ns_dns_next_record(
57 | struct ns_dns_message *, int, struct ns_dns_resource_record *);
58 |
59 | /*
60 | * Parse the record data from a DNS resource record.
61 | *
62 | * - A: struct in_addr *ina
63 | * - AAAA: struct in6_addr *ina
64 | * - CNAME: char buffer
65 | *
66 | * Returns -1 on error.
67 | *
68 | * TODO(mkm): MX
69 | */
70 | int ns_dns_parse_record_data(struct ns_dns_message *,
71 | struct ns_dns_resource_record *, void *, size_t);
72 |
73 | /*
74 | * Send a DNS query to the remote end.
75 | */
76 | void ns_send_dns_query(struct ns_connection *, const char *, int);
77 |
78 | /*
79 | * Insert a DNS header to an IO buffer.
80 | *
81 | * Return number of bytes inserted.
82 | */
83 | int ns_dns_insert_header(struct mbuf *, size_t, struct ns_dns_message *);
84 |
85 | /*
86 | * Append already encoded body from an existing message.
87 | *
88 | * This is useful when generating a DNS reply message which includes
89 | * all question records.
90 | *
91 | * Return number of appened bytes.
92 | */
93 | int ns_dns_copy_body(struct mbuf *, struct ns_dns_message *);
94 |
95 | /*
96 | * Encode and append a DNS resource record to an IO buffer.
97 | *
98 | * The record metadata is taken from the `rr` parameter, while the name and data
99 | * are taken from the parameters, encoded in the appropriate format depending on
100 | * record type, and stored in the IO buffer. The encoded values might contain
101 | * offsets within the IO buffer. It's thus important that the IO buffer doesn't
102 | * get trimmed while a sequence of records are encoded while preparing a DNS
103 | *reply.
104 | *
105 | * This function doesn't update the `name` and `rdata` pointers in the `rr`
106 | *struct
107 | * because they might be invalidated as soon as the IO buffer grows again.
108 | *
109 | * Return the number of bytes appened or -1 in case of error.
110 | */
111 | int ns_dns_encode_record(struct mbuf *, struct ns_dns_resource_record *,
112 | const char *, size_t, const void *, size_t);
113 |
114 | /* Low-level: parses a DNS response. */
115 | int ns_parse_dns(const char *, int, struct ns_dns_message *);
116 |
117 | /*
118 | * Uncompress a DNS compressed name.
119 | *
120 | * The containing dns message is required because the compressed encoding
121 | * and reference suffixes present elsewhere in the packet.
122 | *
123 | * If name is less than `dst_len` characters long, the remainder
124 | * of `dst` is terminated with `\0' characters. Otherwise, `dst` is not
125 | *terminated.
126 | *
127 | * If `dst_len` is 0 `dst` can be NULL.
128 | * Return the uncompressed name length.
129 | */
130 | size_t ns_dns_uncompress_name(struct ns_dns_message *, struct ns_str *, char *,
131 | int);
132 |
133 | /*
134 | * Attach built-in DNS event handler to the given listening connection.
135 | *
136 | * DNS event handler parses incoming UDP packets, treating them as DNS
137 | * requests. If incoming packet gets successfully parsed by the DNS event
138 | * handler, a user event handler will receive `NS_DNS_REQUEST` event, with
139 | * `ev_data` pointing to the parsed `struct ns_dns_message`.
140 | *
141 | * See
142 | * https://github.com/cesanta/fossa/tree/master/examples/captive_dns_server[captive_dns_server]
143 | * example on how to handle DNS request and send DNS reply.
144 | */
145 | void ns_set_protocol_dns(struct ns_connection *);
146 |
147 | #ifdef __cplusplus
148 | }
149 | #endif /* __cplusplus */
150 | #endif /* NS_HTTP_HEADER_DEFINED */
151 |
--------------------------------------------------------------------------------
/src/internal.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #ifndef NS_INTERNAL_HEADER_INCLUDED
7 | #define NS_INTERNAL_HEADER_INCLUDED
8 |
9 | #ifndef NS_MALLOC
10 | #define NS_MALLOC malloc
11 | #endif
12 |
13 | #ifndef NS_CALLOC
14 | #define NS_CALLOC calloc
15 | #endif
16 |
17 | #ifndef NS_REALLOC
18 | #define NS_REALLOC realloc
19 | #endif
20 |
21 | #ifndef NS_FREE
22 | #define NS_FREE free
23 | #endif
24 |
25 | #ifndef MBUF_REALLOC
26 | #define MBUF_REALLOC NS_REALLOC
27 | #endif
28 |
29 | #ifndef MBUF_FREE
30 | #define MBUF_FREE NS_FREE
31 | #endif
32 |
33 | #define NS_SET_PTRPTR(_ptr, _v) \
34 | do { \
35 | if (_ptr) *(_ptr) = _v; \
36 | } while (0)
37 |
38 | #ifndef NS_INTERNAL
39 | #define NS_INTERNAL static
40 | #endif
41 |
42 | #if !defined(NS_MGR_EV_MGR) && defined(__linux__)
43 | #define NS_MGR_EV_MGR 1 /* epoll() */
44 | #endif
45 | #if !defined(NS_MGR_EV_MGR)
46 | #define NS_MGR_EV_MGR 0 /* select() */
47 | #endif
48 |
49 | #ifdef PICOTCP
50 | #define NO_LIBC
51 | #define NS_DISABLE_FILESYSTEM
52 | #define NS_DISABLE_POPEN
53 | #define NS_DISABLE_CGI
54 | #define NS_DISABLE_DIRECTORY_LISTING
55 | #define NS_DISABLE_SOCKETPAIR
56 | #define NS_DISABLE_PFS
57 | #endif
58 |
59 | #include "../fossa.h"
60 |
61 | /* internals that need to be accessible in unit tests */
62 | NS_INTERNAL struct ns_connection *ns_finish_connect(struct ns_connection *nc,
63 | int proto,
64 | union socket_address *sa,
65 | struct ns_add_sock_opts);
66 |
67 | NS_INTERNAL int ns_parse_address(const char *str, union socket_address *sa,
68 | int *proto, char *host, size_t host_len);
69 | NS_INTERNAL void ns_call(struct ns_connection *, int ev, void *ev_data);
70 | NS_INTERNAL void ns_forward(struct ns_connection *, struct ns_connection *);
71 | NS_INTERNAL void ns_add_conn(struct ns_mgr *mgr, struct ns_connection *c);
72 | NS_INTERNAL void ns_remove_conn(struct ns_connection *c);
73 |
74 | #ifndef NS_DISABLE_FILESYSTEM
75 | NS_INTERNAL int find_index_file(char *, size_t, const char *, ns_stat_t *);
76 | #endif
77 |
78 | #ifdef _WIN32
79 | void to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len);
80 | #endif
81 |
82 | /*
83 | * Reassemble the content of the buffer (buf, blen) which should be
84 | * in the HTTP chunked encoding, by collapsing data chunks to the
85 | * beginning of the buffer.
86 | *
87 | * If chunks get reassembled, modify hm->body to point to the reassembled
88 | * body and fire NS_HTTP_CHUNK event. If handler sets NSF_DELETE_CHUNK
89 | * in nc->flags, delete reassembled body from the mbuf.
90 | *
91 | * Return reassembled body size.
92 | */
93 | NS_INTERNAL size_t ns_handle_chunked(struct ns_connection *nc,
94 | struct http_message *hm, char *buf,
95 | size_t blen);
96 |
97 | /* Forward declarations for testing. */
98 | extern void *(*test_malloc)(size_t);
99 | extern void *(*test_calloc)(size_t, size_t);
100 |
101 | #endif /* NS_INTERNAL_HEADER_INCLUDED */
102 |
--------------------------------------------------------------------------------
/src/json-rpc.c:
--------------------------------------------------------------------------------
1 | /* Copyright (c) 2014 Cesanta Software Limited */
2 | /* All rights reserved */
3 |
4 | #ifndef NS_DISABLE_JSON_RPC
5 |
6 | #include "internal.h"
7 |
8 | int ns_rpc_create_reply(char *buf, int len, const struct ns_rpc_request *req,
9 | const char *result_fmt, ...) {
10 | static const struct json_token null_tok = {"null", 4, 0, JSON_TYPE_NULL};
11 | const struct json_token *id = req->id == NULL ? &null_tok : req->id;
12 | va_list ap;
13 | int n = 0;
14 |
15 | n += json_emit(buf + n, len - n, "{s:s,s:", "jsonrpc", "2.0", "id");
16 | if (id->type == JSON_TYPE_STRING) {
17 | n += json_emit_quoted_str(buf + n, len - n, id->ptr, id->len);
18 | } else {
19 | n += json_emit_unquoted_str(buf + n, len - n, id->ptr, id->len);
20 | }
21 | n += json_emit(buf + n, len - n, ",s:", "result");
22 |
23 | va_start(ap, result_fmt);
24 | n += json_emit_va(buf + n, len - n, result_fmt, ap);
25 | va_end(ap);
26 |
27 | n += json_emit(buf + n, len - n, "}");
28 |
29 | return n;
30 | }
31 |
32 | int ns_rpc_create_request(char *buf, int len, const char *method,
33 | const char *id, const char *params_fmt, ...) {
34 | va_list ap;
35 | int n = 0;
36 |
37 | n += json_emit(buf + n, len - n, "{s:s,s:s,s:s,s:", "jsonrpc", "2.0", "id",
38 | id, "method", method, "params");
39 | va_start(ap, params_fmt);
40 | n += json_emit_va(buf + n, len - n, params_fmt, ap);
41 | va_end(ap);
42 |
43 | n += json_emit(buf + n, len - n, "}");
44 |
45 | return n;
46 | }
47 |
48 | int ns_rpc_create_error(char *buf, int len, struct ns_rpc_request *req,
49 | int code, const char *message, const char *fmt, ...) {
50 | va_list ap;
51 | int n = 0;
52 |
53 | n += json_emit(buf + n, len - n, "{s:s,s:V,s:{s:i,s:s,s:", "jsonrpc", "2.0",
54 | "id", req->id == NULL ? "null" : req->id->ptr,
55 | req->id == NULL ? 4 : req->id->len, "error", "code", code,
56 | "message", message, "data");
57 | va_start(ap, fmt);
58 | n += json_emit_va(buf + n, len - n, fmt, ap);
59 | va_end(ap);
60 |
61 | n += json_emit(buf + n, len - n, "}}");
62 |
63 | return n;
64 | }
65 |
66 | int ns_rpc_create_std_error(char *buf, int len, struct ns_rpc_request *req,
67 | int code) {
68 | const char *message = NULL;
69 |
70 | switch (code) {
71 | case JSON_RPC_PARSE_ERROR:
72 | message = "parse error";
73 | break;
74 | case JSON_RPC_INVALID_REQUEST_ERROR:
75 | message = "invalid request";
76 | break;
77 | case JSON_RPC_METHOD_NOT_FOUND_ERROR:
78 | message = "method not found";
79 | break;
80 | case JSON_RPC_INVALID_PARAMS_ERROR:
81 | message = "invalid parameters";
82 | break;
83 | case JSON_RPC_SERVER_ERROR:
84 | message = "server error";
85 | break;
86 | default:
87 | message = "unspecified error";
88 | break;
89 | }
90 |
91 | return ns_rpc_create_error(buf, len, req, code, message, "N");
92 | }
93 |
94 | int ns_rpc_dispatch(const char *buf, int len, char *dst, int dst_len,
95 | const char **methods, ns_rpc_handler_t *handlers) {
96 | struct json_token tokens[200];
97 | struct ns_rpc_request req;
98 | int i, n;
99 |
100 | memset(&req, 0, sizeof(req));
101 | n = parse_json(buf, len, tokens, sizeof(tokens) / sizeof(tokens[0]));
102 | if (n <= 0) {
103 | int err_code = (n == JSON_STRING_INVALID) ? JSON_RPC_PARSE_ERROR
104 | : JSON_RPC_SERVER_ERROR;
105 | return ns_rpc_create_std_error(dst, dst_len, &req, err_code);
106 | }
107 |
108 | req.message = tokens;
109 | req.id = find_json_token(tokens, "id");
110 | req.method = find_json_token(tokens, "method");
111 | req.params = find_json_token(tokens, "params");
112 |
113 | if (req.id == NULL || req.method == NULL) {
114 | return ns_rpc_create_std_error(dst, dst_len, &req,
115 | JSON_RPC_INVALID_REQUEST_ERROR);
116 | }
117 |
118 | for (i = 0; methods[i] != NULL; i++) {
119 | int mlen = strlen(methods[i]);
120 | if (mlen == req.method->len &&
121 | memcmp(methods[i], req.method->ptr, mlen) == 0)
122 | break;
123 | }
124 |
125 | if (methods[i] == NULL) {
126 | return ns_rpc_create_std_error(dst, dst_len, &req,
127 | JSON_RPC_METHOD_NOT_FOUND_ERROR);
128 | }
129 |
130 | return handlers[i](dst, dst_len, &req);
131 | }
132 |
133 | int ns_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
134 | int max_toks, struct ns_rpc_reply *rep,
135 | struct ns_rpc_error *er) {
136 | int n = parse_json(buf, len, toks, max_toks);
137 |
138 | memset(rep, 0, sizeof(*rep));
139 | memset(er, 0, sizeof(*er));
140 |
141 | if (n > 0) {
142 | if ((rep->result = find_json_token(toks, "result")) != NULL) {
143 | rep->message = toks;
144 | rep->id = find_json_token(toks, "id");
145 | } else {
146 | er->message = toks;
147 | er->id = find_json_token(toks, "id");
148 | er->error_code = find_json_token(toks, "error.code");
149 | er->error_message = find_json_token(toks, "error.message");
150 | er->error_data = find_json_token(toks, "error.data");
151 | }
152 | }
153 | return n;
154 | }
155 |
156 | #endif /* NS_DISABLE_JSON_RPC */
157 |
--------------------------------------------------------------------------------
/src/json-rpc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | /*
7 | * === JSON-RPC
8 | */
9 |
10 | #ifndef NS_JSON_RPC_HEADER_DEFINED
11 | #define NS_JSON_RPC_HEADER_DEFINED
12 |
13 | #ifdef __cplusplus
14 | extern "C" {
15 | #endif /* __cplusplus */
16 |
17 | /* JSON-RPC request */
18 | struct ns_rpc_request {
19 | struct json_token *message; /* Whole RPC message */
20 | struct json_token *id; /* Message ID */
21 | struct json_token *method; /* Method name */
22 | struct json_token *params; /* Method params */
23 | };
24 |
25 | /* JSON-RPC response */
26 | struct ns_rpc_reply {
27 | struct json_token *message; /* Whole RPC message */
28 | struct json_token *id; /* Message ID */
29 | struct json_token *result; /* Remote call result */
30 | };
31 |
32 | /* JSON-RPC error */
33 | struct ns_rpc_error {
34 | struct json_token *message; /* Whole RPC message */
35 | struct json_token *id; /* Message ID */
36 | struct json_token *error_code; /* error.code */
37 | struct json_token *error_message; /* error.message */
38 | struct json_token *error_data; /* error.data, can be NULL */
39 | };
40 |
41 | /*
42 | * Parse JSON-RPC reply contained in `buf`, `len` into JSON tokens array
43 | * `toks`, `max_toks`. If buffer contains valid reply, `reply` structure is
44 | * populated. The result of RPC call is located in `reply.result`. On error,
45 | * `error` structure is populated. Returns: the result of calling
46 | * `parse_json(buf, len, toks, max_toks)`:
47 | *
48 | * On success, an offset inside `json_string` is returned
49 | * where parsing has finished. On failure, a negative number is
50 | * returned, one of:
51 | *
52 | * - #define JSON_STRING_INVALID -1
53 | * - #define JSON_STRING_INCOMPLETE -2
54 | * - #define JSON_TOKEN_ARRAY_TOO_SMALL -3
55 | */
56 | int ns_rpc_parse_reply(const char *buf, int len, struct json_token *toks,
57 | int max_toks, struct ns_rpc_reply *,
58 | struct ns_rpc_error *);
59 |
60 | /*
61 | * Create JSON-RPC request in a given buffer.
62 | *
63 | * Return length of the request, which
64 | * can be larger then `len` that indicates an overflow.
65 | * `params_fmt` format string should conform to `json_emit()` API,
66 | * see https://github.com/cesanta/frozen
67 | */
68 | int ns_rpc_create_request(char *buf, int len, const char *method,
69 | const char *id, const char *params_fmt, ...);
70 |
71 | /*
72 | * Create JSON-RPC reply in a given buffer.
73 | *
74 | * Return length of the reply, which
75 | * can be larger then `len` that indicates an overflow.
76 | * `result_fmt` format string should conform to `json_emit()` API,
77 | * see https://github.com/cesanta/frozen
78 | */
79 | int ns_rpc_create_reply(char *buf, int len, const struct ns_rpc_request *req,
80 | const char *result_fmt, ...);
81 |
82 | /*
83 | * Create JSON-RPC error reply in a given buffer.
84 | *
85 | * Return length of the error, which
86 | * can be larger then `len` that indicates an overflow.
87 | * `fmt` format string should conform to `json_emit()` API,
88 | * see https://github.com/cesanta/frozen
89 | */
90 | int ns_rpc_create_error(char *buf, int len, struct ns_rpc_request *req,
91 | int code, const char *message, const char *fmt, ...);
92 |
93 | /* JSON-RPC standard error codes */
94 | #define JSON_RPC_PARSE_ERROR (-32700)
95 | #define JSON_RPC_INVALID_REQUEST_ERROR (-32600)
96 | #define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)
97 | #define JSON_RPC_INVALID_PARAMS_ERROR (-32602)
98 | #define JSON_RPC_INTERNAL_ERROR (-32603)
99 | #define JSON_RPC_SERVER_ERROR (-32000)
100 |
101 | /*
102 | * Create JSON-RPC error in a given buffer.
103 | *
104 | * Return length of the error, which
105 | * can be larger then `len` that indicates an overflow. See
106 | * JSON_RPC_*_ERROR definitions for standard error values:
107 | *
108 | * - #define JSON_RPC_PARSE_ERROR (-32700)
109 | * - #define JSON_RPC_INVALID_REQUEST_ERROR (-32600)
110 | * - #define JSON_RPC_METHOD_NOT_FOUND_ERROR (-32601)
111 | * - #define JSON_RPC_INVALID_PARAMS_ERROR (-32602)
112 | * - #define JSON_RPC_INTERNAL_ERROR (-32603)
113 | * - #define JSON_RPC_SERVER_ERROR (-32000)
114 | */
115 | int ns_rpc_create_std_error(char *, int, struct ns_rpc_request *, int code);
116 |
117 | typedef int (*ns_rpc_handler_t)(char *buf, int len, struct ns_rpc_request *);
118 |
119 | /*
120 | * Dispatches a JSON-RPC request.
121 | *
122 | * Parses JSON-RPC request contained in `buf`, `len`.
123 | * Then, dispatches the request to the correct handler method.
124 | * Valid method names should be specified in NULL
125 | * terminated array `methods`, and corresponding handlers in `handlers`.
126 | * Result is put in `dst`, `dst_len`. Return: length of the result, which
127 | * can be larger then `dst_len` that indicates an overflow.
128 | * Overflown bytes are not written to the buffer.
129 | * If method is not found, an error is automatically generated.
130 | */
131 | int ns_rpc_dispatch(const char *buf, int, char *dst, int dst_len,
132 | const char **methods, ns_rpc_handler_t *handlers);
133 |
134 | #ifdef __cplusplus
135 | }
136 | #endif /* __cplusplus */
137 | #endif /* NS_JSON_RPC_HEADER_DEFINED */
138 |
--------------------------------------------------------------------------------
/src/modules.mk:
--------------------------------------------------------------------------------
1 | COMMON = ../../common
2 | FROZEN = ../deps/frozen
3 |
4 | HEADERS = common.h \
5 | $(COMMON)/osdep.h \
6 | $(COMMON)/mbuf.h \
7 | $(COMMON)/sha1.h \
8 | $(COMMON)/md5.h \
9 | $(COMMON)/base64.h \
10 | $(COMMON)/str_util.h \
11 | $(FROZEN)/frozen.h \
12 | net.h \
13 | util.h \
14 | http.h \
15 | json-rpc.h \
16 | mqtt.h \
17 | mqtt-broker.h \
18 | dns.h \
19 | dns-server.h \
20 | resolv.h \
21 | coap.h
22 |
23 | SOURCES = $(COMMON)/mbuf.c \
24 | $(COMMON)/sha1.c \
25 | $(COMMON)/md5.c \
26 | $(COMMON)/base64.c \
27 | $(COMMON)/str_util.c \
28 | $(COMMON)/dirent.c \
29 | $(FROZEN)/frozen.c \
30 | net.c \
31 | multithreading.c \
32 | http.c \
33 | util.c \
34 | json-rpc.c \
35 | mqtt.c \
36 | mqtt-broker.c \
37 | dns.c \
38 | dns-server.c \
39 | resolv.c \
40 | coap.c
41 |
--------------------------------------------------------------------------------
/src/mqtt-broker.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | * This software is dual-licensed: you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License version 2 as
6 | * published by the Free Software Foundation. For the terms of this
7 | * license, see .
8 | *
9 | * You are free to use this software under the terms of the GNU General
10 | * Public License, but WITHOUT ANY WARRANTY; without even the implied
11 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 | * See the GNU General Public License for more details.
13 | *
14 | * Alternatively, you can license this software under a commercial
15 | * license, as set out in .
16 | */
17 |
18 | /*
19 | * === MQTT Broker
20 | */
21 |
22 | #ifndef NS_MQTT_BROKER_HEADER_INCLUDED
23 | #define NS_MQTT_BROKER_HEADER_INCLUDED
24 |
25 | #ifdef NS_ENABLE_MQTT_BROKER
26 |
27 | #include "mqtt.h"
28 |
29 | #ifdef __cplusplus
30 | extern "C" {
31 | #endif /* __cplusplus */
32 |
33 | #define NS_MQTT_MAX_SESSION_SUBSCRIPTIONS 512;
34 |
35 | struct ns_mqtt_broker;
36 |
37 | /* MQTT session (Broker side). */
38 | struct ns_mqtt_session {
39 | struct ns_mqtt_broker *brk; /* Broker */
40 | struct ns_mqtt_session *next, *prev; /* ns_mqtt_broker::sessions linkage */
41 | struct ns_connection *nc; /* Connection with the client */
42 | size_t num_subscriptions; /* Size of `subscriptions` array */
43 | struct ns_mqtt_topic_expression *subscriptions;
44 | void *user_data; /* User data */
45 | };
46 |
47 | /* MQTT broker. */
48 | struct ns_mqtt_broker {
49 | struct ns_mqtt_session *sessions; /* Session list */
50 | void *user_data; /* User data */
51 | };
52 |
53 | /* Initialize a MQTT broker. */
54 | void ns_mqtt_broker_init(struct ns_mqtt_broker *, void *);
55 |
56 | /*
57 | * Process a MQTT broker message.
58 | *
59 | * Listening connection expects a pointer to an initialized `ns_mqtt_broker`
60 | * structure in the `user_data` field.
61 | *
62 | * Basic usage:
63 | *
64 | * [source,c]
65 | * -----
66 | * ns_mqtt_broker_init(&brk, NULL);
67 | *
68 | * if ((nc = ns_bind(&mgr, address, ns_mqtt_broker)) == NULL) {
69 | * // fail;
70 | * }
71 | * nc->user_data = &brk;
72 | * -----
73 | *
74 | * New incoming connections will receive a `ns_mqtt_session` structure
75 | * in the connection `user_data`. The original `user_data` will be stored
76 | * in the `user_data` field of the session structure. This allows the user
77 | * handler to store user data before `ns_mqtt_broker` creates the session.
78 | *
79 | * Since only the NS_ACCEPT message is processed by the listening socket,
80 | * for most events the `user_data` will thus point to a `ns_mqtt_session`.
81 | */
82 | void ns_mqtt_broker(struct ns_connection *, int, void *);
83 |
84 | /*
85 | * Iterate over all mqtt sessions connections. Example:
86 | *
87 | * struct ns_mqtt_session *s;
88 | * for (s = ns_mqtt_next(brk, NULL); s != NULL; s = ns_mqtt_next(brk, s)) {
89 | * // Do something
90 | * }
91 | */
92 | struct ns_mqtt_session *ns_mqtt_next(struct ns_mqtt_broker *,
93 | struct ns_mqtt_session *);
94 |
95 | #ifdef __cplusplus
96 | }
97 | #endif /* __cplusplus */
98 |
99 | #endif /* NS_ENABLE_MQTT_BROKER */
100 | #endif /* NS_MQTT_HEADER_INCLUDED */
101 |
--------------------------------------------------------------------------------
/src/multithreading.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | #include "internal.h"
7 |
8 | #ifdef NS_ENABLE_THREADS
9 |
10 | static void multithreaded_ev_handler(struct ns_connection *c, int ev, void *p);
11 |
12 | /*
13 | * This thread function executes user event handler.
14 | * It runs an event manager that has only one connection, until that
15 | * connection is alive.
16 | */
17 | static void *per_connection_thread_function(void *param) {
18 | struct ns_connection *c = (struct ns_connection *) param;
19 | struct ns_mgr m;
20 |
21 | ns_mgr_init(&m, NULL);
22 | ns_add_conn(&m, c);
23 | while (m.active_connections != NULL) {
24 | ns_mgr_poll(&m, 1000);
25 | }
26 | ns_mgr_free(&m);
27 |
28 | return param;
29 | }
30 |
31 | static void link_conns(struct ns_connection *c1, struct ns_connection *c2) {
32 | c1->priv_2 = c2;
33 | c2->priv_2 = c1;
34 | }
35 |
36 | static void unlink_conns(struct ns_connection *c) {
37 | struct ns_connection *peer = (struct ns_connection *) c->priv_2;
38 | if (peer != NULL) {
39 | peer->flags |= NSF_SEND_AND_CLOSE;
40 | peer->priv_2 = NULL;
41 | }
42 | c->priv_2 = NULL;
43 | }
44 |
45 | static void forwarder_ev_handler(struct ns_connection *c, int ev, void *p) {
46 | (void) p;
47 | if (ev == NS_RECV && c->priv_2) {
48 | ns_forward(c, c->priv_2);
49 | } else if (ev == NS_CLOSE) {
50 | unlink_conns(c);
51 | }
52 | }
53 |
54 | static void spawn_handling_thread(struct ns_connection *nc) {
55 | struct ns_mgr dummy = {};
56 | sock_t sp[2];
57 | struct ns_connection *c[2];
58 |
59 | /*
60 | * Create a socket pair, and wrap each socket into the connection with
61 | * dummy event manager.
62 | * c[0] stays in this thread, c[1] goes to another thread.
63 | */
64 | ns_socketpair(sp, SOCK_STREAM);
65 | c[0] = ns_add_sock(&dummy, sp[0], forwarder_ev_handler);
66 | c[1] = ns_add_sock(&dummy, sp[1], nc->listener->priv_1);
67 |
68 | /* Interlink client connection with c[0] */
69 | link_conns(c[0], nc);
70 |
71 | /*
72 | * Switch c[0] manager from the dummy one to the real one. c[1] manager
73 | * will be set in another thread, allocated on stack of that thread.
74 | */
75 | ns_add_conn(nc->mgr, c[0]);
76 |
77 | /*
78 | * Dress c[1] as nc.
79 | * TODO(lsm): code in accept_conn() looks similar. Refactor.
80 | */
81 | c[1]->listener = nc->listener;
82 | c[1]->proto_handler = nc->proto_handler;
83 | c[1]->proto_data = nc->proto_data;
84 | c[1]->user_data = nc->user_data;
85 |
86 | ns_start_thread(per_connection_thread_function, c[1]);
87 | }
88 |
89 | static void multithreaded_ev_handler(struct ns_connection *c, int ev, void *p) {
90 | (void) p;
91 | if (ev == NS_ACCEPT) {
92 | spawn_handling_thread(c);
93 | c->handler = forwarder_ev_handler;
94 | }
95 | }
96 |
97 | void ns_enable_multithreading(struct ns_connection *nc) {
98 | /* Wrap user event handler into our multithreaded_ev_handler */
99 | nc->priv_1 = nc->handler;
100 | nc->handler = multithreaded_ev_handler;
101 | }
102 | #endif
103 |
--------------------------------------------------------------------------------
/src/resolv.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014 Cesanta Software Limited
3 | * All rights reserved
4 | */
5 |
6 | /*
7 | * === Asynchronouns DNS resolver
8 | */
9 |
10 | #ifndef NS_RESOLV_HEADER_DEFINED
11 | #define NS_RESOLV_HEADER_DEFINED
12 |
13 | #include "dns.h"
14 |
15 | #ifdef __cplusplus
16 | extern "C" {
17 | #endif /* __cplusplus */
18 |
19 | typedef void (*ns_resolve_callback_t)(struct ns_dns_message *, void *);
20 |
21 | /* Options for `ns_resolve_async_opt`. */
22 | struct ns_resolve_async_opts {
23 | const char *nameserver_url;
24 | int max_retries; /* defaults to 2 if zero */
25 | int timeout; /* in seconds; defaults to 5 if zero */
26 | int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */
27 | int only_literal; /* only resolves literal addrs; sync cb invocation */
28 | };
29 |
30 | /* See `ns_resolve_async_opt()` */
31 | int ns_resolve_async(struct ns_mgr *, const char *, int, ns_resolve_callback_t,
32 | void *data);
33 |
34 | /*
35 | * Resolved a DNS name asynchronously.
36 | *
37 | * Upon successful resolution, the user callback will be invoked
38 | * with the full DNS response message and a pointer to the user's
39 | * context `data`.
40 | *
41 | * In case of timeout while performing the resolution the callback
42 | * will receive a NULL `msg`.
43 | *
44 | * The DNS answers can be extracted with `ns_next_record` and
45 | * `ns_dns_parse_record_data`:
46 | *
47 | * [source,c]
48 | * ----
49 | * struct in_addr ina;
50 | * struct ns_dns_resource_record *rr = ns_next_record(msg, NS_DNS_A_RECORD,
51 | * NULL);
52 | * ns_dns_parse_record_data(msg, rr, &ina, sizeof(ina));
53 | * ----
54 | */
55 | int ns_resolve_async_opt(struct ns_mgr *, const char *, int,
56 | ns_resolve_callback_t, void *data,
57 | struct ns_resolve_async_opts opts);
58 |
59 | /*
60 | * Resolve a name from `/etc/hosts`.
61 | *
62 | * Returns 0 on success, -1 on failure.
63 | */
64 | int ns_resolve_from_hosts_file(const char *host, union socket_address *usa);
65 |
66 | #ifdef __cplusplus
67 | }
68 | #endif /* __cplusplus */
69 | #endif /* NS_RESOLV_HEADER_DEFINED */
70 |
--------------------------------------------------------------------------------
/test/Makefile:
--------------------------------------------------------------------------------
1 | SOURCES=unit_test.c test_util.c ../fossa.c
2 | CFLAGS = -W -Wall -I../.. -pthread -DNS_ENABLE_COAP -DNS_ENABLE_IPV6 -DNS_ENABLE_THREADS -DNS_ENABLE_MQTT_BROKER -DNS_ENABLE_DNS_SERVER \
3 | -DNS_INTERNAL="" -DNS_MODULE_LINES -include unit_test.h -DNS_MALLOC=test_malloc -DNS_CALLOC=test_calloc -lssl $(CFLAGS_EXTRA)
4 |
5 | all: test
6 |
7 | unit_test: $(SOURCES) ../fossa.h
8 | @$(CC) $(SOURCES) -o $@ $(CFLAGS)
9 |
10 | test: unit_test
11 | @MallocLogFile=/dev/null ./unit_test $(TEST_FILTER)
12 |
--------------------------------------------------------------------------------
/test/ca.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpAIBAAKCAQEAv3/TSSi5hZDwMKG43eqe+GzR1lRMXVYt9I1Mr987v1DT99xR
3 | Dcpfo/3aj6B/V/G67oPz+zbVZN/ZPvvA1Z82T7ixcBFsGIXgEWzxUm1UCUf51ftl
4 | MlOaf24cdyegi0y8hRdkWLoC7w0vuMfrgR6cmpbI2LSDSMaXXX2qDoofQsFUYaJN
5 | Nn3uqRK0ixs/jzbzbAT9q2BWYwySUX4VEgADpmi0FyANDjEhmdktxQW9l6IGGzF8
6 | M9mA053hIgZwo+9qf9X3nfNUTWMvisMQtxm0mRYgvD53Oix08VLs6bodNTVOLQoc
7 | H0uH3CTs+H3Z0CkcZaAJe/kwCLFhls9ee3M0nQIDAQABAoIBAQCsADPWUi3QOg6C
8 | n79cE5AVsigHSlAMxYshTIjErs0LWZ4J0mk66bpdoXTd7Fp0szojYYGS8f1ZTXXj
9 | jFv3g7lUgZ9d+UgN/rDy9dcLIgeJDozoFZUfTthF/LC0lXMtqw7ou8n1p51a+Y0T
10 | ev2cS9J9R1G+0uPYSgdKgcRsqsLJQS4fu5CAk9d0aeTTl009uxcn9yfTUjwOaR5J
11 | PuNmunAEvhE/DGSkt5oNXo7t8Q2L3mYSM0MwKdDFqoQdZAV6TMTv22Mjb6SxOOnJ
12 | r5gNK2BmM6oNPWvzY0PoI0LcLgFNDWIMqIq4mg73MdzszakaNRDlOYtLAuKbTF3Q
13 | SDq8OkZBAoGBAOn6B5jBxSa+5GcIIeGqtiRhDMExyblt3Gk2gaw6UIZpvVDXPWWm
14 | r0tkGJrYecmqesN7DGmmdkyx8KONF+yzYLxSsIEGNesvVYe6PXTDZYYI57As4Z4W
15 | DFlCDt2FaKuMXxyOlUCiXg94z8IJBJ2ldCmmG34gBSvuFe6V5x4XE3crAoGBANGG
16 | P7AWw6uygfjog6B2dFT6n+9UhpyJlqwfPi5eD9V5JXtWlH6xWi3dRfuYAIafg95I
17 | W8/OZGHrj44gNCgYjvZHud+H3NPJPZ7lftoay5KeShBAa/pCd67OMxp1SvvONYcp
18 | 7TSwm5s+hOJvQOpw2wg0cXnfrxGKpGLOFaRddp9XAoGAFdeXefUs2G8dl1i1AQIU
19 | utSsgiSJtlvBJblG5bMT7VhVqgRN4P1sg9c2TM5EoETf7PvBruMxS/uYgUwcnaYp
20 | M6tser7/rZLfoyoJrqrHAXo3VsT50u4v/O0jwh5AJTOXdW0CFeSSb1NR4cVBvw3B
21 | CFpPWrjWgsFZHsqzpqV01b0CgYEAkDft4pDowmgumlvBLlQaotuX9q6hsWHrOjKP
22 | JG9OSswGhq0DrWj5/5PNNe5cfk2SARChUZpo8hWoTFXSUL8GuHKKeFgWIhjkt1iU
23 | RiAne5ZEuIb/S9UweDwqZM3TfRtlMNIlGh1uHh+cbBfUAQsJWM5wRUk4QcTCfdgI
24 | gYhrvCUCgYBB6u8Q49RjrTBxWK8bcZOjVhYNrd3xrCunFVMt2QAXGGrRaXpqUMnp
25 | xNUmGe9vGux+s0TRguZcLEX3vX+wFyBfFKwZY9hSU7PFY/da8echpu37JasKvAov
26 | 5+5XWI5RgF+SFVk+Q7St2BlSJa/vBAH8vtrX9Dt/hN/VSo2mAPAyMQ==
27 | -----END RSA PRIVATE KEY-----
28 | -----BEGIN CERTIFICATE-----
29 | MIIDjjCCAnagAwIBAgIJAIOEuwkahzkOMA0GCSqGSIb3DQEBBQUAMDgxCzAJBgNV
30 | BAMTAm5zMQswCQYDVQQKEwJuczELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1Ymxp
31 | bjAeFw0xNDA4MzAxOTA3NDNaFw0yNDA4MjcxOTA3NDNaMDgxCzAJBgNVBAMTAm5z
32 | MQswCQYDVQQKEwJuczELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpbjCCASIw
33 | DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9/00kouYWQ8DChuN3qnvhs0dZU
34 | TF1WLfSNTK/fO79Q0/fcUQ3KX6P92o+gf1fxuu6D8/s21WTf2T77wNWfNk+4sXAR
35 | bBiF4BFs8VJtVAlH+dX7ZTJTmn9uHHcnoItMvIUXZFi6Au8NL7jH64EenJqWyNi0
36 | g0jGl119qg6KH0LBVGGiTTZ97qkStIsbP48282wE/atgVmMMklF+FRIAA6ZotBcg
37 | DQ4xIZnZLcUFvZeiBhsxfDPZgNOd4SIGcKPvan/V953zVE1jL4rDELcZtJkWILw+
38 | dzosdPFS7Om6HTU1Ti0KHB9Lh9wk7Ph92dApHGWgCXv5MAixYZbPXntzNJ0CAwEA
39 | AaOBmjCBlzAdBgNVHQ4EFgQUsz/nOHpjMkV8pk9dFpy41batoTcwaAYDVR0jBGEw
40 | X4AUsz/nOHpjMkV8pk9dFpy41batoTehPKQ6MDgxCzAJBgNVBAMTAm5zMQswCQYD
41 | VQQKEwJuczELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpboIJAIOEuwkahzkO
42 | MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAEDOtAl7bgAXgcL3HRlV
43 | H71tkUaok589PIqsTE4d8s8tFBZ92CyWD8ZPU46HbbyJXMFoFxiN7PvCzOBlgoZM
44 | r80HJWZc9tSlqK0NIbIyk1aeM06+F8qB+8/vw/spIkdYzDv3avwyOrc6fFnEzbwz
45 | 5BFFrF2G9JajRKAP5snAV9iM8I2TD4l+w75MXXl7/DBEohdMBsTeDrrXj4q4sgoB
46 | L/yLeCoK6inkMTU5DwcGbiqvNnZA+9T654qlAlKjPMObGGPphK5/QKcOnV7Qtdju
47 | DHzDsDimdVbz9G1cxXs/AI/35GD7IDTdNTtmBhkf4/tsQ7Ua80xpIowb1fFUHmo1
48 | UAo=
49 | -----END CERTIFICATE-----
50 |
--------------------------------------------------------------------------------
/test/client.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIIEpAIBAAKCAQEAwV5xaK7ez2/TX7vSgJ0a3YbZj2l1VQ2rMzqO1Id01xlWbF/U
3 | rebwhAdVtWcT9R6RaBTPDGaILkV38u77M2BxIHX4MSnR6WezoA2bGMgvt3+tq2N6
4 | q+xkj57vwBEqedBjscVtFkoWtsX8pKwtNlMB1NvTa8p5+BNsvpvzaDX+51+FotId
5 | wvieQfQYgFg36HpOtOyyIV31rZ/5+qtoce8gU6wApHxmovTnQPoduNM6fOUJCHDd
6 | Lz90EeBREtoTVgoWcKvQoCEwJQSBmeDZgkA8Q1OYmbYoS12tIyi8rTkseRj5BvPH
7 | iXfNmHFKliAjvlsml5qI44I9DoagPubTf6qR5wIDAQABAoIBACZ6VZTgH0Ql22jU
8 | ZhnjqUHloIsyEAABvUxvXZaa8bwPtavREfAc4UVUdFCpl0YSdBrC8URlbrnOZwT3
9 | WxMpILm139JgoP2R/iNeMbunsh8QkA1nuTRW0NfnZ4vPnqUou33XbFKgIY7zLMfT
10 | 3xdNQzMJHzP20Xh03RG81J2rCPMfLScTRo2XxcSxmhhS/p2WLk6pnmMHiNgYGGwX
11 | gcdK5lIVjMMNxgcltC30x90v0o0GDRM8/+wua+/vfn8rr3iudv9IHzL8xIzpi6NY
12 | CXJ8Kxd6Jtgsr3Boj5i6Mqi3Q/Trxt+rIA4bKAFXxwcp4+GmRIJtQFFiTWXpLCPC
13 | tLT4CHECgYEA7iCbrGjWHJ4QsUWUGrGlw1/sQ0SIv9BdZm8RydHzpRVtQOi+YOuU
14 | i6raVaXWzUBKgKcs/htVjAMTiePs/yhlU/MGXivz6uTX/nrD7ISJImmK2K50hgUe
15 | +UBnFKmBMVaNxD9RFWPJkfmNXfW7nBkqSa9CxlBcYPuOcPtZDqRl+gkCgYEAz+HX
16 | 8wh3SHKb1cAI+o4caclpUTpGa9/zW4k+7gOh72WCKaqxTNvBvNyZGdXc9t5ToDSf
17 | xxsDXWG10lcHBIGLj4QBEoSWp9I43lid5swY3mCo7CjTl+1l03IfDNaC6CYQFp5p
18 | ZnKlsQUwR38t/uiyZpnnicCAZjqIfJbeQ5jD6G8CgYB8ufmwQa08ihJmN/KOVNRl
19 | VF31EfWquqHhYHXpxx2eL23tXLszGtHQoioASIANPAqJ/oaTho+1aXsXc5oUP/1r
20 | DlUciFsXgswb0APFY9pMewmt2xrPg+koVvJnIS25QQO6cguvb3gKDLNeLrMY3RmI
21 | RNNt+nOYnMqMJSsNf1CmuQKBgQCiCZxWaCbyZcNqncFh7BvhqYlaM15o/6ulkhln
22 | VZWIEUugRtjk2/bry9fa94TBORNeMSbKABhjVaJwTj2+GWw7dd2QHaGBNq/1QIX0
23 | POq1jAqf6kLkjbttUes6CosHgYPQ3bGylXLpxO2ZDV1A8Qj+SMDd8xsilEWHN+IQ
24 | NqeeKQKBgQDe4c7VVG+WvRRKshTh8+tjzc9nXKE2AWgwnw729SMFZO/WqX2FPp2C
25 | 7C99XJTVBsCBy8VzuyaojeTKkag0YL3v6UTZYUeyu0YTHGQ33WVPaqdCAo840nmG
26 | ttwHVqshB9c67HHiYOOFt1VmT3xW6x6yympUyRqR0L+BZ1wOS3h2vQ==
27 | -----END RSA PRIVATE KEY-----
28 | -----BEGIN CERTIFICATE-----
29 | MIIC6DCCAdACBRQJQlZlMA0GCSqGSIb3DQEBBQUAMDgxCzAJBgNVBAMTAm5zMQsw
30 | CQYDVQQKEwJuczELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkR1YmxpbjAeFw0xNDA4
31 | MzAxOTA3NDRaFw0yNDA4MjcxOTA3NDRaMDgxCzAJBgNVBAMTAm5zMQswCQYDVQQK
32 | EwJuczELMAkGA1UEBhMCSUUxDzANBgNVBAcTBkdhbHdheTCCASIwDQYJKoZIhvcN
33 | AQEBBQADggEPADCCAQoCggEBAMFecWiu3s9v01+70oCdGt2G2Y9pdVUNqzM6jtSH
34 | dNcZVmxf1K3m8IQHVbVnE/UekWgUzwxmiC5Fd/Lu+zNgcSB1+DEp0elns6ANmxjI
35 | L7d/ratjeqvsZI+e78ARKnnQY7HFbRZKFrbF/KSsLTZTAdTb02vKefgTbL6b82g1
36 | /udfhaLSHcL4nkH0GIBYN+h6TrTssiFd9a2f+fqraHHvIFOsAKR8ZqL050D6HbjT
37 | OnzlCQhw3S8/dBHgURLaE1YKFnCr0KAhMCUEgZng2YJAPENTmJm2KEtdrSMovK05
38 | LHkY+Qbzx4l3zZhxSpYgI75bJpeaiOOCPQ6GoD7m03+qkecCAwEAATANBgkqhkiG
39 | 9w0BAQUFAAOCAQEAJ+wZ/IgAF5LIu0yOfJlaFRJLunKHZENigiVjYvkTdM7NI3O2
40 | 1AZGY4O8H5Fs3YT5ZY3vas/n6IwWTk3o/JSPXojMFo82XkbI1k2cm3oLtwgEGN3p
41 | s5yFsjZE3H7fQJ9wHIzESBPHFY6dwwgMsNENuAM2zkwFpbAkisKhjK+EyUCXauok
42 | 7zJY6RVPMaNojsje4iE/SBtSOnK/9WDBAgpCznHrSChJmKs4FsU7ZTO+Dg+0vQln
43 | l8/yBcEGAFe0GA2D9NvZKH5IoNmitvtU9zdNDK4dzC3Q+C28IjW5jE8peDFtdGs1
44 | P0u4kRxmb4UH1DchgoWlZjL2lSFScJ7L4xY2aQ==
45 | -----END CERTIFICATE-----
46 |
--------------------------------------------------------------------------------
/test/data/auth/a.txt:
--------------------------------------------------------------------------------
1 | hi
2 |
--------------------------------------------------------------------------------
/test/data/auth/passwords.txt:
--------------------------------------------------------------------------------
1 | joe:foo.com:77bbd68c7bc5cd7b6bb33a19e2fc7007
2 |
--------------------------------------------------------------------------------
/test/data/cgi/index.cgi:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env perl
2 |
3 | use Cwd;
4 | use CGI;
5 |
6 | use vars '%in';
7 | CGI::ReadParse();
8 |
9 | print "Content-Type: text/html\r\nStatus: 201 Created\r\n\r\n";
10 |
11 | print "