diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java
index eb3a184b1ab3f8..27408a4934f637 100644
--- a/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java
+++ b/examples/tv-casting-app/android/App/app/src/main/jni/com/chip/casting/TvCastingApp.java
@@ -17,6 +17,8 @@
  */
 package com.chip.casting;
 
+import java.util.ArrayList;
+
 public class TvCastingApp {
   private static final String TAG = TvCastingApp.class.getSimpleName();
 
@@ -178,7 +180,7 @@ public native boolean targetNavigator_subscribeToCurrentTarget(
       SubscriptionEstablishedCallback subscriptionEstablishedHandler);
 
   public native boolean targetNavigator_subscribeToTargetList(
-      SuccessCallback<TargetNavigatorTypes.TargetInfo> readSuccessHandler,
+      SuccessCallback<ArrayList<TargetNavigatorTypes.TargetInfo>> readSuccessHandler,
       FailureCallback readFailureHandler,
       int minInterval,
       int maxInterval,
diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp
index ef682b67da3d78..f9bbe7a649f531 100644
--- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp
+++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/MatterCallbackHandler-JNI.cpp
@@ -307,7 +307,8 @@ jobject TargetListSuccessHandlerJNI::ConvertToJObject(
         }
 
         jmethodID constructor = env->GetMethodID(responseTypeClass, "<init>", "(Ljava/lang/Integer;java/lang/String;)V");
-        jobject jTargetInfo   = env->NewObject(responseTypeClass, constructor, targetInfo.identifier, targetInfo.name);
+        chip::UtfString targetInfoName(env, targetInfo.name);
+        jobject jTargetInfo = env->NewObject(responseTypeClass, constructor, targetInfo.identifier, targetInfoName.jniValue());
 
         chip::JniReferences::GetInstance().AddToList(jArrayList, jTargetInfo);
     }
diff --git a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp
index 4edb41683f1962..cec6ec3c2962bc 100644
--- a/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp
+++ b/examples/tv-casting-app/android/App/app/src/main/jni/cpp/TvCastingApp-JNI.cpp
@@ -30,6 +30,7 @@
 #include <lib/core/CHIPError.h>
 #include <lib/core/Optional.h>
 #include <lib/support/CHIPJNIError.h>
+#include <lib/support/CHIPListUtils.h>
 #include <lib/support/JniReferences.h>
 #include <lib/support/JniTypeWrappers.h>
 
@@ -173,7 +174,7 @@ CHIP_ERROR CreateParameter(JNIEnv * env, jobject jParameter,
 }
 
 CHIP_ERROR CreateContentSearch(JNIEnv * env, jobject jSearch,
-                               chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type & search)
+                               chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type & search, ListFreer & listFreer)
 {
     jclass jContentSearchClass;
     ReturnErrorOnFailure(
@@ -192,18 +193,21 @@ CHIP_ERROR CreateContentSearch(JNIEnv * env, jobject jSearch,
     jmethodID jNextMid    = env->GetMethodID(env->GetObjectClass(jIterator), "next", "()Ljava/lang/Object;");
     jmethodID jHasNextMid = env->GetMethodID(env->GetObjectClass(jIterator), "hasNext", "()Z");
 
-    chip::app::Clusters::ContentLauncher::Structs::Parameter::Type * parameterList =
-        new chip::app::Clusters::ContentLauncher::Structs::Parameter::Type[parameterListSize];
+    auto * parameterListHolder = new ListHolder<chip::app::Clusters::ContentLauncher::Structs::Parameter::Type>(parameterListSize);
+    listFreer.add(parameterListHolder);
     int parameterIndex = 0;
     while (env->CallBooleanMethod(jIterator, jHasNextMid))
     {
         jobject jParameter = env->CallObjectMethod(jIterator, jNextMid);
         chip::app::Clusters::ContentLauncher::Structs::Parameter::Type parameter;
         ReturnErrorOnFailure(CreateParameter(env, jParameter, parameter));
-        parameterList[parameterIndex++] = parameter;
+        parameterListHolder->mList[parameterIndex].type           = parameter.type;
+        parameterListHolder->mList[parameterIndex].value          = parameter.value;
+        parameterListHolder->mList[parameterIndex].externalIDList = parameter.externalIDList;
+        parameterIndex++;
     }
     search.parameterList = chip::app::DataModel::List<chip::app::Clusters::ContentLauncher::Structs::Parameter::Type>(
-        parameterList, parameterListSize);
+        parameterListHolder->mList, parameterListSize);
 
     return CHIP_NO_ERROR;
 }
@@ -221,8 +225,9 @@ JNI_METHOD(jboolean, contentLauncher_1launchContent)
     const char * nativeData             = env->GetStringUTFChars(jData, 0);
     chip::Optional<chip::CharSpan> data = MakeOptional(CharSpan::fromCharString(nativeData));
 
+    ListFreer listFreer;
     chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type search;
-    CHIP_ERROR err = CreateContentSearch(env, jSearch, search);
+    CHIP_ERROR err = CreateContentSearch(env, jSearch, search, listFreer);
     VerifyOrExit(CHIP_NO_ERROR == err,
                  ChipLogError(AppServer,
                               "contentLauncher_1launchContent::Could not create ContentSearch object %" CHIP_ERROR_FORMAT,
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj
index 890346e0616d88..0a4ab42cb3c900 100644
--- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj
@@ -8,6 +8,9 @@
 
 /* Begin PBXBuildFile section */
 		3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */; };
+		3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */; };
+		3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */; };
+		3C4E53B628E5595A00F293E8 /* ContentLauncherTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */; };
 		3CCB87212869085400771BAD /* MatterTvCastingBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB87202869085400771BAD /* MatterTvCastingBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		3CCB8737286A555500771BAD /* libTvCastingCommon.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CCB8735286A555500771BAD /* libTvCastingCommon.a */; };
 		3CCB8738286A555500771BAD /* libmbedtls.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CCB8736286A555500771BAD /* libmbedtls.a */; settings = {ATTRIBUTES = (Required, ); }; };
@@ -17,11 +20,18 @@
 		3CCB8742286A593700771BAD /* DiscoveredNodeDataConverter.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */; };
 		3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873D286A593700771BAD /* CastingServerBridge.mm */; };
 		3CCB8744286A593700771BAD /* DiscoveredNodeDataConverter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CCB873E286A593700771BAD /* DiscoveredNodeDataConverter.mm */; };
+		3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3CF8532628E37F1000F07B9F /* MatterError.mm */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
 		3C4AE64E286A7D40005B52A4 /* OnboardingPayload.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OnboardingPayload.h; sourceTree = "<group>"; };
 		3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnboardingPayload.m; sourceTree = "<group>"; };
+		3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MediaPlaybackTypes.mm; sourceTree = "<group>"; };
+		3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TargetNavigatorTypes.mm; sourceTree = "<group>"; };
+		3C4E53B328E5185F00F293E8 /* TargetNavigatorTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TargetNavigatorTypes.h; sourceTree = "<group>"; };
+		3C4E53B428E5593700F293E8 /* ContentLauncherTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ContentLauncherTypes.h; sourceTree = "<group>"; };
+		3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = ContentLauncherTypes.mm; sourceTree = "<group>"; };
+		3CA1CA7728E243750023ED44 /* MediaPlaybackTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTypes.h; sourceTree = "<group>"; };
 		3CCB871D2869085400771BAD /* MatterTvCastingBridge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MatterTvCastingBridge.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		3CCB87202869085400771BAD /* MatterTvCastingBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MatterTvCastingBridge.h; sourceTree = "<group>"; };
 		3CCB8735286A555500771BAD /* libTvCastingCommon.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libTvCastingCommon.a; path = lib/libTvCastingCommon.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -32,6 +42,8 @@
 		3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DiscoveredNodeDataConverter.hpp; sourceTree = "<group>"; };
 		3CCB873D286A593700771BAD /* CastingServerBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CastingServerBridge.mm; sourceTree = "<group>"; };
 		3CCB873E286A593700771BAD /* DiscoveredNodeDataConverter.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DiscoveredNodeDataConverter.mm; sourceTree = "<group>"; };
+		3CF8532528E37ED800F07B9F /* MatterError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MatterError.h; sourceTree = "<group>"; };
+		3CF8532628E37F1000F07B9F /* MatterError.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MatterError.mm; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -77,6 +89,14 @@
 				3CCB873C286A593700771BAD /* DiscoveredNodeDataConverter.hpp */,
 				3C4AE64E286A7D40005B52A4 /* OnboardingPayload.h */,
 				3C4AE64F286A7D4D005B52A4 /* OnboardingPayload.m */,
