예제 #1
0
static pwr_tStatus	logg_open_file( logg_t_loggconf_list	*conflist_ptr,
					int			first_time)
{
	int			csts;
	char			filename[80];
	pwr_tTime		time;
	char			timestr[80];

	if ( !first_time)
	{
	  /* Check if it's time for a new try to open the file */
	  conflist_ptr->wait_count++;
	  if (conflist_ptr->wait_count < 10)
	    return REM__SUCCESS;
	  conflist_ptr->wait_count = 0;
	}

	/* Open file */
	logg_get_filename( conflist_ptr->loggconf->LoggFile,
			filename, LOGG_FILE_EXT);

#if defined OS_LYNX || defined OS_LINUX
	conflist_ptr->outfile = fopen( filename, "a+");
#else
	conflist_ptr->outfile = fopen( filename, "w+", "shr=get");
#endif
	if (conflist_ptr->outfile != NULL)
	{
	  /* Write a file header */
          time_GetTime( &time);
	  time_AtoAscii( &time, time_eFormat_DateAndTime, timestr, 
		sizeof(timestr));
	  csts = fprintf( conflist_ptr->outfile,
			"RemLogg file opened at %s\n\n", timestr);
	  if (csts >= 0)
	  {
	    conflist_ptr->loggconf->FileOpenCount++;
#if defined OS_ELN || defined OS_VMS
	    fgetname( conflist_ptr->outfile, filename);
#endif
	    errh_CErrLog( REM__LOGGFILEOPEN, errh_ErrArgAF(filename), NULL);
	    conflist_ptr->file_open = 1;
	    return REM__SUCCESS;
	  }
	  else
	  {
	    fclose( conflist_ptr->outfile);
	  }
	}
	errh_CErrLog( REM__LOGGFILE, errh_ErrArgAF(filename), NULL);
	return REM__LOGGFILE;
}
예제 #2
0
static pwr_tStatus InitTrendList( trend_tCtx ctx)
{
  pwr_tStatus	    sts;
  pwr_tUInt32	    dummy;
  pwr_tTypeId	    type;
  int		    tix;
  pwr_tAttrRef	    aref;
  pwr_tAttrRef	    oaref;
  pwr_tAName   	    name;
  pwr_tDisableAttr  disabled;

  /* Init DsTrend objects */
  /* Scan through typelist and insert valid objects in list and initiate */
  /* the DsTrend objects. */

  for ( sts = gdh_GetClassListAttrRef(pwr_cClass_DsTrend, &aref); 
	ODD(sts); 
	sts = gdh_GetNextAttrRef( pwr_cClass_DsTrend, &aref, &aref) ) {
    trend_sListEntry    *ep;
    pwr_sClass_DsTrend  *o;

    sts = gdh_AttrrefToName( &aref, name, sizeof(name), cdh_mNName);  
    if (EVEN(sts))
      continue;

    /* Check if parent object is disabled */
    sts = gdh_AttrArefToObjectAref( &aref, &oaref);
    if ( ODD(sts)) {
      sts = gdh_ArefDisabled( &oaref, &disabled);
      if ( ODD(sts) && disabled)
	continue;
    }

    ep = calloc(1, sizeof(*ep));
    if (ep == NULL) {
      errh_CErrLog(DS__ERRALLOC, NULL);
      errh_SetStatus( PWR__SRVTERM);
      exit(DS__ERRALLOC);
    }

    sts = gdh_RefObjectInfo(name, (pwr_tAddress *)&ep->o, 
		      &ep->o_subid, sizeof(*ep->o));
    if (EVEN(sts)) {
      errh_Error("Couldn't get subscription for '%s'\n%m", name, sts);
      free(ep);
      continue;
    }
    o = ep->o;       

   /* Set init values */
    o->BufferStatus[0] = 1;
    o->BufferStatus[1] = 1;
    o->NoOfBuffers = 2;
    o->NoOfBufElement = 239;

    /* Initiate DsTrend object, sampled attribute must be on local node */	  

    sts = gdh_DLRefObjectInfoAttrref((pwr_sAttrRef *)&o->DataName, 
		  (pwr_tAddress *)&o->DataPointer, &o->DataSubId);
    if (EVEN(sts)) {
      if ( sts == GDH__RTDBNULL && IsDisabled( &o->DataName))
	  continue;

      errh_Error("Couldn't get direct link to %s's attribute DataName\n%m", name, sts);
      gdh_UnrefObjectInfo(ep->o_subid);
      free(ep);
      continue;
    }

    sts = gdh_GetAttributeCharAttrref((pwr_sAttrRef *)&o->DataName,
					&type, &dummy, &dummy, &dummy);
    if (EVEN(sts)) {
      errh_Error("Couldn't get datatype for %s's attribute DataName\n%m", name, sts);
      gdh_UnrefObjectInfo(ep->o_subid);
      free(ep);
      continue;
    }
    tix = cdh_TypeIdToIndex(type);

    if (!IsValidType(tix)) {
      errh_Error("No valid datatype for %s's attribute DataName\n%m", name, DS__ERRTYPE);
      gdh_UnrefObjectInfo(ep->o_subid);
      free(ep);
      continue;
    }
      
    o->DataType = tix;
    if ( o->Multiple == 0)
      o->Multiple = 1;
    o->NoOfSample = (o->StorageTime * ctx->scantime) / o->Multiple;

    if(o->NoOfSample > o->NoOfBufElement)
      o->NoOfSample = o->NoOfBufElement;

    o->ScanTime = ctx->scantime;

    ep->next = ctx->o_list;
    ctx->o_list = ep;
  }

  /* Init DsTrendCurve objects */

  /* Scan through typelist and insert valid objects in list and initiate
     the DsTrend objects.  */

  for (sts = gdh_GetClassListAttrRef(pwr_cClass_DsTrendCurve, &aref); 
       ODD(sts); 
       sts = gdh_GetNextAttrRef( pwr_cClass_DsTrendCurve, &aref, &aref) ) {
    trend_sListEntryTC  *ep;
    pwr_sClass_DsTrendCurve  *o;
    int i;
    int found;

    sts = gdh_AttrrefToName( &aref, name, sizeof(name), cdh_mNName);  
    if (EVEN(sts))
      continue;

    /* Check if parent object is disabled */
    sts = gdh_AttrArefToObjectAref( &aref, &oaref);
    if ( ODD(sts)) {
      sts = gdh_ArefDisabled( &oaref, &disabled);
      if ( ODD(sts) && disabled)
	continue;
    }

    ep = calloc(1, sizeof(*ep));
    if (ep == NULL) {
      errh_CErrLog(DS__ERRALLOC, NULL);
      errh_SetStatus( PWR__SRVTERM);
      exit(DS__ERRALLOC);
    }

    ep->first_scan = 1;

    sts = gdh_RefObjectInfo(name, (pwr_tAddress *)&ep->o, 
		      &ep->o_subid, sizeof(*ep->o));
    if (EVEN(sts)) {
      errh_Error("Couldn't get subscription for '%s'\n%m", name, sts);
      free(ep);
      continue;
    }
    o = ep->o;       

    if ( o->Function & 1) {
      /* Data stored by user */
      gdh_UnrefObjectInfo(ep->o_subid);
      free(ep);
      continue;
    }

    ep->multiple = (int) (o->ScanTime / ctx->scantime_tc + 0.5);
    o->NoOfSample = (int) (o->StorageTime / ctx->scantime_tc * ep->multiple + 0.5);

    /* Initiate DsTrendCuve object, sampled attribute must be on local node */	  

    found = 0;
    for ( i = 0; i < 10; i++) {
      if ( cdh_ObjidIsNull( o->Attribute[i].Objid))
	continue;

      /* Link to attribute */
      sts = gdh_DLRefObjectInfoAttrref((pwr_sAttrRef *)&o->Attribute[i], 
				       (pwr_tAddress *)&ep->datap[i], &ep->data_subid[i]);
      if (EVEN(sts)) {
	if ( sts == GDH__RTDBNULL && IsDisabled( &o->Attribute[i]))
	  continue;
	
	errh_Error("Couldn't get direct link to %s's attribute %d, %m", name, i+1, sts);
	ep->datap[i] = 0;
	continue;
      }
     
      sts = gdh_GetAttributeCharAttrref((pwr_sAttrRef *)&o->Attribute[i],
					&type, &dummy, &dummy, &dummy);
      if (EVEN(sts)) {
	errh_Error("Couldn't get datatype for %s's attribute DataName\n%m", name, sts);
	gdh_UnrefObjectInfo(ep->data_subid[i]);
	ep->datap[i] = 0;
	continue;
      }
      tix = cdh_TypeIdToIndex(type);
      ep->data_size[i] = cdh_TypeToSize( type);

      if (!IsValidType(tix)) {
	errh_Error("No valid datatype for %s's attribute DataName\n%m", name, DS__ERRTYPE);
	gdh_UnrefObjectInfo(ep->data_subid[i]);
	ep->datap[i] = 0;
	continue;
      }
      
      o->AttributeType[i] = type;

      /* Link to buffer */
      sts = gdh_DLRefObjectInfoAttrref((pwr_sAttrRef *)&o->Buffers[i], 
				       (pwr_tAddress *)&ep->buffheadp[i], &ep->buff_subid[i]);
      if (EVEN(sts)) {
	errh_Error("Couldn't get direct link to %s's buffer %d, %m", name, i+1, sts);
	gdh_UnrefObjectInfo(ep->data_subid[i]);
	ep->datap[i] = 0;
	continue;
      }
      ep->buffp[i] = (char *)ep->buffheadp[i] + pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));

      /* Get buffer size */
      sts = gdh_GetAttributeCharAttrref( &o->Buffers[i], 0, &ep->buff_size[i], 0, 0);
      if ( EVEN(sts)) return sts;

      ep->buff_size[i] -= pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));

      found = 1;
    }
    if ( !found) {
      errh_Error("No valid attributes for %s", name);
      gdh_UnrefObjectInfo(ep->o_subid);
      free(ep);
      continue;
    }

    /* Link to time buffer */
    if ( cdh_ObjidIsNotNull( o->TimeBuffer.Objid)) {
      sts = gdh_DLRefObjectInfoAttrref((pwr_sAttrRef *)&o->TimeBuffer, 
				       (pwr_tAddress *)&ep->timeheadp, &ep->timebuff_subid);
      if (EVEN(sts)) {
	errh_Error("Couldn't get direct link to %s's time buffer, %m", name, sts);
	ep->timeheadp = 0;
	ep->timebuffp = 0;
      }
      else
 	ep->timebuffp = (char *)ep->timeheadp + pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));
	
      if ( o->TimeResolution == pwr_eTimeResolutionEnum_Nanosecond)
	ep->time_size = 8;
      else
	ep->time_size = 4;

      /* Get buffer size */
      sts = gdh_GetAttributeCharAttrref( &o->TimeBuffer, 0, &ep->timebuff_size, 0, 0);
      if ( EVEN(sts)) return sts;

      ep->timebuff_size -= pwr_AlignLW(sizeof(pwr_sClass_CircBuffHeader));
    }

    /* Calculate number of samples */
    for ( i = 0; i < 10; i++) {
      if ( !ep->datap[i])
	continue;

      if ( o->NoOfSample > ep->buff_size[i] / ep->data_size[i])
	o->NoOfSample = ep->buff_size[i] / ep->data_size[i];
    }
    if ( ep->timebuffp) {
      if ( o->NoOfSample > ep->timebuff_size / ep->time_size)
	o->NoOfSample = ep->timebuff_size / ep->time_size;
    }
    for ( i = 0; i < 10; i++) {
      if ( !ep->datap[i])
	continue;

      ep->buffheadp[i]->Size = o->NoOfSample;
      ep->buffheadp[i]->ElementSize = ep->data_size[i];
    }
    if ( ep->timebuffp) {
      ep->timeheadp->Size = o->NoOfSample;
      ep->timeheadp->ElementSize = ep->time_size;
    }
     
    ep->next = ctx->o_list_tc;
    ctx->o_list_tc = ep;
  }

  if ( ctx->o_list == NULL && ctx->o_list_tc == NULL)
    return DS__NOOBJECT;
  else
    return DS__SUCCESS;
}
예제 #3
0
static pwr_tStatus	logg_print(	logg_ctx	loggctx,
				   	pwr_tUInt32	ident,
				   	char		*msg)
{
	int			csts;
	int			found;
	int			i;
	logg_t_loggconf_list	*conflist_ptr;
	logg_t_loggconf_list	*garbage_conflist_ptr;
	int			garbage_loggconf_found;

	if ( loggctx->loggconf_count == 0)
	  /* Not configured */
	  return REM__SUCCESS;

	/* Identify the identity */
	found = 0;
	garbage_loggconf_found = 0;
	conflist_ptr = loggctx->loggconflist;
	for ( i = 0; i < loggctx->loggconf_count; i++)
	{
	  if ( conflist_ptr->loggconf->Identity == 0)
	  {
	    /* This is the garbage loggfile */
	    garbage_conflist_ptr = conflist_ptr;
	    garbage_loggconf_found = 1;
	  }
	  if ( conflist_ptr->loggconf->Identity == ident)
	  {
	    found = 1;
	    break;
	  }
	  conflist_ptr++;
	}
	if ( !found)
	{
	  if ( garbage_loggconf_found)
	  {
	    /* Write the logg on the garbage file */
	    conflist_ptr = garbage_conflist_ptr;
	  }
	  else
	  {
	    errh_CErrLog( REM__LOGGIDEN, NULL);
	    return REM__SUCCESS;
	  }
	}
/*	csts = fwrite( msg, min( strlen(msg),LOGG_MAX_SIZE), 1, 
		conflist_ptr->outfile);
	if (csts == 0)
*/
	csts = fprintf( conflist_ptr->outfile, "%s\n", msg);
	if ( csts < 0)
	{
	  /* File error, close file and try to open it later */
	  errh_CErrLog( REM__LOGGWRITE, NULL);
	  fclose( conflist_ptr->outfile);
	  conflist_ptr->file_open = 0;
	}
	else
	{
	  csts = fflush( conflist_ptr->outfile);
	  if ( csts != 0)	
	  {
	    /* File error, close file and try to open it later */
	    errh_CErrLog( REM__LOGGWRITE, NULL);
	    fclose( conflist_ptr->outfile);
	    conflist_ptr->file_open = 0;
	  }
	  else
	    conflist_ptr->loggconf->LoggCount++;
	}

	return REM__SUCCESS;
}
예제 #4
0
static unsigned int remnode_send(remnode_item *remnode,
                                 pwr_sClass_RemTrans *remtrans,
                                 char *buf,
                                 int buf_size)
{
  unsigned int          sts, i;
  unsigned int          size_of_telegram, datasize;
  unsigned int          number_of_DLE = 0;
  unsigned int          delta_pos = 0;
  unsigned int          pos_counter = 0;
  unsigned int          follow_on = FALSE;
  unsigned int          A_telegram = FALSE;
  unsigned char         ch, cpu_number, CPU;
  unsigned char         BCC = DLE ^ ETX;
  unsigned char         datasize_low_byte, datasize_high_byte;
  unsigned char         received_char = '\0';
  unsigned char         response_buffer[RESP_MESSAGE_SIZE];
  unsigned char         *restore_buf_ptr = (unsigned char *)buf;
  static unsigned char  sstx[2] = {STX, '\0'};
  static unsigned char  sdle[2] = {DLE, '\0'};
  static unsigned char  snak[2] = {NAK, '\0'};
  fd_set read_fd;
  struct timeval tv;


  /* Define complete telegrams for sending */

  struct{
    unsigned char telegram_header[HEADER_SIZE];
    unsigned char telegram[MAX_SIZE_DATA_BLOCK*2 + NUMBER_OF_STOP_CHAR];
  }sendbuffer;

  struct{
    unsigned char telegram_header[FOLLOW_ON_HEADER_SIZE];
    unsigned char telegram[MAX_SIZE_DATA_BLOCK*2 + NUMBER_OF_STOP_CHAR];
  }follow_on_sendbuffer;


  do     /* Send 128 byte telegrams until message is finished */
  {
    if ( !follow_on )
    {
      A_telegram = TRUE;
/*************************************************************************/
/**    Send A-telegram.                                                 **/
/*************************************************************************/
/**    Check if follow on telegrams are needed.                         **/
/*************************************************************************/
      if ( buf_size - pos_counter > MAX_SIZE_DATA_BLOCK )
      {
        delta_pos = MAX_SIZE_DATA_BLOCK;
        follow_on = TRUE;
      }
      else
      {
        delta_pos = buf_size - pos_counter;
      }

/*************************************************************************/
/**    Calculate the size of the A-telegram.                            **/
/*************************************************************************/
      /* Count DLE characters */
      for ( i=0 ; i<delta_pos ; i++ )
      {
         if ( *buf++ == DLE )
            number_of_DLE += 1;
      }
      size_of_telegram = HEADER_SIZE+
                         delta_pos+number_of_DLE+NUMBER_OF_STOP_CHAR;

/*************************************************************************/
/**    Fill in the telegram header and calculate BCC.                   **/
/*************************************************************************/
      /* Size have to be expressed in number of 16 bits words. */
      /* If odd number of bytes add one. */

      datasize = buf_size/2 + buf_size%2;
      datasize_low_byte = (unsigned char)(BYTE_MASK & datasize);
      datasize = datasize >> 8;
      datasize_high_byte = (unsigned char)(BYTE_MASK & datasize);
      cpu_number = (unsigned char)remtrans->Address[2];
      CPU = '\xFF';
      CPU = CPU_NR_MASK & cpu_number;

      sendbuffer.telegram_header[0] = '\0';
      sendbuffer.telegram_header[1] = '\0';
      sendbuffer.telegram_header[2] = 'A';
      sendbuffer.telegram_header[3] = 'D';
      sendbuffer.telegram_header[4] = (unsigned char)remtrans->Address[0];
      sendbuffer.telegram_header[5] = (unsigned char)remtrans->Address[1];
      sendbuffer.telegram_header[6] = datasize_high_byte;
      sendbuffer.telegram_header[7] = datasize_low_byte;
      sendbuffer.telegram_header[8] = '\xFF';
      sendbuffer.telegram_header[9] = CPU;

      /* Calculate checksum for the header */
      for ( i=0 ; i<HEADER_SIZE ; i++ )
      {
        BCC ^= sendbuffer.telegram_header[i];
      }
/*************************************************************************/
/**   Fill up A-telegram with contents of message and calculate BCC     **/
/*************************************************************************/
      buf = (char *)restore_buf_ptr;
      for ( i=0 ; i<(delta_pos+number_of_DLE) ; i++ )
      {
        ch = sendbuffer.telegram[i] = *buf++;
        BCC ^= ch;
        if ( ch == DLE )
        {
          sendbuffer.telegram[++i] = DLE;
          BCC ^= ch;
        }
      }
      if ( delta_pos%2 )
      {
        /* Ensure that a even number of bytes is treated */
        sendbuffer.telegram[i++] = '\0';
        size_of_telegram += 1;
      }
      sendbuffer.telegram[i++] = DLE;
      sendbuffer.telegram[i++] = ETX;
      sendbuffer.telegram[i]   = BCC;

      pos_counter = delta_pos;
    }
    else  /* follow on telegram */
    {

/*************************************************************************/
/**    Send follow on telegram.                                         **/
/*************************************************************************/
/**    Check if more follow on telegrams are needed.                    **/
/*************************************************************************/
      if ( buf_size - pos_counter > MAX_SIZE_DATA_BLOCK )
      {
        delta_pos = MAX_SIZE_DATA_BLOCK;
        follow_on = TRUE;
      }
      else
      {
        delta_pos = buf_size - pos_counter;
        follow_on = FALSE;
      }

/*************************************************************************/
/**    Calculate the size of the follow on telegram.                    **/
/*************************************************************************/
      /* Count DLE characters */
      restore_buf_ptr = (unsigned char *)buf;
      number_of_DLE = 0;
      for ( i=0 ; i<delta_pos ; i++ )
      {
         if ( *buf++ == DLE )
            number_of_DLE += 1;
      }
      size_of_telegram = FOLLOW_ON_HEADER_SIZE+
                         delta_pos+number_of_DLE+NUMBER_OF_STOP_CHAR;

/*************************************************************************/
/**    Fill in the follow on telegram header and calculate BCC.         **/
/*************************************************************************/
      follow_on_sendbuffer.telegram_header[0] = '\xFF';
      follow_on_sendbuffer.telegram_header[1] = '\0';
      follow_on_sendbuffer.telegram_header[2] = 'A';
      follow_on_sendbuffer.telegram_header[3] = 'D';

      /* Calculate checksum for the header */
      BCC = DLE ^ ETX;
      for ( i=0 ; i<FOLLOW_ON_HEADER_SIZE ; i++ )
      {
        BCC ^= follow_on_sendbuffer.telegram_header[i];
      }

/*************************************************************************/
/* Fill up follow on telegram with contents of message and calculate BCC */
/*************************************************************************/
      buf = (char *)restore_buf_ptr;
      for ( i = 0 ; i < (delta_pos+number_of_DLE) ; i++ )
      {
        ch = follow_on_sendbuffer.telegram[i] = *buf++;
        BCC ^= ch;
        if ( ch == DLE )
        {
          follow_on_sendbuffer.telegram[++i] = DLE;
          BCC ^= ch;
        }
      }
      if ( delta_pos%2 )
      {
        /* Ensure that a even number of bytes is treated */
        follow_on_sendbuffer.telegram[i++] = '\0';
        size_of_telegram += 1;
      }
      follow_on_sendbuffer.telegram[i++] = DLE;
      follow_on_sendbuffer.telegram[i++] = ETX;
      follow_on_sendbuffer.telegram[i]   = BCC;

      pos_counter += delta_pos;

    }

/*************************************************************************/
/**    Execute the send procedure                                       **/
/*************************************************************************/
    /* Send STX and wait for answer */
    sts = write(ser_fd, sstx, 1);
    rlog("snd STX", 0);
    if ( sts > 0) {
      load_timeval(&tv, rn_RK512->CharTimeout);
      FD_ZERO(&read_fd);
      FD_SET(ser_fd, &read_fd);
      select(ser_fd+1, &read_fd, NULL, NULL, &tv);
      sts = read(ser_fd, &received_char, 1);
    }
    if ( sts > 0) { //om det inte var timeout

      if ( received_char == STX ) {
	rlog("snd STX received", 0);
	/* Both nodes is in sending mode. */
	/* Cancel this send operation and wait for next timeout or receive */
	write(ser_fd, snak, 1);
	return(FALSE);
      }
      if ( received_char == DLE ) {
	/* Contact is established. Send telegram */
	rlog("snd DLE received, contact", 0);
	if ( A_telegram ) {
	  sts = write(ser_fd, &sendbuffer, size_of_telegram);
	  rlog("snd message sent", size_of_telegram);
	  A_telegram = FALSE;
	}
	else {
	  sts = write(ser_fd, &follow_on_sendbuffer, size_of_telegram);
	  rlog("snd message sent", size_of_telegram);
	}
	if ( sts > 0 ) {
	  /* wait for break character or timeout */
	  load_timeval(&tv, rn_RK512->CharTimeout);
	  FD_ZERO(&read_fd);
	  FD_SET(ser_fd, &read_fd);
	  select(ser_fd+1, &read_fd, NULL, NULL, &tv);
	  sts = read(ser_fd, &received_char, 1);

          if ( sts > 0 &&(received_char == DLE) ) {

/*************************************************************************/
/**   The sending was a SUCCESS. Take care of the response message      **/
/*************************************************************************/
	    rlog("snd DLE received, success", 0);
	    load_timeval(&tv, rn_RK512->CharTimeout);
	    FD_ZERO(&read_fd);
	    FD_SET(ser_fd, &read_fd);
	    select(ser_fd+1, &read_fd, NULL, NULL, &tv);
	    sts = read(ser_fd, &received_char, 1);

            if ( sts > 0 &&(received_char == STX) ) {
              /* Send DLE acknowledge and wait for response data */
	      sts = write(ser_fd, sdle, 1);
              if ( sts > 0 ) {
                BCC = '\0';
                for (i=0 ;
                     i < RESP_MESSAGE_SIZE && sts > 0;
                     i++ ) {

		  load_timeval(&tv, rn_RK512->CharTimeout);
		  FD_ZERO(&read_fd);
		  FD_SET(ser_fd, &read_fd);
		  select(ser_fd+1, &read_fd, NULL, NULL, &tv);
		  sts = read(ser_fd, &received_char, 1);

                  response_buffer[i] = received_char;
                  BCC ^= received_char;
                }  /* endfor */

                if ( sts > 0 &&
                     (response_buffer[2] == '\0') ) {
                  /* Compare received BCC with calculated */
		  load_timeval(&tv, rn_RK512->CharTimeout);
		  FD_ZERO(&read_fd);
		  FD_SET(ser_fd, &read_fd);
		  select(ser_fd+1, &read_fd, NULL, NULL, &tv);
		  sts = read(ser_fd, &received_char, 1);
                  if ( sts > 0 &&
                       ( BCC == received_char ) ) {
                    /* Response telegram received OK */
		    sts = write(ser_fd, sdle, 1);
                    if ( response_buffer[3] != 0 ) {
                      /* This response contains a error code */
                      errh_CErrLog(REM__SIEMENSERROR,
                                   errh_ErrArgL(response_buffer[3]) );
                    }
                  }
                  else {
                    /* Wrong checksum. */
                    sts = FALSE;
                  }
                }
                else {
                  /* This is not a response message as expected */
		  sts = write(ser_fd, snak, 1);
                  sts = FALSE;
                }
              } /* ENDIF. DLE acknowledge failed */
            }
            else
            {
              /* STX character in response message was expected. */
              /* Ensure that error status is returned */
              sts = FALSE;
            }
          }
          else
          {
            /* DLE ack. after sending telegram was expected. */
            /* Ensure that error status is returned */
	    rlog("snd DLE missing", 0);
            sts = FALSE;
          }
        } /* ENDIF. Contact established but tty_write failed */
      }
      else
      {
        /* Failed in making contact. Wrong response character. */
        /* Ensure that error status is returned */
        sts = FALSE;
      }
    }  /* ENDIF. tty_write or tty_read failed */

/*************************************************************************/
/**  Check final status.                                                **/
/*************************************************************************/
    if ( EVEN(sts))
    {
      /* The send procedure has failed */
      sts = write(ser_fd, snak, 1);
      rlog("snd failed, NAK sent", 0);

      follow_on = FALSE;

      /* Ensure that error status is returned */
      sts = FALSE;
    }

  }while( follow_on );