diff --git a/rust/bt-ascs/src/server.rs b/rust/bt-ascs/src/server.rs
index 49b1225..982968f 100644
--- a/rust/bt-ascs/src/server.rs
+++ b/rust/bt-ascs/src/server.rs
@@ -2,7 +2,9 @@
 // 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};
@@ -143,15 +145,18 @@
             return None;
         }
         let mut notification = Vec::with_capacity(2 + self.response_codes.len() * 3);
-        // Opcode and Number_of_ASEs
+        // Opcode
         notification.push(self.opcode.unwrap().into());
-        if self.response_codes[0].ase_id_value() == 0x00 {
+        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());
@@ -364,7 +369,6 @@
 enum AseAdditionalParameters {
     /// When in states with no additional parameters: Idle, Releasing
     None,
-    /// When CodecConfigured
     CodecConfigured {
         framing: Framing,
         preferred_phys: Vec<Phy>,
@@ -374,6 +378,16 @@
         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 {
@@ -383,6 +397,10 @@
             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> {
@@ -409,10 +427,53 @@
                 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,
@@ -430,6 +491,16 @@
         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 {
@@ -529,8 +600,164 @@
 }
 
 #[derive(Debug)]
+pub struct QosConfigureResponder {
+    endpoint: AudioStreamEndpoint,
+    configuration: QosConfiguration,
+    sender: futures::channel::oneshot::Sender<Result<AudioStreamEndpoint, ResponseCode>>,
+}
+
+impl QosConfigureResponder {
+    pub fn reject(self, err: ResponseCode) {
+        let _ = self.sender.send(Err(err));
+    }
+
+    pub fn accept(mut self) {
+        self.endpoint.state = AseState::QosConfigured;
+        self.endpoint.additional = self.configuration.into();
+        let _ = self.sender.send(Ok(self.endpoint));
+    }
+}
+
+#[derive(Debug)]
+pub struct EnableResponder {
+    endpoint: AudioStreamEndpoint,
+    metadata: Vec<Metadata>,
+    sender: futures::channel::oneshot::Sender<Result<AudioStreamEndpoint, ResponseCode>>,
+}
+
+impl EnableResponder {
+    pub fn reject(self, err: ResponseCode) {
+        let _ = self.sender.send(Err(err));
+    }
+
+    pub fn accept(mut self) {
+        let AseAdditionalParameters::QosConfigured { configuration, .. } = self.endpoint.additional
+        else {
+            // Shouldn't happen
+            let _ = self
+                .sender
+                .send(Err(ResponseCode::UnspecifiedError { ase_id: self.endpoint.ase_id }));
+            return;
+        };
+        self.endpoint.state = AseState::Enabling;
+        self.endpoint.additional = AseAdditionalParameters::Streaming {
+            cig_id: configuration.cig_id,
+            cis_id: configuration.cis_id,
+            metadata: self.metadata,
+            qos_configured: configuration,
+        };
+        let _ = self.sender.send(Ok(self.endpoint));
+    }
+}
+
+#[derive(Debug)]
+pub struct DisableResponder {
+    endpoint: AudioStreamEndpoint,
+    sender: futures::channel::oneshot::Sender<Result<AudioStreamEndpoint, ResponseCode>>,
+}
+
+impl DisableResponder {
+    pub fn reject(self, err: ResponseCode) {
+        let _ = self.sender.send(Err(err));
+    }
+
+    pub fn accept(mut self) {
+        let AseAdditionalParameters::Streaming { qos_configured, .. } = self.endpoint.additional
+        else {
+            unreachable!();
+        };
+        self.endpoint.state = AseState::QosConfigured;
+        self.endpoint.additional = qos_configured.into();
+        let _ = self.sender.send(Ok(self.endpoint));
+    }
+}
+
+#[derive(Debug)]
+pub struct UpdateMetadataResponder {
+    endpoint: AudioStreamEndpoint,
+    metadata: Vec<Metadata>,
+    sender: futures::channel::oneshot::Sender<Result<AudioStreamEndpoint, ResponseCode>>,
+}
+
+impl UpdateMetadataResponder {
+    pub fn reject(self, err: ResponseCode) {
+        let _ = self.sender.send(Err(err));
+    }
+
+    pub fn accept(mut self) {
+        let AseAdditionalParameters::Streaming { metadata, .. } = &mut self.endpoint.additional
+        else {
+            unreachable!();
+        };
+        *metadata = self.metadata;
+        let _ = self.sender.send(Ok(self.endpoint));
+    }
+}
+
+#[derive(Debug)]
 pub enum ServiceEvent {
-    CodecConfigure { configuration: CodecConfiguration, responder: CodecConfigureResponder },
+    CodecConfigure {
+        configuration: CodecConfiguration,
+        responder: CodecConfigureResponder,
+    },
+    QosConfigure {
+        /// Peer configuring this stream
+        peer_id: PeerId,
+        /// Stream ID of the stream being configured
+        /// This ID is unique to the peer
+        // TODO: Consider replacing with source or sink, AseId should map to (Peer, Cig, Cis) at
+        // this point
+        target_configuration: QosConfiguration,
+        responder: QosConfigureResponder,
+    },
+    Enable {
+        /// Peer enabling this stream
+        peer_id: PeerId,
+        /// Stream ID of the stream being configured
+        ase_id: AseId,
+        /// Stream that this is being tied to.
+        /// This CIS may already be established after QosConfigure and will
+        /// match the QosConfigured value.
+        cis: (CigId, CisId),
+        /// Additional Metadata provided
+        /// Also available using
+        /// AudioStreamControlServiceServer::get_metadata(peer_id, ase_id)
+        metadata: Vec<Metadata>,
+        /// Responder.  Responding positively to this will start streaming if
+        /// the StreamEndpoint is a sink endpoint.  For a source
+        /// endpoint, an additional Start event will be generated to
+        /// indicate when the client is ready to receive data.
+        responder: EnableResponder,
+    },
+    /// Ok to start streaming.
+    /// Sent only for Source Endpoints.
+    /// No responder, this event has already been accepted.
+    Start {
+        peer_id: PeerId,
+        ase_id: AseId,
+        cis: (CigId, CisId),
+    },
+    /// Disable this stream.
+    /// Stop sending data on the CisId and CigId listed, or expect the client to
+    /// stop sending audio data.
+    Disable {
+        /// Peer disabling this stream
+        peer_id: PeerId,
+        /// Stream ID of this stream
+        ase_id: AseId,
+        /// Isochronous Stream that was previously in use.
+        cis: (CigId, CisId),
+        /// Responder.  Responding positively will indicate to the client that
+        /// data has ceased being sent.
+        responder: DisableResponder,
+    },
+    /// Update Metadata
+    UpdateMetadata {
+        peer_id: PeerId,
+        ase_id: AseId,
+        metadata: Vec<Metadata>,
+        responder: UpdateMetadataResponder,
+    },
 }
 
 impl CodecConfiguration {
@@ -551,6 +778,25 @@
     }
 }
 
+impl QosConfiguration {
+    fn into_event(
+        self,
+        peer_id: PeerId,
+        endpoint: AudioStreamEndpoint,
+        sender: oneshot::Sender<Result<AudioStreamEndpoint, ResponseCode>>,
+    ) -> crate::server::ServiceEvent {
+        ServiceEvent::QosConfigure {
+            peer_id,
+            target_configuration: self.clone(),
+            responder: crate::server::QosConfigureResponder {
+                endpoint,
+                configuration: self,
+                sender,
+            },
+        }
+    }
+}
+
 impl AseControlOperation {
     fn apply(
         self,
@@ -560,6 +806,7 @@
         let mut current_response_codes = Vec::new();
         let mut waiting = Vec::new();
         let mut events: Vec<crate::server::ServiceEvent> = Vec::new();
+        let mut endpoints = Vec::new();
         let opcode: Option<AseControlPointOpcode> = (&self).try_into().ok();
         match self {
             Self::ConfigCodec { codec_configurations, mut responses } => {
@@ -581,7 +828,205 @@
                     events.push(codec_configuration.into_event(endpoint.clone(), send));
                 }
             }
-            _ => todo!(),
+            Self::ConfigQos { qos_configurations, mut responses } => {
+                current_response_codes.append(&mut responses);
+                for configuration in qos_configurations {
+                    let ase_id = configuration.ase_id;
+                    let Some(endpoint) = endpoint_map.get(&ase_id) else {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseId { value: ase_id.into() });
+                        continue;
+                    };
+                    if !opcode.unwrap().allowed_in_state(&endpoint.state) {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseStateMachineTransition { ase_id });
+                        continue;
+                    }
+                    let (send, recv) = oneshot::channel();
+                    waiting.push(recv);
+                    events.push(configuration.into_event(peer_id, endpoint.clone(), send));
+                }
+            }
+            Self::Enable { ases_with_metadata, mut responses } => {
+                current_response_codes.append(&mut responses);
+                for AseIdWithMetadata { ase_id, metadata } in ases_with_metadata {
+                    let Some(endpoint) = endpoint_map.get(&ase_id) else {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseId { value: ase_id.into() });
+                        continue;
+                    };
+                    if !opcode.unwrap().allowed_in_state(&endpoint.state) {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseStateMachineTransition { ase_id });
+                        continue;
+                    }
+                    let (sender, recv) = oneshot::channel();
+                    waiting.push(recv);
+                    let cis = endpoint.get_cis().unwrap();
+                    let event = ServiceEvent::Enable {
+                        ase_id,
+                        cis,
+                        peer_id,
+                        metadata: metadata.clone(),
+                        responder: EnableResponder { endpoint: endpoint.clone(), metadata, sender },
+                    };
+                    events.push(event);
+                }
+            }
+            Self::ReceiverStartReady { ases } => {
+                for ase_id in ases {
+                    let Some(endpoint) = endpoint_map.get(&ase_id) else {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseId { value: ase_id.into() });
+                        continue;
+                    };
+                    if !opcode.unwrap().allowed_in_state(&endpoint.state) {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseStateMachineTransition { ase_id });
+                        continue;
+                    }
+                    if endpoint.direction != AudioDirection::Source {
+                        current_response_codes.push(ResponseCode::InvalidAseDirection { ase_id });
+                        continue;
+                    }
+                    let cis = endpoint.get_cis().unwrap();
+                    // Automatically accept.
+                    let mut endpoint = endpoint.clone();
+                    endpoint.state = AseState::Streaming;
+                    endpoints.push(endpoint);
+                    current_response_codes.push(ResponseCode::Success { ase_id });
+                    events.push(ServiceEvent::Start { peer_id, ase_id, cis });
+                }
+            }
+            Self::Disable { ases } => {
+                for ase_id in ases {
+                    let Some(endpoint) = endpoint_map.get(&ase_id) else {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseId { value: ase_id.into() });
+                        continue;
+                    };
+                    if !opcode.unwrap().allowed_in_state(&endpoint.state) {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseStateMachineTransition { ase_id });
+                        continue;
+                    }
+                    let AseAdditionalParameters::Streaming { cig_id, cis_id, .. } =
+                        endpoint.additional
+                    else {
+                        unreachable!();
+                    };
+                    if endpoint.direction == AudioDirection::Source {
+                        // Accept automatically, and wait for the ReceiverStopReady to send Disable
+                        // event.
+                        let mut endpoint = endpoint.clone();
+                        endpoint.state = AseState::Disabling;
+                        endpoints.push(endpoint);
+                        current_response_codes.push(ResponseCode::Success { ase_id });
+                        continue;
+                    }
+                    let (sender, recv) = oneshot::channel();
+                    waiting.push(recv);
+                    events.push(ServiceEvent::Disable {
+                        peer_id,
+                        ase_id,
+                        cis: (cig_id, cis_id),
+                        responder: DisableResponder { endpoint: endpoint.clone(), sender },
+                    });
+                }
+            }
+            Self::ReceiverStopReady { ases } => {
+                for ase_id in ases {
+                    let Some(endpoint) = endpoint_map.get(&ase_id) else {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseId { value: ase_id.into() });
+                        continue;
+                    };
+                    if !opcode.unwrap().allowed_in_state(&endpoint.state) {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseStateMachineTransition { ase_id });
+                        continue;
+                    }
+                    if endpoint.direction != AudioDirection::Source {
+                        current_response_codes.push(ResponseCode::InvalidAseDirection { ase_id });
+                        continue;
+                    }
+                    let AseAdditionalParameters::Streaming { cig_id, cis_id, .. } =
+                        endpoint.additional
+                    else {
+                        unreachable!();
+                    };
+                    let (sender, recv) = oneshot::channel();
+                    waiting.push(recv);
+                    events.push(ServiceEvent::Disable {
+                        peer_id,
+                        ase_id,
+                        cis: (cig_id, cis_id),
+                        responder: DisableResponder { endpoint: endpoint.clone(), sender },
+                    });
+                }
+            }
+            Self::Release { ases } => {
+                for ase_id in ases {
+                    let Some(endpoint) = endpoint_map.get(&ase_id) else {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseId { value: ase_id.into() });
+                        continue;
+                    };
+                    if !opcode.unwrap().allowed_in_state(&endpoint.state) {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseStateMachineTransition { ase_id });
+                        continue;
+                    }
+                    // Automatically accept.  We will automatically perform the Released operation
+                    // on the next poll.
+                    let mut endpoint = endpoint.clone();
+                    endpoint.state = AseState::Releasing;
+                    endpoint.additional = AseAdditionalParameters::None;
+                    current_response_codes.push(ResponseCode::Success { ase_id });
+                    endpoints.push(endpoint);
+                }
+            }
+            Self::Released { ase_id } => {
+                // Should only happen when we detect a link loss and are told so by the client.
+                // Therefore we can transition immediately.
+                // If there is no endpoint by that ase_id, we do nothing.
+                if let Some(mut endpoint) = endpoint_map.get(&ase_id).cloned() {
+                    // TODO(b/433287917): implement caching with either preferred or cached
+                    // configurations
+                    endpoint.state = AseState::Idle;
+                    endpoint.additional = AseAdditionalParameters::None;
+                    endpoints.push(endpoint);
+                } else {
+                    log::warn!("Received Released for unknown endpoint: {ase_id:?}");
+                }
+            }
+            Self::UpdateMetadata { ases_with_metadata, mut responses } => {
+                current_response_codes.append(&mut responses);
+                for AseIdWithMetadata { ase_id, metadata } in ases_with_metadata {
+                    let Some(endpoint) = endpoint_map.get(&ase_id) else {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseId { value: ase_id.into() });
+                        continue;
+                    };
+                    if ![AseState::Enabling, AseState::Streaming].contains(&endpoint.state) {
+                        current_response_codes
+                            .push(ResponseCode::InvalidAseStateMachineTransition { ase_id });
+                        continue;
+                    }
+                    let (sender, recv) = oneshot::channel();
+                    waiting.push(recv);
+                    events.push(ServiceEvent::UpdateMetadata {
+                        peer_id,
+                        ase_id,
+                        metadata: metadata.clone(),
+                        responder: UpdateMetadataResponder {
+                            endpoint: endpoint.clone(),
+                            metadata,
+                            sender,
+                        },
+                    });
+                }
+            }
         }
         (
             events,
@@ -589,7 +1034,7 @@
                 peer_id,
                 opcode,
                 current_response_codes,
-                endpoints: Vec::new(),
+                endpoints,
                 waiting: waiting.into_iter().collect(),
             },
         )
diff --git a/rust/bt-ascs/src/tests.rs b/rust/bt-ascs/src/tests.rs
index 7dd7a30..60ca82c 100644
--- a/rust/bt-ascs/src/tests.rs
+++ b/rust/bt-ascs/src/tests.rs
@@ -14,6 +14,7 @@
 use crate::server::AudioStreamControlServiceServer;
 use crate::server::ServiceEvent;
 use crate::server::{ASCS_SERVICE_ID, ASCS_UUID};
+use crate::types::CodecConfiguration;
 use crate::*;
 
 #[track_caller]
@@ -195,16 +196,41 @@
     assert!(peer_one_value[1] != peer_two_value[1]);
 }
 
-#[test]
-fn invalid_operation() {
-    let (mut ascs_server, fake_server, mut server_events) = published_server();
+#[track_caller]
+fn expect_control_point_notified(
+    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
+    server_events: &mut UnboundedReceiver<FakeServerEvent>,
+) -> Vec<u8> {
+    // Expect the write to be responded to / acknowledged and a notification from
+    // the CP handle and the Source ASE
+    match expect_service_event(server_events) {
+        FakeServerEvent::WriteResponded { value, .. } => assert!(value.is_ok()),
+        x => panic!("Expected acknowledge of write, got {x:?}"),
+    };
+    assert!(poll_server(ascs_server).is_pending());
+    match expect_service_event(server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(1), handle);
+            value
+        }
+        x => panic!("Expected acknowledge of write, got {x:?}"),
+    }
+}
 
