Search in sources :

Example 26 with Packet

use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.

the class FXEventUpdaterListReceiver method receive.

@Override
public void receive(List<Packet> packets) {
    for (Packet packet : packets) {
        if (packet instanceof FXStatusPacket) {
            FXStatusPacket fx = (FXStatusPacket) packet;
            FXStatusPacket previous = previousPacketMap.get(fx.getIdentifier());
            previousPacketMap.put(fx.getIdentifier(), fx);
            Integer warningIgnoreValue = fxWarningIgnoreMap.get(fx.getAddress());
            useData(fx, previous, warningIgnoreValue == null ? FXWarningModeChangePacket.DEFAULT_IGNORED_WARNING_MODE_VALUE_CONSTANT : warningIgnoreValue);
        }
    }
}
Also used : Packet(me.retrodaredevil.solarthing.packets.Packet)

Example 27 with Packet

use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.

the class AlterManagerAction method isDocumentMadeByUs.

private boolean isDocumentMadeByUs(Instant now, ScheduledCommandData scheduledCommandData, StoredPacketGroup existingDocument) {
    LargeIntegrityPacket largeIntegrityPacket = (LargeIntegrityPacket) existingDocument.getPackets().stream().filter(p -> p instanceof LargeIntegrityPacket).findAny().orElse(null);
    if (largeIntegrityPacket == null) {
        LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, "The stored document did not have a LargeIntegrity packet. Someone must be trying to stop a scheduled command!");
        return false;
    }
    String sender = largeIntegrityPacket.getSender();
    if (!commandManager.getSender().equals(sender)) {
        LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "The sender of the large integrity packet we are inspecting is not us (" + commandManager.getSender() + "). It is " + sender + ". Might be a malicious actor, might be a bad setup.");
        return false;
    }
    String encryptedHash = largeIntegrityPacket.getEncryptedHash();
    String data;
    try {
        synchronized (CIPHER) {
            data = Decrypt.decrypt(CIPHER, commandManager.getKeyPair().getPublic(), encryptedHash);
        }
    } catch (InvalidKeyException e) {
        throw new RuntimeException("Should be a valid key!", e);
    } catch (DecryptException e) {
        LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, "The document we are inspecting had a large integrity packet with the sender: " + sender + ", but that's us and we couldn't decrypt their payload. Likely a malicious actor", e);
        return false;
    }
    final String[] split = data.split(",", 2);
    LOGGER.debug("decrypted data: " + data);
    if (split.length != 2) {
        LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, "split.length: " + split.length + " split: " + Arrays.asList(split));
        return false;
    }
    String hexMillis = split[0];
    // String message = split[1]; We don't care what the message is. We don't even care enough to check if it matches the payload's hash
    long dateMillis;
    try {
        dateMillis = Long.parseLong(hexMillis, 16);
    } catch (NumberFormatException e) {
        LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "Error parsing hex date millis", e);
        return false;
    }
    if (dateMillis < scheduledCommandData.getScheduledTimeMillis()) {
        LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, "The dateMillis for this is less than the command's scheduled execution time! This must be a malicious actor!");
        return false;
    }
    if (dateMillis > now.toEpochMilli()) {
        LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, "The dateMillis for this is greater than now! This should never ever happen.");
        return false;
    }
    return true;
}
Also used : CommandManager(me.retrodaredevil.solarthing.commands.util.CommandManager) Packet(me.retrodaredevil.solarthing.packets.Packet) Arrays(java.util.Arrays) AlterPacketsProvider(me.retrodaredevil.solarthing.AlterPacketsProvider) LoggerFactory(org.slf4j.LoggerFactory) InstanceTargetPackets(me.retrodaredevil.solarthing.packets.instance.InstanceTargetPackets) VersionedPacket(me.retrodaredevil.solarthing.database.VersionedPacket) LargeIntegrityPacket(me.retrodaredevil.solarthing.packets.security.LargeIntegrityPacket) ActivePeriod(me.retrodaredevil.solarthing.type.alter.flag.ActivePeriod) ImmutableStoredAlterPacket(me.retrodaredevil.solarthing.type.alter.ImmutableStoredAlterPacket) DeleteAlterPacket(me.retrodaredevil.solarthing.commands.packets.open.DeleteAlterPacket) InvalidKeyException(me.retrodaredevil.solarthing.packets.security.crypto.InvalidKeyException) Duration(java.time.Duration) FlagPacket(me.retrodaredevil.solarthing.type.alter.packets.FlagPacket) RequestCommandPacket(me.retrodaredevil.solarthing.commands.packets.open.RequestCommandPacket) DecryptException(me.retrodaredevil.solarthing.packets.security.crypto.DecryptException) Instant(java.time.Instant) IncompatibleUpdateTokenException(me.retrodaredevil.solarthing.database.exception.IncompatibleUpdateTokenException) ZoneId(java.time.ZoneId) Executors(java.util.concurrent.Executors) ExecutionReason(me.retrodaredevil.solarthing.reason.ExecutionReason) List(java.util.List) SolarThingConstants(me.retrodaredevil.solarthing.SolarThingConstants) TimeRange(me.retrodaredevil.solarthing.util.TimeRange) TimeRangeActivePeriod(me.retrodaredevil.solarthing.type.alter.flag.TimeRangeActivePeriod) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ScheduledCommandPacket(me.retrodaredevil.solarthing.type.alter.packets.ScheduledCommandPacket) OpenSource(me.retrodaredevil.solarthing.type.open.OpenSource) TargetPacketGroup(me.retrodaredevil.solarthing.packets.collection.TargetPacketGroup) Cipher(javax.crypto.Cipher) ArrayList(java.util.ArrayList) RequestFlagPacket(me.retrodaredevil.solarthing.commands.packets.open.RequestFlagPacket) FlagData(me.retrodaredevil.solarthing.type.alter.flag.FlagData) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) OpenSourceExecutionReason(me.retrodaredevil.solarthing.reason.OpenSourceExecutionReason) ScheduleCommandPacket(me.retrodaredevil.solarthing.commands.packets.open.ScheduleCommandPacket) ExecutorService(java.util.concurrent.ExecutorService) SimpleAction(me.retrodaredevil.action.SimpleAction) ScheduledCommandData(me.retrodaredevil.solarthing.type.alter.packets.ScheduledCommandData) Logger(org.slf4j.Logger) PacketCollectionCreator(me.retrodaredevil.solarthing.packets.collection.PacketCollectionCreator) KeyUtil(me.retrodaredevil.solarthing.packets.security.crypto.KeyUtil) SolarThingDatabase(me.retrodaredevil.solarthing.database.SolarThingDatabase) Decrypt(me.retrodaredevil.solarthing.packets.security.crypto.Decrypt) DatabaseCache(me.retrodaredevil.solarthing.database.cache.DatabaseCache) StoredAlterPacket(me.retrodaredevil.solarthing.type.alter.StoredAlterPacket) ImmutableRequestCommandPacket(me.retrodaredevil.solarthing.commands.packets.open.ImmutableRequestCommandPacket) StoredPacketGroup(me.retrodaredevil.solarthing.packets.collection.StoredPacketGroup) SecurityPacketReceiver(me.retrodaredevil.solarthing.program.SecurityPacketReceiver) AlterPacket(me.retrodaredevil.solarthing.type.alter.AlterPacket) UpdateConflictSolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.UpdateConflictSolarThingDatabaseException) PublicKeyLookUp(me.retrodaredevil.solarthing.packets.security.crypto.PublicKeyLookUp) Collections(java.util.Collections) PacketCollection(me.retrodaredevil.solarthing.packets.collection.PacketCollection) CommandOpenPacket(me.retrodaredevil.solarthing.commands.packets.open.CommandOpenPacket) SolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException) LargeIntegrityPacket(me.retrodaredevil.solarthing.packets.security.LargeIntegrityPacket) InvalidKeyException(me.retrodaredevil.solarthing.packets.security.crypto.InvalidKeyException) DecryptException(me.retrodaredevil.solarthing.packets.security.crypto.DecryptException)

Example 28 with Packet

use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.

the class AlterManagerAction method receivePacketWithIntegrity.

private void receivePacketWithIntegrity(String sender, TargetPacketGroup packetGroup) {
    LOGGER.debug("Sender: " + sender + " is authorized and sent a packet targeting no fragments, so we will see if we want to handle anything from it.");
    long now = System.currentTimeMillis();
    List<StoredAlterPacket> storedAlterPacketsToUpload = new ArrayList<>();
    List<DeleteAlterPacket> deleteAlterPackets = new ArrayList<>();
    for (Packet packet : packetGroup.getPackets()) {
        if (packet instanceof ScheduleCommandPacket) {
            ScheduleCommandPacket scheduleCommandPacket = (ScheduleCommandPacket) packet;
            ScheduledCommandData data = scheduleCommandPacket.getData();
            ExecutionReason executionReason = new OpenSourceExecutionReason(new OpenSource(sender, packetGroup.getDateMillis(), scheduleCommandPacket, // this is legacy data and shouldn't be used anywhere, so it doesn't matter what we put here
            scheduleCommandPacket.getUniqueString()));
            ScheduledCommandPacket scheduledCommandPacket = new ScheduledCommandPacket(data, executionReason);
            // This databaseId is basically an arbitrary way to generate a unique ID. It contains some stuff such as the command name to debug more easily
            String databaseId = "alter-scheduled-command-" + data.getCommandName() + "-" + Long.toHexString(data.getScheduledTimeMillis()) + "-" + sender + "-" + Math.random();
            StoredAlterPacket storedAlterPacket = new ImmutableStoredAlterPacket(databaseId, now, scheduledCommandPacket, this.sourceId);
            storedAlterPacketsToUpload.add(storedAlterPacket);
        } else if (packet instanceof DeleteAlterPacket) {
            DeleteAlterPacket deleteAlterPacket = (DeleteAlterPacket) packet;
            try {
                database.validateUpdateToken(deleteAlterPacket.getUpdateToken());
                deleteAlterPackets.add(deleteAlterPacket);
            } catch (IncompatibleUpdateTokenException ex) {
                LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "For some reason we have an incompatible update token!", ex);
            }
        } else if (packet instanceof RequestFlagPacket) {
            RequestFlagPacket requestFlagPacket = (RequestFlagPacket) packet;
            // Originally I was going to not upload a FlagPacket if an existing FlagPacket's
            // time range fully encapsulated the newly requested one, but that adds some complexity
            // that is not needed at the moment
            FlagData flagData = requestFlagPacket.getFlagData();
            ExecutionReason executionReason = new OpenSourceExecutionReason(new OpenSource(sender, packetGroup.getDateMillis(), requestFlagPacket, // this is legacy data and shouldn't be used anywhere, so it doesn't matter what we put here
            requestFlagPacket.getUniqueString()));
            FlagPacket flagPacket = new FlagPacket(flagData, executionReason);
            String databaseId = "alter-flag-" + flagData.getFlagName() + "-" + sender + "-" + Math.random();
            StoredAlterPacket storedAlterPacket = new ImmutableStoredAlterPacket(databaseId, now, flagPacket, sourceId);
            storedAlterPacketsToUpload.add(storedAlterPacket);
        }
    }
    if (storedAlterPacketsToUpload.isEmpty() && deleteAlterPackets.isEmpty()) {
        // Nothing for us to do, so no need to schedule a runnable
        return;
    }
    executorService.execute(() -> {
        int uploadCount = 0;
        try {
            for (StoredAlterPacket storedAlterPacket : storedAlterPacketsToUpload) {
                this.database.getAlterDatabase().upload(storedAlterPacket);
                uploadCount++;
            }
        } catch (SolarThingDatabaseException e) {
            // TODO in future we should try multiple times to upload
            LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "Could not upload a stored alter packet! uploaded: " + uploadCount + " / " + storedAlterPacketsToUpload.size(), e);
        }
        int deleteCount = 0;
        try {
            for (DeleteAlterPacket deleteAlterPacket : deleteAlterPackets) {
                this.database.getAlterDatabase().delete(deleteAlterPacket.getDocumentIdToDelete(), deleteAlterPacket.getUpdateToken());
                deleteCount++;
            }
        } catch (SolarThingDatabaseException e) {
            LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "Could not delete alter packets! deleted: " + deleteCount + " / " + deleteAlterPackets.size(), e);
        }
    });
}
Also used : Packet(me.retrodaredevil.solarthing.packets.Packet) VersionedPacket(me.retrodaredevil.solarthing.database.VersionedPacket) LargeIntegrityPacket(me.retrodaredevil.solarthing.packets.security.LargeIntegrityPacket) ImmutableStoredAlterPacket(me.retrodaredevil.solarthing.type.alter.ImmutableStoredAlterPacket) DeleteAlterPacket(me.retrodaredevil.solarthing.commands.packets.open.DeleteAlterPacket) FlagPacket(me.retrodaredevil.solarthing.type.alter.packets.FlagPacket) RequestCommandPacket(me.retrodaredevil.solarthing.commands.packets.open.RequestCommandPacket) ScheduledCommandPacket(me.retrodaredevil.solarthing.type.alter.packets.ScheduledCommandPacket) RequestFlagPacket(me.retrodaredevil.solarthing.commands.packets.open.RequestFlagPacket) ScheduleCommandPacket(me.retrodaredevil.solarthing.commands.packets.open.ScheduleCommandPacket) StoredAlterPacket(me.retrodaredevil.solarthing.type.alter.StoredAlterPacket) ImmutableRequestCommandPacket(me.retrodaredevil.solarthing.commands.packets.open.ImmutableRequestCommandPacket) AlterPacket(me.retrodaredevil.solarthing.type.alter.AlterPacket) CommandOpenPacket(me.retrodaredevil.solarthing.commands.packets.open.CommandOpenPacket) FlagPacket(me.retrodaredevil.solarthing.type.alter.packets.FlagPacket) RequestFlagPacket(me.retrodaredevil.solarthing.commands.packets.open.RequestFlagPacket) ImmutableStoredAlterPacket(me.retrodaredevil.solarthing.type.alter.ImmutableStoredAlterPacket) StoredAlterPacket(me.retrodaredevil.solarthing.type.alter.StoredAlterPacket) ArrayList(java.util.ArrayList) ExecutionReason(me.retrodaredevil.solarthing.reason.ExecutionReason) OpenSourceExecutionReason(me.retrodaredevil.solarthing.reason.OpenSourceExecutionReason) IncompatibleUpdateTokenException(me.retrodaredevil.solarthing.database.exception.IncompatibleUpdateTokenException) UpdateConflictSolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.UpdateConflictSolarThingDatabaseException) SolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException) ScheduledCommandPacket(me.retrodaredevil.solarthing.type.alter.packets.ScheduledCommandPacket) FlagData(me.retrodaredevil.solarthing.type.alter.flag.FlagData) DeleteAlterPacket(me.retrodaredevil.solarthing.commands.packets.open.DeleteAlterPacket) ScheduleCommandPacket(me.retrodaredevil.solarthing.commands.packets.open.ScheduleCommandPacket) ImmutableStoredAlterPacket(me.retrodaredevil.solarthing.type.alter.ImmutableStoredAlterPacket) OpenSource(me.retrodaredevil.solarthing.type.open.OpenSource) OpenSourceExecutionReason(me.retrodaredevil.solarthing.reason.OpenSourceExecutionReason) RequestFlagPacket(me.retrodaredevil.solarthing.commands.packets.open.RequestFlagPacket) ScheduledCommandData(me.retrodaredevil.solarthing.type.alter.packets.ScheduledCommandData)

