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 #define BT_RFCOMM_GET_DLCI(addr)                  (((addr) & 0xfc) >> 2)
137 #define BT_RFCOMM_GET_FRAME_TYPE(ctrl)            ((ctrl) & 0xef)
138 #define BT_RFCOMM_GET_MSG_TYPE(type)              (((type) & 0xfc) >> 2)
139 #define BT_RFCOMM_GET_MSG_CR(type)                (((type) & 0x02) >> 1)
140 #define BT_RFCOMM_GET_LEN(len)                    (((len) & 0xfe) >> 1)
141 #define BT_RFCOMM_GET_LEN_EXTENDED(first, second) ((((first) & 0xfe) >> 1) | ((second) << 7))
142 #define BT_RFCOMM_GET_CHANNEL(dlci)               ((dlci) >> 1)
143 #define BT_RFCOMM_GET_PF(ctrl)                    (((ctrl) & 0x10) >> 4)
144 
145 #define BT_RFCOMM_SET_ADDR(dlci, cr)       ((((dlci) & 0x3f) << 2) | \
146 					    ((cr) << 1) | 0x01)
147 #define BT_RFCOMM_SET_CTRL(type, pf)       (((type) & 0xef) | ((pf) << 4))
148 #define BT_RFCOMM_SET_LEN_8(len)           (((len) << 1) | 1)
149 #define BT_RFCOMM_SET_LEN_16(len)          ((len) << 1)
150 #define BT_RFCOMM_SET_MSG_TYPE(type, cr)   (((type) << 2) | (cr << 1) | 0x01)
151 
152 #define BT_RFCOMM_LEN_EXTENDED(len)        (!((len) & 0x01))
153 
154 /* For CR in UIH Packet header
155  * Initiating station have the C/R bit set to 1 and those sent by the
156  * responding station have the C/R bit set to 0
157  */
158 #define BT_RFCOMM_UIH_CR(role)             ((role) == BT_RFCOMM_ROLE_INITIATOR)
159 
160 /* For CR in Non UIH Packet header
161  * Command
162  * Initiator --> Responder 1
163  * Responder --> Initiator 0
164  * Response
165  * Initiator --> Responder 0
166  * Responder --> Initiator 1
167  */
168 #define BT_RFCOMM_CMD_CR(role)             ((role) == BT_RFCOMM_ROLE_INITIATOR)
169 #define BT_RFCOMM_RESP_CR(role)            ((role) == BT_RFCOMM_ROLE_ACCEPTOR)
170 
171 /* For CR in MSG header
172  * If the C/R bit is set to 1 the message is a command,
173  * if it is set to 0 the message is a response.
174  */
175 #define BT_RFCOMM_MSG_CMD_CR               1
176 #define BT_RFCOMM_MSG_RESP_CR              0
177 
178 #define BT_RFCOMM_DLCI(role, channel)      ((((channel) & 0x1f) << 1) | \
179 					    ((role) == BT_RFCOMM_ROLE_ACCEPTOR))
180 
181 /* Excluding ext bit */
182 #define BT_RFCOMM_MAX_LEN_8 127
183 
184 /* Length can be 2 bytes depending on data size */
185 #define BT_RFCOMM_HDR_SIZE  (sizeof(struct bt_rfcomm_hdr) + 1)
186 
187 #define BT_RFCOMM_FCS_LEN_UIH      2
188 #define BT_RFCOMM_FCS_LEN_NON_UIH  3
189 
190 /* For non UIH packets
191  * The P bit set to 1 shall be used to solicit a response frame with the
192  * F bit set to 1 from the other station.
193  */
194 #define BT_RFCOMM_PF_NON_UIH         1
195 
196 /* For UIH packets
197  * Both stations set the P-bit to 0
198  * If credit based flow control is used, If P/F is 1 then one credit byte
199  * will be there after control in the frame else no credit byte.
200  */
201 #define BT_RFCOMM_PF_UIH             0
202 #define BT_RFCOMM_PF_UIH_CREDIT      1
203 #define BT_RFCOMM_PF_UIH_NO_CREDIT   0
204 
205 #define BT_RFCOMM_PN_CFC_CMD   0xf0
206 #define BT_RFCOMM_PN_CFC_RESP  0xe0
207 
208 /* Initialize RFCOMM signal layer */
209 void bt_rfcomm_init(void);
210