net/bluetooth/mgmt.c

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

File Facts

System
Linux kernel
Corpus path
net/bluetooth/mgmt.c
Extension
.c
Size
272701 bytes
Lines
10635
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source 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 cmd_lookup {
	struct sock *sk;
	struct hci_dev *hdev;
	u8 mgmt_status;
};

static void settings_rsp(struct mgmt_pending_cmd *cmd, void *data)
{
	struct cmd_lookup *match = data;

	send_settings_rsp(cmd->sk, cmd->opcode, match->hdev);

	if (match->sk == NULL) {
		match->sk = cmd->sk;
		sock_hold(match->sk);
	}
}

static void cmd_status_rsp(struct mgmt_pending_cmd *cmd, void *data)
{
	u8 *status = data;

	mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, *status);
}

static void cmd_complete_rsp(struct mgmt_pending_cmd *cmd, void *data)
{
	struct cmd_lookup *match = data;

	/* dequeue cmd_sync entries using cmd as data as that is about to be
	 * removed/freed.
	 */
	hci_cmd_sync_dequeue(match->hdev, NULL, cmd, NULL);

	if (cmd->cmd_complete) {
		cmd->cmd_complete(cmd, match->mgmt_status);
		return;
	}

	cmd_status_rsp(cmd, data);
}

static int generic_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
{
	return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
				 cmd->param, cmd->param_len);
}

static int addr_cmd_complete(struct mgmt_pending_cmd *cmd, u8 status)
{
	return mgmt_cmd_complete(cmd->sk, cmd->hdev->id, cmd->opcode, status,
				 cmd->param, sizeof(struct mgmt_addr_info));
}

static u8 mgmt_bredr_support(struct hci_dev *hdev)
{
	if (!lmp_bredr_capable(hdev))
		return MGMT_STATUS_NOT_SUPPORTED;
	else if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
		return MGMT_STATUS_REJECTED;
	else
		return MGMT_STATUS_SUCCESS;
}

static u8 mgmt_le_support(struct hci_dev *hdev)
{
	if (!lmp_le_capable(hdev))
		return MGMT_STATUS_NOT_SUPPORTED;
	else if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
		return MGMT_STATUS_REJECTED;
	else
		return MGMT_STATUS_SUCCESS;
}

static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
					   int err)
{
	struct mgmt_pending_cmd *cmd = data;

	bt_dev_dbg(hdev, "err %d", err);

	/* Make sure cmd still outstanding. */
	if (err == -ECANCELED || !mgmt_pending_valid(hdev, cmd))
		return;

	hci_dev_lock(hdev);

	if (err) {
		u8 mgmt_err = mgmt_status(err);
		mgmt_cmd_status(cmd->sk, cmd->hdev->id, cmd->opcode, mgmt_err);

Annotation

Implementation Notes