Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
proview
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Esteban Blanc
proview
Commits
185ac1f1
Commit
185ac1f1
authored
Dec 09, 2009
by
Claes Sjofors
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modbus TCP server implemented
parent
ab87999a
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
2090 additions
and
49 deletions
+2090
-49
otherio/changelog.txt
otherio/changelog.txt
+2
-1
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_server.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_server.c
+1161
-0
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_servermodule.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_servermodule.c
+159
-0
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_slave.c
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_slave.c
+42
-9
otherio/lib/rt/src/os_linux/rt_io_mb_locals.h
otherio/lib/rt/src/os_linux/rt_io_mb_locals.h
+86
-0
otherio/lib/rt/src/rt_io_otherio.meth
otherio/lib/rt/src/rt_io_otherio.meth
+2
-0
otherio/wbl/mcomp/src/otherio.wb_load
otherio/wbl/mcomp/src/otherio.wb_load
+425
-21
src/exp/rt/src/rt_plc_process.c
src/exp/rt/src/rt_plc_process.c
+2
-0
src/lib/rt/src/rt_plc_thread.c
src/lib/rt/src/rt_plc_thread.c
+20
-17
src/wbl/pwrb/src/pwrb_c_chanai.wb_load
src/wbl/pwrb/src/pwrb_c_chanai.wb_load
+5
-0
src/wbl/pwrb/src/pwrb_c_chanao.wb_load
src/wbl/pwrb/src/pwrb_c_chanao.wb_load
+5
-0
src/wbl/pwrb/src/pwrb_c_chandi.wb_load
src/wbl/pwrb/src/pwrb_c_chandi.wb_load
+5
-0
src/wbl/pwrb/src/pwrb_c_chando.wb_load
src/wbl/pwrb/src/pwrb_c_chando.wb_load
+5
-0
src/wbl/pwrb/src/pwrb_c_chanii.wb_load
src/wbl/pwrb/src/pwrb_c_chanii.wb_load
+5
-0
src/wbl/pwrb/src/pwrb_c_chanio.wb_load
src/wbl/pwrb/src/pwrb_c_chanio.wb_load
+5
-0
wb/lib/wb/src/wb_c_chandi.cpp
wb/lib/wb/src/wb_c_chandi.cpp
+100
-1
wb/lib/wb/src/wb_c_chanii.cpp
wb/lib/wb/src/wb_c_chanii.cpp
+61
-0
No files found.
otherio/changelog.txt
View file @
185ac1f1
...
...
@@ -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 mo
o
re 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.
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_server.c
0 → 100644
View file @
185ac1f1
/*
* 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.
*/
/* rt_io_m_mb_tcp_server.c -- io methods for Modbus/TCP Server */
#include <stdio.h>
#include <string.h>
#include <errno.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 <pthread.h>
#include "pwr.h"
#include "co_cdh.h"
#include "pwr_baseclasses.h"
#include "pwr_basecomponentclasses.h"
#include "pwr_otherioclasses.h"
#include "pwr_version.h"
#include "rt_gdh.h"
#include "rt_io_base.h"
#include "rt_io_bus.h"
#include "rt_thread.h"
#include "rt_io_msg.h"
#include "rt_errh.h"
#include "rt_thread.h"
#include "co_cdh.h"
#include "co_time.h"
#include "rt_mb_msg.h"
#include "rt_io_mb_locals.h"
char
rcv_buffer
[
65536
];
static
pwr_tStatus
mb_init_channels
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
);
static
void
mb_shift_write
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
);
static
void
mb_shift_read
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
);
typedef
struct
{
io_sRack
*
rp
;
int
idx
;
}
mb_sCondata
;
static
void
mb_close_connection
(
io_sRack
*
rp
,
int
l_idx
)
{
pwr_sClass_Modbus_TCP_Server
*
op
=
(
pwr_sClass_Modbus_TCP_Server
*
)
rp
->
op
;
io_sServerLocal
*
local
=
rp
->
Local
;
pwr_tStatus
sts
;
sts
=
thread_Cancel
(
&
local
->
connections
[
l_idx
].
t
);
close
(
local
->
connections
[
l_idx
].
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
op
->
Connections
--
;
}
static
void
*
mb_receive
(
void
*
data
)
{
io_sRack
*
rp
=
((
mb_sCondata
*
)
data
)
->
rp
;
int
l_idx
=
((
mb_sCondata
*
)
data
)
->
idx
;
io_sServerLocal
*
local
=
rp
->
Local
;
int
c_socket
=
local
->
connections
[
l_idx
].
c_socket
;
pwr_sClass_Modbus_TCP_Server
*
op
=
(
pwr_sClass_Modbus_TCP_Server
*
)
rp
->
op
;
ssize_t
data_size
;
rec_buf
*
rb
;
unsigned
char
fc
;
unsigned
char
exception_code
;
ssize_t
ssts
;
int
size_of_msg
;
free
(
data
);
op
->
Connections
++
;
while
(
1
)
{
size_of_msg
=
0
;
data_size
=
recv
(
c_socket
,
rcv_buffer
,
sizeof
(
rec_buf
),
0
);
if
(
data_size
<
0
)
{
op
->
ErrorCount
++
;
continue
;
}
if
(
data_size
==
0
)
{
/* Disconnected */
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
if
(
op
->
DisableServer
)
continue
;
while
(
data_size
>
0
)
{
if
(
data_size
<
sizeof
(
mbap_header
))
break
;
op
->
RX_packets
++
;
rb
=
(
rec_buf
*
)
&
rcv_buffer
[
size_of_msg
];
if
(
rb
->
head
.
length
==
0
)
break
;
size_of_msg
+=
ntohs
(
rb
->
head
.
length
)
+
6
;
data_size
-=
ntohs
(
rb
->
head
.
length
)
+
6
;
fc
=
(
unsigned
char
)
*
rb
->
buf
;
time_GetTime
(
&
local
->
connections
[
l_idx
].
last_req_time
);
exception_code
=
0
;
switch
(
fc
)
{
case
pwr_eModbus_FCEnum_ReadHoldingRegisters
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_TCP_ServerModule
*
mp
;
read_req
*
rmsg
=
(
read_req
*
)
rb
;
rsp_read
msg
;
int
found
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
head
.
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_TCP_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
addr
-=
mp
->
ReadAddress
;
if
(
addr
<
0
||
addr
+
quant
*
2
>
local_card
->
output_size
)
{
exception_code
=
2
;
break
;
}
msg
.
fc
=
fc
;
msg
.
bc
=
quant
*
2
;
msg
.
head
.
trans_id
=
rmsg
->
head
.
trans_id
;
// msg.head.length = htons( sizeof(msg) - 6);
msg
.
head
.
length
=
htons
(
sizeof
(
msg
)
-
sizeof
(
msg
.
buf
)
+
quant
*
2
-
6
);
msg
.
head
.
unit_id
=
rmsg
->
head
.
unit_id
;
msg
.
head
.
proto_id
=
rmsg
->
head
.
proto_id
;
thread_MutexLock
(
&
local
->
mutex
);
memcpy
(
msg
.
buf
,
(
char
*
)
local_card
->
output_area
+
addr
,
quant
*
2
);
thread_MutexUnlock
(
&
local
->
mutex
);
ssts
=
send
(
c_socket
,
&
msg
,
ntohs
(
msg
.
head
.
length
)
+
6
,
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_ReadCoils
:
case
pwr_eModbus_FCEnum_ReadDiscreteInputs
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_TCP_ServerModule
*
mp
;
read_req
*
rmsg
=
(
read_req
*
)
rb
;
rsp_read
msg
;
int
found
;
unsigned
char
mask
;
unsigned
int
bytes
;
int
i
;
int
offs
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
head
.
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_TCP_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
offs
=
addr
/
8
;
bytes
=
(
addr
+
quant
)
/
8
+
(((
addr
+
quant
)
%
8
==
0
)
?
0
:
1
)
-
offs
;
if
(
addr
<
0
||
offs
+
bytes
+
local_card
->
do_offset
>
local_card
->
output_size
||
offs
+
bytes
>
local_card
->
do_size
)
{
exception_code
=
2
;
break
;
}
memset
(
&
msg
,
0
,
sizeof
(
msg
));
msg
.
fc
=
fc
;
msg
.
bc
=
bytes
;
msg
.
head
.
trans_id
=
rmsg
->
head
.
trans_id
;
// msg.head.length = htons( sizeof(msg) - 6);
msg
.
head
.
length
=
htons
(
sizeof
(
msg
)
-
sizeof
(
msg
.
buf
)
+
bytes
-
6
);
msg
.
head
.
unit_id
=
rmsg
->
head
.
unit_id
;
msg
.
head
.
proto_id
=
rmsg
->
head
.
proto_id
;
thread_MutexLock
(
&
local
->
mutex
);
if
(
addr
%
8
==
0
)
{
memcpy
(
msg
.
buf
,
(
char
*
)
local_card
->
output_area
+
local_card
->
do_offset
+
addr
/
8
,
bytes
);
mask
=
0
;
for
(
i
=
0
;
i
<
quant
%
8
;
i
++
)
mask
|=
1
<<
i
;
if
(
quant
%
8
!=
0
)
{
unsigned
char
*
b
=
(
unsigned
char
*
)
msg
.
buf
;
b
[
bytes
-
1
]
&=
mask
;
}
}
else
{
mb_shift_read
(
(
unsigned
char
*
)
local_card
->
output_area
+
local_card
->
do_offset
+
addr
/
8
,
(
unsigned
char
*
)
msg
.
buf
,
addr
%
8
,
quant
);
}
thread_MutexUnlock
(
&
local
->
mutex
);
ssts
=
send
(
c_socket
,
&
msg
,
ntohs
(
msg
.
head
.
length
)
+
6
,
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteSingleRegister
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_TCP_ServerModule
*
mp
;
write_single_req
*
rmsg
=
(
write_single_req
*
)
rb
;
rsp_single_write
msg
;
int
found
;
short
addr
=
ntohs
(
rmsg
->
addr
);
unsigned
char
unit_id
=
rmsg
->
head
.
unit_id
;
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_TCP_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
addr
-=
mp
->
WriteAddress
;
if
(
addr
<
0
||
addr
+
2
>
local_card
->
input_size
)
{
exception_code
=
2
;
break
;
}
thread_MutexLock
(
&
local
->
mutex
);
memcpy
(
(
char
*
)
local_card
->
input_area
+
addr
,
&
rmsg
->
value
,
2
);
thread_MutexUnlock
(
&
local
->
mutex
);
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
value
=
rmsg
->
value
;
msg
.
head
.
trans_id
=
rmsg
->
head
.
trans_id
;
msg
.
head
.
length
=
htons
(
sizeof
(
msg
)
-
6
);
msg
.
head
.
unit_id
=
rmsg
->
head
.
unit_id
;
msg
.
head
.
proto_id
=
rmsg
->
head
.
proto_id
;
ssts
=
send
(
c_socket
,
&
msg
,
sizeof
(
msg
),
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteMultipleRegisters
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_TCP_ServerModule
*
mp
;
write_reg_req
*
rmsg
=
(
write_reg_req
*
)
rb
;
rsp_write
msg
;
int
found
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
head
.
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_TCP_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
addr
-=
mp
->
WriteAddress
;
if
(
addr
<
0
||
addr
+
quant
*
2
>
local_card
->
input_size
)
{
exception_code
=
2
;
break
;
}
thread_MutexLock
(
&
local
->
mutex
);
memcpy
(
(
char
*
)
local_card
->
input_area
+
addr
,
rmsg
->
reg
,
quant
*
2
);
thread_MutexUnlock
(
&
local
->
mutex
);
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
quant
=
rmsg
->
quant
;
msg
.
head
.
trans_id
=
rmsg
->
head
.
trans_id
;
msg
.
head
.
length
=
htons
(
sizeof
(
msg
)
-
6
);
msg
.
head
.
unit_id
=
rmsg
->
head
.
unit_id
;
msg
.
head
.
proto_id
=
rmsg
->
head
.
proto_id
;
ssts
=
send
(
c_socket
,
&
msg
,
sizeof
(
msg
),
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteSingleCoil
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_TCP_ServerModule
*
mp
;
write_single_req
*
rmsg
=
(
write_single_req
*
)
rb
;
rsp_single_write
msg
;
int
found
;
unsigned
char
mask
;
int
offs
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
value
=
ntohs
(
rmsg
->
value
);
unsigned
char
unit_id
=
rmsg
->
head
.
unit_id
;
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_TCP_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
offs
=
addr
/
8
;
if
(
addr
<
0
||
offs
+
local_card
->
di_offset
>=
local_card
->
input_size
||
offs
>=
local_card
->
di_size
)
{
exception_code
=
2
;
break
;
}
mask
=
1
<<
(
addr
%
8
);
thread_MutexLock
(
&
local
->
mutex
);
if
(
value
)
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
offs
)
|=
mask
;
else
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
offs
)
&=
~
mask
;
thread_MutexUnlock
(
&
local
->
mutex
);
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
value
=
rmsg
->
value
;
msg
.
head
.
trans_id
=
rmsg
->
head
.
trans_id
;
msg
.
head
.
length
=
htons
(
sizeof
(
msg
)
-
6
);
msg
.
head
.
unit_id
=
rmsg
->
head
.
unit_id
;
msg
.
head
.
proto_id
=
rmsg
->
head
.
proto_id
;
ssts
=
send
(
c_socket
,
&
msg
,
sizeof
(
msg
),
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
break
;
}
case
pwr_eModbus_FCEnum_WriteMultipleCoils
:
{
io_sCard
*
cardp
;
io_sServerModuleLocal
*
local_card
;
pwr_sClass_Modbus_TCP_ServerModule
*
mp
;
write_reg_req
*
rmsg
=
(
write_reg_req
*
)
rb
;
rsp_write
msg
;
int
found
;
unsigned
char
mask
;
unsigned
int
bytes
;
int
i
;
int
offs
;
short
addr
=
ntohs
(
rmsg
->
addr
);
short
quant
=
ntohs
(
rmsg
->
quant
);
unsigned
char
unit_id
=
rmsg
->
head
.
unit_id
;
if
(
quant
<
1
||
quant
>=
0x07d0
)
{
exception_code
=
3
;
break
;
}
/* Check the address */
found
=
0
;
for
(
cardp
=
rp
->
cardlist
;
cardp
;
cardp
=
cardp
->
next
)
{
mp
=
(
pwr_sClass_Modbus_TCP_ServerModule
*
)
cardp
->
op
;
if
(
mp
->
UnitId
==
unit_id
)
{
local_card
=
cardp
->
Local
;
found
=
1
;
break
;
}
}
if
(
!
found
)
{
exception_code
=
2
;
break
;
}
offs
=
addr
/
8
;
bytes
=
(
addr
+
quant
)
/
8
+
(((
addr
+
quant
)
%
8
==
0
)
?
0
:
1
)
-
offs
;
if
(
addr
<
0
||
offs
+
bytes
+
local_card
->
di_offset
>
local_card
->
input_size
||
offs
+
bytes
>
local_card
->
di_size
)
{
exception_code
=
2
;
break
;
}
thread_MutexLock
(
&
local
->
mutex
);
if
(
addr
%
8
==
0
)
{
if
(
quant
%
8
!=
0
)
{
mask
=
0
;
for
(
i
=
0
;
i
<
quant
%
8
;
i
++
)
mask
|=
1
<<
i
;
memcpy
(
(
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
,
rmsg
->
reg
,
bytes
-
1
);
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
+
bytes
-
1
)
&=
~
mask
;
*
((
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
+
bytes
-
1
)
|=
*
((
char
*
)
rmsg
->
reg
+
bytes
-
1
)
&
mask
;
}
else
memcpy
(
(
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
,
rmsg
->
reg
,
bytes
);
}
else
{
mb_shift_write
(
(
unsigned
char
*
)
rmsg
->
reg
,
(
unsigned
char
*
)
local_card
->
input_area
+
local_card
->
di_offset
+
addr
/
8
,
addr
%
8
,
quant
);
}
thread_MutexUnlock
(
&
local
->
mutex
);
msg
.
fc
=
fc
;
msg
.
addr
=
rmsg
->
addr
;
msg
.
quant
=
rmsg
->
quant
;
msg
.
head
.
trans_id
=
rmsg
->
head
.
trans_id
;
msg
.
head
.
length
=
htons
(
sizeof
(
msg
)
-
6
);
msg
.
head
.
unit_id
=
rmsg
->
head
.
unit_id
;
msg
.
head
.
proto_id
=
rmsg
->
head
.
proto_id
;
ssts
=
send
(
c_socket
,
&
msg
,
sizeof
(
msg
),
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
break
;
}
case
43
:
{
/* Encapsulated Interface Transport, Read Device Identification */
read_dev_id_req
*
rmsg
=
(
read_dev_id_req
*
)
rb
;
rsp_dev_id
msg
;
int
i
;
int
len
;
if
(
rmsg
->
mei_type
!=
0x2b
)
{
exception_code
=
1
;
break
;
}
if
(
rmsg
->
id_code
!=
1
)
{
exception_code
=
1
;
break
;
}
if
(
rmsg
->
object_id
!=
0
)
{
exception_code
=
1
;
break
;
}
msg
.
fc
=
rmsg
->
fc
;
msg
.
mei_type
=
rmsg
->
mei_type
;
msg
.
id_code
=
rmsg
->
id_code
;
msg
.
conformity_level
=
1
;
msg
.
more_follows
=
0
;
msg
.
next_object_id
=
0
;
msg
.
number_of_objects
=
3
;
i
=
0
;
/* Vendor name */
msg
.
list
[
i
++
]
=
0
;
len
=
strlen
(
"Proview"
);
msg
.
list
[
i
++
]
=
len
;
strncpy
(
(
char
*
)
&
msg
.
list
[
i
],
"Proview"
,
len
);
i
+=
len
;
/* Product code */
msg
.
list
[
i
++
]
=
0
;
len
=
strlen
(
"-"
);
msg
.
list
[
i
++
]
=
len
;
strncpy
(
(
char
*
)
&
msg
.
list
[
i
],
"-"
,
len
);
i
+=
len
;
/* Major Minor Revision */
msg
.
list
[
i
++
]
=
0
;
len
=
strlen
(
pwrv_cPwrVersionStr
);
msg
.
list
[
i
++
]
=
len
;
strncpy
(
(
char
*
)
&
msg
.
list
[
i
],
pwrv_cPwrVersionStr
,
len
);
i
+=
len
;
msg
.
head
.
trans_id
=
rmsg
->
head
.
trans_id
;
msg
.
head
.
length
=
htons
(
sizeof
(
msg
)
-
sizeof
(
msg
.
list
)
+
i
-
6
);
msg
.
head
.
unit_id
=
rmsg
->
head
.
unit_id
;
msg
.
head
.
proto_id
=
rmsg
->
head
.
proto_id
;
ssts
=
send
(
c_socket
,
&
msg
,
ntohs
(
msg
.
head
.
length
)
+
6
,
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
break
;
}
default:
exception_code
=
1
;
}
if
(
exception_code
)
{
rsp_fault
rsp_f
;
rsp_f
.
fc
=
fc
+
0x80
;
rsp_f
.
ec
=
exception_code
;
rsp_f
.
head
.
trans_id
=
rb
->
head
.
trans_id
;
rsp_f
.
head
.
length
=
htons
(
sizeof
(
rsp_f
)
-
6
);
rsp_f
.
head
.
unit_id
=
rb
->
head
.
unit_id
;
ssts
=
send
(
c_socket
,
&
rsp_f
,
sizeof
(
rsp_f
),
MSG_DONTWAIT
);
if
(
ssts
<
0
)
{
op
->
Connections
--
;
close
(
c_socket
);
local
->
connections
[
l_idx
].
occupied
=
0
;
errh_Error
(
"Connection lost for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
return
0
;
}
op
->
TX_packets
++
;
}
}
}
return
0
;
}
static
void
*
mb_connect
(
void
*
arg
)
{
io_sRack
*
rp
=
(
io_sRack
*
)
arg
;
io_sServerLocal
*
local
=
rp
->
Local
;
int
sts
;
pwr_sClass_Modbus_TCP_Server
*
op
;
struct
sockaddr_in
r_addr
;
socklen_t
r_addr_len
;
int
c_socket
;
mb_sCondata
*
condata
;
int
idx
;
int
found
;
int
i
;
op
=
(
pwr_sClass_Modbus_TCP_Server
*
)
rp
->
op
;
while
(
1
)
{
/* Wait for client connect request */
r_addr_len
=
sizeof
(
r_addr
);
c_socket
=
accept
(
local
->
s
,
(
struct
sockaddr
*
)
&
r_addr
,
&
r_addr_len
);
if
(
c_socket
<
0
)
{
errh_Error
(
"Error accept IO modbus tcp server %s, %d"
,
rp
->
Name
,
local
->
s
);
continue
;
}
if
(
op
->
DisableServer
)
continue
;
errh_Info
(
"Connection accepted for IO modbus tcp server %s, %d"
,
rp
->
Name
,
c_socket
);
/* Close other connections to this address */
for
(
i
=
0
;
i
<
MB_MAX_CONNECTIONS
;
i
++
)
{
if
(
local
->
connections
[
i
].
occupied
&&
r_addr_len
==
local
->
connections
[
i
].
addrlen
&&
r_addr
.
sin_family
==
local
->
connections
[
i
].
addr
.
sin_family
&&
memcmp
(
&
r_addr
.
sin_addr
,
&
local
->
connections
[
i
].
addr
.
sin_addr
,
sizeof
(
r_addr
.
sin_addr
))
==
0
)
{
mb_close_connection
(
rp
,
i
);
}
}
/* Find next empty in connection list */
found
=
0
;
for
(
i
=
0
;
i
<
MB_MAX_CONNECTIONS
;
i
++
)
{
if
(
!
local
->
connections
[
i
].
occupied
)
{
found
=
1
;
idx
=
i
;
break
;
}
}
if
(
!
found
)
{
/* Remove the oldest connection */
int
oldest_idx
=
0
;
for
(
i
=
1
;
i
<
MB_MAX_CONNECTIONS
;
i
++
)
{
if
(
time_Acomp
(
&
local
->
connections
[
i
].
last_req_time
,
&
local
->
connections
[
oldest_idx
].
last_req_time
)
<
0
)
oldest_idx
=
i
;
}
mb_close_connection
(
rp
,
oldest_idx
);
errh_Info
(
"Connection closed, IO modbus tcp server %s, %d"
,
rp
->
Name
,
local
->
s
);
idx
=
oldest_idx
;
}
local
->
connections
[
idx
].
c_socket
=
c_socket
;
local
->
connections
[
idx
].
occupied
=
1
;
time_GetTime
(
&
local
->
connections
[
idx
].
last_req_time
);
local
->
connections
[
idx
].
addrlen
=
r_addr_len
;
memcpy
(
&
local
->
connections
[
idx
].
addr
,
&
r_addr
,
r_addr_len
);
/* Create a thread for this connection */
condata
=
(
mb_sCondata
*
)
malloc
(
sizeof
(
mb_sCondata
));
condata
->
rp
=
rp
;
condata
->
idx
=
idx
;
sts
=
thread_Create
(
&
local
->
connections
[
idx
].
t
,
0
,
mb_receive
,
(
void
*
)
condata
);
if
(
EVEN
(
sts
))
{
local
->
connections
[
idx
].
occupied
=
0
;
errh_Error
(
"Error creating thread IO modbus tcp server %s, %d"
,
rp
->
Name
,
local
->
s
);
free
(
condata
);
continue
;
}
}
return
0
;
}
/*----------------------------------------------------------------------------*\
Init method for the Modbus/TCP server
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackInit
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
io_sServerLocal
*
local
;
pthread_t
thread
;
pwr_tOName
name
;
pwr_tStatus
sts
;
pwr_sClass_Modbus_TCP_Server
*
op
;
int
i
;
unsigned
short
port
;
op
=
(
pwr_sClass_Modbus_TCP_Server
*
)
rp
->
op
;
op
->
Connections
=
0
;
port
=
op
->
Port
==
0
?
502
:
op
->
Port
;
sts
=
gdh_ObjidToName
(
rp
->
Objid
,
(
char
*
)
&
name
,
sizeof
(
name
),
cdh_mNName
);
errh_Info
(
"Init of Modbus TCP Server %s"
,
name
);
rp
->
Local
=
calloc
(
1
,
sizeof
(
io_sServerLocal
));
local
=
rp
->
Local
;
if
(
op
->
DisableServer
)
return
IO__SUCCESS
;
/* Create socket, store in local struct */
uid_t
ruid
;
ruid
=
getuid
();
printf
(
"ruid: %d
\n
"
,
ruid
);
local
->
s
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
local
->
s
<
0
)
{
errh_Error
(
"Error creating socket for IO modbus tcp server %s, %d"
,
rp
->
Name
,
local
->
s
);
return
0
;
}
local
->
loc_addr
.
sin_family
=
AF_INET
;
local
->
loc_addr
.
sin_port
=
htons
(
port
);
for
(
i
=
0
;
i
<
10
;
i
++
)
{
sts
=
bind
(
local
->
s
,
(
struct
sockaddr
*
)
&
local
->
loc_addr
,
sizeof
(
local
->
loc_addr
));
if
(
sts
==
0
)
break
;
perror
(
"Modbus TCP Bind socket failure, retrying... "
);
sleep
(
10
);
}
if
(
sts
!=
0
)
{
printf
(
"Modbus TCP Bind socket failure, exiting"
);
errh_Error
(
"Error bind socket to port for IO modbus tcp server %s, %d"
,
rp
->
Name
,
local
->
s
);
return
0
;
}
errh_Info
(
"Modbus TCP Sever bind to port %d, %s"
,
port
,
name
);
sts
=
listen
(
local
->
s
,
16
);
sts
=
thread_MutexInit
(
&
local
->
mutex
);
if
(
EVEN
(
sts
))
return
sts
;
/* Create a thread that listens for connections */
sts
=
pthread_create
(
&
thread
,
NULL
,
mb_connect
,
(
void
*
)
rp
);
if
(
sts
!=
0
)
return
sts
;
sts
=
mb_init_channels
(
ctx
,
ap
,
rp
);
if
(
EVEN
(
sts
))
return
sts
;
op
->
Status
=
MB__NORMAL
;
return
IO__SUCCESS
;
}
static
pwr_tStatus
mb_init_channels
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
io_sServerModuleLocal
*
local_card
;
io_sCard
*
cardp
;
io_sServerLocal
*
local
;
short
input_counter
;
short
output_counter
;
short
card_input_counter
;
short
card_output_counter
;
pwr_sClass_Modbus_TCP_Server
*
op
;
pwr_sClass_Modbus_TCP_ServerModule
*
mp
;
char
name
[
196
];
pwr_tStatus
sts
;
pwr_tCid
cid
;
io_sChannel
*
chanp
;
int
i
,
latent_input_counter
,
latent_output_counter
;
pwr_tInt32
chan_size
;
pwr_sClass_ChanDi
*
chan_di
;
pwr_sClass_ChanDo
*
chan_do
;
pwr_sClass_ChanAi
*
chan_ai
;
pwr_sClass_ChanAit
*
chan_ait
;
pwr_sClass_ChanIi
*
chan_ii
;
pwr_sClass_ChanAo
*
chan_ao
;
pwr_sClass_ChanIo
*
chan_io
;
sts
=
gdh_ObjidToName
(
rp
->
Objid
,
(
char
*
)
&
name
,
sizeof
(
name
),
cdh_mNName
);
op
=
(
pwr_sClass_Modbus_TCP_Server
*
)
rp
->
op
;
local
=
rp
->
Local
;
/* Create socket, store in local struct */
/* Do configuration check and initialize modules. */
cardp
=
rp
->
cardlist
;
input_counter
=
0
;
output_counter
=
0
;
card_input_counter
=
0
;
card_output_counter
=
0
;
latent_input_counter
=
0
;
latent_output_counter
=
0
;
while
(
cardp
)
{
local_card
=
calloc
(
1
,
sizeof
(
*
local_card
));
cardp
->
Local
=
local_card
;
input_counter
=
input_counter
+
card_input_counter
+
latent_input_counter
;
output_counter
=
output_counter
+
card_output_counter
+
latent_output_counter
;
local_card
->
input_area
=
(
void
*
)
&
(
op
->
Inputs
)
+
input_counter
;
local_card
->
output_area
=
(
void
*
)
&
(
op
->
Outputs
)
+
output_counter
;
card_input_counter
=
0
;
card_output_counter
=
0
;
latent_input_counter
=
0
;
latent_output_counter
=
0
;
/* From v4.1.3 we can have subclasses, find the super class */
cid
=
cardp
->
Class
;
while
(
ODD
(
gdh_GetSuperClass
(
cid
,
&
cid
,
cardp
->
Objid
)))
;
switch
(
cid
)
{
case
pwr_cClass_Modbus_TCP_ServerModule
:
mp
=
(
pwr_sClass_Modbus_TCP_ServerModule
*
)
cardp
->
op
;
mp
->
Status
=
pwr_eModbusModule_StatusEnum_StatusUnknown
;
for
(
i
=
0
;
i
<
cardp
->
ChanListSize
;
i
++
)
{
chanp
=
&
cardp
->
chanlist
[
i
];
if
(
is_diag
(
&
chanp
->
ChanAref
))
{
chanp
->
udata
|=
PB_UDATA_DIAG
;
switch
(
chanp
->
ChanClass
)
{
case
pwr_cClass_ChanIi
:
chanp
->
offset
=
((
pwr_sClass_ChanIi
*
)
chanp
->
cop
)
->
Number
;
chanp
->
size
=
GetChanSize
(
((
pwr_sClass_ChanIi
*
)
chanp
->
cop
)
->
Representation
);
break
;
default:
errh_Error
(
"Diagnostic channel class, card %s"
,
cardp
->
Name
);
}
continue
;
}
if
(
chanp
->
ChanClass
!=
pwr_cClass_ChanDi
)
{
card_input_counter
+=
latent_input_counter
;
latent_input_counter
=
0
;
}
if
(
chanp
->
ChanClass
!=
pwr_cClass_ChanDo
)
{
card_output_counter
+=
latent_output_counter
;
latent_output_counter
=
0
;
}
switch
(
chanp
->
ChanClass
)
{
case
pwr_cClass_ChanDi
:
chan_di
=
(
pwr_sClass_ChanDi
*
)
chanp
->
cop
;
if
(
chan_di
->
Number
==
0
)
{
card_input_counter
+=
latent_input_counter
;
latent_input_counter
=
0
;
}
chanp
->
offset
=
card_input_counter
;
chanp
->
mask
=
1
<<
chan_di
->
Number
;
if
(
chan_di
->
Representation
==
pwr_eDataRepEnum_Bit16
)
chanp
->
mask
=
swap16
(
chanp
->
mask
);
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
);
if
(
local_card
->
di_size
==
0
)
local_card
->
di_offset
=
chanp
->
offset
;
if
(
chan_di
->
Number
==
0
||
local_card
->
di_size
==
0
)
local_card
->
di_size
+=
GetChanSize
(
chan_di
->
Representation
);
// printf("Di channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_di->Number, chanp->offset);
break
;
case
pwr_cClass_ChanAi
:
chan_ai
=
(
pwr_sClass_ChanAi
*
)
chanp
->
cop
;
chanp
->
offset
=
card_input_counter
;
chan_size
=
GetChanSize
(
chan_ai
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_input_counter
+=
chan_size
;
io_AiRangeToCoef
(
chanp
);
// printf("Ai channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ai->Number, chanp->offset);
break
;
case
pwr_cClass_ChanAit
:
chan_ait
=
(
pwr_sClass_ChanAit
*
)
chanp
->
cop
;
chanp
->
offset
=
card_input_counter
;
chan_size
=
GetChanSize
(
chan_ait
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_input_counter
+=
chan_size
;
io_AiRangeToCoef
(
chanp
);
break
;
case
pwr_cClass_ChanIi
:
chan_ii
=
(
pwr_sClass_ChanIi
*
)
chanp
->
cop
;
chanp
->
offset
=
card_input_counter
;
chan_size
=
GetChanSize
(
chan_ii
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_input_counter
+=
chan_size
;
// printf("Ii channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ii->Number, chanp->offset);
break
;
case
pwr_cClass_ChanDo
:
chan_do
=
(
pwr_sClass_ChanDo
*
)
chanp
->
cop
;
if
(
chan_do
->
Number
==
0
)
{
card_output_counter
+=
latent_output_counter
;
latent_output_counter
=
0
;
}
chanp
->
offset
=
card_output_counter
;
chan_size
=
GetChanSize
(
chan_do
->
Representation
);
chanp
->
mask
=
1
<<
chan_do
->
Number
;
if
(
chan_do
->
Representation
==
pwr_eDataRepEnum_Bit16
)
chanp
->
mask
=
swap16
(
chanp
->
mask
);
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
);
if
(
local_card
->
do_size
==
0
)
local_card
->
do_offset
=
chanp
->
offset
;
if
(
chan_do
->
Number
==
0
||
local_card
->
do_size
==
0
)
local_card
->
do_size
+=
GetChanSize
(
chan_do
->
Representation
);
// printf("Do channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_do->Number, chanp->offset);
break
;
case
pwr_cClass_ChanAo
:
chan_ao
=
(
pwr_sClass_ChanAo
*
)
chanp
->
cop
;
chanp
->
offset
=
card_output_counter
;
chan_size
=
GetChanSize
(
chan_ao
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_output_counter
+=
chan_size
;
io_AoRangeToCoef
(
chanp
);
// printf("Ao channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_ao->Number, chanp->offset);
break
;
case
pwr_cClass_ChanIo
:
chan_io
=
(
pwr_sClass_ChanIo
*
)
chanp
->
cop
;
chanp
->
offset
=
card_output_counter
;
chan_size
=
GetChanSize
(
chan_io
->
Representation
);
chanp
->
size
=
chan_size
;
chanp
->
mask
=
0
;
card_output_counter
+=
chan_size
;
// printf("Io channel found in %s, Number %d, Offset %d\n", cardp->Name, chan_io->Number, chanp->offset);
break
;
}
}
/* End - for ... */
break
;
}
/* End - switch ... */
local_card
->
input_size
=
card_input_counter
+
latent_input_counter
;
local_card
->
output_size
=
card_output_counter
+
latent_output_counter
;
cardp
=
cardp
->
next
;
}
local
->
input_size
=
input_counter
+
card_input_counter
+
latent_input_counter
;
local
->
output_size
=
output_counter
+
card_output_counter
+
latent_output_counter
;
return
IO__SUCCESS
;
}
static
void
mb_shift_write
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
)
{
int
i
;
if
(
sh
+
quant
<=
8
)
{
unsigned
char
mask
=
0
;
for
(
i
=
sh
;
i
<
sh
+
quant
;
i
++
)
mask
|=
1
<<
i
;
out
[
0
]
&=
~
mask
;
out
[
0
]
|=
mask
&
(
in
[
0
]
<<
sh
);
return
;
}
for
(
i
=
0
;
i
<
(
quant
+
sh
)
/
8
;
i
++
)
{
if
(
i
==
0
)
{
unsigned
char
mask
=
~
0
<<
sh
;
out
[
0
]
&=
~
mask
;
out
[
0
]
|=
mask
&
(
in
[
0
]
<<
sh
);
}
else
{
out
[
i
]
=
in
[
i
]
<<
sh
;
out
[
i
]
|=
in
[
i
-
1
]
>>
(
8
-
sh
);
}
}
if
(
(
quant
+
sh
)
%
8
!=
0
)
{
unsigned
char
mask
=
~
0
<<
((
quant
+
sh
)
%
8
);
mask
=
~
mask
;
out
[
i
]
&=
~
mask
;
out
[
i
]
|=
mask
&
(
in
[
i
]
<<
sh
);
out
[
i
]
|=
mask
&
(
in
[
i
-
1
]
>>
(
8
-
sh
));
}
}
void
mb_shift_read
(
unsigned
char
*
in
,
unsigned
char
*
out
,
int
sh
,
int
quant
)
{
int
i
;
if
(
sh
+
quant
<=
8
)
{
unsigned
char
mask
=
~
0
;
mask
=
mask
>>
(
8
-
quant
);
out
[
0
]
=
mask
&
(
in
[
0
]
>>
sh
);
return
;
}
for
(
i
=
0
;
i
<
quant
/
8
;
i
++
)
{
out
[
i
]
=
in
[
i
]
>>
sh
;
out
[
i
]
|=
in
[
i
+
1
]
<<
(
8
-
sh
);
}
out
[
i
]
=
in
[
i
]
>>
sh
;
if
(
(
quant
+
sh
)
/
8
>
quant
/
8
)
out
[
i
]
|=
in
[
i
+
1
]
<<
(
8
-
sh
);
if
(
quant
%
8
!=
0
)
{
unsigned
char
mask
=
~
0
;
mask
=
mask
>>
(
8
-
(
quant
%
8
));
out
[
i
]
&=
mask
;
}
}
/*----------------------------------------------------------------------------*\
Read method for the Modbus TCP server
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackRead
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Write method for the Modbus_TCP server
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackWrite
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
\*----------------------------------------------------------------------------*/
static
pwr_tStatus
IoRackClose
(
io_tCtx
ctx
,
io_sAgent
*
ap
,
io_sRack
*
rp
)
{
io_sServerLocal
*
local
=
rp
->
Local
;
int
i
;
for
(
i
=
1
;
i
<
MB_MAX_CONNECTIONS
;
i
++
)
{
if
(
local
->
connections
[
i
].
occupied
)
mb_close_connection
(
rp
,
i
);
}
close
(
local
->
s
);
return
IO__SUCCESS
;
}
/*----------------------------------------------------------------------------*\
Every method to be exported to the workbench should be registred here.
\*----------------------------------------------------------------------------*/
pwr_dExport
pwr_BindIoMethods
(
Modbus_TCP_Server
)
=
{
pwr_BindIoMethod
(
IoRackInit
),
pwr_BindIoMethod
(
IoRackRead
),
pwr_BindIoMethod
(
IoRackWrite
),
pwr_BindIoMethod
(
IoRackClose
),
pwr_NullMethod
};
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_servermodule.c
0 → 100644
View file @
185ac1f1
/*
* 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
};
otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_slave.c
View file @
185ac1f1
...
...
@@ -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
);
...
...
otherio/lib/rt/src/os_linux/rt_io_mb_locals.h
View file @
185ac1f1
...
...
@@ -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
,
...
...
otherio/lib/rt/src/rt_io_otherio.meth
View file @
185ac1f1
...
...
@@ -3,3 +3,5 @@ MotionControl_USBIO
Modbus_TCP_Slave
Modbus_Module
Modbus_Master
Modbus_TCP_Server
Modbus_TCP_ServerModule
otherio/wbl/mcomp/src/otherio.wb_load
View file @
185ac1f1
Volume OtherIO $ClassVolume 0.0.250.10
Body SysBody 01-JAN-1970 01:00:00.00
Attr NextOix = "_X
60
"
Attr NextCix = "_X
6
"
Attr NextTix[0] = "_X
4
"
Attr NextOix = "_X
77
"
Attr NextCix = "_X
8
"
Attr NextTix[0] = "_X
5
"
EndBody
Object Type $TypeHier 1 15-NOV-2007 14:35:37.90
Object MotionControl_StatusEnum $TypeDef 1 15-NOV-2007 14:36:24.17
...
...
@@ -176,6 +176,13 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr Value = 5
EndBody
EndObject
Object WriteSingleRegister $Value 77 04-DEC-2009 16:09:01.59
Body SysBody 04-DEC-2009 16:09:09.77
Attr Text = "WriteSingleRegister"
Attr PgmName = "WriteSingleRegister"
Attr Value = 6
EndBody
EndObject
Object WriteMultipleCoils $Value 36 07-FEB-2008 15:57:24.44
Body SysBody 07-FEB-2008 15:57:51.21
Attr Text = "WriteMultipleCoils"
...
...
@@ -238,6 +245,60 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndBody
EndObject
EndObject
Object ModbusSever_StatusEnum $TypeDef 4 25-NOV-2009 11:10:38.85
Body SysBody 25-NOV-2009 11:07:36.39
Attr TypeRef = "pwrs:Type-$Enum"
Attr Elements = 1
EndBody
Object OK $Value 70 25-NOV-2009 11:07:36.39
Body SysBody 25-NOV-2009 11:07:36.39
Attr Text = "OK"
Attr PgmName = "OK"
EndBody
EndObject
Object IllegalFunctionCode $Value 71 25-NOV-2009 11:08:32.76
Body SysBody 25-NOV-2009 11:08:35.79
Attr Text = "IllegalFunctionCode"
Attr PgmName = "IllegalFunctionCode"
Attr Value = 1
EndBody
EndObject
Object IllegalDataAddress $Value 72 25-NOV-2009 11:07:36.39
Body SysBody 25-NOV-2009 11:07:36.39
Attr Text = "IllegalDataAddress"
Attr PgmName = "IllegalDataAddress"
Attr Value = 2
EndBody
EndObject
Object IllegalDataValue $Value 73 25-NOV-2009 11:07:36.39
Body SysBody 25-NOV-2009 11:07:36.39
Attr Text = "IllegalDataValue"
Attr PgmName = "IllegalDataValue"
Attr Value = 3
EndBody
EndObject
Object ServerFailure $Value 74 25-NOV-2009 11:08:55.88
Body SysBody 25-NOV-2009 11:08:58.05
Attr Text = "ServerFailure"
Attr PgmName = "ServerFailure"
Attr Value = 4
EndBody
EndObject
Object Acknowledge $Value 75 25-NOV-2009 11:09:36.94
Body SysBody 25-NOV-2009 11:09:39.43
Attr Text = "Acknowledge"
Attr PgmName = "Acknowledge"
Attr Value = 5
EndBody
EndObject
Object SeverBusy $Value 76 25-NOV-2009 11:09:52.33
Body SysBody 25-NOV-2009 11:09:58.88
Attr Text = "SeverBusy"
Attr PgmName = "SeverBusy"
Attr Value = 6
EndBody
EndObject
EndObject
EndObject
Object Class $ClassHier 2 15-NOV-2007 14:35:40.72
!/**
...
...
@@ -505,7 +566,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
Object RtBody $ObjBodyDef 1 08-FEB-2008 10:26:36.84
Body SysBody 08-FEB-2008 10:26:36.85
Attr StructName = "Modbus_TCP_Slave"
Attr NextAix = "_X
19
"
Attr NextAix = "_X
20
"
EndBody
!/**
! Description of slave
...
...
@@ -531,8 +592,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
! Status of the slave. Shows if tcp-link to slave is up or not.
!*/
Object Status $Attribute 3 08-FEB-2008 10:29:48.44
Body SysBody 0
8-FEB-2008 10:30:23.06
Body SysBody 0
4-DEC-2009 17:14:32.80
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$Status"
EndBody
EndObject
...
...
@@ -572,6 +634,13 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$String32"
EndBody
EndObject
Object Port $Attribute 19 04-DEC-2009 17:22:45.73
Body SysBody 04-DEC-2009 17:23:01.72
Attr PgmName = "Port"
Attr Flags = 16777216
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Flag that disables the slave.
! Flag that disables the initialization of the slave, if initialized turns off i/o-handling.
...
...
@@ -588,8 +657,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
! When ErrorCount reaches the ErrorLimit all inputs are reset to zero.
!*/
Object ErrorCount $Attribute 7 08-FEB-2008 10:50:15.18
Body SysBody 0
8-FEB-2008 10:55:49.84
Body SysBody 0
4-DEC-2009 17:14:50.70
Attr PgmName = "ErrorCount"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
...
...
@@ -612,8 +682,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
! try to reconnect at this cylicity.
!*/
Object ReconnectCount $Attribute 9 08-FEB-2008 10:56:12.51
Body SysBody 0
8-FEB-2008 10:56:17.20
Body SysBody 0
4-DEC-2009 17:15:01.53
Attr PgmName = "ReconnectCount"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
...
...
@@ -657,8 +728,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
! Received number of messages from slave.
!*/
Object RX_packets $Attribute 11 08-FEB-2008 10:57:16.79
Body SysBody 0
8-FEB-2008 10:57:21.35
Body SysBody 0
4-DEC-2009 17:15:16.28
Attr PgmName = "RX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
...
...
@@ -667,8 +739,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
! Sent number of messages to slave.
!*/
Object TX_packets $Attribute 12 08-FEB-2008 10:57:31.03
Body SysBody 0
8-FEB-2008 10:57:34.53
Body SysBody 0
4-DEC-2009 17:15:24.38
Attr PgmName = "TX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
...
...
@@ -765,7 +838,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
! the number of registers you want to read. The represenation on the ChanIi should
! be set to UInt16 or Int16. ChanAi and ChanDi is also applicable. In case of ChanDi the
! representation should be set to Bit16.
!
!
! @b WriteSingleCoil (FC 5)
! This function code is used to write to one single coil.
! Typically the output data area is defined by one ChanDo's which represent
...
...
@@ -850,19 +923,10 @@ Volume OtherIO $ClassVolume 0.0.250.10
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! @Summary Status of the module.
! Status of the module. The status can be any of:
! OK
! IllegalFunction
! IllegalDataAddress
! IllegalDataValue
! SlaveServiceFailure
! Unknown
!*/
Object Status $Attribute 7 08-FEB-2008 11:20:34.93
Body SysBody 0
8-FEB-2008 11:31:11.41
Body SysBody 0
4-DEC-2009 17:15:47.85
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "OtherIO:Type-ModbusModule_StatusEnum"
EndBody
EndObject
...
...
@@ -1032,5 +1096,345 @@ Volume OtherIO $ClassVolume 0.0.250.10
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Server object for Modbus TCP I/O.
! Server object for Modbus TCP I/O.
!
! The defines a Modbus/TCP server, i.e. makes it possible to act as a slave
! in the communication with a Modbus/TCP master.
!
! The Server object is placed in the node hierarchy under the node object.
!
! @classlink Modbus_TCP_ServerModule otherio_modbus_tcp_servermodule.html
!*/
Object Modbus_TCP_Server $ClassDef 6 25-NOV-2009 10:32:40.64
Body SysBody 25-NOV-2009 10:30:31.66
Attr Editor = 0
Attr Method = 0
Attr Flags = 8272
EndBody
Object RtBody $ObjBodyDef 1 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:32:51.18
Attr StructName = "Modbus_TCP_Server"
Attr NextAix = "_X39"
EndBody
!/**
! Description of the object.
!*/
Object Description $Attribute 19 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:30:31.66
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! Datasheet URL.
!*/
Object DataSheet $Attribute 20 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:30:31.66
Attr PgmName = "DataSheet"
Attr TypeRef = "pwrs:Type-$URL"
EndBody
EndObject
!/**
! Current status of the server.
!*/
Object Status $Attribute 21 25-NOV-2009 10:30:31.66
Body SysBody 04-DEC-2009 17:14:06.15
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$Status"
EndBody
EndObject
!/**
! @Summary Process that handles the card. Plc(1), rt_io_comm(2) or application process(4).
! Process that handles the server.
!
! 1: The server 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 server is read by the rt_io_comm process.
! 4: The server is handled by an application program.
!*/
Object Process $Attribute 22 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:30:31.66
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the server.
! The PlcThread object of the plc thread that handles the server.
! The server is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 23 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:30:31.66
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! @Summary Optional port number.
! Optional port number.
! By default the server listens to the Modbus TCP port 502.
! If another port should be used for the communication, it can be
! specified here.
!*/
Object Port $Attribute 38 04-DEC-2009 16:56:46.71
Body SysBody 04-DEC-2009 16:56:55.46
Attr PgmName = "Port"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! If Yes, the server is disabled.
!*/
Object DisableServer $Attribute 25 25-NOV-2009 10:33:08.29
Body SysBody 25-NOV-2009 10:33:10.93
Attr PgmName = "DisableServer"
Attr TypeRef = "pwrb:Type-YesNoEnum"
EndBody
EndObject
!/**
! @Summary Error count of the server.
! ErrorCount will increase every cycle if status is not MB__NORMAL.
! When ErrorCount reaches the ErrorLimit all inputs are reset to zero.
!*/
Object ErrorCount $Attribute 26 25-NOV-2009 10:30:31.66
Body SysBody 04-DEC-2009 16:55:35.20
Attr PgmName = "ErrorCount"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! @Summary Error limit of the server.
! ErrorCount will increase every cycle if status is not MB__NORMAL.
! When ErrorCount reaches the ErrorLimit all inputs are reset to zero.
!*/
Object ErrorLimit $Attribute 27 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:30:31.66
Attr PgmName = "ErrorLimit"
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Number of current connections.
!*/
Object Connections $Attribute 31 25-NOV-2009 11:03:25.72
Body SysBody 25-NOV-2009 11:04:00.16
Attr PgmName = "Connections"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Received number of messages for the server.
!*/
Object RX_packets $Attribute 32 25-NOV-2009 10:30:31.66
Body SysBody 04-DEC-2009 16:55:52.73
Attr PgmName = "RX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Sent number of messages from the server.
!*/
Object TX_packets $Attribute 33 25-NOV-2009 10:30:31.66
Body SysBody 04-DEC-2009 16:56:00.02
Attr PgmName = "TX_packets"
Attr Flags = 1040
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Input area.
! Area where alla input data is stored.
!*/
Object Inputs $Attribute 36 27-NOV-2009 09:42:27.83
Body SysBody 27-NOV-2009 09:42:46.12
Attr PgmName = "Inputs"
Attr Flags = 3090
Attr Elements = 256
Attr TypeRef = "pwrs:Type-$UInt8"
EndBody
EndObject
!/**
! @Summary Ouput area.
! Area where alla output data is stored.
!*/
Object Outputs $Attribute 37 27-NOV-2009 09:42:27.83
Body SysBody 27-NOV-2009 09:43:03.16
Attr PgmName = "Outputs"
Attr Flags = 3090
Attr Elements = 256
Attr TypeRef = "pwrs:Type-$UInt8"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 61 25-NOV-2009 10:30:31.66
Object IoRackInit $Method 62 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:34:14.57
Attr MethodName = "Modbus_TCP_Server-IoRackInit"
EndBody
EndObject
Object IoRackClose $Method 63 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:34:23.88
Attr MethodName = "Modbus_TCP_Server-IoRackClose"
EndBody
EndObject
Object IoRackRead $Method 64 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:34:31.89
Attr MethodName = "Modbus_TCP_Server-IoRackRead"
EndBody
EndObject
Object IoRackWrite $Method 65 25-NOV-2009 10:30:31.66
Body SysBody 25-NOV-2009 10:34:39.46
Attr MethodName = "Modbus_TCP_Server-IoRackWrite"
EndBody
EndObject
EndObject
Object Template Modbus_TCP_Server 2149285888 01-JAN-1970 01:00:00.00
Body RtBody 01-JAN-1970 01:00:00.00
EndBody
EndObject
EndObject
!/**
! @Version 1.0
! @Group IO
! @Summary Server Modue object for Modbus TCP I/O.
! Server Module object for Modbus TCP I/O.
!
! The Module object is placed as a child to a Modbus_TCP_Server object
! and is the father of channel objects that define the input and
! output area for the module.
!
! @classlink Modbus_TCP_Server otherio_modbus_tcp_server.html
!*/
Object Modbus_TCP_ServerModule $ClassDef 7 25-NOV-2009 11:05:45.82
Body SysBody 25-NOV-2009 11:05:23.49
Attr Editor = 0
Attr Method = 0
Attr Flags = 16464
EndBody
Object RtBody $ObjBodyDef 1 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:06:00.66
Attr StructName = "Modbus_TCP_ServerModule"
Attr NextAix = "_X21"
EndBody
!/**
! Description of the object.
!*/
Object Description $Attribute 11 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:05:23.49
Attr PgmName = "Description"
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! @Summary Address for reading registers.
! Address for reading with function code ReadHoldingRegisters.
! The value defines the starting address for the input channels
! of class ChanIi and ChanAi.
!
! Note that the address for ReadDiscreteInputs and ReadCoils are
! not affected by the ReadAddress.
!*/
Object ReadAddress $Attribute 12 04-DEC-2009 16:53:13.17
Body SysBody 04-DEC-2009 16:53:32.47
Attr PgmName = "ReadAddress"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Address for writing registers.
! Address for reading with function code WriteMultipleRegisters and
! WriteSingleRegister.
! The value defines the starting address for the output channels
! of class ChanIo and ChanAo.
!
! Note that the address for WriteSingleCoil and WriteMultipleCoils
! are not affected by the WriteAddress.
!*/
Object WriteAddress $Attribute 13 04-DEC-2009 16:53:43.87
Body SysBody 04-DEC-2009 16:53:45.81
Attr PgmName = "WriteAddress"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! @Summary Unit id.
! Identification of the modbus unit to communicate with. It is typically
! only used if communicating with a tpc gateway that is connected to a
! Modbus serial line with possibly several units. Usually this has no
! meaning and should be set to zero (0).
!*/
Object UnitId $Attribute 14 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:05:23.49
Attr PgmName = "UnitId"
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Module status.
!*/
Object Status $Attribute 15 25-NOV-2009 11:05:23.49
Body SysBody 04-DEC-2009 17:13:22.55
Attr PgmName = "Status"
Attr Flags = 1040
Attr TypeRef = "OtherIO:Type-ModbusSever_StatusEnum"
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 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:05:23.49
Attr PgmName = "Process"
Attr TypeRef = "pwrb:Type-IoProcessMask"
EndBody
EndObject
!/**
! @Summary Plc thread that handles the module.
! The PlcThread object of the plc thread that handles the module.
! The master is read with the scantime of the thread.
!*/
Object ThreadObject $Attribute 19 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:05:23.49
Attr PgmName = "ThreadObject"
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
EndObject
Object IoMethods $RtMethod 66 25-NOV-2009 11:05:23.49
Object IoCardInit $Method 67 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:14:04.41
Attr MethodName = "Modbus_TCP_ServerModule-IoCardInit"
EndBody
EndObject
Object IoCardRead $Method 68 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:14:15.11
Attr MethodName = "Modbus_TCP_ServerModule-IoCardRead"
EndBody
EndObject
Object IoCardWrite $Method 69 25-NOV-2009 11:05:23.49
Body SysBody 25-NOV-2009 11:14:21.27
Attr MethodName = "Modbus_TCP_ServerModule-IoCardWrite"
EndBody
EndObject
EndObject
Object Template Modbus_TCP_ServerModule 2149548032 01-JAN-1970 01:00:00.00
Body RtBody 01-JAN-1970 01:00:00.00
EndBody
EndObject
EndObject
EndObject
EndVolume
src/exp/rt/src/rt_plc_process.c
View file @
185ac1f1
...
...
@@ -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
);
...
...
src/lib/rt/src/rt_plc_thread.c
View file @
185ac1f1
...
...
@@ -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
)
{
...
...
src/wbl/pwrb/src/pwrb_c_chanai.wb_load
View file @
185ac1f1
...
...
@@ -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"
...
...
src/wbl/pwrb/src/pwrb_c_chanao.wb_load
View file @
185ac1f1
...
...
@@ -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
...
...
src/wbl/pwrb/src/pwrb_c_chandi.wb_load
View file @
185ac1f1
...
...
@@ -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
...
...
src/wbl/pwrb/src/pwrb_c_chando.wb_load
View file @
185ac1f1
...
...
@@ -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
...
...
src/wbl/pwrb/src/pwrb_c_chanii.wb_load
View file @
185ac1f1
...
...
@@ -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
...
...
src/wbl/pwrb/src/pwrb_c_chanio.wb_load
View file @
185ac1f1
...
...
@@ -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
...
...
wb/lib/wb/src/wb_c_chandi.cpp
View file @
185ac1f1
...
...
@@ -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
};
wb/lib/wb/src/wb_c_chanii.cpp
View file @
185ac1f1
...
...
@@ -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
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment