Socket write (socket_write)

socket_write is an asset in the ocpi.assets.util_comps component library. Implementations include socket_write RCC Worker (socket_write.rcc). Tested platforms include Rocky9, xilinx24_1_aarch32.

Design

The Socket Write component forwards all incoming data to a TCP port or acts as a demultiplexer/router by parsing any protocol and routing different opcodes to various output ports.

The serving/listening TCP ports, along with various ways to determine the Worker’s “done” status, are extremely configurable using Properties.

Note

This Component provides minimal error checking and is not recommended for production use, but is only intended for prototyping and testing of other Components.

A block diagram representation of the implementation is given in Figure 168:

socket_write block diagram.

Figure 168: socket_write block diagram.

Interface

<ComponentSpec>
  <Port Name="in" numberofopcodes='256'/>
  <Port Name="out" numberofopcodes='256' optional='true' producer='true'/>

  <!-- Socket to write to -->
  <Property name="outSocket" type="Struct" writable="true">
    <Member name='address' type='string' stringLength='16' default='0.0.0.0'/>
    <Member name='expectedClients' type='ushort' default='0'/>
    <Member name='port' type='ushort'/>
    <Member name='ports' arrayLength="256" type='ushort'/>
    <Member name='messagesInStream' type='bool' arrayLength="256" default='false'/>
  </Property>

  <!-- Statistics for each opcode -->
  <Property name="current" type="Struct" volatile="true">
    <Member name="Total" type="Struct">
      <Member name="bytes" type="ULongLong"/>
      <Member name="messages" type="ULongLong"/>
    </Member>
    <Member name="Opcode" type="Struct" arrayLength="256">
      <Member name="bytes" type="ULongLong"/>
      <Member name="messages" type="ULongLong"/>
    </Member>
  </Property>

  <Property name="stopOn" type="Struct" writable="true">
    <!-- Stop on TOTAL bytes/messages  -->
    <Member name="Total" type="Struct">
      <Member name="bytes" type="ULongLong"/>
      <Member name="messages" type="ULongLong"/>
    </Member>
    <!-- Stop on bytes/messages with a certain opcode -->
    <Member name="Opcode" type="Struct" arrayLength="256">
      <Member name="bytes" type="ULongLong"/>
      <Member name="messages" type="ULongLong"/>
    </Member>
    <!-- Stop on bytes/messages with any single unspecified opcode -->
    <Member name="Any" type="Struct">
      <Member name="bytes" type="ULongLong"/>
      <Member name="messages" type="ULongLong"/>
    </Member>
    <!-- Stop on ZLM for given opcode. To disable, not within 0..255 -->
    <Member name='ZLM' type='UShort'/>
  </Property>
</ComponentSpec>

Properties

  • outSocket

    • Type: struct

      • Members:

        • address:

          • data_type: string

          • stringlength: 16

        • expectedClients:

          • data_type: ushort

        • port:

          • data_type: ushort

        • ports:

          • data_type: ushort

          • arraydimensions: ['256']

        • messagesInStream:

          • data_type: bool

          • arraydimensions: ['256']

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: False

    • Default value: None

  • current

    • Type: struct

      • Members:

        • Total:

          • bytes:

            • data_type: ulonglong

          • messages:

            • data_type: ulonglong

        • Opcode:

          • bytes:

            • data_type: ulonglong

          • messages:

            • data_type: ulonglong

    • Access:

      • Parameter: False

      • Writable: False

      • Initial: False

      • Volatile: True

    • Default value: None

  • stopOn

    • Type: struct

      • Members:

        • Total:

          • bytes:

            • data_type: ulonglong

          • messages:

            • data_type: ulonglong

        • Opcode:

          • bytes:

            • data_type: ulonglong

          • messages:

            • data_type: ulonglong

        • Any:

          • bytes:

            • data_type: ulonglong

          • messages:

            • data_type: ulonglong

        • ZLM:

          • data_type: ushort

    • Access:

      • Parameter: False

      • Writable: True

      • Initial: False

      • Volatile: False

    • Default value: None

Ports

Inputs:

  • in

    • Protocol: None

    • Optional: False

Outputs:

  • out

    • Protocol: None

    • Optional: True

Implementations

Dependencies

The dependencies to other elements in OpenCPI are:

  • <assets>/components/util_comps/.rcc/socket_write.cc

  • <assets>/components/util_comps/.rcc/ ext_src/connection.cpp

  • <assets>/components/util_comps/.rcc/ ext_src/connection.hpp

  • <assets>/components/util_comps/.rcc/ ext_src/connection_manager.cpp

  • <assets>/components/util_comps/.rcc/ ext_src/connection_manager.hpp

  • <assets>/components/util_comps/.rcc/ ext_src/outbound.hpp

  • <assets>/components/util_comps/.rcc/ ext_src/server.cpp

  • <assets>/components/util_comps/.rcc/ ext_src/server.hpp

  • <assets>/components/util_comps/.rcc/ asio/\* 1

Limitations

Limitations of socket_write are:

  • None.

Testing

Usage (local/x86)

After building the component, the user needs to type make tests RCC_CONTAINERS=1 in the socket_write.test directory. Various properties and data flows will be tested to try to cover as many use cases as possible.

If the user would like to execute only one test, TESTS=test_XX can be added to the end of the command.

Experimental: Usage (remote/ARM)

Full test environment configuration (e.g. NFS mounting, OCPI_CDK_DIR, etc.) on the remote GPP is beyond the scope of this document. The test procedures assume that both shells’ current working directory is the socket_write.test directory (NFS-mounted on remote) and ocpirun is in the remote’s current PATH. NFS must be used for the scripts to properly verify the outputs.

In the host shell, the user types make tests IP=xx.xx.xx.xx. A command that can be copied and then pasted into the remote shell will be displayed. This command should be executed in less than a minute to ensure the test system begins listening before the host times out. The timeout can be changed using the LISTEN_TIMEOUT variable. Once the remote shell returns to the bash prompt, pressing “Enter” on the host will begin the verification process.

Single tests can be performed in the same manner as documented above.

Detailed Theory of Operation

Each test_XX subdirectory has the following files:

  • description - a one-line description of the test

  • application.xml - the OAS XML for the test setup

  • portmap - (optional) list of TCP ports paired to output files

  • localinclude.mk - (optional) custom Makefile rules needed for test

  • golden.md5 - (optional) MD5 checksums of golden/expected output

  • generate.[sh|pl|py] - (optional) script to generate test data

  • verify.sh - (optional) script to verify output(s)

Data is sourced with a source component (often pattern or file_read) within the OAS. If the former, the source data is encapsulated in the OAS. When the latter, a generate.py script generates the required data. Most OASs dump the “current” property to a file UUT.current.dump, which is also confirmed to match expected output. Some tests connect a file_write_demux to the out port to verify pass-through operation.

If generate.sh does not exist, a default one is created that will run generate.pl and/or generate.py if they exist and are executable. This default script is removed with make clean.

At test launch, if a file portmap exists, it launches a Python-based utility script busy_loop_socket.py, which opens a client on a given port and repeatedly attempts to connect. Each line is a port number followed by a (relative) file path where the data is written upon successful connection.

If verify.sh does not exist, a default one is created that will ensure the application did not time out and then run md5sum to verify all the checksums listed in golden.md5. This default script is also removed upon make clean.

1

Externally provided ASIO library for asynchronous IO with C++, with OpenCPI-specific build system

References