Pelion Device Ready example for Advantech WISE-1570 (MTB_ADV_WISE_1570)

Committer:
Juho Eskeli
Date:
Fri Jan 25 21:13:29 2019 +0200
Revision:
1:75f7384f9a0b
Parent:
0:2b6d1f2f42fa
Documentation updated

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Juho Eskeli 0:2b6d1f2f42fa 1 // ----------------------------------------------------------------------------
Juho Eskeli 0:2b6d1f2f42fa 2 // Copyright 2016-2018 ARM Ltd.
Juho Eskeli 0:2b6d1f2f42fa 3 //
Juho Eskeli 0:2b6d1f2f42fa 4 // SPDX-License-Identifier: Apache-2.0
Juho Eskeli 0:2b6d1f2f42fa 5 //
Juho Eskeli 0:2b6d1f2f42fa 6 // Licensed under the Apache License, Version 2.0 (the "License");
Juho Eskeli 0:2b6d1f2f42fa 7 // you may not use this file except in compliance with the License.
Juho Eskeli 0:2b6d1f2f42fa 8 // You may obtain a copy of the License at
Juho Eskeli 0:2b6d1f2f42fa 9 //
Juho Eskeli 0:2b6d1f2f42fa 10 // http://www.apache.org/licenses/LICENSE-2.0
Juho Eskeli 0:2b6d1f2f42fa 11 //
Juho Eskeli 0:2b6d1f2f42fa 12 // Unless required by applicable law or agreed to in writing, software
Juho Eskeli 0:2b6d1f2f42fa 13 // distributed under the License is distributed on an "AS IS" BASIS,
Juho Eskeli 0:2b6d1f2f42fa 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Juho Eskeli 0:2b6d1f2f42fa 15 // See the License for the specific language governing permissions and
Juho Eskeli 0:2b6d1f2f42fa 16 // limitations under the License.
Juho Eskeli 0:2b6d1f2f42fa 17 // ----------------------------------------------------------------------------
Juho Eskeli 0:2b6d1f2f42fa 18 #ifndef MBED_TEST_MODE
Juho Eskeli 0:2b6d1f2f42fa 19
Juho Eskeli 0:2b6d1f2f42fa 20 #include "mbed.h"
Juho Eskeli 0:2b6d1f2f42fa 21 #include "simple-mbed-cloud-client.h"
Juho Eskeli 0:2b6d1f2f42fa 22 #include "LittleFileSystem.h"
Juho Eskeli 0:2b6d1f2f42fa 23 #include "mbed_shared_queues.h"
Juho Eskeli 0:2b6d1f2f42fa 24
Juho Eskeli 0:2b6d1f2f42fa 25 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
Juho Eskeli 0:2b6d1f2f42fa 26 // This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed
Juho Eskeli 0:2b6d1f2f42fa 27 EventQueue eventQueue;
Juho Eskeli 0:2b6d1f2f42fa 28
Juho Eskeli 0:2b6d1f2f42fa 29 // Default block device
Juho Eskeli 0:2b6d1f2f42fa 30 BlockDevice *bd = BlockDevice::get_default_instance();
Juho Eskeli 0:2b6d1f2f42fa 31 LittleFileSystem fs("fs");
Juho Eskeli 0:2b6d1f2f42fa 32 StorageHelper sh(bd, &fs);
Juho Eskeli 0:2b6d1f2f42fa 33
Juho Eskeli 0:2b6d1f2f42fa 34 // Default network interface object
Juho Eskeli 0:2b6d1f2f42fa 35 NetworkInterface *net = NetworkInterface::get_default_instance();
Juho Eskeli 0:2b6d1f2f42fa 36
Juho Eskeli 0:2b6d1f2f42fa 37 // Declaring pointers for access to Pelion Device Management Client resources outside of main()
Juho Eskeli 0:2b6d1f2f42fa 38 MbedCloudClientResource *button_res;
Juho Eskeli 0:2b6d1f2f42fa 39 MbedCloudClientResource *pattern_res;
Juho Eskeli 0:2b6d1f2f42fa 40
Juho Eskeli 0:2b6d1f2f42fa 41 // SimpleMbedCloudClient handles registering over LwM2M to Pelion Device Management
Juho Eskeli 0:2b6d1f2f42fa 42 SimpleMbedCloudClient *client;
Juho Eskeli 0:2b6d1f2f42fa 43
Juho Eskeli 0:2b6d1f2f42fa 44 // shared EventQueue for scheduling client re-registration
Juho Eskeli 0:2b6d1f2f42fa 45 events::EventQueue *_shared_queue = mbed::mbed_event_queue();
Juho Eskeli 0:2b6d1f2f42fa 46
Juho Eskeli 0:2b6d1f2f42fa 47 // This function gets triggered by the timer. It's easy to replace it by an InterruptIn and fall() mode on a real button
Juho Eskeli 0:2b6d1f2f42fa 48 void fake_button_press() {
Juho Eskeli 0:2b6d1f2f42fa 49 int v = button_res->get_value_int() + 1;
Juho Eskeli 0:2b6d1f2f42fa 50
Juho Eskeli 0:2b6d1f2f42fa 51 button_res->set_value(v);
Juho Eskeli 0:2b6d1f2f42fa 52
Juho Eskeli 0:2b6d1f2f42fa 53 printf("Simulated button clicked %d times\n", v);
Juho Eskeli 0:2b6d1f2f42fa 54 }
Juho Eskeli 0:2b6d1f2f42fa 55
Juho Eskeli 0:2b6d1f2f42fa 56 /**
Juho Eskeli 0:2b6d1f2f42fa 57 * PUT handler
Juho Eskeli 0:2b6d1f2f42fa 58 * @param resource The resource that triggered the callback
Juho Eskeli 0:2b6d1f2f42fa 59 * @param newValue Updated value for the resource
Juho Eskeli 0:2b6d1f2f42fa 60 */
Juho Eskeli 0:2b6d1f2f42fa 61 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) {
Juho Eskeli 0:2b6d1f2f42fa 62 printf("PUT received, new value: %s\n", newValue.c_str());
Juho Eskeli 0:2b6d1f2f42fa 63 }
Juho Eskeli 0:2b6d1f2f42fa 64
Juho Eskeli 0:2b6d1f2f42fa 65 /**
Juho Eskeli 0:2b6d1f2f42fa 66 * POST handler
Juho Eskeli 0:2b6d1f2f42fa 67 * @param resource The resource that triggered the callback
Juho Eskeli 0:2b6d1f2f42fa 68 * @param buffer If a body was passed to the POST function, this contains the data.
Juho Eskeli 0:2b6d1f2f42fa 69 * Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
Juho Eskeli 0:2b6d1f2f42fa 70 * @param size Size of the body
Juho Eskeli 0:2b6d1f2f42fa 71 */
Juho Eskeli 0:2b6d1f2f42fa 72 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
Juho Eskeli 0:2b6d1f2f42fa 73 printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
Juho Eskeli 0:2b6d1f2f42fa 74
Juho Eskeli 0:2b6d1f2f42fa 75 static DigitalOut augmentedLed(LED1); // LED that is used for blinking the pattern
Juho Eskeli 0:2b6d1f2f42fa 76
Juho Eskeli 0:2b6d1f2f42fa 77 // Parse the pattern string, and toggle the LED in that pattern
Juho Eskeli 0:2b6d1f2f42fa 78 string s = std::string(pattern_res->get_value().c_str());
Juho Eskeli 0:2b6d1f2f42fa 79 size_t i = 0;
Juho Eskeli 0:2b6d1f2f42fa 80 size_t pos = s.find(':');
Juho Eskeli 0:2b6d1f2f42fa 81 while (pos != string::npos) {
Juho Eskeli 0:2b6d1f2f42fa 82 wait_ms(atoi(s.substr(i, pos - i).c_str()));
Juho Eskeli 0:2b6d1f2f42fa 83 augmentedLed = !augmentedLed;
Juho Eskeli 0:2b6d1f2f42fa 84
Juho Eskeli 0:2b6d1f2f42fa 85 i = ++pos;
Juho Eskeli 0:2b6d1f2f42fa 86 pos = s.find(':', pos);
Juho Eskeli 0:2b6d1f2f42fa 87
Juho Eskeli 0:2b6d1f2f42fa 88 if (pos == string::npos) {
Juho Eskeli 0:2b6d1f2f42fa 89 wait_ms(atoi(s.substr(i, s.length()).c_str()));
Juho Eskeli 0:2b6d1f2f42fa 90 augmentedLed = !augmentedLed;
Juho Eskeli 0:2b6d1f2f42fa 91 }
Juho Eskeli 0:2b6d1f2f42fa 92 }
Juho Eskeli 0:2b6d1f2f42fa 93 }
Juho Eskeli 0:2b6d1f2f42fa 94
Juho Eskeli 0:2b6d1f2f42fa 95 /**
Juho Eskeli 0:2b6d1f2f42fa 96 * Notification callback handler
Juho Eskeli 0:2b6d1f2f42fa 97 * @param resource The resource that triggered the callback
Juho Eskeli 0:2b6d1f2f42fa 98 * @param status The delivery status of the notification
Juho Eskeli 0:2b6d1f2f42fa 99 */
Juho Eskeli 0:2b6d1f2f42fa 100 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
Juho Eskeli 0:2b6d1f2f42fa 101 printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
Juho Eskeli 0:2b6d1f2f42fa 102 }
Juho Eskeli 0:2b6d1f2f42fa 103
Juho Eskeli 0:2b6d1f2f42fa 104 #if defined(MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP) || defined(MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP_QUEUE)
Juho Eskeli 0:2b6d1f2f42fa 105 static bool register_update_called = false;
Juho Eskeli 0:2b6d1f2f42fa 106 /**
Juho Eskeli 0:2b6d1f2f42fa 107 * shared EventQueue callback handler for client re-registration
Juho Eskeli 0:2b6d1f2f42fa 108 */
Juho Eskeli 0:2b6d1f2f42fa 109 static void reregister_callback(void)
Juho Eskeli 0:2b6d1f2f42fa 110 {
Juho Eskeli 0:2b6d1f2f42fa 111 client->register_update();
Juho Eskeli 0:2b6d1f2f42fa 112 }
Juho Eskeli 0:2b6d1f2f42fa 113 #endif
Juho Eskeli 0:2b6d1f2f42fa 114
Juho Eskeli 0:2b6d1f2f42fa 115 /**
Juho Eskeli 0:2b6d1f2f42fa 116 * Registration callback handler
Juho Eskeli 0:2b6d1f2f42fa 117 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
Juho Eskeli 0:2b6d1f2f42fa 118 */
Juho Eskeli 0:2b6d1f2f42fa 119 void registered(const ConnectorClientEndpointInfo *endpoint) {
Juho Eskeli 0:2b6d1f2f42fa 120 printf("Connected to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
Juho Eskeli 0:2b6d1f2f42fa 121
Juho Eskeli 0:2b6d1f2f42fa 122 /* When using UDP, start re-registration 30s after initial registration. Allows update campaign to start. */
Juho Eskeli 0:2b6d1f2f42fa 123 #if defined(MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP) || defined(MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP_QUEUE)
Juho Eskeli 0:2b6d1f2f42fa 124 if(!register_update_called) {
Juho Eskeli 0:2b6d1f2f42fa 125 register_update_called = true;
Juho Eskeli 0:2b6d1f2f42fa 126 _shared_queue->call_in(30000, reregister_callback);
Juho Eskeli 0:2b6d1f2f42fa 127 }
Juho Eskeli 0:2b6d1f2f42fa 128 #endif
Juho Eskeli 0:2b6d1f2f42fa 129 }
Juho Eskeli 0:2b6d1f2f42fa 130
Juho Eskeli 0:2b6d1f2f42fa 131 int main(void) {
Juho Eskeli 0:2b6d1f2f42fa 132 // Call StorageHelper to initialize FS for us
Juho Eskeli 0:2b6d1f2f42fa 133 sh.init();
Juho Eskeli 0:2b6d1f2f42fa 134
Juho Eskeli 0:2b6d1f2f42fa 135 // Initialize client only after making sure FS is ready
Juho Eskeli 0:2b6d1f2f42fa 136 client = new SimpleMbedCloudClient(net, bd, &fs);
Juho Eskeli 0:2b6d1f2f42fa 137
Juho Eskeli 0:2b6d1f2f42fa 138 printf("Starting Simple Pelion Device Management Client example\n");
Juho Eskeli 0:2b6d1f2f42fa 139 //Uncomment the following line to demonstrate update
Juho Eskeli 0:2b6d1f2f42fa 140 //printf("FW updated OTA\n");
Juho Eskeli 0:2b6d1f2f42fa 141 printf("Connecting to the network...\n");
Juho Eskeli 0:2b6d1f2f42fa 142
Juho Eskeli 0:2b6d1f2f42fa 143 // Connect to the internet (DHCP is expected to be on)
Juho Eskeli 0:2b6d1f2f42fa 144 nsapi_error_t status = net->connect();
Juho Eskeli 0:2b6d1f2f42fa 145
Juho Eskeli 0:2b6d1f2f42fa 146 if (status != NSAPI_ERROR_OK) {
Juho Eskeli 0:2b6d1f2f42fa 147 printf("Connecting to the network failed %d!\n", status);
Juho Eskeli 0:2b6d1f2f42fa 148 return -1;
Juho Eskeli 0:2b6d1f2f42fa 149 }
Juho Eskeli 0:2b6d1f2f42fa 150
Juho Eskeli 0:2b6d1f2f42fa 151 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
Juho Eskeli 0:2b6d1f2f42fa 152
Juho Eskeli 0:2b6d1f2f42fa 153 // SimpleMbedCloudClient handles registering over LwM2M to Pelion Device Management
Juho Eskeli 0:2b6d1f2f42fa 154 int client_status = client->init();
Juho Eskeli 0:2b6d1f2f42fa 155 if (client_status != 0) {
Juho Eskeli 0:2b6d1f2f42fa 156 printf("Pelion Client initialization failed (%d)\n", client_status);
Juho Eskeli 0:2b6d1f2f42fa 157 return -1;
Juho Eskeli 0:2b6d1f2f42fa 158 }
Juho Eskeli 0:2b6d1f2f42fa 159
Juho Eskeli 0:2b6d1f2f42fa 160 // Creating resources, which can be written or read from the cloud
Juho Eskeli 0:2b6d1f2f42fa 161 button_res = client->create_resource("3200/0/5501", "button_count");
Juho Eskeli 0:2b6d1f2f42fa 162 button_res->set_value(0);
Juho Eskeli 0:2b6d1f2f42fa 163 button_res->methods(M2MMethod::GET);
Juho Eskeli 0:2b6d1f2f42fa 164 button_res->observable(true);
Juho Eskeli 0:2b6d1f2f42fa 165 button_res->attach_notification_callback(button_callback);
Juho Eskeli 0:2b6d1f2f42fa 166
Juho Eskeli 0:2b6d1f2f42fa 167 pattern_res = client->create_resource("3201/0/5853", "blink_pattern");
Juho Eskeli 0:2b6d1f2f42fa 168 pattern_res->set_value("500:500:500:500:500:500:500:500");
Juho Eskeli 0:2b6d1f2f42fa 169 pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
Juho Eskeli 0:2b6d1f2f42fa 170 pattern_res->attach_put_callback(pattern_updated);
Juho Eskeli 0:2b6d1f2f42fa 171
Juho Eskeli 0:2b6d1f2f42fa 172 MbedCloudClientResource *blink_res = client->create_resource("3201/0/5850", "blink_action");
Juho Eskeli 0:2b6d1f2f42fa 173 blink_res->methods(M2MMethod::POST);
Juho Eskeli 0:2b6d1f2f42fa 174 blink_res->attach_post_callback(blink_callback);
Juho Eskeli 0:2b6d1f2f42fa 175
Juho Eskeli 0:2b6d1f2f42fa 176 printf("Initialized Pelion Client. Registering...\n");
Juho Eskeli 0:2b6d1f2f42fa 177
Juho Eskeli 0:2b6d1f2f42fa 178 // Callback that fires when registering is complete
Juho Eskeli 0:2b6d1f2f42fa 179 client->on_registered(&registered);
Juho Eskeli 0:2b6d1f2f42fa 180
Juho Eskeli 0:2b6d1f2f42fa 181 // Register with Pelion Device Management
Juho Eskeli 0:2b6d1f2f42fa 182 client->register_and_connect();
Juho Eskeli 0:2b6d1f2f42fa 183
Juho Eskeli 0:2b6d1f2f42fa 184 // Placeholder for callback to update local resource when GET comes.
Juho Eskeli 0:2b6d1f2f42fa 185 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
Juho Eskeli 0:2b6d1f2f42fa 186 Ticker timer;
Juho Eskeli 0:2b6d1f2f42fa 187 timer.attach(eventQueue.event(&fake_button_press), 5.0);
Juho Eskeli 0:2b6d1f2f42fa 188
Juho Eskeli 0:2b6d1f2f42fa 189 // You can easily run the eventQueue in a separate thread if required
Juho Eskeli 0:2b6d1f2f42fa 190 eventQueue.dispatch_forever();
Juho Eskeli 0:2b6d1f2f42fa 191 }
Juho Eskeli 0:2b6d1f2f42fa 192 #endif