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 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 // OCClient.cpp : Defines the entry point for the console application.
23 #include "iotivity_config.h"
29 #include <condition_variable>
30 #include "OCPlatform.h"
33 #if defined(HAVE_PTHREAD_H)
36 #if defined(HAVE_WINDOWS_H)
42 struct dereference_compare
44 bool operator()(std::shared_ptr<OCResource> lhs, std::shared_ptr<OCResource> rhs )const
49 typedef std::set<std::shared_ptr<OCResource>, dereference_compare> DiscoveredResourceSet;
51 DiscoveredResourceSet discoveredResources;
52 const int SUCCESS_RESPONSE = 0;
53 std::shared_ptr<OCResource> curResource;
54 std::mutex resourceLock;
55 static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
65 Light() : m_state(false), m_power(0), m_name("")
78 void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation& rep,
79 const int& eCode, const int& sequenceNumber)
81 if(eCode == SUCCESS_RESPONSE)
83 std::cout << "OBSERVE RESULT:"<<std::endl;
84 if(sequenceNumber == (int) ObserveAction::ObserveRegister)
86 std::cout << "\tObserve Registration Confirmed: "<< std::endl;
88 else if (sequenceNumber == (int) ObserveAction::ObserveUnregister)
90 std::cout << "\tObserve Cancel Confirmed: "<< std::endl;
92 std::cout << "DONE"<<std::endl;
97 std::cout << "\tSequenceNumber: "<< sequenceNumber << std::endl;
100 rep.getValue("state", mylight.m_state);
101 rep.getValue("power", mylight.m_power);
102 rep.getValue("name", mylight.m_name);
104 std::cout << "\tstate: " << mylight.m_state << std::endl;
105 std::cout << "\tpower: " << mylight.m_power << std::endl;
106 std::cout << "\tname: " << mylight.m_name << std::endl;
108 if(observe_count() == 11)
110 std::cout<<"Cancelling Observe..."<<std::endl;
111 OCStackResult result = curResource->cancelObserve(OC::QualityOfService::HighQos);
113 std::cout << "Cancel result: "<< result << " waiting for confirmation ..." <<std::endl;
118 std::cout << "onObserve Response error: " << eCode << std::endl;
123 void onPost2(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
125 if(eCode == SUCCESS_RESPONSE || eCode == OC_STACK_RESOURCE_CHANGED)
127 std::cout << "POST request was successful" << std::endl;
129 if(rep.hasAttribute("createduri"))
131 std::cout << "\tUri of the created resource: "
132 << rep.getValue<std::string>("createduri") << std::endl;
136 rep.getValue("state", mylight.m_state);
137 rep.getValue("power", mylight.m_power);
138 rep.getValue("name", mylight.m_name);
140 std::cout << "\tstate: " << mylight.m_state << std::endl;
141 std::cout << "\tpower: " << mylight.m_power << std::endl;
142 std::cout << "\tname: " << mylight.m_name << std::endl;
145 if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
146 std::cout << std::endl << "Observe is used." << std::endl << std::endl;
147 else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
148 std::cout << std::endl << "ObserveAll is used." << std::endl << std::endl;
150 curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve,
151 OC::QualityOfService::HighQos);
156 std::cout << "onPost2 Response error: " << eCode << std::endl;
161 void onPost(const HeaderOptions& /*headerOptions*/,
162 const OCRepresentation& rep, const int eCode)
164 if(eCode == SUCCESS_RESPONSE || eCode == OC_STACK_RESOURCE_CHANGED)
166 std::cout << "POST request was successful" << std::endl;
168 if(rep.hasAttribute("createduri"))
170 std::cout << "\tUri of the created resource: "
171 << rep.getValue<std::string>("createduri") << std::endl;
175 rep.getValue("state", mylight.m_state);
176 rep.getValue("power", mylight.m_power);
177 rep.getValue("name", mylight.m_name);
179 std::cout << "\tstate: " << mylight.m_state << std::endl;
180 std::cout << "\tpower: " << mylight.m_power << std::endl;
181 std::cout << "\tname: " << mylight.m_name << std::endl;
184 OCRepresentation rep2;
186 std::cout << "Posting light representation..."<<std::endl;
188 mylight.m_state = true;
189 mylight.m_power = 55;
191 rep2.setValue("state", mylight.m_state);
192 rep2.setValue("power", mylight.m_power);
194 curResource->post(rep2, QueryParamsMap(), &onPost2, OC::QualityOfService::HighQos);
198 std::cout << "onPost Response error: " << eCode << std::endl;
203 // Local function to put a different state for this resource
204 void postLightRepresentation(std::shared_ptr<OCResource> resource)
208 OCRepresentation rep;
210 std::cout << "Posting light representation..."<<std::endl;
212 mylight.m_state = false;
213 mylight.m_power = 105;
215 rep.setValue("state", mylight.m_state);
216 rep.setValue("power", mylight.m_power);
218 // Invoke resource's post API with rep, query map and the callback parameter
219 resource->post(rep, QueryParamsMap(), &onPost, OC::QualityOfService::HighQos);
223 // callback handler on PUT request
224 void onPut(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
226 if(eCode == SUCCESS_RESPONSE || eCode == OC_STACK_RESOURCE_CHANGED)
228 std::cout << "PUT request was successful" << std::endl;
230 rep.getValue("state", mylight.m_state);
231 rep.getValue("power", mylight.m_power);
232 rep.getValue("name", mylight.m_name);
234 std::cout << "\tstate: " << mylight.m_state << std::endl;
235 std::cout << "\tpower: " << mylight.m_power << std::endl;
236 std::cout << "\tname: " << mylight.m_name << std::endl;
238 postLightRepresentation(curResource);
242 std::cout << "onPut Response error: " << eCode << std::endl;
247 // Local function to put a different state for this resource
248 void putLightRepresentation(std::shared_ptr<OCResource> resource)
252 OCRepresentation rep;
254 std::cout << "Putting light representation..."<<std::endl;
256 mylight.m_state = true;
257 mylight.m_power = 15;
259 rep.setValue("state", mylight.m_state);
260 rep.setValue("power", mylight.m_power);
262 // Invoke resource's put API with rep, query map and the callback parameter
263 resource->put(rep, QueryParamsMap(), &onPut, OC::QualityOfService::HighQos);
267 // Callback handler on GET request
268 void onGet(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
270 if(eCode == SUCCESS_RESPONSE)
272 std::cout << "GET request was successful" << std::endl;
273 std::cout << "Resource URI: " << rep.getUri() << std::endl;
275 rep.getValue("state", mylight.m_state);
276 rep.getValue("power", mylight.m_power);
277 rep.getValue("name", mylight.m_name);
279 std::cout << "\tstate: " << mylight.m_state << std::endl;
280 std::cout << "\tpower: " << mylight.m_power << std::endl;
281 std::cout << "\tname: " << mylight.m_name << std::endl;
283 putLightRepresentation(curResource);
287 std::cout << "onGET Response error: " << eCode << std::endl;
292 // Local function to get representation of light resource
293 void getLightRepresentation(std::shared_ptr<OCResource> resource)
297 std::cout << "Getting Light Representation..."<<std::endl;
298 // Invoke resource's get API with the callback parameter
301 resource->get(test, &onGet,OC::QualityOfService::HighQos);
305 void receivedPlatformInfo(const OCRepresentation& rep)
307 std::cout << "\nPlatform Information received ---->\n";
309 std::string values[] =
311 "pi", "Platform ID ",
312 "mnmn", "Manufacturer name ",
313 "mnml", "Manufacturer url ",
314 "mnmo", "Manufacturer Model No ",
315 "mndt", "Manufactured Date ",
316 "mnpv", "Manufacturer Platform Version ",
317 "mnos", "Manufacturer OS version ",
318 "mnhw", "Manufacturer hardware version ",
319 "mnfv", "Manufacturer firmware version ",
320 "mnsl", "Manufacturer support url ",
321 "st", "Manufacturer system time "
324 for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]) ; i += 2)
326 if(rep.getValue(values[i], value))
328 std::cout << values[i + 1] << " : "<< value << std::endl;
333 void receivedDeviceInfo(const OCRepresentation& rep)
335 std::cout << "\nDevice Information received ---->\n";
337 std::string values[] =
341 "lcv", "Spec version url ",
342 "dmv", "Data Model Model ",
345 for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]); i += 2)
347 if (rep.getValue(values[i], value))
349 std::cout << values[i + 1] << " : " << value << std::endl;
354 // Callback to found resources
355 void foundResource(std::shared_ptr<OCResource> resource)
357 std::string resourceURI;
358 std::string hostAddress;
360 std::string platformDiscoveryURI = "/oic/p";
361 std::string deviceDiscoveryURI = "/oic/d";
365 // Do some operations with resource object.
368 std::lock_guard<std::mutex> lk(resourceLock);
370 if(discoveredResources.find(resource) == discoveredResources.end())
372 std::cout << "Found resource " << resource->uniqueIdentifier() <<
373 " for the first time on server with ID: "<< resource->sid()<<std::endl;
374 discoveredResources.insert(resource);
378 std::cout<<"Found resource "<< resource->uniqueIdentifier() << " again!"<<std::endl;
383 std::cout << "Found another resource, ignoring"<<std::endl;
387 std::cout<<"DISCOVERED Resource:"<<std::endl;
388 // Get the resource URI
389 resourceURI = resource->uri();
390 std::cout << "\tURI of the resource: " << resourceURI << std::endl;
392 // Get the resource host address
393 hostAddress = resource->host();
394 std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
398 std::cout << "Querying for platform information... " << std::endl;
400 ret = OCPlatform::getPlatformInfo("", platformDiscoveryURI, CT_ADAPTER_IP,
401 &receivedPlatformInfo);
403 if (ret == OC_STACK_OK)
405 std::cout << "Get platform information is done." << std::endl;
409 std::cout << "Get platform information failed." << std::endl;
412 std::cout << "Querying for device information... " << std::endl;
414 ret = OCPlatform::getDeviceInfo(resource->host(), deviceDiscoveryURI,
415 resource->connectivityType(), &receivedDeviceInfo);
417 if (ret == OC_STACK_OK)
419 std::cout << "Getting device information is done." << std::endl;
423 std::cout << "Getting device information failed." << std::endl;
426 // Get the resource types
427 std::cout << "\tList of resource types: " << std::endl;
428 for(auto &resourceTypes : resource->getResourceTypes())
430 std::cout << "\t\t" << resourceTypes << std::endl;
433 // Get the resource interfaces
434 std::cout << "\tList of resource interfaces: " << std::endl;
435 for(auto &resourceInterfaces : resource->getResourceInterfaces())
437 std::cout << "\t\t" << resourceInterfaces << std::endl;
440 if(resourceURI == "/a/light")
442 curResource = resource;
444 // Call a local function which will internally invoke get
445 // API on the resource pointer
446 getLightRepresentation(resource);
451 // Resource is invalid
452 std::cout << "Resource is invalid" << std::endl;
456 catch(std::exception& e)
458 std::cerr << "Exception in foundResource: "<< e.what() <<std::endl;
464 std::cout << std::endl;
465 std::cout << "Usage : simpleclientHQ <ObserveType> <ConnectivityType>" << std::endl;
466 std::cout << " ObserveType : 1 - Observe" << std::endl;
467 std::cout << " ObserveType : 2 - ObserveAll" << std::endl;
468 std::cout << " ConnectivityType: Default IP" << std::endl;
469 std::cout << " ConnectivityType : 0 - IP"<< std::endl;
472 int main(int argc, char* argv[]) {
474 std::ostringstream requestURI;
476 OCConnectivityType connectivityType = CT_ADAPTER_IP;
481 OBSERVE_TYPE_TO_USE = ObserveType::Observe;
483 else if (argc ==2 || argc==3)
485 int value = std::stoi(argv[1]);
487 OBSERVE_TYPE_TO_USE = ObserveType::Observe;
489 OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
491 OBSERVE_TYPE_TO_USE = ObserveType::Observe;
495 std::size_t inputValLen;
496 int optionSelected = std::stoi(argv[2], &inputValLen);
498 if(inputValLen == strlen(argv[2]))
500 if(optionSelected == 0)
502 std::cout << "Using IP."<< std::endl;
503 connectivityType = CT_ADAPTER_IP;
507 std::cout << "Invalid connectivity type selected. Using default IP"
513 std::cout << "Invalid connectivity type selected. Using default IP"
524 catch(std::exception&)
526 std::cout << "Invalid input argument." << std::endl;
532 // Create PlatformConfig object
534 OC::ServiceType::InProc,
535 OC::ModeType::Client,
538 OC::QualityOfService::HighQos
541 OCPlatform::Configure(cfg);
545 // Find all resources
546 requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
548 OCPlatform::findResource("", requestURI.str(),
549 connectivityType, &foundResource, OC::QualityOfService::LowQos);
550 std::cout<< "Finding Resource... " <<std::endl;
552 // Find resource is done twice so that we discover the original resources a second time.
553 // These resources will have the same uniqueidentifier (yet be different objects), so that
554 // we can verify/show the duplicate-checking code in foundResource(above);
555 OCPlatform::findResource("", requestURI.str(),
556 connectivityType, &foundResource, OC::QualityOfService::LowQos);
557 std::cout<< "Finding Resource for second time... " <<std::endl;
559 // A condition variable will free the mutex it is given, then do a non-
560 // intensive block until 'notify' is called on it. In this case, since we
561 // don't ever call cv.notify, this should be a non-processor intensive version
564 std::condition_variable cv;
565 std::unique_lock<std::mutex> lock(blocker);
569 catch(OCException& e)
571 oclog() << "Exception in main: "<<e.what();