1 /** @file
2  *  @brief Bluetooth RFCOMM handling
3  */
4 
5 /*
6  * Copyright (c) 2015-2016 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_RFCOMM_H_
11 #define ZEPHYR_INCLUDE_BLUETOOTH_RFCOMM_H_
12 
13 /**
14  * @brief RFCOMM
15  * @defgroup bt_rfcomm RFCOMM
16  * @ingroup bluetooth
17  * @{
18  */
19 
20 #include <zephyr/bluetooth/buf.h>
21 #include <zephyr/bluetooth/conn.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /* RFCOMM channels (1-30): pre-allocated for profiles to avoid conflicts */
28 enum {
29 	BT_RFCOMM_CHAN_HFP_HF = 1,
30 	BT_RFCOMM_CHAN_HFP_AG,
31 	BT_RFCOMM_CHAN_HSP_AG,
32 	BT_RFCOMM_CHAN_HSP_HS,
33 	BT_RFCOMM_CHAN_SPP,
34 };
35 
36 struct bt_rfcomm_dlc;
37 
38 /** @brief RFCOMM DLC operations structure. */
39 struct bt_rfcomm_dlc_ops {
40 	/** DLC connected callback
41 	 *
42 	 *  If this callback is provided it will be called whenever the
43 	 *  connection completes.
44 	 *
45 	 *  @param dlc The dlc that has been connected
46 	 */
47 	void (*connected)(struct bt_rfcomm_dlc *dlc);
48 
49 	/** DLC disconnected callback
50 	 *
51 	 *  If this callback is provided it will be called whenever the
52 	 *  dlc is disconnected, including when a connection gets
53 	 *  rejected or cancelled (both incoming and outgoing)
54 	 *
55 	 *  @param dlc The dlc that has been Disconnected
56 	 */
57 	void (*disconnected)(struct bt_rfcomm_dlc *dlc);
58 
59 	/** DLC recv callback
60 	 *
61 	 *  @param dlc The dlc receiving data.
62 	 *  @param buf Buffer containing incoming data.
63 	 */
64 	void (*recv)(struct bt_rfcomm_dlc *dlc, struct net_buf *buf);
65 
66 	/** DLC sent callback
67 	 *
68 	 *  @param dlc The dlc which has sent data.
69 	 *  @param err Sent result.
70 	 */
71 	void (*sent)(struct bt_rfcomm_dlc *dlc, int err);
72 };
73 
74 /** @brief Role of RFCOMM session and dlc. Used only by internal APIs
75  */
76 typedef enum bt_rfcomm_role {
77 	BT_RFCOMM_ROLE_ACCEPTOR,
78 	BT_RFCOMM_ROLE_INITIATOR
79 } __packed bt_rfcomm_role_t;
80 
81 /** @brief RFCOMM DLC structure. */
82 struct bt_rfcomm_dlc {
83 	/* Response Timeout eXpired (RTX) timer */
84 	struct k_work_delayable    rtx_work;
85 
86 	/* Queue for outgoing data */
87 	struct k_fifo              tx_queue;
88 
89 	/* TX credits, Reuse as a binary sem for MSC FC if CFC is not enabled */
90 	struct k_sem               tx_credits;
91 
92 	struct bt_rfcomm_session  *session;
93 	struct bt_rfcomm_dlc_ops  *ops;
94 	struct bt_rfcomm_dlc      *_next;
95 
96 	bt_security_t              required_sec_level;
97 	bt_rfcomm_role_t           role;
98 
99 	uint16_t                      mtu;
100 	uint8_t                       dlci;
101 	uint8_t                       state;
102 	uint8_t                       rx_credit;
103 
104 	/* Stack & kernel data for TX thread */
105 	struct k_thread            tx_thread;
106 #if defined(CONFIG_BT_RFCOMM_DLC_STACK_SIZE)
107 	K_KERNEL_STACK_MEMBER(stack, CONFIG_BT_RFCOMM_DLC_STACK_SIZE);
108 #endif /* CONFIG_BT_RFCOMM_DLC_STACK_SIZE */
109 };
110 
111 struct bt_rfcomm_server {
112 	/** Server Channel */
113 	uint8_t channel;
114 
115 	/** Server accept callback
116 	 *
117 	 *  This callback is called whenever a new incoming connection requires
118 	 *  authorization.
119 	 *
120 	 *  @param conn The connection that is requesting authorization
121 	 *  @param dlc Pointer to received the allocated dlc
122 	 *
123 	 *  @return 0 in case of success or negative value in case of error.
124 	 */
125 	int (*accept)(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc);
126 
127 	struct bt_rfcomm_server	*_next;
128 };
129 
130 /** @brief Register RFCOMM server
131  *
132  *  Register RFCOMM server for a channel, each new connection is authorized
133  *  using the accept() callback which in case of success shall allocate the dlc
134  *  structure to be used by the new connection.
135  *
136  *  @param server Server structure.
137  *
138  *  @return 0 in case of success or negative value in case of error.
139  */
140 int bt_rfcomm_server_register(struct bt_rfcomm_server *server);
141 
142 /** @brief Connect RFCOMM channel
143  *
144  *  Connect RFCOMM dlc by channel, once the connection is completed dlc
145  *  connected() callback will be called. If the connection is rejected
146  *  disconnected() callback is called instead.
147  *
148  *  @param conn Connection object.
149  *  @param dlc Dlc object.
150  *  @param channel Server channel to connect to.
151  *
152  *  @return 0 in case of success or negative value in case of error.
153  */
154 int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc,
155 			  uint8_t channel);
156 
157 /** @brief Send data to RFCOMM
158  *
159  *  Send data from buffer to the dlc. Length should be less than or equal to
160  *  mtu.
161  *
162  *  @param dlc Dlc object.
163  *  @param buf Data buffer.
164  *
165  *  @return Bytes sent in case of success or negative value in case of error.
166  */
167 int bt_rfcomm_dlc_send(struct bt_rfcomm_dlc *dlc, struct net_buf *buf);
168 
169 /** @brief Disconnect RFCOMM dlc
170  *
171  *  Disconnect RFCOMM dlc, if the connection is pending it will be
172  *  canceled and as a result the dlc disconnected() callback is called.
173  *
174  *  @param dlc Dlc object.
175  *
176  *  @return 0 in case of success or negative value in case of error.
177  */
178 int bt_rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc);
179 
180 /** @brief Allocate the buffer from pool after reserving head room for RFCOMM,
181  *  L2CAP and ACL headers.
182  *
183  *  @param pool Which pool to take the buffer from.
184  *
185  *  @return New buffer.
186  */
187 struct net_buf *bt_rfcomm_create_pdu(struct net_buf_pool *pool);
188 
189 #ifdef __cplusplus
190 }
191 #endif
192 
193 /**
194  * @}
195  */
196 
197 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_RFCOMM_H_ */
198