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: