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