Files
pyxis/lib/tdeck_ui/Telemetry/LocationMessagePolicy.cpp
T

111 lines
3.8 KiB
C++

#include "LocationMessagePolicy.h"
namespace Telemetry {
namespace {
bool hasHumanText(const InboundLocationMessage& message) {
return (message.title.present && message.title.size != 0U) ||
(message.content.present && message.content.size != 0U);
}
void setChatActions(LocationMessageDecision& decision, bool enabled) {
decision.persist = enabled;
decision.route = enabled;
decision.notify = enabled;
}
} // namespace
LocationMessageDecision classifyInboundLocationMessage(
const InboundLocationMessage& message) {
LocationMessageDecision decision;
decision.authenticated_sender = message.authenticated_sender;
decision.received_at_millis = message.received_at_millis;
if (!message.telemetry.present) {
return decision;
}
const bool human_text = hasHumanText(message);
BinaryView telemetry_payload;
const FieldValueResult field_result = unwrapLxmfBinaryFieldValue(
message.telemetry.raw_value.data,
message.telemetry.raw_value.size,
telemetry_payload);
if (field_result != FieldValueResult::OK ||
decodeLocationTelemetry(telemetry_payload.data,
telemetry_payload.size,
decision.location) != DecodeResult::OK) {
decision.kind = LocationMessageKind::MALFORMED_LOCATION;
decision.log_malformed = true;
setChatActions(decision, human_text);
decision.drop = !human_text;
return decision;
}
if (message.custom_meta.present &&
decodeCustomLocationMeta(message.custom_meta.raw_value.data,
message.custom_meta.raw_value.size,
decision.meta) != CustomMetaResult::OK) {
// Metadata controls cease, expiry, and source ordering. Applying the
// telemetry while ignoring malformed metadata would violate all three.
decision.kind = LocationMessageKind::MALFORMED_LOCATION;
decision.log_malformed = true;
setChatActions(decision, human_text);
decision.drop = !human_text;
return decision;
}
if (!isValidPeerLocationInput(decision.location,
decision.meta,
message.received_at_millis)) {
decision.kind = LocationMessageKind::MALFORMED_LOCATION;
decision.log_malformed = true;
setChatActions(decision, human_text);
decision.drop = !human_text;
return decision;
}
decision.kind = decision.meta.has_cease && decision.meta.cease
? LocationMessageKind::VALID_CEASE
: LocationMessageKind::VALID_LOCATION;
decision.apply_location = true;
setChatActions(decision, human_text);
return decision;
}
LocationMessageExecution executeLocationMessageDecision(
const LocationMessageDecision& decision,
LocationMessageEffects& effects) {
LocationMessageExecution execution;
if (decision.log_malformed) {
effects.logMalformedLocation();
execution.malformed_logged = true;
}
if (decision.apply_location) {
execution.location_attempted = true;
execution.location_result = effects.applyLocation(
decision.authenticated_sender,
decision.location,
decision.meta,
decision.received_at_millis);
}
if (!decision.persist) return execution;
execution.persistence_attempted = true;
execution.persisted = effects.persistMessage();
if (!execution.persisted) return execution;
if (decision.route) {
effects.routeMessage();
execution.routed = true;
}
if (decision.notify) {
effects.notifyMessage();
execution.notified = true;
}
return execution;
}
} // namespace Telemetry