├── .gitattributes ├── .gitignore ├── .idea ├── IOT-ESP8266-Google-Home.iml ├── deployment.xml ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── vcs.xml └── workspace.xml ├── API.ai └── matrix-ai.zip ├── ArduinoJson ├── ArduinoJson.h ├── ArduinoJson.hpp └── ArduinoJson │ ├── Configuration.hpp │ ├── Data │ ├── Encoding.hpp │ ├── JsonBufferAllocated.hpp │ ├── JsonFloat.hpp │ ├── JsonInteger.hpp │ ├── JsonVariantAs.hpp │ ├── JsonVariantComparer.hpp │ ├── JsonVariantContent.hpp │ ├── JsonVariantDefault.hpp │ ├── JsonVariantType.hpp │ ├── List.hpp │ ├── ListConstIterator.hpp │ ├── ListIterator.hpp │ ├── ListNode.hpp │ ├── ReferenceType.hpp │ └── ValueSetter.hpp │ ├── Deserialization │ ├── Comments.hpp │ ├── JsonParser.hpp │ ├── JsonParserImpl.hpp │ └── StringWriter.hpp │ ├── DynamicJsonBuffer.hpp │ ├── JsonArray.hpp │ ├── JsonArrayImpl.hpp │ ├── JsonArraySubscript.hpp │ ├── JsonBuffer.hpp │ ├── JsonBufferBase.hpp │ ├── JsonBufferImpl.hpp │ ├── JsonObject.hpp │ ├── JsonObjectImpl.hpp │ ├── JsonObjectSubscript.hpp │ ├── JsonPair.hpp │ ├── JsonVariant.hpp │ ├── JsonVariantBase.hpp │ ├── JsonVariantComparisons.hpp │ ├── JsonVariantImpl.hpp │ ├── Polyfills │ ├── attributes.hpp │ ├── ctype.hpp │ ├── isFloat.hpp │ ├── isInteger.hpp │ ├── math.hpp │ ├── normalize.hpp │ ├── parseFloat.hpp │ └── parseInteger.hpp │ ├── RawJson.hpp │ ├── Serialization │ ├── DummyPrint.hpp │ ├── DynamicStringBuilder.hpp │ ├── IndentedPrint.hpp │ ├── JsonPrintable.hpp │ ├── JsonSerializer.hpp │ ├── JsonSerializerImpl.hpp │ ├── JsonWriter.hpp │ ├── Prettyfier.hpp │ ├── StaticStringBuilder.hpp │ └── StreamPrintAdapter.hpp │ ├── StaticJsonBuffer.hpp │ ├── StringTraits │ ├── ArduinoStream.hpp │ ├── CharPointer.hpp │ ├── FlashString.hpp │ ├── StdStream.hpp │ ├── StdString.hpp │ └── StringTraits.hpp │ └── TypeTraits │ ├── EnableIf.hpp │ ├── FloatTraits.hpp │ ├── IsArray.hpp │ ├── IsBaseOf.hpp │ ├── IsChar.hpp │ ├── IsConst.hpp │ ├── IsFloatingPoint.hpp │ ├── IsIntegral.hpp │ ├── IsSame.hpp │ ├── IsSignedIntegral.hpp │ ├── IsUnsignedIntegral.hpp │ ├── RemoveConst.hpp │ └── RemoveReference.hpp ├── ESP8266 └── WebSocketClient │ └── ESP8266_WebSocketClient │ └── ESP8266_WebSocketClient.ino ├── Procfile ├── README.md ├── app.json ├── app.py ├── arduinoWebSockets ├── .gitignore ├── LICENSE ├── README.md ├── examples │ ├── Nginx │ │ └── esp8266.ssl.reverse.proxy.conf │ ├── ParticleWebSocketClient │ │ └── application.cpp │ ├── WebSocketClient │ │ └── WebSocketClient.ino │ ├── WebSocketClientAVR │ │ └── WebSocketClientAVR.ino │ ├── WebSocketClientSSL │ │ └── WebSocketClientSSL.ino │ ├── WebSocketClientSocketIO │ │ └── WebSocketClientSocketIO.ino │ ├── WebSocketServer │ │ ├── WebSocketServer.ino │ │ ├── WebSocketServerFragmentation.ino │ │ └── WebSocketServerHttpHeaderValidation.ino │ └── WebSocketServer_LEDcontrol │ │ └── WebSocketServer_LEDcontrol.ino ├── library.json ├── library.properties ├── src │ ├── WebSockets.cpp │ ├── WebSockets.h │ ├── WebSocketsClient.cpp │ ├── WebSocketsClient.h │ ├── WebSocketsServer.cpp │ ├── WebSocketsServer.h │ ├── libb64 │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── cdecode.c │ │ ├── cdecode_inc.h │ │ ├── cencode.c │ │ └── cencode_inc.h │ └── libsha1 │ │ ├── libsha1.c │ │ └── libsha1.h └── tests │ ├── webSocket.html │ └── webSocketServer │ ├── index.js │ └── package.json ├── matrix-ai.zip ├── requirements.txt └── runtime.txt /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | test-env/ 49 | -------------------------------------------------------------------------------- /.idea/IOT-ESP8266-Google-Home.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/deployment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /API.ai/matrix-ai.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nassir-malik/IOT-ESP8266-Google-Home/d72b859894849fed2add3f75cdfd59edcd0fc461/API.ai/matrix-ai.zip -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson.h: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "ArduinoJson.hpp" 11 | 12 | using namespace ArduinoJson; 13 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "ArduinoJson/DynamicJsonBuffer.hpp" 11 | #include "ArduinoJson/JsonArray.hpp" 12 | #include "ArduinoJson/JsonObject.hpp" 13 | #include "ArduinoJson/JsonVariantComparisons.hpp" 14 | #include "ArduinoJson/StaticJsonBuffer.hpp" 15 | 16 | #include "ArduinoJson/Deserialization/JsonParserImpl.hpp" 17 | #include "ArduinoJson/JsonArrayImpl.hpp" 18 | #include "ArduinoJson/JsonBufferImpl.hpp" 19 | #include "ArduinoJson/JsonObjectImpl.hpp" 20 | #include "ArduinoJson/JsonVariantImpl.hpp" 21 | #include "ArduinoJson/Serialization/JsonSerializerImpl.hpp" 22 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Configuration.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | // enable deprecated functions by default 11 | #ifndef ARDUINOJSON_ENABLE_DEPRECATED 12 | #define ARDUINOJSON_ENABLE_DEPRECATED 1 13 | #endif 14 | 15 | #ifdef ARDUINO // assume this is an embedded platform 16 | 17 | // store using float instead of double to reduce the memory usage (issue #134) 18 | #ifndef ARDUINOJSON_USE_DOUBLE 19 | #define ARDUINOJSON_USE_DOUBLE 0 20 | #endif 21 | 22 | // store using a long because it usually match the size of a float. 23 | #ifndef ARDUINOJSON_USE_LONG_LONG 24 | #define ARDUINOJSON_USE_LONG_LONG 0 25 | #endif 26 | #ifndef ARDUINOJSON_USE_INT64 27 | #define ARDUINOJSON_USE_INT64 0 28 | #endif 29 | 30 | // Arduino has its own implementation of String to replace std::string 31 | #ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING 32 | #define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 33 | #endif 34 | 35 | #ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM 36 | #define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1 37 | #endif 38 | 39 | // On AVR archiecture, we can use PROGMEM 40 | #ifndef ARDUINOJSON_ENABLE_PROGMEM 41 | #ifdef PROGMEM 42 | #define ARDUINOJSON_ENABLE_PROGMEM 1 43 | #else 44 | #define ARDUINOJSON_ENABLE_PROGMEM 0 45 | #endif 46 | #endif 47 | 48 | // Arduino doesn't have std::string 49 | #ifndef ARDUINOJSON_ENABLE_STD_STRING 50 | #define ARDUINOJSON_ENABLE_STD_STRING 0 51 | #endif 52 | 53 | // Arduino doesn't support STL stream 54 | #ifndef ARDUINOJSON_ENABLE_STD_STREAM 55 | #define ARDUINOJSON_ENABLE_STD_STREAM 0 56 | #endif 57 | 58 | #ifndef ARDUINOJSON_ENABLE_ALIGNMENT 59 | #ifdef ARDUINO_ARCH_AVR 60 | // alignment isn't needed for 8-bit AVR 61 | #define ARDUINOJSON_ENABLE_ALIGNMENT 0 62 | #else 63 | // but must processor needs pointer to be align on word size 64 | #define ARDUINOJSON_ENABLE_ALIGNMENT 1 65 | #endif 66 | #endif 67 | 68 | // low value to prevent stack overflow 69 | #ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT 70 | #define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10 71 | #endif 72 | 73 | #else // assume this is a computer 74 | 75 | // on a computer we have plenty of memory so we can use doubles 76 | #ifndef ARDUINOJSON_USE_DOUBLE 77 | #define ARDUINOJSON_USE_DOUBLE 1 78 | #endif 79 | 80 | // use long long when available 81 | #ifndef ARDUINOJSON_USE_LONG_LONG 82 | #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800) 83 | #define ARDUINOJSON_USE_LONG_LONG 1 84 | #else 85 | #define ARDUINOJSON_USE_LONG_LONG 0 86 | #endif 87 | #endif 88 | 89 | // use _int64 on old versions of Visual Studio 90 | #ifndef ARDUINOJSON_USE_INT64 91 | #if defined(_MSC_VER) && _MSC_VER <= 1700 92 | #define ARDUINOJSON_USE_INT64 1 93 | #else 94 | #define ARDUINOJSON_USE_INT64 0 95 | #endif 96 | #endif 97 | 98 | // on a computer, we can use std::string 99 | #ifndef ARDUINOJSON_ENABLE_STD_STRING 100 | #define ARDUINOJSON_ENABLE_STD_STRING 1 101 | #endif 102 | 103 | // on a computer, there is no reason to beleive Arduino String is available 104 | #ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING 105 | #define ARDUINOJSON_ENABLE_ARDUINO_STRING 0 106 | #endif 107 | 108 | // PROGMEM is only available on AVR architecture 109 | #ifndef ARDUINOJSON_ENABLE_PROGMEM 110 | #define ARDUINOJSON_ENABLE_PROGMEM 0 111 | #endif 112 | 113 | // on a computer, we can assume that the STL is there 114 | #ifndef ARDUINOJSON_ENABLE_STD_STREAM 115 | #define ARDUINOJSON_ENABLE_STD_STREAM 1 116 | #endif 117 | 118 | // on a computer, there is no reason to beleive Arduino Stream is available 119 | #ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM 120 | #define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0 121 | #endif 122 | 123 | #ifndef ARDUINOJSON_ENABLE_ALIGNMENT 124 | // even if not required, most cpu's are faster with aligned pointers 125 | #define ARDUINOJSON_ENABLE_ALIGNMENT 1 126 | #endif 127 | 128 | // on a computer, we should have a lot of space on the stack 129 | #ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT 130 | #define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50 131 | #endif 132 | 133 | #endif 134 | 135 | #if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64 136 | #error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together 137 | #endif 138 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/Encoding.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | class Encoding { 14 | public: 15 | // Optimized for code size on a 8-bit AVR 16 | static char escapeChar(char c) { 17 | const char *p = escapeTable(false); 18 | while (p[0] && p[1] != c) { 19 | p += 2; 20 | } 21 | return p[0]; 22 | } 23 | 24 | // Optimized for code size on a 8-bit AVR 25 | static char unescapeChar(char c) { 26 | const char *p = escapeTable(true); 27 | for (;;) { 28 | if (p[0] == '\0') return c; 29 | if (p[0] == c) return p[1]; 30 | p += 2; 31 | } 32 | } 33 | 34 | private: 35 | static const char *escapeTable(bool excludeIdenticals) { 36 | return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0]; 37 | } 38 | }; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonBufferAllocated.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../JsonBuffer.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace Internals { 14 | 15 | class JsonBufferAllocated { 16 | public: 17 | void *operator new(size_t n, JsonBuffer *jsonBuffer) throw() { 18 | if (!jsonBuffer) return NULL; 19 | return jsonBuffer->alloc(n); 20 | } 21 | 22 | void operator delete(void *, JsonBuffer *)throw() {} 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonFloat.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../Configuration.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace Internals { 14 | 15 | #if ARDUINOJSON_USE_DOUBLE 16 | typedef double JsonFloat; 17 | #else 18 | typedef float JsonFloat; 19 | #endif 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonInteger.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../Configuration.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace Internals { 14 | 15 | #if ARDUINOJSON_USE_LONG_LONG 16 | typedef long long JsonInteger; 17 | typedef unsigned long long JsonUInt; 18 | #elif ARDUINOJSON_USE_INT64 19 | typedef __int64 JsonInteger; 20 | typedef unsigned _int64 JsonUInt; 21 | #else 22 | typedef long JsonInteger; 23 | typedef unsigned long JsonUInt; 24 | #endif 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonVariantAs.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | // A metafunction that returns the type of the value returned by 14 | // JsonVariant::as() 15 | template 16 | struct JsonVariantAs { 17 | typedef T type; 18 | }; 19 | 20 | template <> 21 | struct JsonVariantAs { 22 | typedef const char* type; 23 | }; 24 | 25 | template <> 26 | struct JsonVariantAs { 27 | typedef JsonArray& type; 28 | }; 29 | 30 | template <> 31 | struct JsonVariantAs { 32 | typedef const JsonArray& type; 33 | }; 34 | 35 | template <> 36 | struct JsonVariantAs { 37 | typedef JsonObject& type; 38 | }; 39 | 40 | template <> 41 | struct JsonVariantAs { 42 | typedef const JsonObject& type; 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonVariantComparer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../JsonVariantBase.hpp" 11 | #include "../StringTraits/StringTraits.hpp" 12 | #include "../TypeTraits/EnableIf.hpp" 13 | 14 | namespace ArduinoJson { 15 | namespace Internals { 16 | template 17 | struct JsonVariantComparer {}; 18 | 19 | template 20 | struct JsonVariantComparer< 21 | TString, 22 | typename TypeTraits::EnableIf::value>::type> { 23 | template 24 | static bool equals(const JsonVariantBase &variant, 25 | const TString &comparand) { 26 | const char *value = variant.template as(); 27 | return Internals::StringTraits::equals(comparand, value); 28 | } 29 | }; 30 | 31 | template 32 | struct JsonVariantComparer< 33 | TComparand, typename TypeTraits::EnableIf< 34 | !TypeTraits::IsVariant::value && 35 | !TypeTraits::IsString::value>::type> { 36 | template 37 | static bool equals(const JsonVariantBase &variant, 38 | const TComparand &comparand) { 39 | return variant.template as() == comparand; 40 | } 41 | }; 42 | 43 | template 44 | struct JsonVariantComparer::value>::type> { 47 | template 48 | static bool equals(const JsonVariantBase &left, 49 | const TVariant2 &right) { 50 | if (left.template is() && right.template is()) 51 | return left.template as() == right.template as(); 52 | if (left.template is() && right.template is()) 53 | return left.template as() == 54 | right.template as(); 55 | if (left.template is() && right.template is()) 56 | return left.template as() == right.template as(); 57 | if (left.template is() && right.template is()) 58 | return left.template as() == right.template as(); 59 | if (left.template is() && right.template is()) 60 | return left.template as() == right.template as(); 61 | if (left.template is() && right.template is()) 62 | return strcmp(left.template as(), right.template as()) == 63 | 0; 64 | 65 | return false; 66 | } 67 | }; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonVariantContent.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "JsonFloat.hpp" 11 | #include "JsonInteger.hpp" 12 | 13 | namespace ArduinoJson { 14 | 15 | // Forward declarations 16 | class JsonArray; 17 | class JsonObject; 18 | 19 | namespace Internals { 20 | // A union that defines the actual content of a JsonVariant. 21 | // The enum JsonVariantType determines which member is in use. 22 | union JsonVariantContent { 23 | JsonFloat asFloat; // used for double and float 24 | JsonUInt asInteger; // used for bool, char, short, int and longs 25 | const char* asString; // asString can be null 26 | JsonArray* asArray; // asArray cannot be null 27 | JsonObject* asObject; // asObject cannot be null 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonVariantDefault.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | template 14 | struct JsonVariantDefault { 15 | static T get() { 16 | return T(); 17 | } 18 | }; 19 | 20 | template 21 | struct JsonVariantDefault : JsonVariantDefault {}; 22 | 23 | template 24 | struct JsonVariantDefault : JsonVariantDefault {}; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/JsonVariantType.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | class JsonArray; 12 | class JsonObject; 13 | 14 | namespace Internals { 15 | 16 | // Enumerated type to know the current type of a JsonVariant. 17 | // The value determines which member of JsonVariantContent is used. 18 | enum JsonVariantType { 19 | JSON_UNDEFINED, // JsonVariant has not been initialized 20 | JSON_UNPARSED, // JsonVariant contains an unparsed string 21 | JSON_STRING, // JsonVariant stores a const char* 22 | JSON_BOOLEAN, // JsonVariant stores a bool 23 | JSON_POSITIVE_INTEGER, // JsonVariant stores an unsigned long 24 | JSON_NEGATIVE_INTEGER, // JsonVariant stores an unsigned long that must be 25 | // negated 26 | JSON_ARRAY, // JsonVariant stores a pointer to a JsonArray 27 | JSON_OBJECT, // JsonVariant stores a pointer to a JsonObject 28 | 29 | // The following values are reserved for float values 30 | // Multiple values are used for double, depending on the number of decimal 31 | // digits that must be printed in the JSON output. 32 | // This little trick allow to save one extra member in JsonVariant 33 | JSON_FLOAT_0_DECIMALS 34 | // JSON_FLOAT_1_DECIMAL 35 | // JSON_FLOAT_2_DECIMALS 36 | // ... 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/List.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../JsonBuffer.hpp" 11 | #include "ListConstIterator.hpp" 12 | #include "ListIterator.hpp" 13 | 14 | namespace ArduinoJson { 15 | namespace Internals { 16 | 17 | // A singly linked list of T. 18 | // The linked list is composed of ListNode. 19 | // It is derived by JsonArray and JsonObject 20 | template 21 | class List { 22 | public: 23 | typedef T value_type; 24 | typedef ListNode node_type; 25 | typedef ListIterator iterator; 26 | typedef ListConstIterator const_iterator; 27 | 28 | // Creates an empty List attached to a JsonBuffer. 29 | // The JsonBuffer allows to allocate new nodes. 30 | // When buffer is NULL, the List is not able to grow and success() returns 31 | // false. This is used to identify bad memory allocations and parsing 32 | // failures. 33 | explicit List(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} 34 | 35 | // Returns true if the object is valid 36 | // Would return false in the following situation: 37 | // - the memory allocation failed (StaticJsonBuffer was too small) 38 | // - the JSON parsing failed 39 | bool success() const { 40 | return _buffer != NULL; 41 | } 42 | 43 | // Returns the numbers of elements in the list. 44 | // For a JsonObject, it would return the number of key-value pairs 45 | size_t size() const { 46 | size_t nodeCount = 0; 47 | for (node_type *node = _firstNode; node; node = node->next) nodeCount++; 48 | return nodeCount; 49 | } 50 | 51 | iterator add() { 52 | node_type *newNode = new (_buffer) node_type(); 53 | 54 | if (_firstNode) { 55 | node_type *lastNode = _firstNode; 56 | while (lastNode->next) lastNode = lastNode->next; 57 | lastNode->next = newNode; 58 | } else { 59 | _firstNode = newNode; 60 | } 61 | 62 | return iterator(newNode); 63 | } 64 | 65 | iterator begin() { 66 | return iterator(_firstNode); 67 | } 68 | iterator end() { 69 | return iterator(NULL); 70 | } 71 | 72 | const_iterator begin() const { 73 | return const_iterator(_firstNode); 74 | } 75 | const_iterator end() const { 76 | return const_iterator(NULL); 77 | } 78 | 79 | void remove(iterator it) { 80 | node_type *nodeToRemove = it._node; 81 | if (!nodeToRemove) return; 82 | if (nodeToRemove == _firstNode) { 83 | _firstNode = nodeToRemove->next; 84 | } else { 85 | for (node_type *node = _firstNode; node; node = node->next) 86 | if (node->next == nodeToRemove) node->next = nodeToRemove->next; 87 | } 88 | } 89 | 90 | protected: 91 | JsonBuffer *_buffer; 92 | 93 | private: 94 | node_type *_firstNode; 95 | }; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/ListConstIterator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "ListNode.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace Internals { 14 | 15 | // A read-only forward itertor for List 16 | template 17 | class ListConstIterator { 18 | public: 19 | explicit ListConstIterator(const ListNode *node = NULL) : _node(node) {} 20 | 21 | const T &operator*() const { 22 | return _node->content; 23 | } 24 | const T *operator->() { 25 | return &_node->content; 26 | } 27 | 28 | bool operator==(const ListConstIterator &other) const { 29 | return _node == other._node; 30 | } 31 | 32 | bool operator!=(const ListConstIterator &other) const { 33 | return _node != other._node; 34 | } 35 | 36 | ListConstIterator &operator++() { 37 | if (_node) _node = _node->next; 38 | return *this; 39 | } 40 | 41 | ListConstIterator &operator+=(size_t distance) { 42 | while (_node && distance) { 43 | _node = _node->next; 44 | --distance; 45 | } 46 | return *this; 47 | } 48 | 49 | private: 50 | const ListNode *_node; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/ListIterator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "ListConstIterator.hpp" 11 | #include "ListNode.hpp" 12 | 13 | namespace ArduinoJson { 14 | namespace Internals { 15 | 16 | template 17 | class List; 18 | 19 | // A read-write forward iterator for List 20 | template 21 | class ListIterator { 22 | friend class List; 23 | 24 | public: 25 | explicit ListIterator(ListNode *node = NULL) : _node(node) {} 26 | 27 | T &operator*() const { 28 | return _node->content; 29 | } 30 | T *operator->() { 31 | return &_node->content; 32 | } 33 | 34 | bool operator==(const ListIterator &other) const { 35 | return _node == other._node; 36 | } 37 | 38 | bool operator!=(const ListIterator &other) const { 39 | return _node != other._node; 40 | } 41 | 42 | ListIterator &operator++() { 43 | if (_node) _node = _node->next; 44 | return *this; 45 | } 46 | 47 | ListIterator &operator+=(size_t distance) { 48 | while (_node && distance) { 49 | _node = _node->next; 50 | --distance; 51 | } 52 | return *this; 53 | } 54 | 55 | operator ListConstIterator() const { 56 | return ListConstIterator(_node); 57 | } 58 | 59 | private: 60 | ListNode *_node; 61 | }; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/ListNode.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include // for NULL 11 | 12 | #include "JsonBufferAllocated.hpp" 13 | 14 | namespace ArduinoJson { 15 | namespace Internals { 16 | 17 | // A node for a singly-linked list. 18 | // Used by List and its iterators. 19 | template 20 | struct ListNode : public Internals::JsonBufferAllocated { 21 | ListNode() : next(NULL) {} 22 | 23 | ListNode *next; 24 | T content; 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/ReferenceType.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | // A type that is meant to be used by reference only (JsonArray and JsonObject) 14 | class ReferenceType { 15 | public: 16 | bool operator==(const ReferenceType& other) const { 17 | // two JsonArray are equal if they are the same instance 18 | // (we don't compare the content) 19 | return this == &other; 20 | } 21 | 22 | bool operator!=(const ReferenceType& other) const { 23 | return this != &other; 24 | } 25 | 26 | protected: 27 | ReferenceType() {} 28 | 29 | private: 30 | // copy constructor is private 31 | ReferenceType(const ReferenceType&); 32 | 33 | // copy operator is private 34 | ReferenceType& operator=(const ReferenceType&); 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Data/ValueSetter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../JsonBuffer.hpp" 11 | #include "../JsonVariant.hpp" 12 | #include "../StringTraits/StringTraits.hpp" 13 | #include "../TypeTraits/EnableIf.hpp" 14 | 15 | namespace ArduinoJson { 16 | namespace Internals { 17 | 18 | template 19 | struct ValueSetter { 20 | template 21 | static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) { 22 | destination = source; 23 | return true; 24 | } 25 | }; 26 | 27 | template 28 | struct ValueSetter::should_duplicate>::type> { 30 | template 31 | static bool set(JsonBuffer* buffer, TDestination& destination, 32 | TSourceRef source) { 33 | const char* copy = buffer->strdup(source); 34 | if (!copy) return false; 35 | destination = copy; 36 | return true; 37 | } 38 | }; 39 | 40 | template 41 | struct ValueSetter::should_duplicate>::type> { 43 | template 44 | static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) { 45 | // unsigned char* -> char* 46 | destination = reinterpret_cast(source); 47 | return true; 48 | } 49 | }; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Deserialization/Comments.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | template 13 | void skipSpacesAndComments(TInput& input) { 14 | for (;;) { 15 | switch (input.current()) { 16 | // spaces 17 | case ' ': 18 | case '\t': 19 | case '\r': 20 | case '\n': 21 | input.move(); 22 | continue; 23 | 24 | // comments 25 | case '/': 26 | switch (input.next()) { 27 | // C-style block comment 28 | case '*': 29 | input.move(); // skip '/' 30 | // no need to skip '*' 31 | for (;;) { 32 | input.move(); 33 | if (input.current() == '\0') return; 34 | if (input.current() == '*' && input.next() == '/') { 35 | input.move(); // skip '*' 36 | input.move(); // skip '/' 37 | break; 38 | } 39 | } 40 | break; 41 | 42 | // C++-style line comment 43 | case '/': 44 | // not need to skip "//" 45 | for (;;) { 46 | input.move(); 47 | if (input.current() == '\0') return; 48 | if (input.current() == '\n') break; 49 | } 50 | break; 51 | 52 | // not a comment, just a '/' 53 | default: 54 | return; 55 | } 56 | break; 57 | 58 | default: 59 | return; 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Deserialization/JsonParser.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../JsonBuffer.hpp" 11 | #include "../JsonVariant.hpp" 12 | #include "../TypeTraits/IsConst.hpp" 13 | #include "StringWriter.hpp" 14 | 15 | namespace ArduinoJson { 16 | namespace Internals { 17 | 18 | // Parse JSON string to create JsonArrays and JsonObjects 19 | // This internal class is not indended to be used directly. 20 | // Instead, use JsonBuffer.parseArray() or .parseObject() 21 | template 22 | class JsonParser { 23 | public: 24 | JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer, 25 | uint8_t nestingLimit) 26 | : _buffer(buffer), 27 | _reader(reader), 28 | _writer(writer), 29 | _nestingLimit(nestingLimit) {} 30 | 31 | JsonArray &parseArray(); 32 | JsonObject &parseObject(); 33 | 34 | JsonVariant parseVariant() { 35 | JsonVariant result; 36 | parseAnythingTo(&result); 37 | return result; 38 | } 39 | 40 | private: 41 | JsonParser &operator=(const JsonParser &); // non-copiable 42 | 43 | static bool eat(TReader &, char charToSkip); 44 | FORCE_INLINE bool eat(char charToSkip) { 45 | return eat(_reader, charToSkip); 46 | } 47 | 48 | const char *parseString(); 49 | bool parseAnythingTo(JsonVariant *destination); 50 | FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination); 51 | 52 | inline bool parseArrayTo(JsonVariant *destination); 53 | inline bool parseObjectTo(JsonVariant *destination); 54 | inline bool parseStringTo(JsonVariant *destination); 55 | 56 | static inline bool isInRange(char c, char min, char max) { 57 | return min <= c && c <= max; 58 | } 59 | 60 | static inline bool isLetterOrNumber(char c) { 61 | return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') || 62 | isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; 63 | } 64 | 65 | static inline bool isQuote(char c) { 66 | return c == '\'' || c == '\"'; 67 | } 68 | 69 | JsonBuffer *_buffer; 70 | TReader _reader; 71 | TWriter _writer; 72 | uint8_t _nestingLimit; 73 | }; 74 | 75 | template 76 | struct JsonParserBuilder { 77 | typedef typename Internals::StringTraits::Reader InputReader; 78 | typedef JsonParser TParser; 79 | 80 | static TParser makeParser(TJsonBuffer *buffer, TString &json, 81 | uint8_t nestingLimit) { 82 | return TParser(buffer, InputReader(json), *buffer, nestingLimit); 83 | } 84 | }; 85 | 86 | template 87 | struct JsonParserBuilder< 88 | TJsonBuffer, TChar *, 89 | typename TypeTraits::EnableIf::value>::type> { 90 | typedef typename Internals::StringTraits::Reader TReader; 91 | typedef StringWriter TWriter; 92 | typedef JsonParser TParser; 93 | 94 | static TParser makeParser(TJsonBuffer *buffer, TChar *json, 95 | uint8_t nestingLimit) { 96 | return TParser(buffer, TReader(json), TWriter(json), nestingLimit); 97 | } 98 | }; 99 | 100 | template 101 | inline typename JsonParserBuilder::TParser makeParser( 102 | TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { 103 | return JsonParserBuilder::makeParser(buffer, json, 104 | nestingLimit); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Deserialization/JsonParserImpl.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Comments.hpp" 11 | #include "JsonParser.hpp" 12 | 13 | template 14 | inline bool ArduinoJson::Internals::JsonParser::eat( 15 | TReader &reader, char charToSkip) { 16 | skipSpacesAndComments(reader); 17 | if (reader.current() != charToSkip) return false; 18 | reader.move(); 19 | return true; 20 | } 21 | 22 | template 23 | inline bool 24 | ArduinoJson::Internals::JsonParser::parseAnythingTo( 25 | JsonVariant *destination) { 26 | if (_nestingLimit == 0) return false; 27 | _nestingLimit--; 28 | bool success = parseAnythingToUnsafe(destination); 29 | _nestingLimit++; 30 | return success; 31 | } 32 | 33 | template 34 | inline bool 35 | ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( 36 | JsonVariant *destination) { 37 | skipSpacesAndComments(_reader); 38 | 39 | switch (_reader.current()) { 40 | case '[': 41 | return parseArrayTo(destination); 42 | 43 | case '{': 44 | return parseObjectTo(destination); 45 | 46 | default: 47 | return parseStringTo(destination); 48 | } 49 | } 50 | 51 | template 52 | inline ArduinoJson::JsonArray & 53 | ArduinoJson::Internals::JsonParser::parseArray() { 54 | // Create an empty array 55 | JsonArray &array = _buffer->createArray(); 56 | 57 | // Check opening braket 58 | if (!eat('[')) goto ERROR_MISSING_BRACKET; 59 | if (eat(']')) goto SUCCESS_EMPTY_ARRAY; 60 | 61 | // Read each value 62 | for (;;) { 63 | // 1 - Parse value 64 | JsonVariant value; 65 | if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; 66 | if (!array.add(value)) goto ERROR_NO_MEMORY; 67 | 68 | // 2 - More values? 69 | if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY; 70 | if (!eat(',')) goto ERROR_MISSING_COMMA; 71 | } 72 | 73 | SUCCESS_EMPTY_ARRAY: 74 | SUCCES_NON_EMPTY_ARRAY: 75 | return array; 76 | 77 | ERROR_INVALID_VALUE: 78 | ERROR_MISSING_BRACKET: 79 | ERROR_MISSING_COMMA: 80 | ERROR_NO_MEMORY: 81 | return JsonArray::invalid(); 82 | } 83 | 84 | template 85 | inline bool ArduinoJson::Internals::JsonParser::parseArrayTo( 86 | JsonVariant *destination) { 87 | JsonArray &array = parseArray(); 88 | if (!array.success()) return false; 89 | 90 | *destination = array; 91 | return true; 92 | } 93 | 94 | template 95 | inline ArduinoJson::JsonObject & 96 | ArduinoJson::Internals::JsonParser::parseObject() { 97 | // Create an empty object 98 | JsonObject &object = _buffer->createObject(); 99 | 100 | // Check opening brace 101 | if (!eat('{')) goto ERROR_MISSING_BRACE; 102 | if (eat('}')) goto SUCCESS_EMPTY_OBJECT; 103 | 104 | // Read each key value pair 105 | for (;;) { 106 | // 1 - Parse key 107 | const char *key = parseString(); 108 | if (!key) goto ERROR_INVALID_KEY; 109 | if (!eat(':')) goto ERROR_MISSING_COLON; 110 | 111 | // 2 - Parse value 112 | JsonVariant value; 113 | if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; 114 | if (!object.set(key, value)) goto ERROR_NO_MEMORY; 115 | 116 | // 3 - More keys/values? 117 | if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT; 118 | if (!eat(',')) goto ERROR_MISSING_COMMA; 119 | } 120 | 121 | SUCCESS_EMPTY_OBJECT: 122 | SUCCESS_NON_EMPTY_OBJECT: 123 | return object; 124 | 125 | ERROR_INVALID_KEY: 126 | ERROR_INVALID_VALUE: 127 | ERROR_MISSING_BRACE: 128 | ERROR_MISSING_COLON: 129 | ERROR_MISSING_COMMA: 130 | ERROR_NO_MEMORY: 131 | return JsonObject::invalid(); 132 | } 133 | 134 | template 135 | inline bool ArduinoJson::Internals::JsonParser::parseObjectTo( 136 | JsonVariant *destination) { 137 | JsonObject &object = parseObject(); 138 | if (!object.success()) return false; 139 | 140 | *destination = object; 141 | return true; 142 | } 143 | 144 | template 145 | inline const char * 146 | ArduinoJson::Internals::JsonParser::parseString() { 147 | typename TypeTraits::RemoveReference::type::String str = 148 | _writer.startString(); 149 | 150 | skipSpacesAndComments(_reader); 151 | char c = _reader.current(); 152 | 153 | if (isQuote(c)) { // quotes 154 | _reader.move(); 155 | char stopChar = c; 156 | for (;;) { 157 | c = _reader.current(); 158 | if (c == '\0') break; 159 | _reader.move(); 160 | 161 | if (c == stopChar) break; 162 | 163 | if (c == '\\') { 164 | // replace char 165 | c = Encoding::unescapeChar(_reader.current()); 166 | if (c == '\0') break; 167 | _reader.move(); 168 | } 169 | 170 | str.append(c); 171 | } 172 | } else { // no quotes 173 | for (;;) { 174 | if (!isLetterOrNumber(c)) break; 175 | _reader.move(); 176 | str.append(c); 177 | c = _reader.current(); 178 | } 179 | } 180 | 181 | return str.c_str(); 182 | } 183 | 184 | template 185 | inline bool ArduinoJson::Internals::JsonParser::parseStringTo( 186 | JsonVariant *destination) { 187 | bool hasQuotes = isQuote(_reader.current()); 188 | const char *value = parseString(); 189 | if (value == NULL) return false; 190 | if (hasQuotes) { 191 | *destination = value; 192 | } else { 193 | *destination = RawJson(value); 194 | } 195 | return true; 196 | } 197 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Deserialization/StringWriter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | template 14 | class StringWriter { 15 | public: 16 | class String { 17 | public: 18 | String(TChar** ptr) : _writePtr(ptr), _startPtr(*ptr) {} 19 | 20 | void append(TChar c) { 21 | *(*_writePtr)++ = c; 22 | } 23 | 24 | const char* c_str() const { 25 | *(*_writePtr)++ = 0; 26 | return reinterpret_cast(_startPtr); 27 | } 28 | 29 | private: 30 | TChar** _writePtr; 31 | TChar* _startPtr; 32 | }; 33 | 34 | StringWriter(TChar* buffer) : _ptr(buffer) {} 35 | 36 | String startString() { 37 | return String(&_ptr); 38 | } 39 | 40 | private: 41 | TChar* _ptr; 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/DynamicJsonBuffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "JsonBufferBase.hpp" 11 | 12 | #include 13 | 14 | #if defined(__clang__) 15 | #pragma clang diagnostic push 16 | #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 17 | #elif defined(__GNUC__) 18 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 19 | #pragma GCC diagnostic push 20 | #endif 21 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 22 | #endif 23 | 24 | namespace ArduinoJson { 25 | class DefaultAllocator { 26 | public: 27 | void* allocate(size_t size) { 28 | return malloc(size); 29 | } 30 | void deallocate(void* pointer) { 31 | free(pointer); 32 | } 33 | }; 34 | 35 | template 36 | class DynamicJsonBufferBase 37 | : public JsonBufferBase > { 38 | struct Block; 39 | struct EmptyBlock { 40 | Block* next; 41 | size_t capacity; 42 | size_t size; 43 | }; 44 | struct Block : EmptyBlock { 45 | uint8_t data[1]; 46 | }; 47 | 48 | public: 49 | DynamicJsonBufferBase(size_t initialSize = 256) 50 | : _head(NULL), _nextBlockCapacity(initialSize) {} 51 | 52 | ~DynamicJsonBufferBase() { 53 | Block* currentBlock = _head; 54 | 55 | while (currentBlock != NULL) { 56 | Block* nextBlock = currentBlock->next; 57 | _allocator.deallocate(currentBlock); 58 | currentBlock = nextBlock; 59 | } 60 | } 61 | 62 | size_t size() const { 63 | size_t total = 0; 64 | for (const Block* b = _head; b; b = b->next) total += b->size; 65 | return total; 66 | } 67 | 68 | virtual void* alloc(size_t bytes) { 69 | alignNextAlloc(); 70 | return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes); 71 | } 72 | 73 | class String { 74 | public: 75 | String(DynamicJsonBufferBase* parent) 76 | : _parent(parent), _start(NULL), _length(0) {} 77 | 78 | void append(char c) { 79 | if (_parent->canAllocInHead(1)) { 80 | char* end = static_cast(_parent->allocInHead(1)); 81 | *end = c; 82 | if (_length == 0) _start = end; 83 | } else { 84 | char* newStart = 85 | static_cast(_parent->allocInNewBlock(_length + 1)); 86 | if (_start && newStart) memcpy(newStart, _start, _length); 87 | if (newStart) newStart[_length] = c; 88 | _start = newStart; 89 | } 90 | _length++; 91 | } 92 | 93 | const char* c_str() { 94 | append(0); 95 | return _start; 96 | } 97 | 98 | private: 99 | DynamicJsonBufferBase* _parent; 100 | char* _start; 101 | int _length; 102 | }; 103 | 104 | String startString() { 105 | return String(this); 106 | } 107 | 108 | private: 109 | void alignNextAlloc() { 110 | if (_head) _head->size = this->round_size_up(_head->size); 111 | } 112 | 113 | bool canAllocInHead(size_t bytes) const { 114 | return _head != NULL && _head->size + bytes <= _head->capacity; 115 | } 116 | 117 | void* allocInHead(size_t bytes) { 118 | void* p = _head->data + _head->size; 119 | _head->size += bytes; 120 | return p; 121 | } 122 | 123 | void* allocInNewBlock(size_t bytes) { 124 | size_t capacity = _nextBlockCapacity; 125 | if (bytes > capacity) capacity = bytes; 126 | if (!addNewBlock(capacity)) return NULL; 127 | _nextBlockCapacity *= 2; 128 | return allocInHead(bytes); 129 | } 130 | 131 | bool addNewBlock(size_t capacity) { 132 | size_t bytes = sizeof(EmptyBlock) + capacity; 133 | Block* block = static_cast(_allocator.allocate(bytes)); 134 | if (block == NULL) return false; 135 | block->capacity = capacity; 136 | block->size = 0; 137 | block->next = _head; 138 | _head = block; 139 | return true; 140 | } 141 | 142 | TAllocator _allocator; 143 | Block* _head; 144 | size_t _nextBlockCapacity; 145 | }; 146 | 147 | #if defined(__clang__) 148 | #pragma clang diagnostic pop 149 | #elif defined(__GNUC__) 150 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 151 | #pragma GCC diagnostic pop 152 | #endif 153 | #endif 154 | 155 | // Implements a JsonBuffer with dynamic memory allocation. 156 | // You are strongly encouraged to consider using StaticJsonBuffer which is much 157 | // more suitable for embedded systems. 158 | typedef DynamicJsonBufferBase DynamicJsonBuffer; 159 | } 160 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonArray.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Data/JsonBufferAllocated.hpp" 11 | #include "Data/List.hpp" 12 | #include "Data/ReferenceType.hpp" 13 | #include "Data/ValueSetter.hpp" 14 | #include "JsonVariant.hpp" 15 | #include "Serialization/JsonPrintable.hpp" 16 | #include "StringTraits/StringTraits.hpp" 17 | #include "TypeTraits/EnableIf.hpp" 18 | #include "TypeTraits/IsArray.hpp" 19 | #include "TypeTraits/IsFloatingPoint.hpp" 20 | #include "TypeTraits/IsSame.hpp" 21 | 22 | // Returns the size (in bytes) of an array with n elements. 23 | // Can be very handy to determine the size of a StaticJsonBuffer. 24 | #define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \ 25 | (sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type)) 26 | 27 | namespace ArduinoJson { 28 | 29 | // Forward declarations 30 | class JsonObject; 31 | class JsonBuffer; 32 | class JsonArraySubscript; 33 | 34 | // An array of JsonVariant. 35 | // 36 | // The constructor is private, instances must be created via 37 | // JsonBuffer::createArray() or JsonBuffer::parseArray(). 38 | // A JsonArray can be serialized to a JSON string via JsonArray::printTo(). 39 | // It can also be deserialized from a JSON string via JsonBuffer::parseArray(). 40 | class JsonArray : public Internals::JsonPrintable, 41 | public Internals::ReferenceType, 42 | public Internals::List, 43 | public Internals::JsonBufferAllocated { 44 | public: 45 | // Create an empty JsonArray attached to the specified JsonBuffer. 46 | // You should not call this constructor directly. 47 | // Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray(). 48 | explicit JsonArray(JsonBuffer *buffer) 49 | : Internals::List(buffer) {} 50 | 51 | // Gets the value at the specified index 52 | const JsonArraySubscript operator[](size_t index) const; 53 | 54 | // Gets or sets the value at specified index 55 | JsonArraySubscript operator[](size_t index); 56 | 57 | // Adds the specified value at the end of the array. 58 | // 59 | // bool add(TValue); 60 | // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, 61 | // const std::string&, const String&, 62 | // const JsonArray&, const JsonObject& 63 | template 64 | typename TypeTraits::EnableIf::value, bool>::type add( 65 | const T &value) { 66 | return add_impl(value); 67 | } 68 | // 69 | // bool add(TValue); 70 | // TValue = const char*, const char[N], const FlashStringHelper* 71 | template 72 | bool add(const T *value) { 73 | return add_impl(value); 74 | } 75 | // 76 | // bool add(TValue value, uint8_t decimals); 77 | // TValue = float, double 78 | template 79 | bool add(T value, uint8_t decimals) { 80 | return add_impl(JsonVariant(value, decimals)); 81 | } 82 | 83 | // Sets the value at specified index. 84 | // 85 | // bool add(size_t index, TValue); 86 | // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, 87 | // const std::string&, const String&, 88 | // const JsonArray&, const JsonObject& 89 | template 90 | typename TypeTraits::EnableIf::value, bool>::type set( 91 | size_t index, const T &value) { 92 | return set_impl(index, value); 93 | } 94 | // 95 | // bool add(size_t index, TValue); 96 | // TValue = const char*, const char[N], const FlashStringHelper* 97 | template 98 | bool set(size_t index, const T *value) { 99 | return set_impl(index, value); 100 | } 101 | // 102 | // bool set(size_t index, TValue value, uint8_t decimals); 103 | // TValue = float, double 104 | template 105 | typename TypeTraits::EnableIf::value, 106 | bool>::type 107 | set(size_t index, T value, uint8_t decimals) { 108 | return set_impl(index, JsonVariant(value, decimals)); 109 | } 110 | 111 | // Gets the value at the specified index. 112 | template 113 | typename Internals::JsonVariantAs::type get(size_t index) const { 114 | const_iterator it = begin() += index; 115 | return it != end() ? it->as() : Internals::JsonVariantDefault::get(); 116 | } 117 | 118 | // Check the type of the value at specified index. 119 | template 120 | bool is(size_t index) const { 121 | const_iterator it = begin() += index; 122 | return it != end() ? it->is() : false; 123 | } 124 | 125 | // Creates a JsonArray and adds a reference at the end of the array. 126 | // It's a shortcut for JsonBuffer::createArray() and JsonArray::add() 127 | JsonArray &createNestedArray(); 128 | 129 | // Creates a JsonObject and adds a reference at the end of the array. 130 | // It's a shortcut for JsonBuffer::createObject() and JsonArray::add() 131 | JsonObject &createNestedObject(); 132 | 133 | // Removes element at specified index. 134 | void remove(size_t index) { 135 | remove(begin() += index); 136 | } 137 | using Internals::List::remove; 138 | 139 | // Returns a reference an invalid JsonArray. 140 | // This object is meant to replace a NULL pointer. 141 | // This is used when memory allocation or JSON parsing fail. 142 | static JsonArray &invalid() { 143 | static JsonArray instance(NULL); 144 | return instance; 145 | } 146 | 147 | // Imports a 1D array 148 | template 149 | bool copyFrom(T (&array)[N]) { 150 | return copyFrom(array, N); 151 | } 152 | 153 | // Imports a 1D array 154 | template 155 | bool copyFrom(T *array, size_t len) { 156 | bool ok = true; 157 | for (size_t i = 0; i < len; i++) { 158 | ok &= add(array[i]); 159 | } 160 | return ok; 161 | } 162 | 163 | // Imports a 2D array 164 | template 165 | bool copyFrom(T (&array)[N1][N2]) { 166 | bool ok = true; 167 | for (size_t i = 0; i < N1; i++) { 168 | JsonArray &nestedArray = createNestedArray(); 169 | for (size_t j = 0; j < N2; j++) { 170 | ok &= nestedArray.add(array[i][j]); 171 | } 172 | } 173 | return ok; 174 | } 175 | 176 | // Exports a 1D array 177 | template 178 | size_t copyTo(T (&array)[N]) const { 179 | return copyTo(array, N); 180 | } 181 | 182 | // Exports a 1D array 183 | template 184 | size_t copyTo(T *array, size_t len) const { 185 | size_t i = 0; 186 | for (const_iterator it = begin(); it != end() && i < len; ++it) 187 | array[i++] = *it; 188 | return i; 189 | } 190 | 191 | // Exports a 2D array 192 | template 193 | void copyTo(T (&array)[N1][N2]) const { 194 | size_t i = 0; 195 | for (const_iterator it = begin(); it != end() && i < N1; ++it) { 196 | it->as().copyTo(array[i++]); 197 | } 198 | } 199 | 200 | #if ARDUINOJSON_ENABLE_DEPRECATED 201 | DEPRECATED("use remove() instead") 202 | FORCE_INLINE void removeAt(size_t index) { 203 | return remove(index); 204 | } 205 | #endif 206 | 207 | private: 208 | template 209 | bool set_impl(size_t index, TValueRef value) { 210 | iterator it = begin() += index; 211 | if (it == end()) return false; 212 | return Internals::ValueSetter::set(_buffer, *it, value); 213 | } 214 | 215 | template 216 | bool add_impl(TValueRef value) { 217 | iterator it = Internals::List::add(); 218 | if (it == end()) return false; 219 | return Internals::ValueSetter::set(_buffer, *it, value); 220 | } 221 | }; 222 | 223 | namespace Internals { 224 | template <> 225 | struct JsonVariantDefault { 226 | static JsonArray &get() { 227 | return JsonArray::invalid(); 228 | } 229 | }; 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonArrayImpl.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "JsonArray.hpp" 11 | #include "JsonArraySubscript.hpp" 12 | #include "JsonObject.hpp" 13 | 14 | namespace ArduinoJson { 15 | 16 | inline JsonArray &JsonArray::createNestedArray() { 17 | if (!_buffer) return JsonArray::invalid(); 18 | JsonArray &array = _buffer->createArray(); 19 | add(array); 20 | return array; 21 | } 22 | 23 | inline JsonObject &JsonArray::createNestedObject() { 24 | if (!_buffer) return JsonObject::invalid(); 25 | JsonObject &object = _buffer->createObject(); 26 | add(object); 27 | return object; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonArraySubscript.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Configuration.hpp" 11 | #include "JsonVariantBase.hpp" 12 | 13 | #ifdef _MSC_VER 14 | #pragma warning(push) 15 | #pragma warning(disable : 4522) 16 | #endif 17 | 18 | namespace ArduinoJson { 19 | class JsonArraySubscript : public JsonVariantBase { 20 | public: 21 | FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index) 22 | : _array(array), _index(index) {} 23 | 24 | FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) { 25 | _array.set(_index, src); 26 | return *this; 27 | } 28 | 29 | // Replaces the value 30 | // 31 | // operator=(TValue) 32 | // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, 33 | // const std::string&, const String&, 34 | // const JsonArray&, const JsonObject& 35 | template 36 | FORCE_INLINE JsonArraySubscript& operator=(const T& src) { 37 | _array.set(_index, src); 38 | return *this; 39 | } 40 | // 41 | // operator=(TValue) 42 | // TValue = const char*, const char[N], const FlashStringHelper* 43 | template 44 | FORCE_INLINE JsonArraySubscript& operator=(const T* src) { 45 | _array.set(_index, src); 46 | return *this; 47 | } 48 | 49 | FORCE_INLINE bool success() const { 50 | return _index < _array.size(); 51 | } 52 | 53 | template 54 | FORCE_INLINE typename Internals::JsonVariantAs::type as() const { 55 | return _array.get(_index); 56 | } 57 | 58 | template 59 | FORCE_INLINE bool is() const { 60 | return _array.is(_index); 61 | } 62 | 63 | // Replaces the value 64 | // 65 | // bool set(TValue) 66 | // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, 67 | // const std::string&, const String&, 68 | // const JsonArray&, const JsonObject& 69 | template 70 | FORCE_INLINE bool set(const TValue& value) { 71 | return _array.set(_index, value); 72 | } 73 | // 74 | // bool set(TValue) 75 | // TValue = const char*, const char[N], const FlashStringHelper* 76 | template 77 | FORCE_INLINE bool set(const TValue* value) { 78 | return _array.set(_index, value); 79 | } 80 | // 81 | // bool set(TValue, uint8_t decimals); 82 | // TValue = float, double 83 | template 84 | FORCE_INLINE bool set(const TValue& value, uint8_t decimals) { 85 | return _array.set(_index, value, decimals); 86 | } 87 | 88 | private: 89 | JsonArray& _array; 90 | const size_t _index; 91 | }; 92 | 93 | #if ARDUINOJSON_ENABLE_STD_STREAM 94 | inline std::ostream& operator<<(std::ostream& os, 95 | const JsonArraySubscript& source) { 96 | return source.printTo(os); 97 | } 98 | #endif 99 | 100 | inline JsonArraySubscript JsonArray::operator[](size_t index) { 101 | return JsonArraySubscript(*this, index); 102 | } 103 | 104 | inline const JsonArraySubscript JsonArray::operator[](size_t index) const { 105 | return JsonArraySubscript(*const_cast(this), index); 106 | } 107 | 108 | template 109 | inline JsonArraySubscript JsonVariantBase::operator[](int index) { 110 | return as()[index]; 111 | } 112 | 113 | template 114 | inline const JsonArraySubscript JsonVariantBase::operator[]( 115 | int index) const { 116 | return as()[index]; 117 | } 118 | 119 | } // namespace ArduinoJson 120 | 121 | #ifdef _MSC_VER 122 | #pragma warning(pop) 123 | #endif 124 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonBuffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include // for size_t 11 | #include // for uint8_t 12 | #include 13 | 14 | #include "JsonVariant.hpp" 15 | #include "TypeTraits/EnableIf.hpp" 16 | #include "TypeTraits/IsArray.hpp" 17 | 18 | #if defined(__clang__) 19 | #pragma clang diagnostic push 20 | #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 21 | #elif defined(__GNUC__) 22 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 23 | #pragma GCC diagnostic push 24 | #endif 25 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 26 | #endif 27 | 28 | namespace ArduinoJson { 29 | class JsonArray; 30 | class JsonObject; 31 | 32 | // Entry point for using the library. 33 | // 34 | // Handle the memory management (done in derived classes) and calls the parser. 35 | // This abstract class is implemented by StaticJsonBuffer which implements a 36 | // fixed memory allocation. 37 | class JsonBuffer { 38 | public: 39 | // CAUTION: NO VIRTUAL DESTRUCTOR! 40 | // If we add a virtual constructor the Arduino compiler will add malloc() and 41 | // free() to the binary, adding 706 useless bytes. 42 | // virtual ~JsonBuffer() {} 43 | 44 | // Allocates an empty JsonArray. 45 | // 46 | // Returns a reference to the new JsonArray or JsonArray::invalid() if the 47 | // allocation fails. 48 | JsonArray &createArray(); 49 | 50 | // Allocates an empty JsonObject. 51 | // 52 | // Returns a reference to the new JsonObject or JsonObject::invalid() if the 53 | // allocation fails. 54 | JsonObject &createObject(); 55 | 56 | // Duplicates a string 57 | // 58 | // char* strdup(TValue); 59 | // TValue = const std::string&, const String&, 60 | template 61 | typename TypeTraits::EnableIf::value, 62 | char *>::type 63 | strdup(const TString &src) { 64 | return Internals::StringTraits::duplicate(src, this); 65 | } 66 | // 67 | // char* strdup(TValue); 68 | // TValue = const char*, const char[N], const FlashStringHelper* 69 | template 70 | char *strdup(const TString *src) { 71 | return Internals::StringTraits::duplicate(src, this); 72 | } 73 | 74 | // Allocates n bytes in the JsonBuffer. 75 | // Return a pointer to the allocated memory or NULL if allocation fails. 76 | virtual void *alloc(size_t size) = 0; 77 | 78 | protected: 79 | // Preserve aligment if necessary 80 | static FORCE_INLINE size_t round_size_up(size_t bytes) { 81 | #if ARDUINOJSON_ENABLE_ALIGNMENT 82 | const size_t x = sizeof(void *) - 1; 83 | return (bytes + x) & ~x; 84 | #else 85 | return bytes; 86 | #endif 87 | } 88 | }; 89 | } 90 | 91 | #if defined(__clang__) 92 | #pragma clang diagnostic pop 93 | #elif defined(__GNUC__) 94 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 95 | #pragma GCC diagnostic pop 96 | #endif 97 | #endif 98 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonBufferBase.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Deserialization/JsonParser.hpp" 11 | 12 | #if defined(__clang__) 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 15 | #elif defined(__GNUC__) 16 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 17 | #pragma GCC diagnostic push 18 | #endif 19 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 20 | #endif 21 | 22 | namespace ArduinoJson { 23 | template 24 | class JsonBufferBase : public JsonBuffer { 25 | public: 26 | // Allocates and populate a JsonArray from a JSON string. 27 | // 28 | // The First argument is a pointer to the JSON string, the memory must be 29 | // writable 30 | // because the parser will insert null-terminators and replace escaped chars. 31 | // 32 | // The second argument set the nesting limit 33 | // 34 | // Returns a reference to the new JsonObject or JsonObject::invalid() if the 35 | // allocation fails. 36 | // With this overload, the JsonBuffer will make a copy of the string 37 | // 38 | // JsonArray& parseArray(TString); 39 | // TString = const std::string&, const String& 40 | template 41 | typename TypeTraits::EnableIf::value, 42 | JsonArray &>::type 43 | parseArray(const TString &json, 44 | uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 45 | return Internals::makeParser(that(), json, nestingLimit).parseArray(); 46 | } 47 | // 48 | // JsonArray& parseArray(TString); 49 | // TString = const char*, const char[N], const FlashStringHelper* 50 | template 51 | JsonArray &parseArray( 52 | TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 53 | return Internals::makeParser(that(), json, nestingLimit).parseArray(); 54 | } 55 | // 56 | // JsonArray& parseArray(TString); 57 | // TString = std::istream&, Stream& 58 | template 59 | JsonArray &parseArray( 60 | TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 61 | return Internals::makeParser(that(), json, nestingLimit).parseArray(); 62 | } 63 | 64 | // Allocates and populate a JsonObject from a JSON string. 65 | // 66 | // The First argument is a pointer to the JSON string, the memory must be 67 | // writable 68 | // because the parser will insert null-terminators and replace escaped chars. 69 | // 70 | // The second argument set the nesting limit 71 | // 72 | // Returns a reference to the new JsonObject or JsonObject::invalid() if the 73 | // allocation fails. 74 | // 75 | // JsonObject& parseObject(TString); 76 | // TString = const std::string&, const String& 77 | template 78 | typename TypeTraits::EnableIf::value, 79 | JsonObject &>::type 80 | parseObject(const TString &json, 81 | uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 82 | return Internals::makeParser(that(), json, nestingLimit).parseObject(); 83 | } 84 | // 85 | // JsonObject& parseObject(TString); 86 | // TString = const char*, const char[N], const FlashStringHelper* 87 | template 88 | JsonObject &parseObject( 89 | TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 90 | return Internals::makeParser(that(), json, nestingLimit).parseObject(); 91 | } 92 | // 93 | // JsonObject& parseObject(TString); 94 | // TString = std::istream&, Stream& 95 | template 96 | JsonObject &parseObject( 97 | TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 98 | return Internals::makeParser(that(), json, nestingLimit).parseObject(); 99 | } 100 | 101 | // Generalized version of parseArray() and parseObject(), also works for 102 | // integral types. 103 | // 104 | // JsonVariant parse(TString); 105 | // TString = const std::string&, const String& 106 | template 107 | typename TypeTraits::EnableIf::value, 108 | JsonVariant>::type 109 | parse(const TString &json, 110 | uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 111 | return Internals::makeParser(that(), json, nestingLimit).parseVariant(); 112 | } 113 | // 114 | // JsonVariant parse(TString); 115 | // TString = const char*, const char[N], const FlashStringHelper* 116 | template 117 | JsonVariant parse(TString *json, 118 | uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 119 | return Internals::makeParser(that(), json, nestingLimit).parseVariant(); 120 | } 121 | // 122 | // JsonVariant parse(TString); 123 | // TString = std::istream&, Stream& 124 | template 125 | JsonVariant parse(TString &json, 126 | uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { 127 | return Internals::makeParser(that(), json, nestingLimit).parseVariant(); 128 | } 129 | 130 | private: 131 | TDerived *that() { 132 | return static_cast(this); 133 | } 134 | }; 135 | } 136 | 137 | #if defined(__clang__) 138 | #pragma clang diagnostic pop 139 | #elif defined(__GNUC__) 140 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 141 | #pragma GCC diagnostic pop 142 | #endif 143 | #endif 144 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonBufferImpl.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Deserialization/JsonParser.hpp" 11 | 12 | inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() { 13 | JsonArray *ptr = new (this) JsonArray(this); 14 | return ptr ? *ptr : JsonArray::invalid(); 15 | } 16 | 17 | inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() { 18 | JsonObject *ptr = new (this) JsonObject(this); 19 | return ptr ? *ptr : JsonObject::invalid(); 20 | } 21 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonObjectImpl.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "JsonArray.hpp" 11 | #include "JsonObject.hpp" 12 | #include "JsonObjectSubscript.hpp" 13 | 14 | namespace ArduinoJson { 15 | 16 | template 17 | inline JsonArray &JsonObject::createNestedArray_impl(TStringRef key) { 18 | if (!_buffer) return JsonArray::invalid(); 19 | JsonArray &array = _buffer->createArray(); 20 | set(key, array); 21 | return array; 22 | } 23 | 24 | template 25 | inline JsonObject &JsonObject::createNestedObject_impl(TStringRef key) { 26 | if (!_buffer) return JsonObject::invalid(); 27 | JsonObject &object = _buffer->createObject(); 28 | set(key, object); 29 | return object; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonObjectSubscript.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Configuration.hpp" 11 | #include "JsonVariantBase.hpp" 12 | #include "TypeTraits/EnableIf.hpp" 13 | 14 | #ifdef _MSC_VER 15 | #pragma warning(push) 16 | #pragma warning(disable : 4522) 17 | #endif 18 | 19 | namespace ArduinoJson { 20 | 21 | template 22 | class JsonObjectSubscript 23 | : public JsonVariantBase > { 24 | typedef JsonObjectSubscript this_type; 25 | 26 | public: 27 | FORCE_INLINE JsonObjectSubscript(JsonObject& object, TStringRef key) 28 | : _object(object), _key(key) {} 29 | 30 | FORCE_INLINE this_type& operator=(const this_type& src) { 31 | _object.set(_key, src); 32 | return *this; 33 | } 34 | 35 | // Set the specified value 36 | // 37 | // operator=(TValue); 38 | // TValue = bool, char, long, int, short, float, double, 39 | // const std::string&, const String&, 40 | // const JsonArray&, const JsonObject& 41 | template 42 | FORCE_INLINE 43 | typename TypeTraits::EnableIf::value, 44 | this_type&>::type 45 | operator=(const TValue& src) { 46 | _object.set(_key, src); 47 | return *this; 48 | } 49 | // 50 | // operator=(TValue); 51 | // TValue = const char*, const char[N], const FlashStringHelper* 52 | template 53 | FORCE_INLINE this_type& operator=(const TValue* src) { 54 | _object.set(_key, src); 55 | return *this; 56 | } 57 | 58 | FORCE_INLINE bool success() const { 59 | return _object.containsKey(_key); 60 | } 61 | 62 | template 63 | FORCE_INLINE typename Internals::JsonVariantAs::type as() const { 64 | return _object.get(_key); 65 | } 66 | 67 | template 68 | FORCE_INLINE bool is() const { 69 | return _object.is(_key); 70 | } 71 | 72 | // Sets the specified value. 73 | // 74 | // bool set(TValue); 75 | // TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant, 76 | // const std::string&, const String&, 77 | // const JsonArray&, const JsonObject& 78 | template 79 | FORCE_INLINE 80 | typename TypeTraits::EnableIf::value, 81 | bool>::type 82 | set(const TValue& value) { 83 | return _object.set(_key, value); 84 | } 85 | // 86 | // bool set(TValue); 87 | // TValue = const char*, const char[N], const FlashStringHelper* 88 | template 89 | FORCE_INLINE bool set(const TValue* value) { 90 | return _object.set(_key, value); 91 | } 92 | // 93 | // bool set(TValue, uint8_t decimals); 94 | // TValue = float, double 95 | template 96 | FORCE_INLINE bool set(const TValue& value, uint8_t decimals) { 97 | return _object.set(_key, value, decimals); 98 | } 99 | 100 | private: 101 | JsonObject& _object; 102 | TStringRef _key; 103 | }; 104 | 105 | #if ARDUINOJSON_ENABLE_STD_STREAM 106 | template 107 | inline std::ostream& operator<<(std::ostream& os, 108 | const JsonObjectSubscript& source) { 109 | return source.printTo(os); 110 | } 111 | #endif 112 | } // namespace ArduinoJson 113 | 114 | #ifdef _MSC_VER 115 | #pragma warning(pop) 116 | #endif 117 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonPair.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "JsonVariant.hpp" 11 | 12 | namespace ArduinoJson { 13 | 14 | // A key value pair for JsonObject. 15 | struct JsonPair { 16 | const char* key; 17 | JsonVariant value; 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonVariantBase.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Data/JsonVariantAs.hpp" 11 | #include "Polyfills/attributes.hpp" 12 | #include "Serialization/JsonPrintable.hpp" 13 | 14 | namespace ArduinoJson { 15 | 16 | // Forward declarations. 17 | class JsonArraySubscript; 18 | template 19 | class JsonObjectSubscript; 20 | 21 | template 22 | class JsonVariantBase : public Internals::JsonPrintable { 23 | public: 24 | #if ARDUINOJSON_ENABLE_DEPRECATED 25 | DEPRECATED("use as() instead") 26 | FORCE_INLINE JsonArray &asArray() const { 27 | return as(); 28 | } 29 | 30 | DEPRECATED("use as() instead") 31 | FORCE_INLINE JsonObject &asObject() const { 32 | return as(); 33 | } 34 | 35 | DEPRECATED("use as() instead") 36 | FORCE_INLINE const char *asString() const { 37 | return as(); 38 | } 39 | #endif 40 | 41 | // Gets the variant as an array. 42 | // Returns a reference to the JsonArray or JsonArray::invalid() if the 43 | // variant 44 | // is not an array. 45 | FORCE_INLINE operator JsonArray &() const { 46 | return as(); 47 | } 48 | 49 | // Gets the variant as an object. 50 | // Returns a reference to the JsonObject or JsonObject::invalid() if the 51 | // variant is not an object. 52 | FORCE_INLINE operator JsonObject &() const { 53 | return as(); 54 | } 55 | 56 | template 57 | FORCE_INLINE operator T() const { 58 | return as(); 59 | } 60 | 61 | template 62 | FORCE_INLINE const typename Internals::JsonVariantAs::type as() const { 63 | return impl()->template as(); 64 | } 65 | 66 | template 67 | FORCE_INLINE bool is() const { 68 | return impl()->template is(); 69 | } 70 | 71 | // Mimics an array or an object. 72 | // Returns the size of the array or object if the variant has that type. 73 | // Returns 0 if the variant is neither an array nor an object 74 | size_t size() const { 75 | return as().size() + as().size(); 76 | } 77 | 78 | // Mimics an array. 79 | // Returns the element at specified index if the variant is an array. 80 | // Returns JsonVariant::invalid() if the variant is not an array. 81 | FORCE_INLINE const JsonArraySubscript operator[](int index) const; 82 | FORCE_INLINE JsonArraySubscript operator[](int index); 83 | 84 | // Mimics an object. 85 | // Returns the value associated with the specified key if the variant is 86 | // an object. 87 | // Return JsonVariant::invalid() if the variant is not an object. 88 | // 89 | // const JsonObjectSubscript operator[](TKey) const; 90 | // TKey = const std::string&, const String& 91 | template 92 | FORCE_INLINE typename TypeTraits::EnableIf< 93 | Internals::StringTraits::has_equals, 94 | const JsonObjectSubscript >::type 95 | operator[](const TString &key) const { 96 | return as()[key]; 97 | } 98 | // 99 | // const JsonObjectSubscript operator[](TKey) const; 100 | // TKey = const std::string&, const String& 101 | template 102 | FORCE_INLINE typename TypeTraits::EnableIf< 103 | Internals::StringTraits::has_equals, 104 | JsonObjectSubscript >::type 105 | operator[](const TString &key) { 106 | return as()[key]; 107 | } 108 | // 109 | // JsonObjectSubscript operator[](TKey); 110 | // TKey = const char*, const char[N], const FlashStringHelper* 111 | template 112 | FORCE_INLINE typename TypeTraits::EnableIf< 113 | Internals::StringTraits::has_equals, 114 | JsonObjectSubscript >::type 115 | operator[](const TString *key) { 116 | return as()[key]; 117 | } 118 | // 119 | // JsonObjectSubscript operator[](TKey); 120 | // TKey = const char*, const char[N], const FlashStringHelper* 121 | template 122 | FORCE_INLINE typename TypeTraits::EnableIf< 123 | Internals::StringTraits::has_equals, 124 | const JsonObjectSubscript >::type 125 | operator[](const TString *key) const { 126 | return as()[key]; 127 | } 128 | 129 | private: 130 | const TImpl *impl() const { 131 | return static_cast(this); 132 | } 133 | }; 134 | 135 | namespace TypeTraits { 136 | template 137 | struct IsVariant : IsBaseOf, T> {}; 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonVariantComparisons.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Data/JsonVariantComparer.hpp" 11 | 12 | namespace ArduinoJson { 13 | template 14 | inline bool operator==(const JsonVariantBase &variant, 15 | TComparand comparand) { 16 | return Internals::JsonVariantComparer::equals(variant, comparand); 17 | } 18 | 19 | template 20 | inline typename TypeTraits::EnableIf::value, 21 | bool>::type 22 | operator==(TComparand comparand, const JsonVariantBase &variant) { 23 | return Internals::JsonVariantComparer::equals(variant, comparand); 24 | } 25 | 26 | template 27 | inline bool operator!=(const JsonVariantBase &variant, 28 | TComparand comparand) { 29 | return !Internals::JsonVariantComparer::equals(variant, 30 | comparand); 31 | } 32 | 33 | template 34 | inline typename TypeTraits::EnableIf::value, 35 | bool>::type 36 | operator!=(TComparand comparand, const JsonVariantBase &variant) { 37 | return !Internals::JsonVariantComparer::equals(variant, 38 | comparand); 39 | } 40 | 41 | template 42 | inline bool operator<=(const JsonVariantBase &left, 43 | TComparand right) { 44 | return left.template as() <= right; 45 | } 46 | 47 | template 48 | inline bool operator<=(TComparand comparand, 49 | const JsonVariantBase &variant) { 50 | return comparand <= variant.template as(); 51 | } 52 | 53 | template 54 | inline bool operator>=(const JsonVariantBase &variant, 55 | TComparand comparand) { 56 | return variant.template as() >= comparand; 57 | } 58 | 59 | template 60 | inline bool operator>=(TComparand comparand, 61 | const JsonVariantBase &variant) { 62 | return comparand >= variant.template as(); 63 | } 64 | 65 | template 66 | inline bool operator<(const JsonVariantBase &varian, 67 | TComparand comparand) { 68 | return varian.template as() < comparand; 69 | } 70 | 71 | template 72 | inline bool operator<(TComparand comparand, 73 | const JsonVariantBase &variant) { 74 | return comparand < variant.template as(); 75 | } 76 | 77 | template 78 | inline bool operator>(const JsonVariantBase &variant, 79 | TComparand comparand) { 80 | return variant.template as() > comparand; 81 | } 82 | 83 | template 84 | inline bool operator>(TComparand comparand, 85 | const JsonVariantBase &variant) { 86 | return comparand > variant.template as(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/JsonVariantImpl.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "Configuration.hpp" 11 | #include "JsonArray.hpp" 12 | #include "JsonObject.hpp" 13 | #include "JsonVariant.hpp" 14 | #include "Polyfills/isFloat.hpp" 15 | #include "Polyfills/isInteger.hpp" 16 | #include "Polyfills/parseFloat.hpp" 17 | #include "Polyfills/parseInteger.hpp" 18 | 19 | #include // for strcmp 20 | 21 | namespace ArduinoJson { 22 | 23 | inline JsonVariant::JsonVariant(const JsonArray &array) { 24 | if (array.success()) { 25 | _type = Internals::JSON_ARRAY; 26 | _content.asArray = const_cast(&array); 27 | } else { 28 | _type = Internals::JSON_UNDEFINED; 29 | } 30 | } 31 | 32 | inline JsonVariant::JsonVariant(const JsonObject &object) { 33 | if (object.success()) { 34 | _type = Internals::JSON_OBJECT; 35 | _content.asObject = const_cast(&object); 36 | } else { 37 | _type = Internals::JSON_UNDEFINED; 38 | } 39 | } 40 | 41 | inline JsonArray &JsonVariant::variantAsArray() const { 42 | if (_type == Internals::JSON_ARRAY) return *_content.asArray; 43 | return JsonArray::invalid(); 44 | } 45 | 46 | inline JsonObject &JsonVariant::variantAsObject() const { 47 | if (_type == Internals::JSON_OBJECT) return *_content.asObject; 48 | return JsonObject::invalid(); 49 | } 50 | 51 | template 52 | inline T JsonVariant::variantAsInteger() const { 53 | using namespace Internals; 54 | switch (_type) { 55 | case JSON_UNDEFINED: 56 | return 0; 57 | case JSON_POSITIVE_INTEGER: 58 | case JSON_BOOLEAN: 59 | return static_cast(_content.asInteger); 60 | case JSON_NEGATIVE_INTEGER: 61 | return static_cast(_content.asInteger * -1); 62 | case JSON_STRING: 63 | case JSON_UNPARSED: 64 | if (!_content.asString) return 0; 65 | if (!strcmp("true", _content.asString)) return 1; 66 | return Polyfills::parseInteger(_content.asString); 67 | default: 68 | return static_cast(_content.asFloat); 69 | } 70 | } 71 | 72 | inline const char *JsonVariant::variantAsString() const { 73 | using namespace Internals; 74 | if (_type == JSON_UNPARSED && _content.asString && 75 | !strcmp("null", _content.asString)) 76 | return NULL; 77 | if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString; 78 | return NULL; 79 | } 80 | 81 | template 82 | inline T JsonVariant::variantAsFloat() const { 83 | using namespace Internals; 84 | switch (_type) { 85 | case JSON_UNDEFINED: 86 | return 0; 87 | case JSON_POSITIVE_INTEGER: 88 | case JSON_BOOLEAN: 89 | return static_cast(_content.asInteger); 90 | case JSON_NEGATIVE_INTEGER: 91 | return -static_cast(_content.asInteger); 92 | case JSON_STRING: 93 | case JSON_UNPARSED: 94 | return Polyfills::parseFloat(_content.asString); 95 | default: 96 | return static_cast(_content.asFloat); 97 | } 98 | } 99 | 100 | inline bool JsonVariant::variantIsBoolean() const { 101 | using namespace Internals; 102 | if (_type == JSON_BOOLEAN) return true; 103 | 104 | if (_type != JSON_UNPARSED || _content.asString == NULL) return false; 105 | 106 | return !strcmp(_content.asString, "true") || 107 | !strcmp(_content.asString, "false"); 108 | } 109 | 110 | inline bool JsonVariant::variantIsInteger() const { 111 | using namespace Internals; 112 | 113 | return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER || 114 | (_type == JSON_UNPARSED && Polyfills::isInteger(_content.asString)); 115 | } 116 | 117 | inline bool JsonVariant::variantIsFloat() const { 118 | using namespace Internals; 119 | 120 | return _type >= JSON_FLOAT_0_DECIMALS || 121 | (_type == JSON_UNPARSED && Polyfills::isFloat(_content.asString)); 122 | } 123 | 124 | #if ARDUINOJSON_ENABLE_STD_STREAM 125 | inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) { 126 | return source.printTo(os); 127 | } 128 | #endif 129 | 130 | } // namespace ArduinoJson 131 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/attributes.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #ifdef _MSC_VER 11 | #define FORCE_INLINE __forceinline 12 | #define NO_INLINE __declspec(noinline) 13 | #define DEPRECATED(msg) __declspec(deprecated(msg)) 14 | #else 15 | #define FORCE_INLINE __attribute__((always_inline)) 16 | #define NO_INLINE __attribute__((noinline)) 17 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) 18 | #define DEPRECATED(msg) __attribute__((deprecated(msg))) 19 | #else 20 | #define DEPRECATED(msg) __attribute__((deprecated)) 21 | #endif 22 | #endif 23 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/ctype.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Polyfills { 12 | 13 | inline bool isdigit(char c) { 14 | return '0' <= c && c <= '9'; 15 | } 16 | 17 | inline bool issign(char c) { 18 | return '-' == c || c == '+'; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/isFloat.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include // for strcmp 11 | #include "./ctype.hpp" 12 | 13 | namespace ArduinoJson { 14 | namespace Polyfills { 15 | 16 | inline bool isFloat(const char* s) { 17 | if (!s) return false; 18 | 19 | if (!strcmp(s, "NaN")) return true; 20 | if (issign(*s)) s++; 21 | if (!strcmp(s, "Infinity")) return true; 22 | 23 | while (isdigit(*s)) s++; 24 | 25 | bool has_dot = *s == '.'; 26 | if (has_dot) { 27 | s++; 28 | while (isdigit(*s)) s++; 29 | } 30 | 31 | bool has_exponent = *s == 'e' || *s == 'E'; 32 | if (has_exponent) { 33 | s++; 34 | if (issign(*s)) s++; 35 | if (!isdigit(*s)) return false; 36 | while (isdigit(*s)) s++; 37 | } 38 | 39 | return (has_dot || has_exponent) && *s == '\0'; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/isInteger.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "./ctype.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace Polyfills { 14 | 15 | inline bool isInteger(const char* s) { 16 | if (!s) return false; 17 | if (issign(*s)) s++; 18 | while (isdigit(*s)) s++; 19 | return *s == '\0'; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/math.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | // If Visual Studo 11 | #if defined(_MSC_VER) 12 | 13 | #include 14 | #include 15 | 16 | namespace ArduinoJson { 17 | namespace Polyfills { 18 | template 19 | bool isNaN(T x) { 20 | return _isnan(x) != 0; 21 | } 22 | 23 | template 24 | bool isInfinity(T x) { 25 | return !_finite(x); 26 | } 27 | 28 | template 29 | T nan() { 30 | return std::numeric_limits::quiet_NaN(); 31 | } 32 | 33 | template 34 | T inf() { 35 | return std::numeric_limits::infinity(); 36 | } 37 | } 38 | } 39 | 40 | #else 41 | 42 | #include 43 | 44 | // GCC warning: "conversion to 'float' from 'double' may alter its value" 45 | #ifdef __GNUC__ 46 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 47 | #pragma GCC diagnostic push 48 | #endif 49 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) 50 | #pragma GCC diagnostic ignored "-Wfloat-conversion" 51 | #else 52 | #pragma GCC diagnostic ignored "-Wconversion" 53 | #endif 54 | #endif 55 | 56 | // Workaround for libs that #undef isnan or isinf 57 | // https://bblanchon.github.io/ArduinoJson//issues/284 58 | #if !defined(isnan) || !defined(isinf) 59 | namespace std {} 60 | #endif 61 | 62 | namespace ArduinoJson { 63 | namespace Polyfills { 64 | 65 | template 66 | bool isNaN(T x) { 67 | // Workaround for libs that #undef isnan 68 | // https://bblanchon.github.io/ArduinoJson//issues/284 69 | #ifndef isnan 70 | using namespace std; 71 | #endif 72 | 73 | return isnan(x); 74 | } 75 | 76 | #if defined(_GLIBCXX_HAVE_ISNANL) && _GLIBCXX_HAVE_ISNANL 77 | template <> 78 | inline bool isNaN(double x) { 79 | return isnanl(x); 80 | } 81 | #endif 82 | 83 | #if defined(_GLIBCXX_HAVE_ISNANF) && _GLIBCXX_HAVE_ISNANF 84 | template <> 85 | inline bool isNaN(float x) { 86 | return isnanf(x); 87 | } 88 | #endif 89 | 90 | template 91 | bool isInfinity(T x) { 92 | // Workaround for libs that #undef isinf 93 | // https://bblanchon.github.io/ArduinoJson//issues/284 94 | #ifndef isinf 95 | using namespace std; 96 | #endif 97 | 98 | return isinf(x); 99 | } 100 | 101 | #if defined(_GLIBCXX_HAVE_ISINFL) && _GLIBCXX_HAVE_ISINFL 102 | template <> 103 | inline bool isInfinity(double x) { 104 | return isinfl(x); 105 | } 106 | #endif 107 | 108 | #if defined(_GLIBCXX_HAVE_ISINFF) && _GLIBCXX_HAVE_ISINFF 109 | template <> 110 | inline bool isInfinity(float x) { 111 | return isinff(x); 112 | } 113 | #endif 114 | 115 | template 116 | T nan() { 117 | return static_cast(NAN); 118 | } 119 | 120 | template 121 | T inf() { 122 | return static_cast(INFINITY); 123 | } 124 | 125 | #if defined(__GNUC__) 126 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 127 | #pragma GCC diagnostic pop 128 | #endif 129 | #endif 130 | } 131 | } 132 | #endif 133 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/normalize.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Polyfills { 12 | 13 | #ifdef ARDUINO 14 | 15 | // on embedded platform, favor code size over speed 16 | 17 | template 18 | short normalize(T& value) { 19 | short powersOf10 = 0; 20 | while (value && value < 1) { 21 | powersOf10--; 22 | value *= 10; 23 | } 24 | while (value > 10) { 25 | powersOf10++; 26 | value /= 10; 27 | } 28 | return powersOf10; 29 | } 30 | 31 | #else 32 | 33 | // on non-embedded platform, favor speed over code size 34 | 35 | template 36 | short normalize(T& value) { 37 | if (value == 0.0) return 0; 38 | 39 | short powersOf10 = static_cast(floor(log10(value))); 40 | value /= pow(T(10), powersOf10); 41 | 42 | return powersOf10; 43 | } 44 | 45 | #endif 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/parseFloat.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../TypeTraits/FloatTraits.hpp" 11 | #include "./ctype.hpp" 12 | #include "./math.hpp" 13 | 14 | namespace ArduinoJson { 15 | namespace Polyfills { 16 | 17 | template 18 | inline T parseFloat(const char* s) { 19 | typedef TypeTraits::FloatTraits traits; 20 | typedef typename traits::mantissa_type mantissa_t; 21 | typedef typename traits::exponent_type exponent_t; 22 | 23 | if (!s) return 0; 24 | 25 | bool negative_result = false; 26 | switch (*s) { 27 | case '-': 28 | negative_result = true; 29 | case '+': 30 | s++; 31 | } 32 | 33 | if (*s == 'n' || *s == 'N') return traits::nan(); 34 | if (*s == 'i' || *s == 'I') 35 | return negative_result ? -traits::inf() : traits::inf(); 36 | 37 | mantissa_t mantissa = 0; 38 | exponent_t exponent_offset = 0; 39 | 40 | while (isdigit(*s)) { 41 | if (mantissa < traits::mantissa_max / 10) 42 | mantissa = mantissa * 10 + (*s - '0'); 43 | else 44 | exponent_offset++; 45 | s++; 46 | } 47 | 48 | if (*s == '.') { 49 | s++; 50 | while (isdigit(*s)) { 51 | if (mantissa < traits::mantissa_max / 10) { 52 | mantissa = mantissa * 10 + (*s - '0'); 53 | exponent_offset--; 54 | } 55 | s++; 56 | } 57 | } 58 | 59 | int exponent = 0; 60 | if (*s == 'e' || *s == 'E') { 61 | s++; 62 | bool negative_exponent = false; 63 | if (*s == '-') { 64 | negative_exponent = true; 65 | s++; 66 | } else if (*s == '+') { 67 | s++; 68 | } 69 | 70 | while (isdigit(*s)) { 71 | exponent = exponent * 10 + (*s - '0'); 72 | if (exponent + exponent_offset > traits::exponent_max) { 73 | if (negative_exponent) 74 | return negative_result ? -0.0f : 0.0f; 75 | else 76 | return negative_result ? -traits::inf() : traits::inf(); 77 | } 78 | s++; 79 | } 80 | if (negative_exponent) exponent = -exponent; 81 | } 82 | exponent += exponent_offset; 83 | 84 | T result = traits::make_float(static_cast(mantissa), exponent); 85 | 86 | return negative_result ? -result : result; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Polyfills/parseInteger.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include "../Configuration.hpp" 13 | #include "./ctype.hpp" 14 | 15 | namespace ArduinoJson { 16 | namespace Polyfills { 17 | template 18 | T parseInteger(const char *s) { 19 | if (!s) return 0; 20 | 21 | T result = 0; 22 | bool negative_result = false; 23 | 24 | switch (*s) { 25 | case '-': 26 | negative_result = true; 27 | case '+': 28 | s++; 29 | break; 30 | } 31 | 32 | while (isdigit(*s)) { 33 | result = static_cast(result * 10 + (*s - '0')); 34 | s++; 35 | } 36 | 37 | return negative_result ? static_cast(result * -1) : result; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/RawJson.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | 12 | // A special type of data that can be used to insert pregenerated JSON portions. 13 | class RawJson { 14 | public: 15 | explicit RawJson(const char* str) : _str(str) {} 16 | operator const char*() const { 17 | return _str; 18 | } 19 | 20 | private: 21 | const char* _str; 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/DummyPrint.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | // A dummy Print implementation used in JsonPrintable::measureLength() 14 | class DummyPrint { 15 | public: 16 | size_t print(char) { 17 | return 1; 18 | } 19 | 20 | size_t print(const char* s) { 21 | return strlen(s); 22 | } 23 | }; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/DynamicStringBuilder.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../StringTraits/StringTraits.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace Internals { 14 | 15 | // A Print implementation that allows to write in a String 16 | template 17 | class DynamicStringBuilder { 18 | public: 19 | DynamicStringBuilder(TString &str) : _str(str) {} 20 | 21 | size_t print(char c) { 22 | StringTraits::append(_str, c); 23 | return 1; 24 | } 25 | 26 | size_t print(const char *s) { 27 | size_t initialLen = _str.length(); 28 | StringTraits::append(_str, s); 29 | return _str.length() - initialLen; 30 | } 31 | 32 | private: 33 | DynamicStringBuilder &operator=(const DynamicStringBuilder &); 34 | 35 | TString &_str; 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/IndentedPrint.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | // Decorator on top of Print to allow indented output. 14 | // This class is used by JsonPrintable::prettyPrintTo() but can also be used 15 | // for your own purpose, like logging. 16 | template 17 | class IndentedPrint { 18 | public: 19 | explicit IndentedPrint(Print &p) : sink(&p) { 20 | level = 0; 21 | tabSize = 2; 22 | isNewLine = true; 23 | } 24 | 25 | size_t print(char c) { 26 | size_t n = 0; 27 | if (isNewLine) n += writeTabs(); 28 | n += sink->print(c); 29 | isNewLine = c == '\n'; 30 | return n; 31 | } 32 | 33 | size_t print(const char *s) { 34 | // TODO: optimize 35 | size_t n = 0; 36 | while (*s) n += print(*s++); 37 | return n; 38 | } 39 | 40 | // Adds one level of indentation 41 | void indent() { 42 | if (level < MAX_LEVEL) level++; 43 | } 44 | 45 | // Removes one level of indentation 46 | void unindent() { 47 | if (level > 0) level--; 48 | } 49 | 50 | // Set the number of space printed for each level of indentation 51 | void setTabSize(uint8_t n) { 52 | if (n < MAX_TAB_SIZE) tabSize = n & MAX_TAB_SIZE; 53 | } 54 | 55 | private: 56 | Print *sink; 57 | uint8_t level : 4; 58 | uint8_t tabSize : 3; 59 | bool isNewLine : 1; 60 | 61 | size_t writeTabs() { 62 | size_t n = 0; 63 | for (int i = 0; i < level * tabSize; i++) n += sink->print(' '); 64 | return n; 65 | } 66 | 67 | static const int MAX_LEVEL = 15; // because it's only 4 bits 68 | static const int MAX_TAB_SIZE = 7; // because it's only 3 bits 69 | }; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/JsonPrintable.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../Configuration.hpp" 11 | #include "../TypeTraits/EnableIf.hpp" 12 | #include "DummyPrint.hpp" 13 | #include "DynamicStringBuilder.hpp" 14 | #include "IndentedPrint.hpp" 15 | #include "JsonSerializer.hpp" 16 | #include "JsonWriter.hpp" 17 | #include "Prettyfier.hpp" 18 | #include "StaticStringBuilder.hpp" 19 | 20 | #if ARDUINOJSON_ENABLE_STD_STREAM 21 | #include "StreamPrintAdapter.hpp" 22 | #endif 23 | 24 | namespace ArduinoJson { 25 | namespace Internals { 26 | 27 | // Implements all the overloads of printTo() and prettyPrintTo() 28 | // Caution: this class use a template parameter to avoid virtual methods. 29 | // This is a bit curious but allows to reduce the size of JsonVariant, JsonArray 30 | // and JsonObject. 31 | template 32 | class JsonPrintable { 33 | public: 34 | template 35 | typename TypeTraits::EnableIf::value, 36 | size_t>::type 37 | printTo(Print &print) const { 38 | JsonWriter writer(print); 39 | JsonSerializer >::serialize(downcast(), writer); 40 | return writer.bytesWritten(); 41 | } 42 | 43 | #if ARDUINOJSON_ENABLE_STD_STREAM 44 | std::ostream &printTo(std::ostream &os) const { 45 | StreamPrintAdapter adapter(os); 46 | printTo(adapter); 47 | return os; 48 | } 49 | #endif 50 | 51 | size_t printTo(char *buffer, size_t bufferSize) const { 52 | StaticStringBuilder sb(buffer, bufferSize); 53 | return printTo(sb); 54 | } 55 | 56 | template 57 | size_t printTo(char (&buffer)[N]) const { 58 | return printTo(buffer, N); 59 | } 60 | 61 | template 62 | typename TypeTraits::EnableIf::has_append, size_t>::type 63 | printTo(TString &str) const { 64 | DynamicStringBuilder sb(str); 65 | return printTo(sb); 66 | } 67 | 68 | template 69 | size_t prettyPrintTo(IndentedPrint &print) const { 70 | Prettyfier p(print); 71 | return printTo(p); 72 | } 73 | 74 | size_t prettyPrintTo(char *buffer, size_t bufferSize) const { 75 | StaticStringBuilder sb(buffer, bufferSize); 76 | return prettyPrintTo(sb); 77 | } 78 | 79 | template 80 | size_t prettyPrintTo(char (&buffer)[N]) const { 81 | return prettyPrintTo(buffer, N); 82 | } 83 | 84 | template 85 | typename TypeTraits::EnableIf::value, 86 | size_t>::type 87 | prettyPrintTo(Print &print) const { 88 | IndentedPrint indentedPrint(print); 89 | return prettyPrintTo(indentedPrint); 90 | } 91 | 92 | template 93 | typename TypeTraits::EnableIf::has_append, size_t>::type 94 | prettyPrintTo(TString &str) const { 95 | DynamicStringBuilder sb(str); 96 | return prettyPrintTo(sb); 97 | } 98 | 99 | size_t measureLength() const { 100 | DummyPrint dp; 101 | return printTo(dp); 102 | } 103 | 104 | size_t measurePrettyLength() const { 105 | DummyPrint dp; 106 | return prettyPrintTo(dp); 107 | } 108 | 109 | private: 110 | const T &downcast() const { 111 | return *static_cast(this); 112 | } 113 | }; 114 | 115 | #if ARDUINOJSON_ENABLE_STD_STREAM 116 | template 117 | inline std::ostream &operator<<(std::ostream &os, const JsonPrintable &v) { 118 | return v.printTo(os); 119 | } 120 | #endif 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/JsonSerializer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "JsonWriter.hpp" 11 | 12 | namespace ArduinoJson { 13 | 14 | class JsonArray; 15 | class JsonArraySubscript; 16 | class JsonObject; 17 | template 18 | class JsonObjectSubscript; 19 | class JsonVariant; 20 | 21 | namespace Internals { 22 | 23 | template 24 | class JsonSerializer { 25 | public: 26 | static void serialize(const JsonArray &, Writer &); 27 | static void serialize(const JsonArraySubscript &, Writer &); 28 | static void serialize(const JsonObject &, Writer &); 29 | template 30 | static void serialize(const JsonObjectSubscript &, Writer &); 31 | static void serialize(const JsonVariant &, Writer &); 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/JsonSerializerImpl.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../JsonArray.hpp" 11 | #include "../JsonArraySubscript.hpp" 12 | #include "../JsonObject.hpp" 13 | #include "../JsonObjectSubscript.hpp" 14 | #include "../JsonVariant.hpp" 15 | #include "JsonSerializer.hpp" 16 | 17 | template 18 | inline void ArduinoJson::Internals::JsonSerializer::serialize( 19 | const JsonArray& array, Writer& writer) { 20 | writer.beginArray(); 21 | 22 | JsonArray::const_iterator it = array.begin(); 23 | while (it != array.end()) { 24 | serialize(*it, writer); 25 | 26 | ++it; 27 | if (it == array.end()) break; 28 | 29 | writer.writeComma(); 30 | } 31 | 32 | writer.endArray(); 33 | } 34 | 35 | template 36 | inline void ArduinoJson::Internals::JsonSerializer::serialize( 37 | const JsonArraySubscript& arraySubscript, Writer& writer) { 38 | serialize(arraySubscript.as(), writer); 39 | } 40 | 41 | template 42 | inline void ArduinoJson::Internals::JsonSerializer::serialize( 43 | const JsonObject& object, Writer& writer) { 44 | writer.beginObject(); 45 | 46 | JsonObject::const_iterator it = object.begin(); 47 | while (it != object.end()) { 48 | writer.writeString(it->key); 49 | writer.writeColon(); 50 | serialize(it->value, writer); 51 | 52 | ++it; 53 | if (it == object.end()) break; 54 | 55 | writer.writeComma(); 56 | } 57 | 58 | writer.endObject(); 59 | } 60 | 61 | template 62 | template 63 | inline void ArduinoJson::Internals::JsonSerializer::serialize( 64 | const JsonObjectSubscript& objectSubscript, Writer& writer) { 65 | serialize(objectSubscript.template as(), writer); 66 | } 67 | 68 | template 69 | inline void ArduinoJson::Internals::JsonSerializer::serialize( 70 | const JsonVariant& variant, Writer& writer) { 71 | switch (variant._type) { 72 | case JSON_UNDEFINED: 73 | return; 74 | 75 | case JSON_ARRAY: 76 | serialize(*variant._content.asArray, writer); 77 | return; 78 | 79 | case JSON_OBJECT: 80 | serialize(*variant._content.asObject, writer); 81 | return; 82 | 83 | case JSON_STRING: 84 | writer.writeString(variant._content.asString); 85 | return; 86 | 87 | case JSON_UNPARSED: 88 | writer.writeRaw(variant._content.asString); 89 | return; 90 | 91 | case JSON_NEGATIVE_INTEGER: 92 | writer.writeRaw('-'); 93 | case JSON_POSITIVE_INTEGER: 94 | writer.writeInteger(variant._content.asInteger); 95 | return; 96 | 97 | case JSON_BOOLEAN: 98 | writer.writeBoolean(variant._content.asInteger != 0); 99 | return; 100 | 101 | default: 102 | uint8_t decimals = 103 | static_cast(variant._type - JSON_FLOAT_0_DECIMALS); 104 | writer.writeFloat(variant._content.asFloat, decimals); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/JsonWriter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include 11 | #include "../Data/Encoding.hpp" 12 | #include "../Data/JsonFloat.hpp" 13 | #include "../Data/JsonInteger.hpp" 14 | #include "../Polyfills/attributes.hpp" 15 | #include "../Polyfills/math.hpp" 16 | #include "../Polyfills/normalize.hpp" 17 | 18 | namespace ArduinoJson { 19 | namespace Internals { 20 | 21 | // Writes the JSON tokens to a Print implementation 22 | // This class is used by: 23 | // - JsonArray::writeTo() 24 | // - JsonObject::writeTo() 25 | // - JsonVariant::writeTo() 26 | // Its derived by PrettyJsonWriter that overrides some members to add 27 | // indentation. 28 | template 29 | class JsonWriter { 30 | public: 31 | explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {} 32 | 33 | // Returns the number of bytes sent to the Print implementation. 34 | // This is very handy for implementations of printTo() that must return the 35 | // number of bytes written. 36 | size_t bytesWritten() const { 37 | return _length; 38 | } 39 | 40 | void beginArray() { 41 | writeRaw('['); 42 | } 43 | void endArray() { 44 | writeRaw(']'); 45 | } 46 | 47 | void beginObject() { 48 | writeRaw('{'); 49 | } 50 | void endObject() { 51 | writeRaw('}'); 52 | } 53 | 54 | void writeColon() { 55 | writeRaw(':'); 56 | } 57 | void writeComma() { 58 | writeRaw(','); 59 | } 60 | 61 | void writeBoolean(bool value) { 62 | writeRaw(value ? "true" : "false"); 63 | } 64 | 65 | void writeString(const char *value) { 66 | if (!value) { 67 | writeRaw("null"); 68 | } else { 69 | writeRaw('\"'); 70 | while (*value) writeChar(*value++); 71 | writeRaw('\"'); 72 | } 73 | } 74 | 75 | void writeChar(char c) { 76 | char specialChar = Encoding::escapeChar(c); 77 | if (specialChar) { 78 | writeRaw('\\'); 79 | writeRaw(specialChar); 80 | } else { 81 | writeRaw(c); 82 | } 83 | } 84 | 85 | void writeFloat(JsonFloat value, uint8_t digits = 2) { 86 | if (Polyfills::isNaN(value)) return writeRaw("NaN"); 87 | 88 | if (value < 0.0) { 89 | writeRaw('-'); 90 | value = -value; 91 | } 92 | 93 | if (Polyfills::isInfinity(value)) return writeRaw("Infinity"); 94 | 95 | short powersOf10; 96 | if (value > 1000 || value < 0.001) { 97 | powersOf10 = Polyfills::normalize(value); 98 | } else { 99 | powersOf10 = 0; 100 | } 101 | 102 | // Round up last digit (so that print(1.999, 2) prints as "2.00") 103 | value += getRoundingBias(digits); 104 | 105 | // Extract the integer part of the value and print it 106 | JsonUInt int_part = static_cast(value); 107 | JsonFloat remainder = value - static_cast(int_part); 108 | writeInteger(int_part); 109 | 110 | // Print the decimal point, but only if there are digits beyond 111 | if (digits > 0) { 112 | writeRaw('.'); 113 | } 114 | 115 | // Extract digits from the remainder one at a time 116 | while (digits-- > 0) { 117 | // Extract digit 118 | remainder *= 10.0; 119 | char currentDigit = char(remainder); 120 | remainder -= static_cast(currentDigit); 121 | 122 | // Print 123 | writeRaw(char('0' + currentDigit)); 124 | } 125 | 126 | if (powersOf10 < 0) { 127 | writeRaw("e-"); 128 | writeInteger(-powersOf10); 129 | } 130 | 131 | if (powersOf10 > 0) { 132 | writeRaw('e'); 133 | writeInteger(powersOf10); 134 | } 135 | } 136 | 137 | void writeInteger(JsonUInt value) { 138 | char buffer[22]; 139 | char *ptr = buffer + sizeof(buffer) - 1; 140 | 141 | *ptr = 0; 142 | do { 143 | *--ptr = static_cast(value % 10 + '0'); 144 | value /= 10; 145 | } while (value); 146 | 147 | writeRaw(ptr); 148 | } 149 | 150 | void writeRaw(const char *s) { 151 | _length += _sink.print(s); 152 | } 153 | void writeRaw(char c) { 154 | _length += _sink.print(c); 155 | } 156 | 157 | protected: 158 | Print &_sink; 159 | size_t _length; 160 | 161 | private: 162 | JsonWriter &operator=(const JsonWriter &); // cannot be assigned 163 | 164 | static JsonFloat getLastDigit(uint8_t digits) { 165 | // Designed as a compromise between code size and speed 166 | switch (digits) { 167 | case 0: 168 | return 1e-0; 169 | case 1: 170 | return 1e-1; 171 | case 2: 172 | return 1e-2; 173 | case 3: 174 | return 1e-3; 175 | default: 176 | return getLastDigit(uint8_t(digits - 4)) * 1e-4; 177 | } 178 | } 179 | 180 | FORCE_INLINE static JsonFloat getRoundingBias(uint8_t digits) { 181 | return 0.5 * getLastDigit(digits); 182 | } 183 | }; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/Prettyfier.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "IndentedPrint.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace Internals { 14 | 15 | // Converts a compact JSON string into an indented one. 16 | template 17 | class Prettyfier { 18 | public: 19 | explicit Prettyfier(IndentedPrint& p) : _sink(p) { 20 | _previousChar = 0; 21 | _inString = false; 22 | } 23 | 24 | size_t print(char c) { 25 | size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c); 26 | _previousChar = c; 27 | return n; 28 | } 29 | 30 | size_t print(const char* s) { 31 | // TODO: optimize 32 | size_t n = 0; 33 | while (*s) n += print(*s++); 34 | return n; 35 | } 36 | 37 | private: 38 | Prettyfier& operator=(const Prettyfier&); // cannot be assigned 39 | 40 | bool inEmptyBlock() { 41 | return _previousChar == '{' || _previousChar == '['; 42 | } 43 | 44 | size_t handleStringChar(char c) { 45 | bool isQuote = c == '"' && _previousChar != '\\'; 46 | 47 | if (isQuote) _inString = false; 48 | 49 | return _sink.print(c); 50 | } 51 | 52 | size_t handleMarkupChar(char c) { 53 | switch (c) { 54 | case '{': 55 | case '[': 56 | return writeBlockOpen(c); 57 | 58 | case '}': 59 | case ']': 60 | return writeBlockClose(c); 61 | 62 | case ':': 63 | return writeColon(); 64 | 65 | case ',': 66 | return writeComma(); 67 | 68 | case '"': 69 | return writeQuoteOpen(); 70 | 71 | default: 72 | return writeNormalChar(c); 73 | } 74 | } 75 | 76 | size_t writeBlockClose(char c) { 77 | size_t n = 0; 78 | n += unindentIfNeeded(); 79 | n += _sink.print(c); 80 | return n; 81 | } 82 | 83 | size_t writeBlockOpen(char c) { 84 | size_t n = 0; 85 | n += indentIfNeeded(); 86 | n += _sink.print(c); 87 | return n; 88 | } 89 | 90 | size_t writeColon() { 91 | size_t n = 0; 92 | n += _sink.print(": "); 93 | return n; 94 | } 95 | 96 | size_t writeComma() { 97 | size_t n = 0; 98 | n += _sink.print(",\r\n"); 99 | return n; 100 | } 101 | 102 | size_t writeQuoteOpen() { 103 | _inString = true; 104 | size_t n = 0; 105 | n += indentIfNeeded(); 106 | n += _sink.print('"'); 107 | return n; 108 | } 109 | 110 | size_t writeNormalChar(char c) { 111 | size_t n = 0; 112 | n += indentIfNeeded(); 113 | n += _sink.print(c); 114 | return n; 115 | } 116 | 117 | size_t indentIfNeeded() { 118 | if (!inEmptyBlock()) return 0; 119 | 120 | _sink.indent(); 121 | return _sink.print("\r\n"); 122 | } 123 | 124 | size_t unindentIfNeeded() { 125 | if (inEmptyBlock()) return 0; 126 | 127 | _sink.unindent(); 128 | return _sink.print("\r\n"); 129 | } 130 | 131 | char _previousChar; 132 | IndentedPrint& _sink; 133 | bool _inString; 134 | }; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/StaticStringBuilder.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | // A Print implementation that allows to write in a char[] 14 | class StaticStringBuilder { 15 | public: 16 | StaticStringBuilder(char *buf, size_t size) : end(buf + size - 1), p(buf) { 17 | *p = '\0'; 18 | } 19 | 20 | size_t print(char c) { 21 | if (p >= end) return 0; 22 | *p++ = c; 23 | *p = '\0'; 24 | return 1; 25 | } 26 | 27 | size_t print(const char *s) { 28 | char *begin = p; 29 | while (p < end && *s) *p++ = *s++; 30 | *p = '\0'; 31 | return p - begin; 32 | } 33 | 34 | private: 35 | char *end; 36 | char *p; 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/Serialization/StreamPrintAdapter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../Configuration.hpp" 11 | 12 | #if ARDUINOJSON_ENABLE_STD_STREAM 13 | 14 | #include 15 | 16 | namespace ArduinoJson { 17 | namespace Internals { 18 | 19 | class StreamPrintAdapter { 20 | public: 21 | explicit StreamPrintAdapter(std::ostream& os) : _os(os) {} 22 | 23 | size_t print(char c) { 24 | _os << c; 25 | return 1; 26 | } 27 | 28 | size_t print(const char* s) { 29 | _os << s; 30 | return strlen(s); 31 | } 32 | 33 | private: 34 | // cannot be assigned 35 | StreamPrintAdapter& operator=(const StreamPrintAdapter&); 36 | 37 | std::ostream& _os; 38 | }; 39 | } 40 | } 41 | 42 | #endif // ARDUINOJSON_ENABLE_STD_STREAM 43 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/StaticJsonBuffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "JsonBufferBase.hpp" 11 | 12 | #if defined(__clang__) 13 | #pragma clang diagnostic push 14 | #pragma clang diagnostic ignored "-Wnon-virtual-dtor" 15 | #elif defined(__GNUC__) 16 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 17 | #pragma GCC diagnostic push 18 | #endif 19 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 20 | #endif 21 | 22 | namespace ArduinoJson { 23 | 24 | class StaticJsonBufferBase : public JsonBufferBase { 25 | public: 26 | class String { 27 | public: 28 | String(StaticJsonBufferBase* parent) : _parent(parent) { 29 | _start = parent->_buffer + parent->_size; 30 | } 31 | 32 | void append(char c) { 33 | if (_parent->canAlloc(1)) { 34 | char* last = static_cast(_parent->doAlloc(1)); 35 | *last = c; 36 | } 37 | } 38 | 39 | const char* c_str() const { 40 | if (_parent->canAlloc(1)) { 41 | char* last = static_cast(_parent->doAlloc(1)); 42 | *last = '\0'; 43 | return _start; 44 | } else { 45 | return NULL; 46 | } 47 | } 48 | 49 | private: 50 | StaticJsonBufferBase* _parent; 51 | char* _start; 52 | }; 53 | 54 | StaticJsonBufferBase(char* buffer, size_t capa) 55 | : _buffer(buffer), _capacity(capa), _size(0) {} 56 | 57 | size_t capacity() const { 58 | return _capacity; 59 | } 60 | size_t size() const { 61 | return _size; 62 | } 63 | 64 | virtual void* alloc(size_t bytes) { 65 | alignNextAlloc(); 66 | if (!canAlloc(bytes)) return NULL; 67 | return doAlloc(bytes); 68 | } 69 | 70 | String startString() { 71 | return String(this); 72 | } 73 | 74 | private: 75 | void alignNextAlloc() { 76 | _size = round_size_up(_size); 77 | } 78 | 79 | bool canAlloc(size_t bytes) const { 80 | return _size + bytes <= _capacity; 81 | } 82 | 83 | void* doAlloc(size_t bytes) { 84 | void* p = &_buffer[_size]; 85 | _size += bytes; 86 | return p; 87 | } 88 | 89 | char* _buffer; 90 | size_t _capacity; 91 | size_t _size; 92 | }; 93 | 94 | // Implements a JsonBuffer with fixed memory allocation. 95 | // The template paramenter CAPACITY specifies the capacity of the buffer in 96 | // bytes. 97 | template 98 | class StaticJsonBuffer : public StaticJsonBufferBase { 99 | public: 100 | explicit StaticJsonBuffer() : StaticJsonBufferBase(_buffer, CAPACITY) {} 101 | 102 | private: 103 | char _buffer[CAPACITY]; 104 | }; 105 | } 106 | 107 | #if defined(__clang__) 108 | #pragma clang diagnostic pop 109 | #elif defined(__GNUC__) 110 | #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) 111 | #pragma GCC diagnostic pop 112 | #endif 113 | #endif 114 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/StringTraits/ArduinoStream.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #if ARDUINOJSON_ENABLE_ARDUINO_STREAM 11 | 12 | #include 13 | 14 | namespace ArduinoJson { 15 | namespace Internals { 16 | 17 | struct ArduinoStreamTraits { 18 | class Reader { 19 | Stream& _stream; 20 | char _current, _next; 21 | 22 | public: 23 | Reader(Stream& stream) : _stream(stream), _current(0), _next(0) {} 24 | 25 | void move() { 26 | _current = _next; 27 | _next = 0; 28 | } 29 | 30 | char current() { 31 | if (!_current) _current = read(); 32 | return _current; 33 | } 34 | 35 | char next() { 36 | // assumes that current() has been called 37 | if (!_next) _next = read(); 38 | return _next; 39 | } 40 | 41 | private: 42 | char read() { 43 | // don't use _stream.read() as it ignores the timeout 44 | char c = 0; 45 | _stream.readBytes(&c, 1); 46 | return c; 47 | } 48 | }; 49 | }; 50 | 51 | template 52 | struct StringTraits::type>::value>::type> 57 | : ArduinoStreamTraits {}; 58 | } 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/StringTraits/CharPointer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace Internals { 12 | 13 | template 14 | struct CharPointerTraits { 15 | class Reader { 16 | const TChar* _ptr; 17 | 18 | public: 19 | Reader(const TChar* ptr) 20 | : _ptr(ptr ? ptr : reinterpret_cast("")) {} 21 | 22 | void move() { 23 | ++_ptr; 24 | } 25 | 26 | TChar current() const { 27 | return _ptr[0]; 28 | } 29 | 30 | TChar next() const { 31 | return _ptr[1]; 32 | } 33 | }; 34 | 35 | static bool equals(const TChar* str, const char* expected) { 36 | return strcmp(reinterpret_cast(str), expected) == 0; 37 | } 38 | 39 | template 40 | static char* duplicate(const TChar* str, Buffer* buffer) { 41 | if (!str) return NULL; 42 | size_t size = strlen(reinterpret_cast(str)) + 1; 43 | void* dup = buffer->alloc(size); 44 | if (dup != NULL) memcpy(dup, str, size); 45 | return static_cast(dup); 46 | } 47 | 48 | static const bool has_append = false; 49 | static const bool has_equals = true; 50 | static const bool should_duplicate = false; 51 | }; 52 | 53 | template 54 | struct StringTraits::value>::type> 56 | : CharPointerTraits {}; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/StringTraits/FlashString.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #if ARDUINOJSON_ENABLE_PROGMEM 11 | 12 | namespace ArduinoJson { 13 | namespace Internals { 14 | template <> 15 | struct StringTraits { 16 | class Reader { 17 | const char* _ptr; 18 | 19 | public: 20 | Reader(const __FlashStringHelper* ptr) 21 | : _ptr(reinterpret_cast(ptr)) {} 22 | 23 | void move() { 24 | _ptr++; 25 | } 26 | 27 | char current() const { 28 | return pgm_read_byte_near(_ptr); 29 | } 30 | 31 | char next() const { 32 | return pgm_read_byte_near(_ptr + 1); 33 | } 34 | }; 35 | 36 | static bool equals(const __FlashStringHelper* str, const char* expected) { 37 | return strcmp_P(expected, (PGM_P)str) == 0; 38 | } 39 | 40 | template 41 | static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) { 42 | if (!str) return NULL; 43 | size_t size = strlen_P((PGM_P)str) + 1; 44 | void* dup = buffer->alloc(size); 45 | if (dup != NULL) memcpy_P(dup, (PGM_P)str, size); 46 | return static_cast(dup); 47 | } 48 | 49 | static const bool has_append = false; 50 | static const bool has_equals = true; 51 | static const bool should_duplicate = true; 52 | }; 53 | } 54 | } 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/StringTraits/StdStream.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #if ARDUINOJSON_ENABLE_STD_STREAM 11 | 12 | #include 13 | 14 | namespace ArduinoJson { 15 | namespace Internals { 16 | 17 | struct StdStreamTraits { 18 | class Reader { 19 | std::istream& _stream; 20 | char _current, _next; 21 | 22 | public: 23 | Reader(std::istream& stream) : _stream(stream), _current(0), _next(0) {} 24 | 25 | void move() { 26 | _current = _next; 27 | _next = 0; 28 | } 29 | 30 | char current() { 31 | if (!_current) _current = read(); 32 | return _current; 33 | } 34 | 35 | char next() { 36 | // assumes that current() has been called 37 | if (!_next) _next = read(); 38 | return _next; 39 | } 40 | 41 | private: 42 | Reader& operator=(const Reader&); // Visual Studio C4512 43 | 44 | char read() { 45 | return _stream.eof() ? '\0' : static_cast(_stream.get()); 46 | } 47 | }; 48 | }; 49 | 50 | template 51 | struct StringTraits::type>::value>::type> 56 | : StdStreamTraits {}; 57 | } 58 | } 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/StringTraits/StdString.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #if ARDUINOJSON_ENABLE_STD_STRING || ARDUINOJSON_ENABLE_ARDUINO_STRING 11 | 12 | #if ARDUINOJSON_ENABLE_ARDUINO_STRING 13 | #include 14 | #endif 15 | 16 | #if ARDUINOJSON_ENABLE_STD_STRING 17 | #include 18 | #endif 19 | 20 | namespace ArduinoJson { 21 | namespace Internals { 22 | 23 | template 24 | struct StdStringTraits { 25 | template 26 | static char* duplicate(const TString& str, Buffer* buffer) { 27 | if (!str.c_str()) return NULL; // <- Arduino string can return NULL 28 | size_t size = str.length() + 1; 29 | void* dup = buffer->alloc(size); 30 | if (dup != NULL) memcpy(dup, str.c_str(), size); 31 | return static_cast(dup); 32 | } 33 | 34 | struct Reader : CharPointerTraits::Reader { 35 | Reader(const TString& str) : CharPointerTraits::Reader(str.c_str()) {} 36 | }; 37 | 38 | static bool equals(const TString& str, const char* expected) { 39 | return 0 == strcmp(str.c_str(), expected); 40 | } 41 | 42 | static void append(TString& str, char c) { 43 | str += c; 44 | } 45 | 46 | static void append(TString& str, const char* s) { 47 | str += s; 48 | } 49 | 50 | static const bool has_append = true; 51 | static const bool has_equals = true; 52 | static const bool should_duplicate = true; 53 | }; 54 | 55 | #if ARDUINOJSON_ENABLE_ARDUINO_STRING 56 | template <> 57 | struct StringTraits : StdStringTraits {}; 58 | template <> 59 | struct StringTraits : StdStringTraits { 60 | }; 61 | #endif 62 | 63 | #if ARDUINOJSON_ENABLE_STD_STRING 64 | template <> 65 | struct StringTraits : StdStringTraits {}; 66 | #endif 67 | } 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/StringTraits/StringTraits.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../Configuration.hpp" 11 | #include "../TypeTraits/EnableIf.hpp" 12 | #include "../TypeTraits/IsBaseOf.hpp" 13 | #include "../TypeTraits/IsChar.hpp" 14 | #include "../TypeTraits/RemoveReference.hpp" 15 | 16 | namespace ArduinoJson { 17 | namespace Internals { 18 | 19 | template 20 | struct StringTraits {}; 21 | 22 | template 23 | struct StringTraits : StringTraits {}; 24 | 25 | template 26 | struct StringTraits : StringTraits {}; 27 | } 28 | } 29 | 30 | #include "ArduinoStream.hpp" 31 | #include "CharPointer.hpp" 32 | #include "FlashString.hpp" 33 | #include "StdStream.hpp" 34 | #include "StdString.hpp" 35 | 36 | namespace ArduinoJson { 37 | namespace TypeTraits { 38 | template 39 | struct IsString { 40 | static const bool value = false; 41 | }; 42 | 43 | template 44 | struct IsString::has_equals>::type> { 46 | static const bool value = Internals::StringTraits::has_equals; 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/EnableIf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace TypeTraits { 12 | 13 | // A meta-function that return the type T if Condition is true. 14 | template 15 | struct EnableIf {}; 16 | 17 | template 18 | struct EnableIf { 19 | typedef T type; 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/FloatTraits.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include 11 | #include // for size_t 12 | #include "../Polyfills/math.hpp" 13 | 14 | namespace ArduinoJson { 15 | namespace TypeTraits { 16 | 17 | template 18 | struct FloatTraits {}; 19 | 20 | #if !defined(__SIZEOF_DOUBLE__) || __SIZEOF_DOUBLE__ >= 8 21 | template 22 | struct FloatTraits { 23 | typedef int64_t mantissa_type; 24 | static const short mantissa_bits = 52; 25 | static const mantissa_type mantissa_max = 26 | (static_cast(1) << mantissa_bits) - 1; 27 | 28 | typedef int16_t exponent_type; 29 | static const exponent_type exponent_max = 308; 30 | 31 | template 32 | static T make_float(T m, TExponent e) { 33 | if (e >= 0) 34 | return m * (e & 1 ? 1e1 : 1) * (e & 2 ? 1e2 : 1) * (e & 4 ? 1e4 : 1) * 35 | (e & 8 ? 1e8 : 1) * (e & 16 ? 1e16 : 1) * (e & 32 ? 1e32 : 1) * 36 | (e & 64 ? 1e64 : 1) * (e & 128 ? 1e128 : 1) * 37 | (e & 256 ? 1e256 : 1); 38 | e = -e; 39 | return m * (e & 1 ? 1e-1 : 1) * (e & 2 ? 1e-2 : 1) * (e & 4 ? 1e-4 : 1) * 40 | (e & 8 ? 1e-8 : 1) * (e & 16 ? 1e-16 : 1) * (e & 32 ? 1e-32 : 1) * 41 | (e & 64 ? 1e-64 : 1) * (e & 128 ? 1e-128 : 1) * 42 | (e & 256 ? 1e-256 : 1); 43 | } 44 | 45 | static T nan() { 46 | return Polyfills::nan(); 47 | } 48 | 49 | static T inf() { 50 | return Polyfills::inf(); 51 | } 52 | }; 53 | #endif 54 | 55 | template 56 | struct FloatTraits { 57 | typedef int32_t mantissa_type; 58 | static const short mantissa_bits = 23; 59 | static const mantissa_type mantissa_max = 60 | (static_cast(1) << mantissa_bits) - 1; 61 | 62 | typedef int8_t exponent_type; 63 | static const exponent_type exponent_max = 38; 64 | 65 | template 66 | static T make_float(T m, TExponent e) { 67 | if (e > 0) 68 | return m * (e & 1 ? 1e1f : 1) * (e & 2 ? 1e2f : 1) * (e & 4 ? 1e4f : 1) * 69 | (e & 8 ? 1e8f : 1) * (e & 16 ? 1e16f : 1) * (e & 32 ? 1e32f : 1); 70 | e = -e; 71 | return m * (e & 1 ? 1e-1f : 1) * (e & 2 ? 1e-2f : 1) * (e & 4 ? 1e-4f : 1) * 72 | (e & 8 ? 1e-8f : 1) * (e & 16 ? 1e-16f : 1) * (e & 32 ? 1e-32f : 1); 73 | } 74 | 75 | static T nan() { 76 | return Polyfills::nan(); 77 | } 78 | 79 | static T inf() { 80 | return Polyfills::inf(); 81 | } 82 | }; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsArray.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace TypeTraits { 12 | 13 | // A meta-function that return the type T without the const modifier 14 | template 15 | struct IsArray { 16 | static const bool value = false; 17 | }; 18 | template 19 | struct IsArray { 20 | static const bool value = true; 21 | }; 22 | template 23 | struct IsArray { 24 | static const bool value = true; 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsBaseOf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace TypeTraits { 12 | 13 | // A meta-function that returns true if Derived inherits from TBase is an 14 | // integral type. 15 | template 16 | class IsBaseOf { 17 | protected: // <- to avoid GCC's "all member functions in class are private" 18 | typedef char Yes[1]; 19 | typedef char No[2]; 20 | 21 | static Yes &probe(const TBase *); 22 | static No &probe(...); 23 | 24 | public: 25 | enum { 26 | value = sizeof(probe(reinterpret_cast(0))) == sizeof(Yes) 27 | }; 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsChar.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "IsSame.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace TypeTraits { 14 | 15 | // A meta-function that returns true if T is a charater 16 | template 17 | struct IsChar { 18 | static const bool value = IsSame::value || 19 | IsSame::value || 20 | IsSame::value; 21 | }; 22 | 23 | template 24 | struct IsChar : IsChar {}; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsConst.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace TypeTraits { 12 | 13 | // A meta-function that return the type T without the const modifier 14 | template 15 | struct IsConst { 16 | static const bool value = false; 17 | }; 18 | 19 | template 20 | struct IsConst { 21 | static const bool value = true; 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsFloatingPoint.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "IsSame.hpp" 11 | 12 | namespace ArduinoJson { 13 | namespace TypeTraits { 14 | 15 | // A meta-function that returns true if T is a floating point type 16 | template 17 | struct IsFloatingPoint { 18 | static const bool value = IsSame::value || IsSame::value; 19 | }; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsIntegral.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "IsSame.hpp" 11 | #include "IsSignedIntegral.hpp" 12 | #include "IsUnsignedIntegral.hpp" 13 | 14 | namespace ArduinoJson { 15 | namespace TypeTraits { 16 | 17 | // A meta-function that returns true if T is an integral type. 18 | template 19 | struct IsIntegral { 20 | static const bool value = TypeTraits::IsSignedIntegral::value || 21 | TypeTraits::IsUnsignedIntegral::value || 22 | TypeTraits::IsSame::value; 23 | // CAUTION: differs from std::is_integral as it doesn't include bool 24 | }; 25 | 26 | template 27 | struct IsIntegral : IsIntegral {}; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsSame.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace TypeTraits { 12 | 13 | // A meta-function that returns true if types T and U are the same. 14 | template 15 | struct IsSame { 16 | static const bool value = false; 17 | }; 18 | 19 | template 20 | struct IsSame { 21 | static const bool value = true; 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsSignedIntegral.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../Configuration.hpp" 11 | #include "IsSame.hpp" 12 | 13 | namespace ArduinoJson { 14 | namespace TypeTraits { 15 | 16 | // A meta-function that returns true if T is an integral type. 17 | template 18 | struct IsSignedIntegral { 19 | static const bool value = TypeTraits::IsSame::value || 20 | TypeTraits::IsSame::value || 21 | TypeTraits::IsSame::value || 22 | TypeTraits::IsSame::value || 23 | #if ARDUINOJSON_USE_LONG_LONG 24 | TypeTraits::IsSame::value || 25 | #endif 26 | 27 | #if ARDUINOJSON_USE_INT64 28 | TypeTraits::IsSame::value || 29 | #endif 30 | false; 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | #include "../Configuration.hpp" 11 | #include "IsSame.hpp" 12 | 13 | namespace ArduinoJson { 14 | namespace TypeTraits { 15 | 16 | // A meta-function that returns true if T is an integral type. 17 | template 18 | struct IsUnsignedIntegral { 19 | static const bool value = TypeTraits::IsSame::value || 20 | TypeTraits::IsSame::value || 21 | TypeTraits::IsSame::value || 22 | TypeTraits::IsSame::value || 23 | #if ARDUINOJSON_USE_LONG_LONG 24 | TypeTraits::IsSame::value || 25 | #endif 26 | 27 | #if ARDUINOJSON_USE_INT64 28 | TypeTraits::IsSame::value || 29 | #endif 30 | false; 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/RemoveConst.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace TypeTraits { 12 | 13 | // A meta-function that return the type T without the const modifier 14 | template 15 | struct RemoveConst { 16 | typedef T type; 17 | }; 18 | template 19 | struct RemoveConst { 20 | typedef T type; 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ArduinoJson/ArduinoJson/TypeTraits/RemoveReference.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Benoit Blanchon 2014-2017 2 | // MIT License 3 | // 4 | // Arduino JSON library 5 | // https://bblanchon.github.io/ArduinoJson/ 6 | // If you like this project, please add a star! 7 | 8 | #pragma once 9 | 10 | namespace ArduinoJson { 11 | namespace TypeTraits { 12 | 13 | // A meta-function that return the type T without the reference modifier. 14 | template 15 | struct RemoveReference { 16 | typedef T type; 17 | }; 18 | template 19 | struct RemoveReference { 20 | typedef T type; 21 | }; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ESP8266/WebSocketClient/ESP8266_WebSocketClient/ESP8266_WebSocketClient.ino: -------------------------------------------------------------------------------- 1 | /* 2 | *Netmedias 3 | * 4 | * Created on: 24.05.2015 5 | * 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | // @@@@@@@@@@@@@@@ You only need to midify modify wi-fi and domain info @@@@@@@@@@@@@@@@@@@@ 15 | const char* ssid = "enter your ssid name"; //enter your ssid/ wi-fi(case sensitiv) router name - 2.4 Ghz only 16 | const char* password = "enter ssid password"; // enter ssid password (case sensitiv) 17 | char host[] = "espiot.herokuapp.com"; //enter your Heroku domain name like "espiot.herokuapp.com" 18 | // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 19 | 20 | int port = 80; 21 | char path[] = "/ws"; 22 | ESP8266WiFiMulti WiFiMulti; 23 | WebSocketsClient webSocket; 24 | const int relayPin = 16; 25 | DynamicJsonBuffer jsonBuffer; 26 | String currState; 27 | int pingCount=0; 28 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { //uint8_t * 29 | 30 | 31 | switch(type) { 32 | case WStype_DISCONNECTED: 33 | Serial.println("Disconnected! "); 34 | Serial.println("Connecting..."); 35 | webSocket.begin(host, port, path); 36 | webSocket.onEvent(webSocketEvent); 37 | break; 38 | 39 | case WStype_CONNECTED: 40 | { 41 | Serial.println("Connected! "); 42 | // send message to server when Connected 43 | webSocket.sendTXT("Connected"); 44 | } 45 | break; 46 | 47 | case WStype_TEXT: 48 | Serial.println("Got data"); 49 | //data = (char*)payload; 50 | processWebScoketRequest((char*)payload); 51 | break; 52 | 53 | case WStype_BIN: 54 | 55 | hexdump(payload, length); 56 | Serial.print("Got bin"); 57 | // send data to server 58 | webSocket.sendBIN(payload, length); 59 | break; 60 | } 61 | 62 | } 63 | 64 | void setup() { 65 | Serial.begin(115200); 66 | Serial.setDebugOutput(true); 67 | 68 | pinMode(relayPin, OUTPUT); 69 | 70 | for(uint8_t t = 4; t > 0; t--) { 71 | delay(1000); 72 | } 73 | Serial.println(); 74 | Serial.println(); 75 | Serial.print("Connecting to "); 76 | 77 | //Serial.println(ssid); 78 | WiFiMulti.addAP(ssid, password); 79 | 80 | //WiFi.disconnect(); 81 | while(WiFiMulti.run() != WL_CONNECTED) { 82 | Serial.print("."); 83 | delay(100); 84 | } 85 | Serial.println("Connected to wi-fi"); 86 | webSocket.begin(host, port, path); 87 | webSocket.onEvent(webSocketEvent); 88 | 89 | } 90 | 91 | void loop() { 92 | webSocket.loop(); 93 | //If you make change to delay mak sure adjust the ping 94 | delay(2000); 95 | // make sure after every 40 seconds send a ping to Heroku 96 | //so it does not terminate the websocket connection 97 | //This is to keep the conncetion alive between ESP and Heroku 98 | if (pingCount > 20) { 99 | pingCount = 0; 100 | webSocket.sendTXT("\"heartbeat\":\"keepalive\""); 101 | } 102 | else { 103 | pingCount += 1; 104 | } 105 | } 106 | 107 | void processWebScoketRequest(String data){ 108 | 109 | JsonObject& root = jsonBuffer.parseObject(data); 110 | String device = (const char*)root["device"]; 111 | String location = (const char*)root["location"]; 112 | String state = (const char*)root["state"]; 113 | String query = (const char*)root["query"]; 114 | String message=""; 115 | 116 | Serial.println(data); 117 | if(query == "cmd"){ //if query check state 118 | Serial.println("Received command!"); 119 | if(state=="on"){ 120 | digitalWrite(relayPin, HIGH); 121 | message = "{\"state\":\"ON\"}"; 122 | currState = "ON"; 123 | }else{ 124 | digitalWrite(relayPin, LOW); 125 | message = "{\"state\":\"OFF\"}"; 126 | currState = "OFF"; 127 | } 128 | 129 | }else if(query == "?"){ //if command then execute 130 | Serial.println("Received query!"); 131 | int state = digitalRead(relayPin); 132 | if(currState=="ON"){ 133 | message = "{\"state\":\"ON\"}"; 134 | }else{ 135 | message = "{\"state\":\"OFF\"}"; 136 | } 137 | }else{//can not recognized the command 138 | Serial.println("Command is not recognized!"); 139 | } 140 | Serial.print("Sending response back"); 141 | Serial.println(message); 142 | // send message to server 143 | webSocket.sendTXT(message); 144 | if(query == "cmd" || query == "?"){webSocket.sendTXT(message);} 145 | } 146 | 147 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: python app.py 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IOT-ESP8266-Google-Home 2 | 3 | YouTube tutorial -->https://www.youtube.com/watch?v=Uvg0ruRkKgY 4 | 5 | In This project you will beable to control ESP8266 with Google Home without opening a firewall port or setuping a revers proxy. 6 | 7 | 1. Download this project and unzip. 8 | 9 | 2. Deploy this project to Heroku by clicking this button 10 | [![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy) 11 | 12 | 3. Copy following folders to "C:\Program Files (x86)\Arduino\libraries", or install the libraries via the Arduino Library manager. 13 | 14 | arduinoWebSockets (WebSockets by Markus Sattler) 15 | 16 | ArduinoJson (ArduinoJson by Benolt Blanchon) 17 | 18 | 4. Update and flash your ESP8266 with "ESP8266/WebSocketClient/ESP8266_WebSocketClient/ESP8266_WebSocketClient.ino" 19 | 20 | 5. Create an API.ai agent and import "matrix-ai.zip" and setup Google integration and webhook 21 | 22 | 6. Test and enjoy. 23 | 24 | 25 | ## Troubleshooting 26 | 27 | 1. Make sure Google Home device is logged in to same account as your API.ai account. 28 | 29 | 2. If unable to trigger relay power cycle the ESP8266. 30 | 31 | 3. If you are still unable to trigger the relay then restart Heroku app by selecting option "Restat all dynos" and then power cycle the ESP8266. 32 | 33 | 3. If you see crash errors in Arduino IDE serial monitor the use a better power supply. 34 | 35 | 4. Use a saprate power source for relay or use 5volts power source and use 3.3 voltage regulator to power ESP8266 from same power supply. 36 | 37 | 5. Make sure you enter the correct URL for webhook in API.ai 38 | 39 | 6. Make sure Google action option is enabled. 40 | 41 | 7. If it still does not work then go to church and pray to God -:) 42 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IOT ESP8266 Google Home", 3 | "description": "Works with IOT devices over the firewall with google home", 4 | "repository": "https://github.com/nassir-malik/IOT-ESP8266-Google-Home", 5 | "logo": "https://node-js-sample.herokuapp.com/node.png", 6 | "keywords": ["esp8266", "google home", "wihtout ifttt", "iot", "arduino"] 7 | } 8 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import websockets 2 | import asyncio 3 | import json 4 | import time, os 5 | 6 | 7 | class HttpWSSProtocol(websockets.WebSocketServerProtocol): 8 | rwebsocket = None 9 | rddata = None 10 | async def handler(self): 11 | try: 12 | request_line, headers = await websockets.http.read_message(self.reader) 13 | method, path, version = request_line[:-2].decode().split(None, 2) 14 | #websockets.accept() 15 | except Exception as e: 16 | print(e.args) 17 | self.writer.close() 18 | self.ws_server.unregister(self) 19 | 20 | raise 21 | 22 | # TODO: Check headers etc. to see if we are to upgrade to WS. 23 | if path == '/ws': 24 | # HACK: Put the read data back, to continue with normal WS handling. 25 | self.reader.feed_data(bytes(request_line)) 26 | self.reader.feed_data(headers.as_bytes().replace(b'\n', b'\r\n')) 27 | 28 | return await super(HttpWSSProtocol, self).handler() 29 | else: 30 | try: 31 | return await self.http_handler(method, path, version) 32 | except Exception as e: 33 | print(e) 34 | finally: 35 | 36 | self.writer.close() 37 | self.ws_server.unregister(self) 38 | 39 | 40 | async def http_handler(self, method, path, version): 41 | response = '' 42 | try: 43 | 44 | googleRequest = self.reader._buffer.decode('utf-8') 45 | googleRequestJson = json.loads(googleRequest) 46 | 47 | #{"location": "living", "state": "on", "device": "lights"} 48 | if 'what' in googleRequestJson['result']['resolvedQuery']: 49 | ESPparameters = googleRequestJson['result']['parameters'] 50 | ESPparameters['query'] = '?' 51 | else: 52 | ESPparameters = googleRequestJson['result']['parameters'] 53 | ESPparameters['query'] = 'cmd' 54 | # send command to ESP over websocket 55 | if self.rwebsocket== None: 56 | print("Device is not connected!") 57 | return 58 | await self.rwebsocket.send(json.dumps(ESPparameters)) 59 | 60 | #wait for response and send it back to API.ai as is 61 | self.rddata = await self.rwebsocket.recv() 62 | #{"speech": "It is working", "displayText": "It is working"} 63 | print(self.rddata) 64 | state = json.loads(self.rddata)['state'] 65 | self.rddata = '{"speech": "It is turned '+state+'", "displayText": "It is turned '+state+'"}' 66 | 67 | response = '\r\n'.join([ 68 | 'HTTP/1.1 200 OK', 69 | 'Content-Type: text/json', 70 | '', 71 | ''+self.rddata+'', 72 | ]) 73 | except Exception as e: 74 | print(e) 75 | self.writer.write(response.encode()) 76 | 77 | def updateData(data): 78 | HttpWSSProtocol.rddata = data 79 | 80 | async def ws_handler(websocket, path): 81 | game_name = 'g1' 82 | try: 83 | HttpWSSProtocol.rwebsocket = websocket 84 | await websocket.send(json.dumps({'event': 'OK'})) 85 | data ='{"empty":"empty"}' 86 | while True: 87 | data = await websocket.recv() 88 | updateData(data) 89 | except Exception as e: 90 | print(e) 91 | finally: 92 | print("") 93 | 94 | 95 | 96 | port = int(os.getenv('PORT', 5687)) 97 | start_server = websockets.serve(ws_handler, '', port, klass=HttpWSSProtocol) 98 | # logger.info('Listening on port %d', port) 99 | 100 | asyncio.get_event_loop().run_until_complete(start_server) 101 | asyncio.get_event_loop().run_forever() 102 | -------------------------------------------------------------------------------- /arduinoWebSockets/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | /tests/webSocketServer/node_modules 30 | -------------------------------------------------------------------------------- /arduinoWebSockets/README.md: -------------------------------------------------------------------------------- 1 | WebSocket Server and Client for Arduino 2 | =========================================== 3 | 4 | a WebSocket Server and Client for Arduino based on RFC6455. 5 | 6 | 7 | ##### Supported features of RFC6455 ##### 8 | - text frame 9 | - binary frame 10 | - connection close 11 | - ping 12 | - pong 13 | - continuation frame 14 | 15 | ##### Limitations ##### 16 | - max input length is limited to the ram size and the ```WEBSOCKETS_MAX_DATA_SIZE``` define 17 | - max output length has no limit (the hardware is the limit) 18 | - Client send big frames with mask 0x00000000 (on AVR all frames) 19 | - continuation frame reassembly need to be handled in the application code 20 | 21 | ##### Limitations for Async ##### 22 | - Functions called from within the context of the websocket event might not honor `yield()` and/or `delay()`. See [this issue](https://github.com/Links2004/arduinoWebSockets/issues/58#issuecomment-192376395) for more info and a potential workaround. 23 | - wss / SSL is not possible. 24 | 25 | ##### Supported Hardware ##### 26 | - ESP8266 [Arduino for ESP8266](https://github.com/Links2004/Arduino) 27 | - ESP31B 28 | - Particle with STM32 ARM Cortex M3 29 | - ATmega328 with Ethernet Shield (ATmega branch) 30 | - ATmega328 with enc28j60 (ATmega branch) 31 | - ATmega2560 with Ethernet Shield (ATmega branch) 32 | - ATmega2560 with enc28j60 (ATmega branch) 33 | 34 | ###### Note: ###### 35 | 36 | version 2.0 and up is not compatible with AVR/ATmega, check ATmega branch. 37 | 38 | Arduino for AVR not supports std namespace of c++. 39 | 40 | ### wss / SSL ### 41 | supported for: 42 | - wss client on the ESP8266 43 | - wss / SSL is not natively supported in WebSocketsServer however it is possible to achieve secure websockets 44 | by running the device behind an SSL proxy. See [Nginx](examples/Nginx/esp8266.ssl.reverse.proxy.conf) for a 45 | sample Nginx server configuration file to enable this. 46 | 47 | ### ESP Async TCP ### 48 | 49 | This libary can run in Async TCP mode on the ESP. 50 | 51 | The mode can be activated in the ```WebSockets.h``` (see WEBSOCKETS_NETWORK_TYPE define). 52 | 53 | [ESPAsyncTCP](https://github.com/me-no-dev/ESPAsyncTCP) libary is required. 54 | 55 | 56 | ### High Level Client API ### 57 | 58 | - `begin` : Initiate connection sequence to the websocket host. 59 | ``` 60 | void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); 61 | void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); 62 | ``` 63 | - `onEvent`: Callback to handle for websocket events 64 | 65 | ``` 66 | void onEvent(WebSocketClientEvent cbEvent); 67 | ``` 68 | 69 | - `WebSocketClientEvent`: Handler for websocket events 70 | ``` 71 | void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length) 72 | ``` 73 | Where `WStype_t type` is defined as: 74 | ``` 75 | typedef enum { 76 | WStype_ERROR, 77 | WStype_DISCONNECTED, 78 | WStype_CONNECTED, 79 | WStype_TEXT, 80 | WStype_BIN, 81 | WStype_FRAGMENT_TEXT_START, 82 | WStype_FRAGMENT_BIN_START, 83 | WStype_FRAGMENT, 84 | WStype_FRAGMENT_FIN, 85 | } WStype_t; 86 | ``` 87 | 88 | ### Issues ### 89 | Submit issues to: https://github.com/Links2004/arduinoWebSockets/issues 90 | 91 | [![Join the chat at https://gitter.im/Links2004/arduinoWebSockets](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Links2004/arduinoWebSockets?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 92 | 93 | ### License and credits ### 94 | 95 | The library is licensed under [LGPLv2.1](https://github.com/Links2004/arduinoWebSockets/blob/master/LICENSE) 96 | 97 | [libb64](http://libb64.sourceforge.net/) written by Chris Venter. It is distributed under Public Domain see [LICENSE](https://github.com/Links2004/arduinoWebSockets/blob/master/src/libb64/LICENSE). 98 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/Nginx/esp8266.ssl.reverse.proxy.conf: -------------------------------------------------------------------------------- 1 | # ESP8266 nginx SSL reverse proxy configuration file (tested and working on nginx v1.10.0) 2 | 3 | # proxy cache location 4 | proxy_cache_path /opt/etc/nginx/cache levels=1:2 keys_zone=ESP8266_cache:10m max_size=10g inactive=5m use_temp_path=off; 5 | 6 | # webserver proxy 7 | server { 8 | 9 | # general server parameters 10 | listen 50080; 11 | server_name myDomain.net; 12 | access_log /opt/var/log/nginx/myDomain.net.access.log; 13 | 14 | # SSL configuration 15 | ssl on; 16 | ssl_certificate /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/fullchain.pem; 17 | ssl_certificate_key /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/privkey.pem; 18 | ssl_session_cache builtin:1000 shared:SSL:10m; 19 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 20 | ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; 21 | ssl_prefer_server_ciphers on; 22 | 23 | location / { 24 | 25 | # proxy caching configuration 26 | proxy_cache ESP8266_cache; 27 | proxy_cache_revalidate on; 28 | proxy_cache_min_uses 1; 29 | proxy_cache_use_stale off; 30 | proxy_cache_lock on; 31 | # proxy_cache_bypass $http_cache_control; 32 | # include the sessionId cookie value as part of the cache key - keeps the cache per user 33 | # proxy_cache_key $proxy_host$request_uri$cookie_sessionId; 34 | 35 | # header pass through configuration 36 | proxy_set_header Host $host; 37 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 38 | proxy_set_header X-Forwarded-Proto $scheme; 39 | 40 | # ESP8266 custom headers which identify to the device that it's running through an SSL proxy 41 | proxy_set_header X-SSL On; 42 | proxy_set_header X-SSL-WebserverPort 50080; 43 | proxy_set_header X-SSL-WebsocketPort 50081; 44 | 45 | # extra debug headers 46 | add_header X-Proxy-Cache $upstream_cache_status; 47 | add_header X-Forwarded-For $proxy_add_x_forwarded_for; 48 | 49 | # actual proxying configuration 50 | proxy_ssl_session_reuse on; 51 | # target the IP address of the device with proxy_pass 52 | proxy_pass http://192.168.0.20; 53 | proxy_read_timeout 90; 54 | } 55 | } 56 | 57 | # websocket proxy 58 | server { 59 | 60 | # general server parameters 61 | listen 50081; 62 | server_name myDomain.net; 63 | access_log /opt/var/log/nginx/myDomain.net.wss.access.log; 64 | 65 | # SSL configuration 66 | ssl on; 67 | ssl_certificate /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/fullchain.pem; 68 | ssl_certificate_key /usr/builtin/etc/certificate/lets-encrypt/myDomain.net/privkey.pem; 69 | ssl_session_cache builtin:1000 shared:SSL:10m; 70 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 71 | ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4; 72 | ssl_prefer_server_ciphers on; 73 | 74 | location / { 75 | 76 | # websocket upgrade tunnel configuration 77 | proxy_pass http://192.168.0.20:81; 78 | proxy_http_version 1.1; 79 | proxy_set_header Upgrade $http_upgrade; 80 | proxy_set_header Connection "Upgrade"; 81 | proxy_read_timeout 86400; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/ParticleWebSocketClient/application.cpp: -------------------------------------------------------------------------------- 1 | /* To compile using make CLI, create a folder under \firmware\user\applications and copy application.cpp there. 2 | * Then, copy src files under particleWebSocket folder. 3 | */ 4 | 5 | #include "application.h" 6 | #include "particleWebSocket/WebSocketsClient.h" 7 | 8 | WebSocketsClient webSocket; 9 | 10 | void webSocketEvent(WStype_t type, uint8_t* payload, size_t length) 11 | { 12 | switch (type) 13 | { 14 | case WStype_DISCONNECTED: 15 | Serial.printlnf("[WSc] Disconnected!"); 16 | break; 17 | case WStype_CONNECTED: 18 | Serial.printlnf("[WSc] Connected to URL: %s", payload); 19 | webSocket.sendTXT("Connected\r\n"); 20 | break; 21 | case WStype_TEXT: 22 | Serial.printlnf("[WSc] get text: %s", payload); 23 | break; 24 | case WStype_BIN: 25 | Serial.printlnf("[WSc] get binary length: %u", length); 26 | break; 27 | } 28 | } 29 | 30 | void setup() 31 | { 32 | Serial.begin(9600); 33 | 34 | WiFi.setCredentials("[SSID]", "[PASSWORD]", WPA2, WLAN_CIPHER_AES_TKIP); 35 | WiFi.connect(); 36 | 37 | webSocket.begin("192.168.1.153", 85, "/ClientService/?variable=Test1212"); 38 | webSocket.onEvent(webSocketEvent); 39 | } 40 | 41 | void loop() 42 | { 43 | webSocket.sendTXT("Hello world!"); 44 | delay(500); 45 | webSocket.loop(); 46 | } 47 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketClient/WebSocketClient.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClient.ino 3 | * 4 | * Created on: 24.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | ESP8266WiFiMulti WiFiMulti; 18 | WebSocketsClient webSocket; 19 | 20 | 21 | #define USE_SERIAL Serial1 22 | 23 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 24 | 25 | 26 | switch(type) { 27 | case WStype_DISCONNECTED: 28 | USE_SERIAL.printf("[WSc] Disconnected!\n"); 29 | break; 30 | case WStype_CONNECTED: 31 | { 32 | USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); 33 | 34 | // send message to server when Connected 35 | webSocket.sendTXT("Connected"); 36 | } 37 | break; 38 | case WStype_TEXT: 39 | USE_SERIAL.printf("[WSc] get text: %s\n", payload); 40 | 41 | // send message to server 42 | // webSocket.sendTXT("message here"); 43 | break; 44 | case WStype_BIN: 45 | USE_SERIAL.printf("[WSc] get binary length: %u\n", length); 46 | hexdump(payload, length); 47 | 48 | // send data to server 49 | // webSocket.sendBIN(payload, length); 50 | break; 51 | } 52 | 53 | } 54 | 55 | void setup() { 56 | // USE_SERIAL.begin(921600); 57 | USE_SERIAL.begin(115200); 58 | 59 | //Serial.setDebugOutput(true); 60 | USE_SERIAL.setDebugOutput(true); 61 | 62 | USE_SERIAL.println(); 63 | USE_SERIAL.println(); 64 | USE_SERIAL.println(); 65 | 66 | for(uint8_t t = 4; t > 0; t--) { 67 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 68 | USE_SERIAL.flush(); 69 | delay(1000); 70 | } 71 | 72 | WiFiMulti.addAP("SSID", "passpasspass"); 73 | 74 | //WiFi.disconnect(); 75 | while(WiFiMulti.run() != WL_CONNECTED) { 76 | delay(100); 77 | } 78 | 79 | webSocket.begin("192.168.0.123", 81); 80 | //webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization 81 | webSocket.onEvent(webSocketEvent); 82 | 83 | } 84 | 85 | void loop() { 86 | webSocket.loop(); 87 | } 88 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketClientAVR/WebSocketClientAVR.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientAVR.ino 3 | * 4 | * Created on: 10.12.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | 16 | 17 | // Enter a MAC address for your controller below. 18 | // Newer Ethernet shields have a MAC address printed on a sticker on the shield 19 | byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 20 | 21 | // Set the static IP address to use if the DHCP fails to assign 22 | IPAddress ip(192, 168, 0, 177); 23 | 24 | WebSocketsClient webSocket; 25 | 26 | 27 | 28 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 29 | 30 | 31 | switch(type) { 32 | case WStype_DISCONNECTED: 33 | Serial.println("[WSc] Disconnected!\n"); 34 | break; 35 | case WStype_CONNECTED: 36 | { 37 | Serial.print("[WSc] Connected to url: "); 38 | Serial.println((char *)payload); 39 | // send message to server when Connected 40 | webSocket.sendTXT("Connected"); 41 | } 42 | break; 43 | case WStype_TEXT: 44 | Serial.print("[WSc] get text: "); 45 | Serial.println((char *)payload); 46 | // send message to server 47 | // webSocket.sendTXT("message here"); 48 | break; 49 | case WStype_BIN: 50 | Serial.print("[WSc] get binary length: "); 51 | Serial.println(length); 52 | // hexdump(payload, length); 53 | 54 | // send data to server 55 | // webSocket.sendBIN(payload, length); 56 | break; 57 | } 58 | 59 | } 60 | 61 | void setup() 62 | { 63 | // Open serial communications and wait for port to open: 64 | Serial.begin(115200); 65 | while (!Serial) {} 66 | 67 | // start the Ethernet connection: 68 | if (Ethernet.begin(mac) == 0) { 69 | Serial.println("Failed to configure Ethernet using DHCP"); 70 | // no point in carrying on, so do nothing forevermore: 71 | // try to congifure using IP address instead of DHCP: 72 | Ethernet.begin(mac, ip); 73 | } 74 | 75 | webSocket.begin("192.168.0.123", 8011); 76 | webSocket.onEvent(webSocketEvent); 77 | 78 | } 79 | 80 | 81 | void loop() 82 | { 83 | webSocket.loop(); 84 | } 85 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketClientSSL/WebSocketClientSSL.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientSSL.ino 3 | * 4 | * Created on: 10.12.2015 5 | * 6 | * note SSL is only possible with the ESP8266 7 | * 8 | */ 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | ESP8266WiFiMulti WiFiMulti; 20 | WebSocketsClient webSocket; 21 | 22 | 23 | #define USE_SERIAL Serial1 24 | 25 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 26 | 27 | 28 | switch(type) { 29 | case WStype_DISCONNECTED: 30 | USE_SERIAL.printf("[WSc] Disconnected!\n"); 31 | break; 32 | case WStype_CONNECTED: 33 | { 34 | USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); 35 | 36 | // send message to server when Connected 37 | webSocket.sendTXT("Connected"); 38 | } 39 | break; 40 | case WStype_TEXT: 41 | USE_SERIAL.printf("[WSc] get text: %s\n", payload); 42 | 43 | // send message to server 44 | // webSocket.sendTXT("message here"); 45 | break; 46 | case WStype_BIN: 47 | USE_SERIAL.printf("[WSc] get binary length: %u\n", length); 48 | hexdump(payload, length); 49 | 50 | // send data to server 51 | // webSocket.sendBIN(payload, length); 52 | break; 53 | } 54 | 55 | } 56 | 57 | void setup() { 58 | // USE_SERIAL.begin(921600); 59 | USE_SERIAL.begin(115200); 60 | 61 | //Serial.setDebugOutput(true); 62 | USE_SERIAL.setDebugOutput(true); 63 | 64 | USE_SERIAL.println(); 65 | USE_SERIAL.println(); 66 | USE_SERIAL.println(); 67 | 68 | for(uint8_t t = 4; t > 0; t--) { 69 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 70 | USE_SERIAL.flush(); 71 | delay(1000); 72 | } 73 | 74 | WiFiMulti.addAP("SSID", "passpasspass"); 75 | 76 | //WiFi.disconnect(); 77 | while(WiFiMulti.run() != WL_CONNECTED) { 78 | delay(100); 79 | } 80 | 81 | webSocket.beginSSL("192.168.0.123", 81); 82 | webSocket.onEvent(webSocketEvent); 83 | 84 | } 85 | 86 | void loop() { 87 | webSocket.loop(); 88 | } 89 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketClientSocketIO/WebSocketClientSocketIO.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketClientSocketIO.ino 3 | * 4 | * Created on: 06.06.2016 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | ESP8266WiFiMulti WiFiMulti; 18 | WebSocketsClient webSocket; 19 | 20 | 21 | #define USE_SERIAL Serial1 22 | 23 | #define MESSAGE_INTERVAL 30000 24 | #define HEARTBEAT_INTERVAL 25000 25 | 26 | uint64_t messageTimestamp = 0; 27 | uint64_t heartbeatTimestamp = 0; 28 | bool isConnected = false; 29 | 30 | void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { 31 | 32 | 33 | switch(type) { 34 | case WStype_DISCONNECTED: 35 | USE_SERIAL.printf("[WSc] Disconnected!\n"); 36 | isConnected = false; 37 | break; 38 | case WStype_CONNECTED: 39 | { 40 | USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); 41 | isConnected = true; 42 | 43 | // send message to server when Connected 44 | // socket.io upgrade confirmation message (required) 45 | webSocket.sendTXT("5"); 46 | } 47 | break; 48 | case WStype_TEXT: 49 | USE_SERIAL.printf("[WSc] get text: %s\n", payload); 50 | 51 | // send message to server 52 | // webSocket.sendTXT("message here"); 53 | break; 54 | case WStype_BIN: 55 | USE_SERIAL.printf("[WSc] get binary length: %u\n", length); 56 | hexdump(payload, length); 57 | 58 | // send data to server 59 | // webSocket.sendBIN(payload, length); 60 | break; 61 | } 62 | 63 | } 64 | 65 | void setup() { 66 | // USE_SERIAL.begin(921600); 67 | USE_SERIAL.begin(115200); 68 | 69 | //Serial.setDebugOutput(true); 70 | USE_SERIAL.setDebugOutput(true); 71 | 72 | USE_SERIAL.println(); 73 | USE_SERIAL.println(); 74 | USE_SERIAL.println(); 75 | 76 | for(uint8_t t = 4; t > 0; t--) { 77 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 78 | USE_SERIAL.flush(); 79 | delay(1000); 80 | } 81 | 82 | WiFiMulti.addAP("SSID", "passpasspass"); 83 | 84 | //WiFi.disconnect(); 85 | while(WiFiMulti.run() != WL_CONNECTED) { 86 | delay(100); 87 | } 88 | 89 | webSocket.beginSocketIO("192.168.0.123", 81); 90 | //webSocket.setAuthorization("user", "Password"); // HTTP Basic Authorization 91 | webSocket.onEvent(webSocketEvent); 92 | 93 | } 94 | 95 | void loop() { 96 | webSocket.loop(); 97 | 98 | if(isConnected) { 99 | 100 | uint64_t now = millis(); 101 | 102 | if(now - messageTimestamp > MESSAGE_INTERVAL) { 103 | messageTimestamp = now; 104 | // example socket.io message with type "messageType" and JSON payload 105 | webSocket.sendTXT("42[\"messageType\",{\"greeting\":\"hello\"}]"); 106 | } 107 | if((now - heartbeatTimestamp) > HEARTBEAT_INTERVAL) { 108 | heartbeatTimestamp = now; 109 | // socket.io heartbeat message 110 | webSocket.sendTXT("2"); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketServer/WebSocketServer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServer.ino 3 | * 4 | * Created on: 22.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | ESP8266WiFiMulti WiFiMulti; 16 | 17 | WebSocketsServer webSocket = WebSocketsServer(81); 18 | 19 | #define USE_SERIAL Serial1 20 | 21 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 22 | 23 | switch(type) { 24 | case WStype_DISCONNECTED: 25 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 26 | break; 27 | case WStype_CONNECTED: 28 | { 29 | IPAddress ip = webSocket.remoteIP(num); 30 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 31 | 32 | // send message to client 33 | webSocket.sendTXT(num, "Connected"); 34 | } 35 | break; 36 | case WStype_TEXT: 37 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 38 | 39 | // send message to client 40 | // webSocket.sendTXT(num, "message here"); 41 | 42 | // send data to all connected clients 43 | // webSocket.broadcastTXT("message here"); 44 | break; 45 | case WStype_BIN: 46 | USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); 47 | hexdump(payload, length); 48 | 49 | // send message to client 50 | // webSocket.sendBIN(num, payload, length); 51 | break; 52 | } 53 | 54 | } 55 | 56 | void setup() { 57 | // USE_SERIAL.begin(921600); 58 | USE_SERIAL.begin(115200); 59 | 60 | //Serial.setDebugOutput(true); 61 | USE_SERIAL.setDebugOutput(true); 62 | 63 | USE_SERIAL.println(); 64 | USE_SERIAL.println(); 65 | USE_SERIAL.println(); 66 | 67 | for(uint8_t t = 4; t > 0; t--) { 68 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 69 | USE_SERIAL.flush(); 70 | delay(1000); 71 | } 72 | 73 | WiFiMulti.addAP("SSID", "passpasspass"); 74 | 75 | while(WiFiMulti.run() != WL_CONNECTED) { 76 | delay(100); 77 | } 78 | 79 | webSocket.begin(); 80 | webSocket.onEvent(webSocketEvent); 81 | } 82 | 83 | void loop() { 84 | webSocket.loop(); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketServer/WebSocketServerFragmentation.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServer.ino 3 | * 4 | * Created on: 22.05.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | ESP8266WiFiMulti WiFiMulti; 16 | 17 | WebSocketsServer webSocket = WebSocketsServer(81); 18 | 19 | #define USE_SERIAL Serial 20 | 21 | String fragmentBuffer = ""; 22 | 23 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 24 | 25 | switch(type) { 26 | case WStype_DISCONNECTED: 27 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 28 | break; 29 | case WStype_CONNECTED: { 30 | IPAddress ip = webSocket.remoteIP(num); 31 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 32 | 33 | // send message to client 34 | webSocket.sendTXT(num, "Connected"); 35 | } 36 | break; 37 | case WStype_TEXT: 38 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 39 | break; 40 | case WStype_BIN: 41 | USE_SERIAL.printf("[%u] get binary length: %u\n", num, length); 42 | hexdump(payload, length); 43 | break; 44 | 45 | // Fragmentation / continuation opcode handling 46 | // case WStype_FRAGMENT_BIN_START: 47 | case WStype_FRAGMENT_TEXT_START: 48 | fragmentBuffer = (char*)payload; 49 | USE_SERIAL.printf("[%u] get start start of Textfragment: %s\n", num, payload); 50 | break; 51 | case WStype_FRAGMENT: 52 | fragmentBuffer += (char*)payload; 53 | USE_SERIAL.printf("[%u] get Textfragment : %s\n", num, payload); 54 | break; 55 | case WStype_FRAGMENT_FIN: 56 | fragmentBuffer += (char*)payload; 57 | USE_SERIAL.printf("[%u] get end of Textfragment: %s\n", num, payload); 58 | USE_SERIAL.printf("[%u] full frame: %s\n", num, fragmentBuffer.c_str()); 59 | break; 60 | } 61 | 62 | } 63 | 64 | void setup() { 65 | // USE_SERIAL.begin(921600); 66 | USE_SERIAL.begin(115200); 67 | 68 | //Serial.setDebugOutput(true); 69 | USE_SERIAL.setDebugOutput(true); 70 | 71 | USE_SERIAL.println(); 72 | USE_SERIAL.println(); 73 | USE_SERIAL.println(); 74 | 75 | for(uint8_t t = 4; t > 0; t--) { 76 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 77 | USE_SERIAL.flush(); 78 | delay(1000); 79 | } 80 | 81 | WiFiMulti.addAP("SSID", "passpasspass"); 82 | 83 | while(WiFiMulti.run() != WL_CONNECTED) { 84 | delay(100); 85 | } 86 | 87 | webSocket.begin(); 88 | webSocket.onEvent(webSocketEvent); 89 | } 90 | 91 | void loop() { 92 | webSocket.loop(); 93 | } 94 | 95 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketServer/WebSocketServerHttpHeaderValidation.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServerHttpHeaderValidation.ino 3 | * 4 | * Created on: 08.06.2016 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | ESP8266WiFiMulti WiFiMulti; 16 | 17 | WebSocketsServer webSocket = WebSocketsServer(81); 18 | 19 | #define USE_SERIAL Serial1 20 | 21 | const unsigned long int validSessionId = 12345; //some arbitrary value to act as a valid sessionId 22 | 23 | /* 24 | * Returns a bool value as an indicator to describe whether a user is allowed to initiate a websocket upgrade 25 | * based on the value of a cookie. This function expects the rawCookieHeaderValue to look like this "sessionId=|" 26 | */ 27 | bool isCookieValid(String rawCookieHeaderValue) { 28 | 29 | if (rawCookieHeaderValue.indexOf("sessionId") != -1) { 30 | String sessionIdStr = rawCookieHeaderValue.substring(rawCookieHeaderValue.indexOf("sessionId=") + 10, rawCookieHeaderValue.indexOf("|")); 31 | unsigned long int sessionId = strtoul(sessionIdStr.c_str(), NULL, 10); 32 | return sessionId == validSessionId; 33 | } 34 | return false; 35 | } 36 | 37 | /* 38 | * The WebSocketServerHttpHeaderValFunc delegate passed to webSocket.onValidateHttpHeader 39 | */ 40 | bool validateHttpHeader(String headerName, String headerValue) { 41 | 42 | //assume a true response for any headers not handled by this validator 43 | bool valid = true; 44 | 45 | if(headerName.equalsIgnoreCase("Cookie")) { 46 | //if the header passed is the Cookie header, validate it according to the rules in 'isCookieValid' function 47 | valid = isCookieValid(headerValue); 48 | } 49 | 50 | return valid; 51 | } 52 | 53 | void setup() { 54 | // USE_SERIAL.begin(921600); 55 | USE_SERIAL.begin(115200); 56 | 57 | //Serial.setDebugOutput(true); 58 | USE_SERIAL.setDebugOutput(true); 59 | 60 | USE_SERIAL.println(); 61 | USE_SERIAL.println(); 62 | USE_SERIAL.println(); 63 | 64 | for(uint8_t t = 4; t > 0; t--) { 65 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 66 | USE_SERIAL.flush(); 67 | delay(1000); 68 | } 69 | 70 | WiFiMulti.addAP("SSID", "passpasspass"); 71 | 72 | while(WiFiMulti.run() != WL_CONNECTED) { 73 | delay(100); 74 | } 75 | 76 | //connecting clients must supply a valid session cookie at websocket upgrade handshake negotiation time 77 | const char * headerkeys[] = { "Cookie" }; 78 | size_t headerKeyCount = sizeof(headerkeys) / sizeof(char*); 79 | webSocket.onValidateHttpHeader(validateHttpHeader, headerkeys, headerKeyCount); 80 | webSocket.begin(); 81 | } 82 | 83 | void loop() { 84 | webSocket.loop(); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /arduinoWebSockets/examples/WebSocketServer_LEDcontrol/WebSocketServer_LEDcontrol.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * WebSocketServer_LEDcontrol.ino 3 | * 4 | * Created on: 26.11.2015 5 | * 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define LED_RED 15 18 | #define LED_GREEN 12 19 | #define LED_BLUE 13 20 | 21 | #define USE_SERIAL Serial 22 | 23 | 24 | ESP8266WiFiMulti WiFiMulti; 25 | 26 | ESP8266WebServer server = ESP8266WebServer(80); 27 | WebSocketsServer webSocket = WebSocketsServer(81); 28 | 29 | void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { 30 | 31 | switch(type) { 32 | case WStype_DISCONNECTED: 33 | USE_SERIAL.printf("[%u] Disconnected!\n", num); 34 | break; 35 | case WStype_CONNECTED: { 36 | IPAddress ip = webSocket.remoteIP(num); 37 | USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); 38 | 39 | // send message to client 40 | webSocket.sendTXT(num, "Connected"); 41 | } 42 | break; 43 | case WStype_TEXT: 44 | USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); 45 | 46 | if(payload[0] == '#') { 47 | // we get RGB data 48 | 49 | // decode rgb data 50 | uint32_t rgb = (uint32_t) strtol((const char *) &payload[1], NULL, 16); 51 | 52 | analogWrite(LED_RED, ((rgb >> 16) & 0xFF)); 53 | analogWrite(LED_GREEN, ((rgb >> 8) & 0xFF)); 54 | analogWrite(LED_BLUE, ((rgb >> 0) & 0xFF)); 55 | } 56 | 57 | break; 58 | } 59 | 60 | } 61 | 62 | void setup() { 63 | //USE_SERIAL.begin(921600); 64 | USE_SERIAL.begin(115200); 65 | 66 | //USE_SERIAL.setDebugOutput(true); 67 | 68 | USE_SERIAL.println(); 69 | USE_SERIAL.println(); 70 | USE_SERIAL.println(); 71 | 72 | for(uint8_t t = 4; t > 0; t--) { 73 | USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); 74 | USE_SERIAL.flush(); 75 | delay(1000); 76 | } 77 | 78 | pinMode(LED_RED, OUTPUT); 79 | pinMode(LED_GREEN, OUTPUT); 80 | pinMode(LED_BLUE, OUTPUT); 81 | 82 | digitalWrite(LED_RED, 1); 83 | digitalWrite(LED_GREEN, 1); 84 | digitalWrite(LED_BLUE, 1); 85 | 86 | WiFiMulti.addAP("SSID", "passpasspass"); 87 | 88 | while(WiFiMulti.run() != WL_CONNECTED) { 89 | delay(100); 90 | } 91 | 92 | // start webSocket server 93 | webSocket.begin(); 94 | webSocket.onEvent(webSocketEvent); 95 | 96 | if(MDNS.begin("esp8266")) { 97 | USE_SERIAL.println("MDNS responder started"); 98 | } 99 | 100 | // handle index 101 | server.on("/", []() { 102 | // send index.html 103 | server.send(200, "text/html", "LED Control:

