/************************************************************/
/*                                                          */
/* File        : userrockmfifo.c                            */
/* Description : tl compiler definitions                    */
/*                                                          */
/* Command     : rockmfifo                                  */
/* Comment     : ROCKM FIFO library tcl interface           */
/*                                                          */
/* Author      : Sfiligoi Igor                              */
/*                                                          */
/* Created       : 30.06.1997                               */
/* Last modified : 01.07.1997                               */
/*                                                          */
/************************************************************/

#include <stdlib.h>
#include <string.h>
#include <Error.h>

#include "userrockmfifo.h"
#include <rockmfifo.h>

/* rockmfifo open data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_open(rockmfifot_t_open *data)
{
 unsigned char cancache;
 int res;

 if (!data->cancache_present)
   data->cancache.nr = ROCKMFIFOT_Ccancache_minimal;

 switch (data->cancache.nr)
   {
   case ROCKMFIFOT_Ccancache_off:
     cancache = ROCKM_FIFO_CACHE_OFF;
     break;
   case ROCKMFIFOT_Ccancache_minimal:
     cancache = ROCKM_FIFO_CACHE_MINIMAL;
     break;
   case ROCKMFIFOT_Ccancache_advanced:
     cancache = ROCKM_FIFO_CACHE_ADVANCED;
     break;
   case ROCKMFIFOT_Ccancache_block:
     cancache = ROCKM_FIFO_CACHE_BLOCK;
     break;
   case ROCKMFIFOT_Ccancache_block_advanced:
     cancache = ROCKM_FIFO_CACHE_BLOCK_ADVANCED;
     break;
   default:
     data->errorstr = (char *) malloc(64);
     sprintf(data->errorstr,"Invalid cancache value: %i.",data->cancache.nr);

     return TL_OK+1;
   }

 res = rockm_fifo_open((ROCKM_id) data->rid,cancache,(ROCKM_FIFO_id *) &data->result);

 if (res!=ROCKM_ERROR_OK)
   {
      char *tmp;

      tmp = ErrorGetMessage();
      data->errorstr = (char *) malloc(strlen(tmp)+1);
      strcpy(data->errorstr,tmp);

      return TL_OK+res;
   }

 return TL_OK;
}

/* rockmfifo close data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_close(rockmfifot_t_close *data)
{
  ROCKM_FIFO_RAW cache;
  int err;
  
  err = rockm_fifo_close((ROCKM_FIFO_id) data->fid,&cache);

  if (err!=ROCKM_ERROR_OK)
    {
      char *tmp;

      tmp = ErrorGetMessage();
      data->errorstr = (char *) malloc(strlen(tmp)+1);
      strcpy(data->errorstr,tmp);

      return TL_OK+err;
    }

  /* return cache data */

  {
    int i;

    for (i=cache.nrels-1; i>=0; i--)
      {
	_STR_natural *listel;

	listel = (_STR_natural *) malloc(sizeof(_STR_natural));
	listel->next = data->result;
	listel->element = cache.els[i];
	data->result = listel;
      }
  }

  free(cache.els);

  return TL_OK;
}

/* rockmfifo isempty data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_isempty(rockmfifot_t_isempty *data)
{
 int err;

 err = rockm_fifo_isnotempty((ROCKM_FIFO_id) data->fid);

 if (err==ROCKM_ERROR_OK)
   {
     data->result = 0;   /* false */
     return TL_OK;
   }
 else if (err==ROCKM_ERROR_FIFO_EMPTY)
   {
     data->result = 1;  /* true */
     return TL_OK;
   }
 else
    { /* error */
      char *tmp;

      tmp = ErrorGetMessage();
      data->errorstr = (char *) malloc(strlen(tmp)+1);
      strcpy(data->errorstr,tmp);

      return TL_OK+err;
    }

}

