Working with SDDS Data

This section describes how to work with SDDS data in the sandbox, including how to write, ingest, manipulate, and introspect the data.

SDDS Data via REDHAWK Components

The sandbox along with the SourceSDDS and SinkSDDS REDHAWK components allow a user to ingest and emit SDDS data during a user’s session. These two components provide a fully-compliant capability when processing SDDS network traffic. Consult the appropriate documentation for the SDDS specification and each of the components.

Each of these components requires a network address specification to access the appropriate host interface. The following table describes the two different network addresses supported by these components.

SDDS Address Specification
Protocol Address Port VLAN
UDP IPv4 address 1024 - 65535 number (optional)
MULTICAST 224.0.0.0 - 239.255.25.255 1024 - 65535 number (optional)

Writing SDDS Data to a Network Interface

To generate SDDS packet data, the rh.SinkSDDS component is used to send BulkIO data over the network interface as SDDS packets. This component accepts three different BulkIO data types (octet, short and float) and then formats the data, SRI, and time stamp information into valid SDDS packets.

The following example uses the sandbox’s DataSource and the rh.SinkSDDS component to generate SDDS packets to be sent over interface eth0, the IP address 127.0.0.1, and port 29000.

>>> from ossie.utils import sb
>>> sig=sb.DataSource()
>>> sdds_out = sb.launch("rh.SinkSDDS")
>>> sdds_out.network_settings.interface="eth0"
>>> sdds_out.network_settings.ip_address="127.0.0.1"
>>> sdds_out.network_settings.port=29000
>>> sig.connect(sdds_out, usesPortName="shortOut")
>>> data=range(1024)
>>> SRI=sig.SRI()
>>> SRI.xdelta = 1/1000.0
>>> sig.push(data, SRI=SRI, EOS=False, loop=False)

Reading SDDS Data from a Network Interface

To read SDDS packet data, the rh.SourceSDDS component is used to receive SDDS data from a network interface. This component transforms the SDDS packet data into BulkIO data, SRI, and time stamps for downstream connections.

The following example configures a rh.SourceSDDS component to read data from interface eth0, send it to IP address 127.0.0.1 and port 29495, and forward the data to a sandbox DataSink over a short typed port.

>>> from ossie.utils import sb
>>> dsink=sb.DataSink()
>>> sdds_in = sb.launch("rh.SourceSDDS")
>>> sdds_in.attachment_override.ip_address="127.0.0.1"
>>> sdds_in.attachment_override.port=29495
>>> sdds_in.attachment_override.enable=True
>>> sdds_in.interface="eth0"
>>> sdds_in.connect(dsink,usesPortName="dataShortOut")

In lieu of the attachment_override property, both components support the BulkIO dataSDDS interface and BULKIO::SDDSStreamDefinition structure. This interface defines an attach method, which is implemented by each component, and performs the necessary actions to connect to the SDDS source defined in the BULKIO::SDDSStreamDefinition structure.

The following table describes the members of the BULKIO::SDDSStreamDefinition structure.

BULKIO::SDDSStreamDefinition
Name Type Description
id string Stream ID to identify the data or Allocation ID for attachment
dataFormat SDDSDataDigraph Payload type of SDDS packet
multicastAddress string Multicast address
vlan long Virtual LAN number
port long Port number
sampleRate long Sampling frequence of SDDS payload data (egress only)
timeTagValid boolean Marks packets with valid time stamp field (egress only)
privateInfo string User-generated text

The following example configures the rh.SourceSDDS component to read data using the address specification defined by the BULKIO::SDDSStreamDefinition structure, and forward the data to a sandbox DataSink over it’s short typed port.

>>> from ossie.utils import sb
>>> from bulkio.bulkioInterfaces import BULKIO
>>> dsink=sb.DataSink()
>>> sdds_in = sb.launch("rh.SourceSDDS")
>>> sdds_in.connect(dsink,usesPortName="dataShortOut")
>>> sdds_port=sdds_in.getPort("dataSddsIn")
>>> sd = BULKIO.SDDSStreamDefinition("my_stream", BULKIO.SDDS_SI, "127.0.0.1",  0, 29495, 8000, True, "testing")
>>> attach_id = sdds_port.attach(sd, "username")

Capturing SDDS Data and the Sandbox’s DataSourceSDDS

This section describes how to capture SDDS Data packets, introspect their contents, and manipulate the data using the sandbox.

SDDS Data and the Sandbox’s DataSourceSDDS

Independent of the components, the sandbox also provides a snapshot and introspection capability through the DataSourceSDDS class. The following commands create the DataSourceSDDS object.

>>> from ossie.utils import sb
>>> ds=sb.DataSourceSDDS()

Using this object, the user can capture an arbitrary number of packets and then introspect their contents. The content analysis and packet decomposition is provided through the SDDSAnalyzer class. To initiate a data capture, call the DataSourceSDDS’s getData or getStreamDef. By default, these methods return a SDDSAnalyzer object that contains all the raw packet data.

getData( mgroup, hostip, port=29495, pkts=1000, pktlen=1080, block=True, returnSddsAnalyzer=True)

Parameters:
  mgroup = multicast address or IP address
  hostip = address of host interface to use
  port = port number to listen on
  pkts = number of packets to capture
  pktlen = length in bytes of a single packet
  block = will block until all packets are read
  returnSddsAnalyzer = returns SDDS analyzer object instead of raw data

Returns:
 SDDSAnalyzer:  provides SDDS packet introspection and tracking
   or
  tuple:  data - converted raw data to a list of numbers
          rawdata - actual data read from socket
          pktlen - packet length provided during capture
          pkts  - number of packets read
          totalRead - total number of bytes read

Using the SDDSAnalyzer

Using the SDDSAnalyzer, you can perform the following actions:

SDDS Packets

The resulting SDDS packet objects, provided by the SDDSAnalyzer, allow for inspection and manipulation of each packet’s underlying data. The python help utility for ossie.utils.sdds.sdds_packet module describes these methods in more detail. The following sample code creates a SDDS packet object and sets the sample rate and payload contents of the packet.

from ossie.utils.sdds import *
pkt=sdds_packet()
pkt.header.set_rate(10e6)
pkt.header.get_rate()
# OUT: 10000000.0
pkt.payload.sb.set_data(1024*[100])

# diplay the payload contents as list of numbers
pkt.payload.sb.get_data()
# OUT: [100, 100, 100, 100, 100,
  ....
100, 100, 100, 100, 100 ]

# print out the entire contents of the sdds packet as array of octets
pkt.asBuffer()

DataSinkSDDS in the Sandbox

The rh.SinkSDDS component provides a fully compliant capability for ingesting BulkIO’s data streams and publishing SDDS packets to a network. To support use cases that do not require this level of compliance, the sandbox provides the DataSinkSDDS object that can capture the stream definitions and SRI data from a BulkIO SDDS interface that publishes this information. Below is a sample code session showing how to connect to a DataSinkSDDS object and capture the stream definition.

from ossie.utils import sb
from bulkio import BULKIO

def inStreamDef(sd,userid):
     print "stream def: ", sd
     print "user: ", userid

sink=sb.DataSinkSDDS()
src=sb.DataSourceSDDS()
src.connect(sink)

sd=BULKIO.SDDSStreamDefinition("data1", BULKIO.SDDS_SB,"239.1.1.0",0,29495,1000000,False,"")
#
# triggers default process to print out stream definition and user id
src.attach(sd,"stream1")

#
# setup callback for attachment
sink.registerAttachCallback(inStreamDef)
src.attach(sd,"stream2")