IOT-2258: Allow secure and nonsecure endpoints with OCCreateResource.
[iotivity.git] / resource / csdk / security / src / doxmresource.c
index 3cd5619..b2a2445 100644 (file)
@@ -38,6 +38,7 @@
 #include "resourcemanager.h"
 #include "doxmresource.h"
 #include "pstatresource.h"
+#include "deviceonboardingstate.h"
 #include "aclresource.h"
 #include "amaclresource.h"
 #include "pconfresource.h"
@@ -99,13 +100,62 @@ static OicSecDoxm_t gDefaultDoxm =
     {.id = {0}},            /* OicUuid_t rownerID */
 };
 
+#define R PERMISSION_READ
+#define W PERMISSION_WRITE
+#define RW PERMISSION_READ | PERMISSION_WRITE
+
+// NOTE that this table must match the DoxmProperty_t enum in doxmresource.h
+static const uint8_t gDoxmPropertyAccessModes[DOXM_PROPERTY_COUNT][DOS_STATE_COUNT] =
+{ // RESET RFOTM  RFPRO   RFNOP   SRESET
+    { R,    R,      R,      R,      R   }, // .oxmtype TODO [IOT-2105]
+    { R,    R,      R,      R,      R   }, // .oxms
+    { R,    RW,     R,      R,      R   }, // .oxmsel
+    { R,    R,      R,      R,      R   }, // .sct
+    { R,    RW,     R,      R,      R   }, // .owned
+#ifdef MULTIPLE_OWNER
+    { RW,   RW,    RW,      RW,     RW  }, // .subowner
+    { RW,   RW,    RW,      RW,     RW  }, // .mom
+#endif // MULTIPLE_OWNER
+    { R,    RW,     R,      R,      R   }, // .deviceuuid
+    { R,    RW,     R,      R,      R   }, // .devowneruuid
+    { R,    RW,     R,      R,      RW  }  // .rowneruuid
+};
+
+#undef R
+#undef W
+#undef RW
+
+static bool IsPropertyReadOnly(DoxmProperty_t p,
+                               OicSecDeviceOnboardingState_t s)
+{
+    bool ret = false;
+
+    if (PERMISSION_READ == gDoxmPropertyAccessModes[p][s])
+    {
+        OIC_LOG_V(DEBUG, TAG, "%s: property %d is read-only in state %d.",
+           __func__, p, s);
+        ret = true;
+    }
+
+    return ret;
+}
+
 /**
- * This method is internal method.
- * the param roParsed is optionally used to know whether cborPayload has
- * at least read only property value or not.
- */
+ * Internal method converts CBOR into DOXM data, and determines if a read-only
+ *  Property was parsed in the CBOR payload.
+ *
+ * @param[in] cborPayload The doxm data in cbor format.
+ * @param[in] size Size of the cborPayload. In case 0 is provided it assigns CBOR_SIZE (255) value.
+ * @param[out] doxm Pointer to @ref OicSecDoxm_t.
+ * @param[out] roParsed Ptr to bool marked "true" iff a read-only Property is parsed
+ * @param[in] stateForReadOnlyCheck The state to use when determining if a Property is
+ *                              read-only.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+*/
 static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t size,
-                                OicSecDoxm_t **doxm, bool *roParsed);
+                                OicSecDoxm_t **doxm, bool *roParsed,
+                                OicSecDeviceOnboardingState_t stateForReadOnlyCheck);
 
 void DeleteDoxmBinData(OicSecDoxm_t* doxm)
 {
@@ -143,8 +193,8 @@ void DeleteDoxmBinData(OicSecDoxm_t* doxm)
     }
 }
 
-OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, size_t *size,
-                                bool rwOnly)
+OCStackResult DoxmToCBORPayloadPartial(const OicSecDoxm_t *doxm,
+    uint8_t **payload, size_t *size, const bool *propertiesToInclude)
 {
     if (NULL == doxm || NULL == payload || NULL != *payload || NULL == size)
     {
@@ -174,87 +224,101 @@ OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, siz
     cborEncoderResult = cbor_encoder_create_map(&encoder, &doxmMap, CborIndefiniteLength);
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Map.");
 
-    //OxmType -- Not Mandatory
-    if (doxm->oxmTypeLen > 0)
+    // oxmtype
+    // TODO [IOT-2105]: resolve "oxmtype" undocumented tag/value
+    if (propertiesToInclude[DOXM_OXMTYPE] && doxm->oxmTypeLen > 0)
     {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s.", __func__, OIC_JSON_OXM_TYPE_NAME);
         CborEncoder oxmType;
         cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_TYPE_NAME,
             strlen(OIC_JSON_OXM_TYPE_NAME));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Tag.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmtype Tag.");
         cborEncoderResult = cbor_encoder_create_array(&doxmMap, &oxmType, doxm->oxmTypeLen);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Array.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmtype Array.");
 
         for (size_t i = 0; i < doxm->oxmTypeLen; i++)
         {
             cborEncoderResult = cbor_encode_text_string(&oxmType, doxm->oxmType[i],
                 strlen(doxm->oxmType[i]));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Value.");
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmtype Value.");
         }
         cborEncoderResult = cbor_encoder_close_container(&doxmMap, &oxmType);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmType.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmtype.");
     }
 
-    //Oxm -- Not Mandatory
-    if (doxm->oxmLen > 0 && false == rwOnly)
+    // oxms Property
+    if (propertiesToInclude[DOXM_OXMS] && doxm->oxmLen > 0)
     {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_OXMS_NAME);
         CborEncoder oxm;
         cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXMS_NAME,
             strlen(OIC_JSON_OXMS_NAME));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Tag.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxms Tag.");
         cborEncoderResult = cbor_encoder_create_array(&doxmMap, &oxm, doxm->oxmLen);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Array.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxms Array.");
 
         for (size_t i = 0; i < doxm->oxmLen; i++)
         {
             cborEncoderResult = cbor_encode_int(&oxm, doxm->oxm[i]);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Value");
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxms Value");
         }
         cborEncoderResult = cbor_encoder_close_container(&doxmMap, &oxm);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmName.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxms.");
     }
 
