+struct fr_buff {
+ unsigned int frame_len; /* length of frame */
+ unsigned int hdr_len; /* length of header within frame */
+ unsigned char data[RFID_MAX_FRAMELEN];
+};
+
+#define frb_payload(x) (x.data + x.hdr_len)
+
+
+/* RFID transceive buffer. */
+struct rfid_xcvb {
+ struct rfix_xcvb *next; /* next in queue of buffers */
+
+ u_int64_t timeout; /* timeout to wait for reply */
+ struct fr_buff tx;
+ struct fr_buff rx;
+
+ //struct rfid_protocol_handle *h; /* connection to which we belong */
+};
+
+struct tcl_tx_context {
+ const unsigned char *tx;
+ unsigned char *rx;
+ const unsigned char *next_tx_byte;
+ unsigned char *next_rx_byte;
+ unsigned int rx_len;
+ unsigned int tx_len;
+ struct rfid_protocol_handle *h;
+};
+
+#define tcl_ctx_todo(ctx) (ctx->tx_len - (ctx->next_tx_byte - ctx->tx))
+
+static int
+tcl_refill_xcvb(struct rfid_xcvb *xcvb, struct tcl_tx_context *ctx)
+{
+ struct tcl_handle *th = &ctx->h->priv.tcl;
+
+ if (ctx->next_tx_byte >= ctx->tx + ctx->tx_len) {
+ DEBUGP("tyring to refill tx xcvb but no data left!\n");
+ return -1;
+ }
+
+ if (tcl_build_prologue_i(th, xcvb->tx.data,
+ &xcvb->tx.hdr_len) < 0)
+ return -1;
+
+ if (tcl_ctx_todo(ctx) > th->fsc - xcvb->tx.hdr_len)
+ xcvb->tx.frame_len = max_net_tx_framesize(th);
+ else
+ xcvb->tx.frame_len = tcl_ctx_todo(ctx);
+
+ memcpy(frb_payload(xcvb->tx), ctx->next_tx_byte,
+ xcvb->tx.frame_len);
+
+ ctx->next_tx_byte += xcvb->tx.frame_len;
+
+ /* check whether we need to set the chaining bit */
+ if (ctx->next_tx_byte < ctx->tx + ctx->tx_len)
+ xcvb->tx.data[0] |= 0x10;
+
+ /* add hdr_len after copying the net payload */
+ xcvb->tx.frame_len += xcvb->tx.hdr_len;
+
+ xcvb->timeout = th->fwt;
+
+ return 0;
+}
+
+static void fill_xcvb_wtxm(struct tcl_handle *th, struct rfid_xcvb *xcvb,
+ unsigned char inf)
+{
+ /* Acknowledge WTXM */
+ tcl_build_prologue_s(th, xcvb->tx.data, &xcvb->tx.hdr_len);
+ /* set two bits that make this block a wtx */
+ xcvb->tx.data[0] |= 0x30;
+ xcvb->tx.data[xcvb->tx.hdr_len] = inf;
+ xcvb->tx.frame_len = xcvb->tx.hdr_len+1;
+ xcvb->timeout = th->fwt * inf;
+}
+
+static int check_cid(struct tcl_handle *th, struct rfid_xcvb *xcvb)
+{
+ if (xcvb->rx.data[0] & TCL_PCB_CID_FOLLOWING) {
+ if (xcvb->rx.data[1] != th->cid) {
+ DEBUGP("CID %u is not valid, we expected %u\n",
+ xcvb->rx.data[1], th->cid);
+ return 0;
+ }
+ }
+ return 1;
+}