mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-14 19:29:11 +08:00

* NOISSUE- Add OPC-UA adapter Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * NOISSUE - Add opc-adapter PoC, docker and vendor Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Convert OPC messages to SenML Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Add gopcua package Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * lora-adapter typo Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Add OPC Reader Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Typo fix Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Typo fix Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Update copyright headers Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Fix reviews Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Fix reviews Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Add opc config Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Add all opc envars in the config Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Config typo Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Add route map Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Use opcua package instead of opc Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Fix OPCUA typo Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Rm MQTT sub Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Move interefaces to root Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Fix revieews and typo Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Update Gopkg.toml Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com> * Add all envars into .env Signed-off-by: Manuel Imperiale <manuel.imperiale@gmail.com>
184 lines
4.1 KiB
Go
184 lines
4.1 KiB
Go
// Copyright 2018-2019 opcua authors. All rights reserved.
|
|
// Use of this source code is governed by a MIT-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
package uacp
|
|
|
|
import (
|
|
"github.com/gopcua/opcua/errors"
|
|
"github.com/gopcua/opcua/ua"
|
|
)
|
|
|
|
// MessageType definitions.
|
|
//
|
|
// Specification: Part 6, 7.1.2.2
|
|
const (
|
|
MessageTypeHello = "HEL"
|
|
MessageTypeAcknowledge = "ACK"
|
|
MessageTypeError = "ERR"
|
|
MessageTypeReverseHello = "RHE"
|
|
)
|
|
|
|
// ChunkType definitions.
|
|
//
|
|
// Specification: Part 6, 6.7.2.2
|
|
const (
|
|
ChunkTypeIntermediate = 'C'
|
|
ChunkTypeFinal = 'F'
|
|
ChunkTypeAbort = 'A'
|
|
)
|
|
|
|
// Header represents a OPC UA Connection Header.
|
|
//
|
|
// Specification: Part 6, 7.1.2.2
|
|
type Header struct {
|
|
MessageType string
|
|
ChunkType byte
|
|
MessageSize uint32
|
|
}
|
|
|
|
func (h *Header) Decode(b []byte) (int, error) {
|
|
buf := ua.NewBuffer(b)
|
|
h.MessageType = string(buf.ReadN(3))
|
|
h.ChunkType = buf.ReadByte()
|
|
h.MessageSize = buf.ReadUint32()
|
|
return buf.Pos(), buf.Error()
|
|
}
|
|
|
|
func (h *Header) Encode() ([]byte, error) {
|
|
buf := ua.NewBuffer(nil)
|
|
if len(h.MessageType) != 3 {
|
|
return nil, errors.Errorf("invalid message type: %q", h.MessageType)
|
|
}
|
|
buf.Write([]byte(h.MessageType))
|
|
buf.WriteByte(h.ChunkType)
|
|
buf.WriteUint32(h.MessageSize)
|
|
return buf.Bytes(), buf.Error()
|
|
}
|
|
|
|
// Hello represents a OPC UA Hello.
|
|
//
|
|
// Specification: Part6, 7.1.2.3
|
|
type Hello struct {
|
|
Version uint32
|
|
ReceiveBufSize uint32
|
|
SendBufSize uint32
|
|
MaxMessageSize uint32
|
|
MaxChunkCount uint32
|
|
EndpointURL string
|
|
}
|
|
|
|
func (h *Hello) Decode(b []byte) (int, error) {
|
|
buf := ua.NewBuffer(b)
|
|
h.Version = buf.ReadUint32()
|
|
h.ReceiveBufSize = buf.ReadUint32()
|
|
h.SendBufSize = buf.ReadUint32()
|
|
h.MaxMessageSize = buf.ReadUint32()
|
|
h.MaxChunkCount = buf.ReadUint32()
|
|
h.EndpointURL = buf.ReadString()
|
|
return buf.Pos(), buf.Error()
|
|
}
|
|
|
|
func (h *Hello) Encode() ([]byte, error) {
|
|
buf := ua.NewBuffer(nil)
|
|
buf.WriteUint32(h.Version)
|
|
buf.WriteUint32(h.ReceiveBufSize)
|
|
buf.WriteUint32(h.SendBufSize)
|
|
buf.WriteUint32(h.MaxMessageSize)
|
|
buf.WriteUint32(h.MaxChunkCount)
|
|
buf.WriteString(h.EndpointURL)
|
|
return buf.Bytes(), buf.Error()
|
|
}
|
|
|
|
// Acknowledge represents a OPC UA Acknowledge.
|
|
//
|
|
// Specification: Part6, 7.1.2.4
|
|
type Acknowledge struct {
|
|
Version uint32
|
|
ReceiveBufSize uint32
|
|
SendBufSize uint32
|
|
MaxMessageSize uint32
|
|
MaxChunkCount uint32
|
|
}
|
|
|
|
func (a *Acknowledge) Decode(b []byte) (int, error) {
|
|
buf := ua.NewBuffer(b)
|
|
a.Version = buf.ReadUint32()
|
|
a.ReceiveBufSize = buf.ReadUint32()
|
|
a.SendBufSize = buf.ReadUint32()
|
|
a.MaxMessageSize = buf.ReadUint32()
|
|
a.MaxChunkCount = buf.ReadUint32()
|
|
return buf.Pos(), buf.Error()
|
|
}
|
|
|
|
func (a *Acknowledge) Encode() ([]byte, error) {
|
|
buf := ua.NewBuffer(nil)
|
|
buf.WriteUint32(a.Version)
|
|
buf.WriteUint32(a.ReceiveBufSize)
|
|
buf.WriteUint32(a.SendBufSize)
|
|
buf.WriteUint32(a.MaxMessageSize)
|
|
buf.WriteUint32(a.MaxChunkCount)
|
|
return buf.Bytes(), buf.Error()
|
|
}
|
|
|
|
// ReverseHello represents a OPC UA ReverseHello.
|
|
//
|
|
// Specification: Part6, 7.1.2.6
|
|
type ReverseHello struct {
|
|
ServerURI string
|
|
EndpointURL string
|
|
}
|
|
|
|
func (r *ReverseHello) Decode(b []byte) (int, error) {
|
|
buf := ua.NewBuffer(b)
|
|
r.ServerURI = buf.ReadString()
|
|
r.EndpointURL = buf.ReadString()
|
|
return buf.Pos(), buf.Error()
|
|
}
|
|
|
|
func (r *ReverseHello) Encode() ([]byte, error) {
|
|
buf := ua.NewBuffer(nil)
|
|
buf.WriteString(r.ServerURI)
|
|
buf.WriteString(r.EndpointURL)
|
|
return buf.Bytes(), buf.Error()
|
|
}
|
|
|
|
// Error represents a OPC UA Error.
|
|
//
|
|
// Specification: Part6, 7.1.2.5
|
|
type Error struct {
|
|
ErrorCode uint32
|
|
Reason string
|
|
}
|
|
|
|
func (e *Error) Decode(b []byte) (int, error) {
|
|
buf := ua.NewBuffer(b)
|
|
e.ErrorCode = buf.ReadUint32()
|
|
e.Reason = buf.ReadString()
|
|
return buf.Pos(), buf.Error()
|
|
}
|
|
|
|
func (e *Error) Encode() ([]byte, error) {
|
|
buf := ua.NewBuffer(nil)
|
|
buf.WriteUint32(e.ErrorCode)
|
|
buf.WriteString(e.Reason)
|
|
return buf.Bytes(), buf.Error()
|
|
}
|
|
|
|
func (e *Error) Error() string {
|
|
return ua.StatusCode(e.ErrorCode).Error()
|
|
}
|
|
|
|
type Message struct {
|
|
Data []byte
|
|
}
|
|
|
|
func (m *Message) Decode(b []byte) (int, error) {
|
|
m.Data = b
|
|
return len(b), nil
|
|
}
|
|
|
|
func (m *Message) Encode() ([]byte, error) {
|
|
return m.Data, nil
|
|
}
|