zephyr/subsys/bluetooth/host/rfcomm_internal.h

168 lines
5.0 KiB
C
Raw Normal View History

/** @file
* @brief Internal APIs for Bluetooth RFCOMM handling.
*/
/*
* Copyright (c) 2015-2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <bluetooth/rfcomm.h>
/* RFCOMM signalling connection specific context */
struct bt_rfcomm_session {
/* L2CAP channel this context is associated with */
struct bt_l2cap_br_chan br_chan;
struct bt_rfcomm_dlc *dlcs;
uint16_t mtu;
uint8_t state;
bt_rfcomm_role_t role;
};
enum {
BT_RFCOMM_STATE_IDLE,
BT_RFCOMM_STATE_INIT,
Bluetooth: RFCOMM: Handle security for incoming connections Added required_sec_level in dlc struct so that user can set it. If current security level is greater than or equal to the required security level then connection will be accepted right away, otherwise security elevation will be reqiested and connection will be accepted once it is done. > ACL Data RX: Handle 256 flags 0x02 dlen 8 Channel: 64 len 4 [PSM 3 mode 0] {chan 0} RFCOMM: Set Async Balance Mode (SABM) (0x2f) Address: 0x0b cr 1 dlci 0x02 Control: 0x3f poll/final 1 Length: 0 FCS: 0x59 < HCI Command: Authentication Requested (0x01|0x0011) plen 2 Handle: 256 > HCI Event: Command Status (0x0f) plen 4 Authentication Requested (0x01|0x0011) ncmd 1 Status: Success (0x00) > HCI Event: Link Key Request (0x17) plen 6 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) < HCI Command: Link Key Request Negative Reply (0x01|0x000c) plen 6 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) > HCI Event: Command Complete (0x0e) plen 10 Link Key Request Negative Reply (0x01|0x000c) ncmd 1 Status: Success (0x00) Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) > HCI Event: IO Capability Request (0x31) plen 6 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) < HCI Command: IO Capability Request Reply (0x01|0x002b) plen 9 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) IO capability: DisplayYesNo (0x01) OOB data: Authentication data not present (0x00) Authentication: Dedicated Bonding - MITM required (0x03) > HCI Event: Command Complete (0x0e) plen 10 IO Capability Request Reply (0x01|0x002b) ncmd 1 Status: Success (0x00) Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) > HCI Event: IO Capability Response (0x32) plen 9 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) IO capability: DisplayYesNo (0x01) OOB data: Authentication data not present (0x00) Authentication: Dedicated Bonding - MITM required (0x03) > HCI Event: User Confirmation Request (0x33) plen 10 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) Passkey: 104251 < HCI Command: User Confirmation Request Reply (0x01|0x002c) plen 6 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) > HCI Event: Command Complete (0x0e) plen 10 User Confirmation Request Reply (0x01|0x002c) ncmd 1 Status: Success (0x00) Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) > HCI Event: Simple Pairing Complete (0x36) plen 7 Status: Success (0x00) Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) > HCI Event: Link Key Notification (0x18) plen 23 Address: A0:A8:CD:40:99:98 (OUI A0-A8-CD) Link key: 7c5e5bbc67268293202913902fd0d5fe Key type: Authenticated Combination key from P-192 (0x05) > HCI Event: Auth Complete (0x06) plen 3 Status: Success (0x00) Handle: 256 > HCI Event: Encryption Key Refresh Complete (0x30) plen 3 Status: Success (0x00) Handle: 256 < HCI Command: Set Connection Encryption (0x01|0x0013) plen 3 Handle: 256 Encryption: Enabled (0x01) > HCI Event: Command Status (0x0f) plen 4 Set Connection Encryption (0x01|0x0013) ncmd 1 Status: Success (0x00) > HCI Event: Encryption Change (0x08) plen 4 Status: Success (0x00) Handle: 256 Encryption: Enabled with E0 (0x01) < ACL Data TX: Handle 256 flags 0x00 dlen 8 Channel: 64 len 4 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Ack (UA) (0x63) Address: 0x0b cr 1 dlci 0x02 Control: 0x73 poll/final 1 Length: 0 FCS: 0x92 Change-Id: Ia01f2984dda77d58b724f869eb526734f1846ad6 Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
2016-10-03 23:33:52 +08:00
BT_RFCOMM_STATE_SECURITY_PENDING,
BT_RFCOMM_STATE_CONNECTING,
BT_RFCOMM_STATE_CONNECTED,
BT_RFCOMM_STATE_CONFIG,
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
Bluetooth: RFCOMM: Perform MSC transaction after dlc MSC (Modem status command) is used to convey RS-232 control and break signals. This shall be sent prior to any user data after dlc. Remote also would have sent it which is handled in this patch This has meaning only if a port emulation entity is there on top (which is not there in zephyr right now). So currently v24 signal is hard coded like below. DV = 1 IC = 0 RTR = 1 RTC = 1 FC = 0 EXT = 0 < ACL Data TX: Handle 256 flags 0x00 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x01 cr 0 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0xaa MCC Message type: Modem Status Command CMD (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 > ACL Data RX: Handle 256 flags 0x02 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x03 cr 1 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0x70 MCC Message type: Modem Status Command CMD (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 < ACL Data TX: Handle 256 flags 0x00 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x01 cr 0 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0xaa MCC Message type: Modem Status Command RSP (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 > ACL Data RX: Handle 256 flags 0x02 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x03 cr 1 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0x70 MCC Message type: Modem Status Command RSP (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 Change-Id: Iab06f12de2f2357485309eb622c8c5e13db7011c Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
2016-08-22 20:47:29 +08:00
struct bt_rfcomm_msc {
uint8_t dlci;
uint8_t v24_signal;
} __packed;
#define BT_RFCOMM_DISC 0x43
#define BT_RFCOMM_DM 0x0f
Bluetooth: RFCOMM: Perform MSC transaction after dlc MSC (Modem status command) is used to convey RS-232 control and break signals. This shall be sent prior to any user data after dlc. Remote also would have sent it which is handled in this patch This has meaning only if a port emulation entity is there on top (which is not there in zephyr right now). So currently v24 signal is hard coded like below. DV = 1 IC = 0 RTR = 1 RTC = 1 FC = 0 EXT = 0 < ACL Data TX: Handle 256 flags 0x00 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x01 cr 0 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0xaa MCC Message type: Modem Status Command CMD (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 > ACL Data RX: Handle 256 flags 0x02 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x03 cr 1 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0x70 MCC Message type: Modem Status Command CMD (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 < ACL Data TX: Handle 256 flags 0x00 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x01 cr 0 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0xaa MCC Message type: Modem Status Command RSP (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 > ACL Data RX: Handle 256 flags 0x02 dlen 12 Channel: 64 len 8 [PSM 3 mode 0] {chan 0} RFCOMM: Unnumbered Info with Header Check (UIH) (0xef) Address: 0x03 cr 1 dlci 0x00 Control: 0xef poll/final 0 Length: 4 FCS: 0x70 MCC Message type: Modem Status Command RSP (0x38) Length: 2 dlci 2 fc 0 rtc 1 rtr 1 ic 0 dv 1 Change-Id: Iab06f12de2f2357485309eb622c8c5e13db7011c Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
2016-08-22 20:47:29 +08:00
/* DV = 1 IC = 0 RTR = 1 RTC = 1 FC = 0 EXT = 0 */
#define BT_RFCOMM_DEFAULT_V24_SIG 0x8d
#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) (CONFIG_BLUETOOTH_HCI_SEND_RESERVE + \
sizeof(struct bt_hci_acl_hdr) + \
sizeof(struct bt_l2cap_hdr) + \
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
2016-10-25 00:39:27 +08:00
#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
/* Initialize RFCOMM signal layer */
void bt_rfcomm_init(void);