From 37c97498ca1575a4de6ecf952fa2895c75fad7b5 Mon Sep 17 00:00:00 2001 From: nishi Date: Thu, 13 Jun 2024 03:30:36 +0000 Subject: [PATCH] modem works git-svn-id: file:///raid/svn-main/nishi-dataworks/trunk@289 d4a5a174-5a4a-5b4b-b672-37683c10d7d5 --- RemoteClient/hayes.c | 135 ++++++++++++++++++++++++++++++++++++++++++- RemoteClient/tcpip.c | 3 +- Server/hayes.c | 20 ++++--- 3 files changed, 149 insertions(+), 9 deletions(-) diff --git a/RemoteClient/hayes.c b/RemoteClient/hayes.c index 1630827..bffa914 100644 --- a/RemoteClient/hayes.c +++ b/RemoteClient/hayes.c @@ -28,7 +28,140 @@ /* -------------------------------------------------------------------------- */ /* --- END LICENSE --- */ +#include +#include +#include +#include + +#include + +#include +#include +#include + extern int argc; extern char** argv; -int rcli_init(void) {} +int port = -1; +bool connected; + +bool option(const char* str, const char* shortopt, const char* longopt); + +int get_ioport() { +#ifdef PC98 + if(port == 0) return 0x30; +#else + if(port == 0) { + return 0x3f8; + } else if(port == 1) { + return 0x2f8; + } else if(port == 2) { + return 0x3e8; + } else if(port == 3) { + return 0x2e8; + } +#endif + return 0; +} + + +void write_serial(const char* str) { + const char* ptr = str; + while(1) { + if(inp(get_ioport() + 5) & 0x20) { + outp(get_ioport(), *ptr); + ptr++; + if(*ptr == 0) break; + } + } +} + +char* modem_response(void) { + char* buf = malloc(1); + buf[0] = 0; + char cbuf[2]; + cbuf[1] = 0; + while(1) { + if(inp(get_ioport() + 5) & 1) { + unsigned short b = inp(get_ioport()); + char ch = b & 0xff; + if(ch != '\r' && ch != '\n' && ch != 0) { + cbuf[0] = ch; + char* tmp = buf; + buf = __dw_strcat(tmp, cbuf); + free(tmp); + } else if(ch == '\r') { + if(strlen(buf) != 0) break; + } + } + } + return buf; +} + +int rcli_init(void) { + printf("Using Hayes Modem\n"); + connected = false; + int i; + char* dial = NULL; + for(i = 1; i < argc; i++) { + if(argv[i][0] == '/' || argv[i][0] == '-') { + if(option(argv[i], "p", "port")) { + i++; + if(__dw_strcaseequ(argv[i], "COM1")) { + port = 0; +#ifndef PC98 + } else if(__dw_strcaseequ(argv[i], "COM2")) { + port = 1; + } else if(__dw_strcaseequ(argv[i], "COM3")) { + port = 2; + } else if(__dw_strcaseequ(argv[i], "COM4")) { + port = 3; +#endif + } else { + fprintf(stderr, "Invalid port: %s\n", argv[i]); + return 1; + } + } else if(option(argv[i], "h", "help")) { + printf("\n"); + printf("Usage: %s [options] dial\n", argv[0]); + printf("You can use double-dash or slash for long-format flag, and single-dash or slash for short-foramt flag.\n"); + printf("Options:\n"); + printf("\t-p --port [comport] Specify the modem port\n"); + exit(0); + } else { + fprintf(stderr, "Invalid option: %s\n", argv[i]); + return 1; + } + } else { + if(dial != NULL) free(dial); + dial = __dw_strdup(argv[i]); + } + } + if(port == -1) { + fprintf(stderr, "Specify serial port\n"); + return 1; + } + if(dial == NULL){ + fprintf(stderr, "Specify where to dial\n"); + return 1; + } + _bios_serialcom(_COM_INIT, port, _COM_9600 | _COM_NOPARITY | _COM_CHR8 | _COM_STOP1); + write_serial("AT&FE0F1\r"); + char* resp = modem_response(); + bool echo = __dw_strcaseequ(resp, "AT&FE0F1") || __dw_strcaseequ(resp, "NO CARRIER"); + if(resp != NULL && echo) free(resp); /* Kill echo */ + if(resp == NULL) return 1; + if(echo) resp = modem_response(); + if(resp == NULL) return 1; + if(__dw_strcaseequ(resp, "OK")) { + printf("Modem ready\n"); + printf("Dialing\n"); + write_serial("ATDT"); + write_serial(dial); + write_serial("\r"); + printf("%s\n", modem_response()); + printf("%s\n", modem_response()); + return 0; + } + return 1; +} diff --git a/RemoteClient/tcpip.c b/RemoteClient/tcpip.c index fe0b376..e23c9f5 100644 --- a/RemoteClient/tcpip.c +++ b/RemoteClient/tcpip.c @@ -30,6 +30,7 @@ #include #include +#include extern int argc; extern char** argv; @@ -48,7 +49,7 @@ int rcli_init(void) { port = atoi(argv[i]); } else if(option(argv[i], "h", "help")) { printf("\n"); - printf("Usage: %s [options] database\n", argv[0]); + printf("Usage: %s [options] host\n", argv[0]); printf("You can use double-dash or slash for long-format flag, and single-dash or slash for short-foramt flag.\n"); printf("Options:\n"); printf("\t-p --port [port] Specify the port to be listened on\n"); diff --git a/Server/hayes.c b/Server/hayes.c index cef2789..9321eef 100644 --- a/Server/hayes.c +++ b/Server/hayes.c @@ -54,6 +54,8 @@ void protocol_loop(int sock); void disconnect(int sock); void writeline(int sock, const char* str); +#define INIT_MODEM "AT&FE0F1" + bool option(const char* str, const char* shortopt, const char* longopt); int port = -1; @@ -78,8 +80,8 @@ int get_ioport() { void write_serial(const char* str) { const char* ptr = str; while(1) { - if(_bios_serialcom(_COM_STATUS, port, 0) & 0x10) { - _bios_serialcom(_COM_SEND, port, *ptr); + if(inp(get_ioport() + 5) & 0x20) { + outp(get_ioport(), *ptr); ptr++; if(*ptr == 0) break; } @@ -102,8 +104,8 @@ char* modem_response(void) { char cbuf[2]; cbuf[1] = 0; while(1) { - if(_bios_serialcom(_COM_STATUS, port, 0) & 0x0100) { - unsigned short b = _bios_serialcom(_COM_RECEIVE, port, 0); + if(inp(get_ioport() + 5) & 1) { + unsigned short b = inp(get_ioport()); char ch = b & 0xff; if(ch != '\r' && ch != '\n' && ch != 0) { cbuf[0] = ch; @@ -276,10 +278,10 @@ int server_init(void) { printf("Serial port is at I/O 0x%4.4x\n", get_ioport()); } _bios_serialcom(_COM_INIT, port, _COM_9600 | _COM_NOPARITY | _COM_CHR8 | _COM_STOP1); - write_serial("AT&FE0F1\r"); - if(!fancy) printf("<- AT&FE0F1\n"); + write_serial(INIT_MODEM "\r"); + if(!fancy) printf("<- " INIT_MODEM "\n"); char* resp = modem_response(); - bool echo = __dw_strcaseequ(resp, "AT&FE0F1") || __dw_strcaseequ(resp, "NO CARRIER"); + bool echo = __dw_strcaseequ(resp, INIT_MODEM) || __dw_strcaseequ(resp, "NO CARRIER"); if(resp != NULL && echo) free(resp); /* Kill echo */ if(resp == NULL) return 0; if(echo) resp = modem_response(); @@ -289,6 +291,7 @@ int server_init(void) { fancy_ready(); } else { printf("Modem initialization successful\n"); + outp(get_ioport() + 4, 1); } } else { if(fancy) printf("\x1b[2J\x1b[1;1H"); @@ -314,6 +317,7 @@ void server_loop(void) { printf("Disconnected\n"); } connected = false; + outp(get_ioport() + 4, 1); continue; } int i; @@ -385,6 +389,8 @@ void writeline(int sock, const char* str) { } void disconnect(int sock) { + while((inp(get_ioport() + 5) & 0x20) == 0); + delay(100); while(inp(get_ioport() + 6) & (1 << 7)) outp(get_ioport() + 4, 0); connected = false; } -- 2.43.0