Skip to content
Merged
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
4 changes: 2 additions & 2 deletions cmd/modemmenu/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ command = env > %s; cat "$MODEM_SESSION_FILE" >> %s; echo args: {user} {baud} {d
cmd := exec.Command(bin, "-config", lineMenu(conf))
cmd.Stdin, cmd.Stdout, cmd.Stderr = s, s, s
cmd.Env = append(os.Environ(), "DMODEM_RATE=33600/31200", "DMODEM_CALLERID=5559999",
"DMODEM_DIALED=5551000", "DMODEM_CHANNEL=Local/s@test", "TMPDIR="+dir)
"DMODEM_DIALED=5551000", "DMODEM_CHANNEL=Local/s@test", "DMODEM_PEER=203.0.113.5:5060", "TMPDIR="+dir)
cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true, Setctty: true}
if err := cmd.Start(); err != nil {
t.Fatal(err)
Expand Down Expand Up @@ -254,7 +254,7 @@ command = env > %s; cat "$MODEM_SESSION_FILE" >> %s; echo args: {user} {baud} {d
env, _ := os.ReadFile(envOut)
for _, w := range []string{"MODEM_USER=alice", "MODEM_PASSWORD=secret", "MODEM_BAUD=33600",
"MODEM_DIALED=5551000", "MODEM_CALLERID=5559999", "MODEM_SELECTION=info",
"MODEM_AUTH=file", "MODEM_CHANNEL=Local/s@test", "MODEM_DATETIME=", `"user": "alice"`,
"MODEM_AUTH=file", "MODEM_CHANNEL=Local/s@test", "MODEM_PEER=203.0.113.5:5060", "MODEM_DATETIME=", `"user": "alice"`,
`"password": "secret"`, `"dialed": "5551000"`} {
if !bytes.Contains(env, []byte(w)) {
t.Errorf("no %s in the environment and session file:\n%s", w, env)
Expand Down
1 change: 1 addition & 0 deletions cmd/modemmenu/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func headerEnv(h map[string]string, trust bool) []string {
"DMODEM_CHANNEL": "MODEM_CHANNEL", "DMODEM_PROFILE": "MODEM_PROFILE",
"DMODEM_RATE": "MODEM_RATE", "DMODEM_CALLERID": "MODEM_CALLERID",
"DMODEM_DIALED": "MODEM_DIALED", "DMODEM_CONNECTED": "MODEM_EPOCH",
"DMODEM_PEER": "MODEM_PEER",
}
var env []string
for d, m := range call {
Expand Down
7 changes: 4 additions & 3 deletions cmd/modemmenu/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
func TestHeader(t *testing.T) {
a, b := net.Pipe()
s := newSession("33600/31200", "555\n1000", "", time.Unix(1791666309, 0))
s.User, s.Password = "alice", "secret"
s.User, s.Password, s.Peer = "alice", "secret", "203.0.113.5:5060"
go func() {
writeHeader(a, s, false)
a.Write([]byte("data"))
Expand All @@ -30,7 +30,8 @@ func TestHeader(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if h["MODEM_USER"] != "alice" || h["MODEM_DIALED"] != "555 1000" || h["MODEM_PASSWORD"] != "" {
if h["MODEM_USER"] != "alice" || h["MODEM_DIALED"] != "555 1000" || h["MODEM_PASSWORD"] != "" ||
h["MODEM_PEER"] != "203.0.113.5:5060" {
t.Errorf("header %v", h)
}
rest := make([]byte, 4)
Expand All @@ -40,7 +41,7 @@ func TestHeader(t *testing.T) {
}
env := strings.Join(headerEnv(h, false), "\n")
if !strings.Contains(env, "DMODEM_RATE=33600/31200") || !strings.Contains(env, "DMODEM_CONNECTED=1791666309") ||
strings.Contains(env, "UPSTREAM") {
!strings.Contains(env, "DMODEM_PEER=203.0.113.5:5060") || strings.Contains(env, "UPSTREAM") {
t.Errorf("env %s", env)
}
if env := strings.Join(headerEnv(h, true), "\n"); !strings.Contains(env, "MODEMMENU_UPSTREAM_USER=alice") {
Expand Down
28 changes: 17 additions & 11 deletions cmd/modemmenu/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ import (
// session is what is known of the call and the caller, handed to the
// selection in its environment, its command line and its session file
type session struct {
User string `json:"user"`
Password string `json:"password,omitempty"`
Auth string `json:"auth"`
Dialed string `json:"dialed"`
CallerID string `json:"callerid"`
Baud string `json:"baud"`
Rate string `json:"rate"`
TxRate string `json:"tx_rate"`
RxRate string `json:"rx_rate"`
Channel string `json:"channel"`
User string `json:"user"`
Password string `json:"password,omitempty"`
Auth string `json:"auth"`
Dialed string `json:"dialed"`
CallerID string `json:"callerid"`
Baud string `json:"baud"`
Rate string `json:"rate"`
TxRate string `json:"tx_rate"`
RxRate string `json:"rx_rate"`
Channel string `json:"channel"`
// the address the call came from by VoIP (the SIP peer's: app_dmodem's
// DMODEM_PEER), "" if not told
Peer string `json:"peer"`
Profile string `json:"profile"`
Connected time.Time `json:"connected"`
Selection string `json:"selection"`
Expand All @@ -51,13 +54,15 @@ type session struct {
}

// newSession from app_dmodem's environment (DMODEM_RATE "tx/rx",
// DMODEM_CALLERID, DMODEM_DIALED, DMODEM_CHANNEL, DMODEM_PROFILE), what the
// DMODEM_CALLERID, DMODEM_DIALED, DMODEM_CHANNEL, DMODEM_PROFILE,
// DMODEM_PEER), what the
// command line overrides of it
func newSession(rate, dialed, callerID string, now time.Time) *session {
s := &session{
Dialed: dialed,
CallerID: callerID,
Channel: os.Getenv("DMODEM_CHANNEL"),
Peer: os.Getenv("DMODEM_PEER"),
Profile: os.Getenv("DMODEM_PROFILE"),
Connected: now,
}
Expand Down Expand Up @@ -111,6 +116,7 @@ func (s *session) vars(withPassword bool) map[string]string {
"rx_rate": s.RxRate,
"speed": s.Speed(),
"channel": s.Channel,
"peer": s.Peer,
"profile": s.Profile,
"selection": s.Selection,
"time_left": s.TimeLeft,
Expand Down
1 change: 1 addition & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,7 @@ cooked terminal (`tty = sane`), and return to the menu.
| `{date}`, `{time}` | `MODEM_DATE`, `MODEM_TIME` | the connection's date and time |
| `{datetime}`, `{epoch}` | `MODEM_DATETIME`, `MODEM_EPOCH` | the same, RFC 3339 and Unix time |
| `{channel}`, `{profile}` | `MODEM_CHANNEL`, `MODEM_PROFILE` | app_dmodem's channel and profile |
| `{peer}` | `MODEM_PEER` | the address the call came from by SIP (app_dmodem's `DMODEM_PEER`), empty if not known; the BBS places a caller without a caller ID by it |
| `{selection}` | `MODEM_SELECTION` | the item chosen |
| `{time_left}` | `MODEM_TIME_LEFT` | whole minutes left, empty without a limit |
| `{seconds_left}` | `MODEM_SECONDS_LEFT` | the same in seconds |
Expand Down
8 changes: 5 additions & 3 deletions docs/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ exten => 5551000,1,DModem(menu)

modemmenu reads the call's details from app_dmodem's environment:
`DMODEM_RATE` (tx/rx bit/s), `DMODEM_CALLERID`, `DMODEM_DIALED`,
`DMODEM_CHANNEL` and `DMODEM_PROFILE`. `DMODEM_DIALED` needs an
`DMODEM_CHANNEL`, `DMODEM_PROFILE` and `DMODEM_PEER` (the address the
call came from by SIP). `DMODEM_DIALED` needs an
app_dmodem that sets it. The `-rate`, `-callerid` and `-dialed` options
set these instead, e.g. under a getty on another modem.

Expand Down Expand Up @@ -53,8 +54,9 @@ socket_group = asterisk

A socket has no environment, so app_dmodem's `header = yes` sends the
call's details first: `DMODEM_CHANNEL`, `DMODEM_PROFILE`, `DMODEM_RATE`,
`DMODEM_CALLERID`, `DMODEM_DIALED` and `DMODEM_CONNECTED` (Unix time),
one `NAME=value` per line, then an empty line, then the caller's bytes.
`DMODEM_CALLERID`, `DMODEM_DIALED`, `DMODEM_CONNECTED` (Unix time) and
`DMODEM_PEER`, one `NAME=value` per line, then an empty line, then the
caller's bytes.
`[server] header = yes` (the default) reads it; with `header = no` the
caller's bytes come from the start and the details are unknown.

Expand Down
2 changes: 2 additions & 0 deletions samples/modemmenu.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
; {epoch} MODEM_EPOCH seconds since 1970
; {channel} MODEM_CHANNEL the Asterisk channel
; {profile} MODEM_PROFILE the dmodem.conf profile
; {peer} MODEM_PEER the address the call came from by SIP
; (app_dmodem's DMODEM_PEER; "" unknown)
; {selection} MODEM_SELECTION the [item ...] chosen
;
; The rate, dialed number and caller ID come from app_dmodem's DMODEM_RATE,
Expand Down
Loading