linux/net/bluetooth/l2cap_core.c

/*
   BlueZ - Bluetooth protocol stack for Linux
   Copyright (C) 2000-2001 Qualcomm Incorporated
   Copyright (C) 2009-2010 Gustavo F. Padovan <[email protected]>
   Copyright (C) 2010 Google Inc.
   Copyright (C) 2011 ProFUSION Embedded Systems
   Copyright (c) 2012 Code Aurora Forum.  All rights reserved.

   Written 2000,2001 by Maxim Krasnyansky <[email protected]>

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
   published by the Free Software Foundation;

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
   SOFTWARE IS DISCLAIMED.
*/

/* Bluetooth L2CAP core. */

#include <linux/module.h>

#include <linux/debugfs.h>
#include <linux/crc16.h>
#include <linux/filter.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>

#include "smp.h"

#define LE_FLOWCTL_MAX_CREDITS

bool disable_ertm;
bool enable_ecred = IS_ENABLED();

static u32 l2cap_feat_mask =;

static LIST_HEAD(chan_list);
static DEFINE_RWLOCK(chan_list_lock);

static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
				       u8 code, u8 ident, u16 dlen, void *data);
static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
			   void *data);
static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size);
static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);

static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
		     struct sk_buff_head *skbs, u8 event);
static void l2cap_retrans_timeout(struct work_struct *work);
static void l2cap_monitor_timeout(struct work_struct *work);
static void l2cap_ack_timeout(struct work_struct *work);

static inline u8 bdaddr_type(u8 link_type, u8 bdaddr_type)
{}

static inline u8 bdaddr_src_type(struct hci_conn *hcon)
{}

static inline u8 bdaddr_dst_type(struct hci_conn *hcon)
{}

/* ---- L2CAP channels ---- */

static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
						   u16 cid)
{}

static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn,
						   u16 cid)
{}

/* Find channel with given SCID.
 * Returns a reference locked channel.
 */
static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
						 u16 cid)
{}

/* Find channel with given DCID.
 * Returns a reference locked channel.
 */
static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
						 u16 cid)
{}

static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
						    u8 ident)
{}

static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src,
						      u8 src_type)
{}

int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm)
{}
EXPORT_SYMBOL_GPL();

int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid)
{}

static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
{}

static void l2cap_state_change(struct l2cap_chan *chan, int state)
{}

static inline void l2cap_state_change_and_error(struct l2cap_chan *chan,
						int state, int err)
{}

static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
{}

static void __set_retrans_timer(struct l2cap_chan *chan)
{}

static void __set_monitor_timer(struct l2cap_chan *chan)
{}

static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head,
					       u16 seq)
{}

/* ---- L2CAP sequence number lists ---- */

/* For ERTM, ordered lists of sequence numbers must be tracked for
 * SREJ requests that are received and for frames that are to be
 * retransmitted. These seq_list functions implement a singly-linked
 * list in an array, where membership in the list can also be checked
 * in constant time. Items can also be added to the tail of the list
 * and removed from the head in constant time, without further memory
 * allocs or frees.
 */

static int l2cap_seq_list_init(struct l2cap_seq_list *seq_list, u16 size)
{}

static inline void l2cap_seq_list_free(struct l2cap_seq_list *seq_list)
{}

static inline bool l2cap_seq_list_contains(struct l2cap_seq_list *seq_list,
					   u16 seq)
{}

static inline u16 l2cap_seq_list_pop(struct l2cap_seq_list *seq_list)
{}

static void l2cap_seq_list_clear(struct l2cap_seq_list *seq_list)
{}

static void l2cap_seq_list_append(struct l2cap_seq_list *seq_list, u16 seq)
{}

static void l2cap_chan_timeout(struct work_struct *work)
{}

struct l2cap_chan *l2cap_chan_create(void)
{}
EXPORT_SYMBOL_GPL();

static void l2cap_chan_destroy(struct kref *kref)
{}

void l2cap_chan_hold(struct l2cap_chan *c)
{}

struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c)
{}

void l2cap_chan_put(struct l2cap_chan *c)
{}
EXPORT_SYMBOL_GPL();

void l2cap_chan_set_defaults(struct l2cap_chan *chan)
{}
EXPORT_SYMBOL_GPL();

static __u16 l2cap_le_rx_credits(struct l2cap_chan *chan)
{}

static void l2cap_le_flowctl_init(struct l2cap_chan *chan, u16 tx_credits)
{}

static void l2cap_ecred_init(struct l2cap_chan *chan, u16 tx_credits)
{}

void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{}

void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
{}

void l2cap_chan_del(struct l2cap_chan *chan, int err)
{}
EXPORT_SYMBOL_GPL();

static void __l2cap_chan_list_id(struct l2cap_conn *conn, u16 id,
				 l2cap_chan_func_t func, void *data)
{}

