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 +21 -0
- sm2can-0.1.0/PKG-INFO +286 -0
- sm2can-0.1.0/README.md +240 -0
- sm2can-0.1.0/pyproject.toml +86 -0
- sm2can-0.1.0/setup.cfg +4 -0
- sm2can-0.1.0/sm2can.egg-info/PKG-INFO +286 -0
- sm2can-0.1.0/sm2can.egg-info/SOURCES.txt +9 -0
- sm2can-0.1.0/sm2can.egg-info/dependency_links.txt +1 -0
- sm2can-0.1.0/sm2can.egg-info/entry_points.txt +7 -0
- sm2can-0.1.0/sm2can.egg-info/requires.txt +17 -0
- sm2can-0.1.0/sm2can.egg-info/top_level.txt +1 -0
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)
|
|
50
|
+
[](https://python.org)
|
|
51
|
+
[](https://pypi.org/project/sm2can/)
|
|
52
|
+
[](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)
|
|
4
|
+
[](https://python.org)
|
|
5
|
+
[](https://pypi.org/project/sm2can/)
|
|
6
|
+
[](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,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)
|
|
50
|
+
[](https://python.org)
|
|
51
|
+
[](https://pypi.org/project/sm2can/)
|
|
52
|
+
[](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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|