forwarder

package
v0.0.1-alpha.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2022 License: Apache-2.0 Imports: 52 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GatewayIDBytesToLoraEUID

func GatewayIDBytesToLoraEUID(id []byte) lorawan.EUI64

GatewayIDBytesToLoraEUID decodes the given id bytes into a gateway id.

func IsMaybeMapperPacket

func IsMaybeMapperPacket(payload *lorawan.MACPayload) bool

func Run

func Run(cmd *cobra.Command, args []string)

Run the packet exchange.

Types

type Accounter

type Accounter interface {
	// Allow returns an indication if the user is allowed to receive
	// the packet that took the given amount of airtime from the gateway.
	Allow(user common.Address, airtime time.Duration) bool

	// AddPayment must be called each time a router sends an airtime
	// payment to the forwarder. The accounter will store/track these
	// and determines if the router is allowed to receive more data.
	AddPayment(payment *router.AirtimePaymentEvent)
}

Accounter is implemented by account strategies that determine if a packet must be forwarded to a router or not because it hasn't paid for the service gateways connected to the packet exchange provide.

type Backend

type Backend interface {
	// Stop closes the backend.
	Stop() error

	// Start starts the backend.
	Start() error

	// SetDownlinkTxAckFunc sets the DownlinkTXAck handler func.
	SetDownlinkTxAckFunc(func(*gw.DownlinkTxAck))

	// SetGatewayStatsFunc sets the GatewayStats handler func.
	SetGatewayStatsFunc(func(*gw.GatewayStats))

	// SetUplinkFrameFunc sets the UplinkFrame handler func.
	SetUplinkFrameFunc(func(*gw.UplinkFrame))

	// SetRawPacketForwarderEventFunc sets the RawPacketForwarderEvent handler func.
	SetRawPacketForwarderEventFunc(func(*gw.RawPacketForwarderEvent))

	// SetSubscribeEventFunc sets the Subscribe handler func.
	SetSubscribeEventFunc(func(events.Subscribe))

	// SendDownlinkFrame sends the given downlink frame.
	SendDownlinkFrame(*gw.DownlinkFrame) error

	// ApplyConfiguration applies the given configuration to the gateway.
	ApplyConfiguration(*gw.GatewayConfiguration) error

	// RawPacketForwarderCommand sends the given raw command to the packet-forwarder.
	RawPacketForwarderCommand(*gw.RawPacketForwarderCommand) error
}

Backend defines the interface that a backend must implement.

type Config

type Config struct {
	Forwarder struct {
		// Backend holdsconfiguration related to the forwarders gateway
		// endpoint and supported protocol.
		Backend struct {
			SemtechUDP *struct {
				UDPBind    *string `mapstructure:"udp_bind"`
				FakeRxTime *bool   `mapstructure:"fake_rx_time"`
			} `mapstructure:"semtech_udp"`

			BasicStation  *struct{} `mapstructure:"basic_station"`
			Concentratord *struct{} `mapstructure:"concentratord"`
		}

		// Gateways holds configuration related to gateways.
		Gateways struct {
			// Store describes how gateways are stored/loaded in the forwarder.
			Store struct {
				// YamlStorePath indicates that gateways are stored in a
				// YAML based file store located on the local file system.
				// Only data for gateways in the store is forwarded.
				YamlStorePath *string `mapstructure:"file"`
			}

			// RecordUnknown records gateways that connect to the forwarder but
			// are not in the forwarders gateway store. Recorded gateways can
			// be imported later if required.
			RecordUnknown *struct {
				// File points to a file on the local file system where
				// unknown gateways that connect are recorded.
				File string
			} `mapstructure:"record_unknown"`
			// RegistryAddress holds the address where the gateway registry is
			// deployed on chain. It is used to retrieve gateway details to
			// determine which gateways in the store are onboarded on ThingsIX
			// and have their details. Once token support is integrated to ThingsIX
			// only data for these gateways will be forwarded.
			RegistryAddress *common.Address `mapstructure:"gateway_registry"`

			// Refresh indicates the interval in which the gateway registry is
			// used to check if gateways from the forwarders store are onboarded
			// have their gateways set.
			Refresh *time.Duration
		}

		Routers struct {
			// Default routers that will receive all gateway data unfiltered
			Default []*Router

			// OnChain idicates that ThingsIX routers are loaded from the router
			// registry as deployed on the blockchain.
			OnChain *struct {
				// RegistryContract indicates when non-nil that router information must
				// be fetched from the registry smart contract (required blockchain cfg)
				RegistryContract common.Address `mapstructure:"registry"`

				// Interval indicates how often the routes are refreshed
				UpdateInterval *time.Duration `mapstructure:"interval"`
			} `mapstructure:"on_chain"`

			// ThingsIXApi indicates when non-nil that router information must be
			// fetched from the ThingsIX API
			ThingsIXApi *struct {
				Endpoint *string
				// Interval indicates how often the routes are refreshed
				UpdateInterval *time.Duration `mapstructure:"interval"`
			} `mapstructure:"thingsix_api"`
		}

		// Optional account strategy configuration, if not specified no account is used meaning
		// that all packets are exchanged between gateway and routers.
		Accounting *struct{}
	}

	Log struct {
		Level     logrus.Level
		Timestamp bool
	}

	BlockChain struct {
		Polygon *struct {
			Endpoint      string
			ChainID       uint64 `mapstructure:"chain_id"`
			Confirmations uint64
		}
	}

	Metrics *struct {
		Prometheus *struct {
			Address string
			Path    string
		}
	}
}

