Line data Source code
1 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 : #include <zephyr/bluetooth/l2cap.h>
23 :
24 : #ifdef __cplusplus
25 : extern "C" {
26 : #endif
27 :
28 : /** RFCOMM Maximum Header Size. The length could be 2 bytes, it depends on information length. */
29 1 : #define BT_RFCOMM_HDR_MAX_SIZE 4
30 : /** RFCOMM FCS Size */
31 1 : #define BT_RFCOMM_FCS_SIZE 1
32 :
33 : /** @brief Helper to calculate needed buffer size for RFCOMM PDUs.
34 : * Useful for creating buffer pools.
35 : *
36 : * @param mtu Needed RFCOMM PDU MTU.
37 : *
38 : * @return Needed buffer size to match the requested RFCOMM PDU MTU.
39 : */
40 1 : #define BT_RFCOMM_BUF_SIZE(mtu) \
41 : BT_L2CAP_BUF_SIZE(BT_RFCOMM_HDR_MAX_SIZE + BT_RFCOMM_FCS_SIZE + (mtu))
42 :
43 : /* RFCOMM channels (1-30): pre-allocated for profiles to avoid conflicts */
44 0 : enum {
45 : BT_RFCOMM_CHAN_HFP_HF = 1,
46 : BT_RFCOMM_CHAN_HFP_AG,
47 : BT_RFCOMM_CHAN_HSP_AG,
48 : BT_RFCOMM_CHAN_HSP_HS,
49 : BT_RFCOMM_CHAN_SPP,
50 : BT_RFCOMM_CHAN_DYNAMIC_START,
51 : };
52 :
53 : struct bt_rfcomm_dlc;
54 :
55 : /** @brief RFCOMM DLC operations structure. */
56 1 : struct bt_rfcomm_dlc_ops {
57 : /** DLC connected callback
58 : *
59 : * If this callback is provided it will be called whenever the
60 : * connection completes.
61 : *
62 : * @param dlc The dlc that has been connected
63 : */
64 1 : void (*connected)(struct bt_rfcomm_dlc *dlc);
65 :
66 : /** DLC disconnected callback
67 : *
68 : * If this callback is provided it will be called whenever the
69 : * dlc is disconnected, including when a connection gets
70 : * rejected or cancelled (both incoming and outgoing)
71 : *
72 : * @param dlc The dlc that has been Disconnected
73 : */
74 1 : void (*disconnected)(struct bt_rfcomm_dlc *dlc);
75 :
76 : /** DLC recv callback
77 : *
78 : * @param dlc The dlc receiving data.
79 : * @param buf Buffer containing incoming data.
80 : */
81 1 : void (*recv)(struct bt_rfcomm_dlc *dlc, struct net_buf *buf);
82 :
83 : /** DLC sent callback
84 : *
85 : * @param dlc The dlc which has sent data.
86 : * @param err Sent result.
87 : */
88 1 : void (*sent)(struct bt_rfcomm_dlc *dlc, int err);
89 : };
90 :
91 : /** @brief Role of RFCOMM session and dlc. Used only by internal APIs
92 : */
93 0 : typedef enum bt_rfcomm_role {
94 : BT_RFCOMM_ROLE_ACCEPTOR,
95 : BT_RFCOMM_ROLE_INITIATOR
96 1 : } __packed bt_rfcomm_role_t;
97 :
98 : /** @brief RFCOMM DLC structure. */
99 1 : struct bt_rfcomm_dlc {
100 : /* Response Timeout eXpired (RTX) timer */
101 0 : struct k_work_delayable rtx_work;
102 :
103 : /* Queue for outgoing data */
104 0 : struct k_fifo tx_queue;
105 :
106 : /* TX credits, Reuse as a binary sem for MSC FC if CFC is not enabled */
107 0 : struct k_sem tx_credits;
108 :
109 : /* Worker for RFCOMM TX */
110 0 : struct k_work tx_work;
111 :
112 0 : struct bt_rfcomm_session *session;
113 0 : struct bt_rfcomm_dlc_ops *ops;
114 : struct bt_rfcomm_dlc *_next;
115 :
116 0 : bt_security_t required_sec_level;
117 0 : bt_rfcomm_role_t role;
118 :
119 0 : uint16_t mtu;
120 0 : uint8_t dlci;
121 0 : uint8_t state;
122 0 : uint8_t rx_credit;
123 : };
124 :
125 0 : struct bt_rfcomm_server {
126 : /** Server Channel
127 : *
128 : * Possible values:
129 : * 0 A dynamic value will be auto-allocated when bt_rfcomm_server_register() is
130 : * called.
131 : *
132 : * 0x01 - 0x1e Dynamically allocated. May be pre-set by the application before server
133 : * registration (not recommended however), or auto-allocated by the stack
134 : * if the 0 is passed.
135 : */
136 1 : uint8_t channel;
137 :
138 : /** Server accept callback
139 : *
140 : * This callback is called whenever a new incoming connection requires
141 : * authorization.
142 : *
143 : * @param conn The connection that is requesting authorization
144 : * @param server Pointer to the server structure this callback relates to
145 : * @param dlc Pointer to received the allocated dlc
146 : *
147 : * @return 0 in case of success or negative value in case of error.
148 : */
149 1 : int (*accept)(struct bt_conn *conn, struct bt_rfcomm_server *server,
150 : struct bt_rfcomm_dlc **dlc);
151 :
152 : struct bt_rfcomm_server *_next;
153 : };
154 :
155 : /** @brief RFCOMM RPN baud rate values */
156 0 : enum {
157 : BT_RFCOMM_RPN_BAUD_RATE_2400 = 0x0,
158 : BT_RFCOMM_RPN_BAUD_RATE_4800 = 0x1,
159 : BT_RFCOMM_RPN_BAUD_RATE_7200 = 0x2,
160 : BT_RFCOMM_RPN_BAUD_RATE_9600 = 0x3,
161 : BT_RFCOMM_RPN_BAUD_RATE_19200 = 0x4,
162 : BT_RFCOMM_RPN_BAUD_RATE_38400 = 0x5,
163 : BT_RFCOMM_RPN_BAUD_RATE_57600 = 0x6,
164 : BT_RFCOMM_RPN_BAUD_RATE_115200 = 0x7,
165 : BT_RFCOMM_RPN_BAUD_RATE_230400 = 0x8
166 : };
167 :
168 : /** @brief RFCOMM RPN data bit values */
169 0 : enum {
170 : BT_RFCOMM_RPN_DATA_BITS_5 = 0x0,
171 : BT_RFCOMM_RPN_DATA_BITS_6 = 0x1,
172 : BT_RFCOMM_RPN_DATA_BITS_7 = 0x2,
173 : BT_RFCOMM_RPN_DATA_BITS_8 = 0x3
174 : };
175 :
176 : /** @brief RFCOMM RPN stop bit values */
177 0 : enum {
178 : BT_RFCOMM_RPN_STOP_BITS_1 = 0,
179 : BT_RFCOMM_RPN_STOP_BITS_1_5 = 1
180 : };
181 :
182 : /** @brief RFCOMM RPN parity bit values */
183 0 : enum {
184 : BT_RFCOMM_RPN_PARITY_NONE = 0x0,
185 : BT_RFCOMM_RPN_PARITY_ODD = 0x1,
186 : BT_RFCOMM_RPN_PARITY_EVEN = 0x3,
187 : BT_RFCOMM_RPN_PARITY_MARK = 0x5,
188 : BT_RFCOMM_RPN_PARITY_SPACE = 0x7
189 : };
190 :
191 : /** @brief Combine data bits, stop bits and parity into a single line settings byte
192 : *
193 : * @param data Data bits value (0-3)
194 : * @param stop Stop bits value (0-1)
195 : * @param parity Parity value (0-7)
196 : *
197 : * @return Combined line settings byte
198 : */
199 1 : #define BT_RFCOMM_SET_LINE_SETTINGS(data, stop, parity) ((data & 0x3) | \
200 : ((stop & 0x1) << 2) | \
201 : ((parity & 0x7) << 3))
202 :
203 0 : #define BT_RFCOMM_RPN_FLOW_NONE 0x00
204 0 : #define BT_RFCOMM_RPN_XON_CHAR 0x11
205 0 : #define BT_RFCOMM_RPN_XOFF_CHAR 0x13
206 :
207 : /* Set 1 to all the param mask except reserved */
208 0 : #define BT_RFCOMM_RPN_PARAM_MASK_ALL 0x3f7f
209 :
210 : /** @brief RFCOMM Remote Port Negotiation (RPN) structure */
211 1 : struct bt_rfcomm_rpn {
212 0 : uint8_t dlci;
213 0 : uint8_t baud_rate;
214 0 : uint8_t line_settings;
215 0 : uint8_t flow_control;
216 0 : uint8_t xon_char;
217 0 : uint8_t xoff_char;
218 0 : uint16_t param_mask;
219 : } __packed;
220 :
221 : /** @brief Register RFCOMM server
222 : *
223 : * Register RFCOMM server for a channel, each new connection is authorized
224 : * using the accept() callback which in case of success shall allocate the dlc
225 : * structure to be used by the new connection.
226 : *
227 : * @param server Server structure.
228 : *
229 : * @return 0 in case of success or negative value in case of error.
230 : */
231 1 : int bt_rfcomm_server_register(struct bt_rfcomm_server *server);
232 :
233 : /** @brief Connect RFCOMM channel
234 : *
235 : * Connect RFCOMM dlc by channel, once the connection is completed dlc
236 : * connected() callback will be called. If the connection is rejected
237 : * disconnected() callback is called instead.
238 : *
239 : * @param conn Connection object.
240 : * @param dlc Dlc object.
241 : * @param channel Server channel to connect to.
242 : *
243 : * @return 0 in case of success or negative value in case of error.
244 : */
245 1 : int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc,
246 : uint8_t channel);
247 :
248 : /** @brief Send data to RFCOMM
249 : *
250 : * Send data from buffer to the dlc. Length should be less than or equal to
251 : * mtu.
252 : *
253 : * @param dlc Dlc object.
254 : * @param buf Data buffer.
255 : *
256 : * @return Bytes sent in case of success or negative value in case of error.
257 : */
258 1 : int bt_rfcomm_dlc_send(struct bt_rfcomm_dlc *dlc, struct net_buf *buf);
259 :
260 : /** @brief Disconnect RFCOMM dlc
261 : *
262 : * Disconnect RFCOMM dlc, if the connection is pending it will be
263 : * canceled and as a result the dlc disconnected() callback is called.
264 : *
265 : * @param dlc Dlc object.
266 : *
267 : * @return 0 in case of success or negative value in case of error.
268 : */
269 1 : int bt_rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc);
270 :
271 : /** @brief Allocate the buffer from pool after reserving head room for RFCOMM,
272 : * L2CAP and ACL headers.
273 : *
274 : * @param pool Which pool to take the buffer from.
275 : *
276 : * @return New buffer.
277 : */
278 1 : struct net_buf *bt_rfcomm_create_pdu(struct net_buf_pool *pool);
279 :
280 : /**
281 : * @brief Send Remote Port Negotiation command
282 : *
283 : * @param dlc Pointer to the RFCOMM DLC
284 : * @param rpn Pointer to the RPN parameters to send
285 : *
286 : * @return 0 on success, negative error code on failure
287 : */
288 1 : int bt_rfcomm_send_rpn_cmd(struct bt_rfcomm_dlc *dlc, struct bt_rfcomm_rpn *rpn);
289 :
290 : #ifdef __cplusplus
291 : }
292 : #endif
293 :
294 : /**
295 : * @}
296 : */
297 :
298 : #endif /* ZEPHYR_INCLUDE_BLUETOOTH_RFCOMM_H_ */
|