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"
37 #include <condition_variable>
38 #include "OCPlatform.h"
43 static const char* SVR_DB_FILE_NAME = "./oic_svr_db_client.dat";
44 typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;
46 DiscoveredResourceMap discoveredResources;
47 std::shared_ptr<OCResource> curResource;
48 static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
49 static OCConnectivityType TRANSPORT_TYPE_TO_USE = OCConnectivityType::CT_ADAPTER_IP;
50 std::mutex curResourceLock;
60 Light() : m_state(false), m_power(0), m_name("")
73 void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation& rep,
74 const int& eCode, const int& sequenceNumber)
78 if(eCode == OC_STACK_OK && sequenceNumber <= MAX_SEQUENCE_NUMBER)
80 if(sequenceNumber == OC_OBSERVE_REGISTER)
82 std::cout << "Observe registration action is successful" << std::endl;
85 std::cout << "OBSERVE RESULT:"<<std::endl;
86 std::cout << "\tSequenceNumber: "<< sequenceNumber << std::endl;
87 rep.getValue("state", mylight.m_state);
88 rep.getValue("power", mylight.m_power);
89 rep.getValue("name", mylight.m_name);
91 std::cout << "\tstate: " << mylight.m_state << std::endl;
92 std::cout << "\tpower: " << mylight.m_power << std::endl;
93 std::cout << "\tname: " << mylight.m_name << std::endl;
95 if(observe_count() == 11)
97 std::cout<<"Cancelling Observe..."<<std::endl;
98 OCStackResult result = curResource->cancelObserve();
100 std::cout << "Cancel result: "<< result <<std::endl;
102 std::cout << "DONE"<<std::endl;
108 if(eCode == OC_STACK_OK)
110 std::cout << "No observe option header is returned in the response." << std::endl;
111 std::cout << "For a registration request, it means the registration failed"
116 std::cout << "onObserve Response error: " << eCode << std::endl;
121 catch(std::exception& e)
123 std::cout << "Exception: " << e.what() << " in onObserve" << std::endl;
128 void onPost2(const HeaderOptions& /*headerOptions*/,
129 const OCRepresentation& rep, const int eCode)
133 if(eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED
134 || eCode == OC_STACK_RESOURCE_CHANGED)
136 std::cout << "POST request was successful" << std::endl;
138 if(rep.hasAttribute("createduri"))
140 std::cout << "\tUri of the created resource: "
141 << rep.getValue<std::string>("createduri") << std::endl;
145 rep.getValue("state", mylight.m_state);
146 rep.getValue("power", mylight.m_power);
147 rep.getValue("name", mylight.m_name);
149 std::cout << "\tstate: " << mylight.m_state << std::endl;
150 std::cout << "\tpower: " << mylight.m_power << std::endl;
151 std::cout << "\tname: " << mylight.m_name << std::endl;
154 if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
155 std::cout << std::endl << "Observe is used." << std::endl << std::endl;
156 else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
157 std::cout << std::endl << "ObserveAll is used." << std::endl << std::endl;
159 curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve);
164 std::cout << "onPost2 Response error: " << eCode << std::endl;
168 catch(std::exception& e)
170 std::cout << "Exception: " << e.what() << " in onPost2" << std::endl;
175 void onPost(const HeaderOptions& /*headerOptions*/,
176 const OCRepresentation& rep, const int eCode)
180 if(eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED
181 || eCode == OC_STACK_RESOURCE_CHANGED)
183 std::cout << "POST request was successful" << std::endl;
185 if(rep.hasAttribute("createduri"))
187 std::cout << "\tUri of the created resource: "
188 << rep.getValue<std::string>("createduri") << std::endl;
192 rep.getValue("state", mylight.m_state);
193 rep.getValue("power", mylight.m_power);
194 rep.getValue("name", mylight.m_name);
196 std::cout << "\tstate: " << mylight.m_state << std::endl;
197 std::cout << "\tpower: " << mylight.m_power << std::endl;
198 std::cout << "\tname: " << mylight.m_name << std::endl;
201 OCRepresentation rep2;
203 std::cout << "Posting light representation..."<<std::endl;
205 mylight.m_state = true;
206 mylight.m_power = 55;
208 rep2.setValue("state", mylight.m_state);
209 rep2.setValue("power", mylight.m_power);
211 curResource->post(rep2, QueryParamsMap(), &onPost2);
215 std::cout << "onPost Response error: " << eCode << std::endl;
219 catch(std::exception& e)
221 std::cout << "Exception: " << e.what() << " in onPost" << std::endl;
225 // Local function to put a different state for this resource
226 void postLightRepresentation(std::shared_ptr<OCResource> resource)
230 OCRepresentation rep;
232 std::cout << "Posting light representation..."<<std::endl;
234 mylight.m_state = false;
235 mylight.m_power = 105;
237 rep.setValue("state", mylight.m_state);
238 rep.setValue("power", mylight.m_power);
240 // Invoke resource's post API with rep, query map and the callback parameter
241 resource->post(rep, QueryParamsMap(), &onPost);
245 // callback handler on PUT request
246 void onPut(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
250 if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CHANGED)
252 std::cout << "PUT request was successful" << std::endl;
254 rep.getValue("state", mylight.m_state);
255 rep.getValue("power", mylight.m_power);
256 rep.getValue("name", mylight.m_name);
258 std::cout << "\tstate: " << mylight.m_state << std::endl;
259 std::cout << "\tpower: " << mylight.m_power << std::endl;
260 std::cout << "\tname: " << mylight.m_name << std::endl;
262 postLightRepresentation(curResource);
266 std::cout << "onPut Response error: " << eCode << std::endl;
270 catch(std::exception& e)
272 std::cout << "Exception: " << e.what() << " in onPut" << std::endl;
276 // Local function to put a different state for this resource
277 void putLightRepresentation(std::shared_ptr<OCResource> resource)
281 OCRepresentation rep;
283 std::cout << "Putting light representation..."<<std::endl;
285 mylight.m_state = true;
286 mylight.m_power = 15;
288 rep.setValue("state", mylight.m_state);
289 rep.setValue("power", mylight.m_power);
291 // Invoke resource's put API with rep, query map and the callback parameter
292 resource->put(rep, QueryParamsMap(), &onPut);
296 // Callback handler on GET request
297 void onGet(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
301 if(eCode == OC_STACK_OK)
303 std::cout << "GET request was successful" << std::endl;
304 std::cout << "Resource URI: " << rep.getUri() << std::endl;
306 rep.getValue("state", mylight.m_state);
307 rep.getValue("power", mylight.m_power);
308 rep.getValue("name", mylight.m_name);
310 std::cout << "\tstate: " << mylight.m_state << std::endl;
311 std::cout << "\tpower: " << mylight.m_power << std::endl;
312 std::cout << "\tname: " << mylight.m_name << std::endl;
314 putLightRepresentation(curResource);
318 std::cout << "onGET Response error: " << eCode << std::endl;
322 catch(std::exception& e)
324 std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
328 // Local function to get representation of light resource
329 void getLightRepresentation(std::shared_ptr<OCResource> resource)
333 std::cout << "Getting Light Representation..."<<std::endl;
334 // Invoke resource's get API with the callback parameter
337 resource->get(test, &onGet);
341 void receivedPlatformInfo(const OCRepresentation& rep)
343 std::cout << "\nPlatform Information received ---->\n";
345 std::string values[] =
347 "pi", "Platform ID ",
348 "mnmn", "Manufacturer name ",
349 "mnml", "Manufacturer url ",
350 "mnmo", "Manufacturer Model No ",
351 "mndt", "Manufactured Date ",
352 "mnpv", "Manufacturer Platform Version ",
353 "mnos", "Manufacturer OS version ",
354 "mnhw", "Manufacturer hardware version ",
355 "mnfv", "Manufacturer firmware version ",
356 "mnsl", "Manufacturer support url ",
357 "st", "Manufacturer system time "
360 for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]) ; i += 2)
362 if(rep.getValue(values[i], value))
364 std::cout << values[i + 1] << " : "<< value << std::endl;
369 void receivedDeviceInfo(const OCRepresentation& rep)
371 std::cout << "\nDevice Information received ---->\n";
373 std::string values[] =
377 "lcv", "Spec version url ",
378 "dmv", "Data Model Model ",
381 for (unsigned int i = 0; i < sizeof(values) / sizeof(values[0]); i += 2)
383 if (rep.getValue(values[i], value))
385 std::cout << values[i + 1] << " : " << value << std::endl;
390 // Callback to found resources
391 void foundResource(std::shared_ptr<OCResource> resource)
393 std::cout << "In foundResource\n";
394 std::string resourceURI;
395 std::string hostAddress;
397 std::string platformDiscoveryURI = "/oic/p";
398 std::string deviceDiscoveryURI = "/oic/d";
403 std::lock_guard<std::mutex> lock(curResourceLock);
404 if(discoveredResources.find(resource->uniqueIdentifier()) == discoveredResources.end())
406 std::cout << "Found resource " << resource->uniqueIdentifier() <<
407 " for the first time on server with ID: "<< resource->sid()<<std::endl;
408 discoveredResources[resource->uniqueIdentifier()] = resource;
412 std::cout<<"Found resource "<< resource->uniqueIdentifier() << " again!"<<std::endl;
417 std::cout << "Found another resource, ignoring"<<std::endl;
422 // Do some operations with resource object.
425 std::cout<<"DISCOVERED Resource:"<<std::endl;
426 // Get the resource URI
427 resourceURI = resource->uri();
428 std::cout << "\tURI of the resource: " << resourceURI << std::endl;
430 // Get the resource host address
431 hostAddress = resource->host();
432 std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
436 std::cout << "Querying for platform information... " << std::endl;
438 ret = OCPlatform::getPlatformInfo("", platformDiscoveryURI, CT_ADAPTER_IP,
439 &receivedPlatformInfo);
441 if (ret == OC_STACK_OK)
443 std::cout << "Get platform information is done." << std::endl;
447 std::cout << "Get platform information failed." << std::endl;
450 std::cout << "Querying for device information... " << std::endl;
452 ret = OCPlatform::getDeviceInfo(resource->host(), deviceDiscoveryURI, CT_ADAPTER_IP,
453 &receivedDeviceInfo);
455 if (ret == OC_STACK_OK)
457 std::cout << "Getting device information is done." << std::endl;
461 std::cout << "Getting device information failed." << std::endl;
464 // Get the resource types
465 std::cout << "\tList of resource types: " << std::endl;
466 for(auto &resourceTypes : resource->getResourceTypes())
468 std::cout << "\t\t" << resourceTypes << std::endl;
471 // Get the resource interfaces
472 std::cout << "\tList of resource interfaces: " << std::endl;
473 for(auto &resourceInterfaces : resource->getResourceInterfaces())
475 std::cout << "\t\t" << resourceInterfaces << std::endl;
478 if(resourceURI == "/a/light")
480 if (resource->connectivityType() & TRANSPORT_TYPE_TO_USE)
482 curResource = resource;
483 // Get the resource host address
484 std::cout << "\tAddress of selected resource: " << resource->host() << std::endl;
486 // Call a local function which will internally invoke get API on the resource pointer
487 getLightRepresentation(resource);
493 // Resource is invalid
494 std::cout << "Resource is invalid" << std::endl;
498 catch(std::exception& e)
500 std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
506 std::cout << std::endl;
507 std::cout << "---------------------------------------------------------------------\n";
508 std::cout << "Usage : simpleclient <ObserveType> <TransportType>" << std::endl;
509 std::cout << " ObserveType : 1 - Observe" << std::endl;
510 std::cout << " ObserveType : 2 - ObserveAll" << std::endl;
511 std::cout << " TransportType : 1 - IP" << std::endl;
512 std::cout << " TransportType : 2 - TCP" << std::endl;
513 std::cout << "---------------------------------------------------------------------\n\n";
516 void checkObserverValue(int value)
520 OBSERVE_TYPE_TO_USE = ObserveType::Observe;
521 std::cout << "<===Setting ObserveType to Observe===>\n\n";
525 OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
526 std::cout << "<===Setting ObserveType to ObserveAll===>\n\n";
530 std::cout << "<===Invalid ObserveType selected."
531 <<" Setting ObserveType to Observe===>\n\n";
535 void checkTransportValue(int value)
539 TRANSPORT_TYPE_TO_USE = OCConnectivityType::CT_ADAPTER_IP;
540 std::cout << "<===Setting TransportType to IP===>\n\n";
544 TRANSPORT_TYPE_TO_USE = OCConnectivityType::CT_ADAPTER_TCP;
545 std::cout << "<===Setting TransportType to TCP===>\n\n";
549 std::cout << "<===Invalid TransportType selected."
550 <<" Setting TransportType to IP===>\n\n";
554 static FILE* client_open(const char* /*path*/, const char *mode)
556 return fopen(SVR_DB_FILE_NAME, mode);
559 int main(int argc, char* argv[]) {
561 std::ostringstream requestURI;
562 OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
568 std::cout << "<===Setting ObserveType to Observe and ConnectivityType to IP===>\n\n";
572 checkObserverValue(std::stoi(argv[1]));
576 checkObserverValue(std::stoi(argv[1]));
577 checkTransportValue(std::stoi(argv[2]));
581 std::cout << "<===Invalid number of command line arguments===>\n\n";
585 catch(std::exception& )
587 std::cout << "<===Invalid input arguments===>\n\n";
591 // Create PlatformConfig object
593 OC::ServiceType::InProc,
597 OC::QualityOfService::HighQos,
601 OCPlatform::Configure(cfg);
604 // makes it so that all boolean values are printed as 'true/false' in this stream
605 std::cout.setf(std::ios::boolalpha);
606 // Find all resources
607 requestURI << OC_RSRVD_WELL_KNOWN_URI;// << "?rt=core.light";
609 OCPlatform::findResource("", requestURI.str(),
610 CT_DEFAULT, &foundResource);
611 std::cout<< "Finding Resource... " <<std::endl;
613 // Find resource is done twice so that we discover the original resources a second time.
614 // These resources will have the same uniqueidentifier (yet be different objects), so that
615 // we can verify/show the duplicate-checking code in foundResource(above);
616 OCPlatform::findResource("", requestURI.str(),
617 CT_DEFAULT, &foundResource);
618 std::cout<< "Finding Resource for second time..." << std::endl;
620 // A condition variable will free the mutex it is given, then do a non-
621 // intensive block until 'notify' is called on it. In this case, since we
622 // don't ever call cv.notify, this should be a non-processor intensive version
625 std::condition_variable cv;
626 std::unique_lock<std::mutex> lock(blocker);
629 }catch(OCException& e)
631 oclog() << "Exception in main: "<<e.what();