/***************************************************/
/*                                                 */
/* File        : userrockfifo.c                    */
/* Description : tl compiler definitions           */
/*                                                 */
/* Command     : rockfifo                          */
/* Comment     : ROCK FIFO library tcl interface   */
/*                                                 */
/* Created       : 18.02.1997                      */
/* Last modified : 08.04.1997                      */
/*                                                 */
/***************************************************/

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

#include <rockfifo.h>
#include "userrockfifo.h"

/* rockfifo decode data function*/
/* return TL_OK iff no error */
int rockfifot_tl_decode(rockfifot_t_decode *data)
{
  int err;
  ROCK_FIFO_FRAMEs readels;

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

  err = rock_fifo_frame_blockread((ROCK_FIFO_id) data->fid, data->nrels, &readels);

  switch (err)
    {
    case ROCK_ERROR_OK:
    case ROCK_ERROR_FIFO_EMPTY:
    case ROCK_ERROR_FIFO_FRAME_PARITY:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"");
      }
      break; /* no message */
    case ROCK_ERROR_FIFO_FRAME_HEADER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"header error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_FOOTER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"footer error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(16);
	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_ROCKFIFOT_OTframe *listel;
	int j;

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

	listel->element.header.sy = readels.frames[i].header.sy;
	listel->element.header.last = readels.frames[i].header.last;
	listel->element.header.cradd = readels.frames[i].header.cradd;
	listel->element.header.trigger = readels.frames[i].header.trigger;

	listel->element.slaves = NULL;

	for (j=0;j<16;j++)
	  {
	    int k;

	    for (k=readels.frames[i].slv[j].nrels-1;k>=0;k--)
	      {
		_STR_ROCKFIFOT_OTslave *slvel;

		slvel = (_STR_ROCKFIFOT_OTslave *) malloc(sizeof(_STR_ROCKFIFOT_OTslave));
		slvel->next = listel->element.slaves;
		listel->element.slaves = slvel;

		listel->element.slaves->element.slvadd = j;
		listel->element.slaves->element.channel = readels.frames[i].slv[j].els[k].channel;
		listel->element.slaves->element.reserved = readels.frames[i].slv[j].els[k].reserved;
		listel->element.slaves->element.slvdata = readels.frames[i].slv[j].els[k].data;
	      }

	    free(readels.frames[i].slv[j].els);
	  }
	listel->element.footer.last = readels.frames[i].footer.last;
	listel->element.footer.softparity = readels.frames[i].footer.softparity;
	listel->element.footer.hardparity = readels.frames[i].footer.hardparity;
      }
  }

  free(readels.frames);
  return TL_OK;
}

/* rockfifo read_frame data function*/
/* return TL_OK iff no error */
int rockfifot_tl_read_frame(rockfifot_t_read_frame *data)
{
  int err;
  ROCK_FIFO_RAW readels;

  err = rock_fifo_frame_rawread((ROCK_FIFO_id) data->fid, &readels);

  switch (err)
    {
    case ROCK_ERROR_OK:
    case ROCK_ERROR_FIFO_EMPTY:
    case ROCK_ERROR_FIFO_FRAME_PARITY:
      break; /* no message */
    case ROCK_ERROR_FIFO_FRAME_HEADER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"header error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_FOOTER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"footer error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(16);
	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;
}

/* rockfifo read_frame_bits data function*/
/* return TL_OK iff no error */
int rockfifot_tl_read_frame_bits(rockfifot_t_read_frame_bits *data)
{
  int err;
  ROCK_FIFO_RAW_bits readels;

  err = rock_fifo_frame_rawread_bits((ROCK_FIFO_id) data->fid, &readels);

  switch (err)
    {
    case ROCK_ERROR_OK:
    case ROCK_ERROR_FIFO_EMPTY:
    case ROCK_ERROR_FIFO_FRAME_PARITY:
      break; /* no message */
    case ROCK_ERROR_FIFO_FRAME_HEADER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"header error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_FOOTER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"footer error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(16);
	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_ROCKFIFOT_OTread_bits_el *listel;

	listel = (_STR_ROCKFIFOT_OTread_bits_el *) malloc(sizeof(_STR_ROCKFIFOT_OTread_bits_el));
	listel->next = data->result.elements;
	listel->element.nvd = readels.els[i].nvd;
	listel->element.ff = readels.els[i].ff;
	listel->element.hf = readels.els[i].hf;
	listel->element.ef = readels.els[i].ef;
	listel->element.fifodata = readels.els[i].fifodata;
	data->result.elements = listel;
      }
  }

  free(readels.els);

  return TL_OK;
}

