diff --git a/rust/bt-mcs/src/server.rs b/rust/bt-mcs/src/server.rs
index 59e5d68..f666070 100644
--- a/rust/bt-mcs/src/server.rs
+++ b/rust/bt-mcs/src/server.rs
@@ -5,10 +5,12 @@
 //! Implements the Media Control Service (MCS) server.
 
 use bt_common::Uuid;
-use bt_gatt::server::{LocalService, Server as _, ServiceDefinition, ServiceEvent, ServiceId};
+use bt_gatt::server::{
+    LocalService, ReadResponder, Server as _, ServiceDefinition, ServiceEvent, ServiceId,
+};
 use bt_gatt::types::{
-    AttributePermissions, CharacteristicProperties, CharacteristicProperty, Handle, SecurityLevels,
-    ServiceKind,
+    AttributePermissions, CharacteristicProperties, CharacteristicProperty, GattError, Handle,
+    SecurityLevels, ServiceKind,
 };
 use bt_gatt::Characteristic;
 use futures::stream::Stream;
@@ -218,16 +220,106 @@
     }
 }
 
+/// Local state of the mandatory characteristics in this server.
+#[derive(Debug, Clone, PartialEq, Eq)]
+struct McsLocalState {
+    /// Content Control ID (CCID) identifying this media service instance.
+    ccid: u8,
+    /// Human-readable media player application name.
+    player_name: String,
+    /// Title of the currently selected track (empty if no track loaded).
+    track_title: String,
+    /// Total duration of the current track (MCS v1.0.1 Section 3.6).
+    track_duration: TrackDuration,
+    /// Base playback position of the current track (MCS v1.0.1 Section 3.7).
+    track_position: TrackPosition,
+    /// Timestamp when `track_position` was set or updated.
+    position_updated_at: Option<std::time::Instant>,
+    /// Current player activity state.
+    media_state: MediaState,
+}
+
+impl McsLocalState {
+    /// Creates a new [`McsLocalState`] with default values for an inactive
+    /// player with no track loaded per MCS v1.0.1 Section 3.
+    fn new(ccid: u8, player_name: impl Into<String>) -> Self {
+        Self {
+            ccid,
+            player_name: player_name.into(),
+            track_title: String::new(),
+            track_duration: TrackDuration::Unknown,
+            track_position: TrackPosition::Unavailable,
+            position_updated_at: None,
+            media_state: MediaState::Inactive,
+        }
+    }
+
+    /// Calculates the instantaneous track position based on elapsed playback
+    /// time (MCS v1.0.1 Section 3.7).
+    fn current_track_position(&self) -> TrackPosition {
+        // Per MCS Section 3.17, an inactive player has no current track, so it is
+        // unavailable.
+        if self.media_state == MediaState::Inactive {
+            return TrackPosition::Unavailable;
+        }
+
+        // Playback timing has not started since the track was just initialized.
+        let Some(updated_at) = self.position_updated_at else {
+            return self.track_position;
+        };
+
+        // Playback is paused/seeking, so the position remains fixed.
+        if self.media_state != MediaState::Playing {
+            return self.track_position;
+        }
+
+        let base = match (self.track_position, self.track_duration) {
+            (TrackPosition::FromStart(base), _) => base,
+            (TrackPosition::FromEnd(end), TrackDuration::Duration(total)) => {
+                total.saturating_sub(end)
+            }
+            _ => return self.track_position,
+        };
+
+        // TODO(b/540400364): Factor in optional playback speed when supported
+        let mut current = base + updated_at.elapsed();
+        if let TrackDuration::Duration(total) = self.track_duration {
+            current = current.min(total);
+        }
+        TrackPosition::FromStart(current)
+    }
+
+    /// Reads the characteristic bytes for `handle` at `offset`.
+    fn handle_read(&self, handle: Handle, offset: usize) -> Result<Vec<u8>, GattError> {
+        // Track Changed is notify-only. Return Error. See MCS v1.0.1 Section 3.4.
+        if handle == TRACK_CHANGED_HANDLE {
+            return Err(GattError::ReadNotPermitted);
+        }
+
+        let read_at_offset =
+            |bytes: &[u8]| bytes.get(offset..).map(Vec::from).ok_or(GattError::InvalidOffset);
+        match handle {
+            MEDIA_PLAYER_NAME_HANDLE => read_at_offset(self.player_name.as_bytes()),
+            TRACK_TITLE_HANDLE => read_at_offset(self.track_title.as_bytes()),
+            TRACK_DURATION_HANDLE => read_at_offset(&self.track_duration.raw_10ms().to_le_bytes()),
+            TRACK_POSITION_HANDLE => {
+                read_at_offset(&self.current_track_position().raw_10ms().to_le_bytes())
+            }
+            MEDIA_STATE_HANDLE => read_at_offset(&[self.media_state.into()]),
+            CONTENT_CONTROL_ID_HANDLE => read_at_offset(&[self.ccid]),
+            _ => Err(GattError::InvalidHandle),
+        }
+    }
+}
+
 /// Builder for configuring an MCS or GMCS GATT service.
