iotivity 0.9.0
[platform/upstream/iotivity.git] / resource / docs / guides / HowToGuidesIndex.txt
1 /*!\r
2 \r
3 @page OCHowTo How To... Guides\r
4 \r
5 @ref Guide_Representative_Devices "Sample representative devices used in these tutorials"\r
6 \r
7 @ref Guide_Stack_Init "How to initialize the stack"\r
8 \r
9 @ref Guide_Register_Resource "How to register a resource"\r
10 \r
11 @ref Guide_Find_Resource "How to find a resource"\r
12 \r
13 @ref Guide_PUT  "How to set resource state [PUT]"\r
14 \r
15 @ref Guide_GET "How to query resource state [GET]"\r
16 \r
17 @ref Guide_Observe "How to observe resource state [Observe]"\r
18 \r
19 \r
20 \r
21 ********************************************************************\r
22 \r
23 \r
24 @page Guide_Representative_Devices Representative Devices\r
25 \r
26 The best way to understand the concepts for IoTivity is through following an example and understanding the use case. The following devices are referred to throughout this document for use cases and basic operations. The details are listed here for reference so that implementers can compare the responses from these devices with their configuration to develop an understanding of what the responses mean.\r
27 \r
28 @section Rep_Light_Device Light devices (192.168.1.11-13)\r
29 \r
30 A lighting device that can handle up to two light bulbs with dimmers. Each light bulb resource has two attributes:\r
31 \li Power: controls power and can have a value of 0 (off) or 1 (on)\r
32 \li Level: current dimmer level with a value from 1 (low) to 10 (full)\r
33 \r
34 The separation of the attributes allows the light to return to the previous light level when the power is toggled.\r
35 \r
36 @subsection Rep_Light_Device_Description Description of resources on this device type\r
37 \r
38 <table cellspacing="0" cellpadding="0" border=1 >\r
39 \r
40 <tr>\r
41 <td valign="top" ><b>Resource</b></td>\r
42 <td valign="top" ><b>Description</b></td>\r
43 </tr>\r
44 \r
45 <tr>\r
46 <td valign="top" ><p>/oc/core</p></td>\r
47 <td valign="top" ><p>Standard resource listing in JSON format.</p></td>\r
48 </tr>\r
49 \r
50 <tr>\r
51 <td valign="top" ><p>/oc/core/d</p></td>\r
52 <td valign="top" ><p>Virtual (hidden) resource that describes the device. It is searchable and supports the JSON attributes listed in the appendix.</p></td>\r
53 </tr>\r
54 \r
55 <tr>\r
56 <td valign="top" ><p>/lights</p></td>\r
57 <td valign="top" ><p>The resource collection that contains light resources</p>\r
58 \r
59 <p>rt=alpha.light</p>\r
60 \r
61 <p>if=oc.mi.ll (linked-list)</p></td>\r
62 </tr>\r
63 \r
64 <tr>\r
65 <td valign="top" ><p>/light/1</p></td>\r
66 <td valign="top" ><p>The resource associated with the first light bulb attached to this device </p>\r
67 \r
68 <p>rt=alpha.light</p>\r
69 \r
70 <p>if=oc.mi.def (default)</p></td>\r
71 </tr>\r
72 \r
73 <tr>\r
74 <td valign="top" ><p>/light/2</p></td>\r
75 <td valign="top" ><p>The resource associated with the second light bulb attached to this device</p>\r
76 \r
77 <p>rt=alpha.light</p>\r
78 \r
79 <p>if=oc.mi.def (default)</p></td>\r
80 </tr>\r
81 \r
82 </table>\r
83 \r
84 \r
85 \r
86 @subsection Rep_Light_Device_Resource_11 Resource(s) at 192.168.1.11\r
87 \r
88 This device contains a single light resource. The following lists the valid resources and their typical state:\r
89 \r
90 <table cellspacing="0" cellpadding="0" border=1>\r
91 \r
92 <tr>\r
93 <td valign="top" ><b>Resource</b></td>\r
94 <td valign="top" ><b>Representation</b></td>\r
95 </tr>\r
96 \r
97 <tr>\r
98 <td valign="top" ><p>/oc/core</p></td>\r
99 <td valign="top" ><p>[</p>\r
100 \r
101 <p>{ "href" : "/lights", "rt" : ["alpha.light"], "if" : ["oc.mi.ll"]},</p>\r
102 \r
103 <p>{ "href" : "/light/1", "rt" : ["alpha.light"], "if" : ["oc.mi.def"], "obs" : 1}</p>\r
104 \r
105 <p>]</p></td>\r
106 </tr>\r
107 \r
108 <tr>\r
109 <td valign="top" ><p>/oc/core/d</p></td>\r
110 <td valign="top" ><p>{</p>\r
111 \r
112 <p>"di" : "12345678-1234-1234-0000000000000011",</p>\r
113 \r
114 <p>"dn" : "Alpha Light Controller",</p>\r
115 \r
116 <p>"dd" : "A Light Controller"</p>\r
117 \r
118 <p>}</p></td>\r
119 </tr>\r
120 \r
121 <tr>\r
122 <td valign="top" ><p>/light/1</p></td>\r
123 <td valign="top" ><p>{ "power" : 0, "level" : 4 }</p></td>\r
124 </tr>\r
125 \r
126 </table>\r
127 \r
128 \r
129 \r
130 \r
131 @subsection Rep_Light_Device_Resource_12 Resource(s) at 192.168.1.12\r
132 \r
133 This device contains a single light resource. The following lists the valid resources and their typical state:\r
134 \r
135 <table cellspacing="0" cellpadding="0" border=1>\r
136 \r
137 <tr>\r
138 <td valign="top" ><b>Resource</b></td>\r
139 <td valign="top" ><b>Representation</b></td>\r
140 </tr>\r
141 \r
142 <tr>\r
143 <td valign="top" ><p>/oc/core</p></td>\r
144 <td valign="top" ><p>[</p>\r
145 \r
146 <p>{ "href" : "/lights", "rt" : ["alpha.light"], "if" : ["oc.mi.ll"]},</p>\r
147 \r
148 <p>{ "href" : "/light/2", "rt" : ["alpha.light"], "if" : ["oc.mi.def"], "obs":1}</p>\r
149 \r
150 <p>]</p></td>\r
151 </tr>\r
152 \r
153 <tr>\r
154 <td valign="top" ><p>/oc/core/d</p></td>\r
155 <td valign="top" ><p>{</p>\r
156 \r
157 <p>"di" : "12345678-1234-1234-0000000000000012",</p>\r
158 \r
159 <p>"dn" : "Alpha Light Controller",</p>\r
160 \r
161 <p>"dd" : "A Light Controller"</p>\r
162 \r
163 <p>}</p></td>\r
164 </tr>\r
165 \r
166 <tr>\r
167 <td valign="top" ><p>/light/2</p></td>\r
168 <td valign="top" ><p>{ "power" : 1, "level" : 6 }</p></td>\r
169 </tr>\r
170 \r
171 </table>\r
172 \r
173 \r
174 \r
175 @subsection Rep_Light_Device_Resource_13 Resource(s) at 192.168.1.13\r
176 \r
177 This device contains two light resources. The following lists the valid resources and their typical state:\r
178 \r
179 <table cellspacing="0" cellpadding="0" border=1> \r
180 \r
181 <tr>\r
182 <td valign="top" ><p>Resource</p></td>\r
183 <td valign="top" ><p>Representation</p></td>\r
184 </tr>\r
185 \r
186 <tr>\r
187 <td valign="top" ><p>/oc/core</p></td>\r
188 <td valign="top" ><p>[</p>\r
189 \r
190 <p>{ "href" : "/lights", "rt" : ["alpha.light"], "if" : ["oc.mi.ll"]},</p>\r
191 \r
192 <p>{ "href" : "/light/1", "rt" : ["alpha.light"], "if" : ["oc.mi.def"], "obs":1},</p>\r
193 \r
194 <p>{ "href" : "/light/2", "rt" : ["alpha.light"], "if" : ["oc.mi.def"], "obs":1}</p>\r
195 \r
196 <p>]</p></td>\r
197 </tr>\r
198 \r
199 <tr>\r
200 <td valign="top" ><p>/oc/core/d</p></td>\r
201 <td valign="top" ><p>{</p>\r
202 \r
203 <p>"di" : "12345678-1234-1234-0000000000000013",</p>\r
204 \r
205 <p>"dn" : "Alpha Light Controller",</p>\r
206 \r
207 <p>"dd" : "A Light Controller"</p>\r
208 \r
209 <p>}</p></td>\r
210 </tr>\r
211 \r
212 <tr>\r
213 <td valign="top" ><p>/light/1</p></td>\r
214 <td valign="top" ><p>{ "power" : 0, "level" : 8 }</p></td>\r
215 </tr>\r
216 \r
217 <tr>\r
218 <td valign="top" ><p>/light/2</p></td>\r
219 <td valign="top" ><p>{ "power" : 1, "level" : 10 }</p></td>\r
220 </tr>\r
221 \r
222 </table>\r
223 \r
224 \r
225 \r
226 @page Guide_Stack_Init Stack Initialization\r
227 \r
228 @section Stack_Init_SD Sequence Diagram\r
229 \r
230 @image html seq_stack_init.png\r
231 \r
232 @note API calls take only important parameters. We omitted some of the parameters for clarity.\r
233 \r
234 The asynchronous processing block handles incoming network traffic including packet processing, scheduled tasks including communication timeouts and callbacks to the application resulting from these activities.\r
235  \r
236 @section Stack_Init_CPP Stack Initialization in C++\r
237 \r
238 @code {.cpp}\r
239     // Create PlatformConfig object\r
240     PlatformConfig cfg;\r
241     cfg.ipAddress = "134.134.161.33";\r
242     cfg.port = 5683;\r
243     cfg.mode = ModeType::Client;\r
244     cfg.serviceType = ServiceType::InProc;\r
245 \r
246     // Create a OCPlatform instance.\r
247     // Note: Platform creation is synchronous call.\r
248     try\r
249     {\r
250         OCPlatform platform(cfg);\r
251     }catch(OCException& e)\r
252     {\r
253         //Handle error\r
254     }\r
255  @endcode\r
256 \r
257 Stack initialization in C++ consists of:\r
258 @li Creating a OCPlatform object with Platform configuration which allows definition of role operation (server or client), stack operation (in-process or out-of-process), etc.\r
259 @note\r
260 @li This is a synchronous call. The application will receive an exception if platform object creation fails.\r
261 @li The C++ SDK handles all of the memory allocation and collection. Therefore, the application need not worry about memory management related to the stack.\r
262 @li Platform creation happens on the main thread while the message pump happens on a worker thread.\r
263 \r
264 \r
265 \r
266 \r
267 \r
268 ********************************************************************\r
269 \r
270 @page Guide_Register_Resource Registering A Resource\r
271 \r
272 Registering a resource requires two basic items:\r
273 \li A handler to process requests from the stack, and\r
274 \li A URI path to register the resource. \r
275 The URI path should be rooted (in other words, start with a slash). The stack will construct the fully qualified URI by adding the URI authority to the provided URI path. For example, given a service running on port 5683 in a device at IP address 192.168.1.1, if the application registers a resource with a URI path "/light/1", the resulting fully qualified URI is "oc://192.168.1.1:5683/light/1", which uniquely identifies the resource's location (IP address port and path).\r
276 @note Only one resource can be registered at a given URI.\r
277  \r
278 @image HTML seq_register_resource_2.png\r
279 \r
280 @section Register_Resource_SD Sequence Diagram\r
281 The following call sequence diagram outlines the operations performed in the stack when a resource is registered:\r
282 \r
283 @image HTML seq_register_resource.png\r
284 \r
285 <b>Step 1</b>:\r
286 Assuming the application has created a valid OCPlatform object, the application registers a new resource with the stack by calling OCPlatform::registerResource(...).\r
287 \r
288 In this example, the call would take the form:\r
289 \r
290         platform.registerResource(&handle, "/light/1", "light", "oc.mi.def", handler, OC_DISCOVERABLE)\r
291 \r
292 The handle is a reference to the resource that is used on other APIs. The URI path ("/light/1") is where on this server that the resource can be located. The URI path is unique; this call will fail if the application attempts to register another resource using an existing URI. The resource type ("light") and interface ("oc.mi.def") are properties of the resource used in the discovery process. The handler is a function called from the stack to process requests. The flags control how the stack should handle the resource. The OC_DISCOVERABLE flag indicates that the resource should be reported if a client performs a resource discovery on this server.\r
293 \r
294 <b>Step 2</b>:\r
295 \r
296 The OCPlatform::registerResource(...) method delegates the call to the appropriate instance of the stack (in-process or out-of-process via IPC).\r
297 \r
298 <b>Step 3</b>:\r
299 The internal registerResource(...) method constructs a C++ entity handler and registers it with the C SDK using OCCreateResource(...).\r
300 \r
301 In this example, the call would take the form:\r
302 \r
303         OCCreateResource(&handle, "light", "oc.mi.def", "/light/1", handler, OC_ DISCOVERABLE)\r
304 \r
305 Many of these parameters are passed through to the C SDK directly. However, the entity handler is a proxy function for the handler passed from OCPlatform::registerResource(...).\r
306  \r
307 @section Register_Resource_CPP Register Resource in C++ [Server]\r
308 \r
309 @code{.cpp}\r
310     OCResourceHandle resourceHandle;\r
311     std::string resourceURI = "/light/1"; \r
312     std::string resourceTypeName = "alpha.light\r
313     std::string resourceInterface = DEFAULT_INTERFACE; \r
314     uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;\r
315 \r
316     OCStackResult result = platform.registerResource(resourceHandle, \r
317                                                         resourceURI,\r
318                                                         resourceTypeName,\r
319                                                         resourceInterface,\r
320                                                         &entityHandler,\r
321                                                         resourceProperty);\r
322 \r
323     if (OC_STACK_OK == result)\r
324     {\r
325         //Successfull\r
326     }\r
327 \r
328 \r
329 @endcode\r
330 \r
331 \r
332 \r
333 ********************************************************************\r
334 \r
335 @page Guide_Find_Resource Finding A Resource\r
336 \r
337 This operation returns all resources of given type on the network service. This operation is sent via multicast to all services. However, the filter limits the responders to just those that support the resource type in the query. Currently only exact matches are supported.\r
338 \r
339 @image HTML seq_find_resource_2.png\r
340 \r
341 @section Find_Resource_SD Sequence Diagram\r
342 \r
343 The following sequence diagram illustrates the resource discovery process over the network when using CoAP. The mechanism is different for Bluetooth, SSDP/HTTP, etc. In the case of CoAP, a 'get' request is sent via multicast to all IoTivity devices. Each device processes the query and responds if the request filter is satisfied. \r
344 \r
345 In the following example, the client requests all of the light resources with a resource type (rt). Both lights respond to the request, but the fan does not.\r
346 \r
347 @image HTML seq_find_resource_3.png\r
348 \r
349 \r
350 The following sequence diagram describes the call sequence for discovery from the client side.\r
351 @image HTML seq_find_resource.png\r
352 \r
353 Notes:\r
354 \li Assuming that the client has a properly initialized OCPlatform object, a C++ SDK client can discover resources by calling OCPlatform::findResources(...).\r
355 \r
356 In this example, the call would take the form:\r
357 \r
358         platform.findResources("", "/oc/core?rt=alpha.light", findHandler)\r
359 \r
360 The first parameter is the URI authority (target host), which, when empty, indicates that this is for all nodes. The second parameter ("/oc/core?rt=alpha.light") is the URI path and URI query. The URI path ("/oc/core") indicates the resource and the URI query ("rt=alpha.light") is the filter.\r
361 \r
362 \li The SDK call findResources(...) internally delegates the call directly to the in-process or to the out-of process stack via IPC based on the stack configuration.\r
363 \li Within the stack, findResource(...) calls the C API function OCDoResource(...). In this example, the call is OCDoResource(&handle, OC_REST_GET, "/oc/core?rt=alpha.light", 0, 0, OC_NON_CONFIRMABLE,  ...)\r
364 \li OCDoResource determines which transport is needed to dispatch the request and delegates the call. In the case of CoAP, the following calls are made:\r
365         - Calls OCDoCoapResource(OC_REST_GET, OC_NON_CONFIRMABLE, token, "/oc/core?rt=alpha.light", 0). The token in this example is a nonce that ties a CoAP response back to the CoAP request. Internally, this method creates the CoAP PDU for dispatching.\r
366         - Calls coap_send(context, host, pdu), which is a wrapper for the implementation below.\r
367         - Calls coap_send_impl(context, host, packet), which dispatches the packet to the socket and does the appropriate CoAP bookkeeping.\r
368         - Calls OCSend(socket, buffer, size...), which is a wrapper for the socket implementation as the functions for dispatching a UDP packet can vary in the embedded systems.\r
369 \li Servers that offer the resource on the network will reply to the query. The message pump that is evoked from the OCProcess(...) function in the C SDK receives these response packets and dispatches them to the callback associated with the original request based on the CoAP message ID. These responses will come back at the timing defined by their servers. The client stack has timeouts for these responses that are listed in the appendices.\r
370 \li As previously mentioned, the stack matches the response to the original request using the message ID and send the results to the callback associated with the request. At this level, the raw payload is presented in JSON format. It is the responsibility of the callback passed to OCDoResource(...) to parse this result.\r
371 \li The C++ SDK provides a callback to OCDoResource(...) that will parse the results, construct collections of OCResource objects from the response, and pass them to a C++ client using the handler passed to the platform.findResource(...) method. The handler will be called once for each resource server that responds to the query.\r
372 \r
373 Notes:\r
374 \li Some of the API call parameters have been omitted for brevity.\r
375 \li The findResource() method can be used in the following ways:\r
376         - Find all resources on the network that match the provided criteria\r
377         - Query a specific (single) server for the resources that it provides matching the provided criteria\r
378 \li The findResource() method may be used multiple times to find a resource\r
379 \li The findResource() callback is called from the message pump thread in multithreaded environments\r
380 \li Blocking in the findResource() callback will block other stack processing including servicing the network I/O which can cause delays and missed packets.\r
381 \r
382 <b>Detailed server call sequence diagram</b>\r
383 The following sequence diagram illustrates the call sequence for discovery from the server side. \r
384 \r
385 @note When the request is sent to all nodes, all nodes will run through this sequence.\r
386 \r
387 @image HTML seq_find_resource_4.png\r
388 \r
389 Notes:\r
390 \li The discovery request under CoAP is handled like any other resource GET request. The request can be received via unicast or multicast, but the response, if any, is always sent via unicast.\r
391 \li The stack dispatches the request to an entity handler that is defined by the stack.\r
392 \li The handler for "/oc/core", processes the URI query, if any, and builds a list of resources that match the criteria and returns the result in JSON to the network transport.\r
393 \li In the case of CoAP, if the request is made to all nodes (multicast) and the resource list is empty, no response is sent to the clients. If the request is directed (unicast) or the resource list has results, the response is sent unicast back the client.\r
394 \r
395 \r
396 @section Find_Resource_CPP Register Resource in C++ [Client]\r
397 \r
398 @code{.cpp}\r
399 // Callback to found resources\r
400     void foundResource(std::shared_ptr<OCResource> resource)\r
401     {\r
402             \r
403     std::string resourceURI;\r
404     std::string hostAddress;\r
405     try\r
406     {\r
407         // Do some operations with resource object.\r
408         if(resource)\r
409         {\r
410             std::cout<<"DISCOVERED Resource:"<<std::endl;\r
411             // Get the resource URI\r
412             resourceURI = resource->uri();\r
413             std::cout << "\tURI of the resource: " << resourceURI << std::endl;\r
414 \r
415             // Get the resource host address\r
416             hostAddress = resource->host();\r
417             std::cout << "\tHost address of the resource: " << hostAddress << std::endl;\r
418 \r
419             // Get the resource types\r
420             std::cout << "\tList of resource types: " << std::endl;\r
421             for(auto &resourceTypes : resource->getResourceTypes())\r
422             {\r
423                 std::cout << "\t\t" << resourceTypes << std::endl;\r
424             }\r
425 \r
426             // Get the resource interfaces\r
427             std::cout << "\tList of resource interfaces: " << std::endl;\r
428             for(auto &resourceInterfaces : resource->getResourceInterfaces())\r
429             {\r
430                 std::cout << "\t\t" << resourceInterfaces << std::endl;\r
431             }\r
432 \r
433             if(resourceURI == "/a/light1")\r
434             {\r
435                 // Found interested resource\r
436             }\r
437         }\r
438         else\r
439         {\r
440             // Resource is invalid\r
441             std::cout << "Resource is invalid" << std::endl;\r
442         }\r
443 \r
444     }\r
445     catch(std::exception& e)\r
446     {\r
447         //log\r
448     }\r
449 \r
450     }\r
451 \r
452 \r
453     try\r
454     {\r
455         OCPlatform platform(cfg);\r
456 \r
457         // Find all resources\r
458         platform.findResource("", "coap://224.0.1.187/oc/core?rt=alpha.light", &foundResource);\r
459 \r
460     }catch(OCException& e)\r
461     {\r
462         //Handle Error\r
463     }\r
464 \r
465 \r
466 @endcode\r
467 \r
468 @section Find_Resource_OTA_Request Over the air Request\r
469 \r
470 The request is sent to all nodes on the network:\r
471 \r
472 <table cellspacing="0" cellpadding="0" border=1>\r
473 \r
474 <tr>\r
475 <td valign="top" ><p>Field</p></td>\r
476 <td valign="top" ><p>Value</p></td>\r
477 <td valign="top" ><p>Note(s)</p></td>\r
478 </tr>\r
479 \r
480 <tr>\r
481 <td valign="top" ><p>Address</p></td>\r
482 <td valign="top" ><p>224.0.1.187:5683</p></td>\r
483 <td valign="top" ><p>Multicast packet</p></td>\r
484 </tr>\r
485 \r
486 <tr>\r
487 <td valign="top" ><p>Header</p></td>\r
488 <td valign="top" ><p>NON, GET, MID=0x7d40</p></td>\r
489 <td valign="top" ><p>Multicast discovery request should be non-confirmable</p></td>\r
490 </tr>\r
491 \r
492 <tr>\r
493 <td valign="top" ><p>URI-Path</p></td>\r
494 <td valign="top" ><p>oc</p></td>\r
495 <td rowspan="3" valign="top" ><p>"/oc/core?rt=alpha.light"</p></td>\r
496 </tr>\r
497 \r
498 <tr>\r
499 <td valign="top" ><p>URI-Path</p></td>\r
500 <td valign="top" ><p>core</p></td>\r
501 </tr>\r
502 \r
503 <tr>\r
504 <td valign="top" ><p>URI-Query</p></td>\r
505 <td valign="top" ><p>rt=alpha.light</p></td>\r
506 <td valign="middle" ><p><br />\r
507 </p></td>\r
508 </tr>\r
509 \r
510 <tr>\r
511 <td valign="top" ><p>Accept</p></td>\r
512 <td valign="top" ><p>application/json</p></td>\r
513 <td valign="top" ><p><br />\r
514 </p></td>\r
515 </tr>\r
516 \r
517 \r
518 </table>\r
519 \r
520 \r
521 \r
522 @section Find_Resource_OTA_Response Over the air Response(s)\r
523 \r
524 Assuming that all of the representative devices (see @ref Guide_Representative_Devices "Representative Devices") are online, three responses are expected. Only the three devices with light resources respond; the list of resources has been filtered to contain just the resources that match the criteria.\r
525 \r
526 <b>From 192.168.1.11</b>:\r
527 \r
528 <table cellspacing="0" cellpadding="0" border=1> \r
529 <tr>\r
530 <td valign="top" ><p>Field</p></td>\r
531 <td valign="top" ><p>Value</p></td>\r
532 <td valign="top" ><p>Explanation</p></td>\r
533 </tr>\r
534 \r
535 <tr>\r
536 <td valign="top" ><p>Address</p></td>\r
537 <td valign="top" ><p>192.168.1.1:5683</p></td>\r
538 <td valign="top" ><p>Client Address</p></td>\r
539 </tr>\r
540 \r
541 <tr>\r
542 <td valign="top" ><p>Header</p></td>\r
543 <td valign="top" ><p>ACK, CONTENT, MID=0x7d40</p></td>\r
544 <td valign="top" ><p>Success w/content</p></td>\r
545 </tr>\r
546 \r
547 <tr>\r
548 <td valign="top" ><p>Content</p>\r
549 \r
550 <p>Format</p></td>\r
551 <td valign="top" ><p>application/json</p></td>\r
552 <td valign="top" ><p><br />\r
553 </p></td>\r
554 </tr>\r
555 \r
556 <tr>\r
557 <td valign="top" ><p>Payload</p></td>\r
558 <td valign="top" ><p>[</p>\r
559 \r
560 <p>{ "href" : "/light/1", "rt":["alpha.light"], "if":["oc.mi.def"], "obs":1}</p>\r
561 \r
562 <p>]</p></td>\r
563 <td valign="top" ><p><br />\r
564 </p></td>\r
565 </tr>\r
566 \r
567 </table>\r
568 \r
569 <b>From 192.168.1.12</b>:\r
570 \r
571 <table cellspacing="0" cellpadding="0" border=1>\r
572 \r
573 <tr>\r
574 <td valign="top" ><p>Field</p></td>\r
575 <td valign="top" ><p>Value</p></td>\r
576 <td valign="top" ><p>Explanation</p></td>\r
577 </tr>\r
578 \r
579 <tr>\r
580 <td valign="top" ><p>Address</p></td>\r
581 <td valign="top" ><p>192.168.1.1:5683</p></td>\r
582 <td valign="top" ><p>Client Address</p></td>\r
583 </tr>\r
584 \r
585 <tr>\r
586 <td valign="top" ><p>Header</p></td>\r
587 <td valign="top" ><p>ACK, CONTENT, MID=0x7d40</p></td>\r
588 <td valign="top" ><p>Success w/content</p></td>\r
589 </tr>\r
590 \r
591 <tr>\r
592 <td valign="top" ><p>Content</p>\r
593 \r
594 <p>Format</p></td>\r
595 <td valign="top" ><p>application/json</p></td>\r
596 <td valign="top" ><p><br />\r
597 </p></td>\r
598 </tr>\r
599 \r
600 <tr>\r
601 <td valign="top" ><p>Payload</p></td>\r
602 <td valign="top" ><p>[</p>\r
603 \r
604 <p>{ "href" : "/light/2", "rt":["alpha.light"], "if":["oc.mi.def"], "obs":1}</p>\r
605 \r
606 <p>]</p></td>\r
607 <td valign="top" ><p><br />\r
608 </p></td>\r
609 </tr>\r
610 \r
611 </table>\r
612 \r
613 \r
614 \r
615 <b>From 192.168.1.13</b>:\r
616 \r
617 <table cellspacing="0" cellpadding="0" border=1> \r
618 <tr>\r
619 <td valign="top" ><p>Field</p></td>\r
620 <td valign="top" ><p>Value</p></td>\r
621 <td valign="top" ><p>Explanation</p></td>\r
622 </tr>\r
623 \r
624 <tr>\r
625 <td valign="top" ><p>Address</p></td>\r
626 <td valign="top" ><p>192.168.1.1:5683</p></td>\r
627 <td valign="top" ><p>Client Address</p></td>\r
628 </tr>\r
629 \r
630 <tr>\r
631 <td valign="top" ><p>Header</p></td>\r
632 <td valign="top" ><p>ACK, CONTENT, MID=0x7d40</p></td>\r
633 <td valign="top" ><p>Success w/content</p></td>\r
634 </tr>\r
635 \r
636 <tr>\r
637 <td valign="top" ><p>Content</p>\r
638 \r
639 <p>Format</p></td>\r
640 <td valign="top" ><p>application/json</p></td>\r
641 <td valign="top" ><p><br />\r
642 </p></td>\r
643 </tr>\r
644 \r
645 <tr>\r
646 <td valign="top" ><p>Payload</p></td>\r
647 <td valign="top" ><p>[</p>\r
648 \r
649 <p>{ "href" : "/light/1", "rt":["alpha.light"], "if":["oc.mi.def"], "obs":1},</p>\r
650 \r
651 <p>{ "href" : "/light/2", "rt":["alpha.light"], "if":["oc.mi.def"], "obs":1}</p>\r
652 \r
653 <p>]</p></td>\r
654 <td valign="top" ><p><br />\r
655 </p></td>\r
656 </tr>\r
657 \r
658 </table>\r
659 \r
660 \r
661 \r
662 ********************************************************************\r
663 \r
664 @page Guide_PUT Setting a resource state [PUT]\r
665 \r
666 This operation sets the value of a simple resource. In this example, we turn on a light resource and set the brightness to 50%.\r
667 \r
668 @section PUT_SD Sequence Diagram\r
669 \r
670 @image HTML seq_put.png\r
671 \r
672 Steps:\r
673 1.      The client application calls resource.put(...) to set representation of resource. \r
674 Example call: \r
675 resource.put(attributeMap, queryParamsMap, &onPut);   \r
676 2.      Client SDK internally calls the setResourceAttributes function of the client wrapper.\r
677 Example call:\r
678 OCDoResource(OC_REST_PUT, "//192.168.1.11/light/1, 0, 0, OC_CONFIRMABLE, callback);\r
679 3.      Send PUT request to remote device\r
680 4.      The OCProcess() service function (server-side message pump) reads the packet from the socket and dispatches the request to the entity handler for the provided URI.\r
681 5.      The entity handler, which was provided by an upper layer when the resource was registered, parses the representation and in the case of the C++ API passes the results to the upper layer handler. In a C only environment, the results would also be processed in the entity handler.\r
682 6.      The upper layer entity handler written by the app developer/vendor is invoked, and response is formed accordingly.\r
683 7.      The upper layer entity handler returns success or failure with a response.\r
684 8.      Returns   success or failure to lower layer for transmission to client.\r
685 9.      Returns success or failure to lower layer for transmission to client.\r
686 10.     Returns success or failure to lower layer for transmission to client.\r
687 11.     Result is formatted and sent over network to client\r
688 12.     The OCProcess() service function (client-side message pump) reads results and passes the results back to the client application via the callback passed to OCDoResource\r
689 \r
690 \r
691 @section PUT__Client_CPP Set Resource's State [PUT] in C++ [Client]\r
692 \r
693 @code{.cpp}\r
694 void putLightRepresentation(std::shared_ptr<OCResource> resource)\r
695 {\r
696     if(resource)\r
697     {\r
698         OCRepresentation rep;\r
699 \r
700         std::cout << "Putting light representation..."<<std::endl;\r
701         // Create AttributeMap\r
702         AttributeMap attributeMap;\r
703         // Add the attribute name and values in the attribute map\r
704         AttributeValues stateVal;\r
705         stateVal.push_back("true");\r
706 \r
707         AttributeValues powerVal;\r
708         powerVal.push_back("10");\r
709 \r
710         attributeMap["state"] = stateVal;\r
711         attributeMap["power"] = powerVal;\r
712 \r
713         // Create QueryParameters Map and add query params (if any)\r
714         QueryParamsMap queryParamsMap;\r
715 \r
716         rep.setAttributeMap(attributeMap);\r
717 \r
718         // Invoke resource's put API with attribute map, query map and the callback parameter\r
719         resource->put(rep, queryParamsMap, &onPut);\r
720     }\r
721 }\r
722 \r
723 // callback handler on PUT request\r
724 void onPut(const OCRepresentation& rep, const int eCode)\r
725 {\r
726     if(eCode == SUCCESS_RESPONSE)\r
727     {\r
728         std::cout << "PUT request was successful" << std::endl;\r
729 \r
730         AttributeMap attributeMap = rep.getAttributeMap();\r
731 \r
732         for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)\r
733         {\r
734             std::cout << "\tAttribute name: "<< it->first << " value: ";\r
735             for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)\r
736             {\r
737                 std::cout <<"\t"<< *valueItr << " ";\r
738             }\r
739 \r
740             std::cout << std::endl;\r
741         }\r
742 \r
743         std::vector<OCRepresentation> children = rep.getChildren();\r
744 \r
745         for(auto oit = children.begin(); oit != children.end(); ++oit)\r
746         {\r
747             attributeMap = oit->getAttributeMap();\r
748 \r
749             for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)\r
750             {\r
751                 std::cout << "\tAttribute name: "<< it->first << " value: ";\r
752                 for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)\r
753                 {\r
754                     std::cout <<"\t"<< *valueItr << " ";\r
755                 }\r
756 \r
757                 std::cout << std::endl;\r
758             }\r
759         }\r
760 \r
761     }\r
762     else\r
763     {\r
764         std::cout << "onPut Response error: " << eCode << std::endl;\r
765         std::exit(-1);\r
766     }\r
767 }\r
768 \r
769 @endcode\r
770 \r
771 @section PUT_Server_CPP Set Resource's State [PUT] in C++ [Server]\r
772 \r
773 @code{.cpp}\r
774 //Entity handle sample for PUT\r
775             if(requestType == "PUT")\r
776             {\r
777                 cout << "\t\t\trequestType : PUT\n";\r
778 \r
779                 // Check for query params (if any)\r
780                 QueryParamsMap queryParamsMap = request->getQueryParameters();\r
781 \r
782                 cout << "\t\t\tquery params: \n";\r
783                 for(auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)\r
784                 {\r
785                     cout << "\t\t\t\t" << it->first << ":" << it->second << endl;\r
786                 }\r
787 \r
788                 // Get the representation from the request\r
789                 OCRepresentation rep = request->getResourceRepresentation();\r
790 \r
791                 myLightResource.setRepresentation(rep); // See code snippet below\r
792 \r
793                 // Do related operations related to PUT request // See code snippet below\r
794                 rep = myLightResource.getRepresentation();\r
795 \r
796                 if(response)\r
797                 {\r
798                     \r
799                     response->setErrorCode(200);\r
800 \r
801                     auto findRes = queryParamsMap.find("if");\r
802 \r
803                     if(findRes != queryParamsMap.end())\r
804                     {\r
805                         response->setResourceRepresentation(rep, findRes->second);\r
806                     }\r
807                     else\r
808                     {\r
809                         response->setResourceRepresentation(rep, DEFAULT_INTERFACE);\r
810                     }\r
811                 }\r
812 }\r
813 \r
814     void setRepresentation(OCRepresentation& light)\r
815     {\r
816         AttributeMap attributeMap = light.getAttributeMap();\r
817 \r
818         if(attributeMap.find("state") != attributeMap.end() && attributeMap.find("power") != attributeMap.end())\r
819         {\r
820             cout << "\t\t\t" << "Received representation: " << endl;\r
821             cout << "\t\t\t\t" << "power: " << attributeMap["power"][0] << endl;\r
822             cout << "\t\t\t\t" << "state: " << attributeMap["state"][0] << endl;\r
823 \r
824             m_state = attributeMap["state"][0].compare("true") == 0;\r
825             m_power= std::stoi(attributeMap["power"][0]);\r
826         }\r
827     }\r
828 \r
829     OCRepresentation getRepresentation()\r
830     {\r
831         OCRepresentation light;\r
832 \r
833         light.setUri(m_lightUri);\r
834 \r
835         std::vector<std::string> interfaces;\r
836         //interfaces.push_back(m_lightInterface);\r
837 \r
838         light.setResourceInterfaces(interfaces);\r
839 \r
840         std::vector<std::string> types;\r
841         //types.push_back(m_lightType);\r
842 \r
843         light.setResourceTypes(types);\r
844 \r
845         AttributeMap attributeMap;\r
846         AttributeValues stateVal;\r
847         if(m_state)\r
848         {\r
849             stateVal.push_back("true");\r
850         }\r
851         else\r
852         {\r
853             stateVal.push_back("false");\r
854         }\r
855 \r
856         AttributeValues powerVal;\r
857         powerVal.push_back(to_string(m_power));\r
858 \r
859         attributeMap["state"] = stateVal;\r
860         attributeMap["power"] = powerVal;\r
861 \r
862         light.setAttributeMap(attributeMap);\r
863 \r
864         return light;\r
865     }\r
866 \r
867 @endcode\r
868 \r
869 \r
870 @section PUT_OTA_Response Over the air request\r
871 \r
872 In this example, we are pushing state to one of the lights. At this point, the resource was discovered by its type, and we understand its interface and the attributes exposed by the resource.\r
873 \r
874 <table cellspacing="0" cellpadding="0" border=1> \r
875 \r
876 <tr>\r
877 <td valign="top" ><p>Field</p></td>\r
878 <td valign="top" ><p>Value</p></td>\r
879 <td valign="top" ><p>Note(s)</p></td>\r
880 </tr>\r
881 \r
882 <tr>\r
883 <td valign="top" ><p>Address</p></td>\r
884 <td valign="top" ><p>192.168.1.13:5683</p></td>\r
885 <td valign="top" ><p>Unicast packet</p></td>\r
886 </tr>\r
887 \r
888 <tr>\r
889 <td valign="top" ><p>Header</p></td>\r
890 <td valign="top" ><p>CON, PUT, MID=0x7d41</p></td>\r
891 <td valign="top" ><p>Confirmation is requested</p></td>\r
892 </tr>\r
893 \r
894 <tr>\r
895 <td valign="top" ><p>URI-Path</p></td>\r
896 <td valign="top" ><p>light</p></td>\r
897 <td rowspan="2" valign="top" ><p>"/light/1"</p></td>\r
898 </tr>\r
899 \r
900 <tr>\r
901 <td valign="top" ><p>URI-Path</p></td>\r
902 <td valign="top" ><p>1</p></td>\r
903 </tr>\r
904 \r
905 <tr>\r
906 <td valign="top" ><p>Content-Type</p></td>\r
907 <td valign="top" ><p>application/json</p></td>\r
908 <td valign="top" ><p><br />\r
909 </p></td>\r
910 </tr>\r
911 \r
912 <tr>\r
913 <td valign="top" ><p>Payload</p></td>\r
914 <td valign="top" ><p>{</p>\r
915 \r
916 <p>"power" : 1,</p>\r
917 \r
918 <p>"level" : 5</p>\r
919 \r
920 <p>}</p></td>\r
921 <td valign="top" ><p><br />\r
922 </p></td>\r
923 </tr>\r
924 \r
925 </table>\r
926 \r
927 \r
928 @section PUT_OTA_Response Over the air response(s)\r
929 \r
930 Assuming that the request is valid and the resource is able to complete the transition, the following represents a successful change in state.\r
931 \r
932 <b>From 192.168.1.13</b>:\r
933 \r
934 <table cellspacing="0" cellpadding="0" border=1> \r
935 \r
936 <tr>\r
937 <td valign="top" ><p>Field</p></td>\r
938 <td valign="top" ><p>Value</p></td>\r
939 <td valign="top" ><p>Explanation</p></td>\r
940 </tr>\r
941 \r
942 <tr>\r
943 <td valign="top" ><p>Address</p></td>\r
944 <td valign="top" ><p>192.168.1.1:5683</p></td>\r
945 <td valign="top" ><p>Client Address</p></td>\r
946 </tr>\r
947 \r
948 <tr>\r
949 <td valign="top" ><p>Header</p></td>\r
950 <td valign="top" ><p>ACK, CHANGED, MID=0x7d41</p></td>\r
951 <td valign="top" ><p>Success (changed)</p></td>\r
952 </tr>\r
953 \r
954 </table>\r
955 \r
956 \r
957 \r
958 **********************************************************************\r
959 \r
960 @page Guide_GET Querying resource State [GET]\r
961 \r
962 This operation fetches the value of a simple resource. In this example, we fetch the state from the light resource.\r
963 \r
964 @section GET_SD Sequence Diagram\r
965 @image HTML seq_get.png\r
966 \r
967 Steps:\r
968 1.      The client application calls resource.get(...) to retrieve a representation from the resources.\r
969 2.      The call is marshalled to the stack which is either running in-process or out-of-process (daemon).\r
970 3.      The C API is called to dispatch the request. The call may look like the following:\r
971 OCDoResource(OC_REST_GET, "//192.168.1.11/light/1, 0, 0, OC_CONFIRMABLE, callback); \r
972 4.      Where CoAP is used as a transport, the lower stack will send a GET request to the target server.\r
973 5.      On the server side, the OCProcess() function (message pump) receives and parses the request from the socket, then dispatches it to the correct entity handler based on the URI of the request.\r
974 6.      Where the C++ API is used, the C++ entity handler parses the payload and marshals it to the client application depending on if the server stack is running in-process or out-of-process (daemon).\r
975 7.      The C++ SDK passes it up the C++ handler associated with the OCResource.\r
976 8.      The handler returns the result code and representation to the SDK.\r
977 9.      The SDK marshals the result code and representation to the C++ entity handler.\r
978 10.     The entity handler returns the result code and representation to the CoAP protocol.\r
979 11.     The CoAP protocol transports the results to the client device.\r
980 12.     The results are returned the OCDoResource callback.\r
981 13.     The results are returned to the C++ client application's asyncResultCallback.\r
982 \r
983 @section GET_Client_CPP Querying resource State [GET] in C++ [Client]\r
984 @code{.cpp}\r
985 // Local function to get representation of light resource\r
986 void getLightRepresentation(std::shared_ptr<OCResource> resource)\r
987 {\r
988     if(resource)\r
989     {\r
990         std::cout << "Getting Light Representation..."<<std::endl;\r
991         // Invoke resource's get API with the callback parameter\r
992 \r
993         QueryParamsMap test;\r
994         resource->get(test, &onGet);\r
995     }\r
996 }\r
997 \r
998 // callback handler on GET request\r
999 void onGet(const OCRepresentation& rep, const int eCode)\r
1000 {\r
1001     if(eCode == SUCCESS_RESPONSE)\r
1002     {\r
1003         std::cout << "GET request was successful" << std::endl;\r
1004 \r
1005         AttributeMap attributeMap = rep.getAttributeMap();\r
1006 \r
1007         std::cout << "Resource URI: " << rep.getUri() << std::endl;\r
1008 \r
1009         for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)\r
1010         {\r
1011             std::cout << "\tAttribute name: "<< it->first << " value: ";\r
1012             for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)\r
1013             {\r
1014                 std::cout <<"\t"<< *valueItr << " ";\r
1015             }\r
1016 \r
1017             std::cout << std::endl;\r
1018         }\r
1019 \r
1020         std::vector<OCRepresentation> children = rep.getChildren();\r
1021 \r
1022         for(auto oit = children.begin(); oit != children.end(); ++oit)\r
1023         {\r
1024             std::cout << "Child Resource URI: " << oit->getUri() << std::endl;\r
1025 \r
1026             attributeMap = oit->getAttributeMap();\r
1027 \r
1028             for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)\r
1029             {\r
1030                 std::cout << "\tAttribute name: "<< it->first << " value: ";\r
1031                 for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)\r
1032                 {\r
1033                     std::cout <<"\t"<< *valueItr << " ";\r
1034                 }\r
1035 \r
1036                 std::cout << std::endl;\r
1037             }\r
1038         }\r
1039 \r
1040         putLightRepresentation(curResource);\r
1041     }\r
1042     else\r
1043     {\r
1044         std::cout << "onGET Response error: " << eCode << std::endl;\r
1045         std::exit(-1);\r
1046     }\r
1047 }\r
1048 \r
1049 \r
1050 @endcode\r
1051 \r
1052 @section GET_Server_CPP Querying resource State [GET] in C++ [Server]\r
1053 @code{.cpp}\r
1054 \r
1055 // Handling GET request in Entity handler            \r
1056 if(requestType == "GET")\r
1057             {\r
1058                 cout << "\t\t\trequestType : GET\n";\r
1059 \r
1060                 // Check for query params (if any)\r
1061                 QueryParamsMap queryParamsMap = request->getQueryParameters();\r
1062 \r
1063                 cout << "\t\t\tquery params: \n";\r
1064                 for(QueryParamsMap::iterator it = queryParamsMap.begin(); it != queryParamsMap.end(); it++)\r
1065                 {\r
1066                     cout << "\t\t\t\t" << it->first << ":" << it->second << endl;\r
1067                 }\r
1068 \r
1069                 // Process query params and do required operations ..\r
1070 \r
1071                 // Get the representation of this resource at this point and send it as response\r
1072                 // AttributeMap attributeMap;\r
1073                 OCRepresentation rep;\r
1074                 rep = myLightResource.getRepresentation();\r
1075 \r
1076                 if(response)\r
1077                 {\r
1078                     // TODO Error Code\r
1079                     response->setErrorCode(200);\r
1080 \r
1081                     auto findRes = queryParamsMap.find("if");\r
1082 \r
1083                     if(findRes != queryParamsMap.end())\r
1084                     {\r
1085                         response->setResourceRepresentation(rep, findRes->second);\r
1086                     }\r
1087                     else\r
1088                     {\r
1089                         response->setResourceRepresentation(rep, DEFAULT_INTERFACE);\r
1090                     }\r
1091                 }\r
1092             }\r
1093 \r
1094 \r
1095 @endcode\r
1096 \r
1097 \r
1098 @section GET_OTA_Response Over the air request\r
1099 \r
1100 In this example, we are querying state from one of the lights. At this point, the resource was discovered by its type, and we understand its interface and the attributes that the resource exposes.\r
1101 \r
1102 <table cellspacing="0" cellpadding="0" border=1>\r
1103 \r
1104 <tr>\r
1105 <td valign="top" ><p>Field</p></td>\r
1106 <td valign="top" ><p>Value</p></td>\r
1107 <td valign="top" ><p>Note(s)</p></td>\r
1108 </tr>\r
1109 \r
1110 <tr>\r
1111 <td valign="top" ><p>Address</p></td>\r
1112 <td valign="top" ><p>192.168.1.11:5683</p></td>\r
1113 <td valign="top" ><p>Unicast packet</p></td>\r
1114 </tr>\r
1115 \r
1116 <tr>\r
1117 <td valign="top" ><p>Header</p></td>\r
1118 <td valign="top" ><p>CON, GET, MID=0x7d42</p></td>\r
1119 <td valign="top" ><p>Confirmation is requested</p></td>\r
1120 </tr>\r
1121 \r
1122 <tr>\r
1123 <td valign="top" ><p>URI-Path</p></td>\r
1124 <td valign="top" ><p>light</p></td>\r
1125 <td rowspan="2" valign="top" ><p>"/light/1"</p></td>\r
1126 </tr>\r
1127 \r
1128 <tr>\r
1129 <td valign="top" ><p>URI-Path</p></td>\r
1130 <td valign="top" ><p>1</p></td>\r
1131 </tr>\r
1132 \r
1133 <tr>\r
1134 <td valign="top" ><p>Accept</p></td>\r
1135 <td valign="top" ><p>application/json</p></td>\r
1136 <td valign="top" ><p><br />\r
1137 </p></td>\r
1138 </tr>\r
1139 \r
1140 </table>\r
1141 \r
1142 \r
1143 \r
1144 @section GET_OTA_Response Over the air response(s)\r
1145 \r
1146 Assuming that the request is valid, we expect the following reply from the resource.\r
1147 \r
1148 <b>From 192.168.1.11</b>:\r
1149 \r
1150 <table cellspacing="0" cellpadding="0" border=1> \r
1151 <tr>\r
1152 <td valign="top" ><p>Field</p></td>\r
1153 <td valign="top" ><p>Value</p></td>\r
1154 <td valign="top" ><p>Explanation</p></td>\r
1155 </tr>\r
1156 \r
1157 <tr>\r
1158 <td valign="top" ><p>Address</p></td>\r
1159 <td valign="top" ><p>192.168.1.1:5683</p></td>\r
1160 <td valign="top" ><p>Client Address</p></td>\r
1161 </tr>\r
1162 \r
1163 <tr>\r
1164 <td valign="top" ><p>Header</p></td>\r
1165 <td valign="top" ><p>ACK, CONTENT, MID=0x7d42</p></td>\r
1166 <td valign="top" ><p>Success w/Content</p></td>\r
1167 </tr>\r
1168 \r
1169 <tr>\r
1170 <td valign="top" ><p>Content</p>\r
1171 \r
1172 <p>Type</p></td>\r
1173 <td valign="top" ><p>application/json</p></td>\r
1174 <td valign="top" ><p><br />\r
1175 </p></td>\r
1176 </tr>\r
1177 \r
1178 <tr>\r
1179 <td valign="top" ><p>Payload</p></td>\r
1180 <td valign="top" ><p>{</p>\r
1181 \r
1182 <p>"power" : 0,</p>\r
1183 \r
1184 <p>"level" : 10</p>\r
1185 \r
1186 <p>}</p></td>\r
1187 <td valign="top" ><p><br />\r
1188 </p></td>\r
1189 </tr>\r
1190 \r
1191 </table>\r
1192 \r
1193 \r
1194 \r
1195 \r
1196 **********************************************************************\r
1197 \r
1198 @page Guide_Observe Observing resource state [Observe]\r
1199 \r
1200 This operation fetches and registers as an observer for the value of a simple resource. In this example, we fetch the state of the light resource. For more implementation details, see "Observing Resources in CoAP" listed in the referenced documents. (https://datatracker.ietf.org/doc/draft-ietf-core-observe/?include_text=1)\r
1201 \r
1202 The handling of observation registration is application specific. It should not be assumed that a resource is observable, or a resource can handle any specific number of observers. If the server responds with a success (2.xx) code, the registration is considered successful.\r
1203 \r
1204 Notifications from the server to the client may be confirmable or non-confirmable. If the client returns a RST message, the observation registration should be dropped immediately. If the client fails to acknowledge a number of confirmable requests, the server should assume that the client has abandoned the observation and drop the registration.\r
1205 \r
1206 If the observed resource is removed, the server sends a NOTFOUND status to all observers.\r
1207 \r
1208 If an observed resource fails to notify a client before the max-age of a resource value update, the client should attempt to re-register the observation.\r
1209 \r
1210 \r
1211 @section Observe_SD Sequence Diagram\r
1212 @image HTML seq_observe.png\r
1213 \r
1214 Steps:\r
1215 1.      The client application calls resource.observe(...) to retrieve a representation from the resources.\r
1216 2.      The call is marshalled to the stack which is either running in-process or out-of-process (daemon).\r
1217 3.      The C API is called to dispatch the request. The call may look like this:\r
1218 OCDoResource(OC_REST_GET | OC_REST_OBSERVE, "//192.168.1.11/light/1, 0, 0, OC_CONFIRMABLE, callback);\r
1219 4.      Where CoAP is used as a transport, the lower stack will send a GET request to the target server. The primary difference between a GET request and an observe request is that the observe request contains an observe option indicating that, in addition to querying this resource, the client wishes to get notifications if/when the resource state changes.\r
1220 5.      On the server side, the OCProcess() function (message pump) receives and parses the request from the socket, then dispatches it to the correct entity handler based on the URI of the request. The request to the entity handler will indicate that the request is both a query and subscription request. The entity handler MAY take note of this, but it is not responsible to tracking the observers. The stack tracks the observers of record.\r
1221 6.      Where the C++ API is used the C++ entity handler parses the payload and marshals it to the client application depending on if the server stack is running in-process or out-of-process (daemon).\r
1222 7.      The C++ SDK passes it up the C++ handler associated with the OCResource.\r
1223 8.      The handler returns the result code and representation to the SDK.\r
1224 9.      The SDK marshals the result code and representation to the C++ entity handler.\r
1225 10.     The entity handler returns the result code and representation to the CoAP protocol.\r
1226 11.     The CoAP protocol transport the results to the client device.\r
1227 12.     The results are returned to the OCDoResource callback.\r
1228 13.     The results are returned to the C++ client application's asyncResultCallback.\r
1229 14.     If the entity handler has registered   observers, it will periodically be called with the observe flag set so that it may sample or poll underlying hardware to determine if the state has changes.\r
1230 15.     When the application has deemed that the resource state has changed either via polling (entity handler observe) or via external signal, the application should call OCNotifyObservers(). This tells the stack the observers need updating.\r
1231 16.     For each observer of a changed resource, the entity handler is called to generate a representation that is transmitted to the observing clients. \r
1232 17.     Where CoAP is used as a transport, a packet with content is sent to the devices that have observing clients. The packets may be confirmable or non-confirmable based on application needs.\r
1233 18.     The client-side OCProcess function (message pump) receives the message and matches it to the original request based on the CoAP token ID and dispatches the appropriate \r
1234 C API callback.\r
1235 19.     The C API callback passes the final results to the C++ client application's asyncResultCallback.\r
1236 20.     When the C++ client no longer desires to receive notifications from the server, it calls observation cancellation method cancelObserve(). \r
1237 21.     The C++ cancellation method calls the OCCancel() function from the C API.\r
1238 22.     OCCancel() finds the observation that is associated with the operation and sends an observe deregistration request to the server.\r
1239 \r
1240 \r
1241 @section Observe_Client_CPP Observing resource state [Observe] in C++ [Client]\r
1242 @code{.cpp}\r
1243       if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)\r
1244             std::cout << endl << "Observe is used." << endl << endl;\r
1245         else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)\r
1246             std::cout << endl << "ObserveAll is used." << endl << endl;\r
1247 \r
1248         QueryParamsMap test;\r
1249 \r
1250         curResource->observe(OBSERVE_TYPE_TO_USE, test, &onObserve);\r
1251 \r
1252 // callback\r
1253 void onObserve(const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)\r
1254 {\r
1255     if(eCode == SUCCESS_RESPONSE)\r
1256     {\r
1257         AttributeMap attributeMap = rep.getAttributeMap();\r
1258 \r
1259         std::cout << "OBSERVE RESULT:"<<std::endl;\r
1260         std::cout << "\tSequenceNumber: "<< sequenceNumber << endl;\r
1261         for(auto it = attributeMap.begin(); it != attributeMap.end(); ++it)\r
1262         {\r
1263             std::cout << "\tAttribute name: "<< it->first << " value: ";\r
1264             for(auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr)\r
1265             {\r
1266                 std::cout <<"\t"<< *valueItr << " ";\r
1267             }\r
1268 \r
1269             std::cout << std::endl;\r
1270         }\r
1271 \r
1272         if(observe_count() > 30)\r
1273         {\r
1274             std::cout<<"Cancelling Observe..."<<std::endl;\r
1275             OCStackResult result = curResource->cancelObserve();\r
1276 \r
1277             std::cout << "Cancel result: "<< result <<std::endl;\r
1278             sleep(10);\r
1279             std::cout << "DONE"<<std::endl;\r
1280             std::exit(0);\r
1281         }\r
1282     }\r
1283     else\r
1284     {\r
1285         std::cout << "onObserve Response error: " << eCode << std::endl;\r
1286         std::exit(-1);\r
1287     }\r
1288 }\r
1289 \r
1290 \r
1291 @endcode\r
1292 \r
1293 \r
1294 \r
1295 @section Observe_Server_CPP Observing resource state [Observe] in C++ [Server]\r
1296 @code{.cpp}\r
1297 // Handling observe in server's entity handler        \r
1298 if(requestFlag == RequestHandlerFlag::ObserverFlag)\r
1299         {\r
1300             pthread_t threadId;\r
1301 \r
1302             cout << "\t\trequestFlag : Observer\n";\r
1303             gObservation = 1;\r
1304 \r
1305             static int startedThread = 0;\r
1306 \r
1307             // Observation happens on a different thread in ChangeLightRepresentation function.\r
1308             // If we have not created the thread already, we will create one here.\r
1309             if(!startedThread)\r
1310             {\r
1311                 pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL);\r
1312                 startedThread = 1;\r
1313             }\r
1314 \r
1315 // ChangeLightRepresentaion is an observation function,\r
1316 // which notifies any changes to the resource to stack\r
1317 // via notifyObservers\r
1318 void * ChangeLightRepresentation (void *param)\r
1319 {\r
1320     // This function continuously monitors for the changes\r
1321     while (1)\r
1322     {\r
1323         sleep (5);\r
1324 \r
1325         if (gObservation)\r
1326         {\r
1327             // If under observation if there are any changes to the light resource\r
1328             // we call notifyObservors\r
1329             //\r
1330             // For demostration we are changing the power value and notifying.\r
1331             myLightResource.m_power += 10;\r
1332 \r
1333             cout << "\nPower updated to : " << myLightResource.m_power << endl;\r
1334             cout << "Notifying observers with resource handle: " << myLightResource.getHandle() << endl;\r
1335 \r
1336             OCStackResult result = OCPlatform::notifyObservers(myLightResource.getHandle());\r
1337 \r
1338             if(OC_STACK_NO_OBSERVERS == result)\r
1339             {\r
1340                 cout << "No More observers, stopping notifications" << endl;\r
1341                 gObservation = 0;\r
1342             }\r
1343         }\r
1344     }\r
1345 \r
1346     return NULL;\r
1347 }\r
1348 \r
1349 \r
1350 @endcode\r
1351 \r
1352 \r
1353 \r
1354 \r
1355 @section Oberve_OTA_Response Over the air request\r
1356 \r
1357 The following observation request is basically a GET request with the observation option set.\r
1358 \r
1359 <table cellspacing="0" cellpadding="0" border=1> \r
1360 <tr>\r
1361 <td valign="top" ><p>Fields</p></td>\r
1362 <td valign="top" ><p>Value</p></td>\r
1363 <td valign="top" ><p>Notes</p></td>\r
1364 </tr>\r
1365 \r
1366 <tr>\r
1367 <td valign="top" ><p>Address</p></td>\r
1368 <td valign="top" ><p>192.168.1.11:5683</p></td>\r
1369 <td valign="top" ><p>Unicast packet</p></td>\r
1370 </tr>\r
1371 \r
1372 <tr>\r
1373 <td valign="top" ><p>Header</p></td>\r
1374 <td valign="top" ><p>CON, GET, MID=0x7d44, TOK=0x3f</p></td>\r
1375 <td valign="top" ><p>Confirmation requested</p></td>\r
1376 </tr>\r
1377 \r
1378 <tr>\r
1379 <td valign="top" ><p>Observe</p></td>\r
1380 <td valign="top" ><p>Register (0)</p></td>\r
1381 <td valign="top" ><p>This indicates registration</p></td>\r
1382 </tr>\r
1383 \r
1384 <tr>\r
1385 <td valign="top" ><p>URI-Path</p></td>\r
1386 <td valign="top" ><p>Light</p></td>\r
1387 <td valign="top" ><p>"/light/1 "</p></td>\r
1388 </tr>\r
1389 \r
1390 <tr>\r
1391 <td valign="top" ><p>URI-Path</p></td>\r
1392 <td valign="top" ><p>1</p></td>\r
1393 <td valign="top" ><p><br />\r
1394 </p></td>\r
1395 </tr>\r
1396 \r
1397 <tr>\r
1398 <td valign="top" ><p>Accept</p></td>\r
1399 <td valign="top" ><p>application/json</p></td>\r
1400 <td valign="top" ><p>Requesting result in JSON</p></td>\r
1401 </tr>\r
1402 \r
1403 </table>\r
1404 \r
1405 \r
1406 \r
1407 @section Observe_OTA_Response Over the air response(s)\r
1408 \r
1409 A successful observe request would be similar to the following:\r
1410 \r
1411 <table cellspacing="0" cellpadding="0" border=1> \r
1412 <tr>\r
1413 <td valign="top" ><p>Field</p></td>\r
1414 <td valign="top" ><p>Value</p></td>\r
1415 <td valign="top" ><p>Explanation</p></td>\r
1416 </tr>\r
1417 \r
1418 <tr>\r
1419 <td valign="top" ><p>Address</p></td>\r
1420 <td valign="top" ><p>192.168.1.1:5683</p></td>\r
1421 <td valign="top" ><p>Client Address</p></td>\r
1422 </tr>\r
1423 \r
1424 <tr>\r
1425 <td valign="top" ><p>Header</p></td>\r
1426 <td valign="top" ><p>ACK, CONTENT, MID=0x7d44, TOK=0x3f</p></td>\r
1427 <td valign="top" ><p>Success w/content</p></td>\r
1428 </tr>\r
1429 \r
1430 <tr>\r
1431 <td valign="top" ><p>Observe</p></td>\r
1432 <td valign="top" ><p>12</p></td>\r
1433 <td valign="top" ><p>Sequence number for ordering</p></td>\r
1434 </tr>\r
1435 \r
1436 <tr>\r
1437 <td valign="top" ><p>Max-Age</p></td>\r
1438 <td valign="top" ><p>30</p></td>\r
1439 <td valign="top" ><p>Indicates that the value is fresh for 30 seconds.</p>\r
1440 \r
1441 <p>It also indicates that the server should send an</p>\r
1442 \r
1443 <p>update within this time period.</p></td>\r
1444 </tr>\r
1445 \r
1446 <tr>\r
1447 <td valign="top" ><p>Content</p>\r
1448 \r
1449 <p>Type</p></td>\r
1450 <td valign="top" ><p>application/json</p></td>\r
1451 <td valign="top" ><p><br />\r
1452 </p></td>\r
1453 </tr>\r
1454 \r
1455 <tr>\r
1456 <td valign="top" ><p>Payload</p></td>\r
1457 <td valign="top" ><p>{</p>\r
1458 \r
1459 <p>"power" : 0,</p>\r
1460 \r
1461 <p>"level" : 10</p>\r
1462 \r
1463 <p>}</p></td>\r
1464 <td valign="top" ><p><br />\r
1465 </p></td>\r
1466 </tr>\r
1467 \r
1468 </table>\r
1469 \r
1470 <b>Subsequent Notifications from 192.168.1.1 </b>\r
1471 \r
1472 If the light resource is being observed and the light transitions from an off state to an on state, a notification is sent to the client from the server. The following is an example of such a notification:\r
1473 \r
1474 \r
1475 <table cellspacing="0" cellpadding="0" border=1> \r
1476 <tr>\r
1477 <td valign="top" ><p>Field</p></td>\r
1478 <td valign="top" ><p>Value</p></td>\r
1479 <td valign="top" ><p>Explanation</p></td>\r
1480 </tr>\r
1481 \r
1482 <tr>\r
1483 <td valign="top" ><p>Address</p></td>\r
1484 <td valign="top" ><p>192.168.1.1:5683</p></td>\r
1485 <td valign="top" ><p>Client Address</p></td>\r
1486 </tr>\r
1487 \r
1488 <tr>\r
1489 <td valign="top" ><p>Header</p></td>\r
1490 <td valign="top" ><p>CON, CONTENT, MID=0x7D45, TOK=0x3f</p></td>\r
1491 <td valign="top" ><p>Content, Can be confirmable or non-confirmable</p></td>\r
1492 </tr>\r
1493 \r
1494 <tr>\r
1495 <td valign="top" ><p>Observe</p></td>\r
1496 <td valign="top" ><p>15</p></td>\r
1497 <td valign="top" ><p>Monotonically increasing until overflow</p></td>\r
1498 </tr>\r
1499 \r
1500 <tr>\r
1501 <td valign="top" ><p>Max-Age</p></td>\r
1502 <td valign="top" ><p>30</p></td>\r
1503 <td valign="top" ><p>Indicates that the value is fresh for 30 seconds.</p>\r
1504 \r
1505 <p>It also indicates that the server should send an</p>\r
1506 \r
1507 <p>update within this time period.</p></td>\r
1508 </tr>\r
1509 \r
1510 <tr>\r
1511 <td valign="top" ><p>Payload</p></td>\r
1512 <td valign="top" ><p>{</p>\r
1513 \r
1514 <p>"power" : 1,</p>\r
1515 \r
1516 <p>"level" : 10</p>\r
1517 \r
1518 <p>}</p></td>\r
1519 <td valign="top" ><p><br />\r
1520 </p></td>\r
1521 </tr>\r
1522 \r
1523 </table>\r
1524 \r
1525 Since the above notification was marked confirmable, the client should acknowledge the notification with a packet such as the following:\r
1526 \r
1527 <table cellspacing="0" cellpadding="0" border=1> \r
1528 \r
1529 <tr>\r
1530 <td valign="top" ><p>Field</p></td>\r
1531 <td valign="top" ><p>Value</p></td>\r
1532 <td valign="top" ><p>Explanation</p></td>\r
1533 </tr>\r
1534 \r
1535 <tr>\r
1536 <td valign="top" ><p>Address</p></td>\r
1537 <td valign="top" ><p>192.168.1.11:5683</p></td>\r
1538 <td valign="top" ><p>Unicast packet</p></td>\r
1539 </tr>\r
1540 \r
1541 <tr>\r
1542 <td valign="top" ><p>Header</p></td>\r
1543 <td valign="top" ><p>ACK, MID=0x7D45, TOK=0x3f</p></td>\r
1544 <td valign="top" ><p>Success</p></td>\r
1545 </tr>\r
1546 \r
1547 </table>\r
1548 \r
1549 \r
1550 \r
1551 \r
1552 \r
1553 **********************************************************************\r
1554 \r
1555 \r
1556 */\r