From 55f7913ed320147b91eb1d8f23d8081d6262ea83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20R=C3=BChl?= Date: Mon, 16 Jan 2023 18:03:47 +0100 Subject: [PATCH] feat(plc4go/bacnet): basic mapping to reader/writer --- plc4go/internal/bacnetip/MessageCodec.go | 59 +++++++++++++++++-- plc4go/internal/bacnetip/Reader.go | 8 +-- .../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 b1df57d4a35..97b821c8369 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 e30ecfad016..20487490bdb 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 231b0b5ce0f..7e32e48d497 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 {