Commit 185ac1f1 authored by Claes Sjofors's avatar Claes Sjofors

Modbus TCP server implemented

parent ab87999a
......@@ -3,5 +3,6 @@
071220 cs usbio Methods and objects for MotionControl USB I/O added.
080229 rk modbus New I/O-system for Modbus TCP implemented.
081016 rk modbus Added class Modbus_Master.
081016 rk modbus Added moore functionality.
081016 rk modbus Added more functionality.
090301 cs usbio Bugfix for Ai on port B. If Ai and Di/Do were mixed the Ai didn't work.
091208 cs modbus Modbus TCP Server implemented.
This diff is collapsed.
/*
* Proview $Id$
* Copyright (C) 2005 SSAB Oxelsund 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include "pwr.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "rt_io_base.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_io_bus.h"
#include "rt_mb_msg.h"
#include "rt_io_mb_locals.h"
#include "co_time.h"
/*----------------------------------------------------------------------------*\
Init method for the Modbus module
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardInit (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sServerModuleLocal *local;
pwr_sClass_Modbus_TCP_ServerModule *op;
int i;
op = (pwr_sClass_Modbus_TCP_ServerModule *) cp->op;
local = (io_sServerModuleLocal *) cp->Local;
for (i = 0; i < IO_MAXCHAN; i++) {
local->scancount[i] = 0;
}
op->Status = pwr_eModbusModule_StatusEnum_StatusUnknown;
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Read method for the Modbus TCP module
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardRead (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sServerModuleLocal *local;
io_sServerLocal *local_server;
pwr_sClass_Modbus_TCP_ServerModule *op;
pwr_sClass_Modbus_TCP_Server *server;
printf( "Module: Read method\n");
op = (pwr_sClass_Modbus_TCP_ServerModule *) cp->op;
local = (io_sServerModuleLocal *) cp->Local;
server = (pwr_sClass_Modbus_TCP_Server *) rp->op;
local_server = (io_sServerLocal *) rp->Local;
if ( server->DisableServer || !local)
return IO__SUCCESS;
if (server->Status == MB__NORMAL) {
thread_MutexLock( &local_server->mutex);
io_card_read(ctx, rp, cp, local->input_area, NULL, pwr_eByteOrderingEnum_BigEndian, pwr_eFloatRepEnum_FloatIntel);
thread_MutexUnlock( &local_server->mutex);
}
// printf("Method Modbus_Module-IoCardRead\n");
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Write method for the Pb module
\*----------------------------------------------------------------------------*/
static pwr_tStatus IoCardWrite (
io_tCtx ctx,
io_sAgent *ap,
io_sRack *rp,
io_sCard *cp
)
{
io_sServerModuleLocal *local;
io_sServerLocal *local_server;
pwr_sClass_Modbus_TCP_ServerModule *op;
pwr_sClass_Modbus_TCP_Server *server;
printf( "Module: Write method\n");
op = (pwr_sClass_Modbus_TCP_ServerModule *) cp->op;
local = (io_sServerModuleLocal *) cp->Local;
server = (pwr_sClass_Modbus_TCP_Server *) rp->op;
local_server = (io_sServerLocal *) rp->Local;
if ( server->DisableServer || !local)
return IO__SUCCESS;
if (server->Status == MB__NORMAL) {
thread_MutexLock( &local_server->mutex);
io_card_write(ctx, cp, local->output_area, pwr_eByteOrderingEnum_BigEndian, pwr_eFloatRepEnum_FloatIntel);
thread_MutexUnlock( &local_server->mutex);
}
// printf("Method Modbus_Module-IoCardWrite\n");
return IO__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport pwr_BindIoMethods(Modbus_TCP_ServerModule) = {
pwr_BindIoMethod(IoCardInit),
pwr_BindIoMethod(IoCardRead),
pwr_BindIoMethod(IoCardWrite),
pwr_NullMethod
};
......@@ -19,7 +19,6 @@
/* rt_io_m_pb_dp_slave.c -- io methods for a profibus DP slave */
#pragma pack(1)
#include <stdio.h>
#include <string.h>
......@@ -62,12 +61,14 @@ static int connect_slave( io_sRackLocal *local, io_sRack *rp)
fd_set fdr; /* For select call */
fd_set fdw; /* For select call */
struct timeval tv;
unsigned short port;
time_GetTimeMonotonic( &local->last_try_connect_time);
op = (pwr_sClass_Modbus_TCP_Slave *) rp->op;
/* Create socket, store in local struct */
port = op->Port == 0 ? 502 : op->Port;
local->s = socket(AF_INET, SOCK_STREAM, 0);
if (local->s < 0) {
......@@ -84,7 +85,7 @@ static int connect_slave( io_sRackLocal *local, io_sRack *rp)
/* Initialize remote address structure */
local->rem_addr.sin_family = AF_INET;
local->rem_addr.sin_port = htons(502);
local->rem_addr.sin_port = htons(port);
local->rem_addr.sin_addr.s_addr = inet_addr((char *) &(op->Address));
/* Connect to remote address */
......@@ -139,7 +140,7 @@ pwr_tStatus mb_recv_data(io_sRackLocal *local,
pwr_tCid cid;
unsigned char fc;
short int trans_id;
short int size_of_msg = 0;
short int size_of_msg;
/* Receive answer */
......@@ -153,10 +154,18 @@ pwr_tStatus mb_recv_data(io_sRackLocal *local,
FD_SET(local->s, &fdw);
FD_SET(local->s, &fde);
size_of_msg = 0;
tv.tv_sec = 0;
tv.tv_usec = 0;
sts = select(32, &fdr, &fdw, &fde, &tv);
if (sts < 0) {
sp->Status = MB__CONNLOST;
close(local->s);
errh_Error( "Connection lost to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
if (!(FD_ISSET(local->s, &fdw))) {
sp->Status = MB__CONNDOWN;
......@@ -182,6 +191,7 @@ pwr_tStatus mb_recv_data(io_sRackLocal *local,
if (sts < 0) {
sp->Status = MB__CONNLOST;
close(local->s);
errh_Error( "Connection lost to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
......@@ -201,6 +211,7 @@ pwr_tStatus mb_recv_data(io_sRackLocal *local,
if (data_size < 0) {
sp->Status = MB__CONNLOST;
close(local->s);
errh_Error( "Connection lost to modbus slave, %s", rp->Name);
return IO__SUCCESS;
}
......@@ -341,9 +352,7 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
if (!mp->Continous && !mp->SendOp) {
break;
}
mp->SendOp = FALSE;
local_card = cardp->Local;
if (mask & mb_mSendMask_ReadReq) {
......@@ -352,6 +361,8 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
case pwr_eModbus_FCEnum_ReadDiscreteInputs: {
read_req rr;
mp->SendOp = FALSE;
local->trans_id++;
local_card->trans_id = local->trans_id;
......@@ -361,7 +372,8 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
rr.head.unit_id = mp->UnitId;
rr.fc = mp->FunctionCode;
rr.addr = htons(mp->Address);
rr.quant = ntohs(local_card->input_size * 8);
rr.quant = htons(local_card->no_di);
// rr.quant = ntohs(local_card->input_size * 8);
sts = send(local->s, &rr, sizeof(read_req), MSG_DONTWAIT);
if (sts < 0) {
......@@ -380,6 +392,8 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
case pwr_eModbus_FCEnum_ReadInputRegisters: {
read_req rr;
mp->SendOp = FALSE;
local->trans_id++;
local_card->trans_id = local->trans_id;
......@@ -411,6 +425,8 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
case pwr_eModbus_FCEnum_WriteSingleCoil: {
write_single_req wsr;
mp->SendOp = FALSE;
local->trans_id++;
local_card->trans_id = local->trans_id;
......@@ -428,6 +444,10 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
if (*(short int *)local_card->output_area)
wsr.value = ntohs(0xFF00);
else wsr.value = 0;
} else if (local_card->output_size == 1) {
if (*(char *)local_card->output_area)
wsr.value = ntohs(0xFF00);
else wsr.value = 0;
} else wsr.value = 0;
sts = send(local->s, &wsr, ntohs(wsr.head.length) + 6, MSG_DONTWAIT);
......@@ -445,6 +465,8 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
case pwr_eModbus_FCEnum_WriteMultipleCoils: {
write_coils_req wcr;
mp->SendOp = FALSE;
local->trans_id++;
local_card->trans_id = local->trans_id;
......@@ -455,7 +477,8 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
wcr.head.unit_id = mp->UnitId;
wcr.fc = mp->FunctionCode;
wcr.addr = htons(mp->Address);
wcr.quant = ntohs((local_card->output_size) * 8);
wcr.quant = htons(local_card->no_do);
// wcr.quant = ntohs((local_card->output_size) * 8);
wcr.bc = local_card->output_size;
memcpy(wcr.reg, local_card->output_area, local_card->output_size);
......@@ -474,6 +497,8 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
case pwr_eModbus_FCEnum_WriteMultipleRegisters: {
write_reg_req wrr;
mp->SendOp = FALSE;
local->trans_id++;
local_card->trans_id = local->trans_id;
......@@ -539,6 +564,8 @@ static pwr_tStatus IoRackInit (
short output_counter;
short card_input_counter;
short card_output_counter;
short no_di;
short no_do;
pwr_sClass_Modbus_TCP_Slave *op;
pwr_sClass_Modbus_Module *mp;
char name[196];
......@@ -596,6 +623,8 @@ static pwr_tStatus IoRackInit (
card_output_counter = 0;
latent_input_counter = 0;
latent_output_counter = 0;
no_di = 0;
no_do = 0;
/* From v4.1.3 we can have subclasses, find the super class */
......@@ -648,6 +677,7 @@ static pwr_tStatus IoRackInit (
if (chan_di->Representation == pwr_eDataRepEnum_Bit32)
chanp->mask = swap32((unsigned short) chanp->mask);
if (chan_di->Number == 0) latent_input_counter = GetChanSize(chan_di->Representation);
no_di++;
// printf("Di channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_di->Number, chanp->offset);
break;
......@@ -696,6 +726,7 @@ static pwr_tStatus IoRackInit (
if (chan_do->Representation == pwr_eDataRepEnum_Bit32)
chanp->mask = swap32((unsigned short) chanp->mask);
if (chan_do->Number == 0) latent_output_counter = GetChanSize(chan_do->Representation);
no_do++;
// printf("Do channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_do->Number, chanp->offset);
break;
......@@ -727,6 +758,8 @@ static pwr_tStatus IoRackInit (
local_card->input_size = card_input_counter + latent_input_counter;
local_card->output_size = card_output_counter + latent_output_counter;
local_card->no_di = no_di;
local_card->no_do = no_do;
cardp = cardp->next;
}
......@@ -757,7 +790,7 @@ static pwr_tStatus IoRackRead (
sp = (pwr_sClass_Modbus_TCP_Slave *) rp->op;
if (sp->Status == MB__CONNDOWN && sp->DisableSlave != 1) {
if (((sp->Status == MB__CONNDOWN) || (sp->Status == MB__CONNLOST)) && sp->DisableSlave != 1) {
/* Reconnect */
time_GetTimeMonotonic( &now);
......
......@@ -58,6 +58,8 @@
#define PB_UDATA_DIAG 1
#define MB_MAX_CONNECTIONS 20
typedef pwr_tMask mb_tSendMask;
typedef enum {
......@@ -93,6 +95,43 @@ typedef struct {
short int no_do;
} io_sCardLocal;
typedef struct {
pwr_tTime last_req_time;
thread_s t;
int c_socket;
struct sockaddr_in addr;
socklen_t addrlen;
int occupied;
} io_sServerConnection;
typedef struct {
int initialized;
int s;
int current_socket;
short int trans_id;
struct sockaddr_in loc_addr; /* Remote socket description */
int input_size;
int output_size;
thread_sMutex mutex;
io_sServerConnection connections[MB_MAX_CONNECTIONS];
} io_sServerLocal;
typedef struct {
void *input_area;
void *output_area;
int scancount[IO_MAXCHAN];
int trans_id;
int input_size;
int output_size;
int no_di;
int no_do;
int di_offset;
int do_offset;
int di_size;
int do_size;
} io_sServerModuleLocal;
#pragma pack(1)
typedef struct
{
......@@ -145,6 +184,14 @@ typedef struct _write_coils_req {
unsigned char reg[250];
} write_coils_req;
typedef struct _read_dev_id_req {
mbap_header head;
unsigned char fc;
unsigned char mei_type;
unsigned char id_code;
unsigned char object_id;
} read_dev_id_req;
typedef struct _res_write {
unsigned char fc;
short int addr;
......@@ -163,6 +210,45 @@ typedef struct _res_fault {
unsigned char ec;
} res_fault;
typedef struct _rsp_fault {
mbap_header head;
unsigned char fc;
unsigned char ec;
} rsp_fault;
typedef struct _rsp_read {
mbap_header head;
unsigned char fc;
unsigned char bc;
short int buf[250];
} rsp_read;
typedef struct _rsp_write {
mbap_header head;
unsigned char fc;
short int addr;
short int quant;
} rsp_write;
typedef struct _rsp_single_write {
mbap_header head;
unsigned char fc;
short int addr;
short int value;
} rsp_single_write;
typedef struct _rsp_dev_id {
mbap_header head;
unsigned char fc;
unsigned char mei_type;
unsigned char id_code;
unsigned char conformity_level;
unsigned char more_follows;
unsigned char next_object_id;
unsigned char number_of_objects;
unsigned char list[80];
} rsp_dev_id;
#pragma pack(0)
pwr_tStatus mb_recv_data(io_sRackLocal *local,
......
......@@ -3,3 +3,5 @@ MotionControl_USBIO
Modbus_TCP_Slave
Modbus_Module
Modbus_Master
Modbus_TCP_Server
Modbus_TCP_ServerModule
This diff is collapsed.
......@@ -170,6 +170,7 @@ int main (
/* Once threads has set their priority don't run as root */
#if 0
ruid = getuid();
if (ruid == 0) {
......@@ -180,6 +181,7 @@ int main (
}
else
setreuid(ruid, ruid);
#endif
qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcInitDone);
qcom_WaitAnd(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_newPlcStart, qcom_cTmoEternal);
......
......@@ -29,6 +29,8 @@
#if defined(OS_LINUX)
# include <pwd.h>
# include <signal.h>
# include <linux/capability.h>
# include <sys/types.h>
#endif
#include "pwr.h"
......@@ -98,23 +100,6 @@ plc_thread (
phase = (long int)que_Get(&sts, &tp->q_in, NULL, NULL);
pwr_Assert(phase == 2);
/* Once thread's has set it's priority don't run as root */
#if defined(OS_LINUX)
struct passwd *pwd;
ruid = getuid();
if (ruid == 0) {
pwd = getpwnam("pwrp");
if (pwd != NULL) {
setreuid(pwd->pw_uid, pwd->pw_uid);
}
}
else
setreuid(ruid, ruid);
#endif
/* Phase 2. */
tp->init(2, tp);
......@@ -133,6 +118,24 @@ plc_thread (
errh_SetStatus( PLC__ERRINITIO);
}
/* Once thread's has set it's priority don't run as root */
#if defined(OS_LINUX)
struct passwd *pwd;
ruid = getuid();
if (ruid == 0) {
pwd = getpwnam("pwrp");
if (pwd != NULL) {
setreuid(pwd->pw_uid, pwd->pw_uid);
}
}
else
setreuid(ruid, ruid);
#endif
tp->init(0, tp);
if (tp->pp->IOHandler->IOReadWriteFlag) {
......
......@@ -273,6 +273,11 @@ SObject pwrb:Class
Attr SigValueUnit = "V"
EndBody
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "ChanIi-PostCreate"
EndBody
EndObject
Object Defaults $Object
Body SysBody
Attr Name = "%02.2d"
......
......@@ -261,6 +261,11 @@ SObject pwrb:Class
Attr Name = "%02.2d"
EndBody
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "ChanIi-PostCreate"
EndBody
EndObject
Object ConfiguratorPcsnn $Menu
Object Pointed $Menu
Object SetDefaults $MenuButton
......
......@@ -165,6 +165,11 @@ SObject pwrb:Class
Attr Name = "%02.2d"
EndBody
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "ChanDi-PostCreate"
EndBody
EndObject
Object ConfiguratorPcsnn $Menu
Object Pointed $Menu
Object SetDefaults $MenuButton
......
......@@ -197,6 +197,11 @@ SObject pwrb:Class
Attr Name = "%02.2d"
EndBody
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "ChanDi-PostCreate"
EndBody
EndObject
Object ConfiguratorPcsnn $Menu
Object Pointed $Menu
Object SetDefaults $MenuButton
......
......@@ -109,6 +109,11 @@ SObject pwrb:Class
Attr Representation = 0
EndBody
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "ChanIi-PostCreate"
EndBody
EndObject
Object RtXtt $RtMenu
Object Signal $MenuRef
Body SysBody
......
......@@ -138,6 +138,11 @@ SObject pwrb:Class
EndBody
EndObject
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "ChanIi-PostCreate"
EndBody
EndObject
Object RtXtt $RtMenu
Object Signal $MenuRef
Body SysBody
......
......@@ -27,8 +27,8 @@
#include "pwr_baseclasses.h"
#include "wb_ldh.h"
#include "wb_wsx.h"
#include "wb_session.h"
/*----------------------------------------------------------------------------*\
Syntax check.
\*----------------------------------------------------------------------------*/
......@@ -46,6 +46,104 @@ static pwr_tStatus SyntaxCheck (
return PWRB__SUCCESS;
}
static pwr_tStatus PostCreate( ldh_tSesContext Session,
pwr_tObjid Object,
pwr_tObjid Father,
pwr_tClassId Class)
{
wb_session *sp = (wb_session *)Session;
int repr_set = 0;
// Fetch Representation from previous sibling
wb_object o = sp->object( Object);
if ( !o) return o.sts();
wb_object before = o.before();
if ( before && before.cid() == o.cid()) {
// Set Representation
wb_attribute ba_repr = sp->attribute( before.oid(), "RtBody", "Representation");
if ( !ba_repr) return ba_repr.sts();
pwr_eDataRepEnum repr;
ba_repr.value( &repr);
wb_attribute a_repr = sp->attribute( Object, "RtBody", "Representation");
if ( !a_repr) return a_repr.sts();
try {
sp->writeAttribute( a_repr, &repr, sizeof(repr));
}
catch ( wb_error& e) {
return e.sts();
}
if ( sp->evenSts()) return sp->sts();
repr_set = 1;
// Set Number
wb_attribute ba_num = sp->attribute( before.oid(), "RtBody", "Number");
if ( !ba_num) return ba_num.sts();
pwr_tUInt16 num;
ba_num.value( &num);
num++;
pwr_tUInt16 max_num;
switch ( repr) {
case pwr_eDataRepEnum_Bit8:
max_num = 7;
break;
case pwr_eDataRepEnum_Bit16:
max_num = 15;
break;
case pwr_eDataRepEnum_Bit32:
max_num = 31;
break;
case pwr_eDataRepEnum_Bit64:
max_num = 63;
break;
default:
max_num = 31;
}
if ( num > max_num)
num = 0;
wb_attribute a_num = sp->attribute( Object, "RtBody", "Number");
if ( !a_num) return a_num.sts();
try {
sp->writeAttribute( a_num, &num, sizeof(num));
}
catch ( wb_error& e) {
return e.sts();
}
if ( sp->evenSts()) return sp->sts();
}
if ( !repr_set) {
wb_cdef father_cdef = sp->cdef(Class);
if ( strcmp( father_cdef.name(), "Modbus_TCP_ServerModule") == 0 ||
strcmp( father_cdef.name(), "Modbus_Module") == 0) {
wb_attribute a = sp->attribute( Object, "RtBody", "Representation");
if ( !a) return a.sts();
pwr_eDataRepEnum value = pwr_eDataRepEnum_Bit8;
try {
sp->writeAttribute( a, &value, sizeof(value));
}
catch ( wb_error& e) {
return e.sts();
}
if ( sp->evenSts()) return sp->sts();
}
}
return PWRB__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
......@@ -53,5 +151,6 @@ static pwr_tStatus SyntaxCheck (
pwr_dExport pwr_BindMethods(ChanDi) = {
pwr_BindMethod(SyntaxCheck),
pwr_BindMethod(PostCreate),
pwr_NullMethod
};
......@@ -27,6 +27,7 @@
#include "pwr_baseclasses.h"
#include "wb_ldh.h"
#include "wb_wsx.h"
#include "wb_session.h"
/*----------------------------------------------------------------------------*\
......@@ -46,6 +47,65 @@ static pwr_tStatus SyntaxCheck (
return PWRB__SUCCESS;
}
static pwr_tStatus PostCreate( ldh_tSesContext Session,
pwr_tObjid Object,
pwr_tObjid Father,
pwr_tClassId Class)
{
wb_session *sp = (wb_session *)Session;
int repr_set = 0;
// Fetch Representation from previous sibling
wb_object o = sp->object( Object);
if ( !o) return o.sts();
wb_object before = o.before();
if ( before && before.cid() == o.cid()) {
// Set Representation
wb_attribute ba_repr = sp->attribute( before.oid(), "RtBody", "Representation");
if ( !ba_repr) return ba_repr.sts();
pwr_eDataRepEnum repr;
ba_repr.value( &repr);
wb_attribute a_repr = sp->attribute( Object, "RtBody", "Representation");
if ( !a_repr) return a_repr.sts();
try {
sp->writeAttribute( a_repr, &repr, sizeof(repr));
}
catch ( wb_error& e) {
return e.sts();
}
if ( sp->evenSts()) return sp->sts();
repr_set = 1;
}
if ( !repr_set) {
wb_cdef father_cdef = sp->cdef(Class);
if ( strcmp( father_cdef.name(), "Modbus_TCP_ServerModule") == 0 ||
strcmp( father_cdef.name(), "Modbus_Module") == 0) {
wb_attribute a = sp->attribute( Object, "RtBody", "Representation");
if ( !a) return a.sts();
pwr_eDataRepEnum value = pwr_eDataRepEnum_Int16;
try {
sp->writeAttribute( a, &value, sizeof(value));
}
catch ( wb_error& e) {
return e.sts();
}
if ( sp->evenSts()) return sp->sts();
}
}
return PWRB__SUCCESS;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
......@@ -53,5 +113,6 @@ static pwr_tStatus SyntaxCheck (
pwr_dExport pwr_BindMethods(ChanIi) = {
pwr_BindMethod(SyntaxCheck),
pwr_BindMethod(PostCreate),
pwr_NullMethod
};
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