/* rockmfifo read data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_read(rockmfifot_t_read *data)
{
  int err;
  ROCKM_FIFO_RAW readels;

  if (!data->nrels_present)
    {
      data->nrels = 1;
    }

  err = rockm_fifo_raw_blockread((ROCKM_FIFO_id) data->fid, data->nrels, &readels);

  if ((err!=ROCKM_ERROR_OK)&&(err!=ROCKM_ERROR_FIFO_EMPTY))
    {
      char *tmp;

      tmp = ErrorGetMessage();
      data->errorstr = (char *) malloc(strlen(tmp)+1);
      strcpy(data->errorstr,tmp);

      return TL_OK+err;
    }

  /* return read data */

  {
    int i;

    for (i=readels.nrels-1; i>=0; i--)
      {
	_STR_natural *listel;

	listel = (_STR_natural *) malloc(sizeof(_STR_natural));
	listel->next = data->result;
	listel->element = readels.els[i];
	data->result = listel;
      }
  }

  free(readels.els);

  return TL_OK;
}

/* rockmfifo decode data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_decode(rockmfifot_t_decode *data)
{
  int err;
  ROCKM_FIFO_FRAMEs readels;

  if (!data->nrels_present)
    {
      data->nrels = 1;
    }

  err = rockm_fifo_frame_blockread((ROCKM_FIFO_id) data->fid, data->nrels, &readels);

  switch (err)
    {
    case ROCKM_ERROR_OK:
    case ROCKM_ERROR_FIFO_EMPTY:
    case ROCKM_ERROR_FIFO_FRAME_PARITY:
    case ROCKM_ERROR_FIFO_FRAME_TRIGGER:
    case ROCKM_ERROR_FIFO_FRAME_LAST:
    case ROCKM_ERROR_FIFO_FRAME_COUNTER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"");
      }
      break; /* no message */
    case ROCKM_ERROR_FIFO_FRAME_SUPER_HEADER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"super header error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SUB_HEADER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"sub header error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SUB_FOOTER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"sub footer error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"overflow error");
      }
      break;
    default:
      { /* serious error */
	char *tmp;
	
	tmp = ErrorGetMessage();
	data->errorstr = (char *) malloc(strlen(tmp)+1);
	strcpy(data->errorstr,tmp);
	
	return TL_OK+err;
      }
      break;
    }

  ErrorClear();
  
  /* return read data */

  {
    int i;

    for (i=readels.nrframes-1; i>=0; i--)
      {
	_STR_ROCKMFIFOT_OTsuperframe *listel;
	int j;

	listel = (_STR_ROCKMFIFOT_OTsuperframe *) malloc(sizeof(_STR_ROCKMFIFOT_OTsuperframe));
	listel->next = data->result.elements;
	data->result.elements = listel;

	listel->element.header.ring = readels.frames[i].header.ring;
	listel->element.header.chadd = readels.frames[i].header.chadd;
	listel->element.header.trigger = readels.frames[i].header.trigger;

	listel->element.subfr = NULL;

	for (j=0;j<8;j++)
	  if (readels.frames[i].subfr[j].ispresent)
	    {
	      _STR_ROCKMFIFOT_OTsubframe *subfrel;
	      int k;
	      	      
	      subfrel = (_STR_ROCKMFIFOT_OTsubframe *) malloc(sizeof(_STR_ROCKMFIFOT_OTsubframe));
	      subfrel->next = listel->element.subfr;
	      listel->element.subfr = subfrel;
	      
	      listel->element.subfr->element.cradd = j;
	      
	      listel->element.subfr->element.header.last = readels.frames[i].subfr[j].header.last;
	      listel->element.subfr->element.header.trigger = readels.frames[i].subfr[j].header.trigger;
	      
	      listel->element.subfr->element.slaves = NULL;
	      
	      for (k=0;k<16;k++)
		{
		  int l;
		  
		  for (l=readels.frames[i].subfr[j].slv[k].nrels-1;l>=0;l--)
		    {
		      _STR_ROCKMFIFOT_OTslave *slvel;
		      
		      slvel = (_STR_ROCKMFIFOT_OTslave *) malloc(sizeof(_STR_ROCKMFIFOT_OTslave));
		      slvel->next = listel->element.subfr->element.slaves;
		      listel->element.subfr->element.slaves = slvel;
		      
		      listel->element.subfr->element.slaves->element.slvadd = k;
		      listel->element.subfr->element.slaves->element.channel = readels.frames[i].subfr[j].slv[k].els[l].channel;
		      listel->element.subfr->element.slaves->element.reserved = readels.frames[i].subfr[j].slv[k].els[l].reserved;
		      listel->element.subfr->element.slaves->element.slvdata = readels.frames[i].subfr[j].slv[k].els[l].data;
		    }
		  
		  free(readels.frames[i].subfr[j].slv[k].els);
		}

	      listel->element.subfr->element.footer.softparity = readels.frames[i].subfr[j].footer.softparity;
	      listel->element.subfr->element.footer.hardparity = readels.frames[i].subfr[j].footer.hardparity;
	      
	    }

	listel->element.footer.softparity_fail = readels.frames[i].footer.softparity_fail;
	listel->element.footer.hardparity_fail = readels.frames[i].footer.hardparity_fail;
	listel->element.footer.overflow = readels.frames[i].footer.overflow;
	listel->element.footer.softcounter = readels.frames[i].footer.softcounter;
	listel->element.footer.hardcounter = readels.frames[i].footer.hardcounter;
       }
  }

  free(readels.frames);

  return TL_OK;
}

