FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:37:05 2017 +0000
Revision:
0:dbad57390bd1
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:dbad57390bd1 1 # The Device Management and Service Enabler feature
ram54288 0:dbad57390bd1 2
ram54288 0:dbad57390bd1 3 mbed Device Server uses the Device Management and Service Enabler to access Object Instances and Resources available on the client. The interface provides this access through the following operations:
ram54288 0:dbad57390bd1 4
ram54288 0:dbad57390bd1 5 - [Create](#the-create-operation)
ram54288 0:dbad57390bd1 6 - Delete
ram54288 0:dbad57390bd1 7 - [Read](#the-read-operation)
ram54288 0:dbad57390bd1 8 - [Write](#the-write-operation)
ram54288 0:dbad57390bd1 9 - [Write Attributes](#the-write-attributes-operation)
ram54288 0:dbad57390bd1 10 - [Execute](#the-execute-operation)
ram54288 0:dbad57390bd1 11
ram54288 0:dbad57390bd1 12 Currently, support for the Create and Delete actions is limited to Object Instances.
ram54288 0:dbad57390bd1 13
ram54288 0:dbad57390bd1 14 The Device Management and Service Enabler Interface supports the following data types:
ram54288 0:dbad57390bd1 15
ram54288 0:dbad57390bd1 16 - Text: for Resources.
ram54288 0:dbad57390bd1 17 - TLV: for Object and Object Instances.
ram54288 0:dbad57390bd1 18
ram54288 0:dbad57390bd1 19 ## The Create operation
ram54288 0:dbad57390bd1 20
ram54288 0:dbad57390bd1 21 There are two types of resources you can create:
ram54288 0:dbad57390bd1 22
ram54288 0:dbad57390bd1 23 - Static: you set the value of the resource once and it does not change during the course of operations.
ram54288 0:dbad57390bd1 24 - Dynamic: the value is expected to change during the course of operations. Therefore, the value is fetched from setter APIs every time the server requests a read operation.
ram54288 0:dbad57390bd1 25
ram54288 0:dbad57390bd1 26 Here is an example of creating a custom static Resource:
ram54288 0:dbad57390bd1 27
ram54288 0:dbad57390bd1 28 ```
ram54288 0:dbad57390bd1 29 #include "mbed-client/m2mobject.h"
ram54288 0:dbad57390bd1 30 #include "mbed-client/m2mobjectinstance.h"
ram54288 0:dbad57390bd1 31 #include "mbed-client/m2mresource.h"
ram54288 0:dbad57390bd1 32 _object = M2MInterfaceFactory::create_object("Test");
ram54288 0:dbad57390bd1 33 if(_object) {
ram54288 0:dbad57390bd1 34 M2MObjectInstance* inst = _object->create_object_instance();
ram54288 0:dbad57390bd1 35 if(inst) {
ram54288 0:dbad57390bd1 36 inst->create_static_resource("S",
ram54288 0:dbad57390bd1 37 "ResourceTest",
ram54288 0:dbad57390bd1 38 STATIC_VALUE,
ram54288 0:dbad57390bd1 39 sizeof(STATIC_VALUE)-1);
ram54288 0:dbad57390bd1 40 ```
ram54288 0:dbad57390bd1 41
ram54288 0:dbad57390bd1 42 And here is an example of creating a custom dynamic Resource:
ram54288 0:dbad57390bd1 43
ram54288 0:dbad57390bd1 44 ```
ram54288 0:dbad57390bd1 45 #include "mbed-client/m2mobject.h"
ram54288 0:dbad57390bd1 46 #include "mbed-client/m2mobjectinstance.h"
ram54288 0:dbad57390bd1 47 #include "mbed-client/m2mresource.h"
ram54288 0:dbad57390bd1 48 _object = M2MInterfaceFactory::create_object("Test");
ram54288 0:dbad57390bd1 49 if(_object) {
ram54288 0:dbad57390bd1 50 M2MObjectInstance* inst = _object->create_object_instance();
ram54288 0:dbad57390bd1 51 if(inst) {
ram54288 0:dbad57390bd1 52 M2MResource* res = inst->create_dynamic_resource("D","ResourceTest",true);
ram54288 0:dbad57390bd1 53 char buffer[20];
ram54288 0:dbad57390bd1 54 int size = sprintf(buffer,"%d",_value);
ram54288 0:dbad57390bd1 55 res->set_operation(M2MBase::GET_PUT_ALLOWED);
ram54288 0:dbad57390bd1 56 res->set_value((const uint8_t*)buffer,
ram54288 0:dbad57390bd1 57 (const uint32_t)size);
ram54288 0:dbad57390bd1 58 ```
ram54288 0:dbad57390bd1 59
ram54288 0:dbad57390bd1 60 For more information on different resource functionalities, please check the [API documentation](https://docs.mbed.com/docs/mbed-client-guide/en/latest/api/annotated.html) for the M2MObject, M2MObjectInstance and M2MResource classes.
ram54288 0:dbad57390bd1 61
ram54288 0:dbad57390bd1 62 ## The Read operation
ram54288 0:dbad57390bd1 63
ram54288 0:dbad57390bd1 64 The Client API allows setting values to Resources, an array of Resource Instances, an Object Instance or all the Object Instances of an Object (TLV format supported). mbed Device Server can then read these values using the **Read** operation.
ram54288 0:dbad57390bd1 65
ram54288 0:dbad57390bd1 66 ## The Write operation
ram54288 0:dbad57390bd1 67
ram54288 0:dbad57390bd1 68 The **Write** operation is used to overwrite the value of a Resource, an array of Resource Instances or multiple Resources from an Object Instance.
ram54288 0:dbad57390bd1 69
ram54288 0:dbad57390bd1 70 Whenever there is a valid `PUT` operation for any of the resources, the application will receive a callback:
ram54288 0:dbad57390bd1 71
ram54288 0:dbad57390bd1 72 ```
ram54288 0:dbad57390bd1 73 void value_updated(M2MBase *base, M2MBase::BaseType type)
ram54288 0:dbad57390bd1 74 ```
ram54288 0:dbad57390bd1 75 Where `M2MBase` is the Object whose value has been updated and `M2MBase::BaseType` is the object type.
ram54288 0:dbad57390bd1 76
ram54288 0:dbad57390bd1 77 Check the code snippet below for usage.
ram54288 0:dbad57390bd1 78 ```
ram54288 0:dbad57390bd1 79 void value_updated(M2MBase *base, M2MBase::BaseType type) {
ram54288 0:dbad57390bd1 80 M2MResource* resource = NULL;
ram54288 0:dbad57390bd1 81 M2MResourceInstance* res_instance = NULL;
ram54288 0:dbad57390bd1 82 M2MObjectInstance* obj_instance = NULL;
ram54288 0:dbad57390bd1 83 M2MObject* obj = NULL;
ram54288 0:dbad57390bd1 84 String object_name = "";
ram54288 0:dbad57390bd1 85 String resource_name = "";
ram54288 0:dbad57390bd1 86 uint16_t object_instance_id = 0;
ram54288 0:dbad57390bd1 87 uint16_t resource_instance_id = 0;
ram54288 0:dbad57390bd1 88 if(base) {
ram54288 0:dbad57390bd1 89 switch(base->base_type()) {
ram54288 0:dbad57390bd1 90 case M2MBase::Object:
ram54288 0:dbad57390bd1 91 obj = (M2MObject *)base;
ram54288 0:dbad57390bd1 92 object_name = obj->name();
ram54288 0:dbad57390bd1 93 break;
ram54288 0:dbad57390bd1 94 case M2MBase::ObjectInstance:
ram54288 0:dbad57390bd1 95 obj_instance = (M2MObjectInstance *)base;
ram54288 0:dbad57390bd1 96 object_name = obj_instance->name();
ram54288 0:dbad57390bd1 97 object_instance_id = obj_instance->instance_id();
ram54288 0:dbad57390bd1 98 break;
ram54288 0:dbad57390bd1 99 case M2MBase::Resource: {
ram54288 0:dbad57390bd1 100 resource = (M2MResource*)base;
ram54288 0:dbad57390bd1 101 object_name = resource->object_name();
ram54288 0:dbad57390bd1 102 object_instance_id = resource->object_instance_id();
ram54288 0:dbad57390bd1 103 resource_name = resource->name();
ram54288 0:dbad57390bd1 104 printf("Value updated, object name %s, object instance id %d, resource name %s\r\n",
ram54288 0:dbad57390bd1 105 resource->object_name().c_str(), resource->object_instance_id(), resource->name().c_str());
ram54288 0:dbad57390bd1 106 }
ram54288 0:dbad57390bd1 107 break;
ram54288 0:dbad57390bd1 108 case M2MBase::ResourceInstance: {
ram54288 0:dbad57390bd1 109 res_instance = (M2MResourceInstance*)base;
ram54288 0:dbad57390bd1 110 object_name = res_instance->object_name();
ram54288 0:dbad57390bd1 111 object_instance_id = res_instance->object_instance_id();
ram54288 0:dbad57390bd1 112 resource_name = res_instance->name();
ram54288 0:dbad57390bd1 113 resource_instance_id = res_instance->instance_id();
ram54288 0:dbad57390bd1 114 }
ram54288 0:dbad57390bd1 115 break;
ram54288 0:dbad57390bd1 116 default:
ram54288 0:dbad57390bd1 117 break;
ram54288 0:dbad57390bd1 118 }
ram54288 0:dbad57390bd1 119 }
ram54288 0:dbad57390bd1 120 }
ram54288 0:dbad57390bd1 121 ```
ram54288 0:dbad57390bd1 122 By default, callbacks are handled in the `value_updated()` function but the application can also define a callback function for an individual resource.
ram54288 0:dbad57390bd1 123
ram54288 0:dbad57390bd1 124 Check the code snippet below for usage.
ram54288 0:dbad57390bd1 125
ram54288 0:dbad57390bd1 126 ```
ram54288 0:dbad57390bd1 127 static void value_updated_global(const char *name) {
ram54288 0:dbad57390bd1 128 if(name) {
ram54288 0:dbad57390bd1 129 ...
ram54288 0:dbad57390bd1 130 }
ram54288 0:dbad57390bd1 131 }
ram54288 0:dbad57390bd1 132
ram54288 0:dbad57390bd1 133 void M2MLWClient::value_updated_function(const char* name) {
ram54288 0:dbad57390bd1 134 if (name) {
ram54288 0:dbad57390bd1 135 ...
ram54288 0:dbad57390bd1 136 }
ram54288 0:dbad57390bd1 137 }
ram54288 0:dbad57390bd1 138
ram54288 0:dbad57390bd1 139 M2MResource* res = inst->create_dynamic_resource("D", "ResourceTest", true);
ram54288 0:dbad57390bd1 140 char buffer[20];
ram54288 0:dbad57390bd1 141 int size = sprintf(buffer,"%d",_value);
ram54288 0:dbad57390bd1 142 res->set_operation(M2MBase::GET_PUT_POST_DELETE_ALLOWED);
ram54288 0:dbad57390bd1 143 res->set_value((const uint8_t*)buffer, (const uint32_t)size);
ram54288 0:dbad57390bd1 144 res->set_value_updated_function(value_updated_callback(this,&MbedClient::value_updated_function));
ram54288 0:dbad57390bd1 145 /* Overloaded function can be used If callback function is not in class scope.
ram54288 0:dbad57390bd1 146 res2->set_value_updated_function(value_updated_callback2(&value_updated_global));
ram54288 0:dbad57390bd1 147 */
ram54288 0:dbad57390bd1 148
ram54288 0:dbad57390bd1 149 ```
ram54288 0:dbad57390bd1 150
ram54288 0:dbad57390bd1 151 ## The Write Attributes operation
ram54288 0:dbad57390bd1 152
ram54288 0:dbad57390bd1 153 Any readable Resource can have attributes that are considered during the [**Observe** operation](info_reporting.md#the-observe-feature). The following attributes are used:
ram54288 0:dbad57390bd1 154
ram54288 0:dbad57390bd1 155 - Minimum Period (pmin)
ram54288 0:dbad57390bd1 156 - Maximum Period (pmax)
ram54288 0:dbad57390bd1 157 - Greater Than (gt)
ram54288 0:dbad57390bd1 158 - Less Than (lt)
ram54288 0:dbad57390bd1 159 - Step (st)
ram54288 0:dbad57390bd1 160
ram54288 0:dbad57390bd1 161 mbed Device Server sets the endpoint attribute values that are used to determine when the endpoint sends the Resource value to the server.
ram54288 0:dbad57390bd1 162
ram54288 0:dbad57390bd1 163 Check the [LWM2M Specification](http://technical.openmobilealliance.org/Technical/technical-information/release-program/current-releases/oma-lightweightm2m-v1-0) for details of all the possible **Write Attributes** defined for different types of Objects and Resources.
ram54288 0:dbad57390bd1 164
ram54288 0:dbad57390bd1 165 ## The Execute operation
ram54288 0:dbad57390bd1 166
ram54288 0:dbad57390bd1 167 mbed Device Server uses the **Execute** operation to perform an action. This operation can only be performed on individual Resources.
ram54288 0:dbad57390bd1 168
ram54288 0:dbad57390bd1 169 <span class="notes">**Note:** mbed Client returns an error when the **Execute** operation is received for Object Instances or Resource Instances.</span>
ram54288 0:dbad57390bd1 170
ram54288 0:dbad57390bd1 171 If you want to execute a piece of code in your application, you can pass a `POST` request from mbed Device Server.
ram54288 0:dbad57390bd1 172 When your Resource receives the `POST` request, mbed Client parses the payload from the request and wraps it in the `M2MResource::M2MExecuteParameter` class. The class object is passed through the execute callback function.
ram54288 0:dbad57390bd1 173 You can then typecast the `void*` argument into the corresponding `M2MResource::M2MExecuteParameter` and access the passed payload and its length through the given API. M2MResource::M2MExecuteParameter contains also information which object and object instance resource belongs to. Make sure that the payload sent through POST request is in `plain/text` format and that the content-type is set as “plain/text” on the POST request call.
ram54288 0:dbad57390bd1 174
ram54288 0:dbad57390bd1 175 Check the code snippet below for usage.
ram54288 0:dbad57390bd1 176
ram54288 0:dbad57390bd1 177 ```
ram54288 0:dbad57390bd1 178 #include "mbed-client/m2mobject.h"
ram54288 0:dbad57390bd1 179 #include "mbed-client/m2mobjectinstance.h"
ram54288 0:dbad57390bd1 180 #include "mbed-client/m2mresource.h"
ram54288 0:dbad57390bd1 181 static void execute_function_2(void *argument) {
ram54288 0:dbad57390bd1 182 if(argument) {
ram54288 0:dbad57390bd1 183 M2MResource::M2MExecuteParameter* param = (M2MResource::M2MExecuteParameter*)argument;
ram54288 0:dbad57390bd1 184 int payload_length = param->get_argument_value_length();
ram54288 0:dbad57390bd1 185 uint8_t* payload = param->get_argument_value();
ram54288 0:dbad57390bd1 186 String object_name = param->get_argument_object_name();
ram54288 0:dbad57390bd1 187 uint16_t object_instance_id = param->get_argument_object_instance_id();
ram54288 0:dbad57390bd1 188 String resource_name = param->get_argument_resource_name();
ram54288 0:dbad57390bd1 189 }
ram54288 0:dbad57390bd1 190
ram54288 0:dbad57390bd1 191 void M2MLWClient::execute_function(void *argument) {
ram54288 0:dbad57390bd1 192 if(argument) {
ram54288 0:dbad57390bd1 193 M2MResource::M2MExecuteParameter* param = (M2MResource::M2MExecuteParameter*)argument;
ram54288 0:dbad57390bd1 194 int payload_length = param->get_argument_value_length();
ram54288 0:dbad57390bd1 195 uint8_t* payload = param->get_argument_value();
ram54288 0:dbad57390bd1 196 String object_name = param->get_argument_object_name();
ram54288 0:dbad57390bd1 197 uint16_t object_instance_id = param->get_argument_object_instance_id();
ram54288 0:dbad57390bd1 198 String resource_name = param->get_argument_resource_name();
ram54288 0:dbad57390bd1 199 }
ram54288 0:dbad57390bd1 200
ram54288 0:dbad57390bd1 201 _object = M2MInterfaceFactory::create_object("Test");
ram54288 0:dbad57390bd1 202 if(_object) {
ram54288 0:dbad57390bd1 203 M2MObjectInstance* inst = _object->create_object_instance();
ram54288 0:dbad57390bd1 204 if(inst) {
ram54288 0:dbad57390bd1 205 M2MResource* res = inst->create_dynamic_resource("D","ResourceTest",true);
ram54288 0:dbad57390bd1 206 char buffer[20];
ram54288 0:dbad57390bd1 207 int size = sprintf(buffer,"%d",_value);
ram54288 0:dbad57390bd1 208 res->set_operation(M2MBase::GET_PUT_POST_ALLOWED);
ram54288 0:dbad57390bd1 209 res->set_value((const uint8_t*)buffer,
ram54288 0:dbad57390bd1 210 (const uint32_t)size);
ram54288 0:dbad57390bd1 211 res->set_execute_function(execute_callback(this,&M2MLWClient::execute_function));
ram54288 0:dbad57390bd1 212 /* Overloaded function can be used If callback function is not in class scope.
ram54288 0:dbad57390bd1 213 res->set_execute_function(execute_callback_2(&execute_function_2));
ram54288 0:dbad57390bd1 214 */
ram54288 0:dbad57390bd1 215 ```
ram54288 0:dbad57390bd1 216
ram54288 0:dbad57390bd1 217 The POST method allows the client to respond immediately with the updated payload value as a piggyback response. If you want to send the payload response to the server later (because the Execute operation may take longer time on device to complete), you can handle this through the API.
ram54288 0:dbad57390bd1 218
ram54288 0:dbad57390bd1 219 You can set the resource API `void set_delayed_response(bool)` to `true`. In this case, the POST request response to the server is an empty acknowledgment. When your resource is ready with the response, you can simply call `send_delayed_post_response()` on that resource and the client sends the latest resource value to the server as part of a separate response to the POST request. By default, `void set_delayed_response(bool)` is `false`, which means that the POST response returns the resource value as a piggyback payload immediately.