+				3CF8532528E37ED800F07B9F /* MatterError.h */,
+				3CF8532628E37F1000F07B9F /* MatterError.mm */,
+				3C4E53B428E5593700F293E8 /* ContentLauncherTypes.h */,
+				3C4E53B528E5595A00F293E8 /* ContentLauncherTypes.mm */,
+				3CA1CA7728E243750023ED44 /* MediaPlaybackTypes.h */,
+				3C4E53AF28E4F28100F293E8 /* MediaPlaybackTypes.mm */,
+				3C4E53B328E5185F00F293E8 /* TargetNavigatorTypes.h */,
+				3C4E53B128E5184C00F293E8 /* TargetNavigatorTypes.mm */,
 			);
 			path = MatterTvCastingBridge;
 			sourceTree = "<group>";
@@ -185,7 +205,11 @@
 			buildActionMask = 2147483647;
 			files = (
 				3CCB8743286A593700771BAD /* CastingServerBridge.mm in Sources */,
+				3C4E53B228E5184C00F293E8 /* TargetNavigatorTypes.mm in Sources */,
+				3CF8532728E37F1000F07B9F /* MatterError.mm in Sources */,
+				3C4E53B628E5595A00F293E8 /* ContentLauncherTypes.mm in Sources */,
 				3CCB8744286A593700771BAD /* DiscoveredNodeDataConverter.mm in Sources */,
+				3C4E53B028E4F28100F293E8 /* MediaPlaybackTypes.mm in Sources */,
 				3CCB873F286A593700771BAD /* DiscoveredNodeData.mm in Sources */,
 				3C4AE650286A7D4D005B52A4 /* OnboardingPayload.m in Sources */,
 			);
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h
index 0bde8e593b2dfb..6d43a0d280c659 100644
--- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.h
@@ -15,8 +15,12 @@
  *    limitations under the License.
  */
 
+#import "ContentLauncherTypes.h"
 #import "DiscoveredNodeData.h"
+#import "MatterError.h"
+#import "MediaPlaybackTypes.h"
 #import "OnboardingPayload.h"
+#import "TargetNavigatorTypes.h"
 #import <Foundation/Foundation.h>
 
 #ifndef CastingServerBridge_h
@@ -24,26 +28,6 @@
 
 @interface CastingServerBridge : NSObject
 
-@property void (^_Nonnull commissioningCompleteCallback)(bool);
-
-@property void (^_Nonnull contentLauncher_launchUrlResponseCallback)(bool);
-@property void (^_Nonnull levelControl_stepResponseCallback)(bool);
-@property void (^_Nonnull levelControl_moveToLevelResponseCallback)(bool);
-@property void (^_Nonnull mediaPlayback_playResponseCallback)(bool);
-@property void (^_Nonnull mediaPlayback_pauseResponseCallback)(bool);
-@property void (^_Nonnull mediaPlayback_stopPlaybackResponseCallback)(bool);
-@property void (^_Nonnull mediaPlayback_nextResponseCallback)(bool);
-@property void (^_Nonnull mediaPlayback_seekResponseCallback)(bool);
-@property void (^_Nonnull mediaPlayback_skipForwardResponseCallback)(bool);
-@property void (^_Nonnull mediaPlayback_skipBackwardResponseCallback)(bool);
-@property void (^_Nonnull applicationLauncher_launchAppResponseCallback)(bool);
-@property void (^_Nonnull applicationLauncher_stopAppResponseCallback)(bool);
-@property void (^_Nonnull applicationLauncher_hideAppResponseCallback)(bool);
-@property void (^_Nonnull targetNavigator_navigateTargetResponseCallback)(bool);
-@property void (^_Nonnull keypadInput_sendKeyResponseCallback)(bool);
-
-@property OnboardingPayload * _Nonnull onboardingPayload;
-
 + (CastingServerBridge * _Nullable)getSharedInstance;
 
 /*!
@@ -110,7 +94,7 @@
     commissioningWindowRequestedHandler:(void (^_Nonnull)(bool))commissioningWindowRequestedHandler;
 
 /*!
- @brief Send a Content Launcher:LaunchURL request to a TV
+ @brief Send a ContentLauncher:LaunchURL request to a TV
 
  @param contentUrl URL of the content to launch on the TV
 
@@ -128,6 +112,53 @@
                       clientQueue:(dispatch_queue_t _Nonnull)clientQueue
                requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler;
 
+/*!
+ @brief Send a ContentLauncher:LaunchContent request to a TV
+
+ @param contentSearch Indicates the content to launch
+
+ @param autoPlay Play Best match automatically if true, otherwise display matches
+
+ @param data App specific data to be passed to the TV
+
+ @param responseCallback Callback for when the response has been received
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+ */
+- (void)contentLauncher_launchContent:(ContentLauncher_ContentSearch * _Nonnull)contentSearch
+                             autoPlay:(bool)autoPlay
+                                 data:(NSString * _Nullable)data
+                     responseCallback:(void (^_Nonnull)(bool))responseCallback
+                          clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                   requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler;
+
+/*!
+ @brief Subscribe to ContentLauncher:SupportedStreamingProtocols
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterval
+                                                 maxInterval:(uint16_t)maxInterval
+                                                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                                          requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                                             successCallback:(void (^_Nonnull)(uint32_t))successCallback
+                                             failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+                             subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
 /*!
  @brief Send a LevelControl:Step request to a TV
 
@@ -181,6 +212,81 @@
                      clientQueue:(dispatch_queue_t _Nonnull)clientQueue
               requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler;
 
+/*!
+ @brief Subscribe to LevelControl:CurrentLevel
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval
+                               maxInterval:(uint16_t)maxInterval
+                               clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                        requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                           successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                           failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+           subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to LevelControl:MinLevel
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)levelControl_subscribeMinLevel:(uint16_t)minInterval
+                           maxInterval:(uint16_t)maxInterval
+                           clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                    requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                       successCallback:(void (^_Nonnull)(uint8_t))successCallback
+                       failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+       subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to LevelControl:MaxLevel
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval
+                           maxInterval:(uint16_t)maxInterval
+                           clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                    requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                       successCallback:(void (^_Nonnull)(uint8_t))successCallback
+                       failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+       subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
 /*!
  @brief Send a MediaPlayback:Play request to a TV
 
@@ -281,6 +387,180 @@
                        clientQueue:(dispatch_queue_t _Nonnull)clientQueue
                 requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler;
 
+/*!
+ @brief Subscribe to MediaPlayback:CurrentState
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackState))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to MediaPlayback:StartTime
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval
+                             maxInterval:(uint16_t)maxInterval
+                             clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                      requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                         successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                         failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+         subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to MediaPlayback:Duration
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval
+                            maxInterval:(uint16_t)maxInterval
+                            clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                     requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                        successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                        failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+        subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to MediaPlayback:SampledPosition
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval
+                                   maxInterval:(uint16_t)maxInterval
+                                   clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                            requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                               successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackPosition * _Nullable))successCallback
+                               failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+               subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to MediaPlayback:PlaybackSpeed
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval
+                                 maxInterval:(uint16_t)maxInterval
+                                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                          requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                             successCallback:(void (^_Nonnull)(float))successCallback
+                             failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+             subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to MediaPlayback:SeekRangeEnd
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to MediaPlayback:SeekRangeStart
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval
+                                  maxInterval:(uint16_t)maxInterval
+                                  clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                           requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                              successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                              failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+              subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
 /*!
  @brief Send a ApplicationLauncher:LaunchApp request to a TV
 
@@ -361,6 +641,56 @@
                            clientQueue:(dispatch_queue_t _Nonnull)clientQueue
                     requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler;
 
+/*!
+ @brief Subscribe to TargetNavigator:TargetList
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(NSMutableArray * _Nullable))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to TargetNavigator:CurrentTarget
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval
+                                   maxInterval:(uint16_t)maxInterval
+                                   clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                            requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                               successCallback:(void (^_Nonnull)(uint8_t))successCallback
+                               failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+               subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
 /*!
  @brief Send a KeypadInput:SendKey request to a TV
 
@@ -379,6 +709,130 @@
                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
          requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler;
 
+/*!
+ @brief Subscribe to ApplicationBasic:VendorName
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval
+                                 maxInterval:(uint16_t)maxInterval
+                                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                          requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                             successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback
+                             failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+             subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to ApplicationBasic:VendorID
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval
+                               maxInterval:(uint16_t)maxInterval
+                               clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                        requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                           successCallback:(void (^_Nonnull)(NSNumber * _Nonnull))successCallback
+                           failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+           subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to ApplicationBasic:ApplicationName
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval
+                                      maxInterval:(uint16_t)maxInterval
+                                      clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                               requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                                  successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback
+                                  failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+                  subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to ApplicationBasic:ProductID
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)applicationBasic_subscribeProductID:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(uint16_t))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
+
+/*!
+ @brief Subscribe to ApplicationBasic:ApplicationVersion
+
+ @param minInterval Minimum interval between attribute read reports
+
+ @param maxInterval Maximum interval between attribute read reports
+
+ @param clientQueue Queue to dispatch the call to the requestSentHandler on
+
+ @param requestSentHandler Handler to call on sending the request
+
+ @param successCallback Callback for when a read report is successfully received
+
+ @param failureCallback Callback for when there is a failure in receiving a read report
+
+ @param subscriptionEstablishedCallback Callback for when the requested subscription has been established successfully
+ */
+- (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval
+                                         maxInterval:(uint16_t)maxInterval
+                                         clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                                  requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                                     successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback
+                                     failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+                     subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback;
 @end
 
 #endif /* CastingServerBridge_h */
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm
index 2eccbf8242a0a9..c690e49af7ef7c 100644
--- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/CastingServerBridge.mm
@@ -19,12 +19,14 @@
 #import "CastingServer.h"
 
 #import "DiscoveredNodeDataConverter.hpp"
+#import "MatterCallbacks.h"
 #import "OnboardingPayload.h"
 
 #include <credentials/DeviceAttestationCredsProvider.h>
 #include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
 #include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
 #include <credentials/examples/DeviceAttestationCredsExample.h>
+#include <lib/support/CHIPListUtils.h>
 #include <lib/support/CHIPMem.h>
 #include <platform/PlatformManager.h>
 #include <platform/TestOnlyCommissionableDataProvider.h>
@@ -34,6 +36,18 @@ @interface CastingServerBridge ()
 // queue used to serialize all work performed by the CastingServerBridge
 @property (atomic, readonly) dispatch_queue_t chipWorkQueue;
 
+@property OnboardingPayload * _Nonnull onboardingPayload;
+
+@property void (^_Nonnull commissioningCompleteCallback)(bool);
+
+@property NSMutableDictionary * commandResponseCallbacks;
+
+@property NSMutableDictionary * subscriptionEstablishedCallbacks;
+
+@property NSMutableDictionary * subscriptionReadSuccessCallbacks;
+
+@property NSMutableDictionary * subscriptionReadFailureCallbacks;
+
 @end
 
 @implementation CastingServerBridge
@@ -96,6 +110,11 @@ - (instancetype)init
 
         _chipWorkQueue = chip::DeviceLayer::PlatformMgrImpl().GetWorkQueue();
 
+        _commandResponseCallbacks = [NSMutableDictionary dictionary];
+        _subscriptionEstablishedCallbacks = [NSMutableDictionary dictionary];
+        _subscriptionReadSuccessCallbacks = [NSMutableDictionary dictionary];
+        _subscriptionReadFailureCallbacks = [NSMutableDictionary dictionary];
+
         chip::DeviceLayer::PlatformMgrImpl().StartEventLoopTask();
 
         CastingServer::GetInstance()->Init();
@@ -209,11 +228,14 @@ - (void)contentLauncher_launchUrl:(NSString * _Nonnull)contentUrl
 {
     ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_launchUrl() called");
 
-    _contentLauncher_launchUrlResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"contentLauncher_launchUrl"];
+
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncherLaunchURL(
             [contentUrl UTF8String], [contentDisplayStr UTF8String], [](CHIP_ERROR err) {
-                [CastingServerBridge getSharedInstance].contentLauncher_launchUrlResponseCallback(CHIP_NO_ERROR == err);
+                void (^responseCallback)(bool) =
+                    [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"contentLauncher_launchUrl"];
+                responseCallback(CHIP_NO_ERROR == err);
             });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -221,6 +243,120 @@ - (void)contentLauncher_launchUrl:(NSString * _Nonnull)contentUrl
     });
 }
 
+- (void)contentLauncher_launchContent:(ContentLauncher_ContentSearch * _Nonnull)contentSearch
+                             autoPlay:(bool)autoPlay
+                                 data:(NSString * _Nullable)data
+                     responseCallback:(void (^_Nonnull)(bool))responseCallback
+                          clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                   requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_launchContent() called");
+
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"contentLauncher_launchContent"];
+
+    // Make a copy of params before we go async.
+    contentSearch = [contentSearch copy];
+    data = [data copy];
+
+    dispatch_async(_chipWorkQueue, ^{
+        ListFreer listFreer;
+        chip::app::Clusters::ContentLauncher::Structs::ContentSearch::Type cppSearch;
+        if (contentSearch.parameterList.count > 0) {
+            auto * parameterListHolder
+                = new ListHolder<chip::app::Clusters::ContentLauncher::Structs::Parameter::Type>(contentSearch.parameterList.count);
+            listFreer.add(parameterListHolder);
+
+            int parameterIndex = 0;
+            for (ContentLauncher_Parameter * parameter in contentSearch.parameterList) {
+                int externalIdListIndex = 0;
+                if (parameter.externalIDList != nil) {
+                    auto * externalIdListHolder
+                        = new ListHolder<chip::app::Clusters::ContentLauncher::Structs::AdditionalInfo::Type>(
+                            parameter.externalIDList.count);
+                    listFreer.add(externalIdListHolder);
+
+                    for (ContentLauncher_AdditionalInfo * additionalInfo in parameter.externalIDList) {
+                        externalIdListHolder->mList[externalIdListIndex].value = chip::CharSpan([additionalInfo.value UTF8String],
+                            [additionalInfo.value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
+                        externalIdListHolder->mList[externalIdListIndex].name = chip::CharSpan([additionalInfo.name UTF8String],
+                            [additionalInfo.name lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
+                        externalIdListIndex++;
+                    }
+                    parameterListHolder->mList[parameterIndex].externalIDList = MakeOptional(
+                        chip::app::DataModel::List<const chip::app::Clusters::ContentLauncher::Structs::AdditionalInfo::Type>(
+                            externalIdListHolder->mList, parameter.externalIDList.count));
+                } else {
+                    parameterListHolder->mList[parameterIndex].externalIDList = chip::Optional<chip::app::DataModel::List<
+                        const chip::app::Clusters::ContentLauncher::Structs::AdditionalInfo::Type>>::Missing();
+                }
+
+                parameterListHolder->mList[parameterIndex].type
+                    = static_cast<chip::app::Clusters::ContentLauncher::ParameterEnum>(parameter.type);
+                parameterListHolder->mList[parameterIndex].value = chip::CharSpan(
+                    [parameter.value UTF8String], [parameter.value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
+                parameterIndex++;
+                cppSearch.parameterList
+                    = chip::app::DataModel::List<chip::app::Clusters::ContentLauncher::Structs::Parameter::Type>(
+                        parameterListHolder->mList, contentSearch.parameterList.count);
+            }
+        }
+
+        CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncher_LaunchContent(cppSearch, autoPlay,
+            MakeOptional(chip::CharSpan([data UTF8String], [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding])),
+            [](CHIP_ERROR err) {
+                void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks
+                    objectForKey:@"contentLauncher_launchContent"];
+                responseCallback(CHIP_NO_ERROR == err);
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler(CHIP_NO_ERROR == err);
+        });
+    });
+}
+
+- (void)contentLauncher_subscribeSupportedStreamingProtocols:(uint16_t)minInterval
+                                                 maxInterval:(uint16_t)maxInterval
+                                                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                                          requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                                             successCallback:(void (^_Nonnull)(uint32_t))successCallback
+                                             failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+                             subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().contentLauncher_subscribeSupportedStreamingProtocols() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback
+                                          forKey:@"contentLauncher_subscribeSupportedStreamingProtocols"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->ContentLauncher_SubscribeToSupportedStreamingProtocols(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::ContentLauncher::Attributes::SupportedStreamingProtocols::TypeInfo::DecodableArgType
+                    supportedStreamingProtocols) {
+                void (^callback)(uint32_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"contentLauncher_subscribeSupportedStreamingProtocols"];
+                callback(supportedStreamingProtocols);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"contentLauncher_subscribeSupportedStreamingProtocols"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"contentLauncher_subscribeSupportedStreamingProtocols"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
 - (void)levelControl_step:(uint8_t)stepMode
                  stepSize:(uint8_t)stepSize
            transitionTime:(uint16_t)transitionTime
@@ -232,12 +368,14 @@ - (void)levelControl_step:(uint8_t)stepMode
 {
     ChipLogProgress(AppServer, "CastingServerBridge().levelControl_step() called");
 
-    _levelControl_stepResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"levelControl_step"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err
             = CastingServer::GetInstance()->LevelControl_Step(static_cast<chip::app::Clusters::LevelControl::StepMode>(stepMode),
                 stepSize, transitionTime, optionMask, optionOverride, [](CHIP_ERROR err) {
-                    [CastingServerBridge getSharedInstance].levelControl_stepResponseCallback(CHIP_NO_ERROR == err);
+                    void (^responseCallback)(bool) =
+                        [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"levelControl_step"];
+                    responseCallback(CHIP_NO_ERROR == err);
                 });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -255,11 +393,13 @@ - (void)levelControl_moveToLevel:(uint8_t)level
 {
     ChipLogProgress(AppServer, "CastingServerBridge().levelControl_moveToLevel() called");
 
-    _levelControl_moveToLevelResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"levelControl_moveToLevel"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_MoveToLevel(
             level, transitionTime, optionMask, optionOverride, [](CHIP_ERROR err) {
-                [CastingServerBridge getSharedInstance].levelControl_moveToLevelResponseCallback(CHIP_NO_ERROR == err);
+                void (^responseCallback)(bool) =
+                    [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"levelControl_moveToLevel"];
+                responseCallback(CHIP_NO_ERROR == err);
             });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -267,16 +407,139 @@ - (void)levelControl_moveToLevel:(uint8_t)level
     });
 }
 
+- (void)levelControl_subscribeCurrentLevel:(uint16_t)minInterval
+                               maxInterval:(uint16_t)maxInterval
+                               clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                        requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                           successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                           failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+           subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeCurrentLevel() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeCurrentLevel"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeCurrentLevel"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeCurrentLevel"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToCurrentLevel(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::LevelControl::Attributes::CurrentLevel::TypeInfo::DecodableArgType currentLevel) {
+                void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"levelControl_subscribeCurrentLevel"];
+                callback(@(currentLevel.Value()));
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"levelControl_subscribeCurrentLevel"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"levelControl_subscribeCurrentLevel"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)levelControl_subscribeMinLevel:(uint16_t)minInterval
+                           maxInterval:(uint16_t)maxInterval
+                           clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                    requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                       successCallback:(void (^_Nonnull)(uint8_t))successCallback
+                       failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+       subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMinLevel() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeMinLevel"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeMinLevel"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeMinLevel"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToMinLevel(
+            nullptr,
+            [](void * context, chip::app::Clusters::LevelControl::Attributes::MinLevel::TypeInfo::DecodableArgType minLevel) {
+                void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"levelControl_subscribeMinLevel"];
+                callback(minLevel);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"levelControl_subscribeMinLevel"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"levelControl_subscribeMinLevel"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)levelControl_subscribeMaxLevel:(uint16_t)minInterval
+                           maxInterval:(uint16_t)maxInterval
+                           clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                    requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                       successCallback:(void (^_Nonnull)(uint8_t))successCallback
+                       failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+       subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().levelControl_subscribeMaxLevel() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"levelControl_subscribeMaxLevel"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"levelControl_subscribeMaxLevel"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"levelControl_subscribeMaxLevel"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->LevelControl_SubscribeToMaxLevel(
+            nullptr,
+            [](void * context, chip::app::Clusters::LevelControl::Attributes::MaxLevel::TypeInfo::DecodableArgType maxLevel) {
+                void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"levelControl_subscribeMaxLevel"];
+                callback(maxLevel);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"levelControl_subscribeMaxLevel"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"levelControl_subscribeMaxLevel"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
 - (void)mediaPlayback_play:(void (^_Nonnull)(bool))responseCallback
                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
         requestSentHandler:(void (^_Nonnull)(bool))requestSentHandler
 {
     ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_play() called");
 
-    _mediaPlayback_playResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_play"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Play([](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].mediaPlayback_playResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_play"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -290,10 +553,12 @@ - (void)mediaPlayback_pause:(void (^_Nonnull)(bool))responseCallback
 {
     ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_pause() called");
 
-    _mediaPlayback_pauseResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_pause"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Pause([](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].mediaPlayback_pauseResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_pause"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -307,10 +572,12 @@ - (void)mediaPlayback_stopPlayback:(void (^_Nonnull)(bool))responseCallback
 {
     ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_stopPlayback() called");
 
-    _mediaPlayback_pauseResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_stopPlayback"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_StopPlayback([](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].mediaPlayback_stopPlaybackResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_stopPlayback"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -324,10 +591,12 @@ - (void)mediaPlayback_next:(void (^_Nonnull)(bool))responseCallback
 {
     ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_next() called");
 
-    _mediaPlayback_nextResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_next"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Next([](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].mediaPlayback_nextResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_next"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -342,10 +611,12 @@ - (void)mediaPlayback_seek:(uint8_t)position
 {
     ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_seek() called");
 
-    _mediaPlayback_seekResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_seek"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_Seek(position, [](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].mediaPlayback_seekResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_seek"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -360,10 +631,12 @@ - (void)mediaPlayback_skipForward:(uint64_t)deltaPositionMilliseconds
 {
     ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipForward() called");
 
-    _mediaPlayback_skipForwardResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_skipForward"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SkipForward(deltaPositionMilliseconds, [](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].mediaPlayback_skipForwardResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipForward"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -378,10 +651,12 @@ - (void)mediaPlayback_skipBackward:(uint64_t)deltaPositionMilliseconds
 {
     ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_skipBackward() called");
 
-    _mediaPlayback_skipBackwardResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"mediaPlayback_skipBackward"];
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SkipBackward(deltaPositionMilliseconds, [](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].mediaPlayback_skipBackwardResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"mediaPlayback_skipBackward"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -389,6 +664,305 @@ - (void)mediaPlayback_skipBackward:(uint64_t)deltaPositionMilliseconds
     });
 }
 
+- (void)mediaPlayback_subscribeCurrentState:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackState))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeCurrentState() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeCurrentState"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeCurrentState"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeCurrentState"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToCurrentState(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::MediaPlayback::Attributes::CurrentState::TypeInfo::DecodableArgType currentState) {
+                void (^callback)(MediaPlayback_PlaybackState) =
+                    [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                        objectForKey:@"mediaPlayback_subscribeCurrentState"];
+                callback(MediaPlayback_PlaybackState(currentState));
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"mediaPlayback_subscribeCurrentState"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"mediaPlayback_subscribeCurrentState"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)mediaPlayback_subscribeStartTime:(uint16_t)minInterval
+                             maxInterval:(uint16_t)maxInterval
+                             clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                      requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                         successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                         failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+         subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeStartTime() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeStartTime"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeStartTime"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeStartTime"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToStartTime(
+            nullptr,
+            [](void * context, chip::app::Clusters::MediaPlayback::Attributes::StartTime::TypeInfo::DecodableArgType startTime) {
+                void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"mediaPlayback_subscribeStartTime"];
+                callback(@(startTime.Value()));
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"mediaPlayback_subscribeStartTime"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"mediaPlayback_subscribeStartTime"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)mediaPlayback_subscribeDuration:(uint16_t)minInterval
+                            maxInterval:(uint16_t)maxInterval
+                            clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                     requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                        successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                        failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+        subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeDuration() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeDuration"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeDuration"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeDuration"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration(
+            nullptr,
+            [](void * context, chip::app::Clusters::MediaPlayback::Attributes::Duration::TypeInfo::DecodableArgType startTime) {
+                void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"mediaPlayback_subscribeDuration"];
+                callback(@(startTime.Value()));
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"mediaPlayback_subscribeDuration"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"mediaPlayback_subscribeDuration"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)mediaPlayback_subscribeSampledPosition:(uint16_t)minInterval
+                                   maxInterval:(uint16_t)maxInterval
+                                   clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                            requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                               successCallback:(void (^_Nonnull)(MediaPlayback_PlaybackPosition * _Nullable))successCallback
+                               failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+               subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSampledPosition() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSampledPosition"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSampledPosition"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSampledPosition"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToSampledPosition(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::MediaPlayback::Attributes::SampledPosition::TypeInfo::DecodableArgType playbackPosition) {
+                void (^callback)(MediaPlayback_PlaybackPosition * _Nullable) =
+                    [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                        objectForKey:@"mediaPlayback_subscribeSampledPosition"];
+                MediaPlayback_PlaybackPosition * objCPlaybackPosition = nil;
+                if (!playbackPosition.IsNull()) {
+                    if (playbackPosition.Value().position.IsNull()) {
+                        objCPlaybackPosition =
+                            [[MediaPlayback_PlaybackPosition alloc] initWithUpdatedAt:@(playbackPosition.Value().updatedAt)
+                                                                             position:nil];
+                    } else {
+                        objCPlaybackPosition =
+                            [[MediaPlayback_PlaybackPosition alloc] initWithUpdatedAt:@(playbackPosition.Value().updatedAt)
+                                                                             position:@(playbackPosition.Value().position.Value())];
+                    }
+                    callback(objCPlaybackPosition);
+                }
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSampledPosition"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSampledPosition"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)mediaPlayback_subscribePlaybackSpeed:(uint16_t)minInterval
+                                 maxInterval:(uint16_t)maxInterval
+                                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                          requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                             successCallback:(void (^_Nonnull)(float))successCallback
+                             failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+             subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribePlaybackSpeed() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribePlaybackSpeed"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToPlaybackSpeed(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::MediaPlayback::Attributes::PlaybackSpeed::TypeInfo::DecodableArgType playbackSpeed) {
+                void (^callback)(float) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"mediaPlayback_subscribePlaybackSpeed"];
+                callback(playbackSpeed);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"mediaPlayback_subscribePlaybackSpeed"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"mediaPlayback_subscribePlaybackSpeed"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)mediaPlayback_subscribeSeekRangeEnd:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSeekRangeEnd() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSeekRangeEnd"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType seekRangeEnd) {
+                void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSeekRangeEnd"];
+                callback(@(seekRangeEnd.Value()));
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSeekRangeEnd"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSeekRangeEnd"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)mediaPlayback_subscribeSeekRangeStart:(uint16_t)minInterval
+                                  maxInterval:(uint16_t)maxInterval
+                                  clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                           requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                              successCallback:(void (^_Nonnull)(NSNumber * _Nullable))successCallback
+                              failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+              subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().mediaPlayback_subscribeSeekRangeStart() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"mediaPlayback_subscribeSeekRangeStart"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->MediaPlayback_SubscribeToDuration(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::MediaPlayback::Attributes::SeekRangeEnd::TypeInfo::DecodableArgType seekRangeStart) {
+                void (^callback)(NSNumber * _Nullable) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSeekRangeStart"];
+                callback(@(seekRangeStart.Value()));
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSeekRangeStart"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"mediaPlayback_subscribeSeekRangeStart"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
 - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId
                         applicationId:(NSString * _Nonnull)applicationId
                                  data:(NSData * _Nullable)data
@@ -398,7 +972,7 @@ - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId
 {
     ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_launchApp() called");
 
-    _applicationLauncher_launchAppResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_launchApp"];
 
     chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application;
     application.catalogVendorId = catalogVendorId;
@@ -407,7 +981,9 @@ - (void)applicationLauncher_launchApp:(uint16_t)catalogVendorId
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_LaunchApp(application,
             chip::MakeOptional(chip::ByteSpan(static_cast<const uint8_t *>(data.bytes), data.length)), [](CHIP_ERROR err) {
-                [CastingServerBridge getSharedInstance].applicationLauncher_launchAppResponseCallback(CHIP_NO_ERROR == err);
+                void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks
+                    objectForKey:@"applicationLauncher_launchApp"];
+                responseCallback(CHIP_NO_ERROR == err);
             });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -423,7 +999,7 @@ - (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId
 {
     ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_stopApp() called");
 
-    _applicationLauncher_stopAppResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_stopApp"];
 
     chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application;
     application.catalogVendorId = catalogVendorId;
@@ -431,7 +1007,9 @@ - (void)applicationLauncher_stopApp:(uint16_t)catalogVendorId
 
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_StopApp(application, [](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].applicationLauncher_stopAppResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"applicationLauncher_stopApp"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -447,7 +1025,7 @@ - (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId
 {
     ChipLogProgress(AppServer, "CastingServerBridge().applicationLauncher_hideApp() called");
 
-    _applicationLauncher_hideAppResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"applicationLauncher_hideApp"];
 
     chip::app::Clusters::ApplicationLauncher::Structs::Application::Type application;
     application.catalogVendorId = catalogVendorId;
@@ -455,7 +1033,9 @@ - (void)applicationLauncher_hideApp:(uint16_t)catalogVendorId
 
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->ApplicationLauncher_HideApp(application, [](CHIP_ERROR err) {
-            [CastingServerBridge getSharedInstance].applicationLauncher_hideAppResponseCallback(CHIP_NO_ERROR == err);
+            void (^responseCallback)(bool) =
+                [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"applicationLauncher_hideApp"];
+            responseCallback(CHIP_NO_ERROR == err);
         });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -471,12 +1051,14 @@ - (void)targetNavigator_navigateTarget:(uint8_t)target
 {
     ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_navigateTarget() called");
 
-    _targetNavigator_navigateTargetResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"targetNavigator_navigateTarget"];
 
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_NavigateTarget(
             target, chip::MakeOptional(chip::CharSpan::fromCharString([data UTF8String])), [](CHIP_ERROR err) {
-                [CastingServerBridge getSharedInstance].targetNavigator_navigateTargetResponseCallback(CHIP_NO_ERROR == err);
+                void (^responseCallback)(bool) = [[CastingServerBridge getSharedInstance].commandResponseCallbacks
+                    objectForKey:@"targetNavigator_navigateTarget"];
+                responseCallback(CHIP_NO_ERROR == err);
             });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -484,6 +1066,103 @@ - (void)targetNavigator_navigateTarget:(uint8_t)target
     });
 }
 
+- (void)targetNavigator_subscribeTargetList:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(NSMutableArray *))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_subscribeTargetList() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"targetNavigator_subscribeTargetList"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"targetNavigator_subscribeTargetList"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"targetNavigator_subscribeTargetList"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_SubscribeToTargetList(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::TargetNavigator::Attributes::TargetList::TypeInfo::DecodableArgType targetList) {
+                void (^callback)(NSMutableArray *) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"targetNavigator_subscribeTargetList"];
+                NSMutableArray * objCTargetList = nil;
+                size_t targetInfoCount;
+                targetList.ComputeSize(&targetInfoCount);
+                if (targetInfoCount > 0) {
+                    objCTargetList = [NSMutableArray arrayWithCapacity:targetInfoCount];
+                    auto iter = targetList.begin();
+                    while (iter.Next()) {
+                        const chip::app::Clusters::TargetNavigator::Structs::TargetInfo::DecodableType & targetInfo
+                            = iter.GetValue();
+                        TargetNavigator_TargetInfo * objCTargetInfo = [[TargetNavigator_TargetInfo alloc]
+                            initWithIdentifier:@(targetInfo.identifier)
+                                          name:[NSString stringWithUTF8String:targetInfo.name.data()]];
+                        [objCTargetList addObject:objCTargetInfo];
+                    }
+                }
+                callback(objCTargetList);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"targetNavigator_subscribeTargetList"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"targetNavigator_subscribeTargetList"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)targetNavigator_subscribeCurrentTarget:(uint16_t)minInterval
+                                   maxInterval:(uint16_t)maxInterval
+                                   clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                            requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                               successCallback:(void (^_Nonnull)(uint8_t))successCallback
+                               failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+               subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().targetNavigator_subscribeCurrentTarget() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"targetNavigator_subscribeCurrentTarget"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"targetNavigator_subscribeCurrentTarget"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"targetNavigator_subscribeCurrentTarget"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->TargetNavigator_SubscribeToCurrentTarget(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::TargetNavigator::Attributes::CurrentTarget::TypeInfo::DecodableArgType currentTarget) {
+                void (^callback)(uint8_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"targetNavigator_subscribeCurrentTarget"];
+                callback(currentTarget);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"targetNavigator_subscribeCurrentTarget"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"targetNavigator_subscribeCurrentTarget"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
 - (void)keypadInput_sendKey:(uint8_t)keyCode
            responseCallback:(void (^_Nonnull)(bool))responseCallback
                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
@@ -491,12 +1170,14 @@ - (void)keypadInput_sendKey:(uint8_t)keyCode
 {
     ChipLogProgress(AppServer, "CastingServerBridge().keypadInput_sendKey() called");
 
-    _keypadInput_sendKeyResponseCallback = responseCallback;
+    [_commandResponseCallbacks setObject:responseCallback forKey:@"keypadInput_sendKey"];
 
     dispatch_async(_chipWorkQueue, ^{
         CHIP_ERROR err = CastingServer::GetInstance()->KeypadInput_SendKey(
             static_cast<chip::app::Clusters::KeypadInput::CecKeyCode>(keyCode), [](CHIP_ERROR err) {
-                [CastingServerBridge getSharedInstance].keypadInput_sendKeyResponseCallback(CHIP_NO_ERROR == err);
+                void (^responseCallback)(bool) =
+                    [[CastingServerBridge getSharedInstance].commandResponseCallbacks objectForKey:@"keypadInput_sendKey"];
+                responseCallback(CHIP_NO_ERROR == err);
             });
         dispatch_async(clientQueue, ^{
             requestSentHandler(CHIP_NO_ERROR == err);
@@ -504,4 +1185,210 @@ - (void)keypadInput_sendKey:(uint8_t)keyCode
     });
 }
 
+- (void)applicationBasic_subscribeVendorName:(uint16_t)minInterval
+                                 maxInterval:(uint16_t)maxInterval
+                                 clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                          requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                             successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback
+                             failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+             subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeVendorName() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeVendorName"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeVendorName"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeVendorName"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToVendorName(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::ApplicationBasic::Attributes::VendorName::TypeInfo::DecodableArgType vendorName) {
+                void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"applicationBasic_subscribeVendorName"];
+                callback([NSString stringWithUTF8String:vendorName.data()]);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"applicationBasic_subscribeVendorName"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"applicationBasic_subscribeVendorName"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)applicationBasic_subscribeVendorID:(uint16_t)minInterval
+                               maxInterval:(uint16_t)maxInterval
+                               clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                        requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                           successCallback:(void (^_Nonnull)(NSNumber * _Nonnull))successCallback
+                           failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+           subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeVendorID() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeVendorID"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeVendorID"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeVendorID"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToVendorID(
+            nullptr,
+            [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::VendorID::TypeInfo::DecodableArgType vendorID) {
+                void (^callback)(NSNumber * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"applicationBasic_subscribeVendorID"];
+                callback(@(vendorID));
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"applicationBasic_subscribeVendorID"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"applicationBasic_subscribeVendorID"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)applicationBasic_subscribeApplicationName:(uint16_t)minInterval
+                                      maxInterval:(uint16_t)maxInterval
+                                      clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                               requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                                  successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback
+                                  failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+                  subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeApplicationName() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeApplicationName"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeApplicationName"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback
+                                          forKey:@"applicationBasic_subscribeApplicationName"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToApplicationName(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::ApplicationBasic::Attributes::ApplicationName::TypeInfo::DecodableArgType applicationName) {
+                void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"applicationBasic_subscribeApplicationName"];
+                callback([NSString stringWithUTF8String:applicationName.data()]);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"applicationBasic_subscribeApplicationName"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"applicationBasic_subscribeApplicationName"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)applicationBasic_subscribeProductID:(uint16_t)minInterval
+                                maxInterval:(uint16_t)maxInterval
+                                clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                         requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                            successCallback:(void (^_Nonnull)(uint16_t))successCallback
+                            failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+            subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeProductID() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeProductID"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeProductID"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback forKey:@"applicationBasic_subscribeProductID"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToProductID(
+            nullptr,
+            [](void * context, chip::app::Clusters::ApplicationBasic::Attributes::ProductID::TypeInfo::DecodableArgType productID) {
+                void (^callback)(uint16_t) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"applicationBasic_subscribeProductID"];
+                callback(productID);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"applicationBasic_subscribeProductID"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"applicationBasic_subscribeProductID"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
+- (void)applicationBasic_subscribeApplicationVersion:(uint16_t)minInterval
+                                         maxInterval:(uint16_t)maxInterval
+                                         clientQueue:(dispatch_queue_t _Nonnull)clientQueue
+                                  requestSentHandler:(void (^_Nonnull)(MatterError * _Nonnull))requestSentHandler
+                                     successCallback:(void (^_Nonnull)(NSString * _Nonnull))successCallback
+                                     failureCallback:(void (^_Nonnull)(MatterError * _Nonnull))failureCallback
+                     subscriptionEstablishedCallback:(void (^_Nonnull)())subscriptionEstablishedCallback
+{
+    ChipLogProgress(AppServer, "CastingServerBridge().applicationBasic_subscribeApplicationVersion() called");
+
+    [_subscriptionReadSuccessCallbacks setObject:successCallback forKey:@"applicationBasic_subscribeApplicationVersion"];
+    [_subscriptionReadFailureCallbacks setObject:failureCallback forKey:@"applicationBasic_subscribeApplicationVersion"];
+    [_subscriptionEstablishedCallbacks setObject:subscriptionEstablishedCallback
+                                          forKey:@"applicationBasic_subscribeApplicationVersion"];
+
+    dispatch_async(_chipWorkQueue, ^{
+        CHIP_ERROR err = CastingServer::GetInstance()->ApplicationBasic_SubscribeToApplicationVersion(
+            nullptr,
+            [](void * context,
+                chip::app::Clusters::ApplicationBasic::Attributes::ApplicationVersion::TypeInfo::DecodableArgType
+                    applicationVersion) {
+                void (^callback)(NSString * _Nonnull) = [[CastingServerBridge getSharedInstance].subscriptionReadSuccessCallbacks
+                    objectForKey:@"applicationBasic_subscribeApplicationVersion"];
+                callback([NSString stringWithUTF8String:applicationVersion.data()]);
+            },
+            [](void * context, CHIP_ERROR err) {
+                void (^callback)(MatterError *) = [[CastingServerBridge getSharedInstance].subscriptionReadFailureCallbacks
+                    objectForKey:@"applicationBasic_subscribeApplicationVersion"];
+                callback([[MatterError alloc] initWithCode:err.AsInteger() message:[NSString stringWithUTF8String:err.AsString()]]);
+            },
+            minInterval, maxInterval,
+            [](void * context) {
+                void (^callback)() = [[CastingServerBridge getSharedInstance].subscriptionEstablishedCallbacks
+                    objectForKey:@"applicationBasic_subscribeApplicationVersion"];
+                callback();
+            });
+        dispatch_async(clientQueue, ^{
+            requestSentHandler([[MatterError alloc] initWithCode:err.AsInteger()
+                                                         message:[NSString stringWithUTF8String:err.AsString()]]);
+        });
+    });
+}
+
 @end
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.h
new file mode 100644
index 00000000000000..49f44df70a4b11
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.h
@@ -0,0 +1,68 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#ifndef ContentLauncherTypes_h
+#define ContentLauncherTypes_h
+
+typedef NS_ENUM(uint8_t, ContentLauncher_ParameterEnum) {
+    Actor = 0x00,
+    Channel = 0x01,
+    Character = 0x02,
+    Director = 0x03,
+    Event = 0x04,
+    Franchise = 0x05,
+    Genre = 0x06,
+    League = 0x07,
+    Popularity = 0x08,
+    Provider = 0x09,
+    Sport = 0x10,
+    SportsTeam = 0x11,
+    Type = 0x12,
+    Video = 0x13,
+};
+
+@interface ContentLauncher_AdditionalInfo : NSObject <NSCopying>
+
+@property (nonatomic, copy) NSString * _Nonnull name;
+@property (nonatomic, copy) NSString * _Nonnull value;
+
+- (ContentLauncher_AdditionalInfo * _Nonnull)initWithName:(NSString * _Nonnull)name value:(NSString * _Nonnull)value;
+- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone;
+@end
+
+@interface ContentLauncher_Parameter : NSObject <NSCopying>
+
+@property (nonatomic) ContentLauncher_ParameterEnum type;
+@property (nonatomic, copy) NSString * _Nonnull value;
+@property (nonatomic, copy) NSArray * _Nullable externalIDList;
+
+- (ContentLauncher_Parameter * _Nonnull)initWithType:(ContentLauncher_ParameterEnum)type
+                                               value:(NSString * _Nonnull)value
+                                      externalIDList:(NSArray * _Nullable)externalIDList;
+- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone;
+@end
+
+@interface ContentLauncher_ContentSearch : NSObject <NSCopying>
+
+@property (nonatomic, copy) NSArray * _Nonnull parameterList;
+
+- (ContentLauncher_ContentSearch * _Nonnull)initWithParameterList:(NSArray * _Nonnull)parameterList;
+- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone;
+@end
+#endif /* ContentLauncherTypes_h */
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.mm
new file mode 100644
index 00000000000000..958de58b054476
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/ContentLauncherTypes.mm
@@ -0,0 +1,83 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "ContentLauncherTypes.h"
+
+@implementation ContentLauncher_AdditionalInfo
+- (ContentLauncher_AdditionalInfo * _Nonnull)initWithName:(NSString * _Nonnull)name value:(NSString * _Nonnull)value
+{
+    self = [super init];
+    if (self) {
+        _name = name;
+        _value = value;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"ContentLauncher_AdditionalInfo: name=%@ value=%@", _name, _value];
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone
+{
+    return [[ContentLauncher_AdditionalInfo alloc] initWithName:_name value:_value];
+}
+@end
+
+@implementation ContentLauncher_Parameter
+- (ContentLauncher_Parameter * _Nonnull)initWithType:(ContentLauncher_ParameterEnum)type
+                                               value:(NSString * _Nonnull)value
+                                      externalIDList:(NSArray * _Nullable)externalIDList
+{
+    self = [super init];
+    if (self) {
+        _type = type;
+        _value = value;
+        _externalIDList = externalIDList;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"ContentLauncher_Parameter: type=%hhu value=%@", _type, _value];
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone
+{
+    return [[ContentLauncher_Parameter alloc] initWithType:_type value:_value externalIDList:_externalIDList];
+}
+@end
+
+@implementation ContentLauncher_ContentSearch
+- (ContentLauncher_ContentSearch * _Nonnull)initWithParameterList:(NSArray * _Nonnull)parameterList
+{
+    self = [super init];
+    if (self) {
+        _parameterList = parameterList;
+    }
+    return self;
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone
+{
+    return [[ContentLauncher_ContentSearch alloc] initWithParameterList:_parameterList];
+}
+@end
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h
new file mode 100644
index 00000000000000..ec018725294162
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.h
@@ -0,0 +1,33 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#ifndef MatterError_h
+#define MatterError_h
+
+@interface MatterError : NSObject
+
+@property uint32_t code;
+
+@property NSString * _Nullable message;
+
+- (MatterError * _Nonnull)initWithCode:(uint32_t)code message:(NSString * _Nullable)message;
+
+@end
+
+#endif /* MatterError_h */
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm
new file mode 100644
index 00000000000000..ce700e5a80338a
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MatterError.mm
@@ -0,0 +1,39 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "MatterError.h"
+
+@implementation MatterError
+
+- (MatterError *)initWithCode:(uint32_t)code message:(NSString * _Nullable)message
+{
+    self = [super init];
+    if (self) {
+        _code = code;
+        _message = message;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"MatterError: code=%d message=%@", _code, _message];
+}
+
+@end
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.h
new file mode 100644
index 00000000000000..f316d75cc43c6b
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.h
@@ -0,0 +1,39 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+#import <Foundation/Foundation.h>
+
+#ifndef MediaPlaybackTypes_h
+#define MediaPlaybackTypes_h
+
+typedef NS_ENUM(uint8_t, MediaPlayback_PlaybackState) {
+    Playing = 0x00,
+    Paused = 0x01,
+    NotPlaying = 0x02,
+    Buffering = 0x03,
+};
+
+@interface MediaPlayback_PlaybackPosition : NSObject <NSCopying>
+
+@property (nonatomic, copy) NSNumber * _Nonnull updatedAt;
+@property (nonatomic, copy) NSNumber * _Nullable position;
+
+- (MediaPlayback_PlaybackPosition * _Nonnull)initWithUpdatedAt:(NSNumber * _Nonnull)updatedAt
+                                                      position:(NSNumber * _Nullable)position;
+- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone;
+@end
+
+#endif /* MediaPlaybackTypes_h */
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.mm
new file mode 100644
index 00000000000000..6c0eb428c63b9e
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/MediaPlaybackTypes.mm
@@ -0,0 +1,44 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "MediaPlaybackTypes.h"
+
+@implementation MediaPlayback_PlaybackPosition
+
+- (MediaPlayback_PlaybackPosition * _Nonnull)initWithUpdatedAt:(NSNumber * _Nonnull)updatedAt
+                                                      position:(NSNumber * _Nullable)position
+{
+    self = [super init];
+    if (self) {
+        _updatedAt = updatedAt;
+        _position = position;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"MediaPlayback_PlaybackPosition: updatedAt=%@ position=%@", _updatedAt, _position];
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone
+{
+    return [[MediaPlayback_PlaybackPosition alloc] initWithUpdatedAt:_updatedAt position:_position];
+}
+@end
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.h
new file mode 100644
index 00000000000000..c00eba2edcfdb8
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.h
@@ -0,0 +1,33 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#ifndef TargetNavigatorTypes_h
+#define TargetNavigatorTypes_h
+
+@interface TargetNavigator_TargetInfo : NSObject <NSCopying>
+
+@property (nonatomic, copy) NSNumber * _Nonnull identifier;
+@property (nonatomic, copy) NSString * _Nonnull name;
+
+- (TargetNavigator_TargetInfo * _Nonnull)initWithIdentifier:(NSNumber * _Nonnull)identifier name:(NSString * _Nonnull)name;
+
+- (id _Nonnull)copyWithZone:(NSZone * _Nullable)zone;
+@end
+
+#endif /* TargetNavigatorTypes_h */
diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.mm
new file mode 100644
index 00000000000000..5f3447d7165674
--- /dev/null
+++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/TargetNavigatorTypes.mm
@@ -0,0 +1,43 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "TargetNavigatorTypes.h"
+
+@implementation TargetNavigator_TargetInfo
+
+- (TargetNavigator_TargetInfo * _Nonnull)initWithIdentifier:(NSNumber * _Nonnull)identifier name:(NSString * _Nonnull)name
+{
+    self = [super init];
+    if (self) {
+        _identifier = identifier;
+        _name = name;
+    }
+    return self;
+}
+
+- (NSString *)description
+{
+    return [NSString stringWithFormat:@"TargetNavigator_TargetInfo: identifier=%@ name=%@", _identifier, _name];
+}
+
+- (id)copyWithZone:(NSZone * _Nullable)zone
+{
+    return [[TargetNavigator_TargetInfo alloc] initWithIdentifier:_identifier name:_name];
+}
+@end
diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj
index 05feeae4cb6e5c..ed740398a117f4 100644
--- a/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj
+++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting.xcodeproj/project.pbxproj
@@ -7,6 +7,9 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		3CA1CA7A28E281080023ED44 /* ClusterSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7928E281080023ED44 /* ClusterSelectorView.swift */; };
+		3CA1CA7C28E282150023ED44 /* MediaPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7B28E282150023ED44 /* MediaPlayerView.swift */; };
+		3CA1CA7E28E284950023ED44 /* MediaPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA1CA7D28E284950023ED44 /* MediaPlayerViewModel.swift */; };
 		3CC0E8FA2841DD3400EC6A18 /* TvCastingApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC0E8F92841DD3400EC6A18 /* TvCastingApp.swift */; };
 		3CC0E8FC2841DD3400EC6A18 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CC0E8FB2841DD3400EC6A18 /* ContentView.swift */; };
 		3CC0E8FE2841DD3500EC6A18 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3CC0E8FD2841DD3500EC6A18 /* Assets.xcassets */; };
