Skip to content

Commit f34d1a6

Browse files
sebi2k1Ubuntu
authored andcommitted
Support non blocking sending
1 parent dd635d3 commit f34d1a6

4 files changed

Lines changed: 58 additions & 8 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"email": "sebastian@sebastianhaas.info"
66
},
77
"description": "A SocketCAN abstraction layer for NodeJS.",
8-
"version": "2.6.0",
8+
"version": "2.7.0",
99
"license": "MIT",
1010
"repository": {
1111
"type": "git",

socketcan.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,32 @@ var buffer = require('buffer');
2828
/**
2929
* @method createRawChannel
3030
* @param channel {string} Channel name (e.g. vcan0)
31+
* @param timestamps {bool} Whether or not timestamps shall be generated when reading a message
32+
* @param protocol {integer} optionally provide another default protocol value (default is CAN_RAW)
3133
* @return {RawChannel} a new channel object or exception
3234
* @for exports
3335
*/
3436
exports.createRawChannel = function(channel, timestamps, protocol)
3537
{
36-
return new can.RawChannel(channel, timestamps, protocol);
38+
return new can.RawChannel(channel, timestamps, protocol, false);
39+
}
40+
41+
/**
42+
* @method createRawChannel
43+
* @param channel {string} Channel name (e.g. vcan0)
44+
* @param options {dict} list of options (timestamps, protocol, non_block_send)
45+
* @return {RawChannel} a new channel object or exception
46+
* @for exports
47+
*/
48+
exports.createRawChannelWithOptions = function(channel, options)
49+
{
50+
if (options === undefined) options = {}
51+
52+
if (options.timestamps === undefined) options.timestamps = false;
53+
if (options.protocol === undefined) options.protocol = 1; /* CAN RAW */
54+
if (options.non_block_send === undefined) options.non_block_send = false;
55+
56+
return new can.RawChannel(channel, options.timestamps, options.protocol, options.non_block_send);
3757
}
3858

3959
//-----------------------------------------------------------------------------

src/rawchannel.cc

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,13 @@ class RawChannel : public Nan::ObjectWrap
103103
}
104104

105105
private:
106-
explicit RawChannel(const char *name, bool timestamps = false, int protocol = CAN_RAW) : m_Thread(0), m_Name(name), m_SocketFd(-1)
106+
explicit RawChannel(const char *name, bool timestamps, int protocol, bool non_block_send)
107+
: m_Thread(0), m_Name(name), m_SocketFd(-1)
107108
{
108109
m_SocketFd = socket(PF_CAN, SOCK_RAW, protocol);
109110
m_ThreadStopRequested = false;
110111
m_TimestampsSupported = timestamps;
112+
m_NonBlockingSend = non_block_send;
111113

112114
if (m_SocketFd > 0)
113115
{
@@ -170,8 +172,9 @@ class RawChannel : public Nan::ObjectWrap
170172
*/
171173
static NAN_METHOD(New)
172174
{
173-
bool timestamps = false;
174-
int protocol = CAN_RAW;
175+
bool timestamps = false;
176+
int protocol = CAN_RAW;
177+
bool non_block_send = false;
175178

176179
CHECK_CONDITION(info.IsConstructCall(), "Must be called with new");
177180
CHECK_CONDITION(info.Length() >= 1, "Too few arguments");
@@ -191,7 +194,13 @@ class RawChannel : public Nan::ObjectWrap
191194
protocol = info[2]->IntegerValue(Nan::GetCurrentContext()).FromJust();
192195
}
193196

194-
RawChannel* hw = new RawChannel(*ascii, timestamps, protocol);
197+
if (info.Length() >= 4)
198+
{
199+
if (info[3]->IsBoolean())
200+
non_block_send = info[3]->IsTrue();
201+
}
202+
203+
RawChannel* hw = new RawChannel(*ascii, timestamps, protocol, non_block_send);
195204
hw->Wrap(info.This());
196205

197206
CHECK_CONDITION(hw->IsValid(), "Error while creating channel");
@@ -326,6 +335,11 @@ class RawChannel : public Nan::ObjectWrap
326335
}
327336
}
328337

338+
int flags = 0;
339+
340+
if (hw->m_NonBlockingSend)
341+
flags = MSG_DONTWAIT;
342+
329343
int i = send(hw->m_SocketFd, &frame, sizeof(struct can_frame), 0);
330344

331345
info.GetReturnValue().Set(i);
@@ -438,6 +452,7 @@ class RawChannel : public Nan::ObjectWrap
438452

439453
bool m_ThreadStopRequested;
440454
bool m_TimestampsSupported;
455+
bool m_NonBlockingSend;
441456

442457
static void * c_thread_entry(void *_this) { assert(_this); reinterpret_cast<RawChannel *>(_this)->ThreadEntry(); return NULL; }
443458

tests/test-raw_basic.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ exports['channel_creation'] = function(test) {
1212
test.done();
1313
}
1414

15+
exports['channel_creation_w_options'] = function(test) {
16+
var channel = can.createRawChannel("vcan0", { timestamps: true, non_block_send: true });
17+
18+
test.throws(function() { channel.stop(); });
19+
20+
var channel = can.createRawChannel("vcan0");
21+
22+
test.throws(function() { channel.stop(); });
23+
24+
test.done();
25+
}
26+
1527
exports['channel_error'] = function(test) {
1628
var channel = can.createRawChannel("vcan1");
1729

@@ -24,8 +36,8 @@ exports['channel_error'] = function(test) {
2436

2537
// Send 100 messages from c2 to c1
2638
exports['rxtx_test'] = function(test) {
27-
var c1 = can.createRawChannel("vcan0");
28-
var c2 = can.createRawChannel("vcan0");
39+
var c1 = can.createRawChannelWithOptions("vcan0", { timestamps: true });
40+
var c2 = can.createRawChannelWithOptions("vcan0", { non_block_send: true });
2941

3042
c1.start();
3143
c2.start();
@@ -36,14 +48,17 @@ exports['rxtx_test'] = function(test) {
3648

3749
c1.addListener("onMessage", function(msg) {
3850
test.equal(msg.data[0], rx_count);
51+
test.ok(msg.ts_sec !== undefined)
3952
rx_count++;
4053
});
4154

55+
// Generate 100 messages
4256
for (var i = 0; i < 100; i++) {
4357
canmsg.data[0] = i;
4458
c2.send(canmsg);
4559
}
4660

61+
// Check after 100ms if all 100 messages have been received
4762
setTimeout(function() {
4863
test.equals(rx_count, i);
4964
c1.stop();

0 commit comments

Comments
 (0)