ModbusConnections.cpp
5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include "ModbusConnections.h"
ModbusConnections::ModbusConnections()
{
}
ModbusConnections::~ModbusConnections()
{
if( m_mapSerial.size() > 0 )
{
// Iterate, remove and destroy ( Searching, Seek & Destroy )
}
if( m_mapTcp.size() > 0 )
{
// Iterate, remove and destroy ( Searching, Seek & Destroy )
}
}
bool ModbusConnections::CreateConnection( const ConnectionConfig &config )
{
std::shared_ptr<IModbusAdapter> ptrNewAdapter = std::make_shared<ModbusAdapter>();
if( ptrNewAdapter == nullptr )
{
// Log a message and bail out
return false;
}
// It looks like the pointer is valid. Time to connect.
ptrNewAdapter->ModbusConnect( config );
if( !ptrNewAdapter->isConnected() )
{
// Unsuccessful. Delete the object and return false
ptrNewAdapter.reset();
return false;
}
std::shared_ptr<IModbusAdapter> ptr = connectionExist( config.getPortEnum(), createEndPoint( config ) );
if( ptr != nullptr )
{
if( !DeleteConnection( config.getPortEnum(), createEndPoint( config ) ) )
{
// Something went wrong here.. Our administration is "wonky" so report false and bail.
// New connection is not created.
ptrNewAdapter.reset();
return false;
}
}
if( config.getType() == ConnectionType::CT_TCP )
{
// === Critical Section ===
std::lock_guard<std::mutex> guard( m_mapTcpMutex );
m_mapTcp.insert( { createEndPoint( config ), ptrNewAdapter } );
// === End Critical Section ===
}
else if( config.getType() == ConnectionType::CT_SERIAL )
{
// === Critical Section ===
std::lock_guard<std::mutex> guard( m_mapSerialMutex );
m_mapSerial.insert( { config.getPortEnum(), ptrNewAdapter } );
// === End Critical Section ===
}
else
{
// No idea what the type is but not something we recognize.
ptrNewAdapter.reset();
return false;
}
return true;
}
bool ModbusConnections::DeleteConnection( const ConnectionPort portName, const std::string &endpoint )
{
std::shared_ptr<IModbusAdapter> ptr = this->connectionExist( portName, endpoint );
if( ptr == nullptr )
{
// Seems like it is already gone. Shouldn't happen, but ok.
return false;
}
// First remove it from the map.
if( portName == ConnectionPort::CP_TCP )
{
// === Critical Section ===
std::lock_guard<std::mutex> guard( m_mapTcpMutex );
m_mapTcp.erase( endpoint );
// === End Critical Section ===
}
else
{
// === Critical Section ===
std::lock_guard<std::mutex> guard( m_mapSerialMutex );
m_mapSerial.erase( portName );
// === End Critical Section ===
}
// Call the disconnect for a clean exit.
ptr->ModbusDisconnect();
// Delete the pointer or decrease the ref-count
ptr.reset();
return true;
}
int ModbusConnections::ConnectionCount()
{
return ( m_mapSerial.size() + m_mapTcp.size() );
}
std::shared_ptr<IModbusAdapter> ModbusConnections::getConnection( const ConnectionPort portName, const std::string &endpoint )
{
return this->connectionExist( portName, endpoint );
}
std::shared_ptr<IModbusAdapter> ModbusConnections::getConnection( const ConnectionPort portName, const std::string &ipAddress, int tcpPortNumber )
{
return this->connectionExist( portName, this->createEndPoint( ipAddress, tcpPortNumber ) );
}
AdapterList ModbusConnections::getConnections()
{
AdapterList lstResult;
{
// === Critical Section ===
std::lock_guard<std::mutex> guard(m_mapSerialMutex);
// First we pick up the Serial Map
for( auto const& [key, value] : m_mapSerial )
{
lstResult.push_back( value );
}
// === End Critical Section ===
}
{
// === Critical Section ===
std::lock_guard<std::mutex> guard(m_mapTcpMutex);
// Next we pick all the entries in the tcp-map
for( auto const& [key, value] : m_mapTcp )
{
lstResult.push_back( value );
}
// === End Critical Section ===
}
return lstResult;
}
std::shared_ptr<IModbusAdapter> ModbusConnections::connectionExist( const ConnectionPort portName, const std::string &endpoint )
{
if( portName == ConnectionPort::CP_TCP )
{
auto search = m_mapTcp.find( endpoint );
if( search != m_mapTcp.end() )
{
return search->second;
}
else
{
return nullptr;
}
}
else
{
auto search = m_mapSerial.find( portName );
if( search != m_mapSerial.end() )
{
return search->second;
}
else
{
return nullptr;
}
}
}
std::string ModbusConnections::createEndPoint( const std::string &ipAddress, int portNumber )
{
if( portNumber > 0 && !ipAddress.empty() )
{
return std::string( "tcp://" + ipAddress + ":" + std::to_string( portNumber ) );
}
return std::string();
}
std::string ModbusConnections::createEndPoint( const ConnectionConfig &config )
{
if( config.getType() != ConnectionType::CT_TCP )
{
// Early opt-out
return std::string();
}
return createEndPoint( config.getIpAddress(), config.getTcpPort() );
}