@@ -43,6 +46,9 @@
 		3C7507B82853EFF000D7DB3A /* CommissioningViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommissioningViewModel.swift; sourceTree = "<group>"; };
 		3CA19434285BA780004768D5 /* ContentLauncherView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentLauncherView.swift; sourceTree = "<group>"; };
 		3CA19436285BA877004768D5 /* ContentLauncherViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentLauncherViewModel.swift; sourceTree = "<group>"; };
+		3CA1CA7928E281080023ED44 /* ClusterSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterSelectorView.swift; sourceTree = "<group>"; };
+		3CA1CA7B28E282150023ED44 /* MediaPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayerView.swift; sourceTree = "<group>"; };
+		3CA1CA7D28E284950023ED44 /* MediaPlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayerViewModel.swift; sourceTree = "<group>"; };
 		3CC0E8F62841DD3400EC6A18 /* TvCasting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TvCasting.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		3CC0E8F92841DD3400EC6A18 /* TvCastingApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TvCastingApp.swift; sourceTree = "<group>"; };
 		3CC0E8FB2841DD3400EC6A18 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
@@ -101,8 +107,11 @@
 				3C7507B62853A3AD00D7DB3A /* CommissionerDiscoveryViewModel.swift */,
 				3C7507AE28529A5F00D7DB3A /* CommissioningView.swift */,
 				3C7507B82853EFF000D7DB3A /* CommissioningViewModel.swift */,
