func (middleware *Middleware) rpcLoop() {
	for {
		if middleware.didServiceInfoChange() {
			middleware.events <- handlers.Event{
				Identifier:      []byte(rpcmessages.OpServiceInfoChanged),
				QueueIfNoClient: false,
			}
		}
		time.Sleep(5 * time.Second)
	}
}
rpcLoop gets new data from the various rpc connections of the middleware and emits events if new data is available
package middleware
import (
	"bufio"
	"encoding/json"
	"fmt"
	"log"
	"os/exec"
	"regexp"
	"strings"
	"time"
	"github.com/digitalbitbox/bitbox-base/middleware/src/authentication"
	"github.com/digitalbitbox/bitbox-base/middleware/src/configuration"
	"github.com/digitalbitbox/bitbox-base/middleware/src/handlers"
	"github.com/digitalbitbox/bitbox-base/middleware/src/ipcnotification"
	"github.com/digitalbitbox/bitbox-base/middleware/src/prometheus"
	"github.com/digitalbitbox/bitbox-base/middleware/src/redis"
	"github.com/digitalbitbox/bitbox-base/middleware/src/rpcmessages"
	"github.com/digitalbitbox/bitbox02-api-go/api/firmware"
	"github.com/digitalbitbox/bitbox02-api-go/api/firmware/messages"
	"github.com/digitalbitbox/bitbox02-api-go/util/semver"
	"golang.org/x/crypto/bcrypt"
)
type UserAuthStruct struct {
	BCryptedPassword string `json:"password"`
	Role             string `json:"role"`
}
const initialAdminPassword = "ICanHasPasword?"
type Middleware struct {
	config              configuration.Configuration
	events              chan handlers.Event
	prometheusClient    prometheus.Client
	redisClient         redis.Redis
	jwtAuth             *authentication.JwtAuth
	serviceInfo         rpcmessages.GetServiceInfoResponse
	baseUpdateProgress  rpcmessages.GetBaseUpdateProgressResponse
	baseUpdateAvailable rpcmessages.IsBaseUpdateAvailableResponse
	baseVersion         *semver.SemVer
	isMiddlewarePasswordSet bool
	isBaseSetupDone         bool
	hsmFirmware *firmware.Device
}
func (middleware *Middleware) GetMiddlewareVersion() string {
	return middleware.config.GetMiddlewareVersion()
}
func NewMiddleware(config configuration.Configuration, hsmFirmware *firmware.Device) (*Middleware, error) {
	middleware := &Middleware{
		config: config,
		events:      make(chan handlers.Event),  
		serviceInfo: rpcmessages.GetServiceInfoResponse{},
		baseUpdateProgress: rpcmessages.GetBaseUpdateProgressResponse{
			State:                 rpcmessages.UpdateNotInProgress,
			ProgressPercentage:    0,
			ProgressDownloadedKiB: 0,
		},
		isMiddlewarePasswordSet: false,
		baseUpdateAvailable: rpcmessages.IsBaseUpdateAvailableResponse{
			ErrorResponse:   &rpcmessages.ErrorResponse{Success: true},
			UpdateAvailable: false,
		},
		baseVersion: semver.NewSemVer(0, 0, 0),
		hsmFirmware: hsmFirmware,
	}
	middleware.prometheusClient = prometheus.NewClient(middleware.config.GetPrometheusURL())
	if !middleware.config.IsRedisMock() {
		middleware.redisClient = redis.NewClient(middleware.config.GetRedisPort())
	} else {
		middleware.redisClient = redis.NewMockClient("")
	}
	err := middleware.checkMiddlewareSetup()
	if err != nil {
		log.Println("failed to update the middleware password set flag")
		return nil, err
	}
	if !middleware.isMiddlewarePasswordSet {
		usersMap := make(map[string]UserAuthStruct)
		bcryptedPassword, err := bcrypt.GenerateFromPassword([]byte(initialAdminPassword), 12)
		if err != nil {
			log.Println("Failed to generate new standard password")
			return nil, err
		}
		usersMap["admin"] = UserAuthStruct{BCryptedPassword: string(bcryptedPassword), Role: "admin"}
		authStructureString, err := json.Marshal(&usersMap)
		if err != nil {
			log.Println("Unable to marshal auth structure map")
			return nil, err
		}
		err = middleware.redisClient.SetString(redis.MiddlewareAuth, string(authStructureString))
		if err != nil {
			log.Println("Unable to initialize auth data structure")
			return nil, err
		}
	}
	middleware.jwtAuth, err = authentication.NewJwtAuth()
	if err != nil {
		return nil, err
	}
	return middleware, nil
}
func (middleware *Middleware) IsBaseUpdateAvailable() rpcmessages.IsBaseUpdateAvailableResponse {
	return middleware.baseUpdateAvailable
}