The Arm Pelion Device Management code to be used for https://cloud.mbed.com/quick-start

DEPRECATED

This example application is not maintained and not recommended. It uses an old version of Mbed OS, Pelion DM, and Arm toolchain. It doesn't work with Mbed Studio.

Please use: https://os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-pelion/

Committer:
Andrew Chong
Date:
Fri Jan 25 10:59:23 2019 +0900
Revision:
3:9bdf8c9bf22d
Parent:
1:e0ba512426a7
Added more to ignore from mercurial.

Who changed what in which revision?

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