sip

package
v0.0.0-...-c55b4a7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 10, 2024 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ElmDataState uint16 = 0x0001
	ElmName      uint16 = 0x0002
	ElmAttribute uint16 = 0x0004
	ElmUnit      uint16 = 0x0008
	ElmMin       uint16 = 0x0010
	ElmMax       uint16 = 0x0020
	ElmData      uint16 = 0x0040
)

Constants for the validElements field in ReadDescriptionResponse and ReadEverythingResponse

View Source
const BroadcastNameplateMsgType = MessageType(99)
View Source
const BrowseOnSlaveInterfaceRequestMsgType = MessageType(107)
View Source
const BrowseOnSlaveInterfaceResponseMsgType = MessageType(108)
View Source
const BrowseRequestMsgType = MessageType(91)
View Source
const BrowseResponseMsgType = MessageType(100)
View Source
const BusyResponseMsgType = MessageType(68)
View Source
const ConnectRequestMsgType = MessageType(63)
View Source
const ConnectResponseMsgType = MessageType(64)
View Source
const ConnectionError = uint16(1)

the server is not able to serve a TCP based S/IP connection. See TCP based communication initialization for further details.

View Source
const EchoMsgType = MessageType(32768)
View Source
const ExceptionMsgType = MessageType(67)
View Source
const IdentifyRequestMsgType = MessageType(93)
View Source
const IdentifyResponseMsgType = MessageType(94)
View Source
const InterfacesRequestMsgType = MessageType(103)
View Source
const InterfacesResponseMsgType = MessageType(104)
View Source
const NameplateRequestMsgType = MessageType(89)
View Source
const NameplateResponseMsgType = MessageType(90)
View Source
const PduProtocolMismatchError = uint16(6)

malformed PDU e.g. received UDP datagram does not correspond to the expected PDU size

View Source
const PduToLargeError = uint16(5)

request or response does not fit to the UDP datagram (limitation of PDU size)

View Source
const PingRequestMsgType = MessageType(65)
View Source
const PingResponseMsgType = MessageType(66)
View Source
const Port = 35021

Port is the default SIP port

View Source
const ReadApplicationsRequestMsgType = MessageType(137)
View Source
const ReadApplicationsResponseMsgType = MessageType(138)
View Source
const ReadDataStateRequestMsgType = MessageType(87)
View Source
const ReadDataStateResponseMsgType = MessageType(88)
View Source
const ReadDescriptionRequestMsgType = MessageType(73)
View Source
const ReadDescriptionResponseMsgType = MessageType(74)
View Source
const ReadEverythingRequestMsgType = MessageType(69)
View Source
const ReadEverythingResponseMsgType = MessageType(70)
View Source
const ReadNodesRequestMsgType = MessageType(139)
View Source
const ReadNodesResponseMsgType = MessageType(140)
View Source
const ReadOnlyDataRequestMsgType = MessageType(71)
View Source
const ReadOnlyDataResponseMsgType = MessageType(72)
View Source
const ReadSegmentRequestMsgType = MessageType(109)
View Source
const ReadSegmentResponseMsgType = MessageType(110)
View Source
const ReadSymbolDataRequestMsgType = MessageType(133)
View Source
const ReadSymbolDataResponseMsgType = MessageType(134)
View Source
const ReadSymbolDescriptionRequestMsgType = MessageType(131)
View Source
const ReadSymbolDescriptionResponseMsgType = MessageType(132)
View Source
const ReadSymbolEverythingRequestMsgType = MessageType(135)
View Source
const ReadSymbolEverythingResponseMsgType = MessageType(136)
View Source
const RemoteServiceRequestMsgType = MessageType(113)
View Source
const RemoteServiceResponseMsgType = MessageType(114)
View Source
const ReservedMsgType = MessageType(92)
View Source
const ResetRequestMsgType = MessageType(97)
View Source
const ResetResponseMsgType = MessageType(98)
View Source
const ServiceSpecificError = uint16(4)

Services are able to have their own error code. Further information are available in the SpecificErrorCode of the Exception structure. See also specific error code descriptions of the service invoked.

