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