Removed #ifdef CA_INTs and other code cleanup.
[platform/upstream/iotivity.git] / resource / examples / simpleclientserver.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 ///
22 /// This sample provides steps to define an interface for a resource
23 /// (properties and methods) and host this resource on the server.
24 /// Additionally, it'll have a client example to discover it as well.
25 ///
26 #include <memory>
27 #include <iostream>
28 #include <stdexcept>
29 #include <condition_variable>
30 #include <map>
31 #include <vector>
32 #include "OCPlatform.h"
33 #include "OCApi.h"
34 using namespace OC;
35
36 OCConnectivityType connectivityType = OC_WIFI;
37
38 class ClientWorker
39 {
40 private:
41     bool m_isFoo;
42     int m_barCount;
43     void putResourceInfo(const HeaderOptions& headerOptions,
44             const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
45     {
46        std::cout << "In PutResourceInfo" << std::endl;
47
48        std::cout <<"Clientside Put response to get was: "<<std::endl;
49        std::cout <<"ErrorCode: "<<eCode <<std::endl;
50
51        if(eCode == 0)
52        {
53             std::cout<<"Successful Put.  Attributes sent were: "<<std::endl;
54
55             rep.getValue("isFoo", m_isFoo);
56             rep.getValue("barCount", m_barCount);
57
58             std::cout << "\tisFoo: "<< m_isFoo << std::endl;
59             std::cout << "\tbarCount: "<< m_barCount << std::endl;
60
61             std::cout<<"Actual New values are: "<<std::endl;
62
63             rep.getValue("isFoo", m_isFoo);
64             rep.getValue("barCount", m_barCount);
65
66             std::cout << "\tisFoo: "<< m_isFoo << std::endl;
67             std::cout << "\tbarCount: "<< m_barCount << std::endl;
68
69             m_cv.notify_all();
70        }
71     }
72
73     void getResourceInfo(const HeaderOptions& headerOptions, const OCRepresentation rep,
74                 const int eCode)
75     {
76         std::cout << "In getResourceInfo" << std::endl;
77
78         std::cout<<"Clientside response to get was: "<<std::endl;
79         std::cout<<"Error Code: "<<eCode<<std::endl;
80
81         if(eCode == 0)
82         {
83             std::cout <<"Successful Get.  Attributes are: "<<std::endl;
84
85             rep.getValue("isFoo", m_isFoo);
86             rep.getValue("barCount", m_barCount);
87
88             std::cout << "\tisFoo: "<< m_isFoo << std::endl;
89             std::cout << "\tbarCount: "<< m_barCount << std::endl;
90
91             std::cout << "Doing a put on q/foo" <<std::endl;
92             OCRepresentation rep2(rep);
93             m_isFoo = false;
94             m_barCount = 211;
95
96             rep2.setValue("isFoo", m_isFoo);
97             rep2.setValue("barCount", m_barCount);
98
99             m_resource->put(rep2, QueryParamsMap(),
100                 PutCallback(std::bind(&ClientWorker::putResourceInfo, this, std::placeholders::_1,
101                      rep2, std::placeholders::_2, std::placeholders::_3)));
102         }
103     }
104
105     void foundResource(std::shared_ptr<OCResource> resource)
106     {
107         std::cout << "In foundResource" << std::endl;
108         if(resource && resource->uri() == "/q/foo")
109         {
110             {
111                 std::lock_guard<std::mutex> lock(m_resourceLock);
112                 if(m_resource)
113                 {
114                     return;
115                 }
116
117                 m_resource = resource;
118             }
119
120             std::cout << "Found Resource: "<<std::endl;
121             std::cout << "\tHost: "<< resource->host()<<std::endl;
122             std::cout << "\tURI:  "<< resource->uri()<<std::endl;
123
124             // Get the resource types
125             std::cout << "\tList of resource types: " << std::endl;
126             for(auto &resourceTypes : resource->getResourceTypes())
127             {
128                 std::cout << "\t\t" << resourceTypes << std::endl;
129             }
130
131             // Get the resource interfaces
132             std::cout << "\tList of resource interfaces: " << std::endl;
133             for(auto &resourceInterfaces : resource->getResourceInterfaces())
134             {
135                 std::cout << "\t\t" << resourceInterfaces << std::endl;
136             }
137
138             std::cout<<"Doing a get on q/foo."<<std::endl;
139
140             resource->get(QueryParamsMap(),
141                 GetCallback(std::bind(&ClientWorker::getResourceInfo, this,
142                 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
143         }
144     }
145
146 public:
147     void start()
148     {
149         ostringstream requestURI;
150         requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.foo";
151
152         std::cout<<"Starting Client find:"<<std::endl;
153         FindCallback f (std::bind(&ClientWorker::foundResource, this, std::placeholders::_1));
154         std::cout<<"result:" <<
155         OCPlatform::findResource("", requestURI.str(), connectivityType, f)
156         << std::endl;
157
158         std::cout<<"Finding Resource..."<<std::endl;
159
160         {
161             std::unique_lock<std::mutex> lk(m_mutex);
162             m_cv.wait(lk);
163         }
164     }
165 private:
166     std::mutex m_mutex;
167     std::mutex m_resourceLock;
168     std::condition_variable m_cv;
169     std::shared_ptr<OCResource> m_resource;
170 };
171
172 struct FooResource
173 {
174     bool m_isFoo;
175     int m_barCount;
176     OCResourceHandle m_resourceHandle;
177     OCRepresentation m_rep;
178
179     FooResource(): m_isFoo(true), m_barCount (0)
180     {
181         m_rep.setUri("/q/foo");
182         m_rep.setValue("isFoo", m_isFoo);
183         m_rep.setValue("barCount", m_barCount);
184     }
185
186     bool createResource()
187     {
188         std::string resourceURI = "/q/foo";
189         std::string resourceTypeName = "core.foo";
190         std::string resourceInterface = DEFAULT_INTERFACE;
191
192         uint8_t resourceProperty = OC_DISCOVERABLE;
193
194         EntityHandler eh(std::bind(&FooResource::entityHandler,
195                     this, std::placeholders::_1));
196         OCStackResult result = OCPlatform::registerResource(m_resourceHandle,
197                 resourceURI, resourceTypeName,
198                                     resourceInterface,
199                                     eh, resourceProperty);
200         if(OC_STACK_OK != result)
201         {
202             std::cout<<"Resource creation unsuccessful"<<std::endl;
203             return false;
204         }
205
206         return true;
207     }
208
209     OCRepresentation get()
210     {
211         m_rep.setValue("isFoo", m_isFoo);
212         m_rep.setValue("barCount", m_barCount);
213
214         return m_rep;
215     }
216
217     void put(OCRepresentation& rep)
218     {
219         rep.getValue("isFoo", m_isFoo);
220         rep.getValue("barCount", m_barCount);
221     }
222
223     OCStackResult sendResponse(std::shared_ptr<OCResourceRequest> pRequest)
224     {
225         auto pResponse = std::make_shared<OC::OCResourceResponse>();
226         pResponse->setRequestHandle(pRequest->getRequestHandle());
227         pResponse->setResourceHandle(pRequest->getResourceHandle());
228         pResponse->setResourceRepresentation(get(), "");
229         pResponse->setErrorCode(200);
230         pResponse->setResponseResult(OC_EH_OK);
231
232         return OCPlatform::sendResponse(pResponse);
233     }
234
235     OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
236     {
237         std::cout<<"\tConsumer Entity Handler:"<<std::endl;
238         OCEntityHandlerResult ehResult = OC_EH_ERROR;
239
240         if(request)
241         {
242             // Note: Most of the handlers are not here, since this is for
243             // demoing client/server co-process existence.
244             // See simpleserver for a more complete example.
245             if(request->getRequestHandlerFlag()  == RequestHandlerFlag::RequestFlag)
246             {
247                 std::cout << "\t\trequestFlag : Request"<<std::endl;
248
249                 if(request->getRequestType() == "GET")
250                 {
251                     std::cout<<"\t\t\trequestType : GET"<<std::endl;
252                     if(OC_STACK_OK == sendResponse(request))
253                     {
254                         ehResult = OC_EH_OK;
255                     }
256                 }
257                 else if (request->getRequestType() == "PUT")
258                 {
259                     std::cout<<"\t\t\trequestType : PUT"<<std::endl;
260
261                     OCRepresentation rep = request->getResourceRepresentation();
262                     put(rep);
263                     if(OC_STACK_OK == sendResponse(request))
264                     {
265                         ehResult = OC_EH_OK;
266                     }
267                 }
268                 else
269                 {
270                     std::cout<<"\t\t\trequestType : UNSUPPORTED: "<<
271                             request->getRequestType()<<std::endl;
272                 }
273             }
274             else
275             {
276                 std::cout <<"\t\trequestFlag : UNSUPPORTED: ";
277
278                 if(request->getRequestHandlerFlag()==RequestHandlerFlag::InitFlag)
279                 {
280                     std::cout<<"InitFlag"<<std::endl;
281                 }
282                 else if(request->getRequestHandlerFlag()== RequestHandlerFlag::ObserverFlag)
283                 {
284                     std::cout<<"ObserverFlag"<<std::endl;
285                 }
286             }
287         }
288         else
289         {
290             std::cout << "Request Invalid!"<<std::endl;
291         }
292
293         return ehResult;
294     }
295
296 };
297
298 int main(int argc, char* argv[])
299 {
300
301     if(argc == 2)
302     {
303         try
304         {
305             std::size_t inputValLen;
306             int optionSelected = stoi(argv[1], &inputValLen);
307
308             if(inputValLen == strlen(argv[1]))
309             {
310                 if(optionSelected == 0)
311                 {
312                     connectivityType = OC_ETHERNET;
313                 }
314                 else if(optionSelected == 1)
315                 {
316                     connectivityType = OC_WIFI;
317                 }
318                 else
319                 {
320                     std::cout << "Invalid connectivity type selected. Using default WIFI"
321                     << std::endl;
322                 }
323             }
324             else
325             {
326                 std::cout << "Invalid connectivity type selected. Using default WIFI" << std::endl;
327             }
328         }
329         catch(exception& e)
330         {
331             std::cout << "Invalid input argument. Using WIFI as connectivity type" << std::endl;
332         }
333     }
334     else
335     {
336         std::cout<< "Usage simpleclientserver <ConnectivityType(0|1)>" << std::endl;
337         std::cout<<"    ConnectivityType: Default WIFI" << std::endl;
338         std::cout << "   ConnectivityType : 0 - ETHERNET" << std::endl;
339         std::cout << "   ConnectivityType : 1 - WIFI" << std::endl;
340     }
341
342     PlatformConfig cfg {
343         OC::ServiceType::InProc,
344         OC::ModeType::Both,
345         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
346         0,         // Uses randomly available port
347         OC::QualityOfService::LowQos
348     };
349
350     OCPlatform::Configure(cfg);
351     FooResource fooRes;
352
353     try
354     {
355
356         if(!fooRes.createResource())
357         {
358             return -1;
359         }
360
361         ClientWorker cw;
362         cw.start();
363     }
364     catch(OCException& e)
365     {
366         std::cout<< "Exception in main: "<<e.what()<<std::endl;
367     }
368
369     return 0;
370 }