/* rockfifo read data function*/
/* return TL_OK iff no error */
int rockfifot_tl_read(rockfifot_t_read *data)
{
  int err;
  ROCK_FIFO_RAW readels;

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

  err = rock_fifo_raw_blockread((ROCK_FIFO_id) data->fid, data->nrels, &readels);

  if ((err!=ROCK_ERROR_OK)&&(err!=ROCK_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;
}

/* rockfifo read_bits data function*/
/* return TL_OK iff no error */
int rockfifot_tl_read_bits(rockfifot_t_read_bits *data)
{
  int err;
  ROCK_FIFO_RAW_bits readels;

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

  err = rock_fifo_raw_blockread_bits((ROCK_FIFO_id) data->fid, data->nrels, &readels);

  if ((err!=ROCK_ERROR_OK)&&(err!=ROCK_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_ROCKFIFOT_OTread_bits_el *listel;

	listel = (_STR_ROCKFIFOT_OTread_bits_el *) malloc(sizeof(_STR_ROCKFIFOT_OTread_bits_el));
	listel->next = data->result;
	listel->element.nvd = readels.els[i].nvd;
	listel->element.ff = readels.els[i].ff;
	listel->element.hf = readels.els[i].hf;
	listel->element.ef = readels.els[i].ef;
	listel->element.fifodata = readels.els[i].fifodata;
	data->result = listel;
      }
  }

  free(readels.els);

  return TL_OK;
}

/* rockfifo close data function*/
/* return TL_OK iff no error */
int rockfifot_tl_close(rockfifot_t_close *data)
{
  ROCK_FIFO_RAW_bits cache;
  int err;
  
  err = rock_fifo_close((ROCK_FIFO_id) data->fid,&cache);

  if (err!=ROCK_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_ROCKFIFOT_OTelbits *listel;

	listel = (_STR_ROCKFIFOT_OTelbits *) malloc(sizeof(_STR_ROCKFIFOT_OTelbits));
	listel->next = data->result;
	listel->element.nvd = cache.els[i].nvd;
	listel->element.ff = cache.els[i].ff;
	listel->element.hf = cache.els[i].hf;
	listel->element.ef = cache.els[i].ef;
	listel->element.fifodata = cache.els[i].fifodata;
	data->result = listel;
      }
  }

  free(cache.els);
  return TL_OK;
}

/* rockfifo open data function*/
/* return TL_OK iff no error */

int rockfifot_tl_open(rockfifot_t_open *data)
{
  int realcancache;
  int err;

  if (!data->cancache_present)
    {
      data->cancache.nr = ROCKFIFOT_Ccancache_minimal;
    }

  switch(data->cancache.nr)
    {
    case ROCKFIFOT_Ccancache_off:
      realcancache = ROCK_FIFO_CACHE_OFF;
      break;
    case ROCKFIFOT_Ccancache_minimal:
      realcancache = ROCK_FIFO_CACHE_MINIMAL;
      break;
    case ROCKFIFOT_Ccancache_advanced:
      realcancache = ROCK_FIFO_CACHE_ADVANCED;
      break;
    case ROCKFIFOT_Ccancache_block:
      realcancache = ROCK_FIFO_CACHE_BLOCK;
      break;
    case ROCKFIFOT_Ccancache_block_advanced:
      realcancache = ROCK_FIFO_CACHE_BLOCK_ADVANCED;
      break;
    }

  if (data->what.nr==ROCKFIFOT_Cwhat_efifo)
      err = rock_fifo_open_efifo((ROCK_id) data->rid, realcancache, (ROCK_FIFO_id *) &(data->result));
  else
    err = rock_fifo_open_dfifo((ROCK_id) data->rid, realcancache, (ROCK_FIFO_id *) &(data->result));

  if (err==ROCK_ERROR_OK)
    return TL_OK;
  else
    {
      char *tmp;

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

      return TL_OK+err;
    }
}

/* rockfifo synch data function*/
/* return TL_OK iff no error */
int rockfifot_tl_synch(rockfifot_t_synch *data)
{
  int err;
  ROCK_FIFO_RAW readels;

  err = rock_fifo_frame_synch((ROCK_FIFO_id) data->fid, &readels);

  if ((err!=ROCK_ERROR_OK)&&(err!=ROCK_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;
}

/* rockfifo synch_bits data function*/
/* return TL_OK iff no error */
int rockfifot_tl_synch_bits(rockfifot_t_synch_bits *data)
{
  int err;
  ROCK_FIFO_RAW_bits readels;

  err = rock_fifo_frame_synch_bits((ROCK_FIFO_id) data->fid, &readels);

  if ((err!=ROCK_ERROR_OK)&&(err!=ROCK_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_ROCKFIFOT_OTread_bits_el *listel;

	listel = (_STR_ROCKFIFOT_OTread_bits_el *) malloc(sizeof(_STR_ROCKFIFOT_OTread_bits_el));
	listel->next = data->result;
	listel->element.nvd = readels.els[i].nvd;
	listel->element.ff = readels.els[i].ff;
	listel->element.hf = readels.els[i].hf;
	listel->element.ef = readels.els[i].ef;
	listel->element.fifodata = readels.els[i].fifodata;
	data->result = listel;
      }
  }

  free(readels.els);
  return TL_OK;
}

/* rockfifo isempty data function*/
/* return TL_OK iff no error */
int rockfifot_tl_isempty(rockfifot_t_isempty *data)
{
 int err;

 err = rock_fifo_isnotempty((ROCK_FIFO_id) data->fid);

 if (err==ROCK_ERROR_OK)
   {
     data->result = 0;   /* false */
     return TL_OK;
   }
 else if (err==ROCK_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;
    }
}

/* rockfifo set_cancache data function*/
/* return TL_OK iff no error */
int rockfifot_tl_setcancache(rockfifot_t_setcancache *data)
{
 int err;
 unsigned char realcancache;

 switch(data->cancache.nr)
   {
   case ROCKFIFOT_Ccancache_off:
     realcancache = ROCK_FIFO_CACHE_OFF;
     break;
   case ROCKFIFOT_Ccancache_minimal:
     realcancache = ROCK_FIFO_CACHE_MINIMAL;
     break;
   case ROCKFIFOT_Ccancache_advanced:
     realcancache = ROCK_FIFO_CACHE_ADVANCED;
     break;
   case ROCKFIFOT_Ccancache_block:
     realcancache = ROCK_FIFO_CACHE_BLOCK;
     break;
   case ROCKFIFOT_Ccancache_block_advanced:
     realcancache = ROCK_FIFO_CACHE_BLOCK_ADVANCED;
     break;
   }

 err = rock_fifo_set_cancache((ROCK_FIFO_id) data->fid, realcancache);

 if (err!=ROCK_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;
}

/* rockfifo flush data function*/
/* return TL_OK iff no error */
int rockfifot_tl_flush(rockfifot_t_flush *data)
{
  ROCK_FIFO_RAW_bits cache;
  int err;
  
  err = rock_fifo_cache_flush((ROCK_FIFO_id) data->fid,&cache);

  if (err!=ROCK_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_ROCKFIFOT_OTread_bits_el *listel;

	listel = (_STR_ROCKFIFOT_OTread_bits_el *) malloc(sizeof(_STR_ROCKFIFOT_OTread_bits_el));
	listel->next = data->result;
	listel->element.nvd = cache.els[i].nvd;
	listel->element.ff = cache.els[i].ff;
	listel->element.hf = cache.els[i].hf;
	listel->element.ef = cache.els[i].ef;
	listel->element.fifodata = cache.els[i].fifodata;
	data->result = listel;
      }
  }

  free(cache.els);
  return TL_OK;
}

/* rockfifo refill data function*/
/* return TL_OK iff no error */
int rockfifot_tl_refill(rockfifot_t_refill *data)
{
 int err;
 ROCK_FIFO_RAW_bits newdata;

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

 {
   int i;

   for (i=0; i<newdata.nrels; i++)
     {
       newdata.els[i].nvd = data->newdata.els[i].nvd;
       newdata.els[i].ff = data->newdata.els[i].ff;
       newdata.els[i].hf = data->newdata.els[i].hf;
       newdata.els[i].ef = data->newdata.els[i].ef;
       newdata.els[i].fifodata = data->newdata.els[i].fifodata;
     }
 }

 err = rock_fifo_cache_refill_bits((ROCK_FIFO_id) data->fid,newdata);

 free(newdata.els);

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

 return TL_OK;
}

/* rockfifo conv frame2raw data function*/
/* return TL_OK iff no error */
int rockfifot_tl_frame2raw(rockfifot_t_frame2raw *data)
{
  int err;
  ROCK_FIFO_FRAME frame;
  ROCK_FIFO_RAW readels;

  frame.header.sy = data->framedata.header.sy;
  frame.header.last = data->framedata.header.last;
  frame.header.cradd = data->framedata.header.cradd;
  frame.header.trigger = data->framedata.header.trigger;

  {
   int i;

   for (i=0; i<16; i++)
     {
       frame.slv[i].nrels=0;
       frame.slv[i].els = (ROCK_FIFO_SLV_data *) malloc(sizeof(ROCK_FIFO_SLV_data)*data->framedata.slaves.nrels); /* worst case */
     }

   for (i=0; i<data->framedata.slaves.nrels; i++)
     {
       int actel;

       actel = frame.slv[data->framedata.slaves.els[i].slvadd].nrels++;
       frame.slv[data->framedata.slaves.els[i].slvadd].els[actel].channel = data->framedata.slaves.els[i].channel;
       frame.slv[data->framedata.slaves.els[i].slvadd].els[actel].reserved = data->framedata.slaves.els[i].reserved;
       frame.slv[data->framedata.slaves.els[i].slvadd].els[actel].data = data->framedata.slaves.els[i].slvdata;
     }
  }

  frame.footer.last = data->framedata.footer.last;
  frame.footer.softparity = data->framedata.footer.softparity;
  frame.footer.hardparity = data->framedata.footer.hardparity;

  err = rock_fifo_conv_frame2raw(frame,&readels);
 
  {
   int i;

   for (i=0; i<16; i++)
     {
       free(frame.slv[i].els);
     }

  }

  if (err!=ROCK_ERROR_OK)
    {
      char *tmp;
      
      tmp = ErrorGetMessage();
      data->errorstr = (char *) malloc(strlen(tmp)+1);
      strcpy(data->errorstr,tmp);
      
      return TL_OK+err;
   }
  
  /* return converted 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;
}

/* rockfifo conv raw2frame data function*/
/* return TL_OK iff no error */
int rockfifot_tl_raw2frame(rockfifot_t_raw2frame *data)
{
  int err;
  ROCK_FIFO_FRAME readel;
  ROCK_FIFO_RAW rawdata;

  rawdata.nrels = data->rawdata.nrels;
  rawdata.els = (unsigned int *) malloc(rawdata.nrels*sizeof(unsigned int));
  
  {
    int i;
    
    for (i=0; i<rawdata.nrels; i++)
      {
	rawdata.els[i] = data->rawdata.els[i];
      }
  }


  err = rock_fifo_conv_raw2frame(rawdata, &readel);

  free(rawdata.els);

  switch (err)
    {
    case ROCK_ERROR_OK:
    case ROCK_ERROR_FIFO_EMPTY:
    case ROCK_ERROR_FIFO_FRAME_PARITY:
      break; /* no message */
    case ROCK_ERROR_FIFO_FRAME_HEADER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"header error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_FOOTER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"footer error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(16);
	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.frame.header.sy = readel.header.sy;
    data->result.frame.header.last = readel.header.last;
    data->result.frame.header.cradd = readel.header.cradd;
    data->result.frame.header.trigger = readel.header.trigger;
    
    data->result.frame.slaves = NULL;
    
    for (j=0;j<16;j++)
      {
	int k;
	
	for (k=readel.slv[j].nrels-1;k>=0;k--)
	  {
	    _STR_ROCKFIFOT_OTslave *slvel;
	    
	    slvel = (_STR_ROCKFIFOT_OTslave *) malloc(sizeof(_STR_ROCKFIFOT_OTslave));
	    slvel->next = data->result.frame.slaves;
	    data->result.frame.slaves = slvel;
	    
	    data->result.frame.slaves->element.slvadd = j;
	    data->result.frame.slaves->element.channel = readel.slv[j].els[k].channel;
	    data->result.frame.slaves->element.reserved = readel.slv[j].els[k].reserved;
	    data->result.frame.slaves->element.slvdata = readel.slv[j].els[k].data;
	  }
	
	free(readel.slv[j].els);
      }
    data->result.frame.footer.last = readel.footer.last;
    data->result.frame.footer.softparity = readel.footer.softparity;
    data->result.frame.footer.hardparity = readel.footer.hardparity;
  }

  return TL_OK;
}

/* rockfifo conv raw_bits2frame data function*/
/* return TL_OK iff no error */
int rockfifot_tl_raw_bits2frame(rockfifot_t_raw_bits2frame *data)
{
  int err;
  ROCK_FIFO_FRAME readel;
  ROCK_FIFO_RAW_bits rawdata;
  
  rawdata.nrels = data->rawdata.nrels;
  rawdata.els = (ROCK_EDFIFO_bits *) malloc(rawdata.nrels*sizeof(ROCK_EDFIFO_bits));
  
  {
    int i;

    for (i=0; i<rawdata.nrels; i++)
      {
       rawdata.els[i].nvd = data->rawdata.els[i].nvd;
       rawdata.els[i].ff = data->rawdata.els[i].ff;
       rawdata.els[i].hf = data->rawdata.els[i].hf;
       rawdata.els[i].ef = data->rawdata.els[i].ef;
       rawdata.els[i].fifodata = data->rawdata.els[i].fifodata;
      }
  }
  

  err = rock_fifo_conv_raw_bits2frame(rawdata, &readel);

  free(rawdata.els);

  switch (err)
    {
    case ROCK_ERROR_OK:
    case ROCK_ERROR_FIFO_EMPTY:
    case ROCK_ERROR_FIFO_FRAME_PARITY:
      break; /* no message */
    case ROCK_ERROR_FIFO_FRAME_HEADER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"header error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_SLAVE:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"slave error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_FOOTER:
      {
	data->result.status = (char *) malloc(16);
	strcpy(data->result.status,"footer error");
      }
      break;
    case ROCK_ERROR_FIFO_FRAME_OVERFLOW:
      {
	data->result.status = (char *) malloc(16);
	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.frame.header.sy = readel.header.sy;
    data->result.frame.header.last = readel.header.last;
    data->result.frame.header.cradd = readel.header.cradd;
    data->result.frame.header.trigger = readel.header.trigger;
    
    data->result.frame.slaves = NULL;
    
    for (j=0;j<16;j++)
      {
	int k;
	
	for (k=readel.slv[j].nrels-1;k>=0;k--)
	  {
	    _STR_ROCKFIFOT_OTslave *slvel;
	    
	    slvel = (_STR_ROCKFIFOT_OTslave *) malloc(sizeof(_STR_ROCKFIFOT_OTslave));
	    slvel->next = data->result.frame.slaves;
	    data->result.frame.slaves = slvel;
	    
	    data->result.frame.slaves->element.slvadd = j;
	    data->result.frame.slaves->element.channel = readel.slv[j].els[k].channel;
	    data->result.frame.slaves->element.reserved = readel.slv[j].els[k].reserved;
	    data->result.frame.slaves->element.slvdata = readel.slv[j].els[k].data;
	  }
	
	free(readel.slv[j].els);
      }
    data->result.frame.footer.last = readel.footer.last;
    data->result.frame.footer.softparity = readel.footer.softparity;
    data->result.frame.footer.hardparity = readel.footer.hardparity;
  }


  return TL_OK;
}