+#[track_caller]
+fn find_ase_id(
+    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
+    fake_server: &FakeServer,
+    server_events: &mut UnboundedReceiver<FakeServerEvent>,
+    handle: Handle,
+) -> u8 {
     // Read the sink uuid
-    fake_server.incoming_read(PeerId(1), ASCS_SERVICE_ID, Handle(3), 0);
+    fake_server.incoming_read(PeerId(1), ASCS_SERVICE_ID, handle, 0);
     // Poll the ascs server, should not result in an ASCS event
-    assert!(poll_server(&mut ascs_server).is_pending());
+    assert!(poll_server(ascs_server).is_pending());
 
-    // Should have the response
+    // Find the AseId
     let sink_value;
     match server_events.poll_next_unpin(&mut futures_test::task::noop_context()) {
         Poll::Ready(Some(FakeServerEvent::ReadResponded { service_id, handle: _, value })) => {
@@ -215,6 +241,27 @@
     };
 
     let ase_id = sink_value[0];
+    // Should start in idle.
+    assert_eq!(sink_value[1], 0x00);
+    assert_eq!(sink_value.len(), 2);
+
+    ase_id
+}
+
+#[track_caller]
+fn find_first_ase_id(
+    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
+    fake_server: &FakeServer,
+    server_events: &mut UnboundedReceiver<FakeServerEvent>,
+) -> u8 {
+    find_ase_id(ascs_server, fake_server, server_events, Handle(3))
+}
+
+#[test]
+fn invalid_operation() {
+    let (mut ascs_server, fake_server, mut server_events) = published_server();
+
+    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);
 
     // Write an operation that is unknown.
     fake_server.incoming_write(
@@ -231,46 +278,18 @@
         x => panic!("Expected to still be pending, got {x:?}"),
     };
 
-    // Expect the write to be responded to / acknowledged and a notification from
-    // the CP handle and the Source ASE
-    match expect_service_event(&mut server_events) {
-        FakeServerEvent::WriteResponded { value, .. } => assert!(value.is_ok()),
-        x => panic!("Expected acknowledge of write, got {x:?}"),
-    };
-    assert!(poll_server(&mut ascs_server).is_pending());
-    match expect_service_event(&mut server_events) {
-        FakeServerEvent::Notified { handle, value, peers, .. } => {
-            assert!(peers.contains(&PeerId(1)));
-            assert_eq!(Handle(1), handle);
-            // Opcode should match
-            // Number_of_ASEs should be 0xFF (Table 4.7)
-            // ASE_ID is 0x00, and Reason should be 0x00
-            assert_eq!(value, &[0x1f, 0xFF, 0x00, 0x01, 0x00]);
-        }
-        x => panic!("Expected acknowledge of write, got {x:?}"),
-    };
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 0xFF (Table 4.7)
+    // ASE_ID is 0x00, and Reason should be 0x00
+    assert_eq!(cp_value, &[0x1f, 0xFF, 0x00, 0x01, 0x00]);
 }
 
 #[test]
 fn invalid_length() {
     let (mut ascs_server, fake_server, mut server_events) = published_server();
 
-    // Read the sink uuid
-    fake_server.incoming_read(PeerId(1), ASCS_SERVICE_ID, Handle(3), 0);
-    // Poll the ascs server, should not result in an ASCS event
-    assert!(poll_server(&mut ascs_server).is_pending());
-
-    // Should have the response
-    let sink_value;
-    match server_events.poll_next_unpin(&mut futures_test::task::noop_context()) {
-        Poll::Ready(Some(FakeServerEvent::ReadResponded { service_id, handle: _, value })) => {
-            assert_eq!(service_id, ASCS_SERVICE_ID);
-            sink_value = value.unwrap();
-        }
-        x => panic!("Expected the read to be responded to got {x:?}"),
-    };
-
-    let ase_id = sink_value[0];
+    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);
 
     // Write an operation that is the wrong length (too short)
     fake_server.incoming_write(
@@ -287,22 +306,736 @@
         x => panic!("Expected to still be pending, got {x:?}"),
     };
 
