Skip to content

Commit cf03d6d

Browse files
authored
feat: new binding interface (#19)
- We now only return a port object if it's open and list and open methods are now exported on an interface - hardware tests now work and only require a loopback (no ready event) - Test pass on darwin (not on mock - it's not up to date yet and coverage is going to drop) - cleanup up tests with modern javascript - Breaking - change the names of the exported types - No more constructors, now all binding specicific open options are specificd on open - Arduino test file for loopback
1 parent d7a855d commit cf03d6d

16 files changed

+455
-570
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ The Bindings provide a low level interface to work with your serialport. It is p
3131
1. Clone this repo `git clone [email protected]:serialport/bindings-cpp.git`
3232
1. Run `npm install` to setup local package dependencies (run this any time you depend on a package local to this repo)
3333
1. Run `npm test` to ensure everything is working properly
34+
1. If you have a serial loopback device (TX to RX) you can run run `TEST_PORT=/path/to/port npm test` for a more comprehensive test suite. (Defaults to 115200 baud customize with the TEST_BAUD env.) You can use an arduino with the `test/arduino-echo` sketch.
3435

3536
### Developing Docs
3637

lib/binding-interface.test.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

lib/binding-interface.ts

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,28 @@ export interface PortInfo {
1414
}
1515

1616
export interface OpenOptions {
17+
/** The path of the port */
18+
path: string
1719
/** The baud rate of the port to be opened. This should match one of the commonly available baud rates, such as 110, 300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, or 115200. Custom rates are supported best effort per platform. The device connected to the serial port is not guaranteed to support the requested baud rate, even if the port itself supports that baud rate. */
1820
baudRate: number
19-
/** Must be one of these: 8, 7, 6, or 5 */
20-
dataBits: 8 | 7 | 6 | 5
21-
/** Prevent other processes from opening the port. Windows does not currently support `false`. */
22-
lock: boolean
23-
stopBits: 1 | 2
24-
parity: 'none' | 'event' | 'mark' | 'odd' | 'space'
25-
/** Flow control Setting */
26-
rtscts: boolean
27-
/** Flow control Setting */
28-
xon: boolean
29-
/** Flow control Setting */
30-
xoff: boolean
31-
/** Flow control Setting */
32-
xany: boolean
33-
/** drop DTR on close */
34-
hupcl: boolean
21+
/** Must be one of these: 8, 7, 6, or 5 defaults to 8 */
22+
dataBits?: 8 | 7 | 6 | 5
23+
/** Prevent other processes from opening the port. Windows does not currently support `false`. Defaults to true */
24+
lock?: boolean
25+
/** defaults to 1 - TODO should be a string */
26+
stopBits?: 1 | 2 | 3
27+
/** Device parity defaults to none */
28+
parity?: 'none' | 'event' | 'mark' | 'odd' | 'space'
29+
/** Flow control Setting. Defaults to false */
30+
rtscts?: boolean
31+
/** Flow control Setting. Defaults to false */
32+
xon?: boolean
33+
/** Flow control Setting. Defaults to false */
34+
xoff?: boolean
35+
/** Flow control Setting defaults to false*/
36+
xany?: boolean
37+
/** drop DTR on close. Defaults to true */
38+
hupcl?: boolean
3539
}
3640

