msousa@0: /*
msousa@0: * Copyright (c) 2002,2016 Mario de Sousa (msousa@fe.up.pt)
msousa@0: *
msousa@0: * This file is part of the Modbus library for Beremiz and matiec.
msousa@0: *
msousa@0: * This Modbus library is free software: you can redistribute it and/or modify
msousa@0: * it under the terms of the GNU Lesser General Public License as published by
msousa@0: * the Free Software Foundation, either version 3 of the License, or
msousa@0: * (at your option) any later version.
msousa@0: *
msousa@0: * This program is distributed in the hope that it will be useful, but
msousa@0: * WITHOUT ANY WARRANTY; without even the implied warranty of
msousa@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
msousa@0: * General Public License for more details.
msousa@0: *
msousa@0: * You should have received a copy of the GNU Lesser General Public License
msousa@0: * along with this Modbus library. If not, see .
msousa@0: *
msousa@0: * This code is made available on the understanding that it will not be
msousa@0: * used in safety-critical situations without a full and competent review.
msousa@0: */
msousa@0:
msousa@0:
msousa@0:
msousa@0: #include /* File control definitions */
msousa@0: #include /* Standard input/output */
msousa@0: #include
msousa@0: #include
msousa@0: #include /* POSIX terminal control definitions */
msousa@0: #include /* Time structures for select() */
msousa@0: #include /* POSIX Symbolic Constants */
msousa@0: #include /* Error definitions */
msousa@0:
msousa@0: #include "mb_layer1.h"
msousa@0: #include "mb_slave_private.h"
msousa@0: #include "mb_master_private.h"
msousa@0: #include "mb_slave.h"
msousa@0: #include "mb_master.h"
msousa@0:
msousa@0: //#define DEBUG /* uncomment to see the data sent and received */
msousa@0:
msousa@0:
msousa@0: #ifndef TRUE
msousa@0: #define TRUE 1
msousa@0: #endif
msousa@0:
msousa@0: #ifndef FALSE
msousa@0: #define FALSE 0
msousa@0: #endif
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: layer1_funct_ptr_t fptr_[4] = {
msousa@0: { /* WARNING: TCP functions MUST be the first, as we have this hardcoded in the code! */
msousa@0: /* more specifically, in the get_ttyfd() macro in mb_slave.c */
msousa@0: /* in the mb_slave_new() function in mb_slave.c */
msousa@0: /* in the mb_master_connect() function in mb_master.c */
msousa@0: &modbus_tcp_write
msousa@0: ,&modbus_tcp_read
msousa@0: ,&modbus_tcp_init
msousa@0: ,&modbus_tcp_done
msousa@0: ,&modbus_tcp_connect
msousa@0: ,&modbus_tcp_listen
msousa@0: ,&modbus_tcp_close
msousa@0: ,&modbus_tcp_silence_init
msousa@0: ,&modbus_tcp_get_min_timeout
msousa@0: },{
msousa@0: &modbus_rtu_write
msousa@0: ,&modbus_rtu_read
msousa@0: ,&modbus_rtu_init
msousa@0: ,&modbus_rtu_done
msousa@0: ,&modbus_rtu_connect
msousa@0: ,&modbus_rtu_listen
msousa@0: ,&modbus_rtu_close
msousa@0: ,&modbus_rtu_silence_init
msousa@0: ,&modbus_rtu_get_min_timeout
msousa@0: },{
msousa@0: &modbus_ascii_write
msousa@0: ,&modbus_ascii_read
msousa@0: ,&modbus_ascii_init
msousa@0: ,&modbus_ascii_done
msousa@0: ,&modbus_ascii_connect
msousa@0: ,&modbus_ascii_listen
msousa@0: ,&modbus_ascii_close
msousa@0: ,&modbus_ascii_silence_init
msousa@0: ,&modbus_ascii_get_min_timeout
msousa@0: },{
msousa@0: NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
msousa@0: }
msousa@0: };
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: /************************************************************************
msousa@0:
msousa@0: initialise / shutdown the library
msousa@0:
msousa@0: These functions sets up/shut down the library state
msousa@0: (allocate memory for buffers, initialise data strcutures, etc)
msousa@0:
msousa@0: **************************************************************************/
msousa@0: #define max(a,b) (((a)>(b))?(a):(b))
msousa@0:
msousa@0: int mb_slave_and_master_init(int nd_count_tcp, int nd_count_rtu, int nd_count_ascii) {
msousa@0: int extra_bytes, extra_bytes_tcp, extra_bytes_rtu, extra_bytes_ascii;
msousa@0:
msousa@0: #ifdef DEBUG
msousa@0: fprintf( stderr, "mb_slave_and_master_init()\n");
msousa@0: fprintf( stderr, "creating %d nodes\n", nd_count);
msousa@0: #endif
msousa@0:
msousa@0: /* initialise layer 1 library */
msousa@0: if (modbus_tcp_init (nd_count_tcp, DEF_OPTIMIZATION, &extra_bytes_tcp ) < 0)
msousa@0: goto error_exit_0;
msousa@0: if (modbus_rtu_init (nd_count_rtu, DEF_OPTIMIZATION, &extra_bytes_rtu ) < 0)
msousa@0: goto error_exit_1;
msousa@0: if (modbus_ascii_init(nd_count_ascii, DEF_OPTIMIZATION, &extra_bytes_ascii) < 0)
msousa@0: goto error_exit_2;
msousa@0: extra_bytes= max(extra_bytes_tcp, extra_bytes_rtu);
msousa@0: extra_bytes= max(extra_bytes , extra_bytes_ascii);
msousa@0:
msousa@0: /* initialise master and slave libraries... */
msousa@0: if (mb_slave_init__(extra_bytes) < 0)
msousa@0: goto error_exit_3;
msousa@0: if (mb_master_init__(extra_bytes) < 0)
msousa@0: goto error_exit_4;
msousa@0: return 0;
msousa@0:
msousa@0: /*
msousa@0: error_exit_3:
msousa@0: modbus_master_done();
msousa@0: */
msousa@0: error_exit_4:
msousa@0: mb_slave_done__();
msousa@0: error_exit_3:
msousa@0: modbus_ascii_done();
msousa@0: error_exit_2:
msousa@0: modbus_rtu_done();
msousa@0: error_exit_1:
msousa@0: modbus_tcp_done();
msousa@0: error_exit_0:
msousa@0: return -1;
msousa@0: }
msousa@0:
msousa@0:
msousa@0:
msousa@0:
msousa@0: int mb_slave_and_master_done(void) {
msousa@0: int res = 0;
msousa@0: res |= mb_slave_done__ ();
msousa@0: res |= mb_master_done__ ();
msousa@0: res |= modbus_ascii_done();
msousa@0: res |= modbus_rtu_done ();
msousa@0: res |= modbus_tcp_done ();
msousa@0: return res;
msousa@0: }
msousa@0: