From: George Nash Date: Mon, 28 Aug 2017 23:25:21 +0000 (-0700) Subject: provisioning: Fixed memory leak X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dab3e302970a77e66f755ee5279fd910e65d1057;p=platform%2Fupstream%2Fiotivity.git provisioning: Fixed memory leak Fixed memory leak found using valgrind. The memory leak was due to the provisionInit function calling sqlite3_open_v2 without calling sqlite3_close There was not provisionClose method in the C++ so it was added to the OCSecure class. To do this OCClosePM was also added to that the code could be used in Windows. The provisioningClose call was added to all of the samples that are currently calling provisioningInit(dbfile) While updating the some of the android samples the tab depth was cleaned. Note the unit tests are not following one of the most basic rules of unit testing. Tests should be isolated and independent. When the cleanup code was added to the unit tests it broke tests that run later. Each individual unit test should be able to run independent of all the other unit tests order should not matter. This commit does a little to break the dependency tests have on other tests, but it did not fix it completely. Many tests rely on the DB being left in a state by another test as well as passing test state to global variables that hold information outside the individual test. Change-Id: Id2c05ecc611516a5cf892ae70bb4e0cd0c115752 Signed-off-by: George Nash --- diff --git a/java/common/src/main/java/org/iotivity/base/OcProvisioning.java b/java/common/src/main/java/org/iotivity/base/OcProvisioning.java index c5d2305ab..1095cb867 100644 --- a/java/common/src/main/java/org/iotivity/base/OcProvisioning.java +++ b/java/common/src/main/java/org/iotivity/base/OcProvisioning.java @@ -44,6 +44,14 @@ public class OcProvisioning { */ public static native void provisionInit(String dbPath) throws OcException; + /** + * Method is used by provisioning manager to close provisioning database. + * + * @throws OcException Indicate failure. + * Use OcException.GetErrorCode() for more details. + */ + public static native void provisionClose() throws OcException; + /** * Method to Discover un-owned devices in its subnet.Un-owned devices need * to be owned by calling ownershipTransferCBdata. diff --git a/java/examples-android/DirectPairing/src/main/java/org/iotivity/base/examples/DirectPairing/MainActivity.java b/java/examples-android/DirectPairing/src/main/java/org/iotivity/base/examples/DirectPairing/MainActivity.java index 90c43015e..b96576dcd 100644 --- a/java/examples-android/DirectPairing/src/main/java/org/iotivity/base/examples/DirectPairing/MainActivity.java +++ b/java/examples-android/DirectPairing/src/main/java/org/iotivity/base/examples/DirectPairing/MainActivity.java @@ -385,6 +385,12 @@ public class MainActivity extends Activity { } + @Override + public void onDestroy() { + super.onDestroy(); + closeIOCStack(); + } + /** * Copy svr db CBOR dat file from assets folder to app data files dir */ @@ -484,6 +490,18 @@ public class MainActivity extends Activity { } } + private void closeIOCStack() { + try { + /* + * Close DataBase + */ + OcProvisioning.provisionClose(); + } catch (OcException e) { + Log.d(TAG, "provisionClose error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + class GetDiscoveredItems extends AsyncTask> { ProgressDialog pDialog; diff --git a/java/examples-android/cloudprovisioningclient/src/main/java/org/iotivity/base/examples/cloudprovisioningclient/CloudProvisioningClient.java b/java/examples-android/cloudprovisioningclient/src/main/java/org/iotivity/base/examples/cloudprovisioningclient/CloudProvisioningClient.java index a5ebb9c2d..8bd4a035c 100644 --- a/java/examples-android/cloudprovisioningclient/src/main/java/org/iotivity/base/examples/cloudprovisioningclient/CloudProvisioningClient.java +++ b/java/examples-android/cloudprovisioningclient/src/main/java/org/iotivity/base/examples/cloudprovisioningclient/CloudProvisioningClient.java @@ -326,140 +326,143 @@ public class CloudProvisioningClient extends Activity implements OcAccountManage private String filePath = ""; private TextView mEventsTextView; @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main_activity); - - signUp = (Button) findViewById(R.id.signup); - signIn = (Button) findViewById(R.id.signin); - signOut = (Button) findViewById(R.id.signout); - getAclId = (Button) findViewById(R.id.getAclId); - getAclInfo = (Button) findViewById(R.id.getAclInfo); - requestCert = (Button) findViewById(R.id.request); - postCrl = (Button) findViewById(R.id.postCRL); - getCrl = (Button) findViewById(R.id.getCRL); - - updateAce = (Button) findViewById(R.id.updateAce); - lyt1 = (LinearLayout) findViewById(R.id.lyt1); - lyt2 = (LinearLayout) findViewById(R.id.lyt2); - signupLyt = (LinearLayout) findViewById(R.id.signupLyt); - signinLyt = (LinearLayout) findViewById(R.id.signinLyt); - - - userid = (TextView) findViewById(R.id.userid); - - mEventsTextView = (TextView) findViewById(R.id.eventView); - - filePath = getFilesDir().getPath() + "/"; // data/data//files/ - //copy CBOR file when application runs first time - settingPreference = PreferenceManager.getDefaultSharedPreferences(this); - boolean isFirstRun = settingPreference.getBoolean("FIRSTRUN", true); - if (isFirstRun) { - copyCborFromAsset(); - SharedPreferences.Editor editor = settingPreference.edit(); - editor.putBoolean("FIRSTRUN", false); - editor.putString("IP", StringConstants.DEFAULT_COAP_DERVER_IP); - editor.putString("PORT", StringConstants.DEFAULT_COAP_DERVER_PORT); - editor.putString("DEVICEID", StringConstants.DEFAULT_DEVICE_ID); - editor.putString("OWNERID", StringConstants.DEFAULT_OWNER_ID); - editor.putString("SERIALNUMBER", StringConstants.DEFAULT_SERIAL_NUMBER); - editor.commit(); - } - if (settingPreference.getString("useruuid", "").equals("")) { - - lyt1.setVisibility(View.GONE); - lyt2.setVisibility(View.GONE); - signupLyt.setVisibility(View.VISIBLE); - signinLyt.setVisibility(View.GONE); - + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main_activity); + + signUp = (Button) findViewById(R.id.signup); + signIn = (Button) findViewById(R.id.signin); + signOut = (Button) findViewById(R.id.signout); + getAclId = (Button) findViewById(R.id.getAclId); + getAclInfo = (Button) findViewById(R.id.getAclInfo); + requestCert = (Button) findViewById(R.id.request); + postCrl = (Button) findViewById(R.id.postCRL); + getCrl = (Button) findViewById(R.id.getCRL); + + updateAce = (Button) findViewById(R.id.updateAce); + lyt1 = (LinearLayout) findViewById(R.id.lyt1); + lyt2 = (LinearLayout) findViewById(R.id.lyt2); + signupLyt = (LinearLayout) findViewById(R.id.signupLyt); + signinLyt = (LinearLayout) findViewById(R.id.signinLyt); + + + userid = (TextView) findViewById(R.id.userid); + + mEventsTextView = (TextView) findViewById(R.id.eventView); + + filePath = getFilesDir().getPath() + "/"; // data/data//files/ + //copy CBOR file when application runs first time + settingPreference = PreferenceManager.getDefaultSharedPreferences(this); + boolean isFirstRun = settingPreference.getBoolean("FIRSTRUN", true); + if (isFirstRun) { + copyCborFromAsset(); + SharedPreferences.Editor editor = settingPreference.edit(); + editor.putBoolean("FIRSTRUN", false); + editor.putString("IP", StringConstants.DEFAULT_COAP_DERVER_IP); + editor.putString("PORT", StringConstants.DEFAULT_COAP_DERVER_PORT); + editor.putString("DEVICEID", StringConstants.DEFAULT_DEVICE_ID); + editor.putString("OWNERID", StringConstants.DEFAULT_OWNER_ID); + editor.putString("SERIALNUMBER", StringConstants.DEFAULT_SERIAL_NUMBER); + editor.commit(); + } + if (settingPreference.getString("useruuid", "").equals("")) { - } else { - userid.setText(settingPreference.getString("useruuid", "")); - lyt1.setVisibility(View.VISIBLE); - lyt2.setVisibility(View.VISIBLE); - signupLyt.setVisibility(View.GONE); - signinLyt.setVisibility(View.VISIBLE); - } + lyt1.setVisibility(View.GONE); + lyt2.setVisibility(View.GONE); + signupLyt.setVisibility(View.VISIBLE); + signinLyt.setVisibility(View.GONE); - initOICStack(); - ocCloudProvisioning = new OcCloudProvisioning(settingPreference.getString("IP", ""), - Integer.valueOf(settingPreference.getString("PORT", ""))); - signUp.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - signUp(); - } - }); - signIn.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - signIn(); - } - }); - signOut.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - signOut(); - } - }); - getAclId.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getAclId(); - } - }); - getAclInfo.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getAclInfo(); - } - }); - requestCert.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - requestCert(); - } - }); - postCrl.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - postCrl(); - } - }); - getCrl.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - getCrl(); - } - }); - updateAce.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - updateAces(); - } - }); + } else { + userid.setText(settingPreference.getString("useruuid", "")); + lyt1.setVisibility(View.VISIBLE); + lyt2.setVisibility(View.VISIBLE); + signupLyt.setVisibility(View.GONE); + signinLyt.setVisibility(View.VISIBLE); } + initOICStack(); + ocCloudProvisioning = new OcCloudProvisioning(settingPreference.getString("IP", ""), + Integer.valueOf(settingPreference.getString("PORT", ""))); - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.menu_cloud_provision, menu); - return true; - } + signUp.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + signUp(); + } + }); + signIn.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + signIn(); + } + }); + signOut.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + signOut(); + } + }); + getAclId.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getAclId(); + } + }); + getAclInfo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getAclInfo(); + } + }); + requestCert.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + requestCert(); + } + }); + postCrl.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + postCrl(); + } + }); + getCrl.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getCrl(); + } + }); + updateAce.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + updateAces(); + } + }); + } @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.action_settings: - setDefualtSettings(); - return (true); + public void onDestroy() { + super.onDestroy(); + closeIOCStack(); + } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_cloud_provision, menu); + return true; + } - } - return (super.onOptionsItemSelected(item)); + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_settings: + setDefualtSettings(); + return (true); } + return (super.onOptionsItemSelected(item)); + } private void signIn() { try { @@ -622,6 +625,18 @@ public class CloudProvisioningClient extends Activity implements OcAccountManage } } + private void closeIOCStack() { + try { + /* + * Close DataBase + */ + OcProvisioning.provisionClose(); + } catch (OcException e) { + logMessage(TAG + "provisionClose error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); diff --git a/java/examples-android/provisioningclient/src/main/java/org/iotivity/base/examples/provisioningclient/ProvisioningClient.java b/java/examples-android/provisioningclient/src/main/java/org/iotivity/base/examples/provisioningclient/ProvisioningClient.java index f39558c89..4a10e58e9 100644 --- a/java/examples-android/provisioningclient/src/main/java/org/iotivity/base/examples/provisioningclient/ProvisioningClient.java +++ b/java/examples-android/provisioningclient/src/main/java/org/iotivity/base/examples/provisioningclient/ProvisioningClient.java @@ -242,32 +242,38 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise }; @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_secure_provision_client); - mEventsTextView = new TextView(this); - mEventsTextView.setGravity(Gravity.BOTTOM); - mEventsTextView.setMovementMethod(new ScrollingMovementMethod()); - LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout); - layout.addView(mEventsTextView, new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f) - ); - filePath = getFilesDir().getPath() + "/"; // data/data//files/ - //copy CBOR file when application runs first time - SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this); - boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true); - if (isFirstRun) { - copyCborFromAsset(); - SharedPreferences.Editor editor = wmbPreference.edit(); - editor.putBoolean("FIRSTRUN", false); - editor.commit(); - } - initOICStack(); - saveCertChain(); - int ret = CaInterface.setCipherSuite(OicCipher.TLS_ECDH_anon_WITH_AES_128_CBC_SHA, - OcConnectivityType.CT_ADAPTER_IP); - Log.e(TAG,"CaInterface.setCipherSuite returned = "+ret); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_secure_provision_client); + mEventsTextView = new TextView(this); + mEventsTextView.setGravity(Gravity.BOTTOM); + mEventsTextView.setMovementMethod(new ScrollingMovementMethod()); + LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout); + layout.addView(mEventsTextView, new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f) + ); + filePath = getFilesDir().getPath() + "/"; // data/data//files/ + //copy CBOR file when application runs first time + SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this); + boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true); + if (isFirstRun) { + copyCborFromAsset(); + SharedPreferences.Editor editor = wmbPreference.edit(); + editor.putBoolean("FIRSTRUN", false); + editor.commit(); } + initOICStack(); + saveCertChain(); + int ret = CaInterface.setCipherSuite(OicCipher.TLS_ECDH_anon_WITH_AES_128_CBC_SHA, + OcConnectivityType.CT_ADAPTER_IP); + Log.e(TAG,"CaInterface.setCipherSuite returned = "+ret); + } + + @Override + public void onDestroy() { + super.onDestroy(); + closeIOCStack(); + } /** * configure OIC platform and call findResource @@ -330,6 +336,18 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise new DiscoveryOTTransferAsyncTask().execute(); } + private void closeIOCStack() { + try { + /* + * Close DataBase + */ + OcProvisioning.provisionClose(); + } catch (OcException e) { + logMessage(TAG + "provisionClose error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + @Override synchronized public void doOwnershipTransferListener(List ProvisionResultList, int hasError) { diff --git a/java/jni/JniOcProvisioning.cpp b/java/jni/JniOcProvisioning.cpp index d8f037cc8..d99ad456d 100644 --- a/java/jni/JniOcProvisioning.cpp +++ b/java/jni/JniOcProvisioning.cpp @@ -215,6 +215,32 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_provisionInit } } +/* + * Class: org_iotivity_base_OcProvisioning + * Method: provisionClose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_provisionClose + (JNIEnv *env, jclass thiz) +{ + OC_UNUSED(thiz); + LOGD("OcProvisioning_provisionClose"); + try + { + OCStackResult result = OCSecure::provisionClose(); + if (OC_STACK_OK != result) + { + ThrowOcException(result, "OCSecure::provisionClose Failed"); + return; + } + } + catch (OCException& e) + { + LOGE("%s", e.reason().c_str()); + ThrowOcException(OC_STACK_ERROR, e.reason().c_str()); + } +} + /* * Class: org_iotivity_base_OcProvisioning * Method: discoverOwnedDevices diff --git a/java/jni/JniOcProvisioning.h b/java/jni/JniOcProvisioning.h index 2e2f46d5e..12dae0a68 100644 --- a/java/jni/JniOcProvisioning.h +++ b/java/jni/JniOcProvisioning.h @@ -60,6 +60,14 @@ JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_discoverUno JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_provisionInit (JNIEnv *, jclass, jstring); +/* + * Class: org_iotivity_base_OcProvisioning + * Method: provisionClose + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_provisionClose + (JNIEnv *, jclass); + /* * Class: org_iotivity_base_OcProvisioning * Method: discoverOwnedDevices diff --git a/resource/IPCA/src/ocfframework.cpp b/resource/IPCA/src/ocfframework.cpp index 13851afd3..0a3b459d2 100644 --- a/resource/IPCA/src/ocfframework.cpp +++ b/resource/IPCA/src/ocfframework.cpp @@ -376,6 +376,7 @@ IPCAStatus OCFFramework::Stop(InputPinCallbackHandle passwordInputCallbackHandle OCSecure::deregisterInputPinCallback(passwordInputCallbackHandle); OCSecure::deregisterDisplayPinCallback(passwordDisplayCallbackHandle); + OCSecure::provisionClose(); m_isStopping = true; diff --git a/resource/IPCA/src/pretendocprovision.cpp b/resource/IPCA/src/pretendocprovision.cpp index 5419d3216..747df7c5f 100644 --- a/resource/IPCA/src/pretendocprovision.cpp +++ b/resource/IPCA/src/pretendocprovision.cpp @@ -36,6 +36,11 @@ OCStackResult OCSecure::provisionInit(const std::string& dbPath) return OC_STACK_OK; } +OCStackResult OCSecure::provisionClose() +{ + return OC_STACK_OK; +} + OCStackResult OCSecure::registerInputPinCallback(InputPinCB inputPinCB, InputPinCallbackHandle* inputPinCallbackHandle) { diff --git a/resource/IPCA/unittests/mockOCProvision.cpp b/resource/IPCA/unittests/mockOCProvision.cpp index ccfd867d8..8bf968ee2 100644 --- a/resource/IPCA/unittests/mockOCProvision.cpp +++ b/resource/IPCA/unittests/mockOCProvision.cpp @@ -38,6 +38,11 @@ OCStackResult OCSecure::provisionInit(const std::string& dbPath) return OC_STACK_OK; } +OCStackResult OCSecure::provisionClose() +{ + return OC_STACK_OK; +} + OCStackResult OCSecure::registerInputPinCallback(InputPinCB inputPinCB, InputPinCallbackHandle* inputPinCallbackHandle) { diff --git a/resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h b/resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h index 9c7200214..5ffafa525 100644 --- a/resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h +++ b/resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h @@ -38,6 +38,8 @@ typedef enum PdmDeviceState { /** * This method is used by provisioning manager to open provisioning database. * + * @see PDMClose() + * * @param[in] dbPath file path of the sqlite3 db * * @return OC_STACK_OK in case of success and other value otherwise. @@ -169,6 +171,8 @@ OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t** staleDevList, size_t* num /** * This method is used by provisioning manager to close provisioning database. * + * @see PDMInit() + * * @return OC_STACK_OK in case of success and other value otherwise. */ OCStackResult PDMClose(); diff --git a/resource/csdk/security/provisioning/include/ocprovisioningmanager.h b/resource/csdk/security/provisioning/include/ocprovisioningmanager.h index ef904bffe..23b2cb128 100644 --- a/resource/csdk/security/provisioning/include/ocprovisioningmanager.h +++ b/resource/csdk/security/provisioning/include/ocprovisioningmanager.h @@ -38,12 +38,23 @@ extern "C" { * TODO: In addition, if there is a device(s) which has not up-to-date credentials, this function will * automatically try to update the deivce(s). * + * @see OCClosePM() + * * @param[in] dbPath file path of the sqlite3 db * * @return OC_STACK_OK in case of success and other value otherwise. */ OCStackResult OC_CALL OCInitPM(const char* dbPath); +/** + * This method is used by provisioning manager to close provisioning database. + * + * @see OCInitPM() + * + * @return OC_STACK_OK in case of success and other value otherwise. + */ +OCStackResult OC_CALL OCClosePM(); + /** * API to cleanup PDM in case of timeout. * It will remove the PDM_DEVICE_INIT state devices from PDM. diff --git a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c index 90210f533..cf71ad4b3 100644 --- a/resource/csdk/security/provisioning/src/ocprovisioningmanager.c +++ b/resource/csdk/security/provisioning/src/ocprovisioningmanager.c @@ -70,7 +70,7 @@ struct ProvPreconfPINCtx * The function is responsible for initializaton of the provisioning manager. It will load * provisioning database which have owned device's list and their linked status. * TODO: In addition, if there is a device(s) which has not up-to-date credentials, this function will - * automatically try to update the deivce(s). + * automatically try to update the device(s). * * @param[in] dbPath file path of the sqlite3 db * @@ -81,6 +81,18 @@ OCStackResult OC_CALL OCInitPM(const char* dbPath) return PDMInit(dbPath); } +/** + * This method is used by provisioning manager to close provisioning database. + * + * @see OCInitPM() + * + * @return OC_STACK_OK in case of success and other value otherwise. + */ +OCStackResult OC_CALL OCClosePM() +{ + return PDMClose(); +} + OCStackResult OC_CALL OCPDMCleanupForTimeout() { return PDMDeleteDeviceWithState(PDM_DEVICE_INIT); diff --git a/resource/csdk/security/provisioning/unittest/otmunittest.cpp b/resource/csdk/security/provisioning/unittest/otmunittest.cpp index 7f45cbf0d..04c0388f7 100644 --- a/resource/csdk/security/provisioning/unittest/otmunittest.cpp +++ b/resource/csdk/security/provisioning/unittest/otmunittest.cpp @@ -303,6 +303,8 @@ TEST(InitForOTM, NullParam) gNumOfUnownDevice = 0; gNumOfOwnDevice = 0; + // close Provisioning DB + EXPECT_EQ(OC_STACK_OK, OCClosePM()); } /* TEST(OCDiscoverSingleDeviceInUnicast, Simple) @@ -331,6 +333,8 @@ TEST(OCDiscoverSingleDeviceInUnicast, Simple) */ TEST(OCDiscoverUnownedDevices, Simple) { + //initialize Provisioning DB Manager + EXPECT_EQ(OC_STACK_OK, OCInitPM(PM_DB_FILE_NAME)); EXPECT_EQ(OC_STACK_OK, OCDiscoverUnownedDevices(DISCOVERY_TIMEOUT, &g_unownedDevices)); RemoveUnknownDeviceFromDevList(g_unownedDevices); @@ -353,10 +357,14 @@ TEST(OCDiscoverUnownedDevices, Simple) } EXPECT_EQ(true, gNumOfUnownDevice > 0); + // close Provisioning DB + EXPECT_EQ(OC_STACK_OK, OCClosePM()); } TEST(OCDoOwnershipTransfer, Simple) { + //initialize Provisioning DB Manager + EXPECT_EQ(OC_STACK_OK, OCInitPM(PM_DB_FILE_NAME)); ASSERT_EQ(true, gNumOfUnownDevice > 0); g_doneCB = false; @@ -370,10 +378,14 @@ TEST(OCDoOwnershipTransfer, Simple) EXPECT_EQ(true, g_callbackResult); EXPECT_EQ(true, g_doneCB); + // close Provisioning DB + EXPECT_EQ(OC_STACK_OK, OCClosePM()); } TEST(OCDiscoverOwnedDevices, Simple) { + //initialize Provisioning DB Manager + EXPECT_EQ(OC_STACK_OK, OCInitPM(PM_DB_FILE_NAME)); OCStackResult result = OC_STACK_ERROR; gNumOfOwnDevice = 0; @@ -427,6 +439,8 @@ TEST(OCDiscoverOwnedDevices, Simple) } EXPECT_EQ(true, gNumOfOwnDevice > 0); + // close Provisioning DB + EXPECT_EQ(OC_STACK_OK, OCClosePM()); } TEST(PerformLinkDevices, NullParam) @@ -639,6 +653,8 @@ TEST(DiscoverMultipleOwnedDevices, NullParam) TEST(OCRemoveDevice, Simple) { + //initialize Provisioning DB Manager + EXPECT_EQ(OC_STACK_OK, OCInitPM(PM_DB_FILE_NAME)); ASSERT_EQ(true, gNumOfUnownDevice > 0); OicUuid_t myUuid; @@ -665,6 +681,8 @@ TEST(OCRemoveDevice, Simple) EXPECT_EQ(OC_STACK_OK, result); EXPECT_EQ(true, g_callbackResult); EXPECT_EQ(true, g_doneCB); + // close Provisioning DB + EXPECT_EQ(OC_STACK_OK, OCClosePM()); } TEST(FinalizeOTMTest, NullParam) diff --git a/resource/csdk/security/provisioning/unittest/provisioningdatabasemanager.cpp b/resource/csdk/security/provisioning/unittest/provisioningdatabasemanager.cpp index 2af25c020..33c834900 100644 --- a/resource/csdk/security/provisioning/unittest/provisioningdatabasemanager.cpp +++ b/resource/csdk/security/provisioning/unittest/provisioningdatabasemanager.cpp @@ -65,21 +65,27 @@ TEST(CallPDMAPIbeforeInit, BeforeInit) TEST(PDMInitTest, PDMInitWithNULL) { EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMAddDeviceTest, NullUUID) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMAddDevice(NULL)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMIsDuplicateDeviceTest, NullUUID) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMIsDuplicateDevice(NULL,NULL)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMIsDuplicateDeviceTest, ValidUUID) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid1 = {{0,}}; memcpy(&uid1.id, ID_1, sizeof(uid1.id)); EXPECT_EQ(OC_STACK_OK, PDMAddDevice(&uid1)); @@ -96,10 +102,12 @@ TEST(PDMIsDuplicateDeviceTest, ValidUUID) EXPECT_EQ(OC_STACK_OK, PDMIsDuplicateDevice(&uid3, &isDuplicate)); EXPECT_FALSE(isDuplicate); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMAddDeviceTest, ValidUUID) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; uint8_t id[UUID_LENGTH] = {0,}; @@ -114,24 +122,30 @@ TEST(PDMAddDeviceTest, ValidUUID) EXPECT_EQ(OC_STACK_OK, PDMAddDevice(&uid)); EXPECT_EQ(OC_STACK_OK, PDMDeleteDevice(&uid)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMLinkDevicesTest, NULLDevice1) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_2, sizeof(uid.id)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMLinkDevices(NULL, &uid)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMLinkDevicesTest, NULLDevice2) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_3, sizeof(uid.id)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMLinkDevices(&uid, NULL)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMLinkDevicesTest, ValidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid1 = {{0,}}; memcpy(&uid1.id, ID_4, sizeof(uid1.id)); EXPECT_EQ(OC_STACK_OK, PDMAddDevice(&uid1)); @@ -143,40 +157,49 @@ TEST(PDMLinkDevicesTest, ValidCase) EXPECT_EQ(OC_STACK_OK, PDMSetDeviceState(&uid2, PDM_DEVICE_ACTIVE)); EXPECT_EQ(OC_STACK_OK, PDMLinkDevices(&uid1, &uid2)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMUnlinkDevicesTest, NULLDevice1) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_3, sizeof(uid.id)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMUnlinkDevices(NULL, &uid)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMUnlinkDevicesTest, NULLDevice2) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_3, sizeof(uid.id)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMUnlinkDevices(&uid, NULL)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMUnlinkDevices, ValidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid1 = {{0,}}; memcpy(&uid1.id, ID_4, sizeof(uid1.id)); OicUuid_t uid2 = {{0,}}; memcpy(&uid2.id, ID_5, sizeof(uid2.id)); EXPECT_EQ(OC_STACK_OK, PDMUnlinkDevices(&uid1, &uid2)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST (PDMDeleteDevice, NULLDeviceID) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMDeleteDevice(NULL)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST (PDMDeleteDevice, ValidButNonExistDeviceID) { - + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; uint8_t id[UUID_LENGTH] = {0,}; for (size_t i = 0 ; i < sizeof(id) ; i++) @@ -188,56 +211,70 @@ TEST (PDMDeleteDevice, ValidButNonExistDeviceID) memcpy(&uid.id, &id, sizeof(uid.id)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMDeleteDevice(&uid)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMGetOwnedDevices, ValidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OCUuidList_t *list = NULL; size_t noOfDevcies = 0; EXPECT_EQ(OC_STACK_OK, PDMGetOwnedDevices(&list, &noOfDevcies)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMGetLinkedDevices, NULLDeviceID) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OCUuidList_t *list = NULL; size_t noOfDevices = 0; EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMGetLinkedDevices(NULL, &list, &noOfDevices)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMGetLinkedDevices, ValidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_1, sizeof(uid.id)); OCUuidList_t *list = NULL; size_t noOfDevices = 0; EXPECT_EQ(OC_STACK_OK, PDMGetLinkedDevices(&uid, &list, &noOfDevices)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMGetLinkedDevices, InvalidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_6, sizeof(uid.id)); OCUuidList_t *list = NULL; size_t noOfDevices = 0; EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMGetLinkedDevices(&uid, &list, &noOfDevices)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMSetLinkStale, NULLDeviceID1) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_1, sizeof(uid.id)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMSetLinkStale(NULL, &uid)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMSetLinkStale, NULLDeviceID2) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid = {{0,}}; memcpy(&uid.id, ID_1, sizeof(uid.id)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMSetLinkStale(&uid, NULL)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMSetLinkStale, ValidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OicUuid_t uid1 = {{0,}}; memcpy(&uid1.id, ID_6, sizeof(uid1.id)); OicUuid_t uid2 = {{0,}}; @@ -252,17 +289,21 @@ TEST(PDMSetLinkStale, ValidCase) EXPECT_EQ(OC_STACK_OK, PDMLinkDevices(&uid1, &uid2)); EXPECT_EQ(OC_STACK_OK, PDMSetLinkStale(&uid1, &uid2)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMGetToBeUnlinkedDevices, ValidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); OCPairList_t *list = NULL; size_t noOfDevices = 0; EXPECT_EQ(OC_STACK_OK, PDMGetToBeUnlinkedDevices(&list, &noOfDevices)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMClose, ValidCase) { + EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); EXPECT_EQ(OC_STACK_OK, PDMClose()); } @@ -293,12 +334,14 @@ TEST(PDMIsLinkExistsTest, DuplicateID) OCStackResult res = PDMIsLinkExists(&uid1, &uid2, &linkExisits); EXPECT_EQ(OC_STACK_OK, res); EXPECT_FALSE(linkExisits); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMSetDeviceStaleTest, NULLUUID) { EXPECT_EQ(OC_STACK_OK, PDMInit(NULL)); EXPECT_EQ(OC_STACK_INVALID_PARAM, PDMSetDeviceState(NULL, PDM_DEVICE_STALE)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMSetDeviceStaleTest, VALIDUUID) @@ -308,6 +351,7 @@ TEST(PDMSetDeviceStaleTest, VALIDUUID) memcpy(&uid1.id, ID_9, sizeof(uid1.id)); EXPECT_EQ(OC_STACK_OK, PDMAddDevice(&uid1)); EXPECT_EQ(OC_STACK_OK,PDMSetDeviceState(&uid1, PDM_DEVICE_STALE)); + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMSetDeviceStaleTest, StaleDeviceNotinDeviceList) @@ -327,6 +371,7 @@ TEST(PDMSetDeviceStaleTest, StaleDeviceNotinDeviceList) EXPECT_FALSE(0 == memcmp(list->dev.id, uid1.id,sizeof(uid1.id))); list = list->next; } + EXPECT_EQ(OC_STACK_OK, PDMClose()); } TEST(PDMSetDeviceStaleTest, StaleDeviceNotinLinkedDevice) @@ -390,4 +435,5 @@ TEST(PDMSetDeviceStaleTest, StaleDeviceNotinLinkedDevice) EXPECT_TRUE(0 == memcmp(ptr->dev.id, uid2.id,sizeof(uid2.id))); ptr = ptr->next; } + EXPECT_EQ(OC_STACK_OK, PDMClose()); } diff --git a/resource/csdk/stack/octbstack_product_secured.def b/resource/csdk/stack/octbstack_product_secured.def index d4620cc4c..2ba3693af 100644 --- a/resource/csdk/stack/octbstack_product_secured.def +++ b/resource/csdk/stack/octbstack_product_secured.def @@ -29,6 +29,7 @@ OCGetPublicKeyFromCSR OCGetRolesResource OCGetUuidFromCSR OCInitPM +OCClosePM OCPDMCleanupForTimeout OCProvisionACL OCSaveACL diff --git a/resource/include/OCProvisioningManager.hpp b/resource/include/OCProvisioningManager.hpp index be7e83dd6..c7a4d11a0 100644 --- a/resource/include/OCProvisioningManager.hpp +++ b/resource/include/OCProvisioningManager.hpp @@ -190,12 +190,23 @@ namespace OC * The API is responsible for initialization of the provisioning manager. It will load * provisioning database which have owned device's list and their linked status. * + * @see OCSecure::provisionClose() + * * @param dbPath file path of the sqlite3 database. * * @return ::OC_STACK_OK in case of success and other value otherwise. */ static OCStackResult provisionInit(const std::string& dbPath); + /** + * This method is used by provisioning manager to close provisioning database. + * + * @see OCSecure::provisionInit() + * + * @return OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult provisionClose(); + /** * API is responsible for discovery of devices in it's subnet. It will list * all the device in subnet which are not yet owned. diff --git a/resource/provisioning/examples/provisioningclient.cpp b/resource/provisioning/examples/provisioningclient.cpp index 5c3ea1ab4..c811e2520 100644 --- a/resource/provisioning/examples/provisioningclient.cpp +++ b/resource/provisioning/examples/provisioningclient.cpp @@ -1678,6 +1678,8 @@ int main(void) // Unregister the input pin callback OCSecure::deregisterInputPinCallback(callbackHandle); + // close database + OCSecure::provisionClose(); } catch(OCException& e) { diff --git a/resource/provisioning/examples/subownerclient.cpp b/resource/provisioning/examples/subownerclient.cpp index 2c9ea8e46..2ca914531 100644 --- a/resource/provisioning/examples/subownerclient.cpp +++ b/resource/provisioning/examples/subownerclient.cpp @@ -406,6 +406,8 @@ int main(void) // Unregister input pin callback OCSecure::deregisterInputPinCallback(callbackHandle); + // close database + OCSecure::provisionClose(); return 0; } diff --git a/resource/provisioning/src/OCProvisioningManager.cpp b/resource/provisioning/src/OCProvisioningManager.cpp index b37c11877..14ba4ae44 100644 --- a/resource/provisioning/src/OCProvisioningManager.cpp +++ b/resource/provisioning/src/OCProvisioningManager.cpp @@ -66,6 +66,7 @@ namespace OC delete context; } + OCStackResult OCSecure::provisionInit(const std::string& dbPath) { OCStackResult result; @@ -85,6 +86,25 @@ namespace OC return result; } + OCStackResult OCSecure::provisionClose() + { + OCStackResult result; + auto cLock = OCPlatform_impl::Instance().csdkLock().lock(); + + if (cLock) + { + std::lock_guard lock(*cLock); + result = OCClosePM(); + } + else + { + oclog() <<"Mutex not found"; + result = OC_STACK_ERROR; + } + + return result; + } + OCStackResult OCSecure::discoverUnownedDevices(unsigned short timeout, DeviceList_t &list) { diff --git a/resource/provisioning/unittests/OCProvisioningTest.cpp b/resource/provisioning/unittests/OCProvisioningTest.cpp index b16bd205e..3f4385d65 100644 --- a/resource/provisioning/unittests/OCProvisioningTest.cpp +++ b/resource/provisioning/unittests/OCProvisioningTest.cpp @@ -44,12 +44,14 @@ namespace OCProvisioningTest { std::string dbPath(""); EXPECT_EQ(OC_STACK_OK, OCSecure::provisionInit(dbPath)); + EXPECT_EQ(OC_STACK_OK, OCSecure::provisionClose()); } TEST(ProvisionInitTest, TestValidPath) { std::string dbPath("./dbPath"); EXPECT_EQ(OC_STACK_OK, OCSecure::provisionInit(dbPath)); + EXPECT_EQ(OC_STACK_OK, OCSecure::provisionClose()); } TEST(DiscoveryTest, SecureResource) @@ -182,9 +184,12 @@ namespace OCProvisioningTest TEST(DeviceInfoTest, DevInfoFromNetwork) { + std::string dbPath("./dbPath"); + EXPECT_EQ(OC_STACK_OK, OCSecure::provisionInit(dbPath)); DeviceList_t owned, unowned; EXPECT_EQ(OC_STACK_OK, OCSecure::getDevInfoFromNetwork(TIMEOUT, owned, unowned)); + EXPECT_EQ(OC_STACK_OK, OCSecure::provisionClose()); } TEST(SetDisplayPinCBTest, SetDisplayPinCBTestNullCB) diff --git a/service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java b/service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java index 0ef8f4245..cc369d9d1 100755 --- a/service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java +++ b/service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java @@ -388,6 +388,18 @@ public class EasysetupActivity extends Activity } } + private void closeIOCStack() { + try { + /* + * Close DataBase + */ + OcProvisioning.provisionClose(); + } catch (OcException e) { + logMessage(TAG + "provisionClose error: " + e.getMessage()); + Log.e(TAG, e.getMessage()); + } + } + OcPlatform.OnResourceFoundListener listener = new OcPlatform.OnResourceFoundListener() { @Override @@ -1150,5 +1162,6 @@ public class EasysetupActivity extends Activity @Override protected void onDestroy() { super.onDestroy(); + closeIOCStack(); } } diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp index 08084a027..d4a202e60 100755 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp @@ -599,6 +599,10 @@ int main() } } +#ifdef __WITH_DTLS__ + // close provisioning db + OCSecure::provisionClose(); +#endif std::cout << "Stopping the client" << std::endl; return 0; diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp index 795b9fd31..138f510ed 100644 --- a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp +++ b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp @@ -597,6 +597,10 @@ int main() } } +#ifdef __WITH_DTLS__ + // close provisioning db + OCSecure::provisionClose(); +#endif std::cout << "Stopping the client" << std::endl; return 0;