diff --git a/rust/bt-ascs/src/client.rs b/rust/bt-ascs/src/client.rs
index 6b7fac7..b20abb4 100644
--- a/rust/bt-ascs/src/client.rs
+++ b/rust/bt-ascs/src/client.rs
@@ -38,6 +38,8 @@
     InvalidStartState { ase_id: AseId, opcode: AseControlPointOpcode, actual: AseState },
     #[error("Remote server rejected operation: {0:?}")]
     RejectedOperation(Vec<ResponseCode>),
+    #[error("ASE {ase_id:?} has invalid direction {direction:?} for opcode {opcode:?}")]
+    InvalidDirection { ase_id: AseId, opcode: AseControlPointOpcode, direction: AudioDirection },
 }
 
 /// Represents a single source/sink ASE state characteristic.
@@ -276,6 +278,8 @@
         Ok(DiscoveredEndpoints { sink: sink_endpoints, source: source_endpoints })
     }
 
+    /// Reads the current value of an ASE characteristic from the remote server
+    /// and decodes it into an [`AudioStreamEndpoint`].
     async fn read_and_create_endpoint(
         gatt_client: &T::PeerService,
         handle: Handle,
@@ -294,35 +298,28 @@
         Ok(endpoint)
     }
 
-    fn verify_ase_ids<I>(&self, ase_ids: I) -> Result<(), Error>
-    where
-        I: IntoIterator<Item = AseId>,
-    {
-        for ase_id in ase_ids {
-            if self.endpoints.lookup_by_ase_id(ase_id).is_none() {
-                return Err(Error::Client(ClientError::UnknownAseId(ase_id)));
-            }
-        }
-        Ok(())
-    }
-
-    fn validate_arguments(
+    /// Validates that the target ASE IDs are known to this client and that
+    /// the requested `opcode` is allowed in their current state according
+    /// to the ASCS state machine.
+    ///
+    /// Returns `Ok(())` if validation passes, or a `ClientError` (such as
+    /// `UnknownAseId` or `InvalidStartState`) if any target ASE fails
+    /// validation.
+    fn validate_arguments<'a>(
         &mut self,
         opcode: AseControlPointOpcode,
-        pending_ases: &HashSet<AseId>,
+        pending_ases: impl IntoIterator<Item = &'a AseId>,
     ) -> Result<(), Error> {
-        self.verify_ase_ids(pending_ases.iter().cloned())?;
-
-        for ase_id in pending_ases {
+        for &ase_id in pending_ases {
             let endpoint = &self
                 .endpoints
-                .lookup_by_ase_id(*ase_id)
-                .ok_or(Error::Client(ClientError::UnknownAseId(*ase_id)))?
+                .lookup_by_ase_id(ase_id)
+                .ok_or(Error::Client(ClientError::UnknownAseId(ase_id)))?
                 .endpoint;
 
             if !opcode.allowed_in_state(&endpoint.state) {
                 return Err(Error::Client(ClientError::InvalidStartState {
-                    ase_id: *ase_id,
+                    ase_id,
                     opcode,
                     actual: endpoint.state,
                 }));
@@ -331,19 +328,8 @@
         Ok(())
     }
 
-    /// Reads the current value of an ASE characteristic from the remote server,
-    /// decodes it as an [`AudioStreamEndpoint`], updates the local cache of
-    /// sink or source endpoints, and returns the updated endpoint.
-    ///
-    /// # Arguments
-    /// * `handle` - The GATT characteristic handle of the ASE to read.
-    /// * `direction` - The direction (Sink or Source) of the ASE.
-    ///
-    /// # Returns
-    /// * `Ok(AudioStreamEndpoint)` - The newly read and updated endpoint
-    ///   struct.
-    /// * `Err(Error)` - If reading from the GATT client fails, or if the read
-    ///   value cannot be decoded.
+    /// Encodes an ASE control operation and writes it to the ASE Control Point
+    /// characteristic.
     async fn write_operation(&mut self, operation: &AseControlOperation) -> Result<(), Error> {
         use bt_common::packet_encoding::Encodable;
 
@@ -468,21 +454,13 @@
 
     /// Performs the Configure Codec operation on one or more ASEs.
     ///
-    /// This method sends the Configure Codec request to the remote server,
-    /// waits for control point notifications for all involved ASEs, and
-    /// verifies that the successfully configured ASEs have transitioned to
-    /// the `CodecConfigured` state.
-    ///
     /// # Arguments
     /// * `codec_configurations` - A vector of `CodecConfiguration` structs
     ///   containing the parameters for each ASE to be configured.
     ///
     /// # Returns
-    /// On success, returns a tuple containing:
-    /// * A `HashMap` mapping each successfully configured `AseId` to its
-    ///   supported `QosParameters` published by the server.
-    /// * A `Vec` containing the `ResponseCode` for any ASEs where the
-    ///   configuration failed.
+    /// On success, returns an [`AseControlOperationOutcome`] containing the
+    /// results of the operation.
     pub async fn configure_codec(
         &mut self,
         codec_configurations: Vec<CodecConfiguration>,
@@ -497,32 +475,13 @@
 
     /// Performs the Configure QoS operation on one or more ASEs.
     ///
-    /// This method sends the Configure QoS request to the remote server,
-    /// waits for control point notifications for all involved ASEs, and
-    /// verifies that the successfully configured ASEs have transitioned to
-    /// the `QosConfigured` state.
-    ///
-    /// # Arguments
-    /// * `qos_configurations` - A vector of `QosConfiguration` structs
-    ///   containing the QoS parameters for each ASE.
-    ///
-    /// # Returns
-    /// On success, returns a `Vec<ResponseCode>` containing the response
-    /// codes for any ASEs where the configuration failed.
-    /// Performs the Configure QoS operation on one or more ASEs.
-    ///
-    /// This method sends the Configure QoS request to the remote server,
-    /// waits for control point notifications for all involved ASEs, and
-    /// verifies that the successfully configured ASEs have transitioned to
-    /// the `QosConfigured` state.
-    ///
     /// # Arguments
     /// * `requests` - A vector of `QosConfigurationRequest` enums specifying
     ///   either custom or server-preferred configurations for each ASE.
     ///
     /// # Returns
-    /// On success, returns a `Vec<ResponseCode>` containing the response
-    /// codes for any ASEs where the configuration failed.
+    /// On success, returns an [`AseControlOperationOutcome`] containing the
+    /// results of the operation.
     pub async fn configure_qos(
         &mut self,
         requests: Vec<QosConfigurationRequest>,
@@ -545,18 +504,13 @@
 
     /// Performs the Enable operation on one or more ASEs.
     ///
-    /// This method sends the Enable request to the remote server,
-    /// waits for control point notifications for all involved ASEs, and
-    /// verifies that the successfully enabled ASEs have transitioned to
-    /// the `Enabling` state.
-    ///
     /// # Arguments
     /// * `ases_with_metadata` - A vector of `AseIdWithMetadata` structs
     ///   specifying the target ASE IDs and their codec metadata.
     ///
     /// # Returns
-    /// On success, returns a `Vec<ResponseCode>` containing the response
-    /// codes for any ASEs where the enable operation failed.
+    /// On success, returns an [`AseControlOperationOutcome`] containing the
+    /// results of the operation.
     pub async fn enable(
         &mut self,
         ases_with_metadata: Vec<AseIdWithMetadata>,
@@ -568,6 +522,40 @@
 
         self.perform_and_verify_operation(op, pending_ases).await
     }
+
+    /// Performs the Receiver Start Ready operation on one or more Source ASEs.
+    ///
+    /// # Arguments
+    /// * `ases` - A vector of `AseId`s to start.
+    ///
+    /// # Returns
+    /// On success, returns an [`AseControlOperationOutcome`] containing the
+    /// results of the operation.
+    pub async fn receiver_start_ready(
+        &mut self,
+        ases: Vec<AseId>,
+    ) -> Result<AseControlOperationOutcome, Error> {
+        let pending_ases: HashSet<AseId> = ases.iter().cloned().collect();
+        self.validate_arguments(AseControlPointOpcode::ReceiverStartReady, &pending_ases)?;
+
+        for ase_id in &pending_ases {
+            let endpoint = self
+                .endpoints
+                .lookup_by_ase_id(*ase_id)
+                .expect("ASE ID verified by validate_arguments");
+            if endpoint.endpoint.direction != AudioDirection::Source {
+                return Err(Error::Client(ClientError::InvalidDirection {
+                    ase_id: *ase_id,
+                    opcode: AseControlPointOpcode::ReceiverStartReady,
+                    direction: endpoint.endpoint.direction,
+                }));
+            }
+        }
+
+        let op = AseControlOperation::ReceiverStartReady { ases };
+
+        self.perform_and_verify_operation(op, pending_ases).await
+    }
 }
 
 #[cfg(test)]
@@ -1378,4 +1366,182 @@
             })
         ));
     }
