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 2023/01/16 17:03:55 UTC

[plc4x] branch develop updated: feat(plc4go/bacnet): basic mapping to reader/writer

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 55f7913ed3 feat(plc4go/bacnet): basic mapping to reader/writer
55f7913ed3 is described below

commit 55f7913ed320147b91eb1d8f23d8081d6262ea83
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon Jan 16 18:03:47 2023 +0100

    feat(plc4go/bacnet): basic mapping to reader/writer
---
 plc4go/internal/bacnetip/MessageCodec.go           | 59 ++++++++++++++++++++--
 plc4go/internal/bacnetip/Reader.go                 |  8 +--
 .../internal/bacnetip/UDPCommunicationsModule.go   |  2 +-
 3 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/plc4go/internal/bacnetip/MessageCodec.go b/plc4go/internal/bacnetip/MessageCodec.go
index b1df57d4a3..97b821c836 100644
--- a/plc4go/internal/bacnetip/MessageCodec.go
+++ b/plc4go/internal/bacnetip/MessageCodec.go
@@ -128,14 +128,63 @@ func (m *ApplicationLayerMessageCodec) Send(message spi.Message) error {
 
 func (m *ApplicationLayerMessageCodec) Expect(ctx context.Context, acceptsMessage spi.AcceptsMessage, handleMessage spi.HandleMessage, handleError spi.HandleError, ttl time.Duration) error {
 	// TODO: implement me
-	return nil
+	panic("not yet implemented")
 }
 
 func (m *ApplicationLayerMessageCodec) SendRequest(ctx context.Context, message spi.Message, acceptsMessage spi.AcceptsMessage, handleMessage spi.HandleMessage, handleError spi.HandleError, ttl time.Duration) error {
-
-	// TODO: implement me
-	m.Send(message)
-
+	address, err := NewAddress(m.remoteAddress)
+	if err != nil {
+		return err
+	}
+	iocb, err := NewIOCB(NewPDU(message, WithPDUDestination(address)), address)
+	if err != nil {
+		return errors.Wrap(err, "error creating IOCB")
+	}
+	go func() {
+		go m.bipSimpleApplication.RequestIO(iocb)
+		iocb.Wait()
+		if err := iocb.ioError; err != nil {
+			if err := handleError(err); err != nil {
+				log.Debug().Err(err).Msg("error handling error")
+				return
+			}
+		} else if response := iocb.ioResponse; response != nil {
+			// TODO: we wrap it into a BVLC for now. Once we change the Readers etc. to accept apdus we can remove that
+			tempBVLC := model.NewBVLCOriginalUnicastNPDU(
+				model.NewNPDU(
+					0,
+					model.NewNPDUControl(
+						false,
+						false,
+						false,
+						false,
+						model.NPDUNetworkPriority_NORMAL_MESSAGE,
+					),
+					nil,
+					nil,
+					nil,
+					nil,
+					nil,
+					nil,
+					nil,
+					nil,
+					response.GetMessage().(model.APDU),
+					0,
+				),
+				0,
+			)
+			if acceptsMessage(tempBVLC) {
+				if err := handleMessage(
+					tempBVLC,
+				); err != nil {
+					log.Debug().Err(err).Msg("error handling message")
+					return
+				}
+			}
+		} else {
+			// TODO: what now?
+		}
+	}()
 	return nil
 }
 
diff --git a/plc4go/internal/bacnetip/Reader.go b/plc4go/internal/bacnetip/Reader.go
index e30ecfad01..20487490bd 100644
--- a/plc4go/internal/bacnetip/Reader.go
+++ b/plc4go/internal/bacnetip/Reader.go
@@ -272,22 +272,22 @@ func (m *Reader) ToPlc4xReadResponse(apdu readWriteModel.APDU, readRequest apiMo
 		return spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues), nil
 	}
 
-	switch complexAck := complexAck.(type) {
+	switch serviceAck := complexAck.GetServiceAck().(type) {
 	case readWriteModel.BACnetServiceAckReadPropertyExactly:
 		// TODO: super lazy implementation for now
 		responseCodes[readRequest.GetTagNames()[0]] = apiModel.PlcResponseCode_OK
-		plcValues[readRequest.GetTagNames()[0]] = spiValues.NewPlcSTRING(complexAck.GetValues().(fmt.Stringer).String())
+		plcValues[readRequest.GetTagNames()[0]] = spiValues.NewPlcSTRING(serviceAck.GetValues().(fmt.Stringer).String())
 	case readWriteModel.BACnetServiceAckReadPropertyMultipleExactly:
 
 		// way to know how to interpret the responses is by aligning them with the
 		// items from the request as this information is not returned by the PLC.
-		if len(readRequest.GetTagNames()) != len(complexAck.GetData()) {
+		if len(readRequest.GetTagNames()) != len(serviceAck.GetData()) {
 			return nil, errors.New("The number of requested items doesn't match the number of returned items")
 		}
 		for i, tagName := range readRequest.GetTagNames() {
 			// TODO: super lazy implementation for now
 			responseCodes[tagName] = apiModel.PlcResponseCode_OK
-			plcValues[tagName] = spiValues.NewPlcSTRING(complexAck.GetData()[i].GetListOfResults().(fmt.Stringer).String())
+			plcValues[tagName] = spiValues.NewPlcSTRING(serviceAck.GetData()[i].GetListOfResults().(fmt.Stringer).String())
 		}
 	}
 
diff --git a/plc4go/internal/bacnetip/UDPCommunicationsModule.go b/plc4go/internal/bacnetip/UDPCommunicationsModule.go
index 231b0b5ce0..7e32e48d49 100644
--- a/plc4go/internal/bacnetip/UDPCommunicationsModule.go
+++ b/plc4go/internal/bacnetip/UDPCommunicationsModule.go
@@ -170,7 +170,7 @@ func NewUDPDirector(address AddressTuple[string, uint16], timeout *int, reuse *b
 	// create the request queue
 	d.request = make(chan _PDU)
 	go func() {
-		for {
+		for d.running {
 			pdu := <-d.request
 			serialize, err := pdu.GetMessage().Serialize()
 			if err != nil {