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 
67 /** @brief Role of RFCOMM session and dlc. Used only by internal APIs
68  */
69 typedef enum bt_rfcomm_role {
70 	BT_RFCOMM_ROLE_ACCEPTOR,
71 	BT_RFCOMM_ROLE_INITIATOR
72 } __packed bt_rfcomm_role_t;
73 
74 /** @brief RFCOMM DLC structure. */
75 struct bt_rfcomm_dlc {
76 	/* Response Timeout eXpired (RTX) timer */
77 	struct k_work_delayable    rtx_work;
78 
79 	/* Queue for outgoing data */
80 	struct k_fifo              tx_queue;
81 
82 	/* TX credits, Reuse as a binary sem for MSC FC if CFC is not enabled */
83 	struct k_sem               tx_credits;
84 
85 	struct bt_rfcomm_session  *session;
86 	struct bt_rfcomm_dlc_ops  *ops;
87 	struct bt_rfcomm_dlc      *_next;
88 
89 	bt_security_t              required_sec_level;
90 	bt_rfcomm_role_t           role;
91 
92 	uint16_t                      mtu;
93 	uint8_t                       dlci;
94 	uint8_t                       state;
95 	uint8_t                       rx_credit;
96 
97 	/* Stack & kernel data for TX thread */
98 	struct k_thread            tx_thread;
99 	K_KERNEL_STACK_MEMBER(stack, 256);
100 };
101 
102 struct bt_rfcomm_server {
103 	/** Server Channel */
104 	uint8_t channel;
105 
106 	/** Server accept callback
107 	 *
108 	 *  This callback is called whenever a new incoming connection requires
109 	 *  authorization.
110 	 *
111 	 *  @param conn The connection that is requesting authorization
112 	 *  @param dlc Pointer to received the allocated dlc
113 	 *
114 	 *  @return 0 in case of success or negative value in case of error.
115 	 */
116 	int (*accept)(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc);
117 
118 	struct bt_rfcomm_server	*_next;
119 };
120 
121 /** @brief Register RFCOMM server
122  *
123  *  Register RFCOMM server for a channel, each new connection is authorized
124  *  using the accept() callback which in case of success shall allocate the dlc
125  *  structure to be used by the new connection.
126  *
127  *  @param server Server structure.
128  *
129  *  @return 0 in case of success or negative value in case of error.
130  */
131 int bt_rfcomm_server_register(struct bt_rfcomm_server *server);
132 
133 /** @brief Connect RFCOMM channel
134  *
135  *  Connect RFCOMM dlc by channel, once the connection is completed dlc
136  *  connected() callback will be called. If the connection is rejected
137  *  disconnected() callback is called instead.
138  *
139  *  @param conn Connection object.
140  *  @param dlc Dlc object.
141  *  @param channel Server channel to connect to.
142  *
143  *  @return 0 in case of success or negative value in case of error.
144  */
145 int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc,
146 			  uint8_t channel);
147 
148 /** @brief Send data to RFCOMM
149  *
150  *  Send data from buffer to the dlc. Length should be less than or equal to
151  *  mtu.
152  *
153  *  @param dlc Dlc object.
154  *  @param buf Data buffer.
155  *
156  *  @return Bytes sent in case of success or negative value in case of error.
157  */
158 int bt_rfcomm_dlc_send(struct bt_rfcomm_dlc *dlc, struct net_buf *buf);
159 
160 /** @brief Disconnect RFCOMM dlc
161  *
162  *  Disconnect RFCOMM dlc, if the connection is pending it will be
163  *  canceled and as a result the dlc disconnected() callback is called.
164  *
165  *  @param dlc Dlc object.
166  *
167  *  @return 0 in case of success or negative value in case of error.
168  */
169 int bt_rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc);
170 
171 /** @brief Allocate the buffer from pool after reserving head room for RFCOMM,
172  *  L2CAP and ACL headers.
173  *
174  *  @param pool Which pool to take the buffer from.
175  *
176  *  @return New buffer.
177  */
178 struct net_buf *bt_rfcomm_create_pdu(struct net_buf_pool *pool);
179 
180 #ifdef __cplusplus
181 }
182 #endif
183 
184 /**
185  * @}
186  */
187 
188 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_RFCOMM_H_ */
189