From 6972483b018963c2f277f0e193382d0574d27ffb Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Sun, 2 Jul 2017 16:03:26 +0200 Subject: [PATCH 01/19] Small bugfix in filenames (case sensitive...), added files for 1.5-compatibility. --- keywords.txt | 4 ++++ library.json | 13 +++++++++++++ library.properties | 9 +++++++++ src/ESP8266AWSImplentations.cpp | 2 +- 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 keywords.txt create mode 100644 library.json create mode 100644 library.properties diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..83b87aa --- /dev/null +++ b/keywords.txt @@ -0,0 +1,4 @@ +Amazon KEYWORD1 +AWS KEYWORD2 +IoT KEYWORD3 +ESP8266 KEYWORD4 diff --git a/library.json b/library.json new file mode 100644 index 0000000..629e7e0 --- /dev/null +++ b/library.json @@ -0,0 +1,13 @@ +{ + "name": "AWS-SDK-ESP8266 by Schm1tz1", + "keywords": "AWS, SDK, ESP8266, IoT", + "description": "SDK for accessing AWS IoT services with ESP8266 devices.", + "repository": + { + "type": "git", + "url": "https://github.com/Schm1tz1/aws-sdk-arduino-esp8266" + }, + "frameworks": "arduino", + "platforms": "*" +} + diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..c10965c --- /dev/null +++ b/library.properties @@ -0,0 +1,9 @@ +name=AWS-SDK-ESP8266 +version=1 +author=Roman Schmitz +maintainer=Roman Schmitz +sentence=SDK for AWS using ESP8266 +paragraph=This library is based on the code by awslabs, svdgraaf and fuzzyhandle. It enables you to easily use AWS IoT Services from a ESP8266 SOC with Arduino. There are some great tutorials and projects on the web, also check YoutTube and my GitHub-Pages for examples. As I weil be using this system quite often, I will try to keep it up-to-date and contribute to the arduino libraries. Feel free to contribute to this code - fork, add your stuff, change things and create pull requests. +category=Communication +url=https://github.com/Schm1tz1/aws-sdk-arduino-esp8266 +architectures=* diff --git a/src/ESP8266AWSImplentations.cpp b/src/ESP8266AWSImplentations.cpp index 607517b..584ce01 100644 --- a/src/ESP8266AWSImplentations.cpp +++ b/src/ESP8266AWSImplentations.cpp @@ -1,7 +1,7 @@ #include /* application.h is Esp8266's standard library. Defines the Arduino String * object, the Arduino delay() procedure, and the Esp8266 TCPClient. */ -#include "Esp8266AWSImplementations.h" +#include "ESP8266AWSImplementations.h" #include "DeviceIndependentInterfaces.h" #include #include From 949502bcb625eeb7dd04c0a7fbe561558a7802c2 Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Sun, 2 Jul 2017 16:11:23 +0200 Subject: [PATCH 02/19] Added example. --- examples/SimpleExample/SimpleExample.ino | 50 ++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/SimpleExample/SimpleExample.ino diff --git a/examples/SimpleExample/SimpleExample.ino b/examples/SimpleExample/SimpleExample.ino new file mode 100644 index 0000000..43add8a --- /dev/null +++ b/examples/SimpleExample/SimpleExample.ino @@ -0,0 +1,50 @@ +#include +#include +#include "ESP8266AWSImplementations.h" + +Esp8266HttpClient httpClient; +Esp8266DateTimeProvider dateTimeProvider; + +AmazonIOTClient iotClient; +ActionError actionError; + +char *ssid="MySSID"; +char *password="MyPASS"; + +void setup() { + Serial.begin(115200); + delay(10); + + // Connect to WAP + Serial.print("Connecting to "); + Serial.println(ssid); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + + iotClient.setAWSRegion("eu-west-1"); + iotClient.setAWSEndpoint("amazonaws.com"); + iotClient.setAWSDomain("foobar.iot.eu-west-1.amazonaws.com"); + iotClient.setAWSPath("/things/example-1/shadow"); + iotClient.setAWSKeyID("ID"); + iotClient.setAWSSecretKey("SECRET"); + iotClient.setHttpClient(&httpClient); + iotClient.setDateTimeProvider(&dateTimeProvider); +} + +void loop(){ + char* shadow = "{\"state\":{\"reported\": {\"foobar\": \"bar\"}}}"; + + char* result = iotClient.update_shadow(shadow, actionError); + Serial.print(result); + + delay(60000); +} + From 957212870653c6aba79e1a70dbf16445fc4b8dcd Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Sun, 2 Jul 2017 17:08:02 +0200 Subject: [PATCH 03/19] Bugfix in example. Static buffer needed... --- examples/SimpleExample/SimpleExample.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/SimpleExample/SimpleExample.ino b/examples/SimpleExample/SimpleExample.ino index 43add8a..56649e3 100644 --- a/examples/SimpleExample/SimpleExample.ino +++ b/examples/SimpleExample/SimpleExample.ino @@ -40,9 +40,10 @@ void setup() { } void loop(){ - char* shadow = "{\"state\":{\"reported\": {\"foobar\": \"bar\"}}}"; - + char shadow[100]; + strcpy(shadow, "{\"state\":{\"reported\": {\"foobar\": \"bar\"}}}"); char* result = iotClient.update_shadow(shadow, actionError); + Serial.print(result); delay(60000); From c731a230b79975275ae5c70111e5ae3181c7235d Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Sun, 2 Jul 2017 17:47:33 +0200 Subject: [PATCH 04/19] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index c10965c..29222d7 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AWS-SDK-ESP8266 -version=1 +version=0.9-beta author=Roman Schmitz maintainer=Roman Schmitz sentence=SDK for AWS using ESP8266 From d67b58542b111861aa7bc86a09587f607ea15901 Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Sun, 2 Jul 2017 21:29:35 +0200 Subject: [PATCH 05/19] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 29222d7..b330a6b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AWS-SDK-ESP8266 -version=0.9-beta +version=0.9.1-beta author=Roman Schmitz maintainer=Roman Schmitz sentence=SDK for AWS using ESP8266 From e000bd95fac70d92d71337f10efd9009e2da9c09 Mon Sep 17 00:00:00 2001 From: Jonathan Schoeller Date: Fri, 15 Dec 2017 17:14:25 +1100 Subject: [PATCH 06/19] Off-by-one array index resulting in buffer overflow awsDate is char[9] and awsTime is char[7]. AWSClient4::createRequest attempts to assign '\0' to awsDate[9] and awsTime[7], resulting in a buffer overflow and possible exception with debug message like "there is no poison after the block. Expected poison address:" from umm_malloc.c. Write '\0' to awsDate[8] and awsTime[6] instead. --- src/AWSClient4.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AWSClient4.cpp b/src/AWSClient4.cpp index 97e03a8..4bb6018 100644 --- a/src/AWSClient4.cpp +++ b/src/AWSClient4.cpp @@ -182,9 +182,9 @@ char* AWSClient4::createRequest(MinimalString &reqPayload) { // @TODO: find out why sprintf doesn't work const char* dateTime = dateTimeProvider->getDateTime(); strncpy(awsDate, dateTime, 8); - awsDate[9] = '\0'; + awsDate[AWS_DATE_LEN4] = '\0'; strncpy(awsTime, dateTime + 8, 6); - awsTime[7] = '\0'; + awsTime[AWS_TIME_LEN4] = '\0'; SHA256* sha256 = new SHA256(); payloadHash = (*sha256)(reqPayload.getCStr(), reqPayload.length()); From 0ffaa481c2082963e6edc640f6cf006c05a078f1 Mon Sep 17 00:00:00 2001 From: Michael Goldstein Date: Sun, 31 Dec 2017 13:26:16 -0600 Subject: [PATCH 07/19] Update AmazonDynamoDBClient.cpp DynamoDB needs https --- src/AmazonDynamoDBClient.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/AmazonDynamoDBClient.cpp b/src/AmazonDynamoDBClient.cpp index b49579e..23931f3 100755 --- a/src/AmazonDynamoDBClient.cpp +++ b/src/AmazonDynamoDBClient.cpp @@ -6095,7 +6095,7 @@ BatchGetItemOutput AmazonDynamoDBClient::batchGetItem(BatchGetItemInput batchGet } contentType = JSON_TYPE; target = BATCHGETITEM_TARGET; - httpS = false; + httpS = true; MinimalString payload = batchGetItemInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6146,7 +6146,7 @@ BatchWriteItemOutput AmazonDynamoDBClient::batchWriteItem(BatchWriteItemInput ba } contentType = JSON_TYPE; target = BATCHWRITEITEM_TARGET; - httpS = false; + httpS = true; MinimalString payload = batchWriteItemInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6197,7 +6197,7 @@ CreateTableOutput AmazonDynamoDBClient::createTable(CreateTableInput createTable } contentType = JSON_TYPE; target = CREATETABLE_TARGET; - httpS = false; + httpS = true; MinimalString payload = createTableInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6248,7 +6248,7 @@ DeleteItemOutput AmazonDynamoDBClient::deleteItem(DeleteItemInput deleteItemInpu } contentType = JSON_TYPE; target = DELETEITEM_TARGET; - httpS = false; + httpS = true; MinimalString payload = deleteItemInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6299,7 +6299,7 @@ DeleteTableOutput AmazonDynamoDBClient::deleteTable(DeleteTableInput deleteTable } contentType = JSON_TYPE; target = DELETETABLE_TARGET; - httpS = false; + httpS = true; MinimalString payload = deleteTableInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6350,7 +6350,7 @@ DescribeTableOutput AmazonDynamoDBClient::describeTable(DescribeTableInput descr } contentType = JSON_TYPE; target = DESCRIBETABLE_TARGET; - httpS = false; + httpS = true; MinimalString payload = describeTableInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6401,7 +6401,7 @@ GetItemOutput AmazonDynamoDBClient::getItem(GetItemInput getItemInput, ActionErr } contentType = JSON_TYPE; target = GETITEM_TARGET; - httpS = false; + httpS = true; MinimalString payload = getItemInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6452,7 +6452,7 @@ ListTablesOutput AmazonDynamoDBClient::listTables(ListTablesInput listTablesInpu } contentType = JSON_TYPE; target = LISTTABLES_TARGET; - httpS = false; + httpS = true; MinimalString payload = listTablesInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6503,7 +6503,7 @@ PutItemOutput AmazonDynamoDBClient::putItem(PutItemInput putItemInput, ActionErr } contentType = JSON_TYPE; target = PUTITEM_TARGET; - httpS = false; + httpS = true; MinimalString payload = putItemInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6554,7 +6554,7 @@ QueryOutput AmazonDynamoDBClient::query(QueryInput queryInput, ActionError& acti } contentType = JSON_TYPE; target = QUERY_TARGET; - httpS = false; + httpS = true; MinimalString payload = queryInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6605,7 +6605,7 @@ ScanOutput AmazonDynamoDBClient::scan(ScanInput scanInput, ActionError& actionEr } contentType = JSON_TYPE; target = SCAN_TARGET; - httpS = false; + httpS = true; MinimalString payload = scanInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6656,7 +6656,7 @@ UpdateItemOutput AmazonDynamoDBClient::updateItem(UpdateItemInput updateItemInpu } contentType = JSON_TYPE; target = UPDATEITEM_TARGET; - httpS = false; + httpS = true; MinimalString payload = updateItemInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { @@ -6707,7 +6707,7 @@ UpdateTableOutput AmazonDynamoDBClient::updateTable(UpdateTableInput updateTable } contentType = JSON_TYPE; target = UPDATETABLE_TARGET; - httpS = false; + httpS = true; MinimalString payload = updateTableInput.jsonSerialize(); char* request; if (httpClient->usesCurl()) { From ed875712eb02df0065ee799ede045893d480f66f Mon Sep 17 00:00:00 2001 From: Michael Goldstein Date: Sun, 31 Dec 2017 13:26:54 -0600 Subject: [PATCH 08/19] Update ESP8266AWSImplentations.cpp More resilient response reading. --- src/ESP8266AWSImplentations.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/ESP8266AWSImplentations.cpp b/src/ESP8266AWSImplentations.cpp index 584ce01..1e60ec5 100644 --- a/src/ESP8266AWSImplentations.cpp +++ b/src/ESP8266AWSImplentations.cpp @@ -7,40 +7,39 @@ #include int delayTime = 500; +const char* fingerprint = "20 E4 92 1C D4 B6 39 57 8C EB 41 8B 23 15 9E A4 69 F0 8B F5"; char* updateCurTime(void); Esp8266HttpClient::Esp8266HttpClient() { } char* Esp8266HttpClient::send(const char* request, const char* serverUrl, int port) { - + //port = 443; WiFiClientSecure sclient; Serial.println(serverUrl); Serial.println(port); Serial.println(request); Serial.println(""); Serial.println(""); - - // String response = ""; + if (sclient.connect(serverUrl, port)) { - + if(sclient.verify(fingerprint,serverUrl)){ + Serial.println("Certificate Matches"); + } else { + Serial.println("Certificate Does Not Match"); + } // Send the request sclient.print(request); - // keep reading the response until it's finished while(sclient.connected()) { - while(sclient.available()){ - char c = sclient.read(); - response.concat(c); - Serial.print('.'); - } - - // disconnect any open connections - sclient.stop(); + response = sclient.readStringUntil('\n'); + // disconnect any open connections + sclient.stop(); } } else { + Serial.println("Connection Unsuccessful"); // connection was unsuccessful sclient.stop(); return "can't setup SSL connection"; @@ -144,9 +143,9 @@ char* updateCurTime(void) { ipos = req2.indexOf("Date:"); if(ipos>0) { GmtDate = req2.substring(ipos,ipos+35); - // Serial.println(GmtDate); + Serial.println(GmtDate); utctime = GmtDate.substring(18,22) + getMonth(GmtDate.substring(14,17)) + GmtDate.substring(11,13) + GmtDate.substring(23,25) + GmtDate.substring(26,28) + GmtDate.substring(29,31); - // Serial.println(utctime.substring(0,14)); + Serial.println(utctime.substring(0,14)); utctime.substring(0,14).toCharArray(dateStamp, 20); } } From e9e5eb7c09488b7ac47cb453ac6df2173a324441 Mon Sep 17 00:00:00 2001 From: Burt Silverman Date: Tue, 8 May 2018 22:56:10 -0400 Subject: [PATCH 09/19] Initial commit for ESP8266 and ESP32 This library has been tested with ESP8266 and ESP32. Some filenames that had 8266 in the name have had the 8266 removed to reflect that. Compilation was done with g++ -Wall option which explains why many char * have been changed to const char *. Also -Wall showed us some local variable errors in AWSClient4.cpp and we added some class members to fix that. I added a content-length header to canonical headers only because I was trying to follow AWS instructions literally. What really matters is that the signedHeaders set in AmazonIOTClient corresponds to those used. A couple of places I conditionally compile against ESP32 and/or ESP8266. Mainly that is to select which header files to include, but there is a functional thing in EspHttpClient::send that does not work for ESP32 as written so I left it out. I had to change the receive logic of that function to receive the entire response and close the persistent connection in a simple manner. Likewise, I modified updateCurlTime to avoid using readString() from the underlying stream. --- README.md | 24 +-- examples/SimpleExample/SimpleExample.ino | 19 +- keywords.txt | 9 +- library.json | 8 +- library.properties | 10 +- src/AWSClient.cpp | 6 +- src/AWSClient.h | 4 +- src/AWSClient2.cpp | 5 +- src/AWSClient2.h | 2 +- src/AWSClient4.cpp | 171 ++++++++++++------ src/AWSClient4.h | 23 ++- src/AmazonDynamoDBClient.cpp | 52 +++--- src/AmazonIOTClient.cpp | 6 +- src/AmazonIOTClient.h | 2 +- src/AmazonKinesisClient.cpp | 36 ++-- src/AmazonSNSClient.cpp | 2 +- src/DeviceIndependentInterfaces.h | 2 +- ...ntations.cpp => ESPAWSImplementations.cpp} | 51 ++++-- ...lementations.h => ESPAWSImplementations.h} | 29 +-- 19 files changed, 264 insertions(+), 197 deletions(-) mode change 100644 => 100755 examples/SimpleExample/SimpleExample.ino rename src/{ESP8266AWSImplentations.cpp => ESPAWSImplementations.cpp} (78%) rename src/{ESP8266AWSImplementations.h => ESPAWSImplementations.h} (50%) diff --git a/README.md b/README.md index 004775c..e672534 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Version 1 of the Experimental AWS SDK for Arduino -An experimental SDK for contacting AWS Services on Arduino-compatible devices. Currently it supports Amazon DynamoDB, Amazon Kinesis and Amazon SNS. More services coming soon. +An experimental SDK for contacting AWS Services on Arduino-compatible devices. Currently it supports Amazon DynamoDB, Amazon Kinesis, Amazon IOT and Amazon SNS. More services coming soon. All Amazon DynamoDB operations are supported. The code for creating, serializing, and deserializing Kinesis input and output objects is included, but the devices that the experimental SDK has been tested on do not have readily available HTTPS support. This code has been included so it can be used by those who want to do further experimenting with Kinesis and HTTPS. @@ -8,14 +8,7 @@ The SDK is extensible to non-Arduino-compatible devices by implementing the inte ## Folder Structure - * /common contains all the common source code - * /sparkcore contains Spark IO Core device-specific implementations - * /edison contains Intel Edison device-specfic implementations - * /galileo contains Intel Galileo device-specific implementations - * /mediatek contains MediaTek LinkIt One device-specific implementations - - -Depending on the device that you are working, Simply copy the those device-specific implementations to the Common directory so you can test out your samples using Arduino IDE. + * /src contains all the common source code Happy experimenting! @@ -145,17 +138,18 @@ For Galileo/Edison, after the wiring is finished, you should be able to connect For Spark, after the wiring is finished, you should be able to connect it to your computer via USB, and *Flash* the code. Be sure to refer to the comments in the samples for help. -#### ESP8266 +#### ESP8266 and ESP32 -You can use these libraries with the [Arduino ESP8266](https://github.com/esp8266/arduino):. +You can use these libraries with the [Arduino ESP8266](https://github.com/esp8266/arduino) or ESP32:. ``` -#include +#include +#include //ESP32 case #include -#include "Esp8266AWSImplementations.h" +#include "EspAWSImplementations.h" -Esp8266HttpClient httpClient; -Esp8266DateTimeProvider dateTimeProvider; +EspHttpClient httpClient; +EspDateTimeProvider dateTimeProvider; AmazonIOTClient iotClient; ActionError actionError; diff --git a/examples/SimpleExample/SimpleExample.ino b/examples/SimpleExample/SimpleExample.ino old mode 100644 new mode 100755 index 56649e3..db4e932 --- a/examples/SimpleExample/SimpleExample.ino +++ b/examples/SimpleExample/SimpleExample.ino @@ -1,15 +1,14 @@ -#include #include -#include "ESP8266AWSImplementations.h" +#include "ESPAWSImplementations.h" -Esp8266HttpClient httpClient; -Esp8266DateTimeProvider dateTimeProvider; +EspHttpClient httpClient; +EspDateTimeProvider dateTimeProvider; AmazonIOTClient iotClient; ActionError actionError; -char *ssid="MySSID"; -char *password="MyPASS"; +const char *ssid="MySSID"; +const char *password="MyPASS"; void setup() { Serial.begin(115200); @@ -40,12 +39,12 @@ void setup() { } void loop(){ - char shadow[100]; - strcpy(shadow, "{\"state\":{\"reported\": {\"foobar\": \"bar\"}}}"); - char* result = iotClient.update_shadow(shadow, actionError); + + const char* shadow = "{\"state\":{\"reported\": {\"foobar\": \"bar\"}}}"; + const char* result = iotClient.update_shadow(shadow, actionError); Serial.print(result); delay(60000); } - + diff --git a/keywords.txt b/keywords.txt index 83b87aa..6d6ba5f 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,4 +1,5 @@ -Amazon KEYWORD1 -AWS KEYWORD2 -IoT KEYWORD3 -ESP8266 KEYWORD4 +Amazon KEYWORD1 +AWS KEYWORD2 +IoT KEYWORD3 +ESP8266 KEYWORD4 +ESP32 KEYWORD5 diff --git a/library.json b/library.json index 629e7e0..58e901e 100644 --- a/library.json +++ b/library.json @@ -1,11 +1,11 @@ { - "name": "AWS-SDK-ESP8266 by Schm1tz1", - "keywords": "AWS, SDK, ESP8266, IoT", - "description": "SDK for accessing AWS IoT services with ESP8266 devices.", + "name": "AWS-SDK-ESP by Schm1tz1 modified by Burt-Silverman", + "keywords": "AWS, SDK, ESP8266, ESP32, IoT", + "description": "SDK for accessing AWS IoT services with ESP* devices.", "repository": { "type": "git", - "url": "https://github.com/Schm1tz1/aws-sdk-arduino-esp8266" + "url": "https://github.com/Burt-Silverman/aws-sdk-arduino-esp" }, "frameworks": "arduino", "platforms": "*" diff --git a/library.properties b/library.properties index b330a6b..1647363 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ -name=AWS-SDK-ESP8266 +name=AWS-SDK-ESP version=0.9.1-beta -author=Roman Schmitz +author=Roman Schmitz , Burt Silverman maintainer=Roman Schmitz -sentence=SDK for AWS using ESP8266 -paragraph=This library is based on the code by awslabs, svdgraaf and fuzzyhandle. It enables you to easily use AWS IoT Services from a ESP8266 SOC with Arduino. There are some great tutorials and projects on the web, also check YoutTube and my GitHub-Pages for examples. As I weil be using this system quite often, I will try to keep it up-to-date and contribute to the arduino libraries. Feel free to contribute to this code - fork, add your stuff, change things and create pull requests. +sentence=An SDK for AWS using ESP8266 and/or ESP32 SOCs. +paragraph=This library is based on the code by awslabs, svdgraaf and fuzzyhandle. It enables you to easily use AWS IoT Services from an ESP8266 or ESP32 SOC with Arduino. There are some great tutorials and projects on the web; also check YoutTube and my GitHub-Pages for examples. As I will be using this system quite often, I will try to keep it up-to-date and contribute to the arduino libraries. Feel free to contribute to this code - fork, add your stuff, change things and create pull requests. category=Communication -url=https://github.com/Schm1tz1/aws-sdk-arduino-esp8266 +url=https://github.com/Burt-Silverman/aws-sdk-arduino-esp architectures=* diff --git a/src/AWSClient.cpp b/src/AWSClient.cpp index 1295e1d..6121216 100644 --- a/src/AWSClient.cpp +++ b/src/AWSClient.cpp @@ -334,7 +334,7 @@ char* AWSClient::createRequest(MinimalString &reqPayload) { return request; } -char* AWSClient::createCurlRequest(MinimalString &reqPayload) { +const char* AWSClient::createCurlRequest(MinimalString &reqPayload) { /* Check that all values have been initialized. */ if (awsRegion == 0 || awsEndpoint == 0 || awsSecKey == 0 || awsKeyID == 0 || httpClient == 0 || dateTimeProvider == 0) @@ -345,12 +345,12 @@ char* AWSClient::createCurlRequest(MinimalString &reqPayload) { return request; } -char* AWSClient::sendData(const char* data) { +const char* AWSClient::sendData(const char* data) { char* server = new char[strlen(awsService) + strlen(awsRegion) + strlen(awsEndpoint) + 4](); sprintf(server, "%s.%s.%s", awsService, awsRegion, awsEndpoint); int port = httpS ? 443 : 80; - char* response = httpClient->send(data, server, port); + const char* response = httpClient->send(data, server, port); delete[] server; return response; } diff --git a/src/AWSClient.h b/src/AWSClient.h index 52cf048..4eb380a 100644 --- a/src/AWSClient.h +++ b/src/AWSClient.h @@ -90,9 +90,9 @@ class AWSClient { /* Creates a http request in curl format, given the payload and current GMT * date in yyyyMMddHHmmss format. Should be exposed to user by extending * class. Returns 0 if client is unititialized. */ - char* createCurlRequest(MinimalString &payload); + const char* createCurlRequest(MinimalString &payload); /* Sends http data. Returns http response, or null on error. */ - char* sendData(const char* data); + const char* sendData(const char* data); /* Empty constructor. Must also be initialized with init. */ AWSClient(); diff --git a/src/AWSClient2.cpp b/src/AWSClient2.cpp index 7353e58..6dbcf39 100644 --- a/src/AWSClient2.cpp +++ b/src/AWSClient2.cpp @@ -29,7 +29,6 @@ static const char* CONTENT_LENGTH_HEADER = "content-length:%d"; static const int CONTENT_LENGTH_HEADER_LEN = 15; static const char* HOST_HEADER = "host:%s.%s.%s"; static const int HOST_HEADER_LEN = 7; -static const char* CONNECTION_HEADER = "Connection:close"; static const int CONNECTION_HEADER_LEN = 16; static const char* CONTENT_TYPE_HEADER = "content-type:%s"; static const int CONTENT_TYPE_HEADER_LEN = 13; @@ -287,12 +286,12 @@ char* AWSClient2::createRequest(MinimalString &reqPayload) { return request; } -char* AWSClient2::sendData(const char* data) { +const char* AWSClient2::sendData(const char* data) { char* server = new char[strlen(awsService) + strlen(awsRegion) + strlen(awsEndpoint) + 4](); sprintf(server, "%s.%s.%s", awsService, awsRegion, awsEndpoint); int port = httpS ? 443 : 80; - char* response = httpClient->send(data, server, port); + const char* response = httpClient->send(data, server, port); delete[] server; return response; } diff --git a/src/AWSClient2.h b/src/AWSClient2.h index 37e2634..9d8811f 100644 --- a/src/AWSClient2.h +++ b/src/AWSClient2.h @@ -81,7 +81,7 @@ class AWSClient2 { * Returns 0 if client is unititialized. */ char* createRequest(MinimalString &payload); /* Sends http data. Returns http response, or null on error. */ - char* sendData(const char* data); + const char* sendData(const char* data); /* Empty constructor. Must also be initialized with init. */ AWSClient2(); diff --git a/src/AWSClient4.cpp b/src/AWSClient4.cpp index 4bb6018..adc5c3e 100644 --- a/src/AWSClient4.cpp +++ b/src/AWSClient4.cpp @@ -1,7 +1,7 @@ /* - * AWSClient.cpp + * AWSClient4.cpp * - * See AWSClient.h for description. + * See AWSClient4.h for description. * See http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html * */ @@ -15,8 +15,9 @@ #include #include -AWSClient4::AWSClient4() { - /* Null until set in init method. */ +AWSClient4::AWSClient4() +{ + /* Null until set in init method or derived class function. */ awsRegion = 0; awsEndpoint = 0; awsSecKey = 0; @@ -25,46 +26,71 @@ AWSClient4::AWSClient4() { dateTimeProvider = 0; method = 0; uri = 0; + payload = ""; } -void AWSClient4::setAWSRegion(const char * awsRegion) { +void +AWSClient4::setAWSRegion(const char * awsRegion) +{ int len = strlen(awsRegion) + 1; this->awsRegion = new char[len](); strcpy(this->awsRegion, awsRegion); } -void AWSClient4::setAWSEndpoint(const char * awsEndpoint) { + +void +AWSClient4::setAWSEndpoint(const char * awsEndpoint) +{ int len = strlen(awsEndpoint) + 1; this->awsEndpoint = new char[len](); strcpy(this->awsEndpoint, awsEndpoint); } -void AWSClient4::setAWSDomain(const char * awsDomain) { + +void +AWSClient4::setAWSDomain(const char * awsDomain) +{ int len = strlen(awsDomain) + 1; this->awsDomain = new char[len](); strcpy(this->awsDomain, awsDomain); } -void AWSClient4::setAWSPath(const char * awsPath) { + +void +AWSClient4::setAWSPath(const char * awsPath) +{ int len = strlen(awsPath) + 1; this->awsPath = new char[len](); strcpy(this->awsPath, awsPath); } -void AWSClient4::setAWSSecretKey(const char * awsSecKey) { + +void +AWSClient4::setAWSSecretKey(const char * awsSecKey) +{ int len = strlen(awsSecKey) + 1; this->awsSecKey = new char[len](); strcpy(this->awsSecKey, awsSecKey); } -void AWSClient4::setAWSKeyID(const char * awsKeyID) { + +void +AWSClient4::setAWSKeyID(const char * awsKeyID) +{ int len = strlen(awsKeyID) + 1; this->awsKeyID = new char[len](); strcpy(this->awsKeyID, awsKeyID); } -void AWSClient4::setHttpClient(IHttpClient* httpClient) { + +void +AWSClient4::setHttpClient(IHttpClient* httpClient) +{ this->httpClient = httpClient; } -void AWSClient4::setDateTimeProvider(IDateTimeProvider* dateTimeProvider) { + +void +AWSClient4::setDateTimeProvider(IDateTimeProvider* dateTimeProvider) +{ this->dateTimeProvider = dateTimeProvider; } -AWSClient4::~AWSClient4() { +AWSClient4::~AWSClient4() +{ if (awsRegion != 0) delete[] awsRegion; if (awsEndpoint != 0) @@ -73,71 +99,95 @@ AWSClient4::~AWSClient4() { delete[] awsSecKey; if (awsKeyID != 0) delete[] awsKeyID; + if (awsDomain != 0) + delete[] awsDomain; + if (awsPath != 0) + delete[] awsPath; } -char* AWSClient4::createCanonicalHeaders() { +void +AWSClient4::createCanonicalHeaders() +{ // headers, alphabetically sorted, lowercase, eg: key:value + // content-length:l // content-type:x // host:host // x-amz-content-sha256:hash // x-amz-date:date - char canonical_headers[500] = ""; - sprintf(canonical_headers, "%scontent-type:%s\n", canonical_headers, contentType); + canonical_headers[0] = 0; + sprintf(canonical_headers, "%scontent-length:%d\n", canonical_headers, + strlen(payload.getCStr())); + sprintf(canonical_headers, "%scontent-type:%s\n", canonical_headers, + contentType); sprintf(canonical_headers, "%shost:%s\n", canonical_headers, awsDomain); // sprintf(canonical_headers, "%srange:bytes=0-9\n", canonical_headers); // s3 - sprintf(canonical_headers, "%sx-amz-content-sha256:%s\n", canonical_headers, payloadHash); - sprintf(canonical_headers, "%sx-amz-date:%sT%sZ\n\n", canonical_headers, awsDate, awsTime); - return canonical_headers; + sprintf(canonical_headers, "%sx-amz-content-sha256:%s\n", + canonical_headers, payloadHash); + sprintf(canonical_headers, "%sx-amz-date:%sT%sZ\n\n", canonical_headers, + awsDate, awsTime); + return; } -char* AWSClient4::createRequestHeaders(char* signature) { - char headers[1000] = ""; +void +AWSClient4::createRequestHeaders(char* signature) +{ + headers[0] = 0; sprintf(headers, "%sContent-Type: %s\r\n", headers, contentType); - sprintf(headers, "%sConnection: close\r\n", headers); - sprintf(headers, "%sContent-Length: %d\r\n", headers, strlen(payload.getCStr())); + sprintf(headers, "%sContent-Length: %d\r\n", headers, + strlen(payload.getCStr())); sprintf(headers, "%sHost: %s\r\n", headers, awsDomain); - sprintf(headers, "%sx-amz-content-sha256: %s\r\n", headers, payloadHash); - sprintf(headers, "%sx-amz-date: %sT%sZ\r\n", headers, awsDate, awsTime); - sprintf(headers, "%sAuthorization: AWS4-HMAC-SHA256 Credential=%s/%s/%s/%s/aws4_request,SignedHeaders=%s,Signature=%s\r\n", headers, awsKeyID, awsDate, awsRegion, awsService, signedHeaders, signature); - return headers; + sprintf(headers, "%sX-Amz-Content-Sha256: %s\r\n", headers, payloadHash); + sprintf(headers, "%sX-Amz-Date: %sT%sZ\r\n", headers, awsDate, awsTime); + sprintf(headers, "%sAuthorization: AWS4-HMAC-SHA256 Credential=%s/%s/%s/%s/" + "aws4_request, SignedHeaders=%s, Signature=%s\r\n", headers, + awsKeyID, awsDate, awsRegion, awsService, signedHeaders, signature); + return; } -char* AWSClient4::createStringToSign(char* canonical_request) { - // return canonical_request; +void +AWSClient4::createStringToSign(char* canonical_request) +{ SHA256* sha256 = new SHA256(); char* hashed = (*sha256)(canonical_request, strlen(canonical_request)); delete sha256; - // return canonical_request; - char string_to_sign[700] = ""; + string_to_sign[0] = 0; sprintf(string_to_sign, "%sAWS4-HMAC-SHA256\n", string_to_sign); sprintf(string_to_sign, "%s%sT%sZ\n", string_to_sign, awsDate, awsTime); - sprintf(string_to_sign, "%s%s/%s/%s/aws4_request\n", string_to_sign, awsDate, awsRegion, awsService); + sprintf(string_to_sign, "%s%s/%s/%s/aws4_request\n", string_to_sign, + awsDate, awsRegion, awsService); sprintf(string_to_sign, "%s%s", string_to_sign, hashed); - return string_to_sign; + return; } -char* AWSClient4::createCanonicalRequest() { - char canonical_request[800] = ""; +void +AWSClient4::createCanonicalRequest() +{ + canonical_request[0] = 0; sprintf(canonical_request, "%s%s\n", canonical_request, method); // VERB sprintf(canonical_request, "%s%s\n", canonical_request, awsPath); // URI - sprintf(canonical_request, "%s%s\n", canonical_request, queryString); // queryString + sprintf(canonical_request, "%s%s\n", canonical_request, + queryString); // queryString - char* headers = createCanonicalHeaders(); + createCanonicalHeaders(); - sprintf(canonical_request, "%s%s", canonical_request, headers); // headers - sprintf(canonical_request, "%s%s\n", canonical_request, signedHeaders); // signed_headers - sprintf(canonical_request, "%s%s", canonical_request, payloadHash); // payload + sprintf(canonical_request, "%s%s", canonical_request, canonical_headers); + // headers + sprintf(canonical_request, "%s%s\n", canonical_request, signedHeaders); + // signed_headers + sprintf(canonical_request, "%s%s", canonical_request, payloadHash); + // payload - return canonical_request; + return; } -char* AWSClient4::createSignature(const char* toSign) { - +char* +AWSClient4::createSignature(const char* toSign) +{ /* Allocate memory for the signature */ char* signature = new char[HASH_HEX_LEN4 + 1](); @@ -172,7 +222,9 @@ char* AWSClient4::createSignature(const char* toSign) { } -char* AWSClient4::createRequest(MinimalString &reqPayload) { +char* +AWSClient4::createRequest(MinimalString &reqPayload) +{ /* Check that all values have been initialized. */ if (awsRegion == 0 || awsEndpoint == 0 || awsSecKey == 0 || awsKeyID == 0 || httpClient == 0 || dateTimeProvider == 0) @@ -192,39 +244,38 @@ char* AWSClient4::createRequest(MinimalString &reqPayload) { payload = reqPayload; - // create the canonical request, we need to copy the results - // @TODO: figure out why the reference doesn't work - char *canonical_request_return = createCanonicalRequest(); - char canonical_request[1000]; - strcpy(canonical_request, canonical_request_return); - // return canonical_request; + // create the canonical request + createCanonicalRequest(); - // create the signing string, we need to copy the results - // @TODO: figure out why the reference doesn't work - char *return_string_to_sign = createStringToSign(canonical_request); - char string_to_sign[500]; - strcpy(string_to_sign, return_string_to_sign); + // create the signing string + createStringToSign(canonical_request); // create the signature char *signature = createSignature(string_to_sign); // create the headers - char *headers = createRequestHeaders(signature); + createRequestHeaders(signature); + delete signature; // get the host/domain // char *host = createHost(); // create the request with all the vars - char* request = new char[strlen(method) + strlen(awsDomain) + strlen(awsPath) + strlen(headers) + strlen(reqPayload.getCStr()) + 16](); - sprintf(request, "%s %s HTTP/1.1\r\n%s\r\n%s\r\n\r\n", method, awsPath, headers, reqPayload.getCStr()); + char* request = new char[strlen(method) + strlen(awsDomain) + + strlen(awsPath) + strlen(headers) + + strlen(reqPayload.getCStr()) + 16](); + sprintf(request, "%s %s HTTP/1.1\r\n%s\r\n%s\r\n\r\n", method, awsPath, + headers, reqPayload.getCStr()); return request; } -char* AWSClient4::sendData(const char* data) { +const char* +AWSClient4::sendData(const char* data) +{ // char* server = createHost(); int port = httpS ? 443 : 80; - char* response = httpClient->send(data, awsDomain, port); + const char* response = httpClient->send(data, awsDomain, port); // delete[] server; return response; } diff --git a/src/AWSClient4.h b/src/AWSClient4.h index 184e055..1f10673 100644 --- a/src/AWSClient4.h +++ b/src/AWSClient4.h @@ -48,11 +48,11 @@ class AWSClient4 { // void initSignedHeaders(); // /* Create the canonical request and the string to sign as described. Return // * value must be deleted by caller. */ - char* createStringToSign(char* canonical_request); + void createStringToSign(char* canonical_request); // /* Given the string to sign, create the signature (a 64-char cstring). // * Return value must be deleted by caller. */ char* createSignature(const char* toSign); - char* createRequestHeaders(char* signature); + void createRequestHeaders(char* signature); // /* Add the headers that will not be signed to the headers array. Called // * after createSignature. */ // void initUnsignedHeaders(const char* signature); @@ -66,11 +66,14 @@ class AWSClient4 { // char* headersToRequest(void); protected: - char* method; - char* uri; - char* queryString; - char* headers; - char* signedHeaders; + const char* method; + const char* uri; + const char* queryString; + char headers[1000]; + char canonical_headers[500]; + char string_to_sign[700]; + char canonical_request[1000]; + const char* signedHeaders; char* payloadHash; /* Used to keep track of time. */ @@ -89,11 +92,11 @@ class AWSClient4 { * yyyyMMddHHmmss format. Should be exposed to user by extending class. * Returns 0 if client is unititialized. */ char* createRequest(MinimalString &payload); - char* createCanonicalRequest(); - char* createCanonicalHeaders(); + void createCanonicalRequest(); + void createCanonicalHeaders(); /* Sends http data. Returns http response, or null on error. */ - char* sendData(const char* data); + const char* sendData(const char* data); /* Empty constructor. Must also be initialized with init. */ AWSClient4(); diff --git a/src/AmazonDynamoDBClient.cpp b/src/AmazonDynamoDBClient.cpp index 23931f3..09037f4 100755 --- a/src/AmazonDynamoDBClient.cpp +++ b/src/AmazonDynamoDBClient.cpp @@ -6097,13 +6097,13 @@ BatchGetItemOutput AmazonDynamoDBClient::batchGetItem(BatchGetItemInput batchGet target = BATCHGETITEM_TARGET; httpS = true; MinimalString payload = batchGetItemInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6148,13 +6148,13 @@ BatchWriteItemOutput AmazonDynamoDBClient::batchWriteItem(BatchWriteItemInput ba target = BATCHWRITEITEM_TARGET; httpS = true; MinimalString payload = batchWriteItemInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6199,13 +6199,13 @@ CreateTableOutput AmazonDynamoDBClient::createTable(CreateTableInput createTable target = CREATETABLE_TARGET; httpS = true; MinimalString payload = createTableInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6250,13 +6250,13 @@ DeleteItemOutput AmazonDynamoDBClient::deleteItem(DeleteItemInput deleteItemInpu target = DELETEITEM_TARGET; httpS = true; MinimalString payload = deleteItemInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6301,13 +6301,13 @@ DeleteTableOutput AmazonDynamoDBClient::deleteTable(DeleteTableInput deleteTable target = DELETETABLE_TARGET; httpS = true; MinimalString payload = deleteTableInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6352,13 +6352,13 @@ DescribeTableOutput AmazonDynamoDBClient::describeTable(DescribeTableInput descr target = DESCRIBETABLE_TARGET; httpS = true; MinimalString payload = describeTableInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6403,13 +6403,13 @@ GetItemOutput AmazonDynamoDBClient::getItem(GetItemInput getItemInput, ActionErr target = GETITEM_TARGET; httpS = true; MinimalString payload = getItemInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6454,13 +6454,13 @@ ListTablesOutput AmazonDynamoDBClient::listTables(ListTablesInput listTablesInpu target = LISTTABLES_TARGET; httpS = true; MinimalString payload = listTablesInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6505,13 +6505,13 @@ PutItemOutput AmazonDynamoDBClient::putItem(PutItemInput putItemInput, ActionErr target = PUTITEM_TARGET; httpS = true; MinimalString payload = putItemInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6556,13 +6556,13 @@ QueryOutput AmazonDynamoDBClient::query(QueryInput queryInput, ActionError& acti target = QUERY_TARGET; httpS = true; MinimalString payload = queryInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6607,13 +6607,13 @@ ScanOutput AmazonDynamoDBClient::scan(ScanInput scanInput, ActionError& actionEr target = SCAN_TARGET; httpS = true; MinimalString payload = scanInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6658,13 +6658,13 @@ UpdateItemOutput AmazonDynamoDBClient::updateItem(UpdateItemInput updateItemInpu target = UPDATEITEM_TARGET; httpS = true; MinimalString payload = updateItemInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -6709,13 +6709,13 @@ UpdateTableOutput AmazonDynamoDBClient::updateTable(UpdateTableInput updateTable target = UPDATETABLE_TARGET; httpS = true; MinimalString payload = updateTableInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; diff --git a/src/AmazonIOTClient.cpp b/src/AmazonIOTClient.cpp index 0d85eca..30ebf8b 100644 --- a/src/AmazonIOTClient.cpp +++ b/src/AmazonIOTClient.cpp @@ -6,18 +6,18 @@ AmazonIOTClient::AmazonIOTClient() : AWSClient4() { this->awsService = "iotdata"; this->contentType = "application/json"; - this->signedHeaders = "content-type;host;x-amz-content-sha256;x-amz-date"; + this->signedHeaders = "content-length;content-type;host;x-amz-content-sha256;x-amz-date"; this->uri = "/"; this->queryString = ""; this->httpS = true; } -char* AmazonIOTClient::update_shadow(MinimalString shadow, ActionError& actionError) { +const char* AmazonIOTClient::update_shadow(MinimalString shadow, ActionError& actionError) { actionError = NONE_ACTIONERROR; this->method = "POST"; char* request = createRequest(shadow); // return request; - char* response = sendData(request); + const char* response = sendData(request); return response; } diff --git a/src/AmazonIOTClient.h b/src/AmazonIOTClient.h index 292bcac..37facf4 100644 --- a/src/AmazonIOTClient.h +++ b/src/AmazonIOTClient.h @@ -16,7 +16,7 @@ class AmazonIOTClient : public AWSClient4 { public: AmazonIOTClient(); - char* update_shadow(MinimalString shadow, ActionError& actionError); + const char* update_shadow(MinimalString shadow, ActionError& actionError); }; #endif /* AMAZONIOTCLIENT_H_ */ diff --git a/src/AmazonKinesisClient.cpp b/src/AmazonKinesisClient.cpp index 5c6973f..9218211 100644 --- a/src/AmazonKinesisClient.cpp +++ b/src/AmazonKinesisClient.cpp @@ -1912,13 +1912,13 @@ KinesisErrorCheckingOnlyOutput AmazonKinesisClient::createStream(CreateStreamInp target = CREATESTREAM_TARGET; httpS = true; MinimalString payload = createStreamInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -1962,13 +1962,13 @@ KinesisErrorCheckingOnlyOutput AmazonKinesisClient::deleteStream(DeleteStreamInp target = DELETESTREAM_TARGET; httpS = true; MinimalString payload = deleteStreamInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -2012,13 +2012,13 @@ DescribeStreamOutput AmazonKinesisClient::describeStream(DescribeStreamInput des target = DESCRIBESTREAM_TARGET; httpS = true; MinimalString payload = describeStreamInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -2063,13 +2063,13 @@ GetRecordsOutput AmazonKinesisClient::getRecords(GetRecordsInput getRecordsInput target = GETRECORDS_TARGET; httpS = true; MinimalString payload = getRecordsInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -2114,13 +2114,13 @@ GetShardIteratorOutput AmazonKinesisClient::getShardIterator(GetShardIteratorInp target = GETSHARDITERATOR_TARGET; httpS = true; MinimalString payload = getShardIteratorInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -2165,13 +2165,13 @@ ListStreamsOutput AmazonKinesisClient::listStreams(ListStreamsInput listStreamsI target = LISTSTREAMS_TARGET; httpS = true; MinimalString payload = listStreamsInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -2216,13 +2216,13 @@ KinesisErrorCheckingOnlyOutput AmazonKinesisClient::mergeShards(MergeShardsInput target = MERGESHARDS_TARGET; httpS = true; MinimalString payload = mergeShardsInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -2266,13 +2266,13 @@ PutRecordOutput AmazonKinesisClient::putRecord(PutRecordInput putRecordInput, Ac target = PUTRECORD_TARGET; httpS = true; MinimalString payload = putRecordInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; @@ -2317,13 +2317,13 @@ KinesisErrorCheckingOnlyOutput AmazonKinesisClient::splitShard(SplitShardInput s target = SPLITSHARD_TARGET; httpS = true; MinimalString payload = splitShardInput.jsonSerialize(); - char* request; + const char* request; if (httpClient->usesCurl()) { request = createCurlRequest(payload); } else { request = createRequest(payload); } - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { actionError = CONNECTION_ACTIONERROR; diff --git a/src/AmazonSNSClient.cpp b/src/AmazonSNSClient.cpp index c99c281..994613d 100644 --- a/src/AmazonSNSClient.cpp +++ b/src/AmazonSNSClient.cpp @@ -96,7 +96,7 @@ PublishOutput AmazonSNSClient::publish(PublishInput publishInput, ActionError& a MinimalString payload = publishInput.serialize(); char* request = createRequest(payload); - char* response = sendData(request); + const char* response = sendData(request); delete[] request; if (response == NULL) { diff --git a/src/DeviceIndependentInterfaces.h b/src/DeviceIndependentInterfaces.h index e7aa79f..be39dd9 100644 --- a/src/DeviceIndependentInterfaces.h +++ b/src/DeviceIndependentInterfaces.h @@ -7,7 +7,7 @@ class IHttpClient { public: virtual ~IHttpClient(); /* Send http request and return the response. */ - virtual char* send(const char *request, const char* serverUrl, + virtual const char* send(const char *request, const char* serverUrl, int port) = 0; /* Returns true if the client uses a curl command, false if the client uses * raw http/https. */ diff --git a/src/ESP8266AWSImplentations.cpp b/src/ESPAWSImplementations.cpp similarity index 78% rename from src/ESP8266AWSImplentations.cpp rename to src/ESPAWSImplementations.cpp index 1e60ec5..905eea1 100644 --- a/src/ESP8266AWSImplentations.cpp +++ b/src/ESPAWSImplementations.cpp @@ -1,19 +1,25 @@ #include -/* application.h is Esp8266's standard library. Defines the Arduino String - * object, the Arduino delay() procedure, and the Esp8266 TCPClient. */ -#include "ESP8266AWSImplementations.h" +/* application.h is Esp's standard library. Defines the Arduino String + * object, the Arduino delay() procedure, and the Esp TCPClient. */ +#include "ESPAWSImplementations.h" #include "DeviceIndependentInterfaces.h" -#include + +#ifdef ESP32 +#include +#endif + #include int delayTime = 500; const char* fingerprint = "20 E4 92 1C D4 B6 39 57 8C EB 41 8B 23 15 9E A4 69 F0 8B F5"; char* updateCurTime(void); -Esp8266HttpClient::Esp8266HttpClient() { +EspHttpClient::EspHttpClient() { } -char* Esp8266HttpClient::send(const char* request, const char* serverUrl, int port) { +const char* +EspHttpClient::send(const char* request, const char* serverUrl, int port) +{ //port = 443; WiFiClientSecure sclient; Serial.println(serverUrl); @@ -21,21 +27,30 @@ char* Esp8266HttpClient::send(const char* request, const char* serverUrl, int po Serial.println(request); Serial.println(""); Serial.println(""); + String response = ""; if (sclient.connect(serverUrl, port)) { +#ifndef ESP32 if(sclient.verify(fingerprint,serverUrl)){ Serial.println("Certificate Matches"); } else { Serial.println("Certificate Does Not Match"); } +#endif + // Send the request sclient.print(request); // keep reading the response until it's finished while(sclient.connected()) { - response = sclient.readStringUntil('\n'); - // disconnect any open connections - sclient.stop(); + bool availableSeen = false; + while(sclient.available()){ + availableSeen = true; + char c = sclient.read(); + response.concat(c); + } + if(availableSeen) + sclient.stop(); // disconnect any open connections } } else { @@ -52,22 +67,22 @@ char* Esp8266HttpClient::send(const char* request, const char* serverUrl, int po return response_char; } -bool Esp8266HttpClient::usesCurl() { +bool EspHttpClient::usesCurl() { /* Does not use curl command. */ return false; } -Esp8266DateTimeProvider::Esp8266DateTimeProvider() { +EspDateTimeProvider::EspDateTimeProvider() { } -const char* Esp8266DateTimeProvider::getDateTime() { +const char* EspDateTimeProvider::getDateTime() { return updateCurTime(); } -bool Esp8266DateTimeProvider::syncTakesArg(void) { +bool EspDateTimeProvider::syncTakesArg(void) { return true; } -void Esp8266DateTimeProvider::sync(const char* dateTime) { +void EspDateTimeProvider::sync(const char* dateTime) { // should have no need for an implementation } @@ -105,9 +120,6 @@ char* updateCurTime(void) { String utctime; String GmtDate; static char dateStamp[20]; - static char chBuf[200]; - char utctimeraw[80]; - char* dpos; WiFiClient client; if (client.connect(timeServer, 80)) { @@ -128,7 +140,10 @@ char* updateCurTime(void) { } // read the http GET Response - String req2 = client.readString(); + const int buflen = 1024; + uint8_t buffer[buflen]; + client.read(buffer, buflen); + String req2 = (char*)buffer; // Serial.println(""); // Serial.println(""); // Serial.print(req2); diff --git a/src/ESP8266AWSImplementations.h b/src/ESPAWSImplementations.h similarity index 50% rename from src/ESP8266AWSImplementations.h rename to src/ESPAWSImplementations.h index 75260c2..dbe32f2 100644 --- a/src/ESP8266AWSImplementations.h +++ b/src/ESPAWSImplementations.h @@ -1,37 +1,42 @@ -#ifndef AWSESP2866IMPLEMENTATIONS_H_ -#define AWSESP2866IMPLEMENTATIONS_H_ +#ifndef AWSESPIMPLEMENTATIONS_H_ +#define AWSESPIMPLEMENTATIONS_H_ #include "DeviceIndependentInterfaces.h" -/* application.h is Esp8266's standard library. Define TCPClient. */ +/* application.h is Esp's standard library. Define TCPClient. */ +#ifdef ESP8266 #include +#else +#include +#include +#endif -/* HttpClient implementation to be used on the Esp8266 Core device. */ -class Esp8266HttpClient: public IHttpClient { +/* HttpClient implementation to be used on the Esp Core device. */ +class EspHttpClient: public IHttpClient { WiFiClientSecure sclient; //TCPClient client; public: - Esp8266HttpClient(); + EspHttpClient(); /* Send http request and return the response. */ - char* send(const char *request, const char* serverUrl, int port); + const char* send(const char *request, const char* serverUrl, int port); /* Returns false. Client uses raw http/https. */ bool usesCurl(void); }; -class Esp8266DateTimeProvider: public IDateTimeProvider { +class EspDateTimeProvider: public IDateTimeProvider { /* The time as a cstring in yyyyMMddHHmmss format. Is written to within and * returned by getDateTime(). */ WiFiClient client; //char dateTime[15]; public: char dateTime[15]; - Esp8266DateTimeProvider(); + EspDateTimeProvider(); /* Retrieve the current GMT date and time in yyyyMMddHHmmss format. */ const char* getDateTime(void); - /* Returns false because Esp8266 has it's own mechanism for syncing that does + /* Returns false because Esp has it's own mechanism for syncing that does * not require an argument. */ bool syncTakesArg(void); - /* Synchronizes Esp8266's date and time with Esp8266's servers. The dateTime + /* Synchronizes Esp's date and time with Esp's servers. The dateTime * argument is ignored. */ void sync(const char* dateTime); }; -#endif /* AWSESP2866IMPLEMENTATIONS_H_ */ +#endif /* AWSESPIMPLEMENTATIONS_H_ */ From 15da837c8fd1467a3456e40867900362a27ad95c Mon Sep 17 00:00:00 2001 From: Burt Silverman Date: Wed, 9 May 2018 21:07:50 -0400 Subject: [PATCH 10/19] Remove some conditional ESP32/ESP8266 code Now there are no conditional header files specified in the library. The only conditional code remaining is WiFiClientSecure::verify, which does not exist under ESP32. --- src/ESPAWSImplementations.cpp | 8 +------- src/ESPAWSImplementations.h | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/ESPAWSImplementations.cpp b/src/ESPAWSImplementations.cpp index 905eea1..9324225 100644 --- a/src/ESPAWSImplementations.cpp +++ b/src/ESPAWSImplementations.cpp @@ -1,13 +1,7 @@ -#include -/* application.h is Esp's standard library. Defines the Arduino String - * object, the Arduino delay() procedure, and the Esp TCPClient. */ #include "ESPAWSImplementations.h" #include "DeviceIndependentInterfaces.h" -#ifdef ESP32 -#include -#endif - +#include #include int delayTime = 500; diff --git a/src/ESPAWSImplementations.h b/src/ESPAWSImplementations.h index dbe32f2..5bef63c 100644 --- a/src/ESPAWSImplementations.h +++ b/src/ESPAWSImplementations.h @@ -1,18 +1,12 @@ #ifndef AWSESPIMPLEMENTATIONS_H_ #define AWSESPIMPLEMENTATIONS_H_ + #include "DeviceIndependentInterfaces.h" -/* application.h is Esp's standard library. Define TCPClient. */ -#ifdef ESP8266 -#include -#else -#include #include -#endif /* HttpClient implementation to be used on the Esp Core device. */ class EspHttpClient: public IHttpClient { WiFiClientSecure sclient; - //TCPClient client; public: EspHttpClient(); /* Send http request and return the response. */ From 303fce3e3e75115a6a04de06a234051d58846957 Mon Sep 17 00:00:00 2001 From: Burt Silverman Date: Tue, 5 Jun 2018 23:30:25 -0400 Subject: [PATCH 11/19] Minor changes to suport ARCH_SAM and ARCH_SAMD WiFiSSLClient vs WiFiClientSecure. Allow a variable SERIALUSB to change the debug serial port for Arduino cards. --- src/ESPAWSImplementations.cpp | 6 +++++- src/ESPAWSImplementations.h | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/ESPAWSImplementations.cpp b/src/ESPAWSImplementations.cpp index 9324225..c47a1d6 100644 --- a/src/ESPAWSImplementations.cpp +++ b/src/ESPAWSImplementations.cpp @@ -15,7 +15,11 @@ const char* EspHttpClient::send(const char* request, const char* serverUrl, int port) { //port = 443; +#if !defined ARDUINO_ARCH_SAM && !defined ARDUINO_ARCH_SAMD WiFiClientSecure sclient; +#else + WiFiSSLClient sclient; +#endif Serial.println(serverUrl); Serial.println(port); Serial.println(request); @@ -25,7 +29,7 @@ EspHttpClient::send(const char* request, const char* serverUrl, int port) String response = ""; if (sclient.connect(serverUrl, port)) { -#ifndef ESP32 +#ifdef ESP8266 if(sclient.verify(fingerprint,serverUrl)){ Serial.println("Certificate Matches"); } else { diff --git a/src/ESPAWSImplementations.h b/src/ESPAWSImplementations.h index 5bef63c..1c1b156 100644 --- a/src/ESPAWSImplementations.h +++ b/src/ESPAWSImplementations.h @@ -2,11 +2,26 @@ #define AWSESPIMPLEMENTATIONS_H_ #include "DeviceIndependentInterfaces.h" + +#if !defined ARDUINO_ARCH_SAM && !defined ARDUINO_ARCH_SAMD #include +#else +#include +#endif + +#if defined ARDUINO_ARCH_SAM || defined ARDUINO_ARCH_SAMD +#ifdef SERIALUSB +#define Serial SerialUSB +#endif +#endif /* HttpClient implementation to be used on the Esp Core device. */ class EspHttpClient: public IHttpClient { +#if !defined ARDUINO_ARCH_SAM && !defined ARDUINO_ARCH_SAMD WiFiClientSecure sclient; +#else + WiFiSSLClient sclient; +#endif public: EspHttpClient(); /* Send http request and return the response. */ From c441b940860a20b398868efdb01fb84d6e59c003 Mon Sep 17 00:00:00 2001 From: Burt Silverman Date: Wed, 6 Jun 2018 00:07:43 -0400 Subject: [PATCH 12/19] Mention ARDUINO_ARCH_SAM and ARDUINO_ARCH_SAMD --- README.md | 2 +- keywords.txt | 2 ++ library.json | 4 ++-- library.properties | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e672534..0323895 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ For Spark, after the wiring is finished, you should be able to connect it to you #### ESP8266 and ESP32 -You can use these libraries with the [Arduino ESP8266](https://github.com/esp8266/arduino) or ESP32:. +You can use these libraries with the [Arduino ESP8266](https://github.com/esp8266/arduino) or ESP32: or ARDUINO_ARCH_SAM or ARDUINO_ARCH_SAMD. ``` #include diff --git a/keywords.txt b/keywords.txt index 6d6ba5f..07ddb84 100644 --- a/keywords.txt +++ b/keywords.txt @@ -3,3 +3,5 @@ AWS KEYWORD2 IoT KEYWORD3 ESP8266 KEYWORD4 ESP32 KEYWORD5 +SAM KEYWORD6 +SAMD KEYWORD7 diff --git a/library.json b/library.json index 58e901e..07a11fa 100644 --- a/library.json +++ b/library.json @@ -1,7 +1,7 @@ { "name": "AWS-SDK-ESP by Schm1tz1 modified by Burt-Silverman", - "keywords": "AWS, SDK, ESP8266, ESP32, IoT", - "description": "SDK for accessing AWS IoT services with ESP* devices.", + "keywords": "AWS, SDK, ESP8266, ESP32, IoT, SAM, SAMD", + "description": "SDK for accessing AWS IoT services with many devices.", "repository": { "type": "git", diff --git a/library.properties b/library.properties index 1647363..4a9d37e 100644 --- a/library.properties +++ b/library.properties @@ -2,8 +2,8 @@ name=AWS-SDK-ESP version=0.9.1-beta author=Roman Schmitz , Burt Silverman maintainer=Roman Schmitz -sentence=An SDK for AWS using ESP8266 and/or ESP32 SOCs. -paragraph=This library is based on the code by awslabs, svdgraaf and fuzzyhandle. It enables you to easily use AWS IoT Services from an ESP8266 or ESP32 SOC with Arduino. There are some great tutorials and projects on the web; also check YoutTube and my GitHub-Pages for examples. As I will be using this system quite often, I will try to keep it up-to-date and contribute to the arduino libraries. Feel free to contribute to this code - fork, add your stuff, change things and create pull requests. +sentence=An SDK for AWS using ESP8266, ESP32, SAM, or SAMD SOCs. +paragraph=This library is based on the code by awslabs, svdgraaf and fuzzyhandle. It enables you to easily use AWS IoT Services from an ESP8266 or ESP32 or SAM or SAMD device with Arduino. There are some great tutorials and projects on the web; also check YoutTube and my GitHub-Pages for examples. As I will be using this system quite often, I will try to keep it up-to-date and contribute to the arduino libraries. Feel free to contribute to this code - fork, add your stuff, change things and create pull requests. category=Communication url=https://github.com/Burt-Silverman/aws-sdk-arduino-esp architectures=* From 7add8253999e01f04eec505b52a3ec79abbfc844 Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Wed, 6 Jun 2018 08:41:57 +0200 Subject: [PATCH 13/19] Update library.json --- library.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.json b/library.json index 07a11fa..902698f 100644 --- a/library.json +++ b/library.json @@ -5,7 +5,7 @@ "repository": { "type": "git", - "url": "https://github.com/Burt-Silverman/aws-sdk-arduino-esp" + "url": "https://github.com/Schm1tz1/aws-sdk-arduino-esp8266" }, "frameworks": "arduino", "platforms": "*" From a6beace37e2ec0049383dd279a37aa58234a1cc8 Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Wed, 6 Jun 2018 08:42:21 +0200 Subject: [PATCH 14/19] Update library.properties --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index 4a9d37e..edcbdd5 100644 --- a/library.properties +++ b/library.properties @@ -5,5 +5,5 @@ maintainer=Roman Schmitz sentence=An SDK for AWS using ESP8266, ESP32, SAM, or SAMD SOCs. paragraph=This library is based on the code by awslabs, svdgraaf and fuzzyhandle. It enables you to easily use AWS IoT Services from an ESP8266 or ESP32 or SAM or SAMD device with Arduino. There are some great tutorials and projects on the web; also check YoutTube and my GitHub-Pages for examples. As I will be using this system quite often, I will try to keep it up-to-date and contribute to the arduino libraries. Feel free to contribute to this code - fork, add your stuff, change things and create pull requests. category=Communication -url=https://github.com/Burt-Silverman/aws-sdk-arduino-esp +url=https://github.com/Schm1tz1/aws-sdk-arduino-esp8266 architectures=* From a36a64320bdbd392737143553fcd2cda211b3c12 Mon Sep 17 00:00:00 2001 From: debsahu Date: Sun, 1 Jul 2018 17:31:46 -0400 Subject: [PATCH 15/19] Add get_shadow() --- src/AmazonIOTClient.cpp | 11 +++++++++++ src/AmazonIOTClient.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/AmazonIOTClient.cpp b/src/AmazonIOTClient.cpp index 30ebf8b..e2a861e 100644 --- a/src/AmazonIOTClient.cpp +++ b/src/AmazonIOTClient.cpp @@ -21,3 +21,14 @@ const char* AmazonIOTClient::update_shadow(MinimalString shadow, ActionError& ac const char* response = sendData(request); return response; } + +const char* AmazonIOTClient::get_shadow(ActionError& actionError) { + actionError = NONE_ACTIONERROR; + + this->method = "GET"; + MinimalString shadow = ""; + char* request = createRequest(shadow); + // return request; + const char* response = sendData(request); + return response; +} diff --git a/src/AmazonIOTClient.h b/src/AmazonIOTClient.h index 37facf4..0ee1559 100644 --- a/src/AmazonIOTClient.h +++ b/src/AmazonIOTClient.h @@ -17,6 +17,7 @@ class AmazonIOTClient : public AWSClient4 { AmazonIOTClient(); const char* update_shadow(MinimalString shadow, ActionError& actionError); + const char* get_shadow(ActionError& actionError); }; #endif /* AMAZONIOTCLIENT_H_ */ From 494c6cbd39636b83fcbd097e2c2713fe323f4358 Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Mon, 2 Jul 2018 18:50:50 +0200 Subject: [PATCH 16/19] Update AmazonIOTClient.h --- src/AmazonIOTClient.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AmazonIOTClient.h b/src/AmazonIOTClient.h index 0ee1559..4727c4b 100644 --- a/src/AmazonIOTClient.h +++ b/src/AmazonIOTClient.h @@ -17,7 +17,7 @@ class AmazonIOTClient : public AWSClient4 { AmazonIOTClient(); const char* update_shadow(MinimalString shadow, ActionError& actionError); - const char* get_shadow(ActionError& actionError); + const char* get_shadow(ActionError& actionError); }; #endif /* AMAZONIOTCLIENT_H_ */ From b2a85e3d944936f310398b0684e03210e72bc844 Mon Sep 17 00:00:00 2001 From: per1234 Date: Sat, 14 Jul 2018 19:26:56 -0700 Subject: [PATCH 17/19] Use a single tab field separator in keywords.txt Each field of keywords.txt is separated by a single true tab. When you use multiple tabs it causes the field to be interpreted as empty. On Arduino IDE 1.6.5 and newer an empty KEYWORD_TOKENTYPE causes the default editor.function.style coloration to be used (as with KEYWORD2, KEYWORD3, LITERAL2). On Arduino IDE 1.6.4 and older it causes the keyword to not be recognized for any special coloration. Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords --- keywords.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/keywords.txt b/keywords.txt index 07ddb84..034be9d 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,7 +1,7 @@ -Amazon KEYWORD1 -AWS KEYWORD2 -IoT KEYWORD3 -ESP8266 KEYWORD4 -ESP32 KEYWORD5 -SAM KEYWORD6 -SAMD KEYWORD7 +Amazon KEYWORD1 +AWS KEYWORD2 +IoT KEYWORD3 +ESP8266 KEYWORD4 +ESP32 KEYWORD5 +SAM KEYWORD6 +SAMD KEYWORD7 From f150efcaeff596259be5bb4ddb8e3077fe40624d Mon Sep 17 00:00:00 2001 From: Roman Schmitz Date: Wed, 22 Aug 2018 07:36:31 +0200 Subject: [PATCH 18/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0323895..ea9481b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Version 1 of the Experimental AWS SDK for Arduino +# Experimental AWS SDK for Arduino An experimental SDK for contacting AWS Services on Arduino-compatible devices. Currently it supports Amazon DynamoDB, Amazon Kinesis, Amazon IOT and Amazon SNS. More services coming soon. From 9dabe495862915e0735cd90cf6e792d27666b0d5 Mon Sep 17 00:00:00 2001 From: per1234 Date: Wed, 12 May 2021 19:15:04 -0700 Subject: [PATCH 19/19] Revert library name change Libraries are locked to the `name` value specified by the library.properties metadata file in the release at the time of the Library Manager submission. Any release with a different name is rejected by the Arduino Library Manager indexer. References: - https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ#why-arent-releases-of-my-library-being-picked-up-by-library-manager - https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ#how-can-i-change-my-librarys-name --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index edcbdd5..1c6db42 100644 --- a/library.properties +++ b/library.properties @@ -1,4 +1,4 @@ -name=AWS-SDK-ESP +name=AWS-SDK-ESP8266 version=0.9.1-beta author=Roman Schmitz , Burt Silverman maintainer=Roman Schmitz