func makeNewDevAddrFunc(ps ...types.DevAddrPrefix) newDevAddrFunc {
	return func(ctx context.Context, dev *ttnpb.EndDevice) types.DevAddr {
		var devAddr types.DevAddr
		random.Read(devAddr[:])
		p := ps[random.Intn(len(ps))]
		return devAddr.WithPrefix(p)
	}
}
makeNewDevAddrFunc returns a newDevAddrFunc, which derives DevAddrs using specified prefixes.
package networkserver
import (
	"context"
	"crypto/tls"
	"fmt"
	"os"
	"sync"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"go.thethings.network/lorawan-stack/v3/pkg/cluster"
	"go.thethings.network/lorawan-stack/v3/pkg/component"
	"go.thethings.network/lorawan-stack/v3/pkg/errors"
	"go.thethings.network/lorawan-stack/v3/pkg/interop"
	"go.thethings.network/lorawan-stack/v3/pkg/log"
	"go.thethings.network/lorawan-stack/v3/pkg/networkserver/internal/time"
	"go.thethings.network/lorawan-stack/v3/pkg/random"
	"go.thethings.network/lorawan-stack/v3/pkg/rpcmiddleware/hooks"
	"go.thethings.network/lorawan-stack/v3/pkg/rpcmiddleware/rpclog"
	"go.thethings.network/lorawan-stack/v3/pkg/ttnpb"
	"go.thethings.network/lorawan-stack/v3/pkg/types"
	"golang.org/x/sync/semaphore"
	"google.golang.org/grpc"
)
const (
	recentDownlinkCount = 20
	fOptsCapacity = 15
	infrastructureDelay = time.Second
	peeringScheduleDelay = infrastructureDelay + 4*time.Second
	maxUplinkSubmissionConcurrency = 1024
)
type windowDurationFunc func(ctx context.Context) time.Duration
func makeWindowDurationFunc(d time.Duration) windowDurationFunc {
	return func(ctx context.Context) time.Duration { return d }
}
type newDevAddrFunc func(ctx context.Context, dev *ttnpb.EndDevice) types.DevAddr