net/bluetooth/hci_conn.c

Source file repositories/reference/linux-study-clean/net/bluetooth/hci_conn.c

File Facts

System
Linux kernel
Corpus path
net/bluetooth/hci_conn.c
Extension
.c
Size
84084 bytes
Lines
3391
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sco_param {
	u16 pkt_type;
	u16 max_latency;
	u8  retrans_effort;
};

struct conn_handle_t {
	struct hci_conn *conn;
	__u16 handle;
};

static const struct sco_param esco_param_cvsd[] = {
	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a,	0x01 }, /* S3 */
	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007,	0x01 }, /* S2 */
	{ EDR_ESCO_MASK | ESCO_EV3,   0x0007,	0x01 }, /* S1 */
	{ EDR_ESCO_MASK | ESCO_HV3,   0xffff,	0x01 }, /* D1 */
	{ EDR_ESCO_MASK | ESCO_HV1,   0xffff,	0x01 }, /* D0 */
};

static const struct sco_param sco_param_cvsd[] = {
	{ EDR_ESCO_MASK | ESCO_HV3,   0xffff,	0xff }, /* D1 */
	{ EDR_ESCO_MASK | ESCO_HV1,   0xffff,	0xff }, /* D0 */
};

static const struct sco_param esco_param_msbc[] = {
	{ EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d,	0x02 }, /* T2 */
	{ EDR_ESCO_MASK | ESCO_EV3,   0x0008,	0x02 }, /* T1 */
};

/* This function requires the caller holds hdev->lock */
void hci_connect_le_scan_cleanup(struct hci_conn *conn, u8 status)
{
	struct hci_conn_params *params;
	struct hci_dev *hdev = conn->hdev;
	struct smp_irk *irk;
	bdaddr_t *bdaddr;
	u8 bdaddr_type;

	bdaddr = &conn->dst;
	bdaddr_type = conn->dst_type;

	/* Check if we need to convert to identity address */
	irk = hci_get_irk(hdev, bdaddr, bdaddr_type);
	if (irk) {
		bdaddr = &irk->bdaddr;
		bdaddr_type = irk->addr_type;
	}

	params = hci_pend_le_action_lookup(&hdev->pend_le_conns, bdaddr,
					   bdaddr_type);
	if (!params)
		return;

	if (params->conn) {
		hci_conn_drop(params->conn);
		hci_conn_put(params->conn);
		params->conn = NULL;
	}

	if (!params->explicit_connect)
		return;

	/* If the status indicates successful cancellation of
	 * the attempt (i.e. Unknown Connection Id) there's no point of
	 * notifying failure since we'll go back to keep trying to
	 * connect. The only exception is explicit connect requests
	 * where a timeout + cancel does indicate an actual failure.
	 */
	if (status && status != HCI_ERROR_UNKNOWN_CONN_ID)
		mgmt_connect_failed(hdev, conn, status);

	/* The connection attempt was doing scan for new RPA, and is
	 * in scan phase. If params are not associated with any other
	 * autoconnect action, remove them completely. If they are, just unmark
	 * them as waiting for connection, by clearing explicit_connect field.
	 */
	params->explicit_connect = false;

	hci_pend_le_list_del_init(params);

	switch (params->auto_connect) {
	case HCI_AUTO_CONN_EXPLICIT:
		hci_conn_params_del(hdev, bdaddr, bdaddr_type);
		/* return instead of break to avoid duplicate scan update */
		return;
	case HCI_AUTO_CONN_DIRECT:
	case HCI_AUTO_CONN_ALWAYS:
		hci_pend_le_list_add(params, &hdev->pend_le_conns);
		break;
	case HCI_AUTO_CONN_REPORT:

Annotation

Implementation Notes