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

wirenboard / wb-mqtt-serial / 1

08 Jul 2025 01:20PM UTC coverage: 73.854% (+1.0%) from 72.836%
1

Pull #963

github

39d9bc
KraPete
Bump version
Pull Request #963: Bump version

6444 of 9057 branches covered (71.15%)

12341 of 16710 relevant lines covered (73.85%)

305.53 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,
8✔
11
                                          const IRegisterAddress& deviceBaseAddress,
12
                                          uint32_t stride,
13
                                          uint32_t registerByteWidth) const override
14
        {
15
            auto addr = LoadRegisterBitsAddress(regCfg, SerialConfig::ADDRESS_PROPERTY_NAME);
8✔
16
            TRegisterDesc res;
8✔
17
            res.DataOffset = (addr.Address & 0xFF);
8✔
18
            res.Address = std::make_shared<TUint32RegisterAddress>(addr.Address >> 8);
8✔
19
            return res;
16✔
20
        }
21
    };
22
}
23

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

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

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

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

57
    TSerialDevice::InvalidateReadCache();
2✔
58
}
2✔
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)
8✔
70
{
71
    auto it = CmdResultCache.find(cmd);
8✔
72
    if (it != CmdResultCache.end()) {
8✔
73
        return it->second;
6✔
74
    }
75

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

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

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

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

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

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

114
    for (uint32_t i = 0; i < reg.GetByteWidth(); ++i) {
31✔
115
        result_buf[i] = result[reg.GetDataOffset() + i];
23✔
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])};
16✔
120
}
121

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