GUACAMOLE-860: [WIP] Interim changes for TN5250 support.

This commit is contained in:
Nick Couchman 2019-08-17 22:04:43 -04:00
parent e1d28d7dee
commit 39a1c25e9b
5 changed files with 117 additions and 25 deletions

2
.gitignore vendored
View File

@ -46,3 +46,5 @@ stamp-h1
# Generated docs # Generated docs
doc/doxygen-output doc/doxygen-output
# IDE Configuration
nbproject/

View File

@ -126,6 +126,10 @@ struct sna_flags {
} sna_flags; } sna_flags;
/**
* Defines the structure of a TN5250 (SNA over Telnet) packet, including
* the fields and the length of each field, as described in RFC1205.
*/
struct sna_packet { struct sna_packet {
/** /**

View File

@ -40,7 +40,8 @@
/** /**
* Support levels for various telnet options, required for connection * Support levels for various telnet options, required for connection
* negotiation by telnet_init(), part of libtelnet. * negotiation by telnet_init(), part of libtelnet. The TN5250 specification
* requires at EOR, BINARY, and TTYPE.
*/ */
static const telnet_telopt_t __telnet_options[] = { static const telnet_telopt_t __telnet_options[] = {
{ TELNET_TELOPT_ECHO, TELNET_WONT, TELNET_DO }, { TELNET_TELOPT_ECHO, TELNET_WONT, TELNET_DO },
@ -55,6 +56,7 @@ static const telnet_telopt_t __telnet_options[] = {
}; };
/** /**
* ***Should be abstracted to common telnet support.***
* Write the entire buffer given to the specified file descriptor, retrying * Write the entire buffer given to the specified file descriptor, retrying
* the write automatically if necessary. This function will return a value * the write automatically if necessary. This function will return a value
* not equal to the buffer's size iff an error occurs which prevents all * not equal to the buffer's size iff an error occurs which prevents all
@ -74,7 +76,7 @@ static int __guac_telnet_write_all(int fd, const char* buffer, int size) {
if (ret_val <= 0) if (ret_val <= 0)
return -1; return -1;
/* If successful, contine with what data remains (if any) */ /* If successful, continue with what data remains (if any) */
remaining -= ret_val; remaining -= ret_val;
buffer += ret_val; buffer += ret_val;
@ -201,6 +203,7 @@ static void* __guac_tn5250_input_thread(void* data) {
} }
/** /**
* ***Abstract to common telnet code.***
* Connects to the telnet server specified within the data associated * Connects to the telnet server specified within the data associated
* with the given guac_client, which will have been populated by * with the given guac_client, which will have been populated by
* guac_client_init. * guac_client_init.
@ -328,13 +331,6 @@ static void __guac_tn5250_send_uint8(telnet_t* telnet, uint8_t value) {
telnet_send(telnet, (char*) (&value), 1); telnet_send(telnet, (char*) (&value), 1);
} }
void guac_tn5250_send_naws(telnet_t* telnet, uint16_t width, uint16_t height) {
telnet_begin_sb(telnet, TELNET_TELOPT_NAWS);
__guac_tn5250_send_uint16(telnet, width);
__guac_tn5250_send_uint16(telnet, height);
telnet_finish_sb(telnet);
}
void guac_tn5250_send_user(telnet_t* telnet, const char* username) { void guac_tn5250_send_user(telnet_t* telnet, const char* username) {
/* IAC SB NEW-ENVIRON IS */ /* IAC SB NEW-ENVIRON IS */
@ -404,6 +400,8 @@ void* guac_tn5250_client_thread(void* data) {
settings->recording_include_keys); settings->recording_include_keys);
} }
/* Calculate required terminal size based on type. */
/* Create terminal */ /* Create terminal */
tn5250_client->term = guac_terminal_create(client, tn5250_client->term = guac_terminal_create(client,
tn5250_client->clipboard, settings->disable_copy, tn5250_client->clipboard, settings->disable_copy,
@ -476,10 +474,83 @@ void* guac_tn5250_client_thread(void* data) {
void __guac_tn5250_send_sna_packet(void* data, tn5250_flags flags, void __guac_tn5250_send_sna_packet(void* data, tn5250_flags flags,
unsigned char opcode, char* data) { unsigned char opcode, char* data) {
/**
* Things to do, here:
* - Put the TN5250 header on
* - Set any flags
* - Set the Opcode
* - Write data
* - Write EOR
*/
} }
void __guac_tn5250_recv_sna_packet(guac_client* client, telnet_event_t* event) { void __guac_tn5250_recv_sna_packet(guac_client* client, telnet_event_t* event) {
/**
* Things to do, here:
* - Check for TN5250 header
* - Take off flags and process
* - Examine Opcode and handle (switch)
* - Read data and handle it (while)
* - Look for EOR (while)
*/
/* Look for TN5250 header - abort if not found. */
/* Grab flags */
/* Process Opcode */
switch (opcode) {
case OPCODE_NOOP:
break;
case OPCODE_INVITE:
break;
case OPCODE_OUTPUT:
break;
case OPCODE_PUT_GET:
break;
case OPCODE_SAVE_SCREEN:
break;
case OPCODE_RESTORE_SCREEN:
break;
case OPCODE_READ_IMMEDIATE:
break:
case OPCODE_READ_SCREEN:
break;
case OPCODE_CANCEL_INVITE:
break;
case OPCODE_MSG_ON:
break;
case OPCODE_MSG_OFF:
break;
default:
}
} }

View File

@ -37,23 +37,23 @@
typedef struct guac_tn5250_client { typedef struct guac_tn5250_client {
/** /**
* Telnet connection settings. * TN5250 connection settings.
*/ */
guac_tn5250_settings* settings; guac_tn5250_settings* settings;
/** /**
* The telnet client thread. * The tn5250 client thread.
*/ */
pthread_t client_thread; pthread_t client_thread;
/** /**
* The file descriptor of the socket connected to the telnet server, * The file descriptor of the socket connected to the tn5250 server,
* or -1 if no connection has been established. * or -1 if no connection has been established.
*/ */
int socket_fd; int socket_fd;
/** /**
* Telnet connection, used by the telnet client thread. * telnet connection, used by the tn5250 client thread.
*/ */
telnet_t* telnet; telnet_t* telnet;
@ -74,7 +74,7 @@ typedef struct guac_tn5250_client {
guac_common_clipboard* clipboard; guac_common_clipboard* clipboard;
/** /**
* The terminal which will render all output from the telnet client. * The terminal which will render all output from the tn5250 client.
*/ */
guac_terminal* term; guac_terminal* term;
@ -86,20 +86,23 @@ typedef struct guac_tn5250_client {
} guac_tn5250_client; } guac_tn5250_client;
/**
* Possible Opcodes that can be sent by the mainframe or the client.
*/
unsigned char tn5250_opcodes[] = { unsigned char tn5250_opcodes[] = {
0x00, /* No operation */ OPCODE_NOOP, /* No operation */
0x01, /* Invite */ OPCODE_INVITE, /* Invite */
0x02, /* Output only */ OPCODE_OUTPUT, /* Output only */
0x03, /* Put/Get */ OPCODE_PUT_GET, /* Put/Get */
0x04, /* Save screen */ OPCODE_SAVE_SCREEN, /* Save screen */
0x05, /* Restore screen */ OPCODE_RESTORE_SCREEN, /* Restore screen */
0x06, /* Read immediate */ OPCODE_READ_IMMEDIATE, /* Read immediate */
0x07, /* Reserved */ 0x07, /* Reserved */
0x08, /* Read screen */ OPCODE_READ_SCREEN, /* Read screen */
0x09, /* Reserved */ 0x09, /* Reserved */
0x0a, /* Cancel invite */ OPCODE_CANCEL_INVITE, /* Cancel invite */
0x0b, /* Turn on message light */ OPCODE_MSG_ON, /* Turn on message light */
0x0c, /* Turn off message light */ OPCODE_MSG_OFF, /* Turn off message light */
NULL NULL
} }

View File

@ -824,6 +824,18 @@ int guac_terminal_write(guac_terminal* term, const char* c, int size);
/** /**
* Sets the character at the given row and column to the specified value. * Sets the character at the given row and column to the specified value.
*
* @param term
* The guac_terminal to manipulate.
*
* @param row
* The row on which the character is located.
*
* @param col
* THe column in which the character is located.
*
* @param codepoint
* The value to set.
*/ */
int guac_terminal_set(guac_terminal* term, int row, int col, int codepoint); int guac_terminal_set(guac_terminal* term, int row, int col, int codepoint);