3741
export interface UpdateOptions {
@@ -56,39 +60,28 @@ export interface PortStatus {
5660
/**
5761
* You never have to use `Binding` objects directly. SerialPort uses them to access the underlying hardware. This documentation is geared towards people who are making bindings for different platforms. This interface is implemented in all bindings.
5862
*/
59-
export abstract class BindingInterface {
60-
/**
61-
Retrieves a list of available serial ports with metadata. The `path` must be guaranteed, and all other fields should be undefined if unavailable. The `path` is either the path or an identifier (eg `COM1`) used to open the serialport.
62-
*/
63-
static async list(): Promise<PortInfo[]> {
64-
throw new Error('Method not implemented.')
65-
}
66-
63+
export interface BindingPortInterface {
64+
readonly openOptions: Required<OpenOptions>
6765
/**
6866
* Required property. `true` if the port is open, `false` otherwise. Should be read-only.
6967
*/
70-
abstract isOpen: boolean
71-
72-
/**
73-
* Opens a connection to the serial port referenced by the path.
74-
*/
75-
abstract open(path: string, options?: OpenOptions): Promise<void>
68+
isOpen: boolean
7669

7770
/**
7871
* Closes an open connection
7972
*/
80-
abstract close(): Promise<void>
73+
close(): Promise<void>
8174

8275
/**
83-
Request a number of bytes from the SerialPort. This function is similar to Node's [`fs.read`](http://nodejs.org/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback) except it will always return at least one byte.
76+
Request a number of bytes from the SerialPort. This function is similar to Node's [`fs.read`](http://nodejs.org/api/fs.html#fs_fs_read_fd_buffer_offset_length_position_callback) as it will attempt to read up to `length` number of bytes. This function has a guarantee that it will always return at least one byte. This leverages os specific polling or async reads so you don't have to.
8477
8578
The in progress reads must error when the port is closed with an error object that has the property `canceled` equal to `true`. Any other error will cause a disconnection.
8679
8780
* @param offset The offset in the buffer to start writing at.
8881
* @param length Specifies the maximum number of bytes to read.
8982
* @returns {Promise} Resolves with the number of bytes read after a read operation.
9083
*/
91-
abstract read(buffer: Buffer, offset: number, length: number): Promise<{ buffer: Buffer; bytesRead: number }>
84+
read(buffer: Buffer, offset: number, length: number): Promise<{ buffer: Buffer; bytesRead: number }>
9285

9386
/**
9487
Write bytes to the SerialPort. Only called when there is no pending write operation.
@@ -97,39 +90,51 @@ export abstract class BindingInterface {
9790
9891
Resolves after the data is passed to the operating system for writing.
9992
*/
100-
abstract write(buffer: Buffer): Promise<void>
93+
write(buffer: Buffer): Promise<void>
10194

10295
/**
10396
Changes connection settings on an open port.
10497
*/
105-
abstract update(options: UpdateOptions): Promise<void>
98+
update(options: UpdateOptions): Promise<void>
10699

107100
/**
108101
* Set control flags on an open port.
109102
* All options are operating system default when the port is opened. Every flag is set on each call to the provided or default values.
110103
*/
111-
abstract set(options: SetOptions): Promise<void>
104+
set(options: SetOptions): Promise<void>
112105

113106
/**
114107
* Get the control flags (CTS, DSR, DCD) on the open port.
115108
*/
116-
abstract get(): Promise<PortStatus>
109+
get(): Promise<PortStatus>
117110

118111
/**
119112
* Get the OS reported baud rate for the open port.
120113
* Used mostly for debugging custom baud rates.
121114
*/
122-
abstract getBaudRate(): Promise<{ baudRate: number }>
115+
getBaudRate(): Promise<{ baudRate: number }>
123116

124117
/**
125118
* Flush (discard) data received but not read, and written but not transmitted.
126119
* Resolves once the flush operation finishes.
127120
*/
128-
abstract flush(): Promise<void>
121+
flush(): Promise<void>
129122

130123
/**
131124
* Drain waits until all output data is transmitted to the serial port. An in progress write should be completed before this returns.
132125
* Resolves once the drain operation finishes.
133126
*/
134-
abstract drain(): Promise<void>
127+
drain(): Promise<void>
128+
}
129+
130+
export interface BindingInterface<Port extends BindingPortInterface = BindingPortInterface, Open extends OpenOptions = OpenOptions> {
131+
/**
132+
Retrieves a list of available serial ports with metadata. The `path` must be guaranteed, and all other fields should be undefined if unavailable. The `path` is either the path or an identifier (eg `COM1`) used to open the serialport.
133+
*/
134+
list(): Promise<PortInfo[]>
135+
/**
136+
* Opens a connection to the serial port referenced by the path.
137+
*/
138+
open(options: Open): Promise<Port>
139+
135140
}

0 commit comments

Comments
 (0)