diff --git a/rust/bt-ascs/src/client.rs b/rust/bt-ascs/src/client.rs
index 691f15a..90a64c4 100644
--- a/rust/bt-ascs/src/client.rs
+++ b/rust/bt-ascs/src/client.rs
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use futures::stream::{BoxStream, StreamExt};
+use futures::stream::{BoxStream, FuturesUnordered, StreamExt};
 use std::collections::{HashMap, HashSet};
 
 use bt_common::packet_encoding::Decodable;
@@ -36,6 +36,8 @@
     UnknownAseId(AseId),
     #[error("ASE {ase_id:?} is in invalid starting state {actual:?} for opcode {opcode:?}")]
     InvalidStartState { ase_id: AseId, opcode: AseControlPointOpcode, actual: AseState },
+    #[error("Remote server rejected operation: {0:?}")]
+    RejectedOperation(Vec<ResponseCode>),
 }
 
 /// Represents a single source/sink ASE state characteristic.
@@ -45,6 +47,88 @@
         BoxStream<'static, Result<CharacteristicNotification, bt_gatt::types::Error>>,
 }
 
+impl ClientEndpoint {
+    pub async fn next_update(&mut self) -> Result<(AseId, AudioStreamEndpoint), Error> {
+        let notification = self
+            .notification_stream
+            .next()
+            .await
+            .ok_or(Error::Client(ClientError::NotificationStreamClosed))??;
+        let new_endpoint = AudioStreamEndpoint::from_char_value(
+            self.endpoint.handle,
+            self.endpoint.direction,
+            &notification.value[..],
+        )
+        .map_err(|e| {
+            bt_gatt::types::Error::Conversion(format!(
+                "Failed to decode AudioStreamEndpoint: {:?}",
+                e
+            ))
+        })?;
+        Ok((self.endpoint.ase_id, new_endpoint))
+    }
+}
+
+/// Represents a client request to configure QoS parameters on an ASE.
+#[derive(Debug, Clone, PartialEq)]
+pub enum QosConfigurationRequest {
+    /// Completely custom QoS configuration parameters.
+    Custom(QosConfiguration),
+
+    /// Automatically derive constraint parameters (framing, PHYs,
+    /// retransmissions, latency, presentation delay) from the server's
+    /// published preferred parameters in the local cache, only requiring
+    /// the host-allocated dynamic properties.
+    Preferred {
+        ase_id: AseId,
+        cig_id: CigId,
+        cis_id: CisId,
+        sdu_interval: SduInterval,
+        max_sdu: MaxSdu,
+    },
+}
+
+impl QosConfigurationRequest {
+    pub fn try_into_config<T: bt_gatt::GattTypes>(
+        self,
+        client: &AudioStreamControlServiceClient<T>,
+    ) -> Result<QosConfiguration, Error> {
+        match self {
+            Self::Custom(c) => Ok(c),
+            Self::Preferred { ase_id, cig_id, cis_id, sdu_interval, max_sdu } => {
+                let endpoint = &client
+                    .endpoints
+                    .lookup_by_ase_id(ase_id)
+                    .ok_or(Error::Client(ClientError::UnknownAseId(ase_id)))?
+                    .endpoint;
+
+                let params = endpoint.qos_parameters().ok_or(Error::Client(
+                    ClientError::InvalidStartState {
+                        ase_id,
+                        opcode: AseControlPointOpcode::ConfigQos,
+                        actual: endpoint.state,
+                    },
+                ))?;
+
+                let presentation_delay = params.presentation_delay_range.min().clone();
+
+                Ok(QosConfiguration {
+                    ase_id,
+                    cig_id,
+                    cis_id,
+                    sdu_interval,
+                    framing: params.framing,
+                    phy: params.preferred_phys.clone(),
+                    max_sdu,
+                    retransmission_number: params.preferred_retransmission_number,
+                    max_transport_latency: params.max_transport_latency,
+                    presentation_delay,
+                })
+            }
+        }
+    }
+}
+
 // See ASCS v1.0.1 4.2 for details.
 pub struct AseControlPoint {
     pub handle: Handle,
@@ -84,6 +168,16 @@
         }
         None
     }
