/***************************************************************************** * mseed.cpp * * Mini-SEED format implementation * * (c) 2000 Andres Heinloo, GFZ Potsdam * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any later * version. For more information, see http://www.gnu.org/ * * ================ * Change log * =============== * * 01.01.2013 Adapted code to CAPS client library requirements (gempa GmbH) *****************************************************************************/ #include #include #include "mseed.h" #include "slink.h" #include #include #include #include #include #include #include namespace Gempa { namespace CAPS { MSEEDFormat::MSEEDFormat(const std::string &netcode, const std::string &stacode, const std::string &loccode, const std::string &chacode, unsigned short freqn, unsigned short freqd, unsigned short packtype_init, uint8_t recordLength) : networkCode(netcode), stationCode(stacode), locationCode(loccode), channelCode(chacode), packType(packtype_init), recordLength(recordLength) { if(freqn == 0 || freqd == 0) { sample_rate_factor = 0; sample_rate_multiplier = 0; } else if(!(freqn % freqd)) { sample_rate_factor = freqn / freqd; sample_rate_multiplier = 1; } else if(!(freqd % freqn)) { sample_rate_factor = -freqd / freqn; sample_rate_multiplier = 1; } else { sample_rate_factor = -freqd; sample_rate_multiplier = freqn; } } MSEEDDataRecord *MSEEDFormat::get_buffer(const SPClock::INT_TIME &it, int usec_correction, int timing_quality, void *&dataptr, int &datalen) { size_t buflen = 1 << recordLength; MSEEDDataRecord *record = new MSEEDDataRecord(); record->data()->resize(buflen); char *buf = record->data()->data(); int n; sl_fsdh_s* fsdh = (sl_fsdh_s *)buf; memset(fsdh, 0, buflen); const int start_frames = (sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s) + sizeof(sl_blkt_1001_s) + 63) & 0xffffffc0; // align to 64 bytes dataptr = (void *)((char *) fsdh + start_frames); datalen = buflen - start_frames; fsdh->dhq_indicator = 'D'; fsdh->reserved = ' '; strncpy(fsdh->station, stationCode.c_str(), 5); if((n = stationCode.length()) < 5) memset(fsdh->station + n, 32, 5 - n); strncpy(fsdh->location, locationCode.c_str(), 2); if((n = locationCode.length()) < 2) memset(fsdh->location + n, 32, 2 - n); strncpy(fsdh->channel, channelCode.c_str(), 3); if((n = channelCode.length()) < 3) memset(fsdh->channel + n, 32, 3 - n); strncpy(fsdh->network, networkCode.c_str(), 2); if((n = networkCode.length()) < 2) memset(fsdh->network + n, 32, 2 - n); int year, doy, hour, min, sec; it.get2(&year, &doy, &hour, &min, &sec); fsdh->start_time.year = htons(year); fsdh->start_time.day = htons(doy+1); fsdh->start_time.hour = hour; fsdh->start_time.min = min; fsdh->start_time.sec = sec; fsdh->start_time.fract = htons(it.microseconds() / 100); fsdh->samprate_fact = (int16_t)htons(sample_rate_factor); fsdh->samprate_mult = (int16_t)htons(sample_rate_multiplier); fsdh->num_blockettes = 1; div_t d_corr = div(usec_correction + ((usec_correction < 0) ? -50: 50), 100); fsdh->time_correct = (int32_t)htonl(d_corr.quot); fsdh->begin_data = htons(start_frames); fsdh->begin_blockette = htons(sizeof(sl_fsdh_s)); sl_blkt_1000_s* blkt_1000 = (sl_blkt_1000_s *)((char *) fsdh + sizeof(sl_fsdh_s)); blkt_1000->blkt_type = htons(1000); // Data Only SEED Blockette blkt_1000->encoding = packType; blkt_1000->word_swap = 1; // big endian blkt_1000->rec_len = recordLength; // 9 = 512 bytes if ( timing_quality >= 0 ) { blkt_1000->next_blkt = htons(sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s)); ++fsdh->num_blockettes; sl_blkt_1001_s* blkt_1001 = (sl_blkt_1001_s *)((char *) fsdh + sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s)); blkt_1001->blkt_type = htons(1001); // Data Extension Blockette blkt_1001->timing_qual = timing_quality; blkt_1001->usec = 0; } return record; } void MSEEDFormat::updateBuffer(MSEEDDataRecord *rec, int samples, int frames) { sl_fsdh_s* fsdh = (sl_fsdh_s *)rec->data()->data(); char temp[7]; sprintf(temp, "%06d", (int)0); memcpy(fsdh->sequence_number,temp,6); fsdh->dhq_indicator = 'D'; fsdh->num_samples = htons(samples); sl_blkt_1000_s* blkt_1000 = (sl_blkt_1000_s *)((char *) fsdh + sizeof(sl_fsdh_s)); if ( ntohs(blkt_1000->next_blkt) != 0 ) { sl_blkt_1001_s* blkt_1001 = (sl_blkt_1001_s *)((char *) fsdh + sizeof(sl_fsdh_s) + sizeof(sl_blkt_1000_s)); blkt_1001->frame_cnt = frames; } rec->unpackHeader(); } } }