static void __l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
			      void *data)
{}

void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
		     void *data)
{}

EXPORT_SYMBOL_GPL();

static void l2cap_conn_update_id_addr(struct work_struct *work)
{}

static void l2cap_chan_le_connect_reject(struct l2cap_chan *chan)
{}

static void l2cap_chan_ecred_connect_reject(struct l2cap_chan *chan)
{}

static void l2cap_chan_connect_reject(struct l2cap_chan *chan)
{}

void l2cap_chan_close(struct l2cap_chan *chan, int reason)
{}
EXPORT_SYMBOL();

static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan)
{}

/* Service level security */
int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator)
{}

static u8 l2cap_get_ident(struct l2cap_conn *conn)
{}

static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
			   void *data)
{}

static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
{}

static void __unpack_enhanced_control(u16 enh, struct l2cap_ctrl *control)
{}

static void __unpack_extended_control(u32 ext, struct l2cap_ctrl *control)
{}

static inline void __unpack_control(struct l2cap_chan *chan,
				    struct sk_buff *skb)
{}

static u32 __pack_extended_control(struct l2cap_ctrl *control)
{}

static u16 __pack_enhanced_control(struct l2cap_ctrl *control)
{}

static inline void __pack_control(struct l2cap_chan *chan,
				  struct l2cap_ctrl *control,
				  struct sk_buff *skb)
{}

static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan)
{}

static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan,
					       u32 control)
{}

static void l2cap_send_sframe(struct l2cap_chan *chan,
			      struct l2cap_ctrl *control)
{}

static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll)
{}

static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan)
{}

void l2cap_send_conn_req(struct l2cap_chan *chan)
{}

static void l2cap_chan_ready(struct l2cap_chan *chan)
{}

static void l2cap_le_connect(struct l2cap_chan *chan)
{}

struct l2cap_ecred_conn_data {};

static void l2cap_ecred_defer_connect(struct l2cap_chan *chan, void *data)
{}

static void l2cap_ecred_connect(struct l2cap_chan *chan)
{}

static void l2cap_le_start(struct l2cap_chan *chan)
{}

static void l2cap_start_connection(struct l2cap_chan *chan)
{}

static void l2cap_request_info(struct l2cap_conn *conn)
{}

static bool l2cap_check_enc_key_size(struct hci_conn *hcon)
{}

static void l2cap_do_start(struct l2cap_chan *chan)
{}

static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
{}

static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
{}

/* ---- L2CAP connections ---- */
static void l2cap_conn_start(struct l2cap_conn *conn)
{}

static void l2cap_le_conn_ready(struct l2cap_conn *conn)
{}

static void l2cap_conn_ready(struct l2cap_conn *conn)
{}

/* Notify sockets that we cannot guaranty reliability anymore */
static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
{}

static void l2cap_info_timeout(struct work_struct *work)
{}

/*
 * l2cap_user
 * External modules can register l2cap_user objects on l2cap_conn. The ->probe
 * callback is called during registration. The ->remove callback is called
 * during unregistration.
 * An l2cap_user object can either be explicitly unregistered or when the
 * underlying l2cap_conn object is deleted. This guarantees that l2cap->hcon,
 * l2cap->hchan, .. are valid as long as the remove callback hasn't been called.
 * External modules must own a reference to the l2cap_conn object if they intend
 * to call l2cap_unregister_user(). The l2cap_conn object might get destroyed at
 * any time if they don't.
 */

int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user)
{}
EXPORT_SYMBOL();

void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user)
{}
EXPORT_SYMBOL();

static void l2cap_unregister_all_users(struct l2cap_conn *conn)
{}

static void l2cap_conn_del(struct hci_conn *hcon, int err)
{}

static void l2cap_conn_free(struct kref *ref)
{}

struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn)
{}
EXPORT_SYMBOL();

void l2cap_conn_put(struct l2cap_conn *conn)
{}
EXPORT_SYMBOL();

/* ---- Socket interface ---- */

/* Find socket with psm and source / destination bdaddr.
 * Returns closest match.
 */
static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
						   bdaddr_t *src,
						   bdaddr_t *dst,
						   u8 link_type)
{}

static void l2cap_monitor_timeout(struct work_struct *work)
{}

static void l2cap_retrans_timeout(struct work_struct *work)
{}

static void l2cap_streaming_send(struct l2cap_chan *chan,
				 struct sk_buff_head *skbs)
{}

static int l2cap_ertm_send(struct l2cap_chan *chan)
{}

static void l2cap_ertm_resend(struct l2cap_chan *chan)
{}

static void l2cap_retransmit(struct l2cap_chan *chan,
			     struct l2cap_ctrl *control)
{}

static void l2cap_retransmit_all(struct l2cap_chan *chan,
				 struct l2cap_ctrl *control)
{}

