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