send correct APDU to bankd

Change-Id: I777f739793dfeec85823519f9d3d43b22090f209
This commit is contained in:
Kevin Redon 2018-10-11 08:41:00 +02:00 committed by Harald Welte
parent 9e34247231
commit bc08db5cee
1 changed files with 15 additions and 31 deletions

View File

@ -384,49 +384,33 @@ static int process_do_error(struct cardem_inst *ci, uint8_t *buf, int len)
return 0; return 0;
} }
static struct apdu_context ac; // this will hold the complete APDU (across calls)
/*! \brief Process a RX-DATA indication message from the SIMtrace2 */ /*! \brief Process a RX-DATA indication message from the SIMtrace2 */
static int process_do_rx_da(struct cardem_inst *ci, uint8_t *buf, int len) static int process_do_rx_da(struct cardem_inst *ci, uint8_t *buf, int len)
{ {
static struct apdu_context ac; struct cardemu_usb_msg_rx_data *data = (struct cardemu_usb_msg_rx_data *) buf; // cast the data from the USB message
struct cardemu_usb_msg_rx_data *data;
int rc; int rc;
data = (struct cardemu_usb_msg_rx_data *) buf;
printf("=> DATA: flags=%x, %s: ", data->flags, printf("=> DATA: flags=%x, %s: ", data->flags,
osmo_hexdump(data->data, data->data_len)); osmo_hexdump(data->data, data->data_len));
rc = apdu_segment_in(&ac, data->data, data->data_len, rc = apdu_segment_in(&ac, data->data, data->data_len,
data->flags & CEMU_DATA_F_TPDU_HDR); data->flags & CEMU_DATA_F_TPDU_HDR); // parse the APDU data in the USB message
if (rc & APDU_ACT_TX_CAPDU_TO_CARD) { if (rc & APDU_ACT_TX_CAPDU_TO_CARD) { // there is no pending data coming from the modem
struct msgb *tmsg = msgb_alloc(1024, "TPDU"); uint8_t* apdu_command = calloc(1, sizeof(ac.hdr) + ac.lc.tot); // to store the APDU command to send
uint8_t *cur; memcpy(apdu_command, &ac.hdr, sizeof(ac.hdr)); // copy APDU command header
/* Copy TPDU header */
cur = msgb_put(tmsg, sizeof(ac.hdr));
memcpy(cur, &ac.hdr, sizeof(ac.hdr));
/* Copy D(c), if any */
if (ac.lc.tot) { if (ac.lc.tot) {
cur = msgb_put(tmsg, ac.lc.tot); memcpy(apdu_command + sizeof(ac.hdr), ac.dc, ac.lc.tot); // copy APDU command data
memcpy(cur, ac.dc, ac.lc.tot);
} }
/* send to actual card */ // send APDU to card
tmsg->l3h = tmsg->tail; RsproPDU_t *pdu = rspro_gen_TpduModem2Card(g_client->clslot, &(BankSlot_t){ .bankId = 0, .slotNr = 0}, apdu_command, sizeof(ac.hdr) + ac.lc.tot); // create RSPRO packet
printf("ok\n"); ipa_client_conn_send_rspro(g_client->bankd_conn, pdu); // send RSPRO packet
RsproPDU_t *pdu = rspro_gen_TpduModem2Card(g_client->clslot, NULL, NULL, 0); // the response will come separately
printf("ko\n"); free(apdu_command);
ipa_client_conn_send_rspro(g_client->bankd_conn, pdu); } else if (ac.lc.tot > ac.lc.cur) { // there is pending data from the modem
// FIXME cardem_request_pb_and_rx(ci, ac.hdr.ins, ac.lc.tot - ac.lc.cur); // send procedure byte to get remaining data
msgb_apdu_sw(tmsg) = msgb_get_u16(tmsg);
ac.sw[0] = msgb_apdu_sw(tmsg) >> 8;
ac.sw[1] = msgb_apdu_sw(tmsg) & 0xff;
printf("SW=0x%04x, len_rx=%d\n", msgb_apdu_sw(tmsg), msgb_l3len(tmsg));
if (msgb_l3len(tmsg))
cardem_request_pb_and_tx(ci, ac.hdr.ins, tmsg->l3h, msgb_l3len(tmsg));
cardem_request_sw_tx(ci, ac.sw);
} else if (ac.lc.tot > ac.lc.cur) {
cardem_request_pb_and_rx(ci, ac.hdr.ins, ac.lc.tot - ac.lc.cur);
} }
return 0; return 0;
} }