nmxp_data.h 10.3 KB
Newer Older
1 2
/*! \file
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
3
 * \brief Data for Nanometrics Protocol Library
4 5 6 7 8 9
 *
 * Author:
 * 	Matteo Quintiliani
 * 	Istituto Nazionale di Geofisica e Vulcanologia - Italy
 *	quintiliani@ingv.it
 *
10
 * $Id: nmxp_data.h,v 1.40 2010-09-01 20:18:23 mtheo Exp $
Matteo Quintiliani's avatar
Matteo Quintiliani committed
11
 *
12 13 14 15 16
 */

#ifndef NMXP_DATA_H
#define NMXP_DATA_H 1

17
#include <stdint.h>
18
#include <stdio.h>
19
#include <time.h>
20

21

22 23 24 25 26 27 28 29
/*! \brief struct tm plus ten thousandth second field */
typedef struct {
    struct tm t;
    uint32_t d;
} NMXP_TM_T;



30 31 32
/*! First 4 bytes of all messages. */
#define NMX_SIGNATURE 0x7abcde0f

33 34 35 36
/*! */
#define NMXP_DATA_IS_LEAP(yr)     ( yr%400==0 || (yr%4==0 && yr%100!=0) )


37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
/*! \brief Defines the type for reason of shutdown */
typedef enum {
    NMXP_SHUTDOWN_NORMAL		= 1,
    NMXP_SHUTDOWN_ERROR			= 2,
    NMXP_SHUTDOWN_TIMEOUT		= 3
} NMXP_SHUTDOWN_REASON;

/*! \brief Defines the client message types */
typedef enum {
   NMXP_MSG_CONNECT			= 100,
   NMXP_MSG_REQUESTPENDING		= 110,
   NMXP_MSG_CANCELREQUEST		= 205,
   NMXP_MSG_TERMINATESUBSCRIPTION	= 200,

   NMXP_MSG_ADDTIMESERIESCHANNELS	= 120,
   NMXP_MSG_ADDSOHCHANNELS		= 121,
   NMXP_MSG_ADDSERIALCHANNELS		= 124,
   NMXP_MSG_ADDTRIGGERCHANNELS		= 122,
   NMXP_MSG_ADDEVENTS			= 123,

   NMXP_MSG_REMOVETIMESERIESCHANNELS	= 130,
   NMXP_MSG_REMOVESOHCHANNELS		= 131,
   NMXP_MSG_REMOVESERIALCHANNELS	= 134,
   NMXP_MSG_REMOVETRIGGERCHANNELS	= 132,
   NMXP_MSG_REMOVEEVENTS		= 133,

   NMXP_MSG_CONNECTREQUEST		= 206,
   NMXP_MSG_CHANNELLISTREQUEST		= 209,
   NMXP_MSG_PRECISLISTREQUEST		= 203,
   NMXP_MSG_CHANNELINFOREQUEST		= 226,
   NMXP_MSG_DATASIZEREQUEST		= 229,
   NMXP_MSG_DATAREQUEST			= 227,
   NMXP_MSG_TRIGGERREQUEST		= 231,
   NMXP_MSG_EVENTREQUEST		= 232
   
} NMXP_MSG_CLIENT;

/*! \brief Defines the server message types. */
typedef enum {
    NMXP_MSG_CHANNELLIST		= 150,
    NMXP_MSG_ERROR			= 190,
    NMXP_MSG_COMPRESSED			= 1,
    NMXP_MSG_DECOMPRESSED		= 4,
    NMXP_MSG_TRIGGER			= 5,
    NMXP_MSG_EVENT			= 6,

    NMXP_MSG_READY			= 208,
    NMXP_MSG_PRECISLIST			= 253,
    NMXP_MSG_CHANNELHEADER		= 256,
    NMXP_MSG_DATASIZE			= 257,
    NMXP_MSG_NAQSEVENT			= 260,
    NMXP_MSG_NAQSTRIGGER		= 259

} NMXP_MSG_SERVER;


/*! \brief Header for all messages. */
typedef struct {
95 96 97
    int32_t signature;
    int32_t type;
    int32_t length;
98 99
} NMXP_MESSAGE_HEADER;

100
#define NMXP_MAX_LENGTH_DATA_BUFFER (4092 * 4)
101

102 103
#define NMXP_DATA_MAX_SIZE_DATE 200

104
/*! \brief Length in bytes of channel strings */
105
#define NMXP_DATA_NETWORK_LENGTH 10
106

107
/*! \brief Length in bytes of station strings */
108
#define NMXP_DATA_STATION_LENGTH 10
109 110

/*! \brief Length in bytes of channel strings */
111
#define NMXP_DATA_CHANNEL_LENGTH 10
112
#define NMXP_DATA_LOCATION_LENGTH 3
113

114 115 116
/*! Time-out for keeping the DataServer connection alive  */
#define NMXP_DAP_TIMEOUT_KEEPALIVE 15

117 118
/*! \brief Parameter structure for functions that process data */
typedef struct {
119
    int32_t key;			/*!< \brief Channel Key */
120 121 122
    char network[NMXP_DATA_NETWORK_LENGTH];	/*!< \brief Network code */
    char station[NMXP_DATA_STATION_LENGTH];	/*!< \brief Station code */
    char channel[NMXP_DATA_CHANNEL_LENGTH];	/*!< \brief Channel code */
123
    char location[NMXP_DATA_LOCATION_LENGTH];	/*!< \brief Location code */
124 125 126 127 128 129
    int32_t packet_type;			/*!< \brief Packet type */
    int32_t x0;				/*!< \brief First sample. It is significant only if x0n_significant != 0 */
    int32_t xn;				/*!< \brief Last sample. It is significant only if x0n_significant != 0 */
    int32_t x0n_significant;			/*!< \brief Declare if xn significant */
    int32_t oldest_seq_no;			/*!< \brief Oldest Sequence number */
    int32_t seq_no;				/*!< \brief Sequence number */
130 131
    double time;			/*!< \brief Time first sample. Epochs. */
    int *pDataPtr;			/*!< \brief Array of samples */
132 133
    int32_t nSamp;				/*!< \brief Number or samples */
    int32_t sampRate;			/*!< \brief Sample rate */
134
    int timing_quality;			/*!< \brief Timing quality for functions send_raw*() */
135
    char quality_indicator;             /*!< \brief Quality indicator D, R, Q or M, new in Seed 2.4 */
136
} NMXP_DATA_PROCESS;
137 138


139 140 141 142 143 144 145 146
/*! \brief For SDS or BUD directory structure */
typedef enum {
    NMXP_TYPE_WRITESEED_SDS = 0,
    NMXP_TYPE_WRITESEED_BUD
} NMXP_DATA_SEED_TYPEWRITE;

#define NMXP_DATA_MAX_SIZE_FILENAME 1024
#define NMXP_DATA_MAX_NUM_OPENED_FILE 200
147 148
/*! \brief Parameter structure for functions that handle mini-seed records */
typedef struct {
149 150 151
    int n_open_files;
    int last_open_file;
    int cur_open_file;
152 153
    int err_general;
    int err_outfile_mseed[NMXP_DATA_MAX_NUM_OPENED_FILE];
154 155 156 157 158
    FILE *outfile_mseed[NMXP_DATA_MAX_NUM_OPENED_FILE];
    char filename_mseed[NMXP_DATA_MAX_NUM_OPENED_FILE][NMXP_DATA_MAX_SIZE_FILENAME];
    char outdirseed[NMXP_DATA_MAX_SIZE_FILENAME];
    char default_network[5];
    NMXP_DATA_SEED_TYPEWRITE type_writeseed;
159 160
    /* pmsr is used like (void *) but it has to be a pointer to MSRecord !!! */
    void *pmsr;
161 162
} NMXP_DATA_SEED;

