libese, libese-hw: better check for error states.

If a device is in error, do not let other commands
proceed.

Additionally, nq-nci needed to better check its
handle state.

Test: booted with a bad device and esed doesn't NULL deref.
Bug: none
Change-Id: I3bceda76f4ce84f95f4128c04e26dbd051972cc5
diff --git a/libese-hw/nxp/pn80t/common.c b/libese-hw/nxp/pn80t/common.c
index 82b0b45..81dd89d 100644
--- a/libese-hw/nxp/pn80t/common.c
+++ b/libese-hw/nxp/pn80t/common.c
@@ -58,6 +58,7 @@
     /* This is a compile-time correctable error only. */
     ALOGE("Pad size too small to use NXP HW (%zu < %zu)", sizeof(ese->pad),
           sizeof(struct NxpState));
+    ese_set_error(ese, kNxpPn80tErrorPlatformInit);
     return -1;
   }
   platform = ese->ops->opts;
@@ -66,6 +67,7 @@
   if (!platform->initialize || !platform->release || !platform->toggle_reset ||
       !platform->wait) {
     ALOGE("Required functions not implemented in supplied platform");
+    ese_set_error(ese, kNxpPn80tErrorPlatformInit);
     return -1;
   }
 
@@ -167,6 +169,9 @@
   uint32_t *timers[TIMER_COUNT];
   uint32_t max_wait = 0;
   const uint8_t *message = kResetSession;
+  if (ese->error.is_err) {
+    return 0;
+  }
   if (end) {
     message = kEndofApduSession;
   }
@@ -273,7 +278,9 @@
   uint32_t wait_min = 0;
   ALOGV("%s: called", __func__);
   ns = NXP_PN80T_STATE(ese);
-  wait_min = nxp_pn80t_send_cooldown(ese, true);
+  if (!ese->error.is_err) {
+    wait_min = nxp_pn80t_send_cooldown(ese, true);
+  }
   /* In practice, this should probably migrate into the kernel
    * and into the spidev code such that each platform can handle it
    * as needed.
diff --git a/libese-hw/nxp/pn80t/nq_nci.c b/libese-hw/nxp/pn80t/nq_nci.c
index 60b7464..cd475f5 100644
--- a/libese-hw/nxp/pn80t/nq_nci.c
+++ b/libese-hw/nxp/pn80t/nq_nci.c
@@ -63,11 +63,17 @@
 
 int platform_toggle_bootloader(void *blob, int val) {
   const struct PlatformHandle *handle = blob;
+  if (!handle) {
+    return -1;
+  }
   return ioctl(handle->fd, ESE_CLEAR_GPIO, val);
 }
 
 int platform_toggle_reset(void *blob, int val) {
   const struct PlatformHandle *handle = blob;
+  if (!handle) {
+    return -1;
+  }
   /* 0=power and 1=no power in the kernel. */
   return ioctl(handle->fd, ESE_SET_PWR, !val);
 }
@@ -95,6 +101,9 @@
 
 int platform_release(void *blob) {
   struct PlatformHandle *handle = blob;
+  if (!handle) {
+    return -1;
+  }
   /* Power off and cooldown should've happened via common code. */
   close(handle->fd);
   free(handle);
diff --git a/libese/ese.c b/libese/ese.c
index 55eb838..01c5345 100644
--- a/libese/ese.c
+++ b/libese/ese.c
@@ -40,6 +40,8 @@
     return -1;
   }
   ALOGV("opening interface '%s'", ese_name(ese));
+  ese->error.is_err = false;
+  ese->error.code = 0;
   if (ese->ops->open) {
     return ese->ops->open(ese, hw_opts);
   }
@@ -100,7 +102,9 @@
   if (!ese) {
     return -1;
   }
-
+  if (ese->error.is_err) {
+    return -1;
+  }
   if (ese->ops->transceive) {
     recvd = ese->ops->transceive(ese, tx_bufs, tx_segs, rx_bufs, rx_segs);
     return ese_error(ese) ? -1 : recvd;