Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graceful hang up (buffer overflow error) #7

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.o
.idea
pjsip.install
slmodemd/.build_profile
d-modem
slmodemd
modem_test
52 changes: 48 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ The repository contains two applications:

slmodemd – A stripped down and patched version of Debian’s sl-modem-daemon package. All kernel driver code has been replaced with socket-based communication, allowing external applications to manage audio streams.

d-modem – External application that interfaces with slmodemd to manage SIP calls and their associated audio streams.
d-modem – External application that interfaces with slmodemd to manage SIP calls and their associated audio streams.

socat.sh - Script that invokes Socat, connecting 2 modems together and transferring data between them via TCP relay (see [Testing](#testing)).

After they have been built, you will need to configure SIP account information in the SIP_LOGIN environment variable:

Expand All @@ -40,7 +42,7 @@ Because there isn’t any dial tone on our SIP connection, you’ll need to disa
atx3
OK

To successfully connect, you will likely need to manually select a modulation and data rate. In our testing, V.32bis (14.4kbps) and below appears to be the most reliable, though V.34 (33.6kbps) connections are sometimes successful. For example, the following command selects V.32bis with a data rate of 4800 – 9600 bps. Refer to the manual for further details.
To successfully connect, you will likely need to manually select a modulation and data rate. In our testing, V.32bis (14.4kbps) and below appears to be the most reliable, though V.34 (33.6kbps) connections are sometimes successful. For example, the following command selects V.32bis with a data rate of 4800 – 9600 bps. Refer to [the manual](./doc/ST56ATCommands.pdf) for further details.

at+ms=132,0,4800,9600
OK
Expand All @@ -60,12 +62,54 @@ Finally, dial the number of the target system. Below shows a connection to the
59515 21-10-28 21:40:21 11 0 -.1 045.0 UTC(NIST) *
59515 21-10-28 21:40:22 11 0 -.1 045.0 UTC(NIST) *
59515 21-10-28 21:40:23 11 0 -.1 045.0 UTC(NIST) *


## Testing
Install multipurpose relay Socat and Minicom.

Run slmodemd from 2 terminals, passing the path to socat.sh in the -e option and specifying different modem devices.

# ./slmodemd/slmodemd -d2 -e ./socat.sh /dev/slamr0

# ./slmodemd/slmodemd -d2 -e ./socat.sh /dev/slamr1

In 2 other terminals, connect to the newly created serial devices:

# minicom -D /dev/ttySL0

# minicom -D /dev/ttySL1

Because there isn’t any dial tone on our network connection, disable dial tone detection:

atx3
OK

To successfully connect, you will likely need to manually select a modulation and data rate:

at+ms=132,1,,14400
OK

Put one modem in answering mode:

ata

Finally, dial the number of the second system. 2130706433 is a decimal number of localhost IP address 127.0.0.1. If you run second modem on another machine, convert its IP address to a decimal number and dial.

atd2130706433

Now modems are connected and can interact with each other:

CONNECT 9600

To stop data transmission, first escape from on-line mode (+++), then hang up:

+++
ath

## Known Issues / Future Work
- Connections are unreliable, and it is currently difficult to connect at speeds higher than 14.4kbps or so. It might be possible to improve this by disabling/reconfiguring PJSIP’s jitter buffer.
- Additional logging/error handling is needed
- The serial interface could be replaced with stdio or a socket, and common AT configuration options could be exposed as command line options
- There is currently no support for receiving calls
- There is currently no support for receiving calls in d-modem.


Copyright 2021 Aon plc
Binary file added doc/ST56ATCommands.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions slmodemd/modem_at.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ static int process_A(struct modem *m, char *p, int *len)
{
int ret;
AT_DBG("AT A command...\n");
memset(m->dial_string, 0, strlen(m->dial_string));
ret = modem_answer(m);
if (ret)
return -1;
Expand Down
2 changes: 1 addition & 1 deletion slmodemd/modem_cmdline.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ static struct opt {
{'s',"shortbuffer","use short buffer (4 periods length)"},
{'d',"debug","debug level (developers only, for ./sl...)",OPTIONAL,INTEGER,"0"},
{'l',"log","logging mode",OPTIONAL,INTEGER,"5"},
{'e',"exec","path to external application that transmits audio over the socket (required)"},
{'e',"exec","path to external application that transmits audio over the socket (required)",MANDATORY,STRING,""},
{}
};

Expand Down
25 changes: 14 additions & 11 deletions slmodemd/modem_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ struct device_struct {
static char inbuf[4096];
static char outbuf[4096];

static pid_t pid;

/*
* ALSA 'driver'
Expand Down Expand Up @@ -626,7 +627,7 @@ static int socket_start (struct modem *m)
exit(-1);
}

pid_t pid = fork();
pid = fork();
if (pid == -1) {
perror("fork");
exit(-1);
Expand All @@ -635,7 +636,13 @@ static int socket_start (struct modem *m)
char str[16];
snprintf(str,sizeof(str),"%d",sockets[0]);
close(sockets[1]);
execl(modem_exec,modem_exec,m->dial_string,str,NULL);

ret = execl(modem_exec,modem_exec,m->dial_string,str,NULL);
if (ret == -1) {
ERR("prog: %s\n", modem_exec);
perror("execl");
exit(-1);
}
} else {
close(sockets[0]);
dev->fd = sockets[1];
Expand All @@ -645,8 +652,6 @@ static int socket_start (struct modem *m)
ret = write(dev->fd, outbuf, ret);
DBG("done delay thing\n");
if (ret < 0) {
close(dev->fd);
dev->fd = -1;
return ret;
}
dev->delay = ret/2;
Expand All @@ -658,9 +663,8 @@ static int socket_stop (struct modem *m)
{
struct device_struct *dev = m->dev_data;
DBG("socket_stop...\n");
close(dev->fd);
dev->fd = -1;
wait(NULL); // for exec'ed child
DBG("kill -%d %d\n", SIGTERM, pid);
kill(pid, SIGTERM); // terminate exec'ed child
return 0;
}

Expand Down Expand Up @@ -758,6 +762,8 @@ static int mdm_device_release(struct device_struct *dev)
static int socket_device_setup(struct device_struct *dev, const char *dev_name)
{
memset(dev,0,sizeof(*dev));
unsigned int pos = strlen(dev_name)-1;
dev->num = atoi(&dev_name[pos]);
return 0;
}

Expand Down Expand Up @@ -969,10 +975,6 @@ static int modem_run(struct modem *m, struct device_struct *dev)
}

modem_process(m,inbuf,outbuf,count);
if (dev->fd == -1) {
DBG("closed connection to child socket process\n");
continue;
}
count = device_write(dev,outbuf,count);
if(count < 0) {
ERR("dev write: %s\n",strerror(errno));
Expand Down Expand Up @@ -1112,6 +1114,7 @@ int modem_main(const char *dev_name)

signal(SIGINT, mark_termination);
signal(SIGTERM, mark_termination);
signal(SIGCHLD, SIG_IGN);

#ifdef SLMODEMD_USER
if (need_realtime) {
Expand Down
10 changes: 10 additions & 0 deletions socat.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

PORT=1234

if [ -z $1 ];
then
exec socat tcp-listen:$PORT fd:$2
else
exec socat tcp-connect:$1:$PORT fd:$2
fi