-    //OxmSel -- Mandatory
-    cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_SEL_NAME,
-        strlen(OIC_JSON_OXM_SEL_NAME));
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Sel Tag.");
-    cborEncoderResult = cbor_encode_int(&doxmMap, doxm->oxmSel);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Sel Value.");
+    // oxmsel Property
+    if (propertiesToInclude[DOXM_OXMSEL] && doxm->oxmLen > 0)
+    {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_OXM_SEL_NAME);
+        cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_SEL_NAME,
+            strlen(OIC_JSON_OXM_SEL_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmsel Tag.");
+        cborEncoderResult = cbor_encode_int(&doxmMap, doxm->oxmSel);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmsel Value.");
+    }
 
-    //sct -- Mandatory
-    if (false == rwOnly)
+    // sct Property
+    if (propertiesToInclude[DOXM_SCT])
     {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
         cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_SUPPORTED_CRED_TYPE_NAME,
             strlen(OIC_JSON_SUPPORTED_CRED_TYPE_NAME));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding sct Tag");
         cborEncoderResult = cbor_encode_int(&doxmMap, doxm->sct);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding sct Value.");
     }
 
-    //Owned -- Mandatory
-    cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OWNED_NAME,
-        strlen(OIC_JSON_OWNED_NAME));
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owned Tag.");
-    cborEncoderResult = cbor_encode_boolean(&doxmMap, doxm->owned);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owned Value.");
+    // owned Property
+    if (propertiesToInclude[DOXM_OWNED])
+    {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_OWNED_NAME);
+        cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OWNED_NAME,
+            strlen(OIC_JSON_OWNED_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding owned Tag.");
+        cborEncoderResult = cbor_encode_boolean(&doxmMap, doxm->owned);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding owned Value.");
+    }
 
-    if (false == rwOnly)
+    // deviceuuid Property
+    if (propertiesToInclude[DOXM_DEVICEUUID])
     {
-        //DeviceId -- Mandatory
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_DEVICE_ID_NAME);
         cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVICE_ID_NAME,
             strlen(OIC_JSON_DEVICE_ID_NAME));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding deviceuuid Tag.");
         ret = ConvertUuidToStr(&doxm->deviceID, &strUuid);
         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
         cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding deviceuuid Value.");
         OICFree(strUuid);
         strUuid = NULL;
     }
 
 #ifdef MULTIPLE_OWNER
     //Device SubOwnerID -- Not Mandatory
-    if(doxm->subOwners)
+    if(propertiesToInclude[DOXM_SUBOWNER] && doxm->subOwners)
     {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_SUBOWNERID_NAME);
         size_t subOwnerLen = 0;
         OicSecSubOwner_t* subOwner = NULL;
         LL_FOREACH(doxm->subOwners, subOwner)
@@ -284,8 +348,9 @@ OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, siz
     }
 
     //Multiple Owner Mode -- Not Mandatory
-    if(doxm->mom)
+    if(propertiesToInclude[DOXM_MOM] && doxm->mom)
     {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_MOM_NAME);
         cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_MOM_NAME,
             strlen(OIC_JSON_MOM_NAME));
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding mom Tag");
@@ -294,27 +359,35 @@ OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, siz
     }
 #endif //MULTIPLE_OWNER
 
-    //devownerid -- Mandatory
-    cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVOWNERID_NAME,
-        strlen(OIC_JSON_DEVOWNERID_NAME));
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owner Id Tag.");
-    ret = ConvertUuidToStr(&doxm->owner, &strUuid);
-    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
-    cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owner Id Value.");
-    OICFree(strUuid);
-    strUuid = NULL;
-
-    //ROwner -- Mandatory
-    cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_ROWNERID_NAME,
-        strlen(OIC_JSON_ROWNERID_NAME));
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Tag.");
-    ret = ConvertUuidToStr(&doxm->rownerID, &strUuid);
-    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
-    cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Value.");
-    OICFree(strUuid);
-    strUuid = NULL;
+    // devowneruuid Property
+    if (propertiesToInclude[DOXM_DEVOWNERUUID])
+    {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_DEVOWNERID_NAME);
+        cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVOWNERID_NAME,
+            strlen(OIC_JSON_DEVOWNERID_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding devowneruuid Tag.");
+        ret = ConvertUuidToStr(&doxm->owner, &strUuid);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+        cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding devowneruuid Value.");
+        OICFree(strUuid);
+        strUuid = NULL;
+    }
+
+    // rowneruuid Property
+    if (propertiesToInclude[DOXM_ROWNERUUID])
+    {
+        OIC_LOG_V(DEBUG, TAG, "%s: including %s Property.", __func__, OIC_JSON_ROWNERID_NAME);
+        cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_ROWNERID_NAME,
+            strlen(OIC_JSON_ROWNERID_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rowneruuid Tag.");
+        ret = ConvertUuidToStr(&doxm->rownerID, &strUuid);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+        cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rowneruuid Value.");
+        OICFree(strUuid);
+        strUuid = NULL;
+    }
 
     //RT -- Mandatory
     CborEncoder rtArray;
@@ -333,12 +406,12 @@ OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, siz
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
 
     //IF-- Mandatory
-     CborEncoder ifArray;
-     cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_IF_NAME,
-             strlen(OIC_JSON_IF_NAME));
-     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
-     cborEncoderResult = cbor_encoder_create_array(&doxmMap, &ifArray, 1);
-     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
+    CborEncoder ifArray;
+    cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_IF_NAME,
+       strlen(OIC_JSON_IF_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
+    cborEncoderResult = cbor_encoder_create_array(&doxmMap, &ifArray, 1);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
     for (size_t i = 0; i < 1; i++)
     {
         cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
@@ -363,11 +436,12 @@ exit:
         OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
         // reallocate and try again!
         OICFree(outPayload);
+        outPayload = NULL;
         // Since the allocated initial memory failed, double the memory.
         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
         OIC_LOG_V(DEBUG, TAG, "Doxm reallocation size : %zd.", cborLen);
         cborEncoderResult = CborNoError;
-        ret = DoxmToCBORPayload(doxm, payload, &cborLen, rwOnly);
+        ret = DoxmToCBORPayloadPartial(doxm, payload, &cborLen, propertiesToInclude);
         *size = cborLen;
     }
 
@@ -383,14 +457,30 @@ exit:
     return ret;
 }
 
+OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm,
+                                 uint8_t **payload, size_t *size)
+{
+    bool allProps[DOXM_PROPERTY_COUNT];
+
+    for (int i = 0; i < DOXM_PROPERTY_COUNT; i++)
+    {
+        allProps[i] = true;
+    }
+
+    allProps[DOXM_OXMTYPE] = false; // TODO [IOT-2105]: resolve "oxmtype" undocumented tag/value
+
+    return DoxmToCBORPayloadPartial(doxm, payload, size, allProps);
+}
+
 OCStackResult CBORPayloadToDoxm(const uint8_t *cborPayload, size_t size,
                                 OicSecDoxm_t **secDoxm)
 {
-    return CBORPayloadToDoxmBin(cborPayload, size, secDoxm, NULL);
+    return CBORPayloadToDoxmBin(cborPayload, size, secDoxm, NULL, DOS_RESET);
 }
 
 static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t size,
-                                OicSecDoxm_t **secDoxm, bool *roParsed)
+                                OicSecDoxm_t **secDoxm, bool *roParsed,
+                                OicSecDeviceOnboardingState_t stateForReadOnlyCheck)
 {
     if (NULL == cborPayload || NULL == secDoxm || NULL != *secDoxm || 0 == size)
     {
@@ -412,9 +502,12 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
     VERIFY_NOT_NULL(TAG, doxm, ERROR);
 
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXM_TYPE_NAME, &doxmMap);
-    //OxmType -- not Mandatory
+    // OxmType
+    // TODO [IOT-2105]: resolve "oxmtype" undocumented tag/value
     if (CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.oxmtype tag in doxmMap.");
+
         CborValue oxmType;
 
         cborFindResult = cbor_value_get_array_length(&doxmMap, &doxm->oxmTypeLen);
@@ -431,6 +524,7 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
         size_t oxmTypeStrlen = 0;
         while (cbor_value_is_valid(&oxmType) && cbor_value_is_text_string(&oxmType))
         {
+            OIC_LOG_V(DEBUG, TAG, "Read doxm.oxmtype value = %s", oxmType);
             cborFindResult = cbor_value_dup_text_string(&oxmType, &doxm->oxmType[i++],
                                                         &oxmTypeStrlen, NULL);
             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding omxType text string.");
@@ -440,19 +534,21 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
     }
 
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXMS_NAME, &doxmMap);
-    //Oxm -- not Mandatory
+
+    // oxms
     if (CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.oxms tag in doxmMap.");
         CborValue oxm;
         cborFindResult = cbor_value_get_array_length(&doxmMap, &doxm->oxmLen);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxmName array Length.");
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxms array Length.");
         VERIFY_SUCCESS(TAG, doxm->oxmLen != 0, ERROR);
 
         doxm->oxm = (OicSecOxm_t *)OICCalloc(doxm->oxmLen, sizeof(*doxm->oxm));
         VERIFY_NOT_NULL(TAG, doxm->oxm, ERROR);
 
         cborFindResult = cbor_value_enter_container(&doxmMap, &oxm);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering oxmName Array.")
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering oxms Array.")
 
         int i = 0;
         while (cbor_value_is_valid(&oxm) && cbor_value_is_integer(&oxm))
@@ -460,15 +556,19 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
             int tmp;
 
             cborFindResult = cbor_value_get_int(&oxm, &tmp);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxmName Value")
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxms Value")
+            OIC_LOG_V(DEBUG, TAG, "Read doxm.oxms value = %d", tmp);
             doxm->oxm[i++] = (OicSecOxm_t)tmp;
             cborFindResult = cbor_value_advance(&oxm);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing oxmName.")
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing oxms.")
         }
 
         if (roParsed)
         {
-            *roParsed = true;
+            if (IsPropertyReadOnly(DOXM_OXMS, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
         }
     }
     else
@@ -483,14 +583,25 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
         }
     }
 
