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