Skip to content

Commit

Permalink
Add a feature specific result callback option
Browse files Browse the repository at this point in the history
This will be called on on any incoming result message
  • Loading branch information
DerAndereAndi committed Mar 11, 2024
1 parent 94aaea2 commit 880d656
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 22 deletions.
3 changes: 3 additions & 0 deletions api/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type FeatureLocalInterface interface {
// Returns an error if there is already a callback for the msgCounter set
AddResponseCallback(msgCounterReference model.MsgCounterType, function func(msg ResponseMessage)) error

// Add a callback function to be invoked when a result message comes in for this feature
AddResultCallback(function func(msg ResponseMessage))

// return all functions
Functions() []model.FunctionType

Expand Down
54 changes: 50 additions & 4 deletions mocks/FeatureLocalInterface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 50 additions & 4 deletions mocks/NodeManagementInterface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 33 additions & 14 deletions spine/feature_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ import (
type FeatureLocal struct {
*Feature

entity api.EntityLocalInterface
functionDataMap map[model.FunctionType]api.FunctionDataCmdInterface
muxResponseCB sync.Mutex
responseCallback map[model.MsgCounterType]func(result api.ResponseMessage)
entity api.EntityLocalInterface
functionDataMap map[model.FunctionType]api.FunctionDataCmdInterface
muxResponseCB sync.Mutex
responseMsgCallback map[model.MsgCounterType]func(result api.ResponseMessage)
responseCallbacks []func(result api.ResponseMessage)

bindings []*model.FeatureAddressType // bindings to remote features
subscriptions []*model.FeatureAddressType // subscriptions to remote features
Expand All @@ -33,9 +34,9 @@ func NewFeatureLocal(id uint, entity api.EntityLocalInterface, ftype model.Featu
featureAddressType(id, entity.Address()),
ftype,
role),
entity: entity,
functionDataMap: make(map[model.FunctionType]api.FunctionDataCmdInterface),
responseCallback: make(map[model.MsgCounterType]func(result api.ResponseMessage)),
entity: entity,
functionDataMap: make(map[model.FunctionType]api.FunctionDataCmdInterface),
responseMsgCallback: make(map[model.MsgCounterType]func(result api.ResponseMessage)),
}

for _, fd := range CreateFunctionData[api.FunctionDataCmdInterface](ftype) {
Expand Down Expand Up @@ -94,28 +95,45 @@ func (r *FeatureLocal) AddResponseCallback(msgCounterReference model.MsgCounterT
r.muxResponseCB.Lock()
defer r.muxResponseCB.Unlock()

_, ok := r.responseCallback[msgCounterReference]
_, ok := r.responseMsgCallback[msgCounterReference]
if ok {
return errors.New("callback already set")
}

r.responseCallback[msgCounterReference] = function
r.responseMsgCallback[msgCounterReference] = function

return nil
}

func (r *FeatureLocal) processResponseCallbacks(msgCounterReference model.MsgCounterType, msg api.ResponseMessage) {
func (r *FeatureLocal) processResponseMsgCallbacks(msgCounterReference model.MsgCounterType, msg api.ResponseMessage) {
r.muxResponseCB.Lock()
defer r.muxResponseCB.Unlock()

cb, ok := r.responseCallback[msgCounterReference]
cb, ok := r.responseMsgCallback[msgCounterReference]
if !ok {
return
}

go cb(msg)

delete(r.responseCallback, msgCounterReference)
delete(r.responseMsgCallback, msgCounterReference)
}

// Add a callback function to be invoked when a result message comes in for this feature
func (r *FeatureLocal) AddResultCallback(function func(msg api.ResponseMessage)) {
r.muxResponseCB.Lock()
defer r.muxResponseCB.Unlock()

r.responseCallbacks = append(r.responseCallbacks, function)
}

func (r *FeatureLocal) processResultCallbacks(msg api.ResponseMessage) {
r.muxResponseCB.Lock()
defer r.muxResponseCB.Unlock()

for _, cb := range r.responseCallbacks {
go cb(msg)
}
}

func (r *FeatureLocal) DataCopy(function model.FunctionType) any {
Expand Down Expand Up @@ -411,7 +429,8 @@ func (r *FeatureLocal) processResult(message *api.Message) *model.ErrorType {
DeviceRemote: message.DeviceRemote,
}

r.processResponseCallbacks(*message.RequestHeader.MsgCounterReference, responseMsg)
r.processResponseMsgCallbacks(*message.RequestHeader.MsgCounterReference, responseMsg)
r.processResultCallbacks(responseMsg)

return nil
}
Expand Down Expand Up @@ -474,7 +493,7 @@ func (r *FeatureLocal) processReply(message *api.Message) *model.ErrorType {
DeviceRemote: message.DeviceRemote,
}

r.processResponseCallbacks(*message.RequestHeader.MsgCounterReference, responseMsg)
r.processResponseMsgCallbacks(*message.RequestHeader.MsgCounterReference, responseMsg)

return nil
}
Expand Down
2 changes: 2 additions & 0 deletions spine/feature_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ func (suite *DeviceClassificationTestSuite) TestDeviceClassification_ResponseCB(

err = suite.localFeature.AddResponseCallback(msgCounter, testFct)
assert.NotNil(suite.T(), err)

suite.localFeature.AddResultCallback(testFct)
}

func (suite *DeviceClassificationTestSuite) TestDeviceClassification_Request_Reply() {
Expand Down

0 comments on commit 880d656

Please sign in to comment.