+
+    pub(crate) fn lookup_by_ase_id_mut(&mut self, ase_id: AseId) -> Option<&mut ClientEndpoint> {
+        if let Some(e) = self.sink.values_mut().find(|e| e.endpoint.ase_id == ase_id) {
+            return Some(e);
+        }
+        if let Some(e) = self.source.values_mut().find(|e| e.endpoint.ase_id == ase_id) {
+            return Some(e);
+        }
+        None
+    }
 }
 
 /// The outcome of an ASE control point operation, partitioning successfully
@@ -192,9 +286,9 @@
             gatt_client.read_characteristic(&handle, 0, &mut buf[..]).await.map_err(Error::Gatt)?;
         let endpoint = AudioStreamEndpoint::from_char_value(handle, direction, &buf[0..read_bytes])
             .map_err(|e| {
-                bt_gatt::types::Error::other(std::io::Error::new(
-                    std::io::ErrorKind::InvalidData,
-                    format!("Failed to decode AudioStreamEndpoint: {:?}", e),
+                bt_gatt::types::Error::Conversion(format!(
+                    "Failed to decode AudioStreamEndpoint: {:?}",
+                    e
                 ))
             })?;
         Ok(endpoint)
@@ -212,37 +306,44 @@
         Ok(())
     }
 
-    async fn read_and_update_endpoint(
+    fn validate_arguments(
         &mut self,
-        handle: &Handle,
-        direction: AudioDirection,
-    ) -> Result<AudioStreamEndpoint, Error> {
-        let mut buf = vec![0; 255];
-        let (read_bytes, _truncated) = self
-            .gatt_client
-            .read_characteristic(handle, 0, &mut buf[..])
-            .await
-            .map_err(Error::Gatt)?;
-        let endpoint =
-            AudioStreamEndpoint::from_char_value(*handle, direction, &buf[0..read_bytes]).map_err(
-                |e| {
-                    bt_gatt::types::Error::other(std::io::Error::new(
-                        std::io::ErrorKind::InvalidData,
-                        format!("Failed to decode AudioStreamEndpoint: {:?}", e),
-                    ))
-                },
-            )?;
+        opcode: AseControlPointOpcode,
+        pending_ases: &HashSet<AseId>,
+    ) -> Result<(), Error> {
+        self.verify_ase_ids(pending_ases.iter().cloned())?;
 
-        let endpoints = match direction {
-            AudioDirection::Sink => &mut self.endpoints.sink,
-            AudioDirection::Source => &mut self.endpoints.source,
-        };
-        if let Some(endpoint_handle) = endpoints.get_mut(handle) {
-            endpoint_handle.endpoint = endpoint.clone();
+        for ase_id in pending_ases {
+            let endpoint = &self
+                .endpoints
+                .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,
+                    opcode,
+                    actual: endpoint.state,
+                }));
+            }
         }
