IOT-1868 [C++ layer] Make OCPlatform start and stop reliably
authorWay Vadhanasin <wayvad@microsoft.com>
Tue, 7 Mar 2017 00:09:50 +0000 (16:09 -0800)
committerDan Mihai <Daniel.Mihai@microsoft.com>
Thu, 9 Mar 2017 15:09:26 +0000 (15:09 +0000)
This change adds reference count to OCPlatform's static start and
stop functions and synchronizes them. It does the following:

1. Ensures that calls to the "C" APIs OCInit and OCStop are balanced.
2. Maintains backward compatibility by introducing new PlatformConfig
   constructor and deprecate the old ones.
3. Updates the existing unit tests and samples.

Because this change allows the framework to stop properly, it exposes
some existing IoTivity leaks in Jenkins (Valgrind validation). Thus
the following leaks are fixed in this change to allow successful
Jenkins runs:

1. caipadapter.c: endpoint cache leak in UDP (no issue for TCP).
- https://build.iotivity.org/ci/job/iotivity-verify-unit_tests/
10907/valgrindResult/pid=24498,0x3fe

2. psinterface.c: CBOR buffer leaks in CreateResetProfile.
- https://build.iotivity.org/ci/job/iotivity-verify-unit_tests/
10922/valgrindResult/pid=2316,0x3ad

3. ocstack.c & securityResourceManager.cpp: persistent storage buffer
leaks as a result of restarting and switching OCPlatform
configuration after shutdown (e.g., between tests).
https://build.iotivity.org/ci/job/iotivity-verify-unit_tests/
10922/valgrindResult/pid=2316,0x3ad

4. OCRepresentationEncodingTest.cpp: representation value leaks.
- https://build.iotivity.org/ci/job/iotivity-verify-unit_tests/
10922/valgrindResult/pid=2316,0x3a9

5. runtest.py: change Valgrind callstack size from the default value
of 12 to 24 so that the test name is visible in the report. Helpful
for reproducibility.

Change-Id: I79406f2cf4282efbb29a69c14e42aae928f54bae
Signed-off-by: Way Vadhanasin <wayvad@microsoft.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/17685
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: Dan Mihai <Daniel.Mihai@microsoft.com>
38 files changed:
resource/csdk/connectivity/src/ip_adapter/caipadapter.c
resource/csdk/security/src/psinterface.c
resource/csdk/security/unittest/securityresourcemanager.cpp
resource/csdk/stack/src/ocstack.c
resource/examples/devicediscoveryclient.cpp
resource/examples/devicediscoveryserver.cpp
resource/examples/directpairingclient.cpp
resource/examples/fridgeclient.cpp
resource/examples/fridgeserver.cpp
resource/examples/garageclient.cpp
resource/examples/garageserver.cpp
resource/examples/groupclient.cpp
resource/examples/groupserver.cpp
resource/examples/lightserver.cpp
resource/examples/mediaserver.cpp
resource/examples/presenceclient.cpp
resource/examples/presenceserver.cpp
resource/examples/rdclient.cpp
resource/examples/roomclient.cpp
resource/examples/roomserver.cpp
resource/examples/simpleclient.cpp
resource/examples/simpleclientHQ.cpp
resource/examples/simpleclientserver.cpp
resource/examples/simpleserver.cpp
resource/examples/threadingsample.cpp
resource/examples/winuiclient.cpp
resource/examples/winuiclient.h
resource/examples/winuiclientgui.cpp
resource/include/OCApi.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/WrapperFactory.h
resource/src/InProcClientWrapper.cpp
resource/src/InProcServerWrapper.cpp
resource/src/OCPlatform_impl.cpp
resource/unittests/OCPlatformTest.cpp
resource/unittests/OCRepresentationEncodingTest.cpp
tools/scons/RunTest.py

index 91cdfd8..edf96c1 100644 (file)
@@ -152,6 +152,11 @@ void CAIPDeinitializeQueueHandles()
     CAQueueingThreadDestroy(g_sendQueueHandle);
     OICFree(g_sendQueueHandle);
     g_sendQueueHandle = NULL;
+
+    // Since the items in g_ownIpEndpointList are allocated once in a big chunk, we only need to
+    // free the first item. Another location this is done is in the CA_INTERFACE_DOWN handler
+    // in CAUpdateStoredIPAddressInfo().
+    OICFree(u_arraylist_get(g_ownIpEndpointList, 0));
     u_arraylist_free(&g_ownIpEndpointList);
     g_ownIpEndpointList = NULL;
 }
index 2f90135..0bd6cca 100644 (file)
@@ -632,7 +632,7 @@ OCStackResult CreateResetProfile(void)
             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
             {
                 OIC_LOG(DEBUG, TAG, "Reset Profile already exists!!");
-                return ret;
+                goto exit;
             }
 
             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