/* rockmfifo read_frame data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_read_frame(rockmfifot_t_read_frame *data)
{
  int err;
  ROCKM_FIFO_RAW readels;

  err = rockm_fifo_frame_rawread((ROCKM_FIFO_id) data->fid, &readels);

  switch (err)
    {
    case ROCKM_ERROR_OK:
    case ROCKM_ERROR_FIFO_EMPTY:
    case ROCKM_ERROR_FIFO_FRAME_PARITY:
    case ROCKM_ERROR_FIFO_FRAME_TRIGGER:
    case ROCKM_ERROR_FIFO_FRAME_LAST:
    case ROCKM_ERROR_FIFO_FRAME_COUNTER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"");
      }
      break; /* no message */
    case ROCKM_ERROR_FIFO_FRAME_SUPER_HEADER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"super header error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SUB_HEADER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"sub header error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SUB_FOOTER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"sub footer error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"overflow error");
      }
      break;
    default:
      { /* serious error */
	char *tmp;
	
	tmp = ErrorGetMessage();
	data->errorstr = (char *) malloc(strlen(tmp)+1);
	strcpy(data->errorstr,tmp);
	
	return TL_OK+err;
      }
      break;
    }

  ErrorClear();
  
  /* return read data */
  {
    int i;

    for (i=readels.nrels-1; i>=0; i--)
      {
	_STR_natural *listel;

	listel = (_STR_natural *) malloc(sizeof(_STR_natural));
	listel->next = data->result.elements;
	listel->element = readels.els[i];
	data->result.elements = listel;
      }
  }

  free(readels.els);


  return TL_OK;
}

/* rockmfifo synch data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_synch(rockmfifot_t_synch *data)
{
  int err;
  ROCKM_FIFO_RAW readels;

  err = rockm_fifo_frame_synch((ROCKM_FIFO_id) data->fid, &readels);

  if ((err!=ROCKM_ERROR_OK)&&(err!=ROCKM_ERROR_FIFO_EMPTY))
    {
      char *tmp;

      tmp = ErrorGetMessage();
      data->errorstr = (char *) malloc(strlen(tmp)+1);
      strcpy(data->errorstr,tmp);

      return TL_OK+err;
    }
  
  /* return read data */

  {
    int i;

    for (i=readels.nrels-1; i>=0; i--)
      {
	_STR_natural *listel;

	listel = (_STR_natural *) malloc(sizeof(_STR_natural));
	listel->next = data->result;
	listel->element = readels.els[i];
	data->result = listel;
      }
  }

  free(readels.els);

  return TL_OK;
}

