Observe handlind added to smart objects and object instances

Signed-off-by: eantwuh <antal.wu-hen-chang@ericsson.com>
diff --git a/src/EPTF_LwM2M_LGen_Functions.ttcn b/src/EPTF_LwM2M_LGen_Functions.ttcn
index 54919e2..53c5652 100644
--- a/src/EPTF_LwM2M_LGen_Functions.ttcn
+++ b/src/EPTF_LwM2M_LGen_Functions.ttcn
@@ -682,6 +682,27 @@
 
         f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_resourceNotObservedIndication, v_LwM2M_eventToProcess.eIdx, -1, {});
       }
+      else if (f_LwM2M_ObjectPath_isObjectInstance(v_LwM2M_eventToProcess.event.resourceNotObserved))
+      {
+        f_LwM2M_ObjectDB_setObjectInstanceObserved(
+          v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
+          v_LwM2M_eventToProcess.event.resourceNotObserved.objectId,
+          v_LwM2M_eventToProcess.event.resourceNotObserved.objectInstanceId,
+          false
+        );
+
+        f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_resourceNotObservedIndication, v_LwM2M_eventToProcess.eIdx, -1, {});
+      }
+      else if (f_LwM2M_ObjectPath_isObject(v_LwM2M_eventToProcess.event.resourceNotObserved))
+      {
+        f_LwM2M_ObjectDB_setObjectObserved(
+          v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
+          v_LwM2M_eventToProcess.event.resourceNotObserved.objectId,
+          false
+        );
+
+        f_EPTF_LwM2M_dispatchEvent(c_LwM2M_eventIdx_resourceNotObservedIndication, v_LwM2M_eventToProcess.eIdx, -1, {});
+      }
     }
     else if (ischosen(v_LwM2M_eventToProcess.event.atomicBlock1Finished))
     {
@@ -1310,7 +1331,7 @@
 	  {
             v_resources[sizeof(v_resources)] := v_res;
             f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " resource found: ", v_resources));
-	    
+
             if (ispresent(v_LwM2M_msgToProcess.pdu.Read_.observe))
             {
 	      vl_contentFormat := 
@@ -1319,9 +1340,9 @@
                 v_LwM2M_msgToProcess.pdu.Read_.accept,
                 v_resources
               );
-	      
+
 	      f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " setting resource observed with contentFormat: ", vl_contentFormat));
-	      
+
               f_LwM2M_ObjectDB_setResourceObserved(
                 v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
                 v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
@@ -1358,6 +1379,25 @@
               v_resources[sizeof(v_resources)] := v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[v_objInst.resources[i]];
 	    }
           }
+          if (ispresent(v_LwM2M_msgToProcess.pdu.Read_.observe))
+          {
+	    vl_contentFormat := 
+            f_EPTF_LwM2M_getEncodingContentFormat(
+              v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].contentFormats,
+              v_LwM2M_msgToProcess.pdu.Read_.accept,
+              v_resources
+            );
+
+	    f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " setting object instance observed with contentFormat: ", vl_contentFormat));
+
+            f_LwM2M_ObjectDB_setObjectInstanceObserved(
+              v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
+              v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
+              v_LwM2M_msgToProcess.pdu.Read_.path.objectInstanceId,
+              true,
+              vl_contentFormat
+            );
+          }
 	}
       }
 
@@ -1365,15 +1405,15 @@
       else if (f_LwM2M_ObjectPath_isObject(v_LwM2M_msgToProcess.pdu.Read_.path))
       {
         var LwM2M_Object v_obj := c_LwM2M_Object_init;
-	
+
         vl_found := f_LwM2M_ObjectDB_getObject(
           v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
           v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
 	  v_obj
 	);
-	
+
 	if (vl_found)
-	{
+	{          
 	  for (var integer v_inst:=0; v_inst<sizeof(v_obj.instances); v_inst:=v_inst+1)
 	  {
             for (var integer i:=0; i<sizeof(v_obj.instances[v_inst].resources); i:=i+1) {
@@ -1384,7 +1424,25 @@
                 v_resources[sizeof(v_resources)] := v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[v_obj.instances[v_inst].resources[i]];
               }
 	    }
-	  }	  
+	  }
+          if (ispresent(v_LwM2M_msgToProcess.pdu.Read_.observe))
+          {
+	    vl_contentFormat := 
+            f_EPTF_LwM2M_getEncodingContentFormat(
+              v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].contentFormats,
+              v_LwM2M_msgToProcess.pdu.Read_.accept,
+              v_resources
+            );
+
+	    f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId, " setting object observed with contentFormat: ", vl_contentFormat));
+
+            f_LwM2M_ObjectDB_setObjectObserved(
+              v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects,
+              v_LwM2M_msgToProcess.pdu.Read_.path.objectId,
+              true,
+              vl_contentFormat
+            );
+          }	  
 	}
       }
 
@@ -1678,10 +1736,11 @@
   {
     f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
     f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
-    
+
     if (v_LwM2M_ctx.deviceIdx >= 0)
     {
-      // Should be made faster by keeping track of the observed resources in a separate list
+      // Should be made faster by keeping track of the observed resources in a separate list!
+
       for (var integer i:=0; i<sizeof(v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources); i:=i+1)
       {
         if (v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[i].observed)
@@ -1692,6 +1751,28 @@
           );
         }
       }
