Skip to content

Commit a05acc2

Browse files
authored
Merge pull request #1947 from peternewman/e1.33-cherry-pick
E1.33 cherry pick third time lucky
2 parents 0b27b6e + a58d5e6 commit a05acc2

39 files changed

Lines changed: 2503 additions & 52 deletions

common/network/HealthCheckedConnection.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,25 @@ namespace network {
2626

2727
HealthCheckedConnection::HealthCheckedConnection(
2828
ola::thread::SchedulerInterface *scheduler,
29+
const ola::TimeInterval heartbeat_interval,
2930
const ola::TimeInterval timeout_interval)
3031
: m_scheduler(scheduler),
31-
m_heartbeat_interval(timeout_interval),
32+
m_heartbeat_interval(heartbeat_interval),
33+
m_timeout_interval(timeout_interval),
3234
m_send_timeout_id(ola::thread::INVALID_TIMEOUT),
3335
m_receive_timeout_id(ola::thread::INVALID_TIMEOUT) {
3436
}
3537

3638

39+
HealthCheckedConnection::HealthCheckedConnection(
40+
ola::thread::SchedulerInterface *scheduler,
41+
const ola::TimeInterval heartbeat_interval)
42+
: HealthCheckedConnection(scheduler,
43+
heartbeat_interval,
44+
ola::TimeInterval(static_cast<int>(
45+
2.5 * heartbeat_interval.AsInt()))) {
46+
}
47+
3748
HealthCheckedConnection::~HealthCheckedConnection() {
3849
if (m_send_timeout_id != ola::thread::INVALID_TIMEOUT)
3950
m_scheduler->RemoveTimeout(m_send_timeout_id);
@@ -101,10 +112,8 @@ bool HealthCheckedConnection::SendNextHeartbeat() {
101112

102113

103114
void HealthCheckedConnection::UpdateReceiveTimer() {
104-
TimeInterval timeout_interval(static_cast<int>(
105-
2.5 * m_heartbeat_interval.AsInt()));
106115
m_receive_timeout_id = m_scheduler->RegisterSingleTimeout(
107-
timeout_interval,
116+
m_timeout_interval,
108117
NewSingleCallback(
109118
this, &HealthCheckedConnection::InternalHeartbeatTimeout));
110119
}

common/network/HealthCheckedConnectionTest.cpp

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,28 @@ class MockHealthCheckedConnection: public HealthCheckedConnection {
5656

5757
MockHealthCheckedConnection(ola::io::ConnectedDescriptor *descriptor,
5858
SelectServer *scheduler,
59+
const ola::TimeInterval heartbeat_interval,
5960
const ola::TimeInterval timeout_interval,
6061
const Options &options,
6162
MockClock *clock)
62-
: HealthCheckedConnection(scheduler, timeout_interval),
63+
: HealthCheckedConnection(scheduler,
64+
heartbeat_interval,
65+
timeout_interval),
66+
m_descriptor(descriptor),
67+
m_ss(scheduler),
68+
m_options(options),
69+
m_next_heartbeat(0),
70+
m_expected_heartbeat(0),
71+
m_channel_ok(true),
72+
m_clock(clock) {
73+
}
74+
75+
MockHealthCheckedConnection(ola::io::ConnectedDescriptor *descriptor,
76+
SelectServer *scheduler,
77+
const ola::TimeInterval heartbeat_interval,
78+
const Options &options,
79+
MockClock *clock)
80+
: HealthCheckedConnection(scheduler, heartbeat_interval),
6381
m_descriptor(descriptor),
6482
m_ss(scheduler),
6583
m_options(options),
@@ -70,8 +88,10 @@ class MockHealthCheckedConnection: public HealthCheckedConnection {
7088
}
7189

7290
void SendHeartbeat() {
91+
OLA_DEBUG << "Maybe send heartbeat";
7392
if (m_options.send_every == 0 ||
7493
m_next_heartbeat % m_options.send_every == 0) {
94+
OLA_DEBUG << "Sending heartbeat";
7595
m_descriptor->Send(&m_next_heartbeat, sizeof(m_next_heartbeat));
7696
}
7797
m_clock->AdvanceTime(0, 180000);
@@ -115,13 +135,18 @@ class HealthCheckedConnectionTest: public CppUnit::TestFixture {
115135
HealthCheckedConnectionTest()
116136
: CppUnit::TestFixture(),
117137
m_ss(NULL, &m_clock),
118-
heartbeat_interval(0, 200000) {
138+
heartbeat_interval(0, 200000),
139+
// Allow a little bit of wiggle room so we don't hit timing issues
140+
// when running the tests
141+
timeout_interval(0, 650000) {
119142
}
120143

121144
CPPUNIT_TEST_SUITE(HealthCheckedConnectionTest);
122145
CPPUNIT_TEST(testSimpleChannel);
123146
CPPUNIT_TEST(testChannelWithPacketLoss);
124147
CPPUNIT_TEST(testChannelWithHeavyPacketLoss);
148+
CPPUNIT_TEST(testChannelWithHeavyPacketLossLongerTimeout);
149+
CPPUNIT_TEST(testChannelWithVeryHeavyPacketLossLongerTimeout);
125150
CPPUNIT_TEST(testPauseAndResume);
126151
CPPUNIT_TEST_SUITE_END();
127152

@@ -131,6 +156,8 @@ class HealthCheckedConnectionTest: public CppUnit::TestFixture {
131156
void testSimpleChannel();
132157
void testChannelWithPacketLoss();
133158
void testChannelWithHeavyPacketLoss();
159+
void testChannelWithHeavyPacketLossLongerTimeout();
160+
void testChannelWithVeryHeavyPacketLossLongerTimeout();
134161
void testPauseAndResume();
135162

136163
void PauseReading(MockHealthCheckedConnection *connection) {
@@ -148,6 +175,7 @@ class HealthCheckedConnectionTest: public CppUnit::TestFixture {
148175
SelectServer m_ss;
149176
LoopbackDescriptor socket;
150177
TimeInterval heartbeat_interval;
178+
TimeInterval timeout_interval;
151179
MockHealthCheckedConnection::Options options;
152180
};
153181

@@ -206,7 +234,7 @@ void HealthCheckedConnectionTest::testChannelWithPacketLoss() {
206234

207235

208236
/**
209-
* Check the channel works when every 2nd heartbeat is lost
237+
* Check the channel fails when 2 of every 3 heartbeats are lost
210238
*/
211239
void HealthCheckedConnectionTest::testChannelWithHeavyPacketLoss() {
212240
options.send_every = 3;
@@ -228,6 +256,57 @@ void HealthCheckedConnectionTest::testChannelWithHeavyPacketLoss() {
228256
}
229257

230258

259+
/**
260+
* Check the channel works when 2 of every 3 heartbeats are lost but the
261+
* timeout interval is 3 * heartbeat_interval rather than the default
262+
*/
263+
void HealthCheckedConnectionTest::
264+
testChannelWithHeavyPacketLossLongerTimeout() {
265+
options.send_every = 3;
266+
MockHealthCheckedConnection connection(&socket,
267+
&m_ss,
268+
heartbeat_interval,
269+
timeout_interval,
270+
options,
271+
&m_clock);
272+
273+
socket.SetOnData(
274+
NewCallback(&connection, &MockHealthCheckedConnection::ReadData));
275+
connection.Setup();
276+
m_ss.AddReadDescriptor(&socket);
277+
connection.Setup();
278+
279+
m_ss.Run();
280+
OLA_ASSERT_TRUE(connection.ChannelOk());
281+
}
282+
283+
284+
/**
285+
* Check the channel fails when 3 of every 4 heartbeats are lost even though
286+
* the timeout interval is 3 * heartbeat_interval
287+
*/
288+
void HealthCheckedConnectionTest::
289+
testChannelWithVeryHeavyPacketLossLongerTimeout() {
290+
options.send_every = 4;
291+
options.abort_on_failure = false;
292+
MockHealthCheckedConnection connection(&socket,
293+
&m_ss,
294+
heartbeat_interval,
295+
timeout_interval,
296+
options,
297+
&m_clock);
298+
299+
socket.SetOnData(
300+
NewCallback(&connection, &MockHealthCheckedConnection::ReadData));
301+
connection.Setup();
302+
m_ss.AddReadDescriptor(&socket);
303+
connection.Setup();
304+
305+
m_ss.Run();
306+
OLA_ASSERT_FALSE(connection.ChannelOk());
307+
}
308+
309+
231310
/**
232311
* Check pausing doesn't mark the channel as bad.
233312
*/

include/ola/e133/E133Enums.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ enum E133DisconnectStatusCode {
9696
enum {
9797
MAX_E133_STATUS_STRING_SIZE = 64
9898
};
99+
100+
// The E1.33 version.
101+
enum {
102+
E133_VERSION = 1
103+
};
99104
} // namespace e133
100105
} // namespace ola
101106
#endif // INCLUDE_OLA_E133_E133ENUMS_H_

include/ola/network/HealthCheckedConnection.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,17 @@
1818
*
1919
* This class adds health checking to a connection, which ensures that the
2020
* connection is able to transfer data in a timely manner. The implementation
21-
* is pretty simple: we define a heart beat interval I, which *must* be the
21+
* is pretty simple: we define a heartbeat interval I, which *must* be the
2222
* same at both ends of the connection. Every I seconds, both ends send a
23-
* heart beat message and if either end doesn't receive a heart beat in
24-
* 2.5 * I, the connection is deemed dead, and the connection is closed.
23+
* heartbeat message and if either end doesn't receive a heartbeat within the
24+
* timeout interval (which defaults to 2.5 * I if not specified), the
25+
* connection is deemed dead, and the connection is closed.
2526
*
2627
* This class provides the basic health check mechanism, the sub class is left
2728
* to define the format of the heartbeat message.
2829
*
2930
* To use this health checked channel, subclass HealthCheckedConnection, and
30-
* provide the SendHeartbeat() and HeartbeatTimeout methods.
31+
* provide the SendHeartbeat() and HeartbeatTimeout() methods.
3132
*
3233
* There are some additional features:
3334
* - Some receivers may want to stop reading from a connection under some
@@ -57,7 +58,10 @@ namespace network {
5758
class HealthCheckedConnection {
5859
public:
5960
HealthCheckedConnection(ola::thread::SchedulerInterface *scheduler,
61+
const ola::TimeInterval heartbeat_interval,
6062
const ola::TimeInterval timeout_interval);
63+
HealthCheckedConnection(ola::thread::SchedulerInterface *scheduler,
64+
const ola::TimeInterval heartbeat_interval);
6165
virtual ~HealthCheckedConnection();
6266

6367
/**
@@ -106,6 +110,7 @@ class HealthCheckedConnection {
106110
private:
107111
ola::thread::SchedulerInterface *m_scheduler;
108112
ola::TimeInterval m_heartbeat_interval;
113+
ola::TimeInterval m_timeout_interval;
109114
ola::thread::timeout_id m_send_timeout_id;
110115
ola::thread::timeout_id m_receive_timeout_id;
111116

include/ola/rdm/RDMEnums.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,9 @@ static const uint8_t MAX_RDM_HOSTNAME_LENGTH = 63;
718718
static const uint8_t MAX_RDM_DOMAIN_NAME_LENGTH = 231;
719719

720720
static const uint8_t DNS_NAME_SERVER_MAX_INDEX = 2;
721+
722+
// Excluding the mandatory NULL terminator
723+
static const uint8_t MAX_RDM_SCOPE_STRING_LENGTH = 62;
721724
} // namespace rdm
722725
} // namespace ola
723726
#endif // INCLUDE_OLA_RDM_RDMENUMS_H_

libs/acn/BrokerClientAddInflator.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation; either version 2 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU Library General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15+
*
16+
* BrokerClientAddInflator.h
17+
* Interface for the BrokerClientAddInflator class.
18+
* Copyright (C) 2023 Peter Newman
19+
*/
20+
21+
#ifndef LIBS_ACN_BROKERCLIENTADDINFLATOR_H_
22+
#define LIBS_ACN_BROKERCLIENTADDINFLATOR_H_
23+
24+
#include "ola/acn/ACNVectors.h"
25+
#include "libs/acn/BaseInflator.h"
26+
27+
namespace ola {
28+
namespace acn {
29+
30+
class BrokerClientAddInflator: public BaseInflator {
31+
friend class BrokerClientAddInflatorTest;
32+
33+
public:
34+
BrokerClientAddInflator()
35+
: BaseInflator() {
36+
}
37+
~BrokerClientAddInflator() {}
38+
39+
uint32_t Id() const { return ola::acn::VECTOR_BROKER_CLIENT_ADD; }
40+
41+
protected:
42+
// The 'header' is 0 bytes in length.
43+
bool DecodeHeader(HeaderSet*,
44+
const uint8_t*,
45+
unsigned int,
46+
unsigned int *bytes_used) {
47+
*bytes_used = 0;
48+
return true;
49+
}
50+
51+
void ResetHeaderField() {} // namespace noop
52+
};
53+
} // namespace acn
54+
} // namespace ola
55+
#endif // LIBS_ACN_BROKERCLIENTADDINFLATOR_H_
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* This program is free software; you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation; either version 2 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU Library General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
15+
*
16+
* BrokerClientEntryChangeInflator.h
17+
* Interface for the BrokerClientEntryChangeInflator class.
18+
* Copyright (C) 2023 Peter Newman
19+
*/
20+
21+
#ifndef LIBS_ACN_BROKERCLIENTENTRYCHANGEINFLATOR_H_
22+
#define LIBS_ACN_BROKERCLIENTENTRYCHANGEINFLATOR_H_
23+
24+
#include "ola/acn/ACNVectors.h"
25+
#include "libs/acn/BaseInflator.h"
26+
27+
namespace ola {
28+
namespace acn {
29+
30+
class BrokerClientEntryChangeInflator: public BaseInflator {
31+
friend class BrokerClientEntryChangeInflatorTest;
32+
33+
public:
34+
BrokerClientEntryChangeInflator()
35+
: BaseInflator() {
36+
}
37+
~BrokerClientEntryChangeInflator() {}
38+
39+
uint32_t Id() const { return ola::acn::VECTOR_BROKER_CLIENT_ENTRY_CHANGE; }
40+
41+
protected:
42+
// The 'header' is 0 bytes in length.
43+
bool DecodeHeader(HeaderSet*,
44+
const uint8_t*,
45+
unsigned int,
46+
unsigned int *bytes_used) {
47+
*bytes_used = 0;
48+
return true;
49+
}
50+
51+
void ResetHeaderField() {} // namespace noop
52+
};
53+
} // namespace acn
54+
} // namespace ola
55+
#endif // LIBS_ACN_BROKERCLIENTENTRYCHANGEINFLATOR_H_

0 commit comments

Comments
 (0)