static void l2cap_send_ack(struct l2cap_chan *chan)
{}

static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan,
					 struct msghdr *msg, int len,
					 int count, struct sk_buff *skb)
{}

static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan,
						 struct msghdr *msg, size_t len)
{}

static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan,
					      struct msghdr *msg, size_t len)
{}

static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan,
					       struct msghdr *msg, size_t len,
					       u16 sdulen)
{}

static int l2cap_segment_sdu(struct l2cap_chan *chan,
			     struct sk_buff_head *seg_queue,
			     struct msghdr *msg, size_t len)
{}

static struct sk_buff *l2cap_create_le_flowctl_pdu(struct l2cap_chan *chan,
						   struct msghdr *msg,
						   size_t len, u16 sdulen)
{}

static int l2cap_segment_le_sdu(struct l2cap_chan *chan,
				struct sk_buff_head *seg_queue,
				struct msghdr *msg, size_t len)
{}

static void l2cap_le_flowctl_send(struct l2cap_chan *chan)
{}

int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
{}
EXPORT_SYMBOL_GPL();

static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq)
{}

static void l2cap_send_srej_tail(struct l2cap_chan *chan)
{}

static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq)
{}

static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq)
{}

static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan)
{}

static void l2cap_tx_state_xmit(struct l2cap_chan *chan,
				struct l2cap_ctrl *control,
				struct sk_buff_head *skbs, u8 event)
{}

static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
				  struct l2cap_ctrl *control,
				  struct sk_buff_head *skbs, u8 event)
{}

static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
		     struct sk_buff_head *skbs, u8 event)
{}

static void l2cap_pass_to_tx(struct l2cap_chan *chan,
			     struct l2cap_ctrl *control)
{}

static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan,
				  struct l2cap_ctrl *control)
{}

/* Copy frame to all raw sockets on that connection */
static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{}

/* ---- L2CAP signalling commands ---- */
static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code,
				       u8 ident, u16 dlen, void *data)
{}

static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen,
				     unsigned long *val)
{}

static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size)
{}

static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size)
{}

static void l2cap_ack_timeout(struct work_struct *work)
{}

int l2cap_ertm_init(struct l2cap_chan *chan)
{}

static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask)
{}

static inline bool __l2cap_ews_supported(struct l2cap_conn *conn)
{}

static inline bool __l2cap_efs_supported(struct l2cap_conn *conn)
{}

static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan,
				      struct l2cap_conf_rfc *rfc)
{}

static inline void l2cap_txwin_setup(struct l2cap_chan *chan)
{}

static void l2cap_mtu_auto(struct l2cap_chan *chan)
{}

static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
{}

static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
{}

static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
				void *data, size_t size, u16 *result)
{}

static int l2cap_build_conf_rsp(struct l2cap_chan *chan, void *data,
				u16 result, u16 flags)
{}

void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan)
{}

static void l2cap_ecred_list_defer(struct l2cap_chan *chan, void *data)
{}

struct l2cap_ecred_rsp_data {};

static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
{}

void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
{}

void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
{}

static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
{}

static inline int l2cap_command_rej(struct l2cap_conn *conn,
				    struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				    u8 *data)
{}

static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
			  u8 *data, u8 rsp_code)
{}

static int l2cap_connect_req(struct l2cap_conn *conn,
			     struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
{}

static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
				    struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				    u8 *data)
{}

static inline void set_default_fcs(struct l2cap_chan *chan)
{}

static void l2cap_send_efs_conf_rsp(struct l2cap_chan *chan, void *data,
				    u8 ident, u16 flags)
{}

static void cmd_reject_invalid_cid(struct l2cap_conn *conn, u8 ident,
				   u16 scid, u16 dcid)
{}

static inline int l2cap_config_req(struct l2cap_conn *conn,
				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				   u8 *data)
{}

static inline int l2cap_config_rsp(struct l2cap_conn *conn,
				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				   u8 *data)
{}

static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				       u8 *data)
{}

static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn,
				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				       u8 *data)
{}

static inline int l2cap_information_req(struct l2cap_conn *conn,
					struct l2cap_cmd_hdr *cmd, u16 cmd_len,
					u8 *data)
{}

static inline int l2cap_information_rsp(struct l2cap_conn *conn,
					struct l2cap_cmd_hdr *cmd, u16 cmd_len,
					u8 *data)
{}

static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
					      struct l2cap_cmd_hdr *cmd,
					      u16 cmd_len, u8 *data)
{}

static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
				struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				u8 *data)
{}

static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
				      struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				      u8 *data)
{}

static int l2cap_le_connect_req(struct l2cap_conn *conn,
				struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				u8 *data)
{}

static inline int l2cap_le_credits(struct l2cap_conn *conn,
				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				   u8 *data)
{}

static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn,
				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				       u8 *data)
{}