R:
G:
B:
"); 104 | }); 105 | 106 | server.begin(); 107 | 108 | // Add service to MDNS 109 | MDNS.addService("http", "tcp", 80); 110 | MDNS.addService("ws", "tcp", 81); 111 | 112 | digitalWrite(LED_RED, 0); 113 | digitalWrite(LED_GREEN, 0); 114 | digitalWrite(LED_BLUE, 0); 115 | 116 | } 117 | 118 | void loop() { 119 | webSocket.loop(); 120 | server.handleClient(); 121 | } 122 | 123 | -------------------------------------------------------------------------------- /arduinoWebSockets/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WebSockets", 3 | "description": "WebSocket Server and Client for Arduino based on RFC6455", 4 | "keywords": "wifi, http, web, server, client, websocket", 5 | "authors": [ 6 | { 7 | "name": "Markus Sattler", 8 | "url": "https://github.com/Links2004", 9 | "maintainer": true 10 | } 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/Links2004/arduinoWebSockets.git" 15 | }, 16 | "version": "2.0.7", 17 | "license": "LGPL-2.1", 18 | "export": { 19 | "exclude": [ 20 | "tests" 21 | ] 22 | }, 23 | "frameworks": "arduino", 24 | "platforms": "*", 25 | "examples": [ 26 | "examples/*/*.ino" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /arduinoWebSockets/library.properties: -------------------------------------------------------------------------------- 1 | name=WebSockets 2 | version=2.0.7 3 | author=Markus Sattler 4 | maintainer=Markus Sattler 5 | sentence=WebSockets for Arduino (Server + Client) 6 | paragraph=use 2.x.x for ESP and 1.3 for AVR 7 | category=Communication 8 | url=https://github.com/Links2004/arduinoWebSockets 9 | architectures=* 10 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/WebSocketsClient.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file WebSocketsClient.h 3 | * @date 20.05.2015 4 | * @author Markus Sattler 5 | * 6 | * Copyright (c) 2015 Markus Sattler. All rights reserved. 7 | * This file is part of the WebSockets for Arduino. 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | * 23 | */ 24 | 25 | #ifndef WEBSOCKETSCLIENT_H_ 26 | #define WEBSOCKETSCLIENT_H_ 27 | 28 | #include "WebSockets.h" 29 | 30 | class WebSocketsClient: private WebSockets { 31 | public: 32 | #ifdef __AVR__ 33 | typedef void (*WebSocketClientEvent)(WStype_t type, uint8_t * payload, size_t length); 34 | #else 35 | typedef std::function WebSocketClientEvent; 36 | #endif 37 | 38 | 39 | WebSocketsClient(void); 40 | ~WebSocketsClient(void); 41 | 42 | void begin(const char *host, uint16_t port, const char * url = "/", const char * protocol = "arduino"); 43 | void begin(String host, uint16_t port, String url = "/", String protocol = "arduino"); 44 | 45 | #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) 46 | void beginSSL(const char *host, uint16_t port, const char * url = "/", const char * = "", const char * protocol = "arduino"); 47 | void beginSSL(String host, uint16_t port, String url = "/", String fingerprint = "", String protocol = "arduino"); 48 | #endif 49 | 50 | void beginSocketIO(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); 51 | void beginSocketIO(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); 52 | 53 | #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) 54 | void beginSocketIOSSL(const char *host, uint16_t port, const char * url = "/socket.io/?EIO=3", const char * protocol = "arduino"); 55 | void beginSocketIOSSL(String host, uint16_t port, String url = "/socket.io/?EIO=3", String protocol = "arduino"); 56 | #endif 57 | 58 | #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) 59 | void loop(void); 60 | #else 61 | // Async interface not need a loop call 62 | void loop(void) __attribute__ ((deprecated)) {} 63 | #endif 64 | 65 | void onEvent(WebSocketClientEvent cbEvent); 66 | 67 | bool sendTXT(uint8_t * payload, size_t length = 0, bool headerToPayload = false); 68 | bool sendTXT(const uint8_t * payload, size_t length = 0); 69 | bool sendTXT(char * payload, size_t length = 0, bool headerToPayload = false); 70 | bool sendTXT(const char * payload, size_t length = 0); 71 | bool sendTXT(String & payload); 72 | 73 | bool sendBIN(uint8_t * payload, size_t length, bool headerToPayload = false); 74 | bool sendBIN(const uint8_t * payload, size_t length); 75 | 76 | bool sendPing(uint8_t * payload = NULL, size_t length = 0); 77 | bool sendPing(String & payload); 78 | 79 | void disconnect(void); 80 | 81 | void setAuthorization(const char * user, const char * password); 82 | void setAuthorization(const char * auth); 83 | 84 | protected: 85 | String _host; 86 | uint16_t _port; 87 | 88 | #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266) 89 | String _fingerprint; 90 | #endif 91 | WSclient_t _client; 92 | 93 | WebSocketClientEvent _cbEvent; 94 | 95 | void messageReceived(WSclient_t * client, WSopcode_t opcode, uint8_t * payload, size_t length, bool fin); 96 | 97 | void clientDisconnect(WSclient_t * client); 98 | bool clientIsConnected(WSclient_t * client); 99 | 100 | #if (WEBSOCKETS_NETWORK_TYPE != NETWORK_ESP8266_ASYNC) 101 | void handleClientData(void); 102 | #endif 103 | 104 | void sendHeader(WSclient_t * client); 105 | void handleHeader(WSclient_t * client, String * headerLine); 106 | 107 | void connectedCb(); 108 | void connectFailedCb(); 109 | 110 | #if (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC) 111 | void asyncConnect(); 112 | #endif 113 | 114 | /** 115 | * called for sending a Event to the app 116 | * @param type WStype_t 117 | * @param payload uint8_t * 118 | * @param length size_t 119 | */ 120 | virtual void runCbEvent(WStype_t type, uint8_t * payload, size_t length) { 121 | if(_cbEvent) { 122 | _cbEvent(type, payload, length); 123 | } 124 | } 125 | 126 | }; 127 | 128 | #endif /* WEBSOCKETSCLIENT_H_ */ 129 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/libb64/AUTHORS: -------------------------------------------------------------------------------- 1 | libb64: Base64 Encoding/Decoding Routines 2 | ====================================== 3 | 4 | Authors: 5 | ------- 6 | 7 | Chris Venter chris.venter@gmail.com http://rocketpod.blogspot.com 8 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/libb64/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright-Only Dedication (based on United States law) 2 | or Public Domain Certification 3 | 4 | The person or persons who have associated work with this document (the 5 | "Dedicator" or "Certifier") hereby either (a) certifies that, to the best of 6 | his knowledge, the work of authorship identified is in the public domain of the 7 | country from which the work is published, or (b) hereby dedicates whatever 8 | copyright the dedicators holds in the work of authorship identified below (the 9 | "Work") to the public domain. A certifier, moreover, dedicates any copyright 10 | interest he may have in the associated work, and for these purposes, is 11 | described as a "dedicator" below. 12 | 13 | A certifier has taken reasonable steps to verify the copyright status of this 14 | work. Certifier recognizes that his good faith efforts may not shield him from 15 | liability if in fact the work certified is not in the public domain. 16 | 17 | Dedicator makes this dedication for the benefit of the public at large and to 18 | the detriment of the Dedicator's heirs and successors. Dedicator intends this 19 | dedication to be an overt act of relinquishment in perpetuity of all present 20 | and future rights under copyright law, whether vested or contingent, in the 21 | Work. Dedicator understands that such relinquishment of all rights includes 22 | the relinquishment of all rights to enforce (by lawsuit or otherwise) those 23 | copyrights in the Work. 24 | 25 | Dedicator recognizes that, once placed in the public domain, the Work may be 26 | freely reproduced, distributed, transmitted, used, modified, built upon, or 27 | otherwise exploited by anyone for any purpose, commercial or non-commercial, 28 | and in any way, including by methods that have not yet been invented or 29 | conceived. -------------------------------------------------------------------------------- /arduinoWebSockets/src/libb64/cdecode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cdecoder.c - c source to a base64 decoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifdef ESP8266 9 | #include 10 | #endif 11 | 12 | #ifndef CORE_HAS_LIBB64 13 | #include "cdecode_inc.h" 14 | 15 | int base64_decode_value(char value_in) 16 | { 17 | static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51}; 18 | static const char decoding_size = sizeof(decoding); 19 | value_in -= 43; 20 | if (value_in < 0 || value_in > decoding_size) return -1; 21 | return decoding[(int)value_in]; 22 | } 23 | 24 | void base64_init_decodestate(base64_decodestate* state_in) 25 | { 26 | state_in->step = step_a; 27 | state_in->plainchar = 0; 28 | } 29 | 30 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in) 31 | { 32 | const char* codechar = code_in; 33 | char* plainchar = plaintext_out; 34 | char fragment; 35 | 36 | *plainchar = state_in->plainchar; 37 | 38 | switch (state_in->step) 39 | { 40 | while (1) 41 | { 42 | case step_a: 43 | do { 44 | if (codechar == code_in+length_in) 45 | { 46 | state_in->step = step_a; 47 | state_in->plainchar = *plainchar; 48 | return plainchar - plaintext_out; 49 | } 50 | fragment = (char)base64_decode_value(*codechar++); 51 | } while (fragment < 0); 52 | *plainchar = (fragment & 0x03f) << 2; 53 | case step_b: 54 | do { 55 | if (codechar == code_in+length_in) 56 | { 57 | state_in->step = step_b; 58 | state_in->plainchar = *plainchar; 59 | return plainchar - plaintext_out; 60 | } 61 | fragment = (char)base64_decode_value(*codechar++); 62 | } while (fragment < 0); 63 | *plainchar++ |= (fragment & 0x030) >> 4; 64 | *plainchar = (fragment & 0x00f) << 4; 65 | case step_c: 66 | do { 67 | if (codechar == code_in+length_in) 68 | { 69 | state_in->step = step_c; 70 | state_in->plainchar = *plainchar; 71 | return plainchar - plaintext_out; 72 | } 73 | fragment = (char)base64_decode_value(*codechar++); 74 | } while (fragment < 0); 75 | *plainchar++ |= (fragment & 0x03c) >> 2; 76 | *plainchar = (fragment & 0x003) << 6; 77 | case step_d: 78 | do { 79 | if (codechar == code_in+length_in) 80 | { 81 | state_in->step = step_d; 82 | state_in->plainchar = *plainchar; 83 | return plainchar - plaintext_out; 84 | } 85 | fragment = (char)base64_decode_value(*codechar++); 86 | } while (fragment < 0); 87 | *plainchar++ |= (fragment & 0x03f); 88 | } 89 | } 90 | /* control should not reach here */ 91 | return plainchar - plaintext_out; 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/libb64/cdecode_inc.h: -------------------------------------------------------------------------------- 1 | /* 2 | cdecode.h - c header for a base64 decoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CDECODE_H 9 | #define BASE64_CDECODE_H 10 | 11 | typedef enum 12 | { 13 | step_a, step_b, step_c, step_d 14 | } base64_decodestep; 15 | 16 | typedef struct 17 | { 18 | base64_decodestep step; 19 | char plainchar; 20 | } base64_decodestate; 21 | 22 | void base64_init_decodestate(base64_decodestate* state_in); 23 | 24 | int base64_decode_value(char value_in); 25 | 26 | int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in); 27 | 28 | #endif /* BASE64_CDECODE_H */ 29 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/libb64/cencode.c: -------------------------------------------------------------------------------- 1 | /* 2 | cencoder.c - c source to a base64 encoding algorithm implementation 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifdef ESP8266 9 | #include 10 | #endif 11 | 12 | #ifndef CORE_HAS_LIBB64 13 | #include "cencode_inc.h" 14 | 15 | const int CHARS_PER_LINE = 72; 16 | 17 | void base64_init_encodestate(base64_encodestate* state_in) 18 | { 19 | state_in->step = step_A; 20 | state_in->result = 0; 21 | state_in->stepcount = 0; 22 | } 23 | 24 | char base64_encode_value(char value_in) 25 | { 26 | static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 27 | if (value_in > 63) return '='; 28 | return encoding[(int)value_in]; 29 | } 30 | 31 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) 32 | { 33 | const char* plainchar = plaintext_in; 34 | const char* const plaintextend = plaintext_in + length_in; 35 | char* codechar = code_out; 36 | char result; 37 | char fragment; 38 | 39 | result = state_in->result; 40 | 41 | switch (state_in->step) 42 | { 43 | while (1) 44 | { 45 | case step_A: 46 | if (plainchar == plaintextend) 47 | { 48 | state_in->result = result; 49 | state_in->step = step_A; 50 | return codechar - code_out; 51 | } 52 | fragment = *plainchar++; 53 | result = (fragment & 0x0fc) >> 2; 54 | *codechar++ = base64_encode_value(result); 55 | result = (fragment & 0x003) << 4; 56 | case step_B: 57 | if (plainchar == plaintextend) 58 | { 59 | state_in->result = result; 60 | state_in->step = step_B; 61 | return codechar - code_out; 62 | } 63 | fragment = *plainchar++; 64 | result |= (fragment & 0x0f0) >> 4; 65 | *codechar++ = base64_encode_value(result); 66 | result = (fragment & 0x00f) << 2; 67 | case step_C: 68 | if (plainchar == plaintextend) 69 | { 70 | state_in->result = result; 71 | state_in->step = step_C; 72 | return codechar - code_out; 73 | } 74 | fragment = *plainchar++; 75 | result |= (fragment & 0x0c0) >> 6; 76 | *codechar++ = base64_encode_value(result); 77 | result = (fragment & 0x03f) >> 0; 78 | *codechar++ = base64_encode_value(result); 79 | 80 | ++(state_in->stepcount); 81 | if (state_in->stepcount == CHARS_PER_LINE/4) 82 | { 83 | *codechar++ = '\n'; 84 | state_in->stepcount = 0; 85 | } 86 | } 87 | } 88 | /* control should not reach here */ 89 | return codechar - code_out; 90 | } 91 | 92 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in) 93 | { 94 | char* codechar = code_out; 95 | 96 | switch (state_in->step) 97 | { 98 | case step_B: 99 | *codechar++ = base64_encode_value(state_in->result); 100 | *codechar++ = '='; 101 | *codechar++ = '='; 102 | break; 103 | case step_C: 104 | *codechar++ = base64_encode_value(state_in->result); 105 | *codechar++ = '='; 106 | break; 107 | case step_A: 108 | break; 109 | } 110 | *codechar++ = 0x00; 111 | 112 | return codechar - code_out; 113 | } 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/libb64/cencode_inc.h: -------------------------------------------------------------------------------- 1 | /* 2 | cencode.h - c header for a base64 encoding algorithm 3 | 4 | This is part of the libb64 project, and has been placed in the public domain. 5 | For details, see http://sourceforge.net/projects/libb64 6 | */ 7 | 8 | #ifndef BASE64_CENCODE_H 9 | #define BASE64_CENCODE_H 10 | 11 | typedef enum 12 | { 13 | step_A, step_B, step_C 14 | } base64_encodestep; 15 | 16 | typedef struct 17 | { 18 | base64_encodestep step; 19 | char result; 20 | int stepcount; 21 | } base64_encodestate; 22 | 23 | void base64_init_encodestate(base64_encodestate* state_in); 24 | 25 | char base64_encode_value(char value_in); 26 | 27 | int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in); 28 | 29 | int base64_encode_blockend(char* code_out, base64_encodestate* state_in); 30 | 31 | #endif /* BASE64_CENCODE_H */ 32 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/libsha1/libsha1.c: -------------------------------------------------------------------------------- 1 | /* from valgrind tests */ 2 | 3 | /* ================ sha1.c ================ */ 4 | /* 5 | SHA-1 in C 6 | By Steve Reid 7 | 100% Public Domain 8 | 9 | Test Vectors (from FIPS PUB 180-1) 10 | "abc" 11 | A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 12 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 13 | 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 14 | A million repetitions of "a" 15 | 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 16 | */ 17 | 18 | /* #define LITTLE_ENDIAN * This should be #define'd already, if true. */ 19 | /* #define SHA1HANDSOFF * Copies data before messing with it. */ 20 | 21 | #ifndef ESP8266 22 | 23 | #define SHA1HANDSOFF 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include "libsha1.h" 30 | 31 | 32 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 33 | 34 | /* blk0() and blk() perform the initial expand. */ 35 | /* I got the idea of expanding during the round function from SSLeay */ 36 | #if BYTE_ORDER == LITTLE_ENDIAN 37 | #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 38 | |(rol(block->l[i],8)&0x00FF00FF)) 39 | #elif BYTE_ORDER == BIG_ENDIAN 40 | #define blk0(i) block->l[i] 41 | #else 42 | #error "Endianness not defined!" 43 | #endif 44 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 45 | ^block->l[(i+2)&15]^block->l[i&15],1)) 46 | 47 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 48 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 49 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 50 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 51 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 52 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 53 | 54 | 55 | /* Hash a single 512-bit block. This is the core of the algorithm. */ 56 | 57 | void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) 58 | { 59 | uint32_t a, b, c, d, e; 60 | typedef union { 61 | unsigned char c[64]; 62 | uint32_t l[16]; 63 | } CHAR64LONG16; 64 | #ifdef SHA1HANDSOFF 65 | CHAR64LONG16 block[1]; /* use array to appear as a pointer */ 66 | memcpy(block, buffer, 64); 67 | #else 68 | /* The following had better never be used because it causes the 69 | * pointer-to-const buffer to be cast into a pointer to non-const. 70 | * And the result is written through. I threw a "const" in, hoping 71 | * this will cause a diagnostic. 72 | */ 73 | CHAR64LONG16* block = (const CHAR64LONG16*)buffer; 74 | #endif 75 | /* Copy context->state[] to working vars */ 76 | a = state[0]; 77 | b = state[1]; 78 | c = state[2]; 79 | d = state[3]; 80 | e = state[4]; 81 | /* 4 rounds of 20 operations each. Loop unrolled. */ 82 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 83 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 84 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 85 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 86 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 87 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 88 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 89 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 90 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 91 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 92 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 93 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 94 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 95 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 96 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 97 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 98 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 99 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 100 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 101 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 102 | /* Add the working vars back into context.state[] */ 103 | state[0] += a; 104 | state[1] += b; 105 | state[2] += c; 106 | state[3] += d; 107 | state[4] += e; 108 | /* Wipe variables */ 109 | a = b = c = d = e = 0; 110 | #ifdef SHA1HANDSOFF 111 | memset(block, '\0', sizeof(block)); 112 | #endif 113 | } 114 | 115 | 116 | /* SHA1Init - Initialize new context */ 117 | 118 | void SHA1Init(SHA1_CTX* context) 119 | { 120 | /* SHA1 initialization constants */ 121 | context->state[0] = 0x67452301; 122 | context->state[1] = 0xEFCDAB89; 123 | context->state[2] = 0x98BADCFE; 124 | context->state[3] = 0x10325476; 125 | context->state[4] = 0xC3D2E1F0; 126 | context->count[0] = context->count[1] = 0; 127 | } 128 | 129 | 130 | /* Run your data through this. */ 131 | 132 | void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len) 133 | { 134 | uint32_t i, j; 135 | 136 | j = context->count[0]; 137 | if ((context->count[0] += len << 3) < j) 138 | context->count[1]++; 139 | context->count[1] += (len>>29); 140 | j = (j >> 3) & 63; 141 | if ((j + len) > 63) { 142 | memcpy(&context->buffer[j], data, (i = 64-j)); 143 | SHA1Transform(context->state, context->buffer); 144 | for ( ; i + 63 < len; i += 64) { 145 | SHA1Transform(context->state, &data[i]); 146 | } 147 | j = 0; 148 | } 149 | else i = 0; 150 | memcpy(&context->buffer[j], &data[i], len - i); 151 | } 152 | 153 | 154 | /* Add padding and return the message digest. */ 155 | 156 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context) 157 | { 158 | unsigned i; 159 | unsigned char finalcount[8]; 160 | unsigned char c; 161 | 162 | #if 0 /* untested "improvement" by DHR */ 163 | /* Convert context->count to a sequence of bytes 164 | * in finalcount. Second element first, but 165 | * big-endian order within element. 166 | * But we do it all backwards. 167 | */ 168 | unsigned char *fcp = &finalcount[8]; 169 | 170 | for (i = 0; i < 2; i++) 171 | { 172 | uint32_t t = context->count[i]; 173 | int j; 174 | 175 | for (j = 0; j < 4; t >>= 8, j++) 176 | *--fcp = (unsigned char) t; 177 | } 178 | #else 179 | for (i = 0; i < 8; i++) { 180 | finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] 181 | >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 182 | } 183 | #endif 184 | c = 0200; 185 | SHA1Update(context, &c, 1); 186 | while ((context->count[0] & 504) != 448) { 187 | c = 0000; 188 | SHA1Update(context, &c, 1); 189 | } 190 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 191 | for (i = 0; i < 20; i++) { 192 | digest[i] = (unsigned char) 193 | ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 194 | } 195 | /* Wipe variables */ 196 | memset(context, '\0', sizeof(*context)); 197 | memset(&finalcount, '\0', sizeof(finalcount)); 198 | } 199 | /* ================ end of sha1.c ================ */ 200 | 201 | 202 | #endif 203 | -------------------------------------------------------------------------------- /arduinoWebSockets/src/libsha1/libsha1.h: -------------------------------------------------------------------------------- 1 | /* ================ sha1.h ================ */ 2 | /* 3 | SHA-1 in C 4 | By Steve Reid 5 | 100% Public Domain 6 | */ 7 | 8 | #ifndef ESP8266 9 | 10 | typedef struct { 11 | uint32_t state[5]; 12 | uint32_t count[2]; 13 | unsigned char buffer[64]; 14 | } SHA1_CTX; 15 | 16 | void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); 17 | void SHA1Init(SHA1_CTX* context); 18 | void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); 19 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context); 20 | 21 | #endif -------------------------------------------------------------------------------- /arduinoWebSockets/tests/webSocket.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 40 | 41 | 42 | 43 | LED Control:
44 |
45 | R:
46 | G:
47 | B:
48 | 49 | -------------------------------------------------------------------------------- /arduinoWebSockets/tests/webSocketServer/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var WebSocketServer = require('websocket').server; 3 | var http = require('http'); 4 | 5 | var server = http.createServer(function(request, response) { 6 | console.log((new Date()) + ' Received request for ' + request.url); 7 | response.writeHead(404); 8 | response.end(); 9 | }); 10 | server.listen(81, function() { 11 | console.log((new Date()) + ' Server is listening on port 8011'); 12 | }); 13 | 14 | wsServer = new WebSocketServer({ 15 | httpServer: server, 16 | // You should not use autoAcceptConnections for production 17 | // applications, as it defeats all standard cross-origin protection 18 | // facilities built into the protocol and the browser. You should 19 | // *always* verify the connection's origin and decide whether or not 20 | // to accept it. 21 | autoAcceptConnections: false 22 | }); 23 | 24 | function originIsAllowed(origin) { 25 | // put logic here to detect whether the specified origin is allowed. 26 | return true; 27 | } 28 | 29 | wsServer.on('request', function(request) { 30 | 31 | if (!originIsAllowed(request.origin)) { 32 | // Make sure we only accept requests from an allowed origin 33 | request.reject(); 34 | console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.'); 35 | return; 36 | } 37 | 38 | var connection = request.accept('arduino', request.origin); 39 | console.log((new Date()) + ' Connection accepted.'); 40 | 41 | connection.on('message', function(message) { 42 | if (message.type === 'utf8') { 43 | console.log('Received Message: ' + message.utf8Data); 44 | // connection.sendUTF(message.utf8Data); 45 | } 46 | else if (message.type === 'binary') { 47 | console.log('Received Binary Message of ' + message.binaryData.length + ' bytes'); 48 | //connection.sendBytes(message.binaryData); 49 | } 50 | }); 51 | 52 | connection.on('close', function(reasonCode, description) { 53 | console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.'); 54 | }); 55 | 56 | connection.sendUTF("Hallo Client!"); 57 | }); -------------------------------------------------------------------------------- /arduinoWebSockets/tests/webSocketServer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webSocketServer", 3 | "version": "1.0.0", 4 | "description": "WebSocketServer for testing", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/Links2004/arduinoWebSockets" 12 | }, 13 | "keywords": [ 14 | "esp8266", 15 | "websocket", 16 | "arduino" 17 | ], 18 | "author": "Markus Sattler", 19 | "license": "LGPLv2", 20 | "bugs": { 21 | "url": "https://github.com/Links2004/arduinoWebSockets/issues" 22 | }, 23 | "homepage": "https://github.com/Links2004/arduinoWebSockets", 24 | "dependencies": { 25 | "websocket": "^1.0.18" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /matrix-ai.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nassir-malik/IOT-ESP8266-Google-Home/d72b859894849fed2add3f75cdfd59edcd0fc461/matrix-ai.zip -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | websockets==3.2 -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.6.5 2 | --------------------------------------------------------------------------------