+
+      for (var integer i:=0; i<sizeof(v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.objs); i:=i+1)
+      {
+        if (v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.objs[i].observed)
+        {
+          f_EPTF_LwM2M_sendNotificationForObject(
+            pl_ptr,
+            v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.objs[i]
+          );
+        }
+
+        for (var integer j:=0; j<sizeof(v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.objs[i].instances); j:=j+1)
+        {
+          if (v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.objs[i].instances[j].observed)
+          {
+            f_EPTF_LwM2M_sendNotificationForObjectInstance(
+              pl_ptr,
+              v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.objs[i].instances[j]
+            );
+          }
+        }
+      }
     }
     else { f_EPTF_LwM2M_Logging_VERBOSE(log2str("device is not initialized")); }
   }
@@ -2005,11 +2086,14 @@
   ///////////////////////////////////////////////////////////
   function f_EPTF_LwM2M_sendNotificationForResource(in EPTF_LGenBase_TestStepArgs pl_ptr, in LwM2M_Resource v_res)
   runs on EPTF_LwM2M_LGen_CT
-  {  
+  {
+    f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
+    f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
+    
     if (v_res.observed) 
     {
 	  //v_res.objId := -1; v_res.objInstId := -1; v_res.id := -1;
-	    
+
 	  v_LwM2M_msgToSend.pdu := c_LWM2M_Notification_init;
 	  v_LwM2M_msgToSend.pdu.Notification.path := { v_res.objId, v_res.objInstId, v_res.id };
 	  v_LwM2M_msgToSend.pdu.Notification.code := 205;
@@ -2025,6 +2109,76 @@
 	  f_LwM2M_step_send(pl_ptr);
     }
   }
+
+  function f_EPTF_LwM2M_sendNotificationForObject(in EPTF_LGenBase_TestStepArgs pl_ptr, in LwM2M_Object p_obj)
+  runs on EPTF_LwM2M_LGen_CT
+  {
+    f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
+    f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
+    
+    if (p_obj.observed)
+    {
+      v_LwM2M_msgToSend.pdu := c_LWM2M_Notification_init;
+      v_LwM2M_msgToSend.pdu.Notification.path := { p_obj.id };
+      v_LwM2M_msgToSend.pdu.Notification.code := 205;
+
+      for (var integer v_inst:=0; v_inst<sizeof(p_obj.instances); v_inst:=v_inst+1)
+      {
+        for (var integer i:=0; i<sizeof(p_obj.instances[v_inst].resources); i:=i+1) {
+          if (f_LwM2M_Resource_checkSpecification(
+            v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[p_obj.instances[v_inst].resources[i]],
+            v_LwM2M_ObjectSpecificationDB, t_LwM2M_ResourceSpecification_Readable))
+          {	  
+            v_LwM2M_msgToSend.pdu.Notification.resources[sizeof(v_LwM2M_msgToSend.pdu.Notification.resources)] := 
+              v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[p_obj.instances[v_inst].resources[i]];
+          }
+        }
+      }	  
+      if (ispresent(p_obj.contentFormat))
+      {
+        v_LwM2M_msgToSend.pdu.Notification.contentFormat := p_obj.contentFormat;
+      }
+      else
+      {
+        v_LwM2M_msgToSend.pdu.Notification.contentFormat := tsp_EPTF_LwM2M_LGen_defaultContentFormat;
+      }	  
+      f_LwM2M_step_send(pl_ptr);
+    }
+  }
+
+  function f_EPTF_LwM2M_sendNotificationForObjectInstance(in EPTF_LGenBase_TestStepArgs pl_ptr, in LwM2M_ObjectInstance p_objInst)
+  runs on EPTF_LwM2M_LGen_CT
+  {
+    f_EPTF_LwM2M_Logging_DEBUG(log2str(%definitionId));
+    f_EPTF_LwM2M_setStepCtx(pl_ptr, v_LwM2M_ctx);
+
+    if (p_objInst.observed)
+    {
+      v_LwM2M_msgToSend.pdu := c_LWM2M_Notification_init;
+      v_LwM2M_msgToSend.pdu.Notification.path := { p_objInst.objId, p_objInst.id };
+      v_LwM2M_msgToSend.pdu.Notification.code := 205;
+
+      for (var integer i:=0; i<sizeof(p_objInst.resources); i:=i+1) {
+        if (f_LwM2M_Resource_checkSpecification(
+          v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[p_objInst.resources[i]],
+          v_LwM2M_ObjectSpecificationDB, t_LwM2M_ResourceSpecification_Readable))
+        {	  
+          v_LwM2M_msgToSend.pdu.Notification.resources[sizeof(v_LwM2M_msgToSend.pdu.Notification.resources)] := 
+            v_LwM2M_DeviceDB.data[v_LwM2M_ctx.deviceIdx].objects.resources[p_objInst.resources[i]];
+        }
+      }
+
+      if (ispresent(p_objInst.contentFormat))
+      {
+        v_LwM2M_msgToSend.pdu.Notification.contentFormat := p_objInst.contentFormat;
+      }
+      else
+      {
+        v_LwM2M_msgToSend.pdu.Notification.contentFormat := tsp_EPTF_LwM2M_LGen_defaultContentFormat;
+      }	  
+      f_LwM2M_step_send(pl_ptr);
+    }
+  }
   
   ///////////////////////////////////////////////////////////
   //  Function: f_EPTF_LwM2M_PduToEventIdx
diff --git a/src/EPTF_LwM2M_Object_Definitions.ttcn b/src/EPTF_LwM2M_Object_Definitions.ttcn
index 2bf9600..3894591 100644
--- a/src/EPTF_LwM2M_Object_Definitions.ttcn
+++ b/src/EPTF_LwM2M_Object_Definitions.ttcn
@@ -65,9 +65,11 @@
        f_LwM2M_ObjectDB_createObject(inout LwM2M_ObjectDB p_db, in LwM2M_ObjectSpecification p_spec)
        f_LwM2M_ObjectDB_getObject(in LwM2M_ObjectDB p_db, in integer p_id, inout LwM2M_Object p_obj)
        f_LwM2M_ObjectDB_getObjectIdx(in LwM2M_ObjectDB p_db, in integer p_id)
+       f_LwM2M_ObjectDB_setObjectObserved(inout LwM2M_ObjectDB p_db, in integer p_objId, in boolean p_observed, in template integer p_contentFormat := omit)
        f_LwM2M_ObjectDB_createObjectInstance(inout LwM2M_ObjectDB p_db, in LwM2M_ObjectSpecificationDB p_spec_db, in integer p_id, in boolean p_createResources := true)
        f_LwM2M_ObjectDB_addResource(inout LwM2M_ObjectDB p_db, in LwM2M_Resource p_resource)
        f_LwM2M_ObjectDB_getObjectInstance(in LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, inout LwM2M_ObjectInstance p_objInst)
+       f_LwM2M_ObjectDB_setObjectInstanceObserved(inout LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in boolean p_observed, in template integer p_contentFormat := omit)
        f_LwM2M_ObjectDB_getResource(in LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, inout LwM2M_Resource p_resource)
        f_LwM2M_ObjectDB_setResource(inout LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, in LwM2M_Resource p_resource)
        f_LwM2M_ObjectDB_getResourceValue(in LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, inout LwM2M_ResourceValue p_value)
@@ -79,15 +81,18 @@
      LwM2M_ObjectDB "1" --> "*\n.resources[]" LwM2M_Resource
 
      class LwM2M_Object {
-       integer id,
-       LwM2M_ObjectInstance_List instances
+       integer id
+       boolean observed
+       integer contentFormat optional
      }
      LwM2M_Object "1" --> "*\n.instances[]" LwM2M_ObjectInstance
      LwM2M_Object "1" --> "1\n.id" LwM2M_ObjectSpecification
 
      class LwM2M_ObjectInstance {
-       integer id,
-       integer objId,
+       integer id
+       integer objId
+       boolean observed
+       integer contentFormat optional
        LwM2M_ResourceIdx_List resources
        f_LwM2M_createResource(inout LwM2M_ObjectInstance p_oi, in LwM2M_ResourceSpecification p_spec)
      }
@@ -163,14 +168,17 @@
        f_LwM2M_ObjectDB_createObject(inout LwM2M_ObjectDB p_db, in LwM2M_ObjectSpecification p_spec)
        f_LwM2M_ObjectDB_getObject(in LwM2M_ObjectDB p_db, in integer p_id, inout LwM2M_Object p_obj)
        f_LwM2M_ObjectDB_getObjectIdx(in LwM2M_ObjectDB p_db, in integer p_id)
+       f_LwM2M_ObjectDB_setObjectObserved(inout LwM2M_ObjectDB p_db, in integer p_objId, in boolean p_observed, in template integer p_contentFormat := omit)
        f_LwM2M_ObjectDB_createObjectInstance(inout LwM2M_ObjectDB p_db, in LwM2M_ObjectSpecificationDB p_spec_db, in integer p_id, in boolean p_createResources := true)
        f_LwM2M_ObjectDB_addResource(inout LwM2M_ObjectDB p_db, in LwM2M_Resource p_resource)
        f_LwM2M_ObjectDB_getObjectInstance(in LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, inout LwM2M_ObjectInstance p_objInst)
+       f_LwM2M_ObjectDB_setObjectInstanceObserved(inout LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in boolean p_observed, in template integer p_contentFormat := omit)
        f_LwM2M_ObjectDB_getResource(in LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, inout LwM2M_Resource p_resource)
        f_LwM2M_ObjectDB_setResource(inout LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, in LwM2M_Resource p_resource)
        f_LwM2M_ObjectDB_getResourceValue(in LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, inout LwM2M_ResourceValue p_value)
        f_LwM2M_ObjectDB_setResourceValue(inout LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, in LwM2M_ResourceValue p_value)
        f_LwM2M_ObjectDB_setResourceObserved(inout LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in integer p_resourceId, in boolean p_observed)
+       f_LwM2M_ObjectDB_getObjectPaths(in LwM2M_ObjectDB p_db, inout ObjectPath_List p_paths)p_objInstId, in integer p_resourceId, in boolean p_observed)
        f_LwM2M_ObjectDB_getObjectPaths(in LwM2M_ObjectDB p_db, inout ObjectPath_List p_paths)
      }
    @enduml