/* rockmfifo cache set data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_setcancache(rockmfifot_t_setcancache *data)
{
 int err;
 unsigned char realcancache;

 switch(data->cancache.nr)
   {
   case ROCKMFIFOT_Ccancache_off:
     realcancache = ROCKM_FIFO_CACHE_OFF;
     break;
   case ROCKMFIFOT_Ccancache_minimal:
     realcancache = ROCKM_FIFO_CACHE_MINIMAL;
     break;
   case ROCKMFIFOT_Ccancache_advanced:
     realcancache = ROCKM_FIFO_CACHE_ADVANCED;
     break;
   case ROCKMFIFOT_Ccancache_block:
     realcancache = ROCKM_FIFO_CACHE_BLOCK;
     break;
   case ROCKMFIFOT_Ccancache_block_advanced:
     realcancache = ROCKM_FIFO_CACHE_BLOCK_ADVANCED;
     break;
   }

 err = rockm_fifo_set_cancache((ROCKM_FIFO_id) data->fid, realcancache);

 if (err!=ROCKM_ERROR_OK)
   { /* error */
     char *tmp;
     
     tmp = ErrorGetMessage();
     data->errorstr = (char *) malloc(strlen(tmp)+1);
     strcpy(data->errorstr,tmp);

     return TL_OK+err;
   }

 return TL_OK;
}

/* rockmfifo cache flush data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_flush(rockmfifot_t_flush *data)
{
  ROCKM_FIFO_RAW cache;
  int err;
  
  err = rockm_fifo_cache_flush((ROCKM_FIFO_id) data->fid,&cache);

  if (err!=ROCKM_ERROR_OK)
    {
      char *tmp;

      tmp = ErrorGetMessage();
      data->errorstr = (char *) malloc(strlen(tmp)+1);
      strcpy(data->errorstr,tmp);

      return TL_OK+err;
    }

  /* return cache data */

  {
    int i;

    for (i=cache.nrels-1; i>=0; i--)
      {
	_STR_natural *listel;

	listel = (_STR_natural *) malloc(sizeof(_STR_natural));
	listel->next = data->result;
	listel->element = cache.els[i];
	data->result = listel;
      }
  }

  free(cache.els);

  return TL_OK;
}

