📄 sci_prot.c
字号:
} } } index++; } } if (rc == SCI_ERROR_OK) { for (i = 0; i < index; i++) { if (request[i] != response[i]) { rc = SCI_ERROR_FAIL; } } if (rc == SCI_ERROR_OK) { if (ioctl (fd[sc_id], IOCTL_GET_PARAMETERS, &sci_parameters) == 0) { current_T = sci_parameters.T; current_f = sci_parameters.f; current_ETU = sci_parameters.ETU; Fi = Fi_TABLE[F]; Di = Di_TABLE[D]; f = f_TABLE[F]; if (f != 0) { sci_parameters.f = f; } if ((Fi != 0) && (Di != 0)) { sci_parameters.ETU = (Fi / Di); } sci_parameters.T = T; if (ioctl (fd[sc_id], IOCTL_SET_PARAMETERS, &sci_parameters) == 0) { rc = SCI_ERROR_OK; sc_cb[sc_id].sc_parameters.T = T; sc_cb[sc_id].sc_parameters.F = F; sc_cb[sc_id].sc_parameters.D = D; } else { sci_parameters.T = current_T; sci_parameters.f = current_f; sci_parameters.ETU = current_ETU; if (ioctl (fd[sc_id], IOCTL_SET_PARAMETERS, &sci_parameters) == 0) { rc = SCI_ERROR_OK; } else { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } } } else { rc = SCI_ERROR_FAIL; } } } } } else { rc = SCI_ERROR_CARD_NOT_ACTIVATED; } } else { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } return (rc);}/****************************************************************************** Name sc_get_ifsd**** Purpose: get the current IFSD setting**** Parameters: sc_id: zero-based number to identify Smart Card controller** ifsd: output pointer to buffer which will hold IFSD value**** Returns: SCI_ERROR_OK: If IFSD was successfully retrieved** other error code if a failure occurs****************************************************************************/SCI_ERROR sc_get_ifsd(unsigned long sc_id, unsigned char *ifsd){ SCI_ERROR rc = SCI_ERROR_OK; unsigned long card_actived; if ((sc_id < SCI_NUMBER_OF_CONTROLLERS) && (ifsd != 0)) { ioctl(fd[sc_id], IOCTL_GET_IS_CARD_ACTIVATED, &card_actived); if (card_actived == 1) { (*ifsd) = (sc_cb[sc_id].proposed_IFSD); } else { rc = SCI_ERROR_CARD_NOT_ACTIVATED; } } else { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } return (rc);}/****************************************************************************** Name sc_set_ifsd**** Purpose: set the current IFSD setting**** Parameters: sc_id: zero-based number to identify Smart Card controller** ifsd: new IFSD value**** Returns: SCI_ERROR_OK: If IFSD was set successfully** other error code if a failure occurs****************************************************************************/SCI_ERROR sc_set_ifsd(unsigned long sc_id, unsigned char ifsd){ SCI_ERROR rc = SCI_ERROR_OK; unsigned long card_actived; if ((sc_id < SCI_NUMBER_OF_CONTROLLERS) && (ifsd >= SC_MIN_IFSD) && (ifsd <= SC_MAX_IFSD)) { ioctl(fd[sc_id], IOCTL_GET_IS_CARD_ACTIVATED, &card_actived); if (card_actived == 1) { sc_cb[sc_id].proposed_IFSD = ifsd; } else { rc = SCI_ERROR_CARD_NOT_ACTIVATED; } } else { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } return (rc);}/****************************************************************************** Name sc_apdu**** Purpose: Send a command APDU (Application Protocol Data Unit) and** receive the response APDU (see ISO/IEC 7816-4:1995(E),** section 5.3,pages 7-9).**** Parameters: sc_id: zero-based Smart Card identifier** p_capdu: (input) pointer to the command APDU buffer** p_rapdu: (output) pointer to the response APDU buffer** p_length:(input) pointer the length of the command APDU** (output) pointer the length of the response APDU**** Returns: SCI_ERROR_OK: if successful** other error code if a failure occurs****************************************************************************/SCI_ERROR sc_apdu(unsigned long sc_id, unsigned char *p_capdu, unsigned char *p_rapdu, unsigned long *p_length){ SCI_ERROR rc = SCI_ERROR_OK; /* return code */ unsigned char *p_body = 0; /* pointer to the body */ unsigned char *p_data = 0; /* pointer to the data */ unsigned long L = 0; /* length of the body */ unsigned short Lc = 0; /* length of command data */ unsigned long Le = 0; /* length of expected data */ unsigned char SW1 = 0; /* first byte of end sequence */ unsigned char SW2 = 0; /* second byte of end sequence */ unsigned char t0_header[5]; /* t0 header */ int i; unsigned long card_present; if ((sc_id < SCI_NUMBER_OF_CONTROLLERS) && (p_capdu != 0) && (p_rapdu != 0) && (p_length != 0) && (*p_length != 0)) { ioctl(fd[sc_id], IOCTL_GET_IS_CARD_PRESENT, &card_present); if (card_present == 1) { /* determine L */ L = (*p_length) - 4; /* identify body */ p_body = p_capdu + 4; /* parse body into relevant fields */ if ((rc = process_body(p_body, L, &p_data, &Lc, &Le)) == SCI_ERROR_OK) { /* transmit/receive APDU data based on transmission protocol */ if (sc_cb[sc_id].sc_parameters.T == 0) { memcpy((void *) t0_header, (const void *) p_capdu, 4); if (Lc == 0) { /* incoming data command */ if (Le == 0) { t0_header[4] = 0; *p_length = 2; } else { if (Le < 256) { t0_header[4] = (unsigned char) Le; *p_length = Le + 2; } else { t0_header[4] = 0; *p_length = 258; } } rc = sc_t0_command(sc_id, t0_header, p_rapdu, (p_rapdu + Le), 1); /* ensure SW1 and SW2 do not indicate an aborted process */ check_incoming_data(p_rapdu, p_length, *(p_rapdu + Le), *(p_rapdu + Le + 1)); } else if (Lc < 256) { /* outgoing data command, ignore Le for the moment */ t0_header[4] = (unsigned char) Lc; /* no incoming data, so p_rapdu will contain only the end sequence */ if ((rc = sc_t0_command(sc_id, t0_header, p_data, p_rapdu,0)) == SCI_ERROR_OK) { if (Le == 0) { *p_length = 2; } else { /* expect to issue a GET_RESPONSE command */ SW1 = p_rapdu[0]; SW2 = p_rapdu[1]; if ((SW1 == 0x61) || ((SW1 == 0x90) && (SW2 == 0x00))) { /* must issue a GET RESPONSE command */ if ((SW1 == 0x61) && (SW2 < Le)) { /* Lx=SW2, change Le to min(Le,Lx) */ Le = (unsigned long) SW2; } /* change INS to GET RESPONSE command */ t0_header[1] = 0xC0; /* change P3 to new Le */ t0_header[4] = (unsigned char) Le; *p_length = Le + 2; rc = sc_t0_command(sc_id, t0_header, p_rapdu, (p_rapdu + Le), 1); /* ensure SW1 and SW2 do not indicate an aborted process */ check_incoming_data(p_rapdu, p_length, *(p_rapdu+Le), *(p_rapdu+Le+1)); } else { /* GET_RESPONSE command not indicated-an error occurred */ *p_length = 2; } } } } else { *p_rapdu = 0x67; *p_length = 2; } } else if (sc_cb[sc_id].sc_parameters.T == 1) { rc = sc_t1_command(sc_id, p_capdu, p_rapdu, p_length); } else { /* unsupported protocol */ rc = SCI_ERROR_FAIL; printf("unsupported protocol"); } } } else { rc = SCI_ERROR_CARD_NOT_PRESENT; } } else { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } return (rc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -