📄 sci_prot.c
字号:
/****************************************************************************** Function: sc_get_parameters**** Purpose: Retrieve the current Smart Card ATR parameters.**** Parameters: sc_id: zero-based number to identify smart card controller** p_sci_parameters: output pointer to Smart Card ATR parameters**** Returns: SCI_ERROR_OK: if successful** other error code if a failure occurs*****************************************************************************/SCI_ERROR sc_get_parameters(unsigned long sc_id, SC_PARAMETERS * p_sc_parameters){ SCI_ERROR rc = SCI_ERROR_OK; unsigned long card_actived; if ((p_sc_parameters != 0) && (sc_id < SCI_NUMBER_OF_CONTROLLERS)) { ioctl(fd[sc_id], IOCTL_GET_IS_CARD_ACTIVATED, &card_actived); if (card_actived == 1) { p_sc_parameters->T = sc_cb[sc_id].sc_parameters.T; p_sc_parameters->maskT = sc_cb[sc_id].sc_parameters.maskT; p_sc_parameters->F = sc_cb[sc_id].sc_parameters.F; p_sc_parameters->D = sc_cb[sc_id].sc_parameters.D; p_sc_parameters->FI = sc_cb[sc_id].sc_parameters.FI; p_sc_parameters->DI = sc_cb[sc_id].sc_parameters.DI; p_sc_parameters->II = sc_cb[sc_id].sc_parameters.II; p_sc_parameters->PI1 = sc_cb[sc_id].sc_parameters.PI1; p_sc_parameters->PI2 = sc_cb[sc_id].sc_parameters.PI2; p_sc_parameters->WI = sc_cb[sc_id].sc_parameters.WI; p_sc_parameters->XI = sc_cb[sc_id].sc_parameters.XI; p_sc_parameters->UI = sc_cb[sc_id].sc_parameters.UI; p_sc_parameters->N = sc_cb[sc_id].sc_parameters.N; p_sc_parameters->CWI = sc_cb[sc_id].sc_parameters.CWI; p_sc_parameters->BWI = sc_cb[sc_id].sc_parameters.BWI; p_sc_parameters->IFSC = sc_cb[sc_id].sc_parameters.IFSC; p_sc_parameters->check = sc_cb[sc_id].sc_parameters.check; } else { rc = SCI_ERROR_CARD_NOT_ACTIVATED; } } else { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } return (rc);}/****************************************************************************** Function: sc_get_atr**** Purpose: Retrieve the ATR. **** Parameters: sc_id: zero-based number to identify smart card controller** ATR: output pointer to ATR buffer** atr_size: output pointer to ATR size** historical_offset: output pointer to historical offset** historical_size: output pointer to historical size**** Returns: SCI_ERROR_OK: if successful** other error code if a failure occurs*****************************************************************************/SCI_ERROR sc_get_atr(unsigned long sc_id, unsigned char *ATR, unsigned char *atr_size, unsigned char *historical_offset, unsigned char *historical_size){ SCI_ERROR rc = SCI_ERROR_OK; int i = 0; unsigned long card_actived; if ((sc_id < SCI_NUMBER_OF_CONTROLLERS) && (ATR != 0) && (atr_size != 0) && (historical_offset != 0) && (historical_size != 0)) { ioctl(fd[sc_id], IOCTL_GET_IS_CARD_ACTIVATED, &card_actived); if (card_actived == 1) { *atr_size = sc_cb[sc_id].atr_size; if (sc_cb[sc_id].atr_size > 0) { for (i = 0; i < (sc_cb[sc_id].atr_size); i++) { ATR[i] = (sc_cb[sc_id].ATR[i]); } *historical_offset = (unsigned char) (sc_cb[sc_id].p_historical - sc_cb[sc_id].ATR); *historical_size = sc_cb[sc_id].historical_size; } else { rc = SCI_ERROR_NO_ATR; } } else { rc = SCI_ERROR_CARD_NOT_ACTIVATED; } } else { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } return (rc);}/****************************************************************************** Name process_body**** Purpose: Parse ADPU body into fields.**** Parameters: p_body: (input) pointer to the command APDU body** L: (input) length of the command APDU body** pp_data:(output) pointer to the data field pointer** p_Lc: (output) pointer to the data field length** p_Le: (output) pointer to the expected data length**** Returns: SCI_ERROR_OK: if successful** SCI_ERROR_FAIL: if one or more fields are invalid****************************************************************************/static SCI_ERROR process_body(unsigned char *p_body, unsigned long L, unsigned char **pp_data, unsigned short *p_Lc, unsigned long *p_Le){ SCI_ERROR rc = SCI_ERROR_OK; /* return code */ unsigned short B2B3 = 0; /* length of expected data */ /* determine Lc and Le */ if (L == 0) { /* case 1 */ *p_Lc = 0; *pp_data = 0; *p_Le = 0; } else if (L == 1) { /* case 2S */ *p_Lc = 0; *pp_data = 0; *p_Le = (unsigned long) p_body[0]; if (*p_Le == 0) { *p_Le = 256; } } else if ((L == (unsigned long) (1 + p_body[0])) && (p_body[0] != 0)) { /* case 3S */ *p_Lc = (unsigned short) p_body[0]; *pp_data = p_body + 1; *p_Le = 0; } else if ((L == (unsigned long) (2 + p_body[0])) && (p_body[0] != 0)) { /* case 4S */ *p_Lc = (unsigned short) p_body[0]; *pp_data = p_body + 1; *p_Le = (unsigned long) p_body[L - 1]; if (*p_Le == 0) { *p_Le = 256; } } else if ((L == 3) && (p_body[0] == 0)) { /* case 2E */ *p_Lc = 0; *pp_data = 0; *p_Le = (*(unsigned long *) (p_body + L - 2)); if (*p_Le == 0) { *p_Le = 65536; } } else { B2B3 = *(unsigned short *) (p_body + 1); if ((p_body[0] == 0) && (B2B3 != 0)) { if (L == (unsigned long) (3 + B2B3)) { /* case 3E */ *p_Lc = B2B3; *pp_data = p_body + 3; *p_Le = 0; } else if (L == (unsigned long) (5 + B2B3)) { /* case 4E */ *p_Lc = B2B3; *pp_data = p_body + 3; *p_Le = (*(unsigned long *) (p_body + L - 2)); if (*p_Le == 0) { *p_Le = 65536; } } else { rc = SCI_ERROR_FAIL; } } else { rc = SCI_ERROR_FAIL; } } return (rc);}/****************************************************************************** Name sc_t0_command**** Purpose: Perform a protocol T=0 command transaction.** (see ISO/IEC 7816-3:1997(E),section 8,pages 15-16).**** Parameters: p_header: the 5-byte command header input buffer** p_body: the data field, input/output buffer** p_end_sequence: the SW1 and SW2 values, output buffer** direction: direction of the data transfer-** 0: write** 1: read**** Returns: SCI_ERROR_OK: if successful** other error code if a failure occurs****************************************************************************/static SCI_ERROR sc_t0_command(unsigned long sc_id, unsigned char *p_header, unsigned char *p_body, unsigned char *p_end_sequence, unsigned long direction){ ssize_t bytes_rec = 0; /* bytes received */ unsigned long bytes_left = 0; /* bytes left to transmit */ unsigned long done = 0; /* command complete flag */ unsigned long end = 0; /* end sequence flag */ unsigned char ins = 0; /* instruction byte used for acknowledgment */ unsigned char current = 0; /* current procedure byte */ SCI_ERROR rc = SCI_ERROR_OK; /* return code */ int i; ins = p_header[1]; bytes_left = p_header[4]; if(bytes_left == 0) { bytes_left = 256; } /* send the command */ if ((rc = write(fd[sc_id], p_header, 5)) > 0) { rc = SCI_ERROR_OK; while ((done == 0) && (rc == SCI_ERROR_OK)) { if(direction == 1) { if(bytes_rec == 2) { current = sc_cb[sc_id].temp_buf[1]; } else { /* read all expected data-ack(1), body(bytes_left), and end sequence(2) */ if((bytes_rec = read(fd[sc_id], &sc_cb[sc_id].temp_buf, bytes_left+3)) > 0) { rc = SCI_ERROR_OK; } else { rc = bytes_rec; } if((rc == SCI_ERROR_OK) || (rc == SCI_ERROR_WWT_TIMEOUT)) { if(bytes_rec == (bytes_left + 3)) { /* all expect data received */ memcpy(p_body, sc_cb[sc_id].temp_buf+1, bytes_left); p_end_sequence[0] = sc_cb[sc_id].temp_buf[bytes_left + 1]; current = sc_cb[sc_id].temp_buf[bytes_left + 2]; end = 1; } else if((bytes_rec == 1) || (bytes_rec == 2)) { /* just a procedure byte or an end sequence was received */ current = sc_cb[sc_id].temp_buf[0]; if(bytes_rec == 2) { /* an end sequence was received, so clear any SCI_ERROR_WWT_TIMEOUT */ rc = SCI_ERROR_OK; } } else { rc=SCI_ERROR_FAIL; } } } } else { /* read 1 procedure byte */ if ((bytes_rec = read(fd[sc_id], ¤t, 1)) > 0) { rc = SCI_ERROR_OK; } else { rc = bytes_rec; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -