mb_ascii.c
changeset 0 ae252e0fd9b8
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 #include <fcntl.h>      /* File control definitions */
       
    26 #include <stdio.h>      /* Standard input/output */
       
    27 #include <string.h>
       
    28 #include <stdlib.h>
       
    29 #include <termio.h>     /* POSIX terminal control definitions */
       
    30 #include <sys/time.h>   /* Time structures for select() */
       
    31 #include <unistd.h>     /* POSIX Symbolic Constants */
       
    32 #include <assert.h>
       
    33 #include <errno.h>      /* Error definitions */
       
    34 #include <ctype.h>
       
    35 #include <time.h>       /* clock_gettime()   */
       
    36 #include <limits.h>     /* required for INT_MAX */
       
    37 
       
    38 #include "mb_layer1.h"
       
    39 #include "mb_ascii_private.h"
       
    40 
       
    41 
       
    42 /* #define DEBUG */         /* uncomment to see the data sent and received */
       
    43 
       
    44 
       
    45 
       
    46 
       
    47 /************************************/
       
    48 /**                                **/
       
    49 /** Include common code...         **/
       
    50 /**                                **/
       
    51 /************************************/
       
    52 
       
    53 #include "mb_ds_util.h"    /* data structures... */
       
    54 #include "mb_time_util.h"  /* time conversion routines... */
       
    55 
       
    56 
       
    57 /**************************************************************/
       
    58 /**************************************************************/
       
    59 /****                                                      ****/
       
    60 /****                                                      ****/
       
    61 /****                Purpose and Formats                   ****/
       
    62 /****                                                      ****/
       
    63 /****                                                      ****/
       
    64 /**************************************************************/
       
    65 /**************************************************************/
       
    66 /*
       
    67 
       
    68    This file implements the ascii formating of the modbus protocol.
       
    69    Many values, protocol related, are hardcoded into the code, as it
       
    70    seems very unlikely this code will ever get re-used for anything
       
    71    else but this specific protocol.
       
    72 
       
    73    Modbus ASCII frames have no timing restrictions whatsoever, and
       
    74    abide by the following format:
       
    75 
       
    76    Header
       
    77    ------
       
    78      size : 1 byte
       
    79      value: ':' (i.e. '\0x3A')
       
    80 
       
    81    Body
       
    82    ----
       
    83      size : variable, multiple of 2
       
    84      value: binary data converted to ascii format,
       
    85             i.e. each binary data byte is converted into two ascii characters
       
    86             representing the byte in hexadecimal. Allowable characters are
       
    87             '0' to '9' and 'A' to 'D'
       
    88 
       
    89    LRC
       
    90    ---
       
    91      size : 2 bytes
       
    92      value: Longitudinal Redundancy Check of data, excluding any headers, tails,
       
    93             etc...
       
    94 
       
    95    Tail
       
    96    ----
       
    97      size : 2 bytes
       
    98      value: 'CR' + 'LF'  (i.e. '\0x0D' + '\0x0A')
       
    99 
       
   100 
       
   101 */
       
   102 
       
   103 
       
   104 
       
   105 /**************************************************************/
       
   106 /**************************************************************/
       
   107 /****                                                      ****/
       
   108 /****                                                      ****/
       
   109 /****                Forward Declarations                  ****/
       
   110 /****                    and Defaults                      ****/
       
   111 /****                                                      ****/
       
   112 /**************************************************************/
       
   113 /**************************************************************/
       
   114 
       
   115 
       
   116 typedef enum {fp_header, fp_body, fp_lrc, fp_tail, fp_done} frame_part_t;
       
   117 
       
   118 
       
   119 
       
   120 
       
   121 /**************************************************************/
       
   122 /**************************************************************/
       
   123 /****                                                      ****/
       
   124 /****                                                      ****/
       
   125 /****              Local Utility functions...              ****/
       
   126 /****                                                      ****/
       
   127 /****                                                      ****/
       
   128 /**************************************************************/
       
   129 /**************************************************************/
       
   130 
       
   131 
       
   132 /*****************************************/
       
   133 /**                                     **/
       
   134 /**             lrc functions           **/
       
   135 /**                                     **/
       
   136 /*****************************************/
       
   137 
       
   138 
       
   139 static inline void lrc_init(u8 *lrc) {
       
   140   *lrc = 0;
       
   141 }
       
   142 
       
   143 static inline void lrc_add_single(u8 *lrc, u8 data) {
       
   144   *lrc += data;
       
   145 }
       
   146 
       
   147 static inline void lrc_add_many(u8 *lrc, u8 *data, int count) {
       
   148   for (; count > 0; count--, *lrc += *data++);
       
   149 }
       
   150 
       
   151 static inline void lrc_end(u8 *lrc) {
       
   152   *lrc = 1 + ~(*lrc);
       
   153 }
       
   154 
       
   155 
       
   156 
       
   157 /**************************************/
       
   158 /**                                  **/
       
   159 /**    Initialise a struct termios   **/
       
   160 /**                                  **/
       
   161 /**************************************/
       
   162 static int termios_init(struct termios *tios,
       
   163                         int baud,
       
   164                         int parity,
       
   165                         int data_bits,
       
   166                         int stop_bits) {
       
   167   speed_t baud_rate;
       
   168 
       
   169   if (tios == NULL)
       
   170     return -1;
       
   171 
       
   172   /* reset all the values... */
       
   173   /* NOTE: the following are initialised later on...
       
   174   tios->c_iflag = 0;
       
   175   tios->c_oflag = 0;
       
   176   tios->c_cflag = 0;
       
   177   tios->c_lflag = 0;
       
   178   */
       
   179   tios->c_line  = 0;
       
   180 
       
   181  /* The minimum number of characters that should be received
       
   182   * to satisfy a call to read().
       
   183   */
       
   184   tios->c_cc[VMIN ] = 0;
       
   185 
       
   186  /* The maximum inter-arrival interval between two characters,
       
   187   * in deciseconds.
       
   188   *
       
   189   * NOTE: we could use this to detect the end of RTU frames,
       
   190   *       but we prefer to use select() that has higher resolution,
       
   191   *       even though this higher resolution is most probably not
       
   192   *       supported, and the effective resolution is 10ms,
       
   193   *       one tenth of a decisecond.
       
   194   */
       
   195   tios->c_cc[VTIME] = 0;
       
   196 
       
   197   /* configure the input modes... */
       
   198   tios->c_iflag =  IGNBRK |  /* ignore BREAK condition on input         */
       
   199                    IGNPAR |  /* ignore framing errors and parity errors */
       
   200                    IXANY;    /* enable any character to restart output  */
       
   201   /*               BRKINT       Only active if IGNBRK is not set.
       
   202    *                            generate SIGINT on BREAK condition,
       
   203    *                            otherwise read BREAK as character \0.
       
   204    *               PARMRK       Only active if IGNPAR is not set.
       
   205    *                            replace bytes with parity errors with
       
   206    *                            \377 \0, instead of \0.
       
   207    *               INPCK        enable input parity checking
       
   208    *               ISTRIP       strip off eighth bit
       
   209    *               IGNCR        ignore carriage return on input
       
   210    *               INLCR        only active if IGNCR is not set.
       
   211    *                            translate newline to carriage return  on input
       
   212    *               ICRNL        only active if IGNCR is not set.
       
   213    *                            translate carriage return to newline on input
       
   214    *               IUCLC        map uppercase characters to lowercase on input
       
   215    *               IXON         enable XON/XOFF flow control on output
       
   216    *               IXOFF        enable XON/XOFF flow control on input
       
   217    *               IMAXBEL      ring bell when input queue is full
       
   218    */
       
   219 
       
   220   /* configure the output modes... */
       
   221   tios->c_oflag = OPOST;     /* enable implementation-defined output processing */
       
   222   /*              ONOCR         don't output CR at column 0
       
   223    *              OLCUC         map lowercase characters to uppercase on output
       
   224    *              ONLCR         map NL to CR-NL on output
       
   225    *              OCRNL         map CR to NL on output
       
   226    *              OFILL         send fill characters for a delay, rather than
       
   227    *                            using a timed delay
       
   228    *              OFDEL         fill character is ASCII DEL. If unset, fill
       
   229    *                            character is ASCII NUL
       
   230    *              ONLRET        don't output CR
       
   231    *              NLDLY         NL delay mask. Values are NL0 and NL1.
       
   232    *              CRDLY         CR delay mask. Values are CR0, CR1, CR2, or CR3.
       
   233    *              TABDLY        horizontal tab delay mask. Values are TAB0, TAB1,
       
   234    *                            TAB2, TAB3, or XTABS. A value of XTABS expands
       
   235    *                            tabs to spaces (with tab stops every eight columns).
       
   236    *              BSDLY         backspace delay mask. Values are BS0 or BS1.
       
   237    *              VTDLY         vertical tab delay mask. Values are VT0 or VT1.
       
   238    *              FFDLY         form feed delay mask. Values are FF0 or FF1.
       
   239    */
       
   240 
       
   241   /* configure the control modes... */
       
   242   tios->c_cflag = CREAD |    /* enable receiver.               */
       
   243                   CLOCAL;    /* ignore modem control lines     */
       
   244   /*              HUPCL         lower modem control lines after last process
       
   245    *                            closes the device (hang up).
       
   246    *              CRTSCTS       flow control (Request/Clear To Send).
       
   247    */
       
   248        if (data_bits == 5) tios->c_cflag |= CS5;
       
   249   else if (data_bits == 6) tios->c_cflag |= CS6;
       
   250   else if (data_bits == 7) tios->c_cflag |= CS7;
       
   251   else if (data_bits == 8) tios->c_cflag |= CS8;
       
   252   else return -1;
       
   253 
       
   254        if (stop_bits == 1) tios->c_cflag &=~ CSTOPB;
       
   255   else if (stop_bits == 2) tios->c_cflag |= CSTOPB;
       
   256   else return -1;
       
   257 
       
   258          if(parity == 0) { /* none */
       
   259     tios->c_cflag &=~ PARENB;
       
   260     tios->c_cflag &=~ PARODD;
       
   261   } else if(parity == 2)  { /* even */
       
   262     tios->c_cflag |= PARENB;
       
   263     tios->c_cflag &=~ PARODD;
       
   264   } else if(parity == 1)  { /* odd */
       
   265     tios->c_cflag |= PARENB;
       
   266     tios->c_cflag |= PARODD;
       
   267   } else return -1;
       
   268 
       
   269 
       
   270   /* configure the local modes... */
       
   271   tios->c_lflag = IEXTEN;    /* enable implementation-defined input processing   */
       
   272   /*              ISIG          when any of the characters INTR, QUIT, SUSP, or DSUSP
       
   273    *                            are received, generate the corresponding signal.
       
   274    *              ICANON        enable canonical mode. This enables the special
       
   275    *                            characters EOF, EOL, EOL2, ERASE, KILL, REPRINT,
       
   276    *                            STATUS, and WERASE, and buffers by lines.
       
   277    *              ECHO          echo input characters.
       
   278    */
       
   279 
       
   280   /* Set the baud rate */
       
   281   /* Must be done before reseting all the values to 0! */
       
   282   switch(baud) {
       
   283     case 110:    baud_rate = B110;    break;
       
   284     case 300:    baud_rate = B300;    break;
       
   285     case 600:    baud_rate = B600;    break;
       
   286     case 1200:   baud_rate = B1200;   break;
       
   287     case 2400:   baud_rate = B2400;   break;
       
   288     case 4800:   baud_rate = B4800;   break;
       
   289     case 9600:   baud_rate = B9600;   break;
       
   290     case 19200:  baud_rate = B19200;  break;
       
   291     case 38400:  baud_rate = B38400;  break;
       
   292     case 57600:  baud_rate = B57600;  break;
       
   293     case 115200: baud_rate = B115200; break;
       
   294     default: return -1;
       
   295   } /* switch() */
       
   296 
       
   297   if ((cfsetispeed(tios, baud_rate) < 0) ||
       
   298       (cfsetospeed(tios, baud_rate) < 0))
       
   299     return -1;;
       
   300 
       
   301   return 0;
       
   302 }
       
   303 
       
   304 
       
   305 
       
   306 
       
   307 
       
   308 /*****************************************/
       
   309 /**                                     **/
       
   310 /**     u8/ascii conversion functions   **/
       
   311 /**                                     **/
       
   312 /*****************************************/
       
   313 
       
   314 /* Convert binary data to ascii format.
       
   315  * Both xxx_data_lengths specify the available bytes in
       
   316  * in the respective arrays.
       
   317  */
       
   318 /* NOTE: this function is only called from a single location
       
   319  *       so we might just as well make it inline...
       
   320  */
       
   321 static inline int bin_2_asc(u8 *bin_data, int bin_data_length,
       
   322                             u8 *asc_data, int asc_data_length) {
       
   323   u8  nibble;
       
   324   int count = 0;
       
   325   u8  *last_bin_data = bin_data + bin_data_length;
       
   326     /* we need L2_TO_ASC_CODING ascii bytes for each bin byte, therefore the
       
   327      * '- (L2_TO_ASC_CODING - 1)'
       
   328      */
       
   329   u8  *last_asc_data = asc_data + asc_data_length - (L2_TO_ASC_CODING - 1);
       
   330 
       
   331   while ((bin_data < last_bin_data) &&
       
   332          (asc_data < last_asc_data)) {
       
   333 
       
   334     nibble = (*bin_data & 0xF0) >> 4;
       
   335     *(asc_data++) = (nibble <= 9)?nibble + '0':nibble - 10 + 'A';
       
   336 
       
   337     nibble = (*bin_data & 0x0F);
       
   338     *(asc_data++) = (nibble <= 9)?nibble + '0':nibble - 10 + 'A';
       
   339 
       
   340     count++;
       
   341     bin_data++;
       
   342   }
       
   343 
       
   344   /* return number of bytes converted... */
       
   345   return count;
       
   346 }
       
   347 
       
   348 
       
   349 /* Convert from lowercase to upper case. */
       
   350 /* It probably does not make sense calling the generic toupper()
       
   351  * whose functionality depends on the current locale.
       
   352  * Our own specific function is most probably much faster...
       
   353  */
       
   354 static inline u8 local_toupper(u8 val) {
       
   355   if ((val >= 'a') && (val <= 'z'))
       
   356     return val - 'a' + 'A';
       
   357   return val;
       
   358 }
       
   359 
       
   360 /* Convert ascii data to bin format.
       
   361  * *asc_data must be a two byte array.
       
   362  *
       
   363  * If a non-ascii character is found, returns -1
       
   364  */
       
   365 /* NOTE: this function is only called from a single location
       
   366  *       so we might just as well make it inline...
       
   367  */
       
   368 static inline int asc_2_bin(u8 *asc_data, u8 *bin_data) {
       
   369   if ((isxdigit(asc_data[0]) == 0) ||
       
   370       (isxdigit(asc_data[1]) == 0))
       
   371     return -1;
       
   372 
       
   373   asc_data[0] = local_toupper(asc_data[0]);
       
   374   asc_data[1] = local_toupper(asc_data[1]);
       
   375 
       
   376   /* hi */ *(bin_data) =  ((asc_data[0] <= '9')?
       
   377                            (asc_data[0] - '0'):(asc_data[0] - 'A' + 10)) * 0x10;
       
   378   /* lo */ *(bin_data) += (asc_data[1] <= '9')?
       
   379                            (asc_data[1] - '0'):(asc_data[1] - 'A' + 10);
       
   380 
       
   381   return 0;
       
   382 }
       
   383 
       
   384 
       
   385 
       
   386 
       
   387 /************************************/
       
   388 /**                                **/
       
   389 /** A data structure - send buffer **/
       
   390 /**                                **/
       
   391 /************************************/
       
   392 
       
   393 /* data structure used to store the data to be sent in ascii format. */
       
   394 /* The binary data is converted into ascii format before transmission. The
       
   395  * frame is not converted as a single whole, but is rather done in chunks.
       
   396  * The size of the chunks depends on the data size of the send_buffer.
       
   397  *
       
   398  * A lrc variable keeps a tab on the current value of the lrc as the data
       
   399  * is being converted.
       
   400  *
       
   401  * Three special functions add the header, lrc and tail to the ascii frame.
       
   402  */
       
   403 
       
   404 /* NOTE: The algorithms in the insert functions require a minimum buffer
       
   405  *       size to work correctly...
       
   406  */
       
   407 #define SEND_BUF_MIN_LENGTH   ASC_FRAME_MIN_ELE_LENGTH
       
   408 
       
   409 typedef struct {
       
   410         lb_buf_t data_buf;
       
   411 
       
   412         u8 lrc; /* the current value of the lrc, in binary format */
       
   413         } send_buf_t;
       
   414 
       
   415 /* A small auxiliary function... */
       
   416 static inline u8 *send_buf_init(send_buf_t *buf, int size, int max_data_start) {
       
   417   /* The algorithms in other functions require a minimum size
       
   418    * to work correctly...
       
   419    */
       
   420   if (size < SEND_BUF_MIN_LENGTH)
       
   421     return NULL;
       
   422 
       
   423   lrc_init(&buf->lrc);
       
   424   return lb_init(&buf->data_buf, size, max_data_start);
       
   425 }
       
   426 
       
   427 /* A small auxiliary function... */
       
   428 static inline void send_buf_done(send_buf_t *buf) {
       
   429   lb_done(&buf->data_buf);
       
   430 }
       
   431 
       
   432 /* A small auxiliary function... */
       
   433 static inline void send_buf_reset(send_buf_t *buf) {
       
   434   lrc_init(&buf->lrc);
       
   435   lb_data_purge_all(&buf->data_buf);
       
   436 }
       
   437 
       
   438 /* A small auxiliary function... */
       
   439 static inline int send_buf_data_count(send_buf_t *buf) {
       
   440   return lb_data_count(&buf->data_buf);
       
   441 }
       
   442 
       
   443 /* A small auxiliary function... */
       
   444 static inline int send_buf_free_count(send_buf_t *buf) {
       
   445   return lb_free_count(&buf->data_buf);
       
   446 }
       
   447 /* A small auxiliary function... */
       
   448 static inline u8 *send_buf_data(send_buf_t *buf) {
       
   449   return lb_data(&buf->data_buf);
       
   450 }
       
   451 
       
   452 /* A small auxiliary function... */
       
   453 static inline u8 *send_buf_free(send_buf_t *buf) {
       
   454   return lb_free(&buf->data_buf);
       
   455 }
       
   456 
       
   457 /* A small auxiliary function... */
       
   458 static inline int send_buf_data_add(send_buf_t *buf, u8 *data, int data_count) {
       
   459   int res = bin_2_asc(data,  data_count, send_buf_free(buf), send_buf_free_count(buf));
       
   460   if (res <=0) return res;
       
   461   lb_data_add(&buf->data_buf, L2_TO_ASC_CODING * res);
       
   462   lrc_add_many(&buf->lrc, data, res);
       
   463   return res;
       
   464 }
       
   465 
       
   466 /* A small auxiliary function... */
       
   467 static inline void send_buf_data_purge(send_buf_t *buf, int count) {
       
   468   lb_data_purge(&buf->data_buf, count);
       
   469 }
       
   470 
       
   471 /* A small auxiliary function... */
       
   472 static inline void send_buf_data_purge_all(send_buf_t *buf) {
       
   473   lb_data_purge_all(&buf->data_buf);
       
   474 }
       
   475 
       
   476 /* A small auxiliary function... */
       
   477 static inline int send_buf_lrc_append(send_buf_t *buf) {
       
   478 #if ASC_FRAME_LRC_LENGTH != 2
       
   479 #error Code assumes LRC length of 2 bytes, but ASC_FRAME_LRC_LENGTH != 2
       
   480 #endif
       
   481   if (lb_free_count(&buf->data_buf) < ASC_FRAME_LRC_LENGTH)
       
   482     return -1;
       
   483   lrc_end(&buf->lrc);
       
   484   bin_2_asc(&buf->lrc, sizeof(buf->lrc),
       
   485             lb_free(&buf->data_buf), ASC_FRAME_LRC_LENGTH);
       
   486   lb_data_add(&buf->data_buf, ASC_FRAME_LRC_LENGTH);
       
   487   return 0;
       
   488 }
       
   489 
       
   490 static inline int send_buf_header_append(send_buf_t *buf) {
       
   491 #if ASC_FRAME_HEADER_LENGTH != 1
       
   492 #error Code assumes HEADER length of 1 bytes, but ASC_FRAME_HEADER_LENGTH != 1
       
   493 #endif
       
   494   if (lb_free_count(&buf->data_buf) < ASC_FRAME_HEADER_LENGTH)
       
   495     return -1;
       
   496 
       
   497   /* add the ':' frame header */
       
   498   *lb_free(&buf->data_buf) = ASC_FRAME_HEADER;
       
   499   lb_data_add(&buf->data_buf, ASC_FRAME_HEADER_LENGTH);
       
   500 
       
   501   return 0;
       
   502 }
       
   503 
       
   504 static inline int send_buf_tail_append(send_buf_t *buf) {
       
   505 #if ASC_FRAME_TAIL_LENGTH != 2
       
   506 #error Code assumes TAIL length of 2 bytes, but ASC_FRAME_TAIL_LENGTH != 2
       
   507 #endif
       
   508   if (lb_free_count(&buf->data_buf) < ASC_FRAME_TAIL_LENGTH)
       
   509     return -1;
       
   510 
       
   511   /* add the CR+LF frame delimiter */
       
   512   lb_free(&buf->data_buf)[0] = ASC_FRAME_TAIL_0;
       
   513   lb_free(&buf->data_buf)[1] = ASC_FRAME_TAIL_1;
       
   514   lb_data_add(&buf->data_buf, ASC_FRAME_TAIL_LENGTH);
       
   515 
       
   516   return 0;
       
   517 }
       
   518 
       
   519 
       
   520 
       
   521 
       
   522 /************************************/
       
   523 /**                                **/
       
   524 /** A data structure - recv buffer **/
       
   525 /**                                **/
       
   526 /************************************/
       
   527 
       
   528 /* data structure used to store the data received from the bus. */
       
   529 
       
   530 /* The ascii data received from the bus is added to the buffer, and is
       
   531  * dynamically converted to binary format. Once a valid frame has been
       
   532  * converted, conversion stops until this valid frame is deleted/purged.
       
   533  */
       
   534 
       
   535 /* NOTE: The algorithms in the insert functions require a minimum buffer
       
   536  *       size to work correctly...
       
   537  */
       
   538 #define RECV_BUF_MIN_LENGTH   ASC_FRAME_MIN_ELE_LENGTH
       
   539 
       
   540 #define RECV_BUF_BIN_BUF_SIZE (MAX_L2_FRAME_LENGTH +                     \
       
   541                                ASC_FRAME_LRC_LENGTH / L2_TO_ASC_CODING)
       
   542 
       
   543 typedef struct {
       
   544         lb_buf_t asc_data_buf;
       
   545         u8       bin_data_buf[RECV_BUF_BIN_BUF_SIZE];
       
   546         int      bin_data_free_ofs;
       
   547 
       
   548         frame_part_t frame_part;
       
   549         u8 lrc; /* the current value of the lrc, in binary format */
       
   550         u8 lrc_1; /* the previous value of the lrc...             */
       
   551           /* NOTE: We do a running conversion between ascii and binary format,
       
   552            *       i.e. we start converting from ascii to binary before we
       
   553            *       have received the complete ascii frame. This means that
       
   554            *       we also do a running computation of our local version of
       
   555            *       the frame lrc.
       
   556            *       The lrc, transmitted at the end of the ascii frame,
       
   557            *       but before the frame tail, also gets converted to binary
       
   558            *       before we get a chance to realize that it is the lrc value,
       
   559            *       and should therefore not be taken into account when computing
       
   560            *       our local version of the lrc.
       
   561            *       So we keep the previous value of the running lrc, and use
       
   562            *       that to confirm whether we have a valid frame.
       
   563            */
       
   564         } recv_buf_t;
       
   565 
       
   566 /* A small auxiliary function... */
       
   567 static inline u8 *recv_buf_init(recv_buf_t *buf, int size, int max_data_start) {
       
   568   /* The algorithms in other functions require a minimum size
       
   569    * to work correctly...
       
   570    */
       
   571   if (size < RECV_BUF_MIN_LENGTH)
       
   572     return NULL;
       
   573 
       
   574   lrc_init(&buf->lrc);
       
   575   buf->bin_data_free_ofs = 0;
       
   576   buf->frame_part = fp_header;
       
   577   return lb_init(&buf->asc_data_buf, size, max_data_start);
       
   578 }
       
   579 
       
   580 /* A small auxiliary function... */
       
   581 static inline void recv_buf_done(recv_buf_t *buf) {
       
   582   lb_done(&buf->asc_data_buf);
       
   583 }
       
   584 
       
   585 /* A small auxiliary function... */
       
   586 static inline void recv_buf_reset(recv_buf_t *buf) {
       
   587   lrc_init(&buf->lrc);
       
   588   buf->bin_data_free_ofs = 0;
       
   589   buf->frame_part = fp_header;
       
   590   lb_data_purge_all(&buf->asc_data_buf);
       
   591 }
       
   592 
       
   593 /* A small auxiliary function... */
       
   594 static inline u8 *recv_buf_data(recv_buf_t *buf) {
       
   595   return lb_data(&buf->asc_data_buf);
       
   596 }
       
   597 
       
   598 /* A small auxiliary function... */
       
   599 static inline u8 *recv_buf_free(recv_buf_t *buf) {
       
   600   return lb_free(&buf->asc_data_buf);
       
   601 }
       
   602 
       
   603 /* The function that really does all the conversion work... */
       
   604 /* It finds frame limits, converts the data into binary format,
       
   605  * and checks for correct lrc in the received frame.
       
   606  */
       
   607 /* NOTE: called indirectly from various locations! Do NOT inline! */
       
   608 static void recv_buf_data_parse(recv_buf_t *buf) {
       
   609   int count;
       
   610   u8  *data;
       
   611 
       
   612   data  = lb_data(&buf->asc_data_buf);
       
   613   count = lb_data_count(&buf->asc_data_buf);
       
   614 
       
   615   /* NOTE: We need at least ASC_FRAME_MIN_ELE_LENGTH bytes to
       
   616    *       to be able to find that element of minimum length
       
   617    */
       
   618   while ((count >= ASC_FRAME_MIN_ELE_LENGTH) && (buf->frame_part != fp_done)) {
       
   619     /* Check for frame header... */
       
   620  /* The following few lines of code assume that ASC_FRAME_HEADER_LENGTH is 1! */
       
   621 #if ASC_FRAME_HEADER_LENGTH != 1
       
   622 #error The code is written in such a way that can only handle ASC_FRAME_HEADER_LENGTH == 1
       
   623 #endif
       
   624     if (data[0] == ASC_FRAME_HEADER) {
       
   625       /* found the beginning of a frame...
       
   626        * Even if we were previously converting a frame without errors,
       
   627        * if we receive a new frame header we discard the previous
       
   628        * frame that went unfinished!
       
   629        */
       
   630       data += ASC_FRAME_HEADER_LENGTH;
       
   631       count -= ASC_FRAME_HEADER_LENGTH;
       
   632       buf->frame_part = fp_body;
       
   633       lrc_init(&buf->lrc);
       
   634       buf->bin_data_free_ofs = 0;
       
   635       continue;
       
   636     }
       
   637 
       
   638     /* Check for frame tail... */
       
   639     /*
       
   640      * Note that the while() condition guarantees that we have at least
       
   641      * two ascii bytes to handle.
       
   642      */
       
   643  /* The following few lines of code assume that ASC_FRAME_TAIL_LENGTH is 2! */
       
   644 #if ASC_FRAME_TAIL_LENGTH != 2
       
   645 #error The code is written in such a way that can only handle ASC_FRAME_TAIL_LENGTH == 2
       
   646 #endif
       
   647     if ((data[0] == ASC_FRAME_TAIL_0) &&
       
   648         (data[1] == ASC_FRAME_TAIL_1)) {
       
   649       /* end of binary data...  */
       
   650       data  += ASC_FRAME_TAIL_LENGTH;
       
   651       count -= ASC_FRAME_TAIL_LENGTH;
       
   652 
       
   653       /* let's check the lrc... */
       
   654       if (buf->bin_data_free_ofs <= 0)
       
   655         /* we have reached the end of a frame that did not include
       
   656          * any binary data, not even the lrc value itself!
       
   657          */
       
   658         goto frame_error;
       
   659 
       
   660       /* Remember that we do not use the most recent lrc value, as this
       
   661        * incorrectly includes the ascii bytes in the frame that code the
       
   662        * frame's lrc. (pls read the note in the recv_but_t typedef)
       
   663        */
       
   664  /* The following few lines of code assume that
       
   665   * (ASC_FRAME_LRC_LENGTH / L2_TO_ASC_CODING) is 1!
       
   666   */
       
   667 #if L2_TO_ASC_CODING != ASC_FRAME_LRC_LENGTH
       
   668 #error The code is written in such a way that can only handle L2_TO_ASC_CODING == ASC_FRAME_LRC_LENGTH
       
   669 #endif
       
   670       lrc_end(&(buf->lrc_1));
       
   671       if (buf->lrc_1 == buf->bin_data_buf[buf->bin_data_free_ofs-1]) {
       
   672         /* we have received a correct frame... */
       
   673         buf->frame_part = fp_done;
       
   674         continue;
       
   675       } else {
       
   676         /* we have found a frame with an lrc error */
       
   677         goto frame_error;
       
   678       }
       
   679     }
       
   680 
       
   681     if (buf->frame_part == fp_header) {
       
   682       /* we are searching for beginning of a frame...
       
   683        * but we did not find it in the previous condition!
       
   684        * We continue looking in the next ascii byte
       
   685        */
       
   686       data++;
       
   687       count--;
       
   688       continue;
       
   689       }
       
   690 
       
   691     if (buf->frame_part == fp_body) {
       
   692       /* we have previously found the beginning of a frame,
       
   693        * and are now converting the body into binary format...
       
   694        *
       
   695        * Note that the while() condition guarantees that we have at least
       
   696        * two ascii bytes to convert into binary format.
       
   697        */
       
   698 
       
   699       /* this is normal data... let's convert... */
       
   700       if (asc_2_bin(data, buf->bin_data_buf + buf->bin_data_free_ofs) < 0)
       
   701         /* error converting from ascii to binary.
       
   702          * This must be due to an invalid ascii character in the ascii data.
       
   703          * We discard the current frame...
       
   704          *
       
   705          * Note that we *do not* increment the data pointer,
       
   706          * nor do we decrement the count variable. One of the ascii bytes could
       
   707          * be the begining of a new valid frame, and we don't want to skip it!
       
   708          */
       
   709         goto frame_error;
       
   710 
       
   711       buf->lrc_1 = buf->lrc;
       
   712       lrc_add_single(&(buf->lrc), *(buf->bin_data_buf + buf->bin_data_free_ofs));
       
   713 
       
   714       data += L2_TO_ASC_CODING;
       
   715       count -= L2_TO_ASC_CODING;
       
   716       if (++(buf->bin_data_free_ofs) >= RECV_BUF_BIN_BUF_SIZE)
       
   717         /* Whoops, this shouldn't be hapening!
       
   718          * The frame we are receiving is larger than the alocated buffer!
       
   719          * Our only alternative is to discard the frame
       
   720          * we are currently receiving...
       
   721          */
       
   722         goto frame_error;
       
   723 
       
   724       continue;
       
   725     }
       
   726 
       
   727     /* if none of the above, then it must be some transmission error */
       
   728     /* Actually, the code will never fall through since if we are in this loop,
       
   729      * (frame_part == header) || (frame_part == body) is always true!
       
   730      */
       
   731     data++;
       
   732     count--;
       
   733 frame_error:
       
   734     lrc_init(&buf->lrc);
       
   735     buf->bin_data_free_ofs = 0;
       
   736     buf->frame_part = fp_header;
       
   737   } /* while () */
       
   738 
       
   739   lb_data_purge(&buf->asc_data_buf, lb_data_count(&buf->asc_data_buf) - count);
       
   740 }
       
   741 
       
   742 /* A small auxiliary function... */
       
   743 static inline void recv_buf_search_frame(recv_buf_t *buf) {
       
   744   if (buf->frame_part != fp_done)
       
   745     recv_buf_data_parse(buf);
       
   746 }
       
   747 
       
   748 /* add ascii format data to buffer */
       
   749 static inline void recv_buf_data_add(recv_buf_t *buf, int count) {
       
   750   lb_data_add(&buf->asc_data_buf, count);
       
   751 }
       
   752 
       
   753 /* A small auxiliary function... */
       
   754 static inline int recv_buf_data_count(recv_buf_t *buf) {
       
   755   return lb_data_count(&buf->asc_data_buf);
       
   756 }
       
   757 
       
   758 /* A small auxiliary function... */
       
   759 static inline int recv_buf_free_count(recv_buf_t *buf) {
       
   760   return lb_free_count(&buf->asc_data_buf);
       
   761 }
       
   762 
       
   763 /* Return pointer to frame, if a valid frame is available */
       
   764 static inline u8 *recv_buf_frame(recv_buf_t *buf) {
       
   765   recv_buf_search_frame(buf);
       
   766   if (buf->frame_part == fp_done)
       
   767     /* we have found a frame...! */
       
   768     return buf->bin_data_buf;
       
   769 
       
   770   /* no frame... */
       
   771   return NULL;
       
   772 }
       
   773 
       
   774 /* Return number of bytes in frame, if a valid frame is available */
       
   775 static inline int recv_buf_frame_count(recv_buf_t *buf) {
       
   776   recv_buf_search_frame(buf);
       
   777   if (buf->frame_part == fp_done)
       
   778     /* we have found a frame...! */
       
   779     return buf->bin_data_free_ofs - ASC_FRAME_LRC_LENGTH/L2_TO_ASC_CODING;
       
   780 
       
   781   /* no frame... */
       
   782   return -1;
       
   783 }
       
   784 
       
   785 /* Delete valid binary format frame! */
       
   786 static inline void recv_buf_frame_purge(recv_buf_t *buf) {
       
   787   /* NOTE: we only delete valid frames!!
       
   788    *       Partially converted frames are not deleted, the
       
   789    *       remaining bytes may be received later!
       
   790    */
       
   791   if (buf->frame_part == fp_done) {
       
   792     buf->frame_part = fp_header;
       
   793     buf->bin_data_free_ofs = 0;
       
   794   }
       
   795 }
       
   796 
       
   797 
       
   798 
       
   799 /************************************/
       
   800 /**                                **/
       
   801 /**  A data structure - nd entry   **/
       
   802 /**                                **/
       
   803 /************************************/
       
   804 
       
   805 /* NOTE: nd = node descriptor */
       
   806 
       
   807 typedef struct {
       
   808          /* The file descriptor associated with this node */
       
   809          /* NOTE: if the node is not yet in use, i.e. if the node is free,
       
   810           *       then fd will be set to -1
       
   811           */
       
   812         int    fd;
       
   813         struct timeval time_15_char_;
       
   814 
       
   815          /* Modbus ascii frames are delimited by a ':' (colon) at the begining of
       
   816           * a frame, and CR-LF sequence at the end the frame.
       
   817           *
       
   818           * Unless we want to take 'ages' reading the data off the serial line
       
   819           * one byte at a time, we risk reading beyond the boundary of the
       
   820           * frame currently being interpreted. The extra data belongs to the
       
   821           * subsequent frame, and must therefore be buffered to be handled
       
   822           * when the next frame is being interpreted.
       
   823           *
       
   824           * The receive buffer is therefore a static variable.
       
   825           */
       
   826         recv_buf_t recv_buf_;
       
   827 
       
   828          /* The send ascii buffer could be a local function variable
       
   829           * instead of a static variable, but we might just as well
       
   830           * allocate the memory at startup and not risk running out
       
   831           * of memory while the module is running.
       
   832           */
       
   833         send_buf_t send_buf_;
       
   834 
       
   835           /* The old settings of the serial port, to be reset when the library is closed... */
       
   836         struct termios old_tty_settings_;
       
   837 
       
   838           /* ignore echo flag.
       
   839            * If set to 1, then it means that we will be reading every byte we
       
   840            * ourselves write out to the bus, so we must ignore those bytes read
       
   841            * before we really read the data sent by remote nodes.
       
   842            *
       
   843            * This comes in useful when using a RS232-RS485 converter that does
       
   844            * not correctly control the RTS-CTS lines...
       
   845            */
       
   846         int ignore_echo;
       
   847  } nd_entry_t;
       
   848 
       
   849 
       
   850 static inline void nd_entry_init(nd_entry_t *nde) {
       
   851   nde->fd = -1; /* The node is free... */
       
   852 }
       
   853 
       
   854 static int nd_entry_connect(nd_entry_t *nde,
       
   855                             node_addr_t *node_addr,
       
   856                             optimization_t opt) {
       
   857 
       
   858   int parity_bits, start_bits, char_bits;
       
   859   struct termios settings;
       
   860   int buf_size;
       
   861 
       
   862   /*
       
   863   if (nde == NULL)
       
   864     goto error_exit_0;
       
   865   */
       
   866   if (nde->fd >= 0)
       
   867     goto error_exit_0;
       
   868 
       
   869   /* initialise the termios data structure */
       
   870   if (termios_init(&settings,
       
   871                    node_addr->addr.ascii.baud,
       
   872                    node_addr->addr.ascii.parity,
       
   873                    node_addr->addr.ascii.data_bits,
       
   874                    node_addr->addr.ascii.stop_bits)
       
   875       < 0) {
       
   876 #ifdef DEBUG
       
   877     fprintf(stderr,   "Invalid serial line settings"
       
   878                       "(baud=%d, parity=%d, data_bits=%d, stop_bits=%d)",
       
   879                       node_addr->addr.ascii.baud,
       
   880                       node_addr->addr.ascii.parity,
       
   881                       node_addr->addr.ascii.data_bits,
       
   882                       node_addr->addr.ascii.stop_bits);
       
   883 #endif
       
   884     goto error_exit_1;
       
   885   }
       
   886 
       
   887     /* set the ignore_echo flag */
       
   888   nde->ignore_echo = node_addr->addr.ascii.ignore_echo;
       
   889 
       
   890     /* initialise send buffer */
       
   891   buf_size = (opt == optimize_size)?SEND_BUFFER_SIZE_SMALL:
       
   892                                     SEND_BUFFER_SIZE_LARGE;
       
   893   if (send_buf_init(&nde->send_buf_, buf_size, buf_size - SEND_BUF_MIN_LENGTH)
       
   894       == NULL) {
       
   895 #ifdef DEBUG
       
   896     fprintf(stderr, "Out of memory: error initializing send buffer");
       
   897 #endif
       
   898     goto error_exit_1;
       
   899   }
       
   900 
       
   901     /* initialise recv buffer */
       
   902   buf_size = (opt == optimize_size)?RECV_BUFFER_SIZE_SMALL:
       
   903                                     RECV_BUFFER_SIZE_LARGE;
       
   904   if (recv_buf_init(&nde->recv_buf_, buf_size, buf_size - RECV_BUF_MIN_LENGTH)
       
   905       == NULL) {
       
   906 #ifdef DEBUG
       
   907     fprintf(stderr, "Out of memory: error initializing receive buffer");
       
   908 #endif
       
   909     goto error_exit_2;
       
   910   }
       
   911 
       
   912     /* open the serial port */
       
   913   if((nde->fd = open(node_addr->addr.ascii.device, O_RDWR | O_NOCTTY | O_NDELAY))
       
   914      < 0) {
       
   915 #ifdef DEBUG
       
   916     fprintf(stderr, "Error opening device %s (errno=%d)",
       
   917                      node_addr->addr.ascii.device, errno);
       
   918 #endif
       
   919     goto error_exit_3;
       
   920   }
       
   921 
       
   922   if(tcgetattr(nde->fd, &nde->old_tty_settings_) < 0) {
       
   923 #ifdef DEBUG
       
   924     fprintf(stderr, "Error reading device's %s original settings.",
       
   925                       node_addr->addr.ascii.device);
       
   926 #endif
       
   927     goto error_exit_4;
       
   928   }
       
   929 
       
   930   if(tcsetattr(nde->fd, TCSANOW, &settings) < 0) {
       
   931 #ifdef DEBUG
       
   932     fprintf(stderr, "Error configuring device %s"
       
   933                     "(baud=%d, parity=%d, data_bits=%d, stop_bits=%d)",
       
   934                     node_addr->addr.ascii.device,
       
   935                     node_addr->addr.ascii.baud,
       
   936                     node_addr->addr.ascii.parity,
       
   937                     node_addr->addr.ascii.data_bits,
       
   938                     node_addr->addr.ascii.stop_bits);
       
   939 #endif
       
   940     goto error_exit_4;
       
   941   }
       
   942 
       
   943   parity_bits   = (node_addr->addr.ascii.parity == 0)?0:1;
       
   944   start_bits    = 1;
       
   945   char_bits     = start_bits  + node_addr->addr.ascii.data_bits +
       
   946                   parity_bits + node_addr->addr.ascii.stop_bits;
       
   947 /*  time_35_char_ = d_to_timeval(3.5*char_bits/baud); */
       
   948   nde->time_15_char_ = d_to_timeval(1.5*char_bits/node_addr->addr.ascii.baud);
       
   949 
       
   950 #ifdef DEBUG
       
   951   printf("nd_entry_connect(): %s open\n", node_addr->addr.ascii.device );
       
   952   printf("nd_entry_connect(): returning fd=%d\n", nde->fd);
       
   953 #endif
       
   954   return nde->fd;
       
   955 
       
   956   error_exit_4:
       
   957     close(nde->fd);
       
   958   error_exit_3:
       
   959     recv_buf_done(&nde->recv_buf_);
       
   960   error_exit_2:
       
   961     send_buf_done(&nde->send_buf_);
       
   962   error_exit_1:
       
   963     nde->fd = -1; /* set the node as free... */
       
   964   error_exit_0:
       
   965     return -1;
       
   966 }
       
   967 
       
   968 
       
   969 
       
   970 static int nd_entry_free(nd_entry_t *nde) {
       
   971   if (nde->fd < 0)
       
   972     /* already free */
       
   973     return -1;
       
   974 
       
   975   /* reset the tty device old settings... */
       
   976   if(tcsetattr(nde->fd, TCSANOW, &nde->old_tty_settings_) < 0)
       
   977     fprintf(stderr, "Error reconfiguring serial port to it's original settings.");
       
   978 
       
   979   recv_buf_done(&nde->recv_buf_);
       
   980   send_buf_done(&nde->send_buf_);
       
   981   close(nde->fd);
       
   982   nde->fd = -1;
       
   983 
       
   984   return 0;
       
   985 }
       
   986 
       
   987 
       
   988 static inline int nd_entry_is_free(nd_entry_t *nde) {
       
   989   return (nde->fd < 0);
       
   990 }
       
   991 
       
   992 
       
   993 
       
   994 
       
   995 /************************************/
       
   996 /**                                **/
       
   997 /**  A data structure - nd table   **/
       
   998 /**                                **/
       
   999 /************************************/
       
  1000 
       
  1001 typedef struct {
       
  1002       /* the array of node descriptors, and current size... */
       
  1003     nd_entry_t *node;
       
  1004     int        node_count;      /* total number of nodes in the node[] array */
       
  1005 } nd_table_t;
       
  1006 
       
  1007 
       
  1008 
       
  1009 #if 1
       
  1010 /* nd_table_init()
       
  1011  *   Version 1 of the nd_table_init() function. 
       
  1012  *   If called more than once, 2nd and any subsequent calls will
       
  1013  *   be interpreted as a request to confirm that it was already correctly 
       
  1014  *   initialized with the requested number of nodes.
       
  1015  */
       
  1016 static int nd_table_init(nd_table_t *ndt, int nd_count) {
       
  1017   int count;
       
  1018 
       
  1019   if (ndt->node != NULL) {
       
  1020     /* this function has already been called, and the node table is already initialised */
       
  1021     return (ndt->node_count == nd_count)?0:-1;
       
  1022   }
       
  1023 
       
  1024   /* initialise the node descriptor metadata array... */
       
  1025   ndt->node = malloc(sizeof(nd_entry_t) * nd_count);
       
  1026   if (ndt->node == NULL) {
       
  1027 #ifdef DEBUG
       
  1028     fprintf(stderr, "Out of memory: error initializing node address buffer");
       
  1029 #endif
       
  1030     return -1;
       
  1031   }
       
  1032   ndt->node_count = nd_count;
       
  1033 
       
  1034     /* initialise the state of each node in the array... */
       
  1035   for (count = 0; count < ndt->node_count; count++) {
       
  1036     nd_entry_init(&ndt->node[count]);
       
  1037   } /* for() */
       
  1038 
       
  1039   return nd_count; /* number of succesfully created nodes! */
       
  1040 }
       
  1041 #else
       
  1042 /* nd_table_init()
       
  1043  *   Version 2 of the nd_table_init() function. 
       
  1044  *   If called more than once, 2nd and any subsequent calls will
       
  1045  *   be interpreted as a request to reserve an extra new_nd_count
       
  1046  *   number of nodes. This will be done using realloc().
       
  1047  */
       
  1048 static int nd_table_init(nd_table_t *ndt, int new_nd_count) {
       
  1049   int count;
       
  1050 
       
  1051   /* initialise the node descriptor metadata array... */
       
  1052   ndt->node = realloc(ndt->node, sizeof(nd_entry_t) * (ndt->node_count + new_nd_count));
       
  1053   if (ndt->node == NULL) {
       
  1054 #ifdef ERRMSG
       
  1055     fprintf(stderr, ERRMSG_HEAD "Out of memory: error initializing node address buffer\n");
       
  1056 #endif
       
  1057     return -1;
       
  1058   }
       
  1059 
       
  1060   /* initialise the state of each newly added node in the array... */
       
  1061   for (count = ndt->node_count; count < ndt->node_count + new_nd_count; count++) {
       
  1062     nd_entry_init(&ndt->node[count]);
       
  1063   } /* for() */
       
  1064   ndt->node_count += new_nd_count;
       
  1065 
       
  1066   return new_nd_count; /* number of succesfully created nodes! */
       
  1067 }
       
  1068 #endif
       
  1069 
       
  1070 
       
  1071 static inline nd_entry_t *nd_table_get_nd(nd_table_t *ndt, int nd) {
       
  1072   if ((nd < 0) || (nd >= ndt->node_count))
       
  1073     return NULL;
       
  1074 
       
  1075   return &ndt->node[nd];
       
  1076 }
       
  1077 
       
  1078 
       
  1079 static inline void nd_table_done(nd_table_t *ndt) {
       
  1080   int i;
       
  1081 
       
  1082   if (ndt->node == NULL) 
       
  1083     return;
       
  1084 
       
  1085     /* close all the connections... */
       
  1086   for (i = 0; i < ndt->node_count; i++)
       
  1087     nd_entry_free(&ndt->node[i]);
       
  1088 
       
  1089   /* Free memory... */
       
  1090   free(ndt->node);
       
  1091   *ndt = (nd_table_t){.node=NULL, .node_count=0};
       
  1092 }
       
  1093 
       
  1094 
       
  1095 
       
  1096 static inline int nd_table_get_free_nd(nd_table_t *ndt) {
       
  1097   int count;
       
  1098 
       
  1099   for (count = 0; count < ndt->node_count; count++) {
       
  1100     if (nd_entry_is_free(&ndt->node[count]))
       
  1101       return count;
       
  1102   }
       
  1103 
       
  1104    /* none found... */
       
  1105   return -1;
       
  1106 }
       
  1107 
       
  1108 
       
  1109 static inline int nd_table_free_nd(nd_table_t *ndt, int nd) {
       
  1110   if ((nd < 0) || (nd >= ndt->node_count))
       
  1111     return -1;
       
  1112 
       
  1113   return nd_entry_free(&ndt->node[nd]);
       
  1114 }
       
  1115 
       
  1116 
       
  1117 
       
  1118 /**************************************************************/
       
  1119 /**************************************************************/
       
  1120 /****                                                      ****/
       
  1121 /****                                                      ****/
       
  1122 /****                Global Library State                  ****/
       
  1123 /****                                                      ****/
       
  1124 /****                                                      ****/
       
  1125 /**************************************************************/
       
  1126 /**************************************************************/
       
  1127 
       
  1128 
       
  1129  /* The node descriptor table... */
       
  1130  /* NOTE: This variable must be correctly initialised here!! */
       
  1131 static nd_table_t nd_table_ = {.node=NULL, .node_count=0};
       
  1132 
       
  1133  /* The optimization choice... */
       
  1134 static optimization_t optimization_;
       
  1135 
       
  1136 
       
  1137 
       
  1138 /**************************************************************/
       
  1139 /**************************************************************/
       
  1140 /****                                                      ****/
       
  1141 /****                                                      ****/
       
  1142 /****             Sending of Modbus ASCII Frames           ****/
       
  1143 /****                                                      ****/
       
  1144 /****                                                      ****/
       
  1145 /**************************************************************/
       
  1146 /**************************************************************/
       
  1147 
       
  1148 /* 
       
  1149  *     NOTE: for now the transmit_timeout is silently ignored in ASCII version!
       
  1150  */
       
  1151 int modbus_ascii_write(int    nd,
       
  1152                        u8    *data,
       
  1153                        size_t data_length,
       
  1154                        u16    transaction_id,
       
  1155                        const struct timespec *transmit_timeout
       
  1156                       )
       
  1157  {
       
  1158   fd_set rfds;
       
  1159   struct timeval timeout;
       
  1160   int res, bin_data_conv, send_retries;
       
  1161   frame_part_t frame_part;
       
  1162   nd_entry_t *nd_entry;
       
  1163 
       
  1164   /* check if nd is correct... */
       
  1165   if ((nd_entry = nd_table_get_nd(&nd_table_, nd)) == NULL)
       
  1166     return -1;
       
  1167 
       
  1168   /* check if nd is initialzed... */
       
  1169   if (nd_entry->fd < 0)
       
  1170     return -1;
       
  1171 
       
  1172   /* THE MAIN LOOP!!! */
       
  1173   send_retries = ASC_FRAME_SEND_RETRY + 1; /* must try at least once... */
       
  1174   while (send_retries > 0) {
       
  1175 
       
  1176     /*******************************
       
  1177      * synchronise with the bus... *
       
  1178      *******************************/
       
  1179     /* Remember that a RS485 bus is half-duplex, so we have to wait until
       
  1180      * nobody is transmitting over the bus for our turn to transmit.
       
  1181      * This will never happen on a modbus network if the master and
       
  1182      * slave state machines never get out of synch (granted, it probably
       
  1183      * only has two states, but a state machine nonetheless), but we want
       
  1184      * to make sure we can re-synchronise if they ever do get out of synch.
       
  1185      *
       
  1186      * The following lines are an attempt at re-synchronising with the bus.
       
  1187      * Unfortunately, due to the completely asynchronous nature of the
       
  1188      * modbus-ascii protocol (there are no time boundaries for sending a frame!),
       
  1189      * it is impossible to guarantee that we will synchronise correctly.
       
  1190      *
       
  1191      * Use of RTS/CTS over a half-duplex coms chanel would eliminate this
       
  1192      * 'feature', but not all RS232/RS485 converters delay activating the
       
  1193      * CTS signal, even though there may be current activity on the bus.
       
  1194      *
       
  1195      * We first wait until the bus is silent for at least 1.5 character interval.
       
  1196      * Note that we only get feedback from the device driver once a whole byte
       
  1197      * has been received, so we must wait longer than 1 character interval to make
       
  1198      * sure there is no current activity on the bus). We then flush the input and
       
  1199      * output queues.
       
  1200      */
       
  1201       /* NOTES:
       
  1202        *   - we do not need to reset the rfds with FD_SET(ttyfd, &rfds)
       
  1203        *     before every call to select! We only wait on one file descriptor,
       
  1204        *     so if select returns succesfully, it must have that same file
       
  1205        *     decriptor set in the rdfs!
       
  1206        *     If select returns with a timeout, then we do not get to call
       
  1207        *     select again!
       
  1208        *   - We do not reset the timeout value. Normally this value is left
       
  1209        *     unchanged when select() returns, so we will be witing for longer
       
  1210        *     than the desired period.
       
  1211        *     On Linux the timeout is changed to reflect the time remaining.
       
  1212        *     In this case, things will work more nicely.
       
  1213        */
       
  1214     FD_ZERO(&rfds);
       
  1215     FD_SET(nd_entry->fd, &rfds);
       
  1216     timeout = nd_entry->time_15_char_;
       
  1217     while ((res = select(nd_entry->fd+1, &rfds, NULL, NULL, &timeout)) != 0) {
       
  1218       if (res > 0) {
       
  1219         /* we are receiving data over the serial port! */
       
  1220         /* Throw the data away!                        */
       
  1221         tcflush(nd_entry->fd, TCIFLUSH); /* flush the input stream */
       
  1222         /* reset the timeout value! */
       
  1223         timeout = nd_entry->time_15_char_;
       
  1224       } else {
       
  1225         /* some kind of error ocurred */
       
  1226         if (errno != EINTR)
       
  1227           /* we were not interrupted by a signal */
       
  1228           return -1;
       
  1229         /* We will be callind select() again.
       
  1230          * We need to reset the FD SET !
       
  1231          */
       
  1232         FD_ZERO(&rfds);
       
  1233         FD_SET(nd_entry->fd, &rfds);
       
  1234       }
       
  1235     } /* while (select()) */
       
  1236 
       
  1237     /* Flush both input and output streams... */
       
  1238     /* NOTE: Due to the nature of the modbus protocol,
       
  1239      *       when a frame is sent all previous
       
  1240      *       frames that may have arrived at the sending node become
       
  1241      *       irrelevant.
       
  1242      */
       
  1243     tcflush(nd_entry->fd, TCIOFLUSH);    /* flush the input & output streams */
       
  1244     recv_buf_reset(&nd_entry->recv_buf_);   /* reset the recv buffer            */
       
  1245 
       
  1246     /**********************
       
  1247      * write to output... *
       
  1248      **********************/
       
  1249     send_buf_reset(&nd_entry->send_buf_);
       
  1250 
       
  1251     frame_part = fp_header; /* start off by sending the header... */
       
  1252     bin_data_conv = 0; /* binary format data already converted to ascii format... */
       
  1253     while ((frame_part != fp_done) ||
       
  1254            (send_buf_data_count(&nd_entry->send_buf_) > 0)) {
       
  1255 
       
  1256        /* build the frame we will send over the wire... */
       
  1257        /* We use a state machine with four states... */
       
  1258       if (frame_part == fp_header) {
       
  1259         if (send_buf_header_append(&nd_entry->send_buf_) >= 0)
       
  1260           frame_part = fp_body;
       
  1261       }
       
  1262       if (frame_part == fp_body) {
       
  1263         res = send_buf_data_add(&nd_entry->send_buf_, data + bin_data_conv, data_length - bin_data_conv);
       
  1264         bin_data_conv += res;
       
  1265         if (bin_data_conv == data_length)
       
  1266           frame_part = fp_lrc;
       
  1267       }
       
  1268       if (frame_part == fp_lrc) {
       
  1269         if (send_buf_lrc_append(&nd_entry->send_buf_) >= 0)
       
  1270           frame_part = fp_tail;
       
  1271       }
       
  1272       if (frame_part == fp_tail) {
       
  1273         if (send_buf_tail_append(&nd_entry->send_buf_) >= 0)
       
  1274           frame_part = fp_done;
       
  1275       }
       
  1276 
       
  1277        /* send the frame... */
       
  1278       if ((res = write(nd_entry->fd,
       
  1279                        send_buf_data(&nd_entry->send_buf_),
       
  1280                        send_buf_data_count(&nd_entry->send_buf_))) < 0) {
       
  1281         if ((errno != EAGAIN ) && (errno != EINTR )) {
       
  1282           break;
       
  1283         } else {
       
  1284           /* there is no harm if we get interrupted while writing the frame.
       
  1285            * The ascii version of modbus does not place any timing
       
  1286            * constraints whatsoever...
       
  1287            *
       
  1288            * We simply continue sending the frame...
       
  1289            */
       
  1290           res = 0;
       
  1291         }
       
  1292       }
       
  1293 #ifdef DEBUG
       
  1294 /* Print each character that has just been sent on the bus */
       
  1295   { int i;
       
  1296     printf("bytes sent -> [");
       
  1297     for(i = 0; i < res; i++)
       
  1298       printf("%c", send_buf_data(&nd_entry->send_buf_)[i]);
       
  1299     printf("]\n");
       
  1300   }
       
  1301 #endif
       
  1302       send_buf_data_purge(&nd_entry->send_buf_, res);
       
  1303 
       
  1304       if ((frame_part == fp_done) &&
       
  1305           (send_buf_data_count(&nd_entry->send_buf_) == 0))
       
  1306         /* sent frame successfully! */
       
  1307         return data_length;
       
  1308 
       
  1309     } /* while(frame_not_sent) */
       
  1310     /* NOTE: Some error occured while trying to transmit. It will probably
       
  1311      *       not go away by itself, but there is no harm in trying again
       
  1312      *       if the upper layer so wishes...
       
  1313      */
       
  1314     send_retries--;
       
  1315   } /* while()  MAIN LOOP */
       
  1316 
       
  1317    /* maximum retries exceeded */
       
  1318   return -1;
       
  1319 }
       
  1320 
       
  1321 
       
  1322 
       
  1323 /**************************************************************/
       
  1324 /**************************************************************/
       
  1325 /****                                                      ****/
       
  1326 /****                                                      ****/
       
  1327 /****             Receiving Modbus ASCII Frames            ****/
       
  1328 /****                                                      ****/
       
  1329 /****                                                      ****/
       
  1330 /**************************************************************/
       
  1331 /**************************************************************/
       
  1332 
       
  1333 
       
  1334 /************************************/
       
  1335 /**                                **/
       
  1336 /**          Read a frame          **/
       
  1337 /**                                **/
       
  1338 /************************************/
       
  1339 
       
  1340 /* A function to read a valid frame off the modbus ascii bus.
       
  1341  *
       
  1342  * NOTES:
       
  1343  *        - The returned frame is guaranteed to be a valid frame.
       
  1344  *        - The returned length does *not* include the LRC.
       
  1345  */
       
  1346 /* NOTE: This function is only called from one place in the rest of the code,
       
  1347  * so we might just as well make it inline...
       
  1348  */
       
  1349 /* RETURNS: number of bytes in received frame
       
  1350  *          -1 on read file error
       
  1351  *          -2 on timeout
       
  1352  */
       
  1353 static inline int read_frame(nd_entry_t *nd_entry,
       
  1354                              u8 **recv_data_ptr,
       
  1355                              struct timespec *end_time)
       
  1356 {
       
  1357   /* temporary variables... */
       
  1358   fd_set rfds;
       
  1359   int res;
       
  1360 
       
  1361   /* start by deleting any previously converted frames... */
       
  1362   recv_buf_frame_purge(&nd_entry->recv_buf_);
       
  1363 
       
  1364   /*==============*
       
  1365    * read a frame *
       
  1366    *==============*/
       
  1367 #ifdef DEBUG
       
  1368   printf("bytes read -> <");
       
  1369 #endif
       
  1370   /* The main loop that reads one frame               */
       
  1371   /*  (multiple calls to read() )                     */
       
  1372   /* and jumps out as soon as it finds a valid frame. */
       
  1373   /* NOTE: Do not change this into a do {...} until() loop!
       
  1374    *       The while loop may find valid frames in the data read off the
       
  1375    *       bus in previous invocations of this same fucntion, and may
       
  1376    *       therefore not execute any loop iteration whatsoever,
       
  1377    *       and not call read()
       
  1378    */
       
  1379   while ((*recv_data_ptr = recv_buf_frame(&nd_entry->recv_buf_)) == NULL) {
       
  1380     /* We need more bytes... */
       
  1381 
       
  1382     /*-----------------------------*
       
  1383      * check for data availability *
       
  1384      *-----------------------------*/
       
  1385     /* if we can't find a valid frame in the existing data, or no data
       
  1386      * was left over, then we need to read more bytes!
       
  1387      */
       
  1388       FD_ZERO(&rfds);
       
  1389       FD_SET(nd_entry->fd, &rfds);
       
  1390       {int sel_res = my_select(nd_entry->fd + 1, &rfds, NULL, end_time);
       
  1391         if (sel_res < 0)
       
  1392           return -1;
       
  1393         if (sel_res == 0)
       
  1394           return -2;
       
  1395       }
       
  1396 
       
  1397     /*------------------*
       
  1398      * read frame bytes *
       
  1399      *------------------*/
       
  1400      /* Read in as many bytes as possible...  */
       
  1401     res = read(nd_entry->fd,
       
  1402                recv_buf_free(&nd_entry->recv_buf_),
       
  1403                recv_buf_free_count(&nd_entry->recv_buf_));
       
  1404     if (res < 0) {
       
  1405       if (errno != EINTR)
       
  1406         return -1;
       
  1407       else
       
  1408         res = 0;
       
  1409     }
       
  1410 #ifdef DEBUG
       
  1411       {/* display the hex code of each character received */
       
  1412         int i;
       
  1413         for (i=0; i < res; i++)
       
  1414           printf("%c", recv_buf_free(&nd_entry->recv_buf_)[i]);
       
  1415       }
       
  1416 #endif
       
  1417     recv_buf_data_add(&nd_entry->recv_buf_, res);
       
  1418   } /* while ()*/
       
  1419 #ifdef DEBUG
       
  1420     printf(">\n");
       
  1421 #endif
       
  1422 
       
  1423   /* We have a frame! */
       
  1424   return recv_buf_frame_count(&nd_entry->recv_buf_);
       
  1425 }
       
  1426 
       
  1427 
       
  1428 
       
  1429 
       
  1430 
       
  1431 /**************************************/
       
  1432 /**                                  **/
       
  1433 /**    Read a Modbus ASCII frame     **/
       
  1434 /**                                  **/
       
  1435 /**************************************/
       
  1436 
       
  1437 /* The public function that reads a valid modbus frame.
       
  1438  *
       
  1439  * The returned frame is guaranteed to be different to the
       
  1440  * the frame stored in send_data, and to start with the
       
  1441  * same slave address stored in send_data[0].
       
  1442  *
       
  1443  * If send_data is NULL, send_data_length = 0, or
       
  1444  * ignore_echo == 0, then the first valid frame read off
       
  1445  * the bus is returned.
       
  1446  *
       
  1447  * return value: The length (in bytes) of the valid frame,
       
  1448  *               -1 on error
       
  1449  *               -2 on timeout
       
  1450  */
       
  1451 
       
  1452 int modbus_ascii_read(int *nd,
       
  1453                       u8 **recv_data_ptr,
       
  1454                       u16 *transaction_id,
       
  1455                       const u8 *send_data,
       
  1456                       int send_length,
       
  1457                       const struct timespec *recv_timeout) {
       
  1458 
       
  1459   struct timespec end_time, *ts_ptr;
       
  1460   int res, recv_length;
       
  1461   int iter;  /* Warning: if you change the var type of iter from int,
       
  1462               *          then you must also change the INT_MAX constant
       
  1463               *          further on in this function...
       
  1464               */
       
  1465   u8 *local_recv_data_ptr;
       
  1466   nd_entry_t *nd_entry;
       
  1467 
       
  1468   /* Check input parameters... */
       
  1469   if (nd == NULL)
       
  1470     return -1;
       
  1471 
       
  1472   if (recv_data_ptr == NULL)
       
  1473     recv_data_ptr = &local_recv_data_ptr;
       
  1474 
       
  1475   if ((send_data == NULL) && (send_length != 0))
       
  1476     return -1;
       
  1477 
       
  1478   /* check if nd is correct... */
       
  1479   if ((nd_entry = nd_table_get_nd(&nd_table_, *nd)) == NULL)
       
  1480     return -1;
       
  1481 
       
  1482   /* check if nd is initialzed... */
       
  1483   if (nd_entry->fd < 0)
       
  1484     return -1;
       
  1485 
       
  1486   /* We will potentially read many frames, and we cannot reset the timeout
       
  1487    * for every frame we read. We therefore determine the absolute time_out,
       
  1488    * and use this as a parameter for each call to read_frame() instead of
       
  1489    * using a relative timeout.
       
  1490    *
       
  1491    * NOTE: see also the timeout related comment in the read_frame()= function!
       
  1492    */
       
  1493   ts_ptr = NULL;
       
  1494   if (recv_timeout != NULL) {
       
  1495      ts_ptr = &end_time;
       
  1496     *ts_ptr = timespec_add_curtime(*recv_timeout);
       
  1497   }
       
  1498 
       
  1499   /* NOTE: When using a half-duplex RS-485 bus, some (most ?) RS232-485
       
  1500    *       converters will send back to the RS232 port whatever we write,
       
  1501    *       so we will read in whatever we write out onto the bus.
       
  1502    *       We will therefore have to compare
       
  1503    *       the first frame we read with the one we sent. If they are
       
  1504    *       identical it is because we are in fact working on a RS-485
       
  1505    *       bus and must therefore read in a second frame which will be
       
  1506    *       the true response to our query.
       
  1507    *       If the first frame we receive is different to the last frame we
       
  1508    *       just sent, then we are *not* working on a RS-485 bus, and
       
  1509    *       that is already the real response to our query.
       
  1510    *
       
  1511    *       Flushing the input cache immediately *after* sending a frame
       
  1512    *       could solve this issue, but we have no guarantee that this
       
  1513    *       process would not get swapped out between the write() and
       
  1514    *       flush() calls, and we could therefore be flushing the response
       
  1515    *       frame along with the last frame we sent!
       
  1516    */
       
  1517 
       
  1518   iter = 0;
       
  1519   while ((res = recv_length = read_frame(nd_entry, recv_data_ptr, ts_ptr)) >= 0) {
       
  1520     if (iter < INT_MAX) iter++;
       
  1521 
       
  1522     if ((send_length <= 0) || (nd_entry->ignore_echo == 0))
       
  1523       /* any valid frame will do... */
       
  1524       return recv_length;
       
  1525 
       
  1526     if ((send_length > L2_FRAME_SLAVEID_OFS + 1) && (iter == 1))
       
  1527      /* We have a frame in send_data,
       
  1528       * so we must make sure we are not reading in the frame just sent...
       
  1529       *
       
  1530       * We must only do this for the first frame we read. Subsequent
       
  1531       * frames are guaranteed not to be the previously sent frame
       
  1532       * since the modbus_ascii_write() resets the recv buffer.
       
  1533       * Remember too that valid modbus responses may be exactly the same
       
  1534       * as the request frame!!
       
  1535       */
       
  1536       if (recv_length == send_length)
       
  1537         if (memcmp(*recv_data_ptr, send_data, recv_length) == 0)
       
  1538           /* recv == send !!! */
       
  1539           /* read in another frame. */
       
  1540           continue;
       
  1541 
       
  1542     /* The frame read is either:
       
  1543      *  - different to the frame in send_data
       
  1544      *  - or there is only the slave id in send_data[L2_FRAME_SLAVEID_OFS]
       
  1545      *  - or both of the above...
       
  1546      */
       
  1547     if (send_length > L2_FRAME_SLAVEID_OFS)
       
  1548       if (recv_length > L2_FRAME_SLAVEID_OFS)
       
  1549         /* check that frame is from/to the correct slave... */
       
  1550         if ((*recv_data_ptr)[L2_FRAME_SLAVEID_OFS] == send_data[L2_FRAME_SLAVEID_OFS])
       
  1551           /* yep, it is... */
       
  1552           return recv_length;
       
  1553 
       
  1554     /* The frame we have received is not acceptable...
       
  1555      * Let's read a new frame.
       
  1556      */
       
  1557   } /* while(...) */
       
  1558 
       
  1559   /* error reading response! */
       
  1560   /* Return the error returned by read_frame! */
       
  1561   return res;
       
  1562 }
       
  1563 
       
  1564 
       
  1565 
       
  1566 
       
  1567 
       
  1568 /**************************************************************/
       
  1569 /**************************************************************/
       
  1570 /****                                                      ****/
       
  1571 /****                                                      ****/
       
  1572 /****        Initialising and Shutting Down Library        ****/
       
  1573 /****                                                      ****/
       
  1574 /****                                                      ****/
       
  1575 /**************************************************************/
       
  1576 /**************************************************************/
       
  1577 
       
  1578 /******************************/
       
  1579 /**                          **/
       
  1580 /**   Load Default Values    **/
       
  1581 /**                          **/
       
  1582 /******************************/
       
  1583 
       
  1584 static void set_defaults(int *baud,
       
  1585                          int *parity,
       
  1586                          int *data_bits,
       
  1587                          int *stop_bits) {
       
  1588   /* Set the default values, if required... */
       
  1589   if (*baud == 0)
       
  1590     *baud = DEF_BAUD_RATE;
       
  1591   if (*data_bits == 0)
       
  1592     *data_bits = DEF_DATA_BITS;
       
  1593   if (*stop_bits == 0) {
       
  1594     if (*parity == 0)
       
  1595       *stop_bits = DEF_STOP_BITS_NOP; /* no parity */
       
  1596     else
       
  1597       *stop_bits = DEF_STOP_BITS_PAR; /* parity used */
       
  1598   }
       
  1599 }
       
  1600 
       
  1601 
       
  1602 
       
  1603 
       
  1604 
       
  1605 /******************************/
       
  1606 /**                          **/
       
  1607 /**    Initialise Library    **/
       
  1608 /**                          **/
       
  1609 /******************************/
       
  1610 
       
  1611 int modbus_ascii_init(int nd_count,
       
  1612                       optimization_t opt,
       
  1613                       int *extra_bytes)
       
  1614 {
       
  1615 #ifdef DEBUG
       
  1616   printf("modbus_asc_init(): called...\n");
       
  1617   printf("creating %d node descriptors\n", nd_count);
       
  1618   if (opt == optimize_speed)
       
  1619     printf("optimizing for speed\n");
       
  1620   if (opt == optimize_size)
       
  1621     printf("optimizing for size\n");
       
  1622 #endif
       
  1623 
       
  1624     /* check input parameters...*/
       
  1625   if (0 == nd_count) {
       
  1626     if (extra_bytes != NULL)
       
  1627       // Not the corect value for this layer. 
       
  1628       // What we set it to in case this layer is not used!
       
  1629       *extra_bytes = 0; 
       
  1630     return 0;
       
  1631   }
       
  1632   if (nd_count <= 0)
       
  1633     goto error_exit_0;
       
  1634 
       
  1635   if (extra_bytes == NULL)
       
  1636     goto error_exit_0;
       
  1637 
       
  1638     /* initialise nd table... */
       
  1639   if (nd_table_init(&nd_table_, nd_count) < 0)
       
  1640     goto error_exit_0;
       
  1641 
       
  1642     /* remember the optimization choice for later reference... */
       
  1643   optimization_ = opt;
       
  1644 
       
  1645 #ifdef DEBUG
       
  1646   printf("modbus_asc_init(): returning succesfuly...\n");
       
  1647 #endif
       
  1648   return 0;
       
  1649 
       
  1650 error_exit_0:
       
  1651   if (extra_bytes != NULL)
       
  1652     *extra_bytes = 0; // The value we set this to in case of error.
       
  1653   return -1;
       
  1654 }
       
  1655 
       
  1656 
       
  1657 
       
  1658 /******************************/
       
  1659 /**                          **/
       
  1660 /**    Open node descriptor  **/
       
  1661 /**                          **/
       
  1662 /******************************/
       
  1663 
       
  1664 /* Open a node for master or slave operation.
       
  1665  * Returns the node descriptor, or -1 on error.
       
  1666  *
       
  1667  * This function is mapped onto both
       
  1668  * modbus_connect() and modbus_listen()
       
  1669  */
       
  1670 int modbus_ascii_connect(node_addr_t node_addr) {
       
  1671   int node_descriptor;
       
  1672   nd_entry_t *nd_entry;
       
  1673 
       
  1674 #ifdef DEBUG
       
  1675   printf("modbus_ascii_connect(): called...\n");
       
  1676   printf("opening %s\n", node_addr.addr.ascii.device);
       
  1677   printf("baud_rate = %d\n", node_addr.addr.ascii.baud);
       
  1678   printf("parity = %d\n", node_addr.addr.ascii.parity);
       
  1679   printf("data_bits = %d\n", node_addr.addr.ascii.data_bits);
       
  1680   printf("stop_bits = %d\n", node_addr.addr.ascii.stop_bits);
       
  1681   printf("ignore_echo = %d\n", node_addr.addr.ascii.ignore_echo);
       
  1682 #endif
       
  1683 
       
  1684   /* Check for valid address family */
       
  1685   if (node_addr.naf != naf_ascii)
       
  1686     /* wrong address type... */
       
  1687     goto error_exit_0;
       
  1688 
       
  1689   /* find a free node descriptor */
       
  1690   if ((node_descriptor = nd_table_get_free_nd(&nd_table_)) < 0)
       
  1691     /* if no free nodes to initialize, then we are finished... */
       
  1692     goto error_exit_0;
       
  1693   if ((nd_entry = nd_table_get_nd(&nd_table_, node_descriptor)) == NULL)
       
  1694     /* strange, this should not occur... */
       
  1695     goto error_exit_0;
       
  1696 
       
  1697   /* set the default values... */
       
  1698   set_defaults(&(node_addr.addr.ascii.baud),
       
  1699                &(node_addr.addr.ascii.parity),
       
  1700                &(node_addr.addr.ascii.data_bits),
       
  1701                &(node_addr.addr.ascii.stop_bits));
       
  1702 
       
  1703   if (nd_entry_connect(nd_entry, &node_addr, optimization_) < 0)
       
  1704     goto error_exit_0;
       
  1705 
       
  1706 #ifdef DEBUG
       
  1707   printf("modbus_ascii_connect(): %s open\n", node_addr.addr.ascii.device );
       
  1708   printf("modbus_ascii_connect(): returning nd=%d\n", node_descriptor);
       
  1709 #endif
       
  1710   return node_descriptor;
       
  1711 
       
  1712   error_exit_0:
       
  1713     return -1;
       
  1714 }
       
  1715 
       
  1716 
       
  1717 
       
  1718 int modbus_ascii_listen(node_addr_t node_addr) {
       
  1719   return modbus_ascii_connect(node_addr);
       
  1720 }
       
  1721 
       
  1722 
       
  1723 
       
  1724 /******************************/
       
  1725 /**                          **/
       
  1726 /**   Close node descriptor  **/
       
  1727 /**                          **/
       
  1728 /******************************/
       
  1729 
       
  1730 int modbus_ascii_close(int nd) {
       
  1731   return nd_table_free_nd(&nd_table_, nd);
       
  1732 }
       
  1733 
       
  1734 
       
  1735 
       
  1736 /******************************/
       
  1737 /**                          **/
       
  1738 /**    Shutdown Library      **/
       
  1739 /**                          **/
       
  1740 /******************************/
       
  1741 
       
  1742 int modbus_ascii_done(void) {
       
  1743   nd_table_done(&nd_table_);
       
  1744   return 0;
       
  1745 }
       
  1746 
       
  1747 
       
  1748 
       
  1749 
       
  1750 
       
  1751 /******************************/
       
  1752 /**                          **/
       
  1753 /**                          **/
       
  1754 /**                          **/
       
  1755 /******************************/
       
  1756 int modbus_ascii_silence_init(void) {
       
  1757   return 0;
       
  1758 }
       
  1759 
       
  1760 
       
  1761 
       
  1762 
       
  1763 /******************************/
       
  1764 /**                          **/
       
  1765 /**                          **/
       
  1766 /**                          **/
       
  1767 /******************************/
       
  1768 
       
  1769 
       
  1770 double modbus_ascii_get_min_timeout(int baud,
       
  1771                                     int parity,
       
  1772                                     int data_bits,
       
  1773                                     int stop_bits) {
       
  1774   int parity_bits, start_bits, char_bits;
       
  1775 
       
  1776   set_defaults(&baud, &parity, &data_bits, &stop_bits);
       
  1777   parity_bits = (parity == 0)?0:1;
       
  1778   start_bits  = 1;
       
  1779   char_bits   = start_bits + data_bits + parity_bits + stop_bits;
       
  1780   return (double)((MAX_ASC_FRAME_LENGTH * char_bits) / baud);
       
  1781 }
       
  1782 
       
  1783 
       
  1784