Class: RubyZmqFramework::CanBridge
- Inherits:
-
Object
- Object
- RubyZmqFramework::CanBridge
- Includes:
- FrameworkModule
- Defined in:
- lib/ruby_zmq_framework/can_bridge.rb
Overview
Reads raw frames off a real SocketCAN interface (can0, vcan0, ...) and rebroadcasts each one onto the ZeroMQ bus. Pure producer: it has no interest in bus traffic, so handle_message is a no-op that only exists to satisfy FrameworkModule's contract.
Talks to the kernel directly via Ruby's built-in Socket + a couple of raw ioctl/struct calls (see linux/can.h, linux/sockios.h) rather than a third-party gem, since no maintained "socketcan" gem is published on RubyGems.
Classic CAN only: reads assume the 16-byte struct can_frame. That is safe even on an FD-enabled interface — the kernel only delivers 72-byte canfd_frames to sockets that opt in via CAN_RAW_FD_FRAMES, which this one never does — but it means FD traffic is invisible here.
Constant Summary collapse
- CAN_RAW =
1- SIOCGIFINDEX =
0x8933- FRAME_SIZE =
sizeof(struct can_frame): 4(id) + 1(len) + 3(pad) + 8(data)
16- CAN_EFF_FLAG =
0x80000000- CAN_EFF_MASK =
0x1FFFFFFF- CAN_SFF_MASK =
0x7FF
Constants included from FrameworkModule
FrameworkModule::HEARTBEAT_INTERVAL
Class Method Summary collapse
Instance Method Summary collapse
-
#close ⇒ Object
Stops the whole node: heartbeat, reader thread, CAN socket.
- #handle_message(topic, payload) ⇒ Object
-
#initialize(bus, interface:, topic: :can_frame) ⇒ CanBridge
constructor
A new instance of CanBridge.
Methods included from FrameworkModule
#broadcast, included, #node_name, #stop_heartbeat
Constructor Details
#initialize(bus, interface:, topic: :can_frame) ⇒ CanBridge
Returns a new instance of CanBridge.
36 37 38 39 40 41 42 |
# File 'lib/ruby_zmq_framework/can_bridge.rb', line 36 def initialize(bus, interface:, topic: :can_frame) @bus = bus @topic = topic @socket = open_can_socket(interface) @running = true start_reader end |
Class Method Details
.parse_frame(raw) ⇒ Object
28 29 30 31 32 33 34 |
# File 'lib/ruby_zmq_framework/can_bridge.rb', line 28 def self.parse_frame(raw) id_raw, len = raw.unpack('L< C') extended = (id_raw & CAN_EFF_FLAG) != 0 can_id = id_raw & (extended ? CAN_EFF_MASK : CAN_SFF_MASK) { id: can_id, extended: extended, dlc: len, data: raw[8, len].bytes } end |
Instance Method Details
#close ⇒ Object
Stops the whole node: heartbeat, reader thread, CAN socket. Closing the socket from here is what interrupts the reader's blocking read.
48 49 50 51 52 53 54 55 56 |
# File 'lib/ruby_zmq_framework/can_bridge.rb', line 48 def close return unless @running @running = false stop_heartbeat @socket.close unless @socket.closed? @reader.join(2) nil end |
#handle_message(topic, payload) ⇒ Object
44 |
# File 'lib/ruby_zmq_framework/can_bridge.rb', line 44 def (topic, payload); end |