Bläddra i källkod

New functions to define the indication timeout (#95)

Stéphane Raimbault 8 år sedan
förälder
incheckning
0f06a0cdee

+ 2 - 0
doc/libmodbus.txt

@@ -128,6 +128,8 @@ Timeout settings::
     linkmb:modbus_set_byte_timeout[3]
     linkmb:modbus_get_response_timeout[3]
     linkmb:modbus_set_response_timeout[3]
+    linkmb:modbus_get_indication_timeout[3]
+    linkmb:modbus_set_indication_timeout[3]
 
 Error recovery mode::
     linkmb:modbus_set_error_recovery[3]

+ 1 - 1
doc/modbus_get_byte_timeout.txt

@@ -39,9 +39,9 @@ modbus_get_byte_timeout(ctx, &to_sec, &to_usec);
 
 SEE ALSO
 --------
+linkmb:modbus_set_byte_timeout[3]
 linkmb:modbus_get_response_timeout[3]
 linkmb:modbus_set_response_timeout[3]
-linkmb:modbus_set_byte_timeout[3]
 
 
 AUTHORS

+ 53 - 0
doc/modbus_get_indication_timeout.txt

@@ -0,0 +1,53 @@
+modbus_get_indication_timeout(3)
+================================
+
+
+NAME
+----
+modbus_get_indication_timeout - get timeout used to wait for an indication (request received by a server).
+
+SYNOPSIS
+--------
+*int modbus_get_indication_timeout(modbus_t *'ctx', uint32_t *'to_sec', uint32_t *'to_usec');*
+
+
+DESCRIPTION
+-----------
+
+The *modbus_get_indication_timeout()* function shall store the timeout interval
+used to wait for an indication in the _to_sec_ and _to_usec_ arguments.
+Indication is the term used by the Modbus protocol to designate a request
+received by the server.
+
+The default value is zero, it means the server will wait forever.
+
+
+RETURN VALUE
+------------
+The function shall return 0 if successful. Otherwise it shall return -1 and set
+errno.
+
+
+EXAMPLE
+-------
+[source,c]
+-------------------
+uint32_t to_sec;
+uint32_t to_usec;
+
+/* Save original timeout */
+modbus_get_indication_timeout(ctx, &to_sec, &to_usec);
+-------------------
+
+
+SEE ALSO
+--------
+linkmb:modbus_set_indication_timeout[3]
+linkmb:modbus_get_response_timeout[3]
+linkmb:modbus_set_response_timeout[3]
+
+
+AUTHORS
+-------
+The libmodbus documentation was written by Stéphane Raimbault
+<stephane.raimbault@gmail.com>

+ 48 - 0
doc/modbus_set_indication_timeout.txt

@@ -0,0 +1,48 @@
+modbus_set_indication_timeout(3)
+================================
+
+
+NAME
+----
+modbus_set_indication_timeout - set timeout between indications
+
+
+SYNOPSIS
+--------
+*void modbus_set_indication_timeout(modbus_t *'ctx', uint32_t 'to_sec', uint32_t 'to_usec');*
+
+
+DESCRIPTION
+-----------
+The *modbus_set_indication_timeout()* function shall set the timeout interval used by
+a server to wait for a request from a client.
+
+The value of _to_usec_ argument must be in the range 0 to 999999.
+
+If both _to_sec_ and _to_usec_ are zero, this timeout will not be used at all.
+In this case, the server will wait forever.
+
+
+RETURN VALUE
+------------
+The function shall return 0 if successful. Otherwise it shall return -1 and set
+errno.
+
+
+ERRORS
+------
+*EINVAL*::
+The argument _ctx_ is NULL or _to_usec_ is larger than 1000000.
+
+
+SEE ALSO
+--------
+linkmb:modbus_get_indication_timeout[3]
+linkmb:modbus_get_response_timeout[3]
+linkmb:modbus_set_response_timeout[3]
+
+
+AUTHORS
+-------
+The libmodbus documentation was written by Stéphane Raimbault
+<stephane.raimbault@gmail.com>

+ 1 - 0
src/modbus-private.h

@@ -98,6 +98,7 @@ struct _modbus {
     int error_recovery;
     struct timeval response_timeout;
     struct timeval byte_timeout;
+    struct timeval indication_timeout;
     const modbus_backend_t *backend;
     void *backend_data;
 };

+ 39 - 2
src/modbus.c

@@ -349,7 +349,7 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
 
     if (ctx->debug) {
         if (msg_type == MSG_INDICATION) {
-            printf("Waiting for a indication...\n");
+            printf("Waiting for an indication...\n");
         } else {
             printf("Waiting for a confirmation...\n");
         }
@@ -368,7 +368,15 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
     if (msg_type == MSG_INDICATION) {
         /* Wait for a message, we don't know when the message will be
          * received */
-        p_tv = NULL;
+        if (ctx->indication_timeout.tv_sec == 0 && ctx->indication_timeout.tv_usec == 0) {
+            /* By default, the indication timeout isn't set */
+            p_tv = NULL;
+        } else {
+            /* Wait for an indication (name of a received request by a server, see schema) */
+            tv.tv_sec = ctx->indication_timeout.tv_sec;
+            tv.tv_usec = ctx->indication_timeout.tv_usec;
+            p_tv = &tv;
+        }
     } else {
         tv.tv_sec = ctx->response_timeout.tv_sec;
         tv.tv_usec = ctx->response_timeout.tv_usec;
@@ -1564,6 +1572,9 @@ void _modbus_init_common(modbus_t *ctx)
 
     ctx->byte_timeout.tv_sec = 0;
     ctx->byte_timeout.tv_usec = _BYTE_TIMEOUT;
+
+    ctx->indication_timeout.tv_sec = 0;
+    ctx->indication_timeout.tv_usec = 0;
 }
 
 /* Define the slave number */
@@ -1673,6 +1684,32 @@ int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
     return 0;
 }
 
+/* Get the timeout interval used by the server to wait for an indication from a client */
+int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec)
+{
+    if (ctx == NULL) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    *to_sec = ctx->indication_timeout.tv_sec;
+    *to_usec = ctx->indication_timeout.tv_usec;
+    return 0;
+}
+
+int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec)
+{
+    /* Indication timeout can be disabled when both values are zero */
+    if (ctx == NULL || to_usec > 999999) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    ctx->indication_timeout.tv_sec = to_sec;
+    ctx->indication_timeout.tv_usec = to_usec;
+    return 0;
+}
+
 int modbus_get_header_length(modbus_t *ctx)
 {
     if (ctx == NULL) {

+ 3 - 0
src/modbus.h

@@ -188,6 +188,9 @@ MODBUS_API int modbus_set_response_timeout(modbus_t *ctx, uint32_t to_sec, uint3
 MODBUS_API int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
 MODBUS_API int modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
 
+MODBUS_API int modbus_get_indication_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
+MODBUS_API int modbus_set_indication_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);
+
 MODBUS_API int modbus_get_header_length(modbus_t *ctx);
 
 MODBUS_API int modbus_connect(modbus_t *ctx);