Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 78 additions & 84 deletions client_ld.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,101 +23,95 @@ func (c *Client) GetLogicalDeviceList() DataModel {
logicalNode := logicalNodes.next

for logicalNode != nil {
var ln LN
ln.Data = C2GoStr((*C.char)(logicalNode.data))

lnRef := fmt.Sprintf("%s/%s", ld.Data, C2GoStr((*C.char)(logicalNode.data)))

cRef := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(cRef))
dataObjects := C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, cRef, C.ACSI_CLASS_DATA_OBJECT)
dataObject := dataObjects.next
for dataObject != nil {
var do DO
do.Data = C2GoStr((*C.char)(dataObject.data))

dataObject = dataObject.next
doRef := fmt.Sprintf("%s/%s.%s", C2GoStr((*C.char)(device.data)), C2GoStr((*C.char)(logicalNode.data)), do.Data)

var das []DA
c.GetDAs(doRef, das)

do.DAs = das
ln.DOs = append(ln.DOs, do)
}

C.LinkedList_destroy(dataObjects)

clnRef := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(clnRef))

dataSets := C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, clnRef, C.ACSI_CLASS_DATA_SET)
dataSet := dataSets.next
for dataSet != nil {
var ds DS
ds.Data = C2GoStr((*C.char)(dataSet.data))

var isDeletable C.bool
dataSetRef := fmt.Sprintf("%s.%s", lnRef, ds.Data)

cdataSetRef := Go2CStr(dataSetRef)
defer C.free(unsafe.Pointer(cdataSetRef))

dataSetMembers := C.IedConnection_getDataSetDirectory(c.conn, &clientError, cdataSetRef, &isDeletable)

if isDeletable {
fmt.Println(fmt.Sprintf(" Data set: %s (deletable)", ds.Data))
} else {
fmt.Println(fmt.Sprintf(" Data set: %s (not deletable)", ds.Data))
func() {
var ln LN
ln.Data = C2GoStr((*C.char)(logicalNode.data))
lnRef := fmt.Sprintf("%s/%s", ld.Data, C2GoStr((*C.char)(logicalNode.data)))
cRef := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(cRef))
dataObjects := C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, cRef, C.ACSI_CLASS_DATA_OBJECT)
dataObject := dataObjects.next
for dataObject != nil {
var do DO
do.Data = C2GoStr((*C.char)(dataObject.data))

dataObject = dataObject.next
doRef := fmt.Sprintf("%s/%s.%s", C2GoStr((*C.char)(device.data)), C2GoStr((*C.char)(logicalNode.data)), do.Data)

var das []DA
c.GetDAs(doRef, das)

do.DAs = das
ln.DOs = append(ln.DOs, do)
}

dataSetMemberRef := dataSetMembers.next
for dataSetMemberRef != nil {
var dsRef DSRef
dsRef.Data = C2GoStr((*C.char)(dataSetMemberRef.data))
ds.DSRefs = append(ds.DSRefs, dsRef)

dataSetMemberRef = dataSetMemberRef.next
C.LinkedList_destroy(dataObjects)
clnRef := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(clnRef))
dataSets := C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, clnRef, C.ACSI_CLASS_DATA_SET)
dataSet := dataSets.next
for dataSet != nil {
func() {
var ds DS
ds.Data = C2GoStr((*C.char)(dataSet.data))
var isDeletable C.bool
dataSetRef := fmt.Sprintf("%s.%s", lnRef, ds.Data)
cdataSetRef := Go2CStr(dataSetRef)
defer C.free(unsafe.Pointer(cdataSetRef))

dataSetMembers := C.IedConnection_getDataSetDirectory(c.conn, &clientError, cdataSetRef, &isDeletable)
if isDeletable {
fmt.Printf(" Data set: %s (deletable)\n", ds.Data)
} else {
fmt.Printf(" Data set: %s (not deletable)\n", ds.Data)
}
dataSetMemberRef := dataSetMembers.next
for dataSetMemberRef != nil {
var dsRef DSRef
dsRef.Data = C2GoStr((*C.char)(dataSetMemberRef.data))
ds.DSRefs = append(ds.DSRefs, dsRef)

dataSetMemberRef = dataSetMemberRef.next
}
C.LinkedList_destroy(dataSetMembers)
dataSet = dataSet.next
ln.DSs = append(ln.DSs, ds)
}()
}
C.LinkedList_destroy(dataSetMembers)
dataSet = dataSet.next
ln.DSs = append(ln.DSs, ds)
}