/* rockmfifo cache refill data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_refill(rockmfifot_t_refill *data)
{
 int err;
 ROCKM_FIFO_RAW newdata;

 newdata.nrels = data->newdata.nrels;
 newdata.els = (unsigned int *) malloc(newdata.nrels*sizeof(unsigned int));

 {
   int i;

   for (i=0; i<newdata.nrels; i++)
       newdata.els[i] = data->newdata.els[i];
 }

 err = rockm_fifo_cache_refill((ROCKM_FIFO_id) data->fid,newdata);

 free(newdata.els);

 if (err!=ROCKM_ERROR_OK)
   {
     char *tmp;
     
     tmp = ErrorGetMessage();
     data->errorstr = (char *) malloc(strlen(tmp)+1);
     strcpy(data->errorstr,tmp);
     
     return TL_OK+err;
   }

 return TL_OK;
}

/* rockmfifo conv raw2frame data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_conv_raw2frame(rockmfifot_t_conv_raw2frame *data)
{
  int err;
  ROCKM_FIFO_RAW rawdata;
  ROCKM_FIFO_FRAME readels;

  rawdata.nrels = data->rawdata.nrels;
  rawdata.els = data->rawdata.els;

  err = rockm_fifo_conv_raw2frame(rawdata, &readels);

  switch (err)
    {
    case ROCKM_ERROR_OK:
    case ROCKM_ERROR_FIFO_EMPTY:
    case ROCKM_ERROR_FIFO_FRAME_PARITY:
    case ROCKM_ERROR_FIFO_FRAME_TRIGGER:
    case ROCKM_ERROR_FIFO_FRAME_LAST:
    case ROCKM_ERROR_FIFO_FRAME_COUNTER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"");
      }
      break; /* no message */
    case ROCKM_ERROR_FIFO_FRAME_SUPER_HEADER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"super header error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SUB_HEADER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"sub header error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_SUB_FOOTER:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"sub footer error");
      }
      break;
    case ROCKM_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(24);
	strcpy(data->result.status,"overflow error");
      }
      break;
    default:
      { /* serious error */
	char *tmp;
	
	tmp = ErrorGetMessage();
	data->errorstr = (char *) malloc(strlen(tmp)+1);
	strcpy(data->errorstr,tmp);
	
	return TL_OK+err;
      }
      break;
    }

  ErrorClear();
  
  /* return read data */

  {
    int j;
    
    data->result.superframe.header.ring = readels.header.ring;
    data->result.superframe.header.chadd = readels.header.chadd;
    data->result.superframe.header.trigger = readels.header.trigger;
    
    data->result.superframe.subfr = NULL;
    
    for (j=0;j<8;j++)
      if (readels.subfr[j].ispresent)
	{
	  _STR_ROCKMFIFOT_OTsubframe *subfrel;
	  int k;
	  
	  subfrel = (_STR_ROCKMFIFOT_OTsubframe *) malloc(sizeof(_STR_ROCKMFIFOT_OTsubframe));
	  subfrel->next = data->result.superframe.subfr;
	  data->result.superframe.subfr = subfrel;
	  
	  data->result.superframe.subfr->element.cradd = j;
	  
	  data->result.superframe.subfr->element.header.last = readels.subfr[j].header.last;
	  data->result.superframe.subfr->element.header.trigger = readels.subfr[j].header.trigger;
	  
	  data->result.superframe.subfr->element.slaves = NULL;
	  
	  for (k=0;k<16;k++)
	    {
	      int l;
	      
	      for (l=readels.subfr[j].slv[k].nrels-1;l>=0;l--)
		{
		  _STR_ROCKMFIFOT_OTslave *slvel;
		  
		  slvel = (_STR_ROCKMFIFOT_OTslave *) malloc(sizeof(_STR_ROCKMFIFOT_OTslave));
		  slvel->next = data->result.superframe.subfr->element.slaves;
		  data->result.superframe.subfr->element.slaves = slvel;
		  
		  data->result.superframe.subfr->element.slaves->element.slvadd = k;
		  data->result.superframe.subfr->element.slaves->element.channel = readels.subfr[j].slv[k].els[l].channel;
		  data->result.superframe.subfr->element.slaves->element.reserved = readels.subfr[j].slv[k].els[l].reserved;
		  data->result.superframe.subfr->element.slaves->element.slvdata = readels.subfr[j].slv[k].els[l].data;
		}
	      
	      free(readels.subfr[j].slv[k].els);
	    }
	  
	  data->result.superframe.subfr->element.footer.softparity = readels.subfr[j].footer.softparity;
	  data->result.superframe.subfr->element.footer.hardparity = readels.subfr[j].footer.hardparity;
	  
	}
    
    data->result.superframe.footer.softparity_fail = readels.footer.softparity_fail;
    data->result.superframe.footer.hardparity_fail = readels.footer.hardparity_fail;
    data->result.superframe.footer.overflow = readels.footer.overflow;
    data->result.superframe.footer.softcounter = readels.footer.softcounter;
    data->result.superframe.footer.hardcounter = readels.footer.hardcounter;
  }

  return TL_OK;
}

