You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
5.0 KiB
184 lines
5.0 KiB
/** @file |
|
* @brief Internal APIs for Bluetooth RFCOMM handling. |
|
*/ |
|
|
|
/* |
|
* Copyright (c) 2015-2016 Intel Corporation |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include <zephyr/bluetooth/classic/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; |
|
|
|
struct bt_rfcomm_hdr_ext { |
|
struct bt_rfcomm_hdr hdr; |
|
uint8_t second_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 |
|
|
|
#define BT_RFCOMM_TEST 0x08 |
|
#define BT_RFCOMM_NSC 0x04 |
|
|
|
#define BT_RFCOMM_FCON 0x28 |
|
#define BT_RFCOMM_FCOFF 0x18 |
|
|
|
/* 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)) |
|
|
|
#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_LEN_EXTENDED(first, second) ((((first) & 0xfe) >> 1) | ((second) << 7)) |
|
#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_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);
|
|
|