C.LinkedList_destroy(dataSets)
C.LinkedList_destroy(dataSets)

clnRef1 := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(clnRef1))
clnRef1 := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(clnRef1))

reports := C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, clnRef1, C.ACSI_CLASS_URCB)
report := reports.next
for report != nil {
var r URReport
r.Data = C2GoStr((*C.char)(report.data))
ln.URReports = append(ln.URReports, r)
reports := C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, clnRef1, C.ACSI_CLASS_URCB)
report := reports.next
for report != nil {
var r URReport
r.Data = C2GoStr((*C.char)(report.data))
ln.URReports = append(ln.URReports, r)

report = report.next
}
C.LinkedList_destroy(reports)
report = report.next
}
C.LinkedList_destroy(reports)

clnRef2 := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(clnRef2))
clnRef2 := Go2CStr(lnRef)
defer C.free(unsafe.Pointer(clnRef2))

reports = C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, clnRef2, C.ACSI_CLASS_BRCB)
report = reports.next
for report != nil {
var r BRReport
r.Data = C2GoStr((*C.char)(report.data))
ln.BRReports = append(ln.BRReports, r)
reports = C.IedConnection_getLogicalNodeDirectory(c.conn, &clientError, clnRef2, C.ACSI_CLASS_BRCB)
report = reports.next
for report != nil {
var r BRReport
r.Data = C2GoStr((*C.char)(report.data))
ln.BRReports = append(ln.BRReports, r)

report = report.next
}
report = report.next
}

C.LinkedList_destroy(reports)
C.LinkedList_destroy(reports)

ld.LNs = append(ld.LNs, ln)
ld.LNs = append(ld.LNs, ln)

logicalNode = logicalNode.next
logicalNode = logicalNode.next
}()
}
C.LinkedList_destroy(logicalNodes)

Expand Down
14 changes: 7 additions & 7 deletions client_report.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ var reportCallbacks = make(map[int32]*reportCallbackHandler)
type ReasonForInclusion int

const (
IEC61850_REASON_NOT_INCLUDED ReasonForInclusion = iota
IEC61850_REASON_DATA_CHANGE
IEC61850_REASON_QUALITY_CHANGE
IEC61850_REASON_DATA_UPDATE
IEC61850_REASON_INTEGRITY
IEC61850_REASON_GI
IEC61850_REASON_UNKNOWN
IEC61850_REASON_NOT_INCLUDED ReasonForInclusion = 0
IEC61850_REASON_DATA_CHANGE ReasonForInclusion = 1
IEC61850_REASON_QUALITY_CHANGE ReasonForInclusion = 2
IEC61850_REASON_DATA_UPDATE ReasonForInclusion = 4
IEC61850_REASON_INTEGRITY ReasonForInclusion = 8
IEC61850_REASON_GI ReasonForInclusion = 16
IEC61850_REASON_UNKNOWN ReasonForInclusion = 32
)

