Separate library that holds helper functions for the main OMF code.

Committer:
danielelopez
Date:
Wed May 30 18:04:26 2018 +0000
Revision:
16:3b0bdbfa48ff
Parent:
15:32ada27d82b4
Child:
17:cc05a00e6ee6
Added flag for turning printouts on or off

Who changed what in which revision?

UserRevisionLine numberNew contents of line
danielelopez 14:6ed67a160616 1 //Copyright 2018 OSIsoft, LLC
danielelopez 0:6156b29d3c91 2 //
danielelopez 0:6156b29d3c91 3 //Licensed under the Apache License, Version 2.0 (the "License");
danielelopez 0:6156b29d3c91 4 //you may not use this file except in compliance with the License.
danielelopez 0:6156b29d3c91 5 //You may obtain a copy of the License at
danielelopez 0:6156b29d3c91 6 //
danielelopez 0:6156b29d3c91 7 //<http://www.apache.org/licenses/LICENSE-2.0>
danielelopez 0:6156b29d3c91 8 //
danielelopez 0:6156b29d3c91 9 //Unless required by applicable law or agreed to in writing, software
danielelopez 0:6156b29d3c91 10 //distributed under the License is distributed on an "AS IS" BASIS,
danielelopez 0:6156b29d3c91 11 //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
danielelopez 0:6156b29d3c91 12 //See the License for the specific language governing permissions and
danielelopez 0:6156b29d3c91 13 //limitations under the License.
danielelopez 0:6156b29d3c91 14
danielelopez 0:6156b29d3c91 15 #include "osisoft-omf.h"
danielelopez 0:6156b29d3c91 16 #include "mbed.h"
danielelopez 0:6156b29d3c91 17 #include "https_request.h"
danielelopez 0:6156b29d3c91 18 #include "ntp-client/NTPClient.h"
danielelopez 10:844e209f1d79 19 #include "config.egressSettings.h"
danielelopez 8:e5fe40b77f8f 20 #include "config.SSLCertificates.h"
danielelopez 8:e5fe40b77f8f 21 #include "config.producerToken.h"
danielelopez 15:32ada27d82b4 22 #include "config.customOMFJSONStructures.h"
danielelopez 0:6156b29d3c91 23
danielelopez 0:6156b29d3c91 24 // ---------------------------------------------------------------------------------------------------
danielelopez 0:6156b29d3c91 25
danielelopez 0:6156b29d3c91 26 // The clock is set usign NTP; if that fails, the clock defaults to the below time
danielelopez 0:6156b29d3c91 27 const int DEFAULT_HARD_CODED_UTC_TIME = 1513175347;
danielelopez 0:6156b29d3c91 28
danielelopez 0:6156b29d3c91 29 // ---------------------------------------------------------------------------------------------------
danielelopez 0:6156b29d3c91 30
danielelopez 0:6156b29d3c91 31 // ************************************************************************
danielelopez 0:6156b29d3c91 32 // Helper function: prints out an HTTP response
danielelopez 0:6156b29d3c91 33 // ************************************************************************
danielelopez 0:6156b29d3c91 34
danielelopez 1:1c31b413ba0c 35 void OMFLib_dump_response(HttpResponse* res)
danielelopez 0:6156b29d3c91 36 {
danielelopez 1:1c31b413ba0c 37 printf("\n\r----- HTTPS POST response -----\n\r");
danielelopez 0:6156b29d3c91 38 // Print the status code
danielelopez 1:1c31b413ba0c 39 mbedtls_printf("Status: %d - %s\n\r", res->get_status_code(), res->get_status_message().c_str());
danielelopez 0:6156b29d3c91 40 // Print the headers
danielelopez 1:1c31b413ba0c 41 mbedtls_printf("Response headers:\n\r");
danielelopez 0:6156b29d3c91 42 for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
danielelopez 1:1c31b413ba0c 43 mbedtls_printf("\t%s: %s\n\r", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str());
danielelopez 0:6156b29d3c91 44 }
danielelopez 0:6156b29d3c91 45 // Print the body
danielelopez 0:6156b29d3c91 46 mbedtls_printf("Response body (%d bytes):\n\n%s", res->get_body_length(), res->get_body_as_string().c_str());
danielelopez 0:6156b29d3c91 47 }
danielelopez 0:6156b29d3c91 48
danielelopez 0:6156b29d3c91 49 // ************************************************************************
danielelopez 0:6156b29d3c91 50 // Helper function that casts floats into strings
danielelopez 0:6156b29d3c91 51 // ************************************************************************
danielelopez 0:6156b29d3c91 52
danielelopez 0:6156b29d3c91 53 string OMFLib_float_to_string(float f) {
danielelopez 0:6156b29d3c91 54 char buffer[20];
danielelopez 0:6156b29d3c91 55 int n = sprintf (buffer, "%f", f);
danielelopez 13:61d3de73a844 56 // Return -1 if a parse failure ocurred
danielelopez 13:61d3de73a844 57 if (string(buffer) == "NaN") {
danielelopez 13:61d3de73a844 58 return string("-1");
danielelopez 13:61d3de73a844 59 } else {
danielelopez 13:61d3de73a844 60 return string(buffer);
danielelopez 13:61d3de73a844 61 }
danielelopez 0:6156b29d3c91 62 }
danielelopez 0:6156b29d3c91 63
danielelopez 0:6156b29d3c91 64 // ************************************************************************
danielelopez 0:6156b29d3c91 65 // Helper function that sends an actual web request
danielelopez 0:6156b29d3c91 66 // ************************************************************************
danielelopez 0:6156b29d3c91 67
danielelopez 0:6156b29d3c91 68 void OMFLib_sendMessageToEndpoint(TLSSocket* socket, const char* action, const char* message_type, const char* body) {
danielelopez 1:1c31b413ba0c 69 printf("\n\r----- HTTPS POST request -----\n\r");
danielelopez 0:6156b29d3c91 70
danielelopez 0:6156b29d3c91 71 // Create the new request
danielelopez 0:6156b29d3c91 72 //HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL); // Old: doesn't re-use sockets
danielelopez 0:6156b29d3c91 73 HttpsRequest* post_req = new HttpsRequest(socket, HTTP_POST, TARGET_URL);
danielelopez 0:6156b29d3c91 74
danielelopez 0:6156b29d3c91 75 // Turn on debugging - this hides TLS connection information
danielelopez 0:6156b29d3c91 76 post_req->set_debug(true);
danielelopez 0:6156b29d3c91 77
danielelopez 0:6156b29d3c91 78 // Add headers: content type and authentication
danielelopez 0:6156b29d3c91 79 post_req->set_header("Content-Type", "application/json");
danielelopez 0:6156b29d3c91 80
danielelopez 0:6156b29d3c91 81 // Set OMF headers
danielelopez 0:6156b29d3c91 82 post_req->set_header("producertoken", PRODUCER_TOKEN);
danielelopez 0:6156b29d3c91 83 post_req->set_header("messagetype", message_type);
danielelopez 0:6156b29d3c91 84 post_req->set_header("action", action);
danielelopez 0:6156b29d3c91 85 post_req->set_header("messageformat", "JSON");
danielelopez 0:6156b29d3c91 86 post_req->set_header("omfversion", "1.0");
danielelopez 0:6156b29d3c91 87
danielelopez 0:6156b29d3c91 88 // Send the body
danielelopez 0:6156b29d3c91 89 printf("Now sending request...");
danielelopez 1:1c31b413ba0c 90 printf("\n\rOutgoing message headers:\n\tmessagetype: %s\n\taction: %s", message_type, action);
danielelopez 1:1c31b413ba0c 91 printf("\n\rOutgoing message body:\n\t%s\n\r", body);
danielelopez 0:6156b29d3c91 92 HttpResponse* post_res = post_req->send(body, strlen(body));
danielelopez 0:6156b29d3c91 93
danielelopez 0:6156b29d3c91 94 // Check the response for an error
danielelopez 0:6156b29d3c91 95 if (!post_res) {
danielelopez 1:1c31b413ba0c 96 printf("HttpRequest failed (error code %d)\n\r", post_req->get_error());
danielelopez 1:1c31b413ba0c 97 printf("Socket connection status after error: %d\n\r", socket->connected());
danielelopez 0:6156b29d3c91 98 //return 1;
danielelopez 0:6156b29d3c91 99 } else {
danielelopez 0:6156b29d3c91 100 // Print the response
danielelopez 1:1c31b413ba0c 101 OMFLib_dump_response(post_res);
danielelopez 1:1c31b413ba0c 102 }
danielelopez 1:1c31b413ba0c 103
danielelopez 1:1c31b413ba0c 104 // Free up the request object
danielelopez 1:1c31b413ba0c 105 delete post_req;
danielelopez 1:1c31b413ba0c 106 }
danielelopez 1:1c31b413ba0c 107
danielelopez 1:1c31b413ba0c 108 // ************************************************************************
danielelopez 1:1c31b413ba0c 109 // Helper function that sends an actual web request; does not reuse sockets
danielelopez 1:1c31b413ba0c 110 // ************************************************************************
danielelopez 1:1c31b413ba0c 111
danielelopez 1:1c31b413ba0c 112 void OMFLib_sendMessageToEndpoint_NoSocketReuse(NetworkInterface* network, const char* action, const char* message_type, const char* body) {
danielelopez 12:8fb2bb26528f 113
danielelopez 16:3b0bdbfa48ff 114 if (ENABLE_PRINTOUTS) printf("\n\r----- HTTPS POST request -----\n\r");
danielelopez 1:1c31b413ba0c 115
danielelopez 1:1c31b413ba0c 116 // Create the new request
danielelopez 1:1c31b413ba0c 117 HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL);
danielelopez 1:1c31b413ba0c 118
danielelopez 1:1c31b413ba0c 119 // Turn on debugging - this hides TLS connection information
danielelopez 11:e34e1f9bfaec 120 //post_req->set_debug(true);
danielelopez 1:1c31b413ba0c 121
danielelopez 1:1c31b413ba0c 122 // Add headers: content type
danielelopez 1:1c31b413ba0c 123 post_req->set_header("Content-Type", CONTENT_TYPE);
danielelopez 1:1c31b413ba0c 124
danielelopez 1:1c31b413ba0c 125 // Set OMF headers
danielelopez 1:1c31b413ba0c 126 post_req->set_header("producertoken", PRODUCER_TOKEN);
danielelopez 1:1c31b413ba0c 127 post_req->set_header("messagetype", message_type);
danielelopez 1:1c31b413ba0c 128 post_req->set_header("action", action);
danielelopez 1:1c31b413ba0c 129 post_req->set_header("messageformat", OMF_MESSAGE_FORMAT);
danielelopez 1:1c31b413ba0c 130 post_req->set_header("omfversion", OMF_VERSION);
danielelopez 1:1c31b413ba0c 131
danielelopez 1:1c31b413ba0c 132 // Send the body
danielelopez 16:3b0bdbfa48ff 133 if (ENABLE_PRINTOUTS) printf("Now sending request... ");
danielelopez 1:1c31b413ba0c 134 //printf("\n\rOutgoing message headers:\n\tmessagetype: %s\n\taction: %s", message_type, action);
danielelopez 1:1c31b413ba0c 135 //printf("\n\rOutgoing message body:\n\t%s\n\r", body);
danielelopez 1:1c31b413ba0c 136 HttpResponse* post_res = post_req->send(body, strlen(body));
danielelopez 12:8fb2bb26528f 137
danielelopez 1:1c31b413ba0c 138 // Check the response for an error
danielelopez 1:1c31b413ba0c 139 if (!post_res) {
danielelopez 16:3b0bdbfa48ff 140 if (ENABLE_PRINTOUTS) printf("HttpRequest failed (error code %d)\n\r", post_req->get_error());
danielelopez 1:1c31b413ba0c 141 //return 1;
danielelopez 1:1c31b413ba0c 142 } else {
danielelopez 1:1c31b413ba0c 143 // Print the response
danielelopez 16:3b0bdbfa48ff 144 if (ENABLE_PRINTOUTS) printf("Success!\n\r");
danielelopez 1:1c31b413ba0c 145 //OMFLib_dump_response(post_res);
danielelopez 0:6156b29d3c91 146 }
danielelopez 0:6156b29d3c91 147
danielelopez 0:6156b29d3c91 148 // Free up the request object
danielelopez 0:6156b29d3c91 149 delete post_req;
danielelopez 0:6156b29d3c91 150 }
danielelopez 0:6156b29d3c91 151
danielelopez 0:6156b29d3c91 152 // ************************************************************************
danielelopez 0:6156b29d3c91 153 // Gets the current time in the appropriate OMF format
danielelopez 0:6156b29d3c91 154 // ************************************************************************
danielelopez 0:6156b29d3c91 155
danielelopez 0:6156b29d3c91 156 string OMFLib_getCurrentTimeString() {
danielelopez 0:6156b29d3c91 157 // Declar vars
danielelopez 0:6156b29d3c91 158 char timestampBuffer[80];
danielelopez 0:6156b29d3c91 159 time_t now;
danielelopez 0:6156b29d3c91 160 struct tm ts;
danielelopez 0:6156b29d3c91 161
danielelopez 0:6156b29d3c91 162 // Get the current time
danielelopez 0:6156b29d3c91 163 time(&now);
danielelopez 0:6156b29d3c91 164
danielelopez 0:6156b29d3c91 165 // Cast the current time into the correct format
danielelopez 0:6156b29d3c91 166 ts = *localtime(&now);
danielelopez 0:6156b29d3c91 167 strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%dT%H:%M:%SZ", &ts);
danielelopez 0:6156b29d3c91 168
danielelopez 0:6156b29d3c91 169 // Return the result
danielelopez 0:6156b29d3c91 170 return string(timestampBuffer);
danielelopez 0:6156b29d3c91 171 }
danielelopez 0:6156b29d3c91 172
danielelopez 0:6156b29d3c91 173 // ************************************************************************
danielelopez 9:e2d177cf9135 174 // Sets the clock via NTP via the nwtwork; can point to a local or internet-based server
danielelopez 0:6156b29d3c91 175 // ************************************************************************
danielelopez 0:6156b29d3c91 176
danielelopez 0:6156b29d3c91 177 void OMFLib_syncClockViaNTP(NetworkInterface* network) {
danielelopez 0:6156b29d3c91 178 // Hard-code a start time... see https://www.epochconverter.com/
danielelopez 0:6156b29d3c91 179 set_time(DEFAULT_HARD_CODED_UTC_TIME);
danielelopez 0:6156b29d3c91 180
danielelopez 1:1c31b413ba0c 181 printf("\n\r----- Setting internal clock -----\n\r");
danielelopez 0:6156b29d3c91 182 // See https://github.com/ARMmbed/ntp-client-example/blob/master/main.cpp
danielelopez 0:6156b29d3c91 183
danielelopez 9:e2d177cf9135 184 // Connect the ntp object to the network
danielelopez 0:6156b29d3c91 185 NTPClient ntp(network);
danielelopez 9:e2d177cf9135 186
danielelopez 9:e2d177cf9135 187 // Set the ntp server to either an internet-based server OR to a local server
danielelopez 9:e2d177cf9135 188 ntp.set_server("2.pool.ntp.org", 123);
danielelopez 9:e2d177cf9135 189
danielelopez 9:e2d177cf9135 190 // Get the timestamp via NTP
danielelopez 0:6156b29d3c91 191 time_t timestamp = ntp.get_timestamp();
danielelopez 0:6156b29d3c91 192 if (timestamp > 0) {
danielelopez 0:6156b29d3c91 193 set_time(timestamp);
danielelopez 0:6156b29d3c91 194 printf("Clock set via NTP to UTC %s", ctime(&timestamp));
danielelopez 0:6156b29d3c91 195 } else {
danielelopez 0:6156b29d3c91 196 printf("NTP time sync failed; clock set to %i UTC seconds.", DEFAULT_HARD_CODED_UTC_TIME);
danielelopez 0:6156b29d3c91 197 }
danielelopez 15:32ada27d82b4 198 }
danielelopez 15:32ada27d82b4 199
danielelopez 15:32ada27d82b4 200 // ************************************************************************
danielelopez 15:32ada27d82b4 201 // Sends the dynamic types, static types, assets, and links messages
danielelopez 15:32ada27d82b4 202 // Uses the SEND_ASSETS_AND_LINKS flag found in config.egressSettings and
danielelopez 15:32ada27d82b4 203 // Uses the custom OMF JSON found in config.customOMFJSONStructures.h
danielelopez 15:32ada27d82b4 204 // ************************************************************************
danielelopez 15:32ada27d82b4 205
danielelopez 15:32ada27d82b4 206 void OMFLib_sendInitialOMFMessages(NetworkInterface* __network_interface) {
danielelopez 15:32ada27d82b4 207 // Send the DYNAMIC types message, so that these types can be referenced in all later messages
danielelopez 15:32ada27d82b4 208 printf("\n\r!!!!!!!! Sending DYNAMIC Types message... !!!!!!!!\n\r");
danielelopez 15:32ada27d82b4 209 //OMFLib_sendMessageToEndpoint(socket, "create", "Type", dynamic_types_message_JSON.c_str());
danielelopez 15:32ada27d82b4 210 //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 211 OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 212
danielelopez 15:32ada27d82b4 213 // Send the container message, to instantiate this particular container; we can now directly start sending data to it using its Id
danielelopez 15:32ada27d82b4 214 printf("\n\r!!!!!!!! Sending Containers message... !!!!!!!!\n\r");
danielelopez 15:32ada27d82b4 215 //OMFLib_sendMessageToEndpoint(socket, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 216 //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 217 OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 218
danielelopez 15:32ada27d82b4 219 // Check whether assets and links should be sent!
danielelopez 15:32ada27d82b4 220 if (SEND_ASSETS_AND_LINKS == true)
danielelopez 15:32ada27d82b4 221 {
danielelopez 15:32ada27d82b4 222
danielelopez 15:32ada27d82b4 223 // ************************************************************************
danielelopez 15:32ada27d82b4 224 // Send the STATIC types message, so that these types can be referenced in all later messages
danielelopez 15:32ada27d82b4 225 // ************************************************************************
danielelopez 15:32ada27d82b4 226
danielelopez 15:32ada27d82b4 227 printf("\n\r!!!!!!!! Sending STATIC Types message... !!!!!!!!\n\r");
danielelopez 15:32ada27d82b4 228 //OMFLib_sendMessageToEndpoint(socket, "create", "Type", static_types_message_JSON.c_str());
danielelopez 15:32ada27d82b4 229 //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", STATIC_TYPES_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 230 OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", STATIC_TYPES_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 231
danielelopez 15:32ada27d82b4 232 // ************************************************************************
danielelopez 15:32ada27d82b4 233 // Send the message to create the PI AF asset; it will not appear in PI AF, though, because it has not yet been positioned...
danielelopez 15:32ada27d82b4 234 // ************************************************************************
danielelopez 15:32ada27d82b4 235
danielelopez 15:32ada27d82b4 236 printf("\n\r!!!!!!!! Sending Assets message... !!!!!!!!\n\r");
danielelopez 15:32ada27d82b4 237 //OMFLib_sendMessageToEndpoint(socket, "create", "Data", assets_message_JSON.c_str());
danielelopez 15:32ada27d82b4 238 //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Data", ASSETS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 239 OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Data", ASSETS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 240
danielelopez 15:32ada27d82b4 241 // ************************************************************************
danielelopez 15:32ada27d82b4 242 // Send the message to link the PI AF asset
danielelopez 15:32ada27d82b4 243 // ************************************************************************
danielelopez 15:32ada27d82b4 244
danielelopez 15:32ada27d82b4 245 printf("\n\r!!!!!!!! Sending Links message... !!!!!!!!\n\r");
danielelopez 15:32ada27d82b4 246 //OMFLib_sendMessageToEndpoint(socket, "create", "Data", LINKS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 247 //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Data", LINKS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 248 OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Data", LINKS_MESSAGE_JSON.c_str());
danielelopez 15:32ada27d82b4 249 }
danielelopez 0:6156b29d3c91 250 }