+				3CA1CA7928E281080023ED44 /* ClusterSelectorView.swift */,
 				3CA19434285BA780004768D5 /* ContentLauncherView.swift */,
 				3CA19436285BA877004768D5 /* ContentLauncherViewModel.swift */,
+				3CA1CA7B28E282150023ED44 /* MediaPlayerView.swift */,
+				3CA1CA7D28E284950023ED44 /* MediaPlayerViewModel.swift */,
 				3CC0E8FF2841DD3500EC6A18 /* Preview Content */,
 			);
 			path = TvCasting;
@@ -201,11 +210,14 @@
 			files = (
 				3CCB8745286A5D0F00771BAD /* CommissionerDiscoveryView.swift in Sources */,
 				3CCB8746286A5D0F00771BAD /* CommissionerDiscoveryViewModel.swift in Sources */,
+				3CA1CA7A28E281080023ED44 /* ClusterSelectorView.swift in Sources */,
 				3CCB8747286A5D0F00771BAD /* CommissioningView.swift in Sources */,
 				3CCB8748286A5D0F00771BAD /* CommissioningViewModel.swift in Sources */,
+				3CA1CA7E28E284950023ED44 /* MediaPlayerViewModel.swift in Sources */,
 				3CCB8749286A5D0F00771BAD /* ContentLauncherView.swift in Sources */,
 				3CCB874A286A5D0F00771BAD /* ContentLauncherViewModel.swift in Sources */,
 				3CC0E8FC2841DD3400EC6A18 /* ContentView.swift in Sources */,
+				3CA1CA7C28E282150023ED44 /* MediaPlayerView.swift in Sources */,
 				3CC0E8FA2841DD3400EC6A18 /* TvCastingApp.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/ClusterSelectorView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ClusterSelectorView.swift
new file mode 100644
index 00000000000000..d7285e82ec1a2b
--- /dev/null
+++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/ClusterSelectorView.swift
@@ -0,0 +1,54 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+import SwiftUI
+
+struct ClusterSelectorView: View {
+    var body: some View {
+        VStack(alignment: .leading) {
+            NavigationLink(
+                destination: ContentLauncherView(),
+                label: {
+                    Text("Content Launcher")
+                        .frame(width: 300, height: 30, alignment: .center)
+                        .border(Color.black, width: 1)
+                }
+            ).background(Color.blue)
+                .foregroundColor(Color.white)
+                .padding()
+            
+            NavigationLink(
+                destination: MediaPlayerView(),
+                label: {
+                    Text("Media Playback")
+                        .frame(width: 300, height: 30, alignment: .center)
+                        .border(Color.black, width: 1)
+                }
+            ).background(Color.blue)
+                .foregroundColor(Color.white)
+                .padding()
+        }
+        .navigationTitle("Cluster selection")
+        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top)
+    }
+}
+
+struct ClusterSelectorView_Previews: PreviewProvider {
+    static var previews: some View {
+        ClusterSelectorView()
+    }
+}
diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift
index b246a3bda45e50..23cee1eb7d341b 100644
--- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift
+++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningView.swift
@@ -66,7 +66,7 @@ struct CommissioningView: View {
             {
                 Text("Commissioning finished!").padding()
                 NavigationLink(
-                    destination: ContentLauncherView(),
+                    destination: ClusterSelectorView(),
                     label: {
                         Text("Next")
                             .frame(width: 100, height: 30, alignment: .center)
diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift
index 3f2d4404d3aa81..5af7d263133557 100644
--- a/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift
+++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/CommissioningViewModel.swift
@@ -45,9 +45,7 @@ class CommissioningViewModel: ObservableObject {
                     self.commisisoningWindowOpened = result
                 })
         }
-        
-        // TBD: Get Onboarding payload
-        
+                
         // Send User directed commissioning request if a commissioner with a known IP addr was selected
         if(selectedCommissioner != nil && selectedCommissioner!.numIPs > 0)
         {
diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift
new file mode 100644
index 00000000000000..296b0a78607f9a
--- /dev/null
+++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerView.swift
@@ -0,0 +1,76 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+import SwiftUI
+
+struct MediaPlayerView: View {
+    @StateObject var viewModel = MediaPlayerViewModel()
+
+    @State private var minIntervalStr: String = ""
+    @State private var maxIntervalStr: String = ""
+    
+    var body: some View {
+        VStack(alignment: .leading) {
+            Text("Subscribe to Current State")
+            
+            HStack() {
+                Text("Min Interval")
+                
+                TextField(
+                    "0",
+                    text: $minIntervalStr
+                )
+                .textInputAutocapitalization(.never)
+                .disableAutocorrection(true)
+                .border(.secondary)
+            }
+            
+            HStack() {
+                Text("Max Interval")
+                
+                TextField(
+                    "10",
+                    text: $maxIntervalStr
+                )
+                .textInputAutocapitalization(.never)
+                .disableAutocorrection(true)
+                .border(.secondary)
+            }
+            
+            Button("Subscribe!") {
+                viewModel.subscribeCurrentState(minInterval: minIntervalStr, maxInterval: maxIntervalStr)
+            }
+            .background(Color.blue)
+            .foregroundColor(Color.white)
+            .cornerRadius(4)
+            .border(Color.black, width: 1)
+            .padding()
+            
+            Text(viewModel.requestStatus ?? "")
+            Text(viewModel.subscriptionStatus ?? "")
+            Text(viewModel.readResponse ?? "")
+        }
+        .navigationTitle("Media Playback")
+        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .top)
+    }
+}
+
+struct MediaPlayerView_Previews: PreviewProvider {
+    static var previews: some View {
+        MediaPlayerView()
+    }
+}
diff --git a/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift
new file mode 100644
index 00000000000000..d401d3f5247d5b
--- /dev/null
+++ b/examples/tv-casting-app/darwin/TvCasting/TvCasting/MediaPlayerViewModel.swift
@@ -0,0 +1,77 @@
+/**
+ *
+ *    Copyright (c) 2020-2022 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+
+import Foundation
+import os.log
+
+class MediaPlayerViewModel: ObservableObject {
+    let Log = Logger(subsystem: "com.matter.casting",
+                     category: "MediaPlayerViewModel")
+    
+    @Published var requestStatus: String?;
+    @Published var subscriptionStatus: String?;
+    @Published var readResponse: String?;
+
+    func subscribeCurrentState(minInterval: String, maxInterval: String)
+    {
+            if let castingServerBridge = CastingServerBridge.getSharedInstance()
+            {
+                castingServerBridge.mediaPlayback_subscribeCurrentState(UInt16(minInterval) ?? 0, maxInterval: UInt16(maxInterval) ?? 10, clientQueue: DispatchQueue.main,
+                                    requestSentHandler: { (result: MatterError) -> () in
+                                        self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.requestSentHandler result \(result)")
+                                        self.requestStatus = result.code == 0 ? "Subscribe request sent!" : "Failed to send Subscribe request!"
+                                    },
+                                    successCallback: { (result: MediaPlayback_PlaybackState) -> () in
+                                        DispatchQueue.main.async {
+                                            self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.successCallback called")
+                                            switch(result)
+                                            {
+                                            case .Playing:
+                                                self.readResponse = "Current state: Playing"
+                                                break
+                                            case .Paused:
+                                                self.readResponse = "Current state: Paused"
+                                                break
+                                            case .NotPlaying:
+                                                self.readResponse = "Current state: NotPlaying"
+                                                break
+                                            case .Buffering:
+                                                self.readResponse = "Current state: Buffering"
+                                                break
+                                            default:
+                                                self.readResponse = "Current state: Unknown!"
+                                                break
+                                            }
+                                        }
+                                    },
+                                    failureCallback: { (result: MatterError) -> () in
+                                        DispatchQueue.main.async {
+                                                self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.failureCallback called with \(result)")
+                                                self.readResponse = "Attribute read failure!"
+                                        }
+                                    },
+                                    subscriptionEstablishedCallback: { () -> () in
+                                        DispatchQueue.main.async {
+                                                self.Log.info("MediaPlayerViewModel.subscribeToCurrentState.subscriptionEstablishedCallback called")
+                                                self.subscriptionStatus = "Subscription established!"
+                                        }
+                                    }
+                    )
+            }
+    }
+}