View Source
const SetIPRequestMsgType = MessageType(95)
View Source
const SetIPResponseMsgType = MessageType(96)
View Source
const SlavesRequestMsgType = MessageType(105)
View Source
const SlavesResponseMsgType = MessageType(106)
View Source
const SupportedUDPServicesMsgType = MessageType(61)
View Source
const SupportedUDPServicesResponseMsgType = MessageType(62)
View Source
const TimeoutError = uint16(2)

a timeout exceeds (see Timeouts for further details) or a TCP connection gets lost. Network activities are controlled by local timeout handling. If the server doesn't respond in time, this error code is used to indicate the error to the user on client-side.

View Source
const UnknownMessageTypeError = uint16(3)

s the server receives an unknown message type, it shall send an exception with this error code to the client. In case of a TCP based S/IP request the server returns the exception to the client and shall close the TCP stream socket connection.

View Source
const WatchdogRequestMsgType = MessageType(101)
View Source
const WatchdogResponseMsgType = MessageType(102)
View Source
const WriteAttributeRequestMsgType = MessageType(77)
View Source
const WriteAttributeResponseMsgType = MessageType(78)
View Source
const WriteDataBitsResponseMsgType = MessageType(86)
View Source
const WriteDataRequestBitsMsgType = MessageType(85)
View Source
const WriteDataRequestMsgType = MessageType(83)
View Source
const WriteDataResponseMsgType = MessageType(84)
View Source
const WriteMinMaxRequestMsgType = MessageType(81)
View Source
const WriteMinMaxResponseMsgType = MessageType(82)
View Source
const WriteNameRequestMsgType = MessageType(75)
View Source
const WriteNameResponseMsgType = MessageType(76)
View Source
const WriteSymbolDataResponseMsgType = MessageType(142)
View Source
const WriteSymbolRequestDataMsgType = MessageType(141)
View Source
const WriteUnitRequestMsgType = MessageType(79)
View Source
const WriteUnitResponseMsgType = MessageType(80)

Variables

View Source
var Error = errors.New("S/IP")

Error defines the S/IP error class. Base of all other S/IP errors

View Source
var ErrorClosed = fmt.Errorf("%w: Connection closed", Error)
View Source
var ErrorInvalidRequestMessageType = fmt.Errorf("%w: Invalid request message type", Error)
View Source
var ErrorInvalidResponseMessageType = fmt.Errorf("%w: Invalid response message type", Error)
View Source
var ErrorRetriesExceeded = fmt.Errorf("%w: Reconnect timeout exceeded", Error)
View Source
var ErrorTimeout = fmt.Errorf("%w: Timeout", Error)

Functions

func BroadcastBrowseRequest

func BroadcastBrowseRequest(conn net.PacketConn) error

BroadcastBrowseRequest broadcasts a BrowseRequest on the passed net.PacketConn from ListenToBrowseResponses. Note that the net.PacketConn will be closed when ListenToBrowseResponses is canceled.

func Browse

func Browse(ctx context.Context, interfaceName string) (<-chan Result[*BrowseResponse], error)

Browse listens to BrowseResponses and broadcasts one BrowseRequest on the given interface. The Listening ends when ctx is canceled.

func ListenToBrowseResponses

func ListenToBrowseResponses(ctx context.Context, interfaceName string) ([]net.PacketConn, <-chan Result[*BrowseResponse], error)

ListenToBrowseResponses listens on interfaceName for BrowseResponses until ctx is canceled. It automatically reserves a free port for listening. The returned net.PacketConn should be used to send BrowseRequests on the listened port. The channel returns any valid BrowseResponse that is received, all errors occured while parsing received packages and all errors with the net.PacketConn. The connection and the channel are closed in case of errors of the latter category.

func Mux

func Mux(ctx context.Context, listener net.Listener, source SyncClient, options ...ConnOption) error

Mux creates a multiplexer which listens on the given listener and forwards the S/IP requests to the source. Reads are optimized by reading only once and broadcasting the response to all listeners. Mux is useful when the source has limited resources and can't handle a larger number of multiple connections.

