can_messenger 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/README.md +7 -1
- data/lib/can_messenger/adapter/socketcan.rb +21 -8
- data/lib/can_messenger/constants.rb +9 -0
- data/lib/can_messenger/messenger.rb +26 -3
- data/lib/can_messenger/version.rb +1 -1
- data/lib/can_messenger.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 51737c6d0bee83617a3cb2c68b634f63a65ae5b1c711a4720d7a5a37a08a0612
|
|
4
|
+
data.tar.gz: aebcbd5b0904849633ce3326f60bf9fd28ca47f8c1982601d25161ec383f3a05
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6d8a36f95f8afcc859d25bd48b5c49b878b7fd1e2e51245ebe142e83dc3e05bc0e2572233da563ec470b0e0b52b3b59ee55c50c7165dc46b7d13302d2df465c
|
|
7
|
+
data.tar.gz: 88bca2b12015fa26df773080f8ad540ec30967b486e6a878afe4319c93b743eb758c6dcef9fe302b2af3ee5776e162129a49236368f31ca1343cc30a117096fc
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [2.2.0] - 2026-03-11
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Make the Ruby Docker workflow install gems against the checked-in lockfile and self-heal stale bundle cache volumes.
|
|
8
|
+
- Promote the docs site stable snapshot to `2.2.0` and add global RubyGems navigation links.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Respect DBC-defined extended CAN IDs when sending messages and when decoding received extended frames.
|
|
13
|
+
- Reject invalid outbound CAN IDs instead of silently coercing them to a different wire value.
|
|
14
|
+
|
|
3
15
|
## [2.1.0] - 2026-02-23
|
|
4
16
|
|
|
5
17
|
### Changed
|
|
@@ -164,7 +176,8 @@
|
|
|
164
176
|
## [0.1.0] - 2024-11-10
|
|
165
177
|
|
|
166
178
|
- Initial release
|
|
167
|
-
[Unreleased]: https://github.com/fk1018/can_messenger/compare/v2.
|
|
179
|
+
[Unreleased]: https://github.com/fk1018/can_messenger/compare/v2.2.0...HEAD
|
|
180
|
+
[2.2.0]: https://github.com/fk1018/can_messenger/compare/v2.1.0...v2.2.0
|
|
168
181
|
[2.1.0]: https://github.com/fk1018/can_messenger/compare/v2.0.0...v2.1.0
|
|
169
182
|
[2.0.0]: https://github.com/fk1018/can_messenger/compare/v1.3.0...v2.0.0
|
|
170
183
|
[1.3.0]: https://github.com/fk1018/can_messenger/compare/v1.2.1...v1.3.0
|
data/README.md
CHANGED
|
@@ -35,6 +35,8 @@ Or install it yourself with:
|
|
|
35
35
|
gem install can_messenger
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
+
RubyGems page: [https://rubygems.org/gems/can_messenger](https://rubygems.org/gems/can_messenger)
|
|
39
|
+
|
|
38
40
|
## Usage
|
|
39
41
|
|
|
40
42
|
### Initializing the Messenger
|
|
@@ -128,6 +130,8 @@ messenger.start_listening(dbc: dbc) do |msg|
|
|
|
128
130
|
end
|
|
129
131
|
```
|
|
130
132
|
|
|
133
|
+
If the DBC message definition uses an extended CAN ID, `send_dbc_message` automatically sends it as an extended frame and `start_listening(dbc: ...)` decodes received extended frames back through the same DBC definition.
|
|
134
|
+
|
|
131
135
|
### Stopping the Listener
|
|
132
136
|
|
|
133
137
|
To stop listening, use:
|
|
@@ -207,7 +211,7 @@ Before using `can_messenger`, please note the following:
|
|
|
207
211
|
|
|
208
212
|
## Development
|
|
209
213
|
|
|
210
|
-
### Docker-first workflow
|
|
214
|
+
### Docker-first workflow
|
|
211
215
|
|
|
212
216
|
Build the development image:
|
|
213
217
|
|
|
@@ -215,6 +219,8 @@ Build the development image:
|
|
|
215
219
|
docker compose build app
|
|
216
220
|
```
|
|
217
221
|
|
|
222
|
+
The Ruby services automatically run `bundle check || bundle install` inside the container, so an existing bundle cache volume stays usable after dependency changes.
|
|
223
|
+
|
|
218
224
|
Run RuboCop:
|
|
219
225
|
|
|
220
226
|
```bash
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "socket"
|
|
4
4
|
require_relative "base"
|
|
5
|
+
require_relative "../constants"
|
|
5
6
|
|
|
6
7
|
module CanMessenger
|
|
7
8
|
module Adapter
|
|
@@ -11,10 +12,11 @@ module CanMessenger
|
|
|
11
12
|
CANFD_FRAME_SIZE = 72
|
|
12
13
|
MIN_FRAME_SIZE = 8
|
|
13
14
|
MAX_FD_DATA = 64
|
|
15
|
+
MAX_STANDARD_ID = 0x7FF
|
|
14
16
|
TIMEOUT = [1, 0].pack("l_2")
|
|
15
17
|
|
|
16
18
|
# Creates and configures a CAN socket bound to the interface.
|
|
17
|
-
def open_socket(can_fd:
|
|
19
|
+
def open_socket(can_fd: nil)
|
|
18
20
|
socket = Socket.open(Socket::PF_CAN, Socket::SOCK_RAW, Socket::CAN_RAW)
|
|
19
21
|
configure_socket(socket, can_fd: can_fd)
|
|
20
22
|
socket
|
|
@@ -25,17 +27,18 @@ module CanMessenger
|
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
# Builds a raw CAN or CAN FD frame for SocketCAN.
|
|
28
|
-
def build_can_frame(id:, data:, extended_id: false, can_fd:
|
|
30
|
+
def build_can_frame(id:, data:, extended_id: false, can_fd: nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity
|
|
29
31
|
if can_fd
|
|
30
32
|
raise ArgumentError, "CAN FD data cannot exceed #{MAX_FD_DATA} bytes" if data.size > MAX_FD_DATA
|
|
31
33
|
elsif data.size > 8
|
|
32
34
|
raise ArgumentError, "CAN data cannot exceed 8 bytes"
|
|
33
35
|
end
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
validate_can_id!(id, extended_id: extended_id)
|
|
38
|
+
|
|
39
|
+
can_id = id
|
|
37
40
|
# Set bit 31 for extended frames
|
|
38
|
-
can_id |=
|
|
41
|
+
can_id |= Constants::EXTENDED_ID_FLAG if extended_id
|
|
39
42
|
|
|
40
43
|
# Pack the ID based on endianness
|
|
41
44
|
id_bytes = endianness == :big ? [can_id].pack("L>") : [can_id].pack("V")
|
|
@@ -52,7 +55,7 @@ module CanMessenger
|
|
|
52
55
|
end
|
|
53
56
|
|
|
54
57
|
# Reads a frame from the socket and parses it into a hash.
|
|
55
|
-
def receive_message(socket:, can_fd:
|
|
58
|
+
def receive_message(socket:, can_fd: nil)
|
|
56
59
|
frame_size = can_fd ? CANFD_FRAME_SIZE : FRAME_SIZE
|
|
57
60
|
frame = socket.recv(frame_size)
|
|
58
61
|
return nil if frame.nil? || frame.size < MIN_FRAME_SIZE
|
|
@@ -72,8 +75,8 @@ module CanMessenger
|
|
|
72
75
|
use_fd = can_fd.nil? ? frame.size >= CANFD_FRAME_SIZE : can_fd
|
|
73
76
|
|
|
74
77
|
raw_id = unpack_frame_id(frame: frame)
|
|
75
|
-
extended = raw_id.anybits?(
|
|
76
|
-
id = raw_id &
|
|
78
|
+
extended = raw_id.anybits?(Constants::EXTENDED_ID_FLAG)
|
|
79
|
+
id = raw_id & Constants::MAX_EXTENDED_ID
|
|
77
80
|
|
|
78
81
|
data_length = if use_fd
|
|
79
82
|
frame[4].ord
|
|
@@ -120,6 +123,16 @@ module CanMessenger
|
|
|
120
123
|
rescue StandardError
|
|
121
124
|
# Ignore close errors so we can report the original failure.
|
|
122
125
|
end
|
|
126
|
+
|
|
127
|
+
def validate_can_id!(id, extended_id:)
|
|
128
|
+
raise ArgumentError, "id must be an Integer" unless id.is_a?(Integer)
|
|
129
|
+
raise ArgumentError, "CAN id cannot be negative" if id.negative?
|
|
130
|
+
|
|
131
|
+
max_id = extended_id ? Constants::MAX_EXTENDED_ID : MAX_STANDARD_ID
|
|
132
|
+
return if id <= max_id
|
|
133
|
+
|
|
134
|
+
raise ArgumentError, "#{extended_id ? "Extended" : "Standard"} CAN id cannot exceed 0x#{max_id.to_s(16).upcase}"
|
|
135
|
+
end
|
|
123
136
|
end
|
|
124
137
|
end
|
|
125
138
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "logger"
|
|
4
4
|
require_relative "adapter/socketcan"
|
|
5
|
+
require_relative "constants"
|
|
5
6
|
|
|
6
7
|
module CanMessenger
|
|
7
8
|
# Messenger
|
|
@@ -64,8 +65,8 @@ module CanMessenger
|
|
|
64
65
|
def send_dbc_message(message_name:, signals:, dbc: @dbc, extended_id: false, can_fd: nil)
|
|
65
66
|
raise ArgumentError, "dbc is required" if dbc.nil?
|
|
66
67
|
|
|
67
|
-
encoded = dbc.encode_can(message_name, signals)
|
|
68
|
-
send_can_message(id: encoded[:id], data: encoded[:data], extended_id: extended_id, can_fd: can_fd)
|
|
68
|
+
encoded = normalized_dbc_message(dbc.encode_can(message_name, signals), extended_id: extended_id)
|
|
69
|
+
send_can_message(id: encoded[:id], data: encoded[:data], extended_id: encoded[:extended_id], can_fd: can_fd)
|
|
69
70
|
rescue ArgumentError
|
|
70
71
|
raise
|
|
71
72
|
rescue StandardError => e
|
|
@@ -134,7 +135,7 @@ module CanMessenger
|
|
|
134
135
|
return if filter && !matches_filter?(message_id: message[:id], filter: filter)
|
|
135
136
|
|
|
136
137
|
if dbc
|
|
137
|
-
decoded = dbc.decode_can(message
|
|
138
|
+
decoded = dbc.decode_can(dbc_decode_id(message), message[:data])
|
|
138
139
|
message[:decoded] = decoded if decoded
|
|
139
140
|
end
|
|
140
141
|
|
|
@@ -156,5 +157,27 @@ module CanMessenger
|
|
|
156
157
|
else true
|
|
157
158
|
end
|
|
158
159
|
end
|
|
160
|
+
|
|
161
|
+
def normalize_can_id(id)
|
|
162
|
+
id & Constants::CAN_ID_MASK
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def dbc_extended_id?(id)
|
|
166
|
+
id.anybits?(Constants::EXTENDED_ID_FLAG)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def normalized_dbc_message(encoded, extended_id:)
|
|
170
|
+
{
|
|
171
|
+
id: normalize_can_id(encoded[:id]),
|
|
172
|
+
data: encoded[:data],
|
|
173
|
+
extended_id: extended_id || dbc_extended_id?(encoded[:id])
|
|
174
|
+
}
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def dbc_decode_id(message)
|
|
178
|
+
return message[:id] unless message[:extended]
|
|
179
|
+
|
|
180
|
+
message[:id] | Constants::EXTENDED_ID_FLAG
|
|
181
|
+
end
|
|
159
182
|
end
|
|
160
183
|
end
|
data/lib/can_messenger.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: can_messenger
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- fk1018
|
|
@@ -23,15 +23,16 @@ files:
|
|
|
23
23
|
- lib/can_messenger.rb
|
|
24
24
|
- lib/can_messenger/adapter/base.rb
|
|
25
25
|
- lib/can_messenger/adapter/socketcan.rb
|
|
26
|
+
- lib/can_messenger/constants.rb
|
|
26
27
|
- lib/can_messenger/dbc.rb
|
|
27
28
|
- lib/can_messenger/messenger.rb
|
|
28
29
|
- lib/can_messenger/version.rb
|
|
29
|
-
homepage: https://github.
|
|
30
|
+
homepage: https://can-messenger.github.io/
|
|
30
31
|
licenses:
|
|
31
32
|
- MIT
|
|
32
33
|
metadata:
|
|
33
34
|
allowed_push_host: https://rubygems.org
|
|
34
|
-
homepage_uri: https://github.
|
|
35
|
+
homepage_uri: https://can-messenger.github.io/
|
|
35
36
|
source_code_uri: https://github.com/fk1018/can_messenger
|
|
36
37
|
changelog_uri: https://github.com/fk1018/can_messenger/blob/main/CHANGELOG.md
|
|
37
38
|
rubygems_mfa_required: 'true'
|