+// TODO(b/549911651): Add support for OTS (Object Transfer Service) integration.
 #[derive(Debug, Clone, PartialEq)]
 pub struct McsServerBuilder {
     /// Service UUID assigned to the service.
     service_uuid: Uuid,
-    /// Content Control ID (CCID) identifying this media service instance. This
-    /// is unique across all MCS/GMCS instances on the host server.
-    ccid: u8,
-    /// Human-readable media player application name.
-    player_name: String,
+    /// Local state of the characteristics in this server.
+    state: McsLocalState,
 }
 
 impl McsServerBuilder {
@@ -242,7 +334,7 @@
     }
 
     fn new(service_uuid: Uuid, ccid: u8, player_name: impl Into<String>) -> Self {
-        Self { service_uuid, ccid, player_name: player_name.into() }
+        Self { service_uuid, state: McsLocalState::new(ccid, player_name) }
     }
 
     /// Constructs the complete GATT [`ServiceDefinition`] containing all 13
@@ -253,7 +345,7 @@
         // host server. Adding a duplicate characteristic will result in an
         // Error.
         let mut service_def = ServiceDefinition::new(
-            ServiceId::new(self.ccid.into()),
+            ServiceId::new(self.state.ccid.into()),
             self.service_uuid,
             ServiceKind::Primary,
         );
@@ -268,12 +360,7 @@
     /// Builds an [`McsServer`] configured with this builder.
     pub fn build<T: bt_gatt::ServerTypes>(self) -> Result<McsServer<T>, Error> {
         let service_def = self.build_service_definition()?;
-        Ok(McsServer {
-            service_def,
-            local_service: Default::default(),
-            ccid: self.ccid,
-            player_name: self.player_name,
-        })
+        Ok(McsServer { service_def, local_service: Default::default(), state: self.state })
     }
 }
 
@@ -284,8 +371,8 @@
     service_def: ServiceDefinition,
     #[pin]
     local_service: LocalServiceState<T>,
-    ccid: u8,
-    player_name: String,
+    /// Local state of the characteristics in this server.
+    state: McsLocalState,
 }
 
 impl<T: bt_gatt::ServerTypes> McsServer<T> {
@@ -315,6 +402,13 @@
 
         Ok(())
     }
