Light manual for INTIFADA (INTegrated Interface Free Asterix Dynamic Analyser)

INTIFADA runs primary on GNU/Linux

Contact: stephane.pion AT free.fr

= Asterix =
Asterix is a structured binary message format primarily used for surveillance
related messages. It is specified by Eurocontrol. See [http://www.eurocontrol.int/asterix/public/subsite_homepage/homepage.html] for further information.

= Intifada =
Intifada could be used to decode or encode a asterix stream. As an Asterix
stream is handled by Intifada, it could be readed or modified.

Asterix structure is described in an xml file description

= writing xml asterix description =
== xml family description ==
Like it can exist several categories with same identification, categories are
grouped in families.
A family identifies a list of categories which could be encountered in the
same stream.
This description must be encountered first in asterix description, followed by
record description.

+verbatim+
<intifada>
  <families>
    <family name="family name, used in user code for identification">
      <id name="record description identification (category)"/>
    </family>
  </families>
</intifada>
-verbatim-

== record description ==
record description consist in the user application profile followed by each
item description.

+verbatim+
<record name="record short description" cat="category id" id="record identification (permit family identification)">
</record>
-verbatim-

== user application profile description ==
A user application profile could be conditional (e.g in category 1 mono radar
target record). intifada handles this possibility

+verbatim+
<uap>
  <frn num="field reference number" reference="item identification"/>
</uap>
<uap if="part item" value="expected value">
  <frn num="" reference=""/>
</uap>
-verbatim-

fields reference numbers (frn) begin to one as in eurocontrol documentation
uap could be repeted.

All items referenced in the uap section must be described.

== Data items description ==
+verbatim+
<item name="item short description" reference="item reference"></item>
-verbatim-
The item reference must be associated in the user application profile

Asterix items can take differents forms. They could be 'fixed', 'extended',
'repetitive' and compound. Some items caracteristics could be described using properties.

=== Fixed data item ===
+verbatim+
<fixed>
<properties>
<property>size=int</property>
<property>force_presence=bool (default=false)</property>
</properties>
</fixed>
-verbatim-
properties description:
* size: item total size in bytes (mandatory)
* force_presence: if true, the item will be present even if there is no one bit at 1
item's data description:
+verbatim+
<part type="type" name="name" start="first bit" size="size in bits"></part>
-verbatim-

'start' is the position of 'name' lsb. It is counted from the lsb bit of the item. It begin at 1
'part' node could have a sub field,
+verbatim+
<converter type="converter object identification"></converter>
-verbatim-

which handle conversion of asterix units in human units. Converter is only called when string conversion
is required
=== Extended data item ===

+verbatim+
<extended>
<properties>
<property>primary_size=int</property>
<property>repetitive=bool repetitive caracteristics (bool)</property>
<property>secondaries_size= secondaries parts size (int) useless if repetitive=true</property>
</properties>
</extended>
-verbatim-
properties description:
* primary_size: first part size in bytes (mandatory)
* repetitive: item is repetitive (each part (first and secondaries) have the same structure)
* secondaries_size: secondaries parts size (if item is repetitive, secondaries size are forced to primary size

==== non repetitive item's data description ====

+verbatim+
<part type="type" name="name" start="lsb bit" size="size in bits" byte="refering part">
-verbatim-
'start' is the position of 'name' lsb. It is counted from de lsb bit of the part.
'byte' indicates part (sic!). 0 is the first part, other values reffering to secondaries part

==== repetitive item's data description ====
same as non repetitive except byte must be ommited as same description is repeted for
each part

=== Repetitive data item ===

+verbatim+
<repetitive>
<properties>
<property>indicatorlength=bool</property>
<property>length=int</property>
</properties>
</repetitive>
-verbatim-
properties description:
* indicatorlength: get from stream (and put to stream) on byte indicating total length of item
* length: subpart size
<part type="type" name="name" start="lsb bit" size="size in bits">
'start' is the position of 'name' lsb. It is counted from the lsb bit of the part. It begin at 1

=== Compound data item ===

+verbatim+
<compound>
<uap>
<frn>
</frn>
</uap>
<item>
</item
</compound>
-verbatim-
compound is the same as record description except fields reference numbers numerotation (as in eurocontrol documentation)
TODO:clearing this part

= Intifada basics =

== Loading Asterix description ==

Records structure are stored in Record class. As xml description is readed, Records classes are filled with
description and stored in Record_Repository (which could be a singleton). These records are cloned as they are
needed to buid an asterix message

+verbatim+
intifada::Configuration_XML_Reader p(asterix_description,asterix_validation);
p.open();
      
intifada::Record_Repository* rep=intifada::Record_Repository::instance();
p.parse(rep);
-verbatim-

Configuration_XML_Reader read XML file.
Configuration_XML_Reader::open() prepare file reading
Configuration_XML_Reader::parse() load Record_Repository from XML description

Remarks, Configuration_XML_Reader inherits from Configuration_Reader, which hold all non XML loading logic.
So, you can read description from anything else as you implemented it.

== Create Asterix message from a stream ==

Asterix messages are handled by intifada::Message class.
intifada::Message must know asterix description and the asterix family it must handle.

+verbatim+
intifada::Record_Repository* rep=intifada::Record_Repository::instance();
intifada::Message msg(rep,"eurocontrol");
const uint8_t*m;
uint16_t msg_size;
...
intifada::Stream::size_type s = msg.set_stream(m,0,msg_size);
-verbatim-

After intifada::Message::set_stream call, Asterix content could be accessed.
In set_stream call, 0 is the offset in the stream m.
msg_size is the m buffer size (to avoid oversizing);

== Update a stream from an Asterix message ==

To get back an asterix message to a stream, intifada::Message have two method.
One to get the future stream size, and one to get back datas. 

+verbatim+
...
intifada::Stream::size_type osize=msg.size();
uint8_t *t=new uint8_t[osize];
intifada::Stream::size_type st=msg.get_stream(t,0,osize);
-verbatim-

In get_stream call, 0 is the offset in the stream t.
osize is the t buffer size (to avoid oversizing);

== Create a asterix message from scratch ==

Remember that a block could contain several records of the same category, and
a message could have several blocks.

The principe is to get a block from a message, and then, a record from a block.

+verbatim+
// Getting a block
intifada::Record_Repository* rep=intifada::Record_Repository::instance();
intifada::Message msg(rep,"eurocontrol");

uint8_t category=1;
intifada::Block *block=msg.get_new_block(category);

// Getting a record
intifada::Record *record=block->get_new_record();

// Now, doing a lot of very interesting things with the record
...
// ... and push back to message
block->push_back(record);
msg.push_back(block);
-verbatim-

Note that 'push_back' operations could be achieved as the associated object was created.

== Walking throught messages ==

maybe you want see each record in a message. Fortunately, intifada is equiped to do that
throught objects functors.
There is two types of object functors:
* intifada::Record_Iterator which give user access on each record in each block of a message,
* intifada::Data_Field::Functor which give user access on each data item of a record.

user must write classes which inherit frome theses classes to do something useful.

=== intifada::Record_Iterator ===
This object functor must be associated at the intifada::Message level(as it goes throught each block)
and give user access to each record found in the blocks
Note that it exist intifada::Record_Const_Iterator to walk throught constant messages

==== Register a Record_Iterator object ====
More than one Record_Iterator object could be used to walk throught a message.
Also, a Record_Iterator object could be associated with one category

Record_Iterator_List handle Record_Iterator objects.

An object functor (Record_Iterator) could be handled with following methods:
+verbatim+
intifada::Record_Iterator_List::register_iterator(Record_Iterator& it,uint8_t c);
intifada::Record_Iterator_List::register_iterator(Record_Const_Iterator& it,uint8_t c);
intifada::Record_Iterator_List::register_iterator(Record_Iterator& it);
intifada::Record_Iterator_List::register_iterator(Record_Const_Iterator& it);
-verbatim-

An object functor could be registered several time with differents categories.

To walk throught a message, call
+verbatim+
intifada::Message::foreach(const Record_Iterator_List& l)
-verbatim-

==== Record_Iterator interface ====
When a new block is encountered in a message, virtual method
+verbatim+
int intifada::Record_Iterator::operator()(uint8_t c)
-verbatim-
is called, 'c' is filled with the block category identification.
For each new record encountered, pure virtual method
+verbatim+
int operator()(Record& i,block_list_size_t& b,record_list_size_t& r)
-verbatim-
is called.
* 'i' is a reference on the encountered record 
* 'b' is the current block number in the message (b=0 for the first block)
* 'r' is the current record number in the current block (r=0 for the first record)

note that there is not a const version of intifada::Message::foreach ... maybe, surely
in a future release.

=== intifada::Data_Field::Functor ===
This object functor must be associated at the intifada::Record level (as it goes throught each data field)

This object functor is very important for dump an asterix message. It avoid to have to explicitly
call each known data field in intifada::Record_Iterator, which is boring and error prone.

==== using Data_Field::Functor ====
This object functor hasn't have to be registered before use. A derived instance could be directly
called using following virtual method
+verbatim+
int intifada::Record::foreach(Data_Field::Functor &it,const Path_Name& path)
-verbatim-
* 'it' is the Data_Field::Functor instance to apply on
* 'path' is the data field where functor must be applied (keep blank if it must be applied averywhere)

==== intifada::Data_Field::Functor interface ====
For each data field encounterd, the following pure virtual method is called:
+verbatim+
int operator()(const Stream::size_type& stream_pos,const Stream::size_type& stream_size,const Path_Name& name,Type& t)=0;
-verbatim-
* 'stream_pos' is the position in the byte stream (npos if not available)
* 'stream size' is the data field stream size
* 'name' is the name of the item
* 't' is the item value

= data types in intifada =
intifada is a typed library. User can create new type using intifada::Type as base class
all data items accesses must be done through types.

== predefined types ==
* intifada::bool_T: bool C type equivalent
* intifada::int8_T: int8_t C type equivalent
* intifada::uint8_T: uint8_t C type equivalent
* intifada::int16_T: int16_t C type equivalent
* intifada::uint16_T: uint16_t C type equivalent
* intifada::int32_T: int32_t C type equivalent
* intifada::uint32_T: uint32_t C type equivalent
* intifada::int64_T: int64_t C type equivalent
* intifada::uint64_T: uint64_t C type equivalent
* intifada::oct_T: octal base type (12 bits)
* intifada::String_Type: string type which handle ascii or icao characters

= Accessing datas =
== Using Path_Name ==

Accessing datas are done through Path_Name which handle path to items.
A separator (.) separate each step to the data.
For example, categories have an item (010) using to identifies emitter system.
It's a fixed two bytes size item. The first byte handle SIC and the second SAC.
The combinaison of two permits to identify emitter.

Accessing to these information must be done with Path_Name at "010.SAC" and "010.SIC"

If data field was repetitive (true repetitive field or extended repetitive field)
Path_Name must be suffixed by the concerned byte access.
e.g "010.SIC.3"

== Accessing datas ==
intifada::Record define two operators to accessing datas

+verbatim+
const Type& intifada::Record::operator()(const Path_Name& name)const
Type& intifada::Record::operator()(const Path_Name& name)
-verbatim-

Knowing SIC is a uint8_T type, getting value could be done using following code
+verbatim+
Record i;
...
uint8_T sic=i("010.SIC");
-verbatim-

note that if you declare sic as a reference on uint8_T, you can directly manipulate
internal asterix data In the case above, to update internal asterix data, use the
following code
+verbatim+
...
sic=0x03;
i("010.SIC")=sic;
-verbatim-