@@ -197,9 +205,11 @@
   //    - <f_LwM2M_ObjectDB_createObject> (*inout* <LwM2M_ObjectDB> p_db, *in* <LwM2M_ObjectSpecification> p_spec)
   //    - <f_LwM2M_ObjectDB_getObject> (*in* <LwM2M_ObjectDB> p_db, *in integer* p_id, *inout* <LwM2M_Object> p_obj)
   //    - <f_LwM2M_ObjectDB_getObjectIdx> (*in* <LwM2M_ObjectDB> p_db, *in integer* p_id)
+  //    - <f_LwM2M_ObjectDB_setObjectObserved> (*inout* <LwM2M_ObjectDB> p_db, *in integer* p_objId, *in boolean* p_observed, *in template integer* p_contentFormat := omit)
   //    - <f_LwM2M_ObjectDB_createObjectInstance> (*inout* <LwM2M_ObjectDB> p_db, *in* <LwM2M_ObjectSpecificationDB> p_spec_db, *in integer* p_id, *in boolean* p_createResources := true)
   //    - <f_LwM2M_ObjectDB_addResource> (*inout* <LwM2M_ObjectDB> p_db, *in* <LwM2M_Resource> p_resource)
   //    - <f_LwM2M_ObjectDB_getObjectInstance> (*in* <LwM2M_ObjectDB> p_db, *in integer* p_objId, *in integer* p_objInstId, *inout* <LwM2M_ObjectInstance> p_objInst)
