aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2019-06-27 23:08:01 +0200
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2019-06-27 23:08:01 +0200
commitb4582f3209a4916ffaa54baa716ab27a87bb961a (patch)
tree86e8deebd6eef2c555975b4e799687644415777a
parentaafbd24502d6d9883ae96a57f64fa3b5ed7c2bcb (diff)
downloadbbs-b4582f3209a4916ffaa54baa716ab27a87bb961a.tar.gz
can accept incoming calls
-rw-r--r--src/main.c25
-rw-r--r--src/main.h4
-rw-r--r--src/modem.c147
-rw-r--r--src/modem.h24
-rw-r--r--src/serial.c38
-rw-r--r--src/serial.h10
6 files changed, 236 insertions, 12 deletions
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
+ * <Description>
+ * <License>
+*/
+
+#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
+ * <Description>
+ * <License>
+*/
+
+#include <unistd.h>
+#include <poll.h>
+#include <string.h>
+#include <signal.h>
+
+#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 <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
+#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 <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+
+int set_interface_attribs (int fd, int speed, int parity);
+
+void set_blocking (int fd, int should_block);