sm2can 0.1.0__tar.gz

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.
sm2can-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aldo Guzman (aldoguzman97)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
sm2can-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,286 @@
1
+ Metadata-Version: 2.4
2
+ Name: sm2can
3
+ Version: 0.1.0
4
+ Summary: Open-source macOS/Linux driver for SM2 Pro (Scanmatik 2 Pro) J2534 CAN adapter
5
+ Author-email: Aldo Guzman <aldoguzman97@users.noreply.github.com>
6
+ Maintainer-email: Aldo Guzman <aldoguzman97@users.noreply.github.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/aldoguzman97/sm2can
9
+ Project-URL: Repository, https://github.com/aldoguzman97/sm2can
10
+ Project-URL: Issues, https://github.com/aldoguzman97/sm2can/issues
11
+ Project-URL: Documentation, https://github.com/aldoguzman97/sm2can/wiki
12
+ Keywords: CAN,OBD,automotive,J2534,Scanmatik,SM2,python-can,reverse-engineering,macOS,Linux,CAN-bus,vehicle-diagnostics
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
27
+ Classifier: Topic :: System :: Hardware :: Hardware Drivers
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.8
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: pyusb>=1.2.0
33
+ Requires-Dist: python-can>=4.0
34
+ Provides-Extra: bluetooth
35
+ Requires-Dist: bleak>=0.21.0; extra == "bluetooth"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0; extra == "dev"
38
+ Requires-Dist: pytest-cov; extra == "dev"
39
+ Requires-Dist: ruff; extra == "dev"
40
+ Requires-Dist: mypy; extra == "dev"
41
+ Provides-Extra: capture
42
+ Requires-Dist: pyshark; extra == "capture"
43
+ Provides-Extra: all
44
+ Requires-Dist: sm2can[bluetooth,capture,dev]; extra == "all"
45
+ Dynamic: license-file
46
+
47
+ # SM2CAN β€” Open-Source Driver for SM2 Pro CAN Adapters on macOS & Linux
48
+
49
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
50
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org)
51
+ [![PyPI](https://img.shields.io/pypi/v/sm2can)](https://pypi.org/project/sm2can/)
52
+ [![CI](https://github.com/aldoguzman97/sm2can/actions/workflows/ci.yml/badge.svg)](https://github.com/aldoguzman97/sm2can/actions)
53
+
54
+ **SM2CAN** is a userspace USB driver that enables SM2 Pro (and compatible)
55
+ J2534 CAN adapters to work on **macOS** and **Linux** β€” platforms the
56
+ manufacturer's driver does not support. It integrates with
57
+ [python-can](https://python-can.readthedocs.io/), making it a drop-in
58
+ replacement for any CAN interface.
59
+
60
+ > **Disclaimer:** This project is **not affiliated with, endorsed by, or
61
+ > sponsored by** the manufacturer of the SM2 Pro hardware. All trademarks
62
+ > are property of their respective owners. This driver was developed using
63
+ > [clean room reverse engineering](LEGAL.md) of a legitimately purchased
64
+ > device for the sole purpose of interoperability. See [LEGAL.md](LEGAL.md)
65
+ > for full details.
66
+
67
+ ## Project Status
68
+
69
+ | Component | Status | Notes |
70
+ |-----------|--------|-------|
71
+ | USB transport (libusb) | βœ… Complete | Tested on macOS 13+ and Ubuntu 22.04+ |
72
+ | USB hardware detection | βœ… Complete | Auto-detects VID 0x20A2 PID 0x0001 |
73
+ | Protocol decoder | πŸ”§ Needs capture | Community USB captures welcome |
74
+ | Protocol auto-detection | βœ… Scaffolded | Tries multiple frame format variants |
75
+ | python-can `Bus` interface | βœ… Complete | `interface='sm2'` via entry point |
76
+ | CLI tools | βœ… Complete | `sm2can probe`, `monitor`, `send` |
77
+ | USB capture analysis | βœ… Complete | Parses pcap/pcapng from USBPcap |
78
+ | Homebrew formula | βœ… Ready | `brew tap aldoguzman97/sm2can` |
79
+ | Linux udev rules | βœ… Included | Non-root USB access |
80
+ | Bluetooth SPP transport | πŸ“‹ Planned | Architecture ready for future support |
81
+
82
+ ### How You Can Help
83
+
84
+ **One USB capture from a Windows session completes this driver.**
85
+ If you can run Wireshark + USBPcap on Windows while connected to a vehicle:
86
+
87
+ ```bash
88
+ pip install sm2can
89
+ sm2can-capture guide # Step-by-step capture instructions
90
+ sm2can-capture decode mycapture.pcapng # Auto-analyzes the protocol
91
+ ```
92
+
93
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the 5-minute capture guide.
94
+
95
+ ## Installation
96
+
97
+ ### Homebrew (macOS)
98
+
99
+ ```bash
100
+ brew tap aldoguzman97/sm2can
101
+ brew install sm2can
102
+ ```
103
+
104
+ ### pip (macOS & Linux)
105
+
106
+ ```bash
107
+ pip install sm2can
108
+ ```
109
+
110
+ ### From source
111
+
112
+ ```bash
113
+ git clone https://github.com/aldoguzman97/sm2can.git
114
+ cd sm2can
115
+ pip install -e ".[dev]"
116
+ ```
117
+
118
+ ### Prerequisites
119
+
120
+ | Platform | Command |
121
+ |----------|---------|
122
+ | **macOS** | `brew install libusb` |
123
+ | **Debian/Ubuntu** | `sudo apt install libusb-1.0-0-dev` |
124
+ | **Fedora/RHEL** | `sudo dnf install libusb1-devel` |
125
+ | **Arch** | `sudo pacman -S libusb` |
126
+
127
+ Python 3.8 or later required.
128
+
129
+ ### Linux: USB Permissions
130
+
131
+ To use without `sudo`:
132
+
133
+ ```bash
134
+ sudo cp scripts/99-sm2pro.rules /etc/udev/rules.d/
135
+ sudo udevadm control --reload-rules && sudo udevadm trigger
136
+ # Log out and back in (user must be in 'plugdev' group)
137
+ ```
138
+
139
+ ## Quick Start
140
+
141
+ ### Detect hardware
142
+
143
+ ```bash
144
+ sm2can probe
145
+ ```
146
+
147
+ ### Monitor CAN bus
148
+
149
+ ```bash
150
+ sm2can monitor --bitrate 500000
151
+ ```
152
+
153
+ ### Send a CAN frame
154
+
155
+ ```bash
156
+ sm2can send 0x7DF 0201000000000000 --bitrate 500000
157
+ ```
158
+
159
+ ### Use with python-can
160
+
161
+ ```python
162
+ import can
163
+
164
+ # SM2CAN registers as a python-can interface plugin automatically
165
+ bus = can.Bus(interface='sm2', channel=0, bitrate=500000)
166
+
167
+ # Receive
168
+ msg = bus.recv(timeout=1.0)
169
+ if msg:
170
+ print(f"0x{msg.arbitration_id:03X}: {msg.data.hex()}")
171
+
172
+ # Send
173
+ bus.send(can.Message(
174
+ arbitration_id=0x7DF,
175
+ data=bytes([0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
176
+ ))
177
+
178
+ bus.shutdown()
179
+ ```
180
+
181
+ ### Direct API
182
+
183
+ ```python
184
+ from sm2can import SM2Device
185
+
186
+ with SM2Device() as dev:
187
+ dev.open(bitrate=500000)
188
+ dev.send(0x7DF, bytes([0x02, 0x01, 0x00, 0, 0, 0, 0, 0]))
189
+ frame = dev.recv(timeout=1.0)
190
+ if frame:
191
+ print(f"0x{frame.arbitration_id:03X}: {frame.data.hex()}")
192
+ ```
193
+
194
+ ## Supported Hardware
195
+
196
+ | Device | USB ID | Interface | Status |
197
+ |--------|--------|-----------|--------|
198
+ | SM2 Pro (original) | `20A2:0001` | USB + BT | Primary target |
199
+ | SM2 Pro (clones) | `20A2:0001` | USB | Should work (same USB protocol) |
200
+
201
+ ### Power Requirements
202
+
203
+ > **Important:** The SM2 Pro requires 12V on the OBD-II connector to boot
204
+ > its application firmware. On USB 5V power alone, the microcontroller
205
+ > enumerates on the bus but the CAN transceiver and command handler do not
206
+ > start. Connect to a vehicle with ignition ON, or supply 12V externally.
207
+
208
+ OBD-II bench power pinout:
209
+
210
+ | Pin | Function |
211
+ |-----|----------|
212
+ | 16 | +12V (battery) |
213
+ | 4 | Chassis ground |
214
+ | 5 | Signal ground |
215
+
216
+ A 12V / 1A wall adapter wired to these pins is sufficient.
217
+
218
+ ## Architecture
219
+
220
+ ```
221
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
222
+ β”‚ Your Application / python-can / opendbc / UDS client β”‚
223
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
224
+ β”‚ SM2Bus (can_interface.py) β”‚
225
+ β”‚ python-can BusABC β€” registered via entry point β”‚
226
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
227
+ β”‚ SM2Device (device.py) β”‚
228
+ β”‚ High-level: open / close / send / recv / background RX β”‚
229
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
230
+ β”‚ ProtocolCodec (protocol.py) β”‚
231
+ β”‚ Encode / decode binary protocol frames β”‚
232
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
233
+ β”‚ USBTransport β”‚ BluetoothTransport (planned) β”‚
234
+ β”‚ (usb_transport.py)β”‚ (bluetooth_transport.py) β”‚
235
+ β”‚ Bulk EP via libusbβ”‚ SPP via platform-native APIs β”‚
236
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
237
+ β”‚ Hardware: EP 0x02 OUT / EP 0x81 IN / 64-byte packets β”‚
238
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
239
+ ```
240
+
241
+ **Why userspace instead of a kernel driver?** A kernel extension (kext on
242
+ macOS, .ko on Linux) requires code signing, kernel version compatibility,
243
+ and administrator installation. A userspace driver via libusb installs with
244
+ pip, works everywhere, and cannot crash your kernel. The SM2 Pro's simple
245
+ 2-endpoint bulk design is ideal for this approach.
246
+
247
+ ## Roadmap
248
+
249
+ - [x] USB transport layer
250
+ - [x] Protocol codec with auto-detection framework
251
+ - [x] python-can `Bus` interface
252
+ - [x] CLI tools (`probe`, `monitor`, `send`)
253
+ - [x] USB capture decoder for protocol analysis
254
+ - [x] Homebrew formula
255
+ - [x] Linux udev rules
256
+ - [ ] Complete protocol specification (pending community captures)
257
+ - [ ] Bluetooth SPP transport
258
+ - [ ] CAN-FD support (if hardware supports it)
259
+ - [ ] ISO-TP (ISO 15765) pass-through
260
+ - [ ] SAE J2534 API shim layer
261
+
262
+ ## Contributing
263
+
264
+ See [CONTRIBUTING.md](CONTRIBUTING.md). The most impactful contribution is
265
+ a USB capture from Windows β€” one file completes the protocol specification
266
+ for everyone.
267
+
268
+ ## Legal
269
+
270
+ This project uses clean room reverse engineering to achieve interoperability
271
+ with legitimately purchased hardware. No proprietary code, firmware, or
272
+ documentation was used. See [LEGAL.md](LEGAL.md) for full details including
273
+ applicable case law.
274
+
275
+ ## License
276
+
277
+ MIT β€” see [LICENSE](LICENSE).
278
+
279
+ Copyright (c) 2026 Aldo Guzman ([@aldoguzman97](https://github.com/aldoguzman97))
280
+
281
+ ## Acknowledgments
282
+
283
+ - [pyusb](https://github.com/pyusb/pyusb) β€” Cross-platform USB access
284
+ - [python-can](https://github.com/hardbyte/python-can) β€” CAN bus abstraction
285
+ - [libusb](https://libusb.info/) β€” Userspace USB I/O
286
+ - Everyone who contributes USB captures
sm2can-0.1.0/README.md ADDED
@@ -0,0 +1,240 @@
1
+ # SM2CAN β€” Open-Source Driver for SM2 Pro CAN Adapters on macOS & Linux
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
4
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org)
5
+ [![PyPI](https://img.shields.io/pypi/v/sm2can)](https://pypi.org/project/sm2can/)
6
+ [![CI](https://github.com/aldoguzman97/sm2can/actions/workflows/ci.yml/badge.svg)](https://github.com/aldoguzman97/sm2can/actions)
7
+
8
+ **SM2CAN** is a userspace USB driver that enables SM2 Pro (and compatible)
9
+ J2534 CAN adapters to work on **macOS** and **Linux** β€” platforms the
10
+ manufacturer's driver does not support. It integrates with
11
+ [python-can](https://python-can.readthedocs.io/), making it a drop-in
12
+ replacement for any CAN interface.
13
+
14
+ > **Disclaimer:** This project is **not affiliated with, endorsed by, or
15
+ > sponsored by** the manufacturer of the SM2 Pro hardware. All trademarks
16
+ > are property of their respective owners. This driver was developed using
17
+ > [clean room reverse engineering](LEGAL.md) of a legitimately purchased
18
+ > device for the sole purpose of interoperability. See [LEGAL.md](LEGAL.md)
19
+ > for full details.
20
+
21
+ ## Project Status
22
+
23
+ | Component | Status | Notes |
24
+ |-----------|--------|-------|
25
+ | USB transport (libusb) | βœ… Complete | Tested on macOS 13+ and Ubuntu 22.04+ |
26
+ | USB hardware detection | βœ… Complete | Auto-detects VID 0x20A2 PID 0x0001 |
27
+ | Protocol decoder | πŸ”§ Needs capture | Community USB captures welcome |
28
+ | Protocol auto-detection | βœ… Scaffolded | Tries multiple frame format variants |
29
+ | python-can `Bus` interface | βœ… Complete | `interface='sm2'` via entry point |
30
+ | CLI tools | βœ… Complete | `sm2can probe`, `monitor`, `send` |
31
+ | USB capture analysis | βœ… Complete | Parses pcap/pcapng from USBPcap |
32
+ | Homebrew formula | βœ… Ready | `brew tap aldoguzman97/sm2can` |
33
+ | Linux udev rules | βœ… Included | Non-root USB access |
34
+ | Bluetooth SPP transport | πŸ“‹ Planned | Architecture ready for future support |
35
+
36
+ ### How You Can Help
37
+
38
+ **One USB capture from a Windows session completes this driver.**
39
+ If you can run Wireshark + USBPcap on Windows while connected to a vehicle:
40
+
41
+ ```bash
42
+ pip install sm2can
43
+ sm2can-capture guide # Step-by-step capture instructions
44
+ sm2can-capture decode mycapture.pcapng # Auto-analyzes the protocol
45
+ ```
46
+
47
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the 5-minute capture guide.
48
+
49
+ ## Installation
50
+
51
+ ### Homebrew (macOS)
52
+
53
+ ```bash
54
+ brew tap aldoguzman97/sm2can
55
+ brew install sm2can
56
+ ```
57
+
58
+ ### pip (macOS & Linux)
59
+
60
+ ```bash
61
+ pip install sm2can
62
+ ```
63
+
64
+ ### From source
65
+
66
+ ```bash
67
+ git clone https://github.com/aldoguzman97/sm2can.git
68
+ cd sm2can
69
+ pip install -e ".[dev]"
70
+ ```
71
+
72
+ ### Prerequisites
73
+
74
+ | Platform | Command |
75
+ |----------|---------|
76
+ | **macOS** | `brew install libusb` |
77
+ | **Debian/Ubuntu** | `sudo apt install libusb-1.0-0-dev` |
78
+ | **Fedora/RHEL** | `sudo dnf install libusb1-devel` |
79
+ | **Arch** | `sudo pacman -S libusb` |
80
+
81
+ Python 3.8 or later required.
82
+
83
+ ### Linux: USB Permissions
84
+
85
+ To use without `sudo`:
86
+
87
+ ```bash
88
+ sudo cp scripts/99-sm2pro.rules /etc/udev/rules.d/
89
+ sudo udevadm control --reload-rules && sudo udevadm trigger
90
+ # Log out and back in (user must be in 'plugdev' group)
91
+ ```
92
+
93
+ ## Quick Start
94
+
95
+ ### Detect hardware
96
+
97
+ ```bash
98
+ sm2can probe
99
+ ```
100
+
101
+ ### Monitor CAN bus
102
+
103
+ ```bash
104
+ sm2can monitor --bitrate 500000
105
+ ```
106
+
107
+ ### Send a CAN frame
108
+
109
+ ```bash
110
+ sm2can send 0x7DF 0201000000000000 --bitrate 500000
111
+ ```
112
+
113
+ ### Use with python-can
114
+
115
+ ```python
116
+ import can
117
+
118
+ # SM2CAN registers as a python-can interface plugin automatically
119
+ bus = can.Bus(interface='sm2', channel=0, bitrate=500000)
120
+
121
+ # Receive
122
+ msg = bus.recv(timeout=1.0)
123
+ if msg:
124
+ print(f"0x{msg.arbitration_id:03X}: {msg.data.hex()}")
125
+
126
+ # Send
127
+ bus.send(can.Message(
128
+ arbitration_id=0x7DF,
129
+ data=bytes([0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
130
+ ))
131
+
132
+ bus.shutdown()
133
+ ```
134
+
135
+ ### Direct API
136
+
137
+ ```python
138
+ from sm2can import SM2Device
139
+
140
+ with SM2Device() as dev:
141
+ dev.open(bitrate=500000)
142
+ dev.send(0x7DF, bytes([0x02, 0x01, 0x00, 0, 0, 0, 0, 0]))
143
+ frame = dev.recv(timeout=1.0)
144
+ if frame:
145
+ print(f"0x{frame.arbitration_id:03X}: {frame.data.hex()}")
146
+ ```
147
+
148
+ ## Supported Hardware
149
+
150
+ | Device | USB ID | Interface | Status |
151
+ |--------|--------|-----------|--------|
152
+ | SM2 Pro (original) | `20A2:0001` | USB + BT | Primary target |
153
+ | SM2 Pro (clones) | `20A2:0001` | USB | Should work (same USB protocol) |
154
+
155
+ ### Power Requirements
156
+
157
+ > **Important:** The SM2 Pro requires 12V on the OBD-II connector to boot
158
+ > its application firmware. On USB 5V power alone, the microcontroller
159
+ > enumerates on the bus but the CAN transceiver and command handler do not
160
+ > start. Connect to a vehicle with ignition ON, or supply 12V externally.
161
+
162
+ OBD-II bench power pinout:
163
+
164
+ | Pin | Function |
165
+ |-----|----------|
166
+ | 16 | +12V (battery) |
167
+ | 4 | Chassis ground |
168
+ | 5 | Signal ground |
169
+
170
+ A 12V / 1A wall adapter wired to these pins is sufficient.
171
+
172
+ ## Architecture
173
+
174
+ ```
175
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
176
+ β”‚ Your Application / python-can / opendbc / UDS client β”‚
177
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
178
+ β”‚ SM2Bus (can_interface.py) β”‚
179
+ β”‚ python-can BusABC β€” registered via entry point β”‚
180
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
181
+ β”‚ SM2Device (device.py) β”‚
182
+ β”‚ High-level: open / close / send / recv / background RX β”‚
183
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
184
+ β”‚ ProtocolCodec (protocol.py) β”‚
185
+ β”‚ Encode / decode binary protocol frames β”‚
186
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
187
+ β”‚ USBTransport β”‚ BluetoothTransport (planned) β”‚
188
+ β”‚ (usb_transport.py)β”‚ (bluetooth_transport.py) β”‚
189
+ β”‚ Bulk EP via libusbβ”‚ SPP via platform-native APIs β”‚
190
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
191
+ β”‚ Hardware: EP 0x02 OUT / EP 0x81 IN / 64-byte packets β”‚
192
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
193
+ ```
194
+
195
+ **Why userspace instead of a kernel driver?** A kernel extension (kext on
196
+ macOS, .ko on Linux) requires code signing, kernel version compatibility,
197
+ and administrator installation. A userspace driver via libusb installs with
198
+ pip, works everywhere, and cannot crash your kernel. The SM2 Pro's simple
199
+ 2-endpoint bulk design is ideal for this approach.
200
+
201
+ ## Roadmap
202
+
203
+ - [x] USB transport layer
204
+ - [x] Protocol codec with auto-detection framework
205
+ - [x] python-can `Bus` interface
206
+ - [x] CLI tools (`probe`, `monitor`, `send`)
207
+ - [x] USB capture decoder for protocol analysis
208
+ - [x] Homebrew formula
209
+ - [x] Linux udev rules
210
+ - [ ] Complete protocol specification (pending community captures)
211
+ - [ ] Bluetooth SPP transport
212
+ - [ ] CAN-FD support (if hardware supports it)
213
+ - [ ] ISO-TP (ISO 15765) pass-through
214
+ - [ ] SAE J2534 API shim layer
215
+
216
+ ## Contributing
217
+
218
+ See [CONTRIBUTING.md](CONTRIBUTING.md). The most impactful contribution is
219
+ a USB capture from Windows β€” one file completes the protocol specification
220
+ for everyone.
221
+
222
+ ## Legal
223
+
224
+ This project uses clean room reverse engineering to achieve interoperability
225
+ with legitimately purchased hardware. No proprietary code, firmware, or
226
+ documentation was used. See [LEGAL.md](LEGAL.md) for full details including
227
+ applicable case law.
228
+
229
+ ## License
230
+
231
+ MIT β€” see [LICENSE](LICENSE).
232
+
233
+ Copyright (c) 2026 Aldo Guzman ([@aldoguzman97](https://github.com/aldoguzman97))
234
+
235
+ ## Acknowledgments
236
+
237
+ - [pyusb](https://github.com/pyusb/pyusb) β€” Cross-platform USB access
238
+ - [python-can](https://github.com/hardbyte/python-can) β€” CAN bus abstraction
239
+ - [libusb](https://libusb.info/) β€” Userspace USB I/O
240
+ - Everyone who contributes USB captures
@@ -0,0 +1,86 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sm2can"
7
+ version = "0.1.0"
8
+ description = "Open-source macOS/Linux driver for SM2 Pro (Scanmatik 2 Pro) J2534 CAN adapter"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.8"
12
+ authors = [
13
+ {name = "Aldo Guzman", email = "aldoguzman97@users.noreply.github.com"},
14
+ ]
15
+ maintainers = [
16
+ {name = "Aldo Guzman", email = "aldoguzman97@users.noreply.github.com"},
17
+ ]
18
+ keywords = ["CAN", "OBD", "automotive", "J2534", "Scanmatik", "SM2", "python-can",
19
+ "reverse-engineering", "macOS", "Linux", "CAN-bus", "vehicle-diagnostics"]
20
+ classifiers = [
21
+ "Development Status :: 3 - Alpha",
22
+ "Intended Audience :: Developers",
23
+ "Intended Audience :: Science/Research",
24
+ "License :: OSI Approved :: MIT License",
25
+ "Operating System :: MacOS",
26
+ "Operating System :: POSIX :: Linux",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.8",
29
+ "Programming Language :: Python :: 3.9",
30
+ "Programming Language :: Python :: 3.10",
31
+ "Programming Language :: Python :: 3.11",
32
+ "Programming Language :: Python :: 3.12",
33
+ "Programming Language :: Python :: 3.13",
34
+ "Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator",
35
+ "Topic :: System :: Hardware :: Hardware Drivers",
36
+ "Typing :: Typed",
37
+ ]
38
+ dependencies = [
39
+ "pyusb>=1.2.0",
40
+ "python-can>=4.0",
41
+ ]
42
+
43
+ [project.optional-dependencies]
44
+ bluetooth = [
45
+ "bleak>=0.21.0", # Cross-platform Bluetooth LE (future SPP bridge)
46
+ ]
47
+ dev = [
48
+ "pytest>=7.0",
49
+ "pytest-cov",
50
+ "ruff",
51
+ "mypy",
52
+ ]
53
+ capture = [
54
+ "pyshark", # For analyzing Windows USB captures (optional)
55
+ ]
56
+ all = ["sm2can[bluetooth,dev,capture]"]
57
+
58
+ [project.urls]
59
+ Homepage = "https://github.com/aldoguzman97/sm2can"
60
+ Repository = "https://github.com/aldoguzman97/sm2can"
61
+ Issues = "https://github.com/aldoguzman97/sm2can/issues"
62
+ Documentation = "https://github.com/aldoguzman97/sm2can/wiki"
63
+
64
+ [project.scripts]
65
+ sm2can = "sm2can.cli:main"
66
+ sm2can-probe = "sm2can.tools.probe:main"
67
+ sm2can-capture = "sm2can.tools.capture_decoder:main"
68
+
69
+ # Register as a python-can interface plugin
70
+ [project.entry-points."can.interface"]
71
+ sm2 = "sm2can.can_interface:SM2Bus"
72
+
73
+ [tool.setuptools.packages.find]
74
+ include = ["sm2can*"]
75
+
76
+ [tool.ruff]
77
+ line-length = 100
78
+ target-version = "py38"
79
+
80
+ [tool.pytest.ini_options]
81
+ testpaths = ["tests"]
82
+
83
+ [tool.mypy]
84
+ python_version = "3.8"
85
+ warn_return_any = true
86
+ warn_unused_configs = true
sm2can-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,286 @@
1
+ Metadata-Version: 2.4
2
+ Name: sm2can
3
+ Version: 0.1.0
4
+ Summary: Open-source macOS/Linux driver for SM2 Pro (Scanmatik 2 Pro) J2534 CAN adapter
5
+ Author-email: Aldo Guzman <aldoguzman97@users.noreply.github.com>
6
+ Maintainer-email: Aldo Guzman <aldoguzman97@users.noreply.github.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/aldoguzman97/sm2can
9
+ Project-URL: Repository, https://github.com/aldoguzman97/sm2can
10
+ Project-URL: Issues, https://github.com/aldoguzman97/sm2can/issues
11
+ Project-URL: Documentation, https://github.com/aldoguzman97/sm2can/wiki
12
+ Keywords: CAN,OBD,automotive,J2534,Scanmatik,SM2,python-can,reverse-engineering,macOS,Linux,CAN-bus,vehicle-diagnostics
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
27
+ Classifier: Topic :: System :: Hardware :: Hardware Drivers
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.8
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Requires-Dist: pyusb>=1.2.0
33
+ Requires-Dist: python-can>=4.0
34
+ Provides-Extra: bluetooth
35
+ Requires-Dist: bleak>=0.21.0; extra == "bluetooth"
36
+ Provides-Extra: dev
37
+ Requires-Dist: pytest>=7.0; extra == "dev"
38
+ Requires-Dist: pytest-cov; extra == "dev"
39
+ Requires-Dist: ruff; extra == "dev"
40
+ Requires-Dist: mypy; extra == "dev"
41
+ Provides-Extra: capture
42
+ Requires-Dist: pyshark; extra == "capture"
43
+ Provides-Extra: all
44
+ Requires-Dist: sm2can[bluetooth,capture,dev]; extra == "all"
45
+ Dynamic: license-file
46
+
47
+ # SM2CAN β€” Open-Source Driver for SM2 Pro CAN Adapters on macOS & Linux
48
+
49
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
50
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://python.org)
51
+ [![PyPI](https://img.shields.io/pypi/v/sm2can)](https://pypi.org/project/sm2can/)
52
+ [![CI](https://github.com/aldoguzman97/sm2can/actions/workflows/ci.yml/badge.svg)](https://github.com/aldoguzman97/sm2can/actions)
53
+
54
+ **SM2CAN** is a userspace USB driver that enables SM2 Pro (and compatible)
55
+ J2534 CAN adapters to work on **macOS** and **Linux** β€” platforms the
56
+ manufacturer's driver does not support. It integrates with
57
+ [python-can](https://python-can.readthedocs.io/), making it a drop-in
58
+ replacement for any CAN interface.
59
+
60
+ > **Disclaimer:** This project is **not affiliated with, endorsed by, or
61
+ > sponsored by** the manufacturer of the SM2 Pro hardware. All trademarks
62
+ > are property of their respective owners. This driver was developed using
63
+ > [clean room reverse engineering](LEGAL.md) of a legitimately purchased
64
+ > device for the sole purpose of interoperability. See [LEGAL.md](LEGAL.md)
65
+ > for full details.
66
+
67
+ ## Project Status
68
+
69
+ | Component | Status | Notes |
70
+ |-----------|--------|-------|
71
+ | USB transport (libusb) | βœ… Complete | Tested on macOS 13+ and Ubuntu 22.04+ |
72
+ | USB hardware detection | βœ… Complete | Auto-detects VID 0x20A2 PID 0x0001 |
73
+ | Protocol decoder | πŸ”§ Needs capture | Community USB captures welcome |
74
+ | Protocol auto-detection | βœ… Scaffolded | Tries multiple frame format variants |
75
+ | python-can `Bus` interface | βœ… Complete | `interface='sm2'` via entry point |
76
+ | CLI tools | βœ… Complete | `sm2can probe`, `monitor`, `send` |
77
+ | USB capture analysis | βœ… Complete | Parses pcap/pcapng from USBPcap |
78
+ | Homebrew formula | βœ… Ready | `brew tap aldoguzman97/sm2can` |
79
+ | Linux udev rules | βœ… Included | Non-root USB access |
80
+ | Bluetooth SPP transport | πŸ“‹ Planned | Architecture ready for future support |
81
+
82
+ ### How You Can Help
83
+
84
+ **One USB capture from a Windows session completes this driver.**
85
+ If you can run Wireshark + USBPcap on Windows while connected to a vehicle:
86
+
87
+ ```bash
88
+ pip install sm2can
89
+ sm2can-capture guide # Step-by-step capture instructions
90
+ sm2can-capture decode mycapture.pcapng # Auto-analyzes the protocol
91
+ ```
92
+
93
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the 5-minute capture guide.
94
+
95
+ ## Installation
96
+
97
+ ### Homebrew (macOS)
98
+
99
+ ```bash
100
+ brew tap aldoguzman97/sm2can
101
+ brew install sm2can
102
+ ```
103
+
104
+ ### pip (macOS & Linux)
105
+
106
+ ```bash
107
+ pip install sm2can
108
+ ```
109
+
110
+ ### From source
111
+
112
+ ```bash
113
+ git clone https://github.com/aldoguzman97/sm2can.git
114
+ cd sm2can
115
+ pip install -e ".[dev]"
116
+ ```
117
+
118
+ ### Prerequisites
119
+
120
+ | Platform | Command |
121
+ |----------|---------|
122
+ | **macOS** | `brew install libusb` |
123
+ | **Debian/Ubuntu** | `sudo apt install libusb-1.0-0-dev` |
124
+ | **Fedora/RHEL** | `sudo dnf install libusb1-devel` |
125
+ | **Arch** | `sudo pacman -S libusb` |
126
+
127
+ Python 3.8 or later required.
128
+
129
+ ### Linux: USB Permissions
130
+
131
+ To use without `sudo`:
132
+
133
+ ```bash
134
+ sudo cp scripts/99-sm2pro.rules /etc/udev/rules.d/
135
+ sudo udevadm control --reload-rules && sudo udevadm trigger
136
+ # Log out and back in (user must be in 'plugdev' group)
137
+ ```
138
+
139
+ ## Quick Start
140
+
141
+ ### Detect hardware
142
+
143
+ ```bash
144
+ sm2can probe
145
+ ```
146
+
147
+ ### Monitor CAN bus
148
+
149
+ ```bash
150
+ sm2can monitor --bitrate 500000
151
+ ```
152
+
153
+ ### Send a CAN frame
154
+
155
+ ```bash
156
+ sm2can send 0x7DF 0201000000000000 --bitrate 500000
157
+ ```
158
+
159
+ ### Use with python-can
160
+
161
+ ```python
162
+ import can
163
+
164
+ # SM2CAN registers as a python-can interface plugin automatically
165
+ bus = can.Bus(interface='sm2', channel=0, bitrate=500000)
166
+
167
+ # Receive
168
+ msg = bus.recv(timeout=1.0)
169
+ if msg:
170
+ print(f"0x{msg.arbitration_id:03X}: {msg.data.hex()}")
171
+
172
+ # Send
173
+ bus.send(can.Message(
174
+ arbitration_id=0x7DF,
175
+ data=bytes([0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
176
+ ))
177
+
178
+ bus.shutdown()
179
+ ```
180
+
181
+ ### Direct API
182
+
183
+ ```python
184
+ from sm2can import SM2Device
185
+
186
+ with SM2Device() as dev:
187
+ dev.open(bitrate=500000)
188
+ dev.send(0x7DF, bytes([0x02, 0x01, 0x00, 0, 0, 0, 0, 0]))
189
+ frame = dev.recv(timeout=1.0)
190
+ if frame:
191
+ print(f"0x{frame.arbitration_id:03X}: {frame.data.hex()}")
192
+ ```
193
+
194
+ ## Supported Hardware
195
+
196
+ | Device | USB ID | Interface | Status |
197
+ |--------|--------|-----------|--------|
198
+ | SM2 Pro (original) | `20A2:0001` | USB + BT | Primary target |
199
+ | SM2 Pro (clones) | `20A2:0001` | USB | Should work (same USB protocol) |
200
+
201
+ ### Power Requirements
202
+
203
+ > **Important:** The SM2 Pro requires 12V on the OBD-II connector to boot
204
+ > its application firmware. On USB 5V power alone, the microcontroller
205
+ > enumerates on the bus but the CAN transceiver and command handler do not
206
+ > start. Connect to a vehicle with ignition ON, or supply 12V externally.
207
+
208
+ OBD-II bench power pinout:
209
+
210
+ | Pin | Function |
211
+ |-----|----------|
212
+ | 16 | +12V (battery) |
213
+ | 4 | Chassis ground |
214
+ | 5 | Signal ground |
215
+
216
+ A 12V / 1A wall adapter wired to these pins is sufficient.
217
+
218
+ ## Architecture
219
+
220
+ ```
221
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
222
+ β”‚ Your Application / python-can / opendbc / UDS client β”‚
223
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
224
+ β”‚ SM2Bus (can_interface.py) β”‚
225
+ β”‚ python-can BusABC β€” registered via entry point β”‚
226
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
227
+ β”‚ SM2Device (device.py) β”‚
228
+ β”‚ High-level: open / close / send / recv / background RX β”‚
229
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
230
+ β”‚ ProtocolCodec (protocol.py) β”‚
231
+ β”‚ Encode / decode binary protocol frames β”‚
232
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
233
+ β”‚ USBTransport β”‚ BluetoothTransport (planned) β”‚
234
+ β”‚ (usb_transport.py)β”‚ (bluetooth_transport.py) β”‚
235
+ β”‚ Bulk EP via libusbβ”‚ SPP via platform-native APIs β”‚
236
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
237
+ β”‚ Hardware: EP 0x02 OUT / EP 0x81 IN / 64-byte packets β”‚
238
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
239
+ ```
240
+
241
+ **Why userspace instead of a kernel driver?** A kernel extension (kext on
242
+ macOS, .ko on Linux) requires code signing, kernel version compatibility,
243
+ and administrator installation. A userspace driver via libusb installs with
244
+ pip, works everywhere, and cannot crash your kernel. The SM2 Pro's simple
245
+ 2-endpoint bulk design is ideal for this approach.
246
+
247
+ ## Roadmap
248
+
249
+ - [x] USB transport layer
250
+ - [x] Protocol codec with auto-detection framework
251
+ - [x] python-can `Bus` interface
252
+ - [x] CLI tools (`probe`, `monitor`, `send`)
253
+ - [x] USB capture decoder for protocol analysis
254
+ - [x] Homebrew formula
255
+ - [x] Linux udev rules
256
+ - [ ] Complete protocol specification (pending community captures)
257
+ - [ ] Bluetooth SPP transport
258
+ - [ ] CAN-FD support (if hardware supports it)
259
+ - [ ] ISO-TP (ISO 15765) pass-through
260
+ - [ ] SAE J2534 API shim layer
261
+
262
+ ## Contributing
263
+
264
+ See [CONTRIBUTING.md](CONTRIBUTING.md). The most impactful contribution is
265
+ a USB capture from Windows β€” one file completes the protocol specification
266
+ for everyone.
267
+
268
+ ## Legal
269
+
270
+ This project uses clean room reverse engineering to achieve interoperability
271
+ with legitimately purchased hardware. No proprietary code, firmware, or
272
+ documentation was used. See [LEGAL.md](LEGAL.md) for full details including
273
+ applicable case law.
274
+
275
+ ## License
276
+
277
+ MIT β€” see [LICENSE](LICENSE).
278
+
279
+ Copyright (c) 2026 Aldo Guzman ([@aldoguzman97](https://github.com/aldoguzman97))
280
+
281
+ ## Acknowledgments
282
+
283
+ - [pyusb](https://github.com/pyusb/pyusb) β€” Cross-platform USB access
284
+ - [python-can](https://github.com/hardbyte/python-can) β€” CAN bus abstraction
285
+ - [libusb](https://libusb.info/) β€” Userspace USB I/O
286
+ - Everyone who contributes USB captures
@@ -0,0 +1,9 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ sm2can.egg-info/PKG-INFO
5
+ sm2can.egg-info/SOURCES.txt
6
+ sm2can.egg-info/dependency_links.txt
7
+ sm2can.egg-info/entry_points.txt
8
+ sm2can.egg-info/requires.txt
9
+ sm2can.egg-info/top_level.txt
@@ -0,0 +1,7 @@
1
+ [can.interface]
2
+ sm2 = sm2can.can_interface:SM2Bus
3
+
4
+ [console_scripts]
5
+ sm2can = sm2can.cli:main
6
+ sm2can-capture = sm2can.tools.capture_decoder:main
7
+ sm2can-probe = sm2can.tools.probe:main
@@ -0,0 +1,17 @@
1
+ pyusb>=1.2.0
2
+ python-can>=4.0
3
+
4
+ [all]
5
+ sm2can[bluetooth,capture,dev]
6
+
7
+ [bluetooth]
8
+ bleak>=0.21.0
9
+
10
+ [capture]
11
+ pyshark
12
+
13
+ [dev]
14
+ pytest>=7.0
15
+ pytest-cov
16
+ ruff
17
+ mypy
@@ -0,0 +1 @@
1
+