mb_tcp.c
changeset 0 ae252e0fd9b8
child 8 f14859c24751
equal deleted inserted replaced
-1:000000000000 0:ae252e0fd9b8
       
     1 /*
       
     2  * Copyright (c) 2002,2016 Mario de Sousa (msousa@fe.up.pt)
       
     3  *
       
     4  * This file is part of the Modbus library for Beremiz and matiec.
       
     5  *
       
     6  * This Modbus library is free software: you can redistribute it and/or modify
       
     7  * it under the terms of the GNU Lesser General Public License as published by
       
     8  * the Free Software Foundation, either version 3 of the License, or
       
     9  * (at your option) any later version.
       
    10  *
       
    11  * This program is distributed in the hope that it will be useful, but
       
    12  * WITHOUT ANY WARRANTY; without even the implied warranty of
       
    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
       
    14  * General Public License for more details.
       
    15  *
       
    16  * You should have received a copy of the GNU Lesser General Public License
       
    17  * along with this Modbus library.  If not, see <http://www.gnu.org/licenses/>.
       
    18  *
       
    19  * This code is made available on the understanding that it will not be
       
    20  * used in safety-critical situations without a full and competent review.
       
    21  */
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 #include <fcntl.h>      /* File control definitions */
       
    28 #include <stdio.h>      /* Standard input/output */
       
    29 #include <string.h>
       
    30 #include <stdlib.h>
       
    31 #include <termio.h>     /* POSIX terminal control definitions */
       
    32 #include <sys/time.h>   /* Time structures for select() */
       
    33 #include <unistd.h>     /* POSIX Symbolic Constants */
       
    34 #include <assert.h>
       
    35 #include <errno.h>      /* Error definitions */
       
    36 #include <time.h>       /* clock_gettime()   */
       
    37 #include <sys/types.h>
       
    38 #include <sys/socket.h>
       
    39 #include <netinet/in.h>  /* required for htons() and ntohs() */
       
    40 #include <netinet/tcp.h> /* TCP level socket options */
       
    41 #include <netinet/ip.h>  /* IP  level socket options */
       
    42 
       
    43 #include <pthread.h>
       
    44 #include <sched.h>       /* sched_yield() */
       
    45 
       
    46 
       
    47 
       
    48 #include "sin_util.h"   /* internet socket utility functions... */
       
    49 #include "mb_layer1.h"  /* The public interface this file implements... */
       
    50 #include "mb_tcp_private.h"
       
    51 
       
    52 
       
    53 
       
    54 /************************************/
       
    55 /**                                **/
       
    56 /** Include common code...         **/
       
    57 /**                                **/
       
    58 /************************************/
       
    59 
       
    60 #include "mb_time_util.h"
       
    61 
       
    62 
       
    63 //#define ERRMSG
       
    64 #define ERRMSG_HEAD "Modbus/TCP: "
       
    65 
       
    66 
       
    67 // #define DEBUG       /* uncomment to see the data sent and received */
       
    68 
       
    69 
       
    70 #ifdef DEBUG
       
    71 #ifndef ERRMSG
       
    72 #define ERRMSG
       
    73 #endif
       
    74 #endif
       
    75 
       
    76 
       
    77 
       
    78 /**************************************************************/
       
    79 /**************************************************************/
       
    80 /****                                                      ****/
       
    81 /****                                                      ****/
       
    82 /****                Forward Declarations                  ****/
       
    83 /****                    and Defaults                      ****/
       
    84 /****                                                      ****/
       
    85 /**************************************************************/
       
    86 /**************************************************************/
       
    87 
       
    88 
       
    89   /* A Node Descriptor metadata,
       
    90    *   Due to the fact that modbus TCP is connection oriented,
       
    91    *   and that if the client detects an error the connection
       
    92    *   must be shut down and re-established automatically,
       
    93    *   the modbus TCP layer needs to keep the address of the remote server.
       
    94    *
       
    95    * We do this by implementing a node descriptor table, in which each
       
    96    *   entry will have the remote address, and the file descriptor
       
    97    *   of the socket currently in use.
       
    98    *
       
    99    * We do not pass the file descriptor up to the next higher layer. We
       
   100    *   send them the node descriptor instead...
       
   101    */
       
   102 #define MB_MASTER_NODE 12
       
   103 #define MB_LISTEN_NODE 14
       
   104 #define MB_SLAVE_NODE  16
       
   105 #define MB_FREE_NODE   18
       
   106 typedef sa_family_t nd_type_t;
       
   107 
       
   108 typedef struct {
       
   109     int    fd;                 /* socket descriptor == file descriptor */
       
   110                                /* NOTE:
       
   111                                 *   Modbus TCP says that on error, we should close
       
   112                                 *   a connection and retry with a new connection.
       
   113                                 *   Since it takes time for a socket to close
       
   114                                 *   a connection if the remote server is down,
       
   115                                 *   we close the connection on the socket, close the
       
   116                                 *   socket itself, and create a new one for the new
       
   117                                 *   connection. There will be times when the node will
       
   118                                 *   not have any valid socket, and it will have to
       
   119                                 *   be created on the fly.
       
   120                                 *   When the node does not have a valid socket,
       
   121                                 *   fd will be set to -1
       
   122                                 */
       
   123     int    node_type;          /*   What kind of use we are giving to this node...
       
   124                                 *   If node_type == MB_MASTER_NODE
       
   125                                 *      The node descriptor was initialised by the
       
   126                                 *      modbus_connect() function.
       
   127                                 *      The node descriptor is being used by a master
       
   128                                 *      device, and the addr contains the address of the slave.
       
   129                                 *      Remember that in this case fd may be >= 0 while
       
   130                                 *      we have a valid connection, or it may be < 0 when
       
   131                                 *      the connection needs to be reset.
       
   132                                 *   If node_type == MB_LISTEN_NODE
       
   133                                 *      The node descriptor was initialised by the
       
   134                                 *      modbus_listen() function.
       
   135                                 *      The node is merely used to accept() new connection
       
   136                                 *      requests. The new slave connections will use another
       
   137                                 *      node to transfer data.
       
   138                                 *      In this case fd must be >= 0.
       
   139                                 *      fd < 0 is an ilegal state and should never occur.
       
   140                                 *   If node_type == MB_SLAVE_NODE
       
   141                                 *      The node descriptor was initialised when a new
       
   142                                 *      connection request arrived on a MB_LISTEN type node.
       
   143                                 *      The node descriptor is being used by a slave device,
       
   144                                 *      and is currently being used to connect to a master.
       
   145                                 *      In this case fd must be >= 0.
       
   146                                 *      fd < 0 is an ilegal state and should never occur.
       
   147                                 *   If node_type == FREE_ND
       
   148                                 *      The node descriptor is currently not being used.
       
   149                                 *      In this case fd is set to -1, but is really irrelevant.
       
   150                                 */
       
   151     struct sockaddr_in addr;   /* The internet adress we are using.
       
   152                                 *   If node_type == MB_MASTER_NODE
       
   153                                 *      addr will be the address of the remote slave
       
   154                                 *   If node_type == MB_LISTEN_NODE
       
   155                                 *      addr will be the address of the local listening port and network interface
       
   156                                 *   If node_type == MB_SLAVE_NODE
       
   157                                 *      addr will be the address of the local port and network interface
       
   158                                 *       of the connection to the specific client.
       
   159                                 */
       
   160     int listen_node;           /* When a slave accepts a connection through a MB_LISTEN_NODE, it will
       
   161                                 * will use an empty node for the new connection, and configure this new node
       
   162                                 * to use the type MB_SLAVE_NODE.
       
   163                                 * The listen_node entry is only used by nodes of type MB_SLAVE_NODE.
       
   164                                 * In this case, listen_node will be the node of type MB_LISTEN_NODE through
       
   165                                 * which the connection request came through...
       
   166                                 */ 
       
   167     int close_on_silence;      /* A flag used only by Master Nodes.
       
   168                                 * When (close_on_silence > 0), then the connection to the
       
   169                                 * slave device will be shut down whenever the
       
   170                                 * modbus_tcp_silence_init() function is called.
       
   171                                 * Remember that the connection will be automatically
       
   172                                 * re-established the next time the user wishes to communicate
       
   173                                 * with the same slave (using this same node descripto).
       
   174                                 * If the user wishes to comply with the sugestion
       
   175                                 * in the OpenModbus Spec, (s)he should set this flag
       
   176                                 * if a silence interval longer than 1 second is expected.
       
   177                                 */
       
   178     int print_connect_error;   /* flag to guarantee we only print an error the first time we
       
   179                                 * attempt to connect to a emote server.
       
   180                                 * Stops us from generting a cascade of errors while the slave
       
   181                                 * is down.
       
   182                                 * Flag will get reset every time we successfully
       
   183                                 * establish a connection, so a message is once again generated 
       
   184                                 * on the next error.
       
   185                                 */
       
   186     u8 *recv_buf;              /* This node's receive buffer
       
   187                                 * The library supports multiple simultaneous connections,
       
   188                                 * and may need to receive multiple frames through mutiple nodes concurrently.
       
   189                                 * To make the library thread-safe, we use one buffer for each node.
       
   190                                 */
       
   191 } nd_entry_t;
       
   192 
       
   193 
       
   194 /* please make sure to lock the node table mutex before calling this function */
       
   195 static int nd_entry_init(nd_entry_t *nde) {
       
   196   nde->addr.sin_family = AF_INET  ;
       
   197   nde->node_type = MB_FREE_NODE;
       
   198   nde->fd = -1; /* not currently connected... */
       
   199   /* initialise recv buffer */
       
   200   nde->recv_buf = malloc(sizeof(u8) * RECV_BUFFER_SIZE);
       
   201   if (nde->recv_buf == NULL)
       
   202     return -1;
       
   203   return 0;
       
   204 }
       
   205 
       
   206 /* please make sure to lock the node table mutex before calling this function */
       
   207 static int nd_entry_done(nd_entry_t *nde) {
       
   208   free(nde->recv_buf);
       
   209   return 0;
       
   210 }
       
   211 
       
   212 
       
   213 
       
   214 typedef struct {
       
   215       /* the array of node descriptors, and current size... */
       
   216     nd_entry_t      *node;           /* array of node entries. if NULL => node table not initialized */
       
   217     int             node_count;      /* total number of nodes in the node[] array */
       
   218     int             free_node_count; /* number of free nodes in the node[] array */
       
   219     pthread_mutex_t mutex;
       
   220 } nd_table_t;
       
   221 
       
   222 
       
   223 
       
   224 static int nd_table_done(nd_table_t *ndt) {
       
   225   int count;
       
   226 
       
   227   if (ndt->node == NULL) 
       
   228     return 0;
       
   229 
       
   230   /* lock the mutex */
       
   231   while (pthread_mutex_lock(&ndt->mutex) != 0) sched_yield();
       
   232   
       
   233   /* initialise the state of each node in the array... */
       
   234   for (count = 0; count < ndt->node_count; count++) {
       
   235     nd_entry_done(&ndt->node[count]);
       
   236   } /* for() */
       
   237 
       
   238   free(ndt->node);
       
   239   pthread_mutex_unlock (&ndt->mutex);
       
   240   pthread_mutex_destroy(&ndt->mutex);
       
   241   *ndt = (nd_table_t){.node=NULL, .node_count=0, .free_node_count=0};
       
   242   
       
   243   return 0;
       
   244 }
       
   245 
       
   246 
       
   247 
       
   248 
       
   249 #if 1
       
   250 /* nd_table_init()
       
   251  *   Version 1 of the nd_table_init() function. 
       
   252  *   If called more than once, 2nd and any subsequent calls will
       
   253  *   be interpreted as a request to confirm that it was already correctly 
       
   254  *   initialized with the requested number of nodes.
       
   255  */
       
   256 static int nd_table_init(nd_table_t *ndt, int nd_count) {
       
   257   int count;
       
   258 
       
   259   if (ndt->node != NULL) {
       
   260     /* this function has already been called, and the node table is already initialised */
       
   261     return (ndt->node_count == nd_count)?0:-1;
       
   262   }
       
   263   
       
   264   /* initialise the node table mutex... */
       
   265   pthread_mutex_init(&ndt->mutex, NULL);
       
   266   if (pthread_mutex_lock(&ndt->mutex) != 0) {
       
   267 #ifdef DEBUG
       
   268     perror("pthread_mutex_lock()");
       
   269     fprintf(stderr, "[%lu] Unable to lock newly crated mutex while creating new node table!\n", pthread_self());
       
   270 #endif
       
   271     pthread_mutex_destroy(&ndt->mutex);
       
   272     return -1;
       
   273   }
       
   274   
       
   275   /* initialise the node descriptor metadata array... */
       
   276   ndt->node = malloc(sizeof(nd_entry_t) * nd_count);
       
   277   if (ndt->node == NULL) {
       
   278 #ifdef DEBUG
       
   279     perror("malloc()");
       
   280     fprintf(stderr, "[%lu] Out of memory: error initializing node address buffer\n", pthread_self());
       
   281 #endif
       
   282 #ifdef ERRMSG
       
   283     perror("malloc()");
       
   284     fprintf(stderr, ERRMSG_HEAD "Out of memory. Error initializing node address buffer\n");
       
   285 #endif
       
   286     pthread_mutex_unlock (&ndt->mutex);
       
   287     pthread_mutex_destroy(&ndt->mutex);
       
   288     return -1;
       
   289   }
       
   290 
       
   291   /* initialise the state of each node in the array... */
       
   292   for (count = 0; count < nd_count; count++) {
       
   293     if (nd_entry_init(&ndt->node[count]) < 0) {
       
   294       pthread_mutex_unlock(&ndt->mutex);
       
   295       nd_table_done(ndt);
       
   296       return -1;
       
   297     }
       
   298     ndt->node_count = count+1;
       
   299     ndt->free_node_count = count+1;
       
   300   } /* for() */
       
   301 
       
   302   ndt->node_count = nd_count;
       
   303   ndt->free_node_count = nd_count;
       
   304 
       
   305   pthread_mutex_unlock(&ndt->mutex);
       
   306   return nd_count; /* number of succesfully created nodes! */
       
   307 }
       
   308 
       
   309 
       
   310 #else
       
   311 /* nd_table_init()
       
   312  *   Version 2 of the nd_table_init() function. 
       
   313  *   If called more than once, 2nd and any subsequent calls will
       
   314  *   be interpreted as a request to reserve an extra new_nd_count
       
   315  *   number of nodes. This will be done using realloc().
       
   316  */
       
   317 static int nd_table_init(nd_table_t *ndt, int new_nd_count) {
       
   318   int count;
       
   319 
       
   320   if (ndt->node == NULL) {
       
   321     /* Node table nt yet initialized => we must initialise the node table mutex... */
       
   322     pthread_mutex_init(&ndt->mutex, NULL);
       
   323   }
       
   324   
       
   325   /* lock the mutex */
       
   326   while (pthread_mutex_lock(&ndt->mutex) != 0) sched_yield();
       
   327   
       
   328   /* initialise the node descriptor metadata array... */
       
   329   ndt->node = realloc(ndt->node, sizeof(nd_entry_t) * (ndt->node_count + new_nd_count));
       
   330   if (ndt->node == NULL) {
       
   331 #ifdef DEBUG
       
   332     perror("malloc()");
       
   333     fprintf(stderr, "[%lu] Out of memory: error initializing node address buffer\n", pthread_self());
       
   334 #endif
       
   335 #ifdef ERRMSG
       
   336     perror("malloc()");
       
   337     fprintf(stderr, ERRMSG_HEAD "Out of memory. Error initializing node address buffer\n");
       
   338 #endif
       
   339     pthread_mutex_unlock (&ndt->mutex);
       
   340     pthread_mutex_destroy(&ndt->mutex);
       
   341     return -1;
       
   342   }
       
   343 
       
   344   /* initialise the state of each newly added node in the array... */
       
   345   for (count = ndt->node_count; count < ndt->node_count + new_nd_count; count++) {
       
   346     if (nd_entry_init(&ndt->node[count]) < 0) {
       
   347       pthread_mutex_unlock(&ndt->mutex);
       
   348       return -1;
       
   349     }
       
   350   } /* for() */
       
   351   ndt->node_count      += new_nd_count;
       
   352   ndt->free_node_count += new_nd_count;
       
   353 
       
   354   pthread_mutex_unlock(&ndt->mutex);
       
   355   return new_nd_count; /* number of succesfully created nodes! */
       
   356 }
       
   357 #endif
       
   358 
       
   359 
       
   360 static int nd_table_get_free_node(nd_table_t *ndt, nd_type_t nd_type) {
       
   361   int count;
       
   362 
       
   363   /* lock the mutex */
       
   364   while (pthread_mutex_lock(&ndt->mutex) != 0) sched_yield();
       
   365 
       
   366   /* check for free nodes... */
       
   367   if (ndt->free_node_count <= 0) {
       
   368     /* no free nodes... */
       
   369     pthread_mutex_unlock(&ndt->mutex);
       
   370     return -1;
       
   371   }
       
   372 
       
   373   /* Decrement the free node counter...*/
       
   374   ndt->free_node_count--;
       
   375 
       
   376   /* search for a free node... */
       
   377   for (count = 0; count < ndt->node_count; count++) {
       
   378     if(ndt->node[count].node_type == MB_FREE_NODE) {
       
   379       /* found one!! Allocate it to the new type! */
       
   380       ndt->node[count].node_type = nd_type;
       
   381       pthread_mutex_unlock(&ndt->mutex);
       
   382       return count;
       
   383     }
       
   384   } /* for() */
       
   385 
       
   386   /* Strange... We should have free nodes, but we didn't finda any! */
       
   387   /* Let's try to get into a consistent state, and return an error! */
       
   388   ndt->free_node_count = 0;
       
   389   pthread_mutex_unlock(&ndt->mutex);
       
   390   return -1;
       
   391 }
       
   392 
       
   393 
       
   394 
       
   395 static void nd_table_close_node(nd_table_t *ndt, int nd) {
       
   396 
       
   397   /* lock the mutex */
       
   398   while (pthread_mutex_lock(&ndt->mutex) != 0) sched_yield();
       
   399 
       
   400   if(ndt->node[nd].node_type == MB_FREE_NODE) {
       
   401     /* Node already free... */
       
   402     pthread_mutex_unlock(&ndt->mutex);
       
   403     return;
       
   404   }
       
   405 
       
   406   /* Increment the free node counter...*/
       
   407   ndt->free_node_count++;
       
   408   /* Mark the node as being free. */
       
   409   ndt->node[nd].node_type = MB_FREE_NODE;
       
   410 
       
   411   pthread_mutex_unlock(&ndt->mutex);
       
   412   return;
       
   413 }
       
   414 
       
   415 
       
   416 
       
   417 /**************************************************************/
       
   418 /**************************************************************/
       
   419 /****                                                      ****/
       
   420 /****                                                      ****/
       
   421 /****                Global Library State                  ****/
       
   422 /****                                                      ****/
       
   423 /****                                                      ****/
       
   424 /**************************************************************/
       
   425 /**************************************************************/
       
   426 
       
   427 
       
   428  /* The node descriptor table... */
       
   429  /* NOTE: The node_table_ Must be initialized correctly here! */
       
   430 static nd_table_t nd_table_ = {.node=NULL, .node_count=0, .free_node_count=0};
       
   431 
       
   432 
       
   433 /**************************************************************/
       
   434 /**************************************************************/
       
   435 /****                                                      ****/
       
   436 /****                                                      ****/
       
   437 /****              Local Utility functions...              ****/
       
   438 /****                                                      ****/
       
   439 /****                                                      ****/
       
   440 /**************************************************************/
       
   441 /**************************************************************/
       
   442 
       
   443 
       
   444 #define min(a,b) ((a<b)?a:b)
       
   445 #define max(a,b) ((a>b)?a:b)
       
   446 
       
   447 /************************************/
       
   448 /**                                **/
       
   449 /**  Configure socket for Modbus   **/
       
   450 /**                                **/
       
   451 /************************************/
       
   452 
       
   453 
       
   454 static int configure_socket(int socket_id) {
       
   455 
       
   456   /* configure the socket */
       
   457     /* Set it to be non-blocking. This is safe because we always use select() before reading from it! 
       
   458      * It is also required for the connect() call. The default timeout in the TCP stack is much too long
       
   459      * (typically blocks for 128 s ??) when the connect does not succedd imediately!
       
   460      */
       
   461   if (fcntl(socket_id, F_SETFL, O_NONBLOCK) < 0) {
       
   462 #ifdef ERRMSG
       
   463     perror("fcntl()");
       
   464     fprintf(stderr, ERRMSG_HEAD "Error configuring socket 'non-blocking' option.\n");
       
   465 #endif
       
   466     return -1;
       
   467   }
       
   468 
       
   469   /* configure the socket */
       
   470     /* set the TCP no delay flag. */
       
   471   {int bool_opt = 1;
       
   472   if (setsockopt(socket_id, SOL_TCP, TCP_NODELAY,
       
   473                  (const void *)&bool_opt, sizeof(bool_opt))
       
   474       < 0) {
       
   475 #ifdef ERRMSG
       
   476     perror("setsockopt()");
       
   477     fprintf(stderr, ERRMSG_HEAD "Error configuring socket 'TCP no delay' option.\n");
       
   478 #endif
       
   479     return -1;
       
   480   }
       
   481   }
       
   482 
       
   483     /* set the IP low delay option. */
       
   484   {int priority_opt = IPTOS_LOWDELAY;
       
   485   if (setsockopt(socket_id, SOL_IP, IP_TOS,
       
   486                  (const void *)&priority_opt, sizeof(priority_opt))
       
   487       < 0) {
       
   488 #ifdef ERRMSG
       
   489     perror("setsockopt()");
       
   490     fprintf(stderr, ERRMSG_HEAD "Error configuring socket 'IP low delay' option.\n");
       
   491 #endif
       
   492     return -1;
       
   493   }
       
   494   }
       
   495 
       
   496 #if 0
       
   497     /* send buffer */
       
   498     /* NOTE: For slave devices, that may be receiving multiple
       
   499      *       requests before they have a chance to reply to the first,
       
   500      *       it probably is a good idea to have a large receive buffer.
       
   501      *       So it is best to leave it with the default configuration, as it is
       
   502      *       larger than the largest Modbus TCP frame.
       
   503      *
       
   504      *       For the send buffer, a smaller buffer should suffice.
       
   505      *       However, it probably does not make sense to
       
   506      *       waste time asking for a smaller buffer, since the larger
       
   507      *       default buffer has already been allocated (the socket has already
       
   508      *       been created!)
       
   509      *
       
   510      *       We might just as well leave out the configuration of the socket
       
   511      *       buffer size...
       
   512      */
       
   513 #define SOCK_BUF_SIZE 300 /* The size proposed in the Modbus TCP spec. */
       
   514   {int sock_buf_size;
       
   515   sock_buf_size = SOCK_BUF_SIZE;
       
   516   if (setsockopt(socket_id, SOL_SOCKET, SO_SNDBUF,
       
   517                  (const void *)&sock_buf_size, sizeof(sock_buf_size))
       
   518       < 0)
       
   519     return -1;
       
   520     /* recv buffer */
       
   521   sock_buf_size = SOCK_BUF_SIZE;
       
   522   if (setsockopt(socket_id, SOL_SOCKET, SO_RCVBUF,
       
   523              (const void *)&sock_buf_size, sizeof(sock_buf_size))
       
   524       < 0)
       
   525     return -1;
       
   526   }
       
   527 #endif
       
   528 
       
   529   return 0;
       
   530 }
       
   531 
       
   532 
       
   533 /************************************/
       
   534 /**                                **/
       
   535 /** Connect socket to remote host  **/
       
   536 /**                                **/
       
   537 /************************************/
       
   538 
       
   539 /* This function will create a new socket, and connect it to a remote host... */
       
   540 static inline int open_connection(int nd, const struct timespec *timeout) {
       
   541   int socket_id, con_res;
       
   542 
       
   543 #ifdef DEBUG
       
   544         printf("[%lu] open_connection(): called, nd = %d\n", pthread_self(), nd);
       
   545 #endif
       
   546 
       
   547   if (nd_table_.node[nd].fd >= 0)
       
   548     /* nd already connected) */
       
   549     return nd_table_.node[nd].fd;
       
   550 
       
   551   if (nd_table_.node[nd].addr.sin_family != AF_INET)
       
   552     /* invalid remote address, or invalid nd */
       
   553     return -1;
       
   554 
       
   555   /* lets try to connect... */
       
   556     /* create the socket */
       
   557   if ((socket_id = socket(PF_INET, DEF_TYPE, 0 /* protocol_num */)) < 0) {
       
   558 #ifdef DEBUG
       
   559     perror("socket()");
       
   560     fprintf(stderr, "[%lu] Error creating socket\n", pthread_self());
       
   561 #endif
       
   562 #ifdef ERRMSG
       
   563     perror("socket()");
       
   564     fprintf(stderr, ERRMSG_HEAD "Error creating socket\n");
       
   565 #endif
       
   566     return -1;
       
   567   }
       
   568 
       
   569   /* configure the socket - includes setting non-blocking option! */
       
   570   if (configure_socket(socket_id) < 0) {
       
   571     close(socket_id);
       
   572     return -1;
       
   573   };
       
   574  
       
   575   /* establish the connection to remote host */
       
   576   con_res = connect(socket_id,
       
   577                     (struct sockaddr *)&(nd_table_.node[nd].addr),
       
   578                     sizeof(nd_table_.node[nd].addr));
       
   579 
       
   580   /* The following condition is not strictly necessary 
       
   581    * (we could let the code fall through)
       
   582    * but it does make the code easier to read/understand...
       
   583    */
       
   584   if (con_res >= 0)
       
   585     goto success_exit; /* connected succesfully on first try! */
       
   586     
       
   587   if (con_res < 0) {
       
   588     if ((errno != EINPROGRESS) && (errno != EALREADY))
       
   589       goto error_exit; /* error in connection request! */
       
   590 
       
   591     /* connection request is ongoing */
       
   592     /* EINPROGRESS -> first call to connect, EALREADY -> subsequent calls to connect */
       
   593     /* Must wait for connect to complete at most 'timeout' seconds */
       
   594     {fd_set fdset;
       
   595      int res, so_error;
       
   596      socklen_t len;
       
   597      struct timespec end_time, *et_ptr;
       
   598      
       
   599      et_ptr = NULL;
       
   600      if (timeout != NULL) {
       
   601         et_ptr = &end_time;
       
   602        *et_ptr = timespec_add_curtime(*timeout);
       
   603      }
       
   604       
       
   605      FD_ZERO(&fdset);
       
   606      FD_SET(socket_id, &fdset);
       
   607      
       
   608      res = my_select(socket_id+1, NULL, &fdset, et_ptr);
       
   609      if (res  < 0) goto error_exit; /* error on call to select */
       
   610      if (res == 0) goto error_exit; /* timeout */
       
   611      /* (res  > 0) -> connection attemt completed. May have been success or failure! */
       
   612      
       
   613      len = sizeof(so_error);
       
   614      res = getsockopt(socket_id, SOL_SOCKET, SO_ERROR, &so_error, &len);
       
   615      if (res  < 0)      goto error_exit; /* error on call to getsockopt */
       
   616      if (so_error != 0) goto error_exit; /* error on connection attempt */
       
   617      goto success_exit; /* succesfully completed connection attempt! */
       
   618                         /* goto sucess_exit is not strcitly necessary - we could let the code fall through! */
       
   619     }
       
   620   }
       
   621 
       
   622 success_exit:
       
   623   nd_table_.node[nd].fd = socket_id;
       
   624   /* Succesfully established connection => print a message next time we have error. */
       
   625   nd_table_.node[nd].print_connect_error = 1;  
       
   626 
       
   627 #ifdef DEBUG
       
   628   printf("[%lu] open_connection(): returning...\n", pthread_self());
       
   629 #endif
       
   630   return socket_id;
       
   631 
       
   632 error_exit:
       
   633 #ifdef ERRMSG
       
   634     if (nd_table_.node[nd].print_connect_error > 0) {
       
   635       perror("connect()");
       
   636       fprintf(stderr, ERRMSG_HEAD "Error establishing socket connection.\n");
       
   637       /* do not print more error messages for this node... */
       
   638       nd_table_.node[nd].print_connect_error = 0;
       
   639     }
       
   640 #endif
       
   641     close(socket_id);
       
   642     return -1;
       
   643 }
       
   644 
       
   645 
       
   646 /* This function will accept a new connection request, and attribute it to a new node... */
       
   647 static inline int accept_connection(int nd) {
       
   648   int socket_id, new_nd;
       
   649 
       
   650 #ifdef DEBUG
       
   651         printf("[%lu] accept_connection(): called, nd = %d\n", pthread_self(), nd);
       
   652 #endif
       
   653 
       
   654   /* NOTE: We MUST accccept8) all connection requests, even if no new node is available.
       
   655    *       => We first accept the connection request, and only later look for a node.
       
   656    *          If no node is free/available for this new connections request, the 
       
   657    *          connection will be accepted and immediately closed.
       
   658    *       Reason:
       
   659    *       When the library is used for a Modbus/TCP server and no free node is 
       
   660    *        available, if we do not accept() all newly arrived connection requests
       
   661    *        we would enter an infinite loop calling
       
   662    *           - select() (in modbus_tcp_read()) 
       
   663    *           - and accept_connection().
       
   664    *        Note that select() will continue to return immediately if the 
       
   665    *        connection request is not accept()ted!
       
   666    */
       
   667   /* lets accept new connection request... */
       
   668   if ((socket_id = accept(nd_table_.node[nd].fd, NULL, NULL)) < 0) {
       
   669 #ifdef ERRMSG
       
   670     perror("accept()");
       
   671     fprintf(stderr, ERRMSG_HEAD "Error while waiting for connection request from new client\n");
       
   672 #endif
       
   673     /* error establishing new connection... */
       
   674     return -1;
       
   675   }
       
   676 
       
   677   /* find a free node */ 
       
   678   if ((new_nd = nd_table_get_free_node(&nd_table_, MB_SLAVE_NODE)) < 0) {
       
   679     /* no available free nodes for the new connection... */
       
   680     close(socket_id);    
       
   681     return -1;
       
   682   }
       
   683 
       
   684   /* configure the socket - includes setting the non-blocking option! */
       
   685   if (configure_socket(socket_id) < 0) {
       
   686     nd_table_close_node(&nd_table_, new_nd);  /* first free up the un-used node. */
       
   687     close(socket_id);
       
   688     return -1;
       
   689   }
       
   690 
       
   691   /* set up the node entry and update the fd sets */
       
   692   nd_table_.node[new_nd].fd = socket_id;
       
   693   nd_table_.node[new_nd].listen_node = nd;
       
   694 
       
   695 #ifdef DEBUG
       
   696         printf("[%lu] accept_connection(): returning new_nd = %d\n", pthread_self(), new_nd);
       
   697 #endif
       
   698   return new_nd;
       
   699 }
       
   700 
       
   701 
       
   702 static inline void close_connection(int nd) {
       
   703   if (nd_table_.node[nd].fd >= 0) {
       
   704     /* disconnect the tcp connection */
       
   705     shutdown(nd_table_.node[nd].fd, SHUT_RDWR);
       
   706 #ifdef ERRMSG
       
   707     int res =
       
   708 #endif
       
   709     close(nd_table_.node[nd].fd);
       
   710 #ifdef ERRMSG
       
   711     if (res < 0) {
       
   712       perror("close()");
       
   713       fprintf(stderr, ERRMSG_HEAD "Error closing socket\n");
       
   714     }
       
   715 #endif
       
   716     nd_table_.node[nd].fd = -1;
       
   717   }
       
   718 
       
   719   if (nd_table_.node[nd].node_type == MB_SLAVE_NODE) {
       
   720     /* If it is a slave node, we will not be receiving any more data over this disconnected node,
       
   721      * (MB_SLAVE_NODE do not get re-connected!), so we free the node...
       
   722      */
       
   723     nd_table_close_node(&nd_table_, nd);
       
   724   }
       
   725 }
       
   726 
       
   727 
       
   728 
       
   729 /************************************/
       
   730 /**                                **/
       
   731 /**     Data format conversion     **/
       
   732 /**                                **/
       
   733 /************************************/
       
   734 
       
   735 /*
       
   736  * Functions to convert u16 variables
       
   737  * between network and host byte order
       
   738  *
       
   739  * NOTE: Modbus uses MSByte first, just like
       
   740  *       tcp/ip, so we use the htons() and
       
   741  *       ntoh() functions to guarantee
       
   742  *       code portability.
       
   743  */
       
   744 
       
   745 static inline u16 mb_hton(u16 h_value) {
       
   746 /*  return h_value; */
       
   747   return htons(h_value);
       
   748 }
       
   749 
       
   750 static inline u16 mb_ntoh(u16 m_value) {
       
   751 /*  return m_value; */
       
   752   return ntohs(m_value);
       
   753 }
       
   754 
       
   755 static inline u8 msb(u16 value) {
       
   756 /*  return Most Significant Byte of value; */
       
   757   return (value >> 8) & 0xFF;
       
   758 }
       
   759 
       
   760 static inline u8 lsb(u16 value) {
       
   761 /*  return Least Significant Byte of value; */
       
   762   return value & 0xFF;
       
   763 }
       
   764 
       
   765 #define u16_v(char_ptr)  (*((u16 *)(&(char_ptr))))
       
   766 
       
   767 
       
   768 /************************************/
       
   769 /**                                **/
       
   770 /**   Build/Check a frame header   **/
       
   771 /**                                **/
       
   772 /************************************/
       
   773 
       
   774 /* A modbus TCP frame header has 6 bytes...
       
   775  *   header[0-1] -> transaction id
       
   776  *   header[2-3] -> must be 0
       
   777  *   header[4-5] -> frame data length (must be <= 255)
       
   778  */
       
   779 #if TCP_HEADER_LENGTH < 6
       
   780 #error This code assumes a header size of 6 bytes, but TCP_HEADER_LENGTH < 6
       
   781 #endif
       
   782 
       
   783 static inline void build_header(u8 *header,
       
   784                                 u16 transaction_id,
       
   785                                 u16 byte_count)
       
   786 {
       
   787   u16_v(header[0]) = mb_hton(transaction_id);
       
   788   header[2] = 0;
       
   789   header[3] = 0;
       
   790   u16_v(header[4]) = mb_hton(byte_count);
       
   791 }
       
   792 
       
   793 
       
   794 static inline int check_header(u8  *header,
       
   795                                u16 *transaction_id,
       
   796                                u16 *byte_count)
       
   797 {
       
   798   if ((header[2] != 0) || (header[3] != 0))
       
   799     return -1;
       
   800 
       
   801   *transaction_id = mb_ntoh(*(u16 *)(header + 0));
       
   802   *byte_count     = mb_ntoh(*(u16 *)(header + 4));
       
   803 
       
   804   if (*byte_count > MAX_L2_FRAME_LENGTH)
       
   805     return -1;
       
   806 
       
   807   return 0;
       
   808 }
       
   809 
       
   810 
       
   811 
       
   812 
       
   813 
       
   814 /**************************************************************/
       
   815 /**************************************************************/
       
   816 /****                                                      ****/
       
   817 /****                                                      ****/
       
   818 /****              Sending of Modbus TCP Frames            ****/
       
   819 /****                                                      ****/
       
   820 /****                                                      ****/
       
   821 /**************************************************************/
       
   822 /**************************************************************/
       
   823 
       
   824 // pthread_mutex_t sendmsg_mutex = PTHREAD_MUTEX_INITIALIZER; 
       
   825 
       
   826 /* NOTE: this function MUST be thread safe!! */
       
   827 int modbus_tcp_write(int nd,  /* node descriptor */
       
   828                      u8 *data,
       
   829                      size_t data_length,
       
   830                      u16 transaction_id,
       
   831                      const struct timespec *transmit_timeout
       
   832                      )
       
   833 {
       
   834 #define data_vector_size 2
       
   835 
       
   836   u8            header[TCP_HEADER_LENGTH];
       
   837   struct iovec  data_vector[data_vector_size] = {
       
   838                          {(void *)header, TCP_HEADER_LENGTH},
       
   839                          {NULL, 0}};
       
   840   struct msghdr msg = {NULL, 0, data_vector, data_vector_size, NULL, 0, 0};
       
   841   int res, bytes_sent;
       
   842 
       
   843 #ifdef DEBUG
       
   844   printf("[%lu] modbus_tcp_write(): called...  nd=%d\n", pthread_self(), nd);
       
   845 #endif
       
   846 
       
   847   if ((nd >= nd_table_.node_count) || (nd < 0))
       
   848     /* invalid node descriptor... */
       
   849     return -1;
       
   850 
       
   851 #ifdef DEBUG
       
   852 //  printf("[%lu] locking mutex...\n", pthread_self());
       
   853 #endif
       
   854 //  while (pthread_mutex_lock(&sendmsg_mutex) != 0);
       
   855 
       
   856   /*************************
       
   857   * prepare the header...  *
       
   858   *************************/
       
   859   build_header(header, transaction_id, data_length);
       
   860 #ifdef DEBUG
       
   861 /* Print the hex value of each character that is about to be
       
   862  * sent over the bus.
       
   863  */
       
   864   { int i;
       
   865     printf("modbus_tcp_write(): sending data...\n");
       
   866     for(i = 0; i < TCP_HEADER_LENGTH; i++)
       
   867       printf("[0x%2X]", header[i]);
       
   868     for(i = 0; i < data_length; i++)
       
   869       printf("[0x%2X]", data[i]);
       
   870     printf("\n");
       
   871   }
       
   872 #endif
       
   873 
       
   874   /******************************************
       
   875    * do we need to re-establish connection? *
       
   876    ******************************************/
       
   877   if (open_connection(nd, transmit_timeout) < 0) {
       
   878 #ifdef DEBUG
       
   879     fprintf(stderr, "[%lu] modbus_tcp_write(): could not establish connection...\n", pthread_self());
       
   880 #endif
       
   881 #ifdef ERRMSG
       
   882     fprintf(stderr, ERRMSG_HEAD "could not establish connection...\n");
       
   883 #endif
       
   884     return -1;
       
   885   }
       
   886 
       
   887   /**********************
       
   888    * write to output... *
       
   889    **********************/
       
   890    /* TWO ALTERNATIVE IMPLEMENTATIONS !!! */
       
   891 #if 0
       
   892     /* write header */
       
   893   bytes_sent = 0;
       
   894   while (1) {
       
   895     res = write(nd_table_.node[nd].fd, header+bytes_sent, TCP_HEADER_LENGTH-bytes_sent);
       
   896     if (res < 0) {
       
   897       if ((errno != EAGAIN ) && (errno != EINTR )) {
       
   898         /* error sending message... */
       
   899         close_connection(nd);
       
   900         return -1;
       
   901       } else {
       
   902         continue;
       
   903       }
       
   904     } else {
       
   905       /* res >= 0 */
       
   906       bytes_sent += res;
       
   907       if (bytes_sent >= TCP_HEADER_LENGTH) {
       
   908         break;
       
   909       }
       
   910 	}
       
   911   }
       
   912 
       
   913       /* write data */
       
   914   bytes_sent = 0;
       
   915   while (1) {
       
   916     res = write(nd_table_.node[nd].fd, data+bytes_sent, data_length-bytes_sent);
       
   917     if (res < 0) {
       
   918       if ((errno != EAGAIN ) && (errno != EINTR )) {
       
   919         /* error sending message... */
       
   920         close_connection(nd);
       
   921         return -1;
       
   922       } else {
       
   923         continue;
       
   924       }
       
   925     } else {
       
   926       /* res >= 0 */
       
   927       bytes_sent += res;
       
   928       if (bytes_sent >= data_length) {
       
   929         /* query succesfully sent! */
       
   930 #ifdef DEBUG
       
   931         printf("[%lu] modbus_tcp_write(): sent %d bytes\n", pthread_self(), TCP_HEADER_LENGTH+data_length);
       
   932 #endif
       
   933         return data_length;
       
   934       }
       
   935 	}
       
   936   }
       
   937 
       
   938    /**********************
       
   939    * write to output... *
       
   940    **********************/
       
   941 #else
       
   942   /* We are optimising for the most likely case, and in doing that
       
   943    * we are making the least likely case have worse behaviour!
       
   944    * Read on for an explanation...
       
   945    *
       
   946    * - The optimised behaviour for the most likely case:
       
   947    * We have set the NO_DELAY flag on the socket, so the IP datagram
       
   948    * is not delayed and is therefore sent as soon as any data is written to
       
   949    * the socket.
       
   950    * In order to send the whole message in a single IP datagram, we have to
       
   951    * write both the the header and the data with a single call to write()
       
   952    * In order to not to have to copy the data around just to add the
       
   953    * message header, we use sendmsg() instead of write()!
       
   954    *
       
   955    * - The worse behaviour for the least likely case:
       
   956    * If for some reason only part of the data is sent with the first call to
       
   957    * write(), a datagram is sent right away, and the subsequent data will
       
   958    * be sent in another datagram. :-(
       
   959    */
       
   960    /* NOTE: since snedmsg() is not thread safe, we use a mutex to protect access to this function... */
       
   961 
       
   962   data_vector[data_vector_size - 1].iov_base = data;
       
   963   data_vector[data_vector_size - 1].iov_len  = data_length;
       
   964   data_vector[                   0].iov_base = header;
       
   965   data_vector[                   0].iov_len  = TCP_HEADER_LENGTH;
       
   966   bytes_sent = 0;
       
   967   while (1) {
       
   968     int sendmsg_errno;
       
   969      /* Please see the comment just above the main loop!! */
       
   970     res = sendmsg(nd_table_.node[nd].fd, &msg, 0);
       
   971     sendmsg_errno = errno;
       
   972     if (res < 0) {
       
   973       if ((sendmsg_errno != EAGAIN ) && (sendmsg_errno != EINTR )) {
       
   974         /* error sending message... */
       
   975         close_connection(nd);
       
   976         return -1;
       
   977       } else {
       
   978         continue;
       
   979       }
       
   980     } else {
       
   981       /* res >= 0 */
       
   982       bytes_sent += res;
       
   983       if (bytes_sent >= data_length + TCP_HEADER_LENGTH) {
       
   984         /* query succesfully sent! */
       
   985 #ifdef DEBUG
       
   986         printf("[%lu] modbus_tcp_write(): sent %d bytes\n", pthread_self(), bytes_sent);
       
   987 #endif
       
   988 //        pthread_mutex_unlock(&sendmsg_mutex);
       
   989 #ifdef DEBUG
       
   990 //        printf("[%lu] unlocked  mutex...\n", pthread_self());
       
   991 #endif
       
   992         return data_length;
       
   993       }
       
   994 
       
   995       /* adjust the data_vector... */
       
   996       if (res < data_vector[0].iov_len) {
       
   997         u8* tmp = data_vector[0].iov_base;
       
   998         tmp += res; 
       
   999         data_vector[0].iov_len -= res;
       
  1000         data_vector[0].iov_base = tmp;
       
  1001       } else {
       
  1002         u8* tmp = data_vector[1].iov_base;
       
  1003         tmp += res; 
       
  1004         res -= data_vector[0].iov_len;
       
  1005         data_vector[0].iov_len  = 0;
       
  1006         data_vector[1].iov_len -= res;
       
  1007         data_vector[1].iov_base = tmp;
       
  1008       }
       
  1009     }
       
  1010   } /* while (1) */
       
  1011 #endif
       
  1012 
       
  1013   /* humour the compiler... */
       
  1014 //  pthread_mutex_unlock(&sendmsg_mutex);
       
  1015 #ifdef DEBUG
       
  1016 //  printf("[%lu] unlocked  mutex...\n", pthread_self());
       
  1017 #endif
       
  1018   return -1;
       
  1019 }
       
  1020 
       
  1021 
       
  1022 
       
  1023 /**************************************************************/
       
  1024 /**************************************************************/
       
  1025 /****                                                      ****/
       
  1026 /****                                                      ****/
       
  1027 /****              Receiving Modbus TCP Frames             ****/
       
  1028 /****                                                      ****/
       
  1029 /****                                                      ****/
       
  1030 /**************************************************************/
       
  1031 /**************************************************************/
       
  1032 
       
  1033 
       
  1034 /* A helper function to modbus_tcp_read()
       
  1035  *
       
  1036  * WARNING: The semantics of this function are not what you would expect!
       
  1037  *
       
  1038  *          if (data_already_available != 0)
       
  1039  *          It assumes that select() has already been called before
       
  1040  *          this function got called, and we are therefore guaranteed
       
  1041  *          to have at least one byte to read off the socket (the fd).
       
  1042  *
       
  1043  *          if (data_already_available == 0)
       
  1044  *          it starts off by calling select()!
       
  1045  *
       
  1046  *
       
  1047  * NOTE: Ususal select semantics for (a: end_time == NULL) and
       
  1048  *       (b: *end_time == 0) also apply.
       
  1049  *
       
  1050  *       (a) Indefinite timeout
       
  1051  *       (b) Try once, and and quit if no data available.
       
  1052  */
       
  1053 /* RETURNS: number of bytes read
       
  1054  *          -1 read error!
       
  1055  *          -2 timeout
       
  1056  */
       
  1057 static int read_bytes(int fd,
       
  1058                       u8 *data,
       
  1059                       int max_data_count,
       
  1060                       const struct timespec *end_time,
       
  1061                       int data_already_available)
       
  1062 {
       
  1063   fd_set rfds;
       
  1064   int res, data_count;
       
  1065 
       
  1066   data_count = 0;
       
  1067 
       
  1068   while (data_count < max_data_count) {
       
  1069     /*============================*
       
  1070      * wait for data availability *
       
  1071      *============================*/
       
  1072     if (data_already_available == 0) {
       
  1073       int sel_res;
       
  1074       FD_ZERO(&rfds);
       
  1075       FD_SET(fd, &rfds);
       
  1076       sel_res = my_select(fd + 1, &rfds, NULL, end_time);
       
  1077       if (sel_res < 0)
       
  1078         return -1;
       
  1079       if (sel_res == 0)
       
  1080         /* timeout! */
       
  1081         return -2;
       
  1082     }
       
  1083 
       
  1084     /*============================*
       
  1085      * read the available data... *
       
  1086      *============================*/
       
  1087     res = read(fd, data + data_count, max_data_count - data_count);
       
  1088     if (res == 0) {
       
  1089       /* We are guaranteed to have data to read off the fd since we called
       
  1090        * select(), but read() returned 0 bytes.
       
  1091        * This means that the remote process has closed down the connection,
       
  1092        * so we return 0.
       
  1093        */
       
  1094       return 0;
       
  1095     }
       
  1096 
       
  1097     if (res < 0) {
       
  1098       if (errno != EINTR)
       
  1099         return -1;
       
  1100       else
       
  1101         res = 0;
       
  1102     }
       
  1103 #ifdef DEBUG
       
  1104     {/* display the hex code of each character received */
       
  1105       int i;
       
  1106       for (i=0; i < res; i++)
       
  1107         printf("<0x%2X>", *(data + data_count + i));
       
  1108     }
       
  1109 #endif
       
  1110     data_count += res;
       
  1111     data_already_available = 0;
       
  1112   } /* while ()*/
       
  1113 
       
  1114   /* data read succesfully... */
       
  1115   return data_count;
       
  1116 }
       
  1117 
       
  1118 
       
  1119 
       
  1120 /***************************************/
       
  1121 /**                                   **/
       
  1122 /**    Read a Modbus TCP frame        **/
       
  1123 /**    off a single identified node.  **/
       
  1124 /**                                   **/
       
  1125 /***************************************/
       
  1126 
       
  1127 /* This private function will read a Modbus TCP frame off a single identified node
       
  1128  * that we know before hand that has data ready to be read off it. The data may or may not be
       
  1129  * a valid Modbus TCP frame. It is up to this function to figure that out.
       
  1130  */
       
  1131 /* NOTES:
       
  1132  *  - We re-use the recv_buf_ to load the frame header, so we have to make
       
  1133  *    sure that the buffer is large enough to take it...
       
  1134  */
       
  1135  /* RETURNS: number of bytes read
       
  1136   *          -1 on read from file/node error
       
  1137   *          -2 on timeout
       
  1138   */
       
  1139 #if RECV_BUFFER_SIZE < TCP_HEADER_LENGTH
       
  1140 #error The receive buffer is smaller than the frame header length.
       
  1141 #endif
       
  1142 
       
  1143 static int modbus_tcp_read_frame(int nd,
       
  1144                                  u16 *transaction_id,
       
  1145                                  struct timespec *ts_ptr) {
       
  1146   int fd, res;
       
  1147   u16 frame_length;
       
  1148 
       
  1149 #ifdef DEBUG
       
  1150   printf("[%lu] modbus_tcp_read_frame(): reading off nd=%d\n", pthread_self(), nd);
       
  1151 #endif
       
  1152   /*=========================*
       
  1153    * read a Modbus TCP frame *
       
  1154    *=========================*/
       
  1155   /* assume error... */
       
  1156   fd = nd_table_.node[nd].fd;
       
  1157 
       
  1158   /*-------------*
       
  1159    * read header *
       
  1160    *-------------*/
       
  1161   if ((res = read_bytes(fd, nd_table_.node[nd].recv_buf, TCP_HEADER_LENGTH, ts_ptr, 1)) != TCP_HEADER_LENGTH) { 
       
  1162 #ifdef DEBUG
       
  1163     printf("[%lu] modbus_tcp_read_frame(): frame with insuficient bytes for a valid header...\n", pthread_self());
       
  1164 #endif
       
  1165     if (res < 0) return res;
       
  1166     return -1;
       
  1167   }
       
  1168 
       
  1169   /* let's check for header consistency... */
       
  1170   if (check_header(nd_table_.node[nd].recv_buf, transaction_id, &frame_length) < 0) {
       
  1171 #ifdef DEBUG
       
  1172     printf("[%lu] modbus_tcp_read_frame(): frame with non valid header...\n", pthread_self());
       
  1173 #endif
       
  1174     return -1;
       
  1175   }
       
  1176 
       
  1177   /*-----------*
       
  1178    * read data *
       
  1179    *-----------*/
       
  1180   if ((res = read_bytes(fd, nd_table_.node[nd].recv_buf, frame_length, ts_ptr, 0)) != frame_length) { 
       
  1181 #ifdef DEBUG
       
  1182     printf("[%lu] modbus_tcp_read_frame(): frame with non valid frame length...\n", pthread_self());
       
  1183 #endif
       
  1184     if (res < 0) return res;
       
  1185     return -1;
       
  1186   }
       
  1187 
       
  1188   /* frame received succesfully... */
       
  1189 #ifdef DEBUG
       
  1190   printf("\n");
       
  1191 #endif
       
  1192   return frame_length;
       
  1193 }
       
  1194 
       
  1195 
       
  1196 
       
  1197 
       
  1198 /***************************************/
       
  1199 /**                                   **/
       
  1200 /**    Read a Modbus TCP frame        **/
       
  1201 /**    OR Accept connection requests  **/
       
  1202 /**    off possibly multiple node...  **/
       
  1203 /**                                   **/
       
  1204 /***************************************/
       
  1205 
       
  1206 /* The public function that reads a valid modbus frame.
       
  1207  * The frame is read from...:
       
  1208  *   -  if (nd >= 0) and (nd is of type MB_MASTER_NODE or MB_SLAVE_NODE)
       
  1209  *          The frame is read from the node descriptor nd 
       
  1210  *   -  if (nd >= 0) and (nd is of type MB_LISTEN_NODE)
       
  1211  *          The frame is read from the all node descriptors of type MB_SLAVE_NODE that were
       
  1212  *          opened as a consequence of a connection request to the nd slave.
       
  1213  *          In this case, new connection requests to nd will also be accepted! 
       
  1214  *   -  if (nd == -1)
       
  1215  *          The frame is read from any valid and initialised node descriptor.
       
  1216  *          In this case, new connection requests to any nd of type MB_LISTEN_NODE will also be accepted! 
       
  1217  *          In this case, the node where the data is eventually read from is returned in *nd.
       
  1218  *
       
  1219  * The send_data and send_length parameters are ignored...
       
  1220  *  (However, these parameters must stay in order to keep the function 
       
  1221  *   interface identical to the ASCII and RTU versons!)
       
  1222  *
       
  1223  * return value: The length (in bytes) of the valid frame,
       
  1224  *               -1 on error
       
  1225  *
       
  1226  * NOTE: Ususal select semantics for (a: recv_timeout == NULL) and
       
  1227  *       (b: *recv_timeout == 0) also apply.
       
  1228  *
       
  1229  *       (a) Indefinite timeout
       
  1230  *       (b) Try once, and and quit if no data available.
       
  1231  */
       
  1232 
       
  1233  /* RETURNS: number of bytes read
       
  1234   *          -1 on read from file/node error
       
  1235   *          -2 on timeout
       
  1236   */
       
  1237 int modbus_tcp_read(int *nd,                /* node descriptor */
       
  1238                     u8 **recv_data_ptr,
       
  1239                     u16 *transaction_id,
       
  1240                     const u8 *send_data,   /* ignored ! */
       
  1241                     int send_length,       /* ignored ! */
       
  1242                     const struct timespec *recv_timeout) {
       
  1243 
       
  1244   struct timespec end_time, *ts_ptr;
       
  1245   u8 *local_recv_data_ptr;
       
  1246   u16 local_transaction_id = 0;
       
  1247 
       
  1248 #ifdef DEBUG
       
  1249   printf("[%lu] modbus_tcp_read(): called...  nd=%d\n", pthread_self(), *nd);
       
  1250 #endif
       
  1251 
       
  1252   if (nd == NULL)
       
  1253     return -1;
       
  1254 
       
  1255   if (*nd >= nd_table_.node_count)
       
  1256     /* invalid *nd                      */
       
  1257     /* remember that *nd < 0 is valid!! */
       
  1258     return -1;
       
  1259 
       
  1260   if (recv_data_ptr == NULL)
       
  1261     recv_data_ptr = &local_recv_data_ptr;
       
  1262   if (transaction_id == NULL)
       
  1263     transaction_id = &local_transaction_id;
       
  1264 
       
  1265   /* We will potentially call read() multiple times to read in a single frame.
       
  1266    * We therefore determine the absolute time_out, and use this as a parameter
       
  1267    * for each call to read_bytes() instead of using a relative timeout.
       
  1268    *
       
  1269    * NOTE: see also the timeout related comment in the read_bytes() function!
       
  1270    */
       
  1271   ts_ptr = NULL;
       
  1272   if (recv_timeout != NULL) {
       
  1273      ts_ptr = &end_time;
       
  1274     *ts_ptr = timespec_add_curtime(*recv_timeout);
       
  1275   }
       
  1276 
       
  1277   /* If we must read off a single node... */
       
  1278   if (*nd >= 0)
       
  1279     /* but the node does not have a valid fd */
       
  1280     if ((nd_table_.node[*nd].node_type == MB_FREE_NODE) ||
       
  1281         (nd_table_.node[*nd].fd < 0))
       
  1282       /* then we return an error... */
       
  1283       return -1;
       
  1284 
       
  1285   /* We will loop forever...
       
  1286    * We jump out of the loop and return from the function as soon as:
       
  1287    *  - we receive a valid modbus message;
       
  1288    *    OR
       
  1289    *  - we time out.
       
  1290    * 
       
  1291    *  NOTE: This loop will close connections through which we receive invalid frames.
       
  1292    *        This means that the set of nodes through which we may receive data may change with each
       
  1293    *        loop iteration.  => We need to re-calculate the fds in each loop iteration! 
       
  1294    */
       
  1295 
       
  1296   while (1) {
       
  1297     int nd_count, fd_high;
       
  1298     fd_set rfds;
       
  1299 
       
  1300     /* We prepare our fd sets here so we can later call select() */
       
  1301     FD_ZERO(&rfds);
       
  1302     fd_high = -1;
       
  1303 
       
  1304     for (nd_count = 0; nd_count < nd_table_.node_count; nd_count++) {
       
  1305       if (nd_table_.node[nd_count].node_type != MB_FREE_NODE)
       
  1306       {
       
  1307         if ((*nd < 0)  // we select from all nodes 
       
  1308             || (*nd == nd_count)  // we select from this specific node
       
  1309               // we are listening on a MB_LISTEN_NODE, so we must also receive requests sent to slave nodes
       
  1310               // whose connection requests arrived through this MB_LISTEN_NDODE 
       
  1311             || ((nd_table_.node[nd_count].node_type == MB_SLAVE_NODE) && (nd_table_.node[nd_count].listen_node == *nd))) 
       
  1312         {
       
  1313           /* check if valid fd */
       
  1314           if (nd_table_.node[nd_count].fd >= 0) {
       
  1315             /* Add the descriptor to the fd set... */
       
  1316             FD_SET(nd_table_.node[nd_count].fd, &rfds);
       
  1317             fd_high = max(fd_high, nd_table_.node[nd_count].fd);
       
  1318           }
       
  1319         }
       
  1320       }
       
  1321     } /* for(;;) */
       
  1322 
       
  1323 #ifdef DEBUG
       
  1324     printf("[%lu] modbus_tcp_read(): while(1) looping. fd_high = %d, nd=%d\n", pthread_self(), fd_high, *nd);
       
  1325 #endif
       
  1326 
       
  1327     if (fd_high == -1)
       
  1328       /* we will not be reading from any node! */
       
  1329       return -1;
       
  1330 
       
  1331     /* We now call select and wait for activity on the nodes we are listening to */
       
  1332     { int sel_res = my_select(fd_high + 1, &rfds, NULL, ts_ptr);
       
  1333       if (sel_res < 0)
       
  1334         return -1;
       
  1335       if (sel_res == 0)
       
  1336         /* timeout! */
       
  1337         return -2;
       
  1338     }
       
  1339 
       
  1340     /* figure out which nd is ready to be read... */
       
  1341     for (nd_count = 0; nd_count < nd_table_.node_count; nd_count++) {
       
  1342       if ((nd_table_.node[nd_count].node_type != MB_FREE_NODE) &&
       
  1343           (nd_table_.node[nd_count].fd >= 0)) {
       
  1344         if (FD_ISSET(nd_table_.node[nd_count].fd, &rfds)) {
       
  1345           /* Found the node descriptor... */
       
  1346 #ifdef DEBUG
       
  1347           printf("[%lu] modbus_tcp_read(): my_select() returned due to activity on node nd=%d\n", pthread_self(), nd_count);
       
  1348 #endif
       
  1349           if (nd_table_.node[nd_count].node_type == MB_LISTEN_NODE) {
       
  1350             /* We must accept a new connection...
       
  1351              * No need to check for errors.
       
  1352              * If one occurs, there is nothing we can do...
       
  1353              */
       
  1354             accept_connection(nd_count);
       
  1355           } else {
       
  1356             /* it is a MB_SLAVE_NODE or a MB_MASTER_NODE */ 
       
  1357             /* We will read a frame off this nd */
       
  1358             int res;
       
  1359             res = modbus_tcp_read_frame(nd_count, transaction_id, ts_ptr);
       
  1360             if (res > 0) {
       
  1361               *nd = nd_count;
       
  1362               *recv_data_ptr = nd_table_.node[nd_count].recv_buf;
       
  1363               return res;
       
  1364             } 
       
  1365             if (res < 0) {
       
  1366                 /* We had an error reading the frame...
       
  1367                  * We handle it by closing the connection, as specified by
       
  1368                  * the modbus TCP protocol!
       
  1369                  *
       
  1370                  * NOTE: The error may have been a timeout, which means this function should return immediately.
       
  1371                  *       However, in this case we let the execution loop once again
       
  1372                  *       in the while(1) loop. My_select() will be called again
       
  1373                  *       and the timeout detected. The timeout error code (-2)
       
  1374                  *       will then be returned correctly!
       
  1375                  */
       
  1376 #ifdef DEBUG
       
  1377               printf("[%lu] modbus_tcp_read(): error reading frame. Closing connection...\n", pthread_self());
       
  1378 #endif
       
  1379               /* We close the socket... */
       
  1380               close_connection(nd_count);
       
  1381             }
       
  1382           }
       
  1383           /* we have found the node descriptor, so let's jump out of the for(;;) loop */
       
  1384           break;
       
  1385         }
       
  1386       }
       
  1387     } /* for(;;) */
       
  1388 
       
  1389     /* We were unsuccesfull reading a frame, so we try again... */
       
  1390   } /* while (1) */
       
  1391 
       
  1392   /* humour the compiler... */
       
  1393   return -1;
       
  1394 }
       
  1395 
       
  1396 
       
  1397 
       
  1398 
       
  1399 
       
  1400 /**************************************************************/
       
  1401 /**************************************************************/
       
  1402 /****                                                      ****/
       
  1403 /****                                                      ****/
       
  1404 /****        Initialising and Shutting Down Library        ****/
       
  1405 /****                                                      ****/
       
  1406 /****                                                      ****/
       
  1407 /**************************************************************/
       
  1408 /**************************************************************/
       
  1409 
       
  1410 
       
  1411 /* Ugly hack...
       
  1412  *  Beremiz will be calling modbus_tcp_init() multiple times (through modbus_init() )
       
  1413  *    (once for each plugin instance)
       
  1414  *  It will also be calling modbus_tcp_done() the same number of times
       
  1415  *  We only want to really shutdown the library the last time it is called.
       
  1416  *  We therefore keep a counter of how many times modbus_tcp_init() is called,
       
  1417  *  and decrement it in modbus_tcp_done()
       
  1418  */
       
  1419 int modbus_tcp_init_counter = 0;
       
  1420 
       
  1421 /******************************/
       
  1422 /**                          **/
       
  1423 /**   Load Default Values    **/
       
  1424 /**                          **/
       
  1425 /******************************/
       
  1426 
       
  1427 static void set_defaults(const char **service) {
       
  1428   /* Set the default values, if required... */
       
  1429   if (*service == NULL)
       
  1430     *service = DEF_SERVICE;
       
  1431 }
       
  1432 
       
  1433 
       
  1434 /******************************/
       
  1435 /**                          **/
       
  1436 /**    Initialise Library    **/
       
  1437 /**                          **/
       
  1438 /******************************/
       
  1439 /* returns the number of nodes succesfully initialised...
       
  1440  * returns -1 on error.
       
  1441  */
       
  1442 int modbus_tcp_init(int nd_count,
       
  1443                     optimization_t opt /* ignored... */,
       
  1444                     int *extra_bytes) {
       
  1445 #ifdef DEBUG
       
  1446   printf("[%lu] modbus_tcp_init(): called...\n", pthread_self());
       
  1447   printf("[%lu] creating %d nodes:\n", pthread_self(), nd_count);
       
  1448 #endif
       
  1449 
       
  1450   modbus_tcp_init_counter++;
       
  1451   
       
  1452     /* set the extra_bytes value... */
       
  1453     /* Please see note before the modbus_rtu_write() function for a
       
  1454      * better understanding of this extremely ugly hack... This will be
       
  1455      * in the mb_rtu.c file!!
       
  1456      *
       
  1457      * The number of extra bytes that must be allocated to the data buffer
       
  1458      * before calling modbus_tcp_write()
       
  1459      */
       
  1460   if (extra_bytes != NULL)
       
  1461     *extra_bytes = 0;
       
  1462 
       
  1463   if (0 == nd_count)
       
  1464     /* no need to initialise this layer! */
       
  1465     return 0;
       
  1466   if (nd_count <= 0)
       
  1467     /* invalid node count... */
       
  1468     goto error_exit_1;
       
  1469 
       
  1470   /* initialise the node table... */
       
  1471   if (nd_table_init(&nd_table_, nd_count) < 0)
       
  1472     goto error_exit_1;
       
  1473 
       
  1474 #ifdef DEBUG
       
  1475   printf("[%lu] modbus_tcp_init(): %d node(s) opened succesfully\n", pthread_self(), nd_count);
       
  1476 #endif
       
  1477   return nd_count; /* number of succesfully created nodes! */
       
  1478 
       
  1479 /*
       
  1480 error_exit_2:
       
  1481   nd_table_done(&nd_table_);
       
  1482 */
       
  1483 error_exit_1:
       
  1484   if (extra_bytes != NULL)
       
  1485     *extra_bytes = 0;
       
  1486   return -1;
       
  1487 }
       
  1488 
       
  1489 
       
  1490 
       
  1491 
       
  1492 
       
  1493 
       
  1494 /******************************/
       
  1495 /**                          **/
       
  1496 /**    Open a Master Node    **/
       
  1497 /**                          **/
       
  1498 /******************************/
       
  1499 int modbus_tcp_connect(node_addr_t node_addr) {
       
  1500   int node_descriptor;
       
  1501   struct sockaddr_in tmp_addr;
       
  1502 
       
  1503 #ifdef DEBUG
       
  1504   printf("[%lu] modbus_tcp_connect(): called...\n", pthread_self());
       
  1505   printf("[%lu]        %s:%s\n", pthread_self(),
       
  1506          node_addr.addr.tcp.host,
       
  1507          node_addr.addr.tcp.service);
       
  1508 #endif
       
  1509 
       
  1510   /* Check for valid address family */
       
  1511   if (node_addr.naf != naf_tcp)
       
  1512     /* wrong address type... */
       
  1513     return -1;
       
  1514 
       
  1515   /* set the default values... */
       
  1516   set_defaults(&(node_addr.addr.tcp.service));
       
  1517 
       
  1518   /* Check the parameters we were passed... */
       
  1519   if(sin_initaddr(&tmp_addr,
       
  1520                   node_addr.addr.tcp.host,    0,
       
  1521                   node_addr.addr.tcp.service, 0,
       
  1522                   DEF_PROTOCOL)
       
  1523        < 0) {
       
  1524 #ifdef ERRMSG
       
  1525     fprintf(stderr, ERRMSG_HEAD "Error parsing/resolving address %s:%s\n",
       
  1526                    node_addr.addr.tcp.host,
       
  1527                    node_addr.addr.tcp.service);
       
  1528 #endif
       
  1529     return -1;
       
  1530   }
       
  1531 
       
  1532   /* find a free node descriptor */
       
  1533   if ((node_descriptor = nd_table_get_free_node(&nd_table_, MB_MASTER_NODE)) < 0)
       
  1534     /* if no free nodes to initialize, then we are finished... */
       
  1535     return -1;
       
  1536 
       
  1537   nd_table_.node[node_descriptor].addr = tmp_addr;
       
  1538   nd_table_.node[node_descriptor].fd   = -1; /* not currently connected... */
       
  1539   nd_table_.node[node_descriptor].close_on_silence = node_addr.addr.tcp.close_on_silence;
       
  1540 
       
  1541   if (nd_table_.node[node_descriptor].close_on_silence < 0)
       
  1542     nd_table_.node[node_descriptor].close_on_silence = DEF_CLOSE_ON_SILENCE;
       
  1543   
       
  1544   /* WE have never tried to connect, so print an error the next time we try to connect */
       
  1545   nd_table_.node[node_descriptor].print_connect_error = 1;
       
  1546 
       
  1547 #ifdef DEBUG
       
  1548   printf("[%lu] modbus_tcp_connect(): returning nd=%d\n", pthread_self(), node_descriptor);
       
  1549 #endif
       
  1550   return node_descriptor;
       
  1551 }
       
  1552 
       
  1553 
       
  1554 
       
  1555 /******************************/
       
  1556 /**                          **/
       
  1557 /**    Open a Slave Node     **/
       
  1558 /**                          **/
       
  1559 /******************************/
       
  1560 
       
  1561 int modbus_tcp_listen(node_addr_t node_addr) {
       
  1562   int fd, nd;
       
  1563 
       
  1564 #ifdef DEBUG
       
  1565   printf("[%lu] modbus_tcp_listen(): called...\n", pthread_self());
       
  1566   printf("[%lu]        %s:%s\n", pthread_self(),
       
  1567          node_addr.addr.tcp.host,
       
  1568          node_addr.addr.tcp.service);
       
  1569 #endif
       
  1570 
       
  1571   /* Check for valid address family */
       
  1572   if (node_addr.naf != naf_tcp)
       
  1573     /* wrong address type... */
       
  1574     goto error_exit_0;
       
  1575 
       
  1576   /* set the default values... */
       
  1577   set_defaults(&(node_addr.addr.tcp.service));
       
  1578 
       
  1579   /* create a socket and bind it to the appropriate port... */
       
  1580   fd = sin_bindsock(node_addr.addr.tcp.host,
       
  1581                     node_addr.addr.tcp.service,
       
  1582                     DEF_PROTOCOL);
       
  1583   if (fd < 0) {
       
  1584 #ifdef ERRMSG
       
  1585     fprintf(stderr, ERRMSG_HEAD "Could not bind to socket %s:%s\n", 
       
  1586                     ((node_addr.addr.tcp.host==NULL)?"#ANY#":node_addr.addr.tcp.host),
       
  1587                     node_addr.addr.tcp.service);
       
  1588 #endif
       
  1589     goto error_exit_0;
       
  1590   }
       
  1591   if (listen(fd, DEF_MAX_PENDING_CONNECTION_REQUESTS) < 0)
       
  1592     goto error_exit_0;
       
  1593 
       
  1594   /* find a free node descriptor */
       
  1595   if ((nd = nd_table_get_free_node(&nd_table_, MB_LISTEN_NODE)) < 0) {
       
  1596     /* if no free nodes to initialize, then we are finished... */
       
  1597     goto error_exit_1;
       
  1598   }
       
  1599 
       
  1600   /* nd_table_.node[nd].addr = tmp_addr; */ /* does not apply for MB_LISTEN_NODE */
       
  1601   nd_table_.node[nd].fd = fd; /* not currently connected... */
       
  1602 
       
  1603 #ifdef DEBUG
       
  1604   printf("[%lu] modbus_tcp_listen(): returning nd=%d\n", pthread_self(), nd);
       
  1605 #endif
       
  1606   return nd;
       
  1607 
       
  1608 error_exit_1:
       
  1609   close(fd);
       
  1610 error_exit_0:
       
  1611   return -1;
       
  1612 }
       
  1613 
       
  1614 
       
  1615 
       
  1616 /******************************/
       
  1617 /**                          **/
       
  1618 /**       Close a node       **/
       
  1619 /**                          **/
       
  1620 /******************************/
       
  1621 
       
  1622 int modbus_tcp_close(int nd) {
       
  1623 #ifdef DEBUG
       
  1624   fprintf(stderr, "[%lu] modbus_tcp_close(): called... nd=%d\n", pthread_self(), nd);
       
  1625 #endif
       
  1626 
       
  1627   if ((nd < 0) || (nd >= nd_table_.node_count)) {
       
  1628     /* invalid nd */
       
  1629 #ifdef DEBUG
       
  1630     fprintf(stderr, "[%lu] modbus_tcp_close(): invalid node %d. Should be < %d\n", pthread_self(), nd, nd_table_.node_count);
       
  1631 #endif
       
  1632     return -1;
       
  1633   }
       
  1634 
       
  1635   if (nd_table_.node[nd].node_type == MB_FREE_NODE)
       
  1636     /* already free node */
       
  1637     return 0;
       
  1638 
       
  1639   close_connection(nd);
       
  1640 
       
  1641   nd_table_close_node(&nd_table_, nd);
       
  1642 
       
  1643   return 0;
       
  1644 }
       
  1645 
       
  1646 
       
  1647 
       
  1648 /**********************************/
       
  1649 /**                              **/
       
  1650 /**  Close all open connections  **/
       
  1651 /**                              **/
       
  1652 /**********************************/
       
  1653 
       
  1654 int modbus_tcp_silence_init(void) {
       
  1655   int nd;
       
  1656 
       
  1657 #ifdef DEBUG
       
  1658   printf("[%lu] modbus_tcp_silence_init(): called...\n", pthread_self());
       
  1659 #endif
       
  1660 
       
  1661   /* close all master connections that remain open... */
       
  1662   for (nd = 0; nd < nd_table_.node_count; nd++)
       
  1663     if (nd_table_.node[nd].node_type == MB_MASTER_NODE)
       
  1664       if (nd_table_.node[nd].close_on_silence > 0)
       
  1665         /* node is is being used for a master device,
       
  1666          * and wishes to be closed...   ...so we close it!
       
  1667          */
       
  1668          close_connection(nd);
       
  1669 
       
  1670   return 0;
       
  1671 }
       
  1672 
       
  1673 
       
  1674 
       
  1675 /******************************/
       
  1676 /**                          **/
       
  1677 /**   Shutdown the Library   **/
       
  1678 /**                          **/
       
  1679 /******************************/
       
  1680 
       
  1681 int modbus_tcp_done(void) {
       
  1682   int i;
       
  1683   
       
  1684   modbus_tcp_init_counter--;
       
  1685   if (modbus_tcp_init_counter != 0) return 0; /* ignore this request */
       
  1686   
       
  1687     /* close all the connections... */
       
  1688   for (i = 0; i < nd_table_.node_count; i++)
       
  1689     modbus_tcp_close(i);
       
  1690 
       
  1691   /* Free memory... */
       
  1692   nd_table_done(&nd_table_);
       
  1693 
       
  1694   return 0;
       
  1695 }
       
  1696 
       
  1697 
       
  1698 
       
  1699 
       
  1700 double modbus_tcp_get_min_timeout(int baud,
       
  1701                                   int parity,
       
  1702                                   int data_bits,
       
  1703                                   int stop_bits) {
       
  1704   return 0;
       
  1705 }