1 /** @file
2  *  @brief Internal APIs for Bluetooth RFCOMM handling.
3  */
4 
5 /*
6  * Copyright (c) 2015-2016 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #include <zephyr/bluetooth/classic/rfcomm.h>
12 
13 typedef enum {
14 	BT_RFCOMM_CFC_UNKNOWN,
15 	BT_RFCOMM_CFC_NOT_SUPPORTED,
16 	BT_RFCOMM_CFC_SUPPORTED,
17 } __packed bt_rfcomm_cfc_t;
18 
19 /* RFCOMM signalling connection specific context */
20 struct bt_rfcomm_session {
21 	/* L2CAP channel this context is associated with */
22 	struct bt_l2cap_br_chan br_chan;
23 	/* Response Timeout eXpired (RTX) timer */
24 	struct k_work_delayable rtx_work;
25 	/* Binary sem for aggregate fc */
26 	struct k_sem fc;
27 	struct bt_rfcomm_dlc *dlcs;
28 	uint16_t mtu;
29 	uint8_t state;
30 	bt_rfcomm_role_t role;
31 	bt_rfcomm_cfc_t cfc;
32 };
33 
34 enum {
35 	BT_RFCOMM_STATE_IDLE,
36 	BT_RFCOMM_STATE_INIT,
37 	BT_RFCOMM_STATE_SECURITY_PENDING,
38 	BT_RFCOMM_STATE_CONNECTING,
39 	BT_RFCOMM_STATE_CONNECTED,
40 	BT_RFCOMM_STATE_CONFIG,
41 	BT_RFCOMM_STATE_USER_DISCONNECT,
42 	BT_RFCOMM_STATE_DISCONNECTING,
43 	BT_RFCOMM_STATE_DISCONNECTED,
44 };
45 
46 struct bt_rfcomm_hdr {
47 	uint8_t address;
48 	uint8_t control;
49 	uint8_t length;
50 } __packed;
51 
52 struct bt_rfcomm_hdr_ext {
53 	struct bt_rfcomm_hdr hdr;
54 	uint8_t second_length;
55 } __packed;
56 
57 #define BT_RFCOMM_SABM  0x2f
58 #define BT_RFCOMM_UA    0x63
59 #define BT_RFCOMM_UIH   0xef
60 
61 struct bt_rfcomm_msg_hdr {
62 	uint8_t type;
63 	uint8_t len;
64 } __packed;
65 
66 #define BT_RFCOMM_PN    0x20
67 struct bt_rfcomm_pn {
68 	uint8_t  dlci;
69 	uint8_t  flow_ctrl;
70 	uint8_t  priority;
71 	uint8_t  ack_timer;
72 	uint16_t mtu;
73 	uint8_t  max_retrans;
74 	uint8_t  credits;
75 } __packed;
76 
77 #define BT_RFCOMM_MSC    0x38
78 struct bt_rfcomm_msc {
79 	uint8_t  dlci;
80 	uint8_t  v24_signal;
81 } __packed;
82 
83 #define BT_RFCOMM_DISC  0x43
84 #define BT_RFCOMM_DM    0x0f
85 
86 #define BT_RFCOMM_RLS   0x14
87 struct bt_rfcomm_rls {
88 	uint8_t  dlci;
89 	uint8_t  line_status;
90 } __packed;
91 
92 #define BT_RFCOMM_RPN   0x24
93 struct bt_rfcomm_rpn {
94 	uint8_t  dlci;
95 	uint8_t  baud_rate;
96 	uint8_t  line_settings;
97 	uint8_t  flow_control;
98 	uint8_t  xon_char;
99 	uint8_t  xoff_char;
100 	uint16_t param_mask;
101 } __packed;
102 
103 #define BT_RFCOMM_TEST  0x08
104 #define BT_RFCOMM_NSC   0x04
105 
106 #define BT_RFCOMM_FCON  0x28
107 #define BT_RFCOMM_FCOFF 0x18
108 
109 /* Default RPN Settings */
110 #define BT_RFCOMM_RPN_BAUD_RATE_9600    0x03
111 #define BT_RFCOMM_RPN_DATA_BITS_8       0x03
112 #define BT_RFCOMM_RPN_STOP_BITS_1       0x00
113 #define BT_RFCOMM_RPN_PARITY_NONE       0x00
114 #define BT_RFCOMM_RPN_FLOW_NONE         0x00
115 #define BT_RFCOMM_RPN_XON_CHAR          0x11
116 #define BT_RFCOMM_RPN_XOFF_CHAR         0x13
117 
118 /* Set 1 to all the param mask except reserved */
119 #define BT_RFCOMM_RPN_PARAM_MASK_ALL    0x3f7f
120 
121 #define BT_RFCOMM_SET_LINE_SETTINGS(data, stop, parity) ((data & 0x3) | \
122 							 ((stop & 0x1) << 2) | \
123 							 ((parity & 0x7) << 3))
124 
125 /* DV = 1 IC = 0 RTR = 1 RTC = 1 FC = 0 EXT = 0 */
126 #define BT_RFCOMM_DEFAULT_V24_SIG 0x8d
127 
128 #define BT_RFCOMM_GET_FC(v24_signal) (((v24_signal) & 0x02) >> 1)
129 
130 #define BT_RFCOMM_SIG_MIN_MTU   23
131 #define BT_RFCOMM_SIG_MAX_MTU   32767
132 
133 #define BT_RFCOMM_CHECK_MTU(mtu) (!!((mtu) >= BT_RFCOMM_SIG_MIN_MTU && \
134 				     (mtu) <= BT_RFCOMM_SIG_MAX_MTU))
135 
136 /* Helper to calculate needed outgoing buffer size.
137  * Length in rfcomm header can be two bytes depending on user data length.
138  * One byte in the tail should be reserved for FCS.
139  */
140 #define BT_RFCOMM_BUF_SIZE(mtu) (BT_BUF_RESERVE + \
141 				 BT_HCI_ACL_HDR_SIZE + BT_L2CAP_HDR_SIZE + \
142 				 sizeof(struct bt_rfcomm_hdr) + 1 + (mtu) + \
143 				 BT_RFCOMM_FCS_SIZE)
144 
145 #define BT_RFCOMM_GET_DLCI(addr)                  (((addr) & 0xfc) >> 2)
146 #define BT_RFCOMM_GET_FRAME_TYPE(ctrl)            ((ctrl) & 0xef)
147 #define BT_RFCOMM_GET_MSG_TYPE(type)              (((type) & 0xfc) >> 2)
148 #define BT_RFCOMM_GET_MSG_CR(type)                (((type) & 0x02) >> 1)
149 #define BT_RFCOMM_GET_LEN(len)                    (((len) & 0xfe) >> 1)
150 #define BT_RFCOMM_GET_LEN_EXTENDED(first, second) ((((first) & 0xfe) >> 1) | ((second) << 7))
151 #define BT_RFCOMM_GET_CHANNEL(dlci)               ((dlci) >> 1)
152 #define BT_RFCOMM_GET_PF(ctrl)                    (((ctrl) & 0x10) >> 4)
153 
154 #define BT_RFCOMM_SET_ADDR(dlci, cr)       ((((dlci) & 0x3f) << 2) | \
155 					    ((cr) << 1) | 0x01)
156 #define BT_RFCOMM_SET_CTRL(type, pf)       (((type) & 0xef) | ((pf) << 4))
157 #define BT_RFCOMM_SET_LEN_8(len)           (((len) << 1) | 1)
158 #define BT_RFCOMM_SET_LEN_16(len)          ((len) << 1)
159 #define BT_RFCOMM_SET_MSG_TYPE(type, cr)   (((type) << 2) | (cr << 1) | 0x01)
160 
161 #define BT_RFCOMM_LEN_EXTENDED(len)        (!((len) & 0x01))
162 
163 /* For CR in UIH Packet header
164  * Initiating station have the C/R bit set to 1 and those sent by the
165  * responding station have the C/R bit set to 0
166  */
167 #define BT_RFCOMM_UIH_CR(role)             ((role) == BT_RFCOMM_ROLE_INITIATOR)
168 
169 /* For CR in Non UIH Packet header
170  * Command
171  * Initiator --> Responder 1
172  * Responder --> Initiator 0
173  * Response
174  * Initiator --> Responder 0
175  * Responder --> Initiator 1
176  */
177 #define BT_RFCOMM_CMD_CR(role)             ((role) == BT_RFCOMM_ROLE_INITIATOR)
178 #define BT_RFCOMM_RESP_CR(role)            ((role) == BT_RFCOMM_ROLE_ACCEPTOR)
179 
180 /* For CR in MSG header
181  * If the C/R bit is set to 1 the message is a command,
182  * if it is set to 0 the message is a response.
183  */
184 #define BT_RFCOMM_MSG_CMD_CR               1
185 #define BT_RFCOMM_MSG_RESP_CR              0
186 
187 #define BT_RFCOMM_DLCI(role, channel)      ((((channel) & 0x1f) << 1) | \
188 					    ((role) == BT_RFCOMM_ROLE_ACCEPTOR))
189 
190 /* Excluding ext bit */
191 #define BT_RFCOMM_MAX_LEN_8 127
192 
193 /* Length can be 2 bytes depending on data size */
194 #define BT_RFCOMM_HDR_SIZE  (sizeof(struct bt_rfcomm_hdr) + 1)
195 #define BT_RFCOMM_FCS_SIZE  1
196 
197 #define BT_RFCOMM_FCS_LEN_UIH      2
198 #define BT_RFCOMM_FCS_LEN_NON_UIH  3
199 
200 /* For non UIH packets
201  * The P bit set to 1 shall be used to solicit a response frame with the
202  * F bit set to 1 from the other station.
203  */
204 #define BT_RFCOMM_PF_NON_UIH         1
205 
206 /* For UIH packets
207  * Both stations set the P-bit to 0
208  * If credit based flow control is used, If P/F is 1 then one credit byte
209  * will be there after control in the frame else no credit byte.
210  */
211 #define BT_RFCOMM_PF_UIH             0
212 #define BT_RFCOMM_PF_UIH_CREDIT      1
213 #define BT_RFCOMM_PF_UIH_NO_CREDIT   0
214 
215 #define BT_RFCOMM_PN_CFC_CMD   0xf0
216 #define BT_RFCOMM_PN_CFC_RESP  0xe0
217 
218 /* Initialize RFCOMM signal layer */
219 void bt_rfcomm_init(void);
220