index 2fa77f4..2141dd0 100644 (file)
@@ -108,7 +108,8 @@ TEST(RegisterHandlerTest, RegisterValidHandler)
 // PersistentStorageHandler Tests
 TEST(PersistentStorageHandlerTest, RegisterNullHandler)
 {
-    EXPECT_EQ(OC_STACK_INVALID_PARAM,
+    // Revert to the default storage handler by setting it to null.
+    EXPECT_EQ(OC_STACK_OK,
             SRMRegisterPersistentStorageHandler(NULL));
 }
 
index cc1abd0..92c311f 100644 (file)
@@ -3467,12 +3467,7 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
 OCStackResult OCRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler)
 {
     OIC_LOG(INFO, TAG, "RegisterPersistentStorageHandler !!");
-    if(!persistentStorageHandler)
-    {
-        OIC_LOG(ERROR, TAG, "The persistent storage handler is invalid");
-        return OC_STACK_INVALID_PARAM;
-    }
-    else
+    if(persistentStorageHandler)
     {
         if( !persistentStorageHandler->open ||
                 !persistentStorageHandler->close ||
index 25250d3..03e36d0 100644 (file)
@@ -138,14 +138,14 @@ int main(int argc, char* argv[]) {
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Client,
-        "0.0.0.0",
-        0,
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+
         platformDiscoveryRequest << OC_MULTICAST_PREFIX << platformDiscoveryURI;
         deviceDiscoveryRequest << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
 
@@ -188,6 +188,8 @@ int main(int argc, char* argv[]) {
         std::unique_lock<std::mutex> lock(blocker);
         cv.wait(lock, []{return false;});
 
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
+
     }catch(OCException& e)
     {
         std::cerr << "Failure in main thread: "<<e.reason()<<std::endl;
index 6923172..e709c71 100644 (file)
@@ -156,12 +156,11 @@ int main()
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
     std::cout<<"Starting server & setting platform info\n";
 
@@ -196,9 +195,8 @@ int main()
     std::unique_lock<std::mutex> lock(blocker);
     cv.wait(lock, []{return false;});
 
-    // No explicit call to stop the platform.
-    // When OCPlatform::destructor is invoked, internally we do platform cleanup
-
+    // Perform platform clean up.
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     return 0;
 
 }
index 703c378..6185e13 100644 (file)
@@ -249,9 +249,6 @@ int main(void)
     PlatformConfig cfg {
         OC::ServiceType::InProc,
             OC::ModeType::Both,
-            "0.0.0.0",
-            0,
-            OC::QualityOfService::LowQos,
             &ps
     };
 
@@ -259,6 +256,8 @@ int main(void)
 
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+
         unsigned int choice;
         for (int out = 0; !out;)
         {
@@ -408,6 +407,8 @@ int main(void)
                     }
             }
         }
+
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch(OCException& e)
     {
index bbbc748..e562883 100644 (file)
@@ -316,13 +316,13 @@ int main(int argc, char* argv[])
     {
         ServiceType::InProc,
         ModeType::Client,
-        "0.0.0.0",
-        0,
-        QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
     ClientFridge cf(connectivityType);
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     return 0;
 }
 
index 9ab20d7..2ce63ba 100644 (file)
@@ -570,12 +570,11 @@ int main ()
     {
         ServiceType::InProc,
         ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
     Refrigerator rf;
 
     std::cout << "Starting server & setting platform info\n";
@@ -603,6 +602,7 @@ int main ()
     DeletePlatformInfo();
     // we will keep the server alive for at most 30 minutes
     std::this_thread::sleep_for(std::chrono::minutes(30));
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     return 0;
 }
 
index 9a91da9..a8c8f93 100644 (file)
@@ -336,14 +336,14 @@ int main(int argc, char* argv[]) {
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Client,
-        "0.0.0.0",
-        0,
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+
         // Find all resources
         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.garage";
 
@@ -360,6 +360,8 @@ int main(int argc, char* argv[]) {
         std::condition_variable cv;
         std::unique_lock<std::mutex> lock(blocker);
         cv.wait(lock);
+
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch(OCException& e)
     {
index f333d45..e8238ef 100644 (file)
@@ -346,12 +346,11 @@ int main(int /*argc*/, char** /*argv[1]*/)
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
     std::cout << "Starting server & setting platform info\n";
 
     OCStackResult result = SetPlatformInfo(platformId, manufacturerName, manufacturerLink,
@@ -394,8 +393,7 @@ int main(int /*argc*/, char** /*argv[1]*/)
         oclog() << e.what();
     }
 
-    // No explicit call to stop the OCPlatform
-    // When OCPlatform destructor is invoked, internally we do Platform cleanup
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
 
     return 0;
 }
index cde8eb2..ef146ab 100644 (file)
@@ -176,13 +176,14 @@ int main(int /*argc*/, char** /*argv[]*/)
     requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=a.collection";
 
     PlatformConfig config
-    { OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+    { OC::ServiceType::InProc, ModeType::Client, nullptr };
 
     bool isRun = true;
 
     try
     {
         OCPlatform::Configure(config);
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
         string resourceTypeName = "a.collection";
 
@@ -255,6 +256,7 @@ int main(int /*argc*/, char** /*argv[]*/)
                     break;
             }
         }
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch (OCException& e)
     {
index f4b5e4d..13cb475 100755 (executable)
@@ -124,7 +124,7 @@ int main(int argc, char* argv[])
     }
 
     PlatformConfig config
-    { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos };
+    { OC::ServiceType::InProc, ModeType::Both, nullptr };
 
     try
     {
@@ -132,6 +132,7 @@ int main(int argc, char* argv[])
         string resourceTypeName = "a.collection";
         string resourceInterface = BATCH_INTERFACE;
         OCPlatform::Configure(config);
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
         // EntityHandler cb = std::bind(, PH::_1, PH::_2);
 
@@ -175,6 +176,8 @@ int main(int argc, char* argv[])
             }
 
         }
+
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch (OCException& e)
     {
index 127b858..a9b605b 100644 (file)
@@ -408,14 +408,12 @@ int main(int /*argc*/, char** /*argv[]*/)
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos,
         &ps
     };
 
     OCPlatform::Configure(cfg);
     std::cout << "Starting server & setting platform info\n";
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
     OCStackResult result = SetPlatformInfo(platformId, manufacturerName, manufacturerLink,
             modelNumber, dateOfManufacture, platformVersion, operatingSystemVersion,
@@ -465,9 +463,8 @@ int main(int /*argc*/, char** /*argv[]*/)
        oclog() << "Exception in main: "<< e.what();
     }
 
-    // No explicit call to stop the platform.
-    // When OCPlatform::destructor is invoked, internally we do platform cleanup
-
+    // Perform platform clean up.
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     return 0;
 }
 
index 0f07e86..d9017e7 100644 (file)
@@ -669,15 +669,14 @@ int main(int argc, char* argv[])
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos,
         &ps
     };
 
     OCPlatform::Configure(cfg);
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+        
         // Create the instance of the resource class
         // (in this case instance of class 'MediaResource').
         MediaResource myMedia;
@@ -695,15 +694,15 @@ int main(int argc, char* argv[])
         std::unique_lock<std::mutex> lock(blocker);
         cout <<"Waiting" << std::endl;
         cv.wait(lock, []{return false;});
+
+        // Perform platform clean up.
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch(OCException &e)
     {
         cout << "OCException in main : " << e.what() << endl;
     }
 
-    // No explicit call to stop the platform.
-    // When OCPlatform::destructor is invoked, internally we do platform cleanup
-
     return 0;
 }
 
index 72b672a..3603162 100644 (file)
@@ -257,15 +257,15 @@ int main(int argc, char* argv[]) {
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Client,
-        "0.0.0.0",
-        0,
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
 
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+
         std::cout << "Created Platform..."<<std::endl;
 
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
@@ -359,6 +359,7 @@ int main(int argc, char* argv[]) {
         std::unique_lock<std::mutex> lock(blocker);
         cv.wait(lock);
 
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch(OCException& e)
     {
index da1d937..a6b7311 100644 (file)
@@ -304,13 +304,13 @@ int main()
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
+
     std::cout << "Starting server & setting platform info\n";
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
     OCStackResult result = SetPlatformInfo(platformId, manufacturerName, manufacturerLink,
             modelNumber, dateOfManufacture, platformVersion, operatingSystemVersion,
@@ -321,6 +321,7 @@ int main()
     if (result != OC_STACK_OK)
     {
         std::cout << "Platform Registration failed\n";
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
         return -1;
     }
 
@@ -329,6 +330,7 @@ int main()
     if (result != OC_STACK_OK)
     {
         std::cout << "Device Registration failed\n";
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
         return -1;
     }
 
@@ -386,8 +388,8 @@ int main()
         oclog() << "Exception in main: "<< e.what();
     }
 
-    // No explicit call to stop the platform.
-    // When OCPlatform destructor is invoked, internally we do platform cleanup
+    // Perform platform clean up.
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
 
     return 0;
 }
index 5960fa2..074e5e0 100644 (file)
@@ -246,11 +246,12 @@ int main(int argc, char* argv[])
 
     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
     PlatformConfig config
-    { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos, &ps};
+    { OC::ServiceType::InProc, ModeType::Both, &ps};
 
     try
     {
         OCPlatform::Configure(config);
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
         int selectedMenu;
         bool isRun = true;
@@ -291,6 +292,7 @@ int main(int argc, char* argv[])
             }
 
         }
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch (OCException& e)
     {
index 6d04a7d..c23e846 100644 (file)
@@ -270,12 +270,11 @@ int main(int argc, char* argv[]) {
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Client,
-        "0.0.0.0",
-        0,
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
     try
     {
@@ -294,6 +293,9 @@ int main(int argc, char* argv[]) {
         std::unique_lock<std::mutex> lock(blocker);
         cv.wait(lock);
 
+        // Perform platform clean up.
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
+
     }catch(OCException& e)
     {
         oclog() << "Exception in main: "<< e.what();
index 8295401..65eefa8 100644 (file)
@@ -656,13 +656,12 @@ int main(int argc, char* argv[])
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
     std::cout << "Starting server & setting platform info\n";
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
     OCStackResult result = SetPlatformInfo(platformId, manufacturerName, manufacturerLink,
             modelNumber, dateOfManufacture, platformVersion, operatingSystemVersion,
@@ -705,8 +704,8 @@ int main(int argc, char* argv[])
         std::cout << "Exception in main: " << e.what();
     }
 
-    // No explicit call to stop the platform.
-    // When OCPlatform destructor is invoked, internally we do platform cleanup
+    // Perform platform clean up.
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
 
     return 0;
 }
index 6c287be..62cdc7e 100644 (file)
@@ -557,16 +557,18 @@ int main(int argc, char* argv[]) {
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Both,
-        OCConnectivityType::CT_ADAPTER_IP,
-        OCConnectivityType::CT_ADAPTER_IP,
-        (OCTransportAdapter)(OCTransportAdapter::OC_ADAPTER_IP|OCTransportAdapter::OC_ADAPTER_TCP),
-        OC::QualityOfService::HighQos,
         &ps
     };
 
+    cfg.transportType = static_cast<OCTransportAdapter>(OCTransportAdapter::OC_ADAPTER_IP | 
+                                                        OCTransportAdapter::OC_ADAPTER_TCP);
+    cfg.QoS = OC::QualityOfService::HighQos;
+
     OCPlatform::Configure(cfg);
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+
         // makes it so that all boolean values are printed as 'true/false' in this stream
         std::cout.setf(std::ios::boolalpha);
         // Find all resources
@@ -592,6 +594,9 @@ int main(int argc, char* argv[]) {
         std::unique_lock<std::mutex> lock(blocker);
         cv.wait(lock);
 
+        // Perform platform clean up.
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
+
     }catch(OCException& e)
     {
         oclog() << "Exception in main: "<<e.what();
index 6d631d3..6219b2c 100644 (file)
@@ -450,15 +450,17 @@ int main(int argc, char* argv[]) {
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Client,
-        "0.0.0.0",
-        0,
-        OC::QualityOfService::HighQos
+        nullptr
     };
+    
+    cfg.QoS = OC::QualityOfService::HighQos;
 
     OCPlatform::Configure(cfg);
 
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+
         // Find all resources
         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
 
@@ -482,6 +484,8 @@ int main(int argc, char* argv[]) {
         std::unique_lock<std::mutex> lock(blocker);
         cv.wait(lock);
 
+        // Perform platform clean up.
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch(OCException& e)
     {
index 596b37f..d5fcd36 100644 (file)
@@ -341,9 +341,7 @@ int main(int argc, char* argv[])
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Both,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
@@ -351,14 +349,18 @@ int main(int argc, char* argv[])
 
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
 
         if(!fooRes.createResource())
         {
+            OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
             return -1;
         }
 
         ClientWorker cw(connectivityType);
         cw.start();
+
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch(OCException& e)
     {
index b232827..006216f 100644 (file)
@@ -672,12 +672,15 @@ int main(int argc, char* argv[])
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        (OCTransportAdapter)(OCTransportAdapter::OC_ADAPTER_IP|OCTransportAdapter::OC_ADAPTER_TCP),
-        OC::QualityOfService::LowQos,
         &ps
     };
 
+    cfg.transportType = static_cast<OCTransportAdapter>(OCTransportAdapter::OC_ADAPTER_IP | 
+                                                        OCTransportAdapter::OC_ADAPTER_TCP);
+    cfg.QoS = OC::QualityOfService::LowQos;
+
     OCPlatform::Configure(cfg);
+    OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
     std::cout << "Starting server & setting platform info\n";
 
     OCStackResult result = SetPlatformInfo(platformId, manufacturerName, manufacturerLink,
@@ -731,8 +734,7 @@ int main(int argc, char* argv[])
         std::cout << "OCException in main : " << e.what() << endl;
     }
 
-    // No explicit call to stop the platform.
-    // When OCPlatform::destructor is invoked, internally we do platform cleanup
+    OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
 
     return 0;
 }
index 3c61b71..78c5412 100644 (file)
@@ -341,15 +341,15 @@ int main(int /*argc*/, char** /*argv[]*/)
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Both,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
-        OC::QualityOfService::LowQos
+        nullptr
     };
 
     OCPlatform::Configure(cfg);
 
     try
     {
+        OC_VERIFY(OCPlatform::start() == OC_STACK_OK);
+
         // main thread running as server
         FooResource fooRes("/q/foo1");
         if(!fooRes.createResource())
@@ -379,6 +379,9 @@ int main(int /*argc*/, char** /*argv[]*/)
         std::condition_variable cv;
         std::unique_lock<std::mutex> lock(blocker);
         cv.wait(lock);
+        
+        // Perform platform clean up.
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);
     }
     catch(OCException& e)
     {
index 1b892cd..ac299ea 100644 (file)
@@ -29,29 +29,37 @@ void LabelPrintf (HWND hwndEdit, TCHAR * szFormat, ...);
 \r
 WinUIClientApp::WinUIClientApp(OCPersistentStorage ps)\r
     : persistentStorage(ps),\r
-      OBSERVE_TYPE_TO_USE(ObserveType::Observe)\r
+      OBSERVE_TYPE_TO_USE(ObserveType::Observe),\r
+      initialized(false)\r
 {\r
 \r
 }\r
 \r
 WinUIClientApp::~WinUIClientApp()\r
 {\r
-\r
+    if (initialized)\r
+    {\r
+        OC_VERIFY(OCPlatform::stop() == OC_STACK_OK);\r
+    }\r
 }\r
 \r
-void WinUIClientApp::Initialize()\r
+bool WinUIClientApp::Initialize()\r
 {\r
+    assert(!initialized);\r
+\r
     // Create PlatformConfig object\r
     PlatformConfig cfg {\r
         OC::ServiceType::InProc,\r
         OC::ModeType::Both,\r
-        "0.0.0.0",\r
-        0,\r
-        OC::QualityOfService::LowQos,\r
         &persistentStorage\r
     };\r
 \r
     OCPlatform::Configure(cfg);\r
+    if (OCPlatform::start() == OC_STACK_OK)\r
+    {\r
+        initialized = true;\r
+    }\r
+    return initialized;\r
 }\r
 \r
 void WinUIClientApp::Run()\r
index b052e4e..53288ee 100644 (file)
@@ -1,89 +1,90 @@
-/* ****************************************************************
- *
- * Copyright 2016 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.
- *
- ******************************************************************/
-
-#ifndef WINUICLIENT_H_
-#define WINUICLIENT_H_
-
-#include <memory>
-#include <mutex>
-#include <map>
-#include "OCPlatform.h"
-#include "OCApi.h"
-#include "OCResource.h"
-
-using namespace OC;
-namespace WinUIClient{
-
-    class Media
-    {
-        public:
-
-            bool m_state;
-            int m_volume;
-            std::string m_name;
-
-            Media() : m_state(false), m_volume(0), m_name("")
-            {
-            }
-    };
-
-    class WinUIClientApp
-    {
-        public:
-            WinUIClientApp(OCPersistentStorage ps);
-            ~WinUIClientApp();
-
-            void Initialize();
-            void Run();
-            void FindResources();
-            void GetMediaRepresentation();
-            void PutMediaRepresentation();
-            void PostMediaRepresentation();
-            void BeginObserving();
-            void CancelObserving();
-
-            std::shared_ptr<OCResource> GetResource();
-            Media GetMedia(){return mymedia;}
-            void SetMedia(bool state, int volume){mymedia.m_state = state; mymedia.m_volume=volume;}
-            bool observing;
-
-        private:
-            void foundResource(std::shared_ptr<OCResource> resource);
-            void onGet(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode);
-            void onPut(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode);
-            void onPost(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode);
-            void onPost2(const HeaderOptions& /*headerOptions*/,const OCRepresentation& rep, const int eCode);
-            void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation& rep, const int& eCode, const int& sequenceNumber);
-        private:
-            int observe_count();
-
-        private:
-            typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;
-
-            OCPersistentStorage persistentStorage;
-            Media mymedia;
-            DiscoveredResourceMap discoveredResources;
-            std::shared_ptr<OCResource> curResource;
-            ObserveType OBSERVE_TYPE_TO_USE;
-            std::mutex curResourceLock;
-    };
-
-}
-
-#endif
-
+/* ****************************************************************\r
+ *\r
+ * Copyright 2016 Intel Corporation All Rights Reserved.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+\r
+#ifndef WINUICLIENT_H_\r
+#define WINUICLIENT_H_\r
+\r
+#include <memory>\r
+#include <mutex>\r
+#include <map>\r
+#include "OCPlatform.h"\r
+#include "OCApi.h"\r
+#include "OCResource.h"\r
+\r
+using namespace OC;\r
+namespace WinUIClient{\r
+\r
+    class Media\r
+    {\r
+        public:\r
+\r
+            bool m_state;\r
+            int m_volume;\r
+            std::string m_name;\r
+\r
+            Media() : m_state(false), m_volume(0), m_name("")\r
+            {\r
+            }\r
+    };\r
+\r
+    class WinUIClientApp\r
+    {\r
+        public:\r
+            WinUIClientApp(OCPersistentStorage ps);\r
+            ~WinUIClientApp();\r
+\r
+            bool Initialize();\r
+            void Run();\r
+            void FindResources();\r
+            void GetMediaRepresentation();\r
+            void PutMediaRepresentation();\r
+            void PostMediaRepresentation();\r
+            void BeginObserving();\r
+            void CancelObserving();\r
+\r
+            std::shared_ptr<OCResource> GetResource();\r
+            Media GetMedia(){return mymedia;}\r
+            void SetMedia(bool state, int volume){mymedia.m_state = state; mymedia.m_volume=volume;}\r
+            bool observing;\r
+\r
+        private:\r
+            void foundResource(std::shared_ptr<OCResource> resource);\r
+            void onGet(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode);\r
+            void onPut(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode);\r
+            void onPost(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode);\r
+            void onPost2(const HeaderOptions& /*headerOptions*/,const OCRepresentation& rep, const int eCode);\r
+            void onObserve(const HeaderOptions /*headerOptions*/, const OCRepresentation& rep, const int& eCode, const int& sequenceNumber);\r
+        private:\r
+            int observe_count();\r
+\r
+        private:\r
+            typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;\r
+\r
+            OCPersistentStorage persistentStorage;\r
+            Media mymedia;\r
+            DiscoveredResourceMap discoveredResources;\r
+            std::shared_ptr<OCResource> curResource;\r
+            ObserveType OBSERVE_TYPE_TO_USE;\r
+            std::mutex curResourceLock;\r
+            bool initialized;\r
+    };\r
+\r
+}\r
+\r
+#endif\r
+\r
index c6921ce..730f899 100644 (file)
@@ -186,8 +186,10 @@ WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
 
               OCPersistentStorage ps = {client_open, fread, fwrite, fclose, unlink };
               app = new WinUIClient::WinUIClientApp(ps);
-              app->Initialize();
-              app->Run();
+              if (app->Initialize())
+              {
+                  app->Run();
+              }
           }
           break;
       case WM_DESTROY:
index 2d200f3..c8250e5 100644 (file)
@@ -31,6 +31,8 @@
 #include <functional>
 #endif
 
+#include "iotivity_debug.h"
+
 #include "octypes.h"
 #include "OCHeaderOption.h"
 #include <OCException.h>
@@ -161,7 +163,34 @@ namespace OC
         /** persistant storage Handler structure (open/read/write/close/unlink). */
         OCPersistentStorage        *ps;
 
+        /**
+         * This flag allows legacy app to opt in the previous behavior of OCPlatform being
+         * cleaned up by the C++ static storage (de)initializer.
+         *
+         * The flag is set to false by default, unless a legacy constructor is used.
+         *
+         * When the flag is set to false (i.e., the new preferred behavior), users of OCPlatform
+         * are responsible for calling start() and stop() explicitly while ensuring that the calls
+         * to them are balanced as the last call to stop() shuts down the underlying stack.
+         */
+        bool                       useLegacyCleanup;
+
         public:
+            PlatformConfig(const ServiceType serviceType_,
+            const ModeType mode_,
+            OCPersistentStorage *ps_)
+                : serviceType(serviceType_),
+                mode(mode_),
+                serverConnectivity(CT_DEFAULT),
+                clientConnectivity(CT_DEFAULT),
+                transportType(OC_DEFAULT_ADAPTER),
+                ipAddress(""),
+                port(0),
+                QoS(QualityOfService::NaQos),
+                ps(ps_),
+                useLegacyCleanup(false)
+        {}
+            /* @deprecated: Use a non deprecated constructor. */
             PlatformConfig()
                 : serviceType(ServiceType::InProc),
                 mode(ModeType::Both),
@@ -171,8 +200,10 @@ namespace OC
                 ipAddress("0.0.0.0"),
                 port(0),
                 QoS(QualityOfService::NaQos),
-                ps(nullptr)
+                ps(nullptr),
+                useLegacyCleanup(true)
         {}
+            /* @deprecated: Use a non deprecated constructor. */
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             OCConnectivityType serverConnectivity_,
@@ -187,9 +218,10 @@ namespace OC
                 ipAddress(""),
                 port(0),
                 QoS(QoS_),
-                ps(ps_)
+                ps(ps_),
+                useLegacyCleanup(true)
         {}
-            // for backward compatibility
+            /* @deprecated: Use a non deprecated constructor. */
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             const std::string& ipAddress_,
@@ -204,8 +236,10 @@ namespace OC
                 ipAddress(ipAddress_),
                 port(port_),
                 QoS(QoS_),
-                ps(ps_)
+                ps(ps_),
+                useLegacyCleanup(true)
         {}
+            /* @deprecated: Use a non deprecated constructor. */
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             const std::string& ipAddress_,
@@ -236,8 +270,10 @@ namespace OC
                 ipAddress(""),
                 port(0),
                 QoS(QoS_),
-                ps(ps_)
+                ps(ps_),
+                useLegacyCleanup(true)
         {}
+            /* @deprecated: Use a non deprecated constructor. */
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             OCConnectivityType serverConnectivity_,
@@ -253,7 +289,8 @@ namespace OC
                 ipAddress(""),
                 port(0),
                 QoS(QoS_),
-                ps(ps_)
+                ps(ps_),
+                useLegacyCleanup(true)
         {}
 
     };
index e51d5df..9891fe8 100644 (file)
@@ -51,6 +51,7 @@ namespace OC
 
         /**
          * API for stop Base layer including resource and connectivity abstraction.
+         * The API is reference counted. The calls to start and stop need to be balanced.
          *
          * @return Returns ::OC_STACK_OK if success.
          */
@@ -59,6 +60,7 @@ namespace OC
         /**
          * API for start Base layer including resource and connectivity abstraction.
          * OCInit will be invoked.
+         * The API is reference counted. The calls to start and stop need to be balanced.
          *
          * @return Returns ::OC_STACK_OK if success.
          */
index 6637c16..bfbab03 100644 (file)
@@ -348,6 +348,8 @@ namespace OC
         IServerWrapper::Ptr m_server;
         IClientWrapper::Ptr m_client;
         std::shared_ptr<std::recursive_mutex> m_csdkLock;
+        std::mutex m_startCountLock;
+        uint32_t m_startCount;
 
     private:
         /**
@@ -361,7 +363,7 @@ namespace OC
         /**
         * Private function to initialize the platform
         */
-        void init(const PlatformConfig& config);
+        OCStackResult init(const PlatformConfig& config);
 
         /**
         * Private constructor/operators to prevent copying
index 5e06e02..0a4eb7e 100644 (file)
@@ -40,9 +40,11 @@ namespace OC
         typedef std::shared_ptr<IWrapperFactory> Ptr;
 
         virtual IClientWrapper::Ptr CreateClientWrapper(
-            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg) =0;
+            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg,
+            OCStackResult *result) =0;
         virtual IServerWrapper::Ptr CreateServerWrapper(
-            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg) =0;
+            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg,
+            OCStackResult *result) =0;
         virtual ~IWrapperFactory(){}
     };
 
@@ -53,30 +55,53 @@ namespace OC
         WrapperFactory(){}
 
         virtual IClientWrapper::Ptr CreateClientWrapper(
-            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
+            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg, OCStackResult *result)
         {
+            if (result)
+            {
+                *result = OC_STACK_NOTIMPL;
+            }
+
             switch(cfg.serviceType)
             {
             case ServiceType::InProc:
+                if (result)
+                {
+                    *result = OC_STACK_OK;
+                }
                 return std::make_shared<InProcClientWrapper>(csdkLock, cfg);
             case ServiceType::OutOfProc:
+                if (result)
+                {
+                    *result = OC_STACK_OK;
+                }
                 return std::make_shared<OutOfProcClientWrapper>(csdkLock, cfg);
+            default:
+                break;
             }
-                       return nullptr;
+            return nullptr;
         }
 
         virtual IServerWrapper::Ptr CreateServerWrapper(
-            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
+            std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg, OCStackResult *result)
         {
+            if (result)
+            {
+                *result = OC_STACK_NOTIMPL;
+            }
+
             switch(cfg.serviceType)
             {
             case ServiceType::InProc:
+                if (result)
+                {
+                    *result = OC_STACK_OK;
+                }
                 return std::make_shared<InProcServerWrapper>(csdkLock, cfg);
-            case ServiceType::OutOfProc:
-                throw OC::OCException(OC::Exception::SVCTYPE_OUTOFPROC, OC_STACK_NOTIMPL);
+            default:
                 break;
             }
-                       return nullptr;
+            return nullptr;
         }
 
         virtual ~WrapperFactory(){}
index 194cb5c..c67e9a5 100644 (file)
@@ -57,22 +57,10 @@ namespace OC
 
     OCStackResult InProcClientWrapper::start()
     {
-        OIC_LOG_V(INFO, TAG, "start ocplatform for client : %d", m_cfg.transportType);
+        OIC_LOG(INFO, TAG, "start");
 
         if (m_cfg.mode == ModeType::Client)
         {
-            OCTransportFlags serverFlags =
-                            static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
-            OCTransportFlags clientFlags =
-                            static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
-            OCStackResult result = OCInit2(OC_CLIENT, serverFlags, clientFlags,
-                                           m_cfg.transportType);
-
-            if (OC_STACK_OK != result)
-            {
-                throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
-            }
-
             if (false == m_threadRun)
             {
                 m_threadRun = true;
@@ -84,25 +72,13 @@ namespace OC
 
     OCStackResult InProcClientWrapper::stop()
     {
-        OIC_LOG(INFO, TAG, "stop ocplatform");
+        OIC_LOG(INFO, TAG, "stop");
 
         if (m_threadRun && m_listeningThread.joinable())
         {
             m_threadRun = false;
             m_listeningThread.join();
         }
-
-        // only stop if we are the ones who actually called 'start'.  We are counting
-        // on the server to do the stop.
-        if (m_cfg.mode == ModeType::Client)
-        {
-            OCStackResult result = OCStop();
-
-            if (OC_STACK_OK != result)
-            {
-               throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, result);
-            }
-        }
         return OC_STACK_OK;
     }
 
index 67a44ca..7d7c200 100644 (file)
@@ -261,43 +261,11 @@ namespace OC
      : m_threadRun(false), m_csdkLock(csdkLock),
        m_cfg { cfg }
     {
-        start();
     }
 
     OCStackResult InProcServerWrapper::start()
     {
-        OIC_LOG_V(INFO, TAG, "start ocplatform for server : %d", m_cfg.transportType);
-
-        OCMode initType;
-        if(m_cfg.mode == ModeType::Server)
-        {
-            initType = OC_SERVER;
-        }
-        else if (m_cfg.mode == ModeType::Both)
-        {
-            initType = OC_CLIENT_SERVER;
-        }
-        else if (m_cfg.mode == ModeType::Gateway)
-        {
-            initType = OC_GATEWAY;
-        }
-        else
-        {
-            throw InitializeException(OC::InitException::NOT_CONFIGURED_AS_SERVER,
-                                         OC_STACK_INVALID_PARAM);
-        }
-
-        OCTransportFlags serverFlags =
-                            static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
-        OCTransportFlags clientFlags =
-                            static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
-        OCStackResult result = OCInit2(initType, serverFlags, clientFlags,
-                                       m_cfg.transportType);
-
-        if(OC_STACK_OK != result)
-        {
-            throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
-        }
+        OIC_LOG(INFO, TAG, "start");
 
         if (false == m_threadRun)
         {
@@ -317,13 +285,6 @@ namespace OC
             m_processThread.join();
         }
 
-        OCStackResult res = OCStop();
-
-        if (OC_STACK_OK != res)
-        {
-           throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, res);
-        }
-
         return OC_STACK_OK;
     }
 
index b04e14e..0908d1f 100644 (file)
@@ -43,6 +43,7 @@
 #include "OCException.h"
 #include "OCUtilities.h"
 #include "ocpayload.h"
+#include "iotivity_debug.h"
 
 #include "logger.h"
 #include "oc_logger.hpp"
@@ -74,39 +75,80 @@ namespace OC
     {
         OIC_LOG(INFO, TAG, "start");
 
-        OCStackResult res = OC_STACK_OK;
-        if (OC_CLIENT == m_modeType)
+        std::lock_guard<std::mutex> lock(m_startCountLock);
+
+        if (0 != m_startCount)
         {
-            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
-            {
-                res = OC_STACK_ERROR;
-            }
+            assert(UINT_MAX != m_startCount);
+            m_startCount++;
+            return OC_STACK_OK;
         }
-        else if (OC_SERVER == m_modeType)
+
+        // Reload from the global configuration.
+        m_cfg = globalConfig();
+
+        // First caller gets to initialize the underlying objects and start the stack.
+        OCStackResult res = init(m_cfg);
+        if (OC_STACK_OK != res)
         {
-            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
-            {
-                res = OC_STACK_ERROR;
-            }
+            return res;
         }
-        else if (OC_CLIENT_SERVER == m_modeType || OC_GATEWAY == m_modeType)
+
+        OCTransportFlags serverFlags =
+                        static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
+        OCTransportFlags clientFlags =
+                        static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
+        res = OCInit2(m_modeType, serverFlags, clientFlags, m_cfg.transportType);
+        if (OC_STACK_OK != res)
         {
-            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
-            {
-                res = OC_STACK_ERROR;
-            }
+            return res;
+        }
 
-            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
-            {
+        switch(m_modeType)
+        {
+            case OC_CLIENT:
+                if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
+                {
+                    res = OC_STACK_ERROR;
+                }
+                break;
+
+            case OC_SERVER:
+                if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
+                {
+                    res = OC_STACK_ERROR;
+                }
+                break;
+
+            case OC_CLIENT_SERVER:
+            case OC_GATEWAY:
+                if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
+                {
+                    res = OC_STACK_ERROR;
+                }
+                if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
+                {
+                    res = OC_STACK_ERROR;
+                }
+                break;
+
+            default:
+                assert(!"Unknown modeType");
                 res = OC_STACK_ERROR;
-            }
+                break;
         }
-        else
+
+        if (OC_STACK_OK != res)
         {
-            res = OC_STACK_ERROR;
+            // Stop the underlying stack.
+            // The counterpart of this function, OCInit2(), is called once by start().
+            OC_VERIFY(OC_STACK_OK == OCStop());
+            return res;
         }
 
-        return res;
+        assert(UINT_MAX != m_startCount);
+        m_startCount++;
+        return OC_STACK_OK;
     }
 
     OCStackResult OCPlatform_impl::stop()
@@ -114,75 +156,109 @@ namespace OC
         OIC_LOG(INFO, TAG, "stop");
 
         OCStackResult res = OC_STACK_OK;
-        if (OC_CLIENT == m_modeType)
+
+        std::lock_guard<std::mutex> lock(m_startCountLock);
+
+        // Only the last call to stop() gets to do the real clean up work.
+        if (m_startCount == 1)
         {
-            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+            if (OC_CLIENT == m_modeType)
             {
-                res = OC_STACK_ERROR;
+                if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+                {
+                    res = OC_STACK_ERROR;
+                }
             }
-        }
-        else if (OC_SERVER == m_modeType)
-        {
-            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+            else if (OC_SERVER == m_modeType)
             {
-                res = OC_STACK_ERROR;
+                if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+                {
+                    res = OC_STACK_ERROR;
+                }
             }
-        }
-        else if (OC_CLIENT_SERVER == m_modeType)
-        {
-            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+            else if (OC_CLIENT_SERVER == m_modeType)
+            {
+                if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+                {
+                    res = OC_STACK_ERROR;
+                }
+
+                if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+                {
+                    res = OC_STACK_ERROR;
+                }
+            }
+            else
             {
                 res = OC_STACK_ERROR;
             }
 
-            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+            if (OC_STACK_OK == res)
             {
-                res = OC_STACK_ERROR;
+                res = OCStop();
             }
         }
-        else
+
+        if (OC_STACK_OK == res)
         {
-            res = OC_STACK_ERROR;
+            assert(0 != m_startCount);
+            m_startCount--;
         }
 
         return res;
     }
 
-    void OCPlatform_impl::init(const PlatformConfig& config)
+    OCStackResult OCPlatform_impl::init(const PlatformConfig& config)
     {
         OIC_LOG(INFO, TAG, "init");
 
+        OCStackResult result = OC_STACK_NOTIMPL;
         switch(config.mode)
         {
             case ModeType::Server:
-                m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
+                m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config, &result);
                 m_modeType = OC_SERVER;
                 break;
 
             case ModeType::Client:
-                m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
+                m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config, &result);
                 m_modeType = OC_CLIENT;
                 break;
 
             case ModeType::Both:
             case ModeType::Gateway:
-                m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
-                m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
+                m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config, &result);
+                m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config, &result);
                 m_modeType = OC_CLIENT_SERVER;
                 break;
-         }
+        }
+
+        if (OC_STACK_OK != result)
+        {
+            m_server.reset();
+            m_client.reset();
+        }
+        return result;
     }
 
     OCPlatform_impl::OCPlatform_impl(const PlatformConfig& config)
      : m_cfg             { config },
        m_WrapperInstance { make_unique<WrapperFactory>() },
-       m_csdkLock        { std::make_shared<std::recursive_mutex>() }
+       m_csdkLock        { std::make_shared<std::recursive_mutex>() },
+       m_startCount(0)
     {
-        init(m_cfg);
+        if (m_cfg.useLegacyCleanup)
+        {
+            start();
+        }
     }
 
     OCPlatform_impl::~OCPlatform_impl(void)
     {
+        if (m_cfg.useLegacyCleanup)
+        {
+            stop();
+        }
     }
 
     OCStackResult OCPlatform_impl::setDefaultDeviceEntityHandler(EntityHandler entityHandler)
index b71b627..ae74b11 100644 (file)
@@ -21,6 +21,7 @@
 #include <OCPlatform.h>
 #include <OCApi.h>
 #include <oic_malloc.h>
+#include <iotivity_debug.h>
 #include <gtest/gtest.h>
 
 namespace OCPlatformTest
@@ -138,13 +139,42 @@ namespace OCPlatformTest
         }
     }
 
+    class Framework
+    {
+    public:
+        Framework(ServiceType serviceType = OC::ServiceType::InProc,
+                  ModeType mode = OC::ModeType::Server,
+                  OCPersistentStorage *ps = nullptr)
+                  : m_started(false)
+        {
+            PlatformConfig cfg(serviceType, mode, ps);
+            OCPlatform::Configure(cfg);
+        }
+        ~Framework()
+        {
+            if (m_started)
+            {
+                OC_VERIFY(OC_STACK_OK == OCPlatform::stop());
+                m_started = false;
+            }
+        }
+        OCStackResult start()
+        {
+            OCStackResult result = OCPlatform::start();
+            if (OC_STACK_OK == result)
+            {
+                m_started = true;
+            }
+            return result;
+        }
+
+    private:
+        bool m_started;
+    };
+
     OCResourceHandle RegisterResource(std::string uri, std::string type, std::string iface)
     {
-        PlatformConfig cfg
-        { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0", 0,
-                OC::QualityOfService::LowQos, &gps };
-        OCPlatform::Configure(cfg);
-        EXPECT_EQ(OC_STACK_OK,OCPlatform::registerResource(
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
                                         resourceHandle, uri, type,
                                         iface, entityHandler, gResourceProperty));
         return resourceHandle;
@@ -152,10 +182,6 @@ namespace OCPlatformTest
 
     OCResourceHandle RegisterResource(std::string uri, std::string type)
     {
-        PlatformConfig cfg
-        { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0", 0,
-                OC::QualityOfService::LowQos, &gps };
-        OCPlatform::Configure(cfg);
         EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
                                         resourceHandle, uri, type,
                                         gResourceInterface, entityHandler, gResourceProperty));
@@ -164,10 +190,6 @@ namespace OCPlatformTest
 
     OCResourceHandle RegisterResource(std::string uri)
     {
-        PlatformConfig cfg
-        { OC::ServiceType::InProc, OC::ModeType::Server, "0.0.0.0", 0,
-                OC::QualityOfService::LowQos, &gps };
-        OCPlatform::Configure(cfg);
         EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
                                         resourceHandle, uri, gResourceTypeName,
                                         gResourceInterface, entityHandler, gResourceProperty));
@@ -176,10 +198,6 @@ namespace OCPlatformTest
 
     OCResourceHandle RegisterResource(std::string uri, OCTpsSchemeFlags resourceTpsTypes)
     {
-        PlatformConfig cfg
-        { OC::ServiceType::OutOfProc, OC::ModeType::Server, "0.0.0.0", 0,
-                OC::QualityOfService::LowQos, &gps };
-        OCPlatform::Configure(cfg);
         EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource(
                                         resourceHandle, uri, gResourceTypeName,
                                         gResourceInterface, entityHandler, gResourceProperty,
@@ -187,104 +205,40 @@ namespace OCPlatformTest
         return resourceHandle;
     }
 
-    //Configure
-    // Enable it when the stack throw an exception
-    // https://jira.iotivity.org/browse/IOT-428
-    TEST(ConfigureTest, DISABLED_ConfigureInvalidModeType)
-    {
-        PlatformConfig cfg {
-             OC::ServiceType::InProc,
-            (OC::ModeType)99,
-             "0.0.0.0",
-             0,
-             OC::QualityOfService::LowQos
-         };
-         OCPlatform::Configure(cfg);
-         EXPECT_ANY_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
-     }
+    TEST(ConfigureTest, ConfigureInvalidModeType)
+    {
+        Framework framework(OC::ServiceType::InProc, (OC::ModeType)99);
+        EXPECT_EQ(OC_STACK_NOTIMPL, framework.start());
+    }
 
-    // Enable it when the stack throw an exception
-    // https://jira.iotivity.org/browse/IOT-428
-    TEST(ConfigureTest, DISABLED_ConfigureInvalidServiceType)
-    {
-        PlatformConfig cfg {
-             (OC::ServiceType)99,
-            OC::ModeType::Client,
-             "0.0.0.0",
-             0,
-             OC::QualityOfService::LowQos
-         };
-         OCPlatform::Configure(cfg);
-         EXPECT_ANY_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
-     }
+    TEST(ConfigureTest, ConfigureInvalidServiceType)
+    {
+        Framework framework((OC::ServiceType)99, OC::ModeType::Client);
+        EXPECT_EQ(OC_STACK_NOTIMPL, framework.start());
+    }
 
     // Enable it when the stack throw an exception
     // https://jira.iotivity.org/browse/IOT-428
     TEST(ConfigureTest, DISABLED_ConfigureClientOutProc)
     {
-        PlatformConfig cfg {
-            OC::ServiceType::OutOfProc,
-            OC::ModeType::Client,
-            "0.0.0.0",
-            0,
-            OC::QualityOfService::LowQos
-        };
-        std::string uri = "/a/light66";
-        std::string type = "core.light";
-        uint8_t gResourceProperty = 0;
-        OCPlatform::Configure(cfg);
-        EXPECT_ANY_THROW(OCPlatform::registerResource(
-             resourceHandle, uri, type,
-             gResourceInterface, entityHandler, gResourceProperty));
+        Framework framework(OC::ServiceType::OutOfProc, OC::ModeType::Client, &gps);
+        EXPECT_EQ(OC_STACK_NOTIMPL, framework.start());
     }
 
     TEST(ConfigureTest, ConfigureServerOutProc)
     {
-        PlatformConfig cfg
-        {
-            OC::ServiceType::OutOfProc,
-            OC::ModeType::Server,
-            "0.0.0.0",
-            0,
-            OC::QualityOfService::LowQos, &gps
-        };
-        std::string uri = "/a/light67";
-        std::string type = "core.light";
-        uint8_t gResourceProperty = 0;
-        OCPlatform::Configure(cfg);
-
-        EXPECT_ANY_THROW(OCPlatform::registerResource(
-             resourceHandle, uri, type,
-             gResourceInterface, entityHandler, gResourceProperty));
-    }
-
-    TEST(ConfigureTest, ConfigureDefault)
-    {
-        std::string uri = "/a/light68";
-        std::string type = "core.light";
-        uint8_t gResourceProperty = 0;
-        PlatformConfig cfg = {};
-        OCPlatform::Configure(cfg);
-
-        EXPECT_NO_THROW(OCPlatform::registerResource(
-                 resourceHandle, uri, type,
-                 gResourceInterface, entityHandler, gResourceProperty));
+        Framework framework(OC::ServiceType::OutOfProc, OC::ModeType::Server);
+        EXPECT_EQ(OC_STACK_NOTIMPL, framework.start());
     }
 
     TEST(ConfigureTest, ConfigureServer)
     {
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Server, &gps);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string uri = "/a/light69";
         std::string type = "core.light";
         uint8_t gResourceProperty = 0;
-        PlatformConfig cfg {
-            OC::ServiceType::InProc,
-            OC::ModeType::Server,
-            "0.0.0.0",
-            0,
-            OC::QualityOfService::LowQos, &gps
-        };
-        OCPlatform::Configure(cfg);
-
         EXPECT_NO_THROW(OCPlatform::registerResource(
                  resourceHandle, uri, type,
                  gResourceInterface, entityHandler, gResourceProperty));
@@ -292,92 +246,43 @@ namespace OCPlatformTest
 
     TEST(ConfigureTest, ConfigureClient)
     {
-        std::string uri = "/a/light70";
-        std::string type = "core.light";
-        uint8_t gResourceProperty = 0;
-        PlatformConfig cfg
-        {
-            OC::ServiceType::InProc,
-            OC::ModeType::Client,
-            "0.0.0.0",
-            0,
-            OC::QualityOfService::LowQos,
-            &gps
-        };
-
-        EXPECT_NO_THROW(OCPlatform::registerResource(
-                 resourceHandle, uri, type,
-                 gResourceInterface, entityHandler, gResourceProperty));
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Client, &gps);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
     }
-    //PersistentStorageTest
-    TEST(ConfigureTest, ConfigureDefaultNULLPersistentStorage)
-    {
-        PlatformConfig cfg {
-             OC::ServiceType::InProc,
-             OC::ModeType::Both,
-             "0.0.0.0",
-             0,
-             OC::QualityOfService::LowQos
-         };
-         OCPlatform::Configure(cfg);
-         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
-     }
 
     //PersistentStorageTest
     TEST(ConfigureTest, ConfigureNULLPersistentStorage)
     {
-        PlatformConfig cfg {
-             OC::ServiceType::InProc,
-             OC::ModeType::Both,
-             "0.0.0.0",
-             0,
-             OC::QualityOfService::LowQos,
-             nullptr
-         };
-         OCPlatform::Configure(cfg);
-         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
-     }
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
 
-    //PersistentStorageTest
-    TEST(ConfigureTest, ConfigurePersistentStorage)
-    {
-         PlatformConfig cfg {
-             OC::ServiceType::InProc,
-             OC::ModeType::Both,
-             "0.0.0.0",
-             0,
-             OC::QualityOfService::LowQos,
-             &gps
-         };
-         OCPlatform::Configure(cfg);
-         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
-     }
+        EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+    }
 
     //PersistentStorageTest
     TEST(ConfigureTest, ConfigureNULLHandlersPersistentStorage)
     {
-        PlatformConfig cfg {
-             OC::ServiceType::InProc,
-             OC::ModeType::Both,
-             "0.0.0.0",
-             0,
-             OC::QualityOfService::LowQos,
-             &gps
-         };
-         OCPlatform::Configure(cfg);
-         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
-     }
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both, &gps);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
 
+        EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+    }
 
     //RegisterResourceTest
     TEST(RegisterResourceTest, RegisterSingleResource)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string uri = "/a/res2";
         EXPECT_NE(HANDLE_ZERO, RegisterResource(uri));
     }
 
     TEST(RegisterResourceTest, RegisterMultipleResources)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string uri = "/a/multi";
         //Good enough for 5 resources.
         for(int i=0; i< 5; i++)
@@ -389,6 +294,9 @@ namespace OCPlatformTest
 
     TEST(RegisterResourceTest, ReregisterResource)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light5"),
             std::string("core.light"));
         EXPECT_EQ(OC_STACK_OK, OC::OCPlatform::unregisterResource(resourceHandle));
@@ -400,6 +308,9 @@ namespace OCPlatformTest
 
     TEST(RegisterResourceTest, RegisterEmptyResource)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         // We should not allow empty URI.
         std::string emptyStr = "";
         EXPECT_ANY_THROW(OCPlatform::registerResource(resourceHandle, emptyStr, emptyStr,
@@ -408,6 +319,9 @@ namespace OCPlatformTest
 
     TEST(RegisterResourceTest, RegisterZeroResourceProperty)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string uri = "/a/light6";
         std::string type = "core.light";
         uint8_t gResourceProperty = 0;
@@ -418,6 +332,9 @@ namespace OCPlatformTest
 
     TEST(RegisterResourceTest, RegisterWithTpsType)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string uri = "/a/light7";
         std::string type = "core.light";
         uint8_t gResourceProperty = 0;
@@ -428,6 +345,9 @@ namespace OCPlatformTest
 
     TEST(RegisterResourceTest, RegisterWithTpsTypeAll)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string uri = "/a/light8";
         std::string type = "core.light";
         uint8_t gResourceProperty = 0;
@@ -438,6 +358,9 @@ namespace OCPlatformTest
 #ifdef TCP_ADAPTER
     TEST(RegisterResourceTest, RegisterWithTpsTypeBitComb)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string uri = "/a/light9";
         std::string type = "core.light";
         uint8_t gResourceProperty = 0;
@@ -450,12 +373,18 @@ namespace OCPlatformTest
     //UnregisterTest
     TEST(UnregisterTest, UnregisterZeroHandleValue)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         EXPECT_ANY_THROW(OC::OCPlatform::unregisterResource(HANDLE_ZERO));
     }
 
     //UnbindResourcesTest
     TEST(UnbindResourcesTest, UnbindResources)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("a/home"),
             std::string("core.home"));
         OCResourceHandle resourceKitchen = RegisterResource(std::string("a/kitchen"),
@@ -472,6 +401,9 @@ namespace OCPlatformTest
 
     TEST(UnbindResourcesTest, UnbindResourcesWithZero)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHandle1 = 0;
         OCResourceHandle resourceHandle2 = 0;
         OCResourceHandle resourceHandle3 = 0;
@@ -487,6 +419,9 @@ namespace OCPlatformTest
     //BindInterfaceToResourceTest
     TEST(BindInterfaceToResourceTest, BindResourceInterface)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light"),
             std::string("core.light"));
         OCStackResult result = OC::OCPlatform::bindInterfaceToResource(resourceHandle,
@@ -500,6 +435,9 @@ namespace OCPlatformTest
     TEST(BindInterfaceToResourceTest, BindZeroResourceInterface)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light1"),
             std::string("core.light"));
         EXPECT_ANY_THROW(OC::OCPlatform::bindInterfaceToResource(resourceHandle, 0));
@@ -508,6 +446,9 @@ namespace OCPlatformTest
     //BindTypeToResourceTest
     TEST(BindTypeToResourceTest, BindResourceType)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light3"),
             std::string("core.light"));
         OCStackResult result = OC::OCPlatform::bindTypeToResource(resourceHandle,
@@ -521,6 +462,9 @@ namespace OCPlatformTest
     TEST(BindTypeToResourceTest, BindZeroResourceType)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light4"),
             std::string("core.light"));
         EXPECT_ANY_THROW(OC::OCPlatform::bindTypeToResource(resourceHandle, 0));
@@ -529,6 +473,9 @@ namespace OCPlatformTest
     //UnbindResourceTest
     TEST(UnbindResourceTest, BindAndUnbindResource)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHandle1 = RegisterResource(std::string("a/unres"),
             std::string("core.unres"));
         OCResourceHandle resourceHandle2 = RegisterResource(std::string("a/unres2"),
@@ -541,6 +488,9 @@ namespace OCPlatformTest
     //PresenceTest
     TEST(PresenceTest, DISABLED_StartAndStopPresence)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         EXPECT_EQ(OC_STACK_OK, OCPlatform::startPresence(30));
         EXPECT_NE(HANDLE_ZERO, RegisterResource( std::string("/a/Presence"),
             std::string("core.Presence")));
@@ -549,12 +499,18 @@ namespace OCPlatformTest
 
     TEST(OCPlatformTest, UnbindZeroRsourceHandleValue)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         EXPECT_ANY_THROW(OCPlatform::unbindResource(HANDLE_ZERO, HANDLE_ZERO));
     }
 
     //NotifyAllObserverTest
     TEST(NotifyAllObserverTest, NotifyAllObservers)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs1"),
             std::string("core.obs"));
         EXPECT_EQ(OC_STACK_NO_OBSERVERS, OCPlatform::notifyAllObservers(resourceHome));
@@ -562,6 +518,9 @@ namespace OCPlatformTest
 
     TEST(NotifyAllObserverTest, NotifyAllObserversWithLowQos)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs2"),
             std::string("core.obs"));
         EXPECT_EQ(OC_STACK_NO_OBSERVERS, OCPlatform::notifyAllObservers(resourceHome,
@@ -570,6 +529,9 @@ namespace OCPlatformTest
 
     TEST(NotifyAllObserverTest, NotifyAllObserversWithMidQos)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs3"),
             std::string("core.obs"));
         EXPECT_EQ(OC_STACK_NO_OBSERVERS, OCPlatform::notifyAllObservers(resourceHome,
@@ -578,6 +540,9 @@ namespace OCPlatformTest
 
     TEST(NotifyAllObserverTest, NotifyAllObserversWithNaQos)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs4"),
             std::string("core.obs"));
         EXPECT_EQ(OC_STACK_NO_OBSERVERS, OCPlatform::notifyAllObservers(resourceHome,
@@ -586,6 +551,9 @@ namespace OCPlatformTest
 
     TEST(NotifyAllObserverTest, NotifyAllObserversWithHighQos)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs5"),
             std::string("core.obs"));
         EXPECT_EQ(OC_STACK_NO_OBSERVERS, OCPlatform::notifyAllObservers(resourceHome,
@@ -598,6 +566,9 @@ namespace OCPlatformTest
     TEST(NotifyAllObserverTest, NotifyListOfObservers)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs6"),
             std::string("core.obs"));
 
@@ -613,6 +584,9 @@ namespace OCPlatformTest
     TEST(NotifyAllObserverTest, NotifyListOfObserversWithLowQos)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs7"),
             std::string("core.obs"));
 
@@ -628,6 +602,9 @@ namespace OCPlatformTest
     TEST(NotifyAllObserverTest, NotifyListOfObserversWithMidQos)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs8"),
             std::string("core.obs"));
 
@@ -643,6 +620,9 @@ namespace OCPlatformTest
     TEST(NotifyAllObserverTest, NotifyListOfObserversWithNaQos)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs9"),
             std::string("core.obs"));
 
@@ -658,6 +638,9 @@ namespace OCPlatformTest
     TEST(NotifyAllObserverTest, NotifyListOfObserversWithHighQos)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs10"),
             std::string("core.obs"));
 
@@ -670,6 +653,9 @@ namespace OCPlatformTest
     //DeviceEntityHandlerTest
     TEST(DeviceEntityHandlerTest, SetDefaultDeviceEntityHandler)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         EXPECT_EQ(OC_STACK_OK, OCPlatform::setDefaultDeviceEntityHandler(entityHandler));
         EXPECT_EQ(OC_STACK_OK, OCPlatform::setDefaultDeviceEntityHandler(nullptr));
     }
@@ -678,10 +664,13 @@ namespace OCPlatformTest
     //FindResource test
     TEST(FindResourceTest, DISABLED_FindResourceValid)
     {
-      std::ostringstream requestURI;
-      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
-      EXPECT_EQ(OC_STACK_OK, OCPlatform::findResource("", requestURI.str(),
-              CT_DEFAULT, &foundResource));
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
+        std::ostringstream requestURI;
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
+        EXPECT_EQ(OC_STACK_OK, OCPlatform::findResource("", requestURI.str(),
+                CT_DEFAULT, &foundResource));
     }
 
 #if defined (_MSC_VER)
@@ -690,8 +679,11 @@ namespace OCPlatformTest
     TEST(FindResourceTest, FindResourceNullResourceURI)
 #endif
     {
-      EXPECT_ANY_THROW(OCPlatform::findResource("", nullptr,
-              CT_DEFAULT, &foundResource));
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
+        EXPECT_ANY_THROW(OCPlatform::findResource("", nullptr,
+                CT_DEFAULT, &foundResource));
     }
 
 
@@ -701,10 +693,13 @@ namespace OCPlatformTest
     TEST(FindResourceTest, FindResourceNullResourceURI1)
 #endif
     {
-      std::ostringstream requestURI;
-      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
-      EXPECT_ANY_THROW(OCPlatform::findResource(nullptr, requestURI.str(),
-              CT_DEFAULT, &foundResource));
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
+        std::ostringstream requestURI;
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
+        EXPECT_ANY_THROW(OCPlatform::findResource(nullptr, requestURI.str(),
+                CT_DEFAULT, &foundResource));
     }
 
 #if defined (_MSC_VER)
@@ -713,22 +708,31 @@ namespace OCPlatformTest
     TEST(FindResourceTest, FindResourceNullHost)
 #endif
     {
-      std::ostringstream requestURI;
-      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
-      EXPECT_ANY_THROW(OCPlatform::findResource(nullptr, requestURI.str(),
-              CT_DEFAULT, &foundResource));
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
+        std::ostringstream requestURI;
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
+        EXPECT_ANY_THROW(OCPlatform::findResource(nullptr, requestURI.str(),
+                CT_DEFAULT, &foundResource));
     }
 
     TEST(FindResourceTest, FindResourceNullresourceHandler)
     {
-      std::ostringstream requestURI;
-      requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
-      EXPECT_THROW(OCPlatform::findResource("", requestURI.str(),
-              CT_DEFAULT, nullptr), OC::OCException);
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
+        std::ostringstream requestURI;
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
+        EXPECT_THROW(OCPlatform::findResource("", requestURI.str(),
+                CT_DEFAULT, nullptr), OC::OCException);
     }
 
     TEST(FindResourceTest, DISABLED_FindResourceWithLowQoS)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::ostringstream requestURI;
         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
@@ -738,6 +742,9 @@ namespace OCPlatformTest
 
     TEST(FindResourceTest, DISABLED_FindResourceWithMidQos)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::ostringstream requestURI;
         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
@@ -747,6 +754,9 @@ namespace OCPlatformTest
 
     TEST(FindResourceTest, DISABLED_FindResourceWithHighQos)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::ostringstream requestURI;
         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
@@ -756,6 +766,9 @@ namespace OCPlatformTest
 
     TEST(FindResourceTest, DISABLED_FindResourceWithNaQos)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::ostringstream requestURI;
         requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=core.light";
         EXPECT_EQ(OC_STACK_OK,
@@ -766,9 +779,10 @@ namespace OCPlatformTest
     //GetDeviceInfo Test
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithValidParameters)
     {
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string deviceDiscoveryURI = "/oic/d";
-        PlatformConfig cfg;
-        OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
@@ -781,17 +795,19 @@ namespace OCPlatformTest
     TEST(GetDeviceInfoTest, GetDeviceInfoNullDeviceURI)
 #endif
     {
-        PlatformConfig cfg;
-        OCPlatform::Configure(cfg);
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         EXPECT_ANY_THROW(
                 OCPlatform::getDeviceInfo("", nullptr, CT_DEFAULT, &receivedDeviceInfo));
     }
 
     TEST(GetDeviceInfoTest, GetDeviceInfoWithNullDeviceInfoHandler)
     {
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string deviceDiscoveryURI = "/oic/d";
-        PlatformConfig cfg;
-        OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_THROW(
@@ -801,9 +817,10 @@ namespace OCPlatformTest
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithLowQos)
     {
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string deviceDiscoveryURI = "/oic/d";
-        PlatformConfig cfg;
-        OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
@@ -813,9 +830,10 @@ namespace OCPlatformTest
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithMidQos)
     {
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string deviceDiscoveryURI = "/oic/d";
-        PlatformConfig cfg;
-        OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
@@ -825,9 +843,10 @@ namespace OCPlatformTest
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithHighQos)
     {
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string deviceDiscoveryURI = "/oic/d";
-        PlatformConfig cfg;
-        OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
@@ -837,9 +856,10 @@ namespace OCPlatformTest
 
     TEST(GetDeviceInfoTest, DISABLED_GetDeviceInfoWithNaQos)
     {
+        Framework framework(OC::ServiceType::InProc, OC::ModeType::Both);
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string deviceDiscoveryURI = "/oic/d";
-        PlatformConfig cfg;
-        OCPlatform::Configure(cfg);
         std::ostringstream requestURI;
         requestURI << OC_MULTICAST_PREFIX << deviceDiscoveryURI;
         EXPECT_EQ(OC_STACK_OK,
@@ -856,6 +876,9 @@ namespace OCPlatformTest
     //RegisterDeviceInfo test
     TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithValidParameters)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCDeviceInfo deviceInfo;
         DuplicateString(&deviceInfo.deviceName, "myDeviceName");
         deviceInfo.types = NULL;
@@ -873,12 +896,18 @@ namespace OCPlatformTest
 
     TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithEmptyObject)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCDeviceInfo di = {0, 0, 0, 0};
         EXPECT_ANY_THROW(OCPlatform::registerDeviceInfo(di));
     }
 
     TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithSetPropertyValue)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string deviceName = "myDeviceName";
         EXPECT_EQ(OC_STACK_OK, OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME,
             deviceName));
@@ -899,6 +928,9 @@ namespace OCPlatformTest
 
     TEST(RegisterDeviceInfoTest, RegisterDeviceInfoWithGetPropertyValue)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         EXPECT_EQ(OC_STACK_OK, OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME,
             "myDeviceName"));
         EXPECT_EQ(OC_STACK_OK, OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_SPEC_VERSION,
@@ -922,12 +954,14 @@ namespace OCPlatformTest
         EXPECT_STREQ("myDataModelVersions", dmv[0].c_str());
 
         EXPECT_STREQ("oic.wk.d", OCGetResourceTypeName(handle, 0));
-        EXPECT_STREQ("oic.d.tv", OCGetResourceTypeName(handle, 1));
-        EXPECT_STREQ("oic.wk.tv", OCGetResourceTypeName(handle, 2));
+        EXPECT_STREQ("oic.wk.tv", OCGetResourceTypeName(handle, 1));
     }
     //SubscribePresence Test
     TEST(SubscribePresenceTest, DISABLED_SubscribePresenceWithValidParameters)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string hostAddress = "192.168.1.2:5000";
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
@@ -941,8 +975,10 @@ namespace OCPlatformTest
     TEST(SubscribePresenceTest, SubscribePresenceWithNullHost)
 #endif
     {
-        OCPlatform::OCPresenceHandle presenceHandle = nullptr;
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
 
+        OCPlatform::OCPresenceHandle presenceHandle = nullptr;
         EXPECT_ANY_THROW(OCPlatform::subscribePresence(presenceHandle, nullptr,
                  CT_DEFAULT, &presenceHandler));
     }
@@ -953,6 +989,9 @@ namespace OCPlatformTest
     TEST(SubscribePresenceTest, SubscribePresenceWithNullPresenceHandler)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_ANY_THROW(OCPlatform::subscribePresence(presenceHandle, nullptr,
@@ -961,6 +1000,9 @@ namespace OCPlatformTest
 
     TEST(SubscribePresenceTest, DISABLED_SubscribePresenceWithResourceType)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribePresence(presenceHandle,
@@ -973,6 +1015,9 @@ namespace OCPlatformTest
     TEST(SubscribePresenceTest, SubscribePresenceWithNullResourceType)
 #endif
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_ANY_THROW(OCPlatform::subscribePresence(presenceHandle,
@@ -981,6 +1026,9 @@ namespace OCPlatformTest
 
     TEST(SubscribePresenceTest, DISABLED_UnsubscribePresenceWithValidHandleAndRT)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribePresence(presenceHandle,
@@ -990,12 +1038,18 @@ namespace OCPlatformTest
 
     TEST(SubscribePresenceTest, UnsubscribePresenceWithNullHandle)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
         EXPECT_ANY_THROW(OCPlatform::unsubscribePresence(presenceHandle));
     }
 
     TEST(SubscribePresenceTest, DISABLED_UnsubscribePresenceWithValidHandle)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
 
         EXPECT_EQ(OC_STACK_OK, OCPlatform::subscribePresence(presenceHandle,
@@ -1007,6 +1061,9 @@ namespace OCPlatformTest
     // SubscribeDevicePresence Test
     TEST(SubscribeDevicePresenceTest, DISABLED_SubscribeDevicePresenceWithValidParameters)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string hostAddress = "192.168.1.2:5000";
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
         std::vector<std::string> di;
@@ -1017,6 +1074,9 @@ namespace OCPlatformTest
 
     TEST(SubscribeDevicePresenceTest, SubscribeDevicePresenceWithNullHost)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
         std::vector<std::string> di;
 
@@ -1026,6 +1086,9 @@ namespace OCPlatformTest
 
     TEST(SubscribeDevicePresenceTest, SubscribeDevicePresenceWithNullOnObserve)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string hostAddress = "192.168.1.2:5000";
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
         std::vector<std::string> di;
@@ -1036,6 +1099,9 @@ namespace OCPlatformTest
 
     TEST(SubscribeDevicePresenceTest, DISABLED_UnsubscribePresenceWithValidHandle)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         std::string hostAddress = "192.168.1.2:5000";
         OCPlatform::OCPresenceHandle presenceHandle = nullptr;
         std::vector<std::string> di;
@@ -1048,21 +1114,30 @@ namespace OCPlatformTest
 
     TEST(FindDirectPairingTest, FindDirectPairingNullCallback)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
         EXPECT_ANY_THROW(OCPlatform::findDirectPairingDevices(1, nullptr));
     }
 
     TEST(FindDirectPairingTest, FindDirectPairingZeroTimeout)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
         EXPECT_ANY_THROW(OCPlatform::findDirectPairingDevices(0, &pairedHandler));
     }
 
     TEST(GetDirectPairedTest, GetDirectPairedNullCallback)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
         EXPECT_ANY_THROW(OCPlatform::getDirectPairedDevices(nullptr));
     }
 
     TEST(DoDirectPairingTest, DoDirectPairingNullCallback)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCDPDev_t peer;
         OCPrm_t pmSel = DP_PRE_CONFIGURED;
         std::string pin("");
@@ -1072,6 +1147,9 @@ namespace OCPlatformTest
 
     TEST(DoDirectPairingTest, DoDirectPairingNullPeer)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCDPDev_t peer;
         OCPrm_t pmSel = DP_PRE_CONFIGURED;
         std::string pin("");
@@ -1081,6 +1159,9 @@ namespace OCPlatformTest
 
     TEST(DoDirectPairingTest, DoDirectPairingNullPeerNullCallback)
     {
+        Framework framework;
+        ASSERT_TRUE(OC_STACK_OK == framework.start());
+
         OCDPDev_t peer;
         OCPrm_t pmSel = DP_PRE_CONFIGURED;
         std::string pin("");
index f2e2df5..6ddbed5 100644 (file)
@@ -1602,6 +1602,8 @@ namespace OCRepresentationEncodingTest
         EXPECT_STREQ("if.firstitem", parsedPayload->interfaces->value);
         EXPECT_EQ(NULL, parsedPayload->interfaces->next);
 
+        OCRepPayloadValue *originalRootValues = parsedPayload->values;
+
         // To make sure rt and if are not duplicated.
         EXPECT_STREQ("BoolAttr", parsedPayload->values->name);
         EXPECT_EQ(true, parsedPayload->values->b);
@@ -1629,6 +1631,9 @@ namespace OCRepresentationEncodingTest
 
         EXPECT_EQ(NULL, parsedPayload->values);
 
+        // Recover the original value to ensure a proper cleanup.
+        parsedPayload->values = originalRootValues;
+
         OICFree(cborData);
         OCRepPayloadDestroy(repPayload);
         OCPayloadDestroy(cparsed);
index fbf1ebd..fee90aa 100644 (file)
@@ -60,8 +60,10 @@ def run_test(env, xml_file, test, test_targets = ['test']):
         # Valgrind suppressions file.
         suppression_file = env.File('#tools/valgrind/iotivity.supp').srcnode().path
 
-        # Set up to run the test under Valgrind.
-        test_cmd = '%s valgrind --leak-check=full --suppressions=%s --xml=yes --xml-file=%s %s' % (valgrind_environment, suppression_file, xml_file, test_cmd)
+        # Set up to run the test under Valgrind. The "--num-callers" option specifies the
+        # callstack depth (default, if not specified, is 12). We are increasing it here to
+        # allow unit test name to be visible in the leak report.
+        test_cmd = '%s valgrind --leak-check=full --suppressions=%s --num-callers=24 --xml=yes --xml-file=%s %s' % (valgrind_environment, suppression_file, xml_file, test_cmd)
     if env.get('TARGET_OS') in ['linux']:
         env.Depends('ut' + test , os.path.join(build_dir, test))
     ut = env.Command('ut' + test, None, test_cmd)