101 lines
3.2 KiB
Go
101 lines
3.2 KiB
Go
// -*- Mode: Go; indent-tabs-mode: t -*-
|
||
//
|
||
// Copyright (C) 2020-2024 IOTech Ltd
|
||
//
|
||
// SPDX-License-Identifier: Apache-2.0
|
||
|
||
package autodiscovery
|
||
|
||
import (
|
||
"fmt"
|
||
"sync"
|
||
|
||
"github.com/google/uuid"
|
||
"golang.org/x/net/context"
|
||
|
||
"github.com/edgexfoundry/device-sdk-go/v4/internal/container"
|
||
"github.com/edgexfoundry/device-sdk-go/v4/internal/controller/http/correlation"
|
||
"github.com/edgexfoundry/device-sdk-go/v4/internal/utils"
|
||
"github.com/edgexfoundry/device-sdk-go/v4/pkg/interfaces"
|
||
bootstrapContainer "github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/container"
|
||
"github.com/edgexfoundry/go-mod-bootstrap/v4/di"
|
||
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
|
||
"github.com/edgexfoundry/go-mod-core-contracts/v4/errors"
|
||
)
|
||
|
||
type discoveryLocker struct {
|
||
busy bool
|
||
mux sync.Mutex
|
||
}
|
||
|
||
var locker discoveryLocker
|
||
|
||
func DiscoveryWrapper(driver interfaces.ProtocolDriver, ctx context.Context, dic *di.Container) {
|
||
lc := bootstrapContainer.LoggingClientFrom(dic.Get)
|
||
locker.mux.Lock()
|
||
if locker.busy {
|
||
lc.Info("another device discovery process is currently running")
|
||
locker.mux.Unlock()
|
||
return
|
||
}
|
||
locker.busy = true
|
||
locker.mux.Unlock()
|
||
|
||
requestId := correlation.IdFromContext(ctx)
|
||
if len(requestId) == 0 {
|
||
requestId = uuid.NewString()
|
||
ctx = context.WithValue(ctx, common.CorrelationHeader, requestId) // nolint: staticcheck
|
||
lc.Debugf("device discovery correlation id is empty, set it to %s", requestId)
|
||
}
|
||
dic.Update(di.ServiceConstructorMap{
|
||
container.DiscoveryRequestIdName: func(get di.Get) any {
|
||
return requestId
|
||
},
|
||
})
|
||
|
||
utils.PublishDeviceDiscoveryProgressSystemEvent(requestId, 0, 0, "", ctx, dic)
|
||
lc.Debugf("protocol discovery triggered with correlation id: %s", requestId)
|
||
err := driver.Discover()
|
||
if err != nil {
|
||
errMsg := fmt.Sprintf("failed to trigger protocol discovery with correlation id: %s, err: %s", requestId, err.Error())
|
||
utils.PublishDeviceDiscoveryProgressSystemEvent(requestId, -1, 0, errMsg, ctx, dic)
|
||
lc.Error(errMsg)
|
||
} else {
|
||
utils.PublishDeviceDiscoveryProgressSystemEvent(requestId, 100, 0, "", ctx, dic)
|
||
}
|
||
|
||
// ReleaseLock
|
||
locker.mux.Lock()
|
||
locker.busy = false
|
||
dic.Update(di.ServiceConstructorMap{
|
||
container.DiscoveryRequestIdName: func(get di.Get) any {
|
||
return ""
|
||
},
|
||
})
|
||
locker.mux.Unlock()
|
||
}
|
||
|
||
func StopDeviceDiscovery(dic *di.Container, requestId string, options map[string]any) errors.EdgeX {
|
||
lc := bootstrapContainer.LoggingClientFrom(dic.Get)
|
||
extdriver := container.ExtendedProtocolDriverFrom(dic.Get)
|
||
if extdriver == nil {
|
||
return errors.NewCommonEdgeX(errors.KindNotImplemented, "Stop device discovery is not implemented", nil)
|
||
}
|
||
|
||
workingId := container.DiscoveryRequestIdFrom(dic.Get)
|
||
if len(workingId) == 0 {
|
||
lc.Debugf("no active discovery process was found")
|
||
return nil
|
||
}
|
||
if len(requestId) != 0 && requestId != workingId {
|
||
lc.Debugf("failed to stop device discovery with request id %s: current working request id is %s", requestId, workingId)
|
||
return errors.NewCommonEdgeX(errors.KindEntityDoesNotExist, "There is no auto discovery process running with the requestId", nil)
|
||
}
|
||
|
||
lc.Debugf("Stopping device discovery – %s", workingId)
|
||
extdriver.StopDeviceDiscovery(options)
|
||
lc.Debugf("Device discovery – %s stop signal is sent", workingId)
|
||
|
||
return nil
|
||
}
|