remsim_client: Process SetAtrReq() and set ATR in SIMtrace2 firmware

Change-Id: Iddcb13c8f4e98aac4e44bda32b8ad4cdeead50e7
diff --git a/src/rspro_util.c b/src/rspro_util.c
index 35619ad..f42caba 100644
--- a/src/rspro_util.c
+++ b/src/rspro_util.c
@@ -340,6 +340,18 @@
 	return pdu;
 }
 
+RsproPDU_t *rspro_gen_SetAtrRes(e_ResultCode res)
+{
+	RsproPDU_t *pdu = CALLOC(1, sizeof(*pdu));
+	if (!pdu)
+		return NULL;
+	pdu->version = 2;
+	pdu->msg.present = RsproPDUchoice_PR_setAtrRes;
+	pdu->msg.choice.setAtrRes.result = res;
+
+	return pdu;
+}
+
 RsproPDU_t *rspro_gen_TpduModem2Card(const ClientSlot_t *client, const BankSlot_t *bank,
 				     const uint8_t *tpdu, unsigned int tpdu_len)
 {
diff --git a/src/rspro_util.h b/src/rspro_util.h
index 6164e58..444d34a 100644
--- a/src/rspro_util.h
+++ b/src/rspro_util.h
@@ -37,6 +37,7 @@
 RsproPDU_t *rspro_gen_ConfigClientBankRes(e_ResultCode res);
 RsproPDU_t *rspro_gen_SetAtrReq(uint16_t client_id, uint16_t slot_nr, const uint8_t *atr,
 				unsigned int atr_len);
+RsproPDU_t *rspro_gen_SetAtrRes(e_ResultCode res);
 RsproPDU_t *rspro_gen_TpduModem2Card(const ClientSlot_t *client, const BankSlot_t *bank,
 				     const uint8_t *tpdu, unsigned int tpdu_len);
 RsproPDU_t *rspro_gen_TpduCard2Modem(const BankSlot_t *bank, const ClientSlot_t *client,
diff --git a/src/simtrace2-remsim_client.c b/src/simtrace2-remsim_client.c
index ae7c015..095c6d6 100644
--- a/src/simtrace2-remsim_client.c
+++ b/src/simtrace2-remsim_client.c
@@ -555,6 +555,28 @@
 	return 0;
 }
 
+static int bankd_handle_setAtrReq(struct bankd_client *bc, RsproPDU_t *pdu)
+{
+	RsproPDU_t *resp;
+	int rc;
+
+	OSMO_ASSERT(pdu);
+	OSMO_ASSERT(RsproPDUchoice_PR_setAtrReq == pdu->msg.present);
+
+	/* FIXME: is this permitted at any time by the SIMtrace2 cardemfirmware? */
+	rc = cardem_request_set_atr(ci, pdu->msg.choice.setAtrReq.atr.buf,
+				    pdu->msg.choice.setAtrReq.atr.size);
+	if (rc == 0)
+		resp = rspro_gen_SetAtrRes(ResultCode_ok);
+	else
+		resp = rspro_gen_SetAtrRes(ResultCode_cardTransmissionError);
+	if (!resp)
+		return -ENOMEM;
+	bankd_conn_send_rspro(g_client, resp);
+
+	return 0;
+}
+
 static int bankd_handle_msg(struct bankd_client *bc, struct msgb *msg)
 {
 	RsproPDU_t *pdu = rspro_dec_msg(msg);
@@ -572,6 +594,9 @@
 	case RsproPDUchoice_PR_tpduCardToModem: // APDU response from card received
 		bankd_handle_tpduCardToModem(bc, pdu);
 		break;
+	case RsproPDUchoice_PR_setAtrReq:
+		bankd_handle_setAtrReq(bc, pdu);
+		break;
 	default:
 		LOGPFSML(bc->bankd_fi, LOGL_ERROR, "Unknown/Unsuppoerted RSPRO PDU %s: %s\n",
 			 rspro_msgt_name(pdu), msgb_hexdump(msg));