func (Config) MetricsPrometheusAddress

func (cfg Config) MetricsPrometheusAddress() string

func (Config) MetricsPrometheusPath

func (cfg Config) MetricsPrometheusPath() string

func (Config) PrometheusEnabled

func (cfg Config) PrometheusEnabled() bool

type CoverageClient

type CoverageClient struct {
}

func NewCoverageClient

func NewCoverageClient() (*CoverageClient, error)

func (*CoverageClient) DeliverDiscoveryPacketReceipt

func (cc *CoverageClient) DeliverDiscoveryPacketReceipt(ctx context.Context, dpr *mapper.DiscoveryPacketReceipt) (*mapper.DiscoveryPacketReceiptResponse, error)

type Exchange

type Exchange struct {
	// contains filtered or unexported fields
}

Exchange has several tasks: - it provides a backend on which trusted gateways can connect - it connects to ThingsIX routers - it keeps a routing table to exchange data between gateways and routers

func NewExchange

func NewExchange(cfg *Config) (*Exchange, error)

NewExchange instantiates a new packet exchange where gateways and routers can exchange packets.

func (*Exchange) Run

func (e *Exchange) Run(ctx context.Context)

Run the exchange until the given ctx expires.

type GatewayEvent

type GatewayEvent struct {
	// contains filtered or unexported fields
}

GatewayEvent is the decoded event received from a gateway through the backend. It contains the raw payload together with some helper function to determine what kind of event was received.

func (GatewayEvent) IsDownlinkAck

func (ge GatewayEvent) IsDownlinkAck() bool

IsDownlinkAck returns an indication if the vent is a downlink ACK.

func (GatewayEvent) IsJoin

func (ge GatewayEvent) IsJoin() bool

IsJoin returns an indication if the vent is a join event.

func (GatewayEvent) IsOnlineOfflineEvent

func (ge GatewayEvent) IsOnlineOfflineEvent() bool

IsOnlineOfflineEvent is an indication if a gateway went offline or became online.

func (ge GatewayEvent) IsUplink() bool

IsUplink returns an indication if the event is an uplink event.

type GatewaySet

type GatewaySet struct {
	// contains filtered or unexported fields
}

GatewaySet sync a gateway store periodically with the gateway registry and keeps track of gateways in the store that are onboarded and have their details set in the ThingsIX gateway registry.

It also maps from gateways their local id to the ThingsIX network id.

func NewGatewaySet

func NewGatewaySet(cfg *Config, store gateway.Store, local map[lorawan.EUI64]*gateway.Gateway, network map[lorawan.EUI64]*gateway.Gateway) *GatewaySet

func (*GatewaySet) ByLocalID

func (gs *GatewaySet) ByLocalID(id lorawan.EUI64) (*gateway.Gateway, bool)

func (*GatewaySet) ByLocalIDString

func (gs *GatewaySet) ByLocalIDString(id string) (*gateway.Gateway, bool)

func (*GatewaySet) ByNetworkID

func (gs *GatewaySet) ByNetworkID(id lorawan.EUI64) (*gateway.Gateway, bool)

func (*GatewaySet) ByNetworkIDBytes

func (gs *GatewaySet) ByNetworkIDBytes(id []byte) (*gateway.Gateway, bool)

func (*GatewaySet) Refresh

func (gs *GatewaySet) Refresh(ctx context.Context)

*

  • Refresh polls until the given ctx expires periodically (interval is configurable)
  • the gateway registry and refreshes its internal gateway sets with gateways that
  • are onboarded and have their details set.

type ID

type ID [32]byte

func (ID) String

func (id ID) String() string

type MapperForwarder

type MapperForwarder struct {
	// contains filtered or unexported fields
}

func NewMapperForwarder

func NewMapperForwarder(exchange *Exchange) (*MapperForwarder, error)

