Пример #1
0
// GetHandlerManager gets a new HandlerManager for ttnctl
func GetHandlerManager(ctx log.Interface, appID string) (*grpc.ClientConn, *handler.ManagerClient) {
	ctx.WithField("Handler", viper.GetString("handler-id")).Info("Discovering Handler...")
	dscConn, client := GetDiscovery(ctx)
	defer dscConn.Close()
	handlerAnnouncement, err := client.Get(GetContext(ctx), &discovery.GetRequest{
		ServiceName: "handler",
		Id:          viper.GetString("handler-id"),
	})
	if err != nil {
		ctx.WithError(errors.FromGRPCError(err)).Fatal("Could not find Handler")
	}

	token := TokenForScope(ctx, scope.App(appID))

	ctx.WithField("Handler", handlerAnnouncement.NetAddress).Info("Connecting with Handler...")
	hdlConn, err := handlerAnnouncement.Dial()
	if err != nil {
		ctx.WithError(err).Fatal("Could not connect to Handler")
	}
	managerClient, err := handler.NewManagerClient(hdlConn, token)
	if err != nil {
		ctx.WithError(err).Fatal("Could not create Handler Manager")
	}
	return hdlConn, managerClient
}
Пример #2
0
// NewGameHub creates a new GameHub for a given log contenxt.
func NewGameHub(ctx log.Interface) GameHub {
	return GameHub{
		Log:      ctx.WithField("module", "GameHub"),
		games:    make(map[string]Game),
		register: make(chan GameRegistrationRequest),
	}
}
Пример #3
0
// NewGameState creates a new game state given a logging context.
func NewGameState(ctx log.Interface) GameState {
	return GameState{
		Users:          make(map[*User]bool),
		Shots:          make(map[*Shot]bool),
		Log:            ctx.WithField("module", "GameState"),
		UpdateInterval: DefaultStateUpdateLoopInterval,
		simulate:       make(chan []Command),
		updateState:    make(chan *GameState),
	}
}
Пример #4
0
// NewGateway creates a new in-memory Gateway structure
func NewGateway(ctx log.Interface, id string) *Gateway {
	ctx = ctx.WithField("GatewayID", id)
	return &Gateway{
		ID:          id,
		Status:      NewStatusStore(),
		Utilization: NewUtilization(),
		Schedule:    NewSchedule(ctx),
		Ctx:         ctx,
	}
}
Пример #5
0
// NewUser creates a new user with a new Gopher to manage the user's new ws
// connection.
func NewUser(ctx log.Interface, ws *websocket.Conn) User {
	id := uuid.NewRandom().String()[:3]

	return User{
		ID:     id,
		Gopher: NewGopher(id, RandomCoordinates(boardSize)),
		Log:    ctx.WithField("module", "User"),
		send:   make(chan []byte, 256),
		ws:     ws,
	}
}
Пример #6
0
// continue looking at dns entry for changes in config
func configLoop(ctx log.Interface, cfgURL string) {
	ticker := time.Tick(15 * time.Second)

	for {
		select {
		case <-ticker:
			newIPs, err := dnscfg.Get(dnsAddr, ldPort)
			if err != nil {
				ctx.WithError(err).Error("dns lookup")
				continue
			}

			if len(newIPs) == 0 {
				ctx.Error("no ip addresses found")
				continue
			}

			oldIPs, err := httpcfg.Get(cfgURL)
			if err != nil {
				ctx.WithError(err).Error("getting config")
				continue
			}

			if eq(newIPs, oldIPs) {
				ctx.Info("config up to date")
				continue
			}

			err = httpcfg.Set(cfgURL, newIPs)
			if err != nil {
				ctx.WithError(err).Error("setting config")
				continue
			}

			ctx.WithField("ips", newIPs).Info("setting config")
		}
	}
}
Пример #7
0
// New creates a new Component
func New(ctx log.Interface, serviceName string, announcedAddress string) (*Component, error) {
	go func() {
		memstats := new(runtime.MemStats)
		for range time.Tick(time.Minute) {
			runtime.ReadMemStats(memstats)
			ctx.WithFields(log.Fields{
				"Goroutines": runtime.NumGoroutine(),
				"Memory":     float64(memstats.Alloc) / 1000000,
			}).Debugf("Stats")
		}
	}()

	// Disable gRPC tracing
	// SEE: https://github.com/grpc/grpc-go/issues/695
	grpc.EnableTracing = false

	component := &Component{
		Config: ConfigFromViper(),
		Ctx:    ctx,
		Identity: &pb_discovery.Announcement{
			Id:             viper.GetString("id"),
			Description:    viper.GetString("description"),
			ServiceName:    serviceName,
			ServiceVersion: fmt.Sprintf("%s-%s (%s)", viper.GetString("version"), viper.GetString("gitCommit"), viper.GetString("buildDate")),
			NetAddress:     announcedAddress,
			Public:         viper.GetBool("public"),
		},
		AccessToken: viper.GetString("auth-token"),
	}

	if err := component.InitAuth(); err != nil {
		return nil, err
	}

	if serviceName != "discovery" && serviceName != "networkserver" {
		var err error
		component.Discovery, err = pb_discovery.NewClient(
			viper.GetString("discovery-address"),
			component.Identity,
			func() string {
				token, _ := component.BuildJWT()
				return token
			},
		)
		if err != nil {
			return nil, err
		}
	}

	if healthPort := viper.GetInt("health-port"); healthPort > 0 {
		http.HandleFunc("/healthz", func(w http.ResponseWriter, req *http.Request) {
			switch component.GetStatus() {
			case StatusHealthy:
				w.WriteHeader(200)
				w.Write([]byte("Status is HEALTHY"))
				return
			case StatusUnhealthy:
				w.WriteHeader(503)
				w.Write([]byte("Status is UNHEALTHY"))
				return
			}
		})
		go http.ListenAndServe(fmt.Sprintf(":%d", healthPort), nil)
	}

	if monitors := viper.GetStringMapString("monitor-servers"); len(monitors) != 0 {
		component.Monitors = make(map[string]*pb_monitor.Client)
		for name, addr := range monitors {
			var err error
			component.Monitors[name], err = pb_monitor.NewClient(ctx.WithField("Monitor", name), addr)
			if err != nil {
				return nil, err
			}
		}
	}

	return component, nil
}
Пример #8
0
func (h *handler) ConvertFromLoRaWAN(ctx log.Interface, ttnUp *pb_broker.DeduplicatedUplinkMessage, appUp *types.UplinkMessage) error {
	// Find Device
	dev, err := h.devices.Get(ttnUp.AppId, ttnUp.DevId)
	if err != nil {
		return err
	}

	// Check for LoRaWAN
	if lorawan := ttnUp.ProtocolMetadata.GetLorawan(); lorawan == nil {
		return errors.NewErrInvalidArgument("Activation", "does not contain LoRaWAN metadata")
	}

	// LoRaWAN: Unmarshal Uplink
	var phyPayload lorawan.PHYPayload
	err = phyPayload.UnmarshalBinary(ttnUp.Payload)
	if err != nil {
		return err
	}
	macPayload, ok := phyPayload.MACPayload.(*lorawan.MACPayload)
	if !ok {
		return errors.NewErrInvalidArgument("Uplink", "does not contain a MAC payload")
	}
	macPayload.FHDR.FCnt = ttnUp.ProtocolMetadata.GetLorawan().FCnt
	appUp.FCnt = macPayload.FHDR.FCnt

	ctx = ctx.WithField("FCnt", appUp.FCnt)

	// LoRaWAN: Validate MIC
	ok, err = phyPayload.ValidateMIC(lorawan.AES128Key(dev.NwkSKey))
	if err != nil {
		return err
	}
	if !ok {
		return errors.NewErrNotFound("device that validates MIC")
	}

	// LoRaWAN: Decrypt
	if macPayload.FPort != nil && *macPayload.FPort != 0 && len(macPayload.FRMPayload) == 1 {
		appUp.FPort = *macPayload.FPort
		ctx = ctx.WithField("FCnt", appUp.FPort)
		if err := phyPayload.DecryptFRMPayload(lorawan.AES128Key(dev.AppSKey)); err != nil {
			return errors.NewErrInternal("Could not decrypt payload")
		}
		if len(macPayload.FRMPayload) == 1 {
			payload, ok := macPayload.FRMPayload[0].(*lorawan.DataPayload)
			if !ok {
				return errors.NewErrInvalidArgument("Uplink FRMPayload", "must be of type *lorawan.DataPayload")
			}
			appUp.PayloadRaw = payload.Bytes
		}
	}

	// LoRaWAN: Publish ACKs as events
	if macPayload.FHDR.FCtrl.ACK {
		h.mqttEvent <- &types.DeviceEvent{
			AppID: appUp.AppID,
			DevID: appUp.DevID,
			Event: types.DownlinkAckEvent,
		}
	}

	return nil
}
Пример #9
0
func work(ctx log.Interface) (err error) {
	path := "Readme.md"
	defer ctx.WithField("path", path).Trace("opening").Stop(&err)
	_, err = os.Open(path)
	return
}