diff --git a/serial.go b/serial.go index abfd7f9..50c758a 100644 --- a/serial.go +++ b/serial.go @@ -49,6 +49,11 @@ type Port interface { // to disable read timeout. SetReadTimeout(t time.Duration) error + // SetBufferSize sets internal buffer sizes for the Read and Write operations. + // Please note that this function may not be available on all OS: + // in that case a FunctionNotImplemented error is returned. + SetBufferSize(txSize, rxSize int) error + // Close the serial port Close() error @@ -159,6 +164,8 @@ const ( InvalidStopBits // InvalidTimeoutValue the timeout value is not valid or not supported InvalidTimeoutValue + // InvalidBufferSize the requested buffer size is not valid or not supported + InvalidBufferSize // ErrorEnumeratingPorts an error occurred while listing serial port ErrorEnumeratingPorts // PortClosed the port has been closed while the operation is in progress @@ -188,6 +195,8 @@ func (e PortError) EncodedErrorString() string { return "Port stop bits invalid or not supported" case InvalidTimeoutValue: return "Timeout value invalid or not supported" + case InvalidBufferSize: + return "Buffer size value invalid or not supported" case ErrorEnumeratingPorts: return "Could not enumerate serial ports" case PortClosed: diff --git a/serial_unix.go b/serial_unix.go index f6ec896..6c52c08 100644 --- a/serial_unix.go +++ b/serial_unix.go @@ -198,6 +198,12 @@ func (port *unixPort) SetReadTimeout(timeout time.Duration) error { return nil } +func (port *unixPort) SetBufferSize(rxSize, txSize int) error { + // Unix does not provide any means to change the buffer size from 4096 bytes. + // The only reported way to do so is the kernel recompilation. + return &PortError{code: FunctionNotImplemented, causedBy: nil} +} + func (port *unixPort) GetModemStatusBits() (*ModemStatusBits, error) { status, err := port.getModemBitsStatus() if err != nil { diff --git a/serial_windows.go b/serial_windows.go index 287856a..bf1b4e1 100644 --- a/serial_windows.go +++ b/serial_windows.go @@ -385,6 +385,17 @@ func (port *windowsPort) SetReadTimeout(timeout time.Duration) error { return nil } +func (port *windowsPort) SetBufferSize(rxSize, txSize int) error { + rxSize_ := uint32(rxSize) + txSize_ := uint32(txSize) + + if err := setupComm(port.handle, rxSize_, txSize_); err != nil { + return &PortError{code: InvalidBufferSize, causedBy: err} + } + + return nil +} + func (port *windowsPort) Break(d time.Duration) error { if err := setCommBreak(port.handle); err != nil { return &PortError{causedBy: err} diff --git a/syscall_windows.go b/syscall_windows.go index c814528..0bbc5e8 100644 --- a/syscall_windows.go +++ b/syscall_windows.go @@ -12,6 +12,8 @@ package serial //sys setCommState(handle syscall.Handle, dcb *dcb) (err error) = SetCommState +//sys setupComm(handle syscall.Handle, rxSize uint32, txSize uint32) (err error) = SetupComm + //sys setCommTimeouts(handle syscall.Handle, timeouts *commTimeouts) (err error) = SetCommTimeouts //sys escapeCommFunction(handle syscall.Handle, function uint32) (res bool) = EscapeCommFunction diff --git a/zsyscall_windows.go b/zsyscall_windows.go index a2411a6..d32cd0c 100644 --- a/zsyscall_windows.go +++ b/zsyscall_windows.go @@ -53,6 +53,7 @@ var ( procSetCommBreak = modkernel32.NewProc("SetCommBreak") procSetCommState = modkernel32.NewProc("SetCommState") procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") + procSetupComm = modkernel32.NewProc("SetupComm") ) func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, value *uint16, valueLen *uint32) (regerrno error) { @@ -159,3 +160,11 @@ func setCommTimeouts(handle syscall.Handle, timeouts *commTimeouts) (err error) } return } + +func setupComm(handle syscall.Handle, rxSize uint32, txSize uint32) (err error) { + r1, _, e1 := syscall.Syscall(procSetupComm.Addr(), 3, uintptr(handle), uintptr(rxSize), uintptr(txSize)) + if r1 == 0 { + err = errnoErr(e1) + } + return +}