blob: 3b94a9829f286fe22c71f55762f8f78f22737554 [file] [log] [blame]
/** @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);