diff --git a/rust/bt-ascs/src/client.rs b/rust/bt-ascs/src/client.rs
new file mode 100644
index 0000000..8f51ce5
--- /dev/null
+++ b/rust/bt-ascs/src/client.rs
@@ -0,0 +1,304 @@
+// Copyright 2026 The Fuchsia Authors. All rights reserved.
+// 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 std::collections::HashMap;
+
+use bt_common::Uuid;
+use bt_gatt::client::{CharacteristicNotification, PeerService, ServiceCharacteristic};
+use bt_gatt::types::Handle;
+
+use crate::types::*;
+
+/// 16-bit UUID value for the characteristics offered by the Audio
+/// Stream Control Service.
+pub const ASE_CONTROL_POINT_UUID: Uuid = Uuid::from_u16(0x2BC6);
+pub const SINK_ASE_UUID: Uuid = Uuid::from_u16(0x2BC4);
+pub const SOURCE_ASE_UUID: Uuid = Uuid::from_u16(0x2BC5);
+
+#[derive(Debug, thiserror::Error, PartialEq, Clone)]
+pub enum ClientError {
+    #[error("Remote server is missing control point characteristic")]
+    MissingControlPointCharacteristic,
+    #[error("Remote server should only have 1 control point characteristic")]
+    ExtraControlPointCharacteristic,
+    #[error("Remote server doesn't have any audio stream endpoints")]
+    MissingAudioStreamEndpoints,
+}
+
+/// Represents a single source/sink ASE state characteristic.
+pub struct AudioStreamEndpointHandle {
+    pub endpoint: AudioStreamEndpoint,
+    pub notification_stream:
+        BoxStream<'static, Result<CharacteristicNotification, bt_gatt::types::Error>>,
+}
+
+// See ASCS v1.0.1 4.2 for details.
+pub struct AseControlPoint {
+    pub handle: Handle,
+    pub notification_stream:
+        BoxStream<'static, Result<CharacteristicNotification, bt_gatt::types::Error>>,
+}
+
+/// Creates Audio Stream Control Service (ASCS) client instance
+pub struct AudioStreamControlServiceClient<T: bt_gatt::GattTypes> {
+    pub gatt_client: T::PeerService,
+    pub control_point: AseControlPoint,
+    pub sink_endpoints: HashMap<Handle, AudioStreamEndpointHandle>,
+    pub source_endpoints: HashMap<Handle, AudioStreamEndpointHandle>,
+}
+
+pub type SinkAndSourceEndpoints =
+    (HashMap<Handle, AudioStreamEndpointHandle>, HashMap<Handle, AudioStreamEndpointHandle>);
+
+impl<T: bt_gatt::GattTypes> AudioStreamControlServiceClient<T> {
+    pub async fn create(gatt_client: T::PeerService) -> Result<Self, Error>
+    where
+        <T as bt_gatt::GattTypes>::NotificationStream: std::marker::Send,
+    {
+        let control_point = Self::discover_control_point(&gatt_client).await?;
+        let (sink_endpoints, source_endpoints) = Self::discover_all_endpoints(&gatt_client).await?;
+
+        Ok(Self { gatt_client, control_point, sink_endpoints, source_endpoints })
+    }
+
+    async fn discover_control_point(gatt_client: &T::PeerService) -> Result<AseControlPoint, Error>
+    where
+        <T as bt_gatt::GattTypes>::NotificationStream: std::marker::Send,
+    {
+        let cp_chars = ServiceCharacteristic::<T>::find(gatt_client, ASE_CONTROL_POINT_UUID)
+            .await
+            .map_err(Error::Gatt)?;
+        if cp_chars.is_empty() {
+            return Err(ClientError::MissingControlPointCharacteristic.into());
+        }
+        if cp_chars.len() > 1 {
+            return Err(ClientError::ExtraControlPointCharacteristic.into());
+        }
+        let cp_handle = *cp_chars[0].handle();
+        let cp_stream = gatt_client.subscribe(&cp_handle);
+        Ok(AseControlPoint { handle: cp_handle, notification_stream: cp_stream.boxed() })
+    }
+
+    async fn discover_all_endpoints(
+        gatt_client: &T::PeerService,
+    ) -> Result<SinkAndSourceEndpoints, Error>
+    where
+        <T as bt_gatt::GattTypes>::NotificationStream: std::marker::Send,
+    {
+        let sink_chars = ServiceCharacteristic::<T>::find(gatt_client, SINK_ASE_UUID)
+            .await
+            .map_err(Error::Gatt)?;
+
+        let source_chars = ServiceCharacteristic::<T>::find(gatt_client, SOURCE_ASE_UUID)
+            .await
+            .map_err(Error::Gatt)?;
+
+        if sink_chars.is_empty() && source_chars.is_empty() {
+            return Err(ClientError::MissingAudioStreamEndpoints.into());
+        }
+
+        let mut sink_endpoints = HashMap::new();
+        for c in sink_chars {
+            let handle = *c.handle();
+            let endpoint =
+                Self::read_and_create_endpoint(gatt_client, handle, AudioDirection::Sink).await?;
+            let notification_stream = gatt_client.subscribe(&handle).boxed();
+            sink_endpoints
+                .insert(handle, AudioStreamEndpointHandle { endpoint, notification_stream });
+        }
+
+        let mut source_endpoints = HashMap::new();
+        for c in source_chars {
+            let handle = *c.handle();
+            let endpoint =
+                Self::read_and_create_endpoint(gatt_client, handle, AudioDirection::Source).await?;
+            let notification_stream = gatt_client.subscribe(&handle).boxed();
+            source_endpoints
+                .insert(handle, AudioStreamEndpointHandle { endpoint, notification_stream });
+        }
+
+        Ok((sink_endpoints, source_endpoints))
+    }
+
+    async fn read_and_create_endpoint(
+        gatt_client: &T::PeerService,
+        handle: Handle,
+        direction: AudioDirection,
+    ) -> Result<AudioStreamEndpoint, Error> {
+        let mut buf = vec![0; 255];
+        let (read_bytes, _truncated) =
+            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),
+                ))
+            })?;
+        Ok(endpoint)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use bt_gatt::test_utils::{FakePeerService, FakeTypes};
+    use bt_gatt::types::{AttributePermissions, CharacteristicProperty};
+    use bt_gatt::Characteristic;
+
+    const CONTROL_POINT_HANDLE: Handle = Handle(1);
+    const SINK_ASE_HANDLE: Handle = Handle(2);
+    const SOURCE_ASE_HANDLE: Handle = Handle(3);
+
+    fn setup_fake_service() -> FakePeerService {
+        let mut service = FakePeerService::new();
+        // Add Control Point
+        service.add_characteristic(
+            Characteristic {
+                handle: CONTROL_POINT_HANDLE,
+                uuid: ASE_CONTROL_POINT_UUID,
+                properties: CharacteristicProperty::Write
+                    | CharacteristicProperty::WriteWithoutResponse
+                    | CharacteristicProperty::Notify,
+                permissions: AttributePermissions::default(),
+                descriptors: vec![],
+            },
+            vec![],
+        );
+        // Add Sink ASE
+        service.add_characteristic(
+            Characteristic {
+                handle: SINK_ASE_HANDLE,
+                uuid: SINK_ASE_UUID,
+                properties: CharacteristicProperty::Read | CharacteristicProperty::Notify,
+                permissions: AttributePermissions::default(),
+                descriptors: vec![],
+            },
+            vec![0x01, 0x00], // ASE ID 1, State Idle
+        );
+        // Add Source ASE
+        service.add_characteristic(
+            Characteristic {
+                handle: SOURCE_ASE_HANDLE,
+                uuid: SOURCE_ASE_UUID,
+                properties: CharacteristicProperty::Read | CharacteristicProperty::Notify,
+                permissions: AttributePermissions::default(),
+                descriptors: vec![],
+            },
+            vec![0x02, 0x00], // ASE ID 2, State Idle
+        );
+        service
+    }
+
+    fn run_to_completion<F: std::future::Future>(fut: F) -> F::Output {
+        let mut fut = std::pin::pin!(fut);
+        let mut cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
+        match fut.as_mut().poll(&mut cx) {
+            std::task::Poll::Ready(res) => res,
+            std::task::Poll::Pending => panic!("Future did not complete synchronously"),
+        }
+    }
+
+    #[test]
+    fn client_creation_success() {
+        let service = setup_fake_service();
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service.clone());
+        let client = run_to_completion(client_fut).expect("client creation should succeed");
+
+        assert_eq!(client.control_point.handle, CONTROL_POINT_HANDLE);
+        assert_eq!(client.sink_endpoints.len(), 1);
+        assert_eq!(client.source_endpoints.len(), 1);
+
+        let sink = &client.sink_endpoints[&SINK_ASE_HANDLE].endpoint;
+        assert_eq!(sink.ase_id, AseId(1));
+        assert_eq!(sink.state, AseState::Idle);
+        assert_eq!(sink.direction, AudioDirection::Sink);
+
+        let source = &client.source_endpoints[&SOURCE_ASE_HANDLE].endpoint;
+        assert_eq!(source.ase_id, AseId(2));
+        assert_eq!(source.state, AseState::Idle);
+        assert_eq!(source.direction, AudioDirection::Source);
+    }
+
+    #[test]
+    fn client_creation_missing_control_point() {
+        let mut service = FakePeerService::new();
+        // Only add Sink (no Control Point)
+        service.add_characteristic(
+            Characteristic {
+                handle: SINK_ASE_HANDLE,
+                uuid: SINK_ASE_UUID,
+                properties: CharacteristicProperty::Read | CharacteristicProperty::Notify,
+                permissions: AttributePermissions::default(),
+                descriptors: vec![],
+            },
+            vec![0x01, 0x00],
+        );
+
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service);
+        let err = match run_to_completion(client_fut) {
+            Err(e) => e,
+            Ok(_) => panic!("expected error, got Ok"),
+        };
+        assert!(matches!(err, Error::Client(ClientError::MissingControlPointCharacteristic)));
+    }
+
+    #[test]
+    fn client_creation_missing_endpoints() {
+        let mut service = FakePeerService::new();
+        // Only add Control Point (no endpoints)
+        service.add_characteristic(
+            Characteristic {
+                handle: CONTROL_POINT_HANDLE,
+                uuid: ASE_CONTROL_POINT_UUID,
+                properties: CharacteristicProperty::Write | CharacteristicProperty::Notify,
+                permissions: AttributePermissions::default(),
+                descriptors: vec![],
+            },
+            vec![],
+        );
+
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service);
+        let err = match run_to_completion(client_fut) {
+            Err(e) => e,
+            Ok(_) => panic!("expected error, got Ok"),
+        };
+        assert!(matches!(err, Error::Client(ClientError::MissingAudioStreamEndpoints)));
+    }
+
+    #[test]
+    fn client_creation_extra_control_point() {
+        let mut service = FakePeerService::new();
+        // Add first Control Point
+        service.add_characteristic(
+            Characteristic {
+                handle: CONTROL_POINT_HANDLE,
+                uuid: ASE_CONTROL_POINT_UUID,
+                properties: CharacteristicProperty::Write | CharacteristicProperty::Notify,
+                permissions: AttributePermissions::default(),
+                descriptors: vec![],
+            },
+            vec![],
+        );
+        // Add second Control Point
+        service.add_characteristic(
+            Characteristic {
+                handle: Handle(4),
+                uuid: ASE_CONTROL_POINT_UUID,
+                properties: CharacteristicProperty::Write | CharacteristicProperty::Notify,
+                permissions: AttributePermissions::default(),
+                descriptors: vec![],
+            },
+            vec![],
+        );
+
+        let client_fut = AudioStreamControlServiceClient::<FakeTypes>::create(service);
+        let err = match run_to_completion(client_fut) {
+            Err(e) => e,
+            Ok(_) => panic!("expected error, got Ok"),
+        };
+        assert!(matches!(err, Error::Client(ClientError::ExtraControlPointCharacteristic)));
+    }
+}
diff --git a/rust/bt-ascs/src/lib.rs b/rust/bt-ascs/src/lib.rs
index f3f7380..8a6a6b4 100644
--- a/rust/bt-ascs/src/lib.rs
+++ b/rust/bt-ascs/src/lib.rs
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+pub mod client;
 pub mod server;
 pub mod types;
 pub use types::Error;
