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.
30 #include <condition_variable>
33 #include "OCPlatform.h"
37 static OCConnectivityType connectivityType = OC_WIFI;
39 static std::ostringstream requestURI;
46 std::string m_resourceType;
47 OCResourceHandle m_resourceHandle;
48 OCRepresentation m_rep;
50 FooResource(std::string uri): m_isFoo(true), m_barCount (0),
51 m_uri(uri), m_resourceType("core.foo")
54 m_rep.setValue("isFoo", m_isFoo);
55 m_rep.setValue("barCount", m_barCount);
60 std::string resourceInterface = DEFAULT_INTERFACE;
62 uint8_t resourceProperty = OC_DISCOVERABLE;
64 EntityHandler eh(std::bind(&FooResource::entityHandler, this,
65 std::placeholders::_1));
66 OCStackResult result = OCPlatform::registerResource(m_resourceHandle, m_uri,
67 m_resourceType, resourceInterface, eh, resourceProperty);
68 if(OC_STACK_OK != result)
70 std::cout<<"Resource creation unsuccessful"<<std::endl;
77 OCRepresentation get()
79 m_rep.setValue("isFoo", m_isFoo);
80 m_rep.setValue("barCount", m_barCount);
85 void put(OCRepresentation& rep)
87 rep.getValue("isFoo", m_isFoo);
88 rep.getValue("barCount", m_barCount);
91 OCStackResult sendResponse(std::shared_ptr<OCResourceRequest> pRequest)
93 auto pResponse = std::make_shared<OC::OCResourceResponse>();
94 pResponse->setRequestHandle(pRequest->getRequestHandle());
95 pResponse->setResourceHandle(pRequest->getResourceHandle());
96 pResponse->setResourceRepresentation(get(), "");
97 pResponse->setErrorCode(200);
98 pResponse->setResponseResult(OC_EH_OK);
100 return OCPlatform::sendResponse(pResponse);
103 OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
105 std::cout<<"\tConsumer Entity Handler:"<<std::endl;
106 OCEntityHandlerResult ehResult = OC_EH_ERROR;
110 // Note: Most of the handlers are not here, since this is for demoing client/server
111 // co-process existence. See simpleserver for a more complete example.
112 if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
114 std::cout << "\t\trequestFlag : Request"<<std::endl;
116 if(request->getRequestType() == "GET")
118 std::cout<<"\t\t\trequestType : GET"<<std::endl;
119 if(OC_STACK_OK == sendResponse(request))
124 else if (request->getRequestType() == "PUT")
126 std::cout<<"\t\t\trequestType : PUT"<<std::endl;
128 OCRepresentation rep = request->getResourceRepresentation();
130 if(OC_STACK_OK == sendResponse(request))
137 std::cout<<"\t\t\trequestType : UNSUPPORTED: " <<
138 request->getRequestType()<<std::endl;
143 std::cout <<"\t\trequestFlag : UNSUPPORTED: ";
145 if(request->getRequestHandlerFlag()==RequestHandlerFlag::InitFlag)
147 std::cout<<"InitFlag"<<std::endl;
149 else if(request->getRequestHandlerFlag()== RequestHandlerFlag::ObserverFlag)
151 std::cout<<"ObserverFlag"<<std::endl;
157 std::cout << "Request Invalid!"<<std::endl;
164 void putResourceInfo(const HeaderOptions& headerOptions,
165 const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
167 bool m_isFoo = false;
169 std::cout << "In PutResourceInfo" << std::endl;
171 std::cout <<"Clientside Put response to get was: "<<std::endl;
172 std::cout <<"ErrorCode: "<<eCode <<std::endl;
176 std::cout<<"Successful Put. Attributes sent were: "<<std::endl;
178 rep.getValue("isFoo", m_isFoo);
179 rep.getValue("barCount", m_barCount);
181 std::cout << "\tisFoo: "<< m_isFoo << std::endl;
182 std::cout << "\tbarCount: "<< m_barCount << std::endl;
184 std::cout<<"Actual New values are: "<<std::endl;
186 rep.getValue("isFoo", m_isFoo);
187 rep.getValue("barCount", m_barCount);
189 std::cout << "\tisFoo: "<< m_isFoo << std::endl;
190 std::cout << "\tbarCount: "<< m_barCount << std::endl;
194 void getResourceInfo(std::shared_ptr<OCResource> resource, const HeaderOptions& headerOptions,
195 const OCRepresentation rep,
198 bool m_isFoo = false;
200 std::cout << "In getResourceInfo" << std::endl;
202 std::cout<<"Clientside response to get was: "<<std::endl;
203 std::cout<<"Error Code: "<<eCode<<std::endl;
207 std::cout <<"Successful Get. Attributes are: "<<std::endl;
209 rep.getValue("isFoo", m_isFoo);
210 rep.getValue("barCount", m_barCount);
212 std::cout << "\tisFoo: "<< m_isFoo << std::endl;
213 std::cout << "\tbarCount: "<< m_barCount << std::endl;
215 std::cout << "Doing a put on q/foo" <<std::endl;
216 OCRepresentation rep2(rep);
220 rep2.setValue("isFoo", m_isFoo);
221 rep2.setValue("barCount", m_barCount);
223 resource->put(rep2, QueryParamsMap(),
224 PutCallback(std::bind(putResourceInfo, std::placeholders::_1,
225 rep2, std::placeholders::_2, std::placeholders::_3)));
229 void printResourceInfo(std::shared_ptr<OCResource> resource)
231 std::cout << "Found Resource: "<<std::endl;
232 std::cout << "\tHost: "<< resource->host()<<std::endl;
233 std::cout << "\tURI: "<< resource->uri()<<std::endl;
235 // Get the resource types
236 std::cout << "\tList of resource types: " << std::endl;
237 for(auto &resourceTypes : resource->getResourceTypes())
239 std::cout << "\t\t" << resourceTypes << std::endl;
242 // Get the resource interfaces
243 std::cout << "\tList of resource interfaces: " << std::endl;
244 for(auto &resourceInterfaces : resource->getResourceInterfaces())
246 std::cout << "\t\t" << resourceInterfaces << std::endl;
250 void foundResource2(std::shared_ptr<OCResource> resource)
252 std::cout << "In foundResource2:" << std::endl;
254 if(resource && resource->uri() == "/q/foo2")
256 printResourceInfo(resource);
258 std::cout<<"Doing a get on q/foo."<<std::endl;
260 resource->get(QueryParamsMap(),
261 GetCallback(std::bind(getResourceInfo, resource,
262 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
266 std::cout << "foundResource2: Ignoring the resource which doesn't have uri /q/foo2\n";
270 void foundResource1(std::shared_ptr<OCResource> resource)
272 std::cout << "In foundResource1:" << std::endl;
273 if(resource && resource->uri() == "/q/foo1")
275 printResourceInfo(resource);
279 std::cout << "foundResource1: Ignoring the resource which doesn't have uri /q/foo1\n";
285 std::cout << "in client1\n";
286 std::cout<<"result1:" << OCPlatform::findResource("", requestURI.str(),
287 connectivityType, foundResource1)<< std::endl;
289 // A condition variable will free the mutex it is given, then do a non-
290 // intensive block until 'notify' is called on it. In this case, since we
291 // don't ever call cv.notify, this should be a non-processor intensive version
294 std::condition_variable cv;
295 std::unique_lock<std::mutex> lock(blocker);
301 std::cout << "in client2\n";
302 std::cout<<"result2:" << OCPlatform::findResource("",
304 connectivityType, foundResource2)<< std::endl;
306 // A condition variable will free the mutex it is given, then do a non-
307 // intensive block until 'notify' is called on it. In this case, since we
308 // don't ever call cv.notify, this should be a non-processor intensive version
311 std::condition_variable cv;
312 std::unique_lock<std::mutex> lock(blocker);
318 FooResource fooRes("/q/foo2");
320 if(!fooRes.createResource())
325 // A condition variable will free the mutex it is given, then do a non-
326 // intensive block until 'notify' is called on it. In this case, since we
327 // don't ever call cv.notify, this should be a non-processor intensive version
330 std::condition_variable cv;
331 std::unique_lock<std::mutex> lock(blocker);
335 int main(int argc, char* argv[])
342 std::size_t inputValLen;
343 int optionSelected = std::stoi(argv[1], &inputValLen);
345 if(inputValLen == strlen(argv[1]))
347 if(optionSelected == 0)
349 connectivityType = OC_ETHERNET;
351 else if(optionSelected == 1)
353 connectivityType = OC_WIFI;
357 std::cout << "Invalid connectivity type selected. Using default WIFI"
363 std::cout << "Invalid connectivity type selected. Using default WIFI" << std::endl;
366 catch(std::exception& e)
368 std::cout << "Invalid input argument. Using WIFI as connectivity type" << std::endl;
373 std::cout<< "Usage threadingsample <ConnectivityType(0|1)>" << std::endl;
374 std::cout<<"ConnectivityType: Default WIFI" << std::endl;
375 std::cout << " ConnectivityType : 0 - ETHERNET" << std::endl;
376 std::cout << " ConnectivityType : 1 - WIFI" << std::endl;
379 requestURI << OC_WELL_KNOWN_QUERY << "?rt=core.foo";
382 OC::ServiceType::InProc,
384 "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
385 0, // Uses randomly available port
386 OC::QualityOfService::LowQos
389 OCPlatform::Configure(cfg);
393 // main thread running as server
394 FooResource fooRes("/q/foo1");
395 if(!fooRes.createResource())
400 // Start a server in a seperate thread
401 std::thread t(server);
406 // Start each client in a seperate thread
407 std::thread t1(client1);
410 // Start each client in a seperate thread
411 std::thread t2(client2);
414 // A condition variable will free the mutex it is given, then do a non-
415 // intensive block until 'notify' is called on it. In this case, since we
416 // don't ever call cv.notify, this should be a non-processor intensive version
419 std::condition_variable cv;
420 std::unique_lock<std::mutex> lock(blocker);
423 catch(OCException& e)
425 std::cout<< "Exception in main: "<<e.what()<<std::endl;