func SendBrowseRequest

func SendBrowseRequest(conn net.PacketConn, address string) error

SendBrowseRequest sends a BrowseRequest on the passed net.PacketConn to a dedicated IP address.

func Serve

func Serve(ctx context.Context, listener net.Listener, source SyncClient, options ...ConnOption) error

Serve creates a server which listens on the given listener and forwards the S/IP requests to the source.

Types

type BrowseRequest

type BrowseRequest struct {
	IPAddress          [4]byte
	MasterOnly         bool
	LowerSercosAddress uint16
	UpperSercosAddress uint16
}

func (*BrowseRequest) MessageType

func (b *BrowseRequest) MessageType() MessageType

func (*BrowseRequest) Read

func (b *BrowseRequest) Read(reader io.Reader) error

func (*BrowseRequest) Write

func (b *BrowseRequest) Write(writer io.Writer) error

type BrowseResponse

type BrowseResponse struct {
	DisplayName []byte

	HostNameLength uint32
	HostName       []byte
	// contains filtered or unexported fields
}

func (*BrowseResponse) MessageType

func (b *BrowseResponse) MessageType() MessageType

func (*BrowseResponse) Read

func (b *BrowseResponse) Read(reader io.Reader) error

func (*BrowseResponse) Write

func (b *BrowseResponse) Write(writer io.Writer) error

type Client

type Client interface {
	ConnProperties
	SyncClient

	GoPing(options ...RequestOption) <-chan error

	GoReadEverything(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) <-chan Result[ReadEverythingResponse]
	GoReadOnlyData(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) <-chan Result[ReadOnlyDataResponse]
	GoReadDescription(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) <-chan Result[ReadDescriptionResponse]
	GoReadDataState(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) <-chan Result[ReadDataStateResponse]

	GoWriteData(slaveIndex, slaveExtension int, idn uint32, data []byte, options ...RequestOption) <-chan error

	Close() error
	Closed() bool
}

Client is like Conn, but with automatic reconnect, a configurable timeout strategy for reconnection, the possibility to cancel single requests with a context.Context and to automatically retry requests.

Ping, ReadXXX, WriteData work like the Conn methods but try to reconnect when the underlying connection has been closed meanwhile. Their further behavior can be configured with options. The GoXXX variants of the methods work asynchronously by returning a channel.

Close closes the currently open connection, if there is anyone yet.

func NewClient

func NewClient(network, address string, options ...ConnOption) Client

NewClient creates a new Client. The backoff strategy for failed connects can be configured with the WithDialBackoff option. If the option is not given, the backoff strategy is an exponential backoff, starting with a backoff time of 500ms, exponentially incremented by factor 1.5, with an overall timeout of 10 seconds. All other options are ignored.

type Conn

type Conn interface {
	ConnProperties

	Ping(ctx context.Context) error

	ReadEverything(ctx context.Context, slaveIndex, slaveExtension int, idn uint32) (ReadEverythingResponse, error)
	ReadOnlyData(ctx context.Context, slaveIndex, slaveExtension int, idn uint32) (ReadOnlyDataResponse, error)
	ReadDescription(ctx context.Context, slaveIndex, slaveExtension int, idn uint32) (ReadDescriptionResponse, error)
	ReadDataState(ctx context.Context, slaveIndex, slaveExtension int, idn uint32) (ReadDataStateResponse, error)
	WriteData(ctx context.Context, slaveIndex, slaveExtension int, idn uint32, data []byte) error

	Close() error
	Closed() bool
}

Conn is a SIP client connection. It can be used to read and write SERCOS parameter values. Its lifetime starts with Dial and ends when the user calls Close, the server does not answer in timely manner (BusyTimeout) or the underlying net.Conn has been closed.

When Dial is successful, the S/IP Connect procedure has already been executed. Ping, ReadXXX, WriteData send the according Request and try to receive the matching Response. They return either with an error or when the Response has been received successfuly.

Conn is able to execute more than one concurrent transaction, see WithConcurrentTransactionLimit.

func Dial

func Dial(network, address string, options ...ConnOption) (Conn, error)

