Exemplo n.º 1
0
int main(int argc, char *argv[]) {
	int port;
	char *name = NULL;
	
    /* verify that all datatypes have the expected syze in bytes */
    check_datatypes();

	if (argc>1) {
		port = atoi(argv[1]);
		if (port == 0) {
			name = argv[1];
		}	
	} else {
		port = 1972;
	}
	
	/* with enabled debug output */
	S = ft_start_buffer_server(port, name, my_request_handler, NULL);
	/* plain server without extra output */
	/*
	S = ft_start_buffer_server(port, name, NULL, NULL);
	*/
	if (S==NULL) return 1;
	signal(SIGINT, abortHandler);
	while (keepRunning) {
		usleep(1000000);
	}
	printf("Ctrl-C pressed -- stopping buffer server...\n");
	ft_stop_buffer_server(S);
	printf("Done.\n");
	return 0;
}
Exemplo n.º 2
0
int main(int argc, char *argv[]) {
    int n, i, c, count = 0, sample = 0, chan = 0, status = 0, verbose = 0, labelSize;
    unsigned char buf[OPENBCI_BUFLEN], byte;
    char *labelString;
    SerialPort SP;
    host_t host;
    struct timespec tic, toc;

    /* these represent the general acquisition system properties */
    int nchans         = OPENBCI_NCHANS;
    float fsample      = OPENBCI_FSAMPLE;

    /* these are used in the communication with the FT buffer and represent statefull information */
    int ftSocket           = -1;
    ft_buffer_server_t *ftServer;
    message_t     *request  = NULL;
    message_t     *response = NULL;
    header_t      *header   = NULL;
    data_t        *data     = NULL;
    ft_chunkdef_t *label    = NULL;

    /* this contains the configuration details */
    configuration config;

    /* configure the default settings */
    config.blocksize     = 10;
    config.port          = 1972;
    config.hostname      = strdup("-");
    config.serial        = strdup("/dev/tty.usbserial-DN0094FY");
    config.reset         = strdup("on");
    config.datalog       = strdup("off");
    config.testsignal    = strdup("off");
    config.timestamp     = strdup("on");
    config.timeref       = strdup("start");

    config.enable_chan1  = strdup("on");
    config.enable_chan2  = strdup("on");
    config.enable_chan3  = strdup("on");
    config.enable_chan4  = strdup("on");
    config.enable_chan5  = strdup("on");
    config.enable_chan6  = strdup("on");
    config.enable_chan7  = strdup("on");
    config.enable_chan8  = strdup("on");
    config.enable_chan9  = strdup("on");
    config.enable_chan10 = strdup("on");
    config.enable_chan11 = strdup("on");

    config.label_chan1  = strdup("ADC1");
    config.label_chan2  = strdup("ADC2");
    config.label_chan3  = strdup("ADC3");
    config.label_chan4  = strdup("ADC4");
    config.label_chan5  = strdup("ADC5");
    config.label_chan6  = strdup("ADC6");
    config.label_chan7  = strdup("ADC7");
    config.label_chan8  = strdup("ADC8");
    config.label_chan9  = strdup("AccelerationX");
    config.label_chan10 = strdup("AccelerationY");
    config.label_chan11 = strdup("AccelerationZ");
    config.label_chan12 = strdup("TimeStamp");

    config.setting_chan1  = strdup("x1060110X");
    config.setting_chan2  = strdup("x2060110X");
    config.setting_chan3  = strdup("x3060110X");
    config.setting_chan4  = strdup("x4060110X");
    config.setting_chan5  = strdup("x5060110X");
    config.setting_chan6  = strdup("x6060110X");
    config.setting_chan7  = strdup("x7060110X");
    config.setting_chan8  = strdup("x8060110X");

    config.impedance_chan1  = strdup("z100Z");
    config.impedance_chan2  = strdup("z200Z");
    config.impedance_chan3  = strdup("z300Z");
    config.impedance_chan4  = strdup("z400Z");
    config.impedance_chan5  = strdup("z500Z");
    config.impedance_chan6  = strdup("z600Z");
    config.impedance_chan7  = strdup("z700Z");
    config.impedance_chan8  = strdup("z800Z");

    if (argc<2) {
        printf(usage);
        exit(0);
    }

    if (argc==2) {
        if (strncmp(argv[1], "/dev", 4)==0 || strncasecmp(argv[1], "COM", 3)==0)
            /* the second argument is the serial port */
            config.serial = strdup(argv[1]);
        else {
            /* the second argument is the configuration file */
            fprintf(stderr, "openbci2ft: loading configuration from '%s'\n", argv[1]);
            if (ini_parse(argv[1], iniHandler, &config) < 0) {
                fprintf(stderr, "Can't load '%s'\n", argv[1]);
                return 1;
            }
        }
    }

    if (argc>2)
        strcpy(host.name, argv[2]);
    else {
        strcpy(host.name, config.hostname);
    }

    if (argc>3)
        host.port = atoi(argv[3]);
    else {
        host.port = config.port;
    }

#define ISTRUE(s) strcasecmp(s, "on")==0
    nchans = 0;
    if (ISTRUE(config.enable_chan1))
        nchans++;
    if (ISTRUE(config.enable_chan2))
        nchans++;
    if (ISTRUE(config.enable_chan3))
        nchans++;
    if (ISTRUE(config.enable_chan4))
        nchans++;
    if (ISTRUE(config.enable_chan5))
        nchans++;
    if (ISTRUE(config.enable_chan6))
        nchans++;
    if (ISTRUE(config.enable_chan7))
        nchans++;
    if (ISTRUE(config.enable_chan8))
        nchans++;
    if (ISTRUE(config.enable_chan9))
        nchans++;
    if (ISTRUE(config.enable_chan10))
        nchans++;
    if (ISTRUE(config.enable_chan11))
        nchans++;
    if (ISTRUE(config.timestamp))
        nchans++;

    fprintf(stderr, "openbci2ft: serial       =  %s\n", config.serial);
    fprintf(stderr, "openbci2ft: hostname     =  %s\n", host.name);
    fprintf(stderr, "openbci2ft: port         =  %d\n", host.port);
    fprintf(stderr, "openbci2ft: blocksize    =  %d\n", config.blocksize);
    fprintf(stderr, "openbci2ft: reset        =  %s\n", config.reset);
    fprintf(stderr, "openbci2ft: datalog      =  %s\n", config.datalog);
    fprintf(stderr, "openbci2ft: timestamp    =  %s\n", config.timestamp);
    fprintf(stderr, "openbci2ft: testsignal   =  %s\n", config.testsignal);

    /* Spawn tcpserver or connect to remote buffer */
    if (strcmp(host.name, "-") == 0) {
        ftServer = ft_start_buffer_server(host.port, NULL, NULL, NULL);
        if (ftServer==NULL) {
            fprintf(stderr, "openbci2ft: could not start up a local buffer serving at port %i\n", host.port);
            return 1;
        }
        ftSocket = 0;
        printf("openbci2ft: streaming to local buffer on port %i\n", host.port);
    }
    else {
        ftSocket = open_connection(host.name, host.port);

        if (ftSocket < 0) {
            fprintf(stderr, "openbci2ft: could not connect to remote buffer at %s:%i\n", host.name, host.port);
            return 1;
        }
        printf("openbci2ft: streaming to remote buffer at %s:%i\n", host.name, host.port);
    }

    /* allocate the elements that will be used in the communication to the FT buffer */
    request      = malloc(sizeof(message_t));
    request->def = malloc(sizeof(messagedef_t));
    request->buf = NULL;
    request->def->version = VERSION;
    request->def->bufsize = 0;

    header      = malloc(sizeof(header_t));
    header->def = malloc(sizeof(headerdef_t));
    header->buf = NULL;

    data      = malloc(sizeof(data_t));
    data->def = malloc(sizeof(datadef_t));
    data->buf = NULL;

    /* define the header */
    header->def->nchans    = nchans;
    header->def->fsample   = fsample;
    header->def->nsamples  = 0;
    header->def->nevents   = 0;
    header->def->data_type = DATATYPE_FLOAT32;
    header->def->bufsize   = 0;

    /* FIXME add the channel names */
    labelSize = 0; /* count the number of bytes required */
    if (ISTRUE (config.enable_chan1))
        labelSize += strlen (config.label_chan1) + 1;
    if (ISTRUE (config.enable_chan2))
        labelSize += strlen (config.label_chan2) + 1;
    if (ISTRUE (config.enable_chan3))
        labelSize += strlen (config.label_chan3) + 1;
    if (ISTRUE (config.enable_chan4))
        labelSize += strlen (config.label_chan4) + 1;
    if (ISTRUE (config.enable_chan5))
        labelSize += strlen (config.label_chan5) + 1;
    if (ISTRUE (config.enable_chan6))
        labelSize += strlen (config.label_chan6) + 1;
    if (ISTRUE (config.enable_chan7))
        labelSize += strlen (config.label_chan7) + 1;
    if (ISTRUE (config.enable_chan8))
        labelSize += strlen (config.label_chan8) + 1;
    if (ISTRUE (config.enable_chan9))
        labelSize += strlen (config.label_chan9) + 1;
    if (ISTRUE (config.enable_chan10))
        labelSize += strlen (config.label_chan10) + 1;
    if (ISTRUE (config.enable_chan11))
        labelSize += strlen (config.label_chan11) + 1;
    if (ISTRUE (config.timestamp))
        labelSize += strlen (config.label_chan12) + 1;

    if (verbose > 0)
        fprintf (stderr, "openbci2ft: labelSize = %d\n", labelSize);

    /* go over all channels for a 2nd time, now copying the strings to the destination */
    labelString = (char *) malloc (labelSize * sizeof(char));
    labelSize   = 0; 
    if (ISTRUE (config.enable_chan1)) {
        strcpy (labelString+labelSize, config.label_chan1);
        labelSize += strlen (config.label_chan1) + 1;
    }
    if (ISTRUE (config.enable_chan2)) {
        strcpy (labelString+labelSize, config.label_chan2);
        labelSize += strlen (config.label_chan2) + 1;
    }
    if (ISTRUE (config.enable_chan3)) {
        strcpy (labelString+labelSize, config.label_chan3);
        labelSize += strlen (config.label_chan3) + 1;
    }
    if (ISTRUE (config.enable_chan4)) {
        strcpy (labelString+labelSize, config.label_chan4);
        labelSize += strlen (config.label_chan4) + 1;
    }
    if (ISTRUE (config.enable_chan5)) {
        strcpy (labelString+labelSize, config.label_chan5);
        labelSize += strlen (config.label_chan5) + 1;
    }
    if (ISTRUE (config.enable_chan6)) {
        strcpy (labelString+labelSize, config.label_chan6);
        labelSize += strlen (config.label_chan6) + 1;
    }
    if (ISTRUE (config.enable_chan7)) {
        strcpy (labelString+labelSize, config.label_chan7);
        labelSize += strlen (config.label_chan7) + 1;
    }
    if (ISTRUE (config.enable_chan8)) {
        strcpy (labelString+labelSize, config.label_chan8);
        labelSize += strlen (config.label_chan8) + 1;
    }
    if (ISTRUE (config.enable_chan9)) {
        strcpy (labelString+labelSize, config.label_chan9);
        labelSize += strlen (config.label_chan9) + 1;
    }
    if (ISTRUE (config.enable_chan10)) {
        strcpy (labelString+labelSize, config.label_chan10);
        labelSize += strlen (config.label_chan10) + 1;
    }
    if (ISTRUE (config.enable_chan11)) {
        strcpy (labelString+labelSize, config.label_chan11);
        labelSize += strlen (config.label_chan11) + 1;
    }
    if (ISTRUE (config.timestamp)) {
        strcpy (labelString+labelSize, config.label_chan12);
        labelSize += strlen (config.label_chan12) + 1;
    }

    /* add the channel label chunk to the header */
    label = (ft_chunkdef_t *) malloc (sizeof (ft_chunkdef_t));
    label->type = FT_CHUNK_CHANNEL_NAMES;
    label->size = labelSize;
    header->def->bufsize = append (&header->buf, header->def->bufsize, label, sizeof (ft_chunkdef_t));
    header->def->bufsize = append (&header->buf, header->def->bufsize, labelString, labelSize);
    FREE (label);
    FREE (labelString);

    /* define the constant part of the data and allocate space for the variable part */
    data->def->nchans = nchans;
    data->def->nsamples = config.blocksize;
    data->def->data_type = DATATYPE_FLOAT32;
    data->def->bufsize = WORDSIZE_FLOAT32 * nchans * config.blocksize;
    data->buf = malloc (data->def->bufsize);

    /* initialization phase, send the header */
    request->def->command = PUT_HDR;
    request->def->bufsize = append (&request->buf, request->def->bufsize, header->def, sizeof (headerdef_t));
    request->def->bufsize = append (&request->buf, request->def->bufsize, header->buf, header->def->bufsize);

    /* this is not needed any more */
    cleanup_header (&header);

    status = clientrequest (ftSocket, request, &response);
    if (verbose > 0)
        fprintf (stderr, "openbci2ft: clientrequest returned %d\n", status);
    if (status)
    {
        fprintf (stderr, "openbci2ft: could not send request to buffer\n");
        exit (1);
    }

    if (status || response == NULL || response->def == NULL)
    {
        fprintf (stderr, "openbci2ft: error in %s on line %d\n", __FILE__,
                __LINE__);
        exit (1);
    }

    cleanup_message (&request);

    if (response->def->command != PUT_OK)
    {
        fprintf (stderr, "openbci2ft: error in 'put header' request.\n");
        exit (1);
    }

    cleanup_message (&response);

    /* open the serial port */
    fprintf (stderr, "openbci2ft: opening serial port ...\n");
    if (!serialOpenByName (&SP, config.serial))
    {
        fprintf (stderr, "Could not open serial port %s\n", config.serial);
        return 1;
    }

    if (!serialSetParameters (&SP, 115200, 8, 0, 0, 0))
    {
        fprintf (stderr, "Could not modify serial port parameters\n");
        return 1;
    }

    fprintf (stderr, "openbci2ft: opening serial port ... ok\n");

    /* 8-bit board will always be initialized upon opening serial port, 32-bit board needs explicit initialization */

    fprintf (stderr, "openbci2ft: initializing ...\n");
    fprintf (stderr,
            "openbci2ft: press reset on the OpenBCI board if this takes too long\n");

    if (ISTRUE (config.reset))
        serialWrite (&SP, 1, "v");	/* soft reset, this will return $$$ */
    else
        serialWrite (&SP, 1, "D");	/* query default channel settings, this will also return $$$ */

    /* wait for '$$$' which indicates that the OpenBCI has been initialized */
    c = 0;
    while (c != 3)
    {
        usleep (1000);
        n = serialRead (&SP, 1, &byte);
        if (n == 1)
        {
            if (byte == '$')
                c++;
            else
                c = 0;
        }
    }				/* while waiting for '$$$' */

    if (strcasecmp (config.datalog, "14s") == 0)
        serialWrite (&SP, 1, "a");
    else if (strcasecmp (config.datalog, "5min") == 0)
        serialWrite (&SP, 1, "A");
    else if (strcasecmp (config.datalog, "15min") == 0)
        serialWrite (&SP, 1, "S");
    else if (strcasecmp (config.datalog, "30min") == 0)
        serialWrite (&SP, 1, "F");
    else if (strcasecmp (config.datalog, "1hr") == 0)
        serialWrite (&SP, 1, "G");
    else if (strcasecmp (config.datalog, "2hr") == 0)
        serialWrite (&SP, 1, "H");
    else if (strcasecmp (config.datalog, "4hr") == 0)
        serialWrite (&SP, 1, "J");
    else if (strcasecmp (config.datalog, "12hr") == 0)
        serialWrite (&SP, 1, "K");
    else if (strcasecmp (config.datalog, "24hr") == 0)
        serialWrite (&SP, 1, "L");
    else if (strcasecmp (config.datalog, "off") != 0)
    {
        fprintf (stderr, "Incorrect specification of datalog\n");
        return 1;
    }

    serialWriteSlow (&SP, strlen (config.setting_chan1), config.setting_chan1);
    serialWriteSlow (&SP, strlen (config.setting_chan2), config.setting_chan2);
    serialWriteSlow (&SP, strlen (config.setting_chan3), config.setting_chan3);
    serialWriteSlow (&SP, strlen (config.setting_chan4), config.setting_chan4);
    serialWriteSlow (&SP, strlen (config.setting_chan5), config.setting_chan5);
    serialWriteSlow (&SP, strlen (config.setting_chan6), config.setting_chan6);
    serialWriteSlow (&SP, strlen (config.setting_chan7), config.setting_chan7);
    serialWriteSlow (&SP, strlen (config.setting_chan8), config.setting_chan8);

    if (strcasecmp (config.testsignal, "gnd") == 0)
        serialWrite (&SP, 1, "0");
    else if (strcasecmp (config.testsignal, "dc") == 0)
        serialWrite (&SP, 1, "-");
    else if (strcasecmp (config.testsignal, "1xSlow") == 0)
        serialWrite (&SP, 1, "=");
    else if (strcasecmp (config.testsignal, "1xFast") == 0)
        serialWrite (&SP, 1, "p");
    else if (strcasecmp (config.testsignal, "2xSlow") == 0)
        serialWrite (&SP, 1, "[");
    else if (strcasecmp (config.testsignal, "2xFast") == 0)
        serialWrite (&SP, 1, "]");
    else if (strcasecmp (config.testsignal, "off") != 0)
    {
        fprintf (stderr, "Incorrect specification of testsignal\n");
        return 1;
    }

    fprintf (stderr, "openbci2ft: initializing ... ok\n");

    printf ("Starting to listen - press CTRL-C to quit\n");

    /* register CTRL-C handler */
    signal (SIGINT, abortHandler);

    /* start streaming data */
    serialWrite (&SP, 1, "b");

    /* determine the reference time for the timestamps */
    if (strcasecmp (config.timeref, "start") == 0)
    {
        /* since the start of the acquisition */
        get_monotonic_time (&tic, TIMESTAMP_REF_BOOT);
    }
    else if (strcasecmp (config.timeref, "boot") == 0)
    {
        /* since the start of the day */
        tic.tv_sec = 0;
        tic.tv_nsec = 0;
    }
    else if (strcasecmp (config.timeref, "epoch") == 0)
    {
        /* since the start of the epoch, i.e. 1-1-1970 */
        tic.tv_sec = 0;
        tic.tv_nsec = 0;
    }
    else
    {
        fprintf (stderr,
                "Incorrect specification of timeref, should be 'start', 'day' or 'epoch'\n");
        return 1;
    }

    while (keepRunning)
    {

        sample = 0;
        while (sample < config.blocksize)
        {
            /* wait for the first byte of the following packet */
            buf[0] = 0;
            while (buf[0] != 0xA0)
            {
                if (serialInputPending (&SP))
                    n = serialRead (&SP, 1, buf);
                else
                    usleep (1000);
            }			/* while */

            /*
             * Header
             *   Byte 1: 0xA0
             *   Byte 2: Sample Number
             *
             * EEG Data
             * Note: values are 24-bit signed, MSB first
             *   Bytes 3-5: Data value for EEG channel 1
             *   Bytes 6-8: Data value for EEG channel 2
             *   Bytes 9-11: Data value for EEG channel 3
             *   Bytes 12-14: Data value for EEG channel 4
             *   Bytes 15-17: Data value for EEG channel 5
             *   Bytes 18-20: Data value for EEG channel 6
             *   Bytes 21-23: Data value for EEG channel 6
             *   Bytes 24-26: Data value for EEG channel 8
             *
             * Accelerometer Data
             * Note: values are 16-bit signed, MSB first
             *   Bytes 27-28: Data value for accelerometer channel X
             *   Bytes 29-30: Data value for accelerometer channel Y
             *   Bytes 31-32: Data value for accelerometer channel Z
             *
             * Footer
             *   Byte 33: 0xC0
             */

            /* read the remaining 32 bytes of the packet */
            while (n < OPENBCI_BUFLEN)
                if (serialInputPending (&SP))
                    n += serialRead (&SP, (OPENBCI_BUFLEN - n), buf + n);
                else
                    usleep (1000);

            if (verbose > 1)
            {
                for (i = 0; i < OPENBCI_BUFLEN; i++)
                    printf ("%02x ", buf[i]);
                printf ("\n");
            }

            chan = 0;
            if (ISTRUE (config.enable_chan1))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[2] << 24 | buf[3] << 16 | buf[4] << 8) /
                    255;
            if (ISTRUE (config.enable_chan2))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[5] << 24 | buf[6] << 16 | buf[7] << 8) /
                    255;
            if (ISTRUE (config.enable_chan3))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[8] << 24 | buf[9] << 16 | buf[10] << 8) /
                    255;
            if (ISTRUE (config.enable_chan4))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[11] << 24 | buf[12] << 16 | buf[13] << 8) /
                    255;
            if (ISTRUE (config.enable_chan5))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[14] << 24 | buf[15] << 16 | buf[16] << 8) /
                    255;
            if (ISTRUE (config.enable_chan6))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[17] << 24 | buf[18] << 16 | buf[19] << 8) /
                    255;
            if (ISTRUE (config.enable_chan7))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[20] << 24 | buf[21] << 16 | buf[22] << 8) /
                    255;
            if (ISTRUE (config.enable_chan8))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB1 * (buf[23] << 24 | buf[24] << 16 | buf[25] << 8) /
                    255;

            if (ISTRUE (config.enable_chan9))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB2 * (buf[26] << 24 | buf[27] << 16) / 32767;
            if (ISTRUE (config.enable_chan10))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB2 * (buf[28] << 24 | buf[29] << 16) / 32767;
            if (ISTRUE (config.enable_chan11))
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    OPENBCI_CALIB2 * (buf[28] << 24 | buf[31] << 16) / 32767;

            if (ISTRUE (config.timestamp))
            {
                if (strcasecmp (config.timeref, "start") == 0)
                    get_monotonic_time (&toc, TIMESTAMP_REF_BOOT);
                else if (strcasecmp (config.timeref, "boot") == 0)
                    get_monotonic_time (&toc, TIMESTAMP_REF_BOOT);
                else if (strcasecmp (config.timeref, "epoch") == 0)
                    get_monotonic_time (&toc, TIMESTAMP_REF_EPOCH);
                ((FLOAT32_T *) (data->buf))[nchans * sample + (chan++)] =
                    get_elapsed_time (&tic, &toc);
            }

            sample++;
        }				/* while c<config.blocksize */

        count += sample;
        printf ("openbci2ft: sample count = %i\n", count);

        /* create the request */
        request = malloc (sizeof (message_t));
        request->def = malloc (sizeof (messagedef_t));
        request->buf = NULL;
        request->def->version = VERSION;
        request->def->bufsize = 0;
        request->def->command = PUT_DAT;

        request->def->bufsize = append (&request->buf, request->def->bufsize, data->def, sizeof (datadef_t));
        request->def->bufsize = append (&request->buf, request->def->bufsize, data->buf, data->def->bufsize);

        status = clientrequest (ftSocket, request, &response);
        if (verbose > 0)
            fprintf (stderr, "openbci2ft: clientrequest returned %d\n", status);
        if (status)
        {
            fprintf (stderr, "openbci2ft: error in %s on line %d\n", __FILE__,
                    __LINE__);
            exit (1);
        }

        if (status)
        {
            fprintf (stderr, "openbci2ft: error in %s on line %d\n", __FILE__,
                    __LINE__);
            exit (1);
        }

        /* FIXME do someting with the response, i.e. check that it is OK */
        cleanup_message (&request);

        if (response == NULL || response->def == NULL
                || response->def->command != PUT_OK)
        {
            fprintf (stderr, "Error when writing samples.\n");
        }
        cleanup_message (&response);

    }				/* while keepRunning */

    /* stop streaming data */
    serialWrite (&SP, 1, "s");

    cleanup_data (&data);

    if (ftSocket > 0)
    {
        close_connection (ftSocket);
    }
    else
    {
        ft_stop_buffer_server (ftServer);
    }

    return 0;
}				/* main */
Exemplo n.º 3
0
int main(int argc, char **argv) {
	host_t ftHost, rdaHost;
	int rdaSocket;
	ft_buffer_server_t *S;
	
	if (sizeof(rda_msg_hdr_t)!=24) {
		fprintf(stderr, "Compiled-in datatypes do not match RDA protocol\n");
		exit(1);
	}

		
	if (argc!=5 && argc!=3) {
		fputs(usage, stderr);
		exit(1);
	}
	
	strncpy(rdaHost.name, argv[1], sizeof(rdaHost.name));
	rdaHost.name[sizeof(rdaHost.name)-1]=0;
	rdaHost.port = atoi(argv[2]);
	
	if (argc==5) {
		strncpy(ftHost.name, argv[3], sizeof(ftHost.name));
		ftHost.name[sizeof(ftHost.name)-1]=0;
		ftHost.port = atoi(argv[4]);
	} else {
		strcpy(ftHost.name, "-");
		ftHost.port = 1972;
	}
	
	/* this isn't a FieldTrip connection, but we can use the same function */
	rdaSocket = open_connection(rdaHost.name, rdaHost.port);
	if (rdaSocket < 0) {
		fprintf(stderr, "Could not connect to RDA server at %s:%i\n", rdaHost.name, rdaHost.port);
		return 1;
	}
				
	/* Spawn tcpserver or connect to remote buffer */
	if (strcmp(ftHost.name, "-") == 0) {
		S = ft_start_buffer_server(ftHost.port, NULL, NULL, NULL);
		if (S==NULL) {
			fprintf(stderr, "Could not start up a FieldTrip buffer serving at port %i\n", ftHost.port);
			return 1;
		}
		ftSocket = 0; 
		printf("Streaming from %s:%i to local buffer on port %i\n", rdaHost.name, rdaHost.port, ftHost.port);
	} else {
		ftSocket = open_connection(ftHost.name, ftHost.port);
		
		if (ftSocket < 0) {
			fprintf(stderr, "Could not connect to FieldTrip buffer at %s:%i\n", ftHost.name, ftHost.port);
			return 1;
		}
		printf("Streaming from %s:%i to remote buffer at %s:%i\n", rdaHost.name, rdaHost.port, ftHost.name, ftHost.port);
	}		
	
	/* register CTRL-C handler */
	signal(SIGINT, abortHandler);
	
	printf("Starting to listen - press CTRL-C to quit\n");

	while (keepRunning) {
		rda_msg_hdr_t header;
		char *buf;
		int n,s;
		
		n = bufread(rdaSocket, &header, sizeof(header));
		
		if (n!=sizeof(header)) {
			fprintf(stderr, "Error while reading packet header from the RDA server\n");
			break;
		}
		
		if (memcmp(_rda_guid, header.guid, 16)!=0) {
			int i;
			fprintf(stderr, "Incorrect GUID in received packet:\n");
			for (i=0;i<16;i++) {
				fprintf(stderr, "0x%02x   should be 0x%02x\n", header.guid[i], _rda_guid[i]);
			}
			break;
		}
		
		buf = (char *) malloc(header.nSize);
		if (buf == NULL) {
			fprintf(stderr, "Out of memory\n");
			break;
		}
		
		memcpy(buf, &header, sizeof(header));
		s = header.nSize - sizeof(header);
		n = bufread(rdaSocket, buf + sizeof(header), s);
		if (s!=n) {
			fprintf(stderr, "Error while reading packet remainder from the RDA server\n");
			free(buf);
			break;
		}
		
		switch(header.nType) {
			case RDA_START_MSG:
				handleStartPacket(ftSocket, header.nSize, buf);
				break;
			case RDA_INT_MSG:
			case RDA_FLOAT_MSG:			
				handleDataPacket(ftSocket, header.nSize, buf);
				break;
			case RDA_STOP_MSG:
				printf("\nRemote Data Acquisition stopped\n\n");
				break;
			default:
				fprintf(stderr, "Unrecognized packet type (%i), has size %i - exiting\n", header.nType, header.nSize);
				keepRunning = 0;
				break;
		}
		
		free(buf);
	}

	close_connection(rdaSocket);

	if (ftSocket > 0) {
		close_connection(ftSocket);
	} else {
		ft_stop_buffer_server(S);
	}
	
	return 0;
}
Exemplo n.º 4
0
int main(int argc, char *argv[])
{
		int n, i, c, sample = 0, status = 0, verbose = 0;
		unsigned char buf[BUFLEN], byte;
		SerialPort SP;
		host_t host;

		/* these represent the acquisition system properties */
		int nchans         = OPENBCI_NCHANS;
		int blocksize      = BLOCKSIZE;
		float fsample      = OPENBCI_FSAMPLE;

		/* these are used in the communication with the FT buffer and represent statefull information */
		int ftSocket           = -1;
		ft_buffer_server_t *ftServer;
		message_t    *request  = NULL;
		message_t    *response = NULL;
		header_t     *header   = NULL;
		data_t       *data     = NULL;

		if (argc<2) {
				printf(usage);
				exit(0);
		}

		if (argc>2)
				strcpy(host.name, argv[2]);
		else {
				strcpy(host.name, FTHOST);
		}

		if (argc>3)
				host.port = atoi(argv[3]);
		else {
				host.port = FTPORT;
		}

		fprintf(stderr, "openbci2ft: device       =  %s\n", argv[1]);
		fprintf(stderr, "openbci2ft: hostname     =  %s\n", host.name);
		fprintf(stderr, "openbci2ft: port         =  %d\n", host.port);

		/* Spawn tcpserver or connect to remote buffer */
		if (strcmp(host.name, "-") == 0) {
				ftServer = ft_start_buffer_server(host.port, NULL, NULL, NULL);
				if (ftServer==NULL) {
						fprintf(stderr, "openbci2ft: could not start up a local buffer serving at port %i\n", host.port);
						return 1;
				}
				ftSocket = 0;
				printf("openbci2ft: streaming to local buffer on port %i\n", host.port);
		}
		else {
				ftSocket = open_connection(host.name, host.port);

				if (ftSocket < 0) {
						fprintf(stderr, "openbci2ft: could not connect to remote buffer at %s:%i\n", host.name, host.port);
						return 1;
				}
				printf("openbci2ft: streaming to remote buffer at %s:%i\n", host.name, host.port);
		}  

		/* allocate the elements that will be used in the communication to the FT buffer */
		request      = malloc(sizeof(message_t));
		request->def = malloc(sizeof(messagedef_t));
		request->buf = NULL;
		request->def->version = VERSION;
		request->def->bufsize = 0;

		header      = malloc(sizeof(header_t));
		header->def = malloc(sizeof(headerdef_t));
		header->buf = NULL;

		data      = malloc(sizeof(data_t));
		data->def = malloc(sizeof(datadef_t));
		data->buf = NULL;

		/* define the header */
		header->def->nchans    = nchans;
		header->def->fsample   = fsample;
		header->def->nsamples  = 0;
		header->def->nevents   = 0;
		header->def->data_type = DATATYPE_FLOAT32;
		header->def->bufsize   = 0;

		/* define the constant part of the data and allocate space for the variable part */
		data->def->nchans    = nchans;
		data->def->nsamples  = blocksize;
		data->def->data_type = DATATYPE_FLOAT32;
		data->def->bufsize   = WORDSIZE_FLOAT32*nchans*blocksize;
		data->buf            = malloc(data->def->bufsize);

		/* initialization phase, send the header */
		request->def->command = PUT_HDR;
		request->def->bufsize = append(&request->buf, request->def->bufsize, header->def, sizeof(headerdef_t));
		request->def->bufsize = append(&request->buf, request->def->bufsize, header->buf, header->def->bufsize);

		/* this is not needed any more */
		cleanup_header(&header);

		status = clientrequest(ftSocket, request, &response);
		if (verbose>0)
				fprintf(stderr, "openbci2ft: clientrequest returned %d\n", status);
		if (status) {
				fprintf(stderr, "openbci2ft: could not send request to buffer\n");
				exit(1);
		}

		if (status || response==NULL || response->def == NULL) {
				fprintf(stderr, "openbci2ft: error in %s on line %d\n", __FILE__, __LINE__);
				exit(1);
		}

		cleanup_message(&request);

		if (response->def->command != PUT_OK) {
				fprintf(stderr, "openbci2ft: error in 'put header' request.\n");
				exit(1);
		}

		cleanup_message(&response);

		/* open the serial port */
		fprintf(stderr, "openbci2ft: opening serial port ...\n");
		if (!serialOpenByName(&SP, argv[1])) {
				fprintf(stderr, "Could not open serial port %s\n", argv[1]);
				return 1;
		}

		if (!serialSetParameters(&SP, 115200, 8, 0, 0, 0)) {
				fprintf(stderr, "Could not modify serial port parameters\n");
				return 1;
		}

		fprintf(stderr, "openbci2ft: opening serial port ... ok\n");

		/* 8-bit board will always be initialized upon opening serial port, 32-bit board needs explicit initialization */
		fprintf(stderr, "openbci2ft: initializing ...\n");

		serialWrite(&SP, 1, "v");
		fprintf(stderr, "openbci2ft: press reset on the OpenBCI board if this takes too long\n");
		usleep(1000);

		/* wait for '$$$' which indicates that the OpenBCI has been initialized */
		c = 0;
		while (c!=3) {
				n = serialRead(&SP, 1, &byte);
				if (n==1) {
						if (byte=='$')
								c++;
						else
								c = 0;
				}
		} /* while waiting for '$$$' */

		fprintf(stderr, "openbci2ft: initializing ... ok\n");

		printf("Starting to listen - press CTRL-C to quit\n");

		/* register CTRL-C handler */
		signal(SIGINT, abortHandler);

		/* start streaming data */
		serialWrite(&SP, 1, "b");

		while (keepRunning) {

				c = 0;
				while (c<blocksize) {
						/* wait for the first byte of the packet */
						buf[0]=0;
						while (buf[0]!=0xA0) {
								if (serialInputPending(&SP))
										n = serialRead(&SP, 1, buf);
								else
										usleep(1000);
						} /* while */

						/* read the remaining 32 bytes of the packet */
						while (n<BUFLEN)
								if (serialInputPending(&SP))
										n += serialRead(&SP, (BUFLEN-n), buf+n);
								else
										usleep(100000);

						if (verbose>1) {
								for (i=0; i<BUFLEN; i++)
										printf("%02x ", buf[i]);
								printf("\n");
						}

						((FLOAT32_T *)(data->buf))[nchans*c + 0] = OPENBCI_CALIB1 * (buf[ 2]<<24 | buf[ 3]<<16 | buf[ 4]<<8)/255;
						((FLOAT32_T *)(data->buf))[nchans*c + 1] = OPENBCI_CALIB1 * (buf[ 5]<<24 | buf[ 6]<<16 | buf[ 7]<<8)/255;
						((FLOAT32_T *)(data->buf))[nchans*c + 2] = OPENBCI_CALIB1 * (buf[ 8]<<24 | buf[ 9]<<16 | buf[10]<<8)/255;
						((FLOAT32_T *)(data->buf))[nchans*c + 3] = OPENBCI_CALIB1 * (buf[11]<<24 | buf[12]<<16 | buf[13]<<8)/255;
						((FLOAT32_T *)(data->buf))[nchans*c + 4] = OPENBCI_CALIB1 * (buf[14]<<24 | buf[15]<<16 | buf[16]<<8)/255;
						((FLOAT32_T *)(data->buf))[nchans*c + 5] = OPENBCI_CALIB1 * (buf[17]<<24 | buf[18]<<16 | buf[19]<<8)/255;
						((FLOAT32_T *)(data->buf))[nchans*c + 6] = OPENBCI_CALIB1 * (buf[20]<<24 | buf[21]<<16 | buf[22]<<8)/255;
						((FLOAT32_T *)(data->buf))[nchans*c + 7] = OPENBCI_CALIB1 * (buf[23]<<24 | buf[24]<<16 | buf[25]<<8)/255;

						((FLOAT32_T *)(data->buf))[nchans*c + 8] = OPENBCI_CALIB2 * (buf[26]<<24 | buf[27]<<16)/32767;
						((FLOAT32_T *)(data->buf))[nchans*c + 9] = OPENBCI_CALIB2 * (buf[28]<<24 | buf[29]<<16)/32767;
						((FLOAT32_T *)(data->buf))[nchans*c +10] = OPENBCI_CALIB2 * (buf[28]<<24 | buf[31]<<16)/32767;

						c++;
				} /* while c<blocksize */

				sample += blocksize;
				printf("openbci2ft: sample count = %i\n", sample);

				/*
				 * Header
				 *   Byte 1: 0xA0
				 *   Byte 2: Sample Number
				 *
				 * EEG Data
				 * Note: values are 24-bit signed, MSB first
				 *   Bytes 3-5: Data value for EEG channel 1
				 *   Bytes 6-8: Data value for EEG channel 2
				 *   Bytes 9-11: Data value for EEG channel 3
				 *   Bytes 12-14: Data value for EEG channel 4
				 *   Bytes 15-17: Data value for EEG channel 5
				 *   Bytes 18-20: Data value for EEG channel 6
				 *   Bytes 21-23: Data value for EEG channel 6
				 *   Bytes 24-26: Data value for EEG channel 8
				 *
				 * Accelerometer Data
				 * Note: values are 16-bit signed, MSB first
				 *   Bytes 27-28: Data value for accelerometer channel X
				 *   Bytes 29-30: Data value for accelerometer channel Y
				 *   Bytes 31-32: Data value for accelerometer channel Z
				 *
				 * Footer
				 *   Byte 33: 0xC0
				 */

				/* create the request */
				request      = malloc(sizeof(message_t));
				request->def = malloc(sizeof(messagedef_t));
				request->buf = NULL;
				request->def->version = VERSION;
				request->def->bufsize = 0;
				request->def->command = PUT_DAT;
				request->def->bufsize = append(&request->buf, request->def->bufsize, data->def, sizeof(datadef_t));
				request->def->bufsize = append(&request->buf, request->def->bufsize, data->buf, data->def->bufsize);

				status = clientrequest(ftSocket, request, &response);
				if (verbose>0)
						fprintf(stderr, "openbci2ft: clientrequest returned %d\n", status);
				if (status) {
						fprintf(stderr, "openbci2ft: error in %s on line %d\n", __FILE__, __LINE__);
						exit(1);
				}

				if (status) {
						fprintf(stderr, "openbci2ft: error in %s on line %d\n", __FILE__, __LINE__);
						exit(1);
				}

				/* FIXME do someting with the response, i.e. check that it is OK */
				cleanup_message(&request);

				if (response == NULL || response->def == NULL || response->def->command!=PUT_OK) {
						fprintf(stderr, "Error when writing samples.\n");
				}
				cleanup_message(&response);

		} /* while keepRunning */

		/* stop streaming data */
		serialWrite(&SP, 1, "s");

		cleanup_data(&data);

		if (ftSocket > 0) {
				close_connection(ftSocket);
		} else {
				ft_stop_buffer_server(ftServer);
		}
		return 0;
} /* main */
Exemplo n.º 5
0
int main(int argc, char *argv[]) {
	int port;
	char *name = NULL;
	union {
		short word;
		char bytes[2];
	} endianTest;
	
	endianTest.bytes[0] = 1;
	endianTest.bytes[1] = 0;

	if (endianTest.word == 1) {
		strcpy(endianness, "little");
	} else {
		strcpy(endianness, "big");
	}

	/* verify that all datatypes have the expected syze in bytes */
	check_datatypes();
	
	#ifdef WIN32
	timeBeginPeriod(1);
	#endif

	if (argc<2) {
		fprintf(stderr, "Usage: recording <directory> [port/unix socket]\n");
		return 1;
	}

	strncpy(baseDirectory, argv[1], sizeof(baseDirectory));

	if (argc>2) {
		port = atoi(argv[2]);
		if (port == 0) {
			name = argv[2];
		}
	} else {
		port = 1972;
	}
	
	memset(queue, sizeof(queue), 0);

	if (!write_contents()) goto cleanup;

	S = ft_start_buffer_server(port, name, my_request_handler, NULL);
	if (S==NULL) return 1;

	signal(SIGINT, abortHandler);
	while (keepRunning) {
		if (queue[qReadPos].command == 0) {
			usleep(1000);
		} else {
			switch(queue[qReadPos].command) {
				case PUT_HDR:
					if (setCounter>0) ft_storage_close(OS);
					write_header_to_disk();
					if (OS==NULL) {
						fprintf(stderr, "!!!!!!!!!!!!! WARNING !!!!!!!!!!\n");
						fprintf(stderr, "!! will NOT save this dataset !!\n");
						fprintf(stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
					}
					break;
				case PUT_DAT:
					if (OS) write_samples_to_disk(queue[qReadPos].quantity, queue[qReadPos].t);
					break;
				case PUT_EVT:
					if (OS) write_events_to_disk(queue[qReadPos].quantity, queue[qReadPos].t);
					break;
			}
			queue[qReadPos].command = 0;
			if (++qReadPos == QUEUE_SIZE) qReadPos = 0;
		}
	}
	printf("Ctrl-C pressed -- stopping buffer server...\n");
	if (setCounter>0 && OS!=NULL) ft_storage_close(OS);
	ft_stop_buffer_server(S);
	printf("Done.\n");

cleanup:
	#ifdef WIN32
	timeEndPeriod(1);
	#endif

	return 0;
}
Exemplo n.º 6
0
int main(int argc, char *argv[])
{
  struct sockaddr_in si_me, si_other;
  socklen_t slen = sizeof(struct sockaddr_in);
  int udpsocket, n;
  char buf[BUFLEN];

  struct {
    uint16_t version;
    uint16_t nchans;
    uint16_t nbit;
    uint16_t fsample;
    uint16_t sec;
    uint16_t smp;
  } packet_v0;

  struct {
    uint8_t version;
    uint8_t nchans;
    uint16_t diagnostic_word;
    uint16_t mode_word;
    uint16_t fsample;
    uint32_t smp;
  } packet_v3;

  /* this is the common denominator of packet format v0 and v3 */
  struct {
    uint16_t version;
    uint16_t nchans;
    uint16_t nbit;
    uint16_t fsample;
    uint32_t smp;
  } packet;

  int sample = 0, status = 0, verbose = 0;
  host_t host;

  /* these represent the acquisition system properties */
  int nchans         = 16;   /* will be updated later on */
  int fsample        = 1000; /* will be updated later on */
  int nbit           = 16;
  int blocksize      = 43;

  /* these are used in the communication with the FT buffer and represent statefull information */
  int ftSocket           = -1;
  ft_buffer_server_t *ftServer;
  message_t    *request  = NULL;
  message_t    *response = NULL;
  header_t     *header   = NULL;
  data_t       *data     = NULL;

  printf(usage);

  if (argc>1)
    strcpy(host.name, argv[1]);
  else {
    strcpy(host.name, FTHOST);
  }

  if (argc>2)
    host.port = atoi(argv[2]);
  else {
    host.port = FTPORT;
  }

  fprintf(stderr, "jaga2ft: hostname     =  %s\n", host.name);
  fprintf(stderr, "jaga2ft: port         =  %d\n", host.port);

  /* Spawn tcpserver or connect to remote buffer */
  if (strcmp(host.name, "-") == 0) {
    ftServer = ft_start_buffer_server(host.port, NULL, NULL, NULL);
    if (ftServer==NULL) {
      fprintf(stderr, "jaga2ft: could not start up a local buffer serving at port %i\n", host.port);
      return 1;
    }
    ftSocket = 0;
    printf("jaga2ft: streaming to local buffer on port %i\n", host.port);
  }
  else {
    ftSocket = open_connection(host.name, host.port);

    if (ftSocket < 0) {
      fprintf(stderr, "jaga2ft: could not connect to remote buffer at %s:%i\n", host.name, host.port);
      return 1;
    }
    printf("jaga2ft: streaming to remote buffer at %s:%i\n", host.name, host.port);
  }  

  /* open the UDP server */
  if ((udpsocket=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    diep("socket udp");
  int enable = 1;
  if (setsockopt(udpsocket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
    diep("setsockopt");
  memset((char *) &si_me, 0, sizeof(si_me));
  si_me.sin_family      = AF_INET;
  si_me.sin_port        = htons(JAGAPORT);
  si_me.sin_addr.s_addr = htonl(INADDR_ANY);
  if (bind(udpsocket, &si_me, sizeof(si_me))==-1)
    diep("bind udp");

  /* allocate the elements that will be used in the communication to the FT buffer */
  request      = malloc(sizeof(message_t));
  request->def = malloc(sizeof(messagedef_t));
  request->buf = NULL;
  request->def->version = VERSION;
  request->def->bufsize = 0;

  header      = malloc(sizeof(header_t));
  header->def = malloc(sizeof(headerdef_t));
  header->buf = NULL;

  data      = malloc(sizeof(data_t));
  data->def = malloc(sizeof(datadef_t));
  data->buf = NULL;

  /* read the first packet to get some information */
  if ((n=recvfrom(udpsocket, buf, BUFLEN, 0, &si_other, &slen))==-1)
    diep("recvfrom()");
  if (verbose>0)
    printf("jaga2ft: received %d byte packet from %s:%d\n", n, inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));

  /* parse the UDP package */
  if (buf[0]==0) {
    packet_v0.version = *(uint16_t *)(buf+0);
    packet_v0.nchans  = *(uint16_t *)(buf+2);
    packet_v0.nbit    = *(uint16_t *)(buf+4);
    packet_v0.fsample = *(uint16_t *)(buf+6);
    packet_v0.sec     = *(uint16_t *)(buf+8);
    packet_v0.smp     = *(uint16_t *)(buf+10);
    /* the packets are quite similar, the data starts at the same location */
    packet.version = packet_v0.version;
    packet.nchans  = packet_v0.nchans;
    packet.nbit    = packet_v0.nbit;
    packet.fsample = packet_v0.fsample;
    packet.smp     = packet_v0.smp;
  }
  else if (buf[0]==3) {
    packet_v3.version         = *(uint8_t  *)(buf+0);
    packet_v3.nchans          = *(uint8_t  *)(buf+1);
    packet_v3.diagnostic_word = *(uint16_t *)(buf+2);
    packet_v3.mode_word       = *(uint16_t *)(buf+4);
    packet_v3.fsample         = *(uint16_t *)(buf+6);
    packet_v3.smp             = *(uint32_t *)(buf+8);
    /* the packets are quite similar, the data starts at the same location */
    packet.version = packet_v3.version;
    packet.nchans  = packet_v3.nchans;
    packet.nbit    = 16;
    packet.fsample = packet_v3.fsample;
    packet.smp     = packet_v3.smp;
  }
  else {
    fprintf(stderr, "invalid packet version");
    exit(1);
  }

  /* update the defaults */
  nchans  = packet.nchans;
  fsample = packet.fsample;

  /* define the header */
  header->def->nchans    = nchans;
  header->def->nsamples  = 0;
  header->def->nevents   = 0;
  header->def->fsample   = fsample;
  header->def->data_type = DATATYPE_UINT16;
  header->def->bufsize   = 0;

  /* define the constant part of the data and allocate space for the variable part */
  data->def->nchans    = nchans;
  data->def->nsamples  = blocksize;
  data->def->data_type = DATATYPE_UINT16;
  data->def->bufsize   = WORDSIZE_UINT16*nchans*blocksize;

  /* initialization phase, send the header */
  request->def->command = PUT_HDR;
  request->def->bufsize = append(&request->buf, request->def->bufsize, header->def, sizeof(headerdef_t));
  request->def->bufsize = append(&request->buf, request->def->bufsize, header->buf, header->def->bufsize);

  /* this is not needed any more */
  cleanup_header(&header);

  status = clientrequest(ftSocket, request, &response);
  if (verbose>0) fprintf(stderr, "jaga2ft: clientrequest returned %d\n", status);
  if (status) {
    fprintf(stderr, "jaga2ft: could not send request to buffer\n");
    exit(1);
  }

  if (status || response==NULL || response->def == NULL) {
    fprintf(stderr, "jaga2ft: err2\n");
    exit(1);
  }

  cleanup_message(&request);

  if (response->def->command != PUT_OK) {
    fprintf(stderr, "jaga2ft: error in 'put header' request.\n");
    exit(1);
  }

  cleanup_message(&response);

  /* register CTRL-C handler */
  signal(SIGINT, abortHandler);

  printf("Starting to listen - press CTRL-C to quit\n");

  /* add a small pause between writing header + first data block */
  usleep(200000);

  while (keepRunning) 
  {

    if (verbose>1) 
      for (n=0; n<12; n++) 
	printf("buf[%2u] = %hhu\n", n, buf[n]);

    /* parse the UDP package */
    if (buf[0]==0) {
      packet_v0.version = *(uint16_t *)(buf+0);
      packet_v0.nchans  = *(uint16_t *)(buf+2);
      packet_v0.nbit    = *(uint16_t *)(buf+4);
      packet_v0.fsample = *(uint16_t *)(buf+6);
      packet_v0.sec     = *(uint16_t *)(buf+8);
      packet_v0.smp     = *(uint16_t *)(buf+10);
      /* the packets are quite similar, the data starts at the same location */
      packet.version = packet_v0.version;
      packet.nchans  = packet_v0.nchans;
      packet.nbit    = packet_v0.nbit;
      packet.fsample = packet_v0.fsample;
      packet.smp     = packet_v0.smp;
    }
    else if (buf[0]==3) {
      packet_v3.version         = *(uint8_t  *)(buf+0);
      packet_v3.nchans          = *(uint8_t  *)(buf+1);
      packet_v3.diagnostic_word = *(uint16_t *)(buf+2);
      packet_v3.mode_word       = *(uint16_t *)(buf+4);
      packet_v3.fsample         = *(uint16_t *)(buf+6);
      packet_v3.smp             = *(uint32_t *)(buf+8);
      /* the packets are quite similar, the data starts at the same location */
      packet.version = packet_v3.version;
      packet.nchans  = packet_v3.nchans;
      packet.nbit    = 16;
      packet.fsample = packet_v3.fsample;
      packet.smp     = packet_v3.smp;
    }
    else {
      fprintf(stderr, "invalid packet version");
      exit(1);
    }

    /* point to the data */
    data->buf = (buf+12);

    /* do some sanity checks */
    if (packet.nchans!=nchans) {
      fprintf(stderr, "jaga2ft: inconsistent number of channels %hu\n", packet.nchans);
      exit(1);
    }
    if (packet.nbit!=nbit) {
      fprintf(stderr, "jaga2ft: inconsistent number of bits %hu\n", packet.nbit);
      exit(1);
    }
    if (packet.fsample!=fsample) {
      fprintf(stderr, "jaga2ft: inconsistent sampling rate %hu\n", packet.fsample);
      exit(1);
    }

    /* create the request */
    request      = malloc(sizeof(message_t));
    request->def = malloc(sizeof(messagedef_t));
    request->buf = NULL;
    request->def->version = VERSION;
    request->def->bufsize = 0;
    request->def->command = PUT_DAT;
    request->def->bufsize = append(&request->buf, request->def->bufsize, data->def, sizeof(datadef_t));
    request->def->bufsize = append(&request->buf, request->def->bufsize, data->buf, data->def->bufsize);

    status = clientrequest(ftSocket, request, &response);
    if (verbose>0) fprintf(stderr, "jaga2ft: clientrequest returned %d\n", status);
    if (status) {
      fprintf(stderr, "jaga2ft: err3\n");
      exit(1);
    }

    if (status) {
      fprintf(stderr, "jaga2ft: err4\n");
      exit(1);
    }

    sample += blocksize;
    printf("jaga2ft: sample count = %i\n", sample);

    /* FIXME do someting with the response, i.e. check that it is OK */
    cleanup_message(&request);

    if (response == NULL || response->def == NULL || response->def->command!=PUT_OK) {
      fprintf(stderr, "Error when writing samples.\n");
    }
    cleanup_message(&response);

    /* read the next packet */
    if ((n=recvfrom(udpsocket, buf, BUFLEN, 0, &si_other, &slen))==-1)
      diep("recvfrom()");
    if (verbose>0)
      printf("jaga2ft: received %d byte packet from %s:%d\n", n, inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));

  } /* while(1) */

  data->buf = NULL; /* this is not allocated on the heap but pointing to somewhere on the stack */
  cleanup_data(&data);
  close(udpsocket);

  if (ftSocket > 0) {
    close_connection(ftSocket);
  } else {
    ft_stop_buffer_server(ftServer);
  }
  return 0;
}