d7fdeca98e966cc1422dc799f57435c1784282c3
[platform/upstream/iotivity.git] / docs / guides / HowToGuidesIndex.txt
1 /*!\r
2 \r
3 @page OCHowTo How To... Guides\r
4 \r
5 @ref Guide_Stack_Init "How to initialize the stack"\r
6 \r
7 @ref Guide_Register_Resource "How to register a resource"\r
8 \r
9 @ref Guide_Find_Resource "How to find a resource"\r
10 \r
11 @ref Guide_PUT  "How to set resource state [PUT]"\r
12 \r
13 @ref Guide_GET "How to query resource state [GET]"\r
14 \r
15 @ref Guide_Observe "How to observe resource state [Observe]"\r
16 \r
17 \r
18 \r
19 ********************************************************************\r
20 \r
21 @page Guide_Stack_Init Stack Initialization \r
22 \r
23 @section Stack_Init_SD Sequence Diagram\r
24 \r
25 @image html seq_stack_init.png\r
26 \r
27 @note API calls take only important parameters. We omitted some of the parameters for clarity.\r
28 \r
29 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
30 \r
31 @section Stack_Init_CPP Stack Initilization in C++\r
32 \r
33 @code {.cpp}\r
34     // Create PlatformConfig object\r
35     PlatformConfig cfg;\r
36     cfg.ipAddress = "134.134.161.33";\r
37     cfg.port = 5683;\r
38     cfg.mode = ModeType::Client;\r
39     cfg.serviceType = ServiceType::InProc;\r
40 \r
41     // Create a OCPlatform instance.\r
42     // Note: Platform creation is synchronous call.\r
43 \r
44     try\r
45     {\r
46         OCPlatform platform(cfg);\r
47     }catch(OCException& e)\r
48     {\r
49         //Handle error\r
50     }\r
51 @endcode\r
52 \r
53 Stack initialization in C++ consists of:\r
54 @li Creating a OCPlatform object with Platform configuration which allows to definition of role operation (server or client), stack operation (in-process or out-of-process), etc.\r
55 @note\r
56 @li This is a synchronous call. The application will receive an exception if platform object creation fails.\r
57 @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
58 @li Platform creation happens on the main thread while the message pump happens on a worker thread.\r
59 \r
60 \r
61 @section Stack_Init_C Stack Initilization in C\r
62 \r
63 @code {.c}\r
64     uint8_t ifname[] = "eth0";\r
65     uint8_t addr[20];\r
66     uint16_t port = 5683;\r
67 \r
68     /*Get IP address initialize stack */\r
69     OCGetInterfaceAddress(ifname, sizeof(ifname), AF_INET, addr, sizeof(addr));\r
70 \r
71     /* Initialize OCStack*/\r
72     if (OCInit((char *) addr, port, OC_CLIENT) != OC_STACK_OK) {\r
73         /* Handle stack initialization failure */\r
74         return 0;\r
75     }\r
76 \r
77 @endcode\r
78 \r
79 \r
80 \r
81 ********************************************************************\r
82 \r
83 @page Guide_Register_Resource Registering A Resource \r
84 \r
85 Registering a resource requires two basic items: a handler that will be called to process requests from the stack and a URI path at which the resource will be registered. \r
86 \r
87 The URI path should be rooted (meaning starts 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", resulting fully qualified URI would be "oc://192.168.1.1:5683/light/1" which uniquely identifies the resource\92s location (IP address port and path). Please note that only one resource can be registered at a given URI.\r
88 \r
89 @section Register_Resource_SD Sequence Diagram\r
90 The following call sequence diagram outlines the operations performed in the stack when a resource is registered:\r
91 \r
92 @image HTML seq_register_resource.png\r
93 \r
94 Steps:\r
95 \r
96 1) Assuming the application has created a valid OCPlatform object, the application registers a new resource with the stack by calling OCPlatform::registerResource(...). In this example, the call would take the form platform.registerResource(&handle, "/light/1", "light", "oc.mi.a", handler, OC_DISCOVERABLE). 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 and this call will fail if the application attempts to register another resource using an existing URI. The resource type ("light") and interface ("oc.mi.a") 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
97 \r
98 2) The OCPlatform::registerResource(...) method delegates the call to the appropriate instance of the stack (in-process or out-of-process via IPC).\r
99 \r
100 3) The internal registerResource(...) method constructs a C++ entity handler and registers it with the C SDK using OCCreateResource(...). In this example, the call would take the form OCCreateResource(&handle, "light", "oc.mi.a", "/light/1", handler, OC_ DISCOVERABLE). 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
101 \r
102 @section Register_Resource_CPP Register Resource in C++ [Server]\r
103 \r
104 @code{.cpp}\r
105     OCResourceHandle resourceHandle;\r
106     std::string resourceURI = "/light/1"; \r
107     std::string resourceTypeName = "alpha.light\r
108     std::string resourceInterface = DEFAULT_INTERFACE; \r
109     uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;\r
110 \r
111     OCStackResult result = platform.registerResource(resourceHandle, \r
112                                                         resourceURI,\r
113                                                         resourceTypeName,\r
114                                                         resourceInterface,\r
115                                                         &entityHandler,\r
116                                                         resourceProperty);\r
117 \r
118     if (OC_STACK_OK == result)\r
119     {\r
120         //Successfull\r
121     }\r
122 \r
123 \r
124 @endcode\r
125 \r
126 @section Register_Resource_C Register Resource in C [Server]\r
127 @code{.c}\r
128 void MyEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * request){\r
129         \r
130 }\r
131 \r
132 void createLightResource() {\r
133     OCResourceHandle handle;\r
134 \r
135     OCStackResult res = OCCreateResource(&handle,\r
136                                     "alpha.light",\r
137                                     "oc.mi.a",\r
138                                     "/light/1",\r
139                                     OC_DISCOVERABLE|OC_OBSERVABLE);\r
140 }\r
141 \r
142 \r
143 @endcode\r
144 \r
145 \r
146 ********************************************************************\r
147 \r
148 @page Guide_Find_Resource Finding A Resource\r
149 \r
150 This operation will return all of the resources of a 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. Again, currently, only exact matches are supported.\r
151 \r
152 @section Find_Resource_SD Sequence Diagram\r
153 The following sequence diagram describes the call sequence for discovery from the client side.\r
154 @image HTML seq_find_resource.png\r
155 \r
156 Notes:\r
157 \r
158 1) Assuming that the client has a properly initialized OCPlatform object, a C++ SDK client can discover resources by calling OCPlatform::findResources(...). In this example, the call would take the form platform.findResources("", "/oc/core?rt=light", findHandler). The first parameter is the URI authority (target host) which in the case where it is empty indicates that this is for all nodes. The second parameter "/oc/core?rt=light" is the URI path and URI query. The URI path ("/oc/core") indicates the resource and the URI query ("rt=light") is the filter.\r
159 \r
160 2) 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
161 \r
162 3) Within the stack, findResource(...) calls the C API function OCDoResource(...). In this example, the call would be OCDoResource(&handle, OC_REST_GET, "/oc/core?rt=light", 0, 0, OC_NON_CONFIRMABLE,  ...)\r
163 \r
164 4) 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
165     a. Calls OCDoCoapResource(OC_REST_GET, OC_NON_CONFIRMABLE, token, "/oc/core?rt=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
166     b. Calls coap_send(context, host, pdu) which is a wrapper for the implementation below.\r
167     c. Calls coap_send_impl(context, host, packet) which dispatches the packet to the socket and does the appropriate CoAP bookkeeping.\r
168     d. 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
169 \r
170 5) Servers that offer the resource on the network will reply to the query. The message pump which is evoked from the OCProcess(...) function in the C SDK, receive these response packets and dispatch them to the callback associated to 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 which are listed in the appendices.\r
171 \r
172 6) As mentioned above 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 in JSON format is presented. It is the responsibility of the callback passed to OCDoResource(...) to perform the parsing of this result.\r
173 \r
174 7) The C++ SDK provides a callback to OCDoResource(...) that will parse the results and construct collections of OCResource objects from the response and pass them to a C++ client using the handler passed to the platform.findResource(...) method. Please note that the handler will be called once for each resource server that responses to the query.\r
175 \r
176 Notes:\r
177 @li Some of the parameters of the API calls above have been omitted for brevity.\r
178 @li The findResource() method can be used in the following ways:\r
179 @li Find all resources on the network that match the provided criteria\r
180 @li Query a specific (single) server for the resources that it provides the provided criteria\r
181 @li The findResource() method may be used multiple times whenever a resource needs be found\r
182 @li The findResource() callback may continue to report discovered resources up to 100 seconds\r
183 @li The findResource() callback will called from the message pump thread in multithreaded environments\r
184 @li Blocking in the findResource() callback will block other stack processing including servicing the network I/O which cannot only cause delays but also missed packets.\r
185 \r
186 \r
187 \r
188 \r
189 @section Find_Resource_CPP Register Resource in C++ [Client]\r
190 \r
191 @code{.cpp}\r
192     // Callback to found resources\r
193     void foundResource(std::shared_ptr<OCResource> resource)\r
194     {\r
195         //Handle resource found\r
196     }\r
197 \r
198 \r
199     try\r
200     {\r
201         OCPlatform platform(cfg);\r
202 \r
203         // Find all resources\r
204         platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.light", &foundResource);\r
205 \r
206     }catch(OCException& e)\r
207     {\r
208         //Handle Error\r
209     }\r
210 \r
211 @endcode\r
212 \r
213 \r
214 @section Find_Resource_C Register Resource in C [Client]\r
215 \r
216 @code{.c}\r
217 /* This is a function called back when a device is discovered */\r
218 OCStackApplicationResult applicationDiscoverCB(OCClientResponse* response) {\r
219     OC_LOG(INFO, TAG, "Found resource\85 ");\r
220 \r
221     /* The IP Address is in response->addr */\r
222     /* The JSON Payload is in response->resJSONPayload */\r
223 \r
224     return OC_STACK_KEEP_TRANSACTION;\r
225 }\r
226 \r
227 int main() {\r
228     /* Initialize OCStack */\r
229 \r
230     /* Start a discovery query*/\r
231     char szQueryUri[64] = { 0 };\r
232     strcpy(szQueryUri, OC_EXPLICIT_DEVICE_DISCOVERY_URI); OCStackResult\r
233 \r
234     OCStackResult result = OCDoResource(\r
235                                OC_REST_GET,\r
236                                szQueryUri,\r
237                                0,\r
238                                0,\r
239                                OC_NON_CONFIRMABLE,\r
240                                applicationDiscoverCB)\r
241 \r
242     if (result != OC_STACK_OK) {\r
243         OC_LOG(ERROR, TAG, "OCStack resource error");\r
244         return 0;\r
245     }\r
246 \r
247     /* Call OCProcess() until done */\r
248 }\r
249 \r
250 @endcode\r
251 \r
252 \r
253 ********************************************************************\r
254 \r
255 @page Guide_PUT Setting a resource state [PUT]\r
256 \r
257 @section PUT_SD Sequence Diagram\r
258 \r
259 @image HTML seq_put.png\r
260 \r
261 @section PUT_Server_CPP Set Resource's State [PUT] in C++ [Server]\r
262 @section PUT__Client_CPP Set Resource's State [PUT] in C++ [Client]\r
263 \r
264 @section PUT_Server_C Set Resource's State [PUT] in C [Server]\r
265 @section PUT_Client_C Set Resource's State [PUT] in C [Client]\r
266 \r
267 \r
268 \r
269 \r
270 \r
271 **********************************************************************\r
272 \r
273 @page Guide_GET Quering resource State [GET]\r
274 \r
275 @section GET_SD Sequence Diagram\r
276 @image HTML seq_get.png\r
277 \r
278 @section GET_Server_CPP Quering resource State [GET] in C++ [Server]\r
279 @section GET_Client_CPP Quering resource State [GET] in C++ [Client]\r
280 \r
281 @section GET_Server_C Quering resource State [GET] in C [Server]\r
282 @section GET_Client_C Quering resource State [GET] in C [Client]\r
283 \r
284 \r
285 \r
286 **********************************************************************\r
287 \r
288 @page Guide_Observe Observing resource state [Observe]\r
289 \r
290 @section Observe_SD Sequence Diagram\r
291 @image HTML seq_observe.png\r
292 \r
293 @section Observe_Server_CPP Observing resource state [Observe] in C++ [Server]\r
294 @section Observe_Client_CPP Observing resource state [Observe] in C++ [Client]\r
295 \r
296 @section Observe_Server_C Observing resource state [Observe] in C [Server]\r
297 @section Observe_Client_C Observing resource state [Observe] in C [Client]\r
298 \r
299 \r
300 \r
301 **********************************************************************\r
302 \r
303 \r
304 */\r