2626import javafx .scene .control .Button ;
2727import javafx .scene .control .ComboBox ;
2828import javafx .scene .control .PasswordField ;
29+ import javafx .scene .control .TextField ;
2930import javafx .scene .input .InputEvent ;
3031import lombok .extern .slf4j .Slf4j ;
3132import org .dpsoftware .MainSingleton ;
4445import java .util .concurrent .Executors ;
4546import java .util .concurrent .ScheduledExecutorService ;
4647import java .util .concurrent .TimeUnit ;
47- import java .util .concurrent .atomic .AtomicBoolean ;
48+ import java .util .concurrent .atomic .AtomicInteger ;
4849import java .util .regex .Matcher ;
4950import java .util .regex .Pattern ;
5051
@@ -68,6 +69,8 @@ public class ImprovDialogController {
6869 public Button cancelButton ;
6970 @ FXML
7071 private SettingsController settingsController ;
72+ @ FXML
73+ public TextField deviceName ;
7174
7275 /**
7376 * Inject main controller containing the TabPane
@@ -96,6 +99,7 @@ protected void initialize() {
9699 if (comPort != null && !comPort .getItems ().isEmpty ()) {
97100 comPort .setValue (comPort .getItems ().getFirst ());
98101 }
102+ deviceName .setText (MainSingleton .getInstance ().config .getOutputDevice ());
99103 baudrate .setValue (Enums .BaudRate .BAUD_RATE_115200 .getBaudRate ());
100104 });
101105 }
@@ -108,6 +112,7 @@ private void setTooltips() {
108112 GuiManager .createTooltip (Constants .TOOLTIP_IMPROV_PWD , wifiPwd );
109113 GuiManager .createTooltip (Constants .TOOLTIP_IMPROV_COM , comPort );
110114 GuiManager .createTooltip (Constants .TOOLTIP_IMPROV_BAUD , baudrate );
115+ GuiManager .createTooltip (Constants .TOOLTIP_DEV_NAME , deviceName );
111116 }
112117
113118 /**
@@ -145,15 +150,25 @@ public void saveAndClose(InputEvent e) {
145150 wifiPwd .commitValue ();
146151 baudrate .commitValue ();
147152 comPort .commitValue ();
148- AtomicBoolean error = new AtomicBoolean (false );
149- AtomicBoolean postponed = new AtomicBoolean (false );
153+ manageImprov ();
154+ CommonUtility .closeCurrentStage (e );
155+ }
156+
157+ /**
158+ * Program device using the IMPROV WiFi protocol
159+ */
160+ private void manageImprov () {
161+ SerialManager serialManager = new SerialManager ();
162+ serialManager .initSerial (comPort .getValue (), baudrate .getValue ());
150163 ScheduledExecutorService scheduler = Executors .newScheduledThreadPool (1 );
164+ AtomicInteger retryNumber = new AtomicInteger (0 );
165+ MainSingleton .getInstance ().guiManager .pipelineManager .stopCapturePipeline ();
166+ final int MAX_RETRY = 5 ;
151167 Runnable checkAndRun = () -> {
152- if (MainSingleton .getInstance ().config != null ) {
153- if (postponed .get ()) {
154- CommonUtility .sleepSeconds (5 );
155- }
156- MainSingleton .getInstance ().guiManager .pipelineManager .stopCapturePipeline ();
168+ boolean improvError ;
169+ retryNumber .getAndIncrement ();
170+ log .debug ("Trying to send an Improv WiFi command" );
171+ if (MainSingleton .getInstance ().config != null && MainSingleton .getInstance ().serial != null && MainSingleton .getInstance ().serial .isOpen ()) {
157172 MainSingleton .getInstance ().config .setOutputDevice (settingsController .modeTabController .serialPort .getValue ());
158173 MainSingleton .getInstance ().config .setMqttEnable (settingsController .networkTabController .mqttEnable .isSelected ());
159174 if (MainSingleton .getInstance ().config .isMqttEnable ()) {
@@ -163,20 +178,71 @@ public void saveAndClose(InputEvent e) {
163178 MainSingleton .getInstance ().config .setMqttUsername (settingsController .networkTabController .mqttUser .getText ());
164179 MainSingleton .getInstance ().config .setMqttPwd (settingsController .networkTabController .mqttPwd .getText ());
165180 }
166- error .set (improvWiFiCommand ());
167- scheduler .shutdown ();
181+ try {
182+ improvError = sendImprov ();
183+ } catch (IOException ex ) {
184+ log .error (ex .getMessage ());
185+ improvError = true ;
186+ }
168187 } else {
169- postponed .set (true );
170- if (!postponed .get ()) {
171- // logger isn't initialized yet, don't use the logger here.
172- System .out .println ("Postponing provisioning..." );
188+ improvError = true ;
189+ }
190+ if (!improvError || retryNumber .get () >= MAX_RETRY ) {
191+ scheduler .shutdown ();
192+ if (MainSingleton .getInstance ().communicationError ) {
193+ MainSingleton .getInstance ().guiManager .showLocalizedNotification (CommonUtility .getWord (Constants .FIRMWARE_PROVISION_NOTIFY ),
194+ CommonUtility .getWord (Constants .FIRMWARE_PROVISION_NOTIFY_HEADER ), Constants .FIREFLY_LUCIFERIN , TrayIcon .MessageType .ERROR );
173195 }
174196 }
175197 };
176- scheduler .scheduleAtFixedRate (checkAndRun , 0 , 500 , TimeUnit .MILLISECONDS );
177- if (!error .get ()) {
178- CommonUtility .closeCurrentStage (e );
198+ scheduler .scheduleAtFixedRate (checkAndRun , 100 , 2000 , TimeUnit .MILLISECONDS );
199+ }
200+
201+ /**
202+ * Send improv wifi msg
203+ *
204+ * @return error
205+ * @throws IOException can't open port
206+ */
207+ private boolean sendImprov () throws IOException {
208+ byte version = 0x01 ;
209+ byte rpcPacketType = 0x03 ;
210+ byte rpcCommandType = 0x01 ;
211+ byte [] ssidBytes = ssid .getValue ().getBytes (StandardCharsets .UTF_8 );
212+ byte [] passBytes = wifiPwd .getText ().getBytes (StandardCharsets .UTF_8 );
213+ int dataLen = 1 + ssidBytes .length + 1 + passBytes .length ;
214+ int packetLen = Constants .IMPROV_HEADER .length + 1 + 1 + 1 + 1 + 1 + dataLen + 1 ;
215+ byte [] packet = new byte [packetLen ];
216+ int idx = 0 ;
217+ // Header
218+ for (byte b : Constants .IMPROV_HEADER ) packet [idx ++] = b ;
219+ packet [idx ++] = version ;
220+ packet [idx ++] = rpcPacketType ;
221+ packet [idx ++] = (byte ) (dataLen + 2 );
222+ packet [idx ++] = rpcCommandType ;
223+ // Data
224+ packet [idx ++] = (byte ) (ssidBytes .length + passBytes .length );
225+ packet [idx ++] = (byte ) ssidBytes .length ;
226+ System .arraycopy (ssidBytes , 0 , packet , idx , ssidBytes .length );
227+ idx += ssidBytes .length ;
228+ packet [idx ++] = (byte ) passBytes .length ;
229+ System .arraycopy (passBytes , 0 , packet , idx , passBytes .length );
230+ idx += passBytes .length ;
231+ // Checksum
232+ int checksum = 0 ;
233+ for (int i = 0 ; i < idx ; i ++) {
234+ checksum += packet [i ] & 0xFF ;
179235 }
236+ byte checksumByte = (byte ) (checksum & 0xFF );
237+ packet [idx ] = checksumByte ;
238+ if (MainSingleton .getInstance ().output != null ) {
239+ log .debug ("Improv WiFi packet sent" );
240+ MainSingleton .getInstance ().improvActive = deviceName .getText ();
241+ MainSingleton .getInstance ().output .write (packet );
242+ } else {
243+ return true ;
244+ }
245+ return false ;
180246 }
181247
182248 /**
@@ -266,58 +332,4 @@ class NetworkInfo {
266332 }
267333 }
268334
269- /**
270- * Program device using the IMPROV WiFi protocol
271- *
272- * @return true if there is a serial error
273- */
274- public boolean improvWiFiCommand () {
275- SerialManager serialManager = new SerialManager ();
276- serialManager .closeSerial ();
277- serialManager .initSerial (comPort .getValue (), baudrate .getValue ());
278- try {
279- byte version = 0x01 ;
280- byte rpcPacketType = 0x03 ;
281- byte rpcCommandType = 0x01 ;
282- byte [] ssidBytes = ssid .getValue ().getBytes (StandardCharsets .UTF_8 );
283- byte [] passBytes = wifiPwd .getText ().getBytes (StandardCharsets .UTF_8 );
284- int dataLen = 1 + ssidBytes .length + 1 + passBytes .length ;
285- int packetLen = Constants .IMPROV_HEADER .length + 1 + 1 + 1 + 1 + 1 + dataLen + 1 ;
286- byte [] packet = new byte [packetLen ];
287- int idx = 0 ;
288- // Header
289- for (byte b : Constants .IMPROV_HEADER ) packet [idx ++] = b ;
290- packet [idx ++] = version ;
291- packet [idx ++] = rpcPacketType ;
292- packet [idx ++] = (byte ) (dataLen + 2 );
293- packet [idx ++] = rpcCommandType ;
294- // Data
295- packet [idx ++] = (byte ) (ssidBytes .length + passBytes .length );
296- packet [idx ++] = (byte ) ssidBytes .length ;
297- System .arraycopy (ssidBytes , 0 , packet , idx , ssidBytes .length );
298- idx += ssidBytes .length ;
299- packet [idx ++] = (byte ) passBytes .length ;
300- System .arraycopy (passBytes , 0 , packet , idx , passBytes .length );
301- idx += passBytes .length ;
302- // Checksum
303- int checksum = 0 ;
304- for (int i = 0 ; i < idx ; i ++) {
305- checksum += packet [i ] & 0xFF ;
306- }
307- byte checksumByte = (byte ) (checksum & 0xFF );
308- packet [idx ] = checksumByte ;
309- if (MainSingleton .getInstance ().output == null ) {
310- MainSingleton .getInstance ().guiManager .showLocalizedNotification (CommonUtility .getWord (Constants .FIRMWARE_PROVISION_NOTIFY ),
311- CommonUtility .getWord (Constants .FIRMWARE_PROVISION_NOTIFY_HEADER ), Constants .FIREFLY_LUCIFERIN , TrayIcon .MessageType .ERROR );
312- return true ;
313- } else {
314- MainSingleton .getInstance ().output .write (packet );
315- }
316- } catch (IOException ex ) {
317- log .error (ex .getMessage ());
318- return true ;
319- }
320- return false ;
321- }
322-
323335}
0 commit comments