Adjust scripts to account for ID normalization
diff --git a/services/i2c/server/src/main.rs b/services/i2c/server/src/main.rs
index 1b410d6..5eb309b 100644
--- a/services/i2c/server/src/main.rs
+++ b/services/i2c/server/src/main.rs
@@ -61,7 +61,9 @@
 // ---------------------------------------------------------------------------
 
 fn i2c_server_loop() -> Result<()> {
-    pw_log::info!("I2C server starting");
+    pw_log::info!("+------------------------+");
+    pw_log::info!("|   I2C Server Starting  |");
+    pw_log::info!("+------------------------+");
 
     // SAFETY: Called once at server startup, exclusive peripheral access.
     let mut backend = unsafe { AspeedI2cBackend::new() };
@@ -261,7 +263,11 @@
         // ConfigureSlave: set slave address on a bus
         // ------------------------------------------------------------------
         I2cOp::ConfigureSlave => {
-            pw_log::info!("I2C dispatch configure slave");
+            pw_log::info!("+------------------------+");
+            pw_log::info!("| I2C Target Configured  |");
+            pw_log::info!("| Bus:  {}                |", header.bus as u32);
+            pw_log::info!("| Addr: 0x{:02X}             |", header.address as u32);
+            pw_log::info!("+------------------------+");
             match backend.configure_slave(header.bus, header.address) {
                 Ok(()) => encode_success(response, 0),
                 Err(code) => encode_error(response, code),
diff --git a/services/mctp/server/src/main.rs b/services/mctp/server/src/main.rs
index e708180..cfec577 100644
--- a/services/mctp/server/src/main.rs
+++ b/services/mctp/server/src/main.rs
@@ -221,13 +221,56 @@
 
 #[cfg(feature = "i2c-polling")]
 fn mctp_loop() -> Result<()> {
+    // Print startup banner with configuration
     #[cfg(feature = "in-process-requester")]
-    pw_log::info!("MCTP server starting (I2C polling mode, REQUESTER, own: eid=0x{:02x} i2c=0x{:02x}, remote: eid=0x{:02x} i2c=0x{:02x})",
-        OWN_EID as u32, OWN_I2C_ADDR as u32, REMOTE_EID as u32, REMOTE_I2C_ADDR as u32);
+    pw_log::info!("+----------------------------+");
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|   MCTP Server Starting     |");
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|   Mode: REQUESTER          |");
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|                            |");
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("| Own:                       |");
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|   EID:  0x{:02X}               |", OWN_EID as u32);
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|   I2C:  0x{:02X}               |", OWN_I2C_ADDR as u32);
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|                            |");
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("| Remote:                    |");
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|   EID:  0x{:02X}               |", REMOTE_EID as u32);
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("|   I2C:  0x{:02X}               |", REMOTE_I2C_ADDR as u32);
+    #[cfg(feature = "in-process-requester")]
+    pw_log::info!("+----------------------------+");
 
     #[cfg(feature = "in-process-responder")]
-    pw_log::info!("MCTP server starting (I2C polling mode, RESPONDER, own: eid=0x{:02x} i2c=0x{:02x}, remote: eid=0x{:02x} i2c=0x{:02x})",
-        OWN_EID as u32, OWN_I2C_ADDR as u32, REMOTE_EID as u32, REMOTE_I2C_ADDR as u32);
+    pw_log::info!("+----------------------------+");
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|   MCTP Server Starting     |");
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|   Mode: RESPONDER          |");
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|                            |");
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("| Own:                       |");
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|   EID:  0x{:02X}               |", OWN_EID as u32);
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|   I2C:  0x{:02X}               |", OWN_I2C_ADDR as u32);
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|                            |");
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("| Remote:                    |");
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|   EID:  0x{:02X}               |", REMOTE_EID as u32);
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("|   I2C:  0x{:02X}               |", REMOTE_I2C_ADDR as u32);
+    #[cfg(feature = "in-process-responder")]
+    pw_log::info!("+----------------------------+");
 
     let mut i2c = IpcI2cClient::new(handle::I2C);
 
@@ -618,6 +661,31 @@
                         &frame_with_dest[..frame_len]
                     );
 
+                    // Debug: log full frame being decoded
+                    if frame_len >= 14 {
+                        pw_log::info!(
+                            "Frame[0-7]:  {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}",
+                            frame_with_dest[0] as u32, frame_with_dest[1] as u32,
+                            frame_with_dest[2] as u32, frame_with_dest[3] as u32,
+                            frame_with_dest[4] as u32, frame_with_dest[5] as u32,
+                            frame_with_dest[6] as u32, frame_with_dest[7] as u32
+                        );
+                        pw_log::info!(
+                            "Frame[8-13]: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}",
+                            frame_with_dest[8] as u32, frame_with_dest[9] as u32,
+                            frame_with_dest[10] as u32, frame_with_dest[11] as u32,
+                            frame_with_dest[12] as u32, frame_with_dest[13] as u32
+                        );
+                    } else if frame_len >= 8 {
+                        pw_log::info!(
+                            "Frame bytes: {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}",
+                            frame_with_dest[0] as u32, frame_with_dest[1] as u32,
+                            frame_with_dest[2] as u32, frame_with_dest[3] as u32,
+                            frame_with_dest[4] as u32, frame_with_dest[5] as u32,
+                            frame_with_dest[6] as u32, frame_with_dest[7] as u32
+                        );
+                    }
+
                     match receiver.decode(&msg_with_dest) {
                         Ok((pkt, hdr)) => {
                             i2c_pkt = i2c_pkt.wrapping_add(1);
diff --git a/target/ast1060-evb/harness/i2c_requester.py b/target/ast1060-evb/harness/i2c_requester.py
index 868ac5e..7386910 100755
--- a/target/ast1060-evb/harness/i2c_requester.py
+++ b/target/ast1060-evb/harness/i2c_requester.py
@@ -1,8 +1,8 @@
 #!/usr/bin/env python3
 """
-Aardvark I2C Multi-Master Transceiver
-Sends pre-fabricated I2C payloads as master and receives responses as slave.
-Operates in multi-master mode.
+Aardvark I2C Multi-Controller Transceiver
+Sends pre-fabricated I2C payloads as controller and receives responses as target.
+Operates in multi-controller mode.
 """
 
 import sys
@@ -64,13 +64,13 @@
     return handle
 
 
-def configure_device(handle, slave_addr=0x42, bitrate_khz=100, bus_timeout_ms=150):
+def configure_device(handle, own_addr=0x42, bitrate_khz=100, bus_timeout_ms=150):
     """
-    Configure the Aardvark for I2C multi-master operation.
+    Configure the Aardvark for I2C multi-controller operation.
 
     Args:
         handle: Aardvark device handle
-        slave_addr: Our slave address (default: 0x42)
+        own_addr: Our I2C address (default: 0x42)
         bitrate_khz: I2C bus speed in kHz (default: 100)
         bus_timeout_ms: Bus lock timeout in ms (default: 150)
     """
@@ -96,32 +96,32 @@
     actual_timeout = aa_i2c_bus_timeout(handle, bus_timeout_ms)
     print(f"  Bus Timeout: {actual_timeout} ms")
 
-    # Enable slave mode with our address
-    # Parameters: handle, slave_addr, maxTxBytes, maxRxBytes
+    # Enable target mode with our address
+    # Parameters: handle, own_addr, maxTxBytes, maxRxBytes
     # Use 0 for unlimited buffer sizes
-    result = aa_i2c_slave_enable(handle, slave_addr, 0, 0)
+    result = aa_i2c_slave_enable(handle, own_addr, 0, 0)
     if result < 0:
-        print(f"  Error enabling slave mode: {aa_status_string(result)}")
+        print(f"  Error enabling target mode: {aa_status_string(result)}")
         sys.exit(1)
-    print(f"  Slave Address: 0x{slave_addr:02X}")
-    print("  Slave Mode: Enabled")
+    print(f"  Our I2C Address: 0x{own_addr:02X}")
+    print("  Target Mode: Enabled")
 
-    print("\nConfiguration complete. Device ready for multi-master operation.")
-    print("  Master: Can send to other devices")
-    print("  Slave:  Can receive from other masters\n")
+    print("\nConfiguration complete. Device ready for multi-controller operation.")
+    print("  Controller: Can send to other devices")
+    print("  Target:     Can receive from other controllers\n")
 
 
 #==========================================================================
 # I2C OPERATIONS
 #==========================================================================
 
-def send_payload(handle, target_addr, payload: List[int], description=""):
+def send_payload(handle, remote_addr, payload: List[int], description=""):
     """
-    Send a payload as I2C master.
+    Send a payload as I2C controller.
 
     Args:
         handle: Aardvark device handle
-        target_addr: Target device address (7-bit)
+        remote_addr: Remote device address (7-bit)
         payload: List of bytes to send
         description: Optional description of the payload
 
@@ -131,15 +131,15 @@
     if description:
         print(f">>> Sending: {description}")
 
-    print(f"    Target: 0x{target_addr:02X}")
+    print(f"    Remote: 0x{remote_addr:02X}")
     print(f"    Length: {len(payload)} bytes")
     print(f"    Data:   {' '.join(f'{b:02X}' for b in payload)}")
 
     # Convert to array
     data_out = array('B', payload)
 
-    # Write to target device
-    num_written = aa_i2c_write(handle, target_addr, AA_I2C_NO_FLAGS, data_out)
+    # Write to remote device
+    num_written = aa_i2c_write(handle, remote_addr, AA_I2C_NO_FLAGS, data_out)
 
     if num_written < 0:
         print(f"    Status: ERROR - {aa_status_string(num_written)}")
@@ -154,7 +154,7 @@
 
 def poll_for_response(handle, timeout_ms=1000, max_buffer=256):
     """
-    Poll for incoming I2C slave data (response from another master).
+    Poll for incoming I2C target data (response from another controller).
 
     Args:
         handle: Aardvark device handle
@@ -171,11 +171,11 @@
         return False, None, []
 
     if result == AA_ASYNC_I2C_READ:
-        # Data was written to us (we're the slave)
+        # Data was written to us (we're the target)
         (num_bytes, addr, data_in) = aa_i2c_slave_read(handle, max_buffer)
 
         if num_bytes < 0:
-            print(f"    Error reading slave data: {aa_status_string(num_bytes)}")
+            print(f"    Error reading data: {aa_status_string(num_bytes)}")
             return False, None, []
 
         # Convert to list
@@ -183,9 +183,9 @@
         return True, addr, data_list
 
     elif result == AA_ASYNC_I2C_WRITE:
-        # Data was read from us (master read from our slave)
+        # Data was read from us (controller read from our target)
         num_bytes = aa_i2c_slave_write_stats(handle)
-        print(f"<<< Master read {num_bytes} bytes from us")
+        print(f"<<< Controller read {num_bytes} bytes from us")
         return False, None, []
 
     else:
@@ -195,7 +195,7 @@
 
 def wait_for_response(handle, timeout_ms=1000, description=""):
     """
-    Wait for and display a response from another master.
+    Wait for and display a response from another controller.
 
     Args:
         handle: Aardvark device handle
@@ -226,9 +226,9 @@
     return True, data
 
 
-def set_slave_response(handle, response_data: List[int]):
+def set_response(handle, response_data: List[int]):
     """
-    Set the data to send when a master reads from us.
+    Set the data to send when a controller reads from us.
 
     Args:
         handle: Aardvark device handle
@@ -237,23 +237,23 @@
     data_array = array('B', response_data)
     result = aa_i2c_slave_set_response(handle, data_array)
     if result < 0:
-        print(f"Error setting slave response: {aa_status_string(result)}")
+        print(f"Error setting response: {aa_status_string(result)}")
     else:
-        print(f"Slave response buffer set ({len(response_data)} bytes)")
+        print(f"Response buffer set ({len(response_data)} bytes)")
 
 
 #==========================================================================
 # TRANSACTION SEQUENCES
 #==========================================================================
 
-def execute_transaction(handle, target_addr, payload, wait_response=True,
+def execute_transaction(handle, remote_addr, payload, wait_response=True,
                         response_timeout=1000, description=""):
     """
     Execute a complete transaction: send payload and optionally wait for response.
 
     Args:
         handle: Aardvark device handle
-        target_addr: Target device address
+        remote_addr: Remote device address
         payload: Payload to send
         wait_response: Whether to wait for a response
         response_timeout: Response timeout in ms
@@ -268,7 +268,7 @@
     print("=" * 80)
 
     # Send the payload
-    success, _ = send_payload(handle, target_addr, payload, "Request")
+    success, _ = send_payload(handle, remote_addr, payload, "Request")
 
     response_data = []
     if success and wait_response:
@@ -292,28 +292,33 @@
 def main():
     """Main entry point."""
     parser = argparse.ArgumentParser(
-        description='Aardvark I2C Multi-Master Transceiver',
+        description='Aardvark I2C Multi-Controller Transceiver',
         formatter_class=argparse.RawDescriptionHelpFormatter,
         epilog='''
-This tool operates in multi-master mode:
-  - Sends payloads as I2C master to target devices
-  - Receives responses as I2C slave from other masters
+This tool operates in multi-controller mode:
+  - Sends payloads as I2C controller to remote devices
+  - Receives responses as I2C target from other controllers
 
 Default configuration:
-  - Slave address: 0x42
+  - Our I2C address: 0x10
+  - Remote I2C address: 0x13
   - Bus speed: 100 kHz
   - Bus timeout: 150 ms
         '''
     )
 
-    parser.add_argument('--slave-addr', type=lambda x: int(x, 0), default=0x42,
-                        metavar='ADDR', help='Our slave address (default: 0x42)')
+    parser.add_argument('--own-addr', type=lambda x: int(x, 0), default=0x10,
+                        metavar='ADDR', help='Our I2C address (default: 0x10)')
+    parser.add_argument('--own-eid', type=lambda x: int(x, 0), default=0x08,
+                        metavar='EID', help='Our MCTP endpoint ID (default: 0x08)')
+    parser.add_argument('--remote-addr', type=lambda x: int(x, 0), default=0x13,
+                        metavar='ADDR', help='Remote device address (default: 0x13)')
+    parser.add_argument('--remote-eid', type=lambda x: int(x, 0), default=0x42,
+                        metavar='EID', help='Remote MCTP endpoint ID (default: 0x42)')
     parser.add_argument('--bitrate', type=int, default=100, metavar='KHZ',
                         help='I2C bus speed in kHz (default: 100)')
     parser.add_argument('--bus-timeout', type=int, default=150, metavar='MS',
                         help='Bus lock timeout in ms (default: 150)')
-    parser.add_argument('--target', type=lambda x: int(x, 0), default=0x10,
-                        metavar='ADDR', help='Target device address (default: 0x10)')
     parser.add_argument('--response-timeout', type=int, default=1000, metavar='MS',
                         help='Response timeout in ms (default: 1000)')
     parser.add_argument('--no-wait-response', action='store_true',
@@ -328,13 +333,68 @@
 
     try:
         # Configure device
-        configure_device(handle, args.slave_addr, args.bitrate, args.bus_timeout)
+        configure_device(handle, args.own_addr, args.bitrate, args.bus_timeout)
+
+        # Display configuration
+        print()
+        print("MCTP Requester Configuration:")
+        print(f"  Our I2C Address:    0x{args.own_addr:02X}")
+        print(f"  Our EID:            0x{args.own_eid:02X}")
+        print(f"  Remote I2C Address: 0x{args.remote_addr:02X}")
+        print(f"  Remote EID:         0x{args.remote_eid:02X}")
+        print()
+
+        # Build MCTP SPDM GET_VERSION payload using configured addresses
+        # Format: [CMD][ByteCount][SrcI2C][MCTP_Ver][DestEID][SrcEID][Flags][MsgType][SPDM][PEC]
+        src_i2c_with_read = (args.own_addr << 1) | 1  # Source I2C with read bit
+
+        # Build the frame (without I2C destination address prefix)
+        frame = [
+            0x0F,                    # Command code (MCTP)
+            0x0A,                    # Byte count (10 bytes)
+            src_i2c_with_read,       # Source I2C address with read bit
+            0x01,                    # MCTP version
+            args.remote_eid,         # Destination EID (responder)
+            args.own_eid,            # Source EID (us)
+            0xC8,                    # Flags (SOM=1, EOM=1, Seq=0, TO=1, Tag=0)
+            0x05,                    # Message type (SPDM)
+            0x10,                    # SPDM GET_VERSION
+            0x84,                    # SPDM request code
+            0x00,                    # Param1
+            0x00,                    # Param2
+        ]
+
+        # Calculate PEC (includes destination I2C address)
+        # For PEC calculation, prepend the destination I2C write address
+        dest_i2c_write = args.remote_addr << 1  # Destination I2C write address
+        frame_with_dest = [dest_i2c_write] + frame
+
+        # Calculate CRC-8 PEC
+        crc = 0
+        for byte in frame_with_dest:
+            crc ^= byte
+            for _ in range(8):
+                if crc & 0x80:
+                    crc = (crc << 1) ^ 0x07
+                else:
+                    crc <<= 1
+                crc &= 0xFF
+
+        frame.append(crc)  # Append PEC to payload
+
+        print(f"Generated GET_VERSION payload:")
+        print(f"  Source I2C:    0x{args.own_addr:02X} (frame: 0x{src_i2c_with_read:02X})")
+        print(f"  Source EID:    0x{args.own_eid:02X}")
+        print(f"  Dest I2C:      0x{args.remote_addr:02X}")
+        print(f"  Dest EID:      0x{args.remote_eid:02X}")
+        print(f"  PEC:           0x{crc:02X}")
+        print()
 
         # Define pre-fabricated payloads
         payloads = [
             {
                 'name': 'MCTP SPDM GET_VERSION',
-                'data': [0x0F, 0x0A, 0x85, 0x01, 0x08, 0x30, 0xC8, 0x05, 0x10, 0x84, 0x00, 0x00, 0x65],
+                'data': frame,
                 'description': 'MCTP over SMBus: SPDM GET_VERSION request'
             },
             # Add more payloads here as needed
@@ -347,7 +407,7 @@
 
             execute_transaction(
                 handle,
-                args.target,
+                args.remote_addr,
                 payload_info['data'],
                 wait_response=not args.no_wait_response,
                 response_timeout=args.response_timeout,
@@ -360,7 +420,7 @@
         print("\n\nInterrupted by user")
 
     finally:
-        # Disable slave mode and close device
+        # Disable target mode and close device
         aa_i2c_slave_disable(handle)
         aa_close(handle)
         print("Aardvark device closed")
diff --git a/target/ast1060-evb/harness/i2c_responder.py b/target/ast1060-evb/harness/i2c_responder.py
new file mode 100755
index 0000000..02227ad
--- /dev/null
+++ b/target/ast1060-evb/harness/i2c_responder.py
@@ -0,0 +1,375 @@
+#!/usr/bin/env python3
+"""
+Aardvark I2C Responder
+Listens for I2C requests and returns a canned response.
+"""
+
+import sys
+import os
+import argparse
+from typing import List
+
+# Add the Aardvark API to the path
+# Assumes script runs at the same level as aardvark-api-linux-x86_64-v6.00 directory
+script_dir = os.path.dirname(os.path.abspath(__file__))
+aardvark_lib_path = os.path.join(script_dir, 'aardvark-api-linux-x86_64-v6.00', 'python')
+sys.path.insert(0, aardvark_lib_path)
+from aardvark_py import *
+
+
+#==========================================================================
+# DEVICE MANAGEMENT
+#==========================================================================
+
+def find_and_connect():
+    """Find and connect to the first available Aardvark device."""
+    print("Searching for Aardvark devices...")
+
+    # Find all attached devices
+    (num, ports, unique_ids) = aa_find_devices_ext(16, 16)
+
+    if num == 0:
+        print("Error: No Aardvark devices found!")
+        sys.exit(1)
+
+    print(f"Found {num} device(s)")
+
+    # Find the first available (not in-use) device
+    device_port = None
+    for i in range(num):
+        port = ports[i]
+        unique_id = unique_ids[i]
+
+        if not (port & AA_PORT_NOT_FREE):
+            device_port = port
+            print(f"Connecting to device on port {port} (S/N: {unique_id:04d}-{unique_id % 1000000:06d})")
+            break
+        else:
+            print(f"Port {port & ~AA_PORT_NOT_FREE} is in use")
+
+    if device_port is None:
+        print("Error: All devices are in use!")
+        sys.exit(1)
+
+    # Open the device
+    handle = aa_open(device_port)
+    if handle <= 0:
+        print(f"Error: Unable to open Aardvark device on port {device_port}")
+        print(f"Error code = {handle}")
+        sys.exit(1)
+
+    print(f"Successfully opened Aardvark device on port {device_port}")
+    return handle
+
+
+def configure_device(handle, own_addr=0x42, bitrate_khz=100, bus_timeout_ms=150):
+    """
+    Configure the Aardvark for I2C operation.
+
+    Args:
+        handle: Aardvark device handle
+        own_addr: Our I2C address (default: 0x42)
+        bitrate_khz: I2C bus speed in kHz (default: 100)
+        bus_timeout_ms: Bus lock timeout in ms (default: 150)
+    """
+    print("\nConfiguring Aardvark I2C interface...")
+
+    # Configure for I2C mode
+    aa_configure(handle, AA_CONFIG_SPI_I2C)
+    print("  Mode: I2C")
+
+    # Enable I2C pullup resistors (2.2k)
+    aa_i2c_pullup(handle, AA_I2C_PULLUP_BOTH)
+    print("  Pullups: Enabled (both lines)")
+
+    # Enable target power
+    aa_target_power(handle, AA_TARGET_POWER_BOTH)
+    print("  Target Power: Enabled")
+
+    # Set the bitrate
+    actual_bitrate = aa_i2c_bitrate(handle, bitrate_khz)
+    print(f"  Bitrate: {actual_bitrate} kHz (requested: {bitrate_khz} kHz)")
+
+    # Set the bus lock timeout
+    actual_timeout = aa_i2c_bus_timeout(handle, bus_timeout_ms)
+    print(f"  Bus Timeout: {actual_timeout} ms")
+
+    # Enable target mode with our address
+    # Parameters: handle, own_addr, maxTxBytes, maxRxBytes
+    # Use 0 for unlimited buffer sizes
+    result = aa_i2c_slave_enable(handle, own_addr, 0, 0)
+    if result < 0:
+        print(f"  Error enabling target mode: {aa_status_string(result)}")
+        sys.exit(1)
+    print(f"  Our I2C Address: 0x{own_addr:02X}")
+    print("  Target Mode: Enabled")
+
+    print("\nConfiguration complete. Device ready.")
+    print(f"  Listening on address: 0x{own_addr:02X}\n")
+
+
+def set_response(handle, response_data: List[int]):
+    """
+    Set the data to send when remote device reads from us.
+
+    Args:
+        handle: Aardvark device handle
+        response_data: List of bytes to respond with
+    """
+    data_array = array('B', response_data)
+    result = aa_i2c_slave_set_response(handle, data_array)
+    if result < 0:
+        print(f"Error setting response: {aa_status_string(result)}")
+        sys.exit(1)
+
+    print(f"Canned response configured ({len(response_data)} bytes):")
+    print(f"  Data: {' '.join(f'{b:02X}' for b in response_data)}")
+
+
+#==========================================================================
+# I2C OPERATIONS
+#==========================================================================
+
+def listen_for_requests(handle, own_addr, remote_addr, response_data, timeout_ms=500, max_buffer=256, transaction_count=0):
+    """
+    Listen for incoming I2C requests and handle them.
+    Uses MCTP multi-controller behavior: receive, then respond.
+
+    Args:
+        handle: Aardvark device handle
+        own_addr: Our I2C address (needed for re-enabling target mode)
+        remote_addr: Remote I2C address to send response to
+        response_data: List of bytes to respond with
+        timeout_ms: Timeout in milliseconds between requests
+        max_buffer: Maximum buffer size for receiving data
+        transaction_count: Max number of transactions (0 = infinite)
+
+    Returns:
+        Number of transactions handled
+    """
+    print("=" * 80)
+    print("Listening for I2C requests... (Press Ctrl+C to stop)")
+    print("=" * 80)
+    print()
+
+    trans_num = 0
+
+    try:
+        while True:
+            # Check if we've reached transaction limit
+            if transaction_count > 0 and trans_num >= transaction_count:
+                print(f"\nReached transaction limit ({transaction_count})")
+                break
+
+            # Poll for async events
+            result = aa_async_poll(handle, timeout_ms)
+
+            if result == AA_ASYNC_NO_DATA:
+                # No data, keep waiting
+                continue
+
+            if result == AA_ASYNC_I2C_READ:
+                # Data was written to us (we're receiving a request)
+                (num_bytes, addr, data_in) = aa_i2c_slave_read(handle, max_buffer)
+
+                if num_bytes < 0:
+                    print(f"Error reading data: {aa_status_string(num_bytes)}")
+                    continue
+
+                # Convert to list
+                data_list = [data_in[i] for i in range(num_bytes)]
+
+                # Display the request
+                print(f"<<< Transaction #{trans_num + 1}: Request received")
+                print(f"    Target Address: 0x{addr:02X} (our address)")
+                print(f"    Length: {num_bytes} bytes")
+                print(f"    Data:   {' '.join(f'{b:02X}' for b in data_list)}")
+                print(f"    Will respond to: 0x{remote_addr:02X} (remote address)")
+                print()
+
+                # Delay before responding
+                import time
+                print(f"    Waiting 1 second before responding...")
+                time.sleep(1.0)
+                print()
+
+                # MCTP multi-controller behavior: switch to controller and send response
+                print(f">>> Switching to controller mode to send response...")
+
+                # Disable target mode
+                print(f"    Disabling target mode...")
+                result = aa_i2c_slave_disable(handle)
+                print(f"    aa_i2c_slave_disable returned: {result}")
+                if result < 0:
+                    print(f"    ERROR disabling target mode: {aa_status_string(result)}")
+                    continue
+                print(f"    Target mode disabled successfully")
+
+                # Add delay to allow remote to switch to target mode
+                # and bus to settle after the request transaction
+                import time
+                print(f"    Waiting for bus to settle and remote to switch to target mode...")
+                time.sleep(0.05)  # 50ms delay
+
+                # Write response as controller to the remote address
+                response_array = array('B', response_data)
+                print(f"    Preparing to write {len(response_data)} bytes to 0x{remote_addr:02X}")
+                print(f"    Data: {' '.join(f'{b:02X}' for b in response_data)}")
+
+                num_written = aa_i2c_write(handle, remote_addr, AA_I2C_NO_FLAGS, response_array)
+
+                print(f"    aa_i2c_write returned: {num_written}")
+                if num_written < 0:
+                    print(f"    ERROR writing response: {aa_status_string(num_written)}")
+                    print(f"    Error code: {num_written}")
+                elif num_written == 0:
+                    print(f"    WARNING: 0 bytes written!")
+                else:
+                    print(f"    SUCCESS: Wrote {num_written} bytes to 0x{remote_addr:02X}")
+                print()
+
+                # Re-enable target mode
+                print(f"    Re-enabling target mode on address 0x{own_addr:02X}...")
+                result = aa_i2c_slave_enable(handle, own_addr, 0, 0)
+                print(f"    aa_i2c_slave_enable returned: {result}")
+                if result < 0:
+                    print(f"    ERROR re-enabling target mode: {aa_status_string(result)}")
+                    break
+
+                print(f">>> Switched back to target mode (listening on 0x{own_addr:02X})")
+                print()
+
+                trans_num += 1
+
+            elif result == AA_ASYNC_I2C_WRITE:
+                # This shouldn't happen in multi-controller mode, but log it if it does
+                num_bytes = aa_i2c_slave_write_stats(handle)
+                print(f"!!! Unexpected passive write event (num_bytes: {num_bytes})")
+                print()
+
+            else:
+                print(f"Unexpected async event: {result}")
+
+    except KeyboardInterrupt:
+        print("\n\nStopped by user")
+
+    return trans_num
+
+
+#==========================================================================
+# MAIN
+#==========================================================================
+
+def main():
+    """Main entry point."""
+    parser = argparse.ArgumentParser(
+        description='Aardvark I2C Responder',
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+        epilog='''
+This tool operates with MCTP multi-controller behavior:
+  - Listens as I2C target for incoming write requests
+  - Switches to I2C controller to actively send response back to requester
+  - Returns to target mode for next request
+
+Default configuration (for in-process-requester mode):
+  - Responder (us): EID=0x42, I2C address=0x13
+  - Requester (peer): EID=0x08, I2C address=0x10
+  - Bus speed: 100 kHz
+  - Bus timeout: 150 ms
+
+Default canned response (MCTP SPDM VERSION response):
+  26 0F 0A 21 01 42 08 D9 05 10 84 00 00 51
+        '''
+    )
+
+    parser.add_argument('--own-addr', type=lambda x: int(x, 0), default=0x13,
+                        metavar='ADDR', help='Our I2C address (default: 0x13)')
+    parser.add_argument('--remote-addr', type=lambda x: int(x, 0), default=0x10,
+                        metavar='ADDR', help='Remote I2C address to respond to (default: 0x10)')
+    parser.add_argument('--own-eid', type=lambda x: int(x, 0), default=0x42,
+                        metavar='EID', help='Our MCTP endpoint ID (default: 0x42)')
+    parser.add_argument('--remote-eid', type=lambda x: int(x, 0), default=0x08,
+                        metavar='EID', help='Remote MCTP endpoint ID (default: 0x08)')
+    parser.add_argument('--bitrate', type=int, default=100, metavar='KHZ',
+                        help='I2C bus speed in kHz (default: 100)')
+    parser.add_argument('--bus-timeout', type=int, default=150, metavar='MS',
+                        help='Bus lock timeout in ms (default: 150)')
+    parser.add_argument('--poll-timeout', type=int, default=500, metavar='MS',
+                        help='Poll timeout in ms (default: 500)')
+    parser.add_argument('--count', type=int, default=0, metavar='N',
+                        help='Number of transactions to handle (0=infinite, default: 0)')
+    parser.add_argument('--response', type=str, default=None, metavar='HEX',
+                        help='Custom response as hex string (e.g., "01 02 03")')
+
+    args = parser.parse_args()
+
+    # Default canned response (MCTP SPDM VERSION response)
+    # Captured from actual Rust responder on I2C bus:
+    # <0x13:W> 0x26 0x0F 0x0A 0x21 0x01 0x42 0x08 0xD9 0x05 0x10 0x84 0x00 0x00 0x51
+    #
+    # Format: [SrcI2C][CMD][ByteCount][DestI2C][MCTP_Ver][DestEID][SrcEID][Flags][MsgType][SPDM][PEC]
+    # Responder (us): EID=0x42, I2C=0x13
+    # Requester (peer): EID=0x08, I2C=0x10
+    # Src I2C: 0x26 = 0x13 << 1 (no read bit in this position)
+    # Dest I2C: 0x21 = 0x10 << 1 | 1 (read bit set)
+    # MCTP: Dest EID=0x42, Source EID=0x08 (note: different from expected!)
+    # PEC=0x51 verified from actual capture
+    canned_response = [
+        0x26, 0x0F, 0x0A, 0x21, 0x01, 0x42, 0x08, 0xD9,
+        0x05, 0x10, 0x84, 0x00, 0x00, 0x51,
+    ]
+
+    # Parse custom response if provided
+    if args.response:
+        try:
+            hex_bytes = args.response.replace(',', ' ').split()
+            canned_response = [int(b, 16) for b in hex_bytes if b.strip()]
+            print(f"Using custom response ({len(canned_response)} bytes)")
+        except ValueError as e:
+            print(f"Error parsing custom response: {e}")
+            sys.exit(1)
+
+    # Find and connect to device
+    handle = find_and_connect()
+
+    try:
+        # Configure device
+        configure_device(handle, args.own_addr, args.bitrate, args.bus_timeout)
+
+        # Display configuration
+        print()
+        print("MCTP Responder Configuration:")
+        print(f"  Our I2C Address:    0x{args.own_addr:02X}")
+        print(f"  Our EID:            0x{args.own_eid:02X}")
+        print(f"  Remote I2C Address: 0x{args.remote_addr:02X}")
+        print(f"  Remote EID:         0x{args.remote_eid:02X}")
+        print()
+        print(f"Active response configured ({len(canned_response)} bytes):")
+        print(f"  Data: {' '.join(f'{b:02X}' for b in canned_response)}")
+        print(f"  Will be sent as I2C controller after receiving requests")
+        print()
+
+        # Listen for requests
+        num_transactions = listen_for_requests(
+            handle,
+            args.own_addr,
+            args.remote_addr,
+            canned_response,
+            args.poll_timeout,
+            transaction_count=args.count
+        )
+
+        print(f"\nTotal transactions handled: {num_transactions}")
+
+    except KeyboardInterrupt:
+        print("\n\nInterrupted by user")
+
+    finally:
+        # Disable target mode and close device
+        aa_i2c_slave_disable(handle)
+        aa_close(handle)
+        print("Aardvark device closed")
+
+
+if __name__ == "__main__":
+    main()