fix serial

This commit is contained in:
ginuerzh 2023-10-15 23:55:52 +08:00
parent 497915f465
commit 5ab729b166
9 changed files with 755 additions and 71 deletions

View File

@ -7,9 +7,8 @@ import (
"github.com/go-gost/core/dialer"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
serial_util "github.com/go-gost/x/internal/util/serial"
serial "github.com/go-gost/x/internal/util/serial"
"github.com/go-gost/x/registry"
goserial "github.com/tarm/serial"
)
func init() {
@ -42,11 +41,11 @@ func (d *serialDialer) Dial(ctx context.Context, addr string, opts ...dialer.Dia
opt(&options)
}
cfg := serial_util.ParseConfigFromAddr(addr)
port, err := goserial.OpenPort(cfg)
cfg := serial.ParseConfigFromAddr(addr)
port, err := serial.OpenPort(cfg)
if err != nil {
return nil, err
}
return serial_util.NewConn(port, &serial_util.Addr{Port: cfg.Name}, nil), nil
return serial.NewConn(port, &serial.Addr{Port: cfg.Name}, nil), nil
}

View File

@ -13,8 +13,7 @@ import (
"github.com/go-gost/relay"
xnet "github.com/go-gost/x/internal/net"
sx "github.com/go-gost/x/internal/util/selector"
serial_util "github.com/go-gost/x/internal/util/serial"
goserial "github.com/tarm/serial"
serial "github.com/go-gost/x/internal/util/serial"
)
func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network, address string, log logger.Logger) (err error) {
@ -62,7 +61,7 @@ func (h *relayHandler) handleConnect(ctx context.Context, conn net.Conn, network
case "unix":
cc, err = (&net.Dialer{}).DialContext(ctx, "unix", address)
case "serial":
cc, err = goserial.OpenPort(serial_util.ParseConfigFromAddr(address))
cc, err = serial.OpenPort(serial.ParseConfigFromAddr(address))
default:
cc, err = h.router.Dial(ctx, network, address)
}

View File

@ -14,10 +14,9 @@ import (
md "github.com/go-gost/core/metadata"
"github.com/go-gost/core/recorder"
xnet "github.com/go-gost/x/internal/net"
serial_util "github.com/go-gost/x/internal/util/serial"
serial "github.com/go-gost/x/internal/util/serial"
xrecorder "github.com/go-gost/x/recorder"
"github.com/go-gost/x/registry"
goserial "github.com/tarm/serial"
)
func init() {
@ -119,14 +118,14 @@ func (h *serialHandler) forwardSerial(ctx context.Context, conn net.Conn, target
log.Debugf("%s >> %s", conn.LocalAddr(), target.Addr)
var port io.ReadWriteCloser
cfg := serial_util.ParseConfigFromAddr(conn.LocalAddr().String())
cfg := serial.ParseConfigFromAddr(conn.LocalAddr().String())
cfg.Name = target.Addr
if opts := h.router.Options(); opts != nil && opts.Chain != nil {
port, err = h.router.Dial(ctx, "serial", serial_util.AddrFromConfig(cfg))
port, err = h.router.Dial(ctx, "serial", serial.AddrFromConfig(cfg))
} else {
cfg.ReadTimeout = h.md.timeout
port, err = goserial.OpenPort(cfg)
port, err = serial.OpenPort(cfg)
}
if err != nil {
log.Error(err)

View File

@ -1,68 +1,169 @@
/*
Goserial is a simple go package to allow you to read and write from
the serial port as a stream of bytes.
It aims to have the same API on all platforms, including windows. As
an added bonus, the windows package does not use cgo, so you can cross
compile for windows from another platform. Unfortunately goinstall
does not currently let you cross compile so you will have to do it
manually:
GOOS=windows make clean install
Currently there is very little in the way of configurability. You can
set the baud rate. Then you can Read(), Write(), or Close() the
connection. Read() will block until at least one byte is returned.
Write is the same. There is currently no exposed way to set the
timeouts, though patches are welcome.
Currently all ports are opened with 8 data bits, 1 stop bit, no
parity, no hardware flow control, and no software flow control. This
works fine for many real devices and many faux serial devices
including usb-to-serial converters and bluetooth serial ports.
You may Read() and Write() simulantiously on the same connection (from
different goroutines).
Example usage:
package main
import (
"github.com/tarm/serial"
"log"
)
func main() {
c := &serial.Config{Name: "COM5", Baud: 115200}
s, err := serial.OpenPort(c)
if err != nil {
log.Fatal(err)
}
n, err := s.Write([]byte("test"))
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 128)
n, err = s.Read(buf)
if err != nil {
log.Fatal(err)
}
log.Print("%q", buf[:n])
}
*/
package serial
import (
"strconv"
"strings"
"errors"
"io"
"time"
)
goserial "github.com/tarm/serial"
const DefaultSize = 8 // Default value for Config.Size
type StopBits byte
type Parity byte
const (
Stop1 StopBits = 1
Stop1Half StopBits = 15
Stop2 StopBits = 2
)
const (
DefaultPort = "COM1"
DefaultBaudRate = 9600
ParityNone Parity = 'N'
ParityOdd Parity = 'O'
ParityEven Parity = 'E'
ParityMark Parity = 'M' // parity bit is always 1
ParitySpace Parity = 'S' // parity bit is always 0
)
// COM1,9600,odd
func ParseConfigFromAddr(addr string) *goserial.Config {
cfg := &goserial.Config{
Name: DefaultPort,
Baud: DefaultBaudRate,
}
ss := strings.Split(addr, ",")
switch len(ss) {
case 1:
cfg.Name = ss[0]
case 2:
cfg.Name = ss[0]
cfg.Baud, _ = strconv.Atoi(ss[1])
case 3:
cfg.Name = ss[0]
cfg.Baud, _ = strconv.Atoi(ss[1])
cfg.Parity = parseParity(ss[2])
}
return cfg
// Config contains the information needed to open a serial port.
//
// Currently few options are implemented, but more may be added in the
// future (patches welcome), so it is recommended that you create a
// new config addressing the fields by name rather than by order.
//
// For example:
//
// c0 := &serial.Config{Name: "COM45", Baud: 115200, ReadTimeout: time.Millisecond * 500}
//
// or
//
// c1 := new(serial.Config)
// c1.Name = "/dev/tty.usbserial"
// c1.Baud = 115200
// c1.ReadTimeout = time.Millisecond * 500
type Config struct {
Name string
Baud int
ReadTimeout time.Duration // Total timeout
// Size is the number of data bits. If 0, DefaultSize is used.
Size byte
// Parity is the bit to use and defaults to ParityNone (no parity bit).
Parity Parity
// Number of stop bits to use. Default is 1 (1 stop bit).
StopBits StopBits
// RTSFlowControl bool
// DTRFlowControl bool
// XONFlowControl bool
// CRLFTranslate bool
}
func AddrFromConfig(cfg *goserial.Config) string {
ss := []string{
cfg.Name,
strconv.Itoa(cfg.Baud),
}
// ErrBadSize is returned if Size is not supported.
var ErrBadSize error = errors.New("unsupported serial data size")
switch cfg.Parity {
case goserial.ParityEven:
ss = append(ss, "even")
case goserial.ParityOdd:
ss = append(ss, "odd")
case goserial.ParityMark:
ss = append(ss, "mark")
case goserial.ParitySpace:
ss = append(ss, "space")
// ErrBadStopBits is returned if the specified StopBits setting not supported.
var ErrBadStopBits error = errors.New("unsupported stop bit setting")
// ErrBadParity is returned if the parity is not supported.
var ErrBadParity error = errors.New("unsupported parity setting")
// OpenPort opens a serial port with the specified configuration
func OpenPort(c *Config) (io.ReadWriteCloser, error) {
size, par, stop := c.Size, c.Parity, c.StopBits
if size == 0 {
size = DefaultSize
}
return strings.Join(ss, ",")
if par == 0 {
par = ParityNone
}
if stop == 0 {
stop = Stop1
}
return openPort(c.Name, c.Baud, size, par, stop, c.ReadTimeout)
}
func parseParity(s string) goserial.Parity {
switch strings.ToLower(s) {
case "o", "odd":
return goserial.ParityOdd
case "e", "even":
return goserial.ParityEven
case "m", "mark":
return goserial.ParityMark
case "s", "space":
return goserial.ParitySpace
default:
return goserial.ParityNone
// Converts the timeout values for Linux / POSIX systems
func posixTimeoutValues(readTimeout time.Duration) (vmin uint8, vtime uint8) {
const MAXUINT8 = 1<<8 - 1 // 255
// set blocking / non-blocking read
var minBytesToRead uint8 = 1
var readTimeoutInDeci int64
if readTimeout > 0 {
// EOF on zero read
minBytesToRead = 0
// convert timeout to deciseconds as expected by VTIME
readTimeoutInDeci = (readTimeout.Nanoseconds() / 1e6 / 100)
// capping the timeout
if readTimeoutInDeci < 1 {
// min possible timeout 1 Deciseconds (0.1s)
readTimeoutInDeci = 1
} else if readTimeoutInDeci > MAXUINT8 {
// max possible timeout is 255 deciseconds (25.5s)
readTimeoutInDeci = MAXUINT8
}
}
return minBytesToRead, uint8(readTimeoutInDeci)
}
// func SendBreak()
// func RegisterBreakHandler(func())

View File

@ -0,0 +1,165 @@
//go:build linux
// +build linux
package serial
import (
"fmt"
"os"
"time"
"unsafe"
"golang.org/x/sys/unix"
)
func openPort(name string, baud int, databits byte, parity Parity, stopbits StopBits, readTimeout time.Duration) (p *Port, err error) {
var bauds = map[int]uint32{
50: unix.B50,
75: unix.B75,
110: unix.B110,
134: unix.B134,
150: unix.B150,
200: unix.B200,
300: unix.B300,
600: unix.B600,
1200: unix.B1200,
1800: unix.B1800,
2400: unix.B2400,
4800: unix.B4800,
9600: unix.B9600,
19200: unix.B19200,
38400: unix.B38400,
57600: unix.B57600,
115200: unix.B115200,
230400: unix.B230400,
460800: unix.B460800,
500000: unix.B500000,
576000: unix.B576000,
921600: unix.B921600,
1000000: unix.B1000000,
1152000: unix.B1152000,
1500000: unix.B1500000,
2000000: unix.B2000000,
2500000: unix.B2500000,
3000000: unix.B3000000,
3500000: unix.B3500000,
4000000: unix.B4000000,
}
rate, ok := bauds[baud]
if !ok {
return nil, fmt.Errorf("Unrecognized baud rate")
}
f, err := os.OpenFile(name, unix.O_RDWR|unix.O_NOCTTY|unix.O_NONBLOCK, 0666)
if err != nil {
return nil, err
}
defer func() {
if err != nil && f != nil {
f.Close()
}
}()
// Base settings
cflagToUse := unix.CREAD | unix.CLOCAL | rate
switch databits {
case 5:
cflagToUse |= unix.CS5
case 6:
cflagToUse |= unix.CS6
case 7:
cflagToUse |= unix.CS7
case 8:
cflagToUse |= unix.CS8
default:
return nil, ErrBadSize
}
// Stop bits settings
switch stopbits {
case Stop1:
// default is 1 stop bit
case Stop2:
cflagToUse |= unix.CSTOPB
default:
// Don't know how to set 1.5
return nil, ErrBadStopBits
}
// Parity settings
switch parity {
case ParityNone:
// default is no parity
case ParityOdd:
cflagToUse |= unix.PARENB
cflagToUse |= unix.PARODD
case ParityEven:
cflagToUse |= unix.PARENB
default:
return nil, ErrBadParity
}
fd := f.Fd()
vmin, vtime := posixTimeoutValues(readTimeout)
t := unix.Termios{
Iflag: unix.IGNPAR,
Cflag: cflagToUse,
Ispeed: rate,
Ospeed: rate,
}
t.Cc[unix.VMIN] = vmin
t.Cc[unix.VTIME] = vtime
if _, _, errno := unix.Syscall6(
unix.SYS_IOCTL,
uintptr(fd),
uintptr(unix.TCSETS),
uintptr(unsafe.Pointer(&t)),
0,
0,
0,
); errno != 0 {
return nil, errno
}
if err = unix.SetNonblock(int(fd), false); err != nil {
return
}
return &Port{f: f}, nil
}
type Port struct {
// We intentionly do not use an "embedded" struct so that we
// don't export File
f *os.File
}
func (p *Port) Read(b []byte) (n int, err error) {
return p.f.Read(b)
}
func (p *Port) Write(b []byte) (n int, err error) {
return p.f.Write(b)
}
// Discards data written to the port but not transmitted,
// or data received but not read
func (p *Port) Flush() error {
const TCFLSH = 0x540B
_, _, errno := unix.Syscall(
unix.SYS_IOCTL,
uintptr(p.f.Fd()),
uintptr(TCFLSH),
uintptr(unix.TCIOFLUSH),
)
if errno == 0 {
return nil
}
return errno
}
func (p *Port) Close() (err error) {
return p.f.Close()
}

View File

@ -0,0 +1,28 @@
//go:build !windows && !linux
// +build !windows,!linux
package serial
import (
"errors"
"time"
)
func openPort(name string, baud int, databits byte, parity Parity, stopbits StopBits, readTimeout time.Duration) (p *Port, err error) {
return nil, errors.New("unsupported platform")
}
type Port struct {
}
func (p *Port) Read(b []byte) (n int, err error) {
return
}
func (p *Port) Write(b []byte) (n int, err error) {
return
}
func (p *Port) Close() (err error) {
return
}

View File

@ -0,0 +1,328 @@
//go:build windows
// +build windows
package serial
import (
"fmt"
"os"
"sync"
"syscall"
"time"
"unsafe"
)
type Port struct {
f *os.File
fd syscall.Handle
rl sync.Mutex
wl sync.Mutex
ro *syscall.Overlapped
wo *syscall.Overlapped
}
type structDCB struct {
DCBlength, BaudRate uint32
flags [4]byte
wReserved, XonLim, XoffLim uint16
ByteSize, Parity, StopBits byte
XonChar, XoffChar, ErrorChar, EofChar, EvtChar byte
wReserved1 uint16
}
type structTimeouts struct {
ReadIntervalTimeout uint32
ReadTotalTimeoutMultiplier uint32
ReadTotalTimeoutConstant uint32
WriteTotalTimeoutMultiplier uint32
WriteTotalTimeoutConstant uint32
}
func openPort(name string, baud int, databits byte, parity Parity, stopbits StopBits, readTimeout time.Duration) (p *Port, err error) {
if len(name) > 0 && name[0] != '\\' {
name = "\\\\.\\" + name
}
h, err := syscall.CreateFile(syscall.StringToUTF16Ptr(name),
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
0,
nil,
syscall.OPEN_EXISTING,
syscall.FILE_ATTRIBUTE_NORMAL|syscall.FILE_FLAG_OVERLAPPED,
0)
if err != nil {
return nil, err
}
f := os.NewFile(uintptr(h), name)
defer func() {
if err != nil {
f.Close()
}
}()
if err = setCommState(h, baud, databits, parity, stopbits); err != nil {
return nil, err
}
if err = setupComm(h, 64, 64); err != nil {
return nil, err
}
if err = setCommTimeouts(h, readTimeout); err != nil {
return nil, err
}
if err = setCommMask(h); err != nil {
return nil, err
}
ro, err := newOverlapped()
if err != nil {
return nil, err
}
wo, err := newOverlapped()
if err != nil {
return nil, err
}
port := new(Port)
port.f = f
port.fd = h
port.ro = ro
port.wo = wo
return port, nil
}
func (p *Port) Close() error {
return p.f.Close()
}
func (p *Port) Write(buf []byte) (int, error) {
p.wl.Lock()
defer p.wl.Unlock()
if err := resetEvent(p.wo.HEvent); err != nil {
return 0, err
}
var n uint32
err := syscall.WriteFile(p.fd, buf, &n, p.wo)
if err != nil && err != syscall.ERROR_IO_PENDING {
return int(n), err
}
return getOverlappedResult(p.fd, p.wo)
}
func (p *Port) Read(buf []byte) (int, error) {
if p == nil || p.f == nil {
return 0, fmt.Errorf("Invalid port on read")
}
p.rl.Lock()
defer p.rl.Unlock()
if err := resetEvent(p.ro.HEvent); err != nil {
return 0, err
}
var done uint32
err := syscall.ReadFile(p.fd, buf, &done, p.ro)
if err != nil && err != syscall.ERROR_IO_PENDING {
return int(done), err
}
return getOverlappedResult(p.fd, p.ro)
}
// Discards data written to the port but not transmitted,
// or data received but not read
func (p *Port) Flush() error {
return purgeComm(p.fd)
}
var (
nSetCommState,
nSetCommTimeouts,
nSetCommMask,
nSetupComm,
nGetOverlappedResult,
nCreateEvent,
nResetEvent,
nPurgeComm,
nFlushFileBuffers uintptr
)
func init() {
k32, err := syscall.LoadLibrary("kernel32.dll")
if err != nil {
panic("LoadLibrary " + err.Error())
}
defer syscall.FreeLibrary(k32)
nSetCommState = getProcAddr(k32, "SetCommState")
nSetCommTimeouts = getProcAddr(k32, "SetCommTimeouts")
nSetCommMask = getProcAddr(k32, "SetCommMask")
nSetupComm = getProcAddr(k32, "SetupComm")
nGetOverlappedResult = getProcAddr(k32, "GetOverlappedResult")
nCreateEvent = getProcAddr(k32, "CreateEventW")
nResetEvent = getProcAddr(k32, "ResetEvent")
nPurgeComm = getProcAddr(k32, "PurgeComm")
nFlushFileBuffers = getProcAddr(k32, "FlushFileBuffers")
}
func getProcAddr(lib syscall.Handle, name string) uintptr {
addr, err := syscall.GetProcAddress(lib, name)
if err != nil {
panic(name + " " + err.Error())
}
return addr
}
func setCommState(h syscall.Handle, baud int, databits byte, parity Parity, stopbits StopBits) error {
var params structDCB
params.DCBlength = uint32(unsafe.Sizeof(params))
params.flags[0] = 0x01 // fBinary
params.flags[0] |= 0x10 // Assert DSR
params.BaudRate = uint32(baud)
params.ByteSize = databits
switch parity {
case ParityNone:
params.Parity = 0
case ParityOdd:
params.Parity = 1
case ParityEven:
params.Parity = 2
case ParityMark:
params.Parity = 3
case ParitySpace:
params.Parity = 4
default:
return ErrBadParity
}
switch stopbits {
case Stop1:
params.StopBits = 0
case Stop1Half:
params.StopBits = 1
case Stop2:
params.StopBits = 2
default:
return ErrBadStopBits
}
r, _, err := syscall.Syscall(nSetCommState, 2, uintptr(h), uintptr(unsafe.Pointer(&params)), 0)
if r == 0 {
return err
}
return nil
}
func setCommTimeouts(h syscall.Handle, readTimeout time.Duration) error {
var timeouts structTimeouts
const MAXDWORD = 1<<32 - 1
// blocking read by default
var timeoutMs int64 = MAXDWORD - 1
if readTimeout > 0 {
// non-blocking read
timeoutMs = readTimeout.Nanoseconds() / 1e6
if timeoutMs < 1 {
timeoutMs = 1
} else if timeoutMs > MAXDWORD-1 {
timeoutMs = MAXDWORD - 1
}
}
/* From http://msdn.microsoft.com/en-us/library/aa363190(v=VS.85).aspx
For blocking I/O see below:
Remarks:
If an application sets ReadIntervalTimeout and
ReadTotalTimeoutMultiplier to MAXDWORD and sets
ReadTotalTimeoutConstant to a value greater than zero and
less than MAXDWORD, one of the following occurs when the
ReadFile function is called:
If there are any bytes in the input buffer, ReadFile returns
immediately with the bytes in the buffer.
If there are no bytes in the input buffer, ReadFile waits
until a byte arrives and then returns immediately.
If no bytes arrive within the time specified by
ReadTotalTimeoutConstant, ReadFile times out.
*/
timeouts.ReadIntervalTimeout = MAXDWORD
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD
timeouts.ReadTotalTimeoutConstant = uint32(timeoutMs)
r, _, err := syscall.Syscall(nSetCommTimeouts, 2, uintptr(h), uintptr(unsafe.Pointer(&timeouts)), 0)
if r == 0 {
return err
}
return nil
}
func setupComm(h syscall.Handle, in, out int) error {
r, _, err := syscall.Syscall(nSetupComm, 3, uintptr(h), uintptr(in), uintptr(out))
if r == 0 {
return err
}
return nil
}
func setCommMask(h syscall.Handle) error {
const EV_RXCHAR = 0x0001
r, _, err := syscall.Syscall(nSetCommMask, 2, uintptr(h), EV_RXCHAR, 0)
if r == 0 {
return err
}
return nil
}
func resetEvent(h syscall.Handle) error {
r, _, err := syscall.Syscall(nResetEvent, 1, uintptr(h), 0, 0)
if r == 0 {
return err
}
return nil
}
func purgeComm(h syscall.Handle) error {
const PURGE_TXABORT = 0x0001
const PURGE_RXABORT = 0x0002
const PURGE_TXCLEAR = 0x0004
const PURGE_RXCLEAR = 0x0008
r, _, err := syscall.Syscall(nPurgeComm, 2, uintptr(h),
PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR, 0)
if r == 0 {
return err
}
return nil
}
func newOverlapped() (*syscall.Overlapped, error) {
var overlapped syscall.Overlapped
r, _, err := syscall.Syscall6(nCreateEvent, 4, 0, 1, 0, 0, 0, 0)
if r == 0 {
return nil, err
}
overlapped.HEvent = syscall.Handle(r)
return &overlapped, nil
}
func getOverlappedResult(h syscall.Handle, overlapped *syscall.Overlapped) (int, error) {
var n int
r, _, err := syscall.Syscall6(nGetOverlappedResult, 4,
uintptr(h),
uintptr(unsafe.Pointer(overlapped)),
uintptr(unsafe.Pointer(&n)), 1, 0, 0)
if r == 0 {
return n, err
}
return n, nil
}

View File

@ -0,0 +1,66 @@
package serial
import (
"strconv"
"strings"
)
const (
DefaultPort = "COM1"
DefaultBaudRate = 9600
)
// COM1,9600,odd
func ParseConfigFromAddr(addr string) *Config {
cfg := &Config{
Name: DefaultPort,
Baud: DefaultBaudRate,
}
ss := strings.Split(addr, ",")
switch len(ss) {
case 1:
cfg.Name = ss[0]
case 2:
cfg.Name = ss[0]
cfg.Baud, _ = strconv.Atoi(ss[1])
case 3:
cfg.Name = ss[0]
cfg.Baud, _ = strconv.Atoi(ss[1])
cfg.Parity = parseParity(ss[2])
}
return cfg
}
func AddrFromConfig(cfg *Config) string {
ss := []string{
cfg.Name,
strconv.Itoa(cfg.Baud),
}
switch cfg.Parity {
case ParityEven:
ss = append(ss, "even")
case ParityOdd:
ss = append(ss, "odd")
case ParityMark:
ss = append(ss, "mark")
case ParitySpace:
ss = append(ss, "space")
}
return strings.Join(ss, ",")
}
func parseParity(s string) Parity {
switch strings.ToLower(s) {
case "o", "odd":
return ParityOdd
case "e", "even":
return ParityEven
case "m", "mark":
return ParityMark
case "s", "space":
return ParitySpace
default:
return ParityNone
}
}

View File

@ -8,11 +8,10 @@ import (
"github.com/go-gost/core/listener"
"github.com/go-gost/core/logger"
md "github.com/go-gost/core/metadata"
serial_util "github.com/go-gost/x/internal/util/serial"
serial "github.com/go-gost/x/internal/util/serial"
limiter "github.com/go-gost/x/limiter/traffic/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper"
"github.com/go-gost/x/registry"
goserial "github.com/tarm/serial"
)
func init() {
@ -35,7 +34,7 @@ func NewListener(opts ...listener.Option) listener.Listener {
}
if options.Addr == "" {
options.Addr = serial_util.DefaultPort
options.Addr = serial.DefaultPort
}
return &serialListener{
@ -49,7 +48,7 @@ func (l *serialListener) Init(md md.Metadata) (err error) {
return
}
l.addr = &serial_util.Addr{Port: l.options.Addr}
l.addr = &serial.Addr{Port: l.options.Addr}
l.cqueue = make(chan net.Conn)
l.closed = make(chan struct{})
@ -87,14 +86,14 @@ func (l *serialListener) listenLoop() {
for {
ctx, cancel := context.WithCancel(context.Background())
err := func() error {
cfg := serial_util.ParseConfigFromAddr(l.options.Addr)
cfg := serial.ParseConfigFromAddr(l.options.Addr)
cfg.ReadTimeout = l.md.timeout
port, err := goserial.OpenPort(cfg)
port, err := serial.OpenPort(cfg)
if err != nil {
return err
}
c := serial_util.NewConn(port, l.addr, cancel)
c := serial.NewConn(port, l.addr, cancel)
c = metrics.WrapConn(l.options.Service, c)
c = limiter.WrapConn(l.options.TrafficLimiter, c)