15 | );
16 | }
17 | }
--------------------------------------------------------------------------------
/airmonitor_dashboard/app/view/not-found/index.scss:
--------------------------------------------------------------------------------
1 | .not-found {
2 | text-align: center;
3 | margin: 80px auto;
4 |
5 | p {
6 | margin: 16px 0;
7 | color: $color-text1-5;
8 | font-size: 14px;
9 | }
10 | }
11 |
12 | .not-found-img {
13 | width: 143px;
14 | height: 104px;
15 | background-size: cover;
16 | background-repeat: no-repeat;
17 | margin: 0 auto;
18 | }
19 |
--------------------------------------------------------------------------------
/airmonitor_dashboard/bone-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "web",
3 | "bundleId": "a120BURLWBPOokpQ"
4 | }
5 |
--------------------------------------------------------------------------------
/airmonitor_dashboard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "airmonitor_dashboard",
3 | "version": "0.0.1",
4 | "description": "airmonitor_dashboard",
5 | "main": "app.js",
6 | "dependencies": {
7 | "@bone/bone-web-sdk": "^0.3.0",
8 | "@bone/bone-web-ui": "latest",
9 | "@bone/bone-web-ui-dpl": "latest",
10 | "@bone/iot-gateway": "^1.0.5",
11 | "@boneweb/iot-plugin-panel": "^1.0.21",
12 | "highcharts": "^6.0.6",
13 | "javascript-time-ago": "^1.0.28",
14 | "react": "^15.1.0",
15 | "react-dom": "^15.1.0"
16 | },
17 | "bnpm": {
18 | "mode": "yarn"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/airmonitor_dashboard/public/drop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyun-linkdevelop/airmonitor_demo/d94188994ec97df709e0a1e90ee32952183fb8d7/airmonitor_dashboard/public/drop.png
--------------------------------------------------------------------------------
/airmonitor_dashboard/public/dust.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyun-linkdevelop/airmonitor_demo/d94188994ec97df709e0a1e90ee32952183fb8d7/airmonitor_dashboard/public/dust.png
--------------------------------------------------------------------------------
/airmonitor_dashboard/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | AirMonitor Dashboard
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/airmonitor_dashboard/public/thermometer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyun-linkdevelop/airmonitor_demo/d94188994ec97df709e0a1e90ee32952183fb8d7/airmonitor_dashboard/public/thermometer.png
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/.library.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "Very minimal crypto",
3 | "repository": {
4 | "url": "https://github.com/intrbiz/arduino-crypto",
5 | "type": "git"
6 | },
7 | "platforms": [
8 | "espressif32",
9 | "espressif8266"
10 | ],
11 | "export": {
12 | "exclude": [
13 | "extras",
14 | "docs",
15 | "tests",
16 | "test",
17 | "*.doxyfile",
18 | "*.pdf"
19 | ],
20 | "include": null
21 | },
22 | "authors": [
23 | {
24 | "maintainer": true,
25 | "name": "Chris Ellis",
26 | "url": null,
27 | "email": null
28 | }
29 | ],
30 | "keywords": [
31 | "other"
32 | ],
33 | "id": 2058,
34 | "name": "Crypto",
35 | "frameworks": [
36 | "arduino"
37 | ],
38 | "version": "1.0.0",
39 | "homepage": null
40 | }
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/Crypto.h:
--------------------------------------------------------------------------------
1 | /**
2 | * An extremely minimal crypto library for Arduino devices.
3 | *
4 | * The SHA256 and AES implementations are derived from axTLS
5 | * (http://axtls.sourceforge.net/), Copyright (c) 2008, Cameron Rich.
6 | *
7 | * Ported and refactored by Chris Ellis 2016.
8 | * pkcs7 padding routines added by Mike Killewald Nov 26, 2017 (adopted from https://github.com/spaniakos/AES).
9 | *
10 | */
11 |
12 | #ifndef CRYPTO_h
13 | #define CRYPTO_h
14 |
15 | #include
16 |
17 | #if defined ESP8266
18 | #include
19 | #endif
20 |
21 | #define SHA256_SIZE 32
22 | #define SHA256HMAC_SIZE 32
23 | #define SHA256HMAC_BLOCKSIZE 64
24 | #define AES_MAXROUNDS 14
25 | #define AES_BLOCKSIZE 16
26 | #define AES_IV_SIZE 16
27 | #define AES_IV_LENGTH 16
28 | #define AES_128_KEY_LENGTH 16
29 | #define AES_256_KEY_LENGTH 16
30 |
31 | /**
32 | * Compute a SHA256 hash
33 | */
34 | class SHA256
35 | {
36 | public:
37 | SHA256();
38 | /**
39 | * Update the hash with new data
40 | */
41 | void doUpdate(const byte *msg, int len);
42 | void doUpdate(const char *msg, unsigned int len) { doUpdate((byte*) msg, len); }
43 | void doUpdate(const char *msg) { doUpdate((byte*) msg, strlen(msg)); }
44 | /**
45 | * Compute the final hash and store it in [digest], digest must be
46 | * at least 32 bytes
47 | */
48 | void doFinal(byte *digest);
49 | /**
50 | * Compute the final hash and check it matches this given expected hash
51 | */
52 | bool matches(const byte *expected);
53 | private:
54 | void SHA256_Process(const byte digest[64]);
55 | uint32_t total[2];
56 | uint32_t state[8];
57 | uint8_t buffer[64];
58 | };
59 |
60 | #define HMAC_OPAD 0x5C
61 | #define HMAC_IPAD 0x36
62 |
63 | /**
64 | * Compute a HMAC using SHA256
65 | */
66 | class SHA256HMAC
67 | {
68 | public:
69 | /**
70 | * Compute a SHA256 HMAC with the given [key] key of [length] bytes
71 | * for authenticity
72 | */
73 | SHA256HMAC(const byte *key, unsigned int keyLen);
74 | /**
75 | * Update the hash with new data
76 | */
77 | void doUpdate(const byte *msg, unsigned int len);
78 | void doUpdate(const char *msg, unsigned int len) { doUpdate((byte*) msg, len); }
79 | void doUpdate(const char *msg) { doUpdate((byte*) msg, strlen(msg)); }
80 | /**
81 | * Compute the final hash and store it in [digest], digest must be
82 | * at least 32 bytes
83 | */
84 | void doFinal(byte *digest);
85 | /**
86 | * Compute the final hash and check it matches this given expected hash
87 | */
88 | bool matches(const byte *expected);
89 | private:
90 | void blockXor(const byte *in, byte *out, byte val, byte len);
91 | SHA256 _hash;
92 | byte _innerKey[SHA256HMAC_BLOCKSIZE];
93 | byte _outerKey[SHA256HMAC_BLOCKSIZE];
94 | };
95 |
96 | /**
97 | * AES 128 and 256, based on code from axTLS
98 | */
99 | class AES
100 | {
101 | public:
102 | typedef enum
103 | {
104 | AES_MODE_128,
105 | AES_MODE_256
106 | } AES_MODE;
107 | typedef enum
108 | {
109 | CIPHER_ENCRYPT = 0x01,
110 | CIPHER_DECRYPT = 0x02
111 | } CIPHER_MODE;
112 |
113 | /**
114 | * Create this cipher instance in either encrypt or decrypt mode
115 | *
116 | * Use the given [key] which must be 16 bytes long for AES 128 and
117 | * 32 bytes for AES 256
118 | *
119 | * Use the given [iv] initialistion vection which must be 16 bytes long
120 | *
121 | * Use the either AES 128 or AES 256 as specified by [mode]
122 | *
123 | * Either encrypt or decrypt as specified by [cipherMode]
124 | */
125 | AES(const uint8_t *key, const uint8_t *iv, AES_MODE mode, CIPHER_MODE cipherMode);
126 |
127 | /**
128 | * Either encrypt or decrypt [in] and store into [out] for [length] bytes, applying no padding
129 | *
130 | * Note: the length must be a multiple of 16 bytes
131 | */
132 | void processNoPad(const uint8_t *in, uint8_t *out, int length);
133 |
134 | /**
135 | * Either encrypt or decrypt [in] and store into [out] for [length] bytes, applying padding as needed
136 | *
137 | * Note: the length must be a multiple of 16 bytes
138 | */
139 | void process(const uint8_t *in, uint8_t *out, int length);
140 |
141 | /** Getter method for size
142 | *
143 | * This function returns the size
144 | * @return an integer, that is the size of the of the padded plaintext,
145 | * thus, the size of the ciphertext.
146 | */
147 | int getSize();
148 |
149 | /** Setter method for size
150 | *
151 | * This function sets the size of the plaintext+pad
152 | *
153 | */
154 | void setSize(int size);
155 |
156 | /** Calculates the size of the plaintext and the padding.
157 | *
158 | * Calculates the size of the plaintext with the size of the
159 | * padding needed. Moreover it stores them in their class variables.
160 | *
161 | * @param in_size the size of the byte array ex sizeof(plaintext)
162 | * @return an int the size of the plaintext plus the padding
163 | */
164 | int calcSizeAndPad(int in_size);
165 |
166 | /** Pads the plaintext
167 | *
168 | * This function pads the plaintext and returns an char array with the
169 | * plaintext and the padding in order for the plaintext to be compatible with
170 | * 16bit size blocks required by AES
171 | *
172 | * @param in the string of the plaintext in a byte array
173 | * @param out The string of the out array.
174 | * @return no return, The padded plaintext is stored in the out pointer.
175 | */
176 | void padPlaintext(const uint8_t* in, uint8_t* out);
177 |
178 | /** Check the if the padding is correct.
179 | *
180 | * This functions checks the padding of the plaintext.
181 | *
182 | * @param in the string of the plaintext in a byte array
183 | * @param size the size of the string
184 | * @return true if correct / false if not
185 | */
186 | bool checkPad(uint8_t* in, int lsize);
187 |
188 | private:
189 | void encryptCBC(const uint8_t *in, uint8_t *out, int length);
190 | void decryptCBC(const uint8_t *in, uint8_t *out, int length);
191 | void convertKey();
192 | void encrypt(uint32_t *data);
193 | void decrypt(uint32_t *data);
194 | uint16_t _rounds;
195 | uint16_t _key_size;
196 | uint32_t _ks[(AES_MAXROUNDS+1)*8];
197 | uint8_t _iv[AES_IV_SIZE];
198 | int _pad_size; // size of padding to add to plaintext
199 | int _size; // size of plaintext plus padding to be ciphered
200 | uint8_t _arr_pad[15];
201 |
202 | CIPHER_MODE _cipherMode;
203 | };
204 |
205 | #if defined ESP8266 || defined ESP32
206 | /**
207 | * ESP8266 and ESP32 specific true random number generator
208 | */
209 | class RNG
210 | {
211 | public:
212 | /**
213 | * Fill the [dst] array with [length] random bytes
214 | */
215 | static void fill(uint8_t *dst, unsigned int length);
216 | /**
217 | * Get a random byte
218 | */
219 | static byte get();
220 | /**
221 | * Get a 32bit random number
222 | */
223 | static uint32_t getLong();
224 | private:
225 | };
226 | #endif
227 |
228 |
229 | #endif
230 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/LICENSE.md:
--------------------------------------------------------------------------------
1 | License
2 | =======
3 | Balsa SCGI
4 | Copyright (c) 2012, Chris Ellis
5 | All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without
8 | modification, are permitted provided that the following conditions are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/README.md:
--------------------------------------------------------------------------------
1 | # ESP8266 Crypto
2 |
3 | This is a minimal, lightweight crypto library for the ESP8266 IOT device. It
4 | provides the following functions:
5 |
6 | * SHA256
7 | * AES 128 and 256
8 | * SHA256HMAC
9 | * RNG
10 |
11 | The SHA256 and AES implementations are based upon the implementations in axTLS
12 | except ported to the ESP8266 Arduino platform, credit to Cameron Rich for the
13 | axTLS project.
14 |
15 | ## Usage
16 |
17 | ### SHA256HMAC
18 |
19 | The following snippet demonstrates how to compute the SHA256 HMAC authentication
20 | code for a message.
21 |
22 | /* Include the crypto library into your project */
23 | #include
24 |
25 | /* The length of the key we will use for this HMAC */
26 | /* The key can be of any length, 16 and 32 are common */
27 | #define KEY_LENGTH 16
28 |
29 | /* Define our */
30 | byte key[KEY_LENGTH] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
31 |
32 | /* Create the HMAC instance with our key */
33 | SHA256HMAC hmac(key, KEY_LENGTH);
34 |
35 | /* Update the HMAC with just a plain string (null terminated) */
36 | hmac.doUpdate("Hello World");
37 |
38 | /* And or with a string and length */
39 | const char *goodbye = "GoodBye World";
40 | hmac.doUpdate(goodbye, strlen(goodbye));
41 |
42 | /* And or with a binary message */
43 | byte message[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
44 | hmac.doUpdate(message, sizeof(message));
45 |
46 | /* Finish the HMAC calculation and return the authentication code */
47 | byte authCode[SHA256HMAC_SIZE];
48 | hmac.doFinal(authCode);
49 |
50 | /* authCode now contains our 32 byte authentication code */
51 | for (byte i; i < SHA256HMAC_SIZE; i++)
52 | {
53 | Serial.print(authCode[i], HEX);
54 | }
55 |
56 | ### SHA256
57 |
58 | The following snippet demonstrates how to compute the SHA256 hash of a message.
59 |
60 | /* Create a SHA256 hash */
61 | SHA256 hasher;
62 |
63 | /* Update the hash with your message, as many times as you like */
64 | const char *hello = "Hello World";
65 | hasher.doUpdate(hello, strlen(hello));
66 |
67 | /* Update the hash with just a plain string*/
68 | hasher.doUpdate("Goodbye World");
69 |
70 | /* Update the hash with a binary message */
71 | byte message[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
72 | hasher.doUpdate(message, sizeof(message));
73 |
74 | /* Compute the final hash */
75 | byte hash[SHA256_SIZE];
76 | hasher.doFinal(hash);
77 |
78 | /* hash now contains our 32 byte hash */
79 | for (byte i; i < SHA256_SIZE; i++)
80 | {
81 | Serial.print(hash[i], HEX);
82 | }
83 |
84 | ## License
85 |
86 | ESP8266 Crypto
87 | Copyright (c) 2016, Chris Ellis, with portions derived from axTLS
88 | All rights reserved.
89 |
90 | Redistribution and use in source and binary forms, with or without
91 | modification, are permitted provided that the following conditions are met:
92 |
93 | 1. Redistributions of source code must retain the above copyright notice, this
94 | list of conditions and the following disclaimer.
95 | 2. Redistributions in binary form must reproduce the above copyright notice,
96 | this list of conditions and the following disclaimer in the documentation
97 | and/or other materials provided with the distribution.
98 |
99 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
100 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
103 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
107 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
108 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
109 |
110 | ## Author
111 |
112 | Chris Ellis
113 |
114 | Twitter: @intrbiz
115 |
116 | Copyright (c) Chris Ellis 2016
117 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/examples/aesSha256Hmac/aesSha256Hmac.ino:
--------------------------------------------------------------------------------
1 | #include // AES 128 CBC with pkcs7, RNG, SHA256 and SHA256HMAC
2 | #include // Base64 encode and decode without line breaks https://github.com/Densaugeo/base64_arduino
3 |
4 | /*
5 | * AES encryption with SHA256HMAC on an ESP8266
6 | */
7 |
8 | #define HMAC_KEY_LENGTH 16
9 | #define AES_KEY_LENGTH 16
10 |
11 | uint8_t* keyEncrypt;
12 | uint8_t* keyHmac;
13 | uint8_t keyHash[SHA256_SIZE];
14 | uint8_t key[AES_KEY_LENGTH] = { 0x1C,0x3E,0x4B,0xAF,0x13,0x4A,0x89,0xC3,0xF3,0x87,0x4F,0xBC,0xD7,0xF3, 0x31, 0x31 };
15 | uint8_t iv[AES_KEY_LENGTH];
16 |
17 | SHA256 sha256;
18 |
19 | // prints given block of given length in HEX
20 | void printBlock(uint8_t* block, int length) {
21 | Serial.print(" { ");
22 | for (int i=0; i?-=[];'./,";
48 | // char packet[] = "0123456789abcdef";
49 |
50 | Serial.println("On the sending side:");
51 |
52 | int packetSize = strlen(packet);
53 | Serial.printf("Packet (%d bytes):\n", packetSize);
54 | Serial.println(packet);
55 |
56 | Serial.print("Packet HEX");
57 | printBlock((uint8_t*)packet, packetSize+1); //+1 to add null termination
58 |
59 | // random initialization vector
60 | RNG::fill(iv, AES_KEY_LENGTH);
61 |
62 | Serial.printf("Random IV (%d bytes)", AES_KEY_LENGTH);
63 | printBlock(iv, AES_KEY_LENGTH);
64 |
65 | AES aes(keyEncrypt, iv, AES::AES_MODE_128, AES::CIPHER_ENCRYPT);
66 |
67 | // create buffer for final message which will contain IV, encrypted message, and HMAC
68 | int encryptedSize = aes.calc_size_n_pad(packetSize);
69 | int ivEncryptedSize = encryptedSize + AES_KEY_LENGTH;
70 | int ivEncryptedHmacSize = ivEncryptedSize + SHA256HMAC_SIZE;
71 | uint8_t ivEncryptedHmac[ivEncryptedHmacSize];
72 |
73 | // copy IV to our final message buffer
74 | memcpy(ivEncryptedHmac, iv, AES_KEY_LENGTH);
75 |
76 | // encrypted is a pointer that points to the encypted messages position in our final message buffer
77 | uint8_t* encrypted = ivEncryptedHmac + AES_KEY_LENGTH;
78 |
79 | // AES 128 CBC and pkcs7 padding
80 | aes.process((uint8_t*)packet, encrypted, packetSize);
81 |
82 | Serial.printf("Encrypted (%d bytes)", encryptedSize);
83 | printBlock(encrypted, encryptedSize);
84 |
85 | // computedHmac is a pointer which points to the HMAC position in our final message buffer
86 | uint8_t* computedHmac = encrypted + encryptedSize;
87 |
88 | // compute HMAC/SHA-256 with keyHmac
89 | SHA256HMAC hmac(keyHmac, HMAC_KEY_LENGTH);
90 | hmac.doUpdate(ivEncryptedHmac, ivEncryptedSize);
91 | hmac.doFinal(computedHmac);
92 |
93 | Serial.printf("Computed HMAC (%d bytes)", SHA256HMAC_SIZE);
94 | printBlock(computedHmac, SHA256HMAC_SIZE);
95 |
96 | Serial.printf("IV | encrypted | HMAC (%d bytes)", ivEncryptedHmacSize);
97 | printBlock(ivEncryptedHmac, ivEncryptedHmacSize);
98 |
99 | // base64 encode
100 | int encodedSize = encode_base64_length(ivEncryptedHmacSize); // get size needed for base64 encoded output
101 | uint8_t encoded[encodedSize];
102 | encode_base64(ivEncryptedHmac, ivEncryptedHmacSize, encoded);
103 |
104 | Serial.printf("Base64 encoded to %d bytes\n", encodedSize);
105 |
106 | // Now on to the receiving side. This would normally be in a different skectch so we would
107 | // again SHA256 hash our secret key to obain keyEncrypt and KeyHmac on the remote side.
108 | // We would then recompute the HMAC using the received iv plus encrypted mesage and
109 | // compare the computed HMAC to the received HMAC. If they match, we can decrypt the message.
110 |
111 | Serial.printf("\nOn the receiving side:\n");
112 |
113 | // base64 decode
114 | int decodedSize = decode_base64_length(encoded);
115 | uint8_t decoded[decodedSize];
116 | decode_base64(encoded, decoded);
117 |
118 | Serial.printf("Received %d bytes\n", encodedSize);
119 | Serial.printf("Base64 decoded IV | encrypted | HMAC (%d bytes)", decodedSize);
120 | printBlock(decoded, decodedSize);
121 |
122 | // receivedHmac is a pointer which points to the received HMAC in our decoded message
123 | uint8_t* receivedHmac = decoded+decodedSize-SHA256HMAC_SIZE;
124 |
125 | Serial.printf("Received HMAC (%d bytes)", SHA256HMAC_SIZE);
126 | printBlock(receivedHmac, SHA256HMAC_SIZE);
127 |
128 | // compute HMAC/SHA-256 with keyHmac
129 | uint8_t remote_computedHmac[SHA256HMAC_SIZE];
130 | SHA256HMAC remote_hmac(keyHmac, HMAC_KEY_LENGTH);
131 | remote_hmac.doUpdate(decoded, decodedSize-SHA256HMAC_SIZE);
132 | remote_hmac.doFinal(remote_computedHmac);
133 |
134 | Serial.printf("Computed HMAC (%d bytes)", SHA256HMAC_SIZE);
135 | printBlock(remote_computedHmac, SHA256HMAC_SIZE);
136 |
137 | if (*receivedHmac == *remote_computedHmac) {
138 | // extract IV
139 | memcpy(iv, decoded, AES_KEY_LENGTH);
140 |
141 | Serial.printf("Received IV (%d bytes)", AES_KEY_LENGTH);
142 | printBlock(iv, AES_KEY_LENGTH);
143 |
144 | // decrypt
145 | int decryptedSize = decodedSize - AES_KEY_LENGTH - SHA256HMAC_SIZE;
146 | char decrypted[decryptedSize];
147 | AES aesDecryptor(keyEncrypt, iv, AES::AES_MODE_128, AES::CIPHER_DECRYPT);
148 | aesDecryptor.process((uint8_t*)decoded + AES_KEY_LENGTH, (uint8_t*)decrypted, decryptedSize);
149 |
150 | Serial.printf("Decrypted Packet HEX (%d bytes)", decryptedSize);
151 | printBlock((uint8_t*)decrypted, decryptedSize);
152 |
153 | Serial.printf("Decrypted Packet (%d bytes):\n", strlen(decrypted));
154 | Serial.println(decrypted);
155 | }
156 | }
157 |
158 | void loop() {
159 | delay(1);
160 | }
161 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/examples/sha256/sha256.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /*
4 | * Compute the SHA256 hash of a message on an ESP8266
5 | */
6 |
7 | void setup()
8 | {
9 | // Setup Serial
10 | Serial.begin(9600);
11 | Serial.println("SHA256 example");
12 |
13 | /* Create a SHA256 hash */
14 | SHA256 hasher;
15 |
16 | /* Update the hash with your message, as many times as you like */
17 | const char *hello = "Hello World";
18 | hasher.doUpdate(hello, strlen(hello));
19 |
20 | /* Update the hash with just a plain string*/
21 | hasher.doUpdate("Goodbye World");
22 |
23 | /* Update the hash with a binary message */
24 | byte message[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
25 | hasher.doUpdate(message, sizeof(message));
26 |
27 | /* Compute the final hash */
28 | byte hash[SHA256_SIZE];
29 | hasher.doFinal(hash);
30 |
31 | /* hash now contains our 32 byte hash */
32 | for (byte i=0; i < SHA256_SIZE; i++)
33 | {
34 | if (hash[i]<0x10) { Serial.print('0'); }
35 | Serial.print(hash[i], HEX);
36 | }
37 | }
38 |
39 |
40 | void loop()
41 | {
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/examples/sha256hmac/sha256hmac.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /*
4 | * Compute the SHA256HMAC of a message on an ESP8266
5 | */
6 |
7 | /* The length of the key we will use for this HMAC */
8 | /* The key can be of any length, 16 and 32 are common */
9 | #define KEY_LENGTH 16
10 |
11 | void setup()
12 | {
13 | // Setup Serial
14 | Serial.begin(9600);
15 | Serial.println("SHA256HMAC example");
16 |
17 | /* Define our */
18 | byte key[KEY_LENGTH] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
19 |
20 | /* Create the HMAC instance with our key */
21 | SHA256HMAC hmac(key, KEY_LENGTH);
22 |
23 | /* Update the HMAC with just a plain string (null terminated) */
24 | hmac.doUpdate("Hello World");
25 |
26 | /* And or with a string and length */
27 | const char *goodbye = "GoodBye World";
28 | hmac.doUpdate(goodbye, strlen(goodbye));
29 |
30 | /* And or with a binary message */
31 | byte message[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
32 | hmac.doUpdate(message, sizeof(message));
33 |
34 | /* Finish the HMAC calculation and return the authentication code */
35 | byte authCode[SHA256HMAC_SIZE];
36 | hmac.doFinal(authCode);
37 |
38 | /* authCode now contains our 32 byte authentication code */
39 | for (byte i=0; i < SHA256HMAC_SIZE; i++)
40 | {
41 | if (authCode[i]<0x10) { Serial.print('0'); }
42 | Serial.print(authCode[i], HEX);
43 | }
44 | }
45 |
46 |
47 | void loop()
48 | {
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For Crypto
3 | #######################################
4 |
5 | #######################################
6 | # Library (KEYWORD3)
7 | #######################################
8 |
9 | Crypto KEYWORD3
10 |
11 | #######################################
12 | # Datatypes (KEYWORD1)
13 | #######################################
14 |
15 | SHA256 KEYWORD1
16 | SHA256HMAC KEYWORD1
17 | AES KEYWORD1
18 | RNG KEYWORD1
19 |
20 | #######################################
21 | # Methods and Functions (KEYWORD2)
22 | #######################################
23 |
24 | doUpdate KEYWORD2
25 | doFinal KEYWORD2
26 | matches KEYWORD2
27 | AES KEYWORD2
28 | process KEYWORD2
29 | fill KEYWORD2
30 | get KEYWORD2
31 | getLong KEYWORD2
32 |
33 | #######################################
34 | # Constants (LITERAL1)
35 | #######################################
36 |
37 | SHA256_SIZE LITERAL1
38 | SHA256HMAC_SIZE LITERAL1
39 | SHA256HMAC_BLOCKSIZE LITERAL1
40 | AES_MAXROUNDS LITERAL1
41 | AES_BLOCKSIZE LITERAL1
42 | AES_IV_SIZE LITERAL1
43 | AES_IV_LENGTH LITERAL1
44 | AES_128_KEY_LENGTH LITERAL1
45 | AES_256_KEY_LENGTH LITERAL1
46 | HMAC_OPAD LITERAL1
47 | HMAC_IPAD LITERAL1
48 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/Crypto/library.properties:
--------------------------------------------------------------------------------
1 | name=Crypto
2 | version=1.0.0
3 | author=Chris Ellis
4 | maintainer=Chris Ellis
5 | sentence=Very minimal crypto
6 | paragraph=Very minimal crypto library derived from axtls
7 | category=Other
8 | url=https://github.com/intrbiz/arduino-crypto
9 | architectures=esp8266,esp32
10 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/.gitignore:
--------------------------------------------------------------------------------
1 | tests/bin
2 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/.library.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PubSubClient",
3 | "repository": {
4 | "url": "https://github.com/knolleary/pubsubclient.git",
5 | "type": "git"
6 | },
7 | "platforms": [
8 | "atmelavr",
9 | "atmelsam",
10 | "espressif8266",
11 | "intel_arc32",
12 | "microchippic32",
13 | "nordicnrf51",
14 | "teensy",
15 | "timsp430"
16 | ],
17 | "frameworks": [
18 | "arduino"
19 | ],
20 | "version": "2.6",
21 | "export": {
22 | "exclude": "tests"
23 | },
24 | "examples": "examples/*/*.ino",
25 | "authors": [
26 | {
27 | "maintainer": false,
28 | "name": "Nick O'Leary",
29 | "url": "https://github.com/knolleary",
30 | "email": null
31 | }
32 | ],
33 | "keywords": [
34 | "ethernet",
35 | "mqtt",
36 | "iot",
37 | "m2m"
38 | ],
39 | "homepage": "http://pubsubclient.knolleary.net",
40 | "id": 89,
41 | "description": "A client library for MQTT messaging. MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000."
42 | }
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: cpp
3 | compiler:
4 | - g++
5 | script: cd tests && make && make test
6 | os:
7 | - linux
8 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/CHANGES.txt:
--------------------------------------------------------------------------------
1 | 2.4
2 | * Add MQTT_SOCKET_TIMEOUT to prevent it blocking indefinitely
3 | whilst waiting for inbound data
4 | * Fixed return code when publishing >256 bytes
5 |
6 | 2.3
7 | * Add publish(topic,payload,retained) function
8 |
9 | 2.2
10 | * Change code layout to match Arduino Library reqs
11 |
12 | 2.1
13 | * Add MAX_TRANSFER_SIZE def to chunk messages if needed
14 | * Reject topic/payloads that exceed MQTT_MAX_PACKET_SIZE
15 |
16 | 2.0
17 | * Add (and default to) MQTT 3.1.1 support
18 | * Fix PROGMEM handling for Intel Galileo/ESP8266
19 | * Add overloaded constructors for convenience
20 | * Add chainable setters for server/callback/client/stream
21 | * Add state function to return connack return code
22 |
23 | 1.9
24 | * Do not split MQTT packets over multiple calls to _client->write()
25 | * API change: All constructors now require an instance of Client
26 | to be passed in.
27 | * Fixed example to match 1.8 api changes - dpslwk
28 | * Added username/password support - WilHall
29 | * Added publish_P - publishes messages from PROGMEM - jobytaffey
30 |
31 | 1.8
32 | * KeepAlive interval is configurable in PubSubClient.h
33 | * Maximum packet size is configurable in PubSubClient.h
34 | * API change: Return boolean rather than int from various functions
35 | * API change: Length parameter in message callback changed
36 | from int to unsigned int
37 | * Various internal tidy-ups around types
38 | 1.7
39 | * Improved keepalive handling
40 | * Updated to the Arduino-1.0 API
41 | 1.6
42 | * Added the ability to publish a retained message
43 |
44 | 1.5
45 | * Added default constructor
46 | * Fixed compile error when used with arduino-0021 or later
47 |
48 | 1.4
49 | * Fixed connection lost handling
50 |
51 | 1.3
52 | * Fixed packet reading bug in PubSubClient.readPacket
53 |
54 | 1.2
55 | * Fixed compile error when used with arduino-0016 or later
56 |
57 |
58 | 1.1
59 | * Reduced size of library
60 | * Added support for Will messages
61 | * Clarified licensing - see LICENSE.txt
62 |
63 |
64 | 1.0
65 | * Only Quality of Service (QOS) 0 messaging is supported
66 | * The maximum message size, including header, is 128 bytes
67 | * The keepalive interval is set to 30 seconds
68 | * No support for Will messages
69 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008-2015 Nicholas O'Leary
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/README.md:
--------------------------------------------------------------------------------
1 | # Arduino Client for MQTT
2 |
3 | This library provides a client for doing simple publish/subscribe messaging with
4 | a server that supports MQTT.
5 |
6 | ## Examples
7 |
8 | The library comes with a number of example sketches. See File > Examples > PubSubClient
9 | within the Arduino application.
10 |
11 | Full API documentation is available here: http://pubsubclient.knolleary.net
12 |
13 | ## Limitations
14 |
15 | - It can only publish QoS 0 messages. It can subscribe at QoS 0 or QoS 1.
16 | - The maximum message size, including header, is **128 bytes** by default. This
17 | is configurable via `MQTT_MAX_PACKET_SIZE` in `PubSubClient.h`.
18 | - The keepalive interval is set to 15 seconds by default. This is configurable
19 | via `MQTT_KEEPALIVE` in `PubSubClient.h`.
20 | - The client uses MQTT 3.1.1 by default. It can be changed to use MQTT 3.1 by
21 | changing value of `MQTT_VERSION` in `PubSubClient.h`.
22 |
23 |
24 | ## Compatible Hardware
25 |
26 | The library uses the Arduino Ethernet Client api for interacting with the
27 | underlying network hardware. This means it Just Works with a growing number of
28 | boards and shields, including:
29 |
30 | - Arduino Ethernet
31 | - Arduino Ethernet Shield
32 | - Arduino YUN – use the included `YunClient` in place of `EthernetClient`, and
33 | be sure to do a `Bridge.begin()` first
34 | - Arduino WiFi Shield - if you want to send packets > 90 bytes with this shield,
35 | enable the `MQTT_MAX_TRANSFER_SIZE` define in `PubSubClient.h`.
36 | - Sparkfun WiFly Shield – [library](https://github.com/dpslwk/WiFly)
37 | - TI CC3000 WiFi - [library](https://github.com/sparkfun/SFE_CC3000_Library)
38 | - Intel Galileo/Edison
39 | - ESP8266
40 |
41 | The library cannot currently be used with hardware based on the ENC28J60 chip –
42 | such as the Nanode or the Nuelectronics Ethernet Shield. For those, there is an
43 | [alternative library](https://github.com/njh/NanodeMQTT) available.
44 |
45 | ## License
46 |
47 | This code is released under the MIT License.
48 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/examples/mqtt_auth/mqtt_auth.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Basic MQTT example with Authentication
3 |
4 | - connects to an MQTT server, providing username
5 | and password
6 | - publishes "hello world" to the topic "outTopic"
7 | - subscribes to the topic "inTopic"
8 | */
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | // Update these with values suitable for your network.
15 | byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
16 | IPAddress ip(172, 16, 0, 100);
17 | IPAddress server(172, 16, 0, 2);
18 |
19 | void callback(char* topic, byte* payload, unsigned int length) {
20 | // handle message arrived
21 | }
22 |
23 | EthernetClient ethClient;
24 | PubSubClient client(server, 1883, callback, ethClient);
25 |
26 | void setup()
27 | {
28 | Ethernet.begin(mac, ip);
29 | // Note - the default maximum packet size is 128 bytes. If the
30 | // combined length of clientId, username and password exceed this,
31 | // you will need to increase the value of MQTT_MAX_PACKET_SIZE in
32 | // PubSubClient.h
33 |
34 | if (client.connect("arduinoClient", "testuser", "testpass")) {
35 | client.publish("outTopic","hello world");
36 | client.subscribe("inTopic");
37 | }
38 | }
39 |
40 | void loop()
41 | {
42 | client.loop();
43 | }
44 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/examples/mqtt_basic/mqtt_basic.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Basic MQTT example
3 |
4 | This sketch demonstrates the basic capabilities of the library.
5 | It connects to an MQTT server then:
6 | - publishes "hello world" to the topic "outTopic"
7 | - subscribes to the topic "inTopic", printing out any messages
8 | it receives. NB - it assumes the received payloads are strings not binary
9 |
10 | It will reconnect to the server if the connection is lost using a blocking
11 | reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
12 | achieve the same result without blocking the main loop.
13 |
14 | */
15 |
16 | #include
17 | #include
18 | #include
19 |
20 | // Update these with values suitable for your network.
21 | byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
22 | IPAddress ip(172, 16, 0, 100);
23 | IPAddress server(172, 16, 0, 2);
24 |
25 | void callback(char* topic, byte* payload, unsigned int length) {
26 | Serial.print("Message arrived [");
27 | Serial.print(topic);
28 | Serial.print("] ");
29 | for (int i=0;i Preferences -> Additional Boards Manager URLs":
20 | http://arduino.esp8266.com/stable/package_esp8266com_index.json
21 | - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
22 | - Select your ESP8266 in "Tools -> Board"
23 |
24 | */
25 |
26 | #include
27 | #include
28 |
29 | // Update these with values suitable for your network.
30 |
31 | const char* ssid = "........";
32 | const char* password = "........";
33 | const char* mqtt_server = "broker.mqtt-dashboard.com";
34 |
35 | WiFiClient espClient;
36 | PubSubClient client(espClient);
37 | long lastMsg = 0;
38 | char msg[50];
39 | int value = 0;
40 |
41 | void setup() {
42 | pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
43 | Serial.begin(115200);
44 | setup_wifi();
45 | client.setServer(mqtt_server, 1883);
46 | client.setCallback(callback);
47 | }
48 |
49 | void setup_wifi() {
50 |
51 | delay(10);
52 | // We start by connecting to a WiFi network
53 | Serial.println();
54 | Serial.print("Connecting to ");
55 | Serial.println(ssid);
56 |
57 | WiFi.begin(ssid, password);
58 |
59 | while (WiFi.status() != WL_CONNECTED) {
60 | delay(500);
61 | Serial.print(".");
62 | }
63 |
64 | Serial.println("");
65 | Serial.println("WiFi connected");
66 | Serial.println("IP address: ");
67 | Serial.println(WiFi.localIP());
68 | }
69 |
70 | void callback(char* topic, byte* payload, unsigned int length) {
71 | Serial.print("Message arrived [");
72 | Serial.print(topic);
73 | Serial.print("] ");
74 | for (int i = 0; i < length; i++) {
75 | Serial.print((char)payload[i]);
76 | }
77 | Serial.println();
78 |
79 | // Switch on the LED if an 1 was received as first character
80 | if ((char)payload[0] == '1') {
81 | digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
82 | // but actually the LED is on; this is because
83 | // it is acive low on the ESP-01)
84 | } else {
85 | digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
86 | }
87 |
88 | }
89 |
90 | void reconnect() {
91 | // Loop until we're reconnected
92 | while (!client.connected()) {
93 | Serial.print("Attempting MQTT connection...");
94 | // Attempt to connect
95 | if (client.connect("ESP8266Client")) {
96 | Serial.println("connected");
97 | // Once connected, publish an announcement...
98 | client.publish("outTopic", "hello world");
99 | // ... and resubscribe
100 | client.subscribe("inTopic");
101 | } else {
102 | Serial.print("failed, rc=");
103 | Serial.print(client.state());
104 | Serial.println(" try again in 5 seconds");
105 | // Wait 5 seconds before retrying
106 | delay(5000);
107 | }
108 | }
109 | }
110 | void loop() {
111 |
112 | if (!client.connected()) {
113 | reconnect();
114 | }
115 | client.loop();
116 |
117 | long now = millis();
118 | if (now - lastMsg > 2000) {
119 | lastMsg = now;
120 | ++value;
121 | snprintf (msg, 75, "hello world #%ld", value);
122 | Serial.print("Publish message: ");
123 | Serial.println(msg);
124 | client.publish("outTopic", msg);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/examples/mqtt_publish_in_callback/mqtt_publish_in_callback.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Publishing in the callback
3 |
4 | - connects to an MQTT server
5 | - subscribes to the topic "inTopic"
6 | - when a message is received, republishes it to "outTopic"
7 |
8 | This example shows how to publish messages within the
9 | callback function. The callback function header needs to
10 | be declared before the PubSubClient constructor and the
11 | actual callback defined afterwards.
12 | This ensures the client reference in the callback function
13 | is valid.
14 |
15 | */
16 |
17 | #include
18 | #include
19 | #include
20 |
21 | // Update these with values suitable for your network.
22 | byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
23 | IPAddress ip(172, 16, 0, 100);
24 | IPAddress server(172, 16, 0, 2);
25 |
26 | // Callback function header
27 | void callback(char* topic, byte* payload, unsigned int length);
28 |
29 | EthernetClient ethClient;
30 | PubSubClient client(server, 1883, callback, ethClient);
31 |
32 | // Callback function
33 | void callback(char* topic, byte* payload, unsigned int length) {
34 | // In order to republish this payload, a copy must be made
35 | // as the orignal payload buffer will be overwritten whilst
36 | // constructing the PUBLISH packet.
37 |
38 | // Allocate the correct amount of memory for the payload copy
39 | byte* p = (byte*)malloc(length);
40 | // Copy the payload to the new buffer
41 | memcpy(p,payload,length);
42 | client.publish("outTopic", p, length);
43 | // Free the memory
44 | free(p);
45 | }
46 |
47 | void setup()
48 | {
49 |
50 | Ethernet.begin(mac, ip);
51 | if (client.connect("arduinoClient")) {
52 | client.publish("outTopic","hello world");
53 | client.subscribe("inTopic");
54 | }
55 | }
56 |
57 | void loop()
58 | {
59 | client.loop();
60 | }
61 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/examples/mqtt_reconnect_nonblocking/mqtt_reconnect_nonblocking.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Reconnecting MQTT example - non-blocking
3 |
4 | This sketch demonstrates how to keep the client connected
5 | using a non-blocking reconnect function. If the client loses
6 | its connection, it attempts to reconnect every 5 seconds
7 | without blocking the main loop.
8 |
9 | */
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | // Update these with values suitable for your hardware/network.
16 | byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
17 | IPAddress ip(172, 16, 0, 100);
18 | IPAddress server(172, 16, 0, 2);
19 |
20 | void callback(char* topic, byte* payload, unsigned int length) {
21 | // handle message arrived
22 | }
23 |
24 | EthernetClient ethClient;
25 | PubSubClient client(ethClient);
26 |
27 | long lastReconnectAttempt = 0;
28 |
29 | boolean reconnect() {
30 | if (client.connect("arduinoClient")) {
31 | // Once connected, publish an announcement...
32 | client.publish("outTopic","hello world");
33 | // ... and resubscribe
34 | client.subscribe("inTopic");
35 | }
36 | return client.connected();
37 | }
38 |
39 | void setup()
40 | {
41 | client.setServer(server, 1883);
42 | client.setCallback(callback);
43 |
44 | Ethernet.begin(mac, ip);
45 | delay(1500);
46 | lastReconnectAttempt = 0;
47 | }
48 |
49 |
50 | void loop()
51 | {
52 | if (!client.connected()) {
53 | long now = millis();
54 | if (now - lastReconnectAttempt > 5000) {
55 | lastReconnectAttempt = now;
56 | // Attempt to reconnect
57 | if (reconnect()) {
58 | lastReconnectAttempt = 0;
59 | }
60 | }
61 | } else {
62 | // Client connected
63 |
64 | client.loop();
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/examples/mqtt_stream/mqtt_stream.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Example of using a Stream object to store the message payload
3 |
4 | Uses SRAM library: https://github.com/ennui2342/arduino-sram
5 | but could use any Stream based class such as SD
6 |
7 | - connects to an MQTT server
8 | - publishes "hello world" to the topic "outTopic"
9 | - subscribes to the topic "inTopic"
10 | */
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | // Update these with values suitable for your network.
18 | byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
19 | IPAddress ip(172, 16, 0, 100);
20 | IPAddress server(172, 16, 0, 2);
21 |
22 | SRAM sram(4, SRAM_1024);
23 |
24 | void callback(char* topic, byte* payload, unsigned int length) {
25 | sram.seek(1);
26 |
27 | // do something with the message
28 | for(uint8_t i=0; i
4 | maintainer=Nick O'Leary
5 | sentence=A client library for MQTT messaging.
6 | paragraph=MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000.
7 | category=Communication
8 | url=http://pubsubclient.knolleary.net
9 | architectures=*
10 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/src/PubSubClient.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | PubSubClient.cpp - A simple client for MQTT.
3 | Nick O'Leary
4 | http://knolleary.net
5 | */
6 |
7 | #include "PubSubClient.h"
8 | #include "Arduino.h"
9 |
10 | PubSubClient::PubSubClient() {
11 | this->_state = MQTT_DISCONNECTED;
12 | this->_client = NULL;
13 | this->stream = NULL;
14 | setCallback(NULL);
15 | }
16 |
17 | PubSubClient::PubSubClient(Client& client) {
18 | this->_state = MQTT_DISCONNECTED;
19 | setClient(client);
20 | this->stream = NULL;
21 | }
22 |
23 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
24 | this->_state = MQTT_DISCONNECTED;
25 | setServer(addr, port);
26 | setClient(client);
27 | this->stream = NULL;
28 | }
29 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) {
30 | this->_state = MQTT_DISCONNECTED;
31 | setServer(addr,port);
32 | setClient(client);
33 | setStream(stream);
34 | }
35 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
36 | this->_state = MQTT_DISCONNECTED;
37 | setServer(addr, port);
38 | setCallback(callback);
39 | setClient(client);
40 | this->stream = NULL;
41 | }
42 | PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
43 | this->_state = MQTT_DISCONNECTED;
44 | setServer(addr,port);
45 | setCallback(callback);
46 | setClient(client);
47 | setStream(stream);
48 | }
49 |
50 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
51 | this->_state = MQTT_DISCONNECTED;
52 | setServer(ip, port);
53 | setClient(client);
54 | this->stream = NULL;
55 | }
56 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) {
57 | this->_state = MQTT_DISCONNECTED;
58 | setServer(ip,port);
59 | setClient(client);
60 | setStream(stream);
61 | }
62 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
63 | this->_state = MQTT_DISCONNECTED;
64 | setServer(ip, port);
65 | setCallback(callback);
66 | setClient(client);
67 | this->stream = NULL;
68 | }
69 | PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
70 | this->_state = MQTT_DISCONNECTED;
71 | setServer(ip,port);
72 | setCallback(callback);
73 | setClient(client);
74 | setStream(stream);
75 | }
76 |
77 | PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
78 | this->_state = MQTT_DISCONNECTED;
79 | setServer(domain,port);
80 | setClient(client);
81 | this->stream = NULL;
82 | }
83 | PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) {
84 | this->_state = MQTT_DISCONNECTED;
85 | setServer(domain,port);
86 | setClient(client);
87 | setStream(stream);
88 | }
89 | PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
90 | this->_state = MQTT_DISCONNECTED;
91 | setServer(domain,port);
92 | setCallback(callback);
93 | setClient(client);
94 | this->stream = NULL;
95 | }
96 | PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
97 | this->_state = MQTT_DISCONNECTED;
98 | setServer(domain,port);
99 | setCallback(callback);
100 | setClient(client);
101 | setStream(stream);
102 | }
103 |
104 | boolean PubSubClient::connect(const char *id) {
105 | return connect(id,NULL,NULL,0,0,0,0);
106 | }
107 |
108 | boolean PubSubClient::connect(const char *id, const char *user, const char *pass) {
109 | return connect(id,user,pass,0,0,0,0);
110 | }
111 |
112 | boolean PubSubClient::connect(const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
113 | return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage);
114 | }
115 |
116 | boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
117 | if (!connected()) {
118 | int result = 0;
119 |
120 | if (domain != NULL) {
121 | result = _client->connect(this->domain, this->port);
122 | } else {
123 | result = _client->connect(this->ip, this->port);
124 | }
125 | if (result == 1) {
126 | nextMsgId = 1;
127 | // Leave room in the buffer for header and variable length field
128 | uint16_t length = 5;
129 | unsigned int j;
130 |
131 | #if MQTT_VERSION == MQTT_VERSION_3_1
132 | uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p', MQTT_VERSION};
133 | #define MQTT_HEADER_VERSION_LENGTH 9
134 | #elif MQTT_VERSION == MQTT_VERSION_3_1_1
135 | uint8_t d[7] = {0x00,0x04,'M','Q','T','T',MQTT_VERSION};
136 | #define MQTT_HEADER_VERSION_LENGTH 7
137 | #endif
138 | for (j = 0;j>1);
154 | }
155 | }
156 |
157 | buffer[length++] = v;
158 |
159 | buffer[length++] = ((MQTT_KEEPALIVE) >> 8);
160 | buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF);
161 | length = writeString(id,buffer,length);
162 | if (willTopic) {
163 | length = writeString(willTopic,buffer,length);
164 | length = writeString(willMessage,buffer,length);
165 | }
166 |
167 | if(user != NULL) {
168 | length = writeString(user,buffer,length);
169 | if(pass != NULL) {
170 | length = writeString(pass,buffer,length);
171 | }
172 | }
173 |
174 | write(MQTTCONNECT,buffer,length-5);
175 |
176 | lastInActivity = lastOutActivity = millis();
177 |
178 | while (!_client->available()) {
179 | unsigned long t = millis();
180 | if (t-lastInActivity >= ((int32_t) MQTT_SOCKET_TIMEOUT*1000UL)) {
181 | _state = MQTT_CONNECTION_TIMEOUT;
182 | _client->stop();
183 | return false;
184 | }
185 | }
186 | uint8_t llen;
187 | uint16_t len = readPacket(&llen);
188 |
189 | if (len == 4) {
190 | if (buffer[3] == 0) {
191 | lastInActivity = millis();
192 | pingOutstanding = false;
193 | _state = MQTT_CONNECTED;
194 | return true;
195 | } else {
196 | _state = buffer[3];
197 | }
198 | }
199 | _client->stop();
200 | } else {
201 | _state = MQTT_CONNECT_FAILED;
202 | }
203 | return false;
204 | }
205 | return true;
206 | }
207 |
208 | // reads a byte into result
209 | boolean PubSubClient::readByte(uint8_t * result) {
210 | uint32_t previousMillis = millis();
211 | while(!_client->available()) {
212 | uint32_t currentMillis = millis();
213 | if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){
214 | return false;
215 | }
216 | }
217 | *result = _client->read();
218 | return true;
219 | }
220 |
221 | // reads a byte into result[*index] and increments index
222 | boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){
223 | uint16_t current_index = *index;
224 | uint8_t * write_address = &(result[current_index]);
225 | if(readByte(write_address)){
226 | *index = current_index + 1;
227 | return true;
228 | }
229 | return false;
230 | }
231 |
232 | uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
233 | uint16_t len = 0;
234 | if(!readByte(buffer, &len)) return 0;
235 | bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH;
236 | uint32_t multiplier = 1;
237 | uint16_t length = 0;
238 | uint8_t digit = 0;
239 | uint16_t skip = 0;
240 | uint8_t start = 0;
241 |
242 | do {
243 | if(!readByte(&digit)) return 0;
244 | buffer[len++] = digit;
245 | length += (digit & 127) * multiplier;
246 | multiplier *= 128;
247 | } while ((digit & 128) != 0);
248 | *lengthLength = len-1;
249 |
250 | if (isPublish) {
251 | // Read in topic length to calculate bytes to skip over for Stream writing
252 | if(!readByte(buffer, &len)) return 0;
253 | if(!readByte(buffer, &len)) return 0;
254 | skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2];
255 | start = 2;
256 | if (buffer[0]&MQTTQOS1) {
257 | // skip message id
258 | skip += 2;
259 | }
260 | }
261 |
262 | for (uint16_t i = start;istream) {
265 | if (isPublish && len-*lengthLength-2>skip) {
266 | this->stream->write(digit);
267 | }
268 | }
269 | if (len < MQTT_MAX_PACKET_SIZE) {
270 | buffer[len] = digit;
271 | }
272 | len++;
273 | }
274 |
275 | if (!this->stream && len > MQTT_MAX_PACKET_SIZE) {
276 | len = 0; // This will cause the packet to be ignored.
277 | }
278 |
279 | return len;
280 | }
281 |
282 | boolean PubSubClient::loop() {
283 | if (connected()) {
284 | unsigned long t = millis();
285 | if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) {
286 | if (pingOutstanding) {
287 | this->_state = MQTT_CONNECTION_TIMEOUT;
288 | _client->stop();
289 | return false;
290 | } else {
291 | buffer[0] = MQTTPINGREQ;
292 | buffer[1] = 0;
293 | _client->write(buffer,2);
294 | lastOutActivity = t;
295 | lastInActivity = t;
296 | pingOutstanding = true;
297 | }
298 | }
299 | if (_client->available()) {
300 | uint8_t llen;
301 | uint16_t len = readPacket(&llen);
302 | uint16_t msgId = 0;
303 | uint8_t *payload;
304 | if (len > 0) {
305 | lastInActivity = t;
306 | uint8_t type = buffer[0]&0xF0;
307 | if (type == MQTTPUBLISH) {
308 | if (callback) {
309 | uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2];
310 | char topic[tl+1];
311 | for (uint16_t i=0;i0
316 | if ((buffer[0]&0x06) == MQTTQOS1) {
317 | msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1];
318 | payload = buffer+llen+3+tl+2;
319 | callback(topic,payload,len-llen-3-tl-2);
320 |
321 | buffer[0] = MQTTPUBACK;
322 | buffer[1] = 2;
323 | buffer[2] = (msgId >> 8);
324 | buffer[3] = (msgId & 0xFF);
325 | _client->write(buffer,4);
326 | lastOutActivity = t;
327 |
328 | } else {
329 | payload = buffer+llen+3+tl;
330 | callback(topic,payload,len-llen-3-tl);
331 | }
332 | }
333 | } else if (type == MQTTPINGREQ) {
334 | buffer[0] = MQTTPINGRESP;
335 | buffer[1] = 0;
336 | _client->write(buffer,2);
337 | } else if (type == MQTTPINGRESP) {
338 | pingOutstanding = false;
339 | }
340 | }
341 | }
342 | return true;
343 | }
344 | return false;
345 | }
346 |
347 | boolean PubSubClient::publish(const char* topic, const char* payload) {
348 | return publish(topic,(const uint8_t*)payload,strlen(payload),false);
349 | }
350 |
351 | boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
352 | return publish(topic,(const uint8_t*)payload,strlen(payload),retained);
353 | }
354 |
355 | boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) {
356 | return publish(topic, payload, plength, false);
357 | }
358 |
359 | boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
360 | if (connected()) {
361 | if (MQTT_MAX_PACKET_SIZE < 5 + 2+strlen(topic) + plength) {
362 | // Too long
363 | return false;
364 | }
365 | // Leave room in the buffer for header and variable length field
366 | uint16_t length = 5;
367 | length = writeString(topic,buffer,length);
368 | uint16_t i;
369 | for (i=0;i 0) {
407 | digit |= 0x80;
408 | }
409 | buffer[pos++] = digit;
410 | llen++;
411 | } while(len>0);
412 |
413 | pos = writeString(topic,buffer,pos);
414 |
415 | rc += _client->write(buffer,pos);
416 |
417 | for (i=0;iwrite((char)pgm_read_byte_near(payload + i));
419 | }
420 |
421 | lastOutActivity = millis();
422 |
423 | return rc == tlen + 4 + plength;
424 | }
425 |
426 | boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
427 | uint8_t lenBuf[4];
428 | uint8_t llen = 0;
429 | uint8_t digit;
430 | uint8_t pos = 0;
431 | uint16_t rc;
432 | uint16_t len = length;
433 | do {
434 | digit = len % 128;
435 | len = len / 128;
436 | if (len > 0) {
437 | digit |= 0x80;
438 | }
439 | lenBuf[pos++] = digit;
440 | llen++;
441 | } while(len>0);
442 |
443 | buf[4-llen] = header;
444 | for (int i=0;i 0) && result) {
454 | bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining;
455 | rc = _client->write(writeBuf,bytesToWrite);
456 | result = (rc == bytesToWrite);
457 | bytesRemaining -= rc;
458 | writeBuf += rc;
459 | }
460 | return result;
461 | #else
462 | rc = _client->write(buf+(4-llen),length+1+llen);
463 | lastOutActivity = millis();
464 | return (rc == 1+llen+length);
465 | #endif
466 | }
467 |
468 | boolean PubSubClient::subscribe(const char* topic) {
469 | return subscribe(topic, 0);
470 | }
471 |
472 | boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
473 | if (qos < 0 || qos > 1) {
474 | return false;
475 | }
476 | if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
477 | // Too long
478 | return false;
479 | }
480 | if (connected()) {
481 | // Leave room in the buffer for header and variable length field
482 | uint16_t length = 5;
483 | nextMsgId++;
484 | if (nextMsgId == 0) {
485 | nextMsgId = 1;
486 | }
487 | buffer[length++] = (nextMsgId >> 8);
488 | buffer[length++] = (nextMsgId & 0xFF);
489 | length = writeString((char*)topic, buffer,length);
490 | buffer[length++] = qos;
491 | return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-5);
492 | }
493 | return false;
494 | }
495 |
496 | boolean PubSubClient::unsubscribe(const char* topic) {
497 | if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
498 | // Too long
499 | return false;
500 | }
501 | if (connected()) {
502 | uint16_t length = 5;
503 | nextMsgId++;
504 | if (nextMsgId == 0) {
505 | nextMsgId = 1;
506 | }
507 | buffer[length++] = (nextMsgId >> 8);
508 | buffer[length++] = (nextMsgId & 0xFF);
509 | length = writeString(topic, buffer,length);
510 | return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-5);
511 | }
512 | return false;
513 | }
514 |
515 | void PubSubClient::disconnect() {
516 | buffer[0] = MQTTDISCONNECT;
517 | buffer[1] = 0;
518 | _client->write(buffer,2);
519 | _state = MQTT_DISCONNECTED;
520 | _client->stop();
521 | lastInActivity = lastOutActivity = millis();
522 | }
523 |
524 | uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t pos) {
525 | const char* idp = string;
526 | uint16_t i = 0;
527 | pos += 2;
528 | while (*idp) {
529 | buf[pos++] = *idp++;
530 | i++;
531 | }
532 | buf[pos-i-2] = (i >> 8);
533 | buf[pos-i-1] = (i & 0xFF);
534 | return pos;
535 | }
536 |
537 |
538 | boolean PubSubClient::connected() {
539 | boolean rc;
540 | if (_client == NULL ) {
541 | rc = false;
542 | } else {
543 | rc = (int)_client->connected();
544 | if (!rc) {
545 | if (this->_state == MQTT_CONNECTED) {
546 | this->_state = MQTT_CONNECTION_LOST;
547 | _client->flush();
548 | _client->stop();
549 | }
550 | }
551 | }
552 | return rc;
553 | }
554 |
555 | PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
556 | IPAddress addr(ip[0],ip[1],ip[2],ip[3]);
557 | return setServer(addr,port);
558 | }
559 |
560 | PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) {
561 | this->ip = ip;
562 | this->port = port;
563 | this->domain = NULL;
564 | return *this;
565 | }
566 |
567 | PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) {
568 | this->domain = domain;
569 | this->port = port;
570 | return *this;
571 | }
572 |
573 | PubSubClient& PubSubClient::setCallback(MQTT_CALLBACK_SIGNATURE) {
574 | this->callback = callback;
575 | return *this;
576 | }
577 |
578 | PubSubClient& PubSubClient::setClient(Client& client){
579 | this->_client = &client;
580 | return *this;
581 | }
582 |
583 | PubSubClient& PubSubClient::setStream(Stream& stream){
584 | this->stream = &stream;
585 | return *this;
586 | }
587 |
588 | int PubSubClient::state() {
589 | return this->_state;
590 | }
591 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/PubSubClient/src/PubSubClient.h:
--------------------------------------------------------------------------------
1 | /*
2 | PubSubClient.h - A simple client for MQTT.
3 | Nick O'Leary
4 | http://knolleary.net
5 | */
6 |
7 | #ifndef PubSubClient_h
8 | #define PubSubClient_h
9 |
10 | #include
11 | #include "IPAddress.h"
12 | #include "Client.h"
13 | #include "Stream.h"
14 |
15 | #define MQTT_VERSION_3_1 3
16 | #define MQTT_VERSION_3_1_1 4
17 |
18 | // MQTT_VERSION : Pick the version
19 | //#define MQTT_VERSION MQTT_VERSION_3_1
20 | #ifndef MQTT_VERSION
21 | #define MQTT_VERSION MQTT_VERSION_3_1_1
22 | #endif
23 |
24 | // MQTT_MAX_PACKET_SIZE : Maximum packet size
25 | #ifndef MQTT_MAX_PACKET_SIZE
26 | #define MQTT_MAX_PACKET_SIZE 512
27 | #endif
28 |
29 | // MQTT_KEEPALIVE : keepAlive interval in Seconds
30 | #ifndef MQTT_KEEPALIVE
31 | #define MQTT_KEEPALIVE 60
32 | #endif
33 |
34 | // MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds
35 | #ifndef MQTT_SOCKET_TIMEOUT
36 | #define MQTT_SOCKET_TIMEOUT 15
37 | #endif
38 |
39 | // MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client
40 | // in each write call. Needed for the Arduino Wifi Shield. Leave undefined to
41 | // pass the entire MQTT packet in each write call.
42 | //#define MQTT_MAX_TRANSFER_SIZE 80
43 |
44 | // Possible values for client.state()
45 | #define MQTT_CONNECTION_TIMEOUT -4
46 | #define MQTT_CONNECTION_LOST -3
47 | #define MQTT_CONNECT_FAILED -2
48 | #define MQTT_DISCONNECTED -1
49 | #define MQTT_CONNECTED 0
50 | #define MQTT_CONNECT_BAD_PROTOCOL 1
51 | #define MQTT_CONNECT_BAD_CLIENT_ID 2
52 | #define MQTT_CONNECT_UNAVAILABLE 3
53 | #define MQTT_CONNECT_BAD_CREDENTIALS 4
54 | #define MQTT_CONNECT_UNAUTHORIZED 5
55 |
56 | #define MQTTCONNECT 1 << 4 // Client request to connect to Server
57 | #define MQTTCONNACK 2 << 4 // Connect Acknowledgment
58 | #define MQTTPUBLISH 3 << 4 // Publish message
59 | #define MQTTPUBACK 4 << 4 // Publish Acknowledgment
60 | #define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1)
61 | #define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2)
62 | #define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3)
63 | #define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request
64 | #define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment
65 | #define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request
66 | #define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment
67 | #define MQTTPINGREQ 12 << 4 // PING Request
68 | #define MQTTPINGRESP 13 << 4 // PING Response
69 | #define MQTTDISCONNECT 14 << 4 // Client is Disconnecting
70 | #define MQTTReserved 15 << 4 // Reserved
71 |
72 | #define MQTTQOS0 (0 << 1)
73 | #define MQTTQOS1 (1 << 1)
74 | #define MQTTQOS2 (2 << 1)
75 |
76 | #ifdef ESP8266
77 | #include
78 | #define MQTT_CALLBACK_SIGNATURE std::function callback
79 | #else
80 | #define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int)
81 | #endif
82 |
83 | class PubSubClient {
84 | private:
85 | Client* _client;
86 | uint8_t buffer[MQTT_MAX_PACKET_SIZE];
87 | uint16_t nextMsgId;
88 | unsigned long lastOutActivity;
89 | unsigned long lastInActivity;
90 | bool pingOutstanding;
91 | MQTT_CALLBACK_SIGNATURE;
92 | uint16_t readPacket(uint8_t*);
93 | boolean readByte(uint8_t * result);
94 | boolean readByte(uint8_t * result, uint16_t * index);
95 | boolean write(uint8_t header, uint8_t* buf, uint16_t length);
96 | uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos);
97 | IPAddress ip;
98 | const char* domain;
99 | uint16_t port;
100 | Stream* stream;
101 | int _state;
102 | public:
103 | PubSubClient();
104 | PubSubClient(Client& client);
105 | PubSubClient(IPAddress, uint16_t, Client& client);
106 | PubSubClient(IPAddress, uint16_t, Client& client, Stream&);
107 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
108 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
109 | PubSubClient(uint8_t *, uint16_t, Client& client);
110 | PubSubClient(uint8_t *, uint16_t, Client& client, Stream&);
111 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
112 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
113 | PubSubClient(const char*, uint16_t, Client& client);
114 | PubSubClient(const char*, uint16_t, Client& client, Stream&);
115 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
116 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
117 |
118 | PubSubClient& setServer(IPAddress ip, uint16_t port);
119 | PubSubClient& setServer(uint8_t * ip, uint16_t port);
120 | PubSubClient& setServer(const char * domain, uint16_t port);
121 | PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE);
122 | PubSubClient& setClient(Client& client);
123 | PubSubClient& setStream(Stream& stream);
124 |
125 | boolean connect(const char* id);
126 | boolean connect(const char* id, const char* user, const char* pass);
127 | boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
128 | boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
129 | void disconnect();
130 | boolean publish(const char* topic, const char* payload);
131 | boolean publish(const char* topic, const char* payload, boolean retained);
132 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
133 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
134 | boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
135 | boolean subscribe(const char* topic);
136 | boolean subscribe(const char* topic, uint8_t qos);
137 | boolean unsubscribe(const char* topic);
138 | boolean loop();
139 | boolean connected();
140 | int state();
141 | };
142 |
143 |
144 | #endif
145 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/WifiManager/.library.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "WifiManager",
3 | "repository": {
4 | "url": "https://github.com/tzapu/WiFiManager.git",
5 | "type": "git"
6 | },
7 | "platforms": [
8 | "espressif8266"
9 | ],
10 | "frameworks": [
11 | "arduino"
12 | ],
13 | "version": "0.12",
14 | "authors": [
15 | {
16 | "maintainer": false,
17 | "name": "tzapu",
18 | "url": "https://github.com/tzapu",
19 | "email": null
20 | }
21 | ],
22 | "keywords": [
23 | "wifi",
24 | "wi-fi"
25 | ],
26 | "id": 567,
27 | "description": "ESP8266 WiFi Connection manager with fallback web configuration portal"
28 | }
--------------------------------------------------------------------------------
/airmonitor_device/lib/WifiManager/.travis.yml:
--------------------------------------------------------------------------------
1 | language: c
2 | before_install:
3 | - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
4 | - sleep 3
5 | - export DISPLAY=:1.0
6 | - wget http://downloads.arduino.cc/arduino-1.6.5-linux64.tar.xz
7 | - tar xf arduino-1.6.5-linux64.tar.xz
8 | - sudo mv arduino-1.6.5 /usr/local/share/arduino
9 | - sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino
10 | install:
11 | - ln -s $PWD /usr/local/share/arduino/libraries/WiFiManager
12 | # boards manager not working on 1.6.7 - 1.6.8
13 | - arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json" --save-prefs
14 | # install lib arduino json not working in 1.6.5
15 | # - arduino --install-library "ArduinoJson"
16 | - git clone https://github.com/bblanchon/ArduinoJson /usr/local/share/arduino/libraries/ArduinoJson
17 | - arduino --install-boards esp8266:esp8266
18 | - arduino --board esp8266:esp8266:generic --save-prefs
19 | - arduino --pref "compiler.warning_level=all" --save-prefs
20 | script:
21 | - "echo $PWD"
22 | - "echo $HOME"
23 | - "ls $PWD"
24 | - source $TRAVIS_BUILD_DIR/travis/common.sh
25 | - build_examples
26 | # - "cat $PWD/examples/AutoConnect/AutoConnect.ino"
27 | # - arduino -v --verbose-build --verify $PWD/examples/AutoConnect/AutoConnect.ino
28 | # - arduino --verify --board arduino:avr:uno $PWD/examples/IncomingCall/IncomingCall.ino
29 | # - arduino --verify --board arduino:avr:uno $PWD/examples/AdafruitIO_GPS/AdafruitIO_GPS.ino
30 | notifications:
31 | email:
32 | on_success: change
33 | on_failure: change
34 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/WifiManager/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 tzapu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/WifiManager/README.md:
--------------------------------------------------------------------------------
1 | # WiFiManager
2 | ESP8266 WiFi Connection manager with fallback web configuration portal
3 |
4 | [](https://travis-ci.org/tzapu/WiFiManager)
5 |
6 | The configuration portal is of the captive variety, so on various devices it will present the configuration dialogue as soon as you connect to the created access point.
7 |
8 | First attempt at a library. Lots more changes and fixes to do. Contributions are welcome.
9 |
10 | #### This works with the ESP8266 Arduino platform with a recent stable release(2.0.0 or newer) https://github.com/esp8266/Arduino
11 |
12 | ## Contents
13 | - [How it works](#how-it-works)
14 | - [Wishlist](#wishlist)
15 | - [Quick start](#quick-start)
16 | - Installing
17 | - [Through Library Manager](#install-through-library-manager)
18 | - [From Github](#checkout-from-github)
19 | - [Using](#using)
20 | - [Documentation](#documentation)
21 | - [Access Point Password](#password-protect-the-configuration-access-point)
22 | - [Callbacks](#callbacks)
23 | - [Configuration Portal Timeout](#configuration-portal-timeout)
24 | - [On Demand Configuration](#on-demand-configuration-portal)
25 | - [Custom Parameters](#custom-parameters)
26 | - [Custom IP Configuration](#custom-ip-configuration)
27 | - [Filter Low Quality Networks](#filter-networks)
28 | - [Debug Output](#debug)
29 | - [Troubleshooting](#troubleshooting)
30 | - [Releases](#releases)
31 | - [Contributors](#contributions-and-thanks)
32 |
33 |
34 | ## How It Works
35 | - when your ESP starts up, it sets it up in Station mode and tries to connect to a previously saved Access Point
36 | - if this is unsuccessful (or no previous network saved) it moves the ESP into Access Point mode and spins up a DNS and WebServer (default ip 192.168.4.1)
37 | - using any wifi enabled device with a browser (computer, phone, tablet) connect to the newly created Access Point
38 | - because of the Captive Portal and the DNS server you will either get a 'Join to network' type of popup or get any domain you try to access redirected to the configuration portal
39 | - choose one of the access points scanned, enter password, click save
40 | - ESP will try to connect. If successful, it relinquishes control back to your app. If not, reconnect to AP and reconfigure.
41 |
42 | ## How It Looks
43 |  
44 |
45 | ## Wishlist
46 | - ~~remove dependency on EEPROM library~~
47 | - ~~move HTML Strings to PROGMEM~~
48 | - ~~cleanup and streamline code~~ (although this is ongoing)
49 | - if timeout is set, extend it when a page is fetched in AP mode
50 | - ~~add ability to configure more parameters than ssid/password~~
51 | - ~~maybe allow setting ip of ESP after reboot~~
52 | - ~~add to Arduino Library Manager~~
53 | - ~~add to PlatformIO~~
54 | - add multiple sets of network credentials
55 | - ~~allow users to customize CSS~~
56 |
57 | ## Quick Start
58 |
59 | ### Installing
60 | You can either install through the Arduino Library Manager or checkout the latest changes or a release from github
61 |
62 | #### Install through Library Manager
63 | __Currently version 0.8+ works with release 2.0.0 or newer of the [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)__
64 | - in Arduino IDE got to Sketch/Include Library/Manage Libraries
65 | 
66 |
67 | - search for WiFiManager
68 | 
69 |
70 | - click Install and start [using it](#using)
71 |
72 | #### Checkout from github
73 | __Github version works with release 2.0.0 or newer of the [ESP8266 core for Arduino](https://github.com/esp8266/Arduino)__
74 | - Checkout library to your Arduino libraries folder
75 |
76 | ### Using
77 | - Include in your sketch
78 | ```cpp
79 | #include //ESP8266 Core WiFi Library (you most likely already have this in your sketch)
80 |
81 | #include //Local DNS Server used for redirecting all requests to the configuration portal
82 | #include //Local WebServer used to serve the configuration portal
83 | #include //https://github.com/tzapu/WiFiManager WiFi Configuration Magic
84 | ```
85 |
86 | - Initialize library, in your setup function add
87 | ```cpp
88 | WiFiManager wifiManager;
89 | ```
90 |
91 | - Also in the setup function add
92 | ```cpp
93 | //first parameter is name of access point, second is the password
94 | wifiManager.autoConnect("AP-NAME", "AP-PASSWORD");
95 | ```
96 | if you just want an unsecured access point
97 | ```cpp
98 | wifiManager.autoConnect("AP-NAME");
99 | ```
100 | or if you want to use and auto generated name from 'ESP' and the esp's Chip ID use
101 | ```cpp
102 | wifiManager.autoConnect();
103 | ```
104 |
105 | After you write your sketch and start the ESP, it will try to connect to WiFi. If it fails it starts in Access Point mode.
106 | While in AP mode, connect to it then open a browser to the gateway IP, default 192.168.4.1, configure wifi, save and it should reboot and connect.
107 |
108 | Also see [examples](https://github.com/tzapu/WiFiManager/tree/master/examples).
109 |
110 | ## Documentation
111 |
112 | #### Password protect the configuration Access Point
113 | You can and should password protect the configuration access point. Simply add the password as a second parameter to `autoConnect`.
114 | A short password seems to have unpredictable results so use one that's around 8 characters or more in length.
115 | The guidelines are that a wifi password must consist of 8 to 63 ASCII-encoded characters in the range of 32 to 126 (decimal)
116 | ```cpp
117 | wifiManager.autoConnect("AutoConnectAP", "password")
118 | ```
119 |
120 | #### Callbacks
121 | ##### Enter Config mode
122 | Use this if you need to do something when your device enters configuration mode on failed WiFi connection attempt.
123 | Before `autoConnect()`
124 | ```cpp
125 | wifiManager.setAPCallback(configModeCallback);
126 | ```
127 | `configModeCallback` declaration and example
128 | ```cpp
129 | void configModeCallback (WiFiManager *myWiFiManager) {
130 | Serial.println("Entered config mode");
131 | Serial.println(WiFi.softAPIP());
132 |
133 | Serial.println(myWiFiManager->getConfigPortalSSID());
134 | }
135 | ```
136 |
137 | ##### Save settings
138 | This gets called when custom parameters have been set **AND** a connection has been established. Use it to set a flag, so when all the configuration finishes, you can save the extra parameters somewhere.
139 |
140 | See [AutoConnectWithFSParameters Example](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters).
141 | ```cpp
142 | wifiManager.setSaveConfigCallback(saveConfigCallback);
143 | ```
144 | `saveConfigCallback` declaration and example
145 | ```cpp
146 | //flag for saving data
147 | bool shouldSaveConfig = false;
148 |
149 | //callback notifying us of the need to save config
150 | void saveConfigCallback () {
151 | Serial.println("Should save config");
152 | shouldSaveConfig = true;
153 | }
154 | ```
155 |
156 | #### Configuration Portal Timeout
157 | If you need to set a timeout so the ESP doesn't hang waiting to be configured, for instance after a power failure, you can add
158 | ```cpp
159 | wifiManager.setConfigPortalTimeout(180);
160 | ```
161 | which will wait 3 minutes (180 seconds). When the time passes, the autoConnect function will return, no matter the outcome.
162 | Check for connection and if it's still not established do whatever is needed (on some modules I restart them to retry, on others I enter deep sleep)
163 |
164 | #### On Demand Configuration Portal
165 | If you would rather start the configuration portal on demand rather than automatically on a failed connection attempt, then this is for you.
166 |
167 | Instead of calling `autoConnect()` which does all the connecting and failover configuration portal setup for you, you need to use `startConfigPortal()`. __Do not use BOTH.__
168 |
169 | Example usage
170 | ```cpp
171 | void loop() {
172 | // is configuration portal requested?
173 | if ( digitalRead(TRIGGER_PIN) == LOW ) {
174 | WiFiManager wifiManager;
175 | wifiManager.startConfigPortal("OnDemandAP");
176 | Serial.println("connected...yeey :)");
177 | }
178 | }
179 | ```
180 | See example for a more complex version. [OnDemandConfigPortal](https://github.com/tzapu/WiFiManager/tree/master/examples/OnDemandConfigPortal)
181 |
182 | #### Custom Parameters
183 | You can use WiFiManager to collect more parameters than just SSID and password.
184 | This could be helpful for configuring stuff like MQTT host and port, [blynk](http://www.blynk.cc) or [emoncms](http://emoncms.org) tokens, just to name a few.
185 | **You are responsible for saving and loading these custom values.** The library just collects and displays the data for you as a convenience.
186 | Usage scenario would be:
187 | - load values from somewhere (EEPROM/FS) or generate some defaults
188 | - add the custom parameters to WiFiManager using
189 | ```cpp
190 | // id/name, placeholder/prompt, default, length
191 | WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
192 | wifiManager.addParameter(&custom_mqtt_server);
193 |
194 | ```
195 | - if connection to AP fails, configuration portal starts and you can set /change the values (or use on demand configuration portal)
196 | - once configuration is done and connection is established [save config callback]() is called
197 | - once WiFiManager returns control to your application, read and save the new values using the `WiFiManagerParameter` object.
198 | ```cpp
199 | mqtt_server = custom_mqtt_server.getValue();
200 | ```
201 | This feature is a lot more involved than all the others, so here are some examples to fully show how it is done.
202 | You should also take a look at adding custom HTML to your form.
203 |
204 | - Save and load custom parameters to file system in json form [AutoConnectWithFSParameters](https://github.com/tzapu/WiFiManager/tree/master/examples/AutoConnectWithFSParameters)
205 | - *Save and load custom parameters to EEPROM* (not done yet)
206 |
207 | #### Custom IP Configuration
208 | You can set a custom IP for both AP (access point, config mode) and STA (station mode, client mode, normal project state)
209 |
210 | ##### Custom Access Point IP Configuration
211 | This will set your captive portal to a specific IP should you need/want such a feature. Add the following snippet before `autoConnect()`
212 | ```cpp
213 | //set custom ip for portal
214 | wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
215 | ```
216 |
217 | ##### Custom Station (client) Static IP Configuration
218 | This will make use the specified IP configuration instead of using DHCP in station mode.
219 | ```cpp
220 | wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,99), IPAddress(192,168,0,1), IPAddress(255,255,255,0));
221 | ```
222 | There are a couple of examples in the examples folder that show you how to set a static IP and even how to configure it through the web configuration portal.
223 |
224 | #### Custom HTML, CSS, Javascript
225 | There are various ways in which you can inject custom HTML, CSS or Javascript into the configuration portal.
226 | The options are:
227 | - inject custom head element
228 | You can use this to any html bit to the head of the configuration portal. If you add a `");
231 | ```
232 | - inject a custom bit of html in the configuration form
233 | ```cpp
234 | WiFiManagerParameter custom_text("
This is just a text paragraph
");
235 | wifiManager.addParameter(&custom_text);
236 | ```
237 | - inject a custom bit of html in a configuration form element
238 | Just add the bit you want added as the last parameter to the custom parameter constructor.
239 | ```cpp
240 | WiFiManagerParameter custom_mqtt_server("server", "mqtt server", "iot.eclipse", 40, " readonly");
241 | ```
242 |
243 | #### Filter Networks
244 | You can filter networks based on signal quality and show/hide duplicate networks.
245 |
246 | - If you would like to filter low signal quality networks you can tell WiFiManager to not show networks below an arbitrary quality %;
247 | ```cpp
248 | wifiManager.setMinimumSignalQuality(10);
249 | ```
250 | will not show networks under 10% signal quality. If you omit the parameter it defaults to 8%;
251 |
252 | - You can also remove or show duplicate networks (default is remove).
253 | Use this function to show (or hide) all networks.
254 | ```cpp
255 | wifiManager.setRemoveDuplicateAPs(false);
256 | ```
257 |
258 | #### Debug
259 | Debug is enabled by default on Serial. To disable add before autoConnect
260 | ```cpp
261 | wifiManager.setDebugOutput(false);
262 | ```
263 |
264 | ## Troubleshooting
265 | If you get compilation errors, more often than not, you may need to install a newer version of the ESP8266 core for Arduino.
266 |
267 | Changes added on 0.8 should make the latest trunk work without compilation errors. Tested down to ESP8266 core 2.0.0. **Please update to version 0.8**
268 |
269 | I am trying to keep releases working with release versions of the core, so they can be installed through boards manager, but if you checkout the latest version directly from github, sometimes, the library will only work if you update the ESP8266 core to the latest version because I am using some newly added function.
270 |
271 | If you connect to the created configuration Access Point but the configuration portal does not show up, just open a browser and type in the IP of the web portal, by default `192.168.4.1`.
272 |
273 | If trying to connect ends up in an endless loop, try to add `setConnectTimeout(60)` before `autoConnect();`. The parameter is timeout to try connecting in seconds.
274 |
275 | ## Releases
276 | #### 0.12
277 | - removed 204 header response
278 | - fixed incompatibility with other libs using isnan and other std:: functions without namespace
279 |
280 | ##### 0.11
281 | - a lot more reliable reconnecting to networks
282 | - custom html in custom parameters (for read only params)
283 | - custom html in custom parameter form (like labels)
284 | - custom head element (like custom css)
285 | - sort networks based on signal quality
286 | - remove duplicate networks
287 |
288 | ##### 0.10
289 | - some css changes
290 | - bug fixes and speed improvements
291 | - added an alternative to waitForConnectResult() for debugging
292 | - changed `setTimeout(seconds)` to `setConfigPortalTimeout(seconds)`
293 |
294 | ##### 0.9
295 | - fixed support for encoded characters in ssid/pass
296 |
297 | ##### 0.8
298 | - made it compile on older versions of ESP8266 core as well, tested down to 2.0.0
299 | - added simple example for Custom IP
300 |
301 | ##### 0.7
302 | - added static IP in station mode
303 | - added example of persisting custom IP to FS config.json
304 | - more option on portal homepage
305 | - added on PlatformIO
306 |
307 | ##### 0.6
308 | - custom parameters
309 | - prettier
310 | - on demand config portal
311 | - commit #100 :D
312 |
313 | ##### 0.5
314 | - Added to Arduino Boards Manager - Thanks Max
315 | - moved most stuff to PROGMEM
316 | - added signal quality and a nice little padlock to show which networks are encrypted
317 |
318 | ##### v0.4 - all of it user contributed changes - Thank you
319 | - added ability to password protect the configuration Access Point
320 | - callback for enter configuration mode
321 | - memory allocation improvements
322 |
323 | ##### v0.3
324 | - removed the need for EEPROM and works with the 2.0.0 and above stable release of the ESP8266 for Arduino IDE package
325 | - removed restart on save of credentials
326 | - updated examples
327 |
328 | ##### v0.2
329 | needs the latest staging version (or at least a recent release of the staging version) to work
330 |
331 | ##### v0.1
332 | works with the staging release ver. 1.6.5-1044-g170995a, built on Aug 10, 2015 of the ESP8266 Arduino library.
333 |
334 |
335 | ### Contributions and thanks
336 | The support and help I got from the community has been nothing short of phenomenal. I can't thank you guys enough. This is my first real attept in developing open source stuff and I must say, now I understand why people are so dedicated to it, it is because of all the wonderful people involved.
337 |
338 | __THANK YOU__
339 |
340 | [Shawn A](https://github.com/tablatronix)
341 |
342 | [Maximiliano Duarte](https://github.com/domonetic)
343 |
344 | [alltheblinkythings](https://github.com/alltheblinkythings)
345 |
346 | [Niklas Wall](https://github.com/niklaswall)
347 |
348 | [Jakub Piasecki](https://github.com/zaporylie)
349 |
350 | [Peter Allan](https://github.com/alwynallan)
351 |
352 | [John Little](https://github.com/j0hnlittle)
353 |
354 | [markaswift](https://github.com/markaswift)
355 |
356 | [franklinvv](https://github.com/franklinvv)
357 |
358 | [Alberto Ricci Bitti](https://github.com/riccibitti)
359 |
360 | [SebiPanther](https://github.com/SebiPanther)
361 |
362 | [jonathanendersby](https://github.com/jonathanendersby)
363 |
364 | [walthercarsten](https://github.com/walthercarsten)
365 |
366 | Sorry if i have missed anyone.
367 |
368 | #### Inspiration
369 | - http://www.esp8266.com/viewtopic.php?f=29&t=2520
370 |
--------------------------------------------------------------------------------
/airmonitor_device/lib/WifiManager/WiFiManager.h:
--------------------------------------------------------------------------------
1 | /**************************************************************
2 | WiFiManager is a library for the ESP8266/Arduino platform
3 | (https://github.com/esp8266/Arduino) to enable easy
4 | configuration and reconfiguration of WiFi credentials using a Captive Portal
5 | inspired by:
6 | http://www.esp8266.com/viewtopic.php?f=29&t=2520
7 | https://github.com/chriscook8/esp-arduino-apboot
8 | https://github.com/esp8266/Arduino/tree/esp8266/hardware/esp8266com/esp8266/libraries/DNSServer/examples/CaptivePortalAdvanced
9 | Built by AlexT https://github.com/tzapu
10 | Licensed under MIT license
11 | **************************************************************/
12 |
13 | #ifndef WiFiManager_h
14 | #define WiFiManager_h
15 |
16 | #include
17 | #include
18 | #include
19 | #include
20 |
21 | extern "C" {
22 | #include "user_interface.h"
23 | }
24 |
25 | const char HTTP_HEAD[] PROGMEM = "{v}";
26 | const char HTTP_STYLE[] PROGMEM = "";
27 | const char HTTP_SCRIPT[] PROGMEM = "";
28 | const char HTTP_HEAD_END[] PROGMEM = "