-        Ok(endpoint)
+        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.
     async fn write_operation(&mut self, operation: &AseControlOperation) -> Result<(), Error> {
         use bt_common::packet_encoding::Encodable;
 
@@ -279,20 +380,14 @@
             let notification = notification.map_err(Error::from)?;
 
             let (cp_notification, _) = ControlPointNotification::decode(&notification.value[..]);
-            let cp_notification = cp_notification.map_err(|e| {
-                bt_gatt::types::Error::other(std::io::Error::new(
-                    std::io::ErrorKind::InvalidData,
-                    format!("Failed to decode ControlPointNotification: {:?}", e),
-                ))
-            })?;
+            let cp_notification = cp_notification.map_err(bt_gatt::types::Error::Encoding)?;
             if cp_notification.opcode != opcode {
                 continue;
             }
 
             if cp_notification.number_of_ases == 0xFF {
-                return Err(Error::Internal(format!(
-                    "Server rejected operation: {:?}",
-                    cp_notification.responses
+                return Err(Error::Client(ClientError::RejectedOperation(
+                    cp_notification.responses,
                 )));
             }
 
@@ -317,25 +412,46 @@
         let responses = self.collect_operation_responses(opcode_u8, pending_ases).await?;
 
         let mut successful_endpoints = HashMap::new();
-        let mut failed_responses = HashMap::new();
         let opcode = AseControlPointOpcode::try_from(&operation).map_err(|e| {
             Error::Internal(format!("Failed to resolve opcode from operation: {:?}", e))
         })?;
 
-        for r in responses.into_values() {
-            if !r.is_success() {
-                failed_responses.insert(r.ase_id(), r);
-                continue;
+        let (successful, failed_responses): (
+            HashMap<AseId, ResponseCode>,
+            HashMap<AseId, ResponseCode>,
+        ) = responses.into_iter().partition(|(_, r)| r.is_success());
+
+        let successful_ases: HashSet<AseId> = successful.keys().cloned().collect();
+
+        if successful_ases.is_empty() {
+            return Ok(AseControlOperationOutcome::new(HashMap::new(), failed_responses));
+        }
+
+        let updated_endpoints = {
+            let mut notification_futures = FuturesUnordered::new();
+            for endpoint in
+                self.endpoints.sink.values_mut().chain(self.endpoints.source.values_mut())
+            {
+                if !successful_ases.contains(&endpoint.endpoint.ase_id) {
+                    continue;
+                }
+                notification_futures.push(endpoint.next_update());
             }
-            let client_endpoint = self
-                .endpoints
-                .lookup_by_ase_id(r.ase_id())
-                .ok_or(Error::Client(ClientError::UnknownAseId(r.ase_id())))?;
-            let handle = client_endpoint.endpoint.handle;
-            let direction = client_endpoint.endpoint.direction;
 
-            let endpoint = self.read_and_update_endpoint(&handle, direction).await?;
+            let mut updated_endpoints = Vec::with_capacity(successful_ases.len());
+            while let Some(res) = notification_futures.next().await {
+                updated_endpoints.push(res?);
+            }
+            updated_endpoints
+        };
 
+        for (ase_id, endpoint) in &updated_endpoints {
+            if let Some(client_endpoint) = self.endpoints.lookup_by_ase_id_mut(*ase_id) {
+                client_endpoint.endpoint = endpoint.clone();
+            }
+        }
+
+        for (ase_id, endpoint) in updated_endpoints {
             if !opcode.allows_transition_to(endpoint.direction, &endpoint.state) {
                 let expected = opcode.operation_target_states(endpoint.direction)[0];
                 return Err(Error::Client(ClientError::UnexpectedStateTransition {
@@ -344,7 +460,7 @@
                     actual: endpoint.state,
                 }));
             }
-            successful_endpoints.insert(endpoint.ase_id, endpoint);
+            successful_endpoints.insert(ase_id, endpoint);
         }
 
         Ok(AseControlOperationOutcome::new(successful_endpoints, failed_responses))
@@ -372,12 +488,60 @@
         codec_configurations: Vec<CodecConfiguration>,
     ) -> Result<AseControlOperationOutcome, Error> {
         let pending_ases: HashSet<AseId> = codec_configurations.iter().map(|c| c.ase_id).collect();
-        self.verify_ase_ids(pending_ases.iter().cloned())?;
+        self.validate_arguments(AseControlPointOpcode::ConfigCodec, &pending_ases)?;
 
         let op = AseControlOperation::ConfigCodec { codec_configurations, responses: vec![] };
 
         self.perform_and_verify_operation(op, pending_ases).await
     }
+
+    /// 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.
+    pub async fn configure_qos(
+        &mut self,
+        requests: Vec<QosConfigurationRequest>,
+    ) -> Result<AseControlOperationOutcome, Error> {
+        let qos_configurations: Vec<QosConfiguration> = requests
+            .into_iter()
+            .map(|req| req.try_into_config(self))
+            .collect::<Result<Vec<_>, Error>>()?;
+
+        let pending_ases: HashSet<AseId> = qos_configurations.iter().map(|q| q.ase_id).collect();
+        self.validate_arguments(AseControlPointOpcode::ConfigQos, &pending_ases)?;
+
+        // TODO(b/431814103): Consider ATT MTU limits when configuring multiple ASEs.
+        // If the encoded request exceeds the current MTU, we may need to break it into
+        // multiple Control Point writes.
+        let op = AseControlOperation::ConfigQos { qos_configurations, responses: vec![] };
+
+        self.perform_and_verify_operation(op, pending_ases).await
+    }
 }
 
 #[cfg(test)]
@@ -593,20 +757,18 @@
         );
 
         #[rustfmt::skip]
-        service.add_characteristic(
-            Characteristic {
+        service.notify(
+            &SINK_ASE_HANDLE,
+            Ok(CharacteristicNotification {
                 handle: SINK_ASE_HANDLE,
-                uuid: SINK_ASE_UUID,
-                properties: CharacteristicProperty::Read | CharacteristicProperty::Notify,
-                permissions: AttributePermissions::default(),
-                descriptors: vec![],
-            },
-            vec![
-                0x01, // ASE ID: 1
-                0x01, // ASE State: Codec Configured
-                0x00, 0x01, 0x02, 0x0A, 0x00, 0x10, 0x27, 0x00, 0x40, 0x9C, 0x00,
-                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
-            ],
+                value: vec![
+                    0x01, // ASE ID: 1
+                    0x01, // ASE State: Codec Configured
+                    0x00, 0x01, 0x02, 0x0A, 0x00, 0x10, 0x27, 0x00, 0x40, 0x9C, 0x00,
+                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+                ],
+                maybe_truncated: false,
+            }),
         );
 
         let configure_fut = client.configure_codec(vec![config1, config2]);
@@ -692,7 +854,394 @@
 
         assert!(matches!(
             err,
-            Error::Internal(ref s) if s.contains("Server rejected operation") && s.contains("InvalidLength")
+            Error::Client(ClientError::RejectedOperation(ref responses)) if matches!(
+                responses.as_slice(),
+                [ResponseCode::InvalidLength { .. }]
+            )
         ));
     }
+
+    #[test]
+    fn configure_qos_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 both Sink and Source endpoints to CodecConfigured with valid
+        // QoS constraints
+        let sink_value = vec![
+            0x01, // ASE ID: 1
+            0x01, // ASE State: Codec Configured
+            0x00, 0x01, 0x02, 0x0A, 0x00, 0x10, 0x27, 0x00, 0x40, 0x9C, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+        ];
+        client.endpoints.sink.get_mut(&SINK_ASE_HANDLE).unwrap().endpoint =
+            AudioStreamEndpoint::from_char_value(
+                SINK_ASE_HANDLE,
+                AudioDirection::Sink,
+                &sink_value,
+            )
+            .unwrap();
+
+        let source_value = vec![
+            0x02, // ASE ID: 2
+            0x01, // ASE State: Codec Configured
+            0x00, 0x01, 0x02, 0x0A, 0x00, 0x10, 0x27, 0x00, 0x40, 0x9C, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+        ];
+        client.endpoints.source.get_mut(&SOURCE_ASE_HANDLE).unwrap().endpoint =
+            AudioStreamEndpoint::from_char_value(
+                SOURCE_ASE_HANDLE,
+                AudioDirection::Source,
+                &source_value,
+            )
+            .unwrap();
+
+        // Request 1 (Preferred): Resolves constraints for AseId(1) from the cache
+        let req1 = QosConfigurationRequest::Preferred {
+            ase_id: AseId(1),
+            cig_id: CigId::try_from(1).unwrap(),
+            cis_id: CisId::try_from(1).unwrap(),
+            sdu_interval: SduInterval::try_from(std::time::Duration::from_micros(10000)).unwrap(),
+            max_sdu: MaxSdu::try_from(100).unwrap(),
+        };
+
+        // Request 2 (Custom): Custom configuration for AseId(2)
+        let req2 = QosConfigurationRequest::Custom(QosConfiguration {
+            ase_id: AseId(2),
+            cig_id: CigId::try_from(1).unwrap(),
+            cis_id: CisId::try_from(2).unwrap(),
+            sdu_interval: SduInterval::try_from(std::time::Duration::from_micros(10000)).unwrap(),
+            framing: Framing::Unframed,
+            phy: vec![Phy::Le1MPhy],
+            max_sdu: MaxSdu::try_from(100).unwrap(),
+            retransmission_number: 2,
+            max_transport_latency: MaxTransportLatency::try_from(std::time::Duration::from_millis(
+                10,
+            ))
+            .unwrap(),
+            presentation_delay: PresentationDelay { microseconds: 40000 },
+        });
+
+        #[rustfmt::skip]
+        service.expect_characteristic_value(
+            &CONTROL_POINT_HANDLE,
+            vec![
+                0x02, // Opcode: Config QoS
+                0x02, // Num ASEs: 2
+                0x01, // ASE ID: 1
+                0x01, 0x01, 0x10, 0x27, 0x00, 0x00, 0x01, 0x64, 0x00, 0x02, 0x0A, 0x00, 0x10, 0x27, 0x00, // ASE 1 Preferred QoS
+                0x02, // ASE ID: 2
+                0x01, 0x02, 0x10, 0x27, 0x00, 0x00, 0x01, 0x64, 0x00, 0x02, 0x0A, 0x00, 0x40, 0x9C, 0x00, // ASE 2 Custom QoS
+            ],
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &CONTROL_POINT_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: CONTROL_POINT_HANDLE,
+                value: vec![
+                    0x02, // Opcode: Config QoS
+                    0x02, // Num ASEs: 2
+                    0x01, 0x00, 0x00, // ASE ID: 1, Success
+                    0x02, 0x00, 0x00, // ASE ID: 2, Success
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &SINK_ASE_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: SINK_ASE_HANDLE,
+                value: vec![
+                    0x01, // ASE ID: 1
+                    0x02, // ASE State: QoS Configured
+                    0x01, 0x01, 0x10, 0x27, 0x00, 0x00, 0x01, 0x64, 0x00, 0x02, 0x0A, 0x00, 0x40, 0x9C, 0x00,
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &SOURCE_ASE_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: SOURCE_ASE_HANDLE,
+                value: vec![
+                    0x02, // ASE ID: 2
+                    0x02, // ASE State: QoS Configured
+                    0x01, 0x02, 0x10, 0x27, 0x00, 0x00, 0x01, 0x64, 0x00, 0x02, 0x0A, 0x00, 0x40, 0x9C, 0x00,
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        let configure_qos_fut = client.configure_qos(vec![req1, req2]);
+        let outcome = run_to_completion(configure_qos_fut).expect("configure QoS should succeed");
+
+        assert_eq!(outcome.rejected().len(), 0);
+        assert_eq!(client.endpoints.sink[&SINK_ASE_HANDLE].endpoint.state, AseState::QosConfigured);
+        assert_eq!(
+            client.endpoints.source[&SOURCE_ASE_HANDLE].endpoint.state,
+            AseState::QosConfigured
+        );
+    }
+
+    #[test]
+    fn configure_qos_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");
+
+        // Transition the sink ASE to Streaming state to test client-side validation.
+        let streaming_value = vec![
+            0x01, // ASE ID: 1
+            0x04, // ASE State: Streaming
+            0x01, 0x01, 0x00,
+        ];
+        client.endpoints.sink.get_mut(&SINK_ASE_HANDLE).unwrap().endpoint =
+            AudioStreamEndpoint::from_char_value(
+                SINK_ASE_HANDLE,
+                AudioDirection::Sink,
+                &streaming_value,
+            )
+            .unwrap();
+
+        let qos_config = QosConfiguration {
+            ase_id: AseId(1),
+            cig_id: CigId::try_from(1).unwrap(),
+            cis_id: CisId::try_from(1).unwrap(),
+            sdu_interval: SduInterval::try_from(std::time::Duration::from_micros(10000)).unwrap(),
+            framing: Framing::Unframed,
+            phy: vec![Phy::Le1MPhy],
+            max_sdu: MaxSdu::try_from(100).unwrap(),
+            retransmission_number: 2,
+            max_transport_latency: MaxTransportLatency::try_from(std::time::Duration::from_millis(
+                10,
+            ))
+            .unwrap(),
+            presentation_delay: PresentationDelay { microseconds: 40000 },
+        };
+
+        let configure_qos_fut =
+            client.configure_qos(vec![QosConfigurationRequest::Custom(qos_config)]);
+        let err =
+            run_to_completion(configure_qos_fut).expect_err("should fail client-side validation");
+
+        assert!(matches!(
+            err,
+            Error::Client(ClientError::InvalidStartState {
+                ase_id: AseId(1),
+                opcode: AseControlPointOpcode::ConfigQos,
+                actual: AseState::Streaming,
+            })
+        ));
+    }
+
+    #[test]
+    fn configure_codec_fail_malformed_control_point_notification() {
+        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");
+
+        let config = CodecConfiguration {
+            ase_id: AseId(1),
+            target_latency: TargetLatency::TargetLowLatency,
+            target_phy: TargetPhy::Le1MPhy,
+            codec_id: CodecId::Assigned(bt_common::core::CodingFormat::Lc3),
+            codec_specific_configuration: vec![],
+        };
+
+        #[rustfmt::skip]
+        service.expect_characteristic_value(
+            &CONTROL_POINT_HANDLE,
+            vec![
+                0x01, // Opcode: Config Codec
+                0x01, // Num ASEs
+                0x01, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // ASE 1 Config
+            ],
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &CONTROL_POINT_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: CONTROL_POINT_HANDLE,
+                value: vec![0x01], // Only 1 byte, malformed (< 2 bytes)
+                maybe_truncated: false,
+            }),
+        );
+
+        let configure_fut = client.configure_codec(vec![config]);
+        let err = run_to_completion(configure_fut).expect_err("should fail with decoding error");
+
+        assert!(matches!(
+            err,
+            Error::Gatt(bt_gatt::types::Error::Encoding(
+                bt_common::packet_encoding::Error::UnexpectedDataLength
+            ))
+        ));
+    }
+
+    #[test]
+    fn configure_codec_fail_malformed_ase_notification() {
+        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");
+
+        let config = CodecConfiguration {
+            ase_id: AseId(1),
+            target_latency: TargetLatency::TargetLowLatency,
+            target_phy: TargetPhy::Le1MPhy,
+            codec_id: CodecId::Assigned(bt_common::core::CodingFormat::Lc3),
+            codec_specific_configuration: vec![],
+        };
+
+        #[rustfmt::skip]
+        service.expect_characteristic_value(
+            &CONTROL_POINT_HANDLE,
+            vec![
+                0x01, // Opcode: Config Codec
+                0x01, // Num ASEs
+                0x01, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // ASE 1 Config
+            ],
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &CONTROL_POINT_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: CONTROL_POINT_HANDLE,
+                value: vec![
+                    0x01, // Opcode: Config Codec
+                    0x01, // Num ASEs: 1
+                    0x01, 0x00, 0x00, // ASE 1 Response: Success
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &SINK_ASE_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: SINK_ASE_HANDLE,
+                value: vec![0x01], // Only 1 byte, malformed (< 2 bytes)
+                maybe_truncated: false,
+            }),
+        );
+
+        let configure_fut = client.configure_codec(vec![config]);
+        let err = run_to_completion(configure_fut).expect_err("should fail with conversion error");
+
+        assert!(matches!(
+            err,
+            Error::Gatt(bt_gatt::types::Error::Conversion(ref s)) if s.contains("Failed to decode AudioStreamEndpoint")
+        ));
+    }
+
+    #[test]
+    fn configure_codec_fail_unexpected_state_updates_local_cache() {
+        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");
+
+        let config1 = CodecConfiguration {
+            ase_id: AseId(1),
+            target_latency: TargetLatency::TargetLowLatency,
+            target_phy: TargetPhy::Le1MPhy,
+            codec_id: CodecId::Assigned(bt_common::core::CodingFormat::Lc3),
+            codec_specific_configuration: vec![],
+        };
+        let config2 = CodecConfiguration {
+            ase_id: AseId(2),
+            target_latency: TargetLatency::TargetLowLatency,
+            target_phy: TargetPhy::Le1MPhy,
+            codec_id: CodecId::Assigned(bt_common::core::CodingFormat::Lc3),
+            codec_specific_configuration: vec![],
+        };
+
+        #[rustfmt::skip]
+        service.expect_characteristic_value(
+            &CONTROL_POINT_HANDLE,
+            vec![
+                0x01, // Opcode: Config Codec
+                0x02, // Num ASEs
+                0x01, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // ASE 1 Config
+                0x02, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, // ASE 2 Config
+            ],
+        );
+
+        #[rustfmt::skip]
+        service.notify(
+            &CONTROL_POINT_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: CONTROL_POINT_HANDLE,
+                value: vec![
+                    0x01, // Opcode: Config Codec
+                    0x02, // Num ASEs: 2
+                    0x01, 0x00, 0x00, // ASE 1 Response: Success
+                    0x02, 0x00, 0x00, // ASE 2 Response: Success
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        // Notify ASE 1 with Codec Configured (valid!)
+        #[rustfmt::skip]
+        service.notify(
+            &SINK_ASE_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: SINK_ASE_HANDLE,
+                value: vec![
+                    0x01, // ASE ID: 1
+                    0x01, // ASE State: Codec Configured
+                    0x00, 0x01, 0x02, 0x0A, 0x00, 0x10, 0x27, 0x00, 0x40, 0x9C, 0x00,
+                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        // Notify ASE 2 with Streaming (invalid for Config Codec!)
+        #[rustfmt::skip]
+        service.notify(
+            &SOURCE_ASE_HANDLE,
+            Ok(CharacteristicNotification {
+                handle: SOURCE_ASE_HANDLE,
+                value: vec![
+                    0x02, // ASE ID: 2
+                    0x04, // ASE State: Streaming (unexpected!)
+                    0x01, // CIG ID: 1
+                    0x02, // CIS ID: 2
+                    0x00, // Metadata Length: 0
+                ],
+                maybe_truncated: false,
+            }),
+        );
+
+        let configure_fut = client.configure_codec(vec![config1, config2]);
+        let err = run_to_completion(configure_fut)
+            .expect_err("should fail with unexpected state transition");
+
+        assert!(matches!(
+            err,
+            Error::Client(ClientError::UnexpectedStateTransition {
+                ase_id: AseId(2),
+                expected: AseState::CodecConfigured,
+                actual: AseState::Streaming,
+            })
+        ));
+
+        // Both endpoints in our local cache MUST be updated with the latest notified
+        // states!
+        assert_eq!(
+            client.endpoints.sink[&SINK_ASE_HANDLE].endpoint.state,
+            AseState::CodecConfigured
+        );
+        assert_eq!(client.endpoints.source[&SOURCE_ASE_HANDLE].endpoint.state, AseState::Streaming);
+    }
 }
diff --git a/rust/bt-ascs/src/types.rs b/rust/bt-ascs/src/types.rs
index 6175baf..fc330d2 100644
--- a/rust/bt-ascs/src/types.rs
+++ b/rust/bt-ascs/src/types.rs
@@ -658,7 +658,7 @@
 }
 
 impl AseControlPointOpcode {
-    pub(crate) fn allowed_in_state(&self, state: &AseState) -> bool {
+    pub fn allowed_in_state(&self, state: &AseState) -> bool {
         let allowed_states: &[AseState] = match self {
             Self::ConfigCodec { .. } => {
                 &[AseState::Idle, AseState::CodecConfigured, AseState::QosConfigured]
@@ -1335,6 +1335,29 @@
     const BYTE_SIZE: usize = 3;
 }
 
+impl TryFrom<std::time::Duration> for SduInterval {
+    type Error = bt_common::packet_encoding::Error;
+    fn try_from(value: std::time::Duration) -> Result<Self, Self::Error> {
+        let Ok(microseconds) = u32::try_from(value.as_micros()) else {
+            return Err(Self::Error::OutOfRange);
+        };
+        if microseconds < 0xFF || microseconds > 0x0FFFFF {
+            return Err(Self::Error::OutOfRange);
+        }
+        Ok(Self(microseconds))
+    }
+}
+
+impl TryFrom<u32> for SduInterval {
+    type Error = bt_common::packet_encoding::Error;
+    fn try_from(value: u32) -> Result<Self, Self::Error> {
+        if value < 0xFF || value > 0x0FFFFF {
+            return Err(Self::Error::OutOfRange);
+        }
+        Ok(Self(value))
+    }
+}
+
 impl Decodable for SduInterval {
     type Error = bt_common::packet_encoding::Error;
 
@@ -1425,6 +1448,16 @@
     const BYTE_SIZE: usize = 2;
 }
 
+impl TryFrom<u16> for MaxSdu {
+    type Error = bt_common::packet_encoding::Error;
+    fn try_from(value: u16) -> Result<Self, Self::Error> {
+        if value > 0xFFF {
+            return Err(Self::Error::OutOfRange);
+        }
+        Ok(Self(value))
+    }
+}
+
 /// Max Transport Latency
 /// Valid range is [0x0005, 0x0FA0].
 /// Transmitted in little-endian, Stored in native-endian.
