/**
 * \page BoxAlgorithm_TCPWriter TCP Writer
__________________________________________________________________

Detailed description
__________________________________________________________________

 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Description|
This box works as a TCP server that writes its input stream out to a TCP socket with minimal header information and encoding.

The main motivation for this box is to allow external applications to receive information in a simple manner from OpenViBE without 
requiring unusual dependencies such as VRPN.

Output:

1) If the outputs of the box are raw numeric values, the box first sends every connecting client eight variables of uint32_t: format version number (in network byte order), endianness of the stream (in network byte order, 0==unknown, 1==little, 2==big, 3==pdp), sampling frequency of the signal, the number of channels, the number of samples per chunk and three variables of padding, 8*4=32 bytes in total. The last 6 variables are in the byte order of the stream. Note that only those variables will be non-zero that are meaningful for the input in question. 

Header layout as a table,

\verbatim
| Name                | Type          | Bytes from start |
| ------------------- | ------------- | ---------------- |
| Format version      | uint32_t        | 0                |
| Endianness          | uint32_t        | 4                |
| Sampling frequency  | uint32_t        | 8                |
| Number of channels  | uint32_t        | 12               |
| Samples per chunk   | uint32_t        | 16               |
| Reserved0           | uint32_t        | 20               |
| Reserved1           | uint32_t        | 24               |
| Reserved2           | uint32_t        | 28               |
\endverbatim
	
1b) If the output is chosen as hex string or descriptive string (these are valid for Stimulation input only), no header is sent.

2) After the possible global header, the data itself is sent. The data is a stream of double chunks for Signal and StreamedMatrix. 
Each chunk is a matrix [nChannels x nSamples], sent in row-major order, i.e. all samples for one channel are sent in a sequence (a row), 
then all samples of the next channel (next row), and so on. This is the same order that OpenViBE uses internally for signal chunks. 

Signal/matrix data layout as a table (k = nSamples, n = nChannels),

\verbatim
| Name                  | Type          | Bytes from start   |
| --------------------  | ------------- | ------------------ |
| Channel 1, sample 1   | double       | 32 + (k*0+0)*8     |
| Channel 1, sample 2   | double       | 32 + (k*0+1)*8     |
| ...                   | ...           | ...                |
| Channel 1, sample k   | double       | 32 + (k*0+(k-1))*8 | 
| Channel 2, sample 1   | double       | 32 + (k*1+0)*8     |
| Channel 2, sample 2   | double       | 32 + (k*1+1)*8     |
| ...                   | ...           | ...                |
| Channel 1, sample k+1 | double       | 32 + (k*n+0)*8     |
| ...                   | ...           | ....               |
\endverbatim

For Stimulations, the data is a sequence of uint64_t if the user chooses raw output, or char strings otherwise.

Multiple clients can connect to the socket of the box. The box keeps sending data to 
each client until either the scenario is stopped or that client disconnects. When
kernel calls box::process() at time t, all clients connected before or at t, 
get forwarded the chunks that are pending in box::process() at time t. Note that
the information how long time has elapsed between the acquisition or scenario startup 
and the client connection is not currently relayed by TCP Writer.
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Description|
__________________________________________________________________

Inputs description
__________________________________________________________________

 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Inputs|
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Inputs|
 *
 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Input1|
The supported input stream types are StreamedMatrix, Signal and Stimulations. The stream type of the input can be changed by the user.
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Input1|
__________________________________________________________________

Settings description
__________________________________________________________________

 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Settings|
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Settings|
 *
 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Setting1|
 Port denotes the TCP port that will accept the client connections. Default is 5678.
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Setting1|
 *
 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Setting2|
 If the input is Stimulations, this setting can change the format the stimulations are sent in to the TCP socket. The choices are raw uint64_t, hex string, or a descriptive string. For other inputs, this setting is ignored.
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Setting2|
 *
__________________________________________________________________

Examples description
__________________________________________________________________

 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Examples|
 There is an example application 'openvibe-examples-openvibe-to-tcpip' that can be used to receive data from this box. 
 The application is intended to be used together with the 'tcp-writer.xml' box tutorial.

 Another way to test the box is to connect to the socket of the box with a 'telnet' application and redirect the telnet output to a file. 
 
 It is also possible to use Acquisition Server's Generic Raw Telnet Reader to read data from the box. In that case, set Start Skip to 32 and header and footer skips to 0, and data format to double. Remember to also set the number of channels and the sampling frequency correctly. This information is not read from the stream by the Generic Raw Telnet Reader.
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Examples|
__________________________________________________________________

Miscellaneous description
__________________________________________________________________

 * |OVP_DocBegin_BoxAlgorithm_TCPWriter_Miscellaneous|
 The box performs no little-endian/big-endian conversions. The data is sent raw in the native format of the host system. The host endianness is encoded into the sent header.
 
 The box sends signal data as chunks with the same chunk size as the stream has.
 
 The box supports only 2 dimensional matrices. To send 1 dimensional matrix, you can try to upgrade it to 2 dimensions with Matrix Transpose box. The box cannot be used to send more than 2 dimensions presently.

 The box writes to all the sockets synchronously in the process() call and drops no data. If the connection is too slow to accommodate the data flow, the box will lag.
 
 Detected transmission errors will cause a disconnection of the client.
 
 Streamed Matrix can be recognized from the TCPWriter header by the sampling rate 0. If the stream is a signal, 
the sampling rate is a positive number. Raw stimulation streams have channel and sample counts per buffer 0 as well.
 
 Known issues: Note that it can be difficult to time-synchronize signals and stimulations exactly on the client side when the client receives data from
 two TCP Writer boxes. Maintaining such synchronization was not a design goal of this box. If you need synchronized streams, it is advised to build
 the connection with LabStreamingLayer: Use LSL Export box and include LSL support in the client.
 * |OVP_DocEnd_BoxAlgorithm_TCPWriter_Miscellaneous|
 */
