181 lines
5.1 KiB
Go
181 lines
5.1 KiB
Go
package manifestsender
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/fiskerinc/cloud-services/pkg/carcommand"
|
|
"github.com/fiskerinc/cloud-services/pkg/common"
|
|
"github.com/fiskerinc/cloud-services/pkg/common/manifestfingerprintparams"
|
|
"github.com/fiskerinc/cloud-services/pkg/db/queries"
|
|
q "github.com/fiskerinc/cloud-services/pkg/db/queries"
|
|
"github.com/fiskerinc/cloud-services/pkg/grpc/sms"
|
|
"github.com/fiskerinc/cloud-services/pkg/logger"
|
|
"github.com/fiskerinc/cloud-services/pkg/redis"
|
|
uhelpers "github.com/fiskerinc/cloud-services/pkg/usecase_helpers"
|
|
"github.com/fiskerinc/cloud-services/pkg/validator"
|
|
vconfig "github.com/fiskerinc/cloud-services/pkg/vehicleconfig"
|
|
errorspkg "github.com/pkg/errors"
|
|
)
|
|
|
|
var FailedToGetCDS = errors.New("did not send tbox as we had failed to get cds")
|
|
|
|
type ManifestSenderDB interface {
|
|
GetUpdateManifests() q.UpdateManifestsInterface
|
|
GetCars() q.CarsInterface
|
|
GetCarUpdates() q.CarUpdatesInterface
|
|
}
|
|
|
|
func NewTBOXManifestSender(
|
|
r redis.Client,
|
|
conf vconfig.ConfigServiceInterface,
|
|
db ManifestSenderDB,
|
|
sms sms.SMSServiceClient,
|
|
cds map[string]string,
|
|
) *TBOXManifestSender {
|
|
t := &TBOXManifestSender{
|
|
Redis: r,
|
|
db: db,
|
|
conf: conf,
|
|
sms: sms,
|
|
cds: cds,
|
|
}
|
|
|
|
return t
|
|
}
|
|
|
|
type TBOXManifestSender struct {
|
|
Redis redis.Client
|
|
db ManifestSenderDB
|
|
conf vconfig.ConfigServiceInterface
|
|
sms sms.SMSServiceClient
|
|
cds map[string]string // I think this can/should be removed. Unused in config route
|
|
}
|
|
|
|
func (t *TBOXManifestSender) Close() {
|
|
t.Redis = nil
|
|
}
|
|
|
|
func (t *TBOXManifestSender) addRollback(manifest *common.UpdateManifest, vin string) error {
|
|
if !manifest.RollbackEnabled {
|
|
return nil
|
|
}
|
|
|
|
var err error
|
|
|
|
db := t.db.GetUpdateManifests()
|
|
for _, ecu := range manifest.ECUs {
|
|
var rollbacks []*common.UpdateManifestECU
|
|
rollbacks, err = db.ECURollback(ecu, vin)
|
|
if err != nil {
|
|
return errorspkg.WithStack(err)
|
|
}
|
|
|
|
ecu.Rollback = rollbacks
|
|
}
|
|
|
|
manifest.RemoveOriginalS19HexFilesRollbacks()
|
|
|
|
return nil
|
|
}
|
|
|
|
// Prepare a manifest, gets cds data if need be
|
|
// This is called in two different locations. One form send_manifest.go and another from car_update_progress.go
|
|
// send_manifest.go includes all the fields one could want, the car_update_progress is not
|
|
func (t *TBOXManifestSender) ProcessSoftwareUpdate(vin string, manifest *common.UpdateManifest, ccd queries.CarConfigDataInterface) (smsID string, err error) {
|
|
// Add rollbacks to manifest
|
|
err = t.addRollback(manifest, vin)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// No CDS means some tasks in the send_manifest has not been run
|
|
// like VOD, CDS, ECU sorting, removing original s19 hex files, and current versions
|
|
if t.cds == nil {
|
|
var cds map[string]string
|
|
cds, err = t.getVODCDS(vin, ccd)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
t.cds = cds
|
|
manifest.SortECUs()
|
|
manifest.RemoveOriginalS19HexFiles()
|
|
manifest.RemoveOriginalS19HexFilesRollbacks()
|
|
|
|
err = uhelpers.PopulateECUsCurrentVersion(t.db.GetCars(), vin, manifest.ECUs)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
// Definitely need to transform the ECU's before the CDS are added so the names all match
|
|
manifest.TransformECUNames()
|
|
manifest.AddCDSToECUs(t.cds)
|
|
manifest.FilterCompatibleECUs(vin)
|
|
|
|
err = t.checkSUMS(manifest)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
fpparams := manifestfingerprintparams.GetFPParams()
|
|
manifest.GenerateFingerprint(fpparams.CurTime(), fpparams.ManifestSerial())
|
|
manifest.Scrub(common.TRex)
|
|
|
|
return t.Send(vin, *manifest)
|
|
}
|
|
|
|
func (t *TBOXManifestSender) checkSUMS(manifest *common.UpdateManifest) error {
|
|
if manifest.ManifestType == common.ConfigUpdateType {
|
|
return nil
|
|
}
|
|
|
|
err := validator.ValidateField(manifest.SUMS, "required,sums_version")
|
|
if err == nil {
|
|
err = manifest.AddSUMSToVOD()
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
// Send the update_manifest out redis to Trex, assume the manifest is all ready to go
|
|
// If we try to send a wakeup sms and the car does not have an ICCID we do not fail, as hopefully it it a test trex
|
|
func (t *TBOXManifestSender) Send(vin string, manifest common.UpdateManifest) (smsID string, err error) {
|
|
logger.Debug().Msgf("Sending redis queue- %s, key- %s, hander- %s, data- %v", "manifestsender", vin, "update_manifest", manifest)
|
|
err = t.Redis.SafeQueueMessage(common.TRex.Key(vin), common.Message{
|
|
Handler: "update_manifest",
|
|
Data: manifest,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Here need to wake it up again
|
|
logger.At(logger.Info(), common.TRex.Key(vin), "update").Msgf("TBOXManifestSender sent %v %s %d", common.TRex, vin, manifest.CarUpdateID)
|
|
if manifest.Type == common.ManifestTypeForced {
|
|
var queueResponse *sms.SMSQueueResponse
|
|
queueResponse, err = carcommand.QueueSMSWakeUp(vin, true, t.Redis, t.db.GetCars(), t.sms)
|
|
if err != nil {
|
|
if errors.Is(err, carcommand.ErrNoICCIDForWakeUp) {
|
|
err = nil
|
|
queueResponse.SentSuccessful = true
|
|
} else {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
if queueResponse.SentSuccessful {
|
|
smsID = queueResponse.SmsMsgID
|
|
} else {
|
|
err = fmt.Errorf("failed to awake car for Send TBOXManifestSender for vin: %s, car update: %d", vin, manifest.CarUpdateID)
|
|
}
|
|
}
|
|
|
|
return smsID, err
|
|
}
|
|
|
|
func (t *TBOXManifestSender) getVODCDS(vin string, db queries.CarConfigDataInterface) (map[string]string, error) {
|
|
return uhelpers.GetCDS(t.conf, db, vin)
|
|
}
|