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; }
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; }
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; }