Commit f4761206 authored by no_author's avatar no_author
Browse files

This commit was manufactured by cvs2svn to create tag 'nmxptool_0_4_0'.

git-svn-id: file:///home/quintiliani/svncopy/nmxptool/tags/nmxptool_0_4_0@110 3cd66e75-5955-46cb-a940-c26e5fc5497d
parent 2a452e95
This diff is collapsed.
/*! \mainpage
*
* \section intro_sec Introduction
*
* This is the documentation for the <i>APIs</i> that implement the <tt>Nanometrics Protocols</tt>.
* They have been developed for interacting with \c NaqsServer and \c DataServer.
*
* The Nanometrics \c NaqsServer provides online access to time-series, serial data, triggers, and state-of-health data via TCP subscription.
*
* The Nanometrics \c DataServer provides local and remote access to nanometrics, serial, and state-of-health data via TCP/IP.
*
* The library offers APIs to:
* \li interact with \c NaqsServer that uses version 1.4 of the <i>Private Data Stream Protocol</i>
* \li interact with \c DataServer that uses version 1.0 of the <i>Nanometrics Data Access Protocol</i>
* \li manage Nanometrics data formats
* \li request, receive and interpret online and offline data
*
* moreover, you can use them to develop software to:
* \li analyze data in realtime (waveforms, triggers, ...)
* \li retrieve and convert on the fly data into the mini-SEED records
* \li feed SeedLink server
*
*
* \section dependencies_sec Dependencies
*
* A library is needed to install and use \c libnmxp:
*
* \li \c libmseed: http://www.iris.edu/manuals/\n
* The Mini-SEED library. A C library framework for manipulating and managing SEED data records.\n
* Author: Chad Trabant, <i>IRIS DMC</i>\n
*
*
* \section install_sec Installation
*
* \c nmxp library has been developed using <i>GNU Build Tools</i> (\c automake, \c autoconf and \c configure script)
* taking in account the Cross-Platform aspects.
* So you should be able to compile and install it everywhere you can launch the following commands:
*
* <tt>./configure</tt>
*
* <tt>make</tt>
*
* <tt>make install</tt>
*
* Please, refer to the file \b README and \b INSTALL for more details.
*
* \section tools_sec Tools
*
* Inside the distribution are available two tools that are clients to interact respectively to \c NaqsServer and \c DataServer.
*
* \li \c nmxp_pds: implements the <i>Nanometrics Private Data Stream Protocol 1.4</i> and permits to retrieve data in near-realtime.\n
* Please, refer to the \b README file or help <tt>nmxp_pds --help</tt>.
* \li \c nmxp_dap: implements the <i>Nanometrics Data Access Protocol 1.0</i> and permits to retrieve backward data.\n
* Please, refer to the \b README file or help <tt>nmxp_dap --help</tt>.
*
*
* \subsection examples_sec Examples
*
* etc...
*
*
* \section license_sec License
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Library General Public License (GNU-LGPL) for more details.
* File \b COPYING inside this distribution.
* The GNU-LGPL and further information can be found here: http://www.gnu.org/
*
*
* \section about_sec About
*
* Matteo Quintiliani - <i>Istituto Nazionale di Geofisica e Vulcanologia</i> - Italy
*
* Mail bug reports and suggestions to <quintiliani@ingv.it>
*
*/
/*! \file
*
* \brief Nanometrics Protocol Library
*
* Author:
* Matteo Quintiliani
* Istituto Nazionale di Geofisica e Vulcanologia - Italy
* quintiliani@ingv.it
*
*/
#ifndef NMXP_H
#define NMXP_H 1
#include "nmxp_base.h"
#include "nmxp_crc32.h"
/*! \brief Flag for buffered packets */
typedef enum {
NMXP_BUFFER_NO = 0,
NMXP_BUFFER_YES = 1
} NMXP_BUFFER_FLAG;
/*! \brief Body of ConnectRequest message*/
typedef struct {
char username[12];
uint32_t version;
uint32_t connection_time;
uint32_t crc32;
} NMXP_CONNECT_REQUEST;
/*! \brief Body of DataRequest message*/
typedef struct {
uint32_t chan_key;
uint32_t start_time;
uint32_t end_time;
} NMXP_DATA_REQUEST;
/*! \brief Sends the message "Connect" on a socket
*
* \param isock A descriptor referencing the socket.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_sendConnect(int isock);
/*! \brief Sends the message "TerminateSubscription" on a socket
*
* \param isock A descriptor referencing the socket.
* \param reason Reason for the shutdown.
* \param message String message. It could be NULL.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_sendTerminateSubscription(int isock, NMXP_SHUTDOWN_REASON reason, char *message);
/*! \brief Receive message "NMXP_CHAN_LIST" from a socket
*
* \param isock A descriptor referencing the socket.
* \param[out] pchannelList List of channels. It will need to be freed!
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_receiveChannelList(int isock, NMXP_CHAN_LIST **pchannelList);
/*! \brief Sends the message "AddTimeSeriesChannels" on a socket
*
* \param isock A descriptor referencing the socket.
* \param channelList List of channel.
* \param shortTermCompletion Short-term-completion time = s, 1<= s <= 300 seconds.
* \param out_format Output format.
* -1 Compressed packets.
* 0 Uncompressed packets.
* 0 < out_format, requested output sample rate.
* \param buffer_flag Server will send or not buffered packets.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_sendAddTimeSeriesChannel(int isock, NMXP_CHAN_LIST *channelList, uint32_t shortTermCompletion, uint32_t out_format, NMXP_BUFFER_FLAG buffer_flag);
/*! \brief Receive Compressed or Decompressed Data message from a socket and launch func_processData() on the extracted data
*
* \param isock A descriptor referencing the socket.
* \param channelList Channel list.
* \param func_processData Pointer to the function manages data extracted. It could be NULL.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_receiveData(int isock, NMXP_CHAN_LIST *channelList,
int (*func_processData)(NMXP_DATA_PROCESS *pd)
);
/*! \brief Sends the message "ConnectRequest" on a socket
*
* \param isock A descriptor referencing the socket.
* \param naqs_username User name (maximum 11 characters), zero terminated.
* \param naqs_password Password.
* \param connection_time Time that the connection was opened.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_sendConnectRequest(int isock, char *naqs_username, char *naqs_password, uint32_t connection_time);
/*! \brief Read connection time from a socket
*
* \param isock A descriptor referencing the socket.
* \param[out] connection_time Time in epoch.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_readConnectionTime(int isock, uint32_t *connection_time);
/*! \brief Wait the message "Ready" from a socket
*
* \param isock A descriptor referencing the socket.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_waitReady(int isock);
/*! \brief Sends the message "DataRequest" on a socket
*
* \param isock A descriptor referencing the socket.
* \param key Channel key for which data are requested.
* \param start_time Start time of the interval for which data are requested. Epoch time.
* \param end_time End time of the interval for which data are requested. Epoch time.
*
* \retval SOCKET_OK on success
* \retval SOCKET_ERROR on error
*
*/
int nmxp_sendDataRequest(int isock, uint32_t key, uint32_t start_time, uint32_t end_time);
/*! \brief Get the list of available channels from a server
*
* \param hostname host name
* \param portnum port number
* \param datatype Type of data contained in the channel.
*
* \return Channel list. It will need to be freed.
*
* \warning Returned value will need to be freed.
*
*/
NMXP_CHAN_LIST *nmxp_getAvailableChannelList(char * hostname, int portnum, NMXP_DATATYPE datatype);
#endif
/*! \file
*
* \brief Base for Nanometrics Protocol Library
*
* Author:
* Matteo Quintiliani
* Istituto Nazionale di Geofisica e Vulcanologia - Italy
* quintiliani@ingv.it
*
*/
#ifndef NMXP_BASE_H
#define NMXP_BASE_H 1
#include "nmxp_data.h"
#include "nmxp_chan.h"
#include "nmxp_log.h"
/*! Maximum time between connection attempts (seconds). */
#define NMXP_SLEEPMAX 10
/*! Return message for succes on socket. */
#define NMXP_SOCKET_OK 0
/*! Return message for error on socket.*/
#define NMXP_SOCKET_ERROR -1
/*! \brief Looks up target host, opens a socket and connects
*
* \param hostname hostname
* \param portNum port number
*
* \retval sd A descriptor referencing the socket.
* \retval -1 "Empty host name", "Cannot lookup host", ...
*
*/
int nmxp_openSocket(char *hostname, int portNum);
/*! \brief Close a socket.
*
* \param isock A descriptor referencing the socket.
*
* \retval 0 Success
* \retval -1 Error
*
*/
int nmxp_closeSocket(int isock);
/*! \brief Sends a buffer on a socket.
*
* \param isock A descriptor referencing the socket.
* \param buffer Data buffer.
* \param length Length in bytes.
*
* \retval NMXP_SOCKET_OK on success
* \retval NMXP_SOCKET_ERROR on error
*
*/
int nmxp_send_ctrl(int isock, void *buffer, int length);
/*! \brief Receives length bytes in a buffer from a socket.
*
* \param isock A descriptor referencing the socket.
* \param[out] buffer Data buffer.
* \param length Length in bytes.
*
* \warning Data buffer it has to be allocated before and big enough to contain length bytes!
*
* \retval NMXP_SOCKET_OK on success
* \retval NMXP_SOCKET_ERROR on error
*
*/
int nmxp_recv_ctrl(int isock, void *buffer, int length);
/*! \brief Sends header of a message.
*
* \param isock A descriptor referencing the socket.
* \param type Type of message within \ref NMXP_MSG_CLIENT.
* \param length Length in bytes.
*
* \retval NMXP_SOCKET_OK on success
* \retval NMXP_SOCKET_ERROR on error
*
*/
int nmxp_sendHeader(int isock, NMXP_MSG_CLIENT type, uint32_t length);
/*! \brief Receives header of a message.
*
* \param isock A descriptor referencing the socket.
* \param[out] type Type of message within \ref NMXP_MSG_CLIENT.
* \param[out] length Length in bytes.
*
* \retval NMXP_SOCKET_OK on success
* \retval NMXP_SOCKET_ERROR on error
*
*/
int nmxp_receiveHeader(int isock, NMXP_MSG_SERVER *type, uint32_t *length);
/*! \brief Sends header and body of a message.
*
* \param isock A descriptor referencing the socket.
* \param type Type of message within \ref NMXP_MSG_CLIENT.
* \param buffer Data buffer. It could be NULL.
* \param length Length in bytes. It must be greater or equal to zero.
*
* \retval NMXP_SOCKET_OK on success
* \retval NMXP_SOCKET_ERROR on error
*
*/
int nmxp_sendMessage(int isock, NMXP_MSG_CLIENT type, void *buffer, uint32_t length);
/*! \brief Receives header and body of a message.
*
* \param isock A descriptor referencing the socket.
* \param[out] type Type of message within \ref NMXP_MSG_SERVER.
* \param[out] buffer Data buffer. It will need to be freed!
* \param[out] length Length in bytes.
*
* \warning buffer will need to be freed!
*
* \retval NMXP_SOCKET_OK on success
* \retval NMXP_SOCKET_ERROR on error
*
*/
int nmxp_receiveMessage(int isock, NMXP_MSG_SERVER *type, void **buffer, uint32_t *length);
/*! \brief Process Compressed Data message by function func_processData().
*
* \param buffer_data Pointer to the data buffer containing Compressed Nanometrics packets.
* \param length_data Buffer length in bytes.
* \param channelList Pointer to the Channel List.
*
* \return Return a pointer to static struct NMXP_DATA_PROCESS.
*
*/
NMXP_DATA_PROCESS *nmxp_processCompressedDataFunc(char* buffer_data, int length_data, NMXP_CHAN_LIST *channelList);
/*! \brief Process decompressed Data message by function func_processData().
*
* \param buffer_data Pointer to the data buffer containing Decompressed Nanometrics packets.
* \param length_data Buffer length in bytes.
* \param channelList Pointer to the Channel List.
*
* \return Return a pointer to static struct NMXP_DATA_PROCESS.
*
*/
NMXP_DATA_PROCESS *nmxp_processDecompressedDataFunc(char* buffer_data, int length_data, NMXP_CHAN_LIST *channelList);
#endif
/*! \file
*
* \brief Channels for Nanometrics Protocol Library
*
* Author:
* Matteo Quintiliani
* Istituto Nazionale di Geofisica e Vulcanologia - Italy
* quintiliani@ingv.it
*
*/
#ifndef NMXP_CHAN_H
#define NMXP_CHAN_H 1
#include <stdint.h>
/*! \brief The key/name info for one channel */
typedef struct {
uint32_t key;
char name[12];
} NMXP_CHAN_KEY;
/*! \brief Max number of channels */
#define MAX_N_CHAN 1000
/*! \brief Channel list */
typedef struct {
uint32_t number;
NMXP_CHAN_KEY channel[MAX_N_CHAN];
} NMXP_CHAN_LIST;
/*! \brief Type of Data */
typedef enum {
NMXP_DATA_TIMESERIES = 1,
NMXP_DATA_SOH = 2,
NMXP_DATA_TRANSERIAL = 6
} NMXP_DATATYPE;
/*! \brief Character separator for channel list */
#define sep_chan_list ','
/*! \brief Return type of data from a channel key */
#define getDataTypeFromKey(key) ((key >> 8) & 0xff)
/*! \brief Looks up a channel key in the list using the name
*
* \param name Channel name.
* \param channelList Channel list.
*
* \return Key of the channel with name. -1 On error.
*
*/
int nmxp_chan_lookupKey(char* name, NMXP_CHAN_LIST *channelList);
/*! \brief Looks up a channel name in the list using a key
*
* \param key Channel key.
* \param channelList Channel list.
*
* \return Name of channel with key. NULL on error.
*
*/
char *nmxp_chan_lookupName(uint32_t key, NMXP_CHAN_LIST *channelList);
/*! \brief Looks up a channel with specified data type.
*
* \param channelList Channel list.
* \param dataType Type of channel.
*
* \return Channel list with specified dataType. It will need to be freed!
*
* \warning Returned value will need to be freed!
*
*/
NMXP_CHAN_LIST *nmxp_chan_getType(NMXP_CHAN_LIST *channelList, NMXP_DATATYPE dataType);
/*! \brief Looks up a channel with specified data type.
*
* \param channelList Channel list.
* \param dataType Type of channel.
* \param sta_chan_list String list of item STA.CHAN, separeted by comma.
*
* \return Channel list with specified dataType. It will need to be freed!
*
* \warning Returned value will need to be freed!
*
*/
NMXP_CHAN_LIST *nmxp_chan_subset(NMXP_CHAN_LIST *channelList, NMXP_DATATYPE dataType, char *sta_chan_list);
/*! Sort list by channel key
*
* \param channelList Channel List
*
*/
void nmxp_chan_sortByKey(NMXP_CHAN_LIST *channelList);
/*! Sort list by channel name
*
* \param channelList Channel List
*
*/
void nmxp_chan_sortByName(NMXP_CHAN_LIST *channelList);
/*! Print channel information
*
* \param channelList Channel List
*
*/
void nmxp_chan_print_channelList(NMXP_CHAN_LIST *channelList);
#endif
/*! \file
*
* \brief Computing a 32 bit CRC.
*
* author: tatu ylonen <ylo@cs.hut.fi>
*
* copyright (c) 1992 tatu ylonen, espoo, finland
* all rights reserved
*
* created: tue feb 11 14:37:27 1992 ylo
*
* functions for computing 32-bit crc.
*
* The implementation here was originally done by Gary S. Brown. I have
* borrowed the tables directly, and made some minor changes to the
* crc32-function (including changing the interface). //ylo
*
*
* ====================================================================
*
* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*
* First, the polynomial itself and its table of feedback terms. The
* polynomial is
*
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
*
* Note that we take it "backwards" and put the highest-order term in
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
* the MSB being 1.
*
* Note that the usual hardware shift register implementation, which
* is what we're using (we're merely optimizing it by doing eight-bit
* chunks at a time) shifts bits into the lowest-order term. In our
* implementation, that means shifting towards the right. Why do we
* do it this way? Because the calculated CRC must be transmitted in
* order from highest-order term to lowest-order term. UARTs transmit
* characters in order from LSB to MSB. By storing the CRC this way,
* we hand it to the UART in the order low-byte to high-byte; the UART
* sends each low-bit to hight-bit; and the result is transmission bit
* by bit from highest- to lowest-order term without requiring any bit
* shuffling on our part. Reception works similarly.
*
* The feedback terms table consists of 256, 32-bit entries. Notes:
*
* The table can be generated at runtime if desired; code to do so
* is shown later. It might not be obvious, but the feedback
* terms simply represent the results of eight shift/xor opera-
* tions for all combinations of data and CRC register values.
*
* The values must be right-shifted by eight bits by the "updcrc"
* logic; the shift must be unsigned (bring in zeroes). On some
* hardware you could probably optimize the shift in assembler by
* using byte-swap instructions.
* polynomial $edb88320
*
* ====================================================================
*
*/
#ifndef NMXP_CRC32_H
#define NMXP_CRC32_H 1
/*! \brief Computes a 32 bit crc of the data in the buffer,
* and returns the crc. the polynomial used is 0xedb88320. */
unsigned long crc32(const unsigned char *buf, unsigned int len);
#endif /* CRC32_H */
/*! \file
*
* \brief Data for Nanometrics Protocol Library
*
* Author:
* Matteo Quintiliani
* Istituto Nazionale di Geofisica e Vulcanologia - Italy
* quintiliani@ingv.it
*
*/
#ifndef NMXP_DATA_H
#define NMXP_DATA_H 1
#include <stdint.h>
#include <stdio.h>
#include <time.h>
/*! First 4 bytes of all messages. */
#define NMX_SIGNATURE 0x7abcde0f
/*! */
#define NMXP_DATA_IS_LEAP(yr) ( yr%400==0 || (yr%4==0 && yr%100!=0) )
/*! \brief Defines the type for reason of shutdown */
typedef enum {
NMXP_SHUTDOWN_NORMAL = 1,
NMXP_SHUTDOWN_ERROR = 2,