-    // Expect the write to be responded to / acknowledged and a notification from
-    // the CP handle and the Source ASE
-    match expect_service_event(&mut server_events) {
-        FakeServerEvent::WriteResponded { value, .. } => assert!(value.is_ok()),
-        x => panic!("Expected acknowledge of write, got {x:?}"),
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 0xFF (Table 4.7)
+    // ASE_ID is 0x00, and Reason should be 0x00
+    assert_eq!(cp_value, &[0x01, 0xFF, 0x00, 0x02, 0x00]);
+}
+
+#[track_caller]
+fn assert_handle_value_eq(
+    ascs_server: &mut Pin<Box<AudioStreamControlServiceServer<FakeTypes>>>,
+    fake_server: &FakeServer,
+    events: &mut UnboundedReceiver<FakeServerEvent>,
+    handle: Handle,
+    expected: &[u8],
+) {
+    // Read the sink uuid
+    fake_server.incoming_read(PeerId(1), ASCS_SERVICE_ID, handle, 0);
+    // Poll the ascs server, should not result in an ASCS event
+    assert!(poll_server(ascs_server).is_pending());
+    let sink_value;
+    match events.poll_next_unpin(&mut futures_test::task::noop_context()) {
+        Poll::Ready(Some(FakeServerEvent::ReadResponded { service_id, handle: _, value })) => {
+            assert_eq!(service_id, ASCS_SERVICE_ID);
+            sink_value = value.unwrap();
+        }
+        x => panic!("Expected the read to be responded to got {x:?}"),
     };
-    assert!(poll_server(&mut ascs_server).is_pending());
+
+    assert_eq!(sink_value, expected);
+}
+
+#[rustfmt::skip]
+fn build_codec_configure(ase_id: u8) -> Vec<u8> {
+    // Balanced Latency, 1m phy, LC3 codec (no company / company codecid): ltv (xx
+    // bytes), 48khz, frame_duration 10ms, stereo audio channels,
+    vec![
+        0x01, 0x01, ase_id, 0x02, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00,
+        0x10, // 16 bytes
+        0x02, 0x01, 0x08, // 48khz
+        0x02, 0x02, 0x01, // 10ms duration
+        0x05, 0x03, 0x00, 0x00, 0x00, 0x03, // FrontLeft + FrontRight
+        0x03, 0x04, 0x64, 0x00, // 100 bytes per codec frame
+    ]
+}
+
+#[test]
+fn invalid_ase_ids() {
+    let (mut ascs_server, fake_server, mut server_events) = published_server();
+
+    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);
+
+    // Try with an invalid ase_id
+    let codec_configure_bad_ase_id = build_codec_configure(0x00);
+
+    fake_server.incoming_write(
+        PeerId(1),
+        ASCS_SERVICE_ID,
+        Handle(1),
+        0,
+        codec_configure_bad_ase_id.clone(),
+    );
+
+    // Should have nothing to respond to
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected to still be pending, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match (0x01)
+    // Number_of_ASEs should be 1
+    // ASE_ID is 0x00, and Reason should be 0x03 (invalid ASE ID)
+    assert_eq!(cp_value, &[0x01, 0x01, 0x00, 0x03, 0x00]);
+
+    // Try with one valid and one invalid
+    let mut codec_configure_two_ase_ids_one_bad = build_codec_configure(ase_id);
+    // Adjust the number of ASEs
+    codec_configure_two_ase_ids_one_bad[1] = 0x02;
+    // This one has a bad ase_id in it
+    // TODO(b/518022833): adjust to find all ASE_IDs and randomly pick a non-used
+    // one)
+    let bad_ase_id_configure = build_codec_configure(ase_id | 0xF0);
+    // Skip the opcode and num of ase_ids in this one
+    codec_configure_two_ase_ids_one_bad.extend(&bad_ase_id_configure[2..]);
+
+    fake_server.incoming_write(
+        PeerId(1),
+        ASCS_SERVICE_ID,
+        Handle(1),
+        0,
+        codec_configure_two_ase_ids_one_bad.clone(),
+    );
+
+    // Should have the one valid CodecConfigure to repond to
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
+            configuration:
+                CodecConfiguration {
+                    target_latency,
+                    target_phy,
+                    codec_id,
+                    codec_specific_configuration,
+                    ase_id: configured_ase_id,
+                },
+            responder,
+        }))) => {
+            use crate::types::*;
+            use bt_common::core::{CodecId, CodingFormat};
+            assert_eq!(AseId(ase_id), configured_ase_id);
+            assert_eq!(target_latency, TargetLatency::TargetBalanced);
+            assert_eq!(target_phy, TargetPhy::Le1MPhy);
+            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
+            assert_eq!(codec_specific_configuration.len(), 16);
+            responder.accept(
+                Framing::Unframed,
+                vec![Phy::Le1MPhy],
+                0x10,
+                MaxTransportLatency::try_from(std::time::Duration::from_millis(40)).unwrap(),
+                PresentationDelayRange::build(20000, 100000).unwrap(),
+            );
+        }
+        x => panic!("Expected CodecConfigure, got {x:?}"),
+    }
+    // Then we should be pending.
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected to still be pending, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 2
+    // ASE_ID should match and succeed, and the other ase_id should have failed.
+    assert_eq!(cp_value, &[0x01, 0x02, ase_id | 0xF0, 0x03, 0x00, ase_id, 0x00, 0x00]);
+}
+
+#[test]
+fn application_rejection() {
+    let (mut ascs_server, fake_server, mut server_events) = published_server();
+
+    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);
+
+    // Codec configure
+    let codec_configure = build_codec_configure(ase_id);
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, codec_configure.clone());
+
+    // Should have a CodecConfigure to respond to. Let's reject.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
+            configuration:
+                CodecConfiguration {
+                    target_latency,
+                    target_phy,
+                    codec_id,
+                    codec_specific_configuration,
+                    ase_id,
+                },
+            responder,
+        }))) => {
+            use crate::types::*;
+            use bt_common::core::{CodecId, CodingFormat};
+            assert_eq!(target_latency, TargetLatency::TargetBalanced);
+            assert_eq!(target_phy, TargetPhy::Le1MPhy);
+            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
+            assert_eq!(codec_specific_configuration.len(), 16);
+            responder.reject(ResponseCode::InsufficientResources { ase_id });
+        }
+
+        x => panic!("Expected CodecConfigure, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and response should match.
+    assert_eq!(cp_value, &[0x01, 0x01, ase_id, 0x0D, 0x00]);
+}
+
+#[test]
+fn endpoint_lifecycle_source() {
+    let (mut ascs_server, fake_server, mut server_events) = published_server();
+
+    let ase_id = find_first_ase_id(&mut ascs_server, &fake_server, &mut server_events);
+
+    // QosConfigure the ase_id, with CIG 0x01, CIS 0x01, SDU Interval 0x1FF,
+    // Unframed, 1m PHY, Max SDU 0x0FFF, RetransmissionNumber 0xFF,
+    // Max_Transport_latency max (0x0FA0), and 30ms (0x007530)
+    let qos_configure = vec![
+        0x02, 0x01, ase_id, 0x01, 0x01, 0x00, 0xFF, 0x01, 0x00, 0x01, 0xFF, 0x0F, 0xFF, 0xA0, 0x0F,
+        0x30, 0x75, 0x00,
+    ];
+    // Can't transition to QoS without CodecConfigure first
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());
+
+    // Should have nothing to respond to
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected to still be pending, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1
+    // ASE_ID is 0x00, and Reason should be 0x04 (invalid state machine transition)
+    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x04, 0x00]);
+
+    // And the ASE should still be in idle.
+    assert_handle_value_eq(
+        &mut ascs_server,
+        &fake_server,
+        &mut server_events,
+        Handle(3),
+        &[ase_id, 0x00],
+    );
+
+    // Go to CodecConfigure
+    let codec_configure = build_codec_configure(ase_id);
+
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, codec_configure.clone());
+
+    // Should have a CodecConfigure to respond to.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
+            configuration:
+                CodecConfiguration {
+                    target_latency,
+                    target_phy,
+                    codec_id,
+                    codec_specific_configuration,
+                    ..
+                },
+            responder,
+        }))) => {
+            use crate::types::*;
+            use bt_common::core::{CodecId, CodingFormat};
+            assert_eq!(target_latency, TargetLatency::TargetBalanced);
+            assert_eq!(target_phy, TargetPhy::Le1MPhy);
+            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
+            assert_eq!(codec_specific_configuration.len(), 16);
+            responder.accept(
+                Framing::Unframed,
+                vec![Phy::Le1MPhy],
+                0x10,
+                MaxTransportLatency::try_from(std::time::Duration::from_millis(40)).unwrap(),
+                PresentationDelayRange::build(20000, 100000).unwrap(),
+            );
+        }
+
+        x => panic!("Expected CodecConfigure, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x01, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
     match expect_service_event(&mut server_events) {
         FakeServerEvent::Notified { handle, value, peers, .. } => {
             assert!(peers.contains(&PeerId(1)));
-            assert_eq!(Handle(1), handle);
-            // Opcode should match
-            // Number_of_ASEs should be 0xFF (Table 4.7)
-            // ASE_ID is 0x00, and Reason should be 0x00
-            assert_eq!(value, &[0x01, 0xFF, 0x00, 0x02, 0x00]);
+            assert_eq!(Handle(3), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x01); // Configured state
+            assert_eq!(value.len(), 2 + 23 + usize::from(value[24]))
+            // state length should be 2 (static) + 24
+            // (configured state) + len of codec
+            // configuration
         }
-        x => panic!("Expected acknowledge of write, got {x:?}"),
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // QoSConfigure
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());
+
+    // Should have a QosConfigure to respond to.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::QosConfigure {
+            peer_id,
+            target_configuration: _,
+            responder,
+        }))) => {
+            assert_eq!(peer_id, PeerId(1));
+            responder.accept();
+        }
+
+        x => panic!("Expected QoSConfigure, got {x:?}"),
     };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(3), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x02); // QoS Configured
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Enable
+    let enable = vec![0x03, 0x01, ase_id, 0x00];
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, enable.clone());
+
+    // Should have an event o respond to.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::Enable {
+            ase_id: enabled_ase_id, responder, ..
+        }))) => {
+            assert_eq!(ase_id, enabled_ase_id.0);
+            responder.accept();
+        }
+
+        x => panic!("Expected Enable, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x03, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(3), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x03); // Enabling
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Receiver Start Ready -> Streaming
+    let receiver_start_ready = vec![0x04, 0x01, ase_id];
+    fake_server.incoming_write(
+        PeerId(1),
+        ASCS_SERVICE_ID,
+        Handle(1),
+        0,
+        receiver_start_ready.clone(),
+    );
+
+    // We auto-accept this, so we should not have a response, but do generate an
+    // event.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::Start {
+            peer_id: _,
+            ase_id: started_ase_id,
+            cis: _,
+        }))) => {
+            assert_eq!(ase_id, started_ase_id.0);
+        }
+        x => panic!("Expected Start, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x04, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(3), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x04); // Streaming
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Disable -> Disabling
+    let disable = vec![0x05, 0x01, ase_id];
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, disable.clone());
+
+    // We auto-accept this, so we should not have a event.
+    // We also don't generate an event until Receiver Stop Ready
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected no event on Disable, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x05, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(3), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x05); // Disabling
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Receiver Stop Ready -> QoSConfigured
+    let receiver_stop_ready = vec![0x06, 0x01, ase_id];
+    fake_server.incoming_write(
+        PeerId(1),
+        ASCS_SERVICE_ID,
+        Handle(1),
+        0,
+        receiver_stop_ready.clone(),
+    );
+
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::Disable {
+            peer_id: _,
+            ase_id: disabled_ase_id,
+            cis: _,
+            responder,
+        }))) => {
+            assert_eq!(ase_id, disabled_ase_id.0);
+            responder.accept();
+        }
+        x => panic!("Expected Disable, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x06, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(3), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x02); // QosConfigured
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Release -> Releasing
+    let release = vec![0x08, 0x01, ase_id];
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, release.clone());
+
+    // We don't expect an event for this (disable has already happened
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected no event from release, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x08, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(3), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x06); // Releasing
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // TODO(b/518022833): Automated behaviors are not done yet
+    // TODO(b/518022833): Test Update Metadata
+}
+
+#[test]
+fn endpoint_lifecycle_sink() {
+    let (mut ascs_server, fake_server, mut server_events) = published_server();
+
+    // Handle 3 is the Sink ASE
+    let ase_id = find_ase_id(&mut ascs_server, &fake_server, &mut server_events, Handle(4));
+
+    // QosConfigure the ase_id, with CIG 0x01, CIS 0x01, SDU Interval 0x1FF,
+    // Unframed, 1m PHY, Max SDU 0x0FFF, RetransmissionNumber 0xFF,
+    // Max_Transport_latency max (0x0FA0), and 30ms (0x007530)
+    let qos_configure = vec![
+        0x02, 0x01, ase_id, 0x01, 0x01, 0x00, 0xFF, 0x01, 0x00, 0x01, 0xFF, 0x0F, 0xFF, 0xA0, 0x0F,
+        0x30, 0x75, 0x00,
+    ];
+    // Can't transition to QoS without CodecConfigure first
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());
+
+    // Should have nothing to respond to
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected to still be pending, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1
+    // ASE_ID is 0x00, and Reason should be 0x04 (invalid state machine transition)
+    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x04, 0x00]);
+
+    // And the ASE should still be in idle.
+    assert_handle_value_eq(
+        &mut ascs_server,
+        &fake_server,
+        &mut server_events,
+        Handle(4),
+        &[ase_id, 0x00],
+    );
+
+    // Go to CodecConfigure
+    let codec_configure = build_codec_configure(ase_id);
+
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, codec_configure.clone());
+
+    // Should have a CodecConfigure to respond to.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::CodecConfigure {
+            configuration:
+                CodecConfiguration {
+                    target_latency,
+                    target_phy,
+                    codec_id,
+                    codec_specific_configuration,
+                    ..
+                },
+            responder,
+        }))) => {
+            use crate::types::*;
+            use bt_common::core::{CodecId, CodingFormat};
+            assert_eq!(target_latency, TargetLatency::TargetBalanced);
+            assert_eq!(target_phy, TargetPhy::Le1MPhy);
+            assert_eq!(codec_id, CodecId::Assigned(CodingFormat::Lc3));
+            assert_eq!(codec_specific_configuration.len(), 16);
+            responder.accept(
+                Framing::Unframed,
+                vec![Phy::Le1MPhy],
+                0x10,
+                MaxTransportLatency::try_from(std::time::Duration::from_millis(40)).unwrap(),
+                PresentationDelayRange::build(20000, 100000).unwrap(),
+            );
+        }
+
+        x => panic!("Expected CodecConfigure, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x01, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(4), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x01); // Configured state
+            assert_eq!(value.len(), 2 + 23 + usize::from(value[24]))
+            // state length should be 2 (static) + 24
+            // (configured state) + len of codec
+            // configuration
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // QoSConfigure
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, qos_configure.clone());
+
+    // Should have a QosConfigure to respond to.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::QosConfigure {
+            peer_id,
+            target_configuration: _,
+            responder,
+        }))) => {
+            assert_eq!(peer_id, PeerId(1));
+            responder.accept();
+        }
+
+        x => panic!("Expected QoSConfigure, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x02, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(4), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x02); // QoS Configured
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Enable
+    let enable = vec![0x03, 0x01, ase_id, 0x00];
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, enable.clone());
+
+    // Should have an event to respond to.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::Enable {
+            ase_id: enabled_ase_id, responder, ..
+        }))) => {
+            assert_eq!(ase_id, enabled_ase_id.0);
+            responder.accept();
+        }
+
+        x => panic!("Expected Enable, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x03, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(4), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x03); // Enabling
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Receiver Start Ready should not be allowed from the client for a Sink ASE
+    let receiver_start_ready = vec![0x04, 0x01, ase_id];
+    fake_server.incoming_write(
+        PeerId(1),
+        ASCS_SERVICE_ID,
+        Handle(1),
+        0,
+        receiver_start_ready.clone(),
+    );
+
+    // Should not have an event for the error.
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected no event for invalid ReceiverStartReady, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x04, 0x01, ase_id, 0x05, 0x00]);
+
+    // TODO: We don't do server-initiated ReceiverStart yet, so we can't proceed to
+    // streaming.
+
+    // Disable -> QosConfigured
+    let disable = vec![0x05, 0x01, ase_id];
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, disable.clone());
+
+    // On Sink ASE, we generate the Disable event when Disabling.
+    match poll_server(&mut ascs_server) {
+        Poll::Ready(Some(Ok(ServiceEvent::Disable {
+            peer_id: _,
+            ase_id: disabled_ase_id,
+            cis: _,
+            responder,
+        }))) => {
+            assert_eq!(ase_id, disabled_ase_id.0);
+            responder.accept();
+        }
+        x => panic!("Expected Disable, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x05, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(4), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x02); // Automatically went to QoSConfigure
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // Receiver Stop Ready is not allowed for a Sink ASE
+    let receiver_stop_ready = vec![0x06, 0x01, ase_id];
+    fake_server.incoming_write(
+        PeerId(1),
+        ASCS_SERVICE_ID,
+        Handle(1),
+        0,
+        receiver_stop_ready.clone(),
+    );
+
+    assert!(poll_server(&mut ascs_server).is_pending());
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and Failure for Invalid ASE
+    // State Transition (since we are already in QosCondfiguredj
+    assert_eq!(cp_value, &[0x06, 0x01, ase_id, 0x04, 0x00]);
+
+    // Release -> Releasing
+    let release = vec![0x08, 0x01, ase_id];
+    fake_server.incoming_write(PeerId(1), ASCS_SERVICE_ID, Handle(1), 0, release.clone());
+
+    // We don't expect an event for this (disable has already happened
+    match poll_server(&mut ascs_server) {
+        Poll::Pending => {}
+        x => panic!("Expected no event from release, got {x:?}"),
+    };
+
+    let cp_value = expect_control_point_notified(&mut ascs_server, &mut server_events);
+    // Opcode should match
+    // Number_of_ASEs should be 1 should match ASE_ID and success 0x00
+    assert_eq!(cp_value, &[0x08, 0x01, ase_id, 0x00, 0x00]);
+
+    // And the ASE should be configured and notified
+    match expect_service_event(&mut server_events) {
+        FakeServerEvent::Notified { handle, value, peers, .. } => {
+            assert!(peers.contains(&PeerId(1)));
+            assert_eq!(Handle(4), handle);
+            assert_eq!(value[0], ase_id);
+            assert_eq!(value[1], 0x06); // Releasing
+        }
+        x => panic!("Expected Endpoint Notification, got {x:?}"),
+    }
+
+    // TODO: Automated behaviors are not done yet
+    // TODO: Test Update Metadata
 }
diff --git a/rust/bt-ascs/src/types.rs b/rust/bt-ascs/src/types.rs
index 0681283..6eb27c9 100644
--- a/rust/bt-ascs/src/types.rs
+++ b/rust/bt-ascs/src/types.rs
@@ -220,7 +220,7 @@
             Self::Enable { .. } => &[AseState::QosConfigured],
             Self::ReceiverStartReady { .. } => &[AseState::Enabling],
             Self::ReceiverStopReady { .. } => &[AseState::Disabling],
-            Self::Disable { .. } => &[AseState::Streaming],
+            Self::Disable { .. } => &[AseState::Streaming, AseState::Enabling],
             Self::UpdateMetadata { .. } => &[AseState::Enabling, AseState::Streaming],
             Self::Release { .. } => &[
                 AseState::Enabling,
@@ -255,7 +255,7 @@
     // The only possible error here is InvalidLength
     Release { ases: Vec<AseId> },
     // This is only initiated by the server
-    Released,
+    Released { ase_id: AseId },
 }
 
 impl AseControlOperation {
@@ -287,7 +287,7 @@
             AseControlOperation::ReceiverStopReady { .. } => Ok(0x06),
             AseControlOperation::UpdateMetadata { .. } => Ok(0x07),
             AseControlOperation::Release { .. } => Ok(0x08),
-            AseControlOperation::Released => Err(Error::ServerOnlyOperation),
+            AseControlOperation::Released { .. } => Err(Error::ServerOnlyOperation),
         }
     }
 }
