Mercurial > 510Connectbot
view src/com/five_ten_sg/connectbot/transport/TN5250.java @ 29:017eeed8332c tn5250
start tn5250 integration
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Tue, 03 Jun 2014 16:02:29 -0700 |
parents | cfcb8d9859a8 |
children | d738f6b876fe |
line wrap: on
line source
/* * 510ConnectBot * Copyright 2014 Carl Byington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.five_ten_sg.connectbot.transport; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.tn5250j.framework.tn5250.Screen5250; import org.tn5250j.framework.tn5250.tnvt; import com.five_ten_sg.connectbot.R; import com.five_ten_sg.connectbot.bean.HostBean; import com.five_ten_sg.connectbot.bean.PortForwardBean; import com.five_ten_sg.connectbot.service.TerminalBridge; import com.five_ten_sg.connectbot.service.TerminalKeyListener; import com.five_ten_sg.connectbot.service.TerminalManager; import com.five_ten_sg.connectbot.util.HostDatabase; import android.content.Context; import android.net.Uri; import android.util.Log; import de.mud.terminal.vt320; /** * @author Carl Byington * */ public class TN5250 extends AbsTransport { private static final String PROTOCOL = "tn5250"; private static final String TAG = "ConnectBot.tn5250"; private static final int DEFAULT_PORT = 23; private Screen5250 screen52; private tnvt handler = null; private Socket socket; private int width; private int height; private boolean connected = false; static final Pattern hostmask; static { hostmask = Pattern.compile("^([0-9a-z.-]+)(:(\\d+))?$", Pattern.CASE_INSENSITIVE); } public TN5250() { super(); } public TN5250(HostBean host, TerminalBridge bridge, TerminalManager manager) { super(host, bridge, manager); } /** * @return protocol part of the URI */ public static String getProtocolName() { return PROTOCOL; } public Uri getUri(String input) { Matcher matcher = hostmask.matcher(input); if (!matcher.matches()) return null; StringBuilder sb = new StringBuilder(); sb.append(PROTOCOL) .append("://") .append(matcher.group(1)); String portString = matcher.group(3); int port = DEFAULT_PORT; if (portString != null) { try { port = Integer.parseInt(portString); if (port < 1 || port > 65535) { port = DEFAULT_PORT; } } catch (NumberFormatException nfe) { // Keep the default port } } if (port != DEFAULT_PORT) { sb.append(':'); sb.append(port); } sb.append("/#") .append(Uri.encode(input)); Uri uri = Uri.parse(sb.toString()); return uri; } /** * Causes transport to connect to the target host. After connecting but before a * session is started, must call back to {@link TerminalBridge#onConnected()}. * After that call a session may be opened. */ @Override public void connect() { screen52 = new Screen5250; handler = new tnvt(screen52, true, false, bridge, manager); connected = handler.connect(host.getHostname(), host.getPort()); if (connected) bridge.onConnected(); } /** * Checks if read() will block. If there are no bytes remaining in * the underlying transport, return true. */ @Override public boolean willBlock() { // we don't use a relay thread between the transport and the vt320 buffer return true; } /** * Reads from the transport. Transport must support reading into a byte array * <code>buffer</code> at the start of <code>offset</code> and a maximum of * <code>length</code> bytes. If the remote host disconnects, throw an * {@link IOException}. * @param buffer byte buffer to store read bytes into * @param offset where to start writing in the buffer * @param length maximum number of bytes to read * @return number of bytes read * @throws IOException when remote host disconnects */ public int read(byte[] buffer, int offset, int length) throws IOException { // we don't use a relay thread between the transport and the vt320 buffer return 0; } /** * Writes to the transport. If the host is not yet connected, simply return without * doing anything. An {@link IOException} should be thrown if there is an error after * connection. * @param buffer bytes to write to transport * @throws IOException when there is a problem writing after connection */ public void write(byte[] buffer) throws IOException { } /** * Writes to the transport. See {@link #write(byte[])} for behavior details. * @param c character to write to the transport * @throws IOException when there is a problem writing after connection */ public void write(int c) throws IOException { } /** * Flushes the write commands to the transport. * @throws IOException when there is a problem writing after connection */ public void flush() throws IOException { } /** * Closes the connection to the terminal. Note that the resulting failure to read * should call {@link TerminalBridge#dispatchDisconnect(boolean)}. !!! */ public void close() { handler.disconnect(); connected = false; } /** * Tells the transport what dimensions the display is currently * @param columns columns of text * @param rows rows of text * @param width width in pixels * @param height height in pixels */ @Override public void setDimensions(int columns, int rows, int width, int height) { // do nothing } public void setOptions(Map<String, String> options) { // do nothing } public Map<String, String> getOptions() { return null; } public void setCompression(boolean compression) { // do nothing } public void setHttpproxy(String httpproxy) { // do nothing } public void setUseAuthAgent(String useAuthAgent) { // do nothing } public void setEmulation(String emulation) { this.emulation = emulation; } public String getEmulation() { return emulation; } public void setHost(HostBean host) { this.host = host; } public void setBridge(TerminalBridge bridge) { this.bridge = bridge; } public void setManager(TerminalManager manager) { this.manager = manager; } /** * Whether or not this transport type can forward ports. * @return true on ability to forward ports */ public boolean canForwardPorts() { return false; } /** * Adds the {@link PortForwardBean} to the list. * @param portForward the port forward bean to add * @return true on successful addition */ public boolean addPortForward(PortForwardBean portForward) { return false; } /** * Enables a port forward member. After calling this method, the port forward should * be operational iff it could be enabled by the transport. * @param portForward member of our current port forwards list to enable * @return true on successful port forward setup */ public boolean enablePortForward(PortForwardBean portForward) { return false; } /** * Disables a port forward member. After calling this method, the port forward should * be non-functioning iff it could be disabled by the transport. * @param portForward member of our current port forwards list to enable * @return true on successful port forward tear-down */ public boolean disablePortForward(PortForwardBean portForward) { return false; } /** * Removes the {@link PortForwardBean} from the available port forwards. * @param portForward the port forward bean to remove * @return true on successful removal */ public boolean removePortForward(PortForwardBean portForward) { return false; } /** * Gets a list of the {@link PortForwardBean} currently used by this transport. * @return the list of port forwards */ public List<PortForwardBean> getPortForwards() { return null; } /** * Whether or not this transport type can transfer files. * @return true on ability to transfer files */ public boolean canTransferFiles() { return false; } /** * Downloads the specified remote file to a local folder. * @param remoteFile The path to the remote file to be downloaded. Must be non-null. * @param localFolder The path to local folder. Null = default external storage folder. * @return true on success, false on failure */ public boolean downloadFile(String remoteFile, String localFolder) { return false; } /** * Uploads the specified local file to the remote host. * @param localFile The path to the local file to be uploaded. Must be non-null. * @param remoteFolder The path to the remote directory. Null == default remote directory. * @return true on success, false on failure */ public boolean uploadFile(String localFile, String remoteFile, String remoteFolder, String mode) { return false; } @Override public int getDefaultPort() { return DEFAULT_PORT; } @Override public boolean isConnected() { return connected; } @Override public boolean isSessionOpen() { return connected; } @Override public boolean isAuthenticated() { return connected; } @Override public String getDefaultNickname(String username, String hostname, int port) { if (port == DEFAULT_PORT) { return String.format("%s", hostname); } else { return String.format("%s:%d", hostname, port); } } @Override public void getSelectionArgs(Uri uri, Map<String, String> selection) { selection.put(HostDatabase.FIELD_HOST_PROTOCOL, PROTOCOL); selection.put(HostDatabase.FIELD_HOST_NICKNAME, uri.getFragment()); selection.put(HostDatabase.FIELD_HOST_HOSTNAME, uri.getHost()); int port = uri.getPort(); if (port < 0) port = DEFAULT_PORT; selection.put(HostDatabase.FIELD_HOST_PORT, Integer.toString(port)); } @Override public HostBean createHost(Uri uri) { HostBean host = new HostBean(); host.setProtocol(PROTOCOL); host.setHostname(uri.getHost()); int port = uri.getPort(); if (port < 0) port = DEFAULT_PORT; host.setPort(port); String nickname = uri.getFragment(); if (nickname == null || nickname.length() == 0) { host.setNickname(getDefaultNickname(host.getUsername(), host.getHostname(), host.getPort())); } else { host.setNickname(uri.getFragment()); } return host; } public String getFormatHint(Context context) { return String.format("%s:%s", context.getString(R.string.format_hostname), context.getString(R.string.format_port)); } @Override public boolean usesNetwork() { return true; } @Override public boolean needsRelay() { // we don't use a relay thread between the transport and the vt320 buffer return false; } @Override public TerminalKeyListener(TerminalManager manager, TerminalBridge bridge, vt320 buffer, String encoding) { return new TerminalKeyListener(manager, bridge, buffer, encoding); } }