static inline int l2cap_ecred_conn_rsp(struct l2cap_conn *conn,
				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				       u8 *data)
{}

static inline int l2cap_ecred_reconf_req(struct l2cap_conn *conn,
					 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
					 u8 *data)
{}

static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
					 struct l2cap_cmd_hdr *cmd, u16 cmd_len,
					 u8 *data)
{}

static inline int l2cap_le_command_rej(struct l2cap_conn *conn,
				       struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				       u8 *data)
{}

static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn,
				   struct l2cap_cmd_hdr *cmd, u16 cmd_len,
				   u8 *data)
{}

static inline void l2cap_le_sig_channel(struct l2cap_conn *conn,
					struct sk_buff *skb)
{}

static inline void l2cap_sig_send_rej(struct l2cap_conn *conn, u16 ident)
{}

static inline void l2cap_sig_channel(struct l2cap_conn *conn,
				     struct sk_buff *skb)
{}

static int l2cap_check_fcs(struct l2cap_chan *chan,  struct sk_buff *skb)
{}

static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan)
{}

static void append_skb_frag(struct sk_buff *skb, struct sk_buff *new_frag,
			    struct sk_buff **last_frag)
{}

static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb,
				struct l2cap_ctrl *control)
{}

static int l2cap_resegment(struct l2cap_chan *chan)
{}

void l2cap_chan_busy(struct l2cap_chan *chan, int busy)
{}

static int l2cap_rx_queued_iframes(struct l2cap_chan *chan)
{}

static void l2cap_handle_srej(struct l2cap_chan *chan,
			      struct l2cap_ctrl *control)
{}

static void l2cap_handle_rej(struct l2cap_chan *chan,
			     struct l2cap_ctrl *control)
{}

static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq)
{}

static int l2cap_rx_state_recv(struct l2cap_chan *chan,
			       struct l2cap_ctrl *control,
			       struct sk_buff *skb, u8 event)
{}

static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
				    struct l2cap_ctrl *control,
				    struct sk_buff *skb, u8 event)
{}

static int l2cap_finish_move(struct l2cap_chan *chan)
{}

static int l2cap_rx_state_wait_p(struct l2cap_chan *chan,
				 struct l2cap_ctrl *control,
				 struct sk_buff *skb, u8 event)
{}

static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
				 struct l2cap_ctrl *control,
				 struct sk_buff *skb, u8 event)
{}

static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq)
{}

static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
		    struct sk_buff *skb, u8 event)
{}

static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
			   struct sk_buff *skb)
{}

static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
{}

static void l2cap_chan_le_send_credits(struct l2cap_chan *chan)
{}

void l2cap_chan_rx_avail(struct l2cap_chan *chan, ssize_t rx_avail)
{}

static int l2cap_ecred_recv(struct l2cap_chan *chan, struct sk_buff *skb)
{}

static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
{}

static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid,
			       struct sk_buff *skb)
{}

static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
				  struct sk_buff *skb)
{}

static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
{}

static void process_pending_rx(struct work_struct *work)
{}

static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
{}

static bool is_valid_psm(u16 psm, u8 dst_type)
{}

struct l2cap_chan_data {};

static void l2cap_chan_by_pid(struct l2cap_chan *chan, void *data)
{}

int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
		       bdaddr_t *dst, u8 dst_type, u16 timeout)
{}
EXPORT_SYMBOL_GPL();

static void l2cap_ecred_reconfigure(struct l2cap_chan *chan)
{}

int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu)
{}

/* ---- L2CAP interface with lower layer (HCI) ---- */

int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
{}

/* Find the next fixed channel in BT_LISTEN state, continue iteration
 * from an existing channel in the list or from the beginning of the
 * global list (by passing NULL as first parameter).
 */
static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c,
						  struct hci_conn *hcon)
{}

static void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
{}

int l2cap_disconn_ind(struct hci_conn *hcon)
{}

static void l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason)
{}

static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
{}

static void l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
{}

/* Append fragment into frame respecting the maximum len of rx_skb */
static int l2cap_recv_frag(struct l2cap_conn *conn, struct sk_buff *skb,
			   u16 len)
{}

static int l2cap_recv_len(struct l2cap_conn *conn, struct sk_buff *skb)
{}

static void l2cap_recv_reset(struct l2cap_conn *conn)
{}

void l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags)
{}

static struct hci_cb l2cap_cb =;

static int l2cap_debugfs_show(struct seq_file *f, void *p)
{}

DEFINE_SHOW_ATTRIBUTE();

static struct dentry *l2cap_debugfs;

int __init l2cap_init(void)
{}

void l2cap_exit(void)
{}

module_param(disable_ertm, bool, 0644);
MODULE_PARM_DESC();

module_param(enable_ecred, bool, 0644);
MODULE_PARM_DESC();