示例#1
0
short int Receive()
{
  static char buf[UDP_MAX_SIZE];
  char unknown[24];
  unsigned char badr[24];
  char *pos;
  struct sockaddr_in from;
  unsigned int fromlen;
  int size;
  unsigned int sts;
  remote_udp_header header;  
  remtrans_item *remtrans;
  unsigned char search_remtrans;
  rem_t_transbuff *transbuff;
  rem_t_transbuff *transbuff_behind;
  remtrans_item *transp;

  /* We have made a select, so we're pretty sure there is something to take */

  fromlen = sizeof(struct sockaddr);

  size = recvfrom(my_socket, &buf, sizeof(buf), 0, 
			(struct sockaddr *) &from, &fromlen);

  if (size < 0) { 		/* Definitly error */
    errh_Info("UDP Receive fail %s", rn_udp->RemoteHostname);
    rn_udp->ErrCount++;
    return(-1);	
  }

  if (rn_udp->Disable) return(1);

  if (memcmp(&from.sin_addr, 
	     &their_addr.sin_addr, 
	     sizeof(struct in_addr)) != 0) {  /*from.sin_port != their_addr.sin_port*/
    memcpy(&badr, &from.sin_addr, 4);
    sprintf(unknown, "%d.%d.%d.%d", badr[0], badr[1], badr[2], badr[3]);
    errh_Info("UDP Receive from unknown source %s", unknown);
    rn_udp->ErrCount++;
    return(1);
  }

  /* Set link up */

  time_since_rcv = 0;
  if (rn_udp->LinkUp == 0) {
    errh_Info("UDP link up %s", rn_udp->RemoteHostname);
    rn_udp->LinkUp = 1;
  }

  if (size > 0 && rn_udp->DisableHeader) {
 
    /* Header disabled, take the first receive remtrans object */ 

    remtrans = rn.remtrans;
    search_remtrans = true;

    while(remtrans && search_remtrans) {
      /* Match? */
      if (remtrans->objp->Direction == REMTRANS_IN) {
        search_remtrans = false;
        sts = RemTrans_Receive(remtrans, buf, size); 
      }
      remtrans = (remtrans_item *) remtrans->next;
    }
    if (search_remtrans) {
      rn_udp->ErrCount++;
      errh_Info("UDP Receive no remtrans %s", rn_udp->RemoteHostname);
    }
  }

  else if (size >= 8) {
    memcpy(&header, &buf, sizeof(remote_udp_header));

    /* Convert the header to host byte order */
    header.msg_size = ntohs(header.msg_size);
    header.msg_id[0] = ntohs(header.msg_id[0]);
    header.msg_id[1] = ntohs(header.msg_id[1]);

    if (header.protocol_id[0] == STX && size == header.msg_size) {
      /* This is a valid remtrans */
      if (header.protocol_id[1] == ETB || header.protocol_id[1] == ENQ) {
        if (header.msg_id[0] == 0 && header.msg_id[1] == 0) {
	  /* Keepalive */
          rn_udp->KeepaliveDiff--;
        }
        else {
          /* Data */
          remtrans = (remtrans_item *) rn.remtrans;
          search_remtrans = true;
          while(remtrans && search_remtrans) {
            /* Match? */
            if (remtrans->objp->Address[0] == header.msg_id[0] && 
                remtrans->objp->Address[1] == header.msg_id[1] && 
                remtrans->objp->Direction == REMTRANS_IN) {
              search_remtrans = false;
              pos = ((char *) &buf) + sizeof(remote_udp_header);
              sts = RemTrans_Receive(remtrans, pos, 
			         header.msg_size-sizeof(remote_udp_header));
              if (header.protocol_id[1] == ENQ) {
                SendAck(header.msg_id[0], header.msg_id[1]);
              }
            }
            remtrans = (remtrans_item *) remtrans->next;
          }
          if (search_remtrans) {
            rn_udp->ErrCount++;
            errh_Info("UDP Receive no remtrans %s", rn_udp->RemoteHostname);
          }
        }
      }
      else if (header.protocol_id[1] == ACK) {
	/* Acknowledge message */ 
        transbuff = (rem_t_transbuff *) rn.transbuff;
        transbuff_behind = (rem_t_transbuff *) rn.transbuff;

        while (transbuff) {
	  transp = (remtrans_item *) transbuff->remtrans;
          if (header.msg_id[0] == transp->objp->Address[0] &&
              header.msg_id[1] == transp->objp->Address[1]) {
            /* This is it, unlink the transbuff */
            if (transbuff == transbuff_behind)
              rn.transbuff = (rem_t_transbuff *) transbuff->next;
            else
              transbuff_behind->next = (rem_t_transbuff *) transbuff->next;
            /* Decrement buffer counter */
            transp->objp->Buffers--;
            /* Free transbuff */
            free(transbuff);
            /* Break the while loop */
            break;
          }
          transbuff_behind = transbuff;
          transbuff = (rem_t_transbuff *) transbuff->next;
        }
      }
      else {
        /* Weird header */
        rn_udp->ErrCount++;
        errh_Info("UDP receive weird header %s, %02x %02x %04x %04x %04x", 
        rn_udp->RemoteHostname,
	header.protocol_id[0],
	header.protocol_id[1],
	header.msg_size,
	header.msg_id[0],
	header.msg_id[1]);
      }
    }
                       
    else {
      /* Weird header */
      rn_udp->ErrCount++;
        errh_Info("UDP receive weird header %s, %02x %02x %04x %04x %04x", 
        rn_udp->RemoteHostname,
	header.protocol_id[0],
	header.protocol_id[1],
	header.msg_size,
	header.msg_id[0],
	header.msg_id[1]);
    }
  }

  else {
    /* Not a remtrans UPD message */
    rn_udp->ErrCount++;
    errh_Info("UDP receive weird message %s", rn_udp->RemoteHostname);
  }

  return(1);

}
示例#2
0
static unsigned int Receive()
{
  int sts;
  int nbr_of_bytes_read = 0;
  unsigned char telegram[512];
  char search_remtrans = FALSE;
  remtrans_item *remtrans;
 
  fd_set read_fd;
  struct timeval tv;

  load_timeval(&tv, rn_serial->ScanTime);
  
  nbr_of_bytes_read = 0;
  telegram[nbr_of_bytes_read] = 0;
  sts = 0;
  
  while (nbr_of_bytes_read < sizeof(telegram)-2)
  {
    // Om vi är under mottagning, vänta tills lästimeout
    if (nbr_of_bytes_read > 0) load_timeval(&tv, rn_serial->ReadTimeout);
    FD_ZERO(&read_fd);
    FD_SET(ser_fd, &read_fd);
    sts = select(ser_fd+1, &read_fd, NULL, NULL, &tv);
    if (sts > 0) { // Tecken finns att läsa
      sts = read(ser_fd, &telegram[nbr_of_bytes_read], 1);
      if(sts > 0) {
        nbr_of_bytes_read++;
        if (telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[0] ||
            telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[1] ||
            telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[2] ||
            telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[3] ||
            telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[4] ||
            telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[5] ||
            telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[6] ||
            telegram[nbr_of_bytes_read-1]==rn_serial->TermChar[7] )
          break;
      }
      else {  // Läsfel
        rn_serial->ErrCount++;        
        break;
      } 
    }
    else {  // Timeout
      break;
    }      
  }
   
  if (nbr_of_bytes_read > 0)  // Vi tog emot ett eller flera tecken
  {
    telegram[nbr_of_bytes_read] = 0;
    if (debug)
    {
      printf("Vi tog emot en trans med terminering 0x%x\n", telegram[nbr_of_bytes_read-1]);
      printf("Telegramet var:%s\n", telegram);
    }
    
    search_remtrans = true;
    remtrans = rn.remtrans;

    while (remtrans && search_remtrans)
    {
      if (remtrans->objp->Direction == REMTRANS_IN )
         search_remtrans = false;
      if ( search_remtrans ) remtrans = (remtrans_item *) remtrans->next;
    }   /* endwhile */

    if ( !search_remtrans )
    {
      sts = RemTrans_Receive(remtrans, (char *)telegram, nbr_of_bytes_read);
      if ( EVEN(sts) )
      {
        remtrans->objp->ErrCount++;
        return (FALSE);
      }
    }

    if (search_remtrans)
    {
      /* No corresponding RemTrans object found */
      rn_serial->ErrCount++;
      return (FALSE);
    }
  }

  return(1);
}
示例#3
0
unsigned int wmq_receive()
{
  MQLONG CompCode;
  MQLONG Reason;

  MQMD MsgDesc = {MQMD_DEFAULT};

  MQLONG DataLength;
  MQCHAR Buffer[200000];
  MQGMO GetMsgOpts = {MQGMO_DEFAULT};

  MQLONG BufferLength = sizeof(Buffer);

  unsigned int sts;

  char search_remtrans;
  remtrans_item *remtrans;

  /* Set options */

  GetMsgOpts.Options = MQGMO_NO_WAIT + MQGMO_ACCEPT_TRUNCATED_MSG;

  MsgDesc.Encoding       = MQENC_NATIVE;
  MsgDesc.CodedCharSetId = MQCCSI_Q_MGR;

  /* Get message */

  MQGET(Hconn, RcvHobj, &MsgDesc, &GetMsgOpts, BufferLength, Buffer, &DataLength, &CompCode, &Reason);

  if (CompCode != MQCC_FAILED) {
  
    if (debug) printf("Received message %d\n", (int) DataLength);
  
    search_remtrans = true;

    remtrans = rn.remtrans;
    while(remtrans && search_remtrans) {
      if ((strncmp(remtrans->objp->TransName, (char *) MsgDesc.CorrelId, MQ_CORREL_ID_LENGTH) == 0) &&
	  (remtrans->objp->Direction == REMTRANS_IN)) {
        search_remtrans = false;
        sts = RemTrans_Receive(remtrans, (char *) &Buffer, DataLength);
	if (sts != STATUS_OK && sts != STATUS_BUFF) 
	  errh_Error("Error from RemTrans_Receive, status %d", sts, 0);
        break;
      }
      remtrans = (remtrans_item *) remtrans->next;
    }
    if (search_remtrans) {
      rn_wmq->ErrCount++;
      errh_Info("No remtrans for received message, msgid %s", MsgDesc.MsgId, 0);
    }
  }
  else if (Reason != MQRC_NO_MSG_AVAILABLE) {
    rn_wmq->ErrCount++;
    errh_Error("Receive failed, reason %d", Reason, 0);

    if (Reason == MQRC_CONNECTION_BROKEN) {
      connected = 0;
    }
  }

  return(sts);
}
示例#4
0
static unsigned int ReceiveHandler(int fd)
{
  unsigned int          sts;
  //unsigned int          nbr_of_bytes_written = 0;
  //unsigned int          nbr_of_bytes_read = 0;
  unsigned int          data_size = 0;
  unsigned int		io_size = 0;
  unsigned int		common_offset = 0;
  char                  cont = TRUE;
  char			search_remtrans = FALSE;
  char                  name[7];
  unsigned char         BCC = '\0';
  unsigned char         receive_buffer[MAX_SIZE_TELEGRAM];
  unsigned char         sdle = DLE;
  unsigned char		received_char;
  remtrans_item         *remtrans;
  int 			i;

  fd_set read_fd;
  struct timeval tv;
  char type_name[4];
  common_buffer_vnet *c_buf;

  /**** set up timeout,****/

  load_timeval(&tv, rn_3964R->CharTimeout);

//  tv.tv_sec = TIMEOUT_REC_CHAR_SEC;
//  tv.tv_usec = TIMEOUT_REC_CHAR_USEC;


/*************************************************************************/
/**    Read telegram	                                                **/
/*************************************************************************/

  cont = TRUE;
  data_size = 0;
  
  while (cont)
  {
    /* Read until DLE is received */

    received_char=0;

    while(received_char != DLE)
    {
      load_timeval(&tv, rn_3964R->CharTimeout);
      FD_ZERO(&read_fd);
      FD_SET(fd, &read_fd);
      select(fd+1, &read_fd, NULL, NULL, &tv);
      if (read(fd, &received_char, 1) > 0) { //om det inte var timeout
        // Prevent writing oob
        if (data_size > MAX_SIZE_TELEGRAM - 10) return (FALSE);
        receive_buffer[data_size++]=received_char;
      }
      else				//timeout gå tillbaka
      {
        errh_Error("3964R mottagning, character timeout");
        return(FALSE);  
      }
    }  

    /* Read one more */
    load_timeval(&tv, rn_3964R->CharTimeout);
    FD_ZERO(&read_fd);
    FD_SET(fd, &read_fd);
    select(fd+1, &read_fd, NULL, NULL, &tv);
    if (read(fd, &receive_buffer[data_size], 1) < 1) {
      errh_Error("3964R mottagning, character timeout");
      return(FALSE);  
    }
 
    if (receive_buffer[data_size] == ETX)
    {
      data_size++;

      /* Read one more, should be checksum */
      load_timeval(&tv, rn_3964R->CharTimeout);
      FD_ZERO(&read_fd);
      FD_SET(fd, &read_fd);
      select(fd+1, &read_fd, NULL, NULL, &tv);
      if (read(fd, &receive_buffer[data_size], 1) < 1) {
        errh_Error("3964R mottagning, character timeout");
        return(FALSE);  
      }
  
      data_size++;
      cont = FALSE;
    }
    else
      if (receive_buffer[data_size] != DLE ) data_size++;
  }

/*************************************************************************/
/**  A complete message is received. Check BCC.                         **/
/*************************************************************************/
  BCC = DLE ^ ETX;

  for (i=0; i<data_size-3; i++)
    if (receive_buffer[i] != DLE)
      BCC ^= receive_buffer[i];
  


  if ( BCC == receive_buffer[data_size-1] ) {
    if(!write(fd,&sdle, 1)) return(FALSE);
  }
  else
  {
    /* Checksum in this telegram is wrong */
    errh_Error("3964R mottagning, felaktig checksumma, %d, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", 
    	data_size, receive_buffer[0], receive_buffer[1], receive_buffer[2], receive_buffer[3], receive_buffer[4], receive_buffer[5],
    	receive_buffer[6], receive_buffer[7], receive_buffer[8], receive_buffer[9], receive_buffer[10], receive_buffer[11]);
    if (debug) printf("  Checksum error\n");
       
    if (use_remote_io) {
      if(!write(fd,&sdle, 1)) return(FALSE);
    }
    else
      return(FALSE);
  }


/*************************************************************************/
/**  Find out if the received message is a array of io updates.         **/
/**  Treat the message and exit.                                        **/
/*************************************************************************/
  {
    io_buffer_vnet *io_buf = (io_buffer_vnet *) &receive_buffer;
    RemUtils_R50ToAscii((unsigned short *) &io_buf->io_name, (char *) &name);

    if (strstr(name, "PSS")) {
      io_size = io_buf->length * 2;     /* Converted to bytes */
      sts = RemIO_Receive_3964R(&rn,
                                (unsigned char *) &io_buf->data,
                                io_size-NET_HEADER_SIZE_IO);
      if (debug) printf("  Receiving I/O area\n");

      time_since_io = 0;
      rn_3964R->LinkUp = 1;

      return(sts);
    }
  }

/*************************************************************************/
/**  Find out if the received message is a array of common data         **/
/**  Search for the RemTrans object that is the target.                 **/
/*************************************************************************/
  c_buf = (common_buffer_vnet *) &receive_buffer;

  RemUtils_R50ToAscii((unsigned short *) &c_buf->common_name, (char *) &name);
  for ( i=0 ; i<4 ; i++ )
  {
    type_name[i] = name[i+3];
  }
  if ( (strncmp(type_name, "COM", 3)) == 0 ){
    search_remtrans = true;
    remtrans = rn.remtrans;
    while(remtrans && search_remtrans)
    {
      if ( remtrans->objp->Address[0] == c_buf->common_name[0] &&
             remtrans->objp->Address[1] == c_buf->common_name[1]    )
          search_remtrans = false;
      if ( search_remtrans )
          remtrans = (remtrans_item *) remtrans->next;
    }   /* endwhile */

/*************************************************************************/
/**  Treat the common data update message and exit.                     **/
/*************************************************************************/
    if ( !search_remtrans ){
      io_size = c_buf->length * 2;     /* Converted to bytes */
      common_offset = c_buf->offset;

      if (io_size > remtrans->objp->MaxLength ){
        remtrans->objp->ErrCount++;
        remtrans->objp->LastSts = STATUS_LENGTH;
        return(FALSE);
      }
      else { 
        memcpy(&remtrans->datap[common_offset], c_buf, io_size);
	time_GetTime(&remtrans->objp->TransTime);
        remtrans->objp->TransCount++;
        remtrans->objp->DataValid = TRUE;
        remtrans->objp->LastSts = STATUS_OK;
        remtrans->objp->DataLength = data_size;
      }
      return(TRUE);
    }
  }
  
/*************************************************************************/
/**   This message contains a ordinary remtrans                         **/
/**   Search for the RemTrans object that is the target.                **/
/**   If remote I/O is not used, the message is stored in the first     **/
/**   found (ingoing) remtrans object. If we use remote I/O we check for**/
/**   matching message header                                           **/
/*************************************************************************/
  search_remtrans = true;
  remtrans = rn.remtrans;
  while(remtrans && search_remtrans)
  {
    if (remtrans->objp->Direction == REMTRANS_IN) {
      if (!use_remote_io) {
        search_remtrans = false;
      }
      else {
        if (remtrans->objp->Address[0] == c_buf->common_name[0] &&
	    remtrans->objp->Address[1] == c_buf->common_name[1])
              search_remtrans = false;
      }
    }
    if ( search_remtrans ) remtrans = (remtrans_item *) remtrans->next;
  }
 
/*************************************************************************/
/**  Treat the remtrans message and exit.                               **/
/*************************************************************************/
  if (!search_remtrans)
  {
    sts = RemTrans_Receive(remtrans, (char *)receive_buffer, data_size-3);
    if ( EVEN(sts) )
    {
      remtrans->objp->ErrCount++;
      return (FALSE);
    }
  }
  else
  {
    /* No remtrans */
    errh_Error("Remtrans 3964R no remtrans for this message");
    rn_3964R->ErrCount++;
    return (FALSE);
  }
  return (TRUE);
}
示例#5
0
unsigned int rmq_receive()
{
  pwr_tStatus sts;
  int search_remtrans = 0;
  remtrans_item* remtrans;
  amqp_rpc_reply_t ret;
  amqp_envelope_t envelope;
  struct timeval t = { 2, 0 };
  rabbit_header header;
  int msg_received = 0;

  amqp_maybe_release_buffers(ctx->conn);
  ret = amqp_consume_message(ctx->conn, &envelope, &t, 0);
  switch (ret.reply_type) {
  case AMQP_RESPONSE_NORMAL: {
    break;
  }
  case AMQP_RESPONSE_NONE:
    return REM__SUCCESS;
  case AMQP_RESPONSE_SERVER_EXCEPTION:
    return REM__EXCEPTION;
  case AMQP_RESPONSE_LIBRARY_EXCEPTION:
    switch (ret.library_error) {
    case AMQP_STATUS_TIMEOUT: {
      amqp_destroy_envelope(&envelope);
      return REM__TIMEOUT;
    }
    case AMQP_STATUS_UNEXPECTED_STATE: {
      amqp_frame_t frame;

      sts = amqp_simple_wait_frame_noblock(ctx->conn, &frame, &t);
      if (sts == AMQP_STATUS_TIMEOUT) {
        printf("Wait frame timeout\n");
        return REM__EXCEPTION;
      } else if (sts == AMQP_STATUS_OK) {
        if (frame.frame_type == AMQP_FRAME_METHOD) {
          switch (frame.payload.method.id) {
          case AMQP_BASIC_ACK_METHOD:
            printf("Basic ack method called\n");
            break;
          case AMQP_BASIC_RETURN_METHOD:
            printf("Basic return method called\n");
            break;
          case AMQP_CHANNEL_CLOSE_METHOD:
            printf("Channel close method called\n");
            break;
          case AMQP_CONNECTION_CLOSE_METHOD:
            printf("Connection close method called\n");
            break;
          default:;
          }
        }
        return REM__EXCEPTION;
      } else
        return REM__EXCEPTION;
    }
    }
    // Reconnect...
    rmq_close(1);
    return REM__EXCEPTION;
  default:
    printf("Unknown Reply type: %d\n", ret.reply_type);
  }

  if (debug)
    printf("Received message %d\n", (int)envelope.message.body.len);

  if (envelope.message.body.len > 0 && rn_rmq->DisableHeader) {
    /* Header disabled, take the first receive remtrans object */

    remtrans = rn.remtrans;
    search_remtrans = 1;

    while (remtrans && search_remtrans) {
      /* Match? */
      if (remtrans->objp->Direction == REMTRANS_IN) {
        search_remtrans = false;
        sts = RemTrans_Receive(remtrans, (char*)envelope.message.body.bytes,
            envelope.message.body.len);
        msg_received = 1;
      }
      remtrans = (remtrans_item*)remtrans->next;
    }
    if (search_remtrans) {
      rn_rmq->ErrCount++;
      errh_Info("RabbitMQ Receive no remtrans %s", rn_rmq->ReceiveQueue);
    }
  } else if (envelope.message.body.len >= sizeof(rabbit_header)) {
    memcpy(&header, envelope.message.body.bytes, sizeof(rabbit_header));

    /* Convert the header to host byte order */
    header.msg_size = ntohs(header.msg_size);
    header.msg_id[0] = ntohs(header.msg_id[0]);
    header.msg_id[1] = ntohs(header.msg_id[1]);

    search_remtrans = 1;
    remtrans = rn.remtrans;
    while (remtrans && search_remtrans) {
      if (remtrans->objp->Address[0] == header.msg_id[0]
          && remtrans->objp->Address[1] == header.msg_id[1]
          && remtrans->objp->Direction == REMTRANS_IN) {
        search_remtrans = false;
        sts = RemTrans_Receive(remtrans,
            (char*)envelope.message.body.bytes + sizeof(rabbit_header),
            envelope.message.body.len);
        if (sts != STATUS_OK && sts != STATUS_BUFF)
          errh_Error("Error from RemTrans_Receive, queue %s, status %d",
              rn_rmq->ReceiveQueue, sts, 0);
        msg_received = 1;
        break;
      }
      remtrans = (remtrans_item*)remtrans->next;
    }
    if (search_remtrans) {
      rn_rmq->ErrCount++;
      errh_Info("No remtrans for received message, queue %s, class %d, type %d",
          rn_rmq->ReceiveQueue, header.msg_id[0], header.msg_id[1]);
    }
  }

  if (ctx->op->Acknowledge) {
    if (msg_received)
      amqp_basic_ack(ctx->conn, ctx->channel, envelope.delivery_tag, 0);
    else
      /* Requeue the message */
      amqp_basic_nack(ctx->conn, ctx->channel, envelope.delivery_tag, 0, 1);
  }
  amqp_destroy_envelope(&envelope);

  return sts;
}