FreeCalypso > hg > fc-sim-tools
diff libcommon/apdu.c @ 9:c9ef9e91dd8e
new libcommon, initial version
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 14 Mar 2021 06:55:38 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/apdu.c Sun Mar 14 06:55:38 2021 +0000 @@ -0,0 +1,84 @@ +#include <sys/types.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +extern FILE *cpipeF, *rpipeF; + +u_char sim_resp_data[258]; +unsigned sim_resp_data_len, sim_resp_sw; + +static void +send_cmd(cmd_apdu, cmd_apdu_len) + u_char *cmd_apdu; + unsigned cmd_apdu_len; +{ + unsigned n; + + for (n = 0; n < cmd_apdu_len; n++) + fprintf(cpipeF, "%02X", cmd_apdu[n]); + putc('\n', cpipeF); + fflush(cpipeF); +} + +static +parse_response_hex_string(input) + char *input; +{ + char *cp; + + sim_resp_data_len = 0; + for (cp = input; *cp; cp += 2) { + if (!isxdigit(cp[0]) || !isxdigit(cp[1])) { + fprintf(stderr, + "comm error: invalid hex string from back end\n"); + return(-1); + } + sim_resp_data[sim_resp_data_len++] = + (decode_hex_digit(cp[0]) << 4) | + decode_hex_digit(cp[1]); + } + return(0); +} + +apdu_exchange(cmd_apdu, cmd_apdu_len) + u_char *cmd_apdu; + unsigned cmd_apdu_len; +{ + char inbuf[518], *cp; + u_char *sw; + int rc; + + send_cmd(cmd_apdu, cmd_apdu_len); + if (!fgets(inbuf, sizeof inbuf, rpipeF)) { + fprintf(stderr, "comm error: EOF reading from back end\n"); + return(-1); + } + cp = index(inbuf, '\n'); + if (!cp) { + fprintf(stderr, + "comm error: response from back end has no newline\n"); + return(-1); + } + *cp = '\0'; + if (!inbuf[0]) { + fprintf(stderr, + "comm error: response from back end is an empty line\n"); + return(-1); + } + if (!isxdigit(inbuf[0]) || !isxdigit(inbuf[1]) || !isxdigit(inbuf[2]) + || !isxdigit(inbuf[3])) { + /* we got a back end error message */ + fprintf(stderr, "%s\n", inbuf); + return(-1); + } + rc = parse_response_hex_string(inbuf); + if (rc < 0) + return(rc); + sim_resp_data_len -= 2; + sw = sim_resp_data + sim_resp_data_len; + sim_resp_sw = (sw[0] << 8) | sw[1]; + return(0); +}