Dial opens a Conn and connects it.

type ConnOption

type ConnOption func(c *connOptions) error

ConnOption is option for Conn

func WithBusyTimeout

func WithBusyTimeout(timeout int) ConnOption

WithBusyTimeout sets the BusyTimeout to negotiate with the server in ms. Default is 2000ms.

func WithConcurrentTransactionLimit

func WithConcurrentTransactionLimit(ct uint) ConnOption

WithConcurrentTransactionLimit limits the number of concurrent requests sent. If the option is not given in Dial, the concurrency is not limited.

func WithDial

func WithDial(dial func(string, string) (io.ReadWriteCloser, error)) ConnOption

WithDial surpasses the net.Conn from the Dial function. This option can be used for testing, logging, middleware purposes in general, or exotic connection types.

func WithDialBackoff

func WithDialBackoff(backoffFactory func() backoff.BackOff) ConnOption

WithDialBackoff configures the backoff strategy for failed connects. See https://pkg.go.dev/github.com/cenkalti/backoff/v4 for more information about backoff strategies. Default is an exponential backoff, starting with a backoff time of 500ms, exponentially incremented by factor 1.5, with an overall timeout of 10 seconds.

func WithLeaseTimeout

func WithLeaseTimeout(timeout int) ConnOption

WithLeaseTimeout sets the LeaseTimeout to negotiate with the server in ms. Default is 10000ms.

func WithMeasureNetworkLatencyICMP

func WithMeasureNetworkLatencyICMP() ConnOption

WithMeasureNetworkLatencyICMP measures the network latency with an ICMP ping. If not set, the network latency is measured with S/IP Ping, which might lead to different latency results, depending on the server implementation. Note that ICMP ping requires specific system config options mentioned here: https://github.com/prometheus-community/#supported-operating-systems

func WithSendKeepAlive

func WithSendKeepAlive() ConnOption

WithSendKeepAlive configures the connection that it is sending Ping requests shortly before the LeaseTimeout ends.

func WithWriter

func WithWriter(writerFactory func(io.Writer) io.Writer) ConnOption

WithWriter allows to control the way requests are sent to the net.Conn. This can be useful to group request and/or send them at defined points in time.

type ConnProperties

type ConnProperties interface {
	Connected() bool

	BusyTimeout() time.Duration
	LeaseTimeout() time.Duration
	LastReceived() time.Time

	MessageTypes() []uint32
}

ConnProperties describes the properties of a Conn.

Connected() bool

If the Conn is currently connected

BusyTimeout() time.Duration

Time span after the server acknowledged to send a Busy response if it is not able to respond to open requests.

LeaseTimeout() time.Duration

Time span without requests after the server will close the connection. When the WithKeepAlive() option is used, the connection will send a Ping request shortly before this time span ends.

LastReceived() time.Time

Timestamp when the last response from the server was received. The Client uses this information to decide if to send a request over the current connection or to open a new one. By this, timeouts caused by servers which do not close the net.Conn directly after they decide to close the SIP connection can be evaded.

type ConnectRequest

type ConnectRequest struct {
	// S/IP protocol version
	// version=1 shall be used for this protocol version
	Version uint32
	// requested busy-timeout the server should use, in milliseconds
	BusyTimeout uint32
	// requested lease-timeout the server should use, in milliseconds
	LeaseTimeout uint32
}

ConnectRequest MessageType 63 In order to initiate a S/IP connection, the client sends a ConnectRequest PDU to the server. This request contains the desired S/IP version number and desired timeout values for the connection.

func (*ConnectRequest) MessageType

func (c *ConnectRequest) MessageType() MessageType

func (*ConnectRequest) Read

func (c *ConnectRequest) Read(reader io.Reader) error

func (*ConnectRequest) Write

func (c *ConnectRequest) Write(writer io.Writer) error

type ConnectResponse

type ConnectResponse struct {

	// supported Request MessageTypes of the server on this TCP connection.
	// The client must only use these message types in a request.
	MessageTypes []uint32
	// contains filtered or unexported fields
}

func (*ConnectResponse) MessageType

func (c *ConnectResponse) MessageType() MessageType

func (*ConnectResponse) Read

func (c *ConnectResponse) Read(reader io.Reader) error

func (*ConnectResponse) Write

func (c *ConnectResponse) Write(writer io.Writer) error

type Exception

type Exception struct {
	CommonErrorCode   uint16
	SpecificErrorCode uint32
}

Exception, MessageType: 67. It contains a common error code and an optional service specific error code.

func (Exception) Error

func (c Exception) Error() string

func (*Exception) MessageType

func (c *Exception) MessageType() MessageType

func (*Exception) Read

func (c *Exception) Read(reader io.Reader) error

func (Exception) Unwrap

func (c Exception) Unwrap() error

func (*Exception) Write

func (c *Exception) Write(writer io.Writer) error
type Header struct {
	TransactionID uint32
	MessageType   MessageType
}

func (*Header) Read

func (h *Header) Read(reader io.Reader) error

func (*Header) Write

func (h *Header) Write(writer io.Writer) error

type Idn

type Idn uint32

func (Idn) String

func (i Idn) String() string

type MessageType

type MessageType uint32

type PDU

type PDU interface {
	Read(io.Reader) error
	Write(io.Writer) error
	MessageType() MessageType
}

PDU can be read from bytes and written to bytes and have a message type

type PingRequest

type PingRequest struct{}

func (*PingRequest) MessageType

func (c *PingRequest) MessageType() MessageType

func (*PingRequest) Read

func (c *PingRequest) Read(io.Reader) error

func (*PingRequest) Write

func (c *PingRequest) Write(io.Writer) error

type PingResponse

type PingResponse struct{}

func (*PingResponse) MessageType

func (c *PingResponse) MessageType() MessageType

func (*PingResponse) Read

func (c *PingResponse) Read(io.Reader) error

func (*PingResponse) Write

func (c *PingResponse) Write(io.Writer) error

type ReadDataStateRequest

type ReadDataStateRequest Request

func (*ReadDataStateRequest) Init

func (r *ReadDataStateRequest) Init(slaveIndex, slaveExtension int, idn uint32)

func (*ReadDataStateRequest) MessageType

func (r *ReadDataStateRequest) MessageType() MessageType

func (*ReadDataStateRequest) Read

func (r *ReadDataStateRequest) Read(reader io.Reader) error

func (*ReadDataStateRequest) Write

func (r *ReadDataStateRequest) Write(writer io.Writer) error

type ReadDataStateResponse

type ReadDataStateResponse struct {
	DataState uint16
}

func (*ReadDataStateResponse) MessageType

func (r *ReadDataStateResponse) MessageType() MessageType

func (*ReadDataStateResponse) Read

func (r *ReadDataStateResponse) Read(reader io.Reader) error

func (*ReadDataStateResponse) Write

func (r *ReadDataStateResponse) Write(writer io.Writer) error

type ReadDescriptionRequest

type ReadDescriptionRequest Request

func (*ReadDescriptionRequest) Init

func (r *ReadDescriptionRequest) Init(slaveIndex, slaveExtension int, idn uint32)

func (*ReadDescriptionRequest) MessageType

func (r *ReadDescriptionRequest) MessageType() MessageType

func (*ReadDescriptionRequest) Read

func (r *ReadDescriptionRequest) Read(reader io.Reader) error

func (*ReadDescriptionRequest) Write

func (r *ReadDescriptionRequest) Write(writer io.Writer) error

type ReadDescriptionResponse

type ReadDescriptionResponse struct {
	Name []byte
	Unit []byte
	// contains filtered or unexported fields
}

func (*ReadDescriptionResponse) MessageType

func (r *ReadDescriptionResponse) MessageType() MessageType

func (*ReadDescriptionResponse) Read

func (r *ReadDescriptionResponse) Read(reader io.Reader) error

func (*ReadDescriptionResponse) Write

func (r *ReadDescriptionResponse) Write(writer io.Writer) error

type ReadEverythingRequest

type ReadEverythingRequest Request

func (*ReadEverythingRequest) MessageType

