so that it doesn't cause a deadlock on destruction.
SimpleClientServer Example that shows off a client and a server operating on the same process. The client only does a discovery and a get
Change-Id: I5221a658e58c9c4f7d0c58cbbc657b6880d860bf
namespace OC
{
- InProcClientWrapper::InProcClientWrapper(PlatformConfig cfg)
+ InProcClientWrapper::InProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg)
+ :m_threadRun(false), m_csdkLock(csdkLock)
{
- OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, OC_CLIENT);
-
- if(OC_STACK_OK != result)
+ // if the config type is server, we ought to never get called. If the config type
+ // is both, we count on the server to run the thread and do the initialize
+ if(cfg.mode == ModeType::Client)
{
- throw InitializeException("Error Initializing Stack", result);
- }
+ OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, OC_CLIENT);
+
+ if(OC_STACK_OK != result)
+ {
+ throw InitializeException("Error Initializing Stack", result);
+ }
- m_threadRun = true;
- m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
+ m_threadRun = true;
+ m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
+ }
}
InProcClientWrapper::~InProcClientWrapper()
{
- if(m_listeningThread.joinable())
+ if(m_threadRun && m_listeningThread.joinable())
{
m_threadRun = false;
m_listeningThread.join();
while(m_threadRun)
{
OCStackResult result;
+ auto cLock = m_csdkLock.lock();
+ if(cLock)
{
- std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
result = OCProcess();
}
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
if(result != OC_STACK_OK)
{
- // TODO: @Erich do something with result if failed?
+ // TODO: do something with result if failed?
}
// To minimize CPU utilization we may wish to do this with sleep
cbdata->context = static_cast<void*>(context);
cbdata->cb = listenCallback;
+ auto cLock = m_csdkLock.lock();
+ if(cLock)
{
- std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
OCDoHandle handle;
result = OCDoResource(&handle, OC_REST_GET, resourceType.c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
}
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
return result;
}
os << host << uri;
// TODO: end of above
-
+ auto cLock = m_csdkLock.lock();
+ if(cLock)
{
- std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
OCDoHandle handle;
//TODO: use above and this line! result = OCDoResource(&handle, OC_REST_GET, uri.c_str(), host.c_str(), nullptr, OC_CONFIRMABLE, cbdata);
result = OCDoResource(&handle, OC_REST_GET, os.str().c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
}
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
return result;
}
// TODO: end of above
cbdata->context = static_cast<void*>(ctx);
+ auto cLock = m_csdkLock.lock();
+
+ if(cLock)
{
- std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
OCDoHandle handle;
//OCDoResource(&handle, OC_REST_PUT, assembleSetResourceUri(uri.c_str(), queryParams).c_str(), host.c_str(), assembleSetResourcePayload(uri, attributes).c_str(), OC_CONFIRMABLE, cbdata);
//TODO: use above and this line! result = OCDoResource(&handle, OC_REST_GET, uri.c_str(), host.c_str(), nullptr, OC_CONFIRMABLE, cbdata);
result = OCDoResource(&handle, OC_REST_PUT, os.str().c_str(), nullptr, assembleSetResourcePayload(attributes).c_str(), OC_NON_CONFIRMABLE, cbdata);
}
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
+
return result;
}
ostringstream os;
os << host<< uri;
-
+
+ auto cLock = m_csdkLock.lock();
+ if(cLock)
{
- std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
//result = OCDoResource(handle, OC_REST_OBSERVE, uri.c_str(), host.c_str(), nullptr, OC_CONFIRMABLE, cbdata);
result = OCDoResource(handle, method, os.str().c_str(), nullptr, nullptr, OC_NON_CONFIRMABLE, cbdata);
}
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+
return result;
}
OCStackResult InProcClientWrapper::CancelObserveResource(OCDoHandle handle, const std::string& host, const std::string& uri)
{
OCStackResult result;
+ auto cLock = m_csdkLock.lock();
+
+ if(cLock)
{
- std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
result = OCCancel(handle);
}
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
+
return result;
}
}
namespace OC
{
- InProcServerWrapper::InProcServerWrapper(PlatformConfig cfg)
+ InProcServerWrapper::InProcServerWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg)
+ :m_csdkLock(csdkLock)
{
- OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, OC_SERVER);
+ OCMode initType;
+
+ if(cfg.mode == ModeType::Server)
+ {
+ initType = OC_SERVER;
+ }
+ else if (cfg.mode == ModeType::Both)
+ {
+ initType = OC_CLIENT_SERVER;
+ }
+ else
+ {
+ throw InitializeException("Cannot construct a Server when configured as a client", OC_STACK_INVALID_PARAM);
+ }
+
+ OCStackResult result = OCInit(cfg.ipAddress.c_str(), cfg.port, initType);
// Setting default entity Handler
entityHandlerMap[(OCResourceHandle) 0] = defaultEntityHandler;
void InProcServerWrapper::processFunc()
{
- while(m_threadRun)
+ auto cLock = m_csdkLock.lock();
+ while(cLock && m_threadRun)
{
OCStackResult result;
{
- // TODO Fix Lock issue
- // std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
result = OCProcess();
}
// TODO: SASHI
}
- std::this_thread::yield();
+ std::this_thread::sleep_for(std::chrono::milliseconds(10));
// To minimize CPU utilization we may wish to do this with sleep
//std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
cout << "\tResource TypeName: " << resourceTypeName << endl;
cout << "\tResource Interface: " << resourceInterface << endl;
+ auto cLock = m_csdkLock.lock();
+
+ if(cLock)
{
- // TODO @SASHI : Something wrong with lock usage
- // std::lock_guard<std::mutex> lock(m_csdkLock);
+ std::lock_guard<std::mutex> lock(*cLock);
result = OCCreateResource(&resourceHandle, // OCResourceHandle *handle
resourceTypeName.c_str(), // const char * resourceTypeName
entityHandlerMap[resourceHandle] = eHandler;
}
}
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
return result;
}
cout << "Binding Type to Resource: \n";
cout << "\tTypeName: " << resourceTypeName << endl;
- OCStackResult result = OCBindResourceTypeToResource(resourceHandle, resourceTypeName.c_str());
+ auto cLock = m_csdkLock.lock();
+ OCStackResult result;
+ if(cLock)
+ {
+ std::lock_guard<std::mutex> lock(*cLock);
+ result = OCBindResourceTypeToResource(resourceHandle, resourceTypeName.c_str());
+ }
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
+
if (result != OC_STACK_OK)
{
throw OCException("Bind Type to resource failed", result);
cout << "Binding Interface to Resource: \n";
cout << "\tInterfaceName: " << resourceInterfaceName << endl;
- OCStackResult result = OCBindResourceInterfaceToResource(resourceHandle, resourceInterfaceName.c_str());
+ auto cLock = m_csdkLock.lock();
+ OCStackResult result;
+ if(cLock)
+ {
+ std::lock_guard<std::mutex> lock(*cLock);
+ result = OCBindResourceInterfaceToResource(resourceHandle, resourceInterfaceName.c_str());
+ }
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
+
if (result != OC_STACK_OK)
{
throw OCException("Bind Interface to resource failed", result);
m_threadRun = false;
m_processThread.join();
}
-
+
OCStop();
}
}
void OCPlatform::init(const PlatformConfig& config)
{
+ m_csdkLock = make_shared<std::mutex>();
std::unique_ptr<WrapperFactory> wrapperInstance(new WrapperFactory());
m_WrapperInstance = std::move(wrapperInstance);
if(config.mode == ModeType::Server)
{
// Call server wrapper init
- m_server = m_WrapperInstance->CreateServerWrapper(config);
+ m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
}
else if(config.mode == ModeType::Client)
{
// Call client wrapper init
- m_client = m_WrapperInstance->CreateClientWrapper(config);
+ m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
}
else
{
// This must be both server and client
- m_server = m_WrapperInstance->CreateServerWrapper(config);
- m_client = m_WrapperInstance->CreateClientWrapper(config);
+ m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
+ m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
}
}
{
if(m_server)
{
- //delete m_server;
+ m_server.reset();
}
if(m_client)
{
- //delete m_client;
+ m_client.reset();
}
}
#include "OCReflect.h"
namespace OC {
- OCResource::OCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes, const std::vector<std::string>& interfaces) :
+ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host, const std::string& uri, bool observable, const std::vector<std::string>& resourceTypes, const std::vector<std::string>& interfaces) :
m_clientWrapper(clientWrapper), m_uri(uri), m_host(host), m_isObservable(observable), m_isCollection(false), m_resourceTypes(resourceTypes), m_interfaces(interfaces), m_observeHandle(nullptr)
{
m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE) != m_interfaces.end();
- if (m_uri.empty() || resourceTypes.empty() || interfaces.empty()|| ! m_clientWrapper)
+ if (m_uri.empty() || resourceTypes.empty() || interfaces.empty()|| m_clientWrapper.expired())
{
- throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), interfaces.empty(), m_clientWrapper.get() == nullptr);
+ throw ResourceInitException(m_uri.empty(), resourceTypes.empty(), interfaces.empty(), m_clientWrapper.expired());
}
}
OCStackResult OCResource::get(std::function<void(const AttributeMap, const int)> attributeHandler)
{
- return m_clientWrapper->GetResourceAttributes(m_host, m_uri, attributeHandler);
+ auto cw = m_clientWrapper.lock();
+
+ if(cw)
+ {
+ return cw->GetResourceAttributes(m_host, m_uri, attributeHandler);
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
}
OCStackResult OCResource::put(const AttributeMap& attributeMap, const QueryParamsMap& queryParametersMap, std::function<void(const AttributeMap, const int)> attributeHandler)
{
- return m_clientWrapper->SetResourceAttributes(m_host, m_uri, attributeMap, queryParametersMap, attributeHandler);
+ auto cw = m_clientWrapper.lock();
+
+ if(cw)
+ {
+ return cw->SetResourceAttributes(m_host, m_uri, attributeMap, queryParametersMap, attributeHandler);
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
}
OCStackResult OCResource::observe(ObserveType observeType, std::function<void(const AttributeMap&, const int&, const int&)> observeHandler)
}
else
{
- return m_clientWrapper->ObserveResource(observeType, &m_observeHandle, m_host, m_uri, observeHandler);
+ auto cw = m_clientWrapper.lock();
+
+ if(cw)
+ {
+ return cw->ObserveResource(observeType, &m_observeHandle, m_host, m_uri, observeHandler);
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
}
}
}
else
{
- OCStackResult ret = m_clientWrapper->CancelObserveResource(m_observeHandle, m_host, m_uri);
- m_observeHandle = nullptr;
- return ret;
+ auto cw = m_clientWrapper.lock();
+
+ if(cw)
+ {
+ OCStackResult ret = cw->CancelObserveResource(m_observeHandle, m_host, m_uri);
+ m_observeHandle = nullptr;
+ return ret;
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
}
}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2014 Intel Corporation All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+///
+/// This sample provides steps to define an interface for a resource
+/// (properties and methods) and host this resource on the server.
+/// Additionally, it'll have a client example to discover it as well.
+///
+#include <memory>
+#include <iostream>
+#include <condition_variable>
+#include <map>
+#include <vector>
+#include "OCPlatform.h"
+#include "OCApi.h"
+using namespace OC;
+
+class ClientWorker
+{
+private:
+ void putResourceInfo(const AttributeMap requestedPut, const AttributeMap attrMap, const int eCode)
+ {
+ std::cout <<"Clientside Put response to get was: "<<std::endl;
+ std::cout <<"ErrorCode: "<<eCode <<std::endl;
+
+ if(eCode == 0)
+ {
+ std::cout<<"Successful Put. Attributes sent were: "<<std::endl;
+
+ for(const auto& attr : requestedPut)
+ {
+ std::cout << "\tName: "<< attr.first << " value: ";
+ for(const auto& val : attr.second)
+ {
+ std::cout << val << " ";
+ }
+
+ std::cout << std::endl;
+ }
+
+ std::cout<<"Actual New values are: "<<std::endl;
+
+ for(const auto& attr : attrMap)
+ {
+ std::cout << "\tName: "<< attr.first << " value: ";
+ for(const auto& val : attr.second)
+ {
+ std::cout << val << " ";
+ }
+
+ std::cout << std::endl;
+ }
+ m_cv.notify_all();
+ }
+ }
+
+ void getResourceInfo(const AttributeMap attrMap, const int eCode)
+ {
+
+ std::cout<<"Clientside response to get was: "<<std::endl;
+ std::cout<<"Error Code: "<<eCode<<std::endl;
+
+ if(eCode == 0)
+ {
+ std::cout <<"Successful Get. Attributes are: "<<std::endl;
+
+ for(const auto& attr : attrMap)
+ {
+ std::cout << "\tName: "<< attr.first << " value: ";
+ for(const auto& val : attr.second)
+ {
+ std::cout << val << " ";
+ }
+
+ std::cout << std::endl;
+ }
+
+ std::cout << "Doing a put on q/foo" <<std::endl;
+ AttributeMap attrMap2(attrMap);
+ attrMap2["isFoo"][0] ="false";
+ attrMap2["barCount"][0]="211";
+
+ m_resource->put(attrMap2, QueryParamsMap(), std::function<void(const AttributeMap, const int)>(std::bind(&ClientWorker::putResourceInfo, this, attrMap2, std::placeholders::_1, std::placeholders::_2)));
+ }
+ }
+
+ void foundResource(std::shared_ptr<OCResource> resource)
+ {
+ if(resource && resource->uri() == "/q/foo")
+ {
+ {
+ std::lock_guard<std::mutex> lock(m_resourceLock);
+ if(m_resource)
+ {
+ return;
+ }
+
+ m_resource = resource;
+ }
+
+ std::cout << "Found Resource: "<<std::endl;
+ std::cout << "\tHost: "<< resource->host()<<std::endl;
+ std::cout << "\tURI: "<< resource->uri()<<std::endl;
+
+ std::cout<<"Doing a get on q/foo."<<std::endl;
+ resource->get(std::function<void(const AttributeMap, const int)>(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
+ }
+ }
+
+public:
+ void start(OCPlatform& platform)
+ {
+ std::cout<<"Starting Client find:"<<std::endl;
+ std::function<void(std::shared_ptr<OCResource>)> f (std::bind(&ClientWorker::foundResource, this, std::placeholders::_1));
+ std::cout<<"result:" << platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.foo", f)<< std::endl;
+ std::cout<<"Finding Resource..."<<std::endl;
+
+ {
+ std::unique_lock<std::mutex> lk(m_mutex);
+ m_cv.wait(lk);
+ }
+ }
+private:
+ std::mutex m_mutex;
+ std::mutex m_resourceLock;
+ std::condition_variable m_cv;
+ std::shared_ptr<OCResource> m_resource;
+};
+
+struct FooResource
+{
+ bool m_isFoo;
+ int m_barCount;
+ OCResourceHandle m_resourceHandle;
+
+ FooResource(): m_isFoo(true), m_barCount (0){}
+
+ bool createResource(OCPlatform& platform)
+ {
+ std::string resourceURI = "/q/foo";
+ std::string resourceTypeName = "core.foo";
+ std::string resourceInterface = DEFAULT_INTERFACE;
+
+ uint8_t resourceProperty = OC_DISCOVERABLE;
+
+ std::function<void(std::shared_ptr<OCResourceRequest>, std::shared_ptr<OCResourceResponse>)> eh(std::bind(&FooResource::entityHandler, this, std::placeholders::_1, std::placeholders::_2));
+ OCStackResult result = platform.registerResource(m_resourceHandle, resourceURI, resourceTypeName,
+ resourceInterface,
+ eh, resourceProperty);
+ if(OC_STACK_OK != result)
+ {
+ std::cout<<"Resource creation unsuccessful"<<std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
+ void getRepresentation(AttributeMap& attributeMap)
+ {
+ AttributeValues isFooVal;
+ isFooVal.push_back(m_isFoo ? "true" : "false");
+
+ AttributeValues barCt;
+ barCt.push_back(to_string(m_barCount));
+
+ attributeMap["isFoo"] = isFooVal;
+ attributeMap["barCount"] = barCt;
+ }
+
+ void setRepresentation(const AttributeMap& attributeMap)
+ {
+ auto fooVector = attributeMap.at("isFoo");
+ m_isFoo = fooVector[0] == "true";
+ auto barVector = attributeMap.at("barCount");
+ m_barCount = std::stoi(barVector[0]);
+ }
+
+ void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
+ {
+ std::cout<<"\tConsumer Entity Handler:"<<std::endl;
+
+ if(request)
+ {
+ // Note: Most of the handlers are not here, since this is for demoing client/server co-process existence.
+ // See simpleserver for a more complete example.
+ if(request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
+ {
+ std::cout << "\t\trequestFlag : Request"<<std::endl;
+
+ if(request->getRequestType() == "GET")
+ {
+ std::cout<<"\t\t\trequestType : GET"<<std::endl;
+
+ AttributeMap attrs;
+ getRepresentation(attrs);
+
+ if(response)
+ {
+ response->setErrorCode(200);
+ response->setResourceRepresentation(attrs);
+ }
+ }
+ else if (request->getRequestType() == "PUT")
+ {
+ std::cout<<"\t\t\trequestType : PUT"<<std::endl;
+
+ setRepresentation(request->getResourceRepresentation());
+
+ if(response)
+ {
+ response->setErrorCode(200);
+ AttributeMap attrs;
+ getRepresentation(attrs);
+ response->setResourceRepresentation(attrs);
+ }
+ }
+ else
+ {
+ std::cout<<"\t\t\trequestType : UNSUPPORTED: "<<request->getRequestType()<<std::endl;
+ }
+ }
+ else
+ {
+ std::cout <<"\t\trequestFlag : UNSUPPORTED: ";
+
+ if(request->getRequestHandlerFlag()==RequestHandlerFlag::InitFlag)
+ {
+ std::cout<<"InitFlag"<<std::endl;
+ }
+ else if(request->getRequestHandlerFlag()== RequestHandlerFlag::ObserverFlag)
+ {
+ std::cout<<"ObserverFlag"<<std::endl;
+ }
+ }
+ }
+ else
+ {
+ std::cout << "Request Invalid!"<<std::endl;
+ }
+ }
+
+};
+int main()
+{
+ PlatformConfig cfg;
+ cfg.ipAddress = "134.134.161.33";
+ cfg.port = 56833;
+ cfg.mode = ModeType::Both;
+ cfg.serviceType = ServiceType::InProc;
+
+ FooResource fooRes;
+
+ try
+ {
+ OCPlatform platform(cfg);
+
+ if(!fooRes.createResource(platform))
+ {
+ return -1;
+ }
+
+ ClientWorker cw;
+ cw.start(platform);
+ }
+ catch(OCException& e)
+ {
+ std::cout<< "Exception in main: "<<e.what()<<std::endl;
+ }
+}
class InProcClientWrapper : public IClientWrapper
{
public:
- InProcClientWrapper(PlatformConfig cfg);
+ InProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg);
virtual ~InProcClientWrapper();
virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void(std::shared_ptr<OCResource>)>& callback);
std::string assembleSetResourcePayload(const AttributeMap& attributes);
std::thread m_listeningThread;
bool m_threadRun;
- std::mutex m_resourceListenerLock;
- std::mutex m_csdkLock;
+ std::weak_ptr<std::mutex> m_csdkLock;
std::vector<std::function<void(OCClientResponse*)>> callbackList;
};
class InProcServerWrapper : public IServerWrapper
{
public:
- InProcServerWrapper(PlatformConfig cfg);
+ InProcServerWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg);
virtual ~InProcServerWrapper();
virtual OCStackResult registerResource(
void processFunc();
std::thread m_processThread;
bool m_threadRun;
- std::mutex m_csdkLock;
+ std::weak_ptr<std::mutex> m_csdkLock;
};
}
std::unique_ptr<WrapperFactory> m_WrapperInstance;
IServerWrapper::Ptr m_server;
IClientWrapper::Ptr m_client;
-
+ std::shared_ptr<std::mutex> m_csdkLock;
/**
* Private function to initalize the platfrom
*/
private:
- IClientWrapper::Ptr m_clientWrapper;
+ std::weak_ptr<IClientWrapper> m_clientWrapper;
std::string m_uri;
std::string m_host;
bool m_isObservable;
OCDoHandle m_observeHandle;
private:
- OCResource(IClientWrapper::Ptr clientWrapper, const std::string& host, const std::string& uri,
+ OCResource(std::weak_ptr<IClientWrapper> clientWrapper, const std::string& host, const std::string& uri,
bool observable, const std::vector<std::string>& resourceTypes, const std::vector<std::string>& interfaces);
};
class OutOfProcClientWrapper : public IClientWrapper
{
public:
- OutOfProcClientWrapper(PlatformConfig cfg) { }
+ OutOfProcClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg) { }
virtual OCStackResult ListenForResource(const std::string& serviceUrl, const std::string& resourceType, std::function<void(std::shared_ptr<OCResource>)>& callback) {return OC_STACK_NOTIMPL;}
virtual OCStackResult GetResourceAttributes(const std::string& host, const std::string& uri, std::function<void(const AttributeMap, const int)>& callback){return OC_STACK_NOTIMPL;}
public:
typedef std::shared_ptr<IWrapperFactory> Ptr;
- virtual IClientWrapper::Ptr CreateClientWrapper(PlatformConfig cfg) =0;
- virtual IServerWrapper::Ptr CreateServerWrapper(PlatformConfig cfg) =0;
+ virtual IClientWrapper::Ptr CreateClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg) =0;
+ virtual IServerWrapper::Ptr CreateServerWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg) =0;
virtual ~IWrapperFactory(){}
};
public:
WrapperFactory(){}
- virtual IClientWrapper::Ptr CreateClientWrapper(PlatformConfig cfg)
+ virtual IClientWrapper::Ptr CreateClientWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg)
{
switch(cfg.serviceType)
{
case ServiceType::InProc:
- return std::make_shared<InProcClientWrapper>(cfg);
+ return std::make_shared<InProcClientWrapper>(csdkLock, cfg);
break;
case ServiceType::OutOfProc:
- return std::make_shared<OutOfProcClientWrapper>(cfg);
+ return std::make_shared<OutOfProcClientWrapper>(csdkLock, cfg);
break;
}
return nullptr;
}
- virtual IServerWrapper::Ptr CreateServerWrapper(PlatformConfig cfg)
+ virtual IServerWrapper::Ptr CreateServerWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg)
{
switch(cfg.serviceType)
{
case ServiceType::InProc:
- return std::make_shared<InProcServerWrapper>(cfg);
+ return std::make_shared<InProcServerWrapper>(csdkLock, cfg);
break;
case ServiceType::OutOfProc:
- // return std::make_shared<OutOfProcServerWrapper>(cfg);
+ // return std::make_shared<OutOfProcServerWrapper>(csdkLock, cfg);
break;
}
return nullptr;
CXX_INC += -I./csdk/logger/include
# Force metatargets to build:
-.PHONY: prep_dirs c_sdk simpleserver simpleclient
+.PHONY: prep_dirs c_sdk simpleserver simpleclient simpleclientserver
all: .PHONY
simpleclient: OCLib.a
$(CXX) $(CXX_FLAGS.$(BUILD)) -o $(SAMPLES_OUT_DIR)/$@ examples/simpleclient.cpp $(CXX_INC) $(OBJ_DIR)/OCLib.a csdk/liboctbstack.a
+simpleclientserver: OCLib.a
+ $(CXX) $(CXX_FLAGS.$(BUILD)) -o $(SAMPLES_OUT_DIR)/$@ examples/simpleclientserver.cpp $(CXX_INC) $(OBJ_DIR)/OCLib.a csdk/liboctbstack.a
+
OCLib.a: OCPlatform.o OCResource.o OCReflect.o InProcServerWrapper.o InProcClientWrapper.o
ar -cvq $(OBJ_DIR)/OCLib.a $(OBJ_DIR)/OCPlatform.o $(OBJ_DIR)/OCResource.o $(OBJ_DIR)/OCReflect.o $(OBJ_DIR)/InProcServerWrapper.o $(OBJ_DIR)/InProcClientWrapper.o
cd csdk && $(MAKE) clean
cd csdk && $(MAKE) deepclean
clean_legacy:
- -rm -f -v OCLib.a *.o simpleserver simpleclient
+ -rm -f -v OCLib.a *.o simpleserver simpleclient simpleclientserver