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

Committer:
danielelopez
Date:
Mon Jun 11 14:17:30 2018 +0000
Revision:
17:cc05a00e6ee6
Parent:
16:3b0bdbfa48ff
Child:
18:c6c9cce5d990
Updated library to require two separate OMF headers, one that contains OMF dynamic and static types and asset JSON and another that contains link and container JSON

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