diff --git a/examples/GettingStarted/basic/basic.ino b/examples/GettingStarted/basic/basic.ino index 64d22d5..23ce2de 100644 --- a/examples/GettingStarted/basic/basic.ino +++ b/examples/GettingStarted/basic/basic.ino @@ -11,13 +11,8 @@ ArrowheadESP Arrowhead; const char* systemName = "securetemperaturesensor"; // name of the system, must match the common name of the certificate int port = 8080; // doesn't really matter what number we type in, since it won't listen on it anyway -const char* publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAubjry6ja1CZUGtRV/0WX" \ -"C37s+mWgWJPtqJxMzaQPP+geZVlnm9QlDBAM+UW5Kjc1BWUPfCrVK6hAmHJQj7T2" \ -"v76/+uV+E8vkg4bFjmwutUENItaZGivxf8Fy1lEEGs0168w1YEvyvrljtaK6Vu3O" \ -"/Yum/KWHf2sGOEJv5xRTZy0HcfIDxXlXGEK43klrcrMAgp/AT59QosBh5zpyvK2K" \ -"hxeO44pFt+EwYtgFYQ2t0gZWnWzHt1e6Hj5/80SAJvWL8IUHcWNzc3BFXfjn503Q" \ -"kbLsSWnFC2uwi5tMdgiZd1zTSYrmkDfr4AMNZO8RxC0bCaM3MxUl+SnSLiPyO6yU" \ -"PwIDAQAB"; +const char* publicKey = ""; +String ArrowheadProviderIP = "91.161.102.110"; void setup() { // put your setup code here, to run once: @@ -33,10 +28,10 @@ void setup() { Arrowhead.getArrowheadESPFS().getProviderInfo().serviceRegistryPort ); - bool startupSuccess = Arrowhead.begin(); // true of connection to WiFi and loading Certificates is successful + bool startupSuccess = Arrowhead.begin(false); // true of connection to WiFi and loading Certificates is successful if(startupSuccess){ String response = ""; - int statusCode = Arrowhead.serviceRegistryEcho(&response); + int statusCode = Arrowhead.serviceRegistryEcho(false, &response); Serial.print("Status code from server: "); Serial.println(statusCode); Serial.print("Response body from server: "); @@ -44,10 +39,10 @@ void setup() { Serial.println("############################"); Serial.println(); - String serviceRegistryEntry = "{\"endOfValidity\":\"2020-12-05 12:00:00\",\"interfaces\":[\"HTTP-SECURE-SenML\"],\"providerSystem\":{\"address\":\" "+ Arrowhead.getIP() +"\",\"authenticationInfo\":\""+ publicKey +"\",\"port\":"+ port +",\"systemName\":\""+ systemName +"\"},\"secure\":\"CERTIFICATE\",\"serviceDefinition\":\"temperature\",\"serviceUri\":\"/\",\"version\":1}"; + String serviceRegistryEntry = "{\"endOfValidity\":\"2021-12-05 12:00:00\",\"interfaces\":[\"HTTP-INSECURE-SenML\"],\"providerSystem\":{\"address\":\" "+ ArrowheadProviderIP +"\",\"authenticationInfo\":\""+ publicKey +"\",\"port\":"+ port +",\"systemName\":\""+ systemName +"\"},\"secure\":\"NOT_SECURE\",\"serviceDefinition\":\"dhtesp1\",\"serviceUri\":\"/\",\"version\":1}"; response = ""; - statusCode = Arrowhead.serviceRegistryRegister(serviceRegistryEntry.c_str(), &response); + statusCode = Arrowhead.serviceRegistryRegister(false, serviceRegistryEntry.c_str(), &response); Serial.print("Status code from server: "); Serial.println(statusCode); Serial.print("Response body from server: "); @@ -63,4 +58,4 @@ void loop() { // put your main code here, to run repeatedly: yield(); -} +} \ No newline at end of file diff --git a/src/ArrowheadESP.cpp b/src/ArrowheadESP.cpp index 4e3d6c2..cf2cb25 100644 --- a/src/ArrowheadESP.cpp +++ b/src/ArrowheadESP.cpp @@ -56,9 +56,8 @@ bool ArrowheadESP::setupWiFi() { return false; } -bool ArrowheadESP::setupCertificates() { - // Set up the NTPClient. It's constructor needs an UDP client. If somebody has a better solution then declaring it here, let me know. - +bool ArrowheadESP::setupCertificates(bool secureMode) { + // By default 'pool.ntp.org' is used with 60 seconds update interval and // no offset NTPClient timeClient(_ntpUDP); @@ -66,52 +65,53 @@ bool ArrowheadESP::setupCertificates() { while (!timeClient.update()) { timeClient.forceUpdate(); } - // Set the proper time for Certificate validation - getArrowheadHTTPSClient().getWiFiClientSecure().setX509Time(timeClient.getEpochTime()); - // Setting the request timeout - getArrowheadHTTPSClient().getWiFiClientSecure().setTimeout(5000); - // Setting the buffer sizes - getArrowheadHTTPSClient().getWiFiClientSecure().setBufferSizes(512, 512); - - // Disable X509 Certificate verification - if (getArrowheadESPFS().getSSLInfo().insecure) { - getArrowheadHTTPSClient().getWiFiClientSecure().setInsecure(); - debugPrintln("Disabled CA verification"); - } - - if(getArrowheadESPFS().loadClientCertificateFiles()) { - - // Load CA certificate - if (getArrowheadHTTPSClient().getWiFiClientSecure().loadCACert(getArrowheadESPFS().getCA())) { - debugPrintln("CA cert loaded"); - } else { - debugPrintln("CA cert failed"); + if (secureMode) { + // Set the proper time for Certificate validation + getArrowheadHTTPSClient().getWiFiClientSecure().setX509Time(timeClient.getEpochTime()); + // Setting the request timeout + getArrowheadHTTPSClient().getWiFiClientSecure().setTimeout(5000); + // Setting the buffer sizes + getArrowheadHTTPSClient().getWiFiClientSecure().setBufferSizes(512, 512); + + // Disable X509 Certificate verification + if (getArrowheadESPFS().getSSLInfo().insecure) { + getArrowheadHTTPSClient().getWiFiClientSecure().setInsecure(); + debugPrintln("Disabled CA verification"); } - //delay(1000); - // Load Client certificate - if (getArrowheadHTTPSClient().getWiFiClientSecure().loadCertificate(getArrowheadESPFS().getCl())) { - debugPrintln("Client cert loaded"); - } else { - debugPrintln("Client cert failed"); - } - //delay(1000); + if(getArrowheadESPFS().loadClientCertificateFiles()) { + + // Load CA certificate + if (getArrowheadHTTPSClient().getWiFiClientSecure().loadCACert(getArrowheadESPFS().getCA())) { + debugPrintln("CA cert loaded"); + } else { + debugPrintln("CA cert failed"); + } + //delay(1000); + + // Load Client certificate + if (getArrowheadHTTPSClient().getWiFiClientSecure().loadCertificate(getArrowheadESPFS().getCl())) { + debugPrintln("Client cert loaded"); + } else { + debugPrintln("Client cert failed"); + } + //delay(1000); + + // Load Private key + if (getArrowheadHTTPSClient().getWiFiClientSecure().loadPrivateKey(getArrowheadESPFS().getPK())) { + debugPrintln("Private key loaded"); + } else { + debugPrintln("Private key failed"); + } + + // close client certificate files + getArrowheadESPFS().closeClientCertificateFiles(); - // Load Private key - if (getArrowheadHTTPSClient().getWiFiClientSecure().loadPrivateKey(getArrowheadESPFS().getPK())) { - debugPrintln("Private key loaded"); - } else { - debugPrintln("Private key failed"); } - - // close client certificate files - getArrowheadESPFS().closeClientCertificateFiles(); - - } - else { - Serial.println("Client certificate files could not be loaded."); + else { + Serial.println("Client certificate files could not be loaded."); + } } - delay(1000); } @@ -156,6 +156,10 @@ ArrowheadESPFS &ArrowheadESP::getArrowheadESPFS() { return _arrowheadEspFs; } +ArrowheadHTTPClient &ArrowheadESP::getArrowheadHTTPClient() { + return _httpClient; +} + ArrowheadHTTPSClient &ArrowheadESP::getArrowheadHTTPSClient() { return _httpsClient; } @@ -177,50 +181,74 @@ void ArrowheadESP::setServiceRegistryAddress(const char *host, int port) { this->_srPort = port; } -int ArrowheadESP::serviceRegistryEcho() { - return getArrowheadHTTPSClient().get(_srHost, _srPort, "/serviceregistry/echo", NULL, NULL); +int ArrowheadESP::serviceRegistryEcho(bool secureMode) { + if (secureMode) + return getArrowheadHTTPSClient().get(_srHost, _srPort, "/serviceregistry/echo", NULL, NULL); + else + return getArrowheadHTTPClient().get(_srHost, _srPort, "/serviceregistry/echo", NULL, NULL); } -int ArrowheadESP::serviceRegistryEcho(String *response) { - return getArrowheadHTTPSClient().get(_srHost, _srPort, "/serviceregistry/echo", NULL, response); +int ArrowheadESP::serviceRegistryEcho(bool secureMode, String *response) { + if (secureMode) + return getArrowheadHTTPSClient().get(_srHost, _srPort, "/serviceregistry/echo", NULL, response); + else + return getArrowheadHTTPClient().get(_srHost, _srPort, "/serviceregistry/echo", NULL, response); } -int ArrowheadESP::serviceRegistryQuery(const char *body) { - return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/query", body); +int ArrowheadESP::serviceRegistryQuery(bool secureMode, const char *body) { + if (secureMode) + return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/query", body); + else + return getArrowheadHTTPClient().post(_srHost, _srPort, "/serviceregistry/query", body); } -int ArrowheadESP::serviceRegistryQuery(const char *body, String *response) { - return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/query", body, response); +int ArrowheadESP::serviceRegistryQuery(bool secureMode, const char *body, String *response) { + if (secureMode) + return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/query", body, response); + else + return getArrowheadHTTPClient().post(_srHost, _srPort, "/serviceregistry/query", body, response); } -int ArrowheadESP::serviceRegistryRegister(const char *body) { - return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/register", body); +int ArrowheadESP::serviceRegistryRegister(bool secureMode, const char *body) { + if (secureMode) + return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/register", body); + else + return getArrowheadHTTPClient().post(_srHost, _srPort, "/serviceregistry/register", body); } -int ArrowheadESP::serviceRegistryRegister(const char *body, String *response) { - return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/register", body, response); +int ArrowheadESP::serviceRegistryRegister(bool secureMode, const char *body, String *response) { + if (secureMode) + return getArrowheadHTTPSClient().post(_srHost, _srPort, "/serviceregistry/register", body, response); + else + return getArrowheadHTTPClient().post(_srHost, _srPort, "/serviceregistry/register", body, response); } -int ArrowheadESP::serviceRegistryUnregister(const char *systemName, int port, const char *serviceDefinition) { +int ArrowheadESP::serviceRegistryUnregister(bool secureMode, const char *systemName, int port, const char *serviceDefinition) { String query = String("?system_name=") + systemName + "&address=" + WiFi.localIP().toString() + "&port=" + port + "&service_definition=" + serviceDefinition; - return getArrowheadHTTPSClient().del(_srHost, _srPort, "/serviceregistry/unregister", query.c_str()); + if (secureMode) + return getArrowheadHTTPSClient().del(_srHost, _srPort, "/serviceregistry/unregister", query.c_str()); + else + return getArrowheadHTTPClient().del(_srHost, _srPort, "/serviceregistry/unregister", query.c_str()); } -int ArrowheadESP::serviceRegistryUnregister(const char *systemName, int port, const char *serviceDefinition, String *response) { +int ArrowheadESP::serviceRegistryUnregister(bool secureMode, const char *systemName, int port, const char *serviceDefinition, String *response) { String query = String("?system_name=") + systemName + "&address=" + WiFi.localIP().toString() + "&port=" + port + "&service_definition=" + serviceDefinition; - return getArrowheadHTTPSClient().del(_srHost, _srPort, "/serviceregistry/unregister", query.c_str(), response); + if (secureMode) + return getArrowheadHTTPSClient().del(_srHost, _srPort, "/serviceregistry/unregister", query.c_str(), response); + else + return getArrowheadHTTPClient().del(_srHost, _srPort, "/serviceregistry/unregister", query.c_str(), response); } -bool ArrowheadESP::begin() { +bool ArrowheadESP::begin(bool secureMode) { debugPrintln("ArrowheadESP - Begin"); // Cannot proceed without WiFi connection if (!setupWiFi()) { return false; } //delay(1000); - setupCertificates(); + setupCertificates(secureMode); if (MDNS.begin("esp8266")) { Serial.println("MDNS responder started"); diff --git a/src/ArrowheadESP.h b/src/ArrowheadESP.h index ac7bda5..0fe52fa 100644 --- a/src/ArrowheadESP.h +++ b/src/ArrowheadESP.h @@ -24,6 +24,7 @@ // Header Includes #include "ArrowheadESPFS/ArrowheadESPFS.h" +#include "ArrowheadHTTPClient/ArrowheadHTTPClient.h" #include "ArrowheadHTTPSClient/ArrowheadHTTPSClient.h" class ArrowheadESP { @@ -33,6 +34,11 @@ class ArrowheadESP { */ ArrowheadESPFS _arrowheadEspFs; + /** + * ArrowheadHTTPClient instance + */ + ArrowheadHTTPClient _httpClient; + /** * ArrowheadHTTPSClient instance */ @@ -81,7 +87,7 @@ class ArrowheadESP { * * @return */ - bool setupCertificates(); + bool setupCertificates(bool secureMode); /** * Sets up the secure web server with certificates * @@ -101,6 +107,13 @@ class ArrowheadESP { */ ArrowheadESPFS& getArrowheadESPFS(); + /** + * Returns the instance of the ArrowheadHTTPClient + * + * @return + */ + ArrowheadHTTPClient& getArrowheadHTTPClient(); + /** * Returns the instance of the ArrowheadHTTPSClient * @@ -151,21 +164,21 @@ class ArrowheadESP { * Echo * @return */ - int serviceRegistryEcho(); + int serviceRegistryEcho(bool secureMode); /** * Echo * * @param response * @return */ - int serviceRegistryEcho(String* response); + int serviceRegistryEcho(bool secureMode, String* response); /** * Query * * @param body * @return */ - int serviceRegistryQuery(const char *body); + int serviceRegistryQuery(bool secureMode, const char *body); /** * Query * @@ -173,14 +186,14 @@ class ArrowheadESP { * @param response * @return */ - int serviceRegistryQuery(const char *body, String* response); + int serviceRegistryQuery(bool secureMode, const char *body, String* response); /** * Register * * @param body * @return */ - int serviceRegistryRegister(const char *body); + int serviceRegistryRegister(bool secureMode, const char *body); /** * Register * @@ -188,14 +201,14 @@ class ArrowheadESP { * @param response * @return */ - int serviceRegistryRegister(const char *body, String* response); + int serviceRegistryRegister(bool secureMode, const char *body, String* response); /** * Unregister * * @param serviceDefinition * @return */ - int serviceRegistryUnregister(const char *systemName, int port, const char *serviceDefinition); + int serviceRegistryUnregister(bool secureMode, const char *systemName, int port, const char *serviceDefinition); /** * Unregister * @@ -203,14 +216,14 @@ class ArrowheadESP { * @param response * @return */ - int serviceRegistryUnregister(const char *systemName, int port, const char *serviceDefinition, String* response); + int serviceRegistryUnregister(bool secureMode, const char *systemName, int port, const char *serviceDefinition, String* response); /** * Starts the operation of the library * * @return */ - bool begin(); + bool begin(bool secureMode); /** * Keeps all connection alive @@ -220,5 +233,4 @@ class ArrowheadESP { int loop(); }; - -#endif //ARROWHEADESP_ARROWHEADESP_H +#endif //ARROWHEADESP_ARROWHEADESP_H \ No newline at end of file diff --git a/src/ArrowheadHTTPClient/ArrowheadHTTPClient.cpp b/src/ArrowheadHTTPClient/ArrowheadHTTPClient.cpp new file mode 100644 index 0000000..3359dc0 --- /dev/null +++ b/src/ArrowheadHTTPClient/ArrowheadHTTPClient.cpp @@ -0,0 +1,146 @@ +// +// Created by Szvetlin Tanyi on 2020. 04. 09. +// Modified by Sébastien Canet on 2021. 10. 12. +// + +#include "ArrowheadHTTPClient.h" + +// ####################################### +// Constructors +// ####################################### + +ArrowheadHTTPClient::ArrowheadHTTPClient() { + debugPrintln("ArrowheadHTTPClient Default Constructor"); +} + +// ####################################### +// Public functions +// ####################################### + +WiFiClient &ArrowheadHTTPClient::getWiFiClient() { + return _wiFiClient; +} + +int ArrowheadHTTPClient::get(const char *address, int port, const char *path, const char *query) { + return request("GET", address, port, path, query, NULL, NULL); +} + +int ArrowheadHTTPClient::get(const char *address, int port, const char *path, const char *query, String *response) { + return request("GET", address, port, path, query, NULL, response); +} + +int ArrowheadHTTPClient::post(const char *address, int port, const char *path, const char *body) { + return request("POST", address, port, path, NULL, body, NULL); +} + +int ArrowheadHTTPClient::post(const char *address, int port, const char *path, const char *body, String *response) { + return request("POST", address, port, path, NULL, body, response); +} + +int ArrowheadHTTPClient::del(const char *address, int port, const char *path, const char *query) { + return request("DELETE", address, port, path, query, NULL, NULL); +} + +int ArrowheadHTTPClient::del(const char *address, int port, const char *path, const char *query, String *response) { + return request("DELETE", address, port, path, query, NULL, response); +} + +int ArrowheadHTTPClient::request(const char *method, const char *host, int port, const char *path, + const char *query, const char *body, String *response) { + if (!_wiFiClient.connect(host, port)) { + debugPrintln(String("Connection failed: ") + host + ":" + String(port)); + return 0; + } + + debugPrintln(String("Connection successful: ") + host + ":" + String(port)); + + String pathWithQueryParams = path; + if(query) { + pathWithQueryParams.concat(query); + } + + String request = String(method) + " " + pathWithQueryParams + " HTTP/1.1\r\n"; +/* TODO header support + for(int i=0; iconcat(c); + } else { + if (c == '\n' && currentLineIsBlank) { + httpBody = true; + } + + if (c == '\n') { + // your starting a new line + currentLineIsBlank = true; + } else if (c != '\r') { + // you've gotten a character on the current line + currentLineIsBlank = false; + } + } + } + } + return code; +} \ No newline at end of file diff --git a/src/ArrowheadHTTPClient/ArrowheadHTTPClient.h b/src/ArrowheadHTTPClient/ArrowheadHTTPClient.h new file mode 100644 index 0000000..3ac9a92 --- /dev/null +++ b/src/ArrowheadHTTPClient/ArrowheadHTTPClient.h @@ -0,0 +1,47 @@ +// +// Created by Szvetlin Tanyi on 2020. 04. 09. +// Modified by Sébastien Canet on 2021. 10. 12. +// + +#ifndef ARROWHEADESP_ARROWHEADHTTPCLIENT_H +#define ARROWHEADESP_ARROWHEADHTTPCLIENT_H + +// Library includes +#include +#include "../Util/Util.h" + +class ArrowheadHTTPClient { +private: + /** + * SSL capable HTTP client + */ + WiFiClient _wiFiClient; +public: + /** + * Default constructor of the class + */ + ArrowheadHTTPClient(); + + /** + * Returns the instance of the HTTP client + * + * @return + */ + WiFiClient& getWiFiClient(); + + int request(const char* method, const char* host, int port, const char* path, const char* query, const char* body, String* response); + int readResponse(String* response); + + int get(const char* address, int port, const char* path, const char* query); + int get(const char* address, int port, const char* path, const char* query, String* response); + + int post(const char* address, int port, const char* path, const char* body); + int post(const char* address, int port, const char* path, const char* body, String* response); + + int del(const char* address, int port, const char* path, const char* query); + int del(const char* address, int port, const char* path, const char* query, String* response); + + // TODO patch, put +}; + +#endif //ARROWHEADESP_ARROWHEADHTTPCLIENT_H \ No newline at end of file diff --git a/src/ArrowheadHTTPSClient/ArrowheadHTTPSClient.h b/src/ArrowheadHTTPSClient/ArrowheadHTTPSClient.h index 79d5e6d..2445b5c 100644 --- a/src/ArrowheadHTTPSClient/ArrowheadHTTPSClient.h +++ b/src/ArrowheadHTTPSClient/ArrowheadHTTPSClient.h @@ -43,5 +43,4 @@ class ArrowheadHTTPSClient { // TODO patch, put }; - -#endif //ARROWHEADESP_ARROWHEADHTTPSCLIENT_H +#endif //ARROWHEADESP_ARROWHEADHTTPSCLIENT_H \ No newline at end of file