/* rockmfifo conv frame2raw data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_conv_frame2raw(rockmfifot_t_conv_frame2raw *data)
{
  ROCKM_FIFO_FRAME aframe;
  ROCKM_FIFO_RAW rawels;


  aframe.header.ring = data->aframe.header.ring;
  aframe.header.chadd = data->aframe.header.chadd;
  aframe.header.trigger = data->aframe.header.trigger;

  {
    int i;

    for (i=0; i<8; i++)
      aframe.subfr[i].ispresent = 0;  /* initialize not present */

    for (i=0; i<data->aframe.subfr.nrels; i++)
      {
	int cradd;

	cradd = data->aframe.subfr.els[i].cradd;

	if (aframe.subfr[cradd].ispresent)
	  { /* Error: duplicate subframe */
	    data->errorstr = (char *) malloc(64);
	    sprintf(data->errorstr,"Duplicate subframe %i.",cradd);
	    return TL_OK+1;
	  }

	aframe.subfr[cradd].ispresent = 1;
	aframe.subfr[cradd].header.last = data->aframe.subfr.els[i].header.last;
	aframe.subfr[cradd].header.trigger = data->aframe.subfr.els[i].header.trigger;

	{
	  int j;
	  int nrslaves[16];

	  /* calc. nr of slaves present and alloc space*/
	  for (j=0; j<16; j++)
	    nrslaves[j]=0;
	  
	  for (j=0; j<data->aframe.subfr.els[i].slaves.nrels; j++)
	    nrslaves[data->aframe.subfr.els[i].slaves.els[j].slvadd]++;

	  for (j=0; j<16; j++)
	    {
	      aframe.subfr[cradd].slv[j].nrels = nrslaves[j];
	      if (nrslaves[j]>0)
		{
		  aframe.subfr[cradd].slv[j].els = (ROCKM_FIFO_SLV_data *) malloc(nrslaves[j]*sizeof(ROCKM_FIFO_SLV_data));
		}
	    }

	  /* do conversion */
	  for (j=0; j<16; j++)
	    nrslaves[j]=0;
	  
	  for (j=0; j<data->aframe.subfr.els[i].slaves.nrels; j++)
	    {
	      int slvadd;

	      slvadd = data->aframe.subfr.els[i].slaves.els[j].slvadd;
	      aframe.subfr[cradd].slv[slvadd].els[nrslaves[slvadd]].channel = data->aframe.subfr.els[i].slaves.els[j].channel;
	      aframe.subfr[cradd].slv[slvadd].els[nrslaves[slvadd]].reserved = data->aframe.subfr.els[i].slaves.els[j].reserved;
	      aframe.subfr[cradd].slv[slvadd].els[nrslaves[slvadd]].data = data->aframe.subfr.els[i].slaves.els[j].slvdata;
	      nrslaves[slvadd]++;
	    }
	}

	aframe.subfr[cradd].footer.softparity = data->aframe.subfr.els[i].footer.softparity;
	aframe.subfr[cradd].footer.hardparity = data->aframe.subfr.els[i].footer.hardparity;
      }

  }

  aframe.footer.softparity_fail = data->aframe.footer.softparity_fail;
  aframe.footer.hardparity_fail = data->aframe.footer.hardparity_fail;
  aframe.footer.overflow = data->aframe.footer.overflow;
  aframe.footer.softcounter = data->aframe.footer.softcounter;
  aframe.footer.hardcounter = data->aframe.footer.hardcounter;

  rockm_fifo_conv_frame2raw(aframe,&rawels);

  {
    int cradd, slvadd;

    for (cradd=0; cradd<8; cradd++)
     if (aframe.subfr[cradd].ispresent)
      for (slvadd=0; slvadd<16; slvadd++)
       if (aframe.subfr[cradd].slv[slvadd].nrels>0)
	free(aframe.subfr[cradd].slv[slvadd].els);
  }

  /* return converted data */

  {
    int i;

    for (i=rawels.nrels-1; i>=0; i--)
      {
	_STR_natural *listel;

	listel = (_STR_natural *) malloc(sizeof(_STR_natural));
	listel->next = data->result;
	listel->element = rawels.els[i];
	data->result = listel;
      }
  }

  free(rawels.els);

  return TL_OK;
}

/* rockmfifo conv whatis data function*/
/* return TL_OK iff no error */
int rockmfifot_tl_conv_whatis(rockmfifot_t_conv_whatis *data)
{
  int whatis;

  data->result = (char *) malloc(64);

  whatis = rockm_fifo_whatis(data->rawel);

  switch (whatis)
    {
    case ROCKM_FIFO_IS_SUPER_HEADER:
      strcpy(data->result,"superheader");
      break;
    case ROCKM_FIFO_IS_SUB_HEADER:
      strcpy(data->result,"subheader");
      break;
    case ROCKM_FIFO_IS_SLAVE:
      strcpy(data->result,"slave");
      break;
    case ROCKM_FIFO_IS_SUB_FOOTER:
      strcpy(data->result,"subfooter");
      break;
    case ROCKM_FIFO_IS_SUPER_FOOTER:
      strcpy(data->result,"superfooter");
      break;
    default:
      strcpy(data->result,"invalid");
      break;
    }

  return TL_OK;
}