/*
 * include needed system headers
 11/9/2005 modified by david fedele to not create file_temp 
 22/11/2005 modified by david fedele to implement crc control */

#include <stdio.h>       /* include standard i/o library */
#include <stdlib.h>      /* include standard library */
#include <string.h>      /* include string library */
#include <ctype.h>      /* include conversion library */
#include <unistd.h>      /* include unix standard library */
#include <sys/types.h>   /* */
#include <sys/stat.h>    /* */
#include <fcntl.h>       /* */
#include <errno.h>       /* error simbol definitions */
#include <time.h>        /* system time definitions */
#include <math.h>        /* math library */

#define MAXBUFFLEN 0x172c8 //0x12a50
#define HEADERLEN 8
/* find cpu header  */
/* starting path --> 0xFAFEDE  */

/***************************************************** */
/* 22/11/2005 modified by david fedele */
unsigned char crc16(unsigned char old,unsigned char data);
/* ***************************************************** */
void findcpuheader_(int *error, int *fd, int *pkt, unsigned long *pkt_counter,
unsigned long *obtt, char* buffer,int *length)

{
    
    int i;
    
    int nread,nwrite;
    unsigned short cpu_header[HEADERLEN];    
    unsigned short temp;
    
    int header_flag;
    unsigned long int start;
    unsigned char pkt_type;
    unsigned long int counter,counter_last=0;
    unsigned long int obt;
    unsigned long int pkt_len;
    char cpucrc;
   
    char buff[MAXBUFFLEN];

    int fd_out;
    char *ptemp;

/***************************************************** */
/* 22/11/2005 modified by david fedele */
    char icc;
/****************************************************** */

    do{

/*  search for 0xFAFEDE*/
	do {
	    *error=0;
	    nread=read(*fd, cpu_header, 2*HEADERLEN);
//	printf("%d \n",2*HEADERLEN);
	    if(nread == 0) {
//		printf("findcpuheader (1): Unexpected end of file %d at %d \n",*fd,nread);
		*error=1;
		return ;
	    }
	    if(nread != 2*HEADERLEN) {
//		printf("findcpuheader (1): Error on reading: bytes read -> nread = %d instead of %d\n",nread,2*HEADERLEN);
		*error=-1;
		return ;
	    }
	    /*** corrects byte ***/ //endianess...
	    for(i=0;i<HEADERLEN;i++){
		temp = cpu_header[i];
		cpu_header[i] = ( (temp&0x00ff) << 8 ) | ( (temp&0xff00) >> 8 );	     
	    };
	    
	    
	    header_flag = 1;
	    
	    start = (cpu_header[0]<<8)|((cpu_header[1]&0xff00)>>8);
	    if(start != 0xfafede)header_flag = 0;
	    pkt_type = (unsigned char)(cpu_header[1]&0x00ff);
	    if((unsigned char)((cpu_header[2]&0xff00)>>8) != pkt_type)header_flag = 0;
	    counter = ((cpu_header[2]&0x00ff)<<16)
		|cpu_header[3];
	    obt = ((cpu_header[4]&0xffff)<<16) | (cpu_header[5]&0xffff);
	    pkt_len = (cpu_header[6]<<8) | ((cpu_header[7]&0xff00)>>8);	    
	    cpucrc = cpu_header[7]&0x00ff;

//	************************************
	    lseek(*fd, -(2*HEADERLEN-1), SEEK_CUR); 
//      SEEK_CUR ---> from current position
//	************************************	    
	}
	while (!header_flag);    
	
/***************************************************** */
/* 22/11/2005 modified by david fedele */
	icc=0;
	for (i =0; i < 8 ; i++){
	  icc=crc16(icc,cpu_header[i]);
	  /*  temp=(cpu_header[i]&0x00ff); */
	  /* 	      icc = crc8_8(icc, temp); */
	  /* 	      temp=(cpu_header[i]&0xff00); */
	  /* 	      icc = crc8_8(icc, temp); */
	}
	/* if(icc==cpucrc) */
/* 	  printf("cpucrc=%hx\ticc=%hx\n\n",cpucrc,icc); */
/****************************************************** */


	counter_last = counter;
/*  print header content  */
/* 	if(    (pkt_type == 0x20) */
/* 	   ||  (pkt_type == 0x07) */
/* 	   ||  (pkt_type == 0x21) */
/* 	   ||  (pkt_type == 0x12) */
/* 	   ||  (pkt_type == 0x83) */
/* 	   ||  (pkt_type == 0x13)){ */
/* 	    printf("\n********************************\n"); */
/* 	    printf("*     >>>> CPU HEADER <<<<     *\n"); */
/* 	    printf("********************************\n"); */
/* 	    printf(" Packet type         \t 0x%x  \n",pkt_type); */
/* 	    printf(" Counter             \t %u    \n",counter); */
/* 	    printf(" On-board time       \t 0x%x  \n",obt); */
/* 	    printf(" Packet length (byte)\t %d    \n",pkt_len); */
/* 	    printf("********************************\n"); */
/* 	}; */
	
//  **************************************
	lseek(*fd, (2*HEADERLEN-1), SEEK_CUR); 
//  SEEK_CUR ---> from current position
//  **************************************
	
    }while((pkt_type != 0x12)&& 
	   (pkt_type != 0x13)&& 
	   (pkt_type != 0x10)&& 
	   (pkt_type != 0x30)&& 
	   (pkt_type != 0x20)&& // RUNHEADER PACKET
	   (pkt_type != 0x21)&& // RUNHEADER PACKET
	   (pkt_type != 0x83));
    
/* come here when a tracker packet is fownd: */    
/* 0x12 --> calibration board 0              */    
/* 0x13 --> calibration board 1              */
/* 0x10 --> event                            */
/* 0x30 --> full event for calib special     */
/* 0x20 --> runheader packet                 */
/* 0x83 --> tracker ALARM (control register) */

    nread = read(*fd, buff, pkt_len);
    if(nread == 0) {
	printf("findcpuheader: Unexpected end of file %d at %d \n",*fd,nread);
	*error=1;
	return ;
    }
    if(nread != pkt_len) {
	printf("findcpuheader: Error on reading: bytes read -> nread = %i instead of %i \n",(int)nread,(int)pkt_len);
	*error=-1;
	return ;
    }
    //    for(i=0;i<12;i++)printf("- %hhx \n",buff[i]);

/* //**************************************************** */
/* //ccccc 11/9/2005 modified by david fedele */
/*     fd_out = creat("bin-aux/packet.dat",0666); */
/*     nwrite = write(fd_out, buff, nread); */
/*     if(nwrite != nread) { */
/* 	printf("findcpuheader: Error on writing: bytes written -> nwrite = %d \n",nwrite); */
/* //	*error=-1; */
/* 	return ; */
/*        } */
/*     close(fd_out); */
/* ***************************************************** */

    ptemp=buffer;
    for(i =0; i< nread; i++){
	*ptemp=buff[i];
	ptemp++;
    };
    *length = nread;
/***************************************************** */
/* 22/11/2005 modified by david fedele */
/* 	    icc=0; */
/* 	    for (i =0; i < HEADERLEN; i++){ */
/* 	      temp=(buff[i]&0xff00); */
/* 	      icc = crc8_8(icc, temp); */
/* 	      temp=(buff[i]&0x00ff); */
/* 	      icc = crc8_8(icc, temp); */
/* 	    } */
/* 	    if(icc==cpucrc) */
/* 	      printf("cpucrc=%hx\ticc=%hx\n\n",cpucrc,icc);  */
	    
/****************************************************** */
    *pkt = (short int)pkt_type;
    *pkt_counter = counter;
    *obtt = obt;
    return;
}
