First implementation for Client and Server in same process. Additionally changed...
authorErich Keane <erich.keane@intel.com>
Tue, 12 Aug 2014 20:42:47 +0000 (13:42 -0700)
committerGerrit Code Review <gerrit@fmygit6001.fm.intel.com>
Wed, 13 Aug 2014 21:44:04 +0000 (14:44 -0700)
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

12 files changed:
OCLib/InProcClientWrapper.cpp
OCLib/InProcServerWrapper.cpp
OCLib/OCPlatform.cpp
OCLib/OCResource.cpp
examples/simpleclientserver.cpp [new file with mode: 0644]
include/InProcClientWrapper.h
include/InProcServerWrapper.h
include/OCPlatform.h
include/OCResource.h
include/OutOfProcClientWrapper.h
include/WrapperFactory.h
makefile

index f1d5604ae4b1321b05c9bb689454af12ae85cc01..1fffd3595f78993d62bc9348498c25988c1f8694 100644 (file)
@@ -28,22 +28,28 @@ using namespace std;
 
 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();
@@ -57,14 +63,20 @@ namespace OC
         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
@@ -184,11 +196,17 @@ namespace OC
         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;
     }
    
@@ -255,13 +273,18 @@ namespace OC
         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;
     }
 
@@ -335,13 +358,21 @@ namespace OC
         // 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;
     }
 
@@ -389,12 +420,19 @@ namespace OC
 
         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;
     }
 
@@ -413,10 +451,18 @@ namespace OC
     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;
     }
    }
index 7f8c07d425f7809929a95081fd19e38b5832fe3a..6f1edf9b8cfd979cd3b57702fd821a0ab02f185b 100644 (file)
@@ -133,9 +133,25 @@ OCStackResult entityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * e
 
 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;
@@ -151,12 +167,12 @@ namespace OC
 
     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();
             }
 
@@ -166,7 +182,7 @@ namespace OC
                 // 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));
         }
@@ -188,9 +204,11 @@ namespace OC
         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
@@ -212,6 +230,10 @@ namespace OC
                 entityHandlerMap[resourceHandle] = eHandler;
             }
         }
+        else
+        {
+            result = OC_STACK_ERROR;
+        }
 
         return result;
     }
@@ -222,7 +244,18 @@ namespace OC
         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);
@@ -236,7 +269,18 @@ namespace OC
         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);
@@ -252,7 +296,7 @@ namespace OC
             m_threadRun = false;
             m_processThread.join();
         }
-
+        
         OCStop();
     }
 }
index 4bb7c9c03d7008f26d2e0ba140359c81da54ee75..f94fca213ca06f08245ebde052a4f69409b8485b 100644 (file)
@@ -56,24 +56,25 @@ namespace OC
 
     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);
         }
     }
 
@@ -81,12 +82,12 @@ namespace OC
     {
         if(m_server)
         {
-            //delete m_server;
+            m_server.reset();
         }
 
         if(m_client)
         {
-            //delete m_client;
+            m_client.reset();
         }
     }
 
index 4f12ef164e3ebb7f20c2ab7205715cd6ba2ad75c..46c1cf8894b8197f8d60951a33924322ea82f2d5 100644 (file)
 #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());
         }
     }
 
@@ -39,12 +39,30 @@ namespace OC {
 
     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)
@@ -55,7 +73,16 @@ namespace OC {
         }
         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;
+            }
         }
     }
 
@@ -67,9 +94,18 @@ namespace OC {
         }
         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;
+            }
         }
     }
 
diff --git a/examples/simpleclientserver.cpp b/examples/simpleclientserver.cpp
new file mode 100644 (file)
index 0000000..e27fa4f
--- /dev/null
@@ -0,0 +1,287 @@
+//******************************************************************
+//
+// 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;
+    }
+}
index 952e2ecd7b757af007e4d7cc254db023a6031f4b..3f864753fe4d32aa8354a957f4b840c775c05176 100644 (file)
@@ -40,7 +40,7 @@ namespace OC
     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);
@@ -57,8 +57,7 @@ namespace OC
         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;
 
     };
index 0f23bce4d611907bbb97eea9db0743b0d741eecd..e0e9a9259a9f63524c73e6755a874defd600cff1 100644 (file)
@@ -34,7 +34,7 @@ namespace OC
     class InProcServerWrapper : public IServerWrapper
     {
     public:
-        InProcServerWrapper(PlatformConfig cfg);
+        InProcServerWrapper(std::weak_ptr<std::mutex> csdkLock, PlatformConfig cfg);
         virtual ~InProcServerWrapper();
 
         virtual OCStackResult registerResource(
@@ -56,7 +56,7 @@ namespace OC
         void processFunc();
         std::thread m_processThread;
         bool m_threadRun;
-        std::mutex m_csdkLock;
+        std::weak_ptr<std::mutex> m_csdkLock;
     };
 }
 
index f1537d82b0270ec4fc277d18b43f2b7f91b25f1f..43626f5d5ef2411487d999eeedd7a77c7f2b8b25 100644 (file)
@@ -258,7 +258,7 @@ namespace OC
         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
         */
index 3ed9045c52b3c4d1c96918d0960909fc64cbcfc8..40b5558cd3baaa2218a10afcacb6a5284bb1f65d 100644 (file)
@@ -191,7 +191,7 @@ namespace OC
 
 
     private:
-        IClientWrapper::Ptr m_clientWrapper;
+        std::weak_ptr<IClientWrapper> m_clientWrapper;
         std::string m_uri;
         std::string m_host;
         bool m_isObservable;
@@ -203,7 +203,7 @@ namespace OC
         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); 
     };
 
index 106080fd6d906457576c11efa64ac50770abab98..e01cca7fa55bb5a589e5d43c57a5dd8c67a6ae73 100644 (file)
@@ -28,7 +28,7 @@ namespace OC
     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;}
index 9615c24763ee60433d6fc70ce155cf1c63979c6d..aa950233c94fd737a597066385d2039febe0d159 100644 (file)
@@ -38,8 +38,8 @@ namespace OC
     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(){}
     };
 
@@ -49,29 +49,29 @@ namespace OC
     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;
index 7e1374a92a1fece7dc141525ab9bdb8c3a184a6b..5225e8ccf08bf2518a4424b04bd636466de8d0a9 100644 (file)
--- a/makefile
+++ b/makefile
@@ -18,7 +18,7 @@ CXX_INC         += -I./csdk/ocrandom/include
 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
 
@@ -39,6 +39,9 @@ simpleserver: OCLib.a
 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
 
@@ -63,4 +66,4 @@ clean: clean_legacy
        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