Skip to content
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
13 changes: 9 additions & 4 deletions cli/runcli.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020-2023, The OTNS Authors.
// Copyright (c) 2020-2026, The OTNS Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -175,9 +175,12 @@ func (cli *CliInstance) Run(handler CliHandler, options *CliOptions) error {
cli.readlineInstance = l
close(cli.Started)

cliStdoutAndFileWriter := io.MultiWriter(l.Stdout(), logger.GetLogWriter())

for {
// update the prompt and read a line
l.SetPrompt(handler.GetPrompt())
currentPrompt := handler.GetPrompt()
l.SetPrompt(currentPrompt)
line, err := l.Readline()

if len(line) > 0 && line[0] == readline.CharInterrupt {
Expand All @@ -203,12 +206,14 @@ func (cli *CliInstance) Run(handler CliHandler, options *CliOptions) error {

cmd := strings.TrimSpace(line)
if len(cmd) == 0 {
stdout.WriteString("")
_, _ = stdout.WriteString("")
_ = stdout.Sync()
continue
}

if err = handler.HandleCommand(cmd, l.Stdout()); err != nil {
logger.Println(currentPrompt+line, false, true) // echo user cmd to OTNS logfile

if err = handler.HandleCommand(cmd, cliStdoutAndFileWriter); err != nil {
_ = stdout.Sync()
return err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/otns-replay/otns_replay.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022-2025, The OTNS Authors.
// Copyright (c) 2022-2026, The OTNS Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -50,7 +50,7 @@ var args struct {
func parseArgs() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s <otns_replay_file.replay>\n", os.Args[0])
fmt.Fprintf(os.Stderr, " Replays a prior simulation in the Web GUI based on a .replay file.\n")
fmt.Fprintln(os.Stderr, " Replays a prior simulation in the Web GUI based on a .replay file.")
}
flag.Parse()

Expand Down
33 changes: 24 additions & 9 deletions dispatcher/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"strconv"
"strings"
"sync"
"syscall"
"time"

"github.com/openthread/ot-ns/dissectpkt"
Expand Down Expand Up @@ -152,7 +153,7 @@ type Dispatcher struct {
func NewDispatcher(ctx *progctx.ProgCtx, cfg *Config, cbHandler CallbackHandler) *Dispatcher {
logger.AssertTrue(!cfg.Realtime || cfg.Speed == 1)
var err error
ln, unixSocketFile := newUnixSocket(cfg.SimulationId)
ln, unixSocketFile := newUnixSocket(cfg.OutputDir, cfg.SimulationId)
vis := visualize.NewNopVisualizer()

d := &Dispatcher{
Expand Down Expand Up @@ -184,7 +185,7 @@ func NewDispatcher(ctx *progctx.ProgCtx, cfg *Config, cbHandler CallbackHandler)
}
d.speed = d.normalizeSpeed(d.speed)
if d.cfg.PcapEnabled {
d.pcap, err = pcap.NewFile("current.pcap", cfg.PcapFrameType, true)
d.pcap, err = pcap.NewFile(d.getPcapFileName(), cfg.PcapFrameType, true)
logger.PanicIfError(err)
d.waitGroup.Add(1)
go d.pcapFrameWriter()
Expand All @@ -199,17 +200,27 @@ func NewDispatcher(ctx *progctx.ProgCtx, cfg *Config, cbHandler CallbackHandler)
return d
}

func newUnixSocket(socketId int) (net.Listener, string) {
err := os.MkdirAll("/tmp/otns", 0777)
logger.FatalIfError(err, err)
unixSocketFile := fmt.Sprintf("/tmp/otns/socket_dispatcher_%d", socketId) // remove old one
err = os.RemoveAll(unixSocketFile)
func newUnixSocket(socketDir string, socketId int) (net.Listener, string) {
unixSocketFile := fmt.Sprintf("%s/socket_%d", socketDir, socketId) // remove old socket

if !isValidUnixSocketPath(unixSocketFile) {
logger.Fatalf("unix socket path too long: %s", unixSocketFile)
}

err := os.Remove(unixSocketFile)
if err != nil && errors.Is(err, os.ErrNotExist) {
err = nil
}
logger.FatalIfError(err, err)
ln, err := net.Listen("unix", unixSocketFile)
logger.FatalIfError(err, err)
return ln, unixSocketFile
}

func isValidUnixSocketPath(path string) bool {
return len(path) < len(syscall.RawSockaddrUnix{}.Path)
}

func (d *Dispatcher) Stop() {
if d.stopped {
return
Expand Down Expand Up @@ -652,7 +663,7 @@ func (d *Dispatcher) processNextEvents(simSpeed float64) bool {
func (d *Dispatcher) eventsReader() {
defer d.waitGroup.Done()
defer logger.Tracef("dispatcher node socket threads stopped.")
defer os.RemoveAll(d.socketName) // delete Unix socket file when done.
defer os.Remove(d.socketName) // delete Unix socket file when done.
defer d.udpln.Close()

logger.Debugf("dispatcher listening on socket %s ...", d.socketName)
Expand Down Expand Up @@ -1455,7 +1466,7 @@ func (d *Dispatcher) dumpPacket(item *Event) {
_, _ = fmt.Fprintf(&sb, "%02X", b)
}

logger.Println(sb.String())
logger.Println(sb.String(), true, true)
}

func (d *Dispatcher) setNodeRole(node *Node, role OtDeviceRole) {
Expand Down Expand Up @@ -1572,3 +1583,7 @@ func (d *Dispatcher) handleRadioState(node *Node, evt *Event) {
})
}
}

func (d *Dispatcher) getPcapFileName() string {
return fmt.Sprintf("%s/%d_otns.pcap", d.cfg.OutputDir, d.cfg.SimulationId)
}
4 changes: 2 additions & 2 deletions dispatcher/dispatcher_config.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2020-2024, The OTNS Authors.
// Copyright (c) 2020-2026, The OTNS Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -54,7 +54,7 @@ func DefaultConfig() *Config {
DefaultWatchOn: false,
DefaultWatchLevel: logger.OffLevelString,
SimulationId: 0,
OutputDir: "tmp",
OutputDir: "",
PhyTxStats: false,
}
}
6 changes: 3 additions & 3 deletions energy/core.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022-2024, The OTNS Authors.
// Copyright (c) 2022-2026, The OTNS Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -146,7 +146,7 @@ func (e *EnergyAnalyser) SaveEnergyDataToFile(name string, timestamp uint64) {

func (e *EnergyAnalyser) writeEnergyByNodes(fileNodes *os.File, timestamp uint64) {
fmt.Fprintf(fileNodes, "Duration of the simulated network (in milliseconds): %d\n", timestamp/1000)
fmt.Fprintf(fileNodes, "ID\tDisabled (mJ)\tIdle (mJ)\tTransmiting (mJ)\tReceiving (mJ)\n")
fmt.Fprintln(fileNodes, "ID\tDisabled (mJ)\tIdle (mJ)\tTransmiting (mJ)\tReceiving (mJ)")

sortedNodes := make([]int, 0, len(e.nodes))
for id := range e.nodes {
Expand All @@ -168,7 +168,7 @@ func (e *EnergyAnalyser) writeEnergyByNodes(fileNodes *os.File, timestamp uint64

func (e *EnergyAnalyser) writeNetworkEnergy(fileNetwork *os.File, timestamp uint64) {
fmt.Fprintf(fileNetwork, "Duration of the simulated network (in milliseconds): %d\n", timestamp/1000)
fmt.Fprintf(fileNetwork, "Time (ms)\tDisabled (mJ)\tIdle (mJ)\tTransmiting (mJ)\tReceiving (mJ)\n")
fmt.Fprintln(fileNetwork, "Time (ms)\tDisabled (mJ)\tIdle (mJ)\tTransmiting (mJ)\tReceiving (mJ)")
for _, snapshot := range e.networkHistory {
fmt.Fprintf(fileNetwork, "%d\t%f\t%f\t%f\t%f\n",
snapshot.Timestamp/1000,
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ require (
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.24.0
golang.org/x/net v0.38.0
golang.org/x/term v0.30.0
golang.org/x/term v0.34.0
google.golang.org/grpc v1.56.3
google.golang.org/protobuf v1.34.1
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -48,7 +48,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.23.0 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
)
Loading
Loading