@@ -9,9 +9,14 @@ class SerialPort extends EventEmitter {
99 this . browser = true ;
1010 this . path = this . options . path ;
1111 this . isOpen = false ;
12- this . port = null ;
12+ this . port = port || null ;
1313 this . writer = null ;
1414 this . reader = null ;
15+ this . isUpdating = false ;
16+ this . pausePromise = Promise . resolve ( ) ;
17+ this . pauseResolve = ( ) => { } ;
18+ this . closeReadPromise = null ;
19+ this . closeReadResolve = ( ) => { } ;
1520 this . baudRate = this . options . baudRate ;
1621 this . requestOptions = this . options . requestOptions || { } ;
1722
@@ -24,45 +29,74 @@ class SerialPort extends EventEmitter {
2429 . catch ( ( error ) => { if ( callback ) { return callback ( error ) } } ) ;
2530 }
2631
32+ async _getPort ( ) {
33+ if ( this . port && ! this . options . forceRequest ) return this . port ;
34+ return window . navigator . serial . requestPort ( this . requestOptions )
35+ }
36+
2737 open ( callback ) {
28- window . navigator . serial . requestPort ( this . requestOptions )
29- . then ( serialPort => {
30- this . port = serialPort ;
31- if ( this . isOpen ) return ;
32- return this . port . open ( { baudRate : this . baudRate || 57600 } ) ;
33- } )
34- . then ( ( ) => this . writer = this . port . writable . getWriter ( ) )
35- . then ( ( ) => this . reader = this . port . readable . getReader ( ) )
36- . then ( async ( ) => {
37- this . emit ( 'open' ) ;
38- this . isOpen = true ;
39- callback ( null ) ;
40- while ( this . port . readable . locked ) {
41- try {
42- const { value, done } = await this . reader . read ( ) ;
43- if ( done ) {
44- break ;
38+ return new Promise ( ( resolve , reject ) => {
39+ this . _getPort ( )
40+ . then ( serialPort => {
41+ this . port = serialPort ;
42+ if ( this . isOpen ) return ;
43+ return this . port . open ( { baudRate : this . baudRate || 57600 } ) ;
44+ } )
45+ . then ( ( ) => this . writer = this . port . writable . getWriter ( ) )
46+ . then ( ( ) => this . reader = this . port . readable . getReader ( ) )
47+ . then ( async ( ) => {
48+ if ( ! this . isUpdating ) this . emit ( 'open' ) ;
49+ this . isOpen = true ;
50+ if ( callback ) callback ( null ) ;
51+ resolve ( null ) ;
52+ while ( this . port . readable . locked ) {
53+ try {
54+ await this . pausePromise ;
55+ const { value, done } = await this . reader . read ( ) ;
56+ if ( done || this . closeReadPromise ) {
57+ break ;
58+ }
59+ this . emit ( 'data' , Buffer . from ( value ) ) ;
60+ } catch ( e ) {
61+ console . error ( e ) ;
4562 }
46- this . emit ( 'data' , Buffer . from ( value ) ) ;
47- } catch ( e ) {
48- console . error ( e ) ;
4963 }
50- }
51- } )
52- . catch ( error => { callback ( error ) } ) ;
64+ this . closeReadResolve ( ) ;
65+ } )
66+ . catch ( error => {
67+ if ( callback ) callback ( error ) ;
68+ reject ( error ) ;
69+ } ) ;
70+ } ) ;
5371 }
5472
5573 async close ( callback ) {
74+ if ( ! this . isOpen ) {
75+ if ( callback ) callback ( null ) ;
76+ return ;
77+ }
78+ if ( this . port . readable . locked ) {
79+ this . closeReadPromise = new Promise ( ( resolve ) => {
80+ this . closeReadResolve = resolve ;
81+ } ) ;
82+ this . pauseResolve ( ) ;
83+ try {
84+ await this . reader . cancel ( ) ;
85+ } catch ( err ) { console . error ( err ) ; }
86+ await this . closeReadPromise ;
87+ this . closeReadPromise = null ;
88+ }
5689 try {
5790 await this . reader . releaseLock ( ) ;
5891 await this . writer . releaseLock ( ) ;
5992 await this . port . close ( ) ;
93+ if ( ! this . isUpdating ) this . emit ( 'close' ) ;
6094 this . isOpen = false ;
6195 } catch ( error ) {
6296 if ( callback ) return callback ( error ) ;
6397 throw error ;
6498 }
65- callback && callback ( null ) ;
99+ if ( callback ) callback ( null ) ;
66100 }
67101
68102 async set ( props = { } , callback ) {
@@ -87,6 +121,27 @@ class SerialPort extends EventEmitter {
87121 if ( callback ) return callback ( null ) ;
88122 }
89123
124+ async get ( callback ) {
125+ const props = { } ;
126+ try {
127+ const signals = await this . port . getSignals ( ) ;
128+ if ( Object . prototype . hasOwnProperty . call ( signals , 'dataCarrierDetect' ) ) {
129+ props . dcd = signals . dataCarrierDetect ;
130+ }
131+ if ( Object . prototype . hasOwnProperty . call ( signals , 'clearToSend' ) ) {
132+ props . cts = signals . clearToSend ;
133+ }
134+ if ( Object . prototype . hasOwnProperty . call ( signals , 'dataSetReady' ) ) {
135+ props . dsr = signals . dataSetReady ;
136+ }
137+ } catch ( error ) {
138+ if ( callback ) return callback ( error ) ;
139+ throw error ;
140+ }
141+ if ( callback ) return callback ( props ) ;
142+ return props ;
143+ }
144+
90145 write ( buffer , callback ) {
91146 this . writer . write ( buffer ) ;
92147 if ( callback ) return callback ( null ) ;
@@ -103,6 +158,40 @@ class SerialPort extends EventEmitter {
103158 if ( callback ) callback ( null , buffer ) ;
104159 }
105160
161+ async update ( options , callback ) {
162+ try {
163+ if (
164+ Object . prototype . hasOwnProperty . call ( options , 'baudRate' )
165+ && this . baudRate !== options . baudRate
166+ ) {
167+ if ( this . isOpen ) {
168+ // try to quietly close then open the port with the new baudRate
169+ this . isUpdating = true ;
170+ await this . close ( ) ;
171+ this . baudRate = options . baudRate ;
172+ await this . open ( ) ;
173+ this . isUpdating = false ;
174+ } else {
175+ this . baudRate = options . baudRate ;
176+ }
177+ }
178+ } catch ( error ) {
179+ if ( callback ) return callback ( error ) ;
180+ throw error ;
181+ }
182+ if ( callback ) callback ( null ) ;
183+ }
184+
185+ pause ( ) {
186+ this . pausePromise = new Promise ( ( resolve ) => {
187+ this . pauseResolve = resolve ;
188+ } ) ;
189+ }
190+
191+ resume ( ) {
192+ this . pauseResolve ( ) ;
193+ }
194+
106195 // TODO: is this correct?
107196 flush ( callback ) {
108197 //this.port.flush(); // is this sync or a promise?
@@ -118,4 +207,4 @@ class SerialPort extends EventEmitter {
118207 }
119208}
120209
121- module . exports = SerialPort ;
210+ module . exports = SerialPort ;
0 commit comments