GUACAMOLE-860: [WIP] Interim changes for TN5250 support.
This commit is contained in:
parent
e1d28d7dee
commit
39a1c25e9b
2
.gitignore
vendored
2
.gitignore
vendored
@ -46,3 +46,5 @@ stamp-h1
|
|||||||
# Generated docs
|
# Generated docs
|
||||||
doc/doxygen-output
|
doc/doxygen-output
|
||||||
|
|
||||||
|
# IDE Configuration
|
||||||
|
nbproject/
|
@ -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 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user