NuMaker connection with AWS IoT thru MQTT/HTTPS

Dependencies:   MQTT_ON_AWS

Committer:
doudoutang
Date:
Tue Dec 01 03:25:48 2020 +0000
Revision:
39:a26be070a2b1
Parent:
36:1bec082ad582
no change

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ccli8 1:5ffad9f24d63 1 /* This example demonstrates connection with AWS IoT through MQTT/HTTPS protocol.
ccli8 1:5ffad9f24d63 2 *
ccli8 1:5ffad9f24d63 3 * AWS IoT: Thing Shadow MQTT Topics
ccli8 1:5ffad9f24d63 4 * http://docs.aws.amazon.com/iot/latest/developerguide/thing-shadow-mqtt.html
ccli8 1:5ffad9f24d63 5 *
ccli8 1:5ffad9f24d63 6 * AWS IoT: Publish to a topic through HTTPS/POST method:
ccli8 1:5ffad9f24d63 7 * http://docs.aws.amazon.com/iot/latest/developerguide/protocols.html
ccli8 1:5ffad9f24d63 8 *
ccli8 1:5ffad9f24d63 9 * AWS IoT: Thing Shadow RESTful API:
ccli8 1:5ffad9f24d63 10 * http://docs.aws.amazon.com/iot/latest/developerguide/thing-shadow-rest-api.html
ccli8 1:5ffad9f24d63 11 */
ccli8 1:5ffad9f24d63 12
ccli8 1:5ffad9f24d63 13 #define AWS_IOT_MQTT_TEST 1
ccli8 1:5ffad9f24d63 14 #define AWS_IOT_HTTPS_TEST 0
ccli8 1:5ffad9f24d63 15
ccli8 1:5ffad9f24d63 16 #include "mbed.h"
ccli8 1:5ffad9f24d63 17
ccli8 17:6f0ff065cd76 18 /* MyTLSSocket = Mbed TLS over TCPSocket */
ccli8 17:6f0ff065cd76 19 #include "MyTLSSocket.h"
ccli8 1:5ffad9f24d63 20
ccli8 1:5ffad9f24d63 21 #if AWS_IOT_MQTT_TEST
ccli8 1:5ffad9f24d63 22 /* MQTT-specific header files */
ccli8 1:5ffad9f24d63 23 #include "MQTTmbed.h"
ccli8 1:5ffad9f24d63 24 #include "MQTTClient.h"
ccli8 1:5ffad9f24d63 25 #endif // End of AWS_IOT_MQTT_TEST
ccli8 1:5ffad9f24d63 26
ccli8 1:5ffad9f24d63 27
ccli8 1:5ffad9f24d63 28 namespace {
ccli8 1:5ffad9f24d63 29
ccli8 1:5ffad9f24d63 30 /* List of trusted root CA certificates
ccli8 1:5ffad9f24d63 31 * currently only GlobalSign, the CA for os.mbed.com
ccli8 1:5ffad9f24d63 32 *
ccli8 1:5ffad9f24d63 33 * To add more than one root, just concatenate them.
ccli8 1:5ffad9f24d63 34 */
ccli8 1:5ffad9f24d63 35 const char SSL_CA_CERT_PEM[] = "-----BEGIN CERTIFICATE-----\n"
doudoutang 39:a26be070a2b1 36 "MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n"
doudoutang 39:a26be070a2b1 37 "ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n"
doudoutang 39:a26be070a2b1 38 "b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n"
doudoutang 39:a26be070a2b1 39 "MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n"
doudoutang 39:a26be070a2b1 40 "b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n"
doudoutang 39:a26be070a2b1 41 "ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n"
doudoutang 39:a26be070a2b1 42 "9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n"
doudoutang 39:a26be070a2b1 43 "IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n"
doudoutang 39:a26be070a2b1 44 "VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n"
doudoutang 39:a26be070a2b1 45 "93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n"
doudoutang 39:a26be070a2b1 46 "jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
doudoutang 39:a26be070a2b1 47 "AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n"
doudoutang 39:a26be070a2b1 48 "A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n"
doudoutang 39:a26be070a2b1 49 "U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n"
doudoutang 39:a26be070a2b1 50 "N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n"
doudoutang 39:a26be070a2b1 51 "o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n"
doudoutang 39:a26be070a2b1 52 "5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n"
doudoutang 39:a26be070a2b1 53 "rqXRfboQnoZsG4q5WTP468SQvvG5\n"
doudoutang 39:a26be070a2b1 54 "-----END CERTIFICATE-----\n";
ccli8 1:5ffad9f24d63 55
ccli8 1:5ffad9f24d63 56 /* User certificate which has been activated and attached with specific thing and policy */
ccli8 1:5ffad9f24d63 57 const char SSL_USER_CERT_PEM[] = "-----BEGIN CERTIFICATE-----\n"
doudoutang 39:a26be070a2b1 58 "MIIDWjCCAkKgAwIBAgIVAP0S4tR63yXVgM2daSOyFdhUMmPMMA0GCSqGSIb3DQEB\n"
doudoutang 39:a26be070a2b1 59 "CwUAME0xSzBJBgNVBAsMQkFtYXpvbiBXZWIgU2VydmljZXMgTz1BbWF6b24uY29t\n"
doudoutang 39:a26be070a2b1 60 "IEluYy4gTD1TZWF0dGxlIFNUPVdhc2hpbmd0b24gQz1VUzAeFw0yMDA5MTQwMzAy\n"
doudoutang 39:a26be070a2b1 61 "MTVaFw00OTEyMzEyMzU5NTlaMB4xHDAaBgNVBAMME0FXUyBJb1QgQ2VydGlmaWNh\n"
doudoutang 39:a26be070a2b1 62 "dGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDhepRd6MQM4QRLLjIe\n"
doudoutang 39:a26be070a2b1 63 "2VPkNW391X+UreNmY5doyFoYsbTCcY3HhY7CLdT4NCQfJQ8/qbx6om9KQQnbeMdI\n"
doudoutang 39:a26be070a2b1 64 "tG0CeRco3jxRM94p+iwrxzxJOOgtEUzm8wOCfNc9S7MBFDUtteboIekBjk5ZaPnS\n"
doudoutang 39:a26be070a2b1 65 "gxsOLFgOdopPO/FxrmE23S5XCt8K77eOZRcGi/+RLyYGIVGQqN87a6qTveRARh9K\n"
doudoutang 39:a26be070a2b1 66 "BHWfIffVZv7/WXHwRSIci35buJHQcTP5kWmT6VOdswYNQzgmi0UxLkSJFAhYzu/J\n"
doudoutang 39:a26be070a2b1 67 "pgrm54Jwf/xKkGwQ4vgeH2EJ+ksBa8Eg5KiLQH9OjZ9BKoeyAPyLQhF642VQmSU3\n"
doudoutang 39:a26be070a2b1 68 "20obAgMBAAGjYDBeMB8GA1UdIwQYMBaAFN50owFGEDexb9nOdsgXxQ+BchtzMB0G\n"
doudoutang 39:a26be070a2b1 69 "A1UdDgQWBBReXbnLWekyRBvkd4YfTePGd7sXIzAMBgNVHRMBAf8EAjAAMA4GA1Ud\n"
doudoutang 39:a26be070a2b1 70 "DwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAf9+gOAOTo22Oo+mpcf6SAADw\n"
doudoutang 39:a26be070a2b1 71 "tN+fInVMgLLW13ViB7dELAYx4YcrPRRrxK6KOQbNeFj62jOon7Zj7GQyFUAG6ePw\n"
doudoutang 39:a26be070a2b1 72 "TUEyuAvYNltYfF2OjsLu7XFrtM8RhmKUOKpP3WJ8AiZvnzknYcdPvAbka8TRK9zC\n"
doudoutang 39:a26be070a2b1 73 "13xouOMkrWD6BY+FPe+xrsCHeJAVpaCRJBLWnkMaR1fyMsL8xGBkFz02BPTO70cN\n"
doudoutang 39:a26be070a2b1 74 "rmVh/dbJz9JifedlcK0ZjfpU3EfiLZ/ydZWqEc2M6VGO0sLOfIahHhqKPq6hbiUu\n"
doudoutang 39:a26be070a2b1 75 "WiwB/ZhYjJI0vQm3/mzTXTEwSwBcRvQusoctZS6Ilb9W9KNttXtQZ5Pd+iWDAw==\n"
doudoutang 39:a26be070a2b1 76 "-----END CERTIFICATE-----\n";
ccli8 1:5ffad9f24d63 77
ccli8 1:5ffad9f24d63 78 /* User private key paired with above */
ccli8 1:5ffad9f24d63 79 const char SSL_USER_PRIV_KEY_PEM[] = "-----BEGIN RSA PRIVATE KEY-----\n"
doudoutang 39:a26be070a2b1 80 "MIIEowIBAAKCAQEA4XqUXejEDOEESy4yHtlT5DVt/dV/lK3jZmOXaMhaGLG0wnGN\n"
doudoutang 39:a26be070a2b1 81 "x4WOwi3U+DQkHyUPP6m8eqJvSkEJ23jHSLRtAnkXKN48UTPeKfosK8c8STjoLRFM\n"
doudoutang 39:a26be070a2b1 82 "5vMDgnzXPUuzARQ1LbXm6CHpAY5OWWj50oMbDixYDnaKTzvxca5hNt0uVwrfCu+3\n"
doudoutang 39:a26be070a2b1 83 "jmUXBov/kS8mBiFRkKjfO2uqk73kQEYfSgR1nyH31Wb+/1lx8EUiHIt+W7iR0HEz\n"
doudoutang 39:a26be070a2b1 84 "+ZFpk+lTnbMGDUM4JotFMS5EiRQIWM7vyaYK5ueCcH/8SpBsEOL4Hh9hCfpLAWvB\n"
doudoutang 39:a26be070a2b1 85 "IOSoi0B/To2fQSqHsgD8i0IReuNlUJklN9tKGwIDAQABAoIBAFvNZ7jwe1nvB6uA\n"
doudoutang 39:a26be070a2b1 86 "bIGo5IImytitY1tqjQp0BAJyiFRDjiAY0avpkd03gd1ohUh080dtWULo/bzSzCui\n"
doudoutang 39:a26be070a2b1 87 "eij85OE74hUOnqpFHvAiXneYj9AULlujDpd9W/F12MCpIIGQ87HfvNrIa7Dperbm\n"
doudoutang 39:a26be070a2b1 88 "iciO/qX/of6JfviRpFUvtX78ANEI5TlHF/hi3ZHQdCVVAezOfsSwRs3jqlIQAz43\n"
doudoutang 39:a26be070a2b1 89 "WRQzkqSE2cfO0Mm3K3D1gTKTPpsPACj665Tzua2QdZgKwFdoiiVla9uUsvtZmeBO\n"
doudoutang 39:a26be070a2b1 90 "BaodrhxZssAtak/hd/TCLVCZq90GMG45AYP6qIvGPQtRKrkMHIbsPXU+MMIWcj9S\n"
doudoutang 39:a26be070a2b1 91 "PJb9CFECgYEA+98lfB/T0fn3Z/KxAMqnzqj7uMEuxq4azmyyv8t6K/nGReSooKX1\n"
doudoutang 39:a26be070a2b1 92 "I7n8LskmKcWZkNTUnZ4zPmz23xHHAGp6h1lbXGDQOHbDXDW+bKGI2ZNnCoCYydzI\n"
doudoutang 39:a26be070a2b1 93 "syJ8jE7OmXgknI1TWG2tt3m3W/JBw2hiE/2HjMIniYkTwNo2an6YobkCgYEA5Syw\n"
doudoutang 39:a26be070a2b1 94 "U11Y+z6fh6qIKziI6fuEPu5rDh0gUvLMg0ZtcIyZwbAI/tqRSADf/7YE6GGHp4l6\n"
doudoutang 39:a26be070a2b1 95 "rSJz2tZCWoXCXFOsBKBAnrV6swwVPBGkfg0hzibEKeZTmxuDPbipgKaAlSfMyIk1\n"
doudoutang 39:a26be070a2b1 96 "NBYF1+/1VTJZSkhftRkjXTdfTTxHWs0N6JnBxHMCgYEAgRy7f2xlTd8AVzXOTGSW\n"
doudoutang 39:a26be070a2b1 97 "Ltbq6qOE0e4P6b9Ixg6NWxuX6t4zHt7T0fOV9XnBaWpUtSyUrROamyaKSoE3bNwo\n"
doudoutang 39:a26be070a2b1 98 "YVeKAMnUEw22SX93VQJdP4NTL8wKBnh6HXHRPK9tMrims+WyUsMuaL4pIyYFViEd\n"
doudoutang 39:a26be070a2b1 99 "Hbg6Ewq378Xn7VUuzdqFbWkCgYA76z5C3aI5Nnthbj3iBwsNGjzOc2m8K/NanK7K\n"
doudoutang 39:a26be070a2b1 100 "F+zfQ3OkB5GiiKT5jXkDk6Se2XktXa2cfOiLq/93SYeyuhG8t+WNWWe2To9ywC4g\n"
doudoutang 39:a26be070a2b1 101 "4vAWxV3+koEDieL7jT+MKnxuAxTwzacCckue1NdxKhPcbyXO5L6xTZv2Rq9lVz2u\n"
doudoutang 39:a26be070a2b1 102 "thzKbwKBgC07iLwQJkcZWo2xNDgO2C2dhWSZaX0VFjA1TZAwbi3+pV0pg9aczgZS\n"
doudoutang 39:a26be070a2b1 103 "8WPCQwB4BBz/4FesMjpy0KoZZsBuvfGDwxTjsvZOm67nqdkM+LIfFt493NNoxxl4\n"
doudoutang 39:a26be070a2b1 104 "kTyDhNIrvXLFMy7UO3q9jUUQ0hWz8EIKKjWI3oApFhB0VtWTB8Kl\n"
doudoutang 39:a26be070a2b1 105 "-----END RSA PRIVATE KEY-----\n";
ccli8 1:5ffad9f24d63 106
ccli8 1:5ffad9f24d63 107 #if AWS_IOT_MQTT_TEST
ccli8 1:5ffad9f24d63 108
doudoutang 39:a26be070a2b1 109 #define AWS_IOT_MQTT_SERVER_NAME "a13s4t1vh7t3tu-ats.iot.ap-northeast-1.amazonaws.com"
doudoutang 39:a26be070a2b1 110 // "a1fljoeglhtf61.iot.us-east-2.amazonaws.com"
doudoutang 39:a26be070a2b1 111
ccli8 1:5ffad9f24d63 112 #define AWS_IOT_MQTT_SERVER_PORT 8883
ccli8 1:5ffad9f24d63 113
doudoutang 39:a26be070a2b1 114 #define AWS_IOT_MQTT_THINGNAME "M487_TYH_TEST"
doudoutang 39:a26be070a2b1 115 #define AWS_IOT_MQTT_CLIENTNAME "TYH_IOT"
ccli8 1:5ffad9f24d63 116
ccli8 1:5ffad9f24d63 117 /* User self-test topic */
ccli8 1:5ffad9f24d63 118 const char USER_MQTT_TOPIC[] = "Nuvoton/Mbed/D001";
ccli8 1:5ffad9f24d63 119 const char *USER_MQTT_TOPIC_FILTERS[] = {
ccli8 1:5ffad9f24d63 120 "Nuvoton/Mbed/+"
ccli8 1:5ffad9f24d63 121 };
ccli8 1:5ffad9f24d63 122 const char USER_MQTT_TOPIC_PUBLISH_MESSAGE[] = "{ \"message\": \"Hello from Nuvoton Mbed device\" }";
ccli8 1:5ffad9f24d63 123
ccli8 1:5ffad9f24d63 124 /* Update thing shadow */
ccli8 1:5ffad9f24d63 125 const char UPDATETHINGSHADOW_MQTT_TOPIC[] = "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/update";
ccli8 1:5ffad9f24d63 126 const char *UPDATETHINGSHADOW_MQTT_TOPIC_FILTERS[] = {
ccli8 1:5ffad9f24d63 127 "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/update/accepted",
ccli8 1:5ffad9f24d63 128 "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/update/rejected"
ccli8 1:5ffad9f24d63 129 };
ccli8 1:5ffad9f24d63 130 const char UPDATETHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE[] = "{ \"state\": { \"reported\": { \"attribute1\": 3, \"attribute2\": \"1\" } } }";
ccli8 1:5ffad9f24d63 131
ccli8 1:5ffad9f24d63 132 /* Get thing shadow */
ccli8 1:5ffad9f24d63 133 const char GETTHINGSHADOW_MQTT_TOPIC[] = "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/get";
ccli8 1:5ffad9f24d63 134 const char *GETTHINGSHADOW_MQTT_TOPIC_FILTERS[] = {
ccli8 1:5ffad9f24d63 135 "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/get/accepted",
ccli8 1:5ffad9f24d63 136 "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/get/rejected"
ccli8 1:5ffad9f24d63 137 };
ccli8 1:5ffad9f24d63 138 const char GETTHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE[] = "";
ccli8 1:5ffad9f24d63 139
ccli8 1:5ffad9f24d63 140 /* Delete thing shadow */
ccli8 1:5ffad9f24d63 141 const char DELETETHINGSHADOW_MQTT_TOPIC[] = "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/delete";
ccli8 1:5ffad9f24d63 142 const char *DELETETHINGSHADOW_MQTT_TOPIC_FILTERS[] = {
ccli8 1:5ffad9f24d63 143 "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/delete/accepted",
ccli8 1:5ffad9f24d63 144 "$aws/things/" AWS_IOT_MQTT_THINGNAME "/shadow/delete/rejected"
ccli8 1:5ffad9f24d63 145 };
ccli8 1:5ffad9f24d63 146 const char DELETETHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE[] = "";
ccli8 1:5ffad9f24d63 147
ccli8 1:5ffad9f24d63 148 /* MQTT user buffer size */
ccli8 1:5ffad9f24d63 149 const int MQTT_USER_BUFFER_SIZE = 600;
ccli8 1:5ffad9f24d63 150
ccli8 1:5ffad9f24d63 151 /* Configure MAX_MQTT_PACKET_SIZE to meet your application.
ccli8 1:5ffad9f24d63 152 * We may meet unknown MQTT error with MAX_MQTT_PACKET_SIZE too small, but
ccli8 1:5ffad9f24d63 153 * MQTT lib doesn't tell enough error message. Try to enlarge it. */
ccli8 1:5ffad9f24d63 154 const int MAX_MQTT_PACKET_SIZE = 1000;
ccli8 1:5ffad9f24d63 155
ccli8 35:36578356ed8a 156 /* Timeout for receiving message with subscribed topic */
ccli8 35:36578356ed8a 157 const int MQTT_RECEIVE_MESSAGE_WITH_SUBSCRIBED_TOPIC_TIMEOUT_MS = 5000;
ccli8 35:36578356ed8a 158
ccli8 1:5ffad9f24d63 159 #endif // End of AWS_IOT_MQTT_TEST
ccli8 1:5ffad9f24d63 160
ccli8 1:5ffad9f24d63 161 #if AWS_IOT_HTTPS_TEST
ccli8 1:5ffad9f24d63 162
ccli8 8:d5ea623ffc1f 163 #define AWS_IOT_HTTPS_SERVER_NAME "a1fljoeglhtf61.iot.us-east-2.amazonaws.com"
ccli8 1:5ffad9f24d63 164 #define AWS_IOT_HTTPS_SERVER_PORT 8443
ccli8 1:5ffad9f24d63 165
ccli8 1:5ffad9f24d63 166 #define AWS_IOT_HTTPS_THINGNAME "Nuvoton-Mbed-D001"
ccli8 1:5ffad9f24d63 167
ccli8 1:5ffad9f24d63 168 /* Publish to user topic through HTTPS/POST
ccli8 1:5ffad9f24d63 169 * HTTP POST https://"endpoint"/topics/"yourTopicHierarchy" */
ccli8 1:5ffad9f24d63 170 const char USER_TOPIC_HTTPS_PATH[] = "/topics/Nuvoton/Mbed/D001?qos=1";
ccli8 1:5ffad9f24d63 171 const char USER_TOPIC_HTTPS_REQUEST_METHOD[] = "POST";
ccli8 1:5ffad9f24d63 172 const char USER_TOPIC_HTTPS_REQUEST_MESSAGE_BODY[] = "{ \"message\": \"Hello from Nuvoton Mbed device\" }";
ccli8 1:5ffad9f24d63 173
ccli8 1:5ffad9f24d63 174 /* Update thing shadow by publishing to UpdateThingShadow topic through HTTPS/POST
ccli8 1:5ffad9f24d63 175 * HTTP POST https://"endpoint"/topics/$aws/things/"thingName"/shadow/update */
ccli8 1:5ffad9f24d63 176 const char UPDATETHINGSHADOW_TOPIC_HTTPS_PATH[] = "/topics/$aws/things/" AWS_IOT_HTTPS_THINGNAME "/shadow/update?qos=1";
ccli8 1:5ffad9f24d63 177 const char UPDATETHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD[] = "POST";
ccli8 1:5ffad9f24d63 178 const char UPDATETHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY[] = "{ \"state\": { \"reported\": { \"attribute1\": 3, \"attribute2\": \"1\" } } }";
ccli8 1:5ffad9f24d63 179
ccli8 1:5ffad9f24d63 180 /* Get thing shadow by publishing to GetThingShadow topic through HTTPS/POST
ccli8 1:5ffad9f24d63 181 * HTTP POST https://"endpoint"/topics/$aws/things/"thingName"/shadow/get */
ccli8 1:5ffad9f24d63 182 const char GETTHINGSHADOW_TOPIC_HTTPS_PATH[] = "/topics/$aws/things/" AWS_IOT_HTTPS_THINGNAME "/shadow/get?qos=1";
ccli8 1:5ffad9f24d63 183 const char GETTHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD[] = "POST";
ccli8 1:5ffad9f24d63 184 const char GETTHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY[] = "";
ccli8 1:5ffad9f24d63 185
ccli8 1:5ffad9f24d63 186 /* Delete thing shadow by publishing to DeleteThingShadow topic through HTTPS/POST
ccli8 1:5ffad9f24d63 187 * HTTP POST https://"endpoint"/topics/$aws/things/"thingName"/shadow/delete */
ccli8 1:5ffad9f24d63 188 const char DELETETHINGSHADOW_TOPIC_HTTPS_PATH[] = "/topics/$aws/things/" AWS_IOT_HTTPS_THINGNAME "/shadow/delete?qos=1";
ccli8 1:5ffad9f24d63 189 const char DELETETHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD[] = "POST";
ccli8 1:5ffad9f24d63 190 const char DELETETHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY[] = "";
ccli8 1:5ffad9f24d63 191
ccli8 1:5ffad9f24d63 192 /* Update thing shadow RESTfully through HTTPS/POST
ccli8 1:5ffad9f24d63 193 * HTTP POST https://endpoint/things/thingName/shadow */
ccli8 1:5ffad9f24d63 194 const char UPDATETHINGSHADOW_THING_HTTPS_PATH[] = "/things/" AWS_IOT_HTTPS_THINGNAME "/shadow";
ccli8 1:5ffad9f24d63 195 const char UPDATETHINGSHADOW_THING_HTTPS_REQUEST_METHOD[] = "POST";
ccli8 1:5ffad9f24d63 196 const char UPDATETHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY[] = "{ \"state\": { \"desired\": { \"attribute1\": 1, \"attribute2\": \"2\" }, \"reported\": { \"attribute1\": 2, \"attribute2\": \"1\" } } }";
ccli8 1:5ffad9f24d63 197
ccli8 1:5ffad9f24d63 198 /* Get thing shadow RESTfully through HTTPS/GET
ccli8 1:5ffad9f24d63 199 * HTTP GET https://"endpoint"/things/"thingName"/shadow */
ccli8 1:5ffad9f24d63 200 const char GETTHINGSHADOW_THING_HTTPS_PATH[] = "/things/" AWS_IOT_HTTPS_THINGNAME "/shadow";
ccli8 1:5ffad9f24d63 201 const char GETTHINGSHADOW_THING_HTTPS_REQUEST_METHOD[] = "GET";
ccli8 1:5ffad9f24d63 202 const char GETTHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY[] = "";
ccli8 1:5ffad9f24d63 203
ccli8 1:5ffad9f24d63 204 /* Delete thing shadow RESTfully through HTTPS/DELETE
ccli8 1:5ffad9f24d63 205 * HTTP DELETE https://endpoint/things/thingName/shadow */
ccli8 1:5ffad9f24d63 206 const char DELETETHINGSHADOW_THING_HTTPS_PATH[] = "/things/" AWS_IOT_HTTPS_THINGNAME "/shadow";
ccli8 1:5ffad9f24d63 207 const char DELETETHINGSHADOW_THING_HTTPS_REQUEST_METHOD[] = "DELETE";
ccli8 1:5ffad9f24d63 208 const char DELETETHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY[] = "";
ccli8 1:5ffad9f24d63 209
ccli8 1:5ffad9f24d63 210 /* HTTPS user buffer size */
ccli8 1:5ffad9f24d63 211 const int HTTPS_USER_BUFFER_SIZE = 600;
ccli8 1:5ffad9f24d63 212
ccli8 1:5ffad9f24d63 213 const char *HTTPS_OK_STR = "200 OK";
ccli8 1:5ffad9f24d63 214
ccli8 1:5ffad9f24d63 215 #endif // End of AWS_IOT_HTTPS_TEST
ccli8 1:5ffad9f24d63 216
ccli8 1:5ffad9f24d63 217 }
ccli8 1:5ffad9f24d63 218
ccli8 1:5ffad9f24d63 219 #if AWS_IOT_MQTT_TEST
ccli8 1:5ffad9f24d63 220
ccli8 1:5ffad9f24d63 221 /**
ccli8 1:5ffad9f24d63 222 * /brief AWS_IoT_MQTT_Test implements the logic with AWS IoT User/Thing Shadow topics through MQTT.
ccli8 1:5ffad9f24d63 223 */
ccli8 1:5ffad9f24d63 224 class AWS_IoT_MQTT_Test {
ccli8 1:5ffad9f24d63 225
ccli8 1:5ffad9f24d63 226 public:
ccli8 1:5ffad9f24d63 227 /**
ccli8 1:5ffad9f24d63 228 * @brief AWS_IoT_MQTT_Test Constructor
ccli8 1:5ffad9f24d63 229 *
ccli8 1:5ffad9f24d63 230 * @param[in] domain Domain name of the MQTT server
ccli8 1:5ffad9f24d63 231 * @param[in] port Port number of the MQTT server
ccli8 1:5ffad9f24d63 232 * @param[in] net_iface Network interface
ccli8 1:5ffad9f24d63 233 */
ccli8 1:5ffad9f24d63 234 AWS_IoT_MQTT_Test(const char * domain, const uint16_t port, NetworkInterface *net_iface) :
ccli8 1:5ffad9f24d63 235 _domain(domain), _port(port) {
ccli8 17:6f0ff065cd76 236 _tlssocket = new MyTLSSocket(net_iface, SSL_CA_CERT_PEM, SSL_USER_CERT_PEM, SSL_USER_PRIV_KEY_PEM);
ccli8 1:5ffad9f24d63 237 /* Blocking mode */
ccli8 1:5ffad9f24d63 238 _tlssocket->set_blocking(true);
ccli8 1:5ffad9f24d63 239 /* Print Mbed TLS handshake log */
ccli8 1:5ffad9f24d63 240 _tlssocket->set_debug(true);
ccli8 1:5ffad9f24d63 241
ccli8 17:6f0ff065cd76 242 _mqtt_client = new MQTT::Client<MyTLSSocket, Countdown, MAX_MQTT_PACKET_SIZE>(*_tlssocket);
ccli8 1:5ffad9f24d63 243 }
ccli8 1:5ffad9f24d63 244
ccli8 1:5ffad9f24d63 245 /**
ccli8 1:5ffad9f24d63 246 * @brief AWS_IoT_MQTT_Test Destructor
ccli8 1:5ffad9f24d63 247 */
ccli8 1:5ffad9f24d63 248 ~AWS_IoT_MQTT_Test() {
ccli8 1:5ffad9f24d63 249 delete _mqtt_client;
ccli8 1:5ffad9f24d63 250 _mqtt_client = NULL;
ccli8 1:5ffad9f24d63 251
ccli8 1:5ffad9f24d63 252 _tlssocket->close();
ccli8 1:5ffad9f24d63 253 delete _tlssocket;
ccli8 1:5ffad9f24d63 254 _tlssocket = NULL;
ccli8 1:5ffad9f24d63 255 }
ccli8 1:5ffad9f24d63 256 /**
ccli8 1:5ffad9f24d63 257 * @brief Start AWS IoT test through MQTT
ccli8 1:5ffad9f24d63 258 */
ccli8 1:5ffad9f24d63 259 void start_test() {
ccli8 1:5ffad9f24d63 260
ccli8 1:5ffad9f24d63 261 int tls_rc;
ccli8 1:5ffad9f24d63 262 int mqtt_rc;
ccli8 1:5ffad9f24d63 263
ccli8 1:5ffad9f24d63 264 do {
ccli8 1:5ffad9f24d63 265 /* Connect to the server */
ccli8 1:5ffad9f24d63 266 /* Initialize TLS-related stuff */
ccli8 1:5ffad9f24d63 267 printf("Connecting with %s:%d\n", _domain, _port);
ccli8 1:5ffad9f24d63 268 tls_rc = _tlssocket->connect(_domain, _port);
ccli8 1:5ffad9f24d63 269 if (tls_rc != NSAPI_ERROR_OK) {
ccli8 3:4c8cccd32e34 270 printf("Connects with %s:%d failed: %d\n", _domain, _port, tls_rc);
ccli8 1:5ffad9f24d63 271 break;
ccli8 1:5ffad9f24d63 272 }
ccli8 1:5ffad9f24d63 273 printf("Connects with %s:%d OK\n", _domain, _port);
ccli8 1:5ffad9f24d63 274
ccli8 1:5ffad9f24d63 275 /* See the link below for AWS IoT support for MQTT:
ccli8 1:5ffad9f24d63 276 * http://docs.aws.amazon.com/iot/latest/developerguide/protocols.html */
ccli8 1:5ffad9f24d63 277
ccli8 1:5ffad9f24d63 278 /* MQTT connect */
ccli8 1:5ffad9f24d63 279 /* The message broker does not support persistent sessions (connections made with
ccli8 1:5ffad9f24d63 280 * the cleanSession flag set to false. */
ccli8 1:5ffad9f24d63 281 MQTTPacket_connectData conn_data = MQTTPacket_connectData_initializer;
ccli8 1:5ffad9f24d63 282 /* AWS IoT message broker implementation is based on MQTT version 3.1.1
ccli8 1:5ffad9f24d63 283 * 3 = 3.1
ccli8 1:5ffad9f24d63 284 * 4 = 3.1.1 */
ccli8 1:5ffad9f24d63 285 conn_data.MQTTVersion = 4;
ccli8 1:5ffad9f24d63 286 /* Version number of this structure. Must be 0 */
ccli8 1:5ffad9f24d63 287 conn_data.struct_version = 0;
ccli8 1:5ffad9f24d63 288 /* The message broker uses the client ID to identify each client. The client ID is passed
ccli8 1:5ffad9f24d63 289 * in from the client to the message broker as part of the MQTT payload. Two clients with
ccli8 1:5ffad9f24d63 290 * the same client ID are not allowed to be connected concurrently to the message broker.
ccli8 1:5ffad9f24d63 291 * When a client connects to the message broker using a client ID that another client is using,
ccli8 1:5ffad9f24d63 292 * a CONNACK message will be sent to both clients and the currently connected client will be
ccli8 1:5ffad9f24d63 293 * disconnected. */
ccli8 1:5ffad9f24d63 294 conn_data.clientID.cstring = AWS_IOT_MQTT_CLIENTNAME;
ccli8 1:5ffad9f24d63 295 /* The message broker does not support persistent sessions (connections made with
ccli8 1:5ffad9f24d63 296 * the cleanSession flag set to false. The AWS IoT message broker assumes all sessions
ccli8 1:5ffad9f24d63 297 * are clean sessions and messages are not stored across sessions. If an MQTT client
ccli8 1:5ffad9f24d63 298 * attempts to connect to the AWS IoT message broker with the cleanSession set to false,
ccli8 1:5ffad9f24d63 299 * the client will be disconnected. */
ccli8 1:5ffad9f24d63 300 conn_data.cleansession = 1;
ccli8 1:5ffad9f24d63 301 //conn_data.username.cstring = "USERNAME";
ccli8 1:5ffad9f24d63 302 //conn_data.password.cstring = "PASSWORD";
ccli8 1:5ffad9f24d63 303
ccli8 1:5ffad9f24d63 304 MQTT::connackData connack_data;
ccli8 1:5ffad9f24d63 305
ccli8 1:5ffad9f24d63 306 /* _tlssocket must connect to the network endpoint before calling this. */
ccli8 1:5ffad9f24d63 307 printf("MQTT connecting");
ccli8 1:5ffad9f24d63 308 if ((mqtt_rc = _mqtt_client->connect(conn_data, connack_data)) != 0) {
ccli8 1:5ffad9f24d63 309 printf("\rMQTT connects failed: %d\n", mqtt_rc);
ccli8 1:5ffad9f24d63 310 break;
ccli8 1:5ffad9f24d63 311 }
ccli8 1:5ffad9f24d63 312 printf("\rMQTT connects OK\n\n");
ccli8 1:5ffad9f24d63 313
ccli8 1:5ffad9f24d63 314 /* Subscribe/publish user topic */
ccli8 1:5ffad9f24d63 315 printf("Subscribing/publishing user topic\n");
ccli8 1:5ffad9f24d63 316 if (! sub_pub_topic(USER_MQTT_TOPIC, USER_MQTT_TOPIC_FILTERS, sizeof (USER_MQTT_TOPIC_FILTERS) / sizeof (USER_MQTT_TOPIC_FILTERS[0]), USER_MQTT_TOPIC_PUBLISH_MESSAGE)) {
ccli8 1:5ffad9f24d63 317 break;
ccli8 1:5ffad9f24d63 318 }
ccli8 1:5ffad9f24d63 319 printf("Subscribes/publishes user topic OK\n\n");
ccli8 1:5ffad9f24d63 320
ccli8 1:5ffad9f24d63 321 /* Subscribe/publish UpdateThingShadow topic */
ccli8 1:5ffad9f24d63 322 printf("Subscribing/publishing UpdateThingShadow topic\n");
ccli8 1:5ffad9f24d63 323 if (! sub_pub_topic(UPDATETHINGSHADOW_MQTT_TOPIC, UPDATETHINGSHADOW_MQTT_TOPIC_FILTERS, sizeof (UPDATETHINGSHADOW_MQTT_TOPIC_FILTERS) / sizeof (UPDATETHINGSHADOW_MQTT_TOPIC_FILTERS[0]), UPDATETHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE)) {
ccli8 1:5ffad9f24d63 324 break;
ccli8 1:5ffad9f24d63 325 }
ccli8 1:5ffad9f24d63 326 printf("Subscribes/publishes UpdateThingShadow topic OK\n\n");
ccli8 1:5ffad9f24d63 327
ccli8 1:5ffad9f24d63 328 /* Subscribe/publish GetThingShadow topic */
ccli8 1:5ffad9f24d63 329 printf("Subscribing/publishing GetThingShadow topic\n");
ccli8 1:5ffad9f24d63 330 if (! sub_pub_topic(GETTHINGSHADOW_MQTT_TOPIC, GETTHINGSHADOW_MQTT_TOPIC_FILTERS, sizeof (GETTHINGSHADOW_MQTT_TOPIC_FILTERS) / sizeof (GETTHINGSHADOW_MQTT_TOPIC_FILTERS[0]), GETTHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE)) {
ccli8 1:5ffad9f24d63 331 break;
ccli8 1:5ffad9f24d63 332 }
ccli8 1:5ffad9f24d63 333 printf("Subscribes/publishes GetThingShadow topic OK\n\n");
ccli8 1:5ffad9f24d63 334
ccli8 1:5ffad9f24d63 335 /* Subscribe/publish DeleteThingShadow topic */
ccli8 1:5ffad9f24d63 336 printf("Subscribing/publishing DeleteThingShadow topic\n");
ccli8 1:5ffad9f24d63 337 if (! sub_pub_topic(DELETETHINGSHADOW_MQTT_TOPIC, DELETETHINGSHADOW_MQTT_TOPIC_FILTERS, sizeof (DELETETHINGSHADOW_MQTT_TOPIC_FILTERS) / sizeof (DELETETHINGSHADOW_MQTT_TOPIC_FILTERS[0]), DELETETHINGSHADOW_MQTT_TOPIC_PUBLISH_MESSAGE)) {
ccli8 1:5ffad9f24d63 338 break;
ccli8 1:5ffad9f24d63 339 }
ccli8 1:5ffad9f24d63 340 printf("Subscribes/publishes DeleteThingShadow topic OK\n\n");
ccli8 1:5ffad9f24d63 341
ccli8 1:5ffad9f24d63 342 } while (0);
ccli8 1:5ffad9f24d63 343
ccli8 1:5ffad9f24d63 344 printf("MQTT disconnecting");
ccli8 1:5ffad9f24d63 345 if ((mqtt_rc = _mqtt_client->disconnect()) != 0) {
ccli8 23:5111e398e651 346 printf("\rMQTT disconnects failed %d\n\n", mqtt_rc);
ccli8 1:5ffad9f24d63 347 }
ccli8 23:5111e398e651 348 printf("\rMQTT disconnects OK\n\n");
ccli8 1:5ffad9f24d63 349
ccli8 1:5ffad9f24d63 350 _tlssocket->close();
ccli8 1:5ffad9f24d63 351 }
ccli8 1:5ffad9f24d63 352
ccli8 1:5ffad9f24d63 353
ccli8 1:5ffad9f24d63 354 protected:
ccli8 1:5ffad9f24d63 355
ccli8 1:5ffad9f24d63 356 /**
ccli8 1:5ffad9f24d63 357 * @brief Subscribe/publish specific topic
ccli8 1:5ffad9f24d63 358 */
ccli8 1:5ffad9f24d63 359 bool sub_pub_topic(const char *topic, const char **topic_filters, size_t topic_filters_size, const char *publish_message_body) {
ccli8 1:5ffad9f24d63 360
ccli8 1:5ffad9f24d63 361 bool ret = false;
ccli8 1:5ffad9f24d63 362 int mqtt_rc;
ccli8 1:5ffad9f24d63 363
ccli8 1:5ffad9f24d63 364 do {
ccli8 1:5ffad9f24d63 365 const char **topic_filter;
ccli8 1:5ffad9f24d63 366 const char **topic_filter_end = topic_filters + topic_filters_size;
ccli8 1:5ffad9f24d63 367
ccli8 1:5ffad9f24d63 368 for (topic_filter = topic_filters; topic_filter != topic_filter_end; topic_filter ++) {
ccli8 1:5ffad9f24d63 369 /* AWS IoT does not support publishing and subscribing with QoS 2.
ccli8 1:5ffad9f24d63 370 * The AWS IoT message broker does not send a PUBACK or SUBACK when QoS 2 is requested. */
ccli8 1:5ffad9f24d63 371 printf("MQTT subscribing to %s", *topic_filter);
ccli8 1:5ffad9f24d63 372 if ((mqtt_rc = _mqtt_client->subscribe(*topic_filter, MQTT::QOS1, message_arrived)) != 0) {
ccli8 1:5ffad9f24d63 373 printf("\rMQTT subscribes to %s failed: %d\n", *topic_filter, mqtt_rc);
ccli8 1:5ffad9f24d63 374 continue;
ccli8 1:5ffad9f24d63 375 }
ccli8 1:5ffad9f24d63 376 printf("\rMQTT subscribes to %s OK\n", *topic_filter);
ccli8 1:5ffad9f24d63 377 }
ccli8 1:5ffad9f24d63 378
ccli8 35:36578356ed8a 379 /* Clear count of received message with subscribed topic */
ccli8 35:36578356ed8a 380 clear_message_arrive_count();
ccli8 35:36578356ed8a 381
ccli8 1:5ffad9f24d63 382 MQTT::Message message;
ccli8 1:5ffad9f24d63 383
ccli8 1:5ffad9f24d63 384 int _bpos;
ccli8 1:5ffad9f24d63 385
ccli8 1:5ffad9f24d63 386 _bpos = snprintf(_buffer, sizeof (_buffer) - 1, publish_message_body);
ccli8 1:5ffad9f24d63 387 if (_bpos < 0 || ((size_t) _bpos) > (sizeof (_buffer) - 1)) {
ccli8 1:5ffad9f24d63 388 printf("snprintf failed: %d\n", _bpos);
ccli8 1:5ffad9f24d63 389 break;
ccli8 1:5ffad9f24d63 390 }
ccli8 1:5ffad9f24d63 391 _buffer[_bpos] = 0;
ccli8 1:5ffad9f24d63 392 /* AWS IoT does not support publishing and subscribing with QoS 2.
ccli8 1:5ffad9f24d63 393 * The AWS IoT message broker does not send a PUBACK or SUBACK when QoS 2 is requested. */
ccli8 1:5ffad9f24d63 394 message.qos = MQTT::QOS1;
ccli8 1:5ffad9f24d63 395 message.retained = false;
ccli8 1:5ffad9f24d63 396 message.dup = false;
ccli8 1:5ffad9f24d63 397 message.payload = _buffer;
ccli8 1:5ffad9f24d63 398 message.payloadlen = strlen(_buffer);
ccli8 1:5ffad9f24d63 399 /* Print publish message */
ccli8 1:5ffad9f24d63 400 printf("Message to publish:\n");
ccli8 1:5ffad9f24d63 401 printf("%s\n", _buffer);
ccli8 1:5ffad9f24d63 402 printf("MQTT publishing message to %s", topic);
ccli8 1:5ffad9f24d63 403 if ((mqtt_rc = _mqtt_client->publish(topic, message)) != 0) {
ccli8 1:5ffad9f24d63 404 printf("\rMQTT publishes message to %s failed: %d\n", topic, mqtt_rc);
ccli8 1:5ffad9f24d63 405 break;
ccli8 1:5ffad9f24d63 406 }
ccli8 1:5ffad9f24d63 407 printf("\rMQTT publishes message to %s OK\n", topic);
ccli8 1:5ffad9f24d63 408
ccli8 1:5ffad9f24d63 409 /* Receive message with subscribed topic */
ccli8 35:36578356ed8a 410 printf("MQTT receives message with subscribed %s...\n", topic);
ccli8 35:36578356ed8a 411 Timer timer;
ccli8 35:36578356ed8a 412 timer.start();
ccli8 1:5ffad9f24d63 413 while (! _message_arrive_count) {
ccli8 35:36578356ed8a 414 if (timer.read_ms() >= MQTT_RECEIVE_MESSAGE_WITH_SUBSCRIBED_TOPIC_TIMEOUT_MS) {
ccli8 35:36578356ed8a 415 printf("MQTT receives message with subscribed %s TIMEOUT\n", topic);
ccli8 35:36578356ed8a 416 break;
ccli8 35:36578356ed8a 417 }
ccli8 35:36578356ed8a 418
ccli8 1:5ffad9f24d63 419 _mqtt_client->yield(100);
ccli8 1:5ffad9f24d63 420 }
ccli8 35:36578356ed8a 421 if (_message_arrive_count) {
ccli8 35:36578356ed8a 422 printf("MQTT receives message with subscribed %s OK\n", topic);
ccli8 35:36578356ed8a 423 }
ccli8 1:5ffad9f24d63 424 printf("\n");
ccli8 1:5ffad9f24d63 425
ccli8 1:5ffad9f24d63 426 /* Unsubscribe
ccli8 1:5ffad9f24d63 427 * We meet second unsubscribe failed. This is caused by MQTT lib bug. */
ccli8 1:5ffad9f24d63 428 for (topic_filter = topic_filters; topic_filter != topic_filter_end; topic_filter ++) {
ccli8 1:5ffad9f24d63 429 printf("MQTT unsubscribing from %s", *topic_filter);
ccli8 1:5ffad9f24d63 430 if ((mqtt_rc = _mqtt_client->unsubscribe(*topic_filter)) != 0) {
ccli8 1:5ffad9f24d63 431 printf("\rMQTT unsubscribes from %s failed: %d\n", *topic_filter, mqtt_rc);
ccli8 1:5ffad9f24d63 432 continue;
ccli8 1:5ffad9f24d63 433 }
ccli8 1:5ffad9f24d63 434 printf("\rMQTT unsubscribes from %s OK\n", *topic_filter);
ccli8 1:5ffad9f24d63 435 }
ccli8 1:5ffad9f24d63 436
ccli8 1:5ffad9f24d63 437 ret = true;
ccli8 1:5ffad9f24d63 438
ccli8 1:5ffad9f24d63 439 } while (0);
ccli8 1:5ffad9f24d63 440
ccli8 1:5ffad9f24d63 441 return ret;
ccli8 1:5ffad9f24d63 442 }
ccli8 1:5ffad9f24d63 443
ccli8 1:5ffad9f24d63 444 protected:
ccli8 17:6f0ff065cd76 445 MyTLSSocket * _tlssocket;
ccli8 17:6f0ff065cd76 446 MQTT::Client<MyTLSSocket, Countdown, MAX_MQTT_PACKET_SIZE> * _mqtt_client;
ccli8 1:5ffad9f24d63 447
ccli8 1:5ffad9f24d63 448 const char *_domain; /**< Domain name of the MQTT server */
ccli8 1:5ffad9f24d63 449 const uint16_t _port; /**< Port number of the MQTT server */
ccli8 1:5ffad9f24d63 450 char _buffer[MQTT_USER_BUFFER_SIZE]; /**< User buffer */
ccli8 1:5ffad9f24d63 451
ccli8 1:5ffad9f24d63 452 private:
ccli8 1:5ffad9f24d63 453 static volatile uint16_t _message_arrive_count;
ccli8 1:5ffad9f24d63 454
ccli8 1:5ffad9f24d63 455 static void message_arrived(MQTT::MessageData& md) {
ccli8 1:5ffad9f24d63 456 MQTT::Message &message = md.message;
ccli8 1:5ffad9f24d63 457 printf("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
ccli8 1:5ffad9f24d63 458 printf("Payload:\n");
ccli8 1:5ffad9f24d63 459 printf("%.*s\n", message.payloadlen, (char*)message.payload);
ccli8 1:5ffad9f24d63 460 ++ _message_arrive_count;
ccli8 1:5ffad9f24d63 461 }
ccli8 1:5ffad9f24d63 462
ccli8 1:5ffad9f24d63 463 static void clear_message_arrive_count() {
ccli8 1:5ffad9f24d63 464 _message_arrive_count = 0;
ccli8 1:5ffad9f24d63 465 }
ccli8 1:5ffad9f24d63 466 };
ccli8 1:5ffad9f24d63 467
ccli8 1:5ffad9f24d63 468 volatile uint16_t AWS_IoT_MQTT_Test::_message_arrive_count = 0;
ccli8 1:5ffad9f24d63 469
ccli8 1:5ffad9f24d63 470 #endif // End of AWS_IOT_MQTT_TEST
ccli8 1:5ffad9f24d63 471
ccli8 1:5ffad9f24d63 472
ccli8 1:5ffad9f24d63 473 #if AWS_IOT_HTTPS_TEST
ccli8 1:5ffad9f24d63 474
ccli8 1:5ffad9f24d63 475 /**
ccli8 1:5ffad9f24d63 476 * /brief AWS_IoT_HTTPS_Test implements the logic with AWS IoT User/Thing Shadow topics (publish-only)
ccli8 1:5ffad9f24d63 477 * and Thing Shadow RESTful API through HTTPS.
ccli8 1:5ffad9f24d63 478 */
ccli8 1:5ffad9f24d63 479 class AWS_IoT_HTTPS_Test {
ccli8 1:5ffad9f24d63 480
ccli8 1:5ffad9f24d63 481 public:
ccli8 1:5ffad9f24d63 482 /**
ccli8 1:5ffad9f24d63 483 * @brief AWS_IoT_HTTPS_Test Constructor
ccli8 1:5ffad9f24d63 484 *
ccli8 1:5ffad9f24d63 485 * @param[in] domain Domain name of the HTTPS server
ccli8 1:5ffad9f24d63 486 * @param[in] port Port number of the HTTPS server
ccli8 1:5ffad9f24d63 487 * @param[in] net_iface Network interface
ccli8 1:5ffad9f24d63 488 */
ccli8 1:5ffad9f24d63 489 AWS_IoT_HTTPS_Test(const char * domain, const uint16_t port, NetworkInterface *net_iface) :
ccli8 1:5ffad9f24d63 490 _domain(domain), _port(port) {
ccli8 1:5ffad9f24d63 491
ccli8 17:6f0ff065cd76 492 _tlssocket = new MyTLSSocket(net_iface, SSL_CA_CERT_PEM, SSL_USER_CERT_PEM, SSL_USER_PRIV_KEY_PEM);
ccli8 1:5ffad9f24d63 493 /* Non-blocking mode */
ccli8 1:5ffad9f24d63 494 _tlssocket->set_blocking(false);
ccli8 1:5ffad9f24d63 495 /* Print Mbed TLS handshake log */
ccli8 1:5ffad9f24d63 496 _tlssocket->set_debug(true);
ccli8 1:5ffad9f24d63 497 }
ccli8 1:5ffad9f24d63 498 /**
ccli8 1:5ffad9f24d63 499 * @brief AWS_IoT_HTTPS_Test Destructor
ccli8 1:5ffad9f24d63 500 */
ccli8 1:5ffad9f24d63 501 ~AWS_IoT_HTTPS_Test() {
ccli8 1:5ffad9f24d63 502 _tlssocket->close();
ccli8 1:5ffad9f24d63 503 delete _tlssocket;
ccli8 1:5ffad9f24d63 504 _tlssocket = NULL;
ccli8 1:5ffad9f24d63 505 }
ccli8 1:5ffad9f24d63 506 /**
ccli8 1:5ffad9f24d63 507 * @brief Start AWS IoT test through HTTPS
ccli8 1:5ffad9f24d63 508 *
ccli8 1:5ffad9f24d63 509 * @param[in] path The path of the file to fetch from the HTTPS server
ccli8 1:5ffad9f24d63 510 */
ccli8 1:5ffad9f24d63 511 void start_test() {
ccli8 1:5ffad9f24d63 512
ccli8 1:5ffad9f24d63 513 int tls_rc;
ccli8 1:5ffad9f24d63 514
ccli8 1:5ffad9f24d63 515 do {
ccli8 1:5ffad9f24d63 516 /* Connect to the server */
ccli8 1:5ffad9f24d63 517 /* Initialize TLS-related stuff */
ccli8 1:5ffad9f24d63 518 printf("Connecting with %s:%d\n", _domain, _port);
ccli8 1:5ffad9f24d63 519 tls_rc = _tlssocket->connect(_domain, _port);
ccli8 1:5ffad9f24d63 520 if (tls_rc != NSAPI_ERROR_OK) {
ccli8 3:4c8cccd32e34 521 printf("Connects with %s:%d failed: %d\n", _domain, _port, tls_rc);
ccli8 1:5ffad9f24d63 522 break;
ccli8 1:5ffad9f24d63 523 }
ccli8 1:5ffad9f24d63 524 printf("Connects with %s:%d OK\n\n", _domain, _port);
ccli8 1:5ffad9f24d63 525
ccli8 1:5ffad9f24d63 526 /* Publish to user topic through HTTPS/POST */
ccli8 1:5ffad9f24d63 527 printf("Publishing to user topic through HTTPS/POST\n");
ccli8 1:5ffad9f24d63 528 if (! run_req_resp(USER_TOPIC_HTTPS_PATH, USER_TOPIC_HTTPS_REQUEST_METHOD, USER_TOPIC_HTTPS_REQUEST_MESSAGE_BODY)) {
ccli8 1:5ffad9f24d63 529 break;
ccli8 1:5ffad9f24d63 530 }
ccli8 1:5ffad9f24d63 531 printf("Publishes to user topic through HTTPS/POST OK\n\n");
ccli8 1:5ffad9f24d63 532
ccli8 1:5ffad9f24d63 533 /* Update thing shadow by publishing to UpdateThingShadow topic through HTTPS/POST */
ccli8 1:5ffad9f24d63 534 printf("Updating thing shadow by publishing to Update Thing Shadow topic through HTTPS/POST\n");
ccli8 1:5ffad9f24d63 535 if (! run_req_resp(UPDATETHINGSHADOW_TOPIC_HTTPS_PATH, UPDATETHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD, UPDATETHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY)) {
ccli8 1:5ffad9f24d63 536 break;
ccli8 1:5ffad9f24d63 537 }
ccli8 1:5ffad9f24d63 538 printf("Update thing shadow by publishing to Update Thing Shadow topic through HTTPS/POST OK\n\n");
ccli8 1:5ffad9f24d63 539
ccli8 1:5ffad9f24d63 540 /* Get thing shadow by publishing to GetThingShadow topic through HTTPS/POST */
ccli8 1:5ffad9f24d63 541 printf("Getting thing shadow by publishing to GetThingShadow topic through HTTPS/POST\n");
ccli8 1:5ffad9f24d63 542 if (! run_req_resp(GETTHINGSHADOW_TOPIC_HTTPS_PATH, GETTHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD, GETTHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY)) {
ccli8 1:5ffad9f24d63 543 break;
ccli8 1:5ffad9f24d63 544 }
ccli8 1:5ffad9f24d63 545 printf("Get thing shadow by publishing to GetThingShadow topic through HTTPS/POST OK\n\n");
ccli8 1:5ffad9f24d63 546
ccli8 1:5ffad9f24d63 547 /* Delete thing shadow by publishing to DeleteThingShadow topic through HTTPS/POST */
ccli8 1:5ffad9f24d63 548 printf("Deleting thing shadow by publishing to DeleteThingShadow topic through HTTPS/POST\n");
ccli8 1:5ffad9f24d63 549 if (! run_req_resp(DELETETHINGSHADOW_TOPIC_HTTPS_PATH, DELETETHINGSHADOW_TOPIC_HTTPS_REQUEST_METHOD, DELETETHINGSHADOW_TOPIC_HTTPS_REQUEST_MESSAGE_BODY)) {
ccli8 1:5ffad9f24d63 550 break;
ccli8 1:5ffad9f24d63 551 }
ccli8 1:5ffad9f24d63 552 printf("Delete thing shadow by publishing to DeleteThingShadow topic through HTTPS/POST OK\n\n");
ccli8 1:5ffad9f24d63 553
ccli8 1:5ffad9f24d63 554 /* Update thing shadow RESTfully through HTTPS/POST */
ccli8 1:5ffad9f24d63 555 printf("Updating thing shadow RESTfully through HTTPS/POST\n");
ccli8 1:5ffad9f24d63 556 if (! run_req_resp(UPDATETHINGSHADOW_THING_HTTPS_PATH, UPDATETHINGSHADOW_THING_HTTPS_REQUEST_METHOD, UPDATETHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY)) {
ccli8 1:5ffad9f24d63 557 break;
ccli8 1:5ffad9f24d63 558 }
ccli8 1:5ffad9f24d63 559 printf("Update thing shadow RESTfully through HTTPS/POST OK\n\n");
ccli8 1:5ffad9f24d63 560
ccli8 1:5ffad9f24d63 561 /* Get thing shadow RESTfully through HTTPS/GET */
ccli8 1:5ffad9f24d63 562 printf("Getting thing shadow RESTfully through HTTPS/GET\n");
ccli8 1:5ffad9f24d63 563 if (! run_req_resp(GETTHINGSHADOW_THING_HTTPS_PATH, GETTHINGSHADOW_THING_HTTPS_REQUEST_METHOD, GETTHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY)) {
ccli8 1:5ffad9f24d63 564 break;
ccli8 1:5ffad9f24d63 565 }
ccli8 1:5ffad9f24d63 566 printf("Get thing shadow RESTfully through HTTPS/GET OK\n\n");
ccli8 1:5ffad9f24d63 567
ccli8 1:5ffad9f24d63 568 /* Delete thing shadow RESTfully through HTTPS/DELETE */
ccli8 1:5ffad9f24d63 569 printf("Deleting thing shadow RESTfully through HTTPS/DELETE\n");
ccli8 1:5ffad9f24d63 570 if (! run_req_resp(DELETETHINGSHADOW_THING_HTTPS_PATH, DELETETHINGSHADOW_THING_HTTPS_REQUEST_METHOD, DELETETHINGSHADOW_THING_HTTPS_REQUEST_MESSAGE_BODY)) {
ccli8 1:5ffad9f24d63 571 break;
ccli8 1:5ffad9f24d63 572 }
ccli8 1:5ffad9f24d63 573 printf("Delete thing shadow RESTfully through HTTPS/DELETE OK\n\n");
ccli8 1:5ffad9f24d63 574
ccli8 1:5ffad9f24d63 575 } while (0);
ccli8 1:5ffad9f24d63 576
ccli8 1:5ffad9f24d63 577 /* Close socket */
ccli8 1:5ffad9f24d63 578 _tlssocket->close();
ccli8 1:5ffad9f24d63 579 }
ccli8 1:5ffad9f24d63 580
ccli8 1:5ffad9f24d63 581 protected:
ccli8 1:5ffad9f24d63 582
ccli8 1:5ffad9f24d63 583 /**
ccli8 1:5ffad9f24d63 584 * @brief Run request/response through HTTPS
ccli8 1:5ffad9f24d63 585 */
ccli8 1:5ffad9f24d63 586 bool run_req_resp(const char *https_path, const char *https_request_method, const char *https_request_message_body) {
ccli8 1:5ffad9f24d63 587
ccli8 1:5ffad9f24d63 588 bool ret = false;
ccli8 1:5ffad9f24d63 589
ccli8 1:5ffad9f24d63 590 do {
ccli8 1:5ffad9f24d63 591 int tls_rc;
ccli8 1:5ffad9f24d63 592 bool _got200 = false;
ccli8 1:5ffad9f24d63 593
ccli8 1:5ffad9f24d63 594 int _bpos;
ccli8 1:5ffad9f24d63 595
ccli8 1:5ffad9f24d63 596 /* Fill the request buffer */
ccli8 1:5ffad9f24d63 597 _bpos = snprintf(_buffer, sizeof(_buffer) - 1,
ccli8 1:5ffad9f24d63 598 "%s %s HTTP/1.1\r\n" "Host: %s\r\n" "Content-Length: %d\r\n" "\r\n" "%s",
ccli8 1:5ffad9f24d63 599 https_request_method, https_path, AWS_IOT_HTTPS_SERVER_NAME, strlen(https_request_message_body), https_request_message_body);
ccli8 1:5ffad9f24d63 600 if (_bpos < 0 || ((size_t) _bpos) > (sizeof (_buffer) - 1)) {
ccli8 1:5ffad9f24d63 601 printf("snprintf failed: %d\n", _bpos);
ccli8 1:5ffad9f24d63 602 break;
ccli8 1:5ffad9f24d63 603 }
ccli8 1:5ffad9f24d63 604 _buffer[_bpos] = 0;
ccli8 1:5ffad9f24d63 605 /* Print request message */
ccli8 1:5ffad9f24d63 606 printf("HTTPS: Request message:\n");
ccli8 1:5ffad9f24d63 607 printf("%s\n", _buffer);
ccli8 1:5ffad9f24d63 608
ccli8 1:5ffad9f24d63 609 int offset = 0;
ccli8 1:5ffad9f24d63 610 do {
ccli8 1:5ffad9f24d63 611 tls_rc = _tlssocket->send((const unsigned char *) _buffer + offset, _bpos - offset);
ccli8 1:5ffad9f24d63 612 if (tls_rc > 0) {
ccli8 1:5ffad9f24d63 613 offset += tls_rc;
ccli8 1:5ffad9f24d63 614 }
ccli8 1:5ffad9f24d63 615 } while (offset < _bpos &&
ccli8 1:5ffad9f24d63 616 (tls_rc > 0 || tls_rc == MBEDTLS_ERR_SSL_WANT_READ || tls_rc == MBEDTLS_ERR_SSL_WANT_WRITE));
ccli8 1:5ffad9f24d63 617 if (tls_rc < 0) {
ccli8 1:5ffad9f24d63 618 print_mbedtls_error("_tlssocket->send", tls_rc);
ccli8 1:5ffad9f24d63 619 break;
ccli8 1:5ffad9f24d63 620 }
ccli8 1:5ffad9f24d63 621
ccli8 1:5ffad9f24d63 622 /* Read data out of the socket */
ccli8 1:5ffad9f24d63 623 offset = 0;
ccli8 1:5ffad9f24d63 624 size_t content_length = 0;
ccli8 1:5ffad9f24d63 625 size_t offset_end = 0;
ccli8 1:5ffad9f24d63 626 char *line_beg = _buffer;
ccli8 1:5ffad9f24d63 627 char *line_end = NULL;
ccli8 1:5ffad9f24d63 628 do {
ccli8 1:5ffad9f24d63 629 tls_rc = _tlssocket->recv((unsigned char *) _buffer + offset, sizeof(_buffer) - offset - 1);
ccli8 1:5ffad9f24d63 630 if (tls_rc > 0) {
ccli8 1:5ffad9f24d63 631 offset += tls_rc;
ccli8 1:5ffad9f24d63 632 }
ccli8 1:5ffad9f24d63 633
ccli8 1:5ffad9f24d63 634 /* Make it null-terminated */
ccli8 1:5ffad9f24d63 635 _buffer[offset] = 0;
ccli8 1:5ffad9f24d63 636
ccli8 1:5ffad9f24d63 637 /* Scan response message
ccli8 1:5ffad9f24d63 638 *
ccli8 1:5ffad9f24d63 639 * 1. A status line which includes the status code and reason message (e.g., HTTP/1.1 200 OK)
ccli8 1:5ffad9f24d63 640 * 2. Response header fields (e.g., Content-Type: text/html)
ccli8 1:5ffad9f24d63 641 * 3. An empty line (\r\n)
ccli8 1:5ffad9f24d63 642 * 4. An optional message body
ccli8 1:5ffad9f24d63 643 */
ccli8 1:5ffad9f24d63 644 if (! offset_end) {
ccli8 1:5ffad9f24d63 645 line_end = strstr(line_beg, "\r\n");
ccli8 1:5ffad9f24d63 646 if (line_end) {
ccli8 1:5ffad9f24d63 647 /* Scan status line */
ccli8 1:5ffad9f24d63 648 if (! _got200) {
ccli8 1:5ffad9f24d63 649 _got200 = strstr(line_beg, HTTPS_OK_STR) != NULL;
ccli8 1:5ffad9f24d63 650 }
ccli8 1:5ffad9f24d63 651
ccli8 1:5ffad9f24d63 652 /* Scan response header fields for Content-Length
ccli8 1:5ffad9f24d63 653 *
ccli8 1:5ffad9f24d63 654 * NOTE: Assume chunked transfer (Transfer-Encoding: chunked) is not used
ccli8 1:5ffad9f24d63 655 * NOTE: Assume response field name are in lower case
ccli8 1:5ffad9f24d63 656 */
ccli8 1:5ffad9f24d63 657 if (content_length == 0) {
ccli8 1:5ffad9f24d63 658 sscanf(line_beg, "content-length:%d", &content_length);
ccli8 1:5ffad9f24d63 659 }
ccli8 1:5ffad9f24d63 660
ccli8 1:5ffad9f24d63 661 /* An empty line indicates end of response header fields */
ccli8 1:5ffad9f24d63 662 if (line_beg == line_end) {
ccli8 1:5ffad9f24d63 663 offset_end = line_end - _buffer + 2 + content_length;
ccli8 1:5ffad9f24d63 664 }
ccli8 1:5ffad9f24d63 665
ccli8 1:5ffad9f24d63 666 /* Go to next line */
ccli8 1:5ffad9f24d63 667 line_beg = line_end + 2;
ccli8 1:5ffad9f24d63 668 line_end = NULL;
ccli8 1:5ffad9f24d63 669 }
ccli8 1:5ffad9f24d63 670 }
ccli8 1:5ffad9f24d63 671 } while ((offset_end == 0 || offset < offset_end) &&
ccli8 1:5ffad9f24d63 672 (tls_rc > 0 || tls_rc == MBEDTLS_ERR_SSL_WANT_READ || tls_rc == MBEDTLS_ERR_SSL_WANT_WRITE));
ccli8 1:5ffad9f24d63 673 if (tls_rc < 0 &&
ccli8 1:5ffad9f24d63 674 tls_rc != MBEDTLS_ERR_SSL_WANT_READ &&
ccli8 1:5ffad9f24d63 675 tls_rc != MBEDTLS_ERR_SSL_WANT_WRITE) {
ccli8 1:5ffad9f24d63 676 print_mbedtls_error("_tlssocket->read", tls_rc);
ccli8 1:5ffad9f24d63 677 break;
ccli8 1:5ffad9f24d63 678 }
ccli8 1:5ffad9f24d63 679 _bpos = offset;
ccli8 1:5ffad9f24d63 680
ccli8 1:5ffad9f24d63 681 _buffer[_bpos] = 0;
ccli8 1:5ffad9f24d63 682
ccli8 1:5ffad9f24d63 683 /* Print status messages */
ccli8 1:5ffad9f24d63 684 printf("HTTPS: Received %d chars from server\n", _bpos);
ccli8 1:5ffad9f24d63 685 printf("HTTPS: Received 200 OK status ... %s\n", _got200 ? "[OK]" : "[FAIL]");
ccli8 1:5ffad9f24d63 686 printf("HTTPS: Received message:\n");
ccli8 1:5ffad9f24d63 687 printf("%s\n", _buffer);
ccli8 1:5ffad9f24d63 688
ccli8 1:5ffad9f24d63 689 ret = true;
ccli8 1:5ffad9f24d63 690
ccli8 1:5ffad9f24d63 691 } while (0);
ccli8 1:5ffad9f24d63 692
ccli8 1:5ffad9f24d63 693 return ret;
ccli8 1:5ffad9f24d63 694 }
ccli8 1:5ffad9f24d63 695
ccli8 1:5ffad9f24d63 696 protected:
ccli8 17:6f0ff065cd76 697 MyTLSSocket * _tlssocket;
ccli8 1:5ffad9f24d63 698
ccli8 1:5ffad9f24d63 699 const char *_domain; /**< Domain name of the HTTPS server */
ccli8 1:5ffad9f24d63 700 const uint16_t _port; /**< Port number of the HTTPS server */
ccli8 1:5ffad9f24d63 701 char _buffer[HTTPS_USER_BUFFER_SIZE]; /**< User buffer */
ccli8 1:5ffad9f24d63 702 };
ccli8 1:5ffad9f24d63 703
ccli8 1:5ffad9f24d63 704 #endif // End of AWS_IOT_HTTPS_TEST
ccli8 1:5ffad9f24d63 705
ccli8 1:5ffad9f24d63 706 int main() {
ccli8 1:5ffad9f24d63 707
ccli8 1:5ffad9f24d63 708 /* The default 9600 bps is too slow to print full TLS debug info and could
ccli8 1:5ffad9f24d63 709 * cause the other party to time out. */
ccli8 1:5ffad9f24d63 710
ccli8 1:5ffad9f24d63 711 printf("\nStarting AWS IoT test\n");
ccli8 1:5ffad9f24d63 712
ccli8 1:5ffad9f24d63 713 #if defined(MBED_MAJOR_VERSION)
ccli8 1:5ffad9f24d63 714 printf("Using Mbed OS %d.%d.%d\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
ccli8 1:5ffad9f24d63 715 #else
ccli8 1:5ffad9f24d63 716 printf("Using Mbed OS from master.\n");
ccli8 1:5ffad9f24d63 717 #endif
ccli8 1:5ffad9f24d63 718
ccli8 12:97762a6f55e9 719 NetworkInterface *net = NetworkInterface::get_default_instance();
ccli8 12:97762a6f55e9 720 if (NULL == net) {
ccli8 1:5ffad9f24d63 721 printf("Connecting to the network failed. See serial output.\n");
ccli8 1:5ffad9f24d63 722 return 1;
ccli8 1:5ffad9f24d63 723 }
ccli8 12:97762a6f55e9 724 nsapi_error_t status = net->connect();
ccli8 12:97762a6f55e9 725 if (status != NSAPI_ERROR_OK) {
ccli8 12:97762a6f55e9 726 printf("Connecting to the network failed %d!\n", status);
ccli8 12:97762a6f55e9 727 return -1;
ccli8 12:97762a6f55e9 728 }
ccli8 12:97762a6f55e9 729 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
ccli8 1:5ffad9f24d63 730
ccli8 1:5ffad9f24d63 731 #if AWS_IOT_MQTT_TEST
ccli8 12:97762a6f55e9 732 AWS_IoT_MQTT_Test *mqtt_test = new AWS_IoT_MQTT_Test(AWS_IOT_MQTT_SERVER_NAME, AWS_IOT_MQTT_SERVER_PORT, net);
ccli8 1:5ffad9f24d63 733 mqtt_test->start_test();
ccli8 1:5ffad9f24d63 734 delete mqtt_test;
ccli8 1:5ffad9f24d63 735 #endif // End of AWS_IOT_MQTT_TEST
ccli8 1:5ffad9f24d63 736
ccli8 1:5ffad9f24d63 737 #if AWS_IOT_HTTPS_TEST
ccli8 12:97762a6f55e9 738 AWS_IoT_HTTPS_Test *https_test = new AWS_IoT_HTTPS_Test(AWS_IOT_HTTPS_SERVER_NAME, AWS_IOT_HTTPS_SERVER_PORT, net);
ccli8 1:5ffad9f24d63 739 https_test->start_test();
ccli8 1:5ffad9f24d63 740 delete https_test;
ccli8 1:5ffad9f24d63 741 #endif // End of AWS_IOT_HTTPS_TEST
ccli8 36:1bec082ad582 742
ccli8 36:1bec082ad582 743 /* Some cellular modems e.g.: QUECTEL EC2X need graceful exit; otherwise, they will break in next reboot. */
ccli8 36:1bec082ad582 744 status = net->disconnect();
ccli8 36:1bec082ad582 745 if (status != NSAPI_ERROR_OK) {
ccli8 36:1bec082ad582 746 printf("\n\nDisconnect from network interface failed %d\n", status);
ccli8 36:1bec082ad582 747 }
ccli8 1:5ffad9f24d63 748 }