+
+    #[test]
+    fn receiver_start_ready_success() {
+        let mut service = setup_fake_service();
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service.clone());
+        let mut client = run_to_completion(client_fut).expect("client creation should succeed");
+
+        // Pre-condition SOURCE_ASE_HANDLE to Enabling state
+        let source_value = vec![
+            0x02, // ASE ID: 2
+            0x03, // ASE State: Enabling
+            0x01, 0x01, 0x00,
+        ];
+        client.endpoints.source.get_mut(&SOURCE_ASE_HANDLE).unwrap().endpoint =
+            AudioStreamEndpoint::from_char_value(
+                SOURCE_ASE_HANDLE,
+                AudioDirection::Source,
+                &source_value,
+            )
+            .unwrap();
+
+        #[rustfmt::skip]
+        service.expect_characteristic_value(
+            &CONTROL_POINT_HANDLE,
+            vec![
+                0x04, // Opcode: Receiver Start Ready
+                0x01, // Num ASEs
+                0x02, // ASE ID: 2
+            ],
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &CONTROL_POINT_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: CONTROL_POINT_HANDLE,
+                value: vec![
+                    0x04, // Opcode: Receiver Start Ready
+                    0x01, // Num ASEs
+                    0x02, 0x00, 0x00, // ASE ID: 2, Success
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &SOURCE_ASE_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: SOURCE_ASE_HANDLE,
+                value: vec![
+                    0x02, // ASE ID: 2
+                    0x04, // ASE State: Streaming
+                    0x01, // CIG ID: 1
+                    0x01, // CIS ID: 1
+                    0x00, // Metadata Length: 0
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        let start_fut = client.receiver_start_ready(vec![AseId(2)]);
+        let outcome = run_to_completion(start_fut).expect("receiver start ready should succeed");
+
+        assert_eq!(outcome.rejected().len(), 0);
+        assert_eq!(client.endpoints.source[&SOURCE_ASE_HANDLE].endpoint.state, AseState::Streaming);
+    }
+
+    #[test]
+    fn receiver_start_ready_fail_invalid_start_state() {
+        let service = setup_fake_service();
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service.clone());
+        let mut client = run_to_completion(client_fut).expect("client creation should succeed");
+
+        // ASE 2 (Source) is in Idle state, which is invalid for ReceiverStartReady
+        let start_fut = client.receiver_start_ready(vec![AseId(2)]);
+        let err = run_to_completion(start_fut).expect_err("should fail client-side validation");
+
+        assert!(matches!(
+            err,
+            Error::Client(ClientError::InvalidStartState {
+                ase_id: AseId(2),
+                opcode: AseControlPointOpcode::ReceiverStartReady,
+                actual: AseState::Idle,
+            })
+        ));
+    }
+
+    #[test]
+    fn receiver_start_ready_fail_invalid_direction() {
+        let service = setup_fake_service();
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service.clone());
+        let mut client = run_to_completion(client_fut).expect("client creation should succeed");
+
+        // Pre-condition SINK_ASE_HANDLE (ASE 1) to Enabling state
+        let sink_value = vec![
+            0x01, // ASE ID: 1
+            0x03, // ASE State: Enabling
+            0x01, 0x01, 0x00,
+        ];
+        client.endpoints.sink.get_mut(&SINK_ASE_HANDLE).unwrap().endpoint =
+            AudioStreamEndpoint::from_char_value(
+                SINK_ASE_HANDLE,
+                AudioDirection::Sink,
+                &sink_value,
+            )
+            .unwrap();
+
+        let start_fut = client.receiver_start_ready(vec![AseId(1)]);
+        let err = run_to_completion(start_fut).expect_err("should fail client-side validation");
+
+        assert!(matches!(
+            err,
+            Error::Client(ClientError::InvalidDirection {
+                ase_id: AseId(1),
+                opcode: AseControlPointOpcode::ReceiverStartReady,
+                direction: AudioDirection::Sink,
+            })
+        ));
+    }
+
+    #[test]
+    fn receiver_start_ready_rejected() {
+        let mut service = setup_fake_service();
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service.clone());
+        let mut client = run_to_completion(client_fut).expect("client creation should succeed");
+
+        // Pre-condition SOURCE_ASE_HANDLE to Enabling state
+        let source_value = vec![
+            0x02, // ASE ID: 2
+            0x03, // ASE State: Enabling
+            0x01, 0x01, 0x00,
+        ];
+        client.endpoints.source.get_mut(&SOURCE_ASE_HANDLE).unwrap().endpoint =
+            AudioStreamEndpoint::from_char_value(
+                SOURCE_ASE_HANDLE,
+                AudioDirection::Source,
+                &source_value,
+            )
+            .unwrap();
+
+        #[rustfmt::skip]
+        service.expect_characteristic_value(
+            &CONTROL_POINT_HANDLE,
+            vec![
+                0x04, // Opcode: Receiver Start Ready
+                0x01, // Num ASEs
+                0x02, // ASE ID: 2
+            ],
+        );
+
+        // Notify rejection from server due to Insufficient Resources (Response Code
+        // 0x0D)
+        #[rustfmt::skip]
+        service.notify(
+            &CONTROL_POINT_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: CONTROL_POINT_HANDLE,
+                value: vec![
+                    0x04, // Opcode: Receiver Start Ready
+                    0x01, // Num ASEs
+                    0x02, 0x0D, 0x00, // ASE ID: 2, Insufficient Resources
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        let start_fut = client.receiver_start_ready(vec![AseId(2)]);
+        let outcome = run_to_completion(start_fut).expect("receiver start ready should succeed");
+
+        assert_eq!(outcome.rejected().len(), 1);
+        assert_eq!(
+            outcome.rejected()[&AseId(2)],
+            ResponseCode::InsufficientResources { ase_id: AseId(2) }
+        );
+        // The state should remain Enabling
+        assert_eq!(client.endpoints.source[&SOURCE_ASE_HANDLE].endpoint.state, AseState::Enabling);
+    }
 }
