operate method
STROBE main duplexing mode.
Implementation
List<int> operate(bool meta, StrobeOperation operation, List<int> dataConst,
int length, bool more) {
int flags = operation.value;
if (meta) {
flags |= StrobeFlags.M;
}
List<int> data;
if (((flags & (StrobeFlags.I | StrobeFlags.T)) !=
(StrobeFlags.I | StrobeFlags.T)) &&
((flags & (StrobeFlags.I | StrobeFlags.A)) != StrobeFlags.A)) {
if (length == 0) {
throw const MessageException(
"A length should be set for this operation.");
}
data = List<int>.filled(length, 0);
} else {
if (length != 0) {
throw const MessageException(
"Output length must be zero except for PRF, send_MAC, and RATCHET operations.");
}
data = List<int>.from(dataConst);
}
if (more) {
if (flags != _curFlags) {
throw const MessageException(
"Flag should be the same when streaming operations.");
}
} else {
// If `more` isn't set, this is a new operation. Do the begin_op sequence
_op(flags);
_curFlags = flags;
}
// Operation
final bool cAfter =
((flags & (StrobeFlags.C | StrobeFlags.I | StrobeFlags.T)) ==
(StrobeFlags.C | StrobeFlags.T));
final bool cBefore = ((flags & StrobeFlags.C) != 0) && (!cAfter);
_duplex(data, cBefore, cAfter, false);
if ((flags & (StrobeFlags.I | StrobeFlags.A)) ==
(StrobeFlags.I | StrobeFlags.A)) {
return data;
} else if ((flags & (StrobeFlags.I | StrobeFlags.T)) == StrobeFlags.T) {
return data;
} else if ((flags & (StrobeFlags.I | StrobeFlags.A | StrobeFlags.T)) ==
(StrobeFlags.I | StrobeFlags.T)) {
if (more) {
throw const MessageException(
"Not supposed to check a MAC with the 'more' streaming option");
}
int failures = 0;
for (final int dataByte in data) {
failures |= dataByte;
}
return List<int>.from([failures]); // 0 if correct, 1 if not
}
return List.empty();
}