Skip to content

Commit 2234266

Browse files
committed
Able to pass multiple params to FujiBusPacket constructor
1 parent ab86262 commit 2234266

File tree

2 files changed

+112
-48
lines changed

2 files changed

+112
-48
lines changed

lib/bus/rs232/FujiBusPacket.cpp

Lines changed: 80 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@ typedef struct {
88
uint8_t command; /* Command */
99
uint16_t length; /* Total length of packet including header */
1010
uint8_t checksum; /* Checksum of entire packet */
11-
uint8_t fields; /* Describes the fields that follow */
11+
uint8_t descr; /* Describes the fields that follow */
1212
} fujibus_header;
1313

14-
#define FUJI_FIELD_COUNT_MASK 0x07
15-
#define FUJI_FIELD_16_OR_32_MASK 0x40
16-
#define FUJI_FIELD_32_MASK 0x20
14+
#define FUJI_DESCR_COUNT_MASK 0x07
15+
#define FUJI_DESCR_32_MASK 0x02
16+
#define FUJI_DESCR_16_OR_32_MASK 0x04
17+
#define FUJI_DESCR_ADDTL_MASK 0x80
1718

1819
static uint8_t fieldSizeTable[] = {0, 1, 1, 1, 1, 2, 2, 4};
1920
static uint8_t numFieldsTable[] = {0, 1, 2, 3, 4, 1, 2, 1};
2021

22+
2123
std::string FujiBusPacket::decodeSLIP(const std::string &input)
2224
{
2325
unsigned int idx;
@@ -95,11 +97,6 @@ bool FujiBusPacket::parse(const std::string &input)
9597
{
9698
std::string decoded;
9799
fujibus_header *hdr;
98-
uint8_t ck1, ck2;
99-
unsigned int offset;
100-
unsigned int fieldCount;
101-
unsigned int idx, jdx;
102-
uint32_t val, bt;
103100

104101
Debug_printv("Incoming:\n%s\n", util_hexdump(input.data(), input.size()).c_str());
105102

@@ -115,76 +112,116 @@ bool FujiBusPacket::parse(const std::string &input)
115112
return false;
116113
hdr = (fujibus_header *) &decoded[0];
117114
Debug_printv("Header: dev:%02x cmd:%02x len:%d chk:%02x fld:%02x",
118-
hdr->device, hdr->command, hdr->length, hdr->checksum, hdr->fields);
115+
hdr->device, hdr->command, hdr->length, hdr->checksum, hdr->descr);
119116

120117
if (hdr->length != decoded.size())
121118
return false;
122119

123-
// Need to zero out checksum in order to calculate
124-
ck1 = hdr->checksum;
125-
hdr->checksum = 0;
126-
ck2 = calcChecksum(decoded);
127-
if (ck1 != ck2)
128-
return false;
120+
{
121+
uint8_t ck1, ck2;
122+
123+
// Need to zero out checksum in order to calculate
124+
ck1 = hdr->checksum;
125+
hdr->checksum = 0;
126+
ck2 = calcChecksum(decoded);
127+
if (ck1 != ck2)
128+
return false;
129+
}
129130

130131
_device = static_cast<fujiDeviceID_t>(hdr->device);
131132
_command = static_cast<fujiCommandID_t>(hdr->command);
132133

133-
offset = sizeof(*hdr);
134-
fieldCount = numFieldsTable[hdr->fields & FUJI_FIELD_COUNT_MASK];
135-
if (fieldCount)
136134
{
137-
_fieldSize = fieldSizeTable[hdr->fields & FUJI_FIELD_COUNT_MASK];
135+
unsigned val, offset;
136+
std::vector<uint8_t> descr;
137+
138+
offset = sizeof(*hdr) - 1;
139+
do {
140+
val = decoded[offset++];
141+
descr.push_back(val & FUJI_DESCR_COUNT_MASK);
142+
} while (val & FUJI_DESCR_ADDTL_MASK);
138143

139-
for (idx = 0; idx < fieldCount; idx++)
144+
for (const auto &fieldDesc : descr)
140145
{
141-
for (val = jdx = 0; jdx < _fieldSize; jdx++)
146+
unsigned fieldSize, fieldCount;
147+
unsigned idx, jdx;
148+
149+
fieldCount = numFieldsTable[fieldDesc];
150+
if (fieldCount)
142151
{
143-
bt = (uint8_t) decoded[offset + idx * _fieldSize + jdx];
144-
val |= bt << (8 * jdx);
152+
fieldSize = fieldSizeTable[fieldDesc];
153+
154+
for (idx = 0; idx < fieldCount; idx++)
155+
{
156+
uint32_t val, bt;
157+
158+
for (val = jdx = 0; jdx < fieldSize; jdx++)
159+
{
160+
bt = (uint8_t) decoded[offset + idx * fieldSize + jdx];
161+
val |= bt << (8 * jdx);
162+
}
163+
_params.emplace_back(val, fieldSize);
164+
}
165+
166+
offset += idx * fieldSize;
145167
}
146-
_params.push_back(val);
147168
}
148169

149-
offset += idx * _fieldSize;
170+
if (offset < decoded.size())
171+
_data = decoded.substr(offset);
150172
}
151173

152-
if (offset < decoded.size())
153-
_data = decoded.substr(offset);
154-
155174
return true;
156175
}
157176

158177
std::string FujiBusPacket::serialize()
159178
{
160179
fujibus_header hdr, *hptr;
161-
unsigned int idx, jdx;
162-
uint32_t val;
163180

164181
hdr.device = _device;
165182
hdr.command = _command;
166183
hdr.length = sizeof(hdr);
167184
hdr.checksum = 0;
168-
hdr.fields = 0;
185+
hdr.descr = 0;
169186

170187
std::string output(sizeof(hdr), '\0');
171188

172189
if (_params.size())
173190
{
174-
hdr.fields = _params.size() - 1;
175-
if (_fieldSize > 1)
176-
{
177-
hdr.fields |= FUJI_FIELD_16_OR_32_MASK;
178-
if (_fieldSize == 4)
179-
hdr.fields |= FUJI_FIELD_32_MASK;
180-
hdr.fields++;
181-
}
191+
std::vector<uint8_t> descr;
192+
unsigned fieldSize = 0;
193+
unsigned idx, jdx, kdx, val;
194+
PacketParam *param;
195+
182196

183197
for (idx = 0; idx < _params.size(); idx++)
184198
{
185-
for (jdx = 0, val = _params[idx]; jdx < _fieldSize; jdx++, val >>= 8)
186-
output.push_back(val & 0xFF);
199+
for (jdx = idx; jdx < _params.size(); jdx++)
200+
{
201+
param = &_params[jdx];
202+
if (fieldSize && fieldSize != param->size)
203+
break;
204+
fieldSize = param->size;
205+
206+
for (kdx = val = 0; kdx < fieldSize; kdx++, val >>= 8)
207+
output.push_back(val & 0xFF);
208+
}
209+
210+
uint8_t fieldDescr = jdx - idx - 1;
211+
if (fieldSize > 1)
212+
{
213+
fieldDescr |= FUJI_DESCR_16_OR_32_MASK;
214+
if (fieldSize == 4)
215+
fieldDescr |= FUJI_DESCR_32_MASK;
216+
fieldDescr++;
217+
}
218+
219+
descr.push_back(fieldDescr);
187220
}
221+
222+
hdr.descr = descr[0];
223+
descr.erase(descr.begin());
224+
output.insert(0, (char *) descr.data(), descr.size());
188225
}
189226

190227
if (_data)
@@ -195,7 +232,7 @@ std::string FujiBusPacket::serialize()
195232
*hptr = hdr;
196233
hptr->checksum = calcChecksum(output);
197234
Debug_printv("Packet header: dev:%02x cmd:%02x len:%d chk:%02x fld:%02x",
198-
hptr->device, hptr->command, hptr->length, hptr->checksum, hptr->fields);
235+
hptr->device, hptr->command, hptr->length, hptr->checksum, hptr->descr);
199236
return encodeSLIP(output);
200237
}
201238

lib/bus/rs232/FujiBusPacket.h

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,59 @@ enum {
1616
SLIP_ESC_ESC = 0xDD,
1717
};
1818

19+
struct PacketParam {
20+
uint32_t value;
21+
uint8_t size;
22+
23+
template<typename T>
24+
PacketParam(T v) : value(static_cast<uint32_t>(v)), size(sizeof(T)) {
25+
static_assert(std::is_same_v<T, uint8_t> ||
26+
std::is_same_v<T, uint16_t> ||
27+
std::is_same_v<T, uint32_t>,
28+
"Param can only be uint8_t, uint16_t, or uint32_t");
29+
}
30+
PacketParam(uint32_t v, uint8_t s) : value(v), size(s) {
31+
if (s != 1 && s != 2 && s != 4)
32+
throw std::invalid_argument("Param size must be 1, 2, or 4");
33+
}
34+
};
35+
1936
class FujiBusPacket
2037
{
2138
private:
2239
fujiDeviceID_t _device;
2340
fujiCommandID_t _command;
24-
unsigned int _fieldSize;
25-
std::vector<unsigned int> _params;
41+
std::vector<PacketParam> _params;
2642
std::optional<std::string> _data = std::nullopt;
2743

2844
std::string decodeSLIP(const std::string &input);
2945
std::string encodeSLIP(const std::string &input);
3046
bool parse(const std::string &input);
3147
uint8_t calcChecksum(const std::string &buf);
3248

49+
void processArg(uint8_t v) { _params.emplace_back(v); }
50+
void processArg(uint16_t v) { _params.emplace_back(v); }
51+
void processArg(uint32_t v) { _params.emplace_back(v); }
52+
53+
void processArg(const std::string& s) { _data = s; }
54+
3355
public:
3456
FujiBusPacket() = default;
35-
FujiBusPacket(fujiDeviceID_t dev, fujiCommandID_t cmd, const std::string &dbuf) :
36-
_device(dev), _command(cmd), _data(dbuf) {}
57+
58+
template<typename... Args>
59+
FujiBusPacket(fujiDeviceID_t dev, fujiCommandID_t cmd, Args&&... args)
60+
: _device(dev), _command(cmd)
61+
{
62+
(processArg(std::forward<Args>(args)), ...); // fold expression
63+
}
3764

3865
static std::unique_ptr<FujiBusPacket> fromSerialized(const std::string &input);
3966

4067
std::string serialize();
4168

4269
fujiDeviceID_t device() { return _device; }
4370
fujiCommandID_t command() { return _command; }
44-
unsigned int param(unsigned int index) { return _params[index]; }
71+
uint32_t param(unsigned int index) { return _params[index].value; }
4572
unsigned int paramCount() { return _params.size(); }
4673
std::optional<std::string> data() const { return _data; }
4774
};

0 commit comments

Comments
 (0)