+  //    - <f_LwM2M_ObjectDB_setObjectInstanceObserved> (*inout* <LwM2M_ObjectDB> p_db, *in integer* p_objId, *in integer* p_objInstId, *in boolean* p_observed, *in template integer* p_contentFormat := omit)
   //    - <f_LwM2M_ObjectDB_getResource> (*in* <LwM2M_ObjectDB> p_db, *in integer* p_objId, *in integer* p_objInstId, *in integer* p_resourceId, *inout* <LwM2M_Resource> p_resource)
   //    - <f_LwM2M_ObjectDB_setResource> (*inout* <LwM2M_ObjectDB> p_db, *in integer* p_objId, *in integer* p_objInstId, *in integer* p_resourceId, *in* <LwM2M_Resource> p_resource)
   //    - <f_LwM2M_ObjectDB_getResourceValue> (*in* <LwM2M_ObjectDB> p_db, *in integer* p_objId, *in integer* p_objInstId, *in integer* p_resourceId, *inout* <LwM2M_ResourceValue> p_value)
@@ -236,7 +246,9 @@
  /*****************************************************************
    @startuml EPTF_LwM2M_Object_Definitions.LwM2M_Object.jpg
      class LwM2M_Object {
-       integer id,
+       integer id
+       boolean observed
+       integer contentFormat optional
        LwM2M_ObjectInstance_List instances
      }
    @enduml
@@ -252,25 +264,33 @@
   //
   //  Elements:
   //    id  - *integer* - smart object id
+  //    observed - *boolean* - true in case the object is observed, false otherwise
+  //    contentFormat - *integer* *optional* - content format code of the observation(s)
   //    instances  - <LwM2M_ObjectInstance_List> - objec instances of the smart object
   ///////////////////////////////////////////////////////////
   type record LwM2M_Object
   {
     integer id,
+    boolean observed,
+    integer contentFormat optional,
     LwM2M_ObjectInstance_List instances
   }
 	
   const LwM2M_Object c_LwM2M_Object_init :=
   {
     id := -1,
+    observed := false,
+    contentFormat := omit,
     instances := {}
   }
 
  /*****************************************************************
    @startuml EPTF_LwM2M_Object_Definitions.LwM2M_ObjectInstance.jpg
      class LwM2M_ObjectInstance {
-       integer id,
-       integer objId,
+       integer id
+       integer objId
+       boolean observed
+       integer contentFormat optional
        LwM2M_ResourceIdx_List resources
        f_LwM2M_createResource(inout LwM2M_ObjectInstance p_oi, in LwM2M_ResourceSpecification p_spec)
      }
@@ -288,6 +308,8 @@
   //  Elements:
   //    id - *integer* - instance id of the <LwM2M_Object>
   //    objId  - *integer* - object id of the parent <LwM2M_Object>
+  //    observed - *boolean* - true in case the object is observed, false otherwise
+  //    contentFormat - *integer* *optional* - content format code of the observation(s)
   //    resources - <LwM2M_ResourceIdx_List> - pointers to the resources of the object instance's own resources (stored in the parent <LwM2M_Object>.resources)
   //
   //  Related Functions:
@@ -297,6 +319,8 @@
   {
     integer id,
     integer objId,
+    boolean observed,
+    integer contentFormat optional,
     LwM2M_ResourceIdx_List resources
   }
 
@@ -312,6 +336,8 @@
   {
     id := -1,
     objId := -1,
+    observed := false,
+    contentFormat := omit,
     resources := {}
   }
 	
diff --git a/src/EPTF_LwM2M_Object_Functions.ttcn b/src/EPTF_LwM2M_Object_Functions.ttcn
index 1f1ff8d..32a06a3 100644
--- a/src/EPTF_LwM2M_Object_Functions.ttcn
+++ b/src/EPTF_LwM2M_Object_Functions.ttcn
@@ -318,6 +318,44 @@
   }
   
   ///////////////////////////////////////////////////////////
+  //  Function: f_LwM2M_ObjectDB_setObjectObserved
+  //
+  //  Purpose:
+  //    Sets the observation flag of an already linked in <LwM2M_Object> in a <LwM2M_ObjectDB> database
+  //
+  //  Parameters:
+  //    p_db - *in* <LwM2M_ObjectDB> - DB instance
+  //    p_objId - *in integer* - object id
+  //    p_observed - *in boolean* - observation flag
+  //    p_contentFormat - *in integer optional* - preferred content format
+  //
+  //  Returns:
+  //    boolean - if the instance was found
+  //
+  //  Related Type:
+  //    <LwM2M_ObjectDB>
+  ///////////////////////////////////////////////////////////
+  function f_LwM2M_ObjectDB_setObjectObserved(inout LwM2M_ObjectDB p_db, in integer p_objId, in boolean p_observed, in template integer p_contentFormat := omit)
+  return boolean
+  {
+    var integer vl_idx := f_LwM2M_ObjectDB_getObjectIdx(p_db, p_objId);
+    if (vl_idx >= 0)
+    {
+      p_db.objs[vl_idx].observed := p_observed;
+      if (ispresent(p_contentFormat))
+      {
+        p_db.objs[vl_idx].contentFormat := valueof(p_contentFormat);
+      }
+      else
+      {
+        p_db.objs[vl_idx].contentFormat := omit;
+      }
+      return true;
+    }
+    return false;
+  }
+  
+  ///////////////////////////////////////////////////////////
   //  Function: f_LwM2M_ObjectDB_createObjectInstance
   //
   //  Purpose:
@@ -442,6 +480,46 @@
   }
   
   ///////////////////////////////////////////////////////////
+  //  Function: f_LwM2M_ObjectDB_setObjectInstanceObserved
+  //
+  //  Purpose:
+  //    Sets the observation flag of an already linked in <LwM2M_ObjectInstance> in a <LwM2M_ObjectDB> database
+  //
+  //  Parameters:
+  //    p_db - *in* <LwM2M_ObjectDB> - DB instance
+  //    p_objId - *in integer* - object id
+  //    p_objInstId - *in integer* - object instance id
+  //    p_observed - *in boolean* - observation flag
+  //    p_contentFormat - *in integer optional* - preferred content format
+  //
+  //  Returns:
+  //    boolean - if the instance was found
+  //
+  //  Related Type:
+  //    <LwM2M_ObjectDB>
+  ///////////////////////////////////////////////////////////
+  function f_LwM2M_ObjectDB_setObjectInstanceObserved(inout LwM2M_ObjectDB p_db, in integer p_objId, in integer p_objInstId, in boolean p_observed, in template integer p_contentFormat := omit)
+  return boolean
+  {
+    var integer vl_objIdx := f_LwM2M_ObjectDB_getObjectIdx(p_db, p_objId);
+    if (vl_objIdx >= 0) {
+      if (sizeof(p_db.objs[vl_objIdx].instances) > p_objInstId and p_objInstId >= 0) {
+        p_db.objs[vl_objIdx].instances[p_objInstId].observed := p_observed;
+        if (ispresent(p_contentFormat))
+        {
+          p_db.objs[vl_objIdx].instances[p_objInstId].contentFormat := valueof(p_contentFormat);
+        }
+        else
+        {
+          p_db.objs[vl_objIdx].instances[p_objInstId].contentFormat := omit;
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+  
+  ///////////////////////////////////////////////////////////
   //  Function: f_LwM2M_ObjectDB_getResource
   //
   //  Purpose:
@@ -609,7 +687,7 @@
     }
     return false;
   }
-  
+
   ///////////////////////////////////////////////////////////
   //  Function: f_LwM2M_ObjectDB_getObjectPaths
   //
diff --git a/test/EPTF_LwM2M_Tests.cfg b/test/EPTF_LwM2M_Tests.cfg
index 2b3c889..610f4d1 100644
--- a/test/EPTF_LwM2M_Tests.cfg
+++ b/test/EPTF_LwM2M_Tests.cfg
@@ -112,6 +112,12 @@
 EPTF_LwM2M_Tests.tc_observe_subscription
 EPTF_LwM2M_Tests.tc_observe_notification
 EPTF_LwM2M_Tests.tc_observe_unsubscribe
+EPTF_LwM2M_Tests.tc_observe_object_subscription
+EPTF_LwM2M_Tests.tc_observe_object_notification
+EPTF_LwM2M_Tests.tc_observe_object_unsubscribe
+EPTF_LwM2M_Tests.tc_observe_object_instance_subscription
+EPTF_LwM2M_Tests.tc_observe_object_instance_notification
+EPTF_LwM2M_Tests.tc_observe_object_instance_unsubscribe
 
 /*
 /////////////////////
diff --git a/test/EPTF_LwM2M_Tests.ttcn b/test/EPTF_LwM2M_Tests.ttcn
index 037aef0..d1a276a 100644
--- a/test/EPTF_LwM2M_Tests.ttcn
+++ b/test/EPTF_LwM2M_Tests.ttcn
@@ -506,6 +506,46 @@
     },
     payload := omit
   }
+  
+  template CoAP_ReqResp t_COAP_observe_object :=
+  {
+    header := 
+    {
+      version := 1,
+      msg_type := CONFIRMABLE,
+      code := METHOD_GET,
+      message_id := 0
+    },
+    token := ''O,
+    options :=  
+    {      
+      { observe := 0 },
+      { uri_path := "3303" },
+      { accept := 11542 }
+    },
+    payload := omit
+  }
+  
+  template CoAP_ReqResp t_COAP_observe_object_instance :=
+  {
+    header := 
+    {
+      version := 1,
+      msg_type := CONFIRMABLE,
+      code := METHOD_GET,
+      message_id := 0
+    },
+    token := ''O,
+    options :=  
+    {      
+      { observe := 0 },
+      { uri_path := "3303" },
+      { uri_path := "0" },
+      { uri_path := "5700" },
+      { accept := 11542 }
+    },
+    payload := omit
+  }
 
   template CoAP_ReqResp t_CON_PUT_Block1_FwUg_num0 :=
   { 
@@ -2039,6 +2079,102 @@
     f_LWM2M_Tests_end();
   }
 
+  function f_tc_observe_subscription(in template CoAP_ReqResp p_obs_req) runs on LWM2M_FSM_CT
+  {
+    f_LWM2M_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    f_initialization();
+    f_registration(peer);
+
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(p_obs_req), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_Read, t_addr(0, ?), 3.0));
+
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_LwM2M_stepName_handleReadRequest, valueof(t_addr(0, 0)), {}, false);
+
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
+
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_LWM2M_Tests_end();
+  }
+
+  function f_tc_observe_notification(in template CoAP_ReqResp p_obs_req) runs on LWM2M_FSM_CT
+  {
+    f_LWM2M_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    f_initialization();
+    f_registration(peer);
+
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(p_obs_req), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_Read, t_addr(0, ?), 3.0));
+
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_LwM2M_stepName_handleReadRequest, valueof(t_addr(0, 0)), {}, false);
+
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
+
+    f_MBT_execute(c_LwM2M_stepName_sendNotificationForObservedResources, valueof(t_addr(0, 0)), {}, false);
+
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
+
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_LWM2M_Tests_end();
+  }
+
+  function f_tc_observe_unsubscribe(in template CoAP_ReqResp p_obs_req) runs on LWM2M_FSM_CT
+  {
+    f_LWM2M_Tests_begin();
+
+    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
+    f_IFW_CoapPeer_setRemote(peer, "sut");
+    f_IFW_initComponents();
+
+    f_initialization();
+    f_registration(peer);
+
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(p_obs_req), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_Read, t_addr(0, ?), 3.0));
+
+    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
+    f_MBT_execute(c_LwM2M_stepName_handleReadRequest, valueof(t_addr(0, 0)), {}, false);
+
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
+
+    f_MBT_execute(c_LwM2M_stepName_sendNotificationForObservedResources, valueof(t_addr(0, 0)), {}, false);
+
+    f_IFW_CoapPeer_receive(peer);
+    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
+
+    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_RST_Empty), USE_LAST_RECEIVED_MID, USE_GIVEN_TOKEN);
+    f_IFW_CoapPeer_send(peer);
+
+    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_resourceNotObservedIndication, t_addr(0, ?), 3.0));
+
+    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
+
+    f_LWM2M_Tests_end();
+  }
+
   ///////////////////////////////////////////////////////////
   //
   // Testcase: tc_observe_subscription
@@ -2063,29 +2199,7 @@
   ******************************************************************/
   testcase tc_observe_subscription() runs on LWM2M_FSM_CT
   {
-    f_LWM2M_Tests_begin();
-
-    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
-    f_IFW_CoapPeer_setRemote(peer, "sut");
-    f_IFW_initComponents();
-
-    f_initialization();
-    f_registration(peer);
-
-    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_COAP_observe), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
-    f_IFW_CoapPeer_send(peer);
-
-    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_Read, t_addr(0, ?), 3.0));
-
-    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
-    f_MBT_execute(c_LwM2M_stepName_handleReadRequest, valueof(t_addr(0, 0)), {}, false);
-
-    f_IFW_CoapPeer_receive(peer);
-    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
-
-    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
-
-    f_LWM2M_Tests_end();
+    f_tc_observe_subscription(t_COAP_observe);
   }
 
   ///////////////////////////////////////////////////////////
@@ -2114,34 +2228,7 @@
   ******************************************************************/
   testcase tc_observe_notification() runs on LWM2M_FSM_CT
   {
-    f_LWM2M_Tests_begin();
-
-    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
-    f_IFW_CoapPeer_setRemote(peer, "sut");
-    f_IFW_initComponents();
-
-    f_initialization();
-    f_registration(peer);
-
-    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_COAP_observe), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
-    f_IFW_CoapPeer_send(peer);
-
-    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_Read, t_addr(0, ?), 3.0));
-
-    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
-    f_MBT_execute(c_LwM2M_stepName_handleReadRequest, valueof(t_addr(0, 0)), {}, false);
-
-    f_IFW_CoapPeer_receive(peer);
-    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
-
-    f_MBT_execute(c_LwM2M_stepName_sendNotificationForObservedResources, valueof(t_addr(0, 0)), {}, false);
-
-    f_IFW_CoapPeer_receive(peer);
-    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
-
-    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
-
-    f_LWM2M_Tests_end();
+    f_tc_observe_notification(t_COAP_observe);
   }
 
   ///////////////////////////////////////////////////////////
@@ -2165,44 +2252,186 @@
   *     Peer <- Applib: COAP Content with Observe
   *     FSM -> Applib: c_LwM2M_stepName_sendNotificationForObservedResources
   *     Peer <- Applib: COAP Content with Observe
