Title: Schools Interoperability Framework Association
1SIF Implementation Specification for Developers
- Schools Interoperability Framework Association
2Questions to be Answered
- Why do I need to know and whats in it for me?
- What is it?
- What are the components?
- What is the difference between architecture and
infrastructure? - What is the Data Model Section?
3Goals
- Give a basic overview of the sections in the spec
- Highlight and discuss implications for end users
- Offer examples where applicable
- Answer any questions as they come up or at the
end of the overview
4Why Standards?
- Standards are important to build upon to achieve
agreement between vendors on data movement and
interoperability. - The SIF Specification is built on other data
standards such as - HTTPS
- XML
- NCES Handbooks
- Other standards where appropriate
5What is the SIF Specification?
- Data standard
- Document that defines accepted rules
- Describes the data (what) infrastructure (how)
- Provides a complete set of rules from start to
finish
6Sections of Document
- Preamble
- Introduction
- Architecture
- Infrastructure
- Data Model
- Appendices
- References
7Preamble
- Goals
- Compliance
- Disclaimer WITH ALL THE BIG, SCARY CAPITAL LETTERS
8Architecture (Concepts)
- The playing field (the Zone)
- The players
- Existing applications
- Their agents
- The Zone Integration Server
- The positions
- Publishers, Subscribers, Requesters, Providers,
Responders
9The Plays
- Data Provision
- An applications agent requests data from the
zone or another agent - Requester, Provider, Responder
- Event Reporting
- An agent publishes an event of interest to the
zone (Publisher) - Agents subscribe to events of interest to them
(Subscriber)
10Bat and Ball
- The sports, and now baseball, metaphor does
eventually die... - What were hopefully sending out of the park, the
ball, are SIF Data Objects - Represent real-world objects like students,
staff, parents, rooms, bus stops, etc. - We use an XML brand ball -- the seams are very
predominant ltltltlt gtgtgtgt - And we use a SIF HTTPS or HTTP bat, but you can
bring your own
11Rules of the Game (Zone)
- Agents and ZIS have unique identifiers within the
zone - Examples DistrictZone, LibraryAgent, etc.
- Any number of Requesters per zone
- One object Provider per zone -- Providers must
register intent to provide - Any number of Responders per zone
- Any number of Publishers per zone
- Any number of Subscribers per zone -- Subscribers
must register subscription
12Rules of the Game (Agents)
- All agents must register in order to communicate
- All agents must respond to all messages, whether
supported or not - All agents must provide responses to requests,
whether data object(s) requested are supported or
not - When elements of a data object are not supported
by an agent, the agent should omit them from the
object in events it publishes - Example If an agent doesnt support phone
numbers, it shouldnt place ltPhoneNumbergtlt/PhoneNu
mbergt or ltPhoneNumber/gt in the data object
13Rules of the Game (ZIS)
- What agents are allowed to communicate, once
registered, is governed by ZIS and its
administrator(s) - Access control determines who can
- provide
- subscribe
- publish add/update/delete events
- request data
- respond to data requests
- The ZIS also must maintain two databases, one of
Providers and one of Subscribers - The ZIS also maintains abstract message queues
for each agent--when a message is to be delivered
to an agent, it enters the agents queue as
messages are delivered and acknowledged, they are
removed from the agents queue
14Architecture (Data Objects)
- Data Objects are defined by various working
groups - All data object instances are uniquely identified
within the zone by a GUID, which serves as a
primary key - GUIDs are in most instances highly likely to be
unique until 3400 - Data objects that refer to other data objects use
these keys as references (StudentRefId,
StaffRefId, etc.)
15Data Objects
- Each data object defined by SIF has certain
capabilities associated with it - Some objects can be published in events
- Example StudentPersonal--adding a student,
updated data associated with the student,
deleting the student - Some objects can only be requested
- Example LibraryPatronStatus
- Others can be both
- Student Personal, again
16Architecture (Data Encoding)
- All SIF data objects and messages are encoded
using XML - All SIF messages also have an associated GUID to
uniquely identify messages when handled
asynchronously - Validation of XML messages against specification
versions DTD is optional, but its recommended
that invalid messages should be errors
17Architecture (Communication)
- Communication is asynchronous beyond the
message/ack exchange between ZIS and agents - Example an agent will synchronously receive an
acknowlegement that its request for data has been
received at the ZIS, but the actual response to
the request may arrive or become available at any
time in the future - Most message interchanges between agent and ZIS
are completely synchronous - Example registering, subscribing, etc.
- All agent-to-agent communication is asynchronous
18Push/Pull
- Agents register to use one of two communication
modes - Push
- Pull
- When an agent is registered in Push mode, ZIS
contacts agent with messages as they become
available (agent is a server application) - When an agent is registered in Pull mode, agent
contacts ZIS periodically to see if messages are
available (agent is a client application)
19Security Model
- As real-world objects represented by SIF Data
Model objects are often of a sensitive nature,
support for encryption and authentication, in
conjunction with access control at the ZIS,
define the SIF security model - Specification works from the assumption that
encryption and authentication are provided by the
communication transport layer
20Encryption Levels
- There are five encryption levels in the SIF
security model - No encryption required (0)
- Symmetric key length gt 40 bits (gt 256 bits for
public key) - Symmetric key length gt 56 bits (gt 512 bits for
public key) - Symmetric key length gt 80 bits (gt 768 bits for
public key) - Symmetric key length gt 128 bits (gt 2048 bits
for public key)
21Authentication Levels
- Only authentication protocol supported by SIF is
currently X.509 - There are four authentication levels in the SIF
security model - No authentication required (0)
- A valid certificate must be presented (1)
- A valid certificate from a trusted certificate
authority must be presented (2) - A valid certificate from a trusted certificate
authority must be presented, and the CN (Company
Name) field of the certificate must match the
host/IP address of the sender
22Communication Transport
- SIF Data Model objects (XML) travel over a
transport layer - To SIF, a transport is XML in, XML out
- Default and required transport layer is SIF HTTPS
- Other defined transport is SIF HTTP
- Support for other transport layers/protocols is
possible, but implementation-dependent
23SIF HTTP
- SIF HTTP is essentially a subset of HTTP 1.1
- Post requests only, 200-OK response
- As SIF HTTP may be built upon more full-featured
HTTP implementations, other response status codes
may occur - SIF profiles HTTP 1.1 to allow for not supporting
chunked Transfer-Encoding
24SIF HTTP (Request)
- Required request headers
- Content-Length
- Content-Type application/xmlcharsetutf-8
- Host
- Optional request headers
- Connection close
- Connection Upgrade, Upgrade headers should not
be used - Other headers may be included, but all agents and
ZIS implementations must be able to handle
messages with these headers alone
25SIF HTTP (Response)
- Required response headers
- Content-Length
- Content-Type application/xmlcharsetutf-8
- Date
- Server
- Optional response headers
- Connection close
- Again, other headers are possible, but all agents
and ZIS implementations must handle messages with
these headers alone
26SIF HTTPS
- Default and required transport layer in SIF
- SIF HTTPS is SIF HTTP over TLS 1.0
- Specification delegates implementation of
security and authentication levels to this
transport - Other transports not defined in the standard must
accurately reflect the security/authentication
levels of SIF HTTPS
27Security Model (ZIS)
- Both ZIS and agents can play active role in
security of the zone - The zone administrators at the ZIS can set
minimum security level for the zone by
configuring the SIF HTTPS layer of the ZIS
accordingly - Agents that cannot negotiate to these minimum
levels will be unable to communicate
28Security Model (Agents)
- Agents also have the ability to specify security
levels on a message-by-message basis - The ZIS must not communicate a message with
defined security/authentication levels to
receiving agents with lower security/authenticatio
n levels - When a ZIS supports lower security/authentication
levels (or SIF HTTP), agents that require
heightened security/authentication levels should
not inadvertently communicate their data to the
ZIS over these lower levels
29Architecture (Message Handling)
- Specification defines message handling protocol
in this section predominantly from the ZIS side,
with additional exposition on agent-to-agent
messages (SIF_Event, SIF_Request, SIF_Response) - The ZIS receives message X from the agent, and
does Y - In describing what the ZIS looks at in message X
before doing Y, we can see what it is that an
agent should be sending to the ZIS, or look at
the Infrastructure section for details - In examining message handling, well try to
highlight some important elements and attributes
that are detailed more closely in the
Infrastructure section
30Message Handling/Delivery (Robustness)
- Given the asynchronous nature of most zone
communication, delivery of messages must be
robust - The ZIS must guarantee delivery of messages it
acknowledges receipt of in the event of system
crashes, power failure, etc. - Similar mechanism should be built into agents
i.e. once an agent receives information from its
corresponding application, delivery of that
information to the ZIS should be robust
31Common Message Handling
- The SIF message handling protocol is essentially
receive a SIF_Message, respond with a SIF_Ack - This, of course, reflects the request/response
model of SIF HTTP/S, receive a Post request,
respond with a 200-OK response - A SIF_Message can contain one of the following
- SIF_Register/SIF_Unregister, SIF_Subscribe/SIF_Uns
ubscribe, SIF_Provide/SIF_Unprovide, SIF_Event,
SIF_Request/SIF_Response, SIF_SystemControl,
SIF_Ack
32ZIS Initial Message Handling
- The initial handling of every SIF_Message is the
same in the ZIS - Optionally validate the incoming XML message
against the specification versions DTD, return a
SIF_Ack containing an XML validation error if the
message is invalid - Important elements SIF_Ack/SIF_Status/SIF_Code,
SIF_Ack/SIF_Error/SIF_Category,
Sif_Ack/SIF_Error/SIF_Code - All status and error codes are listed in Appendix
E - This can be the same on the agent side
33Initial Message Handling (cont.)
- Every child element of SIF_Message contains a
SIF_Header - SIF_MsgId is the GUID that uniquely identifies
the message - SIF_Date and SIF_Time form a timestamp for the
message - SIF_Security allows an agent to optionally set
the encryption and authentication requirements
for agents receiving the message - SIF_SourceId is the unique identifier of the
agent that sent the message - SIF_DestinationId identifies the Requester in
responses and identifies Responders as opposed to
Providers in requests
34Initial Message Handling (cont.)
- After optionally validating incoming XML message,
the ZIS retrieves SIF_Header/SIF_SourceId and
determines whether the originating agent is
allowed to communicate the message in the zone
(access control) - If not, returns the corresponding error SIF_Ack
- If the agent is allowed to communicate the
message, the ZIS then begins message-specific
handling
35SIF_Register
- Again, before any agents can participate in the
Zone, they must register - Upon receiving a SIF_Register, the ZIS looks at
SIF_Register/SIF_Version to determine whether the
ZIS supports the requested version (current
version of the spec is 1.0r1) - SIF_MaxBufferSize is examined to determine
whether the agents maximum buffer size meets the
zones minimum buffer size (every ZIS must
support a configurable minimum buffer size) for
the zone - The agent also includes SIF_Mode to specify
whether registering in Push or Pull mode - If registering in Push mode, SIF_Protocol is
examined to make sure the included protocol
information is acceptable to the ZIS - If all looks good, the ZIS stores the agents
registration settings, returns the successful
SIF_Ack and the agent is good to go
36SIF_Register (cont.)
- If the ZIS receives a SIF_Register and the agent
is already registered,the ZIS goes through
exactly the same process - Any changed settings will take effect after the
successful SIF_Ack is returned - This is effectively how a switch to a different
communication protocol than the one in current
use takes place (SIF HTTPS to SIF_HTTP or
vice-versa, one of the SIF protocols to another
protocol or vice-versa)
37SIF_Unregister
- A number of SIF_Messages, SIF_Register,
SIF_Provide, SIF_Subscribe, have corresponding
SIF_Un- messages - In the case of SIF_Register, an agent as some
point may wish to unregister itself from the zone - Upon receiving SIF_Unregister, the ZIS examines
whether the agent (SIF_Header/SIF_SourceId) is
registered - If so, it does the SIF_Unprovide and
SIF_Unsubscribe handling well examine in a
moment to remove any provisions or subscriptions
associated with the agent
38SIF_Provide
- For an agent to be the Provider of an object in
the zone, it must send a SIF_Provide to the ZIS - Upon receiving the SIF_Provide, the ZIS checks
its Providers database to ensure theres not
already a Provider for the included object(s) - The objects are identified by SIF_Provide/SIF_Obje
ct/_at_ObjectName - Upon success, the ZIS adds the agents to its
Providers database for the requested object(s) - Note that in the case of multiple objects, if
provision of any included object fails, there is
no change to the Providers database at the ZIS
39SIF_Unprovide
- Upon receiving a SIF_Unprovide, the ZIS ensures
the agent (SIF_Header/SIF_SourceId) is the
Provider of the included object(s)
(SIF_Unprovide/SIF_Object/_at_ObjectName) - If so the ZIS will remove the agent from its
Providers database and cancel any associated
requests/responses that are pending or in process
40SIF_Subscribe
- In order for an agent to receive events published
in the zone, it must sent a SIF_Subscribe to the
ZIS - Upon receiving SIF_Subscribe, the ZIS checks its
Subscribers database to ensure the agent
(SIF_Header/SIF_SourceId) isnt already
subscribed to the included objects
(SIF_Subscribe/SIF_Object/_at_ObjectName) - Upon success, the ZIS adds the agent to its
Subscribers database for the requested object(s) - Note that in the case of multiple objects, if
subscription to any included object fails, there
is no change to the Subscribers database at the
ZIS
41SIF_Unsubscribe
- Upon receiving a SIF_Unsubscribe, the ZIS ensures
the agent (SIF_Header/SIF_SourceId) is already
subscribed to the included object(s)
(SIF_Unsubscribe/SIF_Object/_at_ObjectName) - If so the ZIS will remove the agent from its
Subscribers database and remove any events
pending for delivery to the agent
42SIF_Event (ZIS)
- SIF_Event is the message that corresponds to an
agent publishing an event to the zone - Any agent can publish events (subject to access
control) i.e., there are no SIF_Publish/SIF_Unpub
lish messages - Upon receiving a SIF_Event the ZIS will examine
its Subscribers database and make copies of the
event for all subscribed agents, placing them in
each agents queue - If the size of the event exceeds an individual
agents SIF_MaxBufferSize, it is recommended that
the ZIS log its inability to deliver the event to
the agent - Remember here that the agent publishing the event
should omit elements it does not support from the
enclosed objects (SIF_Event/SIF_ObjectData),
rather than including empty elements
43SIF_Event (Agent)
- Upon receiving an event from the zone, an agent
should attempt to process it according to the
applications business logic - With events, the agent has three options in
returning a SIF_Ack to the ZIS - If the agent returns a SIF_Ack with
SIF_Ack/SIF_Status/SIF_Code containing 1
(Immediate SIF_Ack), the agent signals the ZIS
that it has stored or processed the message - Setting the SIF_Code to 2 (Intermediate SIF_Ack),
the agent invokes Selective Message Blocking (SMB)
44Selective Message Blocking (SMB)
- SMB allows an agent to signal to the ZIS that it
is going to take some time to process the event
received - The ZIS must persist the event that has been
intermediate-acked until the agent sends the
ZIS a SIF_Ack with SIF_Ack/SIF_Status/SIF_Code
containing 3 (Final SIF_Ack)
45SMB (cont.)
- During SMB, the ZIS does not deliver pending
events to the agent, only requests and responses - This allows agents to request data from the zone
to fulfill its business logic associated with
processing the event - SIF_Register or SIF_Wakeup (well examine this
SIF_SystemControlMessage in a moment) messages
from the agent also terminate SMB - Upon completion of SMB, events can again be
delivered to the agent
46SIF_Request (ZIS)
- An agent requests data from the zone by sending a
SIF_Request to the ZIS - A SIF_Request can be delivered to the Provider of
the object in the zone, or to a Responder - To request data from an objects Provider, an
agent does not include SIF_DestinationId in
SIF_Request/SIF_Header - Placing an agents identifier in
SIF_Request/SIF_Header/SIF_DestinationId requests
the ZIS to route the request to a specific
Responder
47SIF_Request (ZIS) (cont.)
- So, upon receiving a SIF_Request, the ZIS looks
for the presence of SIF_Request/SIF_Header/SIF_Des
tinationId - If absent, the Responder that will receive the
message is the Provider of the object in the
Providers database at the ZIS - The ZIS places the request in the Responders
queue
48SIF_Request (Agent)
- Recall again that agents are required to respond
to all received requests whether or not they
support the requested object (SIF_Request/SIF_Quer
y/SIF_QueryObject/_at_ObjectName) - Whenever an agent sends a SIF_Response, it sets
SIF_Response/SIF_DestinationId to be the
identifier of the agent that made the request
(SIF_Request/SIF_Header/SIF_SourceId) - Allows ZIS to route the response to the agent
that made the request
49SIF_Request (Agent) cont.
- After acknowledging the request, the agent
examines the requested version (SIF_Request/SIF_Ve
rsion) - If it cannot respond in the requested version,
the agent sends a SIF_Response containing
SIF_Response/SIF_Error) - The agent also examines the requested buffer size
(SIF_Request/SIF_MaxBufferSize) - If it cannot group the response data such that
every SIF_Response belonging to the response fits
in SIF_MaxBufferSize, the agent sends a
SIF_Response containing SIF_Response/SIF_Error - And if at any time in processing the request the
agent encounters an error where it cannot
continue, it also sends SIF_Error
50SIF_Request (Agent) (cont.)
- Responses may span multiple SIF_Response
messages, particularly when requesting all
objects of one type in the zone - In processing a request, an agent initializes a
packet counter to 1 - It adds requested objects to the next
SIF_Response until no more will fit in the
requested SIF_MaxBufferSize - Each response receives SIF_Response/SIF_PacketNumb
er set to the current packet counter and the
packet counter is incremented - SIF_Response/SIF_MorePackets is set to Yes or
No accordingly - If there will be only one SIF_Response message,
the agent may omit both SIF_PacketNumber and
SIF_MorePackets
51SIF_Request/SIF_Query
- So how does the agent know what to return in a
response? - The Requester includes a SIF_Query in the request
- Well examine this in the Infrastructure section
52SIF_Response (ZIS)
- Upon receiving a SIF_Response from a Responder,
the ZIS places the response in the Requesters
queue - All responses should fit in the requesting
agents SIF_MaxBufferSize as the
SIF_MaxBufferSize communicated in a SIF_Request
to a Responder should not exceed the Requesters
registered SIF_MaxBufferSize - But if for some reason the response cannot be
placed in the agents queue, the ZIS should log
its inability to deliver the response
53SIF_SystemControl
- SIF_SystemControl controls the flow of data
between ZIS and agent - SIF_SystemControl messages are processed
immediately and do not enter delivery queues for
agents - There are four sub-messages of SIF_SystemControl
- SIF_Ping
- SIF_Sleep
- SIF_Wakeup
- SIF_GetMessage
54SIF_Ping
- When the ZIS or an agent receives
SIF_Message/SIF_SystemControl/SIF_SystemControlDat
a/SIF_Ping, SIF_Ping is simply an empty element
ltSIF_Ping/gt - The receiver of the SIF_Ping either cannot
respond due to a transport error (e.g., the agent
or ZIS is not running) a transport error SIF_Ack
should be generated - Or the receiver can return success
(SIF_Ack/SIF_Status/SIF_Code 0) or sleeping
(SIF_Ack/SIF_Status/SIF_Code 8)
55SIF_Sleep
- SIF_Sleep allows the sender to signal the
receiver that the receiver should not send
messages to the sender until notified - Messages can be sent again once a SIF_Wakeup is
received - When a ZIS receives a SIF_Register from an agent,
this will also indicate that the sleeping agent
is again awake - SIF_Sleep, again, is an empty element,
ltSIF_Sleep/gt - The receiver responds with success
(SIF_Ack/SIF_Status/SIF_Code 0)
56SIF_Wakeup
- SIF_Wakeup allows a sleeping agent or ZIS to
inform the recipient of this message that it is
again awake - SIF_Wakeup, again, is an empty element,
ltSIF_Wakeup/gt - The receiver responds with success
(SIF_Ack/SIF_Status/SIF_Code 0) - It is recommended that agents send SIF_Wakeup on
start-up to the ZIS, in case the ZIS has stopped
delivering messages to a Push mode agent in the
case of an inability to connect to the agent
57SIF_Sleep/SIF_Wakeup vs. SIF_Register/SIF_Unregist
er
- SIF_Sleep/SIF_Wakeup are flow control messages
- While SIF_Register will mark an agent as awake,
SIF_Register also contains protocol information - SIF_Register will not undo a SIF_Unregister, as
agent subscriptions and provisions may be lost
upon SIF_Unregister
58SIF_GetMessage
- And finally, SIF_GetMessage, is the mechanism by
which a Pull mode agent retrieves messages from
the ZIS - Agents should only use SIF_GetMessage if they are
registered in Pull mode - SIF_GetMessage, again, is an empty element,
ltSIF_GetMessage/gt - The ZIS responds either with No messages
available (SIF_Ack/SIF_Status/SIF_Code 9) - Or returns the next available message in
SIF_Ack/SIF_Status/SIF_Data, setting
SIF_Status/SIF_Code to success (0) - If the agent is not registered in Pull mode it
will receive an error SIF_Ack
59SIF_Ack
- SIF_Ack is the response returned to all
SIF_Message requests, both by agents and ZIS - An agent may also send a SIF_Ack to the ZIS when
SMB is invoked - Contains the SIF_Header/SIF_SourceId of the agent
origininating the ack-ed message in
SIF_OriginalSourceId - And similarly contatins the SIF_Header/SIF_MsgId
of the original message in SIF_OriginalMsgId - Optionally includes status or error information,
or data
60Infrastructure
- The Infrastructure sections lists all
Infrastructure elements and attributes in tabular
form - Should closely match specification versions DTD
- Lists elements as mandatory, optional,
repeatable, conditional, or combinations thereof - Provides descriptions of each element and
attribute - As weve covered the highlights in Architecture
(Message Handling),if there are any questions
regarding individual elements or attributes, we
can take a look at the document - But as promised well examine SIF_Query and well
look at the one data object Infrastructure
defines, SIF_ZoneStatus
61SIF_Request/SIF_Query
- SIF_Request/SIF_Query tells the Responder what
the Requester wishes to know - SIF_Query is eventually intended to be a
full-featured query mechanism, but is currently
limited to queries on attributes of a data
objects root attributes - Currently only equality comparisons are supported
- Path syntax is based on XPath/XSLT
62SIF_Query
- The Requester specifies which type of object it
wishes to receive from the responder in
SIF_Query/SIF_QueryObject/_at_ObjectName - If the Requester wishes to limit the elements
returned in each data object returned, it may
include any number of SIF_Query/SIF_QueryObject/SI
F_Element elements - The Requester may also limit which data objects
are returned by including SIF_Query/SIF_ConditionG
roup - otherwise all data objects are returned in the
response
63SIF_ConditionGroup
- SIF_ConditionGroup contains the query conditions
- Three types of conditions
- And (two sets of conditions and-ed together)
- Or (two sets of conditions or-ed together)
- None (only one condition)
- Each SIF_Condition has a SIF_Element, a
SIF_Operator and a SIF_Value, the value to match
on - Operators currently limited to EQ (equal to),
elements are limited to root attributes of the
data object in the current specification version
using the path syntax on the next slide
64Path Syntax
- Weve been using rudimentary XPath throughout for
paths - In SIF we use / and _at_
- In SIF_Query all paths are relative to the
requested data object - Using StudentPersonal, _at_RefId is the RefId
attribute of the StudentPersonal object - Name/FirstName would be the FirstName child of
the StudentPersonals Name element - And PhoneNumber/_at_Type would be the Type attribute
of the StudentPersonals PhoneNumber element - For this version of the specification,
SIF_Condition/SIF_Element values are limited to
root attributes of the data object, so
SIF_Element values are currently limited to, for
example, _at_RefId
65SIF_ZoneStatus
- Infrastructure defines one data object,
SIF_ZoneStatus--events are not published for the
object - Provides a snapshot of the zone
- Offers name of ZIS and information regarding the
ZIS vendor - Lists supported communication protocols/transport
layers - Includes all registered agents with their
protocol information and some state information - Gives lists of providers and subscribers by data
object
66Data Model
- 19 objects in 1.1, 88 in 1.5r1
- Elements and attributes provided in tabular
format similar to Infrastructure section, with
the one difference being that in the
specifications DTD all elements are listed as
optional - This allows unchanged elements to be omitted from
events and responses to be filtered down to
specific elements - Common elements defined
- Name, Address, PhoneNumber
- OtherId, Demographics, GridLocation,
HealthContact, Immunization, Screening - If anyone would like to look at individual data
objects, we can do so
67Appendices
- Index of objects, elements, examples, tables,
etc. - Infrastructure status and error codes
- Various codes used by data objects
68References
- Various standards references
- XML, HTTP, TLS
- Background reading in security and XML
- GUID generation
69Specification Issues
- Certification and the spec
- Vendor software and the spec
- What the spec does and does not do
70Contact Information
- Dr. Larry Fruth lfruth_at_sifinfo.org
- Laurie Collins lcollins_at_sifinfo.org
- Mark Reichert mreichert_at_sifinfo.org