+    // oxmsel
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXM_SEL_NAME, &doxmMap);
     if (CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.oxmsel tag in doxmMap.");
+
         int oxmSel;
 
         cborFindResult = cbor_value_get_int(&doxmMap, &oxmSel);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Sel Name Value.")
+        OIC_LOG_V(DEBUG, TAG, "Read doxm.oxmsel value = %d", oxmSel);
         doxm->oxmSel = (OicSecOxm_t)oxmSel;
+        if (roParsed)
+        {
+            if (IsPropertyReadOnly(DOXM_OXMSEL, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
+        }
     }
     else // PUT/POST JSON may not have oxmsel so set it to the gDoxm->oxmSel
     {
@@ -498,18 +609,24 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
         doxm->oxmSel = gDoxm->oxmSel;
     }
 
+    // sct
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_SUPPORTED_CRED_TYPE_NAME, &doxmMap);
     if (CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.oxmsel tag in doxmMap.");
         int sct;
 
         cborFindResult = cbor_value_get_int(&doxmMap, &sct);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Sct Name Value.")
+        OIC_LOG_V(DEBUG, TAG, "Read doxm.sct value = %d", sct);
         doxm->sct = (OicSecCredType_t)sct;
 
         if (roParsed)
         {
-            *roParsed = true;
+            if (IsPropertyReadOnly(DOXM_SCT, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
         }
     }
     else // PUT/POST JSON may not have sct so set it to the gDoxm->sct
@@ -518,11 +635,22 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
         doxm->sct = gDoxm->sct;
     }
 
+    // owned
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OWNED_NAME, &doxmMap);
     if (CborNoError == cborFindResult && cbor_value_is_boolean(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.owned tag in doxmMap.");
         cborFindResult = cbor_value_get_boolean(&doxmMap, &doxm->owned);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Owned Value.")
+        OIC_LOG_V(DEBUG, TAG, "Read doxm.owned value = %s", doxm->owned?"true":"false");
+
+        if (roParsed)
+        {
+            if (IsPropertyReadOnly(DOXM_OWNED, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
+        }
     }
     else // PUT/POST JSON may not have owned so set it to the gDomx->owned
     {
@@ -530,15 +658,26 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
         doxm->owned = gDoxm->owned;
     }
 
+    // deviceuuid
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_DEVICE_ID_NAME, &doxmMap);
     if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.deviceuuid tag in doxmMap.");
         cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
-        ret = ConvertStrToUuid(strUuid , &doxm->deviceID);
+        OIC_LOG_V(DEBUG, TAG, "Read doxm.deviceuuid value = %s", strUuid);
+        ret = ConvertStrToUuid(strUuid, &doxm->deviceID);
         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
         OICFree(strUuid);
         strUuid  = NULL;
+
+        if (roParsed)
+        {
+            if (IsPropertyReadOnly(DOXM_DEVICEUUID, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
+        }
     }
     else
     {
@@ -546,15 +685,26 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
         memcpy(doxm->deviceID.id, &gDoxm->deviceID.id, sizeof(doxm->deviceID.id));
     }
 
+    // devowneruuid
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_DEVOWNERID_NAME, &doxmMap);
     if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.devowneruuid tag in doxmMap.");
         cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Owner Value.");
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding devowneruuid Value.");
+        OIC_LOG_V(DEBUG, TAG, "Read doxm.devowneruuid value = %s", strUuid);
         ret = ConvertStrToUuid(strUuid , &doxm->owner);
         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
         OICFree(strUuid);
         strUuid  = NULL;
+
+        if (roParsed)
+        {
+            if (IsPropertyReadOnly(DOXM_DEVOWNERUUID, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
+        }
     }
     else
     {
@@ -566,6 +716,7 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_MOM_NAME, &doxmMap);
     if(CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.mom tag in doxmMap.");
         int mode = 0;
         cborFindResult = cbor_value_get_int(&doxmMap, &mode);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding mom Name Value.")
@@ -575,6 +726,13 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
             VERIFY_NOT_NULL(TAG, doxm->mom, ERROR);
         }
         doxm->mom->mode = (OicSecMomType_t)mode;
+        if (roParsed)
+        {
+            if (IsPropertyReadOnly(DOXM_MOM, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
+        }
     }
     else if(NULL != gDoxm && NULL != gDoxm->mom)
     {
@@ -590,6 +748,7 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_SUBOWNERID_NAME, &doxmMap);
     if(CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.subowner tag in doxmMap.");
         size_t subOwnerLen = 0;
         CborValue subOwnerCbor;
         cborFindResult = cbor_value_get_array_length(&doxmMap, &subOwnerLen);
@@ -620,6 +779,13 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
             cborFindResult = cbor_value_advance(&subOwnerCbor);
             VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing SubOwnerId.")
         }
+        if (roParsed)
+        {
+            if (IsPropertyReadOnly(DOXM_SUBOWNER, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
+        }
     }
     else if(NULL != gDoxm && NULL != gDoxm->subOwners)
     {
@@ -638,15 +804,26 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
     }
 #endif //MULTIPLE_OWNER
 
+    // rowneruuid
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_ROWNERID_NAME, &doxmMap);
     if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
     {
+        OIC_LOG(DEBUG, TAG, "Found doxm.rowneruuid tag in doxmMap.");
         cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Value.");
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding rowneruuid Value.");
+        OIC_LOG_V(DEBUG, TAG, "Read doxm.rowneruuid value = %s", strUuid);
         ret = ConvertStrToUuid(strUuid , &doxm->rownerID);
         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
         OICFree(strUuid);
         strUuid  = NULL;
+
+        if (roParsed)
+        {
+            if (IsPropertyReadOnly(DOXM_ROWNERUUID, stateForReadOnlyCheck))
+            {
+                *roParsed = true;
+            }
+        }
     }
     else
     {
@@ -682,7 +859,7 @@ static bool UpdatePersistentStorage(OicSecDoxm_t * doxm)
         // Convert Doxm data into CBOR for update to persistent storage
         uint8_t *payload = NULL;
         size_t size = 0;
-        OCStackResult res = DoxmToCBORPayload(doxm, &payload, &size, false);
+        OCStackResult res = DoxmToCBORPayload(doxm, &payload, &size);
         if (payload && (OC_STACK_OK == res)
             && (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, payload, size)))
         {
@@ -719,8 +896,8 @@ static bool ValidateQuery(const char * query)
 
     bool bOwnedQry = false;         // does querystring contains 'owned' query ?
     bool bOwnedMatch = false;       // does 'owned' query value matches with doxm.owned status?
-    bool bDeviceIDQry = false;      // does querystring contains 'deviceid' query ?
-    bool bDeviceIDMatch = false;    // does 'deviceid' query matches with doxm.deviceid ?
+    bool bDeviceIDQry = false;      // does querystring contains 'deviceuuid' query ?
+    bool bDeviceIDMatch = false;    // does 'deviceuuid' query matches with doxm.deviceuuid ?
     bool bInterfaceQry = false;      // does querystring contains 'if' query ?
     bool bInterfaceMatch = false;    // does 'if' query matches with oic.if.baseline ?
 #ifdef MULTIPLE_OWNER
@@ -775,6 +952,11 @@ static bool ValidateQuery(const char * query)
             bDeviceIDQry = true;
             OicUuid_t subject = {.id={0}};
 
+            if (sizeof(subject.id) < parseIter.valLen)
+            {
+                OIC_LOG (ERROR, TAG, "Subject ID length is too long");
+                return false;
+            }
             memcpy(subject.id, parseIter.valPos, parseIter.valLen);
             if (0 == memcmp(&gDoxm->deviceID.id, &subject.id, sizeof(gDoxm->deviceID.id)))
             {
@@ -825,7 +1007,7 @@ static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest
 
     if (ehRet == OC_EH_OK)
     {
-        if (OC_STACK_OK != DoxmToCBORPayload(gDoxm, &payload, &size, false))
+        if (OC_STACK_OK != DoxmToCBORPayload(gDoxm, &payload, &size))
         {
             OIC_LOG(WARNING, TAG, "DoxmToCBORPayload failed in HandleDoxmGetRequest");
         }
@@ -843,23 +1025,25 @@ static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest
     return ehRet;
 }
 
-static void updateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
+OCStackResult DoxmUpdateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
 {
+    OCStackResult result = OC_STACK_OK;
+
     if(src && dst)
-   {
-        // update oxmsel
+    {
+        // Update oxmsel
         dst->oxmSel = src->oxmSel;
 
-        //update owner
+        // Update owner
         memcpy(&(dst->owner), &(src->owner), sizeof(OicUuid_t));
 
-        //update rowner
+        // Update rowner
         memcpy(&(dst->rownerID), &(src->rownerID), sizeof(OicUuid_t));
 
-        //update deviceuuid
+        // Update deviceuuid
         memcpy(&(dst->deviceID), &(src->deviceID), sizeof(OicUuid_t));
 
-        //Update owned status
+        // Update owned status
         if(dst->owned != src->owned)
         {
             dst->owned = src->owned;
@@ -868,18 +1052,25 @@ static void updateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
 #ifdef MULTIPLE_OWNER
         if(src->mom)
         {
-            OIC_LOG(DEBUG, TAG, "dectected 'mom' property");
+            OIC_LOG(DEBUG, TAG, "Detected 'mom' property");
             if(NULL == dst->mom)
             {
                 dst->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
-                if(NULL != dst->mom)
+                if (NULL == dst->mom)
                 {
-                    dst->mom->mode = src->mom->mode;
+                    result = OC_STACK_NO_MEMORY;
                 }
             }
+
+            if (NULL != dst->mom)
+            {
+                dst->mom->mode = src->mom->mode;
+            }
         }
 #endif //MULTIPLE_OWNER
     }
+
+    return result;
 }
 
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
@@ -896,11 +1087,12 @@ void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
 
     if(CA_STATUS_OK == errorInfo->result)
     {
-        const CASecureEndpoint_t* authenticatedSubOwnerInfo = CAGetSecureEndpointData(object);
-        if(authenticatedSubOwnerInfo)
+        CASecureEndpoint_t authenticationSubOwnerInfo;
+        CAResult_t caRes = CAGetSecureEndpointData(object, &authenticationSubOwnerInfo);
+        if (CA_STATUS_OK == caRes)
         {
-            if (0 == memcmp(authenticatedSubOwnerInfo->identity.id, gDoxm->owner.id,
-                            authenticatedSubOwnerInfo->identity.id_length))
+            if (0 == memcmp(authenticationSubOwnerInfo.identity.id, gDoxm->owner.id,
+                            authenticationSubOwnerInfo.identity.id_length))
             {
                 OIC_LOG(WARNING, TAG, "Super owner tried MOT, this request will be ignored.");
                 return;
@@ -910,8 +1102,8 @@ void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
             LL_FOREACH(gDoxm->subOwners, subOwnerInst)
             {
                 if(0 == memcmp(subOwnerInst->uuid.id,
-                               authenticatedSubOwnerInfo->identity.id,
-                               authenticatedSubOwnerInfo->identity.id_length))
+                               authenticationSubOwnerInfo.identity.id,
+                               authenticationSubOwnerInfo.identity.id_length))
                 {
                     break;
                 }
@@ -923,8 +1115,13 @@ void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
                 if(subOwnerInst)
                 {
                     char* strUuid = NULL;
-                    memcpy(subOwnerInst->uuid.id, authenticatedSubOwnerInfo->identity.id,
-                           authenticatedSubOwnerInfo->identity.id_length);
+                    if (sizeof(subOwnerInst->uuid.id) < authenticationSubOwnerInfo.identity.id_length)
+                    {
+                        OIC_LOG(ERROR, TAG, "Identity id is too long");
+                        return;
+                    }
+                    memcpy(subOwnerInst->uuid.id, authenticationSubOwnerInfo.identity.id,
+                           authenticationSubOwnerInfo.identity.id_length);
                     if(OC_STACK_OK != ConvertUuidToStr(&subOwnerInst->uuid, &strUuid))
                     {
                         OIC_LOG(ERROR, TAG, "Failed to allocate memory.");
@@ -940,6 +1137,10 @@ void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
                 }
             }
         }
+        else
+        {
+            OIC_LOG_V(ERROR, TAG, "Could not CAGetSecureEndpointData: %d", caRes);
+        }
     }
 
     if(CA_STATUS_OK != CAregisterPskCredentialsHandler(GetDtlsPskCredentials))
@@ -1018,7 +1219,7 @@ static void RegisterOTMSslHandshakeCallback(CAErrorCallback callback)
 static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRequest)
 {
     OIC_LOG (DEBUG, TAG, "Doxm EntityHandle  processing POST request");
-    OCEntityHandlerResult ehRet = OC_EH_ERROR;
+    OCEntityHandlerResult ehRet = OC_EH_INTERNAL_SERVER_ERROR;
     OicUuid_t emptyOwner = {.id = {0} };
     static uint16_t previousMsgId = 0;
     bool isDuplicatedMsg = false;
@@ -1034,7 +1235,10 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
         uint8_t *payload = ((OCSecurityPayload *)ehRequest->payload)->securityData;
         size_t size = ((OCSecurityPayload *)ehRequest->payload)->payloadSize;
         bool roParsed = false;
-        OCStackResult res = CBORPayloadToDoxmBin(payload, size, &newDoxm, &roParsed);
+        OicSecDostype_t onboardingState;
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDos(&onboardingState), ERROR);
+        OCStackResult res = CBORPayloadToDoxmBin(payload, size, &newDoxm, &roParsed,
+            onboardingState.state);
         if (newDoxm && OC_STACK_OK == res)
         {
             /*
@@ -1051,7 +1255,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
             // Check request on RO property
             if (true == roParsed)
             {
-                OIC_LOG(ERROR, TAG, "Not acceptable request because of read-only propertys");
+                OIC_LOG(ERROR, TAG, "Not acceptable request because of read-only properties");
                 ehRet = OC_EH_NOT_ACCEPTABLE;
                 goto exit;
             }
@@ -1061,12 +1265,19 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
             {
                 if (false == ValidateOxmsel(gDoxm->oxm, gDoxm->oxmLen, &newDoxm->oxmSel))
                 {
-                    OIC_LOG(ERROR, TAG, "Not acceptable request because oxmsel does not support on Server");
+                    OIC_LOG(ERROR, TAG, "Not acceptable request because oxmsel is not supported on Server");
                     ehRet = OC_EH_NOT_ACCEPTABLE;
                     goto exit;
                 }
-                //Update gDoxm based on newDoxm
-                updateWriteableProperty(newDoxm, gDoxm);
+
+                // Update gDoxm based on newDoxm
+                res = DoxmUpdateWriteableProperty(newDoxm, gDoxm);
+                if (OC_STACK_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "gDoxm properties were not able to be updated so we cannot handle the request.");
+                    ehRet = OC_EH_ERROR;
+                    goto exit;
+                }
 
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
 #ifdef MULTIPLE_OWNER
@@ -1400,6 +1611,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
              * Tool is attempting to change the state to 'Owned' with a
              * qualified value for the field 'Owner'
              */
+            // TODO [IOT-2107] reconcile POST handler behavior with Specification
             if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
                     (memcmp(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)) == 0))
             {
@@ -1410,12 +1622,6 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                     ehRet = OC_EH_ERROR;
                     goto exit;
                 }
-                ownerRes = SetAmaclRownerId(&gDoxm->owner);
-                if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
-                {
-                    ehRet = OC_EH_ERROR;
-                    goto exit;
-                }
                 ownerRes = SetCredRownerId(&gDoxm->owner);
                 if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
                 {
@@ -1560,7 +1766,7 @@ OCStackResult CreateDoxmResource()
                                          OIC_RSRC_DOXM_URI,
                                          DoxmEntityHandler,
                                          NULL,
-                                         OC_SECURE |
+                                         OC_SECURE | OC_NONSECURE |
                                          OC_DISCOVERABLE);
 
     if (OC_STACK_OK != ret)
@@ -1809,26 +2015,6 @@ OCStackResult DeInitDoxmResource()
     }
 }
 
-OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID)
-{
-    if (deviceID && gDoxm)
-    {
-       *deviceID = gDoxm->deviceID;
-        return OC_STACK_OK;
-    }
-    return OC_STACK_ERROR;
-}
-
-OCStackResult GetDoxmIsOwned(bool *isOwned)
-{
-    if (isOwned && gDoxm)
-    {
-       *isOwned = gDoxm->owned;
-        return OC_STACK_OK;
-    }
-    return OC_STACK_ERROR;
-}
-
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
 OCStackResult SetDoxmDeviceIDSeed(const uint8_t* seed, size_t seedSize)
 {
@@ -1859,11 +2045,21 @@ OCStackResult SetDoxmDeviceIDSeed(const uint8_t* seed, size_t seedSize)
 }
 #endif
 
-OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceID)
+OCStackResult GetDoxmDeviceID(OicUuid_t *deviceuuid)
+{
+    if (deviceuuid && gDoxm)
+    {
+        *deviceuuid = gDoxm->deviceID;
+        return OC_STACK_OK;
+    }
+    return OC_STACK_ERROR;
+}
+
+OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceuuid)
 {
     bool isOwnerUpdated = false;
     bool isRownerUpdated = false;
-    if (NULL == deviceID)
+    if (NULL == deviceuuid)
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -1889,36 +2085,36 @@ OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceID)
     memcpy(prevUuid.id, gDoxm->deviceID.id, sizeof(prevUuid.id));
 
     //Change the device UUID
-    memcpy(gDoxm->deviceID.id, deviceID->id, sizeof(deviceID->id));
+    memcpy(gDoxm->deviceID.id, deviceuuid->id, sizeof(gDoxm->deviceID.id));
 
     //Change the owner ID if necessary
     if (memcmp(gDoxm->owner.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
     {
-        memcpy(gDoxm->owner.id, deviceID->id, sizeof(deviceID->id));
+        memcpy(gDoxm->owner.id, deviceuuid->id, sizeof(gDoxm->owner.id));
         isOwnerUpdated = true;
     }
     //Change the resource owner ID if necessary
+    // TODO [IOT-2023] change this behavior and upate the usage of this function
+    // so that rowneruuid for each resource is set by OBT
     if (memcmp(gDoxm->rownerID.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
     {
-        memcpy(gDoxm->rownerID.id, deviceID->id, sizeof(deviceID->id));
+        memcpy(gDoxm->rownerID.id, deviceuuid->id, sizeof(gDoxm->rownerID.id));
         isRownerUpdated = true;
     }
-    // TODO: T.B.D Change resource owner for pstat, acl and cred
 
     //Update PS
     if (!UpdatePersistentStorage(gDoxm))
     {
         //revert UUID in case of PSI error
-        memcpy(gDoxm->deviceID.id, prevUuid.id, sizeof(prevUuid.id));
+        memcpy(gDoxm->deviceID.id, prevUuid.id, sizeof(gDoxm->deviceID.id));
         if (isOwnerUpdated)
         {
-            memcpy(gDoxm->owner.id, prevUuid.id, sizeof(prevUuid.id));
+            memcpy(gDoxm->owner.id, prevUuid.id, sizeof(gDoxm->owner.id));
         }
         if (isRownerUpdated)
         {
-            memcpy(gDoxm->rownerID.id, prevUuid.id, sizeof(prevUuid.id));
+            memcpy(gDoxm->rownerID.id, prevUuid.id, sizeof(gDoxm->rownerID.id));
         }
-        // TODO: T.B.D Revert resource owner for pstat, acl and cred
 
         OIC_LOG(ERROR, TAG, "Failed to update persistent storage");
         return OC_STACK_ERROR;
@@ -1926,34 +2122,64 @@ OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceID)
     return OC_STACK_OK;
 }
 
-OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid)
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devowneruuid)
+{
+    if (gDoxm && devowneruuid)
+    {
+        memcpy(&(devowneruuid->id), &(gDoxm->owner.id), sizeof(devowneruuid->id));
+        return OC_STACK_OK;
+    }
+    return OC_STACK_ERROR;
+}
+
+OCStackResult SetDoxmDevOwnerId(const OicUuid_t *devowneruuid)
+{
+    if (gDoxm && devowneruuid)
+    {
+        memcpy(&(gDoxm->owner.id), &(devowneruuid->id), sizeof(gDoxm->owner.id));
+        return OC_STACK_OK;
+    }
+    return OC_STACK_ERROR;
+}
+
+OCStackResult GetDoxmIsOwned(bool *isowned)
+{
+    if (isowned && gDoxm)
+    {
+        *isowned = gDoxm->owned;
+        return OC_STACK_OK;
+    }
+    return OC_STACK_ERROR;
+}
+
+OCStackResult SetDoxmIsOwned(const bool isowned)
 {
-    OCStackResult retVal = OC_STACK_ERROR;
     if (gDoxm)
     {
-        OIC_LOG_V(DEBUG, TAG, "GetDoxmDevOwnerId(): gDoxm owned =  %d.", \
-            gDoxm->owned);
-        if (gDoxm->owned)
-        {
-            *devownerid = gDoxm->owner;
-            retVal = OC_STACK_OK;
-        }
+        gDoxm->owned = isowned;
+        return OC_STACK_OK;
     }
-    return retVal;
+    return OC_STACK_ERROR;
 }
 
 OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid)
 {
-    OCStackResult retVal = OC_STACK_ERROR;
-    if (gDoxm)
+    if (gDoxm && rowneruuid)
     {
-        if( gDoxm->owned )
-        {
-            *rowneruuid = gDoxm->rownerID;
-                    retVal = OC_STACK_OK;
-        }
+        memcpy(&(rowneruuid->id), &(gDoxm->rownerID.id), sizeof(rowneruuid->id));
+        return OC_STACK_OK;
     }
-    return retVal;
+    return OC_STACK_ERROR;
+}
+
+OCStackResult SetDoxmRownerId(const OicUuid_t *rowneruuid)
+{
+    if (gDoxm && rowneruuid)
+    {
+        memcpy(&(gDoxm->rownerID.id), &(rowneruuid->id), sizeof(gDoxm->rownerID.id));
+        return OC_STACK_OK;
+    }
+    return OC_STACK_ERROR;
 }
 
 #ifdef MULTIPLE_OWNER
@@ -1991,6 +2217,49 @@ bool IsSubOwner(const OicUuid_t* uuid)
     }
     return retVal;
 }
