static int l2cap_sock_release(struct socket *sock)
{
	struct sock *sk = sock->sk;
	struct sock *srv_sk = NULL;
	int err;

	BT_DBG("sock %p, sk %p", sock, sk);

	if (!sk)
		return 0;

	/* If this is an ATT Client socket, find the matching Server */
	if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA && !l2cap_pi(sk)->incoming)
		srv_sk = l2cap_find_sock_by_fixed_cid_and_dir(L2CAP_CID_LE_DATA,
					&bt_sk(sk)->src, &bt_sk(sk)->dst, 1);

	/* If server socket found, request tear down */
	BT_DBG("client:%p server:%p", sk, srv_sk);
	if (srv_sk)
		l2cap_sock_set_timer(srv_sk, 1);

	err = l2cap_sock_shutdown(sock, 2);

	sock_orphan(sk);
	l2cap_sock_kill(sk);
	return err;
}
示例#2
0
static int l2cap_sock_release(struct socket *sock)
{
	struct sock *sk = sock->sk;
	struct sock *sk2 = NULL;
	int err;

	BT_DBG("sock %p, sk %p", sock, sk);

	if (!sk)
		return 0;

	/* If this is an ATT socket, find it's matching server/client */
	if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA)
		sk2 = l2cap_find_sock_by_fixed_cid_and_dir(L2CAP_CID_LE_DATA,
					&bt_sk(sk)->src, &bt_sk(sk)->dst,
					l2cap_pi(sk)->incoming ? 0 : 1);

	/* If matching socket found, request tear down */
	BT_DBG("sock:%p companion:%p", sk, sk2);
	if (sk2)
		l2cap_sock_set_timer(sk2, 1);

	err = l2cap_sock_shutdown(sock, 2);

	sock_orphan(sk);
	l2cap_sock_kill(sk);
	return err;
}
示例#3
0
int smp_link_encrypt_cmplt(struct l2cap_conn *conn, u8 status, u8 encrypt)
{
	struct hci_conn *hcon = conn->hcon;

	BT_DBG("smp: %d %d %d", status, encrypt, hcon->sec_req);

	clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
#ifdef BLUETOOTH_CUSTOMIZE
	if (test_bit(HCI_CONN_LE_CONN_UPDATE_PEND, &hcon->pend)) {
		struct sock *sk;
		BT_DBG("HCI_CONN_LE_CONN_UPDATE_PEND");
		sk = l2cap_find_sock_by_fixed_cid_and_dir(4, conn->src, conn->dst, 0);
		if (sk) {
			BT_DBG("call hci_le_conn_update");
			hci_le_conn_update(hcon, 
				bt_sk(sk)->le_params.interval_min,
				bt_sk(sk)->le_params.interval_max,
				bt_sk(sk)->le_params.latency,
				bt_sk(sk)->le_params.supervision_timeout);
		}
	}
#endif /* BLUETOOTH_CUSTOMIZE */

	if (!status && encrypt && hcon->sec_level < hcon->pending_sec_level)
		hcon->sec_level = hcon->pending_sec_level;

	if (!status && encrypt && !hcon->sec_req)
		return smp_distribute_keys(conn, 0);

	/* Fall back to Pairing request if failed a Link Security request */
	else if (hcon->sec_req  && (status || !encrypt))
		smp_conn_security(conn, hcon->pending_sec_level);

	hci_conn_put(hcon);

	return 0;
}