Example 29 with Packet

use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.

the class MXEventUpdaterListReceiver method useData.

private void useData(MXStatusPacket mx, MXStatusPacket last) {
    final Integer previousChargerModeValue;
    final Integer previousRawAuxModeValue;
    final Integer previousErrorModeValue;
    if (last == null) {
        previousChargerModeValue = null;
        previousRawAuxModeValue = null;
        previousErrorModeValue = null;
    } else {
        previousChargerModeValue = last.getChargerModeValue();
        previousRawAuxModeValue = last.getRawAuxModeValue();
        previousErrorModeValue = last.getErrorModeValue();
    }
    int chargerModeValue = mx.getChargerModeValue();
    int rawAuxModeValue = mx.getRawAuxModeValue();
    int errorModeValue = mx.getErrorModeValue();
    List<Packet> eventPackets = new ArrayList<>();
    if (previousChargerModeValue == null || chargerModeValue != previousChargerModeValue) {
        eventPackets.add(new ImmutableMXChargerModeChangePacket(mx.getIdentifier(), chargerModeValue, previousChargerModeValue));
    }
    if (previousRawAuxModeValue == null || rawAuxModeValue != previousRawAuxModeValue) {
        eventPackets.add(new ImmutableMXAuxModeChangePacket(mx.getIdentifier(), rawAuxModeValue, previousRawAuxModeValue));
    }
    if (previousErrorModeValue == null || errorModeValue != previousErrorModeValue) {
        eventPackets.add(new ImmutableMXErrorModeChangePacket(mx.getIdentifier(), errorModeValue, previousErrorModeValue));
    }
    if (last != null && mx.isNewDay(last)) {
        eventPackets.add(new ImmutableMXRawDayEndPacket(mx.getAddress(), mx.getDailyKWH(), mx.getDailyAH(), mx.getDailyAHSupport()));
    }
    if (!eventPackets.isEmpty()) {
        eventReceiver.receive(eventPackets);
    }
}
Also used : Packet(me.retrodaredevil.solarthing.packets.Packet) ImmutableMXChargerModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXChargerModeChangePacket) ImmutableMXAuxModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXAuxModeChangePacket) ImmutableMXErrorModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXErrorModeChangePacket) ImmutableMXRawDayEndPacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXRawDayEndPacket) ImmutableMXAuxModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXAuxModeChangePacket) ImmutableMXChargerModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXChargerModeChangePacket) ArrayList(java.util.ArrayList) ImmutableMXRawDayEndPacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXRawDayEndPacket) ImmutableMXErrorModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXErrorModeChangePacket)

