From d6855af62e89e0ecf61d383ebfcf57ebb372d040 Mon Sep 17 00:00:00 2001
From: Claes Sjofors <claes.sjofors@proview.se>
Date: Thu, 4 Mar 2010 09:07:37 +0100
Subject: [PATCH] Modbus TCP, function code WriteSingleRegister added

---
 .../os_linux/rt_io_m_mb_tcp_servermodule.c    |  4 -
 .../rt/src/os_linux/rt_io_m_mb_tcp_slave.c    | 28 +++++++
 otherio/wbl/mcomp/src/otherio.wb_load         | 74 ++++++++++---------
 3 files changed, 66 insertions(+), 40 deletions(-)

diff --git a/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_servermodule.c b/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_servermodule.c
index 2bfca8110..618e792de 100644
--- a/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_servermodule.c
+++ b/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_servermodule.c
@@ -87,8 +87,6 @@ static pwr_tStatus IoCardRead (
   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;
@@ -124,8 +122,6 @@ static pwr_tStatus IoCardWrite (
   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;
diff --git a/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_slave.c b/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_slave.c
index 5c7a18037..c75f3e126 100644
--- a/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_slave.c
+++ b/otherio/lib/rt/src/os_linux/rt_io_m_mb_tcp_slave.c
@@ -303,6 +303,7 @@ pwr_tStatus mb_recv_data(io_sRackLocal *local,
 
 	          case pwr_eModbus_FCEnum_WriteMultipleCoils:
 	          case pwr_eModbus_FCEnum_WriteMultipleRegisters:
+	          case pwr_eModbus_FCEnum_WriteSingleRegister:
 	            // Nothing good to do here
 	            break;
 	        }
@@ -513,6 +514,33 @@ pwr_tStatus mb_send_data(io_sRackLocal *local,
 	      wrr.bc = local_card->output_size;
 	      memcpy(wrr.reg, local_card->output_area, local_card->output_size);
 
+	      sts = send(local->s, &wrr, ntohs(wrr.head.length) + 6, MSG_DONTWAIT);
+	      if (sts < 0) {
+                sp->Status = MB__CONNDOWN;
+                close(local->s);
+                errh_Error( "Connection down to modbus slave, %s", rp->Name);
+                return IO__SUCCESS;
+              }
+	      sp->TX_packets++;
+	      local->expected_msgs++;
+	      break;
+	    }
+	    case pwr_eModbus_FCEnum_WriteSingleRegister: {
+	      write_single_req wrr;
+
+	      mp->SendOp = FALSE;
+
+	      local->trans_id++;
+	      local_card->trans_id = local->trans_id;
+
+              wrr.head.trans_id = htons(local->trans_id);
+              wrr.head.proto_id = 0;
+              wrr.head.length = htons(sizeof(wrr) - 6);
+              wrr.head.unit_id = mp->UnitId;
+              wrr.fc = mp->FunctionCode;
+              wrr.addr = htons(mp->Address);
+	      memcpy(&wrr.value, local_card->output_area, sizeof(wrr.value));
+
 	      sts = send(local->s, &wrr, ntohs(wrr.head.length) + 6, MSG_DONTWAIT);
 	      if (sts < 0) {
                 sp->Status = MB__CONNDOWN;
diff --git a/otherio/wbl/mcomp/src/otherio.wb_load b/otherio/wbl/mcomp/src/otherio.wb_load
index 9e81705e4..eea7b9e86 100644
--- a/otherio/wbl/mcomp/src/otherio.wb_load
+++ b/otherio/wbl/mcomp/src/otherio.wb_load
@@ -637,7 +637,6 @@ Volume OtherIO $ClassVolume 0.0.250.10
         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
@@ -1104,9 +1103,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
     ! 	
     !  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
@@ -1120,27 +1119,27 @@ Volume OtherIO $ClassVolume 0.0.250.10
           Attr StructName = "Modbus_TCP_Server"
           Attr NextAix = "_X39"
         EndBody
-	!/**
-	! Description of the object.
-	!*/
+        !/**
+        ! 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.
-	!*/
+        !/**
+        ! 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.
-	!*/
+        !/**
+        ! 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"
@@ -1178,8 +1177,8 @@ Volume OtherIO $ClassVolume 0.0.250.10
         ! @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.
+        ! 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
@@ -1189,7 +1188,7 @@ Volume OtherIO $ClassVolume 0.0.250.10
         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"
@@ -1297,7 +1296,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
         EndObject
       EndObject
       Object Template Modbus_TCP_Server 2149285888 01-JAN-1970 01:00:00.00
-        Body RtBody 01-JAN-1970 01:00:00.00
+        Body RtBody 03-MAR-2010 16:51:13.57
+          Attr Process = 1
+          Attr ErrorLimit = 50
         EndBody
       EndObject
     EndObject
@@ -1324,40 +1325,40 @@ Volume OtherIO $ClassVolume 0.0.250.10
           Attr StructName = "Modbus_TCP_ServerModule"
           Attr NextAix = "_X21"
         EndBody
-	!/**
-	! Description of the object.
-	!*/
+        !/**
+        ! 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.
+        !/**
+        ! @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.
-	!*/
+        ! 
+        ! 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
+        !/**
+        ! @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 
+        ! 
+        ! 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"
@@ -1367,9 +1368,9 @@ Volume OtherIO $ClassVolume 0.0.250.10
         !/**
         ! @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).   
+        ! 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
@@ -1432,7 +1433,8 @@ Volume OtherIO $ClassVolume 0.0.250.10
         EndObject
       EndObject
       Object Template Modbus_TCP_ServerModule 2149548032 01-JAN-1970 01:00:00.00
-        Body RtBody 01-JAN-1970 01:00:00.00
+        Body RtBody 03-MAR-2010 16:49:58.18
+          Attr Process = 1
         EndBody
       EndObject
     EndObject
-- 
2.30.9