blob: 951a3ec75666459324c3cca511b5a47f73afa8b4 [file] [log] [blame]
Harald Weltea40c8e52019-09-27 19:22:34 +02001#pragma once
2#include <stdint.h>
3#include <stdbool.h>
4#include <osmocom/core/linuxlist.h>
Harald Welte7b64fc02019-10-09 20:49:35 +02005#include <osmocom/core/timer.h>
Harald Weltea40c8e52019-09-27 19:22:34 +02006
7#include <osmocom/core/select.h>
8#include "utils_ringbuffer.h"
9
10enum card_uart_event {
11 /* a single byte was received, it's present at the (uint8_t *) data location */
12 CUART_E_RX_SINGLE,
13 /* an entire block of data was received */
14 CUART_E_RX_COMPLETE,
15 CUART_E_RX_TIMEOUT,
16 /* an entire block of data was written, as instructed in prior card_uart_tx() call */
17 CUART_E_TX_COMPLETE,
18};
19
20extern const struct value_string card_uart_event_vals[];
21
22enum card_uart_ctl {
Harald Welted4328e22019-10-10 10:07:50 +020023 CUART_CTL_RX, /* enable/disable receiver */
24 CUART_CTL_POWER, /* enable/disable ICC power */
25 CUART_CTL_CLOCK, /* enable/disable ICC clock */
26 CUART_CTL_RST, /* enable/disable ICC reset */
27 CUART_CTL_WTIME, /* set the waiting time (in etu) */
Harald Weltea40c8e52019-09-27 19:22:34 +020028};
29
30struct card_uart;
31
32struct card_uart_ops {
33 int (*open)(struct card_uart *cuart, const char *device_name);
34 int (*close)(struct card_uart *cuart);
Harald Welte02dd9112019-10-01 08:55:29 +020035 int (*async_tx)(struct card_uart *cuart, const uint8_t *data, size_t len);
Harald Weltea40c8e52019-09-27 19:22:34 +020036 int (*async_rx)(struct card_uart *cuart, uint8_t *data, size_t len);
37
Harald Welte9700d392019-10-09 20:17:28 +020038 int (*ctrl)(struct card_uart *cuart, enum card_uart_ctl ctl, int arg);
Harald Weltea40c8e52019-09-27 19:22:34 +020039};
40
41/* Card UART driver */
42struct card_uart_driver {
43 /* global list of card UART drivers */
44 struct llist_head list;
45 /* human-readable name of driver */
46 const char *name;
47 /* operations implementing the driver */
48 const struct card_uart_ops *ops;
49};
50
51struct card_uart {
52 /* member in global list of UARTs */
53 struct llist_head list;
54 /* driver serving this UART */
55 const struct card_uart_driver *driver;
56 /* event-handler function */
57 void (*handle_event)(struct card_uart *cuart, enum card_uart_event evt, void *data);
58 /* opaque pointer for user */
59 void *priv;
60
61 /* is the transmitter currently busy (true) or not (false)? */
62 bool tx_busy;
63 /* is the receiver currently enabled or not? */
64 bool rx_enabled;
Harald Welte6603d952019-10-09 20:50:13 +020065 /* should the receiver automatically be nabled after TX completion? */
66 bool rx_after_tx_compl;
Harald Weltea40c8e52019-09-27 19:22:34 +020067
68 /*! after how many bytes should we notify the user? If this is '1', we will
69 * issue CUART_E_RX_SINGLE; if it is > 1, we will issue CUART_E_RX_COMPLETE */
70 uint32_t rx_threshold;
71
Harald Welte7b64fc02019-10-09 20:49:35 +020072 uint32_t wtime_etu;
73 struct osmo_timer_list wtime_tmr;
74
Harald Weltea40c8e52019-09-27 19:22:34 +020075 /* driver-specific private data */
76 union {
77 struct {
78 /* ringbuffer on receive side */
79 uint8_t rx_buf[256];
80 struct ringbuffer rx_ringbuf;
81
82 /* pointer to (user-allocated) transmit buffer and length */
83 const uint8_t *tx_buf;
84 size_t tx_buf_len;
85 /* index: offset of next to be transmitted byte in tx_buf */
86 size_t tx_index;
Harald Welte18ec3222019-09-28 21:41:59 +020087 /* number of bytes we have received echoed back during transmit */
88 uint32_t rx_count_during_tx;
Harald Weltea40c8e52019-09-27 19:22:34 +020089
90 struct osmo_fd ofd;
91 unsigned int baudrate;
92 } tty;
93 } u;
94};
95
96/*! Open the Card UART */
97int card_uart_open(struct card_uart *cuart, const char *driver_name, const char *device_name);
98
99/*! Close the Card UART */
100int card_uart_close(struct card_uart *cuart);
101
102/*! Schedule (asynchronous) transmit data via UART; optionally enable Rx after completion */
Harald Welte6603d952019-10-09 20:50:13 +0200103int card_uart_tx(struct card_uart *cuart, const uint8_t *data, size_t len, bool rx_after_complete);
Harald Weltea40c8e52019-09-27 19:22:34 +0200104
105/*! Schedule (asynchronous) receive data via UART (after CUART_E_RX_COMPLETE) */
106int card_uart_rx(struct card_uart *cuart, uint8_t *data, size_t len);
107
Harald Welte9700d392019-10-09 20:17:28 +0200108int card_uart_ctrl(struct card_uart *cuart, enum card_uart_ctl ctl, int arg);
Harald Weltea40c8e52019-09-27 19:22:34 +0200109
110/*! Set the Rx notification threshold in number of bytes received */
111void card_uart_set_rx_threshold(struct card_uart *cuart, size_t rx_threshold);
112
Harald Welte7b64fc02019-10-09 20:49:35 +0200113/* (re)start the software WTIME timer */
114void card_uart_wtime_restart(struct card_uart *cuart);
115
Harald Weltea40c8e52019-09-27 19:22:34 +0200116void card_uart_notification(struct card_uart *cuart, enum card_uart_event evt, void *data);
117
118int card_uart_driver_register(struct card_uart_driver *drv);