163
/*! \brief Initialize a structure NMXP_DATA_PROCESS
164
 *
165
 *  \param pd Pointer to a NMXP_DATA_PROCESS structure.
166 167
 *
 */
168
int nmxp_data_init(NMXP_DATA_PROCESS *pd);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183


/*! \brief Unpack a 17-byte Nanometrics compressed data bundle.           
 *
 * \param[out] outdata
 * \param indata
 * \param prev
 *
 * \return Number of unpacked data samples, -1 if null bundle. 
 *
 * Author:  Doug Neuhauser
 *          UC Berkeley Seismological Laboratory
 *          doug@seismo.berkeley.edu
 *
 */
184
int nmxp_data_unpack_bundle (int32_t *outdata, unsigned char *indata, int32_t *prev);
185

186

187 188 189 190 191 192
/* \brief Value for parameter exclude_bitmap in the function nmxp_data_trim() */
#define NMXP_DATA_TRIM_EXCLUDE_FIRST 2

/* \brief Value for parameter exclude_bitmap in the function nmxp_data_trim() */
#define NMXP_DATA_TRIM_EXCLUDE_LAST  4

193 194 195 196 197
/*! \brief Convert epoch in string
 */
int nmxp_data_to_str(char *out_str, double time_d);


198 199 200 201 202 203 204 205 206 207
/*! \brief Return year from epoch
 */
int nmxp_data_year_from_epoch(double time_d);


/*! \brief Return julian day from epoch
 */
int nmxp_data_yday_from_epoch(double time_d);


208 209 210 211 212
/*! \brief Trim data within a time interval
 *
 * \param pd Pointer to struct NMXP_DATA_PROCESS
 * \param trim_start_time Start time.
 * \param trim_end_time End time.
213
 * \param exclude_bitmap Bitmap for excluding or not the first and/or the last sample.
214 215 216 217 218 219
 *
 * \retval 2 On success, data has not been trimmed.
 * \retval 1 On success, data has been trimmed.
 * \retval 0 On error.
 *
 */
220
int nmxp_data_trim(NMXP_DATA_PROCESS *pd, double trim_start_time, double trim_end_time, unsigned char exclude_bitmap);
221 222


223 224 225 226 227 228
/*! \brief Return number of epochs in GMT 
 *
 */
time_t nmxp_data_gmtime_now();


229 230 231 232 233 234 235 236
/*! \brief Compute latency from current time and struct NMXP_DATA_PROCESS
 *
 * \param pd Pointer to struct NMXP_DATA_PROCESS
 *
 */
double nmxp_data_latency(NMXP_DATA_PROCESS *pd);


237
/*! \brief Print info about struct NMXP_DATA_PROCESS
238
 *
239
 * \param pd Pointer to struct NMXP_DATA_PROCESS
240
 * \param flag_sample If it is not equal to zero sample values will be printed
241 242
 *
 */
243
int nmxp_data_log(NMXP_DATA_PROCESS *pd, int flag_sample);
244

245

246 247 248 249
/*! \brief Parse string and set value in ret_tm
 *
 *
 */
250
int nmxp_data_parse_date(const char *pstr_date, NMXP_TM_T *ret_tmt);
251 252 253 254 255 256


/*! \brief Wrapper for timegm
 *
 *
 */
257
double nmxp_data_tm_to_time(NMXP_TM_T *tmt);
258

259 260 261 262

/*! \brief Return path of the current directory
 *
 * Return value need to be freed!
263 264 265
 */
char *nmxp_data_gnu_getcwd ();

266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287

/*! \brief Check if the directory exists
 *
 * \retval 1 exists, 0 otherwise.
 */
int nmxp_data_dir_exists (char *dirname);


/*! \brief Check if the directory exists
 *
 * Return value need to be freed!
 */
char *nmxp_data_dir_abspath (char *dirname);


