You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2022/11/14 10:51:58 UTC
[plc4x] branch develop updated: feat(plc4go/bacnet): added building structure to BIPSimpleApplication
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new e43a48f12e feat(plc4go/bacnet): added building structure to BIPSimpleApplication
e43a48f12e is described below
commit e43a48f12eb40b911522feffbc6547c9fb4a27c2
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon Nov 14 11:17:40 2022 +0100
feat(plc4go/bacnet): added building structure to BIPSimpleApplication
---
plc4go/internal/bacnetip/ApplicationModule.go | 56 ++++++--
.../bacnetip/BACnetVirtualLinkLayerService.go | 142 +++++++++++++++++++++
plc4go/internal/bacnetip/NetworkService.go | 4 +
3 files changed, 189 insertions(+), 13 deletions(-)
diff --git a/plc4go/internal/bacnetip/ApplicationModule.go b/plc4go/internal/bacnetip/ApplicationModule.go
index 0371c83bbe..17aba59782 100644
--- a/plc4go/internal/bacnetip/ApplicationModule.go
+++ b/plc4go/internal/bacnetip/ApplicationModule.go
@@ -19,7 +19,10 @@
package bacnetip
-import "github.com/pkg/errors"
+import (
+ "github.com/pkg/errors"
+ "github.com/rs/zerolog/log"
+)
// TODO: implement
type Application struct {
@@ -50,48 +53,47 @@ type BIPSimpleApplication struct {
smap *StateMachineAccessPoint
nsap *NetworkServiceAccessPoint
nse *NetworkServiceElement
+ bip *BIPSimple
+ annexj *AnnexJCodec
+ mux *UDPMultiplexer
}
func NewBIPSimpleApplication(localDevice DeviceEntry, localAddress, deviceInfoCache *DeviceInventory, aseID *int) (*BIPSimpleApplication, error) {
b := &BIPSimpleApplication{}
- controller, err := NewApplicationIOController(localDevice, localAddress, deviceInfoCache, aseID)
+ var err error
+ b.ApplicationIOController, err = NewApplicationIOController(localDevice, localAddress, deviceInfoCache, aseID)
if err != nil {
return nil, errors.Wrap(err, "error creating io controller")
}
- b.ApplicationIOController = controller
b.localAddress = localAddress
// include a application decoder
- applicationServiceAccessPoint, err := NewApplicationServiceAccessPoint(nil, nil)
+ b.asap, err = NewApplicationServiceAccessPoint(nil, nil)
if err != nil {
return nil, errors.Wrap(err, "error creating application service access point")
}
- b.asap = applicationServiceAccessPoint
// pass the device object to the state machine access point, so it can know if it should support segmentation
- stateMachineAccessPoint, err := NewStateMachineAccessPoint(localDevice, deviceInfoCache, nil, nil)
+ b.smap, err = NewStateMachineAccessPoint(localDevice, deviceInfoCache, nil, nil)
if err != nil {
return nil, errors.Wrap(err, "error creating state machine access point")
}
- b.smap = stateMachineAccessPoint
// pass the device object to the state machine access point so it # can know if it should support segmentation
- // Note: deviceInfoCache already passed above so we don't need to do it again here
+ // Note: deviceInfoCache already passed above, so we don't need to do it again here
// a network service access point will be needed
- networkServiceAccessPoint, err := NewNetworkServiceAccessPoint()
+ b.nsap, err = NewNetworkServiceAccessPoint()
if err != nil {
return nil, errors.Wrap(err, "error creating network service access point")
}
- b.nsap = networkServiceAccessPoint
// give the NSAP a generic network layer service element
- networkServiceElement, err := NewNetworkServiceElement()
+ b.nse, err = NewNetworkServiceElement()
if err != nil {
return nil, errors.Wrap(err, "error creating new network service element")
}
- b.nse = networkServiceElement
if err := bind(b.nse, b.nsap); err != nil {
return nil, errors.New("error binding network stack")
}
@@ -101,7 +103,35 @@ func NewBIPSimpleApplication(localDevice DeviceEntry, localAddress, deviceInfoCa
return nil, errors.New("error binding top layers")
}
- // TODO: BIP, etc... udp stack binding here
+ // create a generic BIP stack, bound to the Annex J server on the UDP multiplexer
+ b.bip, err = NewBIPSimple(nil, nil, nil)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating new bip")
+ }
+ b.annexj, err = NewAnnexJCodec(nil, nil)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating new annex j codec")
+ }
+ b.mux, err = NewUDPMultiplexer(b.localAddress, false)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating new udp multiplexer")
+ }
+
+ // bind the bottom layers
+ if err := bind(b.bip, b.annexj, b.mux.annexJ); err != nil {
+ return nil, errors.New("error binding bottom layers")
+ }
+
+ // bind the BIP stack to the network, no network number
+ if err := b.nsap.bind(b.bip, nil, b.localAddress); err != nil {
+ return nil, err
+ }
return b, nil
}
+
+func (b *BIPSimpleApplication) Close() error {
+ log.Debug().Msg("close socket")
+ // pass to the multiplexer, then down to the sockets
+ return b.mux.Close()
+}
diff --git a/plc4go/internal/bacnetip/BACnetVirtualLinkLayerService.go b/plc4go/internal/bacnetip/BACnetVirtualLinkLayerService.go
new file mode 100644
index 0000000000..959ab1b074
--- /dev/null
+++ b/plc4go/internal/bacnetip/BACnetVirtualLinkLayerService.go
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package bacnetip
+
+import (
+ readWriteModel "github.com/apache/plc4x/plc4go/protocols/bacnetip/readwrite/model"
+ "github.com/pkg/errors"
+ "github.com/rs/zerolog/log"
+)
+
+type UDPMultiplexer struct {
+ annexJ interface{}
+}
+
+func (m *UDPMultiplexer) Close() error {
+ panic("implement me")
+}
+
+func NewUDPMultiplexer(address interface{}, noBroadcast bool) (*UDPMultiplexer, error) {
+ log.Debug().Msgf("NewUDPMultiplexer %v noBroadcast=%t", address, noBroadcast)
+ u := &UDPMultiplexer{}
+
+ // TODO: plumb later
+ return u, nil
+}
+
+type AnnexJCodec struct {
+ *Client
+ *Server
+}
+
+func NewAnnexJCodec(cid *int, sid *int) (*AnnexJCodec, error) {
+ log.Debug().Msgf("NewAnnexJCodec cid=%d sid=%d", cid, sid)
+ a := &AnnexJCodec{}
+ client, err := NewClient(cid, a)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating client")
+ }
+ a.Client = client
+ server, err := NewServer(sid, a)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating server")
+ }
+ a.Server = server
+ return a, nil
+}
+
+func (b *AnnexJCodec) Indication(apdu readWriteModel.APDU) error {
+ panic("we need to implement this with generics as we handle npdu not apdu here")
+}
+
+func (b *AnnexJCodec) Confirmation(apdu readWriteModel.APDU) error {
+ panic("we need to implement this with generics as we handle npdu not apdu here")
+}
+
+type _BIPSAP interface {
+ _ServiceAccessPoint
+ _Client
+}
+
+type BIPSAP struct {
+ *ServiceAccessPoint
+ rootStruct _BIPSAP
+}
+
+func NewBIPSAP(sapID *int, rootStruct _BIPSAP) (*BIPSAP, error) {
+ log.Debug().Msgf("NewBIPSAP sapID=%d", sapID)
+ b := &BIPSAP{}
+ serviceAccessPoint, err := NewServiceAccessPoint(sapID, rootStruct)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error creating service access point")
+ }
+ b.ServiceAccessPoint = serviceAccessPoint
+ b.rootStruct = rootStruct
+ return b, nil
+}
+
+func (b *BIPSAP) SapIndication(apdu readWriteModel.APDU, pduDestination []byte) error {
+ log.Debug().Msgf("SapIndication\n%s\n%s", apdu, pduDestination)
+ // TODO: what to do with the destination?
+ // this is a request initiated by the ASE, send this downstream
+ return b.rootStruct.Request(apdu)
+}
+
+func (b *BIPSAP) SapConfirmation(apdu readWriteModel.APDU, pduDestination []byte) error {
+ log.Debug().Msgf("SapConfirmation\n%s\n%s", apdu, pduDestination)
+ // TODO: what to do with the destination?
+ // this is a response from the ASE, send this downstream
+ return b.rootStruct.Request(apdu)
+}
+
+type BIPSimple struct {
+ *BIPSAP
+ *Client
+ *Server
+}
+
+func NewBIPSimple(sapID *int, cid *int, sid *int) (*BIPSimple, error) {
+ log.Debug().Msgf("NewBIPSimple sapID=%d cid=%d sid=%d", sapID, cid, sid)
+ b := &BIPSimple{}
+ bipsap, err := NewBIPSAP(sapID, b)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating bisap")
+ }
+ b.BIPSAP = bipsap
+ client, err := NewClient(cid, b)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating client")
+ }
+ b.Client = client
+ server, err := NewServer(sid, b)
+ if err != nil {
+ return nil, errors.Wrap(err, "error creating server")
+ }
+ b.Server = server
+ return b, nil
+}
+
+func (b *BIPSimple) Indication(apdu readWriteModel.APDU) error {
+ panic("we need to implement this with generics as we handle npdu not apdu here")
+}
+
+func (b *BIPSimple) Response(apdu readWriteModel.APDU) error {
+ panic("we need to implement this with generics as we handle npdu not apdu here")
+}
diff --git a/plc4go/internal/bacnetip/NetworkService.go b/plc4go/internal/bacnetip/NetworkService.go
index b9c9b120a0..a92045d037 100644
--- a/plc4go/internal/bacnetip/NetworkService.go
+++ b/plc4go/internal/bacnetip/NetworkService.go
@@ -28,6 +28,10 @@ func NewNetworkServiceAccessPoint() (*NetworkServiceAccessPoint, error) {
return nil, nil
}
+func (n *NetworkServiceAccessPoint) bind(server _Server, net interface{}, address interface{}) error {
+ panic("not implemented yet")
+}
+
type NetworkServiceElement struct {
// TODO: implement me
}