Beispiel #1
0
/*******************************************************************************
 * 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;
}
Beispiel #4
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);
}