github.com/simpleiot/simpleiot@v0.18.3/modbus/rtu.go (about)

     1  package modbus
     2  
     3  import (
     4  	"encoding/binary"
     5  	"fmt"
     6  	"io"
     7  )
     8  
     9  // RtuADU defines an ADU for RTU packets
    10  type RtuADU struct {
    11  	PDU
    12  	Address byte
    13  	CRC     uint16
    14  }
    15  
    16  // RTU defines an RTU connection
    17  type RTU struct {
    18  	port io.ReadWriteCloser
    19  }
    20  
    21  // NewRTU creates a new RTU transport
    22  func NewRTU(port io.ReadWriteCloser) *RTU {
    23  	return &RTU{
    24  		port: port,
    25  	}
    26  }
    27  
    28  func (r *RTU) Read(p []byte) (int, error) {
    29  	return r.port.Read(p)
    30  }
    31  
    32  func (r *RTU) Write(p []byte) (int, error) {
    33  	return r.port.Write(p)
    34  }
    35  
    36  // Close closes the serial port
    37  func (r *RTU) Close() error {
    38  	return r.port.Close()
    39  }
    40  
    41  // Encode encodes a RTU packet
    42  func (r *RTU) Encode(id byte, pdu PDU) ([]byte, error) {
    43  	ret := make([]byte, len(pdu.Data)+2+2)
    44  	ret[0] = id
    45  	ret[1] = byte(pdu.FunctionCode)
    46  	copy(ret[2:], pdu.Data)
    47  	crc := RtuCrc(ret[:len(ret)-2])
    48  	binary.BigEndian.PutUint16(ret[len(ret)-2:], crc)
    49  	return ret, nil
    50  }
    51  
    52  // Decode decodes a RTU packet
    53  func (r *RTU) Decode(packet []byte) (byte, PDU, error) {
    54  	err := CheckRtuCrc(packet)
    55  	if err != nil {
    56  		return 0, PDU{}, err
    57  	}
    58  
    59  	ret := PDU{}
    60  
    61  	ret.FunctionCode = FunctionCode(packet[1])
    62  
    63  	if len(packet) < 4 {
    64  		return 0, PDU{}, fmt.Errorf("short packet, got %d bytes", len(packet))
    65  	}
    66  
    67  	id := packet[0]
    68  
    69  	ret.Data = packet[2 : len(packet)-2]
    70  
    71  	return id, ret, nil
    72  }
    73  
    74  // Type returns TransportType
    75  func (r *RTU) Type() TransportType {
    76  	return TransportTypeRTU
    77  }