Skip to content

Commit

Permalink
feat(plc4go/bacnet): implement BIPForeignApplication
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Jan 18, 2023
1 parent fa5e0ec commit f655587
Show file tree
Hide file tree
Showing 2 changed files with 393 additions and 1 deletion.
103 changes: 102 additions & 1 deletion plc4go/internal/bacnetip/ApplicationModule.go
Expand Up @@ -213,7 +213,7 @@ type Application struct {
}

func NewApplication(localDevice *LocalDeviceObject, deviceInfoCache *DeviceInfoCache, aseID *int) (*Application, error) {
log.Debug().Msgf("NewApplication localDevice=%v localAddress=%v deviceInfoCache=%s aseID=%d", localDevice, deviceInfoCache, aseID)
log.Debug().Msgf("NewApplication localDevice=%v deviceInfoCache=%s aseID=%d", localDevice, deviceInfoCache, aseID)
a := &Application{}
var err error
a.ApplicationServiceElement, err = NewApplicationServiceElement(aseID, a)
Expand Down Expand Up @@ -616,3 +616,104 @@ func (b *BIPSimpleApplication) Close() error {
// pass to the multiplexer, then down to the sockets
return b.mux.Close()
}

type BIPForeignApplication struct {
*ApplicationIOController
*WhoIsIAmServices
*ReadWritePropertyServices
localAddress Address
asap *ApplicationServiceAccessPoint
smap *StateMachineAccessPoint
nsap *NetworkServiceAccessPoint
nse *NetworkServiceElement
bip *BIPForeign
annexj *AnnexJCodec
mux *UDPMultiplexer
}

func NewBIPForeignApplication(localDevice *LocalDeviceObject, localAddress Address, bbmdAddress *Address, bbmdTTL *int, deviceInfoCache *DeviceInfoCache, aseID *int) (*BIPForeignApplication, error) {
b := &BIPForeignApplication{}
var err error
b.ApplicationIOController, err = NewApplicationIOController(localDevice, deviceInfoCache, aseID)
if err != nil {
return nil, errors.Wrap(err, "error creating io controller")
}
b.WhoIsIAmServices, err = NewWhoIsIAmServices(b)
if err != nil {
return nil, errors.Wrap(err, "error WhoIs/IAm services")
}
b.ReadWritePropertyServices, err = NewReadWritePropertyServices()
if err != nil {
return nil, errors.Wrap(err, "error read write property services")
}

b.localAddress = localAddress

// include a application decoder
b.asap, err = NewApplicationServiceAccessPoint(nil, nil)
if err != nil {
return nil, errors.Wrap(err, "error creating application service access point")
}

// pass the device object to the state machine access point, so it can know if it should support segmentation
b.smap, err = NewStateMachineAccessPoint(localDevice, deviceInfoCache, nil, nil)
if err != nil {
return nil, errors.Wrap(err, "error creating state machine access point")
}

// 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

// a network service access point will be needed
b.nsap, err = NewNetworkServiceAccessPoint(nil, nil, nil)
if err != nil {
return nil, errors.Wrap(err, "error creating network service access point")
}

// give the NSAP a generic network layer service element
b.nse, err = NewNetworkServiceElement(nil)
if err != nil {
return nil, errors.Wrap(err, "error creating new network service element")
}
if err := bind(b.nse, b.nsap); err != nil {
return nil, errors.Wrap(err, "error binding network stack")
}

// bind the top layers
if err := bind(b, b.asap, b.smap, b.nsap); err != nil {
return nil, errors.New("error binding top layers")
}

// create a generic BIP stack, bound to the Annex J server on the UDP multiplexer
b.bip, err = NewBIPForeign(bbmdAddress, bbmdTTL, 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, true)
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.Wrap(err, "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 *BIPForeignApplication) Close() error {
log.Debug().Msg("close socket")

// pass to the multiplexer, then down to the sockets
return b.mux.Close()
}

0 comments on commit f655587

Please sign in to comment.