Commit 5bc8a36a authored by Claes Sjofors's avatar Claes Sjofors

UDP IO implemented

parent a5aba434
......@@ -26,6 +26,8 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
......@@ -42,6 +44,7 @@
#include "rt_io_card_read.h"
#include "rt_io_card_read.h"
#include "rt_io_msg.h"
#include "rt_iom_msg.h"
typedef struct {
float time_since_rcv;
......@@ -60,6 +63,9 @@ typedef struct {
char *input_area;
char *output_area;
int softlimit_logged;
pwr_tTime last_try_connect_time;
pwr_tTime last_receive_time;
unsigned int msgs_lost;
} io_sLocalUDP_IO;
typedef struct {
......@@ -74,26 +80,110 @@ typedef struct {
#define ACK 6
#define UDP_MAX_SIZE 32768
static int SendKeepalive( io_sLocalUDP_IO *local, pwr_sClass_UDP_IO *op)
static char rcv_buffer[65536];
pwr_tStatus udp_recv_data( io_sLocalUDP_IO *local, io_sCard *cp,
char *buf, int buf_size)
{
int sts;
io_sUDP_Header header;
pwr_sClass_UDP_IO *op = (pwr_sClass_UDP_IO *)cp->op;
pwr_tStatus sts;
fd_set fdr; /* For select call */
fd_set fde; /* For select call */
fd_set fdw; /* For select call */
struct timeval tv;
int data_size;
int received = 0;
/* Receive answer */
sts = 1;
/* while (sts > 0) */
{
FD_ZERO(&fdr);
FD_ZERO(&fdw);
FD_ZERO(&fde);
FD_SET(local->socket, &fdr);
FD_SET(local->socket, &fdw);
FD_SET(local->socket, &fde);
tv.tv_sec = 0;
tv.tv_usec = 0;
/* Fill in application header and convert to network byte order */
sts = select(32, &fdr, &fdw, &fde, &tv);
header.protocol_id[0] = STX;
header.protocol_id[1] = ETB;
header.msg_size = htons(sizeof(header));
header.msg_id[0] = 0;
header.msg_id[1] = 0;
if (sts < 0) {
op->Status = IOM__UDP_DOWN;
// close(local->socket);
errh_Error( "Connection lost to modbus slave, %s", cp->Name);
return IO__SUCCESS;
}
if (!(FD_ISSET(local->socket, &fdw))) {
op->Status = IOM__UDP_DOWN;
// close(local->socket);
errh_Error( "Connection down to modbus slave, %s", cp->Name);
return IO__SUCCESS;
}
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fdr);
FD_ZERO(&fde);
FD_SET(local->socket, &fdr);
FD_SET(local->socket, &fde);
sts = sendto( local->socket, &header, sizeof(header), 0,
(struct sockaddr *) &local->remote_addr, sizeof(struct sockaddr));
sts = select(32, &fdr, NULL, &fde, &tv);
if (sts >= 0)
op->KeepAliveDiff++;
if (sts < 0) {
op->Status = IOM__UDP_DOWN;
// close(local->socket);
errh_Error( "Connection lost to modbus slave, %s", cp->Name);
return IO__SUCCESS;
}
if (sts == 0) {
if ( !received)
return 0;
else
return IO__SUCCESS;
}
return sts;
if (sts > 0 && FD_ISSET(local->socket, &fdr)) {
data_size = recv(local->socket, rcv_buffer, local->input_buffer_size, 0);
if (data_size < 0) {
op->Status = IOM__UDP_DOWN;
// close(local->socket);
errh_Error( "UDP IO Connection lost, %s", cp->Name);
return IO__SUCCESS;
}
if (data_size == 0) {
op->Status = IOM__UDP_DOWN;
// close(local->socket);
errh_Error( "UDP IO Connection down, %s", cp->Name);
return IO__SUCCESS;
}
if ( data_size < buf_size) {
if ( !received)
return 0;
else
return IO__SUCCESS;
}
if ( data_size > 0) {
memcpy( buf, rcv_buffer, buf_size);
received = 1;
op->RX_Packets++;
}
}
}
return IO__SUCCESS;
}
static pwr_tStatus IoCardInit( io_tCtx ctx,
......@@ -116,13 +206,17 @@ static pwr_tStatus IoCardInit( io_tCtx ctx,
local = (io_sLocalUDP_IO *) calloc( 1, sizeof(io_sLocalUDP_IO));
cp->Local = local;
time_GetTimeMonotonic( &local->last_receive_time);
op->Link = pwr_eUpDownEnum_Down;
op->Status = IOM__UDP_INIT;
/* Create a socket for UDP */
local->socket = socket(AF_INET, SOCK_DGRAM, 0);
if ( local->socket < 0) {
errh_Error( "UDP_IO, error creating socket, %d, '%s'", local->socket, cp->Name);
op->Status = IO__INITFAIL;
op->Status = IOM__UDP_SOCKET;
return IO__INITFAIL;
}
......@@ -137,14 +231,14 @@ static pwr_tStatus IoCardInit( io_tCtx ctx,
sizeof(local->local_addr));
if (sts != 0) {
errh_Error( "UDP_IO, error bind socket, %d, '%s'", sts, cp->Name);
op->Status = IO__INITFAIL;
op->Status = IOM__UDP_BIND;
return IO__INITFAIL;
}
}
else {
getsockname( local->socket, (struct sockaddr *) &address, &address_len);
op->LocalPort = ntohs(address.sin_port);
}
}
/* Initialize remote address structure */
......@@ -167,7 +261,7 @@ static pwr_tStatus IoCardInit( io_tCtx ctx,
}
else {
errh_Error( "UDP_IO, unknown remote host %s, '%s'", op->RemoteHostName, cp->Name);
op->Status = IO__INITFAIL;
op->Status = IOM__UDP_REMOTE;
return IO__INITFAIL;
}
}
......@@ -179,7 +273,6 @@ static pwr_tStatus IoCardInit( io_tCtx ctx,
memcpy(&local->remote_addr.sin_addr, &badr, 4);
}
op->Link = pwr_eUpDownEnum_Down;
op->KeepAliveDiff = 0;
local->byte_ordering = op->ByteOrdering;
......@@ -217,7 +310,6 @@ static pwr_tStatus IoCardInit( io_tCtx ctx,
}
errh_Info( "Init of UDP_IO '%s'", cp->Name);
op->Status = IO__SUCCESS;
return IO__SUCCESS;
}
......@@ -248,127 +340,37 @@ static pwr_tStatus IoCardRead( io_tCtx ctx,
{
io_sLocalUDP_IO *local = (io_sLocalUDP_IO *)cp->Local;
pwr_sClass_UDP_IO *op = (pwr_sClass_UDP_IO *)cp->op;
fd_set fds; /* For select call */
static char buf[UDP_MAX_SIZE];
char unknown[24];
unsigned char badr[24];
struct sockaddr_in from;
unsigned int fromlen;
int size;
unsigned int sts;
io_sUDP_Header header;
struct timeval tv;
int data_received = 0;
local->time_since_keepalive += ctx->ScanTime;
local->time_since_rcv += ctx->ScanTime;
local->time_since_keepalive = MIN(local->time_since_keepalive, op->KeepAliveTime + 1.0);
local->time_since_rcv = MIN(local->time_since_rcv, op->LinkTimeout + 1.0);
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO( &fds);
FD_SET( local->socket, &fds);
sts = select(32, &fds, NULL, NULL, &tv);
if ( sts < 0) {
op->ErrorCount++;
goto read_error;
}
pwr_tTime now;
pwr_tDeltaTime dt;
fromlen = sizeof(struct sockaddr);
size = recvfrom( local->socket, buf, sizeof(buf), MSG_DONTWAIT,
(struct sockaddr *) &from, &fromlen);
if (size <= 0) {
if ( errno != EAGAIN) {
errh_Info("UDP IO Receive failure %d %s", size, op->RemoteHostName);
op->ErrorCount++;
}
goto read_error;
}
if ( memcmp(&from.sin_addr, &local->remote_addr.sin_addr, sizeof(struct in_addr)) != 0) {
/* Wrong address */
memcpy(&badr, &from.sin_addr, 4);
sprintf(unknown, "%d.%d.%d.%d", badr[0], badr[1], badr[2], badr[3]);
errh_Info("UDP_IO Receive from unknown source %s", unknown);
op->ErrorCount++;
goto read_error;
}
/* Set link up */
local->time_since_rcv = 0;
if ( op->Link == pwr_eUpDownEnum_Down) {
errh_Info("UDP IO link up to %s", op->RemoteHostName);
op->Link = pwr_eUpDownEnum_Up;
}
if ( size < local->input_buffer_size) {
errh_Info("UDP IO message size too small %s", op->RemoteHostName);
op->ErrorCount++;
goto read_error;
}
memcpy( local->input_buffer, buf, size);
if ( !op->EnableHeader)
data_received = 1;
else {
/* Header enabled */
memcpy(&header, buf, sizeof(io_sUDP_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 message */
if (header.protocol_id[1] == ETB || header.protocol_id[1] == ENQ) {
/* Keepalive */
if (header.msg_id[0] == 0 && header.msg_id[1] == 0) {
/* Keepalive */
op->KeepAliveDiff--;
}
else {
/* Data */
data_received = 1;
}
}
else if (header.protocol_id[1] == ACK) {
/* Acknowledge message */
}
else {
/* Weird header */
op->ErrorCount++;
errh_Info("UDP IO receive weird header %s, %02x %02x %04x %04x %04x",
op->RemoteHostName, header.protocol_id[0], header.protocol_id[1],
header.msg_size, header.msg_id[0], header.msg_id[1]);
goto read_error;
}
}
}
if ( data_received) {
sts = udp_recv_data( local, cp,
local->input_buffer, local->input_buffer_size);
if ( ODD(sts)) {
if ( op->EnableHeader)
memcpy( &header, local->input_buffer, sizeof(io_sUDP_Header));
io_bus_card_read( ctx, rp, cp, local->input_area, 0,
local->byte_ordering, pwr_eFloatRepEnum_FloatIEEE);
time_GetTimeMonotonic( &local->last_receive_time);
if ( op->Link == pwr_eUpDownEnum_Down) {
op->Link = pwr_eUpDownEnum_Up;
op->Status = IOM__UDP_UP;
}
}
read_error:
if ( local->time_since_rcv >= op->LinkTimeout && op->LinkTimeout > 0) {
if ( op->Link == pwr_eUpDownEnum_Up) {
errh_Info("UDP IO link down %s", op->RemoteHostName);
if ( op->Link == pwr_eUpDownEnum_Up) {
time_GetTimeMonotonic( &now);
time_Adiff(&dt, &now, &local->last_receive_time);
if ( time_DToFloat( 0, &dt) >= op->LinkTimeout) {
op->Link = pwr_eUpDownEnum_Down;
op->Status = IOM__UDP_DOWN;
}
}
if ( local->time_since_keepalive >= op->KeepAliveTime) {
if ( op->UseKeepAlive)
SendKeepalive( local, op);
local->time_since_keepalive = 0;
}
if ( op->ErrorCount == op->ErrorSoftLimit && !local->softlimit_logged) {
errh_Warning( "IO Card ErrorSoftLimit reached, '%s'", cp->Name);
local->softlimit_logged = 1;
......@@ -389,7 +391,23 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
{
io_sLocalUDP_IO *local = (io_sLocalUDP_IO *)cp->Local;
pwr_sClass_UDP_IO *op = (pwr_sClass_UDP_IO *)cp->op;
int status;
int sts;
pwr_tTime now;
pwr_tDeltaTime dt;
int try_connect = 0;
if ( op->Link == pwr_eUpDownEnum_Down) {
/* Reconnect */
time_GetTimeMonotonic( &now);
time_Adiff(&dt, &now, &local->last_try_connect_time);
if ( time_DToFloat( 0, &dt) >= op->ReconnectTime) {
try_connect = 1;
memcpy( &local->last_try_connect_time, &now, sizeof(local->last_try_connect_time));
}
else
return IO__SUCCESS;
}
if ( op->EnableHeader) {
io_sUDP_Header *hp = (io_sUDP_Header *)local->output_buffer;
......@@ -401,11 +419,23 @@ static pwr_tStatus IoCardWrite( io_tCtx ctx,
hp->msg_id[1] = htons(op->MessageId[1]);
}
io_bus_card_write( ctx, cp, &local->output_area,
io_bus_card_write( ctx, cp, local->output_area,
local->byte_ordering, pwr_eFloatRepEnum_FloatIEEE);
status = sendto( local->socket, local->output_buffer, local->output_buffer_size, 0,
sts = sendto( local->socket, local->output_buffer, local->output_buffer_size, 0,
(struct sockaddr *) &local->remote_addr, sizeof(struct sockaddr));
if ( sts < 0) {
op->Status = IOM__UDP_DOWN;
op->Link = pwr_eUpDownEnum_Down;
}
if ( try_connect) {
if ( sts >= 0) {
op->Status = IOM__UDP_UP;
op->Link = pwr_eUpDownEnum_Up;
}
}
op->TX_Packets++;
if ( op->ErrorCount == op->ErrorSoftLimit && !local->softlimit_logged) {
errh_Warning( "IO Card ErrorSoftLimit reached, '%s'", cp->Name);
......
......@@ -3658,6 +3658,18 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Card object for UDP communication.
! Card object for UDP communication where the message structure
! is defined with channel objects.
!
! The object is configured as a child to a generic Rack object.
!
! @b See also
! @classlink BaseIORack basecomponent_baseiorack.html
!*/
Object UDP_IO $ClassDef 23 18-MAY-2011 07:45:49.88
Body SysBody 18-MAY-2011 07:45:57.07
Attr Editor = 0
......@@ -3667,62 +3679,110 @@ Volume OtherIO $ClassVolume 0.0.250.10
Object RtBody $ObjBodyDef 1 18-MAY-2011 08:04:16.85
Body SysBody 18-MAY-2011 07:46:04.28
Attr StructName = "UDP_IO"
Attr NextAix = "_X24"
Attr NextAix = "_X30"
EndBody
!/**
! Optional description.
!*/
Object Description $Attribute 1 18-MAY-2011 07:46:23.42
Body SysBody 18-MAY-2011 07:46:34.66
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! @Summary Process that handles the module. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the module.
!
! 1: The module is read by the plc process, and is handled by a specific
! thread in the plc, which is specified in the ThreadObject attribute.
! 2: The module is read by the rt_io_comm process.
! 4: The module is handled by an application program.
!*/
Object Process $Attribute 18 18-MAY-2011 08:11:20.37
Body SysBody 18-MAY-2011 08:11:20.37
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the card.
! The PlcThread object of the plc thread that handles the card.
! The card is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 19 18-MAY-2011 08:11:20.45
Body SysBody 18-MAY-2011 08:11:20.45
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! Ethernet device. Not used.
!*/
Object Device $Attribute 2 18-MAY-2011 07:46:57.02
Body SysBody 18-MAY-2011 07:47:17.37
Attr PgmName = "Device"
Attr TypeRef = "pwrs:Type-$String32"
EndBody
EndObject
!/**
! Hostname of remote node.
!*/
Object RemoteHostName $Attribute 3 18-MAY-2011 07:47:46.07
Body SysBody 18-MAY-2011 07:48:06.35
Attr PgmName = "RemoteHostName"
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
!/**
! IP address of remote node.
!*/
Object RemoteAddress $Attribute 4 18-MAY-2011 07:48:27.99
Body SysBody 18-MAY-2011 07:48:40.22
Attr PgmName = "RemoteAddress"
Attr TypeRef = "pwrs:Type-$String40"
EndBody
EndObject
!/**
! Port on remote node.
!*/
Object RemotePort $Attribute 5 18-MAY-2011 07:49:24.89
Body SysBody 18-MAY-2011 07:49:32.49
Attr PgmName = "RemotePort"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Port on local node.
!*/
Object LocalPort $Attribute 6 18-MAY-2011 07:49:42.02
Body SysBody 18-MAY-2011 08:08:29.57
Attr PgmName = "LocalPort"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Byte ordering of remote node.
!*/
Object ByteOrdering $Attribute 20 18-MAY-2011 09:20:56.59
Body SysBody 18-MAY-2011 09:20:56.59
Attr PgmName = "ByteOrdering"
Attr TypeRef = "pwrb:Type-ByteOrderingEnum"
EndBody
EndObject
!/**
! Float representation of remote node. Not yet implemented.
!*/
Object FloatRepresentation $Attribute 25 20-MAY-2011 14:28:22.26
Body SysBody 20-MAY-2011 14:28:16.72
Attr PgmName = "FloatRepresentation"
Attr Flags = 1040
Attr TypeRef = "pwrb:Type-FloatRepEnum"
EndBody
EndObject
!/**
! Link status enumeration. Up or Down.
!*/
Object Link $Attribute 7 18-MAY-2011 07:56:48.39
Body SysBody 18-MAY-2011 08:30:57.24
Attr PgmName = "Link"
......@@ -3730,12 +3790,27 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrb:Type-UpDownEnum"
EndBody
EndObject
!/**
! Time after last received message when link is regarded as down.
!*/
Object LinkTimeout $Attribute 16 18-MAY-2011 08:05:56.37
Body SysBody 18-MAY-2011 08:06:01.94
Attr PgmName = "LinkTimeout"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Time between reconnect messages when link is down.
!*/
Object ReconnectTime $Attribute 26 20-MAY-2011 14:29:16.22
Body SysBody 20-MAY-2011 14:28:38.85
Attr PgmName = "ReconnectTime"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Device status.
!*/
Object Status $Attribute 17 18-MAY-2011 08:07:25.83
Body SysBody 18-MAY-2011 08:31:10.19
Attr PgmName = "Status"
......@@ -3743,12 +3818,38 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$Status"
EndBody
EndObject
!/**
! Number of received packets.
!*/
Object RX_Packets $Attribute 27 18-MAY-2011 16:44:26.32
Body SysBody 18-MAY-2011 16:44:35.97
Attr PgmName = "RX_Packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Number of transmitted packets.
!*/
Object TX_Packets $Attribute 29 18-MAY-2011 16:44:47.12
Body SysBody 18-MAY-2011 16:44:39.29
Attr PgmName = "TX_Packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Not implemented.
!*/
Object EnableHeader $Attribute 8 18-MAY-2011 07:57:46.56
Body SysBody 18-MAY-2011 07:57:52.66
Attr PgmName = "EnableHeader"
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
!/**
! Not implemented.
!*/
Object MessageId $Attribute 23 18-MAY-2011 13:18:27.54
Body SysBody 18-MAY-2011 13:20:04.49
Attr PgmName = "MessageId"
......@@ -3757,18 +3858,27 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Not implemented.
!*/
Object UseKeepAlive $Attribute 9 18-MAY-2011 07:58:13.34
Body SysBody 18-MAY-2011 07:58:16.49
Attr PgmName = "UseKeepAlive"
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
!/**
! Not implemented.
!*/
Object KeepAliveTime $Attribute 10 18-MAY-2011 07:58:36.77
Body SysBody 18-MAY-2011 07:58:43.14
Attr PgmName = "KeepAliveTime"
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Not implemented.
!*/
Object KeepAliveDiff $Attribute 11 18-MAY-2011 07:59:05.34
Body SysBody 18-MAY-2011 08:31:23.43
Attr PgmName = "KeepAliveDiff"
......@@ -3776,6 +3886,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$Int32"
EndBody
EndObject
!/**
! Error counter.
!*/
Object ErrorCount $Attribute 13 18-MAY-2011 08:04:23.30
Body SysBody 18-MAY-2011 08:31:32.05
Attr PgmName = "ErrorCount"
......@@ -3783,18 +3896,27 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Value of the error counter, when a message is sent to the console log.
!*/
Object ErrorSoftLimit $Attribute 14 18-MAY-2011 08:05:05.42
Body SysBody 18-MAY-2011 08:05:08.80
Attr PgmName = "ErrorSoftLimit"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Value of the error counter, when all IO handling is aborted.
!*/
Object ErrorHardLimit $Attribute 15 18-MAY-2011 08:05:13.78
Body SysBody 18-MAY-2011 08:05:16.85
Attr PgmName = "ErrorHardLimit"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Size of input area, calculated at runtime initialization.
!*/
Object InputAreaSize $Attribute 21 18-MAY-2011 09:21:36.79
Body SysBody 18-MAY-2011 09:22:16.57
Attr PgmName = "InputAreaSize"
......@@ -3802,6 +3924,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Size of output area, calculated at runtime initialization.
!*/
Object OutputAreaSize $Attribute 22 18-MAY-2011 09:21:59.29
Body SysBody 18-MAY-2011 09:22:22.58
Attr PgmName = "OutputAreaSize"
......@@ -3853,10 +3978,11 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndBody
EndObject
Object Template UDP_IO 2153742336 01-JAN-1970 01:00:00.00
Body RtBody 18-MAY-2011 08:34:31.13
Body RtBody 20-MAY-2011 14:29:46.64
Attr Process = 1
Attr Device = "eth0"
Attr LinkTimeout = 3.000000e+00
Attr ReconnectTime = 2.000000e+00
Attr KeepAliveTime = 1.000000e+00
EndBody
EndObject
......
!
! Proview $Id$
! Copyright (C) 2005 SSAB Oxelösund AB.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with the program, if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!
! rt_iom_msg.msg -- <short description>
!
.facility IOM,143 /prefix = IOM__ ! IO methods
success <Normal, successful completion> /succ
udp_up <UDP link is up> /succ
udp_init <UDP initalizing> /info
udp_down <UDP link is down> /error
udp_socket <UDP create socket error> /error
udp_bind <UDP bind socket error> /error
udp_remote <UDP unknown remote host> /error
.end
......@@ -31,6 +31,8 @@
130 plc
140 io
141 pb
142 mb
143 iom
180 ini
190 mh
191 ph
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment