Files
SerialTerminalForWindowsTer…/utils.go
T
JiXieShi 31dd9da490 refactor: extract internal/config and eliminate global config var
Move Config struct to internal/config with exported fields. Replace
global var config with package-level cfg pointer. Add OpenLogFile to
config package. Add type alias Config = appconfig.Config in main
package for backward compatibility.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 21:45:08 +08:00

111 lines
2.8 KiB
Go

package main
import (
"fmt"
"github.com/trzsz/trzsz-go/trzsz"
"go.bug.st/serial"
"golang.org/x/term"
"io"
"os"
"os/signal"
"runtime"
"strings"
"sync"
)
func checkPortAvailability(name string) ([]string, error) {
ports, err := serial.GetPortsList()
if err != nil {
return nil, err
}
if len(ports) == 0 {
return nil, fmt.Errorf("无串口")
}
if name == "" {
return ports, fmt.Errorf("串口未指定")
}
for _, port := range ports {
if strings.Compare(port, name) == 0 {
return ports, nil
}
}
return ports, fmt.Errorf("串口 " + name + " 未在线")
}
func OpenSerial() error {
mode := &serial.Mode{
BaudRate: cfg.BaudRate,
StopBits: serial.StopBits(cfg.StopBits),
DataBits: cfg.DataBits,
Parity: serial.Parity(cfg.ParityBit),
}
var err error
serialPort, err = serial.Open(cfg.PortName, mode)
return err
}
func CloseSerial() {
if serialPort == nil {
return
}
if err := serialPort.Close(); err != nil {
fmt.Fprint(os.Stderr, err)
fmt.Fprint(os.Stderr, "\n")
}
}
var termch chan os.Signal
var termchOnce sync.Once
// OpenTrzsz create a TrzszFilter to support trzsz ( trz / tsz ).
//
// ┌────────┐ stdinPipe ┌────────┐ ClientIn ┌─────────────┐ SerialIn ┌────────┐
// │ ├─────────────►│ ├─────────────►│ ├─────────────►│ │
// │ mutual │ │ Client │ │ TrzszFilter │ │ Serial │
// │ │◄─────────────│ │◄─────────────┤ │◄─────────────┤ │
// └────────┘ stdoutPipe └────────┘ ClientOut └─────────────┘ SerialOut └────────┘
func OpenTrzsz() error {
fd := int(os.Stdin.Fd())
width, _, err := term.GetSize(fd)
if err != nil {
if runtime.GOOS != "windows" {
return fmt.Errorf("term get size failed: %w", err)
}
width = 80
}
clientIn, stdinPipe = io.Pipe()
stdoutPipe, clientOut = io.Pipe()
trzszFilter = trzsz.NewTrzszFilter(clientIn, clientOut, serialPort, serialPort,
trzsz.TrzszOptions{TerminalColumns: int32(width), EnableZmodem: true})
trzsz.SetAffectedByWindows(false)
termch = make(chan os.Signal, 1)
termchOnce = sync.Once{}
go func() {
for range termch {
width, _, err := term.GetSize(fd)
if err != nil {
fmt.Printf("term get size failed: %s\n", err)
continue
}
trzszFilter.SetTerminalColumns(int32(width))
}
}()
return nil
}
func CloseTrzsz() {
if termch == nil {
return
}
termchOnce.Do(func() {
signal.Stop(termch)
close(termch)
})
}