func (r *ReadEverythingRequest) MessageType() MessageType

func (*ReadEverythingRequest) Read

func (r *ReadEverythingRequest) Read(reader io.Reader) error

func (*ReadEverythingRequest) Write

func (r *ReadEverythingRequest) Write(writer io.Writer) error

type ReadEverythingResponse

type ReadEverythingResponse struct {
	Name []byte
	Unit []byte
	Data []byte
	// contains filtered or unexported fields
}

func (*ReadEverythingResponse) MessageType

func (r *ReadEverythingResponse) MessageType() MessageType

func (*ReadEverythingResponse) Read

func (r *ReadEverythingResponse) Read(reader io.Reader) error

func (*ReadEverythingResponse) Write

func (r *ReadEverythingResponse) Write(writer io.Writer) error

type ReadOnlyDataRequest

type ReadOnlyDataRequest Request

func (*ReadOnlyDataRequest) Init

func (r *ReadOnlyDataRequest) Init(slaveIndex, slaveExtension int, idn uint32)

func (*ReadOnlyDataRequest) MessageType

func (r *ReadOnlyDataRequest) MessageType() MessageType

func (*ReadOnlyDataRequest) Read

func (r *ReadOnlyDataRequest) Read(reader io.Reader) error

func (*ReadOnlyDataRequest) Write

func (r *ReadOnlyDataRequest) Write(writer io.Writer) error

type ReadOnlyDataResponse

type ReadOnlyDataResponse struct {
	Data []byte
	// contains filtered or unexported fields
}

func (*ReadOnlyDataResponse) MessageType

func (r *ReadOnlyDataResponse) MessageType() MessageType

func (*ReadOnlyDataResponse) Read

func (r *ReadOnlyDataResponse) Read(reader io.Reader) error

func (*ReadOnlyDataResponse) Write

func (r *ReadOnlyDataResponse) Write(writer io.Writer) error

type Request

type Request struct {
	SlaveIndex     uint16
	SlaveExtension uint16
	IDN            uint32
}

Request is the address part of a PDU

type RequestOption

type RequestOption func(r *requestOptions) error

RequestOption is a option for any kind of request

func WithContext

func WithContext(ctx context.Context) RequestOption

WithContext allows to cancel a request with a context.

func WithRetries

func WithRetries(retries uint) RequestOption

WithRetries configures how often a request is retried when it fails. Default is no retry.

func WithTimeout

func WithTimeout(timeout time.Duration) RequestOption

WithTimeout allows to cancel a request with a timeout.

type Result

type Result[T any] struct {
	Ok  T
	Err error
}

func Err

func Err[T any](err error) Result[T]

func NewResult

func NewResult[T any](ok T, err error) Result[T]

func Ok

func Ok[T any](t T) Result[T]

type SyncClient

type SyncClient interface {
	Ping(options ...RequestOption) error

	ReadEverything(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) (ReadEverythingResponse, error)
	ReadOnlyData(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) (ReadOnlyDataResponse, error)
	ReadDescription(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) (ReadDescriptionResponse, error)
	ReadDataState(slaveIndex, slaveExtension int, idn uint32, options ...RequestOption) (ReadDataStateResponse, error)

	WriteData(slaveIndex, slaveExtension int, idn uint32, data []byte, options ...RequestOption) error
}

type WriteDataRequest

type WriteDataRequest struct {
	Data []byte
	// contains filtered or unexported fields
}

func (*WriteDataRequest) MessageType

func (w *WriteDataRequest) MessageType() MessageType

func (*WriteDataRequest) Read

func (w *WriteDataRequest) Read(reader io.Reader) error

func (*WriteDataRequest) Write

func (w *WriteDataRequest) Write(writer io.Writer) error

type WriteDataResponse

type WriteDataResponse struct{}

func (*WriteDataResponse) MessageType

func (c *WriteDataResponse) MessageType() MessageType

func (*WriteDataResponse) Read

func (c *WriteDataResponse) Read(io.Reader) error

func (*WriteDataResponse) Write

func (c *WriteDataResponse) Write(io.Writer) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL