Skip to content

Commit abb4607

Browse files
committed
support for full 64 bit send/receive
1 parent 1be4379 commit abb4607

4 files changed

Lines changed: 82 additions & 53 deletions

File tree

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
},
1414
"scripts": {
1515
"configure": "node-gyp configure",
16-
"build": "node-gyp build"
16+
"build": "node-gyp build",
17+
"test": "NODE_PATH=. nodeunit tests"
1718
},
1819
"devDependencies": {
19-
"node-gyp": ">=1.0.0"
20+
"node-gyp": ">=1.0.0",
21+
"nodeunit": "^0.11.3"
2022
},
2123
"dependencies": {
2224
"nan": "*",

socketcan.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,15 @@ DatabaseService.prototype.onMessage = function (msg) {
290290
continue;
291291

292292
// if this is a mux signal and the muxor isnt in my list...
293-
if (m.muxed && s.muxGroup && s.muxGroup.indexOf(b1mux) == -1) {
293+
if (m.muxed && s.muxGroup && s.muxGroup.indexOf(b1mux[0]) == -1) {
294294
continue;
295295
}
296296

297-
var val = _signals.decode_signal(msg.data, s.bitOffset, s.bitLength,
297+
var ret = _signals.decode_signal(msg.data, s.bitOffset, s.bitLength,
298298
s.endianess == 'little', s.type == 'signed');
299299

300+
var val = ret[0] + (ret[1] << 32)
301+
300302
if (s.slope)
301303
val *= s.slope;
302304

@@ -365,7 +367,7 @@ DatabaseService.prototype.send = function (msg_name) {
365367
}
366368

367369
_signals.encode_signal(canmsg.data, s.bitOffset, s.bitLength,
368-
s.endianess == 'little', s.type == 'signed', val);
370+
s.endianess == 'little', s.type == 'signed', (val & 0xFFFFFFFF), (val >> 32) );
369371
}
370372

371373
this.channel.send(canmsg);

src/signals.cc

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ static u_int64_t _getvalue(u_int8_t * data,
5151
d = be64toh(*((uint64_t *)&data[0]));
5252
}
5353

54-
uint64_t m = (1LLU << length) - 1;
54+
uint64_t m;
55+
if (length == 64) {
56+
m = (uint64_t) UINT64_MAX;
57+
} else {
58+
m = (1LLU << length) - 1;
59+
}
5560
size_t shift;
5661
if (byteOrder == ENDIANESS_INTEL) {
5762
shift = offset;
@@ -130,7 +135,11 @@ NAN_METHOD(DecodeSignal)
130135
retval = Nan::New((u_int32_t)val);
131136
}
132137

133-
info.GetReturnValue().Set(retval);
138+
Local<Array> raw_values = Nan::New<v8::Array>(2);
139+
Nan::Set(raw_values, 0, retval);
140+
Nan::Set(raw_values, 1, Nan::New((u_int32_t) (val >> 32)));
141+
142+
info.GetReturnValue().Set(raw_values);
134143
}
135144

136145
void _setvalue(u_int32_t offset, u_int32_t bitLength, ENDIANESS endianess, u_int8_t data[8], u_int64_t raw_value)
@@ -142,16 +151,22 @@ void _setvalue(u_int32_t offset, u_int32_t bitLength, ENDIANESS endianess, u_int
142151
o = be64toh(*((uint64_t *)&data[0]));
143152
}
144153

145-
uint64_t m = ((1 << bitLength) - 1);
154+
uint64_t m = 0;
155+
if (bitLength == 64) {
156+
m = (uint64_t) UINT64_MAX;
157+
} else {
158+
m = (1LLU << bitLength) - 1;
159+
}
146160
size_t shift;
147161
if (endianess == ENDIANESS_INTEL) {
148162
shift = offset;
149163
} else {
150164
shift = 64 - offset - bitLength;
151165
}
152166

153-
o &= ~(m << shift);
154-
o |= (raw_value & m) << shift;
167+
o &= (uint64_t) ~(m << shift);
168+
o |= (uint64_t) (raw_value & m) << shift;
169+
/* fprintf(stdout, "raw %llu, output %llu, mask %llu shift %llu", raw_value, o, m, shift); */
155170

156171
if (endianess == ENDIANESS_INTEL) {
157172
o = htole64(o);
@@ -184,12 +199,12 @@ void _setvalue(u_int32_t offset, u_int32_t bitLength, ENDIANESS endianess, u_int
184199

185200
// Encode signal according description
186201
// arg[0] - Data array
187-
// arg[1] - startByte one indexed, One indexed, Left(1)->Right(8)
188-
// arg[2] - startBit zero indexed, Right(0)->Left(7)
189-
// arg[3] - bitLength one indexed
190-
// arg[4] - endianess
191-
// arg[5] - sign flag
192-
// arg[6] - value to encode
202+
// arg[1] - bitOffset
203+
// arg[2] - bitLength
204+
// arg[3] - endianess
205+
// arg[4] - sign flag
206+
// arg[5] - first 4 bytes value to encode
207+
// arg[6] - second 4 bytes value to encode
193208
NAN_METHOD(EncodeSignal)
194209
{
195210
u_int32_t offset, bitLength;
@@ -198,7 +213,7 @@ NAN_METHOD(EncodeSignal)
198213
u_int8_t data[8];
199214
u_int64_t raw_value;
200215

201-
CHECK_CONDITION(info.Length() == 6, "Too few arguments");
216+
CHECK_CONDITION(info.Length() >= 6, "Too few arguments");
202217
CHECK_CONDITION(info[0]->IsObject(), "Invalid argument");
203218

204219
Local<Object> jsData = info[0]->ToObject();
@@ -216,20 +231,23 @@ NAN_METHOD(EncodeSignal)
216231
endianess = info[3]->IsTrue() ? ENDIANESS_INTEL : ENDIANESS_MOTOROLA;
217232
sign = info[4]->IsTrue() ? true : false;
218233

219-
if (sign) {
220-
int32_t in_val = info[5]->ToNumber(context).ToLocalChecked()->ToInt32(context).ToLocalChecked()->Value();
234+
/* if (sign) { */
235+
/* int32_t in_val = info[5]->ToNumber(context).ToLocalChecked()->ToInt32(context).ToLocalChecked()->Value(); */
221236

222-
if (in_val < 0) {
223-
in_val *= -1; // Make it a positive number
237+
/* if (in_val < 0) { */
238+
/* in_val *= -1; // Make it a positive number */
224239

225-
raw_value = (~in_val) + 1;
226-
raw_value &= ~(UINT64_MAX << bitLength); // mask valid bits
227-
}
228-
}
240+
/* raw_value = (~in_val) + 1; */
241+
/* raw_value &= ~(UINT64_MAX << bitLength); // mask valid bits */
242+
/* } */
243+
/* } */
229244

230245
raw_value = info[5]->ToNumber(context).ToLocalChecked()->ToUint32(context).ToLocalChecked()->Value();
246+
if (info[6]->IsNumber() || info[6]->IsBoolean()) {
247+
raw_value += ((u_int64_t) info[6]->ToNumber(context).ToLocalChecked()->ToUint32(context).ToLocalChecked()->Value()) << 32;
248+
}
231249

232-
size_t maxBytes = std::min<u_int32_t>(Buffer::Length(jsData), sizeof(data));
250+
size_t maxBytes = std::min<u_int64_t>(Buffer::Length(jsData), sizeof(data));
233251

234252
// Since call may not have supplied enough bytes we have to make a temp copy
235253
memcpy(data, Buffer::Data(jsData), maxBytes);

tests/test-signal_conversion.js

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,43 @@ console.log(data);
2121

2222
signals.encode_signal(data, 12, 12, true, false, 0);
2323
test.deepEqual(data, Buffer.from([0xAB, 0x0E, 0x00, 0, 0, 0, 0, 0]), "Overwriting signal value failed");
24+
25+
signals.encode_signal(data, 0, 64, true, false, 0xEFBEADDE, 0xBEBAFECA);
26+
test.deepEqual(data, Buffer.from([0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE]));
2427
test.done();
2528
}
2629

2730
exports['little_endian_decode'] = function(test) {
2831
data = Buffer.from([0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE]);
2932

30-
test.equals(signals.decode_signal(data, 0, 8, true, false), 0xDE);
31-
test.equals(signals.decode_signal(data, 0, 12, true, false), 0xDDE);
32-
test.equals(signals.decode_signal(data, 0, 16, true, false), 0xADDE);
33-
test.equals(signals.decode_signal(data, 0, 24, true, false), 0xBEADDE);
34-
test.equals(signals.decode_signal(data, 0, 32, true, false), 0xEFBEADDE);
33+
test.deepEqual(signals.decode_signal(data, 0, 8, true, false), [0xDE, 0]);
34+
test.deepEqual(signals.decode_signal(data, 0, 12, true, false), [0xDDE, 0]);
35+
test.deepEqual(signals.decode_signal(data, 0, 16, true, false), [0xADDE, 0]);
36+
test.deepEqual(signals.decode_signal(data, 0, 24, true, false), [0xBEADDE, 0]);
37+
test.deepEqual(signals.decode_signal(data, 0, 32, true, false), [0xEFBEADDE, 0]);
38+
test.deepEqual(signals.decode_signal(data, 0, 64, true, false), [0xEFBEADDE, 0xBEBAFECA]);
3539

36-
test.equals(signals.decode_signal(data, 12, 8, true, false), 0xEA);
37-
test.equals(signals.decode_signal(data, 12, 12, true, false), 0xBEA);
38-
test.equals(signals.decode_signal(data, 12, 20, true, false), 0xEFBEA);
40+
test.deepEqual(signals.decode_signal(data, 12, 8, true, false), [0xEA, 0]);
41+
test.deepEqual(signals.decode_signal(data, 12, 12, true, false), [0xBEA, 0]);
42+
test.deepEqual(signals.decode_signal(data, 12, 20, true, false), [0xEFBEA, 0]);
3943

40-
test.equals(signals.decode_signal(data, 0, 1, true, false), 0);
41-
test.equals(signals.decode_signal(data, 1, 1, true, false), 1);
42-
test.equals(signals.decode_signal(data, 2, 1, true, false), 1);
43-
test.equals(signals.decode_signal(data, 3, 1, true, false), 1);
44+
test.deepEqual(signals.decode_signal(data, 0, 1, true, false), [0, 0]);
45+
test.deepEqual(signals.decode_signal(data, 1, 1, true, false), [1, 0]);
46+
test.deepEqual(signals.decode_signal(data, 2, 1, true, false), [1, 0]);
47+
test.deepEqual(signals.decode_signal(data, 3, 1, true, false), [1, 0]);
4448

4549
test.done();
4650
}
4751

4852
exports['little_endian_signed_decode'] = function(test) {
4953
data = Buffer.from([0xFE, 0xFF, 0x80]);
5054

51-
test.equals(signals.decode_signal(data, 8, 8, true, true), -1);
52-
test.equals(signals.decode_signal(data, 0, 16, true, true), -2);
53-
test.equals(signals.decode_signal(data, 16, 8, true, true), -128);
55+
test.deepEqual(signals.decode_signal(data, 8, 8, true, true), [-1, 0]);
56+
test.deepEqual(signals.decode_signal(data, 0, 16, true, true), [-2, 0]);
57+
test.deepEqual(signals.decode_signal(data, 16, 8, true, true), [-128, 0]);
5458

5559
data = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF]);
56-
test.equals(signals.decode_signal(data, 0, 32, true, true), -1);
60+
test.deepEqual(signals.decode_signal(data, 0, 32, true, true), [-1, 0]);
5761

5862
test.done();
5963
}
@@ -91,22 +95,25 @@ exports['big_endian_encode'] = function(test) {
9195
signals.encode_signal(data, 12, 12, false, false, 0);
9296
test.deepEqual(data, Buffer.from([0xDE, 0xA0, 0x00, 0, 0, 0, 0, 0]), "Overwriting signal value failed");
9397

98+
signals.encode_signal(data, 0, 64, false, false, 0xCAFEBABE, 0xDEADBEEF);
99+
test.deepEqual(data, Buffer.from([0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE]));
100+
94101
test.done();
95102
}
96103

97104
exports['big_endian_decode'] = function(test) {
98105
data = Buffer.from([0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE]);
99106

100-
test.equals(signals.decode_signal(data, 0, 8, false, false), 0xDE);
101-
test.equals(signals.decode_signal(data, 0, 16, false, false), 0xDEAD);
107+
test.deepEqual(signals.decode_signal(data, 0, 8, false, false), [0xDE, 0]);
108+
test.deepEqual(signals.decode_signal(data, 0, 16, false, false), [0xDEAD, 0]);
102109

103-
test.equals(signals.decode_signal(data, 7, 8, false, false), 0x56);
104-
test.equals(signals.decode_signal(data, 15, 16, false, false), 0xDF77);
110+
test.deepEqual(signals.decode_signal(data, 7, 8, false, false), [0x56, 0]);
111+
test.deepEqual(signals.decode_signal(data, 15, 16, false, false), [0xDF77, 0]);
105112

106-
test.equals(signals.decode_signal(data, 0, 1, false, false), 1);
107-
test.equals(signals.decode_signal(data, 1, 1, false, false), 1);
108-
test.equals(signals.decode_signal(data, 2, 1, false, false), 0);
109-
test.equals(signals.decode_signal(data, 3, 1, false, false), 1);
113+
test.deepEqual(signals.decode_signal(data, 0, 1, false, false), [1, 0]);
114+
test.deepEqual(signals.decode_signal(data, 1, 1, false, false), [1, 0]);
115+
test.deepEqual(signals.decode_signal(data, 2, 1, false, false), [0, 0]);
116+
test.deepEqual(signals.decode_signal(data, 3, 1, false, false), [1, 0]);
110117

111118
test.done();
112119
}
@@ -129,9 +136,9 @@ exports['big_endian_signed_encode'] = function(test) {
129136
exports['big_endian_signed_decode'] = function(test) {
130137
data = Buffer.from([0xFF, 0xFE, 0x80 ]);
131138

132-
test.equals(signals.decode_signal(data, 0, 8, false, true), -1);
133-
test.equals(signals.decode_signal(data, 0, 16, false, true), -2);
134-
test.equals(signals.decode_signal(data, 16, 8, false, true), -128);
139+
test.deepEqual(signals.decode_signal(data, 0, 8, false, true), [-1, 0]);
140+
test.deepEqual(signals.decode_signal(data, 0, 16, false, true), [-2, 0]);
141+
test.deepEqual(signals.decode_signal(data, 16, 8, false, true), [-128, 0]);
135142

136143
test.done();
137144
}

0 commit comments

Comments
 (0)