Skip to content

Commit 21203cb

Browse files
author
Federico Fissore
committed
introducing jsch. now network monitor uses SSH to trigger a telnet session at yun side
1 parent 4392938 commit 21203cb

File tree

11 files changed

+149
-53
lines changed

11 files changed

+149
-53
lines changed

app/lib/jsch-0.1.50.jar

248 KB
Binary file not shown.

app/src/cc/arduino/packages/uploaders/HttpUploader.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public boolean requiresAuthorization() {
5151
}
5252

5353
public String getAuthorizationKey() {
54-
return "pwd." + ipAddress;
54+
return "runtime.pwd." + ipAddress;
5555
}
5656

5757
@Override

app/src/processing/app/AbstractMonitor.java

+12-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import java.awt.event.ActionListener;
1212
import java.awt.event.WindowAdapter;
1313
import java.awt.event.WindowEvent;
14-
import java.io.IOException;
1514

1615
import static processing.app.I18n._;
1716

@@ -32,7 +31,7 @@ public AbstractMonitor(String title) {
3231
public void windowClosing(WindowEvent event) {
3332
try {
3433
close();
35-
} catch (IOException e) {
34+
} catch (Exception e) {
3635
// ignore
3736
}
3837
}
@@ -45,7 +44,7 @@ public void windowClosing(WindowEvent event) {
4544
public void actionPerformed(ActionEvent event) {
4645
try {
4746
close();
48-
} catch (IOException e) {
47+
} catch (Exception e) {
4948
// ignore
5049
}
5150
setVisible(false);
@@ -174,7 +173,15 @@ public void run() {
174173
});
175174
}
176175

177-
public abstract void open() throws IOException;
176+
public boolean requiresAuthorization() {
177+
return false;
178+
}
179+
180+
public String getAuthorizationKey() {
181+
return null;
182+
}
183+
184+
public abstract void open() throws Exception;
178185

179-
public abstract void close() throws IOException;
186+
public abstract void close() throws Exception;
180187
}

app/src/processing/app/Base.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ public boolean handleClose(Editor editor) {
924924
editors.remove(editor);
925925
try {
926926
Editor.serialMonitor.close();
927-
} catch (IOException e) {
927+
} catch (Exception e) {
928928
//ignore
929929
}
930930
storeSketches();
@@ -966,7 +966,7 @@ public boolean handleQuit() {
966966
storeSketches();
967967
try {
968968
Editor.serialMonitor.close();
969-
} catch (IOException e) {
969+
} catch (Exception e) {
970970
// ignore
971971
}
972972

app/src/processing/app/Editor.java

+42-14
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222

2323
package processing.app;
2424

25+
import com.jcraft.jsch.JSchException;
2526
import processing.app.debug.*;
27+
import processing.app.forms.PasswordAuthorizationDialog;
2628
import processing.app.syntax.*;
2729
import processing.app.tools.*;
2830
import processing.core.*;
@@ -704,7 +706,7 @@ public void actionPerformed(ActionEvent e) {
704706
JMenu boardsMenu = new JMenu(_("Board"));
705707
Editor.boardsMenus.add(boardsMenu);
706708
toolsMenu.add(boardsMenu);
707-
709+
708710
base.rebuildBoardsMenu(toolsMenu, this);
709711
//Debug: rebuild imports
710712
importMenu.removeAll();
@@ -969,7 +971,7 @@ protected void selectSerialPort(String name) {
969971
Preferences.set("serial.port.file", name);
970972
try {
971973
serialMonitor.close();
972-
} catch (IOException e) {
974+
} catch (Exception e) {
973975
// ignore
974976
}
975977
serialMonitor.setVisible(false);
@@ -983,14 +985,14 @@ protected void selectSerialPort(String name) {
983985

984986
protected void populatePortMenu() {
985987
serialMenu.removeAll();
986-
988+
987989
String selectedPort = Preferences.get("serial.port");
988-
990+
989991
List<BoardPort> ports = Base.getDiscoveryManager().discovery();
990992
for (BoardPort port : ports) {
991993
String address = port.getAddress();
992994
String label = port.getLabel();
993-
995+
994996
JCheckBoxMenuItem item = new JCheckBoxMenuItem(label, address.equals(selectedPort));
995997
item.addActionListener(new SerialMenuListener(address));
996998
serialMenu.add(item);
@@ -2490,14 +2492,39 @@ protected boolean handleExportCheckModified() {
24902492
public void handleSerial() {
24912493
if (uploading) return;
24922494

2493-
try {
2494-
serialMonitor.open();
2495-
serialMonitor.setVisible(true);
2496-
} catch (ConnectException e) {
2497-
statusError(_("Unable to connect: is the sketch using the bridge?"));
2498-
} catch (IOException e) {
2499-
statusError(e);
2500-
}
2495+
boolean success = false;
2496+
do {
2497+
if (serialMonitor.requiresAuthorization() && !Preferences.has(serialMonitor.getAuthorizationKey())) {
2498+
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(this, _("Type board password to access its console"));
2499+
dialog.setLocationRelativeTo(this);
2500+
dialog.setVisible(true);
2501+
2502+
if (dialog.isCancelled()) {
2503+
statusNotice(_("Unable to open serial monitor"));
2504+
return;
2505+
}
2506+
2507+
Preferences.set(serialMonitor.getAuthorizationKey(), dialog.getPassword());
2508+
}
2509+
2510+
try {
2511+
serialMonitor.open();
2512+
serialMonitor.setVisible(true);
2513+
success = true;
2514+
} catch (ConnectException e) {
2515+
statusError(_("Unable to connect: is the sketch using the bridge?"));
2516+
} catch (JSchException e) {
2517+
statusError(_("Unable to connect: wrong password?"));
2518+
} catch (Exception e) {
2519+
statusError(e);
2520+
} finally {
2521+
if (serialMonitor.requiresAuthorization() && !success) {
2522+
Preferences.remove(serialMonitor.getAuthorizationKey());
2523+
}
2524+
}
2525+
2526+
} while (serialMonitor.requiresAuthorization() && !success);
2527+
25012528
}
25022529

25032530

@@ -2522,7 +2549,8 @@ public void run() {
25222549
statusError(_("Error while burning bootloader."));
25232550
e.printStackTrace();
25242551
}
2525-
}});
2552+
}
2553+
});
25262554
}
25272555

25282556

+79-18
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
package processing.app;
22

3+
import com.jcraft.jsch.*;
34
import processing.app.debug.MessageSiphon;
45

56
import java.awt.event.ActionEvent;
67
import java.awt.event.ActionListener;
78
import java.io.IOException;
9+
import java.io.InputStream;
810
import java.io.OutputStream;
9-
import java.net.InetSocketAddress;
10-
import java.net.Socket;
1111
import java.util.regex.Matcher;
1212

13+
import static processing.app.I18n._;
14+
1315
@SuppressWarnings("serial")
1416
public class NetworkMonitor extends AbstractMonitor {
1517

1618
private final String ipAddress;
1719

18-
private Socket socket;
19-
private MessageSiphon consumer;
20+
private MessageSiphon inputConsumer;
21+
private Session session;
22+
private Channel channel;
23+
private MessageSiphon errorConsumer;
2024

2125
public NetworkMonitor(String port, Base base) {
2226
super(port);
@@ -28,7 +32,7 @@ public NetworkMonitor(String port, Base base) {
2832
onSendCommand(new ActionListener() {
2933
public void actionPerformed(ActionEvent event) {
3034
try {
31-
OutputStream out = socket.getOutputStream();
35+
OutputStream out = channel.getOutputStream();
3236
out.write(textField.getText().getBytes());
3337
out.write('\n');
3438
out.flush();
@@ -41,24 +45,81 @@ public void actionPerformed(ActionEvent event) {
4145
}
4246

4347
@Override
44-
public void open() throws IOException {
45-
try {
46-
socket = new Socket();
47-
socket.connect(new InetSocketAddress(ipAddress, 6571), 5000);
48-
consumer = new MessageSiphon(socket.getInputStream(), this);
49-
return;
50-
} catch (IOException e) {
51-
socket = null;
52-
throw e;
48+
public boolean requiresAuthorization() {
49+
return true;
50+
}
51+
52+
@Override
53+
public String getAuthorizationKey() {
54+
return "runtime.pwd." + ipAddress;
55+
}
56+
57+
@Override
58+
public void open() throws Exception {
59+
JSch jSch = new JSch();
60+
session = jSch.getSession("root", ipAddress, 22);
61+
session.setPassword(Preferences.get(getAuthorizationKey()));
62+
63+
session.setUserInfo(new NoInteractionUserInfo());
64+
session.connect(30000);
65+
66+
channel = session.openChannel("exec");
67+
((ChannelExec) channel).setCommand("telnet localhost 6571");
68+
69+
InputStream inputStream = channel.getInputStream();
70+
InputStream errStream = ((ChannelExec) channel).getErrStream();
71+
72+
channel.connect();
73+
74+
inputConsumer = new MessageSiphon(inputStream, this);
75+
errorConsumer = new MessageSiphon(errStream, this);
76+
}
77+
78+
@Override
79+
public void message(String s) {
80+
if (s.contains("can't connect")) {
81+
s = _("Unable to connect: is the sketch using the bridge?");
5382
}
83+
super.message(s); //To change body of overridden methods use File | Settings | File Templates.
5484
}
5585

5686
@Override
57-
public void close() throws IOException {
58-
if (socket != null) {
59-
consumer.stop();
60-
socket.close();
87+
public void close() throws Exception {
88+
if (channel != null) {
89+
inputConsumer.stop();
90+
channel.disconnect();
6191
textArea.setText("");
6292
}
93+
94+
if (session != null) {
95+
session.disconnect();
96+
}
97+
}
98+
99+
public static class NoInteractionUserInfo implements UserInfo {
100+
101+
public String getPassword() {
102+
return null;
103+
}
104+
105+
public boolean promptYesNo(String str) {
106+
return true;
107+
}
108+
109+
public String getPassphrase() {
110+
return null;
111+
}
112+
113+
public boolean promptPassphrase(String message) {
114+
return false;
115+
}
116+
117+
public boolean promptPassword(String message) {
118+
return false;
119+
}
120+
121+
public void showMessage(String message) {
122+
}
123+
63124
}
64125
}

app/src/processing/app/SerialMonitor.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
import java.awt.event.ActionEvent;
2424
import java.awt.event.ActionListener;
25-
import java.io.IOException;
2625

2726
import static processing.app.I18n._;
2827

@@ -49,10 +48,10 @@ public void actionPerformed(ActionEvent event) {
4948
close();
5049
Thread.sleep(100); // Wait for serial port to properly close
5150
open();
52-
} catch (IOException e) {
53-
System.err.println(e);
5451
} catch (InterruptedException e) {
55-
e.printStackTrace();
52+
// noop
53+
} catch (Exception e) {
54+
System.err.println(e);
5655
}
5756
}
5857
});
@@ -82,14 +81,14 @@ private void send(String s) {
8281
}
8382
}
8483

85-
public void open() throws IOException {
84+
public void open() throws Exception {
8685
if (serial != null) return;
8786

8887
serial = new Serial(port, serialRate);
8988
serial.addListener(this);
9089
}
9190

92-
public void close() throws IOException {
91+
public void close() throws Exception {
9392
if (serial != null) {
9493
int[] location = getPlacement();
9594
String locationStr = PApplet.join(PApplet.str(location), ",");

app/src/processing/app/Sketch.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1671,7 +1671,7 @@ protected boolean upload(String buildPath, String suggestedClassName, boolean us
16711671
boolean success = false;
16721672
do {
16731673
if (uploader.requiresAuthorization() && !Preferences.has(uploader.getAuthorizationKey())) {
1674-
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor);
1674+
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor, _("Type board password to upload a new sketch"));
16751675
dialog.setLocationRelativeTo(editor);
16761676
dialog.setVisible(true);
16771677

@@ -1680,7 +1680,7 @@ protected boolean upload(String buildPath, String suggestedClassName, boolean us
16801680
return false;
16811681
}
16821682

1683-
Preferences.set(uploader.getAuthorizationKey(), DigestUtils.sha256Hex(dialog.getPassword()));
1683+
Preferences.set(uploader.getAuthorizationKey(), dialog.getPassword());
16841684
}
16851685

16861686
try {

app/src/processing/app/forms/PasswordAuthorizationDialog.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class PasswordAuthorizationDialog extends JDialog {
2222
protected boolean cancelled;
2323
protected String password;
2424

25-
public PasswordAuthorizationDialog(Frame parent) {
25+
public PasswordAuthorizationDialog(Frame parent, String dialogText) {
2626
super(parent, true);
2727

2828
this.cancelled = false;
@@ -37,7 +37,7 @@ public PasswordAuthorizationDialog(Frame parent) {
3737

3838
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
3939

40-
typePasswordLabel.setText(_("Type board password to upload a new sketch"));
40+
typePasswordLabel.setText(dialogText);
4141

4242
icon.setIcon(new ImageIcon(new File(Base.getContentFile("lib"), "theme/lock.png").getAbsolutePath()));
4343

0 commit comments

Comments
 (0)