func (*MapperForwarder) HandleMapperPacket

func (mc *MapperForwarder) HandleMapperPacket(frame *gw.UplinkFrame, mac *lorawan.MACPayload)

type NetworkEvent

type NetworkEvent struct {
	// contains filtered or unexported fields
}

NetworkEvent represents an event received from the network

type NoAccounting

type NoAccounting struct {
}

func NewNoAccountingStrategy

func NewNoAccountingStrategy() *NoAccounting

NewNoAccountingStrategy returns an Accounter that allows all data to be forwarded to the router and ignore router payments.

func (NoAccounting) AddPayment

func (a NoAccounting) AddPayment(payment *router.AirtimePaymentEvent)

AddPayment ignores the given payment

func (NoAccounting) Allow

func (a NoAccounting) Allow(user common.Address, airtime time.Duration) bool

Allow all data to the given user

type Router

type Router struct {
	// ID is the routers identity as its registered in the smart contract
	ThingsIXID ID
	// Endpoint is the URI where the router can be reached
	Endpoint string
	// Default is an indication if the router is configured in the configuration and wants to receive all data
	Default bool
	// Name is an optional name users can appoint to routers that are in the configuration
	Name string
	// NetIDs is the set of network identifiers this routers wants to receive packets from
	NetIDs []lorawan.NetID
	// Owner is the routers owner
	Owner common.Address
	// contains filtered or unexported fields
}

func NewRouter

func NewRouter(id [32]byte, endpoint string, def bool, netIDs []lorawan.NetID, owner common.Address, accounting Accounter) *Router

func (*Router) AcceptsJoin

func (r *Router) AcceptsJoin(devEUI lorawan.EUI64) bool

AcceptsJoin returns an indication if the device that wants to join the network is accepted by this router.

func (*Router) AllowAirtime

func (r *Router) AllowAirtime(owner common.Address, airtime time.Duration) bool

func (*Router) InterestedIn

func (r *Router) InterestedIn(addr lorawan.DevAddr) bool

InterestedIn returns an indication if router is interested in a message from a device with the given devaddr.

func (*Router) SetJoinFilter

func (r *Router) SetJoinFilter(filter *xorfilter.Xor8)

func (*Router) String

func (r *Router) String() string

type RouterClient

type RouterClient struct {
	// contains filtered or unexported fields
}

RouterClient communicates with a remote router and exchanges messages between the router and the packet exchange.

func NewRouterClient

func NewRouterClient(router *Router,
	routeTableBroadcaster *broadcast.Broadcaster[[]*Router],
	routerEvents chan *NetworkEvent, gatewayEvents *broadcast.Broadcaster[*GatewayEvent],
	routerDetails <-chan *RouterDetails) *RouterClient

NewRouterClient create a new client that connects to a remote routers and handles communication with that router.

func (*RouterClient) Run

func (rc *RouterClient) Run(ctx context.Context)

Run the router client until the given context expires. This includes connecting to the router and opening a bidirectional stream to it to exchange packets.

type RouterDetails

type RouterDetails struct {
	// Endpoint is the URI where the router can be reached
	Endpoint string
	// NetIDs is the set of network identifiers this routers wants to receive packets from
	NetIDs []lorawan.NetID
	// Owner is the routers owner
	Owner common.Address
}

type RoutesUpdaterFunc

type RoutesUpdaterFunc func() ([]*Router, error)

RoutesUpdaterFunc is a callback that retrieves routing information from ThingsIX. It returns the set of routers or an error in case the set could not be fetched.

type RoutingTable

type RoutingTable struct {
	// contains filtered or unexported fields
}

RoutingTable takes care of the communication between the Packet Exchange and external routers. Received data from the packet exchange is routed to routers that have expressed interest in it.

func (*RoutingTable) Run

func (r *RoutingTable) Run(ctx context.Context)

Run starts the integration with the routers on the ThingsIX network until the given context expires.

It fetches the list of registered routers and opens connects with these routers. For each router a client is started that maintains the connection with the router and exchanges messages with it. Periodically the latest set of registered routers is fetched and nieuw router clients are started for fresh registered routers or clients are stopped/updated when they are either removed or updated.

type UnknownGatewayLoggerFunc

type UnknownGatewayLoggerFunc func(localGatewayID lorawan.EUI64)

func NewUnknownGatewayLogger

func NewUnknownGatewayLogger(cfg *Config) UnknownGatewayLoggerFunc

NewUnknownGatewayLogger returns a callback that can be used to record gateways their local id to a source defined in the given cfg. This is used to record unknown gateways that connected to the backend. These can be verified later and if required imported into the gateway store and registered on ThingsIX.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL