18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci BlueZ - Bluetooth protocol stack for Linux 38c2ecf20Sopenharmony_ci Copyright (C) 2000-2001 Qualcomm Incorporated 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci This program is free software; you can redistribute it and/or modify 88c2ecf20Sopenharmony_ci it under the terms of the GNU General Public License version 2 as 98c2ecf20Sopenharmony_ci published by the Free Software Foundation; 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 128c2ecf20Sopenharmony_ci OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 138c2ecf20Sopenharmony_ci FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 148c2ecf20Sopenharmony_ci IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY 158c2ecf20Sopenharmony_ci CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 168c2ecf20Sopenharmony_ci WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 178c2ecf20Sopenharmony_ci ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 188c2ecf20Sopenharmony_ci OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 218c2ecf20Sopenharmony_ci COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 228c2ecf20Sopenharmony_ci SOFTWARE IS DISCLAIMED. 238c2ecf20Sopenharmony_ci*/ 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#ifndef __BLUETOOTH_H 268c2ecf20Sopenharmony_ci#define __BLUETOOTH_H 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include <linux/poll.h> 298c2ecf20Sopenharmony_ci#include <net/sock.h> 308c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define BT_SUBSYS_VERSION 2 338c2ecf20Sopenharmony_ci#define BT_SUBSYS_REVISION 22 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#ifndef AF_BLUETOOTH 368c2ecf20Sopenharmony_ci#define AF_BLUETOOTH 31 378c2ecf20Sopenharmony_ci#define PF_BLUETOOTH AF_BLUETOOTH 388c2ecf20Sopenharmony_ci#endif 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* Bluetooth versions */ 418c2ecf20Sopenharmony_ci#define BLUETOOTH_VER_1_1 1 428c2ecf20Sopenharmony_ci#define BLUETOOTH_VER_1_2 2 438c2ecf20Sopenharmony_ci#define BLUETOOTH_VER_2_0 3 448c2ecf20Sopenharmony_ci#define BLUETOOTH_VER_2_1 4 458c2ecf20Sopenharmony_ci#define BLUETOOTH_VER_4_0 6 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* Reserv for core and drivers use */ 488c2ecf20Sopenharmony_ci#define BT_SKB_RESERVE 8 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define BTPROTO_L2CAP 0 518c2ecf20Sopenharmony_ci#define BTPROTO_HCI 1 528c2ecf20Sopenharmony_ci#define BTPROTO_SCO 2 538c2ecf20Sopenharmony_ci#define BTPROTO_RFCOMM 3 548c2ecf20Sopenharmony_ci#define BTPROTO_BNEP 4 558c2ecf20Sopenharmony_ci#define BTPROTO_CMTP 5 568c2ecf20Sopenharmony_ci#define BTPROTO_HIDP 6 578c2ecf20Sopenharmony_ci#define BTPROTO_AVDTP 7 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define SOL_HCI 0 608c2ecf20Sopenharmony_ci#define SOL_L2CAP 6 618c2ecf20Sopenharmony_ci#define SOL_SCO 17 628c2ecf20Sopenharmony_ci#define SOL_RFCOMM 18 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define BT_SECURITY 4 658c2ecf20Sopenharmony_cistruct bt_security { 668c2ecf20Sopenharmony_ci __u8 level; 678c2ecf20Sopenharmony_ci __u8 key_size; 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci#define BT_SECURITY_SDP 0 708c2ecf20Sopenharmony_ci#define BT_SECURITY_LOW 1 718c2ecf20Sopenharmony_ci#define BT_SECURITY_MEDIUM 2 728c2ecf20Sopenharmony_ci#define BT_SECURITY_HIGH 3 738c2ecf20Sopenharmony_ci#define BT_SECURITY_FIPS 4 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#define BT_DEFER_SETUP 7 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#define BT_FLUSHABLE 8 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci#define BT_FLUSHABLE_OFF 0 808c2ecf20Sopenharmony_ci#define BT_FLUSHABLE_ON 1 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#define BT_POWER 9 838c2ecf20Sopenharmony_cistruct bt_power { 848c2ecf20Sopenharmony_ci __u8 force_active; 858c2ecf20Sopenharmony_ci}; 868c2ecf20Sopenharmony_ci#define BT_POWER_FORCE_ACTIVE_OFF 0 878c2ecf20Sopenharmony_ci#define BT_POWER_FORCE_ACTIVE_ON 1 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci#define BT_CHANNEL_POLICY 10 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci/* BR/EDR only (default policy) 928c2ecf20Sopenharmony_ci * AMP controllers cannot be used. 938c2ecf20Sopenharmony_ci * Channel move requests from the remote device are denied. 948c2ecf20Sopenharmony_ci * If the L2CAP channel is currently using AMP, move the channel to BR/EDR. 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_ci#define BT_CHANNEL_POLICY_BREDR_ONLY 0 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci/* BR/EDR Preferred 998c2ecf20Sopenharmony_ci * Allow use of AMP controllers. 1008c2ecf20Sopenharmony_ci * If the L2CAP channel is currently on AMP, move it to BR/EDR. 1018c2ecf20Sopenharmony_ci * Channel move requests from the remote device are allowed. 1028c2ecf20Sopenharmony_ci */ 1038c2ecf20Sopenharmony_ci#define BT_CHANNEL_POLICY_BREDR_PREFERRED 1 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* AMP Preferred 1068c2ecf20Sopenharmony_ci * Allow use of AMP controllers 1078c2ecf20Sopenharmony_ci * If the L2CAP channel is currently on BR/EDR and AMP controller 1088c2ecf20Sopenharmony_ci * resources are available, initiate a channel move to AMP. 1098c2ecf20Sopenharmony_ci * Channel move requests from the remote device are allowed. 1108c2ecf20Sopenharmony_ci * If the L2CAP socket has not been connected yet, try to create 1118c2ecf20Sopenharmony_ci * and configure the channel directly on an AMP controller rather 1128c2ecf20Sopenharmony_ci * than BR/EDR. 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_ci#define BT_CHANNEL_POLICY_AMP_PREFERRED 2 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci#define BT_VOICE 11 1178c2ecf20Sopenharmony_cistruct bt_voice { 1188c2ecf20Sopenharmony_ci __u16 setting; 1198c2ecf20Sopenharmony_ci}; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci#define BT_VOICE_TRANSPARENT 0x0003 1228c2ecf20Sopenharmony_ci#define BT_VOICE_CVSD_16BIT 0x0060 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci#define BT_SNDMTU 12 1258c2ecf20Sopenharmony_ci#define BT_RCVMTU 13 1268c2ecf20Sopenharmony_ci#define BT_PHY 14 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci#define BT_PHY_BR_1M_1SLOT 0x00000001 1298c2ecf20Sopenharmony_ci#define BT_PHY_BR_1M_3SLOT 0x00000002 1308c2ecf20Sopenharmony_ci#define BT_PHY_BR_1M_5SLOT 0x00000004 1318c2ecf20Sopenharmony_ci#define BT_PHY_EDR_2M_1SLOT 0x00000008 1328c2ecf20Sopenharmony_ci#define BT_PHY_EDR_2M_3SLOT 0x00000010 1338c2ecf20Sopenharmony_ci#define BT_PHY_EDR_2M_5SLOT 0x00000020 1348c2ecf20Sopenharmony_ci#define BT_PHY_EDR_3M_1SLOT 0x00000040 1358c2ecf20Sopenharmony_ci#define BT_PHY_EDR_3M_3SLOT 0x00000080 1368c2ecf20Sopenharmony_ci#define BT_PHY_EDR_3M_5SLOT 0x00000100 1378c2ecf20Sopenharmony_ci#define BT_PHY_LE_1M_TX 0x00000200 1388c2ecf20Sopenharmony_ci#define BT_PHY_LE_1M_RX 0x00000400 1398c2ecf20Sopenharmony_ci#define BT_PHY_LE_2M_TX 0x00000800 1408c2ecf20Sopenharmony_ci#define BT_PHY_LE_2M_RX 0x00001000 1418c2ecf20Sopenharmony_ci#define BT_PHY_LE_CODED_TX 0x00002000 1428c2ecf20Sopenharmony_ci#define BT_PHY_LE_CODED_RX 0x00004000 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci#define BT_MODE 15 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci#define BT_MODE_BASIC 0x00 1478c2ecf20Sopenharmony_ci#define BT_MODE_ERTM 0x01 1488c2ecf20Sopenharmony_ci#define BT_MODE_STREAMING 0x02 1498c2ecf20Sopenharmony_ci#define BT_MODE_LE_FLOWCTL 0x03 1508c2ecf20Sopenharmony_ci#define BT_MODE_EXT_FLOWCTL 0x04 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci#define BT_PKT_STATUS 16 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci#define BT_SCM_PKT_STATUS 0x03 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci__printf(1, 2) 1578c2ecf20Sopenharmony_civoid bt_info(const char *fmt, ...); 1588c2ecf20Sopenharmony_ci__printf(1, 2) 1598c2ecf20Sopenharmony_civoid bt_warn(const char *fmt, ...); 1608c2ecf20Sopenharmony_ci__printf(1, 2) 1618c2ecf20Sopenharmony_civoid bt_err(const char *fmt, ...); 1628c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_BT_FEATURE_DEBUG) 1638c2ecf20Sopenharmony_civoid bt_dbg_set(bool enable); 1648c2ecf20Sopenharmony_cibool bt_dbg_get(void); 1658c2ecf20Sopenharmony_ci__printf(1, 2) 1668c2ecf20Sopenharmony_civoid bt_dbg(const char *fmt, ...); 1678c2ecf20Sopenharmony_ci#endif 1688c2ecf20Sopenharmony_ci__printf(1, 2) 1698c2ecf20Sopenharmony_civoid bt_warn_ratelimited(const char *fmt, ...); 1708c2ecf20Sopenharmony_ci__printf(1, 2) 1718c2ecf20Sopenharmony_civoid bt_err_ratelimited(const char *fmt, ...); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci#define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__) 1748c2ecf20Sopenharmony_ci#define BT_WARN(fmt, ...) bt_warn(fmt "\n", ##__VA_ARGS__) 1758c2ecf20Sopenharmony_ci#define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__) 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_BT_FEATURE_DEBUG) 1788c2ecf20Sopenharmony_ci#define BT_DBG(fmt, ...) bt_dbg(fmt "\n", ##__VA_ARGS__) 1798c2ecf20Sopenharmony_ci#else 1808c2ecf20Sopenharmony_ci#define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__) 1818c2ecf20Sopenharmony_ci#endif 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci#define bt_dev_name(hdev) ((hdev) ? (hdev)->name : "null") 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci#define bt_dev_info(hdev, fmt, ...) \ 1868c2ecf20Sopenharmony_ci BT_INFO("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__) 1878c2ecf20Sopenharmony_ci#define bt_dev_warn(hdev, fmt, ...) \ 1888c2ecf20Sopenharmony_ci BT_WARN("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__) 1898c2ecf20Sopenharmony_ci#define bt_dev_err(hdev, fmt, ...) \ 1908c2ecf20Sopenharmony_ci BT_ERR("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__) 1918c2ecf20Sopenharmony_ci#define bt_dev_dbg(hdev, fmt, ...) \ 1928c2ecf20Sopenharmony_ci BT_DBG("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__) 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#define bt_dev_warn_ratelimited(hdev, fmt, ...) \ 1958c2ecf20Sopenharmony_ci bt_warn_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__) 1968c2ecf20Sopenharmony_ci#define bt_dev_err_ratelimited(hdev, fmt, ...) \ 1978c2ecf20Sopenharmony_ci bt_err_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__) 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci/* Connection and socket states */ 2008c2ecf20Sopenharmony_cienum { 2018c2ecf20Sopenharmony_ci BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ 2028c2ecf20Sopenharmony_ci BT_OPEN, 2038c2ecf20Sopenharmony_ci BT_BOUND, 2048c2ecf20Sopenharmony_ci BT_LISTEN, 2058c2ecf20Sopenharmony_ci BT_CONNECT, 2068c2ecf20Sopenharmony_ci BT_CONNECT2, 2078c2ecf20Sopenharmony_ci BT_CONFIG, 2088c2ecf20Sopenharmony_ci BT_DISCONN, 2098c2ecf20Sopenharmony_ci BT_CLOSED 2108c2ecf20Sopenharmony_ci}; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci/* If unused will be removed by compiler */ 2138c2ecf20Sopenharmony_cistatic inline const char *state_to_string(int state) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci switch (state) { 2168c2ecf20Sopenharmony_ci case BT_CONNECTED: 2178c2ecf20Sopenharmony_ci return "BT_CONNECTED"; 2188c2ecf20Sopenharmony_ci case BT_OPEN: 2198c2ecf20Sopenharmony_ci return "BT_OPEN"; 2208c2ecf20Sopenharmony_ci case BT_BOUND: 2218c2ecf20Sopenharmony_ci return "BT_BOUND"; 2228c2ecf20Sopenharmony_ci case BT_LISTEN: 2238c2ecf20Sopenharmony_ci return "BT_LISTEN"; 2248c2ecf20Sopenharmony_ci case BT_CONNECT: 2258c2ecf20Sopenharmony_ci return "BT_CONNECT"; 2268c2ecf20Sopenharmony_ci case BT_CONNECT2: 2278c2ecf20Sopenharmony_ci return "BT_CONNECT2"; 2288c2ecf20Sopenharmony_ci case BT_CONFIG: 2298c2ecf20Sopenharmony_ci return "BT_CONFIG"; 2308c2ecf20Sopenharmony_ci case BT_DISCONN: 2318c2ecf20Sopenharmony_ci return "BT_DISCONN"; 2328c2ecf20Sopenharmony_ci case BT_CLOSED: 2338c2ecf20Sopenharmony_ci return "BT_CLOSED"; 2348c2ecf20Sopenharmony_ci } 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci return "invalid state"; 2378c2ecf20Sopenharmony_ci} 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci/* BD Address */ 2408c2ecf20Sopenharmony_citypedef struct { 2418c2ecf20Sopenharmony_ci __u8 b[6]; 2428c2ecf20Sopenharmony_ci} __packed bdaddr_t; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci/* BD Address type */ 2458c2ecf20Sopenharmony_ci#define BDADDR_BREDR 0x00 2468c2ecf20Sopenharmony_ci#define BDADDR_LE_PUBLIC 0x01 2478c2ecf20Sopenharmony_ci#define BDADDR_LE_RANDOM 0x02 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic inline bool bdaddr_type_is_valid(u8 type) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci switch (type) { 2528c2ecf20Sopenharmony_ci case BDADDR_BREDR: 2538c2ecf20Sopenharmony_ci case BDADDR_LE_PUBLIC: 2548c2ecf20Sopenharmony_ci case BDADDR_LE_RANDOM: 2558c2ecf20Sopenharmony_ci return true; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci return false; 2598c2ecf20Sopenharmony_ci} 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_cistatic inline bool bdaddr_type_is_le(u8 type) 2628c2ecf20Sopenharmony_ci{ 2638c2ecf20Sopenharmony_ci switch (type) { 2648c2ecf20Sopenharmony_ci case BDADDR_LE_PUBLIC: 2658c2ecf20Sopenharmony_ci case BDADDR_LE_RANDOM: 2668c2ecf20Sopenharmony_ci return true; 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci return false; 2708c2ecf20Sopenharmony_ci} 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) 2738c2ecf20Sopenharmony_ci#define BDADDR_NONE (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}) 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci/* Copy, swap, convert BD Address */ 2768c2ecf20Sopenharmony_cistatic inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2) 2778c2ecf20Sopenharmony_ci{ 2788c2ecf20Sopenharmony_ci return memcmp(ba1, ba2, sizeof(bdaddr_t)); 2798c2ecf20Sopenharmony_ci} 2808c2ecf20Sopenharmony_cistatic inline void bacpy(bdaddr_t *dst, const bdaddr_t *src) 2818c2ecf20Sopenharmony_ci{ 2828c2ecf20Sopenharmony_ci memcpy(dst, src, sizeof(bdaddr_t)); 2838c2ecf20Sopenharmony_ci} 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_civoid baswap(bdaddr_t *dst, const bdaddr_t *src); 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci/* Common socket structures and functions */ 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci#define bt_sk(__sk) ((struct bt_sock *) __sk) 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_cistruct bt_sock { 2928c2ecf20Sopenharmony_ci struct sock sk; 2938c2ecf20Sopenharmony_ci struct list_head accept_q; 2948c2ecf20Sopenharmony_ci struct sock *parent; 2958c2ecf20Sopenharmony_ci unsigned long flags; 2968c2ecf20Sopenharmony_ci void (*skb_msg_name)(struct sk_buff *, void *, int *); 2978c2ecf20Sopenharmony_ci void (*skb_put_cmsg)(struct sk_buff *, struct msghdr *, struct sock *); 2988c2ecf20Sopenharmony_ci}; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cienum { 3018c2ecf20Sopenharmony_ci BT_SK_DEFER_SETUP, 3028c2ecf20Sopenharmony_ci BT_SK_SUSPEND, 3038c2ecf20Sopenharmony_ci}; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_cistruct bt_sock_list { 3068c2ecf20Sopenharmony_ci struct hlist_head head; 3078c2ecf20Sopenharmony_ci rwlock_t lock; 3088c2ecf20Sopenharmony_ci#ifdef CONFIG_PROC_FS 3098c2ecf20Sopenharmony_ci int (* custom_seq_show)(struct seq_file *, void *); 3108c2ecf20Sopenharmony_ci#endif 3118c2ecf20Sopenharmony_ci}; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ciint bt_sock_register(int proto, const struct net_proto_family *ops); 3148c2ecf20Sopenharmony_civoid bt_sock_unregister(int proto); 3158c2ecf20Sopenharmony_civoid bt_sock_link(struct bt_sock_list *l, struct sock *s); 3168c2ecf20Sopenharmony_civoid bt_sock_unlink(struct bt_sock_list *l, struct sock *s); 3178c2ecf20Sopenharmony_ciint bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, 3188c2ecf20Sopenharmony_ci int flags); 3198c2ecf20Sopenharmony_ciint bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg, 3208c2ecf20Sopenharmony_ci size_t len, int flags); 3218c2ecf20Sopenharmony_ci__poll_t bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait); 3228c2ecf20Sopenharmony_ciint bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); 3238c2ecf20Sopenharmony_ciint bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); 3248c2ecf20Sopenharmony_ciint bt_sock_wait_ready(struct sock *sk, unsigned long flags); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_civoid bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh); 3278c2ecf20Sopenharmony_civoid bt_accept_unlink(struct sock *sk); 3288c2ecf20Sopenharmony_cistruct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock); 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci/* Skb helpers */ 3318c2ecf20Sopenharmony_cistruct l2cap_ctrl { 3328c2ecf20Sopenharmony_ci u8 sframe:1, 3338c2ecf20Sopenharmony_ci poll:1, 3348c2ecf20Sopenharmony_ci final:1, 3358c2ecf20Sopenharmony_ci fcs:1, 3368c2ecf20Sopenharmony_ci sar:2, 3378c2ecf20Sopenharmony_ci super:2; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci u16 reqseq; 3408c2ecf20Sopenharmony_ci u16 txseq; 3418c2ecf20Sopenharmony_ci u8 retries; 3428c2ecf20Sopenharmony_ci __le16 psm; 3438c2ecf20Sopenharmony_ci bdaddr_t bdaddr; 3448c2ecf20Sopenharmony_ci struct l2cap_chan *chan; 3458c2ecf20Sopenharmony_ci}; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistruct sco_ctrl { 3488c2ecf20Sopenharmony_ci u8 pkt_status; 3498c2ecf20Sopenharmony_ci}; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cistruct hci_dev; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_citypedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); 3548c2ecf20Sopenharmony_citypedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status, 3558c2ecf20Sopenharmony_ci u16 opcode, struct sk_buff *skb); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci#define HCI_REQ_START BIT(0) 3588c2ecf20Sopenharmony_ci#define HCI_REQ_SKB BIT(1) 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_cistruct hci_ctrl { 3618c2ecf20Sopenharmony_ci u16 opcode; 3628c2ecf20Sopenharmony_ci u8 req_flags; 3638c2ecf20Sopenharmony_ci u8 req_event; 3648c2ecf20Sopenharmony_ci union { 3658c2ecf20Sopenharmony_ci hci_req_complete_t req_complete; 3668c2ecf20Sopenharmony_ci hci_req_complete_skb_t req_complete_skb; 3678c2ecf20Sopenharmony_ci }; 3688c2ecf20Sopenharmony_ci}; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistruct bt_skb_cb { 3718c2ecf20Sopenharmony_ci u8 pkt_type; 3728c2ecf20Sopenharmony_ci u8 force_active; 3738c2ecf20Sopenharmony_ci u16 expect; 3748c2ecf20Sopenharmony_ci u8 incoming:1; 3758c2ecf20Sopenharmony_ci union { 3768c2ecf20Sopenharmony_ci struct l2cap_ctrl l2cap; 3778c2ecf20Sopenharmony_ci struct sco_ctrl sco; 3788c2ecf20Sopenharmony_ci struct hci_ctrl hci; 3798c2ecf20Sopenharmony_ci }; 3808c2ecf20Sopenharmony_ci}; 3818c2ecf20Sopenharmony_ci#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci#define hci_skb_pkt_type(skb) bt_cb((skb))->pkt_type 3848c2ecf20Sopenharmony_ci#define hci_skb_expect(skb) bt_cb((skb))->expect 3858c2ecf20Sopenharmony_ci#define hci_skb_opcode(skb) bt_cb((skb))->hci.opcode 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_cistatic inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) 3888c2ecf20Sopenharmony_ci{ 3898c2ecf20Sopenharmony_ci struct sk_buff *skb; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci skb = alloc_skb(len + BT_SKB_RESERVE, how); 3928c2ecf20Sopenharmony_ci if (skb) 3938c2ecf20Sopenharmony_ci skb_reserve(skb, BT_SKB_RESERVE); 3948c2ecf20Sopenharmony_ci return skb; 3958c2ecf20Sopenharmony_ci} 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_cistatic inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, 3988c2ecf20Sopenharmony_ci unsigned long len, int nb, int *err) 3998c2ecf20Sopenharmony_ci{ 4008c2ecf20Sopenharmony_ci struct sk_buff *skb; 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err); 4038c2ecf20Sopenharmony_ci if (skb) 4048c2ecf20Sopenharmony_ci skb_reserve(skb, BT_SKB_RESERVE); 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci if (!skb && *err) 4078c2ecf20Sopenharmony_ci return NULL; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci *err = sock_error(sk); 4108c2ecf20Sopenharmony_ci if (*err) 4118c2ecf20Sopenharmony_ci goto out; 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci if (sk->sk_shutdown) { 4148c2ecf20Sopenharmony_ci *err = -ECONNRESET; 4158c2ecf20Sopenharmony_ci goto out; 4168c2ecf20Sopenharmony_ci } 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci return skb; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ciout: 4218c2ecf20Sopenharmony_ci kfree_skb(skb); 4228c2ecf20Sopenharmony_ci return NULL; 4238c2ecf20Sopenharmony_ci} 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci/* Shall not be called with lock_sock held */ 4268c2ecf20Sopenharmony_cistatic inline struct sk_buff *bt_skb_sendmsg(struct sock *sk, 4278c2ecf20Sopenharmony_ci struct msghdr *msg, 4288c2ecf20Sopenharmony_ci size_t len, size_t mtu, 4298c2ecf20Sopenharmony_ci size_t headroom, size_t tailroom) 4308c2ecf20Sopenharmony_ci{ 4318c2ecf20Sopenharmony_ci struct sk_buff *skb; 4328c2ecf20Sopenharmony_ci size_t size = min_t(size_t, len, mtu); 4338c2ecf20Sopenharmony_ci int err; 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci skb = bt_skb_send_alloc(sk, size + headroom + tailroom, 4368c2ecf20Sopenharmony_ci msg->msg_flags & MSG_DONTWAIT, &err); 4378c2ecf20Sopenharmony_ci if (!skb) 4388c2ecf20Sopenharmony_ci return ERR_PTR(err); 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci skb_reserve(skb, headroom); 4418c2ecf20Sopenharmony_ci skb_tailroom_reserve(skb, mtu, tailroom); 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci if (!copy_from_iter_full(skb_put(skb, size), size, &msg->msg_iter)) { 4448c2ecf20Sopenharmony_ci kfree_skb(skb); 4458c2ecf20Sopenharmony_ci return ERR_PTR(-EFAULT); 4468c2ecf20Sopenharmony_ci } 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ci skb->priority = sk->sk_priority; 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci return skb; 4518c2ecf20Sopenharmony_ci} 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci/* Similar to bt_skb_sendmsg but can split the msg into multiple fragments 4548c2ecf20Sopenharmony_ci * accourding to the MTU. 4558c2ecf20Sopenharmony_ci */ 4568c2ecf20Sopenharmony_cistatic inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk, 4578c2ecf20Sopenharmony_ci struct msghdr *msg, 4588c2ecf20Sopenharmony_ci size_t len, size_t mtu, 4598c2ecf20Sopenharmony_ci size_t headroom, size_t tailroom) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci struct sk_buff *skb, **frag; 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci skb = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom); 4648c2ecf20Sopenharmony_ci if (IS_ERR_OR_NULL(skb)) 4658c2ecf20Sopenharmony_ci return skb; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci len -= skb->len; 4688c2ecf20Sopenharmony_ci if (!len) 4698c2ecf20Sopenharmony_ci return skb; 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci /* Add remaining data over MTU as continuation fragments */ 4728c2ecf20Sopenharmony_ci frag = &skb_shinfo(skb)->frag_list; 4738c2ecf20Sopenharmony_ci while (len) { 4748c2ecf20Sopenharmony_ci struct sk_buff *tmp; 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci tmp = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom); 4778c2ecf20Sopenharmony_ci if (IS_ERR(tmp)) { 4788c2ecf20Sopenharmony_ci return skb; 4798c2ecf20Sopenharmony_ci } 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci len -= tmp->len; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci *frag = tmp; 4848c2ecf20Sopenharmony_ci frag = &(*frag)->next; 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci return skb; 4888c2ecf20Sopenharmony_ci} 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_cistatic inline int bt_copy_from_sockptr(void *dst, size_t dst_size, 4918c2ecf20Sopenharmony_ci sockptr_t src, size_t src_size) 4928c2ecf20Sopenharmony_ci{ 4938c2ecf20Sopenharmony_ci if (dst_size > src_size) 4948c2ecf20Sopenharmony_ci return -EINVAL; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci return copy_from_sockptr(dst, src, dst_size); 4978c2ecf20Sopenharmony_ci} 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ciint bt_to_errno(u16 code); 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_civoid hci_sock_set_flag(struct sock *sk, int nr); 5028c2ecf20Sopenharmony_civoid hci_sock_clear_flag(struct sock *sk, int nr); 5038c2ecf20Sopenharmony_ciint hci_sock_test_flag(struct sock *sk, int nr); 5048c2ecf20Sopenharmony_ciunsigned short hci_sock_get_channel(struct sock *sk); 5058c2ecf20Sopenharmony_ciu32 hci_sock_get_cookie(struct sock *sk); 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_ciint hci_sock_init(void); 5088c2ecf20Sopenharmony_civoid hci_sock_cleanup(void); 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ciint bt_sysfs_init(void); 5118c2ecf20Sopenharmony_civoid bt_sysfs_cleanup(void); 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ciint bt_procfs_init(struct net *net, const char *name, 5148c2ecf20Sopenharmony_ci struct bt_sock_list *sk_list, 5158c2ecf20Sopenharmony_ci int (*seq_show)(struct seq_file *, void *)); 5168c2ecf20Sopenharmony_civoid bt_procfs_cleanup(struct net *net, const char *name); 5178c2ecf20Sopenharmony_ci 5188c2ecf20Sopenharmony_ciextern struct dentry *bt_debugfs; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ciint l2cap_init(void); 5218c2ecf20Sopenharmony_civoid l2cap_exit(void); 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_BT_BREDR) 5248c2ecf20Sopenharmony_ciint sco_init(void); 5258c2ecf20Sopenharmony_civoid sco_exit(void); 5268c2ecf20Sopenharmony_ci#else 5278c2ecf20Sopenharmony_cistatic inline int sco_init(void) 5288c2ecf20Sopenharmony_ci{ 5298c2ecf20Sopenharmony_ci return 0; 5308c2ecf20Sopenharmony_ci} 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_cistatic inline void sco_exit(void) 5338c2ecf20Sopenharmony_ci{ 5348c2ecf20Sopenharmony_ci} 5358c2ecf20Sopenharmony_ci#endif 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ciint mgmt_init(void); 5388c2ecf20Sopenharmony_civoid mgmt_exit(void); 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_civoid bt_sock_reclassify_lock(struct sock *sk, int proto); 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci#endif /* __BLUETOOTH_H */ 543