162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci BlueZ - Bluetooth protocol stack for Linux 362306a36Sopenharmony_ci Copyright (C) 2000-2001 Qualcomm Incorporated 462306a36Sopenharmony_ci Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> 562306a36Sopenharmony_ci Copyright (C) 2010 Google Inc. 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci This program is free software; you can redistribute it and/or modify 1062306a36Sopenharmony_ci it under the terms of the GNU General Public License version 2 as 1162306a36Sopenharmony_ci published by the Free Software Foundation; 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1462306a36Sopenharmony_ci OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1562306a36Sopenharmony_ci FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 1662306a36Sopenharmony_ci IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 1762306a36Sopenharmony_ci CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 1862306a36Sopenharmony_ci WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1962306a36Sopenharmony_ci ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 2062306a36Sopenharmony_ci OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 2362306a36Sopenharmony_ci COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 2462306a36Sopenharmony_ci SOFTWARE IS DISCLAIMED. 2562306a36Sopenharmony_ci*/ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#ifndef __L2CAP_H 2862306a36Sopenharmony_ci#define __L2CAP_H 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include <asm/unaligned.h> 3162306a36Sopenharmony_ci#include <linux/atomic.h> 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* L2CAP defaults */ 3462306a36Sopenharmony_ci#define L2CAP_DEFAULT_MTU 672 3562306a36Sopenharmony_ci#define L2CAP_DEFAULT_MIN_MTU 48 3662306a36Sopenharmony_ci#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF 3762306a36Sopenharmony_ci#define L2CAP_EFS_DEFAULT_FLUSH_TO 0xFFFFFFFF 3862306a36Sopenharmony_ci#define L2CAP_DEFAULT_TX_WINDOW 63 3962306a36Sopenharmony_ci#define L2CAP_DEFAULT_EXT_WINDOW 0x3FFF 4062306a36Sopenharmony_ci#define L2CAP_DEFAULT_MAX_TX 3 4162306a36Sopenharmony_ci#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */ 4262306a36Sopenharmony_ci#define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ 4362306a36Sopenharmony_ci#define L2CAP_DEFAULT_MAX_PDU_SIZE 1492 /* Sized for AMP packet */ 4462306a36Sopenharmony_ci#define L2CAP_DEFAULT_ACK_TO 200 4562306a36Sopenharmony_ci#define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF 4662306a36Sopenharmony_ci#define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF 4762306a36Sopenharmony_ci#define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF 4862306a36Sopenharmony_ci#define L2CAP_BREDR_MAX_PAYLOAD 1019 /* 3-DH5 packet */ 4962306a36Sopenharmony_ci#define L2CAP_LE_MIN_MTU 23 5062306a36Sopenharmony_ci#define L2CAP_ECRED_CONN_SCID_MAX 5 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100) 5362306a36Sopenharmony_ci#define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000) 5462306a36Sopenharmony_ci#define L2CAP_ENC_TIMEOUT msecs_to_jiffies(5000) 5562306a36Sopenharmony_ci#define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000) 5662306a36Sopenharmony_ci#define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) 5762306a36Sopenharmony_ci#define L2CAP_MOVE_TIMEOUT msecs_to_jiffies(4000) 5862306a36Sopenharmony_ci#define L2CAP_MOVE_ERTX_TIMEOUT msecs_to_jiffies(60000) 5962306a36Sopenharmony_ci#define L2CAP_WAIT_ACK_POLL_PERIOD msecs_to_jiffies(200) 6062306a36Sopenharmony_ci#define L2CAP_WAIT_ACK_TIMEOUT msecs_to_jiffies(10000) 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* L2CAP socket address */ 6362306a36Sopenharmony_cistruct sockaddr_l2 { 6462306a36Sopenharmony_ci sa_family_t l2_family; 6562306a36Sopenharmony_ci __le16 l2_psm; 6662306a36Sopenharmony_ci bdaddr_t l2_bdaddr; 6762306a36Sopenharmony_ci __le16 l2_cid; 6862306a36Sopenharmony_ci __u8 l2_bdaddr_type; 6962306a36Sopenharmony_ci}; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* L2CAP socket options */ 7262306a36Sopenharmony_ci#define L2CAP_OPTIONS 0x01 7362306a36Sopenharmony_cistruct l2cap_options { 7462306a36Sopenharmony_ci __u16 omtu; 7562306a36Sopenharmony_ci __u16 imtu; 7662306a36Sopenharmony_ci __u16 flush_to; 7762306a36Sopenharmony_ci __u8 mode; 7862306a36Sopenharmony_ci __u8 fcs; 7962306a36Sopenharmony_ci __u8 max_tx; 8062306a36Sopenharmony_ci __u16 txwin_size; 8162306a36Sopenharmony_ci}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define L2CAP_CONNINFO 0x02 8462306a36Sopenharmony_cistruct l2cap_conninfo { 8562306a36Sopenharmony_ci __u16 hci_handle; 8662306a36Sopenharmony_ci __u8 dev_class[3]; 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci#define L2CAP_LM 0x03 9062306a36Sopenharmony_ci#define L2CAP_LM_MASTER 0x0001 9162306a36Sopenharmony_ci#define L2CAP_LM_AUTH 0x0002 9262306a36Sopenharmony_ci#define L2CAP_LM_ENCRYPT 0x0004 9362306a36Sopenharmony_ci#define L2CAP_LM_TRUSTED 0x0008 9462306a36Sopenharmony_ci#define L2CAP_LM_RELIABLE 0x0010 9562306a36Sopenharmony_ci#define L2CAP_LM_SECURE 0x0020 9662306a36Sopenharmony_ci#define L2CAP_LM_FIPS 0x0040 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/* L2CAP command codes */ 9962306a36Sopenharmony_ci#define L2CAP_COMMAND_REJ 0x01 10062306a36Sopenharmony_ci#define L2CAP_CONN_REQ 0x02 10162306a36Sopenharmony_ci#define L2CAP_CONN_RSP 0x03 10262306a36Sopenharmony_ci#define L2CAP_CONF_REQ 0x04 10362306a36Sopenharmony_ci#define L2CAP_CONF_RSP 0x05 10462306a36Sopenharmony_ci#define L2CAP_DISCONN_REQ 0x06 10562306a36Sopenharmony_ci#define L2CAP_DISCONN_RSP 0x07 10662306a36Sopenharmony_ci#define L2CAP_ECHO_REQ 0x08 10762306a36Sopenharmony_ci#define L2CAP_ECHO_RSP 0x09 10862306a36Sopenharmony_ci#define L2CAP_INFO_REQ 0x0a 10962306a36Sopenharmony_ci#define L2CAP_INFO_RSP 0x0b 11062306a36Sopenharmony_ci#define L2CAP_CONN_PARAM_UPDATE_REQ 0x12 11162306a36Sopenharmony_ci#define L2CAP_CONN_PARAM_UPDATE_RSP 0x13 11262306a36Sopenharmony_ci#define L2CAP_LE_CONN_REQ 0x14 11362306a36Sopenharmony_ci#define L2CAP_LE_CONN_RSP 0x15 11462306a36Sopenharmony_ci#define L2CAP_LE_CREDITS 0x16 11562306a36Sopenharmony_ci#define L2CAP_ECRED_CONN_REQ 0x17 11662306a36Sopenharmony_ci#define L2CAP_ECRED_CONN_RSP 0x18 11762306a36Sopenharmony_ci#define L2CAP_ECRED_RECONF_REQ 0x19 11862306a36Sopenharmony_ci#define L2CAP_ECRED_RECONF_RSP 0x1a 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/* L2CAP extended feature mask */ 12162306a36Sopenharmony_ci#define L2CAP_FEAT_FLOWCTL 0x00000001 12262306a36Sopenharmony_ci#define L2CAP_FEAT_RETRANS 0x00000002 12362306a36Sopenharmony_ci#define L2CAP_FEAT_BIDIR_QOS 0x00000004 12462306a36Sopenharmony_ci#define L2CAP_FEAT_ERTM 0x00000008 12562306a36Sopenharmony_ci#define L2CAP_FEAT_STREAMING 0x00000010 12662306a36Sopenharmony_ci#define L2CAP_FEAT_FCS 0x00000020 12762306a36Sopenharmony_ci#define L2CAP_FEAT_EXT_FLOW 0x00000040 12862306a36Sopenharmony_ci#define L2CAP_FEAT_FIXED_CHAN 0x00000080 12962306a36Sopenharmony_ci#define L2CAP_FEAT_EXT_WINDOW 0x00000100 13062306a36Sopenharmony_ci#define L2CAP_FEAT_UCD 0x00000200 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci/* L2CAP checksum option */ 13362306a36Sopenharmony_ci#define L2CAP_FCS_NONE 0x00 13462306a36Sopenharmony_ci#define L2CAP_FCS_CRC16 0x01 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci/* L2CAP fixed channels */ 13762306a36Sopenharmony_ci#define L2CAP_FC_SIG_BREDR 0x02 13862306a36Sopenharmony_ci#define L2CAP_FC_CONNLESS 0x04 13962306a36Sopenharmony_ci#define L2CAP_FC_ATT 0x10 14062306a36Sopenharmony_ci#define L2CAP_FC_SIG_LE 0x20 14162306a36Sopenharmony_ci#define L2CAP_FC_SMP_LE 0x40 14262306a36Sopenharmony_ci#define L2CAP_FC_SMP_BREDR 0x80 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/* L2CAP Control Field bit masks */ 14562306a36Sopenharmony_ci#define L2CAP_CTRL_SAR 0xC000 14662306a36Sopenharmony_ci#define L2CAP_CTRL_REQSEQ 0x3F00 14762306a36Sopenharmony_ci#define L2CAP_CTRL_TXSEQ 0x007E 14862306a36Sopenharmony_ci#define L2CAP_CTRL_SUPERVISE 0x000C 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci#define L2CAP_CTRL_RETRANS 0x0080 15162306a36Sopenharmony_ci#define L2CAP_CTRL_FINAL 0x0080 15262306a36Sopenharmony_ci#define L2CAP_CTRL_POLL 0x0010 15362306a36Sopenharmony_ci#define L2CAP_CTRL_FRAME_TYPE 0x0001 /* I- or S-Frame */ 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci#define L2CAP_CTRL_TXSEQ_SHIFT 1 15662306a36Sopenharmony_ci#define L2CAP_CTRL_SUPER_SHIFT 2 15762306a36Sopenharmony_ci#define L2CAP_CTRL_POLL_SHIFT 4 15862306a36Sopenharmony_ci#define L2CAP_CTRL_FINAL_SHIFT 7 15962306a36Sopenharmony_ci#define L2CAP_CTRL_REQSEQ_SHIFT 8 16062306a36Sopenharmony_ci#define L2CAP_CTRL_SAR_SHIFT 14 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci/* L2CAP Extended Control Field bit mask */ 16362306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_TXSEQ 0xFFFC0000 16462306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_SAR 0x00030000 16562306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_SUPERVISE 0x00030000 16662306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_REQSEQ 0x0000FFFC 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_POLL 0x00040000 16962306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_FINAL 0x00000002 17062306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_FRAME_TYPE 0x00000001 /* I- or S-Frame */ 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_FINAL_SHIFT 1 17362306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_REQSEQ_SHIFT 2 17462306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_SAR_SHIFT 16 17562306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_SUPER_SHIFT 16 17662306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_POLL_SHIFT 18 17762306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_TXSEQ_SHIFT 18 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci/* L2CAP Supervisory Function */ 18062306a36Sopenharmony_ci#define L2CAP_SUPER_RR 0x00 18162306a36Sopenharmony_ci#define L2CAP_SUPER_REJ 0x01 18262306a36Sopenharmony_ci#define L2CAP_SUPER_RNR 0x02 18362306a36Sopenharmony_ci#define L2CAP_SUPER_SREJ 0x03 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci/* L2CAP Segmentation and Reassembly */ 18662306a36Sopenharmony_ci#define L2CAP_SAR_UNSEGMENTED 0x00 18762306a36Sopenharmony_ci#define L2CAP_SAR_START 0x01 18862306a36Sopenharmony_ci#define L2CAP_SAR_END 0x02 18962306a36Sopenharmony_ci#define L2CAP_SAR_CONTINUE 0x03 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/* L2CAP Command rej. reasons */ 19262306a36Sopenharmony_ci#define L2CAP_REJ_NOT_UNDERSTOOD 0x0000 19362306a36Sopenharmony_ci#define L2CAP_REJ_MTU_EXCEEDED 0x0001 19462306a36Sopenharmony_ci#define L2CAP_REJ_INVALID_CID 0x0002 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/* L2CAP structures */ 19762306a36Sopenharmony_cistruct l2cap_hdr { 19862306a36Sopenharmony_ci __le16 len; 19962306a36Sopenharmony_ci __le16 cid; 20062306a36Sopenharmony_ci} __packed; 20162306a36Sopenharmony_ci#define L2CAP_LEN_SIZE 2 20262306a36Sopenharmony_ci#define L2CAP_HDR_SIZE 4 20362306a36Sopenharmony_ci#define L2CAP_ENH_HDR_SIZE 6 20462306a36Sopenharmony_ci#define L2CAP_EXT_HDR_SIZE 8 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci#define L2CAP_FCS_SIZE 2 20762306a36Sopenharmony_ci#define L2CAP_SDULEN_SIZE 2 20862306a36Sopenharmony_ci#define L2CAP_PSMLEN_SIZE 2 20962306a36Sopenharmony_ci#define L2CAP_ENH_CTRL_SIZE 2 21062306a36Sopenharmony_ci#define L2CAP_EXT_CTRL_SIZE 4 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cistruct l2cap_cmd_hdr { 21362306a36Sopenharmony_ci __u8 code; 21462306a36Sopenharmony_ci __u8 ident; 21562306a36Sopenharmony_ci __le16 len; 21662306a36Sopenharmony_ci} __packed; 21762306a36Sopenharmony_ci#define L2CAP_CMD_HDR_SIZE 4 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistruct l2cap_cmd_rej_unk { 22062306a36Sopenharmony_ci __le16 reason; 22162306a36Sopenharmony_ci} __packed; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_cistruct l2cap_cmd_rej_mtu { 22462306a36Sopenharmony_ci __le16 reason; 22562306a36Sopenharmony_ci __le16 max_mtu; 22662306a36Sopenharmony_ci} __packed; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistruct l2cap_cmd_rej_cid { 22962306a36Sopenharmony_ci __le16 reason; 23062306a36Sopenharmony_ci __le16 scid; 23162306a36Sopenharmony_ci __le16 dcid; 23262306a36Sopenharmony_ci} __packed; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistruct l2cap_conn_req { 23562306a36Sopenharmony_ci __le16 psm; 23662306a36Sopenharmony_ci __le16 scid; 23762306a36Sopenharmony_ci} __packed; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistruct l2cap_conn_rsp { 24062306a36Sopenharmony_ci __le16 dcid; 24162306a36Sopenharmony_ci __le16 scid; 24262306a36Sopenharmony_ci __le16 result; 24362306a36Sopenharmony_ci __le16 status; 24462306a36Sopenharmony_ci} __packed; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci/* protocol/service multiplexer (PSM) */ 24762306a36Sopenharmony_ci#define L2CAP_PSM_SDP 0x0001 24862306a36Sopenharmony_ci#define L2CAP_PSM_RFCOMM 0x0003 24962306a36Sopenharmony_ci#define L2CAP_PSM_3DSP 0x0021 25062306a36Sopenharmony_ci#define L2CAP_PSM_IPSP 0x0023 /* 6LoWPAN */ 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci#define L2CAP_PSM_DYN_START 0x1001 25362306a36Sopenharmony_ci#define L2CAP_PSM_DYN_END 0xffff 25462306a36Sopenharmony_ci#define L2CAP_PSM_AUTO_END 0x10ff 25562306a36Sopenharmony_ci#define L2CAP_PSM_LE_DYN_START 0x0080 25662306a36Sopenharmony_ci#define L2CAP_PSM_LE_DYN_END 0x00ff 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci/* channel identifier */ 25962306a36Sopenharmony_ci#define L2CAP_CID_SIGNALING 0x0001 26062306a36Sopenharmony_ci#define L2CAP_CID_CONN_LESS 0x0002 26162306a36Sopenharmony_ci#define L2CAP_CID_ATT 0x0004 26262306a36Sopenharmony_ci#define L2CAP_CID_LE_SIGNALING 0x0005 26362306a36Sopenharmony_ci#define L2CAP_CID_SMP 0x0006 26462306a36Sopenharmony_ci#define L2CAP_CID_SMP_BREDR 0x0007 26562306a36Sopenharmony_ci#define L2CAP_CID_DYN_START 0x0040 26662306a36Sopenharmony_ci#define L2CAP_CID_DYN_END 0xffff 26762306a36Sopenharmony_ci#define L2CAP_CID_LE_DYN_END 0x007f 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci/* connect/create channel results */ 27062306a36Sopenharmony_ci#define L2CAP_CR_SUCCESS 0x0000 27162306a36Sopenharmony_ci#define L2CAP_CR_PEND 0x0001 27262306a36Sopenharmony_ci#define L2CAP_CR_BAD_PSM 0x0002 27362306a36Sopenharmony_ci#define L2CAP_CR_SEC_BLOCK 0x0003 27462306a36Sopenharmony_ci#define L2CAP_CR_NO_MEM 0x0004 27562306a36Sopenharmony_ci#define L2CAP_CR_INVALID_SCID 0x0006 27662306a36Sopenharmony_ci#define L2CAP_CR_SCID_IN_USE 0x0007 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci/* credit based connect results */ 27962306a36Sopenharmony_ci#define L2CAP_CR_LE_SUCCESS 0x0000 28062306a36Sopenharmony_ci#define L2CAP_CR_LE_BAD_PSM 0x0002 28162306a36Sopenharmony_ci#define L2CAP_CR_LE_NO_MEM 0x0004 28262306a36Sopenharmony_ci#define L2CAP_CR_LE_AUTHENTICATION 0x0005 28362306a36Sopenharmony_ci#define L2CAP_CR_LE_AUTHORIZATION 0x0006 28462306a36Sopenharmony_ci#define L2CAP_CR_LE_BAD_KEY_SIZE 0x0007 28562306a36Sopenharmony_ci#define L2CAP_CR_LE_ENCRYPTION 0x0008 28662306a36Sopenharmony_ci#define L2CAP_CR_LE_INVALID_SCID 0x0009 28762306a36Sopenharmony_ci#define L2CAP_CR_LE_SCID_IN_USE 0X000A 28862306a36Sopenharmony_ci#define L2CAP_CR_LE_UNACCEPT_PARAMS 0X000B 28962306a36Sopenharmony_ci#define L2CAP_CR_LE_INVALID_PARAMS 0X000C 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci/* connect/create channel status */ 29262306a36Sopenharmony_ci#define L2CAP_CS_NO_INFO 0x0000 29362306a36Sopenharmony_ci#define L2CAP_CS_AUTHEN_PEND 0x0001 29462306a36Sopenharmony_ci#define L2CAP_CS_AUTHOR_PEND 0x0002 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistruct l2cap_conf_req { 29762306a36Sopenharmony_ci __le16 dcid; 29862306a36Sopenharmony_ci __le16 flags; 29962306a36Sopenharmony_ci __u8 data[]; 30062306a36Sopenharmony_ci} __packed; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_cistruct l2cap_conf_rsp { 30362306a36Sopenharmony_ci __le16 scid; 30462306a36Sopenharmony_ci __le16 flags; 30562306a36Sopenharmony_ci __le16 result; 30662306a36Sopenharmony_ci __u8 data[]; 30762306a36Sopenharmony_ci} __packed; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci#define L2CAP_CONF_SUCCESS 0x0000 31062306a36Sopenharmony_ci#define L2CAP_CONF_UNACCEPT 0x0001 31162306a36Sopenharmony_ci#define L2CAP_CONF_REJECT 0x0002 31262306a36Sopenharmony_ci#define L2CAP_CONF_UNKNOWN 0x0003 31362306a36Sopenharmony_ci#define L2CAP_CONF_PENDING 0x0004 31462306a36Sopenharmony_ci#define L2CAP_CONF_EFS_REJECT 0x0005 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci/* configuration req/rsp continuation flag */ 31762306a36Sopenharmony_ci#define L2CAP_CONF_FLAG_CONTINUATION 0x0001 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_cistruct l2cap_conf_opt { 32062306a36Sopenharmony_ci __u8 type; 32162306a36Sopenharmony_ci __u8 len; 32262306a36Sopenharmony_ci __u8 val[]; 32362306a36Sopenharmony_ci} __packed; 32462306a36Sopenharmony_ci#define L2CAP_CONF_OPT_SIZE 2 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci#define L2CAP_CONF_HINT 0x80 32762306a36Sopenharmony_ci#define L2CAP_CONF_MASK 0x7f 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_ci#define L2CAP_CONF_MTU 0x01 33062306a36Sopenharmony_ci#define L2CAP_CONF_FLUSH_TO 0x02 33162306a36Sopenharmony_ci#define L2CAP_CONF_QOS 0x03 33262306a36Sopenharmony_ci#define L2CAP_CONF_RFC 0x04 33362306a36Sopenharmony_ci#define L2CAP_CONF_FCS 0x05 33462306a36Sopenharmony_ci#define L2CAP_CONF_EFS 0x06 33562306a36Sopenharmony_ci#define L2CAP_CONF_EWS 0x07 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci#define L2CAP_CONF_MAX_SIZE 22 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistruct l2cap_conf_rfc { 34062306a36Sopenharmony_ci __u8 mode; 34162306a36Sopenharmony_ci __u8 txwin_size; 34262306a36Sopenharmony_ci __u8 max_transmit; 34362306a36Sopenharmony_ci __le16 retrans_timeout; 34462306a36Sopenharmony_ci __le16 monitor_timeout; 34562306a36Sopenharmony_ci __le16 max_pdu_size; 34662306a36Sopenharmony_ci} __packed; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci#define L2CAP_MODE_BASIC 0x00 34962306a36Sopenharmony_ci#define L2CAP_MODE_RETRANS 0x01 35062306a36Sopenharmony_ci#define L2CAP_MODE_FLOWCTL 0x02 35162306a36Sopenharmony_ci#define L2CAP_MODE_ERTM 0x03 35262306a36Sopenharmony_ci#define L2CAP_MODE_STREAMING 0x04 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci/* Unlike the above this one doesn't actually map to anything that would 35562306a36Sopenharmony_ci * ever be sent over the air. Therefore, use a value that's unlikely to 35662306a36Sopenharmony_ci * ever be used in the BR/EDR configuration phase. 35762306a36Sopenharmony_ci */ 35862306a36Sopenharmony_ci#define L2CAP_MODE_LE_FLOWCTL 0x80 35962306a36Sopenharmony_ci#define L2CAP_MODE_EXT_FLOWCTL 0x81 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_cistruct l2cap_conf_efs { 36262306a36Sopenharmony_ci __u8 id; 36362306a36Sopenharmony_ci __u8 stype; 36462306a36Sopenharmony_ci __le16 msdu; 36562306a36Sopenharmony_ci __le32 sdu_itime; 36662306a36Sopenharmony_ci __le32 acc_lat; 36762306a36Sopenharmony_ci __le32 flush_to; 36862306a36Sopenharmony_ci} __packed; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci#define L2CAP_SERV_NOTRAFIC 0x00 37162306a36Sopenharmony_ci#define L2CAP_SERV_BESTEFFORT 0x01 37262306a36Sopenharmony_ci#define L2CAP_SERV_GUARANTEED 0x02 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci#define L2CAP_BESTEFFORT_ID 0x01 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistruct l2cap_disconn_req { 37762306a36Sopenharmony_ci __le16 dcid; 37862306a36Sopenharmony_ci __le16 scid; 37962306a36Sopenharmony_ci} __packed; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_cistruct l2cap_disconn_rsp { 38262306a36Sopenharmony_ci __le16 dcid; 38362306a36Sopenharmony_ci __le16 scid; 38462306a36Sopenharmony_ci} __packed; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_cistruct l2cap_info_req { 38762306a36Sopenharmony_ci __le16 type; 38862306a36Sopenharmony_ci} __packed; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_cistruct l2cap_info_rsp { 39162306a36Sopenharmony_ci __le16 type; 39262306a36Sopenharmony_ci __le16 result; 39362306a36Sopenharmony_ci __u8 data[]; 39462306a36Sopenharmony_ci} __packed; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci#define L2CAP_MR_SUCCESS 0x0000 39762306a36Sopenharmony_ci#define L2CAP_MR_PEND 0x0001 39862306a36Sopenharmony_ci#define L2CAP_MR_BAD_ID 0x0002 39962306a36Sopenharmony_ci#define L2CAP_MR_SAME_ID 0x0003 40062306a36Sopenharmony_ci#define L2CAP_MR_NOT_SUPP 0x0004 40162306a36Sopenharmony_ci#define L2CAP_MR_COLLISION 0x0005 40262306a36Sopenharmony_ci#define L2CAP_MR_NOT_ALLOWED 0x0006 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_cistruct l2cap_move_chan_cfm { 40562306a36Sopenharmony_ci __le16 icid; 40662306a36Sopenharmony_ci __le16 result; 40762306a36Sopenharmony_ci} __packed; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci#define L2CAP_MC_CONFIRMED 0x0000 41062306a36Sopenharmony_ci#define L2CAP_MC_UNCONFIRMED 0x0001 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_cistruct l2cap_move_chan_cfm_rsp { 41362306a36Sopenharmony_ci __le16 icid; 41462306a36Sopenharmony_ci} __packed; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci/* info type */ 41762306a36Sopenharmony_ci#define L2CAP_IT_CL_MTU 0x0001 41862306a36Sopenharmony_ci#define L2CAP_IT_FEAT_MASK 0x0002 41962306a36Sopenharmony_ci#define L2CAP_IT_FIXED_CHAN 0x0003 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci/* info result */ 42262306a36Sopenharmony_ci#define L2CAP_IR_SUCCESS 0x0000 42362306a36Sopenharmony_ci#define L2CAP_IR_NOTSUPP 0x0001 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_cistruct l2cap_conn_param_update_req { 42662306a36Sopenharmony_ci __le16 min; 42762306a36Sopenharmony_ci __le16 max; 42862306a36Sopenharmony_ci __le16 latency; 42962306a36Sopenharmony_ci __le16 to_multiplier; 43062306a36Sopenharmony_ci} __packed; 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_cistruct l2cap_conn_param_update_rsp { 43362306a36Sopenharmony_ci __le16 result; 43462306a36Sopenharmony_ci} __packed; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci/* Connection Parameters result */ 43762306a36Sopenharmony_ci#define L2CAP_CONN_PARAM_ACCEPTED 0x0000 43862306a36Sopenharmony_ci#define L2CAP_CONN_PARAM_REJECTED 0x0001 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_cistruct l2cap_le_conn_req { 44162306a36Sopenharmony_ci __le16 psm; 44262306a36Sopenharmony_ci __le16 scid; 44362306a36Sopenharmony_ci __le16 mtu; 44462306a36Sopenharmony_ci __le16 mps; 44562306a36Sopenharmony_ci __le16 credits; 44662306a36Sopenharmony_ci} __packed; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_cistruct l2cap_le_conn_rsp { 44962306a36Sopenharmony_ci __le16 dcid; 45062306a36Sopenharmony_ci __le16 mtu; 45162306a36Sopenharmony_ci __le16 mps; 45262306a36Sopenharmony_ci __le16 credits; 45362306a36Sopenharmony_ci __le16 result; 45462306a36Sopenharmony_ci} __packed; 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistruct l2cap_le_credits { 45762306a36Sopenharmony_ci __le16 cid; 45862306a36Sopenharmony_ci __le16 credits; 45962306a36Sopenharmony_ci} __packed; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci#define L2CAP_ECRED_MIN_MTU 64 46262306a36Sopenharmony_ci#define L2CAP_ECRED_MIN_MPS 64 46362306a36Sopenharmony_ci#define L2CAP_ECRED_MAX_CID 5 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_cistruct l2cap_ecred_conn_req { 46662306a36Sopenharmony_ci __le16 psm; 46762306a36Sopenharmony_ci __le16 mtu; 46862306a36Sopenharmony_ci __le16 mps; 46962306a36Sopenharmony_ci __le16 credits; 47062306a36Sopenharmony_ci __le16 scid[]; 47162306a36Sopenharmony_ci} __packed; 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_cistruct l2cap_ecred_conn_rsp { 47462306a36Sopenharmony_ci __le16 mtu; 47562306a36Sopenharmony_ci __le16 mps; 47662306a36Sopenharmony_ci __le16 credits; 47762306a36Sopenharmony_ci __le16 result; 47862306a36Sopenharmony_ci __le16 dcid[]; 47962306a36Sopenharmony_ci}; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistruct l2cap_ecred_reconf_req { 48262306a36Sopenharmony_ci __le16 mtu; 48362306a36Sopenharmony_ci __le16 mps; 48462306a36Sopenharmony_ci __le16 scid[]; 48562306a36Sopenharmony_ci} __packed; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci#define L2CAP_RECONF_SUCCESS 0x0000 48862306a36Sopenharmony_ci#define L2CAP_RECONF_INVALID_MTU 0x0001 48962306a36Sopenharmony_ci#define L2CAP_RECONF_INVALID_MPS 0x0002 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistruct l2cap_ecred_reconf_rsp { 49262306a36Sopenharmony_ci __le16 result; 49362306a36Sopenharmony_ci} __packed; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci/* ----- L2CAP channels and connections ----- */ 49662306a36Sopenharmony_cistruct l2cap_seq_list { 49762306a36Sopenharmony_ci __u16 head; 49862306a36Sopenharmony_ci __u16 tail; 49962306a36Sopenharmony_ci __u16 mask; 50062306a36Sopenharmony_ci __u16 *list; 50162306a36Sopenharmony_ci}; 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci#define L2CAP_SEQ_LIST_CLEAR 0xFFFF 50462306a36Sopenharmony_ci#define L2CAP_SEQ_LIST_TAIL 0x8000 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistruct l2cap_chan { 50762306a36Sopenharmony_ci struct l2cap_conn *conn; 50862306a36Sopenharmony_ci struct kref kref; 50962306a36Sopenharmony_ci atomic_t nesting; 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_ci __u8 state; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci bdaddr_t dst; 51462306a36Sopenharmony_ci __u8 dst_type; 51562306a36Sopenharmony_ci bdaddr_t src; 51662306a36Sopenharmony_ci __u8 src_type; 51762306a36Sopenharmony_ci __le16 psm; 51862306a36Sopenharmony_ci __le16 sport; 51962306a36Sopenharmony_ci __u16 dcid; 52062306a36Sopenharmony_ci __u16 scid; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci __u16 imtu; 52362306a36Sopenharmony_ci __u16 omtu; 52462306a36Sopenharmony_ci __u16 flush_to; 52562306a36Sopenharmony_ci __u8 mode; 52662306a36Sopenharmony_ci __u8 chan_type; 52762306a36Sopenharmony_ci __u8 chan_policy; 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci __u8 sec_level; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci __u8 ident; 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci __u8 conf_req[64]; 53462306a36Sopenharmony_ci __u8 conf_len; 53562306a36Sopenharmony_ci __u8 num_conf_req; 53662306a36Sopenharmony_ci __u8 num_conf_rsp; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci __u8 fcs; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci __u16 tx_win; 54162306a36Sopenharmony_ci __u16 tx_win_max; 54262306a36Sopenharmony_ci __u16 ack_win; 54362306a36Sopenharmony_ci __u8 max_tx; 54462306a36Sopenharmony_ci __u16 retrans_timeout; 54562306a36Sopenharmony_ci __u16 monitor_timeout; 54662306a36Sopenharmony_ci __u16 mps; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci __u16 tx_credits; 54962306a36Sopenharmony_ci __u16 rx_credits; 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci __u8 tx_state; 55262306a36Sopenharmony_ci __u8 rx_state; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci unsigned long conf_state; 55562306a36Sopenharmony_ci unsigned long conn_state; 55662306a36Sopenharmony_ci unsigned long flags; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci __u16 next_tx_seq; 55962306a36Sopenharmony_ci __u16 expected_ack_seq; 56062306a36Sopenharmony_ci __u16 expected_tx_seq; 56162306a36Sopenharmony_ci __u16 buffer_seq; 56262306a36Sopenharmony_ci __u16 srej_save_reqseq; 56362306a36Sopenharmony_ci __u16 last_acked_seq; 56462306a36Sopenharmony_ci __u16 frames_sent; 56562306a36Sopenharmony_ci __u16 unacked_frames; 56662306a36Sopenharmony_ci __u8 retry_count; 56762306a36Sopenharmony_ci __u16 sdu_len; 56862306a36Sopenharmony_ci struct sk_buff *sdu; 56962306a36Sopenharmony_ci struct sk_buff *sdu_last_frag; 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_ci __u16 remote_tx_win; 57262306a36Sopenharmony_ci __u8 remote_max_tx; 57362306a36Sopenharmony_ci __u16 remote_mps; 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci __u8 local_id; 57662306a36Sopenharmony_ci __u8 local_stype; 57762306a36Sopenharmony_ci __u16 local_msdu; 57862306a36Sopenharmony_ci __u32 local_sdu_itime; 57962306a36Sopenharmony_ci __u32 local_acc_lat; 58062306a36Sopenharmony_ci __u32 local_flush_to; 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci __u8 remote_id; 58362306a36Sopenharmony_ci __u8 remote_stype; 58462306a36Sopenharmony_ci __u16 remote_msdu; 58562306a36Sopenharmony_ci __u32 remote_sdu_itime; 58662306a36Sopenharmony_ci __u32 remote_acc_lat; 58762306a36Sopenharmony_ci __u32 remote_flush_to; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci struct delayed_work chan_timer; 59062306a36Sopenharmony_ci struct delayed_work retrans_timer; 59162306a36Sopenharmony_ci struct delayed_work monitor_timer; 59262306a36Sopenharmony_ci struct delayed_work ack_timer; 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci struct sk_buff *tx_send_head; 59562306a36Sopenharmony_ci struct sk_buff_head tx_q; 59662306a36Sopenharmony_ci struct sk_buff_head srej_q; 59762306a36Sopenharmony_ci struct l2cap_seq_list srej_list; 59862306a36Sopenharmony_ci struct l2cap_seq_list retrans_list; 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_ci struct list_head list; 60162306a36Sopenharmony_ci struct list_head global_l; 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_ci void *data; 60462306a36Sopenharmony_ci const struct l2cap_ops *ops; 60562306a36Sopenharmony_ci struct mutex lock; 60662306a36Sopenharmony_ci}; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_cistruct l2cap_ops { 60962306a36Sopenharmony_ci char *name; 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan); 61262306a36Sopenharmony_ci int (*recv) (struct l2cap_chan * chan, 61362306a36Sopenharmony_ci struct sk_buff *skb); 61462306a36Sopenharmony_ci void (*teardown) (struct l2cap_chan *chan, int err); 61562306a36Sopenharmony_ci void (*close) (struct l2cap_chan *chan); 61662306a36Sopenharmony_ci void (*state_change) (struct l2cap_chan *chan, 61762306a36Sopenharmony_ci int state, int err); 61862306a36Sopenharmony_ci void (*ready) (struct l2cap_chan *chan); 61962306a36Sopenharmony_ci void (*defer) (struct l2cap_chan *chan); 62062306a36Sopenharmony_ci void (*resume) (struct l2cap_chan *chan); 62162306a36Sopenharmony_ci void (*suspend) (struct l2cap_chan *chan); 62262306a36Sopenharmony_ci void (*set_shutdown) (struct l2cap_chan *chan); 62362306a36Sopenharmony_ci long (*get_sndtimeo) (struct l2cap_chan *chan); 62462306a36Sopenharmony_ci struct pid *(*get_peer_pid) (struct l2cap_chan *chan); 62562306a36Sopenharmony_ci struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, 62662306a36Sopenharmony_ci unsigned long hdr_len, 62762306a36Sopenharmony_ci unsigned long len, int nb); 62862306a36Sopenharmony_ci int (*filter) (struct l2cap_chan * chan, 62962306a36Sopenharmony_ci struct sk_buff *skb); 63062306a36Sopenharmony_ci}; 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_cistruct l2cap_conn { 63362306a36Sopenharmony_ci struct hci_conn *hcon; 63462306a36Sopenharmony_ci struct hci_chan *hchan; 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_ci unsigned int mtu; 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci __u32 feat_mask; 63962306a36Sopenharmony_ci __u8 remote_fixed_chan; 64062306a36Sopenharmony_ci __u8 local_fixed_chan; 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_ci __u8 info_state; 64362306a36Sopenharmony_ci __u8 info_ident; 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci struct delayed_work info_timer; 64662306a36Sopenharmony_ci 64762306a36Sopenharmony_ci struct sk_buff *rx_skb; 64862306a36Sopenharmony_ci __u32 rx_len; 64962306a36Sopenharmony_ci __u8 tx_ident; 65062306a36Sopenharmony_ci struct mutex ident_lock; 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci struct sk_buff_head pending_rx; 65362306a36Sopenharmony_ci struct work_struct pending_rx_work; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci struct delayed_work id_addr_timer; 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci __u8 disc_reason; 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci struct l2cap_chan *smp; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci struct list_head chan_l; 66262306a36Sopenharmony_ci struct mutex chan_lock; 66362306a36Sopenharmony_ci struct kref ref; 66462306a36Sopenharmony_ci struct list_head users; 66562306a36Sopenharmony_ci}; 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_cistruct l2cap_user { 66862306a36Sopenharmony_ci struct list_head list; 66962306a36Sopenharmony_ci int (*probe) (struct l2cap_conn *conn, struct l2cap_user *user); 67062306a36Sopenharmony_ci void (*remove) (struct l2cap_conn *conn, struct l2cap_user *user); 67162306a36Sopenharmony_ci}; 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 67462306a36Sopenharmony_ci#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 67562306a36Sopenharmony_ci#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci#define L2CAP_CHAN_RAW 1 67862306a36Sopenharmony_ci#define L2CAP_CHAN_CONN_LESS 2 67962306a36Sopenharmony_ci#define L2CAP_CHAN_CONN_ORIENTED 3 68062306a36Sopenharmony_ci#define L2CAP_CHAN_FIXED 4 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci/* ----- L2CAP socket info ----- */ 68362306a36Sopenharmony_ci#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_cistruct l2cap_pinfo { 68662306a36Sopenharmony_ci struct bt_sock bt; 68762306a36Sopenharmony_ci struct l2cap_chan *chan; 68862306a36Sopenharmony_ci struct sk_buff *rx_busy_skb; 68962306a36Sopenharmony_ci}; 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_cienum { 69262306a36Sopenharmony_ci CONF_REQ_SENT, 69362306a36Sopenharmony_ci CONF_INPUT_DONE, 69462306a36Sopenharmony_ci CONF_OUTPUT_DONE, 69562306a36Sopenharmony_ci CONF_MTU_DONE, 69662306a36Sopenharmony_ci CONF_MODE_DONE, 69762306a36Sopenharmony_ci CONF_CONNECT_PEND, 69862306a36Sopenharmony_ci CONF_RECV_NO_FCS, 69962306a36Sopenharmony_ci CONF_STATE2_DEVICE, 70062306a36Sopenharmony_ci CONF_EWS_RECV, 70162306a36Sopenharmony_ci CONF_LOC_CONF_PEND, 70262306a36Sopenharmony_ci CONF_REM_CONF_PEND, 70362306a36Sopenharmony_ci CONF_NOT_COMPLETE, 70462306a36Sopenharmony_ci}; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci#define L2CAP_CONF_MAX_CONF_REQ 2 70762306a36Sopenharmony_ci#define L2CAP_CONF_MAX_CONF_RSP 2 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_cienum { 71062306a36Sopenharmony_ci CONN_SREJ_SENT, 71162306a36Sopenharmony_ci CONN_WAIT_F, 71262306a36Sopenharmony_ci CONN_SREJ_ACT, 71362306a36Sopenharmony_ci CONN_SEND_PBIT, 71462306a36Sopenharmony_ci CONN_REMOTE_BUSY, 71562306a36Sopenharmony_ci CONN_LOCAL_BUSY, 71662306a36Sopenharmony_ci CONN_REJ_ACT, 71762306a36Sopenharmony_ci CONN_SEND_FBIT, 71862306a36Sopenharmony_ci CONN_RNR_SENT, 71962306a36Sopenharmony_ci}; 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci/* Definitions for flags in l2cap_chan */ 72262306a36Sopenharmony_cienum { 72362306a36Sopenharmony_ci FLAG_ROLE_SWITCH, 72462306a36Sopenharmony_ci FLAG_FORCE_ACTIVE, 72562306a36Sopenharmony_ci FLAG_FORCE_RELIABLE, 72662306a36Sopenharmony_ci FLAG_FLUSHABLE, 72762306a36Sopenharmony_ci FLAG_EXT_CTRL, 72862306a36Sopenharmony_ci FLAG_EFS_ENABLE, 72962306a36Sopenharmony_ci FLAG_DEFER_SETUP, 73062306a36Sopenharmony_ci FLAG_LE_CONN_REQ_SENT, 73162306a36Sopenharmony_ci FLAG_ECRED_CONN_REQ_SENT, 73262306a36Sopenharmony_ci FLAG_PENDING_SECURITY, 73362306a36Sopenharmony_ci FLAG_HOLD_HCI_CONN, 73462306a36Sopenharmony_ci}; 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci/* Lock nesting levels for L2CAP channels. We need these because lockdep 73762306a36Sopenharmony_ci * otherwise considers all channels equal and will e.g. complain about a 73862306a36Sopenharmony_ci * connection oriented channel triggering SMP procedures or a listening 73962306a36Sopenharmony_ci * channel creating and locking a child channel. 74062306a36Sopenharmony_ci */ 74162306a36Sopenharmony_cienum { 74262306a36Sopenharmony_ci L2CAP_NESTING_SMP, 74362306a36Sopenharmony_ci L2CAP_NESTING_NORMAL, 74462306a36Sopenharmony_ci L2CAP_NESTING_PARENT, 74562306a36Sopenharmony_ci}; 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_cienum { 74862306a36Sopenharmony_ci L2CAP_TX_STATE_XMIT, 74962306a36Sopenharmony_ci L2CAP_TX_STATE_WAIT_F, 75062306a36Sopenharmony_ci}; 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_cienum { 75362306a36Sopenharmony_ci L2CAP_RX_STATE_RECV, 75462306a36Sopenharmony_ci L2CAP_RX_STATE_SREJ_SENT, 75562306a36Sopenharmony_ci L2CAP_RX_STATE_MOVE, 75662306a36Sopenharmony_ci L2CAP_RX_STATE_WAIT_P, 75762306a36Sopenharmony_ci L2CAP_RX_STATE_WAIT_F, 75862306a36Sopenharmony_ci}; 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_cienum { 76162306a36Sopenharmony_ci L2CAP_TXSEQ_EXPECTED, 76262306a36Sopenharmony_ci L2CAP_TXSEQ_EXPECTED_SREJ, 76362306a36Sopenharmony_ci L2CAP_TXSEQ_UNEXPECTED, 76462306a36Sopenharmony_ci L2CAP_TXSEQ_UNEXPECTED_SREJ, 76562306a36Sopenharmony_ci L2CAP_TXSEQ_DUPLICATE, 76662306a36Sopenharmony_ci L2CAP_TXSEQ_DUPLICATE_SREJ, 76762306a36Sopenharmony_ci L2CAP_TXSEQ_INVALID, 76862306a36Sopenharmony_ci L2CAP_TXSEQ_INVALID_IGNORE, 76962306a36Sopenharmony_ci}; 77062306a36Sopenharmony_ci 77162306a36Sopenharmony_cienum { 77262306a36Sopenharmony_ci L2CAP_EV_DATA_REQUEST, 77362306a36Sopenharmony_ci L2CAP_EV_LOCAL_BUSY_DETECTED, 77462306a36Sopenharmony_ci L2CAP_EV_LOCAL_BUSY_CLEAR, 77562306a36Sopenharmony_ci L2CAP_EV_RECV_REQSEQ_AND_FBIT, 77662306a36Sopenharmony_ci L2CAP_EV_RECV_FBIT, 77762306a36Sopenharmony_ci L2CAP_EV_RETRANS_TO, 77862306a36Sopenharmony_ci L2CAP_EV_MONITOR_TO, 77962306a36Sopenharmony_ci L2CAP_EV_EXPLICIT_POLL, 78062306a36Sopenharmony_ci L2CAP_EV_RECV_IFRAME, 78162306a36Sopenharmony_ci L2CAP_EV_RECV_RR, 78262306a36Sopenharmony_ci L2CAP_EV_RECV_REJ, 78362306a36Sopenharmony_ci L2CAP_EV_RECV_RNR, 78462306a36Sopenharmony_ci L2CAP_EV_RECV_SREJ, 78562306a36Sopenharmony_ci L2CAP_EV_RECV_FRAME, 78662306a36Sopenharmony_ci}; 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_cienum { 78962306a36Sopenharmony_ci L2CAP_MOVE_ROLE_NONE, 79062306a36Sopenharmony_ci L2CAP_MOVE_ROLE_INITIATOR, 79162306a36Sopenharmony_ci L2CAP_MOVE_ROLE_RESPONDER, 79262306a36Sopenharmony_ci}; 79362306a36Sopenharmony_ci 79462306a36Sopenharmony_cienum { 79562306a36Sopenharmony_ci L2CAP_MOVE_STABLE, 79662306a36Sopenharmony_ci L2CAP_MOVE_WAIT_REQ, 79762306a36Sopenharmony_ci L2CAP_MOVE_WAIT_RSP, 79862306a36Sopenharmony_ci L2CAP_MOVE_WAIT_RSP_SUCCESS, 79962306a36Sopenharmony_ci L2CAP_MOVE_WAIT_CONFIRM, 80062306a36Sopenharmony_ci L2CAP_MOVE_WAIT_CONFIRM_RSP, 80162306a36Sopenharmony_ci L2CAP_MOVE_WAIT_LOGICAL_COMP, 80262306a36Sopenharmony_ci L2CAP_MOVE_WAIT_LOGICAL_CFM, 80362306a36Sopenharmony_ci L2CAP_MOVE_WAIT_LOCAL_BUSY, 80462306a36Sopenharmony_ci L2CAP_MOVE_WAIT_PREPARE, 80562306a36Sopenharmony_ci}; 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_civoid l2cap_chan_hold(struct l2cap_chan *c); 80862306a36Sopenharmony_cistruct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c); 80962306a36Sopenharmony_civoid l2cap_chan_put(struct l2cap_chan *c); 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_cistatic inline void l2cap_chan_lock(struct l2cap_chan *chan) 81262306a36Sopenharmony_ci{ 81362306a36Sopenharmony_ci mutex_lock_nested(&chan->lock, atomic_read(&chan->nesting)); 81462306a36Sopenharmony_ci} 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_cistatic inline void l2cap_chan_unlock(struct l2cap_chan *chan) 81762306a36Sopenharmony_ci{ 81862306a36Sopenharmony_ci mutex_unlock(&chan->lock); 81962306a36Sopenharmony_ci} 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_cistatic inline void l2cap_set_timer(struct l2cap_chan *chan, 82262306a36Sopenharmony_ci struct delayed_work *work, long timeout) 82362306a36Sopenharmony_ci{ 82462306a36Sopenharmony_ci BT_DBG("chan %p state %s timeout %ld", chan, 82562306a36Sopenharmony_ci state_to_string(chan->state), timeout); 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci /* If delayed work cancelled do not hold(chan) 82862306a36Sopenharmony_ci since it is already done with previous set_timer */ 82962306a36Sopenharmony_ci if (!cancel_delayed_work(work)) 83062306a36Sopenharmony_ci l2cap_chan_hold(chan); 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci schedule_delayed_work(work, timeout); 83362306a36Sopenharmony_ci} 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_cistatic inline bool l2cap_clear_timer(struct l2cap_chan *chan, 83662306a36Sopenharmony_ci struct delayed_work *work) 83762306a36Sopenharmony_ci{ 83862306a36Sopenharmony_ci bool ret; 83962306a36Sopenharmony_ci 84062306a36Sopenharmony_ci /* put(chan) if delayed work cancelled otherwise it 84162306a36Sopenharmony_ci is done in delayed work function */ 84262306a36Sopenharmony_ci ret = cancel_delayed_work(work); 84362306a36Sopenharmony_ci if (ret) 84462306a36Sopenharmony_ci l2cap_chan_put(chan); 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci return ret; 84762306a36Sopenharmony_ci} 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) 85062306a36Sopenharmony_ci#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) 85162306a36Sopenharmony_ci#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) 85262306a36Sopenharmony_ci#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) 85362306a36Sopenharmony_ci#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ 85462306a36Sopenharmony_ci msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); 85562306a36Sopenharmony_ci#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer) 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_cistatic inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2) 85862306a36Sopenharmony_ci{ 85962306a36Sopenharmony_ci if (seq1 >= seq2) 86062306a36Sopenharmony_ci return seq1 - seq2; 86162306a36Sopenharmony_ci else 86262306a36Sopenharmony_ci return chan->tx_win_max + 1 - seq2 + seq1; 86362306a36Sopenharmony_ci} 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_cistatic inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) 86662306a36Sopenharmony_ci{ 86762306a36Sopenharmony_ci return (seq + 1) % (chan->tx_win_max + 1); 86862306a36Sopenharmony_ci} 86962306a36Sopenharmony_ci 87062306a36Sopenharmony_cistatic inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan) 87162306a36Sopenharmony_ci{ 87262306a36Sopenharmony_ci return NULL; 87362306a36Sopenharmony_ci} 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb) 87662306a36Sopenharmony_ci{ 87762306a36Sopenharmony_ci return -ENOSYS; 87862306a36Sopenharmony_ci} 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_cistatic inline struct sk_buff *l2cap_chan_no_alloc_skb(struct l2cap_chan *chan, 88162306a36Sopenharmony_ci unsigned long hdr_len, 88262306a36Sopenharmony_ci unsigned long len, int nb) 88362306a36Sopenharmony_ci{ 88462306a36Sopenharmony_ci return ERR_PTR(-ENOSYS); 88562306a36Sopenharmony_ci} 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_cistatic inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err) 88862306a36Sopenharmony_ci{ 88962306a36Sopenharmony_ci} 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_cistatic inline void l2cap_chan_no_close(struct l2cap_chan *chan) 89262306a36Sopenharmony_ci{ 89362306a36Sopenharmony_ci} 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_cistatic inline void l2cap_chan_no_ready(struct l2cap_chan *chan) 89662306a36Sopenharmony_ci{ 89762306a36Sopenharmony_ci} 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_cistatic inline void l2cap_chan_no_state_change(struct l2cap_chan *chan, 90062306a36Sopenharmony_ci int state, int err) 90162306a36Sopenharmony_ci{ 90262306a36Sopenharmony_ci} 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_cistatic inline void l2cap_chan_no_defer(struct l2cap_chan *chan) 90562306a36Sopenharmony_ci{ 90662306a36Sopenharmony_ci} 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_cistatic inline void l2cap_chan_no_suspend(struct l2cap_chan *chan) 90962306a36Sopenharmony_ci{ 91062306a36Sopenharmony_ci} 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_cistatic inline void l2cap_chan_no_resume(struct l2cap_chan *chan) 91362306a36Sopenharmony_ci{ 91462306a36Sopenharmony_ci} 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_cistatic inline void l2cap_chan_no_set_shutdown(struct l2cap_chan *chan) 91762306a36Sopenharmony_ci{ 91862306a36Sopenharmony_ci} 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_cistatic inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan) 92162306a36Sopenharmony_ci{ 92262306a36Sopenharmony_ci return 0; 92362306a36Sopenharmony_ci} 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ciextern bool disable_ertm; 92662306a36Sopenharmony_ciextern bool enable_ecred; 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ciint l2cap_init_sockets(void); 92962306a36Sopenharmony_civoid l2cap_cleanup_sockets(void); 93062306a36Sopenharmony_cibool l2cap_is_socket(struct socket *sock); 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_civoid __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan); 93362306a36Sopenharmony_civoid __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan); 93462306a36Sopenharmony_civoid __l2cap_connect_rsp_defer(struct l2cap_chan *chan); 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_ciint l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm); 93762306a36Sopenharmony_ciint l2cap_add_scid(struct l2cap_chan *chan, __u16 scid); 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_cistruct l2cap_chan *l2cap_chan_create(void); 94062306a36Sopenharmony_civoid l2cap_chan_close(struct l2cap_chan *chan, int reason); 94162306a36Sopenharmony_ciint l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, 94262306a36Sopenharmony_ci bdaddr_t *dst, u8 dst_type); 94362306a36Sopenharmony_ciint l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu); 94462306a36Sopenharmony_ciint l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len); 94562306a36Sopenharmony_civoid l2cap_chan_busy(struct l2cap_chan *chan, int busy); 94662306a36Sopenharmony_ciint l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator); 94762306a36Sopenharmony_civoid l2cap_chan_set_defaults(struct l2cap_chan *chan); 94862306a36Sopenharmony_ciint l2cap_ertm_init(struct l2cap_chan *chan); 94962306a36Sopenharmony_civoid l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); 95062306a36Sopenharmony_civoid __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); 95162306a36Sopenharmony_citypedef void (*l2cap_chan_func_t)(struct l2cap_chan *chan, void *data); 95262306a36Sopenharmony_civoid l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func, 95362306a36Sopenharmony_ci void *data); 95462306a36Sopenharmony_civoid l2cap_chan_del(struct l2cap_chan *chan, int err); 95562306a36Sopenharmony_civoid l2cap_send_conn_req(struct l2cap_chan *chan); 95662306a36Sopenharmony_civoid l2cap_move_start(struct l2cap_chan *chan); 95762306a36Sopenharmony_civoid l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, 95862306a36Sopenharmony_ci u8 status); 95962306a36Sopenharmony_civoid __l2cap_physical_cfm(struct l2cap_chan *chan, int result); 96062306a36Sopenharmony_ci 96162306a36Sopenharmony_cistruct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn); 96262306a36Sopenharmony_civoid l2cap_conn_put(struct l2cap_conn *conn); 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_ciint l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); 96562306a36Sopenharmony_civoid l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user); 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci#endif /* __L2CAP_H */ 968