blob: 3d986c609e063669afaeec51457fc7ddfa366c60 [file] [log] [blame]
Harald Weltec68af6a2017-04-30 21:21:52 +02001#ifndef _SERCOMM_H
2#define _SERCOMM_H
3
4#include <osmocom/core/msgb.h>
5
6#define HDLC_FLAG 0x7E
7#define HDLC_ESCAPE 0x7D
8
9#define HDLC_C_UI 0x03
10#define HDLC_C_P_BIT (1 << 4)
11#define HDLC_C_F_BIT (1 << 4)
12
13/* a low sercomm_dlci means high priority. A high DLCI means low priority */
14enum sercomm_dlci {
15 SC_DLCI_HIGHEST = 0,
16 SC_DLCI_DEBUG = 4,
17 SC_DLCI_L1A_L23 = 5,
18 SC_DLCI_LOADER = 9,
19 SC_DLCI_CONSOLE = 10,
20 SC_DLCI_ECHO = 128,
21 _SC_DLCI_MAX
22};
23
Harald Welte13588362017-04-30 23:57:55 +020024struct osmo_sercomm_inst;
Harald Welteea3d3ba2017-05-02 21:24:48 +020025/*! \brief call-back function for per-DLC receive handler
26 * \param[in] sercomm instance on which msg was received
27 * \param[in] dlci DLC Identifier of received msg
28 * \param[in] msg received message that needs to be processed */
Harald Welte13588362017-04-30 23:57:55 +020029typedef void (*dlci_cb_t)(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Weltecc95f4b2017-04-30 21:39:33 +020030
Harald Welteea3d3ba2017-05-02 21:24:48 +020031/*! \brief one instance of a sercomm multiplex/demultiplex */
Harald Welte13588362017-04-30 23:57:55 +020032struct osmo_sercomm_inst {
Harald Welteea3d3ba2017-05-02 21:24:48 +020033 /*! \brief Has this instance been initialized? */
Harald Weltecc95f4b2017-04-30 21:39:33 +020034 int initialized;
Harald Welteea3d3ba2017-05-02 21:24:48 +020035 /*! \brief UART Identifier */
Harald Weltecc95f4b2017-04-30 21:39:33 +020036 int uart_id;
37
Harald Welteea3d3ba2017-05-02 21:24:48 +020038 /*! \brief transmit side */
Harald Weltecc95f4b2017-04-30 21:39:33 +020039 struct {
Harald Welteea3d3ba2017-05-02 21:24:48 +020040 /*! \brief per-DLC queue of pending transmit msgbs */
Harald Weltecc95f4b2017-04-30 21:39:33 +020041 struct llist_head dlci_queues[_SC_DLCI_MAX];
Harald Welteea3d3ba2017-05-02 21:24:48 +020042 /*! \brief msgb currently being transmitted */
Harald Weltecc95f4b2017-04-30 21:39:33 +020043 struct msgb *msg;
Harald Welteea3d3ba2017-05-02 21:24:48 +020044 /*! \brief transmit state */
Harald Weltecc95f4b2017-04-30 21:39:33 +020045 int state;
Harald Welteea3d3ba2017-05-02 21:24:48 +020046 /*! \brief next to-be-transmitted char in msg */
Harald Weltecc95f4b2017-04-30 21:39:33 +020047 uint8_t *next_char;
48 } tx;
49
Harald Welteea3d3ba2017-05-02 21:24:48 +020050 /*! \brief receive side */
Harald Weltecc95f4b2017-04-30 21:39:33 +020051 struct {
Harald Welteea3d3ba2017-05-02 21:24:48 +020052 /*! \brief per-DLC handler call-back functions */
Harald Weltecc95f4b2017-04-30 21:39:33 +020053 dlci_cb_t dlci_handler[_SC_DLCI_MAX];
Harald Welteea3d3ba2017-05-02 21:24:48 +020054 /*! \brief msgb allocation size for rx msgs */
Harald Weltef6adcd72017-05-01 00:19:13 +020055 unsigned int msg_size;
Harald Welteea3d3ba2017-05-02 21:24:48 +020056 /*! \brief currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020057 struct msgb *msg;
Harald Welteea3d3ba2017-05-02 21:24:48 +020058 /*! \brief receive state */
Harald Weltecc95f4b2017-04-30 21:39:33 +020059 int state;
Harald Welteea3d3ba2017-05-02 21:24:48 +020060 /*! \brief DLCI of currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020061 uint8_t dlci;
Harald Welteea3d3ba2017-05-02 21:24:48 +020062 /*! \brief CTRL of currently received msgb */
Harald Weltecc95f4b2017-04-30 21:39:33 +020063 uint8_t ctrl;
64 } rx;
65};
66
67
Harald Weltec68af6a2017-04-30 21:21:52 +020068#ifndef HOST_BUILD
69#include <uart.h>
70/* helper functions for target */
Harald Welte13588362017-04-30 23:57:55 +020071void osmo_sercomm_bind_uart(struct osmo_sercomm_inst *sercomm, int uart);
72int osmo_sercomm_get_uart(struct osmo_sercomm_inst *sercomm);
73void osmo_sercomm_change_speed(struct osmo_sercomm_inst *sercomm, enum uart_baudrate bdrt);
Harald Weltec68af6a2017-04-30 21:21:52 +020074#endif
75
Harald Welte13588362017-04-30 23:57:55 +020076void osmo_sercomm_init(struct osmo_sercomm_inst *sercomm);
77int osmo_sercomm_initialized(struct osmo_sercomm_inst *sercomm);
Harald Weltec68af6a2017-04-30 21:21:52 +020078
79/* User Interface: Tx */
Harald Welte13588362017-04-30 23:57:55 +020080void osmo_sercomm_sendmsg(struct osmo_sercomm_inst *sercomm, uint8_t dlci, struct msgb *msg);
Harald Welte13588362017-04-30 23:57:55 +020081unsigned int osmo_sercomm_tx_queue_depth(struct osmo_sercomm_inst *sercomm, uint8_t dlci);
Harald Weltec68af6a2017-04-30 21:21:52 +020082
83/* User Interface: Rx */
Harald Welte13588362017-04-30 23:57:55 +020084int osmo_sercomm_register_rx_cb(struct osmo_sercomm_inst *sercomm, uint8_t dlci, dlci_cb_t cb);
Harald Weltec68af6a2017-04-30 21:21:52 +020085
86/* Driver Interface */
87
Harald Welte13588362017-04-30 23:57:55 +020088int osmo_sercomm_drv_pull(struct osmo_sercomm_inst *sercomm, uint8_t *ch);
Harald Welte13588362017-04-30 23:57:55 +020089int osmo_sercomm_drv_rx_char(struct osmo_sercomm_inst *sercomm, uint8_t ch);
Harald Weltec68af6a2017-04-30 21:21:52 +020090
Harald Welte13588362017-04-30 23:57:55 +020091static inline struct msgb *osmo_sercomm_alloc_msgb(unsigned int len)
Harald Weltec68af6a2017-04-30 21:21:52 +020092{
93 return msgb_alloc_headroom(len+4, 4, "sercomm_tx");
94}
95
96#endif /* _SERCOMM_H */