diff --git a/rust/bt-ascs/src/server.rs b/rust/bt-ascs/src/server.rs
index 9a329fa..3ee9823 100644
--- a/rust/bt-ascs/src/server.rs
+++ b/rust/bt-ascs/src/server.rs
@@ -2,10 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-use bt_common::core::ltv::LtValue;
 use bt_common::core::CodecId;
 use bt_common::generic_audio::metadata_ltv::Metadata;
-use bt_common::packet_encoding::Encodable;
 use bt_common::{PeerId, Uuid};
 use bt_gatt::server::{LocalService, Server, ServiceDefinition, ServiceId};
 use bt_gatt::server::{ReadResponder, WriteResponder};
@@ -23,6 +21,18 @@
 
 use crate::types::*;
 
+#[derive(Debug, thiserror::Error)]
+pub enum ServerError {
+    #[error("Server Only Operation")]
+    ServerOnlyOperation,
+    #[error("Service is already published")]
+    AlreadyPublished,
+    #[error("Issue publishing service: {0}")]
+    PublishError(#[from] bt_gatt::types::Error),
+    #[error("Unknown Peer: {0}")]
+    UnknownPeer(bt_common::PeerId),
+}
+
 #[pin_project(project = LocalServiceProj)]
 enum LocalServiceState<T: bt_gatt::ServerTypes> {
     NotPublished {
@@ -87,9 +97,9 @@
                     let service_result = futures::ready!(fut.poll(cx));
                     let Ok(service) = service_result else {
                         self.as_mut().set(LocalServiceState::Terminated);
-                        return Poll::Ready(Some(Err(Error::PublishError(
+                        return Poll::Ready(Some(Err(Error::from(ServerError::PublishError(
                             service_result.err().unwrap(),
-                        ))));
+                        )))));
                     };
                     let events = service.publish();
                     self.as_mut().set(LocalServiceState::Published { service, events });
@@ -99,15 +109,15 @@
                     let item = futures::ready!(events.poll_next(cx));
                     let Some(gatt_result) = item else {
                         self.as_mut().set(LocalServiceState::Terminated);
-                        return Poll::Ready(Some(Err(Error::PublishError(
+                        return Poll::Ready(Some(Err(Error::from(ServerError::PublishError(
                             "GATT server terminated".into(),
-                        ))));
+                        )))));
                     };
                     let Ok(event) = gatt_result else {
                         self.as_mut().set(LocalServiceState::Terminated);
-                        return Poll::Ready(Some(Err(Error::PublishError(
+                        return Poll::Ready(Some(Err(Error::from(ServerError::PublishError(
                             gatt_result.err().unwrap(),
-                        ))));
+                        )))));
                     };
                     return Poll::Ready(Some(Ok(event)));
                 }
@@ -144,24 +154,23 @@
         if self.opcode.is_none() || self.response_codes.is_empty() {
             return None;
         }
-        let mut notification = Vec::with_capacity(2 + self.response_codes.len() * 3);
-        // Opcode
-        notification.push(self.opcode.unwrap().into());
-        if let ResponseCode::InvalidLength { .. } | ResponseCode::UnsupportedOpcode { .. } =
-            self.response_codes[0]
+        use bt_common::packet_encoding::Encodable;
+
+        let opcode = self.opcode.unwrap().into();
+        let notification = if let ResponseCode::InvalidLength { .. }
+        | ResponseCode::UnsupportedOpcode { .. } = self.response_codes[0]
         {
-            // UnsupportedOpcode or InvalidLength. Number_of_ASEs shall be set to 0xFF
-            // See ASCS v1.0.1 Table 4.7.  We only include the first response_code.
-            notification.push(0xFF);
-            notification.extend(self.response_codes[0].notify_value());
-            return Some(notification);
-        }
-        // Number_of_ASEs
-        notification.push(self.response_codes.len() as u8);
-        for response in &self.response_codes {
-            notification.extend(response.notify_value());
-        }
-        Some(notification)
+            ControlPointNotification::new_error(opcode, self.response_codes[0].to_code())
+        } else {
+            let mut cp_notification = ControlPointNotification::new(opcode);
+            for response in &self.response_codes {
+                cp_notification.add_response(response.clone());
+            }
+            cp_notification
+        };
+        let mut buf = vec![0; notification.encoded_len()];
+        notification.encode(&mut buf).unwrap();
+        Some(buf)
     }
 }
 
