diff --git a/client/getDevice.go b/client/getDevice.go index cad544a0..121b047b 100644 --- a/client/getDevice.go +++ b/client/getDevice.go @@ -28,7 +28,11 @@ func getRefDeviceFromCache(ctx context.Context, deviceCache *refDeviceCache, if err != nil { refDev.Device().Close(ctx) deviceCache.RemoveDevice(ctx, refDev.DeviceID(), refDev) - refDev.Release(ctx) + defer func() { + if errR := refDev.Release(ctx); errR != nil { + deviceCache.errors(fmt.Errorf("get device from cache error: %w", errR)) + } + }() return nil, nil, false } return refDev, links, true @@ -49,14 +53,18 @@ func (c *Client) GetRefDeviceByIP( newRefDev := NewRefDevice(dev) refDev, stored := c.deviceCache.TryStoreDeviceToTemporaryCache(newRefDev) if !stored { - newRefDev.Release(ctx) + if errR := newRefDev.Release(ctx); errR != nil { + c.errors(fmt.Errorf("get device by IP error: cannot release unstored device: %w", errR)) + } } links, err := getLinksRefDevice(ctx, refDev, c.disableUDPEndpoints) if err != nil { deviceID := refDev.DeviceID() refDev.Device().Close(ctx) c.deviceCache.RemoveDevice(ctx, deviceID, refDev) - refDev.Release(ctx) + if errR := refDev.Release(ctx); errR != nil { + c.errors(fmt.Errorf("get device by IP error: %w", errR)) + } return nil, nil, fmt.Errorf("cannot get links for device %v: %w", deviceID, err) } return refDev, patchResourceLinksEndpoints(links, c.disableUDPEndpoints), nil @@ -86,13 +94,17 @@ func (c *Client) GetRefDevice( newRefDev := NewRefDevice(dev) refDev, stored := c.deviceCache.TryStoreDeviceToTemporaryCache(newRefDev) if !stored { - newRefDev.Release(ctx) + if errR := newRefDev.Release(ctx); errR != nil { + c.errors(fmt.Errorf("get device error: cannot release unstored device: %w", errR)) + } } links, err = getLinksRefDevice(ctx, refDev, c.disableUDPEndpoints) if err != nil { refDev.Device().Close(ctx) c.deviceCache.RemoveDevice(ctx, refDev.DeviceID(), refDev) - refDev.Release(ctx) + if errR := refDev.Release(ctx); errR != nil { + c.errors(fmt.Errorf("get device error: %w", errR)) + } return nil, nil, fmt.Errorf("cannot get links for device %v: %w", deviceID, err) } return refDev, patchResourceLinksEndpoints(links, c.disableUDPEndpoints), nil @@ -137,7 +149,11 @@ func (c *Client) GetDeviceByMulticast(ctx context.Context, deviceID string, opts if err != nil { return DeviceDetails{}, err } - defer refDev.Release(ctx) + defer func() { + if errR := refDev.Release(ctx); errR != nil { + c.errors(fmt.Errorf("get device by multicast error: %w", errR)) + } + }() return c.getDevice(ctx, refDev, links, cfg.getDetails) } @@ -154,6 +170,10 @@ func (c *Client) GetDeviceByIP(ctx context.Context, ip string, opts ...GetDevice if err != nil { return DeviceDetails{}, err } - defer refDev.Release(ctx) + defer func() { + if errR := refDev.Release(ctx); errR != nil { + c.errors(fmt.Errorf("get device by IP error: %w", errR)) + } + }() return c.getDevice(ctx, refDev, links, cfg.getDetails) } diff --git a/client/getDevices.go b/client/getDevices.go index 2bd14dce..bf2cfdc5 100644 --- a/client/getDevices.go +++ b/client/getDevices.go @@ -197,12 +197,12 @@ func getDeviceDetails(ctx context.Context, dev *core.Device, links schema.Resour }, nil } -func (h *discoveryHandler) Handle(ctx context.Context, d *core.Device) { - newRefDev := NewRefDevice(d) +func (h *discoveryHandler) Handle(ctx context.Context, dev *core.Device) { + newRefDev := NewRefDevice(dev) refDev, stored := h.deviceCache.TryStoreDeviceToTemporaryCache(newRefDev) defer refDev.Release(ctx) links, err := getLinksRefDevice(ctx, refDev, h.disableUDPEndpoints) - d = refDev.Device() + d := refDev.Device() if err != nil { refDev.Device().Close(ctx) h.deviceCache.RemoveDevice(ctx, refDev.DeviceID(), refDev) @@ -211,19 +211,25 @@ func (h *discoveryHandler) Handle(ctx context.Context, d *core.Device) { } refDev, stored = h.deviceCache.TryStoreDeviceToTemporaryCache(newRefDev) if !stored { - newRefDev.Release(ctx) + if errR := newRefDev.Release(ctx); errR != nil { + h.errors(fmt.Errorf("discovery error: cannot release unstored device: %w", errR)) + } return } links, err = getLinksRefDevice(ctx, refDev, h.disableUDPEndpoints) if err != nil { refDev.Device().Close(ctx) h.deviceCache.RemoveDevice(ctx, refDev.DeviceID(), refDev) - refDev.Release(ctx) + if errR := refDev.Release(ctx); errR != nil { + h.errors(fmt.Errorf("discovery error: %w", errR)) + } return } d = refDev.Device() } else if !stored { - newRefDev.Release(ctx) + if errR := newRefDev.Release(ctx); errR != nil { + h.errors(fmt.Errorf("discovery error: cannot release unstored device: %w", errR)) + } } deviceTypes := make(kitStrings.Set, len(d.DeviceTypes())) diff --git a/client/observeResource.go b/client/observeResource.go index 65fdaf1c..b40f0726 100644 --- a/client/observeResource.go +++ b/client/observeResource.go @@ -270,14 +270,19 @@ func (c *Client) closeObservingResource(ctx context.Context, o *observationsHand } o.Lock() defer o.Unlock() - if o.device != nil { - defer o.device.Release(ctx) - deviceID := o.device.DeviceID() - if _, err := o.device.StopObservingResource(ctx, o.observationID); err != nil { - c.errors(fmt.Errorf("failed to stop resources observation in device(%s): %w", deviceID, err)) + if o.device == nil { + return + } + defer func() { + if err := o.device.Release(ctx); err != nil { + c.errors(fmt.Errorf("stop resources observation error: %w", err)) } - c.deviceCache.RemoveDeviceFromPermanentCache(ctx, deviceID, o.device) + }() + deviceID := o.device.DeviceID() + if _, err := o.device.StopObservingResource(ctx, o.observationID); err != nil { + c.errors(fmt.Errorf("failed to stop resources observation in device(%s): %w", deviceID, err)) } + c.deviceCache.RemoveDeviceFromPermanentCache(ctx, deviceID, o.device) } func (o *observationsHandler) Handle(ctx context.Context, body coap.DecodeFunc) { diff --git a/client/ownDevice.go b/client/ownDevice.go index c6207c07..e59db064 100644 --- a/client/ownDevice.go +++ b/client/ownDevice.go @@ -2,6 +2,7 @@ package client import ( "context" + "fmt" "github.com/plgd-dev/device/client/core" "github.com/plgd-dev/device/client/core/otm" @@ -32,15 +33,15 @@ func (c *Client) OwnDevice(ctx context.Context, deviceID string, opts ...OwnOpti } func (c *Client) updateCache(ctx context.Context, d *RefDevice, deviceID string) { - if d.DeviceID() != deviceID { - if c.deviceCache.RemoveDevice(ctx, deviceID, d) { - for { - storedDev, stored := c.deviceCache.TryStoreDeviceToTemporaryCache(d) - if stored { - break - } - c.deviceCache.RemoveDevice(ctx, storedDev.DeviceID(), storedDev) - storedDev.Release(ctx) + if d.DeviceID() != deviceID && c.deviceCache.RemoveDevice(ctx, deviceID, d) { + for { + storedDev, stored := c.deviceCache.TryStoreDeviceToTemporaryCache(d) + if stored { + break + } + c.deviceCache.RemoveDevice(ctx, storedDev.DeviceID(), storedDev) + if err := storedDev.Release(ctx); err != nil { + c.errors(fmt.Errorf("update cache error: %w", err)) } } } diff --git a/client/refDeviceCache.go b/client/refDeviceCache.go index 86711eb9..def3b77c 100644 --- a/client/refDeviceCache.go +++ b/client/refDeviceCache.go @@ -70,7 +70,11 @@ func (c *refDeviceCache) getDeviceFromPermanentCache(ctx context.Context, device if !ok { return nil, false } - defer refCacheDev.Release(ctx) + defer func() { + if err := refCacheDev.Release(ctx); err != nil { + c.errors(fmt.Errorf("get device(%s) from cache error: %w", deviceID, err)) + } + }() dev := refCacheDev.device() dev.Acquire() return dev, true @@ -182,13 +186,19 @@ func (c *refDeviceCache) RemoveDeviceFromPermanentCache(ctx context.Context, dev if !ok { return false } - defer refCacheDev.Release(ctx) + defer func() { + if err := refCacheDev.Release(ctx); err != nil { + c.errors(fmt.Errorf("remove device(%s) from cache error: %w", deviceID, err)) + } + }() dev := refCacheDev.device() if dev == device { // remove device from cache - refCacheDev.Release(ctx) + if err := refCacheDev.Release(ctx); err != nil { + c.errors(fmt.Errorf("remove device(%s) from cache error: cannot remove device: %w", deviceID, err)) + } return true } diff --git a/cmd/ocfclient/ocfclient.go b/cmd/ocfclient/ocfclient.go index 3ed10369..b5f2b90a 100644 --- a/cmd/ocfclient/ocfclient.go +++ b/cmd/ocfclient/ocfclient.go @@ -9,7 +9,6 @@ import ( "fmt" "time" - "github.com/plgd-dev/device/client" local "github.com/plgd-dev/device/client" "github.com/plgd-dev/device/schema/interfaces" "github.com/plgd-dev/kit/v2/codec/json" @@ -88,7 +87,7 @@ func (c *OCFClient) Discover(discoveryTimeout time.Duration) (string, error) { func (c *OCFClient) OwnDevice(deviceID string) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() - return c.client.OwnDevice(ctx, deviceID, local.WithOTMs([]client.OTMType{client.OTMType_JustWorks})) + return c.client.OwnDevice(ctx, deviceID, local.WithOTMs([]local.OTMType{local.OTMType_JustWorks})) } // Get all resource Info of the device diff --git a/pkg/net/coap/client.go b/pkg/net/coap/client.go index 58451515..565d049c 100644 --- a/pkg/net/coap/client.go +++ b/pkg/net/coap/client.go @@ -71,14 +71,14 @@ func GetDeviceIDFromIdentityCertificate(cert *x509.Certificate) (string, error) if !ekuHasClient { return "", fmt.Errorf("not contains ExtKeyUsageClientAuth") } - ekuHasOcfId := false + ekuHasOcfID := false for _, eku := range cert.UnknownExtKeyUsage { if eku.Equal(ExtendedKeyUsage_IDENTITY_CERTIFICATE) { - ekuHasOcfId = true + ekuHasOcfID = true break } } - if !ekuHasOcfId { + if !ekuHasOcfID { return "", fmt.Errorf("not contains ExtKeyUsage with OCF ID(1.3.6.1.4.1.44924.1.6") } cn := strings.Split(cert.Subject.CommonName, ":") @@ -88,11 +88,11 @@ func GetDeviceIDFromIdentityCertificate(cert *x509.Certificate) (string, error) if strings.ToLower(cn[0]) != "uuid" { return "", fmt.Errorf("invalid subject common name %v: 'uuid' - not found", cert.Subject.CommonName) } - deviceId, err := uuid.Parse(cn[1]) + deviceID, err := uuid.Parse(cn[1]) if err != nil { return "", fmt.Errorf("invalid subject common name %v: %w", cert.Subject.CommonName, err) } - return deviceId.String(), nil + return deviceID.String(), nil } func VerifyIdentityCertificate(cert *x509.Certificate) error { diff --git a/schema/acl/acl.go b/schema/acl/acl.go index f9d3c45a..4b4bbd6a 100644 --- a/schema/acl/acl.go +++ b/schema/acl/acl.go @@ -46,37 +46,37 @@ const ( AllPermissions = Permission_CREATE | Permission_READ | Permission_WRITE | Permission_DELETE | Permission_NOTIFY ) -func (s Permission) String() string { +func (p Permission) String() string { res := make([]string, 0, 5) - if s.Has(Permission_CREATE) { + if p.Has(Permission_CREATE) { res = append(res, "CREATE") - s &^= Permission_CREATE + p &^= Permission_CREATE } - if s.Has(Permission_READ) { + if p.Has(Permission_READ) { res = append(res, "READ") - s &^= Permission_READ + p &^= Permission_READ } - if s.Has(Permission_WRITE) { + if p.Has(Permission_WRITE) { res = append(res, "WRITE") - s &^= Permission_WRITE + p &^= Permission_WRITE } - if s.Has(Permission_DELETE) { + if p.Has(Permission_DELETE) { res = append(res, "DELETE") - s &^= Permission_DELETE + p &^= Permission_DELETE } - if s.Has(Permission_NOTIFY) { + if p.Has(Permission_NOTIFY) { res = append(res, "NOTIFY") - s &^= Permission_NOTIFY + p &^= Permission_NOTIFY } - if s != 0 { - res = append(res, fmt.Sprintf("unknown(%v)", int(s))) + if p != 0 { + res = append(res, fmt.Sprintf("unknown(%v)", int(p))) } return strings.Join(res, "|") } // Has returns true if the flag is set. -func (b Permission) Has(flag Permission) bool { - return b&flag != 0 +func (p Permission) Has(flag Permission) bool { + return p&flag != 0 } type Resource struct { @@ -123,7 +123,7 @@ const ( ConnectionType_ANON_CLEAR ConnectionType = "anon-clear" ) -// anyof/oneof +// Subject contains anyof/oneof the subtypes type Subject struct { *Subject_Device *Subject_Role diff --git a/schema/cloud/configuration.go b/schema/cloud/configuration.go index 27826e44..24a148c5 100644 --- a/schema/cloud/configuration.go +++ b/schema/cloud/configuration.go @@ -1,10 +1,12 @@ -// Cloud Configuration Resource +// Package cloud implements Cloud Configuration Resource. // https://github.com/openconnectivityfoundation/cloud-services/blob/master/swagger2.0/oic.r.coapcloudconf.swagger.json package cloud const ( + // ConfigurationResourceType is the resource type of the Cloud Configuration Resource. ConfigurationResourceType = "oic.r.coapcloudconf" - ConfigurationResourceURI = "/CoapCloudConfResURI" + // ConfigurationResourceURI is the URI of the Cloud Configuration Resource. + ConfigurationResourceURI = "/CoapCloudConfResURI" ) // ProvisioningStatus indicates the Cloud Provisioning status of the Device. @@ -18,6 +20,7 @@ const ( ProvisioningStatus_FAILED ProvisioningStatus = "failed" ) +// Configuration contains the supported fields of the Cloud Configuration Resource. type Configuration struct { ResourceTypes []string `json:"rt"` Interfaces []string `json:"if"` @@ -29,6 +32,7 @@ type Configuration struct { ProvisioningStatus ProvisioningStatus `json:"cps"` } +// ConfigurationUpdateRequest is used to update the Cloud Configuration Resource. type ConfigurationUpdateRequest struct { AuthorizationProvider string `json:"apn"` URL string `json:"cis"` diff --git a/schema/csr/csr.go b/schema/csr/csr.go index ebab0ed2..3aefb843 100644 --- a/schema/csr/csr.go +++ b/schema/csr/csr.go @@ -11,7 +11,7 @@ type CertificateSigningRequestResponse struct { Interfaces []string `json:"if"` ResourceTypes []string `json:"rt"` Name string `json:"n"` - InstanceId string `json:"id"` + InstanceID string `json:"id"` Encoding CertificateEncoding `json:"encoding"` CertificateSigningRequest interface{} `json:"csr"` } diff --git a/schema/pstat/pstat.go b/schema/pstat/pstat.go index 47e1cc7c..f7559bf2 100644 --- a/schema/pstat/pstat.go +++ b/schema/pstat/pstat.go @@ -24,7 +24,7 @@ type ProvisionStatusResponse struct { CurrentOperationalMode OperationalMode `json:"om"` CurrentProvisioningMode ProvisioningMode `json:"cm"` Name string `json:"n"` - InstanceId string `json:"id"` + InstanceID string `json:"id"` DeviceIsOperational bool `json:"isop"` TargetProvisioningMode ProvisioningMode `json:"tm"` SupportedOperationalModes OperationalMode `json:"sm"`