Example 30 with Packet

use of me.retrodaredevil.solarthing.packets.Packet in project solarthing by wildmountainfarms.

the class MXEventUpdaterListReceiver method receive.

@Override
public void receive(List<Packet> packets) {
    for (Packet packet : packets) {
        if (packet instanceof MXStatusPacket) {
            MXStatusPacket mx = (MXStatusPacket) packet;
            MXStatusPacket previous = previousPacketMap.get(mx.getIdentifier());
            previousPacketMap.put(mx.getIdentifier(), mx);
            useData(mx, previous);
        }
    }
}
Also used : Packet(me.retrodaredevil.solarthing.packets.Packet) ImmutableMXChargerModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXChargerModeChangePacket) ImmutableMXAuxModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXAuxModeChangePacket) ImmutableMXErrorModeChangePacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXErrorModeChangePacket) ImmutableMXRawDayEndPacket(me.retrodaredevil.solarthing.solar.outback.mx.event.ImmutableMXRawDayEndPacket)

Aggregations

Packet (me.retrodaredevil.solarthing.packets.Packet)45 ArrayList (java.util.ArrayList)17 Instant (java.time.Instant)7 List (java.util.List)7 FragmentedPacketGroup (me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup)6 FXStatusPacket (me.retrodaredevil.solarthing.solar.outback.fx.FXStatusPacket)6 Identifiable (me.retrodaredevil.solarthing.packets.identification.Identifiable)5 IdentifierFragment (me.retrodaredevil.solarthing.packets.identification.IdentifierFragment)5 RoverStatusPacket (me.retrodaredevil.solarthing.solar.renogy.rover.RoverStatusPacket)5 OpenSource (me.retrodaredevil.solarthing.type.open.OpenSource)5 Map (java.util.Map)4 CommandOpenPacket (me.retrodaredevil.solarthing.commands.packets.open.CommandOpenPacket)4 InstancePacketGroup (me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup)4 InstanceSourcePacket (me.retrodaredevil.solarthing.packets.instance.InstanceSourcePacket)4 ExecutionReason (me.retrodaredevil.solarthing.reason.ExecutionReason)4 OpenSourceExecutionReason (me.retrodaredevil.solarthing.reason.OpenSourceExecutionReason)4 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)3 ValueNode (com.fasterxml.jackson.databind.node.ValueNode)3 RequestCommandPacket (me.retrodaredevil.solarthing.commands.packets.open.RequestCommandPacket)3 VersionedPacket (me.retrodaredevil.solarthing.database.VersionedPacket)3