/*! \brief Create the directory.
 * Wrapper for mkdir() over different systems.
 */
int nmxp_data_mkdir(const char *dirname);


/*! \brief Create the directory and subdirectories if is needed
288 289
 */
int nmxp_data_mkdirp(const char *filename);
290

291

292 293 294
/*! \brief Initialize a structure NMXP_DATA_SEED
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
295 296 297
 *  \param default_network String containing default network code.
 *  \param outdirseed Root output directory for SDS or BUD structure.
 *  \param type_writeseed Declare SDS or BUD structure.
298 299
 *
 */
300 301 302 303 304
int nmxp_data_seed_init(NMXP_DATA_SEED *data_seed, char *default_network, char *outdirseed, NMXP_DATA_SEED_TYPEWRITE type_writeseed);

/*! \brief Open file in a structure NMXP_DATA_SEED, in case close file before.
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
305 306
 *  
 *  N.B. nmxp_data_seed_fopen() reads information from data_seed->pd.
307 308
 *
 */
309
int nmxp_data_seed_fopen(NMXP_DATA_SEED *data_seed);
310

311 312 313
/*! \brief Close file in a structure NMXP_DATA_SEED
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
314
 *  \param i Index of the file descriptor to delete.
315 316 317 318 319 320 321 322 323 324
 *
 */
int nmxp_data_seed_fclose(NMXP_DATA_SEED *data_seed, int i);

/*! \brief Close all file in a structure NMXP_DATA_SEED
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
 *
 */
int nmxp_data_seed_fclose_all(NMXP_DATA_SEED *data_seed);
325

326 327 328 329 330 331 332

/*! \brief
 *
 */
int nmxp_data_get_filename_ms(NMXP_DATA_SEED *data_seed, char *dirseedchan, char *filenameseed);


333 334
/*! \brief Write mini-seed records from a NMXP_DATA_PROCESS structure.
 *
335
 * \param pd Pointer to struct NMXP_DATA_PROCESS. If it is NULL then flush all data into mini-SEED file.
Matteo Quintiliani's avatar
Matteo Quintiliani committed
336 337
 * \param data_seed Pointer to struct NMXP_DATA_SEED.
 * \param pmsr Pointer to mini-SEED record.
Matteo Quintiliani's avatar
Matteo Quintiliani committed
338 339
 *
 * \warning pmsr is used like (void *) but it has to be a pointer to MSRecord !!!
340 341 342 343
 *
 * \return Returns the number records created on success and -1 on error. Return value of msr_pack().
 *
 */
344
int nmxp_data_msr_pack(NMXP_DATA_PROCESS *pd, NMXP_DATA_SEED *data_seed, void *pmsr);
345

346 347 348 349 350

/*! \brief Swap 2 bytes. 
 *
 * \param in Variable length 2 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
351
 */
352 353 354 355 356 357 358
void nmxp_data_swap_2b (int16_t *in);


/*! \brief Swap 3 bytes. 
 *
 * \param in Variable length 3 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
359
 */
360 361 362 363 364 365 366
void nmxp_data_swap_3b (unsigned char *in);


/*! \brief Swap 4 bytes. 
 *
 * \param in Variable length 4 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
367
 */
368 369 370 371 372 373 374
void nmxp_data_swap_4b (int32_t *in);


/*! \brief Swap 8 bytes. 
 *
 * \param in Variable length 8 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
375
 */
376
void nmxp_data_swap_8b (double *in);
377 378


Matteo Quintiliani's avatar
Matteo Quintiliani committed
379 380 381 382 383 384 385 386 387 388 389
/*! \brief Determine the byte order of the host machine. 
 *  Due to the lack of portable defines to determine host byte order this
 *  run-time test is provided.  The code below actually tests for
 *  little-endianess, the only other alternative is assumed to be big endian.
 *
 *  \retval 0 if the host is little endian.
 *  \retval 1 otherwise.
 */
int nmxp_data_bigendianhost ();


390 391
#endif