/******************************************************************************* * this function is called by the client * it takes care that the request is processed by the buffer *******************************************************************************/ int clientrequest(int server, const message_t *request, message_t **response_ptr) { int verbose = 0; if (verbose>0) fprintf(stderr, "clientrequest: server = %d\n", server); if (verbose>0) print_request(request->def); if (server<0) { fprintf(stderr, "clientrequest: invalid value for server (%d)\n", server); return -1; } else if (server==0) { /* use direct memory acces to the buffer */ if (dmarequest(request, response_ptr)!=0) return -2; } else if (server>0) { /* use TCP connection to the buffer */ if (tcprequest(server, request, response_ptr)!=0) return -3; } if (verbose>0) print_response((*response_ptr)->def); /* everything went fine */ return 0; }
int main(int argc, char *argv[]) { struct emokit_device* d; struct emokit_frame c; int i, j, k, sample = 0, si=0, status = 0, verbose = 0; host_t host; /* these represent the acquisition system properties */ int nchans = NCHANS; int fsample = FSAMPLE; int blocksize = BLOCKSIZE; int channamesize = 0; char *labelsbuf = NULL; /* these are used in the communication and represent statefull information */ int server = -1; message_t *request = NULL; message_t *response = NULL; header_t *header = NULL; data_t *data = NULL; emokit_samp_t *databuf = NULL; // for holding the sample info event_t *event = NULL; ft_chunkdef_t chunkdef; // for holding the channel names if (argc>2) { sprintf(host.name, "%s", argv[1]); host.port = atoi(argv[2]); } else { sprintf(host.name, "%s", DEFAULT_HOSTNAME); host.port = DEFAULT_PORT; } if (verbose>0) fprintf(stderr, "emokit2ft: host.name = %s\n", host.name); if (verbose>0) fprintf(stderr, "emokit2ft: host.port = %d\n", host.port); //------------------------------------------------------------------------------- // open the emotive device d = emokit_create(); k = emokit_get_count(d, EMOKIT_VID, EMOKIT_PID); printf("Current epoc devices connected: %d\n", k); for ( i=k; i<k; i--){ status = emokit_open(d, EMOKIT_VID, EMOKIT_PID, i); if(status != 0) { printf("CANNOT CONNECT: %d:%d\n", i,status); } } if ( status != 0 ) { printf("Could not connect to any device\nDo you have permission to read from : /dev/hidrawX\nsee https://github.com/openyou/emokit/issues/89"); return 1; } printf("Connected\n"); status = emokit_open(d, EMOKIT_VID, EMOKIT_PID, 1); if(status != 0) { printf("CANNOT CONNECT: %d\n", status); return 1; } printf("Connected\n"); //------------------------------------------------------------------------------- /* allocate the elements that will be used in the buffer communication */ 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; /* header buf contains the channel names */ //header->buf = labels; data = malloc(sizeof(data_t)); data->def = malloc(sizeof(datadef_t)); data->buf = NULL; event = malloc(sizeof(event_t)); event->def = malloc(sizeof(eventdef_t)); event->buf = NULL; /* define the header */ header->def->nchans = nchans; header->def->nsamples = 0; header->def->nevents = 0; header->def->fsample = fsample; header->def->data_type = DATATYPE_EMOKIT; header->def->bufsize = 0; FREE(header->buf); //------------------------------------------------------------------------------- /* define the stuff for the channel names */ /* compute the size of the channel names set */ channamesize=0; for( i=0; i<nchans; i++){ for ( j=0; labels[i][j]!='\0'; j++); j++; channamesize+=j; } /* allocate the memory for the channel names, and copy them into it */ labelsbuf = malloc(WORDSIZE_CHAR*channamesize); k=0; for( i=0; i<nchans; i++){ for ( j=0; labels[i][j]!='\0'; j++,k++) { labelsbuf[k]=labels[i][j]; } labelsbuf[k]=labels[i][j]; k++; } chunkdef.type = FT_CHUNK_CHANNEL_NAMES; chunkdef.size = k; // add this info to the header buffer header->def->bufsize = append(&header->buf, header->def->bufsize, &chunkdef, sizeof(ft_chunkdef_t)); header->def->bufsize = append(&header->buf, header->def->bufsize, labelsbuf, chunkdef.size); //------------------------------------------------------------------------------- /* 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); server = open_connection(host.name, host.port); status = tcprequest(server, request, &response); if (verbose>0) fprintf(stderr, "emokit2ft: clientrequest returned %d\n", status); if (status) { fprintf(stderr, "emokit2ft: put header error\n"); exit(1); } free(request->def); free(request); FREE(response->buf); if (response->def->command != PUT_OK) { fprintf(stderr, "emokit2ft: error in 'put header' request.\n"); exit(1); } free(response->def); free(response); /* add a small pause between writing header + first data block */ usleep(200000); //------------------------------------------------------------------------------- /* 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_EMOKIT; data->def->bufsize = WORDSIZE_EMOKIT * nchans * blocksize; FREE(data->buf); databuf = malloc(WORDSIZE_EMOKIT*nchans*blocksize); data->buf = databuf; //------------------------------------------------------------------------------- // Loop sending the data in blocks as it becomes available while (1) { //------------------------------------------------------------------------------- for ( si=0; si<blocksize; si++){ // get a block's worth of samples sample++; // wait until new data to get, 4 milliSec N.B. inter-sample ~= 8 milliSec while( emokit_read_data(d)<=0 ) { usleep(4000); } /* get the new data */ c = emokit_get_next_frame(d); if ( verbose>0 ) { printf("%5d) %5d\t%5d\t%5d\t%5d\t%5d\t%5d\n", sample, c.counter, c.gyroX, c.gyroY, c.F3, c.FC6, c.P7); fflush(stdout); } // copy the samples into the data buffer, in the order we // *said* they should be databuf[(si*nchans)+0] =c.counter; databuf[(si*nchans)+1] =c.AF3 - eeg_zero_offset; databuf[(si*nchans)+2] =c.F7 - eeg_zero_offset; databuf[(si*nchans)+3] =c.F3 - eeg_zero_offset; databuf[(si*nchans)+4] =c.FC5 - eeg_zero_offset; databuf[(si*nchans)+5] =c.T7 - eeg_zero_offset; databuf[(si*nchans)+6] =c.P7 - eeg_zero_offset; databuf[(si*nchans)+7] =c.O1 - eeg_zero_offset; databuf[(si*nchans)+8] =c.O2 - eeg_zero_offset; databuf[(si*nchans)+9] =c.P8 - eeg_zero_offset; databuf[(si*nchans)+10]=c.T8 - eeg_zero_offset; databuf[(si*nchans)+11]=c.FC6 - eeg_zero_offset; databuf[(si*nchans)+12]=c.F4 - eeg_zero_offset; databuf[(si*nchans)+13]=c.F8 - eeg_zero_offset; databuf[(si*nchans)+14]=c.AF4 - eeg_zero_offset; databuf[(si*nchans)+15]=c.gyroX; databuf[(si*nchans)+16]=c.gyroY; } //------------------------------------------------------------------------------- /* create the request */ /* TODO: re-use the request structures rather than re-allocating every time */ request = malloc(sizeof(message_t)); request->def = malloc(sizeof(messagedef_t)); request->buf = NULL; request->def->version = VERSION; request->def->command = PUT_DAT; request->def->bufsize = 0; 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 = tcprequest(server, request, &response); if (verbose>0) fprintf(stderr, "emokit2ft: clientrequest returned %d\n", status); if (status) { fprintf(stderr, "emokit2ft: err3\n"); exit(1); } cleanup_message((void**)&request); if (response == NULL || response->def == NULL || response->def->command!=PUT_OK) { fprintf(stderr, "Error when writing samples.\n"); } cleanup_message((void**)&response); } /* while(1) */ // free all the stuff we've allocated free(labelsbuf); free(databuf); cleanup_message((void**)&header); cleanup_message((void**)&event); cleanup_message((void**)&data); }
int main(int argc, char **argv) { SerialPort SP; int ftBuffer = -1; eventdef_t *evdef; UINT32_T sizetype, sizevalue, bufsize; char *valBuf; messagedef_t reqdef; message_t request, *response; char *confname; if (argc < 2) { confname = "serial_event.conf"; } else { confname = argv[1]; } if (parseConfig(&conf, confname) != 0) { printf("Errors during parsing the configuration file\n"); exit(1); } sizetype = wordsize_from_type(conf.type_type) * conf.type_numel; sizevalue = wordsize_from_type(conf.value_type) * conf.value_numel; bufsize = sizeof(eventdef_t) + sizetype + sizevalue; evdef = (eventdef_t *) malloc(bufsize); if (evdef == NULL) { printf("Out of memory\n"); exit(1); } /* prepare fixed fields */ reqdef.version = VERSION; reqdef.bufsize = bufsize; reqdef.command = PUT_EVT; request.def = &reqdef; request.buf = evdef; evdef->offset = conf.offset; evdef->duration = conf.duration; evdef->type_type = conf.type_type; evdef->type_numel = conf.type_numel; evdef->value_type = conf.value_type; evdef->value_numel = conf.value_numel; evdef->bufsize = sizetype + sizevalue; valBuf = (char *) evdef + sizeof(eventdef_t); memcpy(valBuf, conf.type_buf, sizetype); valBuf += sizetype; memcpy(valBuf, conf.value_buf, sizevalue); if (!serialOpenByName(&SP, conf.comport)) { printf("Could not open serial port.\n"); exit(1); } /* timeout = 1 decisecond (least common denominator) = 100 ms */ if (!serialSetParameters(&SP, conf.baudrate, conf.databits, conf.parity, conf.stopbits, 1)) { printf("Could not modify serial port parameters\n"); exit(1); } ftBuffer = open_connection(conf.hostname, conf.port); if (ftBuffer < 0) { printf("Connection to FieldTrip buffer failed.\n"); exit(1); } sample = conf.sample_start; udp_socket = create_udp_receiver(conf.udp_port); if (udp_socket != -1) { if (pthread_create(&udpThread, NULL, _udp_thread, NULL)) { printf("Warning: UDP socket thread could not be spawned.\n"); closesocket(udp_socket); udp_socket = -1; } } /* register CTRL-C handler */ signal(SIGINT, abortHandler); printf("Starting to listen - press CTRL-C to quit\n"); while (keepRunning) { char input; int n; n = serialRead(&SP, 1, &input); if (n<0) { printf("Error while reading from serial port - exiting\n"); break; } if (n==0) continue; /* timeout - just wait longer */ /* we got one */ if (conf.character != -1 && conf.character != input) { printf("Ignoring input %c\n", input); continue; } if (conf.set_value) *valBuf = input; pthread_mutex_lock(&sampleMutex); evdef->sample = sample; pthread_mutex_unlock(&sampleMutex); if (evdef->sample < 0) { printf("Ignoring negative sample (%i) event...\n", evdef->sample); } else { n = tcprequest(ftBuffer, &request, &response); if (n<0 || response == NULL) { printf("Error in FieldTrip connection\n"); } else { if (response->def == NULL || response->def->command != PUT_OK) { printf("FieldTrip server returned an error\n"); } else { printf("Sent off event (sample = %i, input = %c)\n", evdef->sample, input); } FREE(response->def); FREE(response->buf); free(response); } } pthread_mutex_lock(&sampleMutex); sample += conf.sample_increase; pthread_mutex_unlock(&sampleMutex); } if (udp_socket!=-1) { pthread_join(udpThread, NULL); closesocket(udp_socket); } close_connection(ftBuffer); serialClose(&SP); free(evdef); return 0; }
int main(int argc, char *argv[]) { struct emokit_device* d; struct emokit_frame c; int32_t i, j, k, nsamp = 0, nblk=0, si=0, status = 0, verbose = 1; int32_t putdatrequestsize=0; long int elapsedusec=0, printtime=0; struct timeval starttime, curtime; host_t buffhost; /* these represent the acquisition system properties */ int nchans = NCHANS; int fsample = FSAMPLE; int blocksize = roundf(fsample/((float)BUFFRATE)); int channamesize = 0; char *labelsbuf = NULL; /* these are used in the communication and represent statefull information */ int serverfd = -1; message_t request; char *requestbuf = NULL; data_t data; emokit_samp_t *samples=NULL; message_t *response = NULL; messagedef_t responsedef; header_t header; ft_chunkdef_t chunkdef; // for holding the channel names if ( argc==1 ) usage(); if ( argc>1 && (strcmp(argv[1],"-help")==0 || strcmp(argv[1],"-h")==0) ) { usage(); sig_handler(0); } if (argc>1) { char *fname=argv[1]; int ci=0; /* find the which splits the host and port info */ for (ci=0; fname[ci]!=0; ci++) { if ( fname[ci]==':' ) { /* parse the port info */ buffhost.port=atoi(&(fname[ci+1])); break; } } memcpy(buffhost.name,fname,ci); buffhost.name[ci]=0; /* copy hostname out and null-terminate */ } else { sprintf(buffhost.name, "%s", DEFAULT_HOSTNAME); buffhost.port = DEFAULT_PORT; } if (verbose>0) fprintf(stderr, "emokit2ft: buffer = %s:%d\n", buffhost.name,buffhost.port); if ( argc>2 ) { BUFFRATE = atoi(argv[2]); blocksize = (int)(roundf(fsample/((float)BUFFRATE))); } if (verbose>0) fprintf(stderr, "emokit2ft: BUFFRATE = %d\n", BUFFRATE); if (verbose>0) fprintf(stderr, "emokit2ft: blocksize = %d\n", blocksize); //------------------------------------------------------------------------------- // open the emotive device d = emokit_create(); k = emokit_get_count(d, EMOKIT_VID, EMOKIT_PID); printf("Current epoc devices connected: %d\n", k); status=-1; if ( k>0 ) { for ( i=k-1; i>=0 & i<k; i--) { status = emokit_open(d, EMOKIT_VID, EMOKIT_PID, i); if(status == 0 ) { printf("Connected : %d:%d\n",i,status); break; } else { printf("CANNOT CONNECT: %d:%d\n", i,status); } } } if ( status != 0 ) { printf("Could not connect to any device\nDo you have permission to read from : /dev/hidrawX\nsee https://github.com/openyou/emokit/issues/89\n"); return 1; } //------------------------------------------------------------------------------- /* allocate the elements that will be used in the buffer communication */ request.def = malloc(sizeof(messagedef_t)); request.buf = NULL; request.def->version = VERSION; request.def->bufsize = 0; header.def = malloc(sizeof(headerdef_t)); header.buf = NULL; /* header buf contains the channel names */ //header.buf = labels; /* define the header */ header.def->nchans = nchans; header.def->nsamples = 0; header.def->nevents = 0; header.def->fsample = fsample; header.def->data_type = DATATYPE_EMOKIT; header.def->bufsize = 0; //------------------------------------------------------------------------------- /* define the stuff for the channel names */ /* compute the size of the channel names set */ channamesize=0; for( i=0; i<nchans; i++) { for ( j=0; labels[i][j]!='\0'; j++); j++; channamesize+=j; } /* allocate the memory for the channel names, and copy them into it */ labelsbuf = malloc(WORDSIZE_CHAR*channamesize); k=0; for( i=0; i<nchans; i++) { for ( j=0; labels[i][j]!='\0'; j++,k++) { labelsbuf[k]=labels[i][j]; } labelsbuf[k]=labels[i][j]; k++; } chunkdef.type = FT_CHUNK_CHANNEL_NAMES; chunkdef.size = k; // add this info to the header buffer header.def->bufsize = append(&header.buf, header.def->bufsize, &chunkdef, sizeof(ft_chunkdef_t)); header.def->bufsize = append(&header.buf, header.def->bufsize, labelsbuf, chunkdef.size); //------------------------------------------------------------------------------- /* 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); fprintf(stderr,"emokit2ft: Attempting to open connection to buffer...."); while ( (serverfd = open_connection(buffhost.name,buffhost.port)) < 0 ) { fprintf(stderr, "emokit2ft; failed to create socket. waiting\n"); usleep(1000000);/* sleep for 1second and retry */ } fprintf(stderr,"done.\nSending header..."); status = tcprequest(serverfd, &request, &response); if (status) { fprintf(stderr, "emokit2ft: put header error = %d\n",status); sig_handler(-1); } fprintf(stderr, "done\n"); free(request.buf); free(request.def); if (response->def->command != PUT_OK) { fprintf(stderr, "emokit2ft: error in 'put header' request.\n"); sig_handler(-1); } FREE(response->buf); free(response->def); free(response); /* add a small pause between writing header + first data block */ usleep(200000); //------------------------------------------------------------------------------- /* allocate space for the putdata request as 1 block, this contains [ request_def data_def data ] */ putdatrequestsize = sizeof(messagedef_t) + sizeof(datadef_t) + WORDSIZE_EMOKIT*nchans*blocksize; requestbuf = malloc(putdatrequestsize); /* define the constant part of the send-data request and allocate space for the variable part */ request.def = requestbuf ; request.buf = request.def + 1; /* N.B. cool pointer arithemetic trick for above! */ request.def->version = VERSION; request.def->command = PUT_DAT; request.def->bufsize = putdatrequestsize - sizeof(messagedef_t); /* setup the data part of the message */ data.def = request.buf; data.buf = data.def + 1; /* N.B. cool pointer arithemetic trick for above */ samples = data.buf; /* version with correct type */ /* define the constant part of the data */ data.def->nchans = nchans; data.def->nsamples = blocksize; data.def->data_type = DATATYPE_EMOKIT; data.def->bufsize = WORDSIZE_EMOKIT * nchans * blocksize; //------------------------------------------------------------------------------- // Loop sending the data in blocks as it becomes available gettimeofday(&starttime,NULL); /* get time we started to compute delay before next sample */ while (1) { //------------------------------------------------------------------------------- for ( si=0; si<blocksize; si++) { // get a block's worth of samples // wait until new data to get, 4 milliSec N.B. inter-sample ~= 8 milliSec while( emokit_read_data(d)<=0 ) { usleep(2000); } /* get the new data */ c = emokit_get_next_frame(d); if ( verbose>1 ) { printf("%5d) %5d\t%5d\t%5d\t%5d\t%5d\t%5d\n", nsamp, c.counter, c.gyroX, c.gyroY, c.F3, c.FC6, c.P7); fflush(stdout); } // copy the samples into the data buffer, in the order we // *said* they should be samples[(si*nchans)+0] =c.counter; samples[(si*nchans)+1] =(c.AF3 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+2] =(c.F7 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+3] =(c.F3 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+4] =(c.FC5 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+5] =(c.T7 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+6] =(c.P7 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+7] =(c.O1 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+8] =(c.O2 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+9] =(c.P8 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+10]=(c.T8 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+11]=(c.FC6 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+12]=(c.F4 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+13]=(c.F8 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+14]=(c.AF4 - eeg_zero_offset)*eeg_scale; samples[(si*nchans)+15]=c.gyroX; samples[(si*nchans)+16]=c.gyroY; nsamp+=1;/*nsamp; */ } //------------------------------------------------------------------------------- /* send the data to the buffer */ /* 0. If send data already read response to previous put-data */ if ( nblk > 0 ) { if ( readresponse(serverfd,&responsedef) !=0 || responsedef.command != PUT_OK ) { fprintf(stderr,"emokit2ft: Error writing samples.\n"); } } /* 1. Send the new data, but don't wait for a response */ if ((k = bufwrite(serverfd, request.def, putdatrequestsize)) != putdatrequestsize) { fprintf(stderr, "write size = %d, should be %d\n", k, putdatrequestsize); sig_handler(-1); } /* do some logging */ gettimeofday(&curtime,NULL); elapsedusec=(curtime.tv_usec + 1000000 * curtime.tv_sec) - (starttime.tv_usec + 1000000 * starttime.tv_sec); if ( elapsedusec / 1000000 >= printtime ) { fprintf(stderr,"%d %d %d %f (blk,samp,event,sec)\r",nblk,nsamp,0,elapsedusec/1000000.0); printtime+=10; } nblk+=1; } /* while(1) */ // free all the stuff we've allocated free(labelsbuf); free(requestbuf); }