-
Notifications
You must be signed in to change notification settings - Fork 0
Auto-select COM ports on Windows #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
b09466c
feat: serial-port hardware-ID classifier with unit tests
ramseymcgrath 6e96887
feat: SetupAPI COM-port enumerator (Windows) + non-Windows stub
ramseymcgrath 3ec0de7
feat: auto-select Hurra firmware COM port on Windows
ramseymcgrath 2502025
feat: auto-select com0com virtual port on Windows VCOM endpoint
ramseymcgrath 2feaffd
docs: document Windows COM-port auto-detection
ramseymcgrath 1ea3a29
fix: skip LPT ports in Windows COM enumeration
ramseymcgrath File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /* serial_enum.c — pure hardware-ID classifier (always compiled). */ | ||
| #include "serial_enum.h" | ||
| #include <ctype.h> | ||
|
|
||
| /* Case-insensitive substring search. Returns 1 if `needle` is in `hay`. */ | ||
| static int ci_contains(const char *hay, const char *needle) { | ||
| if (!hay || !needle || !*needle) return 0; | ||
| for (; *hay; hay++) { | ||
| const char *h = hay, *n = needle; | ||
| while (*h && *n && | ||
| tolower((unsigned char)*h) == tolower((unsigned char)*n)) { | ||
| h++; n++; | ||
| } | ||
| if (!*n) return 1; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| port_class_t serial_classify_hwid(const char *hwid) { | ||
| if (!hwid || !*hwid) return PORT_OTHER; | ||
| if (ci_contains(hwid, "VID_1A86")) return PORT_FIRMWARE; | ||
| if (ci_contains(hwid, "COM0COM") || | ||
| ci_contains(hwid, "CNCA") || | ||
| ci_contains(hwid, "CNCB")) return PORT_COM0COM; | ||
| return PORT_OTHER; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| /* | ||
| * serial_enum.h — enumerate serial/COM ports and classify them. | ||
| * | ||
| * The classifier (serial_classify_hwid) is pure and always compiled, so it can | ||
| * be unit-tested on any host. The enumerator (serial_enum) is Windows-only in | ||
| * practice; a stub returns 0 on other platforms. | ||
| */ | ||
| #ifndef HURRA_SERIAL_ENUM_H | ||
| #define HURRA_SERIAL_ENUM_H | ||
|
|
||
| #include <stddef.h> | ||
|
|
||
| typedef enum { | ||
| PORT_OTHER = 0, /* unknown / unrelated COM port */ | ||
| PORT_FIRMWARE, /* WCH CH343 (VID_1A86) — the Hurra device */ | ||
| PORT_COM0COM /* com0com virtual pair end */ | ||
| } port_class_t; | ||
|
|
||
| typedef struct { | ||
| char name[32]; /* "COM5" */ | ||
| char friendly[128]; /* "USB-SERIAL CH343 (COM5)" */ | ||
| port_class_t klass; | ||
| } serial_cand_t; | ||
|
|
||
| /* Classify a Win32 hardware-ID string. Pure; NULL or "" -> PORT_OTHER. | ||
| * Match is case-insensitive substring: | ||
| * "VID_1A86" -> PORT_FIRMWARE | ||
| * "COM0COM" | "CNCA" | "CNCB" -> PORT_COM0COM | ||
| * otherwise -> PORT_OTHER | ||
| */ | ||
| port_class_t serial_classify_hwid(const char *hwid); | ||
|
|
||
| /* Enumerate present COM ports, newest API available per platform. Fills up to | ||
| * `max` candidates, returns the count. Returns 0 on failure or non-Windows. */ | ||
| size_t serial_enum(serial_cand_t *out, size_t max); | ||
|
|
||
| #endif /* HURRA_SERIAL_ENUM_H */ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| /* serial_enum_stub.c — serial_enum for non-Windows builds (no enumeration). */ | ||
| #include "serial_enum.h" | ||
|
|
||
| size_t serial_enum(serial_cand_t *out, size_t max) { | ||
| (void)out; (void)max; | ||
| return 0; /* Unix uses glob-based discover_devices() in bridge.c instead. */ | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Collapsing failure and empty into a single
0return is intentional here, not an oversight — it's the documented design (spec: "SetupAPI / registry failures degrade to 'zero candidates' → existing explicit error paths fire").The two states aren't actionably different at the call sites: in both cases the bridge cannot auto-select a port and must fall back to the explicit-flag error path. Distinguishing them would only change error wording, while complicating the API contract (out-param or sentinel) that every caller has to handle. That's the graceful degradation the summary refers to — a failed SetupAPI call lands on the same clean
bridge_failas 'no device plugged in', never a crash. Keeping the simplesize_t countcontract on purpose (YAGNI).