From 04d21a878ae0dcf7f3562b8701d2ae6b2870b855 Mon Sep 17 00:00:00 2001 From: y4my4my4m <8145020+y4my4my4m@users.noreply.github.com> Date: Thu, 18 May 2023 01:30:42 +0900 Subject: [PATCH] negotiation fix --- src/Home/Net/Programs/Telnet/Telnet.ZC | 37 +++--- .../Net/Programs/Telnet/TelnetNegotiation.ZC | 106 ++++++++++++------ 2 files changed, 94 insertions(+), 49 deletions(-) diff --git a/src/Home/Net/Programs/Telnet/Telnet.ZC b/src/Home/Net/Programs/Telnet/Telnet.ZC index c99c0021..14a6c78d 100644 --- a/src/Home/Net/Programs/Telnet/Telnet.ZC +++ b/src/Home/Net/Programs/Telnet/Telnet.ZC @@ -85,7 +85,7 @@ U0 HandleControlCodes(U8 ch) { SysLog("Vertical Tab\n"); break; case 12: // FF (Form Feed) - SysLog("form feed"); + // SysLog("form feed\n"); DocClear(term.doc); // DocPrint(term.doc, "\f"); break; @@ -216,24 +216,27 @@ U0 ANSIParse() } else if (ansi_code[0] == 6) { // Respond with cursor position - // U8 response[32] = "\x1B[%d;%dR", window_width, window_height; + // U8 response[7] = "\x1B[%d;%dR", term.window_width, term.window_height; SysLog("reported cursor position\n"); - U8 cursorResponse[8]; + // TODO: hardcoded the position 80x24 + // U8 response[9] = "\x1B[80;24R"; + // if (term.sock_ready) TCPSocketSend(term.sock, response, 9); + U8 cursorResponse[9]; cursorResponse[0] = ANSI_ESC; - cursorResponse[1] = ANSI_CSI; - cursorResponse[2] = 0x32; - cursorResponse[3] = 0x35; - cursorResponse[4] = 0x3B; - cursorResponse[5] = 0x38; - cursorResponse[6] = 0x30; - cursorResponse[6] = 0x52; - cursorResponse[7] = 0x00; - if (term.sock_ready) TCPSocketSend(term.sock, cursorResponse, 7); + cursorResponse[1] = '['; // Start of CSI + cursorResponse[2] = '2'; // First digit of "24" + cursorResponse[3] = '4'; // Second digit of "24" + cursorResponse[4] = ';'; // Separator + cursorResponse[5] = '8'; // First digit of "80" + cursorResponse[6] = '0'; // Second digit of "80" + cursorResponse[7] = 'R'; // End of CPR + cursorResponse[8] = 0x00; // Null-terminator + if (term.sock_ready) TCPSocketSend(term.sock, cursorResponse, 9); } else if (ansi_code[0] == 255) { // https://github.com/NuSkooler/enigma-bbs/blob/97cd0c3063b0c9f93a0fa4a44a85318ca81aef43/core/ansi_term.js#L140 SysLog("reported screensize?\n"); - SendWindowSize(term.sock, 25, 80); + // SendWindowSize(term.sock, 80, 25); } ptr++; break; @@ -254,8 +257,8 @@ U0 ANSIParse() ptr++; break; case 'm': - // colors might be printed in the wrong order? - // like, [1;40m and now [40m;1m + // TODO: what happens in this case??? --> [0;1;34;44m + I64 m; Bool isBright = FALSE; for (m = 0; m <= ansi_param_count; m++) { @@ -506,7 +509,7 @@ U0 ANSIParse() // break; // } - SysLog("H or f row:%d, col:%d, cnt:%d\n", row, col, ansi_param_count); + // SysLog("H or f row:%d, col:%d, cnt:%d\n", row, col, ansi_param_count); // Adjust the position based on the window size @@ -713,7 +716,7 @@ receive_data: // parse the buffer ANSIParse; } else { - SysLog("BUF_SIZE: %d\n", BUF_SIZE); + //SysLog("BUF_SIZE: %d\n", BUF_SIZE); if (!term.sock_ready || force_disconnect) DocPrint(term.doc, "Error: Connection closed by the remote host.\n"); else diff --git a/src/Home/Net/Programs/Telnet/TelnetNegotiation.ZC b/src/Home/Net/Programs/Telnet/TelnetNegotiation.ZC index 642fe558..3507131d 100644 --- a/src/Home/Net/Programs/Telnet/TelnetNegotiation.ZC +++ b/src/Home/Net/Programs/Telnet/TelnetNegotiation.ZC @@ -9,6 +9,7 @@ #define LINEMODE 0x22 #define NAWS 0x1F // (Negotiate About Window Size) #define IS 0x00 +#define SEND 0x01 #define SB 0xFA #define SE 0xF0 @@ -28,14 +29,33 @@ // #define TELNET_BRK 243 /* 0xf3 - Break */ // #define TELNET_SYNC 242 /* 0xf2 - Data mark */ // #define TELNET_NOP 241 /* 0xf1 - No operation */ +#define SE_END 240 -U0 SendWindowSize(I64 sock, U16 rows, U16 cols) +// #define TELNET_NAWS 31 +// #define TELNET_TERMINAL_TYPE 24 +#define SEND_LOCATION 23 +#define BINARY_TRANSMISSION 0 + + + +U0 TelnetRequest(I64 sock, U8 option_code) +{ + U8 request[3]; + request[0] = IAC; + request[1] = WILL; + request[2] = option_code; + + TCPSocketSend(sock, request, 3); +} + +U0 SendWindowSize(I64 sock, U16 cols, U16 rows) { U8 buf[9]; buf[0] = IAC; buf[1] = SB; buf[2] = NAWS; + // if dynamic resolution, make sure to account for 255 AIC (byte stuffing needs to be done) buf[3] = cols >> 8; // High byte of columns buf[4] = cols & 0xFF; // Low byte of columns buf[5] = rows >> 8; // High byte of rows @@ -44,42 +64,66 @@ U0 SendWindowSize(I64 sock, U16 rows, U16 cols) buf[8] = SE; SysLog("SendWindowSize: %d x %d\n", cols, rows); - TCPSocketSendString(sock, buf); + TCPSocketSend(sock, buf, 9); } -U0 SendTerminalType(I64 sock, U8 *terminal_type) +U0 SendTerminalType(I64 sock) { - U8 response[256]; - I64 len = StrLen(terminal_type); + + U8 response[14]; response[0] = IAC; response[1] = SB; response[2] = TERMINAL_TYPE; response[3] = IS; - MemCopy(response + 4, terminal_type, len); - SysLog("SendTerminalType: %s\n", terminal_type); + response[4] = 'A'; + response[5] = 'N'; + response[6] = 'S'; + response[7] = 'I'; + response[8] = '-'; + response[9] = 'B'; + response[10] = 'B'; + response[11] = 'S'; - response[len + 4] = IAC; - response[len + 5] = SE; - response[len + 6] = '\0'; - TCPSocketSendString(sock, response); + response[12] = IAC; + response[13] = SE; + + SysLog("SendTerminalType: ANSI-BBS\n"); + TCPSocketSend(sock, response, 14); } -U0 TelnetNegotiate(I64 sock, U8 ptr) +U0 TelnetNegotiate(I64 sock, U8 *ptr) { U8 negotiation_code = *(ptr + 1); U8 option_code = *(ptr + 2); - // Send a response to the server - U8 response[4]; - response[0] = IAC; + + SysLog("Negotiation code: %d | Option code: %d\n", negotiation_code, option_code); + // Check if this is a subnegotiation request + if (negotiation_code == SB) + { + SysLog("SB: %d\n", option_code); + if (option_code == TERMINAL_TYPE && *(ptr + 3) == SEND) + { + SendTerminalType(sock); + } + else if (option_code == NAWS && *(ptr + 3) == SEND) + { + SendWindowSize(sock, 80, 25); + } + return; + } + + // Otherwise, handle it as a normal negotiation... + U8 response[3]; + response[0] = IAC; if (negotiation_code == DO || negotiation_code == DONT) { if (option_code == ECHO) { - if (negotiation_code == DO) + if (negotiation_code == DO || negotiation_code == WILL) { response[1] = WILL; } @@ -101,23 +145,29 @@ U0 TelnetNegotiate(I64 sock, U8 ptr) } else if (option_code == TERMINAL_TYPE) { + SysLog("TERMINAL_TYPE negotiation\n"); if (negotiation_code == DO) { + SysLog("TERMINAL_TYPE WILL\n"); response[1] = WILL; } else { + SysLog("TERMINAL_TYPE WONT\n"); response[1] = WONT; } } else if (option_code == NAWS) { - if (negotiation_code == DO) + SysLog("NAWS negotiation\n"); + if (negotiation_code == DO || negotiation_code == WILL) { + SysLog("NAWS WILL\n"); response[1] = WILL; } else { + SysLog("NAWS WONT\n"); response[1] = WONT; } } @@ -139,22 +189,14 @@ U0 TelnetNegotiate(I64 sock, U8 ptr) } else { - response[1] = DONT; + response[1] = WONT; } response[2] = option_code; - response[3] = '\0'; - - if (term.sock_ready) - { - TCPSocketSendString(sock, response); - // the bugged out SendTerminalType and SendWindowsSize was what crashed the BBS... - if (option_code == TERMINAL_TYPE) SendTerminalType(sock, "ANSI-BBS"); - else if (option_code == NAWS) SendWindowSize(sock, 25, 80); - - // send out the dimension regardless - TCPSocketSendString(term.sock, "\x1B[8;25;80t"); - // TCPSocketSendString(term.sock, "\xdb\b \xdb\b \xdb\b[\xdb\b[\xdb\b \xdb\bM\xdb\ba\xdb\bi\xdb\bn\xdb\bt\xdb\be\xdb\bn\xdb\ba\xdb\bn\xdb\bc\xdb\be\xdb\b \xdb\bC\xdb\bo\xdb\bm\xdb\bp\xdb\bl\xdb\be\xdb\bt\xdb\be\xdb\b \xdb\b]\xdb\b]\xdb\b \b\r\n\r\n\x1b[0m\x1b[2J\r\n\r\n\x1b[0;1;30mHX Force retinal scan in progress ... \x1b[0;0;30m"); - // TCPSocketSendString(term.sock, "\033[s\033[99B\033[99B\033[99B_\033[99C\033[99C\033[99C_\033[6n\033[u\033[0m_\033[2J\033[H"); - } + TCPSocketSend(sock, response, 3); + // if (option_code == NAWS && negotiation_code == DO) + // { + // SysLog("Sending NAWS right away\n"); + // SendWindowSize(sock, 80, 25); + // } } \ No newline at end of file