cuart: Integrate software WT (waiting time) timer
Change-Id: If94d7bdca0e5571d4f2f53862fc574c33a05ce43
diff --git a/ccid_common/cuart.c b/ccid_common/cuart.c
index fc3cfb6..4ea82ba 100644
--- a/ccid_common/cuart.c
+++ b/ccid_common/cuart.c
@@ -2,6 +2,7 @@
#include <string.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/timer.h>
#include "cuart.h"
@@ -25,6 +26,34 @@
return NULL;
}
+/* obtain the current ETU in us */
+static int get_etu_in_us(struct card_uart *cuart)
+{
+ /* FIXME: actually implement this based on the real baud rate */
+ return (1000000/9600);
+}
+
+/* software waiting-time timer has expired */
+static void card_uart_wtime_cb(void *data)
+{
+ struct card_uart *cuart = (struct card_uart *) data;
+ card_uart_notification(cuart, CUART_E_RX_TIMEOUT, NULL);
+ /* should we automatically disable the receiver? */
+}
+
+void card_uart_wtime_restart(struct card_uart *cuart)
+{
+ int secs, usecs;
+
+ usecs = get_etu_in_us(cuart) * cuart->wtime_etu;
+ if (usecs > 1000000) {
+ secs = usecs / 1000000;
+ usecs = usecs % 1000000;
+ } else
+ secs = 0;
+ osmo_timer_schedule(&cuart->wtime_tmr, secs, usecs);
+}
+
int card_uart_open(struct card_uart *cuart, const char *driver_name, const char *device_name)
{
struct card_uart_driver *drv = cuart_drv_by_name(driver_name);
@@ -33,8 +62,10 @@
if (!drv)
return -ENODEV;
+ cuart->wtime_etu = 9600; /* ISO 7816-3 Section 8.1 */
cuart->rx_enabled = true;
cuart->rx_threshold = 1;
+ osmo_timer_setup(&cuart->wtime_tmr, card_uart_wtime_cb, cuart);
rc = drv->ops->open(cuart, device_name);
if (rc < 0)
@@ -60,13 +91,19 @@
OSMO_ASSERT(cuart->driver);
OSMO_ASSERT(cuart->driver->ops);
OSMO_ASSERT(cuart->driver->ops->ctrl);
+
rc = cuart->driver->ops->ctrl(cuart, ctl, arg);
if (rc < 0)
return rc;
switch (ctl) {
+ case CUART_CTL_WTIME:
+ cuart->wtime_etu = arg;
+ break;
case CUART_CTL_RX:
cuart->rx_enabled = arg ? true : false;
+ if (!cuart->rx_enabled)
+ osmo_timer_del(&cuart->wtime_tmr);
break;
default:
break;
diff --git a/ccid_common/cuart.h b/ccid_common/cuart.h
index f35cdd2..9d56035 100644
--- a/ccid_common/cuart.h
+++ b/ccid_common/cuart.h
@@ -2,6 +2,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/timer.h>
#include <osmocom/core/select.h>
#include "utils_ringbuffer.h"
@@ -23,6 +24,7 @@
CUART_CTL_POWER,
CUART_CTL_CLOCK,
CUART_CTL_RST,
+ CUART_CTL_WTIME,
};
struct card_uart;
@@ -65,6 +67,9 @@
* issue CUART_E_RX_SINGLE; if it is > 1, we will issue CUART_E_RX_COMPLETE */
uint32_t rx_threshold;
+ uint32_t wtime_etu;
+ struct osmo_timer_list wtime_tmr;
+
/* driver-specific private data */
union {
struct {
@@ -103,6 +108,9 @@
/*! Set the Rx notification threshold in number of bytes received */
void card_uart_set_rx_threshold(struct card_uart *cuart, size_t rx_threshold);
+/* (re)start the software WTIME timer */
+void card_uart_wtime_restart(struct card_uart *cuart);
+
void card_uart_notification(struct card_uart *cuart, enum card_uart_event evt, void *data);
int card_uart_driver_register(struct card_uart_driver *drv);