1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 /// This sample demonstrates : running one server in main thread, another
23 /// server in a separate thread, and running 2 clients in each thread.
26 #include "iotivity_config.h"
31 #include <condition_variable>
35 #include "OCPlatform.h"
44 static std::ostringstream requestURI;
51 std::string m_resourceType;
52 OCResourceHandle m_resourceHandle;
53 OCRepresentation m_rep;
55 FooResource(std::string uri): m_isFoo(true), m_barCount (0),
56 m_uri(uri), m_resourceType("core.foo")
59 m_rep.setValue("isFoo", m_isFoo);
60 m_rep.setValue("barCount", m_barCount);
65 std::string resourceInterface = DEFAULT_INTERFACE;
67 uint8_t resourceProperty = OC_DISCOVERABLE;
69 EntityHandler eh(std::bind(&FooResource::entityHandler, this,
70 std::placeholders::_1));
71 OCStackResult result = OCPlatform::registerResource(m_resourceHandle, m_uri,
72 m_resourceType, resourceInterface, eh, resourceProperty);
73 if(OC_STACK_OK != result)
75 std::cout<<"Resource creation unsuccessful"<<std::endl;
82 OCRepresentation get()
84 m_rep.setValue("isFoo", m_isFoo);
85 m_rep.setValue("barCount", m_barCount);
90 void put(OCRepresentation& rep)
92 rep.getValue("isFoo", m_isFoo);
93 rep.getValue("barCount", m_barCount);
96 OCStackResult sendResponse(std::shared_ptr<OCResourceRequest> pRequest)
98 auto pResponse = std::make_shared<OC::OCResourceResponse>();
99 pResponse->setRequestHandle(pRequest->getRequestHandle());
100 pResponse->setResourceHandle(pRequest->getResourceHandle());
101 pResponse->setResourceRepresentation(get(), "");
102 pResponse->setErrorCode(200);
103 pResponse->setResponseResult(OC_EH_OK);
105 return OCPlatform::sendResponse(pResponse);
108 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
110 std::cout<<"\tConsumer Entity Handler:"<<std::endl;
111 OCEntityHandlerResult ehResult = OC_EH_ERROR;
115 // Note: Most of the handlers are not here, since this is for demoing client/server
116 // co-process existence. See simpleserver for a more complete example.
117 if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
119 std::cout << "\t\trequestFlag : Request"<<std::endl;
121 if(request->getRequestType() == "GET")
123 std::cout<<"\t\t\trequestType : GET"<<std::endl;
124 if(OC_STACK_OK == sendResponse(request))
129 else if (request->getRequestType() == "PUT")
131 std::cout<<"\t\t\trequestType : PUT"<<std::endl;
133 OCRepresentation rep = request->getResourceRepresentation();
135 if(OC_STACK_OK == sendResponse(request))
142 std::cout<<"\t\t\trequestType : UNSUPPORTED: " <<
143 request->getRequestType()<<std::endl;
148 std::cout <<"\t\trequestFlag : UNSUPPORTED: ";
150 if(request->getRequestHandlerFlag()== RequestHandlerFlag::ObserverFlag)
152 std::cout<<"ObserverFlag"<<std::endl;
158 std::cout << "Request Invalid!"<<std::endl;
165 void putResourceInfo(const HeaderOptions& /*headerOptions*/,
166 const OCRepresentation rep, const OCRepresentation /*rep2*/, const int eCode)
168 bool m_isFoo = false;
170 std::cout << "In PutResourceInfo" << std::endl;
172 std::cout <<"Clientside Put response to get was: "<<std::endl;
173 std::cout <<"ErrorCode: "<<eCode <<std::endl;
177 std::cout<<"Successful Put. Attributes sent were: "<<std::endl;
179 rep.getValue("isFoo", m_isFoo);
180 rep.getValue("barCount", m_barCount);
182 std::cout << "\tisFoo: "<< m_isFoo << std::endl;
183 std::cout << "\tbarCount: "<< m_barCount << std::endl;
185 std::cout<<"Actual New values are: "<<std::endl;
187 rep.getValue("isFoo", m_isFoo);
188 rep.getValue("barCount", m_barCount);
190 std::cout << "\tisFoo: "<< m_isFoo << std::endl;
191 std::cout << "\tbarCount: "<< m_barCount << std::endl;
195 void getResourceInfo(std::shared_ptr<OCResource> resource, const HeaderOptions& /*headerOptions*/,
196 const OCRepresentation rep,
199 bool m_isFoo = false;
201 std::cout << "In getResourceInfo" << std::endl;
203 std::cout<<"Clientside response to get was: "<<std::endl;
204 std::cout<<"Error Code: "<<eCode<<std::endl;
208 std::cout <<"Successful Get. Attributes are: "<<std::endl;
210 rep.getValue("isFoo", m_isFoo);
211 rep.getValue("barCount", m_barCount);
213 std::cout << "\tisFoo: "<< m_isFoo << std::endl;
214 std::cout << "\tbarCount: "<< m_barCount << std::endl;
216 std::cout << "Doing a put on q/foo" <<std::endl;
217 OCRepresentation rep2(rep);
221 rep2.setValue("isFoo", m_isFoo);
222 rep2.setValue("barCount", m_barCount);
224 resource->put(rep2, QueryParamsMap(),
225 PutCallback(std::bind(putResourceInfo, std::placeholders::_1,
226 rep2, std::placeholders::_2, std::placeholders::_3)));
230 void printResourceInfo(std::shared_ptr<OCResource> resource)
232 std::cout << "Found Resource: "<<std::endl;
233 std::cout << "\tHost: "<< resource->host()<<std::endl;
234 std::cout << "\tURI: "<< resource->uri()<<std::endl;
236 // Get the resource types
237 std::cout << "\tList of resource types: " << std::endl;
238 for(auto &resourceTypes : resource->getResourceTypes())
240 std::cout << "\t\t" << resourceTypes << std::endl;
243 // Get the resource interfaces
244 std::cout << "\tList of resource interfaces: " << std::endl;
245 for(auto &resourceInterfaces : resource->getResourceInterfaces())
247 std::cout << "\t\t" << resourceInterfaces << std::endl;
251 void foundResource2(std::shared_ptr<OCResource> resource)
253 std::cout << "In foundResource2:" << std::endl;
255 if(resource && resource->uri() == "/q/foo2")
257 printResourceInfo(resource);
259 std::cout<<"Doing a get on q/foo."<<std::endl;
261 resource->get(QueryParamsMap(),
262 GetCallback(std::bind(getResourceInfo, resource,
263 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
267 std::cout << "foundResource2: Ignoring the resource which doesn't have uri /q/foo2\n";
271 void foundResource1(std::shared_ptr<OCResource> resource)
273 std::cout << "In foundResource1:" << std::endl;
274 if(resource && resource->uri() == "/q/foo1")
276 printResourceInfo(resource);
280 std::cout << "foundResource1: Ignoring the resource which doesn't have uri /q/foo1\n";
286 std::cout << "in client1\n";
287 std::cout<<"result1:" << OCPlatform::findResource("", requestURI.str(),
288 CT_DEFAULT, foundResource1)<< std::endl;
290 // A condition variable will free the mutex it is given, then do a non-
291 // intensive block until 'notify' is called on it. In this case, since we
292 // don't ever call cv.notify, this should be a non-processor intensive version
295 std::condition_variable cv;
296 std::unique_lock<std::mutex> lock(blocker);
302 std::cout << "in client2\n";
303 std::cout<<"result2:" << OCPlatform::findResource("",
305 CT_DEFAULT, foundResource2)<< std::endl;
307 // A condition variable will free the mutex it is given, then do a non-
308 // intensive block until 'notify' is called on it. In this case, since we
309 // don't ever call cv.notify, this should be a non-processor intensive version
312 std::condition_variable cv;
313 std::unique_lock<std::mutex> lock(blocker);
319 FooResource fooRes("/q/foo2");
321 if(!fooRes.createResource())
326 // A condition variable will free the mutex it is given, then do a non-
327 // intensive block until 'notify' is called on it. In this case, since we
328 // don't ever call cv.notify, this should be a non-processor intensive version
331 std::condition_variable cv;
332 std::unique_lock<std::mutex> lock(blocker);
336 int main(int /*argc*/, char** /*argv[]*/)
339 requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.foo";
342 OC::ServiceType::InProc,
344 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
345 0, // Uses randomly available port
346 OC::QualityOfService::LowQos
349 OCPlatform::Configure(cfg);
353 // main thread running as server
354 FooResource fooRes("/q/foo1");
355 if(!fooRes.createResource())
360 // Start a server in a seperate thread
361 std::thread t(server);
366 // Start each client in a seperate thread
367 std::thread t1(client1);
370 // Start each client in a seperate thread
371 std::thread t2(client2);
374 // A condition variable will free the mutex it is given, then do a non-
375 // intensive block until 'notify' is called on it. In this case, since we
376 // don't ever call cv.notify, this should be a non-processor intensive version
379 std::condition_variable cv;
380 std::unique_lock<std::mutex> lock(blocker);
383 catch(OCException& e)
385 std::cout<< "Exception in main: "<<e.what()<<std::endl;