Clean up and refactor; new hw support
(Originally, https://android-review.googlesource.com/#/c/341550/)
This change addresses portability, a pn80t platform abstraction, and
nq-nci support.
Refactor/clean up:
- Adds darwin-sysdeps.c to help avoid reverting again.
- Clean up Android.bp
- T=1: moved T=1 to using bit_specs to keep some
of the readability of bitfields without incurring
weird toolchain side effects.
- T=1 will still rely on compilers keeping uchars
aligned and check it with a div-by-zero build
assertion.
- ESE platform specific methods are now wrapped.
- Adjusted error message constant usage.
- Enclosing {} for every if statement.
- Moved to relative headers for inclusion into other code
bases.
- Added a comment to log.h to make debugging easier globally
in libese code.
PN80T:
- Common code now shared across different
wire configurations.
- Add support for kernel based driver (called nq-nci)
which interacts with the nq-nci behavior for power
management.
- Added cooldown/end of session code to pn80t/common.c
- Migrated the ese_nxp_sample code to NQ_NCI and added the empty
session to test the cooldown code submission.
Bug: 34193473,35105409
Change-Id: I8fc320c8c236282ed103ef3ee3cb8c0dc99d8bcb
Test: unittests pass, tested ese-relay on hardware forwarding globalplatform pro
diff --git a/libese-teq1/Android.bp b/libese-teq1/Android.bp
index 86b9a41..76454f4 100644
--- a/libese-teq1/Android.bp
+++ b/libese-teq1/Android.bp
@@ -23,24 +23,24 @@
local_include_dirs: ["include"],
// Ensure that only explicitly exported symbols are visible.
- cflags: ["-fvisibility=internal"],
+ cflags: ["-fvisibility=internal", "-std=c99"],
debug: {
- cflags: ["-DLOG_NDEBUG=0"],
+ cflags: ["-DLOG_NDEBUG=0"],
},
- shared_libs: ["liblog", "libese"],
+ shared_libs: ["liblog", "libese", "libese-sysdeps"],
export_include_dirs: ["include"],
}
cc_library {
- name: "libese-teq1-private",
- host_supported: true,
+ name: "libese-teq1-private",
+ host_supported: true,
- srcs: ["teq1.c"],
- local_include_dirs: ["include"],
+ srcs: ["teq1.c"],
+ local_include_dirs: ["include"],
- // Ensure that only explicitly exported symbols are visible.
- shared_libs: ["liblog", "libese"],
- export_include_dirs: ["include", "."],
+ // Ensure that only explicitly exported symbols are visible.
+ shared_libs: ["liblog", "libese", "libese-sysdeps"],
+ export_include_dirs: ["include", "."],
}
subdirs = ["tests"]
diff --git a/libese-teq1/include/ese/teq1.h b/libese-teq1/include/ese/teq1.h
index 61831a5..8a3fa2e 100644
--- a/libese-teq1/include/ese/teq1.h
+++ b/libese-teq1/include/ese/teq1.h
@@ -21,20 +21,22 @@
extern "C" {
#endif
-#include <ese/ese.h>
+#include "../../../libese/include/ese/ese.h"
+#include "../../../libese/include/ese/bit_spec.h"
-/* Reserved codes for T=1 devices. */
-#define TEQ1_ERROR_HARD_FAIL 0
-#define TEQ1_ERROR_ABORT 1
-#define TEQ1_ERROR_DEVICE_RESET 2
-
+/* Reserved codes for T=1 devices in EseOperation>errors. */
+enum Teq1Error {
+ kTeq1ErrorHardFail = 0,
+ kTeq1ErrorAbort,
+ kTeq1ErrorDeviceReset,
+ kTeq1ErrorMax,
+};
enum pcb_type {
kPcbTypeInfo0 = 0x0,
kPcbTypeInfo1 = 0x1,
kPcbTypeReceiveReady = 0x2,
kPcbTypeSupervisory = 0x3,
- kPcbTypeMax,
};
enum super_type {
@@ -44,54 +46,52 @@
kSuperTypeWTX = 0x3,
};
-struct PCB {
- union {
- /* Info bits */
- struct {
- uint8_t reserved:5; /* Should be 0. */
- uint8_t more_data:1;
- uint8_t send_seq:1;
- uint8_t bit8:1; /* Must be 0 for I-blocks. */
- } I; /* Information Block */
- /* receive bits */
- struct {
- uint8_t parity_err:1; /* char parity or redundancy code err */
- uint8_t other_err:1; /* any other errors */
- uint8_t unused_1:2;
- uint8_t next_seq:1; /* If the same seq as last frame, then err even if other bits are 0. */
- uint8_t unused_0:1;
- uint8_t pcb_type:2; /* Always (1, 0)=2 for R */
- } R; /* Receive ready block */
- struct {
- uint8_t type:2;
- uint8_t unused_0:3;
- uint8_t response:1;
- uint8_t pcb_type:2;
- } S; /* Supervisory block */
- struct {
- uint8_t data:6;
- uint8_t type:2; /* I = 0|1, R = 2, S = 3 */
- }; /* Bit7-8 access for block type access. */
- /* Bitwise access */
- struct {
- uint8_t bit0:1; /* lsb */
- uint8_t bit1:1;
- uint8_t bit2:1;
- uint8_t bit3:1;
- uint8_t bit4:1;
- uint8_t bit5:1;
- uint8_t bit6:1;
- uint8_t bit7:1; /* msb */
- } bits;
- uint8_t val;
- };
+struct PcbSpec {
+ struct bit_spec type;
+ struct bit_spec data;
+ struct {
+ struct bit_spec more_data;
+ struct bit_spec send_seq;
+ } I;
+ struct {
+ struct bit_spec parity_err;
+ struct bit_spec other_err;
+ struct bit_spec next_seq;
+ } R;
+ struct {
+ struct bit_spec type;
+ struct bit_spec response;
+ } S;
+};
+
+const static struct PcbSpec PCB = {
+ .type = { .value = 3, .shift = 6, },
+ .data = { .value = 63, .shift = 0, },
+ .I = {
+ .more_data = { .value = 1, .shift = 5, },
+ .send_seq = { .value = 1, .shift = 6, },
+ },
+ .R = {
+ /* char parity or redundancy code err */
+ .parity_err = { .value = 1, .shift = 0, },
+ /* any other errors */
+ .other_err = { .value = 1, .shift = 1, },
+ /* If the same seq as last frame, then err even if other bits are 0. */
+ .next_seq = { .value = 1, .shift = 4, },
+ },
+ .S = {
+ .type = { .value = 3, .shift = 0, },
+ .response = { .value = 1, .shift = 5, },
+ },
};
struct Teq1Header {
uint8_t NAD;
- struct PCB PCB;
+ uint8_t PCB;
uint8_t LEN;
-} __attribute__((packed));
+};
+#define TEQ1HEADER_SIZE 3
+#define TEQ1FRAME_SIZE INF_LEN + 1 + TEQ1HEADER_SIZE
#define INF_LEN 254
#define IFSC 254
@@ -103,10 +103,10 @@
union {
uint8_t INF[INF_LEN + 1]; /* Up to 254 with trailing LRC byte. */
};
- /* uint8_t LRC; If CRC was supported, it would be uint16_t. */
+ /* If CRC was supported, it would be uint16_t. */
};
};
-} __attribute__((packed));
+};
/*
@@ -122,6 +122,7 @@
uint8_t seq_bits;
} seq;
};
+
/* Set "last sent" to 1 so we start at 0. */
#define TEQ1_INIT_CARD_STATE(CARD) \
(CARD)->seq.card = 1; \
@@ -146,7 +147,11 @@
teq1_protocol_preprocess_op_t *preprocess;
};
+/* PCB bits */
+#define kTeq1PcbType (3 << 6)
+
/* I-block bits */
+#define kTeq1InfoType (0 << 6)
#define kTeq1InfoMoreBit (1 << 5)
#define kTeq1InfoSeqBit (1 << 6)
@@ -176,9 +181,10 @@
#define TEQ1_S_ABORT(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperAbortBit)
#define TEQ1_S_IFS(R) (kTeq1SuperType | ((R) << 5) | kTeq1SuperIfsBit)
-size_t teq1_transceive(struct EseInterface *ese,
- const uint8_t *const tx_buf, size_t tx_len,
- uint8_t *rx_buf, size_t rx_max);
+uint32_t teq1_transceive(struct EseInterface *ese,
+ const struct Teq1ProtocolOptions *opts,
+ const uint8_t *const tx_buf, uint32_t tx_len,
+ uint8_t *rx_buf, uint32_t rx_max);
uint8_t teq1_compute_LRC(const struct Teq1Frame *frame);
diff --git a/libese-teq1/teq1.c b/libese-teq1/teq1.c
index 9d0b2a5..40d2b1d 100644
--- a/libese-teq1/teq1.c
+++ b/libese-teq1/teq1.c
@@ -14,13 +14,9 @@
* limitations under the License.
*/
-#include <string.h>
-
-#include <ese/ese.h>
-#include <ese/teq1.h>
-
-#define LOG_TAG "ESE_T=1"
-#include <ese/log.h>
+#include "include/ese/teq1.h"
+#include "../libese/include/ese/ese.h"
+#include "../libese/include/ese/log.h"
#include "teq1_private.h"
@@ -94,10 +90,15 @@
}
}
-int teq1_transmit(struct EseInterface *ese, struct Teq1Frame *frame) {
- /* Set during ese_open() by teq1_init. */
- const struct Teq1ProtocolOptions *opts = ese->ops->opts;
+void teq1_dump_buf(const char *prefix, const uint8_t *buf, uint32_t len) {
+ uint32_t recvd = 0;
+ for (recvd = 0; recvd < len; ++recvd)
+ ALOGV("%s[%u]: %.2X", prefix, recvd, buf[recvd]);
+}
+int teq1_transmit(struct EseInterface *ese,
+ const struct Teq1ProtocolOptions *opts,
+ struct Teq1Frame *frame) {
/* Set correct node address. */
frame->header.NAD = opts->node_address;
@@ -106,40 +107,48 @@
/*
* If the card does something weird, like expect an CRC/LRC based on a
- * different
- * header value, the preprocessing can handle it.
+ * different header value, the preprocessing can handle it.
*/
- if (opts->preprocess)
+ if (opts->preprocess) {
opts->preprocess(opts, frame, 1);
+ }
/*
* Begins transmission and ignore errors.
* Failed transmissions will result eventually in a resync then reset.
*/
- teq1_trace_transmit(frame->header.PCB.val, frame->header.LEN);
+ teq1_trace_transmit(frame->header.PCB, frame->header.LEN);
+ teq1_dump_transmit(frame->val, sizeof(frame->header) + frame->header.LEN + 1);
ese->ops->hw_transmit(ese, frame->val,
sizeof(frame->header) + frame->header.LEN + 1, 1);
- /* Even though in practice any WTX BWT extension starts when the above
- * transmit ends.
- * it is easier to implement it in the polling timeout of receive.
+ /*
+ * Even though in practice any WTX BWT extension starts when the above
+ * transmit ends, it is easier to implement it in the polling timeout of
+ * receive.
*/
return 0;
}
-int teq1_receive(struct EseInterface *ese, float timeout,
+int teq1_receive(struct EseInterface *ese,
+ const struct Teq1ProtocolOptions *opts, float timeout,
struct Teq1Frame *frame) {
- const struct Teq1ProtocolOptions *opts = ese->ops->opts;
/* Poll the bus until we see the start of frame indicator, the interface NAD.
*/
- if (ese->ops->poll(ese, opts->host_address, timeout, 0) < 0) {
+ int bytes_consumed = ese->ops->poll(ese, opts->host_address, timeout, 0);
+ if (bytes_consumed < 0 || bytes_consumed > 1) {
/* Timed out or comm error. */
+ ALOGV("%s: comm error: %d", __func__, bytes_consumed);
return -1;
}
- /* We polled for the NAD above. */
- frame->header.NAD = opts->host_address;
+ /* We polled for the NAD above -- if it was consumed, set it here. */
+ if (bytes_consumed) {
+ frame->header.NAD = opts->host_address;
+ }
/* Get the remainder of the header, but keep the line &open. */
- ese->ops->hw_receive(ese, (uint8_t *)(&frame->header.PCB),
- sizeof(frame->header) - 1, 0);
+ ese->ops->hw_receive(ese, (uint8_t *)(&frame->header.NAD + bytes_consumed),
+ sizeof(frame->header) - bytes_consumed, 0);
+ teq1_dump_receive((uint8_t *)(&frame->header.NAD + bytes_consumed),
+ sizeof(frame->header) - bytes_consumed);
if (frame->header.LEN == 255) {
ALOGV("received invalid LEN of 255");
/* Close the receive window and return failure. */
@@ -152,15 +161,17 @@
*/
ese->ops->hw_receive(ese, (uint8_t *)(&(frame->INF[0])),
frame->header.LEN + 1, 1);
- teq1_trace_receive(frame->header.PCB.val, frame->header.LEN);
+ teq1_dump_receive((uint8_t *)(&(frame->INF[0])), frame->header.LEN + 1);
+ teq1_trace_receive(frame->header.PCB, frame->header.LEN);
/*
* If the card does something weird, like expect an CRC/LRC based on a
* different
* header value, the preprocessing should fix up here prior to the LRC check.
*/
- if (opts->preprocess)
+ if (opts->preprocess) {
opts->preprocess(opts, frame, 0);
+ }
/* LRC and other protocol goodness checks are not done here. */
return frame->header.LEN; /* Return data bytes read. */
@@ -168,15 +179,17 @@
uint8_t teq1_fill_info_block(struct Teq1State *state, struct Teq1Frame *frame) {
uint32_t inf_len = INF_LEN;
- if (state->ifs < inf_len)
+ if (state->ifs < inf_len) {
inf_len = state->ifs;
- switch (frame->header.PCB.type) {
+ }
+ switch (bs_get(PCB.type, frame->header.PCB)) {
case kPcbTypeInfo0:
case kPcbTypeInfo1: {
uint32_t len = state->app_data.tx_len;
- if (len > inf_len)
+ if (len > inf_len) {
len = inf_len;
- memcpy(frame->INF, state->app_data.tx_buf, len);
+ }
+ ese_memcpy(frame->INF, state->app_data.tx_buf, len);
frame->header.LEN = (len & 0xff);
ALOGV("Copying %x bytes of app data for transmission", frame->header.LEN);
/* Incrementing here means the caller MUST handle retransmit with prepared
@@ -184,9 +197,10 @@
state->app_data.tx_len -= len;
state->app_data.tx_buf += len;
/* Perform chained transmission if needed. */
- frame->header.PCB.I.more_data = 0;
- if (state->app_data.tx_len > 0)
- frame->header.PCB.I.more_data = 1;
+ bs_assign(&frame->header.PCB, PCB.I.more_data, 0);
+ if (state->app_data.tx_len > 0) {
+ frame->header.PCB |= bs_mask(PCB.I.more_data, 1);
+ }
return len;
}
case kPcbTypeSupervisory:
@@ -198,14 +212,15 @@
}
void teq1_get_app_data(struct Teq1State *state, struct Teq1Frame *frame) {
- switch (frame->header.PCB.type) {
+ switch (bs_get(PCB.type, frame->header.PCB)) {
case kPcbTypeInfo0:
case kPcbTypeInfo1: {
uint8_t len = frame->header.LEN;
/* TODO(wad): Some data will be left on the table. Should this error out? */
- if (len > state->app_data.rx_len)
+ if (len > state->app_data.rx_len) {
len = state->app_data.rx_len;
- memcpy(state->app_data.rx_buf, frame->INF, len);
+ }
+ ese_memcpy(state->app_data.rx_buf, frame->INF, len);
/* The original caller must retain the starting pointer to determine
* actual available data.
*/
@@ -227,8 +242,9 @@
struct Teq1Frame *rx_frame) {
uint8_t lrc = 0;
int chained = 0;
- if (rx_frame->header.PCB.val == 255)
+ if (rx_frame->header.PCB == 255) {
return R(0, 1, 0); /* Other error */
+ }
lrc = teq1_compute_LRC(rx_frame);
if (rx_frame->INF[rx_frame->header.LEN] != lrc) {
@@ -238,46 +254,42 @@
}
/* Check if we were chained and increment the last sent sequence. */
- switch (tx_frame->header.PCB.type) {
+ switch (bs_get(PCB.type, tx_frame->header.PCB)) {
case kPcbTypeInfo0:
case kPcbTypeInfo1:
- chained = tx_frame->header.PCB.I.more_data;
- state->card_state->seq.interface = tx_frame->header.PCB.I.send_seq;
+ chained = bs_get(PCB.I.more_data, tx_frame->header.PCB);
+ state->card_state->seq.interface =
+ bs_get(PCB.I.send_seq, tx_frame->header.PCB);
}
/* Check if we've gone down an easy to catch error hole. The rest will turn up
* on the
* txrx switch.
*/
- switch (rx_frame->header.PCB.type) {
+ switch (bs_get(PCB.type, rx_frame->header.PCB)) {
case kPcbTypeSupervisory:
- if (rx_frame->header.PCB.val != S(RESYNC, RESPONSE) &&
- rx_frame->header.LEN != 1)
+ if (rx_frame->header.PCB != S(RESYNC, RESPONSE) &&
+ rx_frame->header.LEN != 1) {
return R(0, 1, 0);
+ }
break;
case kPcbTypeReceiveReady:
- if (rx_frame->header.LEN != 0)
+ if (rx_frame->header.LEN != 0) {
return R(0, 1, 0);
-#if 0
-/* Handled explicitly. */
- /* R() blocks are always an error if we're not chaining. */
- if (!chained)
- return R(0, 1, 0);
- /* If we are chaining, the R must be the next seq. */
- if (rx_frame->header.PCB.R.next_seq == state->card_state->seq.interface)
- return R(0, 1, 0);
-#endif
+ }
break;
case kPcbTypeInfo0:
case kPcbTypeInfo1:
/* I-blocks must always alternate for each endpoint. */
- if (rx_frame->header.PCB.I.send_seq == state->card_state->seq.card) {
- ALOGV("Got seq %d expected %d", rx_frame->header.PCB.I.send_seq,
+ if ((bs_get(PCB.I.send_seq, rx_frame->header.PCB)) ==
+ state->card_state->seq.card) {
+ ALOGV("Got seq %d expected %d",
+ bs_get(PCB.I.send_seq, rx_frame->header.PCB),
state->card_state->seq.card);
return R(0, 1, 0);
}
/* Update the card's last I-block seq. */
- state->card_state->seq.card = rx_frame->header.PCB.I.send_seq;
+ state->card_state->seq.card = bs_get(PCB.I.send_seq, rx_frame->header.PCB);
default:
break;
};
@@ -291,25 +303,25 @@
/* 0 = TX, 1 = RX */
/* msb = tx pcb, lsb = rx pcb */
/* BUG_ON(!rx_frame && !tx_frame && !next_tx); */
- uint16_t txrx = TEQ1_RULE(tx_frame->header.PCB.val, rx_frame->header.PCB.val);
- struct PCB R_err;
+ uint16_t txrx = TEQ1_RULE(tx_frame->header.PCB, rx_frame->header.PCB);
+ uint8_t R_err;
while (1) {
/* Timeout errors come like invalid frames: 255. */
- if ((R_err.val = teq1_frame_error_check(state, tx_frame, rx_frame)) != 0) {
+ if ((R_err = teq1_frame_error_check(state, tx_frame, rx_frame)) != 0) {
ALOGV("incoming frame failed the error check");
state->last_error_message = "Invalid frame received";
/* Mark the frame as bad for our rule evaluation. */
- txrx = TEQ1_RULE(tx_frame->header.PCB.val, 255);
+ txrx = TEQ1_RULE(tx_frame->header.PCB, 255);
state->errors++;
/* Rule 6.4 */
- if (state->errors >= 6) { /* XXX: Review error count lifetime. */
+ if (state->errors >= 6) {
return kRuleResultResetDevice;
}
/* Rule 7.4.2 */
if (state->errors >= 3) {
/* Rule 7.4.1: state should start with error count = 2 */
- next_tx->header.PCB.val = S(RESYNC, REQUEST);
+ next_tx->header.PCB = S(RESYNC, REQUEST);
/* Resync result in a fresh session, so we should just continue here. */
return kRuleResultContinue;
}
@@ -327,25 +339,22 @@
teq1_get_app_data(state, rx_frame);
return kRuleResultComplete;
- /* Read app data & return. */
- teq1_get_app_data(state, rx_frame);
- return kRuleResultComplete;
-
/* Card begins chained response. */
case TEQ1_RULE(I(0, 0), I(0, 1)):
case TEQ1_RULE(I(1, 0), I(1, 1)):
/* Prep R(N(S)) */
teq1_get_app_data(state, rx_frame);
- next_tx->header.PCB.val = TEQ1_R(!rx_frame->header.PCB.I.send_seq, 0, 0);
+ next_tx->header.PCB =
+ TEQ1_R(!bs_get(PCB.I.send_seq, rx_frame->header.PCB), 0, 0);
next_tx->header.LEN = 0;
return kRuleResultContinue;
/*** Rule 2.2, Rule 5: Chained transmission ***/
case TEQ1_RULE(I(0, 1), R(1, 0, 0)):
case TEQ1_RULE(I(1, 1), R(0, 0, 0)):
- /* Send next block */
- next_tx->header.PCB.val = I(0, 0);
- next_tx->header.PCB.I.send_seq = rx_frame->header.PCB.R.next_seq;
+ /* Send next block -- error-checking assures the R seq is our next seq. */
+ next_tx->header.PCB =
+ TEQ1_I(bs_get(PCB.R.next_seq, rx_frame->header.PCB), 0);
teq1_fill_info_block(state, next_tx); /* Sets M-bit and LEN. */
return kRuleResultContinue;
@@ -358,7 +367,7 @@
case TEQ1_RULE(I(1, 1), S(WTX, REQUEST)):
*/
/* Send S(WTX, RESPONSE) with same INF */
- next_tx->header.PCB.val = S(WTX, RESPONSE);
+ next_tx->header.PCB = S(WTX, RESPONSE);
next_tx->header.LEN = 1;
next_tx->INF[0] = rx_frame->INF[0];
state->wait_mult = rx_frame->INF[0];
@@ -377,7 +386,7 @@
/* Don't support a IFS_REQUEST if we sent an error R-block. */
case TEQ1_RULE(R(0, 0, 0), S(IFS, REQUEST)):
case TEQ1_RULE(R(1, 0, 0), S(IFS, REQUEST)):
- next_tx->header.PCB.val = S(IFS, RESPONSE);
+ next_tx->header.PCB = S(IFS, RESPONSE);
next_tx->header.LEN = 1;
next_tx->INF[0] = rx_frame->INF[0];
state->ifs = rx_frame->INF[0];
@@ -393,7 +402,9 @@
case TEQ1_RULE(R(1, 0, 0), I(1, 1)):
/* Chaining continued; consume partial data and send R(N(S)) */
teq1_get_app_data(state, rx_frame);
- next_tx->header.PCB.val = TEQ1_R(!rx_frame->header.PCB.I.send_seq, 0, 0);
+ /* The card seq bit will be tracked/validated earlier. */
+ next_tx->header.PCB =
+ TEQ1_R(!bs_get(PCB.I.send_seq, rx_frame->header.PCB), 0, 0);
return kRuleResultContinue;
/* Rule 6: Interface can send a RESYNC */
@@ -414,10 +425,11 @@
case TEQ1_RULE(I(1, 0), 255):
case TEQ1_RULE(I(0, 1), 255):
case TEQ1_RULE(I(1, 1), 255):
- next_tx->header.PCB.val = R_err.val;
- next_tx->header.PCB.R.next_seq = tx_frame->header.PCB.I.send_seq;
+ next_tx->header.PCB = R_err;
+ bs_assign(&next_tx->header.PCB, PCB.R.next_seq,
+ bs_get(PCB.I.send_seq, tx_frame->header.PCB));
ALOGV("Rule 7.1,7.5,7.6: bad rx - sending error R: %x = %s",
- next_tx->header.PCB.val, teq1_pcb_to_name(next_tx->header.PCB.val));
+ next_tx->header.PCB, teq1_pcb_to_name(next_tx->header.PCB));
return kRuleResultSingleShot; /* So we still can retransmit the original.
*/
@@ -430,10 +442,10 @@
case TEQ1_RULE(I(1, 0), R(0, 0, 1)):
case TEQ1_RULE(I(1, 0), R(0, 1, 0)):
case TEQ1_RULE(I(1, 0), R(0, 1, 1)):
- next_tx->header.PCB.val = R(0, 0, 0);
- next_tx->header.PCB.R.next_seq = tx_frame->header.PCB.I.send_seq;
+ next_tx->header.PCB =
+ TEQ1_R(bs_get(PCB.I.send_seq, tx_frame->header.PCB), 0, 0);
ALOGV("Rule 7.1,7.5,7.6: weird rx - sending error R: %x = %s",
- next_tx->header.PCB.val, teq1_pcb_to_name(next_tx->header.PCB.val));
+ next_tx->header.PCB, teq1_pcb_to_name(next_tx->header.PCB));
return kRuleResultSingleShot;
/* Rule 7.2: Retransmit the _same_ R-block. */
@@ -499,7 +511,7 @@
case TEQ1_RULE(R(1, 0, 1), S(ABORT, REQUEST)):
case TEQ1_RULE(R(1, 1, 0), S(ABORT, REQUEST)):
case TEQ1_RULE(R(1, 1, 1), S(ABORT, REQUEST)):
- next_tx->header.PCB.val = S(ABORT, REQUEST);
+ next_tx->header.PCB = S(ABORT, REQUEST);
return kRuleResultContinue; /* Takes over prior flow. */
case TEQ1_RULE(S(ABORT, RESPONSE), 255):
return kRuleResultRetransmit;
@@ -515,9 +527,9 @@
* For supported flows: If an operation was paused to
* send it, the caller may then switch to that state and resume.
*/
- if (rx_frame->header.PCB.val != 255) {
+ if (rx_frame->header.PCB != 255) {
ALOGV("Unexpected frame. Marking error and re-evaluating.");
- rx_frame->header.PCB.val = 255;
+ rx_frame->header.PCB = 255;
continue;
}
@@ -531,68 +543,75 @@
* if testing becomes onerous given the loop below.
*/
-API size_t teq1_transceive(struct EseInterface *ese,
- const uint8_t *const tx_buf, size_t tx_len,
- uint8_t *rx_buf, size_t rx_len) {
+API uint32_t teq1_transceive(struct EseInterface *ese,
+ const struct Teq1ProtocolOptions *opts,
+ const uint8_t *const tx_buf, uint32_t tx_len,
+ uint8_t *rx_buf, uint32_t rx_len) {
struct Teq1Frame tx_frame[2];
struct Teq1Frame rx_frame;
struct Teq1Frame *tx = &tx_frame[0];
- int was_reset = 0;
int active = 0;
- int done = 0;
+ bool was_reset = false;
+ bool done = false;
enum RuleResult result = kRuleResultComplete;
- const struct Teq1ProtocolOptions *opts = ese->ops->opts;
struct Teq1CardState *card_state = (struct Teq1CardState *)(&ese->pad[0]);
struct Teq1State init_state =
TEQ1_INIT_STATE(tx_buf, tx_len, rx_buf, rx_len, card_state);
struct Teq1State state =
TEQ1_INIT_STATE(tx_buf, tx_len, rx_buf, rx_len, card_state);
+ _static_assert(TEQ1HEADER_SIZE == sizeof(struct Teq1Header),
+ "Ensure compiler alignment/padding matches wire protocol.");
+ _static_assert(TEQ1FRAME_SIZE == sizeof(struct Teq1Frame),
+ "Ensure compiler alignment/padding matches wire protocol.");
+
/* First I-block is always I(0, M). After that, modulo 2. */
- tx->header.PCB.val = TEQ1_I(!card_state->seq.interface, 0);
+ tx->header.PCB = TEQ1_I(!card_state->seq.interface, 0);
teq1_fill_info_block(&state, tx);
teq1_trace_header();
while (!done) {
/* Populates the node address and LRC prior to attempting to transmit. */
- teq1_transmit(ese, tx);
+ teq1_transmit(ese, opts, tx);
/* If tx was pointed to the inactive frame for a single shot, restore it
* now. */
tx = &tx_frame[active];
/* Clear the RX frame. */
- memset(&rx_frame, 0xff, sizeof(rx_frame));
+ ese_memset(&rx_frame, 0xff, sizeof(rx_frame));
/* -1 indicates a timeout or failure from hardware. */
- if (teq1_receive(ese, opts->bwt * (float)state.wait_mult, &rx_frame) < 0) {
+ if (teq1_receive(ese, opts, opts->bwt * (float)state.wait_mult, &rx_frame) <
+ 0) {
/* TODO(wad): If the ese_error(ese) == 1, should this go ahead and fail?
*/
/* Failures are considered invalid blocks in the rule engine below. */
- rx_frame.header.PCB.val = 255;
+ rx_frame.header.PCB = 255;
}
/* Always reset |wait_mult| once we have calculated the timeout. */
state.wait_mult = 1;
/* Clear the inactive frame header for use as |next_tx|. */
- memset(&tx_frame[!active].header, 0, sizeof(tx_frame[!active].header));
+ ese_memset(&tx_frame[!active].header, 0, sizeof(tx_frame[!active].header));
result = teq1_rules(&state, tx, &rx_frame, &tx_frame[!active]);
ALOGV("[ %s ]", teq1_rule_result_to_name(result));
switch (result) {
case kRuleResultComplete:
- done = 1;
+ done = true;
break;
case kRuleResultRetransmit:
/* TODO(wad) Find a clean way to move into teq1_rules(). */
- if (state.retransmits++ < 3)
+ if (state.retransmits++ < 3) {
continue;
- if (tx->header.PCB.val == S(RESYNC, REQUEST)) {
- ese_set_error(ese, TEQ1_ERROR_HARD_FAIL);
+ }
+ if (tx->header.PCB == S(RESYNC, REQUEST)) {
+ ese_set_error(ese, kTeq1ErrorHardFail);
return 0;
}
/* Fall through */
- tx_frame[!active].header.PCB.val = S(RESYNC, REQUEST);
+ tx_frame[!active].header.PCB = S(RESYNC, REQUEST);
case kRuleResultContinue:
active = !active;
tx = &tx_frame[active];
@@ -600,10 +619,10 @@
state.errors = 0;
continue;
case kRuleResultHardFail:
- ese_set_error(ese, TEQ1_ERROR_HARD_FAIL);
+ ese_set_error(ese, kTeq1ErrorHardFail);
return 0;
case kRuleResultAbort:
- ese_set_error(ese, TEQ1_ERROR_ABORT);
+ ese_set_error(ese, kTeq1ErrorAbort);
return 0;
case kRuleResultSingleShot:
/*
@@ -615,19 +634,19 @@
continue;
case kRuleResultResetDevice:
if (was_reset || !ese->ops->hw_reset || ese->ops->hw_reset(ese) == -1) {
- ese_set_error(ese, TEQ1_ERROR_DEVICE_RESET);
+ ese_set_error(ese, kTeq1ErrorDeviceReset);
return 0; /* Don't keep resetting -- hard fail. */
}
- was_reset = 1;
+ was_reset = true;
/* Fall through to session reset. */
case kRuleResultResetSession:
/* Roll back state and reset. */
state = init_state;
TEQ1_INIT_CARD_STATE(state.card_state);
/* Reset the active frame. */
- memset(tx, 0, sizeof(*tx));
+ ese_memset(tx, 0, sizeof(*tx));
/* Load initial I-block. */
- tx->header.PCB.val = I(0, 0);
+ tx->header.PCB = I(0, 0);
teq1_fill_info_block(&state, tx);
continue;
}
diff --git a/libese-teq1/teq1_private.h b/libese-teq1/teq1_private.h
index 3151753..6bd3d3c 100644
--- a/libese-teq1/teq1_private.h
+++ b/libese-teq1/teq1_private.h
@@ -25,6 +25,11 @@
#define API __attribute__ ((visibility("default")))
#endif /* API */
+/* Mimic C11 _Static_assert behavior for a C99 world. */
+#ifndef _static_assert
+#define _static_assert(what, why) { while (!(1 / (!!(what)))); }
+#endif
+
/*
* Enable T=1 format to reduce to case integers.
* Ensure there are tests to map TEQ1_X() to the shorthand below.
@@ -66,9 +71,9 @@
struct Teq1CardState *card_state;
struct {
uint8_t *tx_buf;
- size_t tx_len;
+ uint32_t tx_len;
uint8_t *rx_buf;
- size_t rx_len;
+ uint32_t rx_len;
} app_data;
};
@@ -102,8 +107,13 @@
const char *teq1_rule_result_to_name(enum RuleResult result);
const char *teq1_pcb_to_name(uint8_t pcb);
-int teq1_transmit(struct EseInterface *ese, struct Teq1Frame *frame);
-int teq1_receive(struct EseInterface *ese, float timeout, struct Teq1Frame *frame);
+int teq1_transmit(struct EseInterface *ese,
+ const struct Teq1ProtocolOptions *opts,
+ struct Teq1Frame *frame);
+int teq1_receive(struct EseInterface *ese,
+ const struct Teq1ProtocolOptions *opts,
+ float timeout,
+ struct Teq1Frame *frame);
uint8_t teq1_fill_info_block(struct Teq1State *state, struct Teq1Frame *frame);
void teq1_get_app_data(struct Teq1State *state, struct Teq1Frame *frame);
uint8_t teq1_frame_error_check(struct Teq1State *state,
@@ -114,6 +124,8 @@
struct Teq1Frame *rx_frame,
struct Teq1Frame *next_tx);
+#define teq1_dump_transmit(_B, _L) teq1_dump_buf("TX", (_B), (_L))
+#define teq1_dump_receive(_B, _L) teq1_dump_buf("RX", (_B), (_L))
#ifdef __cplusplus
} /* extern "C" */
diff --git a/libese-teq1/tests/Android.bp b/libese-teq1/tests/Android.bp
index 9cb2fb4..a54a0af 100644
--- a/libese-teq1/tests/Android.bp
+++ b/libese-teq1/tests/Android.bp
@@ -14,28 +14,13 @@
// limitations under the License.
//
-cc_defaults {
- name: "libese_teq1_tests_default",
- multilib: {
- lib32: {
- suffix: "32",
- },
- lib64: {
- suffix: "64",
- },
- },
-}
-
-test_libraries = [
- "libese",
- "libese-teq1-private",
- "liblog",
-]
-
cc_test {
name: "ese_teq1_unittests",
- defaults: ["libese_teq1_tests_default"],
srcs: ["teq1_unittests.cpp"],
host_supported: true,
- shared_libs: test_libraries,
+ shared_libs: [
+ "libese",
+ "libese-teq1-private",
+ "liblog",
+ ],
}
diff --git a/libese-teq1/tests/teq1_unittests.cpp b/libese-teq1/tests/teq1_unittests.cpp
index 77118fa..aef5e0a 100644
--- a/libese-teq1/tests/teq1_unittests.cpp
+++ b/libese-teq1/tests/teq1_unittests.cpp
@@ -36,7 +36,6 @@
// - Unittests of each function
// - teq1_rules matches Annex A of ISO 7816-3
-
// Tests teq1_frame_error_check to avoid testing every combo that
// ends in 255 in the rule engine.
class Teq1FrameErrorCheck : public virtual Test {
@@ -60,16 +59,16 @@
/* The PCBs above are all valid for a sent unchained I block with advancing
* sequence #s.
*/
- tx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ tx_frame_.header.PCB = TEQ1_I(0, 0);
state_.card_state = &card_state_;
state_.card_state->seq.card = 1;
while (*pcb != 255) {
- rx_frame_.header.PCB.val = *pcb;
+ rx_frame_.header.PCB = *pcb;
rx_frame_.header.LEN = 2;
rx_frame_.INF[0] = 'A';
rx_frame_.INF[1] = 'B';
rx_frame_.INF[2] = teq1_compute_LRC(&rx_frame_);
- EXPECT_EQ(0, teq1_frame_error_check(&state_, &tx_frame_, &rx_frame_)) << teq1_pcb_to_name(rx_frame_.header.PCB.val);
+ EXPECT_EQ(0, teq1_frame_error_check(&state_, &tx_frame_, &rx_frame_)) << teq1_pcb_to_name(rx_frame_.header.PCB);
rx_frame_.INF[2] = teq1_compute_LRC(&rx_frame_) - 1;
// Reset so we check the LRC error instead of a wrong seq.
state_.card_state->seq.card = !state_.card_state->seq.card;
@@ -94,8 +93,9 @@
tx_data_(INF_LEN, 'A'),
rx_data_(INF_LEN, 'B'),
card_state_({ .seq = { .card = 1, .interface = 1, }, }),
- state_(TEQ1_INIT_STATE(tx_data_.data(), tx_data_.size(),
- rx_data_.data(), rx_data_.size(), &card_state_)) {
+ state_(TEQ1_INIT_STATE(tx_data_.data(), static_cast<uint32_t>(tx_data_.size()),
+ rx_data_.data(), static_cast<uint32_t>(rx_data_.size()),
+ &card_state_)) {
memset(&tx_frame_, 0, sizeof(struct Teq1Frame));
memset(&tx_next_, 0, sizeof(struct Teq1Frame));
memset(&rx_frame_, 0, sizeof(struct Teq1Frame));
@@ -122,12 +122,12 @@
class Teq1CompleteTest : public Teq1ErrorFreeTest {
public:
virtual void SetUp() {
- tx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ tx_frame_.header.PCB = TEQ1_I(0, 0);
teq1_fill_info_block(&state_, &tx_frame_);
// Check that the tx_data was fully consumed.
EXPECT_EQ(0UL, state_.app_data.tx_len);
- rx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ rx_frame_.header.PCB = TEQ1_I(0, 0);
rx_frame_.header.LEN = INF_LEN;
ASSERT_EQ(static_cast<unsigned long>(INF_LEN), tx_data_.size()); // Catch fixture changes.
// Supply TX data and make sure it overwrites RX data on consumption.
@@ -137,15 +137,15 @@
virtual void RunRules() {
teq1_trace_header();
- teq1_trace_transmit(tx_frame_.header.PCB.val, tx_frame_.header.LEN);
- teq1_trace_receive(rx_frame_.header.PCB.val, rx_frame_.header.LEN);
+ teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
+ teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
EXPECT_EQ(0, state_.errors);
EXPECT_EQ(NULL, state_.last_error_message)
<< "Last error: " << state_.last_error_message;
- EXPECT_EQ(0, tx_next_.header.PCB.val)
- << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB.val);
+ EXPECT_EQ(0, tx_next_.header.PCB)
+ << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
EXPECT_EQ(kRuleResultComplete, result)
<< "Actual result name: " << teq1_rule_result_to_name(result);
}
@@ -171,8 +171,8 @@
};
TEST_F(Teq1CompleteTest, I10_I10_data) {
- tx_frame_.header.PCB.val = TEQ1_I(1, 0);
- rx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ tx_frame_.header.PCB = TEQ1_I(1, 0);
+ rx_frame_.header.PCB = TEQ1_I(0, 0);
rx_frame_.INF[INF_LEN] = teq1_compute_LRC(&rx_frame_);
RunRules();
// Ensure that the rx_frame data was copied out to rx_data.
@@ -184,28 +184,28 @@
// Note, IFS is not tested as it is not supported on current hardware.
TEST_F(Teq1ErrorFreeTest, I00_WTX0_WTX1_data) {
- tx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ tx_frame_.header.PCB = TEQ1_I(0, 0);
teq1_fill_info_block(&state_, &tx_frame_);
// Check that the tx_data was fully consumed.
EXPECT_EQ(0UL, state_.app_data.tx_len);
- rx_frame_.header.PCB.val = TEQ1_S_WTX(0);
+ rx_frame_.header.PCB = TEQ1_S_WTX(0);
rx_frame_.header.LEN = 1;
rx_frame_.INF[0] = 2; /* Wait x 2 */
rx_frame_.INF[1] = teq1_compute_LRC(&rx_frame_);
teq1_trace_header();
- teq1_trace_transmit(tx_frame_.header.PCB.val, tx_frame_.header.LEN);
- teq1_trace_receive(rx_frame_.header.PCB.val, rx_frame_.header.LEN);
+ teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
+ teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
- teq1_trace_transmit(tx_next_.header.PCB.val, tx_next_.header.LEN);
+ teq1_trace_transmit(tx_next_.header.PCB, tx_next_.header.LEN);
EXPECT_EQ(0, state_.errors);
EXPECT_EQ(NULL, state_.last_error_message)
<< "Last error: " << state_.last_error_message;
- EXPECT_EQ(TEQ1_S_WTX(1), tx_next_.header.PCB.val)
- << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB.val);
+ EXPECT_EQ(TEQ1_S_WTX(1), tx_next_.header.PCB)
+ << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
EXPECT_EQ(state_.wait_mult, 2);
EXPECT_EQ(state_.wait_mult, rx_frame_.INF[0]);
// Ensure the next call will use the original TX frame.
@@ -221,9 +221,9 @@
state_.app_data.tx_buf = tx_data_.data();
teq1_fill_info_block(&state_, &tx_frame_);
// Ensure More bit was set.
- EXPECT_EQ(1, tx_frame_.header.PCB.I.more_data);
+ EXPECT_EQ(1, bs_get(PCB.I.more_data, tx_frame_.header.PCB));
// Check that the tx_data was fully consumed.
- EXPECT_EQ(static_cast<size_t>(oversized_data_len_ - INF_LEN),
+ EXPECT_EQ(static_cast<uint32_t>(oversized_data_len_ - INF_LEN),
state_.app_data.tx_len);
// No one is checking the TX LRC since there is no card present.
@@ -231,11 +231,11 @@
rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
teq1_trace_header();
- teq1_trace_transmit(tx_frame_.header.PCB.val, tx_frame_.header.LEN);
- teq1_trace_receive(rx_frame_.header.PCB.val, rx_frame_.header.LEN);
+ teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
+ teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
- teq1_trace_transmit(tx_next_.header.PCB.val, tx_next_.header.LEN);
+ teq1_trace_transmit(tx_next_.header.PCB, tx_next_.header.LEN);
EXPECT_EQ(0, state_.errors);
EXPECT_EQ(NULL, state_.last_error_message)
<< "Last error: " << state_.last_error_message;
@@ -243,7 +243,7 @@
<< "Actual result name: " << teq1_rule_result_to_name(result);
// Check that the tx_buf was drained already for the next frame.
// ...
- EXPECT_EQ(static_cast<size_t>(oversized_data_len_ - (2 * INF_LEN)),
+ EXPECT_EQ(static_cast<uint32_t>(oversized_data_len_ - (2 * INF_LEN)),
state_.app_data.tx_len);
// Belt and suspenders: make sure no RX buf was used.
EXPECT_EQ(rx_data_.size(), state_.app_data.rx_len);
@@ -253,29 +253,29 @@
TEST_F(Teq1ErrorFreeChainingTest, I01_R1_I11_chaining) {
oversized_data_len_ = INF_LEN * 3;
- tx_frame_.header.PCB.val = TEQ1_I(0, 0);
- rx_frame_.header.PCB.val = TEQ1_R(1, 0, 0);
+ tx_frame_.header.PCB = TEQ1_I(0, 0);
+ rx_frame_.header.PCB = TEQ1_R(1, 0, 0);
RunRules();
- EXPECT_EQ(TEQ1_I(1, 1), tx_next_.header.PCB.val)
- << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB.val);
+ EXPECT_EQ(TEQ1_I(1, 1), tx_next_.header.PCB)
+ << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
};
TEST_F(Teq1ErrorFreeChainingTest, I11_R0_I01_chaining) {
oversized_data_len_ = INF_LEN * 3;
- tx_frame_.header.PCB.val = TEQ1_I(1, 0);
- rx_frame_.header.PCB.val = TEQ1_R(0, 0, 0);
+ tx_frame_.header.PCB = TEQ1_I(1, 0);
+ rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
RunRules();
- EXPECT_EQ(TEQ1_I(0, 1), tx_next_.header.PCB.val)
- << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB.val);
+ EXPECT_EQ(TEQ1_I(0, 1), tx_next_.header.PCB)
+ << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
};
TEST_F(Teq1ErrorFreeChainingTest, I11_R0_I00_chaining) {
oversized_data_len_ = INF_LEN * 2; // Exactly 2 frames worth.
- tx_frame_.header.PCB.val = TEQ1_I(1, 0);
- rx_frame_.header.PCB.val = TEQ1_R(0, 0, 0);
+ tx_frame_.header.PCB = TEQ1_I(1, 0);
+ rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
RunRules();
- EXPECT_EQ(TEQ1_I(0, 0), tx_next_.header.PCB.val)
- << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB.val);
+ EXPECT_EQ(TEQ1_I(0, 0), tx_next_.header.PCB)
+ << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
};
//
@@ -290,19 +290,19 @@
state_.app_data.rx_len = 0;
state_.app_data.tx_len = 0;
- tx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ tx_frame_.header.PCB = TEQ1_I(0, 0);
teq1_fill_info_block(&state_, &tx_frame_);
// No one is checking the TX LRC since there is no card present.
// Assume the card may not even set the error bit.
rx_frame_.header.LEN = 0;
- rx_frame_.header.PCB.val = TEQ1_R(0, 0, 0);
+ rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
}
virtual void TearDown() {
teq1_trace_header();
- teq1_trace_transmit(tx_frame_.header.PCB.val, tx_frame_.header.LEN);
- teq1_trace_receive(rx_frame_.header.PCB.val, rx_frame_.header.LEN);
+ teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
+ teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
// Not counted as an error as it was on the card-side.
@@ -315,22 +315,22 @@
};
TEST_F(Teq1Retransmit, I00_R000_I00) {
- rx_frame_.header.PCB.val = TEQ1_R(0, 0, 0);
+ rx_frame_.header.PCB = TEQ1_R(0, 0, 0);
rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
};
TEST_F(Teq1Retransmit, I00_R001_I00) {
- rx_frame_.header.PCB.val = TEQ1_R(0, 0, 1);
+ rx_frame_.header.PCB = TEQ1_R(0, 0, 1);
rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
};
TEST_F(Teq1Retransmit, I00_R010_I00) {
- rx_frame_.header.PCB.val = TEQ1_R(0, 1, 0);
+ rx_frame_.header.PCB = TEQ1_R(0, 1, 0);
rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
};
TEST_F(Teq1Retransmit, I00_R011_I00) {
- rx_frame_.header.PCB.val = TEQ1_R(0, 1, 1);
+ rx_frame_.header.PCB = TEQ1_R(0, 1, 1);
rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_);
}
@@ -339,25 +339,25 @@
state_.app_data.rx_len = 0;
state_.app_data.tx_len = 0;
- tx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ tx_frame_.header.PCB = TEQ1_I(0, 0);
teq1_fill_info_block(&state_, &tx_frame_);
// No one is checking the TX LRC since there is no card present.
- rx_frame_.header.PCB.val = TEQ1_I(0, 0);
+ rx_frame_.header.PCB = TEQ1_I(0, 0);
rx_frame_.header.LEN = 0;
rx_frame_.INF[0] = teq1_compute_LRC(&rx_frame_) - 1;
teq1_trace_header();
- teq1_trace_transmit(tx_frame_.header.PCB.val, tx_frame_.header.LEN);
- teq1_trace_receive(rx_frame_.header.PCB.val, rx_frame_.header.LEN);
+ teq1_trace_transmit(tx_frame_.header.PCB, tx_frame_.header.LEN);
+ teq1_trace_receive(rx_frame_.header.PCB, rx_frame_.header.LEN);
enum RuleResult result = teq1_rules(&state_, &tx_frame_, &rx_frame_, &tx_next_);
EXPECT_EQ(1, state_.errors);
const char *kNull = NULL;
EXPECT_NE(kNull, state_.last_error_message);
EXPECT_STREQ("Invalid frame received", state_.last_error_message);
- EXPECT_EQ(TEQ1_R(0, 0, 1), tx_next_.header.PCB.val)
- << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB.val);
+ EXPECT_EQ(TEQ1_R(0, 0, 1), tx_next_.header.PCB)
+ << "Actual next TX: " << teq1_pcb_to_name(tx_next_.header.PCB);
EXPECT_EQ(kRuleResultSingleShot, result)
<< "Actual result name: " << teq1_rule_result_to_name(result);
};