+
+    fn handle_read<R: ReadResponder>(&self, handle: Handle, offset: usize, responder: R) {
+        match self.state.handle_read(handle, offset) {
+            Ok(bytes) => responder.respond(&bytes),
+            Err(err) => responder.error(err),
+        }
+    }
 }
 
 impl<T: bt_gatt::ServerTypes> Stream for McsServer<T> {
@@ -325,14 +419,17 @@
         cx: &mut Context<'_>,
     ) -> Poll<Option<Self::Item>> {
         loop {
-            let mut this = self.as_mut().project();
-            let gatt_event = match futures::ready!(this.local_service.as_mut().poll_next(cx)) {
-                None => return Poll::Ready(None),
-                Some(Err(e)) => return Poll::Ready(Some(Err(e))),
-                Some(Ok(event)) => event,
-            };
+            let gatt_event =
+                match futures::ready!(self.as_mut().project().local_service.poll_next(cx)) {
+                    None => return Poll::Ready(None),
+                    Some(Err(e)) => return Poll::Ready(Some(Err(e))),
+                    Some(Ok(event)) => event,
+                };
             match gatt_event {
-                // TODO(b/540400364): Add support for characteristic reads and writes
+                ServiceEvent::Read { peer_id: _, handle, offset, responder } => {
+                    self.handle_read(handle, offset as usize, responder);
+                }
+                // TODO(b/540400364): Add support for characteristic writes
                 _ => continue,
             }
         }
@@ -343,7 +440,9 @@
 mod tests {
     use super::*;
 
-    use bt_gatt::test_utils::{FakeServer, FakeTypes};
+    use bt_common::PeerId;
+    use bt_gatt::test_utils::{FakeServer, FakeServerEvent, FakeTypes};
+    use bt_gatt::types::GattError;
     use futures::{FutureExt, StreamExt};
 
     #[test]
@@ -536,4 +635,304 @@
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert!(matches!(poll_result, Poll::Ready(None)));
     }
+
+    fn setup_test_server(
+        builder: McsServerBuilder,
+    ) -> (
+        McsServer<FakeTypes>,
+        FakeServer,
+        futures::channel::mpsc::UnboundedReceiver<FakeServerEvent>,
+    ) {
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+        let (fake_gatt_server, mut event_receiver) = FakeServer::new();
+        let mut server: McsServer<FakeTypes> = builder.build().expect("server builds successfully");
+        server.publish(fake_gatt_server.clone()).expect("publish succeeds");
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        assert!(matches!(event_receiver.try_recv().unwrap(), FakeServerEvent::Published { .. }));
+        (server, fake_gatt_server, event_receiver)
+    }
+
+    fn assert_read_characteristic(
+        server: &mut McsServer<FakeTypes>,
+        fake_gatt_server: &FakeServer,
+        event_receiver: &mut futures::channel::mpsc::UnboundedReceiver<FakeServerEvent>,
+        handle: Handle,
+        expected: &[u8],
+    ) {
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+        let peer = PeerId(1);
+        let service_id = server.service_def.id();
+        fake_gatt_server.incoming_read(peer, service_id, handle, 0);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
+            event_receiver.try_recv().unwrap()
+        else {
+            panic!("expected ReadResponded");
+        };
+        assert_eq!(value.unwrap(), expected);
+    }
+
+    #[test]
+    fn read_mandatory_characteristics_default_values() {
+        let (mut server, fake_gatt_server, mut event_receiver) =
+            setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
+
+        // Media Player Name (0x2B93)
+        assert_read_characteristic(
+            &mut server,
+            &fake_gatt_server,
+            &mut event_receiver,
+            MEDIA_PLAYER_NAME_HANDLE,
+            b"Test Player",
+        );
+
+        // Track Title (0x2B97)
+        assert_read_characteristic(
+            &mut server,
+            &fake_gatt_server,
+            &mut event_receiver,
+            TRACK_TITLE_HANDLE,
+            b"",
+        );
+
+        // Track Duration (0x2B98)
+        assert_read_characteristic(
+            &mut server,
+            &fake_gatt_server,
+            &mut event_receiver,
+            TRACK_DURATION_HANDLE,
+            &(-1i32).to_le_bytes(),
+        );
+
+        // Track Position (0x2B99)
+        assert_read_characteristic(
+            &mut server,
+            &fake_gatt_server,
+            &mut event_receiver,
+            TRACK_POSITION_HANDLE,
+            &(-1i32).to_le_bytes(),
+        );
+
+        // Media State (0x2BA3)
+        assert_read_characteristic(
+            &mut server,
+            &fake_gatt_server,
+            &mut event_receiver,
+            MEDIA_STATE_HANDLE,
+            &[MediaState::Inactive.into()],
+        );
+
+        // Content Control ID (0x2BA8)
+        assert_read_characteristic(
+            &mut server,
+            &fake_gatt_server,
+            &mut event_receiver,
+            CONTENT_CONTROL_ID_HANDLE,
+            &[0x42],
+        );
+    }
+
+    #[test]
+    fn read_string_characteristics_with_offset() {
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+        let (mut server, fake_gatt_server, mut event_receiver) =
+            setup_test_server(McsServerBuilder::generic(0x42, "Long Player Name"));
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        // Valid offset slice
+        fake_gatt_server.incoming_read(peer, service_id, MEDIA_PLAYER_NAME_HANDLE, 5);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
+            event_receiver.try_recv().unwrap()
+        else {
+            panic!("expected ReadResponded");
+        };
+        assert_eq!(value.unwrap(), b"Player Name");
+
+        // Exact end offset returns empty slice
+        fake_gatt_server.incoming_read(
+            peer,
+            service_id,
+            MEDIA_PLAYER_NAME_HANDLE,
+            "Long Player Name".len() as u32,
+        );
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
+            event_receiver.try_recv().unwrap()
+        else {
+            panic!("expected ReadResponded");
+        };
+        assert_eq!(value.unwrap(), b"");
+
+        // Out-of-bounds offset returns InvalidOffset
+        fake_gatt_server.incoming_read(peer, service_id, MEDIA_PLAYER_NAME_HANDLE, 100);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
+            event_receiver.try_recv().unwrap()
+        else {
+            panic!("expected ReadResponded");
+        };
+        assert!(matches!(
+            value.unwrap_err(),
+            bt_gatt::types::Error::Gatt(GattError::InvalidOffset)
+        ));
+    }
+
+    #[test]
+    fn read_non_readable_characteristics_returns_error() {
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+        let (mut server, fake_gatt_server, mut event_receiver) =
+            setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        // Track Changed is notify-only
+        fake_gatt_server.incoming_read(peer, service_id, TRACK_CHANGED_HANDLE, 0);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
+            event_receiver.try_recv().unwrap()
+        else {
+            panic!("expected ReadResponded");
+        };
+        assert!(matches!(
+            value.unwrap_err(),
+            bt_gatt::types::Error::Gatt(GattError::ReadNotPermitted)
+        ));
+
+        // Unknown handle returns InvalidHandle
+        fake_gatt_server.incoming_read(peer, service_id, Handle(999), 0);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
+            event_receiver.try_recv().unwrap()
+        else {
+            panic!("expected ReadResponded");
+        };
+        assert!(matches!(
+            value.unwrap_err(),
+            bt_gatt::types::Error::Gatt(GattError::InvalidHandle)
+        ));
+    }
+
+    #[test]
+    fn local_state_track_position_calculation() {
+        let mut state = McsLocalState::new(0x01, "Test Player");
+
+        // When no track is loaded, position is Unavailable regardless of state.
+        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);
+        state.media_state = MediaState::Playing;
+        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);
+
+        // When paused or seeking with a loaded track, position does not advance with
+        // time.
+        state.media_state = MediaState::Paused;
+        state.track_position = TrackPosition::from_start(std::time::Duration::from_millis(5000));
+        state.position_updated_at =
+            Some(std::time::Instant::now() - std::time::Duration::from_secs(10));
+        assert_eq!(
+            state.current_track_position(),
+            TrackPosition::from_start(std::time::Duration::from_millis(5000))
+        );
+        state.media_state = MediaState::Seeking;
+        assert_eq!(
+            state.current_track_position(),
+            TrackPosition::from_start(std::time::Duration::from_millis(5000))
+        );
+
+        // When playing with a loaded track (FromStart), position advances based on
+        // elapsed time.
+        state.media_state = MediaState::Playing;
+        state.track_duration = TrackDuration::from_duration(std::time::Duration::from_secs(20));
+        state.track_position = TrackPosition::from_start(std::time::Duration::from_millis(5000));
+        state.position_updated_at =
+            Some(std::time::Instant::now() - std::time::Duration::from_millis(500));
+        let computed = state.current_track_position();
+        let TrackPosition::FromStart(dur) = computed else {
+            panic!("expected FromStart");
+        };
+        assert!(
+            dur >= std::time::Duration::from_millis(5450)
+                && dur <= std::time::Duration::from_millis(5650),
+            "unexpected computed position: {dur:?}"
+        );
+
+        // When elapsed time exceeds track duration, position is clamped to duration.
+        state.position_updated_at =
+            Some(std::time::Instant::now() - std::time::Duration::from_secs(100));
+        assert_eq!(
+            state.current_track_position(),
+            TrackPosition::from_start(std::time::Duration::from_secs(20))
+        );
+
+        // When playing with a track position relative to end (FromEnd), base is
+        // duration - offset.
+        state.track_duration = TrackDuration::from_duration(std::time::Duration::from_secs(30));
+        state.track_position = TrackPosition::from_end(std::time::Duration::from_secs(10));
+        state.position_updated_at =
+            Some(std::time::Instant::now() - std::time::Duration::from_millis(500));
+        // Base is 30s - 10s = 20s. Elapsed 500ms -> ~20.5s from start.
+        let computed = state.current_track_position();
+        let TrackPosition::FromStart(dur) = computed else {
+            panic!("expected FromStart");
+        };
+        assert!(
+            dur >= std::time::Duration::from_millis(20450)
+                && dur <= std::time::Duration::from_millis(20650),
+            "unexpected computed position: {dur:?}"
+        );
+
+        // When FromEnd elapsed time exceeds track duration, position is clamped to
+        // duration.
+        state.position_updated_at =
+            Some(std::time::Instant::now() - std::time::Duration::from_secs(100));
+        assert_eq!(
+            state.current_track_position(),
+            TrackPosition::from_start(std::time::Duration::from_secs(30))
+        );
+
+        // When FromEnd is used with unknown duration, it cannot resolve to FromStart
+        // and returns FromEnd.
+        state.track_duration = TrackDuration::Unknown;
+        state.track_position = TrackPosition::from_end(std::time::Duration::from_secs(10));
+        assert_eq!(
+            state.current_track_position(),
+            TrackPosition::from_end(std::time::Duration::from_secs(10))
+        );
+    }
+
+    #[test]
+    fn read_track_position_during_active_playback() {
+        let (mut server, fake_gatt_server, mut event_receiver) =
+            setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
+
+        // Set server state to Playing with a loaded track at position 500 (5.0
+        // seconds).
+        server.state.media_state = MediaState::Playing;
+        server.state.track_duration =
+            TrackDuration::from_duration(std::time::Duration::from_secs(60));
+        server.state.track_position =
+            TrackPosition::from_start(std::time::Duration::from_millis(5000));
+        server.state.position_updated_at =
+            Some(std::time::Instant::now() - std::time::Duration::from_millis(1000));
+
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+        let peer = PeerId(1);
+        let service_id = server.service_def.id();
+        fake_gatt_server.incoming_read(peer, service_id, TRACK_POSITION_HANDLE, 0);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
+            event_receiver.try_recv().unwrap()
+        else {
+            panic!("expected ReadResponded");
+        };
+
+        let raw_bytes = value.unwrap();
+        assert_eq!(raw_bytes.len(), 4);
+        let raw_10ms = i32::from_le_bytes(raw_bytes.try_into().unwrap());
+        // 5000ms + 1000ms elapsed = 6000ms = 600 units of 10ms (allow minor jitter +/-
+        // 30 units)
+        assert!(raw_10ms >= 580 && raw_10ms <= 640, "unexpected raw_10ms: {raw_10ms}");
+    }
 }
diff --git a/rust/bt-mcs/src/types.rs b/rust/bt-mcs/src/types.rs
index cd49de0..30043ac 100644
--- a/rust/bt-mcs/src/types.rs
+++ b/rust/bt-mcs/src/types.rs
@@ -5,6 +5,7 @@
 use bitflags::bitflags;
 use bt_common::packet_encoding::{Decodable, Encodable, Error as PacketError};
 use bt_common::{decodable_enum, Uuid};
+use std::time::Duration;
 
 /// 16-bit UUID for the Media Control Service (MCS).
 /// Defined in MCS v1.0.1 Section 2
@@ -206,6 +207,13 @@
     }
 }
 
+impl Default for SupportedPlayingOrders {
+    /// Returns standard sequential playing order (`IN_ORDER_ONCE`) by default.
+    fn default() -> Self {
+        Self::IN_ORDER_ONCE
+    }
+}
+
 impl From<PlayingOrder> for SupportedPlayingOrders {
     fn from(order: PlayingOrder) -> Self {
         match order {
@@ -456,6 +464,14 @@
     }
 }
 
+impl Default for SupportedOpcodes {
+    /// Returns basic media playback control opcodes (`PLAY | PAUSE | STOP`) by
+    /// default.
+    fn default() -> Self {
+        Self::PLAY | Self::PAUSE | Self::STOP
+    }
+}
+
 impl From<&MediaControlOpcode> for SupportedOpcodes {
     fn from(opcode: &MediaControlOpcode) -> Self {
         match opcode {
@@ -518,6 +534,152 @@
     }
 }
 
+/// Total duration of the current track (MCS v1.0.1 Section 3.6).
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum TrackDuration {
+    /// Total duration of the current track.
+    Duration(Duration),
+    /// Duration is unknown or no track is loaded.
+    Unknown,
+}
+
+impl TrackDuration {
+    /// Size of the encoded Track Duration characteristic in bytes.
+    pub const SIZE_BYTES: usize = 4;
+
+    /// Raw integer value representing unknown track duration.
+    pub const UNKNOWN_RAW: i32 = -1;
+
+    /// Creates a known track duration.
+    pub const fn from_duration(duration: Duration) -> Self {
+        Self::Duration(duration)
+    }
+
+    /// Creates a track duration from a raw 10-millisecond unit 32-bit signed
+    /// integer.
+    pub fn from_raw_10ms(raw: i32) -> Self {
+        match raw {
+            Self::UNKNOWN_RAW => Self::Unknown,
+            dur if dur >= 0 => Self::Duration(Duration::from_millis(dur as u64 * 10)),
+            _ => Self::Unknown,
+        }
+    }
+
+    /// Returns the raw 32-bit signed integer in 10-millisecond units.
+    pub fn raw_10ms(&self) -> i32 {
+        match self {
+            Self::Unknown => Self::UNKNOWN_RAW,
+            Self::Duration(d) => (d.as_millis() / 10).min(i32::MAX as u128) as i32,
+        }
+    }
+}
+
+impl Encodable for TrackDuration {
+    type Error = PacketError;
+
+    fn encoded_len(&self) -> usize {
+        Self::SIZE_BYTES
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> Result<(), Self::Error> {
+        if buf.len() < Self::SIZE_BYTES {
+            return Err(PacketError::BufferTooSmall);
+        }
+        buf[0..Self::SIZE_BYTES].copy_from_slice(&self.raw_10ms().to_le_bytes());
+        Ok(())
+    }
+}
+
+impl Decodable for TrackDuration {
+    type Error = PacketError;
+
+    fn decode(buf: &[u8]) -> (Result<Self, Self::Error>, usize) {
+        if buf.len() < Self::SIZE_BYTES {
+            return (Err(PacketError::UnexpectedDataLength), 0);
+        }
+        let raw = i32::from_le_bytes([buf[0], buf[1], buf[2], buf[3]]);
+        (Ok(Self::from_raw_10ms(raw)), Self::SIZE_BYTES)
+    }
+}
+
+/// Current track position of the media player in 0.01-second (10 ms) resolution
+/// (MCS v1.0.1 Section 3.7).
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum TrackPosition {
+    /// Absolute offset from the start of the current track.
+    FromStart(Duration),
+    /// Offset relative to the end of the current track.
+    FromEnd(Duration),
+    /// Track position is unavailable, e.g. when no track is loaded or for live
+    /// streams.
+    Unavailable,
+}
+
+impl TrackPosition {
+    /// Size of the encoded Track Position characteristic in bytes.
+    pub const SIZE_BYTES: usize = 4;
+
+    /// Raw integer value representing unavailable position.
+    pub const UNAVAILABLE_RAW: i32 = -1;
+
+    /// Creates a track position representing an absolute offset from the start.
+    pub const fn from_start(duration: Duration) -> Self {
+        Self::FromStart(duration)
+    }
+
+    /// Creates a track position representing an offset relative to the end.
+    pub const fn from_end(duration: Duration) -> Self {
+        Self::FromEnd(duration)
+    }
+
+    /// Creates a track position from a raw 10-millisecond unit 32-bit signed
+    /// integer.
+    pub fn from_raw_10ms(raw: i32) -> Self {
+        match raw {
+            Self::UNAVAILABLE_RAW => Self::Unavailable,
+            pos if pos >= 0 => Self::FromStart(Duration::from_millis(pos as u64 * 10)),
+            neg => Self::FromEnd(Duration::from_millis((-neg) as u64 * 10)),
+        }
+    }
+
+    /// Returns the raw 32-bit signed integer in 10-millisecond units.
+    pub fn raw_10ms(&self) -> i32 {
+        match self {
+            Self::Unavailable => Self::UNAVAILABLE_RAW,
+            Self::FromStart(d) => (d.as_millis() / 10).min(i32::MAX as u128) as i32,
+            Self::FromEnd(d) => -((d.as_millis() / 10).min(i32::MAX as u128) as i32),
+        }
+    }
+}
+
+impl Encodable for TrackPosition {
+    type Error = PacketError;
+
+    fn encoded_len(&self) -> usize {
+        Self::SIZE_BYTES
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> Result<(), Self::Error> {
+        if buf.len() < Self::SIZE_BYTES {
+            return Err(PacketError::BufferTooSmall);
+        }
+        buf[0..Self::SIZE_BYTES].copy_from_slice(&self.raw_10ms().to_le_bytes());
+        Ok(())
+    }
+}
+
+impl Decodable for TrackPosition {
+    type Error = PacketError;
+
+    fn decode(buf: &[u8]) -> (Result<Self, Self::Error>, usize) {
+        if buf.len() < Self::SIZE_BYTES {
+            return (Err(PacketError::UnexpectedDataLength), 0);
+        }
+        let raw = i32::from_le_bytes([buf[0], buf[1], buf[2], buf[3]]);
+        (Ok(Self::from_raw_10ms(raw)), Self::SIZE_BYTES)
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -671,6 +833,7 @@
 
     #[test]
     fn supported_playing_orders_bitmask_success() {
+        assert_eq!(SupportedPlayingOrders::default(), SupportedPlayingOrders::IN_ORDER_ONCE);
         assert_eq!(SupportedPlayingOrders::all().bits(), 0x03FF);
 
         let supported = SupportedPlayingOrders::SINGLE_ONCE
@@ -825,6 +988,10 @@
 
     #[test]
     fn supported_opcodes_bitmask_success() {
+        assert_eq!(
+            SupportedOpcodes::default(),
+            SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE | SupportedOpcodes::STOP
+        );
         assert_eq!(SupportedOpcodes::all().bits(), 0x001F_FFFF);
 
         let opcode_flags = [
@@ -889,4 +1056,57 @@
         assert_eq!(consumed, 0);
         assert_eq!(err.unwrap_err(), PacketError::UnexpectedDataLength);
     }
+
+    #[test]
+    fn track_duration_encode_decode() {
+        assert_eq!(TrackDuration::Unknown.raw_10ms(), -1);
+        assert_eq!(TrackDuration::from_raw_10ms(-1), TrackDuration::Unknown);
+        assert_eq!(TrackDuration::from_raw_10ms(-50), TrackDuration::Unknown);
+
+        let dur = TrackDuration::from_duration(Duration::from_secs(180));
+        assert_eq!(dur.raw_10ms(), 18000);
+        assert_eq!(TrackDuration::from_raw_10ms(18000), dur);
+
+        let mut buf = [0u8; 4];
+        assert!(dur.encode(&mut buf).is_ok());
+        assert_eq!(buf, 18000i32.to_le_bytes());
+
+        let (decoded, consumed) = TrackDuration::decode(&buf);
+        assert_eq!(consumed, 4);
+        assert_eq!(decoded.unwrap(), dur);
+
+        let mut small = [0u8; 3];
+        assert_eq!(dur.encode(&mut small).unwrap_err(), PacketError::BufferTooSmall);
+        let (err, consumed) = TrackDuration::decode(&small);
+        assert_eq!(consumed, 0);
+        assert_eq!(err.unwrap_err(), PacketError::UnexpectedDataLength);
+    }
+
+    #[test]
+    fn track_position_encode_decode() {
+        assert_eq!(TrackPosition::Unavailable.raw_10ms(), -1);
+        assert_eq!(TrackPosition::from_raw_10ms(-1), TrackPosition::Unavailable);
+
+        let start_pos = TrackPosition::from_start(Duration::from_millis(1500));
+        assert_eq!(start_pos.raw_10ms(), 150);
+        assert_eq!(TrackPosition::from_raw_10ms(150), start_pos);
+
+        let end_pos = TrackPosition::from_end(Duration::from_millis(2000));
+        assert_eq!(end_pos.raw_10ms(), -200);
+        assert_eq!(TrackPosition::from_raw_10ms(-200), end_pos);
+
+        let mut buf = [0u8; 4];
+        assert!(start_pos.encode(&mut buf).is_ok());
+        assert_eq!(buf, 150i32.to_le_bytes());
+
+        let (decoded, consumed) = TrackPosition::decode(&buf);
+        assert_eq!(consumed, 4);
+        assert_eq!(decoded.unwrap(), start_pos);
+
+        let mut small = [0u8; 3];
+        assert_eq!(start_pos.encode(&mut small).unwrap_err(), PacketError::BufferTooSmall);
+        let (err, consumed) = TrackPosition::decode(&small);
+        assert_eq!(consumed, 0);
+        assert_eq!(err.unwrap_err(), PacketError::UnexpectedDataLength);
+    }
 }
