int32_t Protocol_T1_Command (struct s_reader *reader, unsigned char * command, uint16_t command_len, unsigned char * rsp, uint16_t * lr) { T1_Block *block; BYTE *buffer, rsp_type, bytes, nr, wtx; uint16_t counter; int32_t ret; bool more; if (command[1] == T1_BLOCK_S_IFS_REQ) { BYTE inf = command[3]; /* Create an IFS request S-Block */ block = T1_Block_NewSBlock (T1_BLOCK_S_IFS_REQ, 1, &inf); cs_debug_mask (D_IFD, "Protocol: Sending block S(IFS request, %d)", inf); /* Send IFSD request */ ret = Protocol_T1_SendBlock (reader, block); /* Receive a block */ ret = Protocol_T1_ReceiveBlock (reader, &block); if (ret == OK) { rsp_type = T1_Block_GetType (block); /* Positive IFS Response S-Block received */ if (rsp_type == T1_BLOCK_S_IFS_RES) { /* Update IFSD value */ inf = (*T1_Block_GetInf (block)); cs_debug_mask (D_IFD, "Protocol: Received block S(IFS response, %d)", inf); } T1_Block_Delete (block); } return ret; } if (command[1] == T1_BLOCK_S_RESYNCH_REQ) { /* Create an Resynch request S-Block */ block = T1_Block_NewSBlock (T1_BLOCK_S_RESYNCH_REQ, 0, NULL); cs_debug_mask (D_IFD, "Protocol: Sending block S(RESYNCH request)"); /* Send request */ ret = Protocol_T1_SendBlock (reader, block); /* Receive a block */ ret = Protocol_T1_ReceiveBlock (reader, &block); if (ret == OK) { rsp_type = T1_Block_GetType (block); /* Positive IFS Response S-Block received */ if (rsp_type == T1_BLOCK_S_RESYNCH_RES) { cs_debug_mask (D_IFD, "Protocol: Received block S(RESYNCH response)"); reader->ns = 0; } T1_Block_Delete (block); } return ret; } /* Calculate the number of bytes to send */ counter = 0; bytes = MIN (command_len, reader->ifsc); /* See if chaining is needed */ more = (command_len > reader->ifsc); /* Increment ns */ reader->ns = (reader->ns == 1) ? 0:1; //toggle from 0 to 1 and back /* Create an I-Block */ block = T1_Block_NewIBlock (bytes, command, reader->ns, more); cs_debug_mask (D_IFD, "Sending block I(%d,%d)", reader->ns, more); /* Send a block */ call (Protocol_T1_SendBlock (reader, block)); while (more) { /* Receive a block */ call (Protocol_T1_ReceiveBlock (reader, &block)); rsp_type = T1_Block_GetType (block); /* Positive ACK R-Block received */ if (rsp_type == T1_BLOCK_R_OK) { cs_debug_mask (D_IFD, "Protocol: Received block R(%d)", T1_Block_GetNR (block)); /* Delete block */ T1_Block_Delete (block); /* Increment ns */ reader->ns = (reader->ns == 1) ? 0:1; //toggle from 0 to 1 and back /* Calculate the number of bytes to send */ counter += bytes; bytes = MIN (command_len - counter, reader->ifsc); /* See if chaining is needed */ more = (command_len - counter > reader->ifsc); /* Create an I-Block */ block = T1_Block_NewIBlock (bytes, command + counter, reader->ns, more); cs_debug_mask (D_IFD, "Protocol: Sending block I(%d,%d)", reader->ns, more); /* Send a block */ call (Protocol_T1_SendBlock (reader, block)); } else { /* Delete block */ T1_Block_Delete (block); cs_debug_mask(D_TRACE, "ERROR T1 Command %02X not implemented in SendBlock", rsp_type); return ERROR; } } /* Reset counter */ ret = OK; buffer = NULL; counter = 0; more = TRUE; wtx = 0; while ((ret == OK) && more) { if (wtx > 1) ICC_Async_SetTimings (reader, wtx * reader->BWT); /* Receive a block */ ret = Protocol_T1_ReceiveBlock (reader, &block); if (wtx > 1) { ICC_Async_SetTimings (reader, reader->BWT); wtx = 0; } if (ret == OK) { rsp_type = T1_Block_GetType (block); if (rsp_type == T1_BLOCK_I) { cs_debug_mask (D_IFD, "Protocol: Received block I(%d,%d)", T1_Block_GetNS(block), T1_Block_GetMore (block)); /* Calculate nr */ nr = (T1_Block_GetNS (block) + 1) % 2; /* Save inf field */ bytes = T1_Block_GetLen (block); buffer = (BYTE *) realloc(buffer, counter + bytes); memcpy (buffer + counter, T1_Block_GetInf (block), bytes); counter += bytes; /* See if chaining is requested */ more = T1_Block_GetMore (block); /* Delete block */ T1_Block_Delete (block); if (more) { /* Create an R-Block */ block = T1_Block_NewRBlock (T1_BLOCK_R_OK, nr); cs_debug_mask (D_IFD, "Protocol: Sending block R(%d)", nr); /* Send R-Block */ ret = Protocol_T1_SendBlock (reader, block); } } /* WTX Request S-Block received */ else if (rsp_type == T1_BLOCK_S_WTX_REQ) { /* Get wtx multiplier */ wtx = (*T1_Block_GetInf (block)); cs_debug_mask (D_IFD, "Protocol: Received block S(WTX request, %d)", wtx); /* Delete block */ T1_Block_Delete (block); /* Create an WTX response S-Block */ block = T1_Block_NewSBlock (T1_BLOCK_S_WTX_RES, 1, &wtx); cs_debug_mask (D_IFD, "Protocol: Sending block S(WTX response, %d)", wtx); /* Send WTX response */ ret = Protocol_T1_SendBlock (reader, block); } else { cs_debug_mask(D_TRACE, "ERROR T1 Command %02X not implemented in Receive Block", rsp_type); ret = ERROR;//not implemented } } } if (ret == OK) { memcpy(rsp, buffer, counter); *lr = counter; } if (buffer != NULL) free (buffer); return ret; }
int32_t Protocol_T1_Command(struct s_reader *reader, unsigned char * command, uint16_t command_len, unsigned char * rsp, uint16_t * lr) { uint8_t block_data[T1_BLOCK_MAX_SIZE]; uint8_t rsp_type, bytes, nr, wtx; uint16_t counter; int32_t ret; bool more; uint32_t block_length = 0; if (command[1] == T1_BLOCK_S_IFS_REQ) { uint8_t inf = command[3]; /* Create an IFS request S-Block */ ICC_Async_SetTimings (reader, reader->CWT); // we are going to send: CWT timeout //cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time ret = T1_Block_SendSBlock(reader, block_data, T1_BLOCK_S_IFS_REQ, 1, &inf); rdr_debug_mask(reader, D_IFD, "Protocol: Sending block S(IFS request, %d)", inf); /* Receive a block */ ICC_Async_SetTimings(reader, reader->BWT); // we are going to receive so set Block Waiting Timeout! //cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type); if (ret == OK) { /* Positive IFS Response S-Block received */ if (rsp_type == T1_BLOCK_S_IFS_RES) { rdr_debug_mask(reader, D_IFD, "Protocol: Received block S(IFS response, %d)", block_data[3]); } } return ret; } else if (command[1] == T1_BLOCK_S_RESYNCH_REQ) { /* Create an Resynch request S-Block */ ICC_Async_SetTimings (reader, reader->CWT); // we are going to send: CWT timeout //cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time ret = T1_Block_SendSBlock(reader, block_data, T1_BLOCK_S_RESYNCH_REQ, 0, NULL); rdr_debug_mask(reader, D_IFD, "Protocol: Sending block S(RESYNCH request)"); /* Receive a block */ ICC_Async_SetTimings(reader, reader->BWT); // we are going to receive so set Block Waiting Timeout! //cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type); if (ret == OK) { /* Positive IFS Response S-Block received */ if (rsp_type == T1_BLOCK_S_RESYNCH_RES) { rdr_debug_mask(reader, D_IFD, "Protocol: Received block S(RESYNCH response)"); reader->ns = 0; } } return ret; } /* Calculate the number of bytes to send */ counter = 0; bytes = MIN (command_len, reader->ifsc); /* See if chaining is needed */ more = (command_len > reader->ifsc); /* Increment ns */ reader->ns = (reader->ns == 1) ? 0:1; //toggle from 0 to 1 and back /* Create an I-Block */ ICC_Async_SetTimings (reader, reader->CWT); // we are going to send: CWT timeout //cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time ret = T1_Block_SendIBlock(reader, block_data, bytes, command, reader->ns, more); rdr_debug_mask(reader, D_IFD, "Sending block I(%d,%d)", reader->ns, more); while ((ret == OK) && more) { /* Receive a block */ ICC_Async_SetTimings(reader, reader->BWT); // we are going to receive so set Block Waiting Timeout! //cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type); if (ret == OK){ /* Positive ACK R-Block received */ if (rsp_type == T1_BLOCK_R_OK) { rdr_debug_mask(reader, D_IFD, "Protocol: Received block R(%d)", T1_Block_GetNR(block_data)); /* Increment ns */ reader->ns = (reader->ns == 1) ? 0:1; //toggle from 0 to 1 and back /* Calculate the number of bytes to send */ counter += bytes; bytes = MIN (command_len - counter, reader->ifsc); /* See if chaining is needed */ more = (command_len - counter > reader->ifsc); /* Send an I-Block */ ICC_Async_SetTimings (reader, reader->CWT); // we are going to send: CWT timeout //cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time ret = T1_Block_SendIBlock(reader, block_data, bytes, command + counter, reader->ns, more); rdr_debug_mask(reader, D_IFD, "Protocol: Sending block I(%d,%d)", reader->ns, more); } else { rdr_debug_mask(reader, D_TRACE, "ERROR: T1 Command %02X not implemented", rsp_type); return ERROR; } } else { rdr_debug_mask(reader, D_TRACE, "ERROR: T1 Command returned error"); return ERROR; } } /* Reset counter */ counter = 0; more = 1; wtx = 1; while ((ret == OK) && more) { /* Receive a block */ ICC_Async_SetTimings(reader, wtx*reader->BWT); // we are going to receive so set Block Waiting Timeout! //cs_sleepus(reader->block_delay); // we were sending, now receiving so wait BGT time ret = Protocol_T1_ReceiveBlock(reader, block_data, &block_length, &rsp_type); wtx = 1; // reset WTX value since its only valid for first received I block if (ret == OK) { if (rsp_type == T1_BLOCK_I) { rdr_debug_mask (reader, D_IFD, "Protocol: Received block I(%d,%d)", T1_Block_GetNS(block_data), T1_Block_GetMore(block_data)); bytes = T1_Block_GetLen(block_data); /* Calculate nr */ nr = (T1_Block_GetNS(block_data) + 1) % 2; if (counter + bytes > T1_BLOCK_MAX_SIZE) return ERROR; memcpy(rsp+counter, block_data+3, bytes); counter += bytes; /* See if chaining is requested */ more = T1_Block_GetMore(block_data); if (more) { /* Send R-Block */ ICC_Async_SetTimings (reader, reader->CWT); // we are going to send: CWT timeout //cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time ret = T1_Block_SendRBlock(reader, block_data, T1_BLOCK_R_OK, nr); rdr_debug_mask(reader, D_IFD, "Protocol: Sending block R(%d)", nr); } } else if (rsp_type == T1_BLOCK_S_WTX_REQ) { /* WTX Request S-Block received */ /* Get wtx multiplier */ wtx = block_data[3]; rdr_debug_mask(reader, D_IFD, "Protocol: Received block S(WTX request, %d)", wtx); /* Send an WTX response S-Block */ ICC_Async_SetTimings (reader, reader->CWT); // we are going to send: CWT timeout //cs_sleepus(reader->block_delay); // we were receiving, now sending so wait BGT time ret = T1_Block_SendSBlock(reader, block_data, T1_BLOCK_S_WTX_RES, 1, &wtx); rdr_debug_mask(reader, D_IFD, "Protocol: Sending block S(WTX response, %d)", wtx); } else { rdr_debug_mask(reader, D_TRACE, "ERROR: T1 Command %02X not implemented in Receive Block", rsp_type); ret = ERROR; //not implemented } } } if (ret == OK) *lr = counter; return ret; }