// OCClient.cpp : Defines the entry point for the console application.
//
+#include "iotivity_config.h"
+
+#include <set>
#include <string>
#include <cstdlib>
-#include <pthread.h>
+#include <mutex>
+#include <condition_variable>
#include "OCPlatform.h"
#include "OCApi.h"
+#if defined(HAVE_PTHREAD_H)
+#include <pthread.h>
+#endif
+#if defined(HAVE_WINDOWS_H)
+#include <windows.h>
+#endif
+
using namespace OC;
+struct dereference_compare
+{
+ bool operator()(std::shared_ptr<OCResource> lhs, std::shared_ptr<OCResource> rhs )const
+ {
+ return *lhs < *rhs;
+ }
+};
+typedef std::set<std::shared_ptr<OCResource>, dereference_compare> DiscoveredResourceSet;
+
+DiscoveredResourceSet discoveredResources;
const int SUCCESS_RESPONSE = 0;
std::shared_ptr<OCResource> curResource;
+std::mutex resourceLock;
static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe;
class Light
return ++oc;
}
-void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep,
+void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation& rep,
const int& eCode, const int& sequenceNumber)
{
if(eCode == SUCCESS_RESPONSE)
{
std::cout << "OBSERVE RESULT:"<<std::endl;
- if(sequenceNumber == 0)
+ if(sequenceNumber == (int) ObserveAction::ObserveRegister)
{
- std::cout << "\tObserve Registration Confirmed: "<< endl;
+ std::cout << "\tObserve Registration Confirmed: "<< std::endl;
}
- else if (sequenceNumber == 1)
+ else if (sequenceNumber == (int) ObserveAction::ObserveUnregister)
{
- std::cout << "\tObserve Cancel Confirmed: "<< endl;
+ std::cout << "\tObserve Cancel Confirmed: "<< std::endl;
sleep(10);
std::cout << "DONE"<<std::endl;
std::exit(0);
}
else
{
- std::cout << "\tSequenceNumber: "<< sequenceNumber << endl;
+ std::cout << "\tSequenceNumber: "<< sequenceNumber << std::endl;
}
rep.getValue("state", mylight.m_state);
std::cout << "\tpower: " << mylight.m_power << std::endl;
std::cout << "\tname: " << mylight.m_name << std::endl;
- if(observe_count() > 30)
+ if(observe_count() == 11)
{
std::cout<<"Cancelling Observe..."<<std::endl;
OCStackResult result = curResource->cancelObserve(OC::QualityOfService::HighQos);
}
}
-void onPost2(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+void onPost2(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
{
- if(eCode == SUCCESS_RESPONSE)
+ if(eCode == SUCCESS_RESPONSE || eCode == OC_STACK_RESOURCE_CHANGED)
{
std::cout << "POST request was successful" << std::endl;
}
if (OBSERVE_TYPE_TO_USE == ObserveType::Observe)
- std::cout << endl << "Observe is used." << endl << endl;
+ std::cout << std::endl << "Observe is used." << std::endl << std::endl;
else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll)
- std::cout << endl << "ObserveAll is used." << endl << endl;
+ std::cout << std::endl << "ObserveAll is used." << std::endl << std::endl;
sleep(1);
curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve,
OC::QualityOfService::HighQos);
}
}
-void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+void onPost(const HeaderOptions& /*headerOptions*/,
+ const OCRepresentation& rep, const int eCode)
{
- if(eCode == SUCCESS_RESPONSE)
+ if(eCode == SUCCESS_RESPONSE || eCode == OC_STACK_RESOURCE_CHANGED)
{
std::cout << "POST request was successful" << std::endl;
}
// callback handler on PUT request
-void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+void onPut(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
{
- if(eCode == SUCCESS_RESPONSE)
+ if(eCode == SUCCESS_RESPONSE || eCode == OC_STACK_RESOURCE_CHANGED)
{
std::cout << "PUT request was successful" << std::endl;
}
// Callback handler on GET request
-void onGet(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+void onGet(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
{
if(eCode == SUCCESS_RESPONSE)
{
// Callback to found resources
void foundResource(std::shared_ptr<OCResource> resource)
{
- if(curResource)
- {
- std::cout << "Found another resource, ignoring"<<std::endl;
- }
-
std::string resourceURI;
std::string hostAddress;
try
// Do some operations with resource object.
if(resource)
{
+ std::lock_guard<std::mutex> lk(resourceLock);
+
+ if(discoveredResources.find(resource) == discoveredResources.end())
+ {
+ std::cout << "Found resource " << resource->uniqueIdentifier() <<
+ " for the first time on server with ID: "<< resource->sid()<<std::endl;
+ discoveredResources.insert(resource);
+ }
+ else
+ {
+ std::cout<<"Found resource "<< resource->uniqueIdentifier() << " again!"<<std::endl;
+ }
+
+ if(curResource)
+ {
+ std::cout << "Found another resource, ignoring"<<std::endl;
+ return;
+ }
+
std::cout<<"DISCOVERED Resource:"<<std::endl;
// Get the resource URI
resourceURI = resource->uri();
{
curResource = resource;
sleep(1);
- // Call a local function which will internally invoke get API on the resource pointer
+ // Call a local function which will internally invoke get
+ // API on the resource pointer
getLightRepresentation(resource);
}
}
}
catch(std::exception& e)
{
- //log(e.what());
+ std::cerr << "Exception in foundResource: "<< e.what() <<std::endl;
}
}
void PrintUsage()
{
std::cout << std::endl;
- std::cout << "Usage : simpleclient <ObserveType>" << std::endl;
+ std::cout << "Usage : simpleclientHQ <ObserveType> <ConnectivityType>" << std::endl;
std::cout << " ObserveType : 1 - Observe" << std::endl;
std::cout << " ObserveType : 2 - ObserveAll" << std::endl;
+ std::cout << " ConnectivityType: Default IP" << std::endl;
+ std::cout << " ConnectivityType : 0 - IP"<< std::endl;
}
int main(int argc, char* argv[]) {
- if (argc == 1)
- {
- OBSERVE_TYPE_TO_USE = ObserveType::Observe;
- }
- else if (argc == 2)
+
+ std::ostringstream requestURI;
+
+ OCConnectivityType connectivityType = CT_ADAPTER_IP;
+ try
{
- int value = atoi(argv[1]);
- if (value == 1)
+ if (argc == 1)
+ {
OBSERVE_TYPE_TO_USE = ObserveType::Observe;
- else if (value == 2)
- OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
+ }
+ else if (argc ==2 || argc==3)
+ {
+ int value = std::stoi(argv[1]);
+ if (value == 1)
+ OBSERVE_TYPE_TO_USE = ObserveType::Observe;
+ else if (value == 2)
+ OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll;
+ else
+ OBSERVE_TYPE_TO_USE = ObserveType::Observe;
+
+ if(argc == 3)
+ {
+ std::size_t inputValLen;
+ int optionSelected = std::stoi(argv[2], &inputValLen);
+
+ if(inputValLen == strlen(argv[2]))
+ {
+ if(optionSelected == 0)
+ {
+ std::cout << "Using IP."<< std::endl;
+ connectivityType = CT_ADAPTER_IP;
+ }
+ else
+ {
+ std::cout << "Invalid connectivity type selected. Using default IP"
+ << std::endl;
+ }
+ }
+ else
+ {
+ std::cout << "Invalid connectivity type selected. Using default IP"
+ << std::endl;
+ }
+ }
+ }
else
- OBSERVE_TYPE_TO_USE = ObserveType::Observe;
+ {
+ PrintUsage();
+ return -1;
+ }
}
- else
+ catch(std::exception&)
{
+ std::cout << "Invalid input argument." << std::endl;
PrintUsage();
return -1;
}
+
// Create PlatformConfig object
PlatformConfig cfg {
OC::ServiceType::InProc,
OC::ModeType::Client,
"0.0.0.0",
0,
- OC::QualityOfService::LowQos
+ OC::QualityOfService::HighQos
};
OCPlatform::Configure(cfg);
try
{
// Find all resources
- OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.light", &foundResource,
- OC::QualityOfService::LowQos);
+ requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
+
+ OCPlatform::findResource("", requestURI.str(),
+ connectivityType, &foundResource, OC::QualityOfService::LowQos);
std::cout<< "Finding Resource... " <<std::endl;
- while(true)
- {
- // some operations
- }
- }catch(OCException& e)
+ // Find resource is done twice so that we discover the original resources a second time.
+ // These resources will have the same uniqueidentifier (yet be different objects), so that
+ // we can verify/show the duplicate-checking code in foundResource(above);
+ OCPlatform::findResource("", requestURI.str(),
+ connectivityType, &foundResource, OC::QualityOfService::LowQos);
+ std::cout<< "Finding Resource for second time... " <<std::endl;
+
+ // A condition variable will free the mutex it is given, then do a non-
+ // intensive block until 'notify' is called on it. In this case, since we
+ // don't ever call cv.notify, this should be a non-processor intensive version
+ // of while(true);
+ std::mutex blocker;
+ std::condition_variable cv;
+ std::unique_lock<std::mutex> lock(blocker);
+ cv.wait(lock);
+
+ }
+ catch(OCException& e)
{
- //log(e.what());
+ oclog() << "Exception in main: "<<e.what();
}
return 0;
}
+