blob: f35cdd288c8d3197c7ba112dae3a93c50e5e6e72 [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>
5
6#include <osmocom/core/select.h>
7#include "utils_ringbuffer.h"
8
9enum card_uart_event {
10 /* a single byte was received, it's present at the (uint8_t *) data location */
11 CUART_E_RX_SINGLE,
12 /* an entire block of data was received */
13 CUART_E_RX_COMPLETE,
14 CUART_E_RX_TIMEOUT,
15 /* an entire block of data was written, as instructed in prior card_uart_tx() call */
16 CUART_E_TX_COMPLETE,
17};
18
19extern const struct value_string card_uart_event_vals[];
20
21enum card_uart_ctl {
22 CUART_CTL_RX,
23 CUART_CTL_POWER,
24 CUART_CTL_CLOCK,
25 CUART_CTL_RST,
26};
27
28struct card_uart;
29
30struct card_uart_ops {
31 int (*open)(struct card_uart *cuart, const char *device_name);
32 int (*close)(struct card_uart *cuart);
Harald Welte02dd9112019-10-01 08:55:29 +020033 int (*async_tx)(struct card_uart *cuart, const uint8_t *data, size_t len);
Harald Weltea40c8e52019-09-27 19:22:34 +020034 int (*async_rx)(struct card_uart *cuart, uint8_t *data, size_t len);
35
Harald Welte9700d392019-10-09 20:17:28 +020036 int (*ctrl)(struct card_uart *cuart, enum card_uart_ctl ctl, int arg);
Harald Weltea40c8e52019-09-27 19:22:34 +020037};
38
39/* Card UART driver */
40struct card_uart_driver {
41 /* global list of card UART drivers */
42 struct llist_head list;
43 /* human-readable name of driver */
44 const char *name;
45 /* operations implementing the driver */
46 const struct card_uart_ops *ops;
47};
48
49struct card_uart {
50 /* member in global list of UARTs */
51 struct llist_head list;
52 /* driver serving this UART */
53 const struct card_uart_driver *driver;
54 /* event-handler function */
55 void (*handle_event)(struct card_uart *cuart, enum card_uart_event evt, void *data);
56 /* opaque pointer for user */
57 void *priv;
58
59 /* is the transmitter currently busy (true) or not (false)? */
60 bool tx_busy;
61 /* is the receiver currently enabled or not? */
62 bool rx_enabled;
63
64 /*! after how many bytes should we notify the user? If this is '1', we will
65 * issue CUART_E_RX_SINGLE; if it is > 1, we will issue CUART_E_RX_COMPLETE */
66 uint32_t rx_threshold;
67
68 /* driver-specific private data */
69 union {
70 struct {
71 /* ringbuffer on receive side */
72 uint8_t rx_buf[256];
73 struct ringbuffer rx_ringbuf;
74
75 /* pointer to (user-allocated) transmit buffer and length */
76 const uint8_t *tx_buf;
77 size_t tx_buf_len;
78 /* index: offset of next to be transmitted byte in tx_buf */
79 size_t tx_index;
Harald Welte18ec3222019-09-28 21:41:59 +020080 /* number of bytes we have received echoed back during transmit */
81 uint32_t rx_count_during_tx;
Harald Weltea40c8e52019-09-27 19:22:34 +020082
83 struct osmo_fd ofd;
84 unsigned int baudrate;
85 } tty;
86 } u;
87};
88
89/*! Open the Card UART */
90int card_uart_open(struct card_uart *cuart, const char *driver_name, const char *device_name);
91
92/*! Close the Card UART */
93int card_uart_close(struct card_uart *cuart);
94
95/*! Schedule (asynchronous) transmit data via UART; optionally enable Rx after completion */
Harald Welte02dd9112019-10-01 08:55:29 +020096int card_uart_tx(struct card_uart *cuart, const uint8_t *data, size_t len);
Harald Weltea40c8e52019-09-27 19:22:34 +020097
98/*! Schedule (asynchronous) receive data via UART (after CUART_E_RX_COMPLETE) */
99int card_uart_rx(struct card_uart *cuart, uint8_t *data, size_t len);
100
Harald Welte9700d392019-10-09 20:17:28 +0200101int card_uart_ctrl(struct card_uart *cuart, enum card_uart_ctl ctl, int arg);
Harald Weltea40c8e52019-09-27 19:22:34 +0200102
103/*! Set the Rx notification threshold in number of bytes received */
104void card_uart_set_rx_threshold(struct card_uart *cuart, size_t rx_threshold);
105
106void card_uart_notification(struct card_uart *cuart, enum card_uart_event evt, void *data);
107
108int card_uart_driver_register(struct card_uart_driver *drv);