+  *     Peer -> Applib: COAP RST
+  *     FSM <- Applib: resourceNotObservedIndication
   *     FSM -> Applib: c_COAP_stepName_cleanUp()
   *     @enduml
   ******************************************************************/
   testcase tc_observe_unsubscribe() runs on LWM2M_FSM_CT
   {
-    f_LWM2M_Tests_begin();
+    f_tc_observe_unsubscribe(t_COAP_observe);
+  }
 
-    var integer peer := f_IFW_addComponent(COAP_PEER, "tester");
-    f_IFW_CoapPeer_setRemote(peer, "sut");
-    f_IFW_initComponents();
+  ///////////////////////////////////////////////////////////
+  //
+  // Testcase: tc_observe_object_subscription
+  //
+  // Purpose:
+  //     Testcase for subscribing to an object value
+  //
+  // Action:
+  //     (see EPTF_LwM2M_Tests.tc_observe_object_subscription.jpg)
+  ///////////////////////////////////////////////////////////
+  /*****************************************************************
+  *     @startuml EPTF_LwM2M_Tests.tc_observe_object_subscription.jpg
+  *     ref over Applib, Peer: tc_initialization
+  *     ref over Applib, Peer: tc_registration
+  *     Peer -> Applib: COAP GET 3303 Observe:0
+  *     FSM <- Applib: c_LwM2M_eventName_Read
+  *     FSM -> Applib: c_COAP_stepName_handleRequest
+  *     FSM -> Applib: c_LwM2M_stepName_handleReadRequest
+  *     Peer <- Applib: COAP Content
+  *     FSM -> Applib: c_COAP_stepName_cleanUp()
+  *     @enduml
+  ******************************************************************/
+  testcase tc_observe_object_subscription() runs on LWM2M_FSM_CT
+  {
+    f_tc_observe_subscription(t_COAP_observe_object);
+  }
 