type reportCallbackHandler struct {
Expand Down
2 changes: 1 addition & 1 deletion config_win64.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
package iec61850

// #cgo CFLAGS: -I./libiec61850/inc/hal/inc -I./libiec61850/inc/common/inc -I./libiec61850/inc/goose -I./libiec61850/inc/iec61850/inc -I./libiec61850/inc/iec61850/inc_private -I./libiec61850/inc/logging -I./libiec61850/inc/mms/inc -I./libiec61850/inc/mms/inc_private -I./libiec61850/inc/mms/iso_mms/asn1c
// #cgo LDFLAGS: -static-libgcc -static-libstdc++ -L./libiec61850/lib/win64 -liec61850 -lws2_32
// #cgo LDFLAGS: -static-libgcc -static-libstdc++ -L${SRCDIR}/libiec61850/lib/win64 -liec61850 -lhal -lws2_32
import "C"
148 changes: 148 additions & 0 deletions goose_publisher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package iec61850

/*
#include "goose_publisher.h"
#include "mms_value.h"

static bool is_publisher_not_null(GoosePublisher p) {
return p != NULL;
}

static void destroy_linked_list_val(LinkedList value) {
LinkedList_destroyDeep(value, (LinkedListValueDeleteFunction)MmsValue_delete);
}
*/
import "C"
import (
"errors"
"unsafe"
)

type (
LinkedListValue struct {
internalLinkedList *C.struct_sLinkedList
}

GoosePublisherConf struct {
InterfaceID string
AppID uint16
DstAddr [6]uint8
VlanID uint16
VlanPriority uint8
}

GoosePublisher struct {
internalPublisher *C.struct_sGoosePublisher
}
)

var (
ErrCreateGoosePublisher = errors.New("can not create goose publisher")
ErrSendGooseValue = errors.New("can not send goose value")
)

func NewGoosePublisher(conf GoosePublisherConf) (publisher *GoosePublisher, err error) {
parameters := C.struct_sCommParameters{}
parameters.appId = C.uint16_t(conf.AppID)
parameters.vlanId = C.uint16_t(conf.VlanID)
parameters.vlanPriority = C.uint8_t(conf.VlanPriority)
for i := 0; i < len(conf.DstAddr); i++ {
parameters.dstAddress[i] = C.uint8_t(conf.DstAddr[i])
}
ether := C.CString(conf.InterfaceID)
defer C.free(unsafe.Pointer(ether))

cGoosePublisher := C.GoosePublisher_create(&parameters, ether)
if !bool(C.is_publisher_not_null(cGoosePublisher)) {
err = ErrCreateGoosePublisher
return
}

publisher = &GoosePublisher{
internalPublisher: cGoosePublisher,
}

return
}

func (receiver *GoosePublisher) SetGoCbRef(goCbRef string) {
ref := C.CString(goCbRef)
defer C.free(unsafe.Pointer(ref))

C.GoosePublisher_setGoCbRef(receiver.internalPublisher, ref)
}

func (receiver *GoosePublisher) SetDataSetRef(dataSetRef string) {
ref := C.CString(dataSetRef)
defer C.free(unsafe.Pointer(ref))

C.GoosePublisher_setDataSetRef(receiver.internalPublisher, ref)
}

func (receiver *GoosePublisher) SetConfRev(confRef uint32) {
C.GoosePublisher_setConfRev(receiver.internalPublisher, C.uint32_t(confRef))
}

func (receiver *GoosePublisher) SetTimeAllowedToLive(timeAllowedToLive uint32) {
C.GoosePublisher_setTimeAllowedToLive(receiver.internalPublisher, C.uint32_t(timeAllowedToLive))
}

func (receiver *GoosePublisher) SetSimulation(simulation bool) {
C.GoosePublisher_setSimulation(receiver.internalPublisher, C.bool(simulation))
}

func (receiver *GoosePublisher) SetStNum(stNum uint32) {
C.GoosePublisher_setStNum(receiver.internalPublisher, C.uint32_t(stNum))
}

func (receiver *GoosePublisher) SetSqNum(sqNum uint32) {
C.GoosePublisher_setSqNum(receiver.internalPublisher, C.uint32_t(sqNum))
}

func (receiver *GoosePublisher) SetNeedsCommission(ndsCom bool) {
C.GoosePublisher_setNeedsCommission(receiver.internalPublisher, C.bool(ndsCom))
}

func (receiver *GoosePublisher) IncreaseStNum() {
C.GoosePublisher_increaseStNum(receiver.internalPublisher)
}

func (receiver *GoosePublisher) Reset() {
C.GoosePublisher_reset(receiver.internalPublisher)
}

func (receiver *GoosePublisher) Publish(dataSet *LinkedListValue) error {
if int(C.GoosePublisher_publish(receiver.internalPublisher, dataSet.internalLinkedList)) == -1 {
return ErrSendGooseValue
}

return nil
}

func (receiver *GoosePublisher) Close() {
C.GoosePublisher_destroy(receiver.internalPublisher)
}

func NewLinkedListValue() *LinkedListValue {
return &LinkedListValue{
internalLinkedList: C.LinkedList_create(),
}
}

func (receiver *LinkedListValue) Add(value *MmsValue) error {
rawVal, err := toMmsValue(value.Type, value.Value)
if err != nil {
return err
}
C.LinkedList_add(receiver.internalLinkedList, unsafe.Pointer(rawVal))

return nil
}

func (receiver *LinkedListValue) Size() int {
return int(C.LinkedList_size(receiver.internalLinkedList))
}

func (receiver *LinkedListValue) Destroy() {
C.destroy_linked_list_val(receiver.internalLinkedList)
}
Loading
Loading