• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wirenboard / wb-mqtt-serial / 2

29 Dec 2025 12:28PM UTC coverage: 76.817% (+4.0%) from 72.836%
2

Pull #1045

github

54aa0c
pgasheev
up changelog
Pull Request #1045: Fix firmware version in WB-M1W2 template

6873 of 9161 branches covered (75.02%)

12966 of 16879 relevant lines covered (76.82%)

1651.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.1
/src/pollable_device.cpp
1
#include "pollable_device.h"
2

3
bool TRegisterComparePredicate::operator()(const PRegister& r1, const PRegister& r2) const
3,940✔
4
{
5
    if (r1->GetConfig()->Type != r2->GetConfig()->Type) {
3,940✔
6
        return r1->GetConfig()->Type > r2->GetConfig()->Type;
968✔
7
    }
8
    auto cmp = r1->GetConfig()->GetAddress().Compare(r2->GetConfig()->GetAddress());
2,972✔
9
    if (cmp != 0) {
2,972✔
10
        return cmp > 0;
2,842✔
11
    }
12
    // addresses are equal, compare offsets
13
    return r1->GetConfig()->GetDataOffset() > r2->GetConfig()->GetDataOffset();
130✔
14
}
15

16
TPollableDevice::TPollableDevice(PSerialDevice device,
404✔
17
                                 std::chrono::steady_clock::time_point currentTime,
18
                                 TPriority priority)
404✔
19
    : Device(device),
20
      Priority(priority),
21
      DisconnectedPollDelay(0)
404✔
22
{
23
    for (const auto& reg: Device->GetRegisters()) {
2,624✔
24
        if ((Priority == TPriority::High && reg->GetConfig()->IsHighPriority()) ||
6,646✔
25
            (Priority == TPriority::Low && !reg->GetConfig()->IsHighPriority()))
4,426✔
26
        {
27
            if (reg->GetConfig()->AccessType != TRegisterConfig::EAccessType::WRITE_ONLY) {
1,110✔
28
                Registers.AddEntry(reg, currentTime);
1,110✔
29
            }
30
        }
31
    }
32
}
404✔
33

34
PRegisterRange TPollableDevice::ReadRegisterRange(TFeaturePort& port,
1,590✔
35
                                                  std::chrono::milliseconds pollLimit,
36
                                                  bool readAtLeastOneRegister,
37
                                                  const util::TSpentTimeMeter& sessionTime,
38
                                                  TSerialClientDeviceAccessHandler& lastAccessedDevice)
39
{
40
    auto currentTime = sessionTime.GetStartTime();
1,590✔
41
    auto registerRange = Device->CreateRegisterRange();
1,590✔
42
    while (Registers.HasReadyItems(currentTime)) {
3,986✔
43
        const auto limit = (readAtLeastOneRegister && registerRange->RegisterList().empty())
3,116✔
44
                               ? std::chrono::milliseconds::max()
4,738✔
45
                               : pollLimit;
3,312✔
46
        const auto& item = Registers.GetTop();
3,312✔
47
        if (!registerRange->Add(port, item.Data, limit)) {
3,312✔
48
            break;
916✔
49
        }
50
        Registers.Pop();
2,396✔
51
    }
52

53
    if (!registerRange->RegisterList().empty()) {
1,590✔
54
        bool readOk = false;
1,516✔
55
        if (lastAccessedDevice.PrepareToAccess(port, Device)) {
1,516✔
56
            Device->ReadRegisterRange(port, registerRange);
1,486✔
57
            readOk = true;
1,486✔
58
        }
59

60
        for (auto& reg: registerRange->RegisterList()) {
3,890✔
61
            reg->SetLastPollTime(currentTime);
2,374✔
62
            if (!readOk) {
2,374✔
63
                reg->SetError(TRegister::TError::ReadError);
66✔
64
            }
65
        }
66

67
        for (const auto& reg: registerRange->RegisterList()) {
3,890✔
68
            ScheduleNextPoll(reg, currentTime);
2,374✔
69
        }
70

71
        Device->SetLastReadTime(currentTime + sessionTime.GetSpentTime());
1,516✔
72
    }
73

74
    return registerRange;
3,180✔
75
}
76