+
+OCStackResult SetMOTStatus(bool enable)
+{
+    OCStackResult ret = OC_STACK_NO_MEMORY;
+    uint8_t *cborPayload = NULL;
+    size_t size = 0;
+    bool isDeallocateRequired = false;
+
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (NULL == gDoxm->mom && !enable)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return OC_STACK_OK;
+    }
+
+    if (NULL == gDoxm->mom)
+    {
+        gDoxm->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
+        VERIFY_NOT_NULL(TAG, gDoxm->mom, ERROR);
+        isDeallocateRequired = true;
+    }
+
+    gDoxm->mom->mode = (enable ? OIC_MULTIPLE_OWNER_ENABLE : OIC_MULTIPLE_OWNER_DISABLE);
+
+    ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+    ret = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, cborPayload, size);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+    isDeallocateRequired = false;
+
+exit:
+    if (isDeallocateRequired)
+    {
+        OICFree(gDoxm->mom);
+    }
+    OICFree(cborPayload);
+    OIC_LOG_V(DEBUG, TAG, "Out %s : %d", __func__, ret);
+    return ret;
+}
+
 #endif //MULTIPLE_OWNER
 
 /**
@@ -2033,7 +2302,7 @@ OCStackResult SetDoxmSelfOwnership(const OicUuid_t* newROwner)
         memcpy(gDoxm->owner.id, newROwner->id, sizeof(newROwner->id));
         memcpy(gDoxm->rownerID.id, newROwner->id, sizeof(newROwner->id));
 
-        ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size, false);
+        ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size);
         VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
 
         ret = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, cborPayload, size);
@@ -2081,7 +2350,7 @@ static bool AreDoxmBinMOTPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t*
 
             if (subOwner1->status != subOwner2->status)
             {
-                OIC_LOG_V(ERROR, TAG, "%s: subOwner status mismatch: (%u, %u)", 
+                OIC_LOG_V(ERROR, TAG, "%s: subOwner status mismatch: (%u, %u)",
                     __func__, (uint32_t)subOwner1->status, (uint32_t)subOwner2->status);
                 return false;
             }
@@ -2091,7 +2360,7 @@ static bool AreDoxmBinMOTPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t*
             subOwner2 = subOwner2->next;
             continue;
         }
-     
+
         OIC_LOG_V(ERROR, TAG, "%s: subOwner list length mismatch", __func__);
         return false;
     }
@@ -2116,7 +2385,7 @@ static bool AreDoxmBinMOTPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t*
 
     if (doxm1->mom->mode != doxm2->mom->mode)
     {
-        OIC_LOG_V(ERROR, TAG, "%s: mom->mode mismatch: (%u, %u)", 
+        OIC_LOG_V(ERROR, TAG, "%s: mom->mode mismatch: (%u, %u)",
             __func__, (uint32_t)doxm1->mom->mode, (uint32_t)doxm2->mom->mode);
         return false;
     }
@@ -2138,7 +2407,7 @@ bool AreDoxmBinPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
 
     if (arrayLength != doxm2->oxmTypeLen)
     {
-        OIC_LOG_V(ERROR, TAG, "%s: oxmTypeLen mismatch: (%" PRIuPTR ", %" PRIuPTR ")", 
+        OIC_LOG_V(ERROR, TAG, "%s: oxmTypeLen mismatch: (%" PRIuPTR ", %" PRIuPTR ")",
             __func__, arrayLength, doxm2->oxmTypeLen);
         return false;
     }
@@ -2154,7 +2423,7 @@ bool AreDoxmBinPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
 
         if (0 != strcmp(doxm1->oxmType[i], doxm2->oxmType[i]))
         {
-            OIC_LOG_V(ERROR, TAG, "%s: oxmType mismatch: (%s, %s)", 
+            OIC_LOG_V(ERROR, TAG, "%s: oxmType mismatch: (%s, %s)",
                 __func__, doxm1->oxmType[i], doxm2->oxmType[i]);
             return false;
         }
@@ -2165,16 +2434,16 @@ bool AreDoxmBinPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
 
     if (arrayLength != doxm2->oxmLen)
     {
-        OIC_LOG_V(ERROR, TAG, "%s: oxmLen mismatch: (%" PRIuPTR ", %" PRIuPTR ")", 
+        OIC_LOG_V(ERROR, TAG, "%s: oxmLen mismatch: (%" PRIuPTR ", %" PRIuPTR ")",
             __func__, arrayLength, doxm2->oxmLen);
         return false;
     }
-   
+
     for (size_t i = 0; i < arrayLength; i++)
     {
         if (doxm1->oxm[i] != doxm2->oxm[i])
         {
-            OIC_LOG_V(ERROR, TAG, "%s: oxmType mismatch: (%u, %u)", 
+            OIC_LOG_V(ERROR, TAG, "%s: oxmType mismatch: (%u, %u)",
                 __func__, (uint32_t)doxm1->oxm[i], (uint32_t)doxm2->oxm[i]);
             return false;
         }
@@ -2183,21 +2452,21 @@ bool AreDoxmBinPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
     //Compare the remaining property values.
     if (doxm1->oxmSel != doxm2->oxmSel)
     {
-        OIC_LOG_V(ERROR, TAG, "%s: oxmSel mismatch: (%u, %u)", 
+        OIC_LOG_V(ERROR, TAG, "%s: oxmSel mismatch: (%u, %u)",
             __func__, (uint32_t)doxm1->oxmSel, (uint32_t)doxm2->oxmSel);
         return false;
     }
 
     if (doxm1->sct != doxm2->sct)
     {
-        OIC_LOG_V(ERROR, TAG, "%s: sct mismatch: (%u, %u)", 
+        OIC_LOG_V(ERROR, TAG, "%s: sct mismatch: (%u, %u)",
             __func__, (uint32_t)doxm1->sct, (uint32_t)doxm2->sct);
         return false;
     }
 
     if (doxm1->owned != doxm2->owned)
     {
-        OIC_LOG_V(ERROR, TAG, "%s: owned mismatch: (%u, %u)", 
+        OIC_LOG_V(ERROR, TAG, "%s: owned mismatch: (%u, %u)",
             __func__, (uint32_t)doxm1->owned, (uint32_t)doxm2->owned);
         return false;
     }
@@ -2207,10 +2476,10 @@ bool AreDoxmBinPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
         OIC_LOG_V(ERROR, TAG, "%s: deviceID mismatch", __func__);
         return false;
     }
-    
+
     if (doxm1->dpc != doxm2->dpc)
     {
-        OIC_LOG_V(ERROR, TAG, "%s: dpc mismatch: (%u, %u)", 
+        OIC_LOG_V(ERROR, TAG, "%s: dpc mismatch: (%u, %u)",
             __func__, (uint32_t)doxm1->dpc, (uint32_t)doxm2->dpc);
         return false;
     }
@@ -2220,7 +2489,7 @@ bool AreDoxmBinPropertyValuesEqual(OicSecDoxm_t* doxm1, OicSecDoxm_t* doxm2)
         OIC_LOG_V(ERROR, TAG, "%s: owner mismatch", __func__);
         return false;
     }
-    
+
     if (0 != memcmp(&doxm1->rownerID, &doxm2->rownerID, sizeof(doxm1->rownerID)))
     {
         OIC_LOG_V(ERROR, TAG, "%s: rownerID mismatch", __func__);