You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

659 lines
32 KiB
C

/***************************************************************************
* Documentation and helpers for miniSEED structures.
*
* This file is part of the miniSEED Library.
*
* Copyright (c) 2023 Chad Trabant, EarthScope Data Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
***************************************************************************/
#ifndef MSEEDFORMAT_H
#define MSEEDFORMAT_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "libmseed.h"
/* Length of Fixed Section of Data Header for miniSEED 3 */
#define MS3FSDH_LENGTH 40
/***************************************************************************
* miniSEED 3.0 Fixed Section of Data Header
* 40 bytes, plus length of identifier, plus length of extra headers
*
* # FIELD TYPE OFFSET
* 1 record indicator char[2] 0
* 2 format version uint8_t 2
* 3 flags uint8_t 3
* 4a nanosecond uint32_t 4
* 4b year uint16_t 8
* 4c day uint16_t 10
* 4d hour uint8_t 12
* 4e min uint8_t 13
* 4f sec uint8_t 14
* 5 data encoding uint8_t 15
* 6 sample rate/period float64 16
* 7 number of samples uint32_t 24
* 8 CRC of record uint32_t 28
* 9 publication version uint8_t 32
* 10 length of identifer uint8_t 33
* 11 length of extra headers uint16_t 34
* 12 length of data payload uint32_t 36
* 13 source identifier char 40
* 14 extra headers char 40 + field 10
* 15 data payload encoded 40 + field 10 + field 11
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS3FSDH_INDICATOR(record) ((char*)record)
#define pMS3FSDH_FORMATVERSION(record) ((uint8_t*)((uint8_t*)record+2))
#define pMS3FSDH_FLAGS(record) ((uint8_t*)((uint8_t*)record+3))
#define pMS3FSDH_NSEC(record) ((uint32_t*)((uint8_t*)record+4))
#define pMS3FSDH_YEAR(record) ((uint16_t*)((uint8_t*)record+8))
#define pMS3FSDH_DAY(record) ((uint16_t*)((uint8_t*)record+10))
#define pMS3FSDH_HOUR(record) ((uint8_t*)((uint8_t*)record+12))
#define pMS3FSDH_MIN(record) ((uint8_t*)((uint8_t*)record+13))
#define pMS3FSDH_SEC(record) ((uint8_t*)((uint8_t*)record+14))
#define pMS3FSDH_ENCODING(record) ((uint8_t*)((uint8_t*)record+15))
#define pMS3FSDH_SAMPLERATE(record) ((double*)((uint8_t*)record+16))
#define pMS3FSDH_NUMSAMPLES(record) ((uint32_t*)((uint8_t*)record+24))
#define pMS3FSDH_CRC(record) ((uint32_t*)((uint8_t*)record+28))
#define pMS3FSDH_PUBVERSION(record) ((uint8_t*)((uint8_t*)record+32))
#define pMS3FSDH_SIDLENGTH(record) ((uint8_t*)((uint8_t*)record+33))
#define pMS3FSDH_EXTRALENGTH(record) ((uint16_t*)((uint8_t*)record+34))
#define pMS3FSDH_DATALENGTH(record) ((uint32_t*)((uint8_t*)record+36))
#define pMS3FSDH_SID(record) ((char*)((uint8_t*)record+40))
/***************************************************************************
* miniSEED 2.4 Fixed Section of Data Header
* 48 bytes total
*
* FIELD TYPE OFFSET
* sequence_number char[6] 0
* dataquality char 6
* reserved char 7
* station char[5] 8
* location char[2] 13
* channel char[3] 15
* network char[2] 18
* year uint16_t 20
* day uint16_t 22
* hour uint8_t 24
* min uint8_t 25
* sec uint8_t 26
* unused uint8_t 27
* fract uint16_t 28
* numsamples uint16_t 30
* samprate_fact int16_t 32
* samprate_mult int16_t 34
* act_flags uint8_t 36
* io_flags uint8_t 37
* dq_flags uint8_t 38
* numblockettes uint8_t 39
* time_correct int32_t 40
* data_offset uint16_t 44
* blockette_offset uint16_t 46
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2FSDH_SEQNUM(record) ((char*)record)
#define pMS2FSDH_DATAQUALITY(record) ((char*)((uint8_t*)record+6))
#define pMS2FSDH_RESERVED(record) ((char*)((uint8_t*)record+7))
#define pMS2FSDH_STATION(record) ((char*)((uint8_t*)record+8))
#define pMS2FSDH_LOCATION(record) ((char*)((uint8_t*)record+13))
#define pMS2FSDH_CHANNEL(record) ((char*)((uint8_t*)record+15))
#define pMS2FSDH_NETWORK(record) ((char*)((uint8_t*)record+18))
#define pMS2FSDH_YEAR(record) ((uint16_t*)((uint8_t*)record+20))
#define pMS2FSDH_DAY(record) ((uint16_t*)((uint8_t*)record+22))
#define pMS2FSDH_HOUR(record) ((uint8_t*)((uint8_t*)record+24))
#define pMS2FSDH_MIN(record) ((uint8_t*)((uint8_t*)record+25))
#define pMS2FSDH_SEC(record) ((uint8_t*)((uint8_t*)record+26))
#define pMS2FSDH_UNUSED(record) ((uint8_t*)((uint8_t*)record+27))
#define pMS2FSDH_FSEC(record) ((uint16_t*)((uint8_t*)record+28))
#define pMS2FSDH_NUMSAMPLES(record) ((uint16_t*)((uint8_t*)record+30))
#define pMS2FSDH_SAMPLERATEFACT(record) ((int16_t*)((uint8_t*)record+32))
#define pMS2FSDH_SAMPLERATEMULT(record) ((int16_t*)((uint8_t*)record+34))
#define pMS2FSDH_ACTFLAGS(record) ((uint8_t*)((uint8_t*)record+36))
#define pMS2FSDH_IOFLAGS(record) ((uint8_t*)((uint8_t*)record+37))
#define pMS2FSDH_DQFLAGS(record) ((uint8_t*)((uint8_t*)record+38))
#define pMS2FSDH_NUMBLOCKETTES(record) ((uint8_t*)((uint8_t*)record+39))
#define pMS2FSDH_TIMECORRECT(record) ((int32_t*)((uint8_t*)record+40))
#define pMS2FSDH_DATAOFFSET(record) ((uint16_t*)((uint8_t*)record+44))
#define pMS2FSDH_BLOCKETTEOFFSET(record) ((uint16_t*)((uint8_t*)record+46))
/***************************************************************************
* miniSEED 2.4 Blockette 100 - sample rate
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* samprate float 4
* flags uint8_t 8
* reserved uint8_t[3] 9
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B100_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B100_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B100_SAMPRATE(blockette) ((float*)((uint8_t*)blockette+4))
#define pMS2B100_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+8))
#define pMS2B100_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+9))
/***************************************************************************
* miniSEED 2.4 Blockette 200 - generic event detection
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* amplitude float 4
* period float 8
* background_est float 12
* flags uint8_t 16
* reserved uint8_t 17
* year uint16_t 18
* day uint16_t 20
* hour uint8_t 22
* min uint8_t 23
* sec uint8_t 24
* unused uint8_t 25
* fract uint16_t 26
* detector char[24] 28
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B200_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B200_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B200_AMPLITUDE(blockette) ((float*)((uint8_t*)blockette+4))
#define pMS2B200_PERIOD(blockette) ((float*)((uint8_t*)blockette+8))
#define pMS2B200_BACKGROUNDEST(blockette) ((float*)((uint8_t*)blockette+12))
#define pMS2B200_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+16))
#define pMS2B200_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+17))
#define pMS2B200_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+18))
#define pMS2B200_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+20))
#define pMS2B200_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+22))
#define pMS2B200_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+23))
#define pMS2B200_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+24))
#define pMS2B200_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+25))
#define pMS2B200_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+26))
#define pMS2B200_DETECTOR(blockette) ((char*)((uint8_t*)blockette+28))
/***************************************************************************
* miniSEED 2.4 Blockette 201 - Murdock event detection
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* amplitude float 4
* period float 8
* background_est float 12
* flags uint8_t 16
* reserved uint8_t 17
* year uint16_t 18
* day uint16_t 20
* hour uint8_t 22
* min uint8_t 23
* sec uint8_t 24
* unused uint8_t 25
* fract uint16_t 26
* snr_values uint8_t[6] 28
* loopback uint8_t 34
* pick_algorithm uint8_t 35
* detector char[24] 36
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B201_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B201_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B201_AMPLITUDE(blockette) ((float*)((uint8_t*)blockette+4))
#define pMS2B201_PERIOD(blockette) ((float*)((uint8_t*)blockette+8))
#define pMS2B201_BACKGROUNDEST(blockette) ((float*)((uint8_t*)blockette+12))
#define pMS2B201_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+16))
#define pMS2B201_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+17))
#define pMS2B201_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+18))
#define pMS2B201_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+20))
#define pMS2B201_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+22))
#define pMS2B201_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+23))
#define pMS2B201_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+24))
#define pMS2B201_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+25))
#define pMS2B201_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+26))
#define pMS2B201_MEDSNR(blockette) ((uint8_t*)((uint8_t*)blockette+28))
#define pMS2B201_LOOPBACK(blockette) ((uint8_t*)((uint8_t*)blockette+34))
#define pMS2B201_PICKALGORITHM(blockette) ((uint8_t*)((uint8_t*)blockette+35))
#define pMS2B201_DETECTOR(blockette) ((char*)((uint8_t*)blockette+36))
/***************************************************************************
* miniSEED 2.4 Blockette 300 - step calibration
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* year uint16_t 4
* day uint16_t 6
* hour uint8_t 8
* min uint8_t 9
* sec uint8_t 10
* unused uint8_t 11
* fract uint16_t 12
* num calibrations uint8_t 14
* flags uint8_t 15
* step duration uint32_t 16
* interval duration uint32_t 20
* amplitude float 24
* input channel char[3] 28
* reserved uint8_t 31
* reference amplitude uint32_t 32
* coupling char[12] 36
* rolloff char[12] 48
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B300_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B300_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B300_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+4))
#define pMS2B300_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+6))
#define pMS2B300_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+8))
#define pMS2B300_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+9))
#define pMS2B300_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+10))
#define pMS2B300_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+11))
#define pMS2B300_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+12))
#define pMS2B300_NUMCALIBRATIONS(blockette) ((uint8_t*)((uint8_t*)blockette+14))
#define pMS2B300_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+15))
#define pMS2B300_STEPDURATION(blockette) ((uint32_t*)((uint8_t*)blockette+16))
#define pMS2B300_INTERVALDURATION(blockette) ((uint32_t*)((uint8_t*)blockette+20))
#define pMS2B300_AMPLITUDE(blockette) ((float*)((uint8_t*)blockette+24))
#define pMS2B300_INPUTCHANNEL(blockette) ((char *)((uint8_t*)blockette+28))
#define pMS2B300_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+31))
#define pMS2B300_REFERENCEAMPLITUDE(blockette) ((uint32_t*)((uint8_t*)blockette+32))
#define pMS2B300_COUPLING(blockette) ((char*)((uint8_t*)blockette+36))
#define pMS2B300_ROLLOFF(blockette) ((char*)((uint8_t*)blockette+48))
/***************************************************************************
* miniSEED 2.4 Blockette 310 - sine calibration
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* year uint16_t 4
* day uint16_t 6
* hour uint8_t 8
* min uint8_t 9
* sec uint8_t 10
* unused uint8_t 11
* fract uint16_t 12
* reserved1 uint8_t 14
* flags uint8_t 15
* duration uint32_t 16
* period float 20
* amplitude float 24
* input channel char[3] 28
* reserved2 uint8_t 31
* reference amplitude uint32_t 32
* coupling char[12] 36
* rolloff char[12] 48
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B310_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B310_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B310_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+4))
#define pMS2B310_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+6))
#define pMS2B310_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+8))
#define pMS2B310_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+9))
#define pMS2B310_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+10))
#define pMS2B310_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+11))
#define pMS2B310_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+12))
#define pMS2B310_RESERVED1(blockette) ((uint8_t*)((uint8_t*)blockette+14))
#define pMS2B310_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+15))
#define pMS2B310_DURATION(blockette) ((uint32_t*)((uint8_t*)blockette+16))
#define pMS2B310_PERIOD(blockette) ((float*)((uint8_t*)blockette+20))
#define pMS2B310_AMPLITUDE(blockette) ((float*)((uint8_t*)blockette+24))
#define pMS2B310_INPUTCHANNEL(blockette) ((char *)((uint8_t*)blockette+28))
#define pMS2B310_RESERVED2(blockette) ((uint8_t*)((uint8_t*)blockette+31))
#define pMS2B310_REFERENCEAMPLITUDE(blockette) ((uint32_t*)((uint8_t*)blockette+32))
#define pMS2B310_COUPLING(blockette) ((char*)((uint8_t*)blockette+36))
#define pMS2B310_ROLLOFF(blockette) ((char*)((uint8_t*)blockette+48))
/***************************************************************************
* miniSEED 2.4 Blockette 320 - pseudo-random calibration
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* year uint16_t 4
* day uint16_t 6
* hour uint8_t 8
* min uint8_t 9
* sec uint8_t 10
* unused uint8_t 11
* fract uint16_t 12
* reserved1 uint8_t 14
* flags uint8_t 15
* duration uint32_t 16
* PtP amplitude float 20
* input channel char[3] 24
* reserved2 uint8_t 27
* reference amplitude uint32_t 28
* coupling char[12] 32
* rolloff char[12] 44
* noise type char[8] 56
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B320_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B320_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B320_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+4))
#define pMS2B320_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+6))
#define pMS2B320_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+8))
#define pMS2B320_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+9))
#define pMS2B320_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+10))
#define pMS2B320_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+11))
#define pMS2B320_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+12))
#define pMS2B320_RESERVED1(blockette) ((uint8_t*)((uint8_t*)blockette+14))
#define pMS2B320_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+15))
#define pMS2B320_DURATION(blockette) ((uint32_t*)((uint8_t*)blockette+16))
#define pMS2B320_PTPAMPLITUDE(blockette) ((float*)((uint8_t*)blockette+20))
#define pMS2B320_INPUTCHANNEL(blockette) ((char *)((uint8_t*)blockette+24))
#define pMS2B320_RESERVED2(blockette) ((uint8_t*)((uint8_t*)blockette+27))
#define pMS2B320_REFERENCEAMPLITUDE(blockette) ((uint32_t*)((uint8_t*)blockette+28))
#define pMS2B320_COUPLING(blockette) ((char*)((uint8_t*)blockette+32))
#define pMS2B320_ROLLOFF(blockette) ((char*)((uint8_t*)blockette+44))
#define pMS2B320_NOISETYPE(blockette) ((char*)((uint8_t*)blockette+56))
/***************************************************************************
* miniSEED 2.4 Blockette 390 - generic calibration
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* year uint16_t 4
* day uint16_t 6
* hour uint8_t 8
* min uint8_t 9
* sec uint8_t 10
* unused uint8_t 11
* fract uint16_t 12
* reserved1 uint8_t 14
* flags uint8_t 15
* duration uint32_t 16
* amplitude float 20
* input channel char[3] 24
* reserved2 uint8_t 27
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B390_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B390_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B390_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+4))
#define pMS2B390_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+6))
#define pMS2B390_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+8))
#define pMS2B390_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+9))
#define pMS2B390_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+10))
#define pMS2B390_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+11))
#define pMS2B390_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+12))
#define pMS2B390_RESERVED1(blockette) ((uint8_t*)((uint8_t*)blockette+14))
#define pMS2B390_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+15))
#define pMS2B390_DURATION(blockette) ((uint32_t*)((uint8_t*)blockette+16))
#define pMS2B390_AMPLITUDE(blockette) ((float*)((uint8_t*)blockette+20))
#define pMS2B390_INPUTCHANNEL(blockette) ((char *)((uint8_t*)blockette+24))
#define pMS2B390_RESERVED2(blockette) ((uint8_t*)((uint8_t*)blockette+27))
/***************************************************************************
* miniSEED 2.4 Blockette 395 - calibration abort
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* year uint16_t 4
* day uint16_t 6
* hour uint8_t 8
* min uint8_t 9
* sec uint8_t 10
* unused uint8_t 11
* fract uint16_t 12
* reserved uint8_t[2] 14
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B395_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B395_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B395_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+4))
#define pMS2B395_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+6))
#define pMS2B395_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+8))
#define pMS2B395_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+9))
#define pMS2B395_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+10))
#define pMS2B395_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+11))
#define pMS2B395_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+12))
#define pMS2B395_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+14))
/***************************************************************************
* miniSEED 2.4 Blockette 400 - beam
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* azimuth float 4
* slowness float 8
* configuration uint16_t 12
* reserved uint8_t[2] 14
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B400_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B400_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B400_AZIMUTH(blockette) ((float*)((uint8_t*)blockette+4))
#define pMS2B400_SLOWNESS(blockette) ((float*)((uint8_t*)blockette+8))
#define pMS2B400_CONFIGURATION(blockette) ((uint16_t*)((uint8_t*)blockette+12))
#define pMS2B400_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+14))
/***************************************************************************
* miniSEED 2.4 Blockette 405 - beam delay
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* delay values uint16_t[1] 4
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B405_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B405_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B405_DELAYVALUES(blockette) ((uint16_t*)((uint8_t*)blockette+4))
/***************************************************************************
* miniSEED 2.4 Blockette 500 - timing
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* VCO correction float 4
* year uint16_t 8
* day uint16_t 10
* hour uint8_t 12
* min uint8_t 13
* sec uint8_t 14
* unused uint8_t 15
* fract uint16_t 16
* microsecond int8_t 18
* reception quality uint8_t 19
* exception count uint32_t 20
* exception type char[16] 24
* clock model char[32] 40
* clock status char[128] 72
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B500_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B500_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B500_VCOCORRECTION(blockette) ((float*)((uint8_t*)blockette+4))
#define pMS2B500_YEAR(blockette) ((uint16_t*)((uint8_t*)blockette+8))
#define pMS2B500_DAY(blockette) ((uint16_t*)((uint8_t*)blockette+10))
#define pMS2B500_HOUR(blockette) ((uint8_t*)((uint8_t*)blockette+12))
#define pMS2B500_MIN(blockette) ((uint8_t*)((uint8_t*)blockette+13))
#define pMS2B500_SEC(blockette) ((uint8_t*)((uint8_t*)blockette+14))
#define pMS2B500_UNUSED(blockette) ((uint8_t*)((uint8_t*)blockette+15))
#define pMS2B500_FSEC(blockette) ((uint16_t*)((uint8_t*)blockette+16))
#define pMS2B500_MICROSECOND(blockette) ((int8_t*)((uint8_t*)blockette+18))
#define pMS2B500_RECEPTIONQUALITY(blockette) ((uint8_t*)((uint8_t*)blockette+19))
#define pMS2B500_EXCEPTIONCOUNT(blockette) ((uint32_t*)((uint8_t*)blockette+20))
#define pMS2B500_EXCEPTIONTYPE(blockette) ((char*)((uint8_t*)blockette+24))
#define pMS2B500_CLOCKMODEL(blockette) ((char*)((uint8_t*)blockette+40))
#define pMS2B500_CLOCKSTATUS(blockette) ((char*)((uint8_t*)blockette+72))
/***************************************************************************
* miniSEED 2.4 Blockette 1000 - data only SEED (miniSEED)
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* encoding uint8_t 4
* byteorder uint8_t 5
* reclen uint8_t 6
* reserved uint8_t 7
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B1000_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B1000_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B1000_ENCODING(blockette) ((uint8_t*)((uint8_t*)blockette+4))
#define pMS2B1000_BYTEORDER(blockette) ((uint8_t*)((uint8_t*)blockette+5))
#define pMS2B1000_RECLEN(blockette) ((uint8_t*)((uint8_t*)blockette+6))
#define pMS2B1000_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+7))
/***************************************************************************
* miniSEED 2.4 Blockette 1001 - data extension
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* timing quality uint8_t 4
* microsecond int8_t 5
* reserved uint8_t 6
* frame count uint8_t 7
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B1001_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B1001_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B1001_TIMINGQUALITY(blockette) ((uint8_t*)((uint8_t*)blockette+4))
#define pMS2B1001_MICROSECOND(blockette) ((int8_t*)((uint8_t*)blockette+5))
#define pMS2B1001_RESERVED(blockette) ((uint8_t*)((uint8_t*)blockette+6))
#define pMS2B1001_FRAMECOUNT(blockette) ((uint8_t*)((uint8_t*)blockette+7))
/***************************************************************************
* miniSEED 2.4 Blockette 2000 - opaque data
*
* FIELD TYPE OFFSET
* type uint16_t 0
* next offset uint16_t 2
* length uint16_t 4
* data offset uint16_t 6
* recnum uint32_t 8
* byteorder uint8_t 12
* flags uint8_t 13
* numheaders uint8_t 14
* payload char[1] 15
*
* Convenience macros for accessing the fields via typed pointers follow:
***************************************************************************/
#define pMS2B2000_TYPE(blockette) ((uint16_t*)(blockette))
#define pMS2B2000_NEXT(blockette) ((uint16_t*)((uint8_t*)blockette+2))
#define pMS2B2000_LENGTH(blockette) ((uint16_t*)((uint8_t*)blockette+4))
#define pMS2B2000_DATAOFFSET(blockette) ((uint16_t*)((uint8_t*)blockette+6))
#define pMS2B2000_RECNUM(blockette) ((uint32_t*)((uint8_t*)blockette+8))
#define pMS2B2000_BYTEORDER(blockette) ((uint8_t*)((uint8_t*)blockette+12))
#define pMS2B2000_FLAGS(blockette) ((uint8_t*)((uint8_t*)blockette+13))
#define pMS2B2000_NUMHEADERS(blockette) ((uint8_t*)((uint8_t*)blockette+14))
#define pMS2B2000_PAYLOAD(blockette) ((char*)((uint8_t*)blockette+15))
/***************************************************************************
* Simple static inline convenience functions to swap bytes to "host
* order", as determined by the swap flag.
***************************************************************************/
static inline int16_t
HO2d (int16_t value, int swapflag)
{
if (swapflag)
{
ms_gswap2 (&value);
}
return value;
}
static inline uint16_t
HO2u (uint16_t value, int swapflag)
{
if (swapflag)
{
ms_gswap2 (&value);
}
return value;
}
static inline int32_t
HO4d (int32_t value, int swapflag)
{
if (swapflag)
{
ms_gswap4 (&value);
}
return value;
}
static inline uint32_t
HO4u (uint32_t value, int swapflag)
{
if (swapflag)
{
ms_gswap4 (&value);
}
return value;
}
static inline float
HO4f (float value, int swapflag)
{
if (swapflag)
{
ms_gswap4 (&value);
}
return value;
}
static inline double
HO8f (double value, int swapflag)
{
if (swapflag)
{
ms_gswap8 (&value);
}
return value;
}
/* Macro to test for sane year and day values, used primarily to
* determine if byte order swapping is needed for miniSEED 2.x.
*
* Year : between 1900 and 2100
* Day : between 1 and 366
*
* This test is non-unique (non-deterministic) for days 1, 256 and 257
* in the year 2056 because the swapped values are also within range.
* If you are using this in 2056 to determine the byte order of miniSEED 2
* you have my deepest sympathies.
*/
#define MS_ISVALIDYEARDAY(Y,D) (Y >= 1900 && Y <= 2100 && D >= 1 && D <= 366)
#ifdef __cplusplus
}
#endif
#endif