77
std::list<PRegister> TPollableDevice::MarkWaitingRegistersAsReadErrorAndReschedule(
8✔
78
    std::chrono::steady_clock::time_point currentTime)
79
{
80
    std::list<PRegister> res;
8✔
81
    while (Registers.HasReadyItems(currentTime)) {
24✔
82
        res.push_back(Registers.GetTop().Data);
16✔
83
        Registers.Pop();
16✔
84
    }
85
    for (const auto& reg: res) {
24✔
86
        ScheduleNextPoll(reg, currentTime);
16✔
87
    }
88
    return res;
8✔
89
}
90

91
std::chrono::steady_clock::time_point TPollableDevice::GetDeadline() const
1,568✔
92
{
93
    if (Priority == TPriority::Low && Device->DeviceConfig()->MinRequestInterval != std::chrono::milliseconds::zero()) {
1,568✔
94
        auto deadline = Registers.GetDeadline();
×
95
        auto minNextReadTime = Device->GetLastReadTime() + Device->DeviceConfig()->MinRequestInterval;
×
96
        return minNextReadTime > deadline ? minNextReadTime : deadline;
×
97
    }
98
    return Registers.GetDeadline();
1,568✔
99
}
100

101
std::chrono::milliseconds TPollableDevice::GetDisconnectedPollDelay() const
106✔
102
{
103
    return DisconnectedPollDelay;
106✔
104
}
105

106
void TPollableDevice::SetDisconnectedPollDelay(const std::chrono::milliseconds& delay)
1,524✔
107
{
108
    DisconnectedPollDelay = delay;
1,524✔
109
}
1,524✔
110

111
TPriority TPollableDevice::GetPriority() const
5,532✔
112
{
113
    return Priority;
5,532✔
114
}
115

116
PSerialDevice TPollableDevice::GetDevice() const
3,240✔
117
{
118
    return Device;
3,240✔
119
}
120

121
bool TPollableDevice::HasRegisters() const
1,928✔
122
{
123
    return !Registers.IsEmpty();
1,928✔
124
}
125

126
void TPollableDevice::RescheduleAllRegisters()
44✔
127
{
128
    for (const auto& reg: Device->GetRegisters()) {
120✔
129
        if ((Priority == TPriority::High && reg->GetConfig()->IsHighPriority()) ||
226✔
130
            (Priority == TPriority::Low && !reg->GetConfig()->IsHighPriority()))
150✔
131
        {
132
            if (reg->GetConfig()->AccessType != TRegisterConfig::EAccessType::WRITE_ONLY) {
72✔
133
                if (reg->IsExcludedFromPolling() && !Registers.Contains(reg)) {
72✔
134
                    reg->SetAvailable(TRegisterAvailability::UNKNOWN);
×
135
                    reg->IncludeInPolling();
×
136
                    Registers.AddEntry(reg, std::chrono::steady_clock::time_point());
×
137
                }
138
            }
139
        }
140
    }
141
}
44✔
142

143
void TPollableDevice::ScheduleNextPoll(PRegister reg, std::chrono::steady_clock::time_point currentTime)
2,390✔
144
{
145
    if (reg->IsExcludedFromPolling()) {
2,390✔
146
        // If register is sporadic it must be read once to get actual value
147
        // Keep polling it until successful read
148
        if (reg->GetValue().GetType() == TRegisterValue::ValueType::Undefined) {
44✔
149
            Registers.AddEntry(reg, currentTime + std::chrono::microseconds(1));
32✔
150
        }
151
        return;
44✔
152
    }
153
    if (Priority == TPriority::High) {
2,346✔
154
        Registers.AddEntry(reg, currentTime + *(reg->GetConfig()->ReadPeriod));
84✔
155
        return;
84✔
156
    }
157
    if (reg->GetConfig()->ReadRateLimit) {
2,262✔
158
        Registers.AddEntry(reg, currentTime + *(reg->GetConfig()->ReadRateLimit));
22✔
159
        return;
22✔
160
    }
161
    // Low priority registers should be scheduled to read as soon as possible,
162
    // but with a small delay after current read.
163
    Registers.AddEntry(reg, currentTime + std::chrono::microseconds(1));
2,240✔
164
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc