1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-11-28 09:24:14 +01:00

introducing jsch. now network monitor uses SSH to trigger a telnet session at yun side

This commit is contained in:
Federico Fissore 2013-06-11 15:02:10 +02:00
parent 4392938f6a
commit 21203cbe1b
11 changed files with 150 additions and 54 deletions

BIN
app/lib/jsch-0.1.50.jar Normal file

Binary file not shown.

View File

@ -51,7 +51,7 @@ public class HttpUploader extends Uploader {
}
public String getAuthorizationKey() {
return "pwd." + ipAddress;
return "runtime.pwd." + ipAddress;
}
@Override

View File

@ -11,7 +11,6 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import static processing.app.I18n._;
@ -32,7 +31,7 @@ public abstract class AbstractMonitor extends JFrame implements MessageConsumer
public void windowClosing(WindowEvent event) {
try {
close();
} catch (IOException e) {
} catch (Exception e) {
// ignore
}
}
@ -45,7 +44,7 @@ public abstract class AbstractMonitor extends JFrame implements MessageConsumer
public void actionPerformed(ActionEvent event) {
try {
close();
} catch (IOException e) {
} catch (Exception e) {
// ignore
}
setVisible(false);
@ -174,7 +173,15 @@ public abstract class AbstractMonitor extends JFrame implements MessageConsumer
});
}
public abstract void open() throws IOException;
public boolean requiresAuthorization() {
return false;
}
public abstract void close() throws IOException;
public String getAuthorizationKey() {
return null;
}
public abstract void open() throws Exception;
public abstract void close() throws Exception;
}

View File

@ -924,7 +924,7 @@ public class Base {
editors.remove(editor);
try {
Editor.serialMonitor.close();
} catch (IOException e) {
} catch (Exception e) {
//ignore
}
storeSketches();
@ -966,7 +966,7 @@ public class Base {
storeSketches();
try {
Editor.serialMonitor.close();
} catch (IOException e) {
} catch (Exception e) {
// ignore
}

View File

@ -22,7 +22,9 @@
package processing.app;
import com.jcraft.jsch.JSchException;
import processing.app.debug.*;
import processing.app.forms.PasswordAuthorizationDialog;
import processing.app.syntax.*;
import processing.app.tools.*;
import processing.core.*;
@ -704,7 +706,7 @@ public class Editor extends JFrame implements RunnerListener {
JMenu boardsMenu = new JMenu(_("Board"));
Editor.boardsMenus.add(boardsMenu);
toolsMenu.add(boardsMenu);
base.rebuildBoardsMenu(toolsMenu, this);
//Debug: rebuild imports
importMenu.removeAll();
@ -969,7 +971,7 @@ public class Editor extends JFrame implements RunnerListener {
Preferences.set("serial.port.file", name);
try {
serialMonitor.close();
} catch (IOException e) {
} catch (Exception e) {
// ignore
}
serialMonitor.setVisible(false);
@ -983,14 +985,14 @@ public class Editor extends JFrame implements RunnerListener {
protected void populatePortMenu() {
serialMenu.removeAll();
String selectedPort = Preferences.get("serial.port");
List<BoardPort> ports = Base.getDiscoveryManager().discovery();
for (BoardPort port : ports) {
String address = port.getAddress();
String label = port.getLabel();
JCheckBoxMenuItem item = new JCheckBoxMenuItem(label, address.equals(selectedPort));
item.addActionListener(new SerialMenuListener(address));
serialMenu.add(item);
@ -2490,14 +2492,39 @@ public class Editor extends JFrame implements RunnerListener {
public void handleSerial() {
if (uploading) return;
try {
serialMonitor.open();
serialMonitor.setVisible(true);
} catch (ConnectException e) {
statusError(_("Unable to connect: is the sketch using the bridge?"));
} catch (IOException e) {
statusError(e);
}
boolean success = false;
do {
if (serialMonitor.requiresAuthorization() && !Preferences.has(serialMonitor.getAuthorizationKey())) {
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(this, _("Type board password to access its console"));
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
if (dialog.isCancelled()) {
statusNotice(_("Unable to open serial monitor"));
return;
}
Preferences.set(serialMonitor.getAuthorizationKey(), dialog.getPassword());
}
try {
serialMonitor.open();
serialMonitor.setVisible(true);
success = true;
} catch (ConnectException e) {
statusError(_("Unable to connect: is the sketch using the bridge?"));
} catch (JSchException e) {
statusError(_("Unable to connect: wrong password?"));
} catch (Exception e) {
statusError(e);
} finally {
if (serialMonitor.requiresAuthorization() && !success) {
Preferences.remove(serialMonitor.getAuthorizationKey());
}
}
} while (serialMonitor.requiresAuthorization() && !success);
}
@ -2522,7 +2549,8 @@ public class Editor extends JFrame implements RunnerListener {
statusError(_("Error while burning bootloader."));
e.printStackTrace();
}
}});
}
});
}

View File

@ -1,22 +1,26 @@
package processing.app;
import com.jcraft.jsch.*;
import processing.app.debug.MessageSiphon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.regex.Matcher;
import static processing.app.I18n._;
@SuppressWarnings("serial")
public class NetworkMonitor extends AbstractMonitor {
private final String ipAddress;
private Socket socket;
private MessageSiphon consumer;
private MessageSiphon inputConsumer;
private Session session;
private Channel channel;
private MessageSiphon errorConsumer;
public NetworkMonitor(String port, Base base) {
super(port);
@ -28,7 +32,7 @@ public class NetworkMonitor extends AbstractMonitor {
onSendCommand(new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
OutputStream out = socket.getOutputStream();
OutputStream out = channel.getOutputStream();
out.write(textField.getText().getBytes());
out.write('\n');
out.flush();
@ -41,24 +45,81 @@ public class NetworkMonitor extends AbstractMonitor {
}
@Override
public void open() throws IOException {
try {
socket = new Socket();
socket.connect(new InetSocketAddress(ipAddress, 6571), 5000);
consumer = new MessageSiphon(socket.getInputStream(), this);
return;
} catch (IOException e) {
socket = null;
throw e;
}
public boolean requiresAuthorization() {
return true;
}
@Override
public void close() throws IOException {
if (socket != null) {
consumer.stop();
socket.close();
public String getAuthorizationKey() {
return "runtime.pwd." + ipAddress;
}
@Override
public void open() throws Exception {
JSch jSch = new JSch();
session = jSch.getSession("root", ipAddress, 22);
session.setPassword(Preferences.get(getAuthorizationKey()));
session.setUserInfo(new NoInteractionUserInfo());
session.connect(30000);
channel = session.openChannel("exec");
((ChannelExec) channel).setCommand("telnet localhost 6571");
InputStream inputStream = channel.getInputStream();
InputStream errStream = ((ChannelExec) channel).getErrStream();
channel.connect();
inputConsumer = new MessageSiphon(inputStream, this);
errorConsumer = new MessageSiphon(errStream, this);
}
@Override
public void message(String s) {
if (s.contains("can't connect")) {
s = _("Unable to connect: is the sketch using the bridge?");
}
super.message(s); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public void close() throws Exception {
if (channel != null) {
inputConsumer.stop();
channel.disconnect();
textArea.setText("");
}
if (session != null) {
session.disconnect();
}
}
public static class NoInteractionUserInfo implements UserInfo {
public String getPassword() {
return null;
}
public boolean promptYesNo(String str) {
return true;
}
public String getPassphrase() {
return null;
}
public boolean promptPassphrase(String message) {
return false;
}
public boolean promptPassword(String message) {
return false;
}
public void showMessage(String message) {
}
}
}

View File

@ -22,7 +22,6 @@ import processing.core.PApplet;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import static processing.app.I18n._;
@ -49,10 +48,10 @@ public class SerialMonitor extends AbstractMonitor {
close();
Thread.sleep(100); // Wait for serial port to properly close
open();
} catch (IOException e) {
System.err.println(e);
} catch (InterruptedException e) {
e.printStackTrace();
// noop
} catch (Exception e) {
System.err.println(e);
}
}
});
@ -82,14 +81,14 @@ public class SerialMonitor extends AbstractMonitor {
}
}
public void open() throws IOException {
public void open() throws Exception {
if (serial != null) return;
serial = new Serial(port, serialRate);
serial.addListener(this);
}
public void close() throws IOException {
public void close() throws Exception {
if (serial != null) {
int[] location = getPlacement();
String locationStr = PApplet.join(PApplet.str(location), ",");

View File

@ -1671,7 +1671,7 @@ public class Sketch {
boolean success = false;
do {
if (uploader.requiresAuthorization() && !Preferences.has(uploader.getAuthorizationKey())) {
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor);
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor, _("Type board password to upload a new sketch"));
dialog.setLocationRelativeTo(editor);
dialog.setVisible(true);
@ -1680,7 +1680,7 @@ public class Sketch {
return false;
}
Preferences.set(uploader.getAuthorizationKey(), DigestUtils.sha256Hex(dialog.getPassword()));
Preferences.set(uploader.getAuthorizationKey(), dialog.getPassword());
}
try {

View File

@ -22,7 +22,7 @@ public class PasswordAuthorizationDialog extends JDialog {
protected boolean cancelled;
protected String password;
public PasswordAuthorizationDialog(Frame parent) {
public PasswordAuthorizationDialog(Frame parent, String dialogText) {
super(parent, true);
this.cancelled = false;
@ -37,7 +37,7 @@ public class PasswordAuthorizationDialog extends JDialog {
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
typePasswordLabel.setText(_("Type board password to upload a new sketch"));
typePasswordLabel.setText(dialogText);
icon.setIcon(new ImageIcon(new File(Base.getContentFile("lib"), "theme/lock.png").getAbsolutePath()));

View File

@ -24,13 +24,14 @@
<fileset dir=".." id="runtime.jars">
<include name="core/core.jar" />
<include name="app/pde.jar" />
<include name="app/lib/ecj.jar" />
<include name="app/lib/commons-codec-1.7.jar" />
<include name="app/lib/commons-exec-1.1.jar" />
<include name="app/lib/commons-httpclient-3.1.jar" />
<include name="app/lib/commons-logging-1.0.4.jar" />
<include name="app/lib/ecj.jar" />
<include name="app/lib/jmdns-3.4.1.jar" />
<include name="app/lib/jna.jar" />
<include name="app/lib/jsch-0.1.50.jar" />
<include name="app/lib/RXTXcomm.jar" />
<include name="app/lib/ant.jar" />
<include name="app/lib/ant-launcher.jar" />

View File

@ -70,13 +70,13 @@
<string>processing.app.Base</string>
<key>JVMVersion</key>
<string>1.5*</string>
<string>1.6*</string>
<key>ClassPath</key>
<!-- In 0149, removed /System/Library/Java from the CLASSPATH because
it can cause problems if users have installed weird files there.
http://dev.processing.org/bugs/show_bug.cgi?id=1045 -->
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/RXTXcomm.jar:$JAVAROOT/commons-codec-1.7.jar:$JAVAROOT/commons-exec-1.1.jar:$JAVAROOT/commons-httpclient-3.1.jar:$JAVAROOT/commons-logging-1.0.4.jar:$JAVAROOT/jmdns-3.4.1.jar</string>
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/RXTXcomm.jar:$JAVAROOT/commons-codec-1.7.jar:$JAVAROOT/commons-exec-1.1.jar:$JAVAROOT/commons-httpclient-3.1.jar:$JAVAROOT/commons-logging-1.0.4.jar:$JAVAROOT/jmdns-3.4.1.jar:$JAVAROOT/jsch-0.1.50.jar</string>
<key>JVMArchs</key>
<array>