From b4582f3209a4916ffaa54baa716ab27a87bb961a Mon Sep 17 00:00:00 2001 From: Jonas Gunz Date: Thu, 27 Jun 2019 23:08:01 +0200 Subject: can accept incoming calls --- src/main.c | 25 +++++++++- src/main.h | 4 +- src/modem.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/modem.h | 24 ++++++++++ src/serial.c | 38 +++++++++++---- src/serial.h | 10 ++++ 6 files changed, 236 insertions(+), 12 deletions(-) create mode 100644 src/modem.c create mode 100644 src/modem.h create mode 100644 src/serial.h diff --git a/src/main.c b/src/main.c index b0630a6..75b37a3 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,6 @@ #include "main.h" +#include "serial.h" +#include "modem.h" struct prog_params parse_args(int argc, char* argv[]) { @@ -135,7 +137,7 @@ int main(int argc, char* argv[]) }//if params.fork if ( params.serial ) - printf("asdf"); + dialup_server(params); else if (params.telnet) telnet_server(params); @@ -144,6 +146,27 @@ int main(int argc, char* argv[]) void dialup_server(struct prog_params params) { + + int fd = open (params.serial_port, O_RDWR | O_NOCTTY | O_SYNC); + if (fd < 0) + { + printf ("error %d opening %s: %s\n", errno, params.serial_port, strerror (errno)); + return; + } + + ///TODO Hardcoded Baudrate. change! + set_interface_attribs (fd, params.serial_baudrate, 0); // set speed to 115,200 bps, 8n1 (no parity) + set_blocking (fd, 0); // set no blocking + + int ret = modem_accept_wait(fd); + printf("maw(): %i\n", ret); + + if(ret) + return; + + printf("Connection!\n"); + + modem_run(fd, 0, NULL); } void telnet_server(struct prog_params params) diff --git a/src/main.h b/src/main.h index 25521be..a22c8f2 100644 --- a/src/main.h +++ b/src/main.h @@ -32,7 +32,7 @@ #define ERROR_HELP( ... ) { \ printf(__VA_ARGS__); \ - printf("Help goes here"); \ + printf("bbs\n-p PORT: telnet port\n-i IP: telnet listen ip\n-s DEVIVE: modem serial device\n-b BAUD: serial baudrate\n-f FILE: use pidfile\n"); \ exit(1); } struct prog_params @@ -59,3 +59,5 @@ void handle_connection(int _socket, struct sockaddr_in _addr); int main(int argc, char* argv[]); void telnet_server(struct prog_params params); + +void dialup_server(struct prog_params params); diff --git a/src/modem.c b/src/modem.c new file mode 100644 index 0000000..b2e7dbd --- /dev/null +++ b/src/modem.c @@ -0,0 +1,147 @@ +/* + * modem.c + * (c) 2019, Jonas Gunz, jonasgunz.de + * + * +*/ + +#include "modem.h" + +int modem_accept_wait(int fd) +{ + if(!fd) + return 1; + + char buff[128]; + int ret; //for retturn values + struct pollfd fds; //poll struct + int cnt = 0; //read byte counter + + fds.fd = fd; + fds.events = POLLIN; + + write(fd, _AT_ECHO_OFF, strlen(_AT_ECHO_OFF) ); + + int ok = 0; + while(1) { + ret = poll(&fds, 1, 1000); + if (ret) + cnt = read(fd, buff, 128); //Dummy read from _AT_ECHO_OFF, should say OK + else + break; + + + if( strstr(buff, "OK") ) + ok = 1; + } + + if(! ok ) + return 3; + + printf("Modem OK\n"); + + while ( 1 ) { //wait for RING + ret = poll(&fds, 1, 2000); //poll in 2s interval + if(ret) { + cnt = read ( fd, buff, 128 ); + if(strstr(buff, "RING")) + break; + } + } + + printf("Modem RINGING\n"); + + write (fd, _AT_ANSWER, strlen(_AT_ANSWER)); //Accept incoming call + ret = poll(&fds, 1, 30000); + if(ret) { + cnt = read (fd, buff, 128); + if(strstr(buff, "CONNECT")) + return 0; + else + return 4; + } + + return 5; +} + +int modem_hang(int fd) +{ +} + +int modem_run(int fd, int argc, char* argv[]) +{ + int in[2]; + int out[2]; + + //1: write, 0: read + if(pipe(in) == -1) + return 1; + + if(pipe(out) == -1) + return 1; + + pid_t pid = fork(); + + if(pid == 0) {//child + close (in[1]); + close (out[0]); + + dup2 (in[0], STDIN_FILENO); + dup2 (out[1], STDOUT_FILENO); + + printf("EXEC ERROR\n\n"); + exit(0); + } + else if (pid < 0) {//error + return 2; + } + else {//parent + int buffsize = 128; + char buff[ buffsize ]; + + close (in[0]); + close (out[1]); + + //setup poll to listen for input + struct pollfd fds[2]; + fds[0].fd = out[0]; + fds[0].events = POLLIN; + fds[1].fd = fd; + fds[1].events = POLLIN; + + while(1) + { + int ret = poll (fds, 2, 100); + + if ( fds[0].revents & POLLIN ) { + int cnt = read (out[0], buff, buffsize); + if(cnt) { + while(1) { //replace +++ to not trigger modem command mode + char *str = strstr(buff, "+++"); + if(str) + str[1] = '*'; + } + + write(fd, buff, cnt); + } + } + if ( fds[1].revents & POLLIN ) { + int cnt = read (fd, buff, buffsize); + if(cnt) { + while(1) { //search for modem error message + char *str = strstr(buff, "NO CARRIER"); + if(str) { //Exit if message found + return 0; + } + } + + write(in[1], buff, cnt); + } + } + + if(kill(pid,0)) //Check if child is still alive, if not return. + return 0; + } + } + +} diff --git a/src/modem.h b/src/modem.h new file mode 100644 index 0000000..bc0cfac --- /dev/null +++ b/src/modem.h @@ -0,0 +1,24 @@ +/* + * modem.h + * (c) 2019, Jonas Gunz, jonasgunz.de + * + * +*/ + +#include +#include +#include +#include + +#define _AT "AT\r\n" +#define _AT_ANSWER "ATA\r\n" +#define _AT_ECHO_OFF "ATE0\r\n" +#define _AT_ECHO_ON "ATE1\r\n\”" +#define _AT_HANGUP "ATH\r\n" +#define _AT_CMD_MODE "+++" + +int modem_accept_wait(int fd); + +int modem_hang(int fd); + +int modem_run(int fd, int argc, char* argv[]); diff --git a/src/serial.c b/src/serial.c index 01f27bb..fe0f8f0 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,8 +1,4 @@ -#include -#include -#include -#include -#include +#include "serial.h" int set_interface_attribs (int fd, int speed, int parity) @@ -11,7 +7,7 @@ set_interface_attribs (int fd, int speed, int parity) memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { - error_message ("error %d from tcgetattr", errno); + //error_message ("error %d from tcgetattr", errno); return -1; } @@ -39,7 +35,7 @@ set_interface_attribs (int fd, int speed, int parity) if (tcsetattr (fd, TCSANOW, &tty) != 0) { - error_message ("error %d from tcsetattr", errno); + //error_message ("error %d from tcsetattr", errno); return -1; } return 0; @@ -52,13 +48,35 @@ set_blocking (int fd, int should_block) memset (&tty, 0, sizeof tty); if (tcgetattr (fd, &tty) != 0) { - error_message ("error %d from tggetattr", errno); + //error_message ("error %d from tggetattr", errno); return; } tty.c_cc[VMIN] = should_block ? 1 : 0; tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout - if (tcsetattr (fd, TCSANOW, &tty) != 0) - error_message ("error %d setting term attributes", errno); + //if (tcsetattr (fd, TCSANOW, &tty) != 0) + //error_message ("error %d setting term attributes", errno); +} + +/* +... +char *portname = "/dev/ttyUSB1" + ... +int fd = open (portname, O_RDWR | O_NOCTTY | O_SYNC); +if (fd < 0) +{ + error_message ("error %d opening %s: %s", errno, portname, strerror (errno)); + return; } + +set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity) +set_blocking (fd, 0); // set no blocking + +write (fd, "hello!\n", 7); // send 7 character greeting + +usleep ((7 + 25) * 100); // sleep enough to transmit the 7 plus + // receive 25: approx 100 uS per char transmit +char buf [100]; +int n = read (fd, buf, sizeof buf); // read up to 100 characters if ready to read +*/ diff --git a/src/serial.h b/src/serial.h new file mode 100644 index 0000000..1e3157d --- /dev/null +++ b/src/serial.h @@ -0,0 +1,10 @@ +#include +#include +#include +#include +#include + + +int set_interface_attribs (int fd, int speed, int parity); + +void set_blocking (int fd, int should_block); -- cgit v1.2.3