#include "dada_pwc_main_multi.h"
#include "dada_def.h"
#include "ascii_header.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
dada_pwc_main_multi_t* dada_pwc_main_multi_create (unsigned num_hdus)
{
dada_pwc_main_multi_t* pwcm = malloc (sizeof(dada_pwc_main_multi_t));
assert (pwcm != 0);
pwcm -> pwc = 0;
pwcm -> log = 0;
pwcm -> hdus = (dada_hdu_t **) malloc(sizeof(dada_hdu_t *) * num_hdus);
pwcm -> num_hdus = num_hdus;
pwcm -> start_function = 0;
pwcm -> buffer_function = 0;
pwcm -> stop_function = 0;
pwcm -> error_function = 0;
pwcm -> header_valid_function = 0;
pwcm -> context = 0;
pwcm -> verbose = 1;
pwcm -> header_valid = 0;
return pwcm;
}
void dada_pwc_main_multi_destroy (dada_pwc_main_multi_t* pwcm)
{
free (pwcm);
}
int dada_pwc_main_multi_prepare (dada_pwc_main_multi_t* pwcm);
int dada_pwc_main_multi_start_transfer (dada_pwc_main_multi_t* pwcm);
int dada_pwc_main_multi_transfer_data (dada_pwc_main_multi_t* pwcm);
int dada_pwc_main_multi_stop_transfer (dada_pwc_main_multi_t* pwcm);
int dada_pwc_main_multi (dada_pwc_main_multi_t* pwcm)
{
if (!pwcm) {
fprintf (stderr, "dada_pwc_main_multi no main!\n");
return -1;
}
if (!pwcm->pwc) {
fprintf (stderr, "dada_pwc_main_multi no PWC command connection\n");
return -1;
}
if (!pwcm->log) {
fprintf (stderr, "dada_pwc_main_multi no logging facility\n");
return -1;
}
if (!pwcm->start_function) {
fprintf (stderr, "dada_pwc_main_multi no start function\n");
return -1;
}
if (!pwcm->buffer_function) {
fprintf (stderr, "dada_pwc_main_multi no buffer function\n");
return -1;
}
if (!pwcm->stop_function) {
fprintf (stderr, "dada_pwc_main_multi no stop function\n");
return -1;
}
if (!pwcm->pwc->log)
pwcm->pwc->log = pwcm->log;
int rval = 0;
while (!dada_pwc_quit (pwcm->pwc))
{
rval = dada_pwc_main_multi_prepare (pwcm);
if (dada_pwc_quit (pwcm->pwc))
break;
if (rval < 0)
dada_pwc_main_multi_process_error (pwcm, rval);
else
{
rval = dada_pwc_main_multi_start_transfer (pwcm);
if (rval < 0)
dada_pwc_main_multi_process_error (pwcm, rval);
else {
rval = dada_pwc_main_multi_transfer_data (pwcm);
if (rval < 0)
dada_pwc_main_multi_process_error (pwcm, rval);
}
rval = dada_pwc_main_multi_stop_transfer (pwcm);
if (rval < 0)
dada_pwc_main_multi_process_error (pwcm, rval);
}
if (pwcm->pwc->state == dada_pwc_fatal_error)
pwcm->pwc->quit = 1;
}
return rval;
}
int dada_pwc_main_multi_prepare (dada_pwc_main_multi_t* pwcm)
{
unsigned i;
for (i=0; i<pwcm->num_hdus; i++)
{
if (pwcm->hdus[i]->header_block) {
pwcm->hdus[i]->header_size = ipcbuf_get_bufsz (pwcm->hdus[i]->header_block);
pwcm->hdus[i]->header = ipcbuf_get_next_write (pwcm->hdus[i]->header_block);
if (!pwcm->hdus[i]->header) {
multilog (pwcm->log, LOG_ERR, "Could not get next header block\n");
return DADA_ERROR_HARD;
}
}
}
for (i=0; i<pwcm->num_hdus; i++)
{
if (pwcm->hdus[i]->data_block && ipcio_is_open (pwcm->hdus[i]->data_block)
&& ipcio_close (pwcm->hdus[i]->data_block) < 0)
{
multilog (pwcm->log, LOG_ERR, "Could not close Data Block\n");
return DADA_ERROR_HARD;
}
}
while (!dada_pwc_quit (pwcm->pwc))
{
pwcm->command = dada_pwc_command_get (pwcm->pwc);
if (dada_pwc_quit (pwcm->pwc))
break;
if (pwcm->command.code == dada_pwc_reset)
{
dada_pwc_set_state (pwcm->pwc, dada_pwc_idle, 0);
}
else if (pwcm->command.code == dada_pwc_header)
{
#ifdef _DEBUG
multilog (pwcm->log, LOG_INFO,
"HEADER START\n%s\nHEADER END\n", pwcm->command.header);
#endif
for (i=0; i<pwcm->num_hdus; i++)
if (pwcm->hdus[i]->header_block)
strncpy (pwcm->hdus[i]->header, pwcm->command.header, pwcm->hdus[i]->header_size);
dada_pwc_set_state (pwcm->pwc, dada_pwc_prepared, 0);
}
else if (pwcm->command.code == dada_pwc_clock)
{
if (pwcm->command.byte_count) {
multilog (pwcm->log, LOG_ERR, "dada_pwc_main_multi_idle internal error. "
"byte count specified in CLOCK command\n");
return DADA_ERROR_SOFT;
}
for (i=0; i<pwcm->num_hdus; i++)
{
if (pwcm->hdus[i]->data_block && ipcio_open (pwcm->hdus[i]->data_block, 'w') < 0) {
multilog (pwcm->log, LOG_ERR, "Could not open data block\n");
return DADA_ERROR_HARD;
}
}
return 0;
}
else if (pwcm->command.code == dada_pwc_start)
{
#ifdef _DEBUG
multilog (pwcm->log, LOG_INFO, "Start recording data\n");
#endif
if (pwcm->command.byte_count)
multilog (pwcm->log, LOG_INFO,
"Will record %"PRIu64" bytes\n", pwcm->command.byte_count);
for (i=0; i<pwcm->num_hdus; i++)
{
if (pwcm->hdus[i]->data_block && ipcio_open (pwcm->hdus[i]->data_block, 'W') < 0) {
multilog (pwcm->log, LOG_ERR, "Could not open data block\n");
return DADA_ERROR_HARD;
}
}
return 0;
}
else if (pwcm->command.code == dada_pwc_stop)
{
if (pwcm->pwc->state == dada_pwc_soft_error)
multilog (pwcm->log, LOG_WARNING, "Resetting soft_error to idle\n");
else
multilog (pwcm->log, LOG_WARNING, "dada_pwc_main_multi_prepare: Unexpected stop command\n");
dada_pwc_set_state (pwcm->pwc, dada_pwc_idle, 0);
}
else
{
multilog (pwcm->log, LOG_ERR, "dada_pwc_main_multi_prepare internal error = "
"unexpected command code %s\n",
dada_pwc_cmd_code_string(pwcm->command.code));
return DADA_ERROR_HARD;
}
}
return 0;
}
int dada_pwc_main_multi_start_transfer (dada_pwc_main_multi_t* pwcm)
{
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_start_transfer: call start function\n");
#endif
time_t utc = pwcm->start_function (pwcm, pwcm->command.utc);
unsigned buffer_size = 64;
static char* buffer = 0;
unsigned i = 0;
if (!buffer)
buffer = malloc (buffer_size);
assert (buffer != 0);
if (utc < 0) {
multilog (pwcm->log, LOG_ERR, "start_function returned invalid UTC\n");
return DADA_ERROR_HARD;
}
if (utc == 0)
buffer = "UNKNOWN";
else
strftime (buffer, buffer_size, DADA_TIMESTR, gmtime (&utc));
multilog (pwcm->log, LOG_INFO, "UTC_START = %s\n", buffer);
if (pwcm->hdus[0]->header_block) {
for (i=0; i<pwcm->num_hdus; i++)
{
if (ascii_header_set (pwcm->hdus[i]->header, "UTC_START", "%s", buffer) < 0) {
multilog (pwcm->log, LOG_ERR, "failed ascii_header_set UTC_START\n");
return DADA_ERROR_SOFT;
}
}
if (utc > 0) {
pwcm->pwc->utc_start = utc;
multilog(pwcm->log, LOG_INFO, "Setting pwcm->pwc->utc_start = %d\n",pwcm->pwc->utc_start);
}
if (pwcm->command.code == dada_pwc_start) {
if (pwcm->header_valid_function)
pwcm->header_valid = pwcm->header_valid_function(pwcm);
else
pwcm->header_valid = 1;
if (pwcm->header_valid) {
#ifdef _DEBUG
multilog(pwcm->log, LOG_INFO, "dada_pwc_main_multi_start_transfer: Marking header filled\n");
#endif
for (i=0; i<pwcm->num_hdus; i++)
{
if ( ipcbuf_mark_filled (pwcm->hdus[i]->header_block, pwcm->hdus[i]->header_size) < 0) {
multilog (pwcm->log, LOG_ERR, "Could not marked header filled or command.code != start\n");
return DADA_ERROR_HARD;
}
}
}
}
}
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_start_transfer: exit change state\n");
#endif
for (i=0; i<pwcm->num_hdus; i++)
ipcbuf_set_soclock_buf ((ipcbuf_t*) pwcm->hdus[i]->data_block);
if (pwcm->command.code == dada_pwc_clock)
return dada_pwc_set_state (pwcm->pwc, dada_pwc_clocking, utc);
else if (pwcm->command.code == dada_pwc_start)
return dada_pwc_set_state (pwcm->pwc, dada_pwc_recording, utc);
multilog (pwcm->log, LOG_ERR, "dada_pwc_main_multi_start_transfer"
" internal error = invalid state\n");
return DADA_ERROR_HARD;
}
int dada_pwc_main_multi_record_start (dada_pwc_main_multi_t* pwcm)
{
uint64_t minimum_record_start = 0;
uint64_t utc_start_byte = 0;
uint64_t command_start_byte = 0;
char* header = 0;
unsigned i = 0;
for (i=0; i<pwcm->num_hdus; i++)
minimum_record_start = ipcio_get_start_minimum (pwcm->hdus[i]->data_block);
for (i=0; i<pwcm->num_hdus; i++)
utc_start_byte = ipcio_get_soclock_byte(pwcm->hdus[i]->data_block);
command_start_byte = utc_start_byte + pwcm->command.byte_count;
if (command_start_byte < minimum_record_start) {
multilog (pwcm->log, LOG_ERR, "Requested start byte=%"PRIu64
" reset to minimum=%"PRIu64"\n", command_start_byte,
minimum_record_start);
command_start_byte = minimum_record_start;
pwcm->command.byte_count = minimum_record_start - utc_start_byte;
}
multilog (pwcm->log, LOG_INFO, "REC_START\n");
multilog (pwcm->log, LOG_INFO, "pwcm->command.utc = %d\n",pwcm->command.utc);
multilog (pwcm->log, LOG_INFO, "pwcm->pwc->utc_start = %d\n",pwcm->pwc->utc_start);
for (i=0; i<pwcm->num_hdus; i++)
{
header = ipcbuf_get_next_write (pwcm->hdus[i]->header_block);
if (header != pwcm->hdus[i]->header) {
memcpy (header, pwcm->hdus[i]->header, pwcm->hdus[i]->header_size);
pwcm->hdus[i]->header = header;
}
}
time_t utc = pwcm->command.utc;
int buffer_size = 64;
char buffer[buffer_size];
strftime (buffer, buffer_size, DADA_TIMESTR, gmtime (&utc));
multilog (pwcm->log, LOG_INFO, "dada_pwc_main_multi_record_start: UTC_START reset to REC_START = %s\n", buffer);
for (i=0; i<pwcm->num_hdus; i++)
{
if (ascii_header_set (pwcm->hdus[i]->header, "UTC_START", "%s", buffer) < 0) {
multilog (pwcm->log, LOG_ERR, "fail ascii_header_set UTC_START\n");
return DADA_ERROR_HARD;
}
multilog (pwcm->log, LOG_INFO, "dada_pwc_main_multi_record_start: OBS_OFFSET = 0\n");
if (ascii_header_set (pwcm->hdus[i]->header, "OBS_OFFSET", "%"PRIu64, 0) < 0) {
multilog (pwcm->log, LOG_ERR, "fail ascii_header_set OBS_OFFSET\n");
return DADA_ERROR_HARD;
}
multilog (pwcm->log, LOG_INFO,"command_start_byte = %"PRIu64", command.byte_"
"count = %"PRIu64"\n",command_start_byte,pwcm->command.byte_count);
if (ipcio_start (pwcm->hdus[i]->data_block, command_start_byte) < 0) {
multilog (pwcm->log, LOG_ERR, "Could not start data block"
" at %"PRIu64"\n", command_start_byte);
return DADA_ERROR_HARD;
}
}
if (!(pwcm->header_valid)) {
if (pwcm->header_valid_function)
pwcm->header_valid = pwcm->header_valid_function(pwcm);
else
pwcm->header_valid = 1;
if (pwcm->header_valid) {
#ifdef _DEBUG
multilog(pwcm->log, LOG_INFO, "dada_pwc_main_multi_record_start: Marking header filled\n");
#endif
for (i=0; i<pwcm->num_hdus; i++)
{
if (ipcbuf_mark_filled (pwcm->hdus[i]->header_block, pwcm->hdus[i]->header_size) < 0) {
multilog (pwcm->log, LOG_ERR, "Could not mark filled header\n");
return DADA_ERROR_HARD;
}
}
} else {
multilog (pwcm->log, LOG_ERR, "Cannot transit from clocking to recoding "
"if when header is invalid\n");;
return DADA_ERROR_HARD;
}
}
return 0;
}
int dada_pwc_main_multi_transfer_data (dada_pwc_main_multi_t* pwcm)
{
uint64_t total_bytes_written = 0;
uint64_t transit_byte = pwcm->command.byte_count;
uint64_t bytes_to_write = pwcm->command.byte_count;
uint64_t buf_bytes = 0;
int64_t bytes_written = 0;
void ** buffers = 0;
uint64_t buffer_size = 0;
uint64_t data_transfer_error_state = 0;
char* command_string = 0;
uint64_t utc_start_set = 0;
int utc_size = 1024;
char utc_buffer[utc_size];
unsigned i = 0;
assert(pwcm->num_hdus > 0);
if (ascii_header_get (pwcm->hdus[0]->header, "UTC_START", "%s", utc_buffer) < 0) {
multilog (pwcm->log, LOG_ERR, "Could not read UTC_START from header\n");
return DADA_ERROR_HARD;
}
if (strcmp(utc_buffer,"UNKNOWN") != 0)
utc_start_set = 1;
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_transfer_data: enter main loop\n");
#endif
while ((!dada_pwc_quit (pwcm->pwc)) && (data_transfer_error_state <= 1)) {
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_transfer_data: check for command\n");
#endif
if (dada_pwc_command_check (pwcm->pwc)) {
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_transfer_data: get command\n");
#endif
pwcm->command = dada_pwc_command_get (pwcm->pwc);
if (pwcm->command.code == dada_pwc_set_utc_start) {
assert(pwcm->command.utc > 0);
if (utc_start_set) {
multilog (pwcm->log, LOG_WARNING, "WARNING, UTC_START was already "
"set. Ignoring set_utc_start command\n");
} else {
strftime (utc_buffer, utc_size, DADA_TIMESTR,
(struct tm*) gmtime(&(pwcm->command.utc)));
#ifdef _DEBUG
fprintf (stderr,"dada_pwc_main_multi_transfer_data: set UTC_START in "
"header to : %s\n",utc_buffer);
#endif
multilog (pwcm->log, LOG_INFO,"UTC_START = %s\n",utc_buffer);
for (i=0; i<pwcm->num_hdus; i++)
{
if (ascii_header_set (pwcm->hdus[i]->header,"UTC_START","%s",utc_buffer) < 0) {
multilog (pwcm->log,LOG_ERR,"failed ascii_header_set UTC_START\n");
return DADA_ERROR_HARD;
}
}
#ifdef _DEBUG
fprintf (stderr,"dada_pwc_main_multi_transfer_data: header block filled\n");
#endif
if (pwcm->pwc->state == dada_pwc_recording) {
if (pwcm->header_valid_function)
pwcm->header_valid = pwcm->header_valid_function(pwcm);
else
pwcm->header_valid = 1;
if (pwcm->header_valid) {
#ifdef _DEBUG
multilog (pwcm->log, LOG_INFO, "dada_pwc_main_multi_transfer_data: marking header valid\n");
#endif
for (i=0; i<pwcm->num_hdus; i++)
{
if (ipcbuf_mark_filled (pwcm->hdus[i]->header_block,pwcm->hdus[i]->header_size) < 0) {
multilog (pwcm->log, LOG_ERR, "Could not mark filled header\n");
return DADA_ERROR_HARD;
}
}
}
}
utc_start_set = 1;
}
pthread_mutex_lock (&(pwcm->pwc->mutex));
pthread_cond_signal (&(pwcm->pwc->cond));
pthread_mutex_unlock (&(pwcm->pwc->mutex));
} else {
if (pwcm->command.code == dada_pwc_record_stop)
command_string = "recording->clocking";
else if (pwcm->command.code == dada_pwc_record_start)
command_string = "clocking->recording";
else if (pwcm->command.code == dada_pwc_stop)
command_string = "stopping";
else {
multilog (pwcm->log, LOG_ERR,
"dada_pwc_main_multi_transfer data internal error = "
"unexpected command code %d\n", pwcm->command.code);
return DADA_ERROR_HARD;
}
if (pwcm->command.byte_count > total_bytes_written) {
transit_byte = pwcm->command.byte_count;
bytes_to_write = pwcm->command.byte_count - total_bytes_written;
multilog (pwcm->log, LOG_INFO, "%s in %"PRIu64" bytes, %"PRIu64
" bytes written\n", command_string, bytes_to_write,
total_bytes_written);
}
else {
multilog (pwcm->log, LOG_INFO, "%s immediately\n", command_string);
transit_byte = total_bytes_written;
bytes_to_write = 0;
if (pwcm->command.byte_count &&
pwcm->command.byte_count < total_bytes_written)
multilog (pwcm->log, LOG_NOTICE,
"requested transit byte=%"PRIu64" passed\n",
pwcm->command.byte_count);
}
}
if (pwcm->verbose) {
if (pwcm->pwc->state == dada_pwc_recording)
multilog (pwcm->log, LOG_INFO, "recording\n");
else if (pwcm->pwc->state == dada_pwc_clocking)
multilog (pwcm->log, LOG_INFO, "clocking\n");
if (transit_byte) {
if (pwcm->command.code == dada_pwc_record_stop)
multilog (pwcm->log, LOG_INFO, "record stop in %"PRIu64" bytes\n",
bytes_to_write);
else if (pwcm->command.code == dada_pwc_record_start)
multilog (pwcm->log, LOG_INFO, "record start in %"PRIu64" bytes\n",
bytes_to_write);
else if (pwcm->command.code == dada_pwc_record_stop)
multilog (pwcm->log, LOG_INFO, "stop in %"PRIu64" bytes\n",
bytes_to_write);
else
;
}
}
}
if (!transit_byte || bytes_to_write) {
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_transfer_data: call buffer function\n");
#endif
buffers = pwcm->buffer_function (pwcm, &buffer_size);
if (buffer_size < 0)
return buffer_size;
if ((data_transfer_error_state) && (buffer_size != 0)) {
data_transfer_error_state = 0;
if (total_bytes_written)
multilog (pwcm->log, LOG_WARNING, "pwc buffer_function "
"recovered from error state\n");
}
if (buffer_size == 0) {
if (pwcm->error_function) {
data_transfer_error_state = pwcm->error_function(pwcm);
} else {
data_transfer_error_state = 2;
}
if (data_transfer_error_state == 2) {
multilog (pwcm->log, LOG_ERR, "pwc buffer_function returned 0 bytes."
" Stopping\n");
for (i=0; i<pwcm->num_hdus; i++)
bytes_written = ipcio_write (pwcm->hdus[i]->data_block, buffers[i], 1);
return DADA_ERROR_SOFT;
}
if ((data_transfer_error_state == 1) && total_bytes_written) {
multilog (pwcm->log, LOG_WARNING, "Warning: pwc buffer function "
"returned 0 bytes. Trying to continue\n");
multilog (pwcm->log, LOG_WARNING, "total_bytes_written = %"PRIu64
", bytes_to_write = %"PRIu64", transit_byte = %"PRIu64"\n",
total_bytes_written, bytes_to_write, transit_byte);
}
}
if (!buffers) {
multilog (pwcm->log, LOG_ERR, "buffer function error\n");
return DADA_ERROR_HARD;
}
if ((!pwcm->header_valid) && (pwcm->pwc->state == dada_pwc_recording)) {
pwcm->header_valid = pwcm->header_valid_function(pwcm);
if (pwcm->header_valid) {
#ifdef _DEBUG
multilog (pwcm->log, LOG_INFO,"dada_pwc_main_multi_transfer_data: marking header filled\n");
#endif
for (i=0; i<pwcm->num_hdus; i++)
{
if (ipcbuf_mark_filled (pwcm->hdus[i]->header_block,pwcm->hdus[i]->header_size) < 0) {
multilog (pwcm->log, LOG_ERR, "Could not mark filled header\n");
return DADA_ERROR_HARD;
}
}
}
}
buf_bytes = buffer_size;
if (transit_byte && buf_bytes > bytes_to_write)
buf_bytes = bytes_to_write;
assert(pwcm->num_hdus > 0);
if (pwcm->hdus[0]->data_block) {
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_transfer_data: write to data block"
" buffers=%p bytes=%"PRIu64"\n", buffers, buf_bytes);
#endif
for (i=0; i<pwcm->num_hdus; i++)
{
if ((!utc_start_set) && (ipcio_space_left (pwcm->hdus[i]->data_block) < buf_bytes)) {
multilog (pwcm->log, LOG_ERR, "Data block full and UTC_START not "
"set.\n");
return DADA_ERROR_FATAL;
}
bytes_written = ipcio_write (pwcm->hdus[i]->data_block, buffers[i], buf_bytes);
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_transfer_data: return from write\n");
#endif
if (bytes_written < 0 || bytes_written < buf_bytes) {
multilog (pwcm->log, LOG_ERR, "Cannot write %"PRIu64
" bytes to Data Block\n", buf_bytes);
return DADA_ERROR_FATAL;
}
}
}
total_bytes_written += buf_bytes;
if (bytes_to_write)
bytes_to_write -= buf_bytes;
if (pwcm->verbose)
multilog (pwcm->log, LOG_INFO, "Written %"PRIu64" bytes\n",
total_bytes_written);
}
if (pwcm->verbose)
multilog (pwcm->log, LOG_INFO, "transit=%"PRIu64" total=%"PRIu64"\n",
transit_byte, total_bytes_written);
if (transit_byte == total_bytes_written) {
#ifdef _DEBUG
fprintf (stderr, "dada_pwc_main_multi_transfer_data: transit state\n");
#endif
transit_byte = 0;
if (pwcm->command.code == dada_pwc_record_stop) {
multilog (pwcm->log, LOG_INFO, "record stop\n");
for (i=0; i<pwcm->num_hdus; i++)
{
if (pwcm->hdus[i]->data_block && ipcio_stop (pwcm->hdus[i]->data_block) < 0){
multilog (pwcm->log, LOG_ERR, "Could not stop data block\n");
return DADA_ERROR_FATAL;
}
}
dada_pwc_set_state (pwcm->pwc, dada_pwc_clocking, 0);
}
else if (pwcm->command.code == dada_pwc_record_start) {
multilog (pwcm->log, LOG_INFO, "record start\n");
if (dada_pwc_main_multi_record_start (pwcm) < 0)
return DADA_ERROR_HARD;
dada_pwc_set_state (pwcm->pwc, dada_pwc_recording, 0);
}
else if (pwcm->command.code == dada_pwc_stop) {
#ifdef _DEBUG
multilog (pwcm->log, LOG_INFO, "stopping... entering idle state\n");
#endif
return 0;
}
else if (pwcm->command.code == dada_pwc_set_utc_start) {
if (total_bytes_written) {
multilog (pwcm->log, LOG_ERR, "Error. unexpected set_utc_start\n");
return DADA_ERROR_HARD;
}
} else if (pwcm->command.code == dada_pwc_clock) {
if (total_bytes_written) {
multilog (pwcm->log, LOG_ERR, "Error. unexpected clock command\n");
return DADA_ERROR_HARD;
}
} else if (pwcm->command.code == dada_pwc_start) {
if (total_bytes_written) {
multilog (pwcm->log, LOG_ERR, "Error. unexpected start command\n");
return DADA_ERROR_HARD;
}
} else {
multilog (pwcm->log, LOG_ERR, "Error. unpected command: %d\n",
pwcm->command.code);
return DADA_ERROR_HARD;
}
assert(pwcm->num_hdus > 0);
if (buf_bytes && pwcm->hdus[0]->data_block) {
for (i=0; i<pwcm->num_hdus; i++)
{
if ((!utc_start_set) && (ipcio_space_left(pwcm->hdus[i]->data_block) < buf_bytes)) {
multilog (pwcm->log, LOG_ERR, "Data block full and UTC_START not "
"set.\n");
return DADA_ERROR_FATAL;
}
if (ipcio_write (pwcm->hdus[i]->data_block, buffers[i] + buf_bytes, buffer_size - buf_bytes) < buf_bytes) {
multilog (pwcm->log, LOG_ERR, "Cannot write %"PRIu64
" bytes to Data Block\n", buf_bytes);
return DADA_ERROR_FATAL;
}
}
total_bytes_written += buf_bytes;
}
}
}
return 0;
}
int dada_pwc_main_multi_stop_transfer (dada_pwc_main_multi_t* pwcm)
{
unsigned i;
pwcm->header_valid = 0;
if (pwcm->stop_function (pwcm) < 0) {
multilog (pwcm->log, LOG_ERR, "dada_pwc_main_multi_stop_transfer"
" stop function returned error code\n");
return DADA_ERROR_HARD;
}
for (i=0; i<pwcm->num_hdus; i++)
{
if (pwcm->hdus[i]->data_block && ipcio_close (pwcm->hdus[i]->data_block) < 0) {
multilog (pwcm->log, LOG_ERR, "Could not close Data Block\n");
return DADA_ERROR_FATAL;
}
}
if (pwcm->pwc->state != dada_pwc_soft_error &&
pwcm->pwc->state != dada_pwc_hard_error &&
pwcm->pwc->state != dada_pwc_fatal_error)
dada_pwc_set_state (pwcm->pwc, dada_pwc_idle, 0);
return 0;
}
void dada_pwc_main_multi_process_error (dada_pwc_main_multi_t* pwcm, int rval) {
int new_state = pwcm->pwc->state;
switch (rval)
{
case DADA_ERROR_SOFT:
if ( (pwcm->pwc->state != dada_pwc_hard_error) &&
(pwcm->pwc->state != dada_pwc_fatal_error) )
new_state = dada_pwc_soft_error;
break;
case DADA_ERROR_HARD:
if (pwcm->pwc->state != dada_pwc_fatal_error)
new_state = dada_pwc_hard_error;
break;
case DADA_ERROR_FATAL:
new_state = dada_pwc_fatal_error;
break;
default:
multilog (pwcm->log, LOG_ERR, "Unknown error state: %d\n",rval);
new_state = dada_pwc_fatal_error;
}
multilog(pwcm->log, LOG_WARNING, "PWC entering error state: %s\n",
dada_pwc_state_to_string(new_state));
if (dada_pwc_set_state (pwcm->pwc, new_state, 0) < 0)
multilog(pwcm->log, LOG_ERR, "Failed to change state from %s to %s\n",
dada_pwc_state_to_string(pwcm->pwc->state),
dada_pwc_state_to_string(new_state));
}