Oww servers can transmit data to clients using the "oww_trx" (or now "Owwl") protocol. Owwl was written at first to facilitate the creation of client programs for this protocol, but has since been expanded to provide server-side functions as well. In addition, other, non-weather, device types are being added, so that owwl can be used to transfer data at high speed from the focal plane computer (FPC) of the QUEST CMB polarization telescope.
./configure make su -c "make install"
This will build and install the library and header files, in the usual location for your system. Check out the configure options (
./configure --help) if you want to change this.
If your system doesn't have the autotools, that's a shame (they're really handy), but you can still build and install owwl manually. You will need a C compiler, and a typical C library, that supports BSD sockets. Owwl does not link to any other libraries.
owwl_new_conn(int socket, void *user_data) ;
socket is the file descriptor of an existing connexion to an owwl server, and
user_data is some arbitrary pointer to be associated with the conn. For a server-only application use
socket = 0, and never call owwl_read().
Most owwl calls will make use of the returned owwl_conn pointer.
Once a full message has been collected, decoded message data will be available in the owwl_conn::data data array.
To call a function for each data stream use owwl_foreach().
To receive connexions from clients you must first provide a listing socket to owwl_tx_new_server(). This will make a note of the socket, and initialize a list structure for connected clients. You can do this for many sockets, e.g. you could have both a TCP socket and a LOCAL (UNIX) socket.
To receive client connexions you must repeatedly call owwl_tx_poll_servers(). This will issue calls to poll, to check for new connexion requests.
Each time you want to send a data message to your clients you must first build it in a buffer, using owwl_tx_build(). This will assemble the data from all data streams in the conn into the buffer. Then send the message with owwl_tx().
The smallest element of owwl data is the 4-byte (i.e. 32-bit) word. Words are sent in network byte order.
Words are grouped together in chunks, consisting of a word giving the number of words following and the chunk type, and then the words.
At the highest level, owwl messages consist of two parts:
The message is built by calling owwl_tx_build(), which constructs first the header and then the body.
|Header Word No.||Value|
|0||OWW_TRX_HEAD + No. words following|
|1||1-word NULL-terminated text string "<tt>Oww</tt>"|
|4||Protocol version number|
The message size is the total length of the message (header + body) in bytes.
Message types may be:
|OWW_TRX_MSG_WSDATA||1||Normal data stream update|
|OWW_TRX_MSG_UPDT||2||Update interval has changed|
|OWW_TRX_MSG_MORT||3||Server about to die|
|Message type||Message body|
|OWW_TRX_MSG_UPDT||latitude and longitude |
The simple bodies consist of a single chunk, consisting of the chunk indentifier code (e.g. OWW_TRX_MSG_UPDT) followed by words giving the values.
Floating point values are passed as 4-byte IEEE reals, and integer values as 4-byte integers, all in network byte order.
This consists of a time chunk, giving the timestamp for the data values, followed by a chunk for each data stream.
Four integer values are given in the time chunk:
|0||OWW_TRX_TIME + 4|
Given as Unix time
|2||Time in local timezone|
|4||Microsecond part to timestamp|
The details of the chunks for different data stream types can best be seen from the source to the owwl_tx_add_data function.
The chunk identifier for each data stream is constructed from four values (from the low byte to the high byte):
To construct the identifier word, the chunk length is added to the serial number multiplied by 256, the device sub-type, and the device type.
See Header Word Codes for a list of the values for building chunk identifiers.
There follow the definitions of the header and data words for each data stream type.
|OWW_TRX_T||+ [OWW_TRX_SUB_TRH | OWW_TRX_SUB_TB]||+ i * OWW_TRX_SERIAL + 1|
|float||Temperature in C|
|OWW_TRX_BP||+ 0||+ i * OWW_TRX_SERIAL + 1|
|float||Barometric pressure in mbar|
|OWW_TRX_RH||+ 0||+ i * OWW_TRX_SERIAL + 1|
|float||Relative humidity in %|
|OWW_TRX_WIND||+ 0||+ i * OWW_TRX_SERIAL + 3|
owwl_data_wind::bearing * 100.0
|long||Wind bearing (clockwise from North) in units of 0.01 degrees|
|float||Wind speed (m.s<sup>-1)|
|float||Wind gust speed (m.s<sup>-1)|
|OWW_TRX_RAIN||+ 0||+ i * OWW_TRX_SERIAL + 4|
|long||Monotonic count (tips)|
|float||Rain since reset (mm)|
|long||Unix time of reset|
|float||Rainfall rate (mm.hour<sup>-1)|
|General purpose counter|
|OWW_TRX_GPC||+ 0||+ i * OWW_TRX_SERIAL + 5|
|long||Unix time of reset|
|OWW_TRX_PSB||+ 0||+ i * OWW_TRX_SERIAL + 2|
|int||PSB channel A|
|int||PSB channel B|
|OWW_TRX_DIODE||+ 0||+ i * OWW_TRX_SERIAL + 1|
|OWW_TRX_GRT||+ 0||+ i * OWW_TRX_SERIAL + 3|
|float||GRT in-phase voltage|
|float||GRT quadrature-phase voltage|
|OWW_TRX_CRYO||+ [OWW_TRX_SUB_TCD | OWW_TRX_SUB_TCG]||+ i * OWW_TRX_SERIAL + 1|
|float||Temperature in K|
|OWW_TRX_HEATER||+ 0||+ i * OWW_TRX_SERIAL + 1|
|float||Heater Voltage in V|
|OWW_TRX_RESISTANCE||+ 0||+ i * OWW_TRX_SERIAL + 1|
|float||Resistance in Ohms|