1
1
import { Subject , BehaviorSubject } from 'rxjs' ;
2
2
import { takeUntil , filter } from 'rxjs/operators' ;
3
3
4
+ const UPLOAD_STATUS_NOPE = 'UPLOAD_STATUS_NOPE' ;
5
+ const UPLOAD_STATUS_DONE = 'UPLOAD_STATUS_DONE' ;
6
+ const UPLOAD_STATUS_ERROR = 'UPLOAD_STATUS_ERROR' ;
7
+ const UPLOAD_STATUS_IN_PROGRESS = 'UPLOAD_STATUS_IN_PROGRESS' ;
8
+
4
9
export default class Daemon {
5
10
constructor ( ) {
6
11
this . socket = null ;
7
12
this . pluginURL = null ;
8
13
this . socketMessages = new Subject ( ) ;
9
14
this . serialMonitorOpened = new BehaviorSubject ( false ) ;
10
15
this . serialMonitorMessages = new Subject ( ) ;
16
+ this . uploading = new BehaviorSubject ( ) ;
11
17
this . devicesList = new BehaviorSubject ( {
12
18
serial : [ ] ,
13
19
network : [ ]
14
20
} ) ;
15
21
this . socketMessages
16
22
. subscribe ( this . handleSocketMessage . bind ( this ) ) ;
17
- this . openingSerial = null ;
18
- this . closingSerial = null ;
19
23
20
24
const devicesListSubscription = this . devicesList . subscribe ( ( devices ) => {
21
25
if ( devices . serial && devices . serial . length > 0 ) {
22
26
this . closeAllPorts ( ) ;
23
27
devicesListSubscription . unsubscribe ( ) ;
24
28
}
25
29
} ) ;
26
- window . addEventListener ( 'beforeunload' , this . closeAllPorts ) ;
27
30
}
28
31
29
32
initSocket ( ) {
@@ -46,7 +49,7 @@ export default class Daemon {
46
49
* @param {Array<device> } a the first list
47
50
* @param {Array<device> } b the second list
48
51
*/
49
- devicesListAreEquals ( a , b ) {
52
+ static devicesListAreEquals ( a , b ) {
50
53
if ( ! a || ! b || a . length !== b . length ) {
51
54
return false ;
52
55
}
@@ -57,13 +60,13 @@ export default class Daemon {
57
60
// Result of a list command
58
61
if ( message . Ports ) {
59
62
const lastDevices = this . devicesList . getValue ( ) ;
60
- if ( message . Network && ! this . devicesListAreEquals ( lastDevices . network , message . Ports ) ) {
63
+ if ( message . Network && ! Daemon . devicesListAreEquals ( lastDevices . network , message . Ports ) ) {
61
64
this . devicesList . next ( {
62
65
serial : lastDevices . serial ,
63
66
network : message . Ports
64
67
} ) ;
65
68
}
66
- else if ( ! message . Network && ! this . devicesListAreEquals ( lastDevices . serial , message . Ports ) ) {
69
+ else if ( ! message . Network && ! Daemon . devicesListAreEquals ( lastDevices . serial , message . Ports ) ) {
67
70
this . devicesList . next ( {
68
71
serial : message . Ports ,
69
72
network : lastDevices . network
@@ -74,6 +77,7 @@ export default class Daemon {
74
77
if ( message . D ) {
75
78
this . serialMonitorMessages . next ( message . D ) ;
76
79
}
80
+ // if (message.ProgrammerStatus )
77
81
}
78
82
79
83
writeSerial ( port , data ) {
@@ -122,14 +126,91 @@ export default class Daemon {
122
126
this . socket . emit ( 'command' , `close ${ port } ` ) ;
123
127
}
124
128
125
- closeAllPorts ( e ) {
126
- if ( e ) {
127
- e . preventDefault ( ) ;
128
- }
129
+ closeAllPorts ( ) {
129
130
const devices = this . devicesList . getValue ( ) . serial ;
130
131
devices . forEach ( device => {
131
132
this . socket . emit ( 'command' , `close ${ device . Name } ` ) ;
132
133
} ) ;
133
- return ;
134
+ }
135
+
136
+ /**
137
+ * Perform an upload via http on the daemon
138
+ * target = {
139
+ * board: "name of the board",
140
+ * port: "port of the board",
141
+ * auth_user: "Optional user to use as authentication",
142
+ * auth_pass: "Optional pass to use as authentication"
143
+ * auth_key: "Optional private key",
144
+ * auth_port: "Optional alternative port (default 22)"
145
+ * network: true or false
146
+ * }
147
+ * data = {
148
+ * commandline: "commandline to execute",
149
+ * signature: "signature of the commandline",
150
+ * files: [
151
+ * {name: "Name of a file to upload on the device", data: 'base64data'}
152
+ * ],
153
+ * options: {}
154
+ * }
155
+ * cb = callback function executing everytime a packet of data arrives through the websocket
156
+ */
157
+ upload ( target , data ) {
158
+ this . uploading . next ( { status : UPLOAD_STATUS_IN_PROGRESS } ) ;
159
+
160
+ if ( data . files . length === 0 ) { // At least one file to upload
161
+ this . uploading . next ( { status : UPLOAD_STATUS_ERROR , err : 'You need at least one file to upload' } ) ;
162
+ return ;
163
+ }
164
+
165
+ // Main file
166
+ const file = data . files [ 0 ] ;
167
+ file . name = file . name . split ( '/' ) ;
168
+ file . name = file . name [ file . name . length - 1 ] ;
169
+
170
+ const payload = {
171
+ board : target . board ,
172
+ port : target . port ,
173
+ commandline : data . commandline ,
174
+ signature : data . signature ,
175
+ hex : file . data ,
176
+ filename : file . name ,
177
+ extra : {
178
+ auth : {
179
+ username : target . auth_user ,
180
+ password : target . auth_pass ,
181
+ private_key : target . auth_key ,
182
+ port : target . auth_port
183
+ } ,
184
+ wait_for_upload_port : data . options . wait_for_upload_port === 'true' || data . options . wait_for_upload_port === true ,
185
+ use_1200bps_touch : data . options . use_1200bps_touch === 'true' || data . options . use_1200bps_touch === true ,
186
+ network : target . network ,
187
+ ssh : target . ssh ,
188
+ params_verbose : data . options . param_verbose ,
189
+ params_quiet : data . options . param_quiet ,
190
+ verbose : data . options . verbose
191
+ } ,
192
+ extrafiles : data . extrafiles || [ ]
193
+ } ;
194
+
195
+ for ( let i = 1 ; i < data . files . length ; i += 1 ) {
196
+ payload . extrafiles . push ( { filename : data . files [ i ] . name , hex : data . files [ i ] . data } ) ;
197
+ }
198
+
199
+ fetch ( `${ this . pluginURL } /upload` , {
200
+ method : 'POST' ,
201
+ headers : {
202
+ 'Content-Type' : 'text/plain; charset=utf-8'
203
+ } ,
204
+ body : JSON . stringify ( payload )
205
+ } )
206
+ . catch ( error => {
207
+ this . uploading . next ( { status : UPLOAD_STATUS_ERROR , err : error } ) ;
208
+ } ) ;
209
+ }
210
+
211
+
212
+ stopUpload ( ) {
213
+ this . uploading . next ( false ) ;
214
+ this . socket . emit ( 'command' , 'killprogrammer' ) ;
134
215
}
135
216
}
0 commit comments