-    f_initialization();
-    f_registration(peer);
+  ///////////////////////////////////////////////////////////
+  //
+  // Testcase: tc_observe_object_notification
+  //
+  // Purpose:
+  //     Testcase for sending notification for an observed object
+  //
+  // Action:
+  //     (see EPTF_LwM2M_Tests.tc_observe_object_notification.jpg)
+  ///////////////////////////////////////////////////////////
+  /*****************************************************************
+  *     @startuml EPTF_LwM2M_Tests.tc_observe_object_notification.jpg
+  *     ref over Applib, Peer: tc_initialization
+  *     ref over Applib, Peer: tc_registration
+  *     Peer -> Applib: COAP GET 3303 Observe:0
+  *     FSM <- Applib: c_LwM2M_eventName_Read
+  *     FSM -> Applib: c_COAP_stepName_handleRequest
+  *     FSM -> Applib: c_LwM2M_stepName_handleReadRequest
+  *     Peer <- Applib: COAP Content with Observe
+  *     FSM -> Applib: c_LwM2M_stepName_sendNotificationForObservedResources
+  *     Peer <- Applib: COAP Content with Observe
+  *     FSM -> Applib: c_COAP_stepName_cleanUp()
+  *     @enduml
+  ******************************************************************/
+  testcase tc_observe_object_notification() runs on LWM2M_FSM_CT
+  {
+    f_tc_observe_notification(t_COAP_observe_object);
+  }
 
-    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_COAP_observe), GENERATE_NEW_MID, GENERATE_NEW_TOKEN);
-    f_IFW_CoapPeer_send(peer);
+  ///////////////////////////////////////////////////////////
+  //
+  // Testcase: tc_observe_object_unsubscribe
+  //
+  // Purpose:
+  //     Testcase for unsubscribing from a resource value
+  //
+  // Action:
+  //     (see EPTF_LwM2M_Tests.tc_observe_object_unsubscribe.jpg)
+  ///////////////////////////////////////////////////////////
+  /*****************************************************************
+  *     @startuml EPTF_LwM2M_Tests.tc_observe_object_unsubscribe.jpg
+  *     ref over Applib, Peer: tc_initialization
+  *     ref over Applib, Peer: tc_registration
+  *     Peer -> Applib: COAP GET 3303 Observe:0
+  *     FSM <- Applib: c_LwM2M_eventName_Read
+  *     FSM -> Applib: c_COAP_stepName_handleRequest
+  *     FSM -> Applib: c_LwM2M_stepName_handleReadRequest
+  *     Peer <- Applib: COAP Content with Observe
+  *     FSM -> Applib: c_LwM2M_stepName_sendNotificationForObservedResources
+  *     Peer <- Applib: COAP Content with Observe
+  *     Peer -> Applib: COAP RST
+  *     FSM <- Applib: resourceNotObservedIndication
+  *     @enduml
+  ******************************************************************/
+  testcase tc_observe_object_unsubscribe() runs on LWM2M_FSM_CT
+  {
+    f_tc_observe_unsubscribe(t_COAP_observe_object);
+  }
 