@@ -288,7 +297,7 @@
 
     pub fn publish(&mut self, server: &T::Server) -> Result<(), Error> {
         if !self.local_service.is_not_published() {
-            return Err(Error::AlreadyPublished);
+            return Err(Error::from(ServerError::AlreadyPublished));
         }
         let LocalServiceState::NotPublished { waker } = std::mem::replace(
             &mut self.local_service,
@@ -306,8 +315,10 @@
         ase_id: AseId,
         cis: (CigId, CisId),
     ) -> Result<(), Error> {
-        let endpoints =
-            self.client_endpoints.get_mut(&peer_id).ok_or(Error::UnknownPeer(peer_id))?;
+        let endpoints = self
+            .client_endpoints
+            .get_mut(&peer_id)
+            .ok_or(Error::from(ServerError::UnknownPeer(peer_id)))?;
         endpoints.established_cis(ase_id, cis);
         for operation in endpoints.autonomous_operations() {
             self.queue_operation_unpin(peer_id, operation);
@@ -321,8 +332,10 @@
         ase_id: AseId,
         cis: (CigId, CisId),
     ) -> Result<(), Error> {
-        let endpoints =
-            self.client_endpoints.get_mut(&peer_id).ok_or(Error::UnknownPeer(peer_id))?;
+        let endpoints = self
+            .client_endpoints
+            .get_mut(&peer_id)
+            .ok_or(Error::from(ServerError::UnknownPeer(peer_id)))?;
         endpoints.released_cis(ase_id, cis);
         for operation in endpoints.autonomous_operations() {
             self.queue_operation_unpin(peer_id, operation);
@@ -383,159 +396,6 @@
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq)]
-enum AudioDirection {
-    Sink,
-    Source,
-}
-
-impl From<&AudioDirection> for bt_common::Uuid {
-    fn from(value: &AudioDirection) -> Self {
-        match value {
-            AudioDirection::Sink => Uuid::from_u16(0x2BC4),
-            AudioDirection::Source => Uuid::from_u16(0x2BC5),
-        }
-    }
-}
-
-#[derive(Debug, Clone)]
-enum AseAdditionalParameters {
-    /// When in states with no additional parameters: Idle, Releasing
-    None,
-    CodecConfigured {
-        framing: Framing,
-        preferred_phys: Vec<Phy>,
-        preferred_retransmission_number: u8,
-        max_transport_latency: MaxTransportLatency,
-        presentation_delay_range: PresentationDelayRange,
-        codec_id: CodecId,
-        codec_config: Vec<u8>,
-    },
-    QosConfigured {
-        configuration: QosConfiguration,
-    },
-    /// When Enabling, Streaming, or Disabling
-    Streaming {
-        cig_id: CigId,
-        cis_id: CisId,
-        metadata: Vec<Metadata>,
-        qos_configured: QosConfiguration,
-    },
-}
-
-impl AseAdditionalParameters {
-    fn char_size(&self) -> usize {
-        match self {
-            AseAdditionalParameters::None => 0,
-            AseAdditionalParameters::CodecConfigured { codec_config, .. } => {
-                23 + codec_config.len()
-            }
-            AseAdditionalParameters::QosConfigured { .. } => 15,
-            AseAdditionalParameters::Streaming { metadata, .. } => {
-                metadata.iter().fold(3, |total, m| total + m.encoded_len() as usize)
-            }
-        }
-    }
-    fn into_char_value(&self) -> Vec<u8> {
-        match self {
-            AseAdditionalParameters::None => Vec::new(),
-            AseAdditionalParameters::CodecConfigured {
-                framing,
-                preferred_phys,
-                preferred_retransmission_number,
-                max_transport_latency,
-                presentation_delay_range,
-                codec_id,
-                codec_config,
-            } => {
-                let mut value = Vec::with_capacity(self.char_size());
-                value.resize(self.char_size() - codec_config.len(), 0);
-                value[0] = (*framing) as u8;
-                value[1] = Phy::to_bits(preferred_phys.iter());
-                value[2] = *preferred_retransmission_number;
-                max_transport_latency.encode(&mut value[3..]).unwrap();
-                presentation_delay_range.encode(&mut value[5..]).unwrap();
-                codec_id.encode(&mut value[17..]).unwrap();
-                value[22] = codec_config.len() as u8;
-                value.extend(codec_config.clone());
-                value
-            }
-            AseAdditionalParameters::QosConfigured {
-                configuration:
-                    QosConfiguration {
-                        cig_id,
-                        cis_id,
-                        sdu_interval,
-                        framing,
-                        phy,
-                        max_sdu,
-                        retransmission_number,
-                        max_transport_latency,
-                        presentation_delay,
-                        ..
-                    },
-            } => {
-                let mut value = Vec::with_capacity(self.char_size());
-                value.resize(self.char_size(), 0);
-                cig_id.encode(&mut value[0..]).unwrap();
-                cis_id.encode(&mut value[1..]).unwrap();
-                sdu_interval.encode(&mut value[2..]).unwrap();
-                framing.encode(&mut value[5..]).unwrap();
-                value[6] = Phy::to_bits(phy.iter());
-                max_sdu.encode(&mut value[7..]).unwrap();
-                value[9] = *retransmission_number;
-                max_transport_latency.encode(&mut value[10..]).unwrap();
-                presentation_delay.encode(&mut value[12..]).unwrap();
-                value
-            }
-            AseAdditionalParameters::Streaming { cig_id, cis_id, metadata, .. } => {
-                let mut value = Vec::with_capacity(self.char_size());
-                value.resize(self.char_size(), 0);
-                cig_id.encode(&mut value[0..]).unwrap();
-                cis_id.encode(&mut value[1..]).unwrap();
-                value[2] = metadata.iter().fold(0usize, |acc, i| acc + i.encoded_len()) as u8;
-                LtValue::encode_all(metadata.clone().into_iter(), &mut value[3..]).unwrap();
-                value
-            }
-        }
-    }
-}
-
-impl From<QosConfiguration> for AseAdditionalParameters {
-    fn from(value: QosConfiguration) -> Self {
-        Self::QosConfigured { configuration: value }
-    }
-}
-
-#[derive(Debug, Clone)]
-struct AudioStreamEndpoint {
-    handle: Handle,
-    direction: AudioDirection,
-    ase_id: AseId,
-    state: AseState,
-    additional: AseAdditionalParameters,
-}
-
-impl AudioStreamEndpoint {
-    fn into_char_value(&self) -> Vec<u8> {
-        let mut value = Vec::with_capacity(2 + self.additional.char_size());
-        value.push(self.ase_id.into());
-        value.push(self.state.into());
-        value.extend(self.additional.into_char_value());
-        value
-    }
-
-    fn get_cis(&self) -> Option<(CigId, CisId)> {
-        match &self.additional {
-            AseAdditionalParameters::QosConfigured { configuration } => {
-                Some((configuration.cig_id, configuration.cis_id))
-            }
-            AseAdditionalParameters::Streaming { cig_id, cis_id, .. } => Some((*cig_id, *cis_id)),
-            _ => None,
-        }
-    }
-}
-
 impl From<&AudioStreamEndpoint> for Characteristic {
     fn from(value: &AudioStreamEndpoint) -> Self {
         let properties = CharacteristicProperty::Read | CharacteristicProperty::Notify;
@@ -712,7 +572,7 @@
             cig_id: configuration.cig_id,
             cis_id: configuration.cis_id,
             metadata: self.metadata,
-            qos_configured: configuration,
+            qos_configured: Some(configuration),
         };
         let _ = self.sender.send(Ok(self.endpoint));
     }
@@ -730,7 +590,8 @@
     }
 
     pub fn accept(mut self) {
-        let AseAdditionalParameters::Streaming { qos_configured, .. } = self.endpoint.additional
+        let AseAdditionalParameters::Streaming { qos_configured: Some(qos_configured), .. } =
+            self.endpoint.additional
         else {
             unreachable!();
         };
diff --git a/rust/bt-ascs/src/types.rs b/rust/bt-ascs/src/types.rs
index 1ca6f3f..324a2b7 100644
--- a/rust/bt-ascs/src/types.rs
+++ b/rust/bt-ascs/src/types.rs
@@ -3,31 +3,32 @@
 // found in the LICENSE file.
 
 use bt_common::packet_encoding::{Decodable, Encodable};
-use bt_common::{codable_as_bitmask, decodable_enum};
+use bt_common::{codable_as_bitmask, decodable_enum, Uuid};
+use bt_gatt::types::Handle;
 use thiserror::Error;
 
+use crate::client::ClientError;
+use crate::server::ServerError;
+use bt_common::core::ltv::LtValue;
 use bt_common::core::CodecId;
 use bt_common::generic_audio::metadata_ltv::Metadata;
+use bt_gatt::types::Error as BtGattError;
 
 /// Error type
 #[derive(Debug, Error)]
 pub enum Error {
-    #[error("Reserved for Future Use: {0}")]
-    ReservedFutureUse(String),
-    #[error("Server Only Operation")]
-    ServerOnlyOperation,
-    #[error("Service is already published")]
-    AlreadyPublished,
-    #[error("Issue publishing service: {0}")]
-    PublishError(bt_gatt::types::Error),
-    #[error("Unsupported configuration: {0}")]
-    Unsupported(String),
-    #[error("Unknown Peer: {0}")]
-    UnknownPeer(bt_common::PeerId),
+    #[error("ASCS Server error: {0}")]
+    Server(#[from] ServerError),
+    #[error("ASCS Client error: {0}")]
+    Client(#[from] ClientError),
+    #[error("GATT operation error: {0}")]
+    Gatt(#[from] BtGattError),
+    #[error("Internal error occurred: {0}")]
+    Internal(String),
 }
 
 #[non_exhaustive]
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ResponseCode {
     Success { ase_id: AseId },
     UnsupportedOpcode { opcode_byte: u8 },
@@ -43,7 +44,7 @@
 }
 
 impl ResponseCode {
-    fn to_code(&self) -> u8 {
+    pub(crate) fn to_code(&self) -> u8 {
         match self {
             ResponseCode::Success { .. } => 0x00,
             ResponseCode::UnsupportedOpcode { .. } => 0x01,
@@ -122,9 +123,81 @@
     pub(crate) fn notify_value(&self) -> Vec<u8> {
         [self.ase_id_value(), self.to_code(), self.reason_byte()].into()
     }
+
+    pub fn decode_response(
+        buf: &[u8],
+        opcode: u8,
+    ) -> Result<Self, bt_common::packet_encoding::Error> {
+        if buf.len() < 3 {
+            return Err(bt_common::packet_encoding::Error::UnexpectedDataLength);
+        }
+        let ase_id_val = buf[0];
+        let code = buf[1];
+        let reason = buf[2];
+        let ase_id = AseId(ase_id_val);
+
+        match code {
+            0x00 => Ok(Self::Success { ase_id }),
+            0x01 => {
+                if ase_id_val != 0 {
+                    return Err(bt_common::packet_encoding::Error::OutOfRange);
+                }
+                Ok(Self::UnsupportedOpcode { opcode_byte: opcode })
+            }
+            0x02 => {
+                if ase_id_val != 0 {
+                    return Err(bt_common::packet_encoding::Error::OutOfRange);
+                }
+                Ok(Self::InvalidLength { opcode_byte: opcode })
+            }
+            0x03 => Ok(Self::InvalidAseId { value: ase_id_val }),
+            0x04 => Ok(Self::InvalidAseStateMachineTransition { ase_id }),
+            0x05 => Ok(Self::InvalidAseDirection { ase_id }),
+            0x06 => Ok(Self::UnsupportedAudioCapablities { ase_id }),
+            0x07 => {
+                let reason = ResponseReason::try_from(reason)
+                    .map_err(|_| bt_common::packet_encoding::Error::OutOfRange)?;
+                Ok(Self::ConfigurationParameterValue {
+                    ase_id,
+                    issue: ResponseIssue::Unsupported,
+                    reason,
+                })
+            }
+            0x08 => {
+                let reason = ResponseReason::try_from(reason)
+                    .map_err(|_| bt_common::packet_encoding::Error::OutOfRange)?;
+                Ok(Self::ConfigurationParameterValue {
+                    ase_id,
+                    issue: ResponseIssue::Rejected,
+                    reason,
+                })
+            }
+            0x09 => {
+                let reason = ResponseReason::try_from(reason)
+                    .map_err(|_| bt_common::packet_encoding::Error::OutOfRange)?;
+                Ok(Self::ConfigurationParameterValue {
+                    ase_id,
+                    issue: ResponseIssue::Invalid,
+                    reason,
+                })
+            }
+            0x0A => {
+                Ok(Self::Metadata { ase_id, issue: ResponseIssue::Unsupported, type_value: reason })
+            }
+            0x0B => {
+                Ok(Self::Metadata { ase_id, issue: ResponseIssue::Rejected, type_value: reason })
+            }
+            0x0C => {
+                Ok(Self::Metadata { ase_id, issue: ResponseIssue::Invalid, type_value: reason })
+            }
+            0x0D => Ok(Self::InsufficientResources { ase_id }),
+            0x0E => Ok(Self::UnspecifiedError { ase_id }),
+            _ => Err(bt_common::packet_encoding::Error::OutOfRange),
+        }
+    }
 }
 
-#[derive(Debug, Clone, PartialEq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ResponseIssue {
     Unsupported,
     Rejected,
@@ -199,6 +272,327 @@
     }
 }
 
+#[derive(Debug, Clone, PartialEq)]
+pub enum AseAdditionalParameters {
+    None,
+    CodecConfigured {
+        framing: Framing,
+        preferred_phys: Vec<Phy>,
+        preferred_retransmission_number: u8,
+        max_transport_latency: MaxTransportLatency,
+        presentation_delay_range: PresentationDelayRange,
+        codec_id: CodecId,
+        codec_config: Vec<u8>,
+    },
+    QosConfigured {
+        configuration: QosConfiguration,
+    },
+    Streaming {
+        cig_id: CigId,
+        cis_id: CisId,
+        metadata: Vec<Metadata>,
+        qos_configured: Option<QosConfiguration>,
+    },
+}
+
+impl AseAdditionalParameters {
+    pub fn char_size(&self) -> usize {
+        match self {
+            AseAdditionalParameters::None => 0,
+            AseAdditionalParameters::CodecConfigured { codec_config, .. } => {
+                23 + codec_config.len()
+            }
+            AseAdditionalParameters::QosConfigured { .. } => 15,
+            AseAdditionalParameters::Streaming { metadata, .. } => {
+                metadata.iter().fold(3, |total, m| total + m.encoded_len() as usize)
+            }
+        }
+    }
+
+    pub fn into_char_value(&self) -> Vec<u8> {
+        match self {
+            AseAdditionalParameters::None => Vec::new(),
+            AseAdditionalParameters::CodecConfigured {
+                framing,
+                preferred_phys,
+                preferred_retransmission_number,
+                max_transport_latency,
+                presentation_delay_range,
+                codec_id,
+                codec_config,
+            } => {
+                let mut value = Vec::with_capacity(self.char_size());
+                value.resize(self.char_size() - codec_config.len(), 0);
+                value[0] = (*framing) as u8;
+                value[1] = Phy::to_bits(preferred_phys.iter());
+                value[2] = *preferred_retransmission_number;
+                max_transport_latency.encode(&mut value[3..]).unwrap();
+                presentation_delay_range.encode(&mut value[5..]).unwrap();
+                codec_id.encode(&mut value[17..]).unwrap();
+                value[22] = codec_config.len() as u8;
+                value.extend(codec_config.clone());
+                value
+            }
+            AseAdditionalParameters::QosConfigured {
+                configuration:
+                    QosConfiguration {
+                        cig_id,
+                        cis_id,
+                        sdu_interval,
+                        framing,
+                        phy,
+                        max_sdu,
+                        retransmission_number,
+                        max_transport_latency,
+                        presentation_delay,
+                        ..
+                    },
+            } => {
+                let mut value = Vec::with_capacity(self.char_size());
+                value.resize(self.char_size(), 0);
+                cig_id.encode(&mut value[0..]).unwrap();
+                cis_id.encode(&mut value[1..]).unwrap();
+                sdu_interval.encode(&mut value[2..]).unwrap();
+                framing.encode(&mut value[5..]).unwrap();
+                value[6] = Phy::to_bits(phy.iter());
+                max_sdu.encode(&mut value[7..]).unwrap();
+                value[9] = *retransmission_number;
+                max_transport_latency.encode(&mut value[10..]).unwrap();
+                presentation_delay.encode(&mut value[12..]).unwrap();
+                value
+            }
+            AseAdditionalParameters::Streaming { cig_id, cis_id, metadata, .. } => {
+                let mut value = Vec::with_capacity(self.char_size());
+                value.resize(self.char_size(), 0);
+                cig_id.encode(&mut value[0..]).unwrap();
+                cis_id.encode(&mut value[1..]).unwrap();
+                value[2] = metadata.iter().fold(0usize, |acc, i| acc + i.encoded_len()) as u8;
+                LtValue::encode_all(metadata.clone().into_iter(), &mut value[3..]).unwrap();
+                value
+            }
+        }
+    }
+
+    pub fn decode(
+        ase_id: AseId,
+        state: &AseState,
+        buf: &[u8],
+    ) -> (Result<Self, ResponseCode>, usize) {
+        match state {
+            AseState::Idle | AseState::Releasing => (Ok(Self::None), 0),
+            AseState::CodecConfigured => {
+                if buf.len() < 23 {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                }
+                let Ok(framing) = Framing::try_from(buf[0]) else {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                };
+                let preferred_phys = Phy::from_bits(buf[1]).collect();
+                let preferred_retransmission_number = buf[2];
+                let Ok(max_transport_latency) = MaxTransportLatency::decode(&buf[3..5]).0 else {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                };
+                let Ok(presentation_delay_range) = PresentationDelayRange::decode(&buf[5..17]).0
+                else {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                };
+                let Ok(codec_id) = CodecId::decode(&buf[17..22]).0 else {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                };
+                let codec_specific_configuration_len = buf[22] as usize;
+                let total_len = 23 + codec_specific_configuration_len;
+                if buf.len() < total_len {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                }
+                let codec_config = buf[23..total_len].to_vec();
+                (
+                    Ok(Self::CodecConfigured {
+                        framing,
+                        preferred_phys,
+                        preferred_retransmission_number,
+                        max_transport_latency,
+                        presentation_delay_range,
+                        codec_id,
+                        codec_config,
+                    }),
+                    total_len,
+                )
+            }
+            AseState::QosConfigured => {
+                if buf.len() < 15 {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                }
+                let mut temp_buf = Vec::with_capacity(16);
+                temp_buf.push(ase_id.into());
+                temp_buf.extend_from_slice(&buf[0..15]);
+                let (config_res, _) = QosConfiguration::decode(&temp_buf);
+                match config_res {
+                    Ok(configuration) => (Ok(Self::QosConfigured { configuration }), 15),
+                    Err(e) => (Err(e), buf.len()),
+                }
+            }
+            AseState::Enabling | AseState::Streaming | AseState::Disabling => {
+                if buf.len() < 3 {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                }
+                let cig_id = match CigId::try_from(buf[0]) {
+                    Ok(id) => id,
+                    Err(_) => return (Err(ResponseCode::invalid_length()), buf.len()),
+                };
+                let cis_id = match CisId::try_from(buf[1]) {
+                    Ok(id) => id,
+                    Err(_) => return (Err(ResponseCode::invalid_length()), buf.len()),
+                };
+                let metadata_length = buf[2] as usize;
+                let total_len = 3 + metadata_length;
+                if buf.len() < total_len {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                }
+
+                use bt_common::core::ltv::Error as LtvError;
+                use bt_common::core::ltv::LtValue;
+                let (metadata_results, consumed) =
+                    Metadata::decode_all(&buf[3..3 + metadata_length]);
+                if consumed != metadata_length {
+                    return (Err(ResponseCode::invalid_length()), buf.len());
+                }
+                let metadata_result: Result<Vec<Metadata>, LtvError<<Metadata as LtValue>::Type>> =
+                    metadata_results.into_iter().collect();
+                let Ok(metadata) = metadata_result else {
+                    match metadata_result.unwrap_err() {
+                        LtvError::MissingType | LtvError::MissingData(_) => {
+                            return (Err(ResponseCode::invalid_length()), buf.len());
+                        }
+                        LtvError::UnrecognizedType(_, type_value) => {
+                            return (
+                                Err(ResponseCode::Metadata {
+                                    ase_id,
+                                    issue: ResponseIssue::Unsupported,
+                                    type_value,
+                                }),
+                                total_len,
+                            );
+                        }
+                        LtvError::LengthOutOfRange(_, t, _)
+                        | LtvError::TypeFailedToDecode(t, _) => {
+                            return (
+                                Err(ResponseCode::Metadata {
+                                    ase_id,
+                                    issue: ResponseIssue::Invalid,
+                                    type_value: t.into(),
+                                }),
+                                total_len,
+                            );
+                        }
+                    }
+                };
+                (Ok(Self::Streaming { cig_id, cis_id, metadata, qos_configured: None }), total_len)
+            }
+        }
+    }
+}
+
+impl From<QosConfiguration> for AseAdditionalParameters {
+    fn from(value: QosConfiguration) -> Self {
+        Self::QosConfigured { configuration: value }
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum AudioDirection {
+    Sink,
+    Source,
+}
+
+impl From<&AudioDirection> for bt_common::Uuid {
+    fn from(value: &AudioDirection) -> Self {
+        match value {
+            AudioDirection::Sink => Uuid::from_u16(0x2BC4),
+            AudioDirection::Source => Uuid::from_u16(0x2BC5),
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct AudioStreamEndpoint {
+    pub handle: Handle,
+    pub direction: AudioDirection,
+    pub ase_id: AseId,
+    pub state: AseState,
+    pub additional: AseAdditionalParameters,
+}
+
+impl AudioStreamEndpoint {
+    /// Decodes an `AudioStreamEndpoint` from an ASE characteristic value.
+    ///
+    /// # Arguments
+    /// * `handle` - The GATT handle of the ASE characteristic.
+    /// * `direction` - The direction of the ASE (Sink or Source).
+    /// * `char_value_buf` - The characteristic value bytes read from the
+    ///   server.
+    ///
+    /// # Expected `char_value_buf` Layout (ASCS v1.0 Section 4.3):
+    /// * **Octet 0:** `ASE_ID` (1 octet)
+    /// * **Octet 1:** `ASE_State` (1 octet)
+    /// * **Octet 2+:** `Additional_ASE_Parameters` (variable octets, see ASCS
+    ///   v1.0 Table 4.2)
+    pub fn from_char_value(
+        handle: Handle,
+        direction: AudioDirection,
+        char_value_buf: &[u8],
+    ) -> Result<Self, ResponseCode> {
+        if char_value_buf.len() < 2 {
+            return Err(ResponseCode::invalid_length());
+        }
+        let ase_id = AseId::try_from(char_value_buf[0])?;
+        let Ok(state) = AseState::try_from(char_value_buf[1]) else {
+            return Err(ResponseCode::invalid_length());
+        };
+        let (additional_res, _) =
+            AseAdditionalParameters::decode(ase_id, &state, &char_value_buf[2..]);
+        let additional = additional_res?;
+
+        Ok(Self { handle, direction, ase_id, state, additional })
+    }
+
+    /// Encodes this endpoint's current state into a GATT characteristic value
+    /// buffer.
+    pub fn into_char_value(&self) -> Vec<u8> {
+        let mut buf = vec![0; self.encoded_len()];
+        self.encode(&mut buf).unwrap();
+        buf
+    }
+
+    pub fn get_cis(&self) -> Option<(CigId, CisId)> {
+        match &self.additional {
+            AseAdditionalParameters::QosConfigured { configuration } => {
+                Some((configuration.cig_id, configuration.cis_id))
+            }
+            AseAdditionalParameters::Streaming { cig_id, cis_id, .. } => Some((*cig_id, *cis_id)),
+            _ => None,
+        }
+    }
+}
+
+impl Encodable for AudioStreamEndpoint {
+    type Error = bt_common::packet_encoding::Error;
+
+    fn encoded_len(&self) -> usize {
+        2 + self.additional.char_size()
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> Result<(), Self::Error> {
+        if buf.len() < self.encoded_len() {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        buf[0] = self.ase_id.into();
+        buf[1] = self.state.into();
+        let add_bytes = self.additional.into_char_value();
+        buf[2..2 + add_bytes.len()].copy_from_slice(&add_bytes);
+        Ok(())
+    }
+}
+
 decodable_enum! {
     pub enum AseControlPointOpcode<u8, bt_common::packet_encoding::Error, OutOfRange> {
         ConfigCodec = 0x01,
@@ -289,7 +683,9 @@
             AseControlOperation::ReceiverStopReady { .. } => Ok(0x06),
             AseControlOperation::UpdateMetadata { .. } => Ok(0x07),
             AseControlOperation::Release { .. } => Ok(0x08),
-            AseControlOperation::Released { .. } => Err(Error::ServerOnlyOperation),
+            AseControlOperation::Released { .. } => {
+                Err(Error::Server(ServerError::ServerOnlyOperation))
+            }
         }
     }
 }
@@ -894,7 +1290,7 @@
 /// preferred range of the Presentation Delay parameter to be requested by the
 /// ASCS Client. Prefered Minimum must be above min, and preferred_max must be
 /// below max. Either of these being None indicates no preference.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq)]
 pub struct PresentationDelayRange {
     min: PresentationDelay,
     max: PresentationDelay,
@@ -904,6 +1300,22 @@
 
 impl PresentationDelayRange {
     const BYTE_SIZE: usize = PresentationDelay::BYTE_SIZE * 4;
+
+    pub fn min(&self) -> &PresentationDelay {
+        &self.min
+    }
+
+    pub fn max(&self) -> &PresentationDelay {
+        &self.max
+    }
+
+    pub fn preferred_min(&self) -> Option<&PresentationDelay> {
+        self.preferred_min.as_ref()
+    }
+
+    pub fn preferred_max(&self) -> Option<&PresentationDelay> {
+        self.preferred_max.as_ref()
+    }
     /// Make a new delay range with no preference. Returns
     /// ResponseCode::InvalidLength if min > max or the value is out of the
     /// acceptable range (PresentationDelay is 24 bits)
@@ -1035,6 +1447,166 @@
     }
 }
 
+impl Decodable for PresentationDelayRange {
+    type Error = ResponseCode;
+
+    fn decode(buf: &[u8]) -> (Result<Self, Self::Error>, usize) {
+        if buf.len() < Self::BYTE_SIZE {
+            return (Err(ResponseCode::invalid_length()), buf.len());
+        }
+        let min = match PresentationDelay::decode(&buf[0..3]).0 {
+            Ok(min) => min,
+            Err(e) => return (Err(e), buf.len()),
+        };
+        let max = match PresentationDelay::decode(&buf[3..6]).0 {
+            Ok(max) => max,
+            Err(e) => return (Err(e), buf.len()),
+        };
+        let pref_min_val = u32::from_le_bytes([buf[6], buf[7], buf[8], 0]);
+        let preferred_min = if pref_min_val == 0 {
+            None
+        } else {
+            Some(PresentationDelay { microseconds: pref_min_val })
+        };
+        let pref_max_val = u32::from_le_bytes([buf[9], buf[10], buf[11], 0]);
+        let preferred_max = if pref_max_val == 0 {
+            None
+        } else {
+            Some(PresentationDelay { microseconds: pref_max_val })
+        };
+        (Ok(Self { min, max, preferred_min, preferred_max }), Self::BYTE_SIZE)
+    }
+}
+
+/// Represents an ASE Control Point notification sent by an ASCS Server to a
+/// Client.
+///
+/// See ASCS v1.0 Section 4.2 for the frame structure and notification
+/// properties.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ControlPointNotification {
+    pub opcode: u8,
+    pub number_of_ases: u8,
+    pub responses: Vec<ResponseCode>,
+}
+
+impl ControlPointNotification {
+    /// Creates a new, empty `ControlPointNotification` for standard multi-ASE
+    /// operations.
+    ///
+    /// The notification starts with a response count of `0`.
+    ///
+    /// # Arguments
+    /// * `opcode` - The opcode of the operation being responded to.
+    pub fn new(opcode: u8) -> Self {
+        Self { opcode, number_of_ases: 0, responses: Vec::new() }
+    }
+
+    /// Creates a new global error `ControlPointNotification`.
+    ///
+    /// A response count of `0xFF` is used strictly when the entire control
+    /// point write is rejected globally before individual ASEs are
+    /// processed (e.g., unrecognized opcode or invalid packet length). The
+    /// notification contains a single error response with an
+    /// ASE ID of `0x00`. See ASCS v1.0 Table 4.7.
+    ///
+    /// # Arguments
+    /// * `opcode` - The opcode of the operation being responded to.
+    /// * `response_code` - Either `0x01` (Unsupported Opcode) or `0x02`
+    ///   (Invalid Length).
+    pub fn new_error(opcode: u8, response_code: u8) -> Self {
+        let code = match response_code {
+            0x01 => ResponseCode::UnsupportedOpcode { opcode_byte: opcode },
+            0x02 => ResponseCode::InvalidLength { opcode_byte: opcode },
+            _ => unreachable!(),
+        };
+        Self { opcode, number_of_ases: 0xFF, responses: vec![code] }
+    }
+
+    /// Adds a single ASE response code to the notification list.
+    ///
+    /// If the notification is currently in a global error state (response count
+    /// `0xFF`), calling this method clears the error and transitions it
+    /// back to a standard multi-ASE response list.
+    ///
+    /// # Arguments
+    /// * `response` - The `ResponseCode` variant to append to the notification.
+    pub fn add_response(&mut self, response: ResponseCode) {
+        if self.number_of_ases == 0xFF {
+            self.number_of_ases = 0;
+            self.responses.clear();
+        }
+        self.responses.push(response);
+        self.number_of_ases = self.responses.len() as u8;
+    }
+}
+
+impl Encodable for ControlPointNotification {
+    type Error = bt_common::packet_encoding::Error;
+
+    fn encoded_len(&self) -> usize {
+        2 + self.responses.len() * 3
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> Result<(), Self::Error> {
+        if buf.len() < self.encoded_len() {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        buf[0] = self.opcode;
+        buf[1] = self.number_of_ases;
+        let mut idx = 2;
+        for r in &self.responses {
+            let val = r.notify_value();
+            buf[idx..idx + 3].copy_from_slice(&val);
+            idx += 3;
+        }
+        Ok(())
+    }
+}
+
+impl Decodable for ControlPointNotification {
+    type Error = bt_common::packet_encoding::Error;
+
+    fn decode(buf: &[u8]) -> (Result<Self, Self::Error>, usize) {
+        if buf.len() < 2 {
+            return (Err(Self::Error::UnexpectedDataLength), buf.len());
+        }
+        let opcode = buf[0];
+        let number_of_ases = buf[1];
+        let responses_buf = &buf[2..];
+        let mut responses = Vec::new();
+
+        if number_of_ases == 0xFF {
+            if responses_buf.len() < 3 {
+                return (Err(Self::Error::UnexpectedDataLength), buf.len());
+            }
+            let r = match ResponseCode::decode_response(&responses_buf[0..3], opcode) {
+                Ok(r) => r,
+                Err(e) => return (Err(e), buf.len()),
+            };
+            if r.ase_id_value() != 0 || (r.to_code() != 0x01 && r.to_code() != 0x02) {
+                return (Err(Self::Error::UnexpectedDataLength), buf.len());
+            }
+            responses.push(r);
+            (Ok(Self { opcode, number_of_ases, responses }), 5)
+        } else {
+            let expected_len = number_of_ases as usize * 3;
+            if responses_buf.len() < expected_len {
+                return (Err(Self::Error::UnexpectedDataLength), buf.len());
+            }
+            for i in 0..(number_of_ases as usize) {
+                let idx = i * 3;
+                let r = match ResponseCode::decode_response(&responses_buf[idx..idx + 3], opcode) {
+                    Ok(r) => r,
+                    Err(e) => return (Err(e), buf.len()),
+                };
+                responses.push(r);
+            }
+            (Ok(Self { opcode, number_of_ases, responses }), 2 + expected_len)
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -1312,4 +1884,122 @@
 
         assert_eq!(&encoded, expected);
     }
+
+    #[test]
+    fn test_ase_endpoint_roundtrip() {
+        use bt_gatt::types::Handle;
+        // Test with AdditionalParameters::None
+        let endpoint_none = AudioStreamEndpoint {
+            handle: Handle(1),
+            direction: AudioDirection::Sink,
+            ase_id: AseId(1),
+            state: AseState::Idle,
+            additional: AseAdditionalParameters::None,
+        };
+        let mut buf = vec![0; endpoint_none.encoded_len()];
+        endpoint_none.encode(&mut buf).unwrap();
+        assert_eq!(buf.len(), 2);
+        assert_eq!(buf, vec![1, 0]);
+
+        let decoded_endpoint_none =
+            AudioStreamEndpoint::from_char_value(Handle(1), AudioDirection::Sink, &buf).unwrap();
+        assert_eq!(decoded_endpoint_none.ase_id, endpoint_none.ase_id);
+        assert_eq!(decoded_endpoint_none.state, endpoint_none.state);
+        assert_eq!(decoded_endpoint_none.additional, endpoint_none.additional);
+
+        // Test with AdditionalParameters::CodecConfigured
+        let delay_range = PresentationDelayRange::build(1000, 2000).unwrap();
+        let endpoint_codec = AudioStreamEndpoint {
+            handle: Handle(2),
+            direction: AudioDirection::Source,
+            ase_id: AseId(2),
+            state: AseState::CodecConfigured,
+            additional: AseAdditionalParameters::CodecConfigured {
+                framing: Framing::Unframed,
+                preferred_phys: vec![Phy::Le1MPhy].into_iter().collect(),
+                preferred_retransmission_number: 3,
+                max_transport_latency: MaxTransportLatency::try_from(
+                    std::time::Duration::from_millis(10),
+                )
+                .unwrap(),
+                presentation_delay_range: delay_range,
+                codec_id: CodecId::Assigned(bt_common::core::CodingFormat::Lc3),
+                codec_config: vec![1, 2, 3],
+            },
+        };
+        let mut buf2 = vec![0; endpoint_codec.encoded_len()];
+        endpoint_codec.encode(&mut buf2).unwrap();
+
+        let decoded_endpoint_codec =
+            AudioStreamEndpoint::from_char_value(Handle(2), AudioDirection::Source, &buf2).unwrap();
+        assert_eq!(decoded_endpoint_codec.ase_id, endpoint_codec.ase_id);
+        assert_eq!(decoded_endpoint_codec.state, endpoint_codec.state);
+        assert_eq!(decoded_endpoint_codec.additional, endpoint_codec.additional);
+    }
+
+    #[test]
+    fn control_point_notification_roundtrip() {
+        // 1. Test Standard Multi-ASE notification roundtrip
+        let mut notification = ControlPointNotification::new(0x01); // Opcode ConfigCodec
+        notification.add_response(ResponseCode::Success { ase_id: AseId(1) });
+        notification.add_response(ResponseCode::InvalidAseId { value: 2 });
+
+        let mut buf = vec![0; notification.encoded_len()];
+        assert!(notification.encode(&mut buf).is_ok());
+
+        #[rustfmt::skip]
+        let expected_bytes = &[
+            0x01, // Opcode
+            0x02, // Number of ASEs
+            0x01, 0x00, 0x00, // Response 1: ASE 1, Success, None
+            0x02, 0x03, 0x00, // Response 2: ASE 2, Invalid ASE ID, None
+        ];
+        assert_eq!(buf, expected_bytes);
+
+        let (decoded, consumed) = ControlPointNotification::decode(&buf);
+        assert_eq!(consumed, buf.len());
+        assert_eq!(decoded.expect("should succeed"), notification);
+
+        // 2. Test Global Error Notification (0xFF) roundtrip
+        let err_notification = ControlPointNotification::new_error(0x01, 0x02); // Invalid Length error
+        let mut err_buf = vec![0; err_notification.encoded_len()];
+        assert!(err_notification.encode(&mut err_buf).is_ok());
+
+        #[rustfmt::skip]
+        let expected_err_bytes = &[
+            0x01, // Opcode
+            0xFF, // Number of ASEs: Global Error
+            0x00, 0x02, 0x00, // ASE 0, Invalid Length, None
+        ];
+        assert_eq!(err_buf, expected_err_bytes);
+
+        let (decoded_err, consumed_err) = ControlPointNotification::decode(&err_buf);
+        assert_eq!(consumed_err, err_buf.len());
+        assert_eq!(decoded_err.expect("should succeed"), err_notification);
+
+        // 3. Test Validation constraint fails on malformed 0xFF notification
+        // Case A: number_of_ases = 0xFF, but ase_id is not 0x00 (e.g., AseId 1)
+        #[rustfmt::skip]
+        let malformed_bytes_ase = &[
+            0x01, // Opcode
+            0xFF, // Global Error
+            0x01, 0x02, 0x00, // ASE 1, Invalid Length, None (ase_id must be 0x00)
+        ];
+        let (res_malformed_ase, _) = ControlPointNotification::decode(malformed_bytes_ase);
+        assert_eq!(res_malformed_ase, Err(bt_common::packet_encoding::Error::OutOfRange));
+
+        // Case B: number_of_ases = 0xFF, but response_code is not 0x01 or 0x02 (e.g.
+        // Success 0x00)
+        #[rustfmt::skip]
+        let malformed_bytes_code = &[
+            0x01, // Opcode
+            0xFF, // Global Error
+            0x00, 0x00, 0x00, // ASE 0, Success, None (response code must be 0x01 or 0x02)
+        ];
+        let (res_malformed_code, _) = ControlPointNotification::decode(malformed_bytes_code);
+        assert_eq!(
+            res_malformed_code,
+            Err(bt_common::packet_encoding::Error::UnexpectedDataLength)
+        );
+    }
 }
