Jim Carver / Mbed OS mbed-cloud-workshop-connect
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2018 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 #include "mbed.h"
00020 #include <stdio.h>
00021 #include <errno.h>
00022 
00023 #include "qspi_api.h"
00024 #include "QSPI.h"
00025 #include "qspi-blockdevice/QSPIFBlockDevice.h"
00026 #define DEVICE_QSPI
00027 
00028 #include "FATFileSystem.h"
00029 #include "LittleFileSystem.h"
00030 #include "simple-mbed-cloud-client.h"
00031 // #include "SDBlockDevice.h"
00032 #include "ISM43362Interface.h"
00033 // #include "SPIFBlockDevice.h" // to use onboard spi flash
00034 
00035 #define WIFI_SSID       "mbed"
00036 #define WIFI_PASSWORD   "workshop-password"
00037 
00038 
00039 
00040 
00041 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
00042 // 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
00043 EventQueue eventQueue;
00044 
00045 // Declaring net interface as a global variable instead of local to avoid stack overflow
00046 ISM43362Interface net;
00047 
00048 // Storage implementation definition, currently using SDBlockDevice (SPI flash, DataFlash, and internal flash are also available)
00049 // SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS);
00050 QSPIFBlockDevice sd(PE_12, PE_13, PE_14, PE_15,PE_10,PE_11,0,8000000);
00051 
00052 // FATFileSystem fs("sd", &bd);
00053 
00054 LittleFileSystem fs("sd");
00055 
00056 // Declaring pointers for access to Mbed Cloud Client resources outside of main()
00057 MbedCloudClientResource *button_res;
00058 MbedCloudClientResource *pattern_res;
00059 
00060 // This function gets triggered by the timer. It's easy to replace it by an InterruptIn and fall() mode on a real button
00061 void fake_button_press() {
00062     int v = button_res->get_value_int() + 1;
00063 
00064     button_res->set_value(v);
00065 
00066     printf("Simulated button clicked %d times\n", v);
00067 }
00068 
00069 /**
00070  * PUT handler
00071  * @param resource The resource that triggered the callback
00072  * @param newValue Updated value for the resource
00073  */
00074 void pattern_updated(MbedCloudClientResource *resource, m2m::String newValue) {
00075     printf("PUT received, new value: %s\n", newValue.c_str());
00076 }
00077 
00078 /**
00079  * POST handler
00080  * @param resource The resource that triggered the callback
00081  * @param buffer If a body was passed to the POST function, this contains the data.
00082  *               Note that the buffer is deallocated after leaving this function, so copy it if you need it longer.
00083  * @param size Size of the body
00084  */
00085 void blink_callback(MbedCloudClientResource *resource, const uint8_t *buffer, uint16_t size) {
00086     printf("POST received. Going to blink LED pattern: %s\n", pattern_res->get_value().c_str());
00087 
00088     static DigitalOut augmentedLed(LED1); // LED that is used for blinking the pattern
00089 
00090     // Parse the pattern string, and toggle the LED in that pattern
00091     string s = std::string(pattern_res->get_value().c_str());
00092     size_t i = 0;
00093     size_t pos = s.find(':');
00094     while (pos != string::npos) {
00095         wait_ms(atoi(s.substr(i, pos - i).c_str()));
00096         augmentedLed = !augmentedLed;
00097 
00098         i = ++pos;
00099         pos = s.find(':', pos);
00100 
00101         if (pos == string::npos) {
00102             wait_ms(atoi(s.substr(i, s.length()).c_str()));
00103             augmentedLed = !augmentedLed;
00104         }
00105     }
00106 }
00107 
00108 /**
00109  * Notification callback handler
00110  * @param resource The resource that triggered the callback
00111  * @param status The delivery status of the notification
00112  */
00113 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
00114     printf("Button notification, status %s (%d)\n", MbedCloudClientResource::delivery_status_to_string(status), status);
00115 }
00116 
00117 /**
00118  * Registration callback handler
00119  * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
00120  */
00121 void registered(const ConnectorClientEndpointInfo *endpoint) {
00122     printf("Connected to Mbed Cloud. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
00123 }
00124 
00125 int main(void) {
00126     printf("Starting Simple Mbed Cloud Client example\n");
00127 
00128     printf("Checking SDCard is Formatted\r\n");
00129     int err = fs.mount(&sd);
00130     printf("%s\n", (err ? "Fail :(" : "OK"));
00131     if (err) {
00132         // Reformat if we can't mount the filesystem
00133         // this should only happen on the first boot
00134         printf("No filesystem found, formatting... ");
00135         fflush(stdout);
00136         err = fs.reformat(&sd);
00137         printf("%s\n", (err ? "Fail :(" : "OK"));
00138         if (err) {
00139             error("error: %s (%d)\n", strerror(-err), err);
00140         }
00141     }
00142     // err = fs.unmount();
00143     // printf("%s\n", (err < 0 ? "Fail :(" : "OK"));
00144     // if (err < 0) {
00145     //     error("error: %s (%d)\n", strerror(-err), err);
00146     // }
00147 
00148     printf("Connecting to the network using Wifi...\n");
00149 
00150     // Connect to the internet (DHCP is expected to be on)
00151     nsapi_error_t status = net.connect(WIFI_SSID, WIFI_PASSWORD, (strlen(WIFI_PASSWORD) > 1) ? NSAPI_SECURITY_WPA_WPA2 : NSAPI_SECURITY_NONE);
00152 
00153     if (status != 0) {
00154         printf("Connecting to the network failed %d!\n", status);
00155         return -1;
00156     }
00157 
00158     printf("Connected to the network successfully. IP address: %s\n", net.get_ip_address());
00159 
00160     // SimpleMbedCloudClient handles registering over LwM2M to Mbed Cloud
00161     SimpleMbedCloudClient client(&net, &sd, &fs);
00162     int client_status = client.init();
00163     if (client_status != 0) {
00164         printf("Initializing Mbed Cloud Client failed (%d)\n", client_status);
00165         return -1;
00166     }
00167 
00168     // Creating resources, which can be written or read from the cloud
00169     button_res = client.create_resource("3200/0/5501", "button_count");
00170     button_res->set_value(0);
00171     button_res->methods(M2MMethod::GET);
00172     button_res->observable(true);
00173     button_res->attach_notification_callback(button_callback);
00174 
00175     pattern_res = client.create_resource("3201/0/5853", "blink_pattern");
00176     pattern_res->set_value("500:500:500:500:500:500:500:500");
00177     pattern_res->methods(M2MMethod::GET | M2MMethod::PUT);
00178     pattern_res->attach_put_callback(pattern_updated);
00179 
00180     MbedCloudClientResource *blink_res = client.create_resource("3201/0/5850", "blink_action");
00181     blink_res->methods(M2MMethod::POST);
00182     blink_res->attach_post_callback(blink_callback);
00183 
00184     printf("Initialized Mbed Cloud Client. Registering...\n");
00185 
00186     // Callback that fires when registering is complete
00187     client.on_registered(&registered);
00188 
00189     // Register with Mbed Cloud
00190     client.register_and_connect();
00191 
00192     // Placeholder for callback to update local resource when GET comes.
00193     // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
00194     Ticker timer;
00195     timer.attach(eventQueue.event(&fake_button_press), 5.0);
00196 
00197     // You can easily run the eventQueue in a separate thread if required
00198     eventQueue.dispatch_forever();
00199 }