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 
94 #define BT_RFCOMM_TEST  0x08
95 #define BT_RFCOMM_NSC   0x04
96 
97 #define BT_RFCOMM_FCON  0x28
98 #define BT_RFCOMM_FCOFF 0x18
99 
100 /* DV = 1 IC = 0 RTR = 1 RTC = 1 FC = 0 EXT = 0 */
101 #define BT_RFCOMM_DEFAULT_V24_SIG 0x8d
102 
103 #define BT_RFCOMM_GET_FC(v24_signal) (((v24_signal) & 0x02) >> 1)
104 
105 #define BT_RFCOMM_SIG_MIN_MTU   23
106 #define BT_RFCOMM_SIG_MAX_MTU   32767
107 
108 #define BT_RFCOMM_CHECK_MTU(mtu) (!!((mtu) >= BT_RFCOMM_SIG_MIN_MTU && \
109 				     (mtu) <= BT_RFCOMM_SIG_MAX_MTU))
110 
111 #define BT_RFCOMM_GET_DLCI(addr)                  (((addr) & 0xfc) >> 2)
112 #define BT_RFCOMM_GET_FRAME_TYPE(ctrl)            ((ctrl) & 0xef)
113 #define BT_RFCOMM_GET_MSG_TYPE(type)              (((type) & 0xfc) >> 2)
114 #define BT_RFCOMM_GET_MSG_CR(type)                (((type) & 0x02) >> 1)
115 #define BT_RFCOMM_GET_LEN(len)                    (((len) & 0xfe) >> 1)
116 #define BT_RFCOMM_GET_LEN_EXTENDED(first, second) ((((first) & 0xfe) >> 1) | ((second) << 7))
117 #define BT_RFCOMM_GET_CHANNEL(dlci)               ((dlci) >> 1)
118 #define BT_RFCOMM_GET_PF(ctrl)                    (((ctrl) & 0x10) >> 4)
119 
120 #define BT_RFCOMM_SET_ADDR(dlci, cr)       ((((dlci) & 0x3f) << 2) | \
121 					    ((cr) << 1) | 0x01)
122 #define BT_RFCOMM_SET_CTRL(type, pf)       (((type) & 0xef) | ((pf) << 4))
123 #define BT_RFCOMM_SET_LEN_8(len)           (((len) << 1) | 1)
124 #define BT_RFCOMM_SET_LEN_16(len)          ((len) << 1)
125 #define BT_RFCOMM_SET_MSG_TYPE(type, cr)   (((type) << 2) | (cr << 1) | 0x01)
126 
127 #define BT_RFCOMM_LEN_EXTENDED(len)        (!((len) & 0x01))
128 
129 /* For CR in UIH Packet header
130  * Initiating station have the C/R bit set to 1 and those sent by the
131  * responding station have the C/R bit set to 0
132  */
133 #define BT_RFCOMM_UIH_CR(role)             ((role) == BT_RFCOMM_ROLE_INITIATOR)
134 
135 /* For CR in Non UIH Packet header
136  * Command
137  * Initiator --> Responder 1
138  * Responder --> Initiator 0
139  * Response
140  * Initiator --> Responder 0
141  * Responder --> Initiator 1
142  */
143 #define BT_RFCOMM_CMD_CR(role)             ((role) == BT_RFCOMM_ROLE_INITIATOR)
144 #define BT_RFCOMM_RESP_CR(role)            ((role) == BT_RFCOMM_ROLE_ACCEPTOR)
145 
146 /* For CR in MSG header
147  * If the C/R bit is set to 1 the message is a command,
148  * if it is set to 0 the message is a response.
149  */
150 #define BT_RFCOMM_MSG_CMD_CR               1
151 #define BT_RFCOMM_MSG_RESP_CR              0
152 
153 #define BT_RFCOMM_DLCI(role, channel)      ((((channel) & 0x1f) << 1) | \
154 					    ((role) == BT_RFCOMM_ROLE_ACCEPTOR))
155 
156 /* Excluding ext bit */
157 #define BT_RFCOMM_MAX_LEN_8 127
158 
159 /* Length can be 2 bytes depending on data size */
160 #define BT_RFCOMM_HDR_SIZE  (sizeof(struct bt_rfcomm_hdr) + 1)
161 
162 #define BT_RFCOMM_FCS_LEN_UIH      2
163 #define BT_RFCOMM_FCS_LEN_NON_UIH  3
164 
165 /* For non UIH packets
166  * The P bit set to 1 shall be used to solicit a response frame with the
167  * F bit set to 1 from the other station.
168  */
169 #define BT_RFCOMM_PF_NON_UIH         1
170 
171 /* For UIH packets
172  * Both stations set the P-bit to 0
173  * If credit based flow control is used, If P/F is 1 then one credit byte
174  * will be there after control in the frame else no credit byte.
175  */
176 #define BT_RFCOMM_PF_UIH             0
177 #define BT_RFCOMM_PF_UIH_CREDIT      1
178 #define BT_RFCOMM_PF_UIH_NO_CREDIT   0
179 
180 #define BT_RFCOMM_PN_CFC_CMD   0xf0
181 #define BT_RFCOMM_PN_CFC_RESP  0xe0
182 
183 /* Initialize RFCOMM signal layer */
184 void bt_rfcomm_init(void);
185