@@ -642,6 +642,20 @@
     }
 }
 
+impl Encodable for CigId {
+    type Error = bt_common::packet_encoding::Error;
+    fn encoded_len(&self) -> core::primitive::usize {
+        Self::BYTE_SIZE
+    }
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < Self::BYTE_SIZE {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        buf[0] = self.0;
+        Ok(())
+    }
+}
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct CisId(u8);
 
@@ -667,6 +681,20 @@
     }
 }
 
+impl Encodable for CisId {
+    type Error = bt_common::packet_encoding::Error;
+    fn encoded_len(&self) -> core::primitive::usize {
+        Self::BYTE_SIZE
+    }
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < Self::BYTE_SIZE {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        buf[0] = self.0;
+        Ok(())
+    }
+}
+
 /// SDU Inteval parameter
 /// This value is 24 bits long and little-endian on the wire.
 /// It is stored native-endian here.
@@ -693,6 +721,20 @@
     }
 }
 
+impl Encodable for SduInterval {
+    type Error = bt_common::packet_encoding::Error;
+    fn encoded_len(&self) -> core::primitive::usize {
+        Self::BYTE_SIZE
+    }
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < Self::BYTE_SIZE {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        [buf[0], buf[1], buf[2], _] = self.0.to_le_bytes();
+        Ok(())
+    }
+}
+
 decodable_enum! {
 pub enum Framing<u8, bt_common::packet_encoding::Error, OutOfRange> {
     Unframed = 0x00,
@@ -704,6 +746,20 @@
     const BYTE_SIZE: usize = 1;
 }
 
+impl Encodable for Framing {
+    type Error = bt_common::packet_encoding::Error;
+    fn encoded_len(&self) -> core::primitive::usize {
+        Self::BYTE_SIZE
+    }
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < Self::BYTE_SIZE {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        buf[0] = (*self).into();
+        Ok(())
+    }
+}
+
 /// Max SDU parameter value.
 /// Valid range is 0x0000-0x0FFF
 /// Transmitted in little-endian. Stored here in native-endian.
@@ -722,6 +778,20 @@
     }
 }
 
+impl Encodable for MaxSdu {
+    type Error = bt_common::packet_encoding::Error;
+    fn encoded_len(&self) -> core::primitive::usize {
+        Self::BYTE_SIZE
+    }
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < Self::BYTE_SIZE {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        [buf[0], buf[1]] = self.0.to_le_bytes();
+        Ok(())
+    }
+}
+
 impl MaxSdu {
     const BYTE_SIZE: usize = 2;
 }
