Skip to content

Commit

Permalink
Put get DevEUIs for DevAddr in separate function.
Browse files Browse the repository at this point in the history
This will return the Redis connection to the pool after the DevEUIs are
retrieved. The get device-session function in the loop also acquires a
Redis connection, which potentially could result in a deadlock.
  • Loading branch information
brocaar committed Nov 28, 2019
1 parent dac5151 commit 445aed5
Showing 1 changed file with 26 additions and 12 deletions.
38 changes: 26 additions & 12 deletions internal/storage/device_session.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,21 +384,12 @@ func DeleteDeviceSession(ctx context.Context, p *redis.Pool, devEUI lorawan.EUI6
func GetDeviceSessionsForDevAddr(ctx context.Context, p *redis.Pool, devAddr lorawan.DevAddr) ([]DeviceSession, error) {
var items []DeviceSession

c := p.Get()
defer c.Close()

devEUIs, err := redis.ByteSlices(c.Do("SMEMBERS", fmt.Sprintf(devAddrKeyTempl, devAddr)))
devEUIs, err := GetDevEUIsForDevAddr(ctx, p, devAddr)
if err != nil {
if err == redis.ErrNil {
return items, nil
}
return nil, errors.Wrap(err, "get members error")
return nil, err
}

for _, b := range devEUIs {
var devEUI lorawan.EUI64
copy(devEUI[:], b)

for _, devEUI := range devEUIs {
s, err := GetDeviceSession(ctx, p, devEUI)
if err != nil {
// TODO: in case not found, remove the DevEUI from the list
Expand Down Expand Up @@ -426,6 +417,29 @@ func GetDeviceSessionsForDevAddr(ctx context.Context, p *redis.Pool, devAddr lor
return items, nil
}

// GetDevEUIsForDevAddr returns the DevEUIs that are using the given DevAddr.
func GetDevEUIsForDevAddr(ctx context.Context, p *redis.Pool, devAddr lorawan.DevAddr) ([]lorawan.EUI64, error) {
c := p.Get()
defer c.Close()

devEUIs, err := redis.ByteSlices(c.Do("SMEMBERS", fmt.Sprintf(devAddrKeyTempl, devAddr)))
if err != nil {
if err == redis.ErrNil {
return nil, nil
}
return nil, errors.Wrap(err, "get deveuis for devaddr error")
}

var out []lorawan.EUI64
for i := range devEUIs {
var devEUI lorawan.EUI64
copy(devEUI[:], devEUIs[i])
out = append(out, devEUI)
}

return out, nil
}

// GetDeviceSessionForPHYPayload returns the device-session matching the given
// PHYPayload. This will fetch all device-sessions associated with the used
// DevAddr and based on FCnt and MIC decide which one to use.
Expand Down

0 comments on commit 445aed5

Please sign in to comment.