• 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.85
/src/devices/lls_device.cpp
1
#include "lls_device.h"
2

3
#include <stddef.h>
4

5
namespace
6
{
7
    class TLLSDeviceRegisterAddressFactory: public TStringRegisterAddressFactory
8
    {
9
    public:
10
        TRegisterDesc LoadRegisterAddress(const Json::Value& regCfg,
16✔
11
                                          const IRegisterAddress& deviceBaseAddress,
12
                                          uint32_t stride,
13
                                          uint32_t registerByteWidth) const override
14
        {
15
            auto addr = LoadRegisterBitsAddress(regCfg, SerialConfig::ADDRESS_PROPERTY_NAME);
16✔
16
            TRegisterDesc res;
16✔
17
            res.DataOffset = (addr.Address & 0xFF);
16✔
18
            res.Address = std::make_shared<TUint32RegisterAddress>(addr.Address >> 8);
16✔
19
            return res;
32✔
20
        }
21
    };
22
}
23

24
void TLLSDevice::Register(TSerialDeviceFactory& factory)
288✔
25
{
26
    factory.RegisterProtocol(
288✔
27
        new TUint32SlaveIdProtocol("lls", TRegisterTypes({{0, "default", "value", Float, true}})),
864✔
28
        new TBasicDeviceFactory<TLLSDevice, TLLSDeviceRegisterAddressFactory>("#/definitions/simple_device",
29
                                                                              "#/definitions/common_channel"));
576✔
30
}
288✔
31

32
TLLSDevice::TLLSDevice(PDeviceConfig config, PProtocol protocol)
2✔
33
    : TSerialDevice(config, protocol),
34
      TUInt32SlaveId(config->SlaveId)
2✔
35
{}
2✔
36

37
static unsigned char dallas_crc8(const unsigned char* data, const unsigned int size)
8✔
38
{
39
    unsigned char crc = 0;
8✔
40
    for (unsigned int i = 0; i < size; ++i) {
84✔
41
        unsigned char inbyte = data[i];
76✔
42
        for (unsigned char j = 0; j < 8; ++j) {
684✔
43
            unsigned char mix = (crc ^ inbyte) & 0x01;
608✔
44
            crc >>= 1;
608✔
45
            if (mix)
608✔
46
                crc ^= 0x8C;
332✔
47
            inbyte >>= 1;
608✔
48
        }
49
    }
50
    return crc;
8✔
51
}
52

53
void TLLSDevice::InvalidateReadCache()
4✔
54
{
55
    CmdResultCache.clear();
4✔
56

57
    TSerialDevice::InvalidateReadCache();
4✔
58
}
4✔
59

60
namespace
61
{
62
    const size_t RESPONSE_BUF_LEN = 100;
63
    const size_t REQUEST_LEN = 4;
64
    const ptrdiff_t HEADER_SZ = 3;
65
    const uint8_t REQUEST_PREFIX = 0x31;
66
    const uint8_t RESPONSE_PREFIX = 0x3E;
67
}
68

69
std::vector<uint8_t> TLLSDevice::ExecCommand(TPort& port, uint8_t cmd)
16✔
70
{
71
    auto it = CmdResultCache.find(cmd);
16✔
72
    if (it != CmdResultCache.end()) {
16✔
73
        return it->second;
12✔
74
    }
75

76
    port.CheckPortOpen();
4✔
77
    port.SkipNoise();
4✔
78

79
    uint8_t buf[RESPONSE_BUF_LEN] = {};
4✔
80
    buf[0] = REQUEST_PREFIX;
4✔
81
    buf[1] = SlaveId;
4✔
82
    buf[2] = cmd;
4✔
83
    buf[3] = dallas_crc8(buf, REQUEST_LEN - 1);
4✔
84
    port.WriteBytes(buf, REQUEST_LEN);
4✔
85
    port.SleepSinceLastInteraction(GetFrameTimeout(port));
4✔
86

87
    int len = port.ReadFrame(buf, RESPONSE_BUF_LEN, GetResponseTimeout(port), GetFrameTimeout(port)).Count;
4✔
88
    if (buf[0] != RESPONSE_PREFIX) {
4✔
89
        throw TSerialDeviceTransientErrorException("invalid response prefix");
×
90
    }
91
    if (buf[1] != SlaveId) {
4✔
92
        throw TSerialDeviceTransientErrorException("invalid response network address");
×
93
    }
94
    if (buf[2] != cmd) {
4✔
95
        throw TSerialDeviceTransientErrorException("invalid response cmd");
×
96
    }
97
    if (buf[len - 1] != dallas_crc8(buf, len - 1)) {
4✔
98
        throw TSerialDeviceTransientErrorException("invalid response crc");
×
99
    }
100

101
    uint8_t* payload = buf + HEADER_SZ;
4✔
102
    std::vector<uint8_t> result = {0};
4✔
103
    result.assign(payload, payload + len - HEADER_SZ);
4✔
104
    return CmdResultCache.insert({cmd, result}).first->second;
8✔
105
}
106

107
TRegisterValue TLLSDevice::ReadRegisterImpl(TPort& port, const TRegisterConfig& reg)
16✔
108
{
109
    uint8_t cmd = GetUint32RegisterAddress(reg.GetAddress());
16✔
110
    auto result = ExecCommand(port, cmd);
32✔
111

112
    int result_buf[8] = {};
16✔
113

114
    for (uint32_t i = 0; i < reg.GetByteWidth(); ++i) {
62✔
115
        result_buf[i] = result[reg.GetDataOffset() + i];
46✔
116
    }
117

118
    return TRegisterValue{
119
        static_cast<uint64_t>((result_buf[3] << 24) | (result_buf[2] << 16) | (result_buf[1] << 8) | result_buf[0])};
32✔
120
}
121

122
std::chrono::milliseconds TLLSDevice::GetFrameTimeout(TPort& port) const
10✔
123
{
124
    auto timeout =
125
        std::chrono::ceil<std::chrono::milliseconds>(port.GetSendTimeBytes(3.5)) + std::chrono::milliseconds(1);
10✔
126
    return std::max(DeviceConfig()->FrameTimeout, timeout);
10✔
127
}
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