An mbed BLE-to-Cloud Gateway using Nucleo-F429ZI+X-Nucleo-IDB05A1 or Nucleo-L476RG+X-Nucleo-IDB05A1+X-Nucleo-IDW01M1.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers simpleclient.h Source File

simpleclient.h

00001 /*
00002  * Copyright (c) 2015 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef __SIMPLECLIENT_H__
00018 #define __SIMPLECLIENT_H__
00019 
00020 #include "mbed-client/m2minterfacefactory.h"
00021 #include "mbed-client/m2mdevice.h"
00022 #include "mbed-client/m2minterfaceobserver.h"
00023 #include "mbed-client/m2minterface.h"
00024 #include "mbed-client/m2mobject.h"
00025 #include "mbed-client/m2mobjectinstance.h"
00026 #include "mbed-client/m2mresource.h"
00027 #include "mbed-client/m2mconfig.h"
00028 #include "mbed-client/m2mblockmessage.h"
00029 #include "security.h"
00030 #include "mbed.h"
00031 
00032 #define ETHERNET        1
00033 #define WIFI            2
00034 #define MESH_LOWPAN_ND  3
00035 #define MESH_THREAD     4
00036 #define ATMEL           5
00037 #define MCR20           6
00038 #define SPIRIT1         7
00039 #define EFR32           8
00040 
00041 #define STRINGIFY(s) #s
00042 
00043 // Check if using mesh networking, define helper
00044 #if MBED_CONF_APP_NETWORK_INTERFACE == MESH_LOWPAN_ND
00045     #define MESH
00046 #elif MBED_CONF_APP_NETWORK_INTERFACE == MESH_THREAD
00047     #define MESH
00048 #endif
00049 
00050 #if defined (MESH) || (MBED_CONF_LWIP_IPV6_ENABLED==true)
00051     // Mesh is always IPV6 - also WiFi and ETH can be IPV6 if IPV6 is enabled
00052     M2MInterface::NetworkStack NETWORK_STACK = M2MInterface::LwIP_IPv6;
00053 #else
00054     // Everything else - we assume it's IPv4
00055     M2MInterface::NetworkStack NETWORK_STACK = M2MInterface::LwIP_IPv4;
00056 #endif
00057 
00058 //Select binding mode: UDP or TCP -- note - Mesh networking is IPv6 UDP ONLY
00059 #ifdef MESH
00060     M2MInterface::BindingMode SOCKET_MODE = M2MInterface::UDP;
00061 #else
00062     // WiFi or Ethernet supports both - TCP by default to avoid
00063     // NAT problems, but UDP will also work - IF you configure
00064     // your network right.
00065     M2MInterface::BindingMode SOCKET_MODE = M2MInterface::TCP;
00066 #endif
00067 
00068 
00069 // MBED_DOMAIN and MBED_ENDPOINT_NAME come
00070 // from the security.h file copied from connector.mbed.com
00071 
00072 struct MbedClientDevice {
00073     const char* Manufacturer;
00074     const char* Type;
00075     const char* ModelNumber;
00076     const char* SerialNumber;
00077 };
00078 
00079 /*
00080 * Wrapper for mbed client stack that handles all callbacks, error handling, and
00081 * other shenanigans to make the mbed client stack easier to use.
00082 *
00083 * The end user should only have to care about configuring the parameters at the
00084 * top of this file and making sure they add the security.h file correctly.
00085 * To add resources you can copy the _TODO__ function and add as many instances as
00086 * you want.
00087 *
00088 */
00089 class MbedClient: public M2MInterfaceObserver {
00090 public:
00091 
00092     // constructor for MbedClient object, initialize private variables
00093     MbedClient(struct MbedClientDevice device) {
00094         _interface = NULL;
00095         _bootstrapped = false;
00096         _error = false;
00097         _registered = false;
00098         _unregistered = false;
00099         _register_security = NULL;
00100         _value = 0;
00101         _object = NULL;
00102         _device = device;
00103     }
00104 
00105     // de-constructor for MbedClient object, you can ignore this
00106     ~MbedClient() {
00107         if(_interface) {
00108             delete _interface;
00109         }
00110         if(_register_security){
00111             delete _register_security;
00112         }
00113     }
00114 
00115     // debug printf function
00116     void trace_printer(const char* str) {
00117         printf("\r\n%s\r\n", str);
00118     }
00119 
00120     /*
00121     *  Creates M2MInterface using which endpoint can
00122     *  setup its name, resource type, life time, connection mode,
00123     *  Currently only LwIPv4 is supported.
00124     */
00125     void create_interface(const char *server_address,
00126                           void *handler=NULL) {
00127     // Randomizing listening port for Certificate mode connectivity
00128     _server_address = server_address;
00129     uint16_t port = 0; // Network interface will randomize with port 0
00130 
00131     // create mDS interface object, this is the base object everything else attaches to
00132     _interface = M2MInterfaceFactory::create_interface(*this,
00133                                                       MBED_ENDPOINT_NAME,       // endpoint name string
00134                                                       "test",                   // endpoint type string
00135                                                       100,                      // lifetime
00136                                                       port,                     // listen port
00137                                                       MBED_DOMAIN,              // domain string
00138                                                       SOCKET_MODE,              // binding mode
00139                                                       NETWORK_STACK,            // network stack
00140                                                       "");                      // context address string
00141     const char *binding_mode = (SOCKET_MODE == M2MInterface::UDP) ? "UDP" : "TCP";
00142     printf("\r\nSOCKET_MODE : %s\r\n", binding_mode);
00143     printf("Connecting to %s\r\n", server_address);
00144 
00145     if(_interface) {
00146         _interface->set_platform_network_handler(handler);
00147     }
00148 
00149     }
00150 
00151     /*
00152     *  check private variable to see if the registration was sucessful or not
00153     */
00154     bool register_successful() {
00155         return _registered;
00156     }
00157 
00158     /*
00159     *  check private variable to see if un-registration was sucessful or not
00160     */
00161     bool unregister_successful() {
00162         return _unregistered;
00163     }
00164 
00165     /*
00166     *  Creates register server object with mbed device server address and other parameters
00167     *  required for client to connect to mbed device server.
00168     */
00169     M2MSecurity* create_register_object() {
00170         // create security object using the interface factory.
00171         // this will generate a security ObjectID and ObjectInstance
00172         M2MSecurity *security = M2MInterfaceFactory::create_security(M2MSecurity::M2MServer);
00173 
00174         // make sure security ObjectID/ObjectInstance was created successfully
00175         if(security) {
00176             // Add ResourceID's and values to the security ObjectID/ObjectInstance
00177             security->set_resource_value(M2MSecurity::M2MServerUri, _server_address);
00178             security->set_resource_value(M2MSecurity::SecurityMode, M2MSecurity::Certificate);
00179             security->set_resource_value(M2MSecurity::ServerPublicKey, SERVER_CERT, sizeof(SERVER_CERT) - 1);
00180             security->set_resource_value(M2MSecurity::PublicKey, CERT, sizeof(CERT) - 1);
00181             security->set_resource_value(M2MSecurity::Secretkey, KEY, sizeof(KEY) - 1);
00182         }
00183         return security;
00184     }
00185 
00186     /*
00187     * Creates device object which contains mandatory resources linked with
00188     * device endpoint.
00189     */
00190     M2MDevice* create_device_object() {
00191         // create device objectID/ObjectInstance
00192         M2MDevice *device = M2MInterfaceFactory::create_device();
00193         // make sure device object was created successfully
00194         if(device) {
00195             // add resourceID's to device objectID/ObjectInstance
00196             device->create_resource(M2MDevice::Manufacturer, _device.Manufacturer);
00197             device->create_resource(M2MDevice::DeviceType, _device.Type);
00198             device->create_resource(M2MDevice::ModelNumber, _device.ModelNumber);
00199             device->create_resource(M2MDevice::SerialNumber, _device.SerialNumber);
00200         }
00201         return device;
00202     }
00203 
00204     /*
00205     * register an object
00206     */
00207     void test_register(M2MSecurity *register_object, M2MObjectList object_list){
00208         if(_interface) {
00209             // Register function
00210             _interface->register_object(register_object, object_list);
00211         }
00212     }
00213 
00214     /*
00215     * unregister all objects
00216     */
00217     void test_unregister() {
00218         if(_interface) {
00219             // Unregister function
00220             _interface->unregister_object(NULL); // NULL will unregister all objects
00221         }
00222     }
00223 
00224     //Callback from mbed client stack when the bootstrap
00225     // is successful, it returns the mbed Device Server object
00226     // which will be used for registering the resources to
00227     // mbed Device server.
00228     void bootstrap_done(M2MSecurity *server_object){
00229         if(server_object) {
00230             _bootstrapped = true;
00231             _error = false;
00232             trace_printer("Bootstrapped");
00233         }
00234     }
00235 
00236     //Callback from mbed client stack when the registration
00237     // is successful, it returns the mbed Device Server object
00238     // to which the resources are registered and registered objects.
00239     void object_registered(M2MSecurity */*security_object*/, const M2MServer &/*server_object*/){
00240         _registered = true;
00241         _unregistered = false;
00242         trace_printer("Registered object successfully!");
00243     }
00244 
00245     //Callback from mbed client stack when the unregistration
00246     // is successful, it returns the mbed Device Server object
00247     // to which the resources were unregistered.
00248     void object_unregistered(M2MSecurity */*server_object*/){
00249         trace_printer("Unregistered Object Successfully");
00250         _unregistered = true;
00251         _registered = false;
00252     }
00253 
00254     /*
00255     * Callback from mbed client stack when registration is updated
00256     */
00257     void registration_updated(M2MSecurity */*security_object*/, const M2MServer & /*server_object*/){
00258         /* The registration is updated automatically and frequently by the
00259         *  mbed client stack. This print statement is turned off because it
00260         *  tends to happen alot.
00261         */
00262         //trace_printer("\r\nRegistration Updated\r\n");
00263     }
00264 
00265     // Callback from mbed client stack if any error is encountered
00266     // during any of the LWM2M operations. Error type is passed in
00267     // the callback.
00268     void error(M2MInterface::Error error){
00269         _error = true;
00270         switch(error){
00271             case M2MInterface::AlreadyExists:
00272                 trace_printer("[ERROR:] M2MInterface::AlreadyExist");
00273                 break;
00274             case M2MInterface::BootstrapFailed:
00275                 trace_printer("[ERROR:] M2MInterface::BootstrapFailed");
00276                 break;
00277             case M2MInterface::InvalidParameters:
00278                 trace_printer("[ERROR:] M2MInterface::InvalidParameters");
00279                 break;
00280             case M2MInterface::NotRegistered:
00281                 trace_printer("[ERROR:] M2MInterface::NotRegistered");
00282                 break;
00283             case M2MInterface::Timeout:
00284                 trace_printer("[ERROR:] M2MInterface::Timeout");
00285                 break;
00286             case M2MInterface::NetworkError:
00287                 trace_printer("[ERROR:] M2MInterface::NetworkError");
00288                 break;
00289             case M2MInterface::ResponseParseFailed:
00290                 trace_printer("[ERROR:] M2MInterface::ResponseParseFailed");
00291                 break;
00292             case M2MInterface::UnknownError:
00293                 trace_printer("[ERROR:] M2MInterface::UnknownError");
00294                 break;
00295             case M2MInterface::MemoryFail:
00296                 trace_printer("[ERROR:] M2MInterface::MemoryFail");
00297                 break;
00298             case M2MInterface::NotAllowed:
00299                 trace_printer("[ERROR:] M2MInterface::NotAllowed");
00300                 break;
00301             case M2MInterface::SecureConnectionFailed:
00302                 trace_printer("[ERROR:] M2MInterface::SecureConnectionFailed");
00303                 break;
00304             case M2MInterface::DnsResolvingFailed:
00305                 trace_printer("[ERROR:] M2MInterface::DnsResolvingFailed");
00306                 break;
00307 
00308             default:
00309                 break;
00310         }
00311     }
00312 
00313     /* Callback from mbed client stack if any value has changed
00314     *  during PUT operation. Object and its type is passed in
00315     *  the callback.
00316     *  BaseType enum from m2mbase.h
00317     *       Object = 0x0, Resource = 0x1, ObjectInstance = 0x2, ResourceInstance = 0x3
00318     */
00319     void value_updated(M2MBase *base, M2MBase::BaseType type) {
00320         printf("\r\nPUT Request Received!");
00321         printf("\r\nName :'%s', \r\nPath : '%s', \r\nType : '%d' (0 for Object, 1 for Resource), \r\nType : '%s'\r\n",
00322                base->name(),
00323                base->uri_path(),
00324                type,
00325                base->resource_type()
00326                );
00327     }
00328 
00329     /*
00330     * update the registration period
00331     */
00332     void test_update_register() {
00333         if (_registered) {
00334             _interface->update_registration(_register_security, 100);
00335         }
00336     }
00337 
00338     /*
00339     * manually configure the security object private variable
00340     */
00341    void set_register_object(M2MSecurity *register_object) {
00342         if (_register_security == NULL) {
00343             _register_security = register_object;
00344         }
00345     }
00346 
00347 private:
00348 
00349     /*
00350     *  Private variables used in class
00351     */
00352     M2MInterface             *_interface;
00353     M2MSecurity              *_register_security;
00354     M2MObject                *_object;
00355     volatile bool            _bootstrapped;
00356     volatile bool            _error;
00357     volatile bool            _registered;
00358     volatile bool            _unregistered;
00359     int                      _value;
00360     struct MbedClientDevice  _device;
00361     String                   _server_address;
00362 };
00363 
00364 #endif // __SIMPLECLIENT_H__