Skip to main content

FAKE_XML

Constant FAKE_XML 

Source
pub const FAKE_XML: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
<RegisterDescription
  ModelName="VivaCam Fake"
  VendorName="vitavision.dev"
  ToolTip="Simulated GigE Vision camera for testing"
  StandardNameSpace="GEV"
  SchemaMajorVersion="1"
  SchemaMinorVersion="1"
  SchemaSubMinorVersion="0"
  MajorVersion="1"
  MinorVersion="0"
  SubMinorVersion="0"
  ProductGuid="76697661-6361-6d00-0000-000000000000"
  VersionGuid="76697661-6361-6d00-0000-000000000001">

  <!-- ════════════════════════════════════════════════════════════════════
       Category Hierarchy (SFNC Standard)
       ════════════════════════════════════════════════════════════════════ -->

  <Category Name="Root" NameSpace="Standard">
    <pFeature>DeviceControl</pFeature>
    <pFeature>ImageFormatControl</pFeature>
    <pFeature>AcquisitionControl</pFeature>
    <pFeature>AnalogControl</pFeature>
    <pFeature>TransportLayerControl</pFeature>
    <pFeature>ChunkDataControl</pFeature>
  </Category>

  <Category Name="DeviceControl">
    <DisplayName>Device Control</DisplayName>
    <pFeature>DeviceVendorName</pFeature>
    <pFeature>DeviceModelName</pFeature>
    <pFeature>DeviceSerialNumber</pFeature>
    <pFeature>DeviceFirmwareVersion</pFeature>
    <pFeature>DeviceID</pFeature>
  </Category>

  <Category Name="ImageFormatControl">
    <DisplayName>Image Format Control</DisplayName>
    <pFeature>SensorType</pFeature>
    <pFeature>SensorWidth</pFeature>
    <pFeature>SensorHeight</pFeature>
    <pFeature>Width</pFeature>
    <pFeature>Height</pFeature>
    <pFeature>OffsetX</pFeature>
    <pFeature>OffsetY</pFeature>
    <pFeature>PixelFormat</pFeature>
  </Category>

  <Category Name="AcquisitionControl">
    <DisplayName>Acquisition Control</DisplayName>
    <pFeature>AcquisitionMode</pFeature>
    <pFeature>AcquisitionStart</pFeature>
    <pFeature>AcquisitionStop</pFeature>
    <pFeature>AcquisitionFrameRateEnable</pFeature>
    <pFeature>AcquisitionFrameRate</pFeature>
    <pFeature>ExposureTime</pFeature>
    <pFeature>ExposureAuto</pFeature>
  </Category>

  <Category Name="AnalogControl">
    <DisplayName>Analog Control</DisplayName>
    <pFeature>Gain</pFeature>
    <pFeature>GainAuto</pFeature>
    <pFeature>BlackLevel</pFeature>
  </Category>

  <Category Name="TransportLayerControl">
    <DisplayName>Transport Layer Control</DisplayName>
    <pFeature>GevTimestampTickFrequency</pFeature>
    <pFeature>GevTimestampValue</pFeature>
    <pFeature>TimestampLatch</pFeature>
  </Category>

  <Category Name="ChunkDataControl">
    <DisplayName>Chunk Data Control</DisplayName>
    <pFeature>ChunkModeActive</pFeature>
    <pFeature>ChunkSelector</pFeature>
    <pFeature>ChunkEnable</pFeature>
  </Category>

  <Category Name="EventControl">
    <DisplayName>Event Control</DisplayName>
    <pFeature>EventSelector</pFeature>
    <pFeature>EventNotification</pFeature>
  </Category>

  <!-- ════════════════════════════════════════════════════════════════════
       Device Control Features
       ════════════════════════════════════════════════════════════════════ -->

  <String Name="DeviceVendorName" NameSpace="Standard">
    <ToolTip>Name of the device vendor</ToolTip>
    <Address>0x20220</Address>
    <Length>32</Length>
    <AccessMode>RO</AccessMode>
  </String>

  <String Name="DeviceModelName" NameSpace="Standard">
    <ToolTip>Name of the device model</ToolTip>
    <Address>0x20200</Address>
    <Length>32</Length>
    <AccessMode>RO</AccessMode>
  </String>

  <String Name="DeviceSerialNumber" NameSpace="Standard">
    <ToolTip>Serial number of the device</ToolTip>
    <Address>0x20240</Address>
    <Length>16</Length>
    <AccessMode>RO</AccessMode>
  </String>

  <String Name="DeviceFirmwareVersion" NameSpace="Standard">
    <ToolTip>Firmware version of the device</ToolTip>
    <Address>0x20260</Address>
    <Length>32</Length>
    <AccessMode>RO</AccessMode>
  </String>

  <String Name="DeviceID" NameSpace="Standard">
    <ToolTip>User-configurable device identifier</ToolTip>
    <Address>0x20280</Address>
    <Length>32</Length>
    <AccessMode>RO</AccessMode>
  </String>

  <!-- ════════════════════════════════════════════════════════════════════
       Image Format Control Features
       ════════════════════════════════════════════════════════════════════ -->

  <Integer Name="SensorWidth" NameSpace="Standard">
    <ToolTip>Physical sensor width in pixels</ToolTip>
    <Address>0x20014</Address>
    <Length>4</Length>
    <AccessMode>RO</AccessMode>
    <Min>1</Min>
    <Max>4096</Max>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <Integer Name="SensorHeight" NameSpace="Standard">
    <ToolTip>Physical sensor height in pixels</ToolTip>
    <Address>0x20018</Address>
    <Length>4</Length>
    <AccessMode>RO</AccessMode>
    <Min>1</Min>
    <Max>4096</Max>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <Integer Name="Width" NameSpace="Standard">
    <ToolTip>Width of the image in pixels</ToolTip>
    <Address>0x20000</Address>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <pMin>WidthMin</pMin>
    <pMax>WidthMax</pMax>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>
  <IntReg Name="WidthMin"><Address>0x20100</Address><Length>4</Length><AccessMode>RO</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>
  <IntReg Name="WidthMax"><Address>0x20104</Address><Length>4</Length><AccessMode>RO</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <Integer Name="Height" NameSpace="Standard">
    <ToolTip>Height of the image in pixels</ToolTip>
    <Address>0x20004</Address>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <pMin>HeightMin</pMin>
    <pMax>HeightMax</pMax>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>
  <IntReg Name="HeightMin"><Address>0x20108</Address><Length>4</Length><AccessMode>RO</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>
  <IntReg Name="HeightMax"><Address>0x2010c</Address><Length>4</Length><AccessMode>RO</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <Integer Name="OffsetX" NameSpace="Standard">
    <ToolTip>Horizontal offset from the sensor origin</ToolTip>
    <Address>0x2000c</Address>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <Min>0</Min>
    <Max>4096</Max>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <Integer Name="OffsetY" NameSpace="Standard">
    <ToolTip>Vertical offset from the sensor origin</ToolTip>
    <Address>0x20010</Address>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <Min>0</Min>
    <Max>4096</Max>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <Enumeration Name="SensorType" NameSpace="Standard">
    <ToolTip>Sensor variant (Monochrome / BayerRG / Color). On real hardware this would be read-only sensor metadata; here it is RW so tests can reconfigure the simulator.</ToolTip>
    <EnumEntry Name="Monochrome"><Value>0</Value></EnumEntry>
    <EnumEntry Name="BayerRG"><Value>1</Value></EnumEntry>
    <EnumEntry Name="Color"><Value>2</Value></EnumEntry>
    <pValue>SensorTypeReg</pValue>
  </Enumeration>
  <IntReg Name="SensorTypeReg"><Address>0x20058</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <Enumeration Name="PixelFormat" NameSpace="Standard">
    <ToolTip>Format of the pixel data — entries are gated by SensorType</ToolTip>
    <EnumEntry Name="Mono8" NameSpace="Standard">
      <Value>0x01080001</Value>
      <pIsImplemented>PfMono8Avail</pIsImplemented>
    </EnumEntry>
    <EnumEntry Name="Mono16" NameSpace="Standard">
      <Value>0x01100007</Value>
      <pIsImplemented>PfMono16Avail</pIsImplemented>
    </EnumEntry>
    <EnumEntry Name="RGB8" NameSpace="Standard">
      <Value>0x02180014</Value>
      <pIsImplemented>PfRGB8Avail</pIsImplemented>
    </EnumEntry>
    <EnumEntry Name="BayerRG8" NameSpace="Standard">
      <Value>0x01080009</Value>
      <pIsImplemented>PfBayerRG8Avail</pIsImplemented>
    </EnumEntry>
    <pValue>PixelFormatReg</pValue>
  </Enumeration>
  <IntReg Name="PixelFormatReg"><Address>0x20008</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <!-- PixelFormat entry availability driven by SensorType:
         Monochrome (0) → Mono8, Mono16
         BayerRG    (1) → BayerRG8
         Color      (2) → RGB8 -->
  <IntSwissKnife Name="PfMono8Avail">
    <Formula>ST = 0</Formula>
    <pVariable Name="ST">SensorTypeReg</pVariable>
  </IntSwissKnife>
  <IntSwissKnife Name="PfMono16Avail">
    <Formula>ST = 0</Formula>
    <pVariable Name="ST">SensorTypeReg</pVariable>
  </IntSwissKnife>
  <IntSwissKnife Name="PfBayerRG8Avail">
    <Formula>ST = 1</Formula>
    <pVariable Name="ST">SensorTypeReg</pVariable>
  </IntSwissKnife>
  <IntSwissKnife Name="PfRGB8Avail">
    <Formula>ST = 2</Formula>
    <pVariable Name="ST">SensorTypeReg</pVariable>
  </IntSwissKnife>

  <!-- ════════════════════════════════════════════════════════════════════
       Device capability inquiry bits

       Real inquiry blocks are addressed as `<pAddress>` (the block base) plus
       a fixed `<Address>` offset, and the individual bits come from a
       <StructReg>. Both terms contribute: keeping only one reads the wrong
       register, which is what made issue #35's camera misreport every
       capability it had.
       ════════════════════════════════════════════════════════════════════ -->
  <IntSwissKnife Name="DeviceRegBaseAddress">
    <Formula>0x20000</Formula>
  </IntSwissKnife>
  <StructReg Comment="Device capability inquiry">
    <pAddress>DeviceRegBaseAddress</pAddress>
    <Address>0x5C</Address>
    <Length>4</Length>
    <AccessMode>RO</AccessMode>
    <Endianess>BigEndian</Endianess>
    <StructEntry Name="FrameRateControlInq_Bit"><Bit>0</Bit></StructEntry>
    <StructEntry Name="ChunkSupportInq_Bit"><Bit>1</Bit></StructEntry>
    <StructEntry Name="SequencerInq_Bit"><Bit>2</Bit></StructEntry>
  </StructReg>

  <!-- ════════════════════════════════════════════════════════════════════
       GigE Vision stream channel registers

       Stream channel N lives at 0x0D00 + N * 0x40, so the packet size
       register is a fixed <Address> plus a <pIndex> scaled by the channel
       stride. Ignoring the <pIndex> term always addresses channel 0.
       ════════════════════════════════════════════════════════════════════ -->
  <Integer Name="GevStreamChannelSelector" NameSpace="Standard">
    <ToolTip>Stream channel the GevSCP* features address</ToolTip>
    <Address>0x20090</Address>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <Sign>Unsigned</Sign>
    <Min>0</Min>
    <Max>1</Max>
    <Endianess>BigEndian</Endianess>
  </Integer>
  <Integer Name="GevSCPSPacketSize" NameSpace="Standard">
    <ToolTip>Stream channel packet size in bytes</ToolTip>
    <Address>0x0D04</Address>
    <pIndex Offset="0x40">GevStreamChannelSelector</pIndex>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <Sign>Unsigned</Sign>
    <Min>0</Min>
    <Max>65535</Max>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <!-- ════════════════════════════════════════════════════════════════════
       Acquisition Control Features
       ════════════════════════════════════════════════════════════════════ -->

  <Enumeration Name="AcquisitionMode" NameSpace="Standard">
    <ToolTip>Camera acquisition mode</ToolTip>
    <EnumEntry Name="Continuous"><Value>0</Value></EnumEntry>
    <EnumEntry Name="SingleFrame"><Value>1</Value></EnumEntry>
    <EnumEntry Name="MultiFrame"><Value>2</Value></EnumEntry>
    <pValue>AcquisitionModeReg</pValue>
  </Enumeration>
  <IntReg Name="AcquisitionModeReg"><Address>0x20020</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <Command Name="AcquisitionStart" NameSpace="Standard">
    <ToolTip>Start image acquisition</ToolTip>
    <Address>0x20024</Address>
    <Length>4</Length>
    <AccessMode>WO</AccessMode>
    <CommandValue>1</CommandValue>
    <Endianess>BigEndian</Endianess>
  </Command>

  <Command Name="AcquisitionStop" NameSpace="Standard">
    <ToolTip>Stop image acquisition</ToolTip>
    <Address>0x20028</Address>
    <Length>4</Length>
    <AccessMode>WO</AccessMode>
    <CommandValue>1</CommandValue>
    <Endianess>BigEndian</Endianess>
  </Command>

  <Boolean Name="AcquisitionFrameRateEnable" NameSpace="Standard">
    <ToolTip>Enable manual control of AcquisitionFrameRate. When false, the frame rate is unavailable for read/write.</ToolTip>
    <pValue>AcquisitionFrameRateEnableReg</pValue>
  </Boolean>
  <IntReg Name="AcquisitionFrameRateEnableReg"><Address>0x20054</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess>
    <pIsImplemented>FrameRateControlInq_Bit</pIsImplemented>
  </IntReg>

  <Float Name="AcquisitionFrameRate" NameSpace="Standard">
    <ToolTip>Target frame rate in Hz</ToolTip>
    <Address>0x2002c</Address>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <Min>1.0</Min>
    <Max>120.0</Max>
    <Endianess>BigEndian</Endianess>
    <pIsAvailable>AcquisitionFrameRateEnable</pIsAvailable>
  </Float>

  <Float Name="ExposureTime" NameSpace="Standard">
    <ToolTip>Exposure time in microseconds — locked to RO when ExposureAuto is not Off</ToolTip>
    <Address>0x20030</Address>
    <Length>8</Length>
    <AccessMode>RW</AccessMode>
    <Min>10.0</Min>
    <Max>1000000.0</Max>
    <Endianess>BigEndian</Endianess>
    <pIsLocked>ExposureAutoActive</pIsLocked>
  </Float>

  <Enumeration Name="ExposureAuto" NameSpace="Standard">
    <ToolTip>Automatic exposure control</ToolTip>
    <EnumEntry Name="Off"><Value>0</Value></EnumEntry>
    <EnumEntry Name="Once"><Value>1</Value></EnumEntry>
    <EnumEntry Name="Continuous"><Value>2</Value></EnumEntry>
    <pValue>ExposureAutoReg</pValue>
  </Enumeration>
  <IntReg Name="ExposureAutoReg"><Address>0x20038</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <IntSwissKnife Name="ExposureAutoActive">
    <Formula>EA &lt;&gt; 0</Formula>
    <pVariable Name="EA">ExposureAutoReg</pVariable>
  </IntSwissKnife>

  <!-- ════════════════════════════════════════════════════════════════════
       Analog Control Features
       ════════════════════════════════════════════════════════════════════ -->

  <Float Name="Gain" NameSpace="Standard">
    <!-- CDATA-wrapped tooltip, as shipped by several vendors: the literal `&`
         and `<` inside are legal here and must survive parsing (issue #45). -->
    <ToolTip><![CDATA[Gain applied to the image in dB — locked to RO when GainAuto is not Off (0 < gain & gain < 48)]]></ToolTip>
    <Address>0x20040</Address>
    <Length>8</Length>
    <AccessMode>RW</AccessMode>
    <Min>0.0</Min>
    <Max>48.0</Max>
    <Endianess>BigEndian</Endianess>
    <pIsLocked>GainAutoActive</pIsLocked>
  </Float>

  <Enumeration Name="GainAuto" NameSpace="Standard">
    <ToolTip>Automatic gain control</ToolTip>
    <EnumEntry Name="Off"><Value>0</Value></EnumEntry>
    <EnumEntry Name="Once"><Value>1</Value></EnumEntry>
    <EnumEntry Name="Continuous"><Value>2</Value></EnumEntry>
    <pValue>GainAutoReg</pValue>
  </Enumeration>
  <IntReg Name="GainAutoReg"><Address>0x20048</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <IntSwissKnife Name="GainAutoActive">
    <Formula>GA &lt;&gt; 0</Formula>
    <pVariable Name="GA">GainAutoReg</pVariable>
  </IntSwissKnife>

  <Integer Name="BlackLevel" NameSpace="Standard">
    <ToolTip>Analog black level offset</ToolTip>
    <Address>0x20050</Address>
    <Length>4</Length>
    <AccessMode>RW</AccessMode>
    <Min>0</Min>
    <Max>255</Max>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <!-- ════════════════════════════════════════════════════════════════════
       Transport Layer Control (Timestamp)
       ════════════════════════════════════════════════════════════════════ -->

  <Integer Name="GevTimestampTickFrequency" NameSpace="Standard">
    <ToolTip>Device timestamp tick frequency in Hz (1 GHz)</ToolTip>
    <Address>0x20060</Address>
    <Length>4</Length>
    <AccessMode>RO</AccessMode>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <Integer Name="GevTimestampValue" NameSpace="Standard">
    <ToolTip>Current device timestamp in ticks (latched)</ToolTip>
    <Address>0x20068</Address>
    <Length>8</Length>
    <AccessMode>RO</AccessMode>
    <Sign>Unsigned</Sign>
    <Endianess>BigEndian</Endianess>
  </Integer>

  <Command Name="TimestampLatch" NameSpace="Standard">
    <ToolTip>Latch the current timestamp into GevTimestampValue</ToolTip>
    <Address>0x20070</Address>
    <Length>4</Length>
    <AccessMode>WO</AccessMode>
    <CommandValue>1</CommandValue>
    <Endianess>BigEndian</Endianess>
  </Command>

  <!-- ════════════════════════════════════════════════════════════════════
       Chunk Data Control
       ════════════════════════════════════════════════════════════════════ -->

  <!-- SFNC defines ChunkModeActive and ChunkEnable as IBoolean, and all 23
       vendor-corpus documents that declare ChunkModeActive use <Boolean> over
       a backing <IntReg> - none uses <Integer>. Declaring them as <Integer>
       here made Camera::configure_chunks, which correctly calls set_bool,
       fail against the only camera we can test with. -->
  <Boolean Name="ChunkModeActive" NameSpace="Standard">
    <ToolTip>Enable chunk data in image frames</ToolTip>
    <pValue>ChunkModeActiveReg</pValue>
  </Boolean>
  <IntReg Name="ChunkModeActiveReg"><Address>0x20080</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <Enumeration Name="ChunkSelector" NameSpace="Standard">
    <ToolTip>Select which chunk feature to configure</ToolTip>
    <EnumEntry Name="Timestamp"><Value>1</Value></EnumEntry>
    <EnumEntry Name="ExposureTime"><Value>2</Value></EnumEntry>
    <EnumEntry Name="Gain"><Value>3</Value></EnumEntry>
    <pValue>ChunkSelectorReg</pValue>
  </Enumeration>
  <IntReg Name="ChunkSelectorReg"><Address>0x20084</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <Boolean Name="ChunkEnable" NameSpace="Standard">
    <ToolTip>Enable the selected chunk feature</ToolTip>
    <pValue>ChunkEnableReg</pValue>
  </Boolean>
  <IntReg Name="ChunkEnableReg"><Address>0x20088</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <!-- Event delivery is selected through GenApi, not through a bootstrap
       register: EventSelector picks a GigE Vision event id and
       EventNotification turns it on. The ids are the standard ones
       (GEV_EVENT_START_OF_TRANSFER = 0x0005, END_OF_TRANSFER = 0x0006). -->
  <Enumeration Name="EventSelector" NameSpace="Standard">
    <ToolTip>Select which event to configure</ToolTip>
    <EnumEntry Name="StartOfTransfer"><Value>5</Value></EnumEntry>
    <EnumEntry Name="EndOfTransfer"><Value>6</Value></EnumEntry>
    <pValue>EventSelectorReg</pValue>
  </Enumeration>
  <IntReg Name="EventSelectorReg"><Address>0x200A0</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

  <Enumeration Name="EventNotification" NameSpace="Standard">
    <ToolTip>Enable notification for the selected event</ToolTip>
    <EnumEntry Name="Off"><Value>0</Value></EnumEntry>
    <EnumEntry Name="On"><Value>1</Value></EnumEntry>
    <pValue>EventNotificationReg</pValue>
  </Enumeration>
  <IntReg Name="EventNotificationReg"><Address>0x200A4</Address><Length>4</Length><AccessMode>RW</AccessMode><Sign>Unsigned</Sign><Endianess>BigEndian</Endianess></IntReg>

</RegisterDescription>
"#;
Expand description

GenApi XML describing a realistic fake camera following SFNC conventions.

The XML is organized with proper SFNC category hierarchy:

Root
├── DeviceControl        — model name, vendor, serial, firmware, device ID
├── ImageFormatControl   — width, height, offset, pixel format, sensor size
├── AcquisitionControl   — start/stop, mode, frame rate, exposure, auto
├── AnalogControl        — gain, gain auto, black level
├── TransportLayerControl — timestamp tick frequency, value, latch
└── ChunkDataControl     — chunk mode, selector, enable

All feature registers use big-endian byte order. Register addresses are documented in the module-level doc comment.