-    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_Read, t_addr(0, ?), 3.0));
+  ///////////////////////////////////////////////////////////
+  //
+  // Testcase: tc_observe_object_instance_subscription
+  //
+  // Purpose:
+  //     Testcase for subscribing to an object instance value
+  //
+  // Action:
+  //     (see EPTF_LwM2M_Tests.tc_observe_object_instance_subscription.jpg)
+  ///////////////////////////////////////////////////////////
+  /*****************************************************************
+  *     @startuml EPTF_LwM2M_Tests.tc_observe_object_instance_subscription.jpg
+  *     ref over Applib, Peer: tc_initialization
+  *     ref over Applib, Peer: tc_registration
+  *     Peer -> Applib: COAP GET 3303/0 Observe:0
+  *     FSM <- Applib: c_LwM2M_eventName_Read
+  *     FSM -> Applib: c_COAP_stepName_handleRequest
+  *     FSM -> Applib: c_LwM2M_stepName_handleReadRequest
+  *     Peer <- Applib: COAP Content
+  *     FSM -> Applib: c_COAP_stepName_cleanUp()
+  *     @enduml
+  ******************************************************************/
+  testcase tc_observe_object_instance_subscription() runs on LWM2M_FSM_CT
+  {
+    f_tc_observe_subscription(t_COAP_observe_object_instance);
+  }
 
-    f_MBT_execute(c_COAP_stepName_handleRequest, valueof(t_addr(0, 0)), {}, false);
-    f_MBT_execute(c_LwM2M_stepName_handleReadRequest, valueof(t_addr(0, 0)), {}, false);
+  ///////////////////////////////////////////////////////////
+  //
+  // Testcase: tc_observe_object_instance_notification
+  //
+  // Purpose:
+  //     Testcase for sending notification for an observed object instance
+  //
+  // Action:
+  //     (see EPTF_LwM2M_Tests.tc_observe_object_instance_notification.jpg)
+  ///////////////////////////////////////////////////////////
+  /*****************************************************************
+  *     @startuml EPTF_LwM2M_Tests.tc_observe_object_instance_notification.jpg
+  *     ref over Applib, Peer: tc_initialization
+  *     ref over Applib, Peer: tc_registration
+  *     Peer -> Applib: COAP GET 3303/0 Observe:0
+  *     FSM <- Applib: c_LwM2M_eventName_Read
+  *     FSM -> Applib: c_COAP_stepName_handleRequest
+  *     FSM -> Applib: c_LwM2M_stepName_handleReadRequest
+  *     Peer <- Applib: COAP Content with Observe
+  *     FSM -> Applib: c_LwM2M_stepName_sendNotificationForObservedResources
+  *     Peer <- Applib: COAP Content with Observe
+  *     FSM -> Applib: c_COAP_stepName_cleanUp()
+  *     @enduml
+  ******************************************************************/
+  testcase tc_observe_object_instance_notification() runs on LWM2M_FSM_CT
+  {
+    f_tc_observe_notification(t_COAP_observe_object_instance);
+  }
 
-    f_IFW_CoapPeer_receive(peer);
-    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
-
-    f_MBT_execute(c_LwM2M_stepName_sendNotificationForObservedResources, valueof(t_addr(0, 0)), {}, false);
-
-    f_IFW_CoapPeer_receive(peer);
-    f_handleVerdict(f_IFW_CoapPeer_check(peer, tr_COAP(RESPONSE_CODE_Content)));
-
-    f_IFW_CoapPeer_setMessageToSend(peer, valueof(t_RST_Empty), USE_LAST_RECEIVED_MID, USE_GIVEN_TOKEN);
-    f_IFW_CoapPeer_send(peer);
-
-    f_handleVerdict(f_MBT_waitFor(c_LwM2M_behaviorType, c_LwM2M_eventName_resourceNotObservedIndication, t_addr(0, ?), 3.0));
-
-    f_MBT_execute(c_COAP_stepName_cleanUp, valueof(t_addr(0, 0)), {}, false);
-
-    f_LWM2M_Tests_end();
+  ///////////////////////////////////////////////////////////
+  //
+  // Testcase: tc_observe_object_instance_unsubscribe
+  //
+  // Purpose:
+  //     Testcase for unsubscribing from an object instance value
+  //
+  // Action:
+  //     (see EPTF_LwM2M_Tests.tc_observe_object_instance_unsubscribe.jpg)
+  ///////////////////////////////////////////////////////////
+  /*****************************************************************
+  *     @startuml EPTF_LwM2M_Tests.tc_observe_object_instance_unsubscribe.jpg
+  *     ref over Applib, Peer: tc_initialization
+  *     ref over Applib, Peer: tc_registration
+  *     Peer -> Applib: COAP GET 3303/0 Observe:0
+  *     FSM <- Applib: c_LwM2M_eventName_Read
+  *     FSM -> Applib: c_COAP_stepName_handleRequest
+  *     FSM -> Applib: c_LwM2M_stepName_handleReadRequest
+  *     Peer <- Applib: COAP Content with Observe
+  *     FSM -> Applib: c_LwM2M_stepName_sendNotificationForObservedResources
+  *     Peer <- Applib: COAP Content with Observe
+  *     Peer -> Applib: COAP RST
+  *     FSM <- Applib: resourceNotObservedIndication
+  *     @enduml
+  ******************************************************************/
+  testcase tc_observe_object_instance_unsubscribe() runs on LWM2M_FSM_CT
+  {
+    f_tc_observe_unsubscribe(t_COAP_observe_object_instance);
   }
 
   ///////////////////////////////////////////////////////////