better ccid error handling, fix buffer leaks

Change-Id: Ib8b8524809e12608a7ade79ce7d7c3ced16eeb57
diff --git a/ccid_common/ccid_device.c b/ccid_common/ccid_device.c
index 11edd3e..b14f194 100644
--- a/ccid_common/ccid_device.c
+++ b/ccid_common/ccid_device.c
@@ -475,14 +475,25 @@
 	const struct ccid_header *ch = (const struct ccid_header *) u;
 	uint8_t seq = u->reset_parameters.hdr.bSeq;
 	struct msgb *resp;
+	int rc;
 
 	/* copy default parameters from somewhere */
 	/* FIXME: T=1 */
-	cs->ci->slot_ops->set_params(cs, seq, CCID_PROTOCOL_NUM_T0, cs->default_pars);
-	cs->pars = *cs->default_pars;
 
-	resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_OK, 0);
-	return ccid_slot_send_unbusy(cs, resp);
+	/* validate parameters; abort if they are not supported */
+	rc = cs->ci->slot_ops->set_params(cs, seq, CCID_PROTOCOL_NUM_T0, cs->default_pars);
+	if (rc < 0) {
+		resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_FAILED, -rc);
+		goto out;
+	}
+
+	msgb_free(msg);
+	/* busy, tdpu like callback */
+	return 1;
+out:
+	msgb_free(msg);
+	ccid_slot_send_unbusy(cs, resp);
+	return 1;
 }
 
 /* Section 6.1.7 */
@@ -523,10 +534,14 @@
 		resp = ccid_gen_parameters_t0(cs, seq, CCID_CMD_STATUS_FAILED, -rc);
 		goto out;
 	}
+
+	msgb_free(msg);
 	/* busy, tdpu like callback */
 	return 1;
 out:
-	return ccid_slot_send_unbusy(cs, resp);
+	msgb_free(msg);
+	ccid_slot_send_unbusy(cs, resp);
+	return 1;
 }
 
 /* Section 6.1.8 */
@@ -682,6 +697,15 @@
 		return ccid_send(ci, resp);
 	}
 
+	if(!cs->icc_present) {
+		LOGPCS(cs, LOGL_ERROR, "No icc present, but another cmd received\n");
+		/* FIXME: ABORT logic as per section 5.3.1 of CCID Spec v1.1 */
+		resp = gen_err_resp(ch->bMessageType, ch->bSlot, get_icc_status(cs), ch->bSeq,
+				CCID_ERR_ICC_MUTE);
+		msgb_free(msg);
+		return ccid_send(ci, resp);
+	}
+
 	LOGPCS(cs, LOGL_DEBUG, "Rx CCID(OUT) %s %s\n",
 		get_value_string(ccid_msg_type_vals, ch->bMessageType), msgb_hexdump(msg));