Skip to content

Commit d663d5b

Browse files
Added queue event collection to tcp/ip client
1 parent 38c4e01 commit d663d5b

File tree

3 files changed

+79
-32
lines changed

3 files changed

+79
-32
lines changed

src/vscp/common/vscp-client-socketcan.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ workerThread(void *pData)
882882
setsockopt(pObj->m_socket, SOL_SOCKET, SO_RCVTIMEO, (const char *) &tv, sizeof(struct timeval));
883883

884884
if (bind(pObj->m_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
885-
spdlog::error("SOCKETCAN client: wrkthread socketcan client: Error in socket bind. Terminating!");
885+
spdlog::error("SOCKETCAN client: workthread socketcan client: Error in socket bind. Terminating!");
886886
close(pObj->m_socket);
887887
sleep(2);
888888
// continue;

src/vscp/common/vscp-client-tcp.cpp

Lines changed: 56 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ vscpClientTcp::vscpClientTcp()
4848
m_guidif.clear();
4949
m_bPolling = false;
5050
m_obid = 0;
51+
52+
vscp_clearVSCPFilter(&m_filterIn); // Accept all events
53+
vscp_clearVSCPFilter(&m_filterOut); // Send all events
54+
55+
sem_init(&m_semReceiveQueue, 0, 0);
56+
57+
pthread_mutex_init(&m_mutexTcpIpObject, NULL);
58+
pthread_mutex_init(&m_mutexReceiveQueue, NULL);
5159
}
5260

5361
///////////////////////////////////////////////////////////////////////////////
@@ -59,6 +67,11 @@ vscpClientTcp::~vscpClientTcp()
5967
// Just to be sure
6068
disconnect();
6169

70+
sem_destroy(&m_semReceiveQueue);
71+
72+
pthread_mutex_destroy(&m_mutexTcpIpObject);
73+
pthread_mutex_destroy(&m_mutexReceiveQueue);
74+
6275
// Clear the input queue (if needed)
6376
// while (m_inputQue.size()) {
6477
// vscpEvent *pev = m_inputQue.front();
@@ -96,17 +109,17 @@ vscpClientTcp::getConfigAsJson(void)
96109
j["keyfile"] = m_keyfile;
97110
j["pwkeyfile"] = m_pwKeyfile;
98111

99-
// Filter
112+
// Filter In
100113

101-
j["priority-filter"] = m_filter.filter_priority;
102-
j["priority-mask"] = m_filter.mask_priority;
103-
j["class-filter"] = m_filter.filter_class;
104-
j["class-mask"] = m_filter.mask_class;
105-
j["type-filter"] = m_filter.filter_type;
106-
j["type-mask"] = m_filter.mask_type;
107-
vscp_writeGuidArrayToString(str, m_filter.filter_GUID);
114+
j["priority-filter"] = m_filterIn.filter_priority;
115+
j["priority-mask"] = m_filterIn.mask_priority;
116+
j["class-filter"] = m_filterIn.filter_class;
117+
j["class-mask"] = m_filterIn.mask_class;
118+
j["type-filter"] = m_filterIn.filter_type;
119+
j["type-mask"] = m_filterIn.mask_type;
120+
vscp_writeGuidArrayToString(str, m_filterIn.filter_GUID);
108121
j["guid-filter"] = str;
109-
vscp_writeGuidArrayToString(str, m_filter.mask_GUID);
122+
vscp_writeGuidArrayToString(str, m_filterIn.mask_GUID);
110123
j["guid-mask"] = str;
111124

112125
return j.dump();
@@ -190,37 +203,37 @@ vscpClientTcp::initFromJson(const std::string &config)
190203
// Filter
191204

192205
if (j.contains("priority-filter")) {
193-
m_filter.filter_priority = j["priority-filter"].get<uint8_t>();
206+
m_filterIn.filter_priority = j["priority-filter"].get<uint8_t>();
194207
}
195208

196209
if (j.contains("priority-mask")) {
197-
m_filter.mask_priority = j["priority-mask"].get<uint8_t>();
210+
m_filterIn.mask_priority = j["priority-mask"].get<uint8_t>();
198211
}
199212

200213
if (j.contains("class-filter")) {
201-
m_filter.filter_class = j["class-filter"].get<uint16_t>();
214+
m_filterIn.filter_class = j["class-filter"].get<uint16_t>();
202215
}
203216

204217
if (j.contains("class-mask")) {
205-
m_filter.mask_class = j["class-mask"].get<uint16_t>();
218+
m_filterIn.mask_class = j["class-mask"].get<uint16_t>();
206219
}
207220

208221
if (j.contains("type-filter")) {
209-
m_filter.filter_type = j["type-filter"].get<uint16_t>();
222+
m_filterIn.filter_type = j["type-filter"].get<uint16_t>();
210223
}
211224

212225
if (j.contains("type-mask")) {
213-
m_filter.mask_type = j["type-mask"].get<uint16_t>();
226+
m_filterIn.mask_type = j["type-mask"].get<uint16_t>();
214227
}
215228

216229
if (j.contains("guid-filter")) {
217230
std::string str = j["guid-filter"].get<std::string>();
218-
vscp_getGuidFromStringToArray(m_filter.filter_GUID, str);
231+
vscp_getGuidFromStringToArray(m_filterIn.filter_GUID, str);
219232
}
220233

221234
if (j.contains("guid-mask")) {
222235
std::string str = j["guid-mask"].get<std::string>();
223-
vscp_getGuidFromStringToArray(m_filter.mask_GUID, str);
236+
vscp_getGuidFromStringToArray(m_filterIn.mask_GUID, str);
224237
}
225238
}
226239
catch (...) {
@@ -477,9 +490,9 @@ vscpClientTcp::setfilter(vscpEventFilter &filter)
477490
return m_tcp.doCmdFilter(&filter);
478491
}
479492
else {
480-
m_mutexReceive.lock();
493+
pthread_mutex_lock(&m_mutexTcpIpObject);
481494
return m_tcpReceive.doCmdFilter(&filter);
482-
m_mutexReceive.unlock();
495+
pthread_mutex_unlock(&m_mutexTcpIpObject);
483496
}
484497
}
485498

@@ -617,18 +630,38 @@ workerThread(vscpClientTcp *pObj)
617630

618631
while (pObj->m_bRun) {
619632

620-
pObj->m_mutexReceive.lock();
633+
pthread_mutex_lock(&pObj->m_mutexTcpIpObject);
621634

622-
// m_pif->rcvloopRead(500);
623635
if (VSCP_ERROR_SUCCESS == m_pifReceive->doCmdBlockingReceive(&ev)) {
624-
pObj->sendToCallbacks(&ev);
636+
637+
if (vscp_doLevel2Filter(&ev, &pObj->m_filterIn)) {
638+
639+
if (pObj->isCallbackEvActive()) {
640+
pObj->m_callbackev(ev, pObj->getCallbackObj());
641+
}
642+
643+
if (pObj->isCallbackExActive()) {
644+
vscpEventEx ex;
645+
if (vscp_convertEventToEventEx(&ex, &ev)) {
646+
pObj->m_callbackex(ex, pObj->getCallbackObj());
647+
}
648+
}
649+
650+
// Add to input queue only if no callback set
651+
if (!pObj->isCallbackEvActive() || !pObj->isCallbackExActive()) {
652+
pthread_mutex_lock(&pObj->m_mutexReceiveQueue);
653+
pObj->m_receiveList.push_back(&ev);
654+
sem_post(&pObj->m_semReceiveQueue);
655+
pthread_mutex_unlock(&pObj->m_mutexReceiveQueue);
656+
}
657+
}
625658
vscp_deleteEvent(&ev);
626659
}
627660

628661
if (!m_pifReceive->isConnected()) {
629662
pObj->m_bRun = false;
630663
}
631664

632-
pObj->m_mutexReceive.unlock();
665+
pthread_mutex_unlock(&pObj->m_mutexTcpIpObject);
633666
}
634667
}

src/vscp/common/vscp-client-tcp.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class vscpClientTcp : public CVscpClient {
4444
tcp:// or stcp:// (SSL connection)
4545
@param strUsername Username used to login on remote host.
4646
@param strPassword Password used to login on remote host.
47-
@param bPolling If true only one connection will be opended to the remote server
48-
on which polling for events will be done. If false one connection will be opended
47+
@param bPolling If true only one connection will be opened to the remote server
48+
on which polling for events will be done. If false one connection will be opened
4949
for send and one for receive. The polling is intended for low end devices which
5050
only accepts one client at the time.
5151
@return Return VSCP_ERROR_SUCCESS of OK and error code else.
@@ -257,25 +257,36 @@ class vscpClientTcp : public CVscpClient {
257257
void sendToCallbacks(vscpEvent *pev);
258258

259259
public:
260-
/// Flag for workerthread run as long it's true
260+
/// Flag for worker thread run as long it's true
261261
bool m_bRun;
262262

263+
// Event lists
264+
// std::list<vscpEvent *> m_sendList;
265+
std::list<vscpEvent *> m_receiveList;
266+
263267
/// Mutex to protect receive tcp/ip object
264-
std::mutex m_mutexReceive;
268+
pthread_mutex_t m_mutexTcpIpObject;
269+
270+
/// Mutex to protect receive queue
271+
pthread_mutex_t m_mutexReceiveQueue;
265272

266273
/*!
267274
Event object to indicate that there is an event in the
268275
output queue
269276
*/
270277
sem_t m_semReceiveQueue;
271278

279+
/// Filters for input/output
280+
vscpEventFilter m_filterIn;
281+
vscpEventFilter m_filterOut;
282+
272283
/// Used for channel id (prevent sent events from being received)
273284
uint32_t m_obid;
274285

275286
private:
276287
/*!
277288
The main interface (sending) is always opened (both in poll and
278-
standard mode). The Receive interface is opended only in normal mode
289+
standard mode). The Receive interface is opened only in normal mode
279290
and do just connect - log in - enable receive loop. Received events
280291
will be sent on the defined callbacks.
281292
*/
@@ -286,12 +297,13 @@ class vscpClientTcp : public CVscpClient {
286297
/// Receiving interface
287298
VscpRemoteTcpIf m_tcpReceive;
288299

289-
// Filter used for both channels
290-
vscpEventFilter m_filter;
291-
292300
// Interface on remote host
293301
cguid m_guidif;
294302

303+
// ------------------------------------------------------------------------
304+
305+
306+
295307
/// Workerthread
296308
std::thread *m_pworkerthread;
297309

@@ -312,6 +324,8 @@ class vscpClientTcp : public CVscpClient {
312324
/// If true the remote host interface will be polled.
313325
bool m_bPolling;
314326

327+
328+
315329
// ------------------------------------------------------------------------
316330
// TLS / SSL
317331
// ------------------------------------------------------------------------

0 commit comments

Comments
 (0)