Embed client working with Cell network.

Dependencies:   C027Interface

Fork of U_Blox_DeviceConnector by Sarah Marsh

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