summaryrefslogtreecommitdiff
path: root/emulator/smp.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-01-07 12:16:11 +0200
committerJohan Hedberg <johan.hedberg@intel.com>2015-01-07 13:13:27 +0200
commit4003a333dc4484dd68671ffecda894f57149ff07 (patch)
tree30ee605defc356fdfff066a8aacf1d7071987289 /emulator/smp.c
parentf5653c83e84d36b0745355d35a9741e0cb0c7901 (diff)
downloadbluez-4003a333dc4484dd68671ffecda894f57149ff07.tar.gz
emulator/bthost: Add support for triggering SMP over BR/EDR
Diffstat (limited to 'emulator/smp.c')
-rw-r--r--emulator/smp.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/emulator/smp.c b/emulator/smp.c
index 5d338b7e0..4f527e990 100644
--- a/emulator/smp.c
+++ b/emulator/smp.c
@@ -47,6 +47,8 @@
#define SMP_CID 0x0006
#define SMP_BREDR_CID 0x0007
+#define L2CAP_FC_SMP_BREDR 0x80
+
#define SMP_PASSKEY_ENTRY_FAILED 0x01
#define SMP_OOB_NOT_AVAIL 0x02
#define SMP_AUTH_REQUIREMENTS 0x03
@@ -462,6 +464,13 @@ static void pairing_rsp(struct smp_conn *conn, const void *data, uint16_t len)
conn->local_key_dist = conn->prsp[5];
conn->remote_key_dist = conn->prsp[6];
+ if (conn->addr_type == BDADDR_BREDR) {
+ conn->local_key_dist &= ~SC_NO_DIST;
+ conn->remote_key_dist &= ~SC_NO_DIST;
+ distribute_keys(conn);
+ return;
+ }
+
if (((conn->prsp[3] & 0x08) && (conn->preq[3] & 0x08)) ||
conn->addr_type == BDADDR_BREDR) {
conn->sc = true;
@@ -788,6 +797,29 @@ int smp_get_ltk(void *smp_data, uint64_t rand, uint16_t ediv, uint8_t *ltk)
return 0;
}
+static void smp_conn_bredr(struct smp_conn *conn, uint8_t encrypt)
+{
+ struct smp *smp = conn->smp;
+ struct bt_l2cap_smp_pairing_request req;
+ uint64_t fixed_chan;
+
+ if (encrypt != 0x02)
+ return;
+
+ conn->sc = true;
+
+ fixed_chan = bthost_conn_get_fixed_chan(smp->bthost, conn->handle);
+ if (!(fixed_chan & L2CAP_FC_SMP_BREDR))
+ return;
+
+ memset(&req, 0, sizeof(req));
+ req.max_key_size = 0x10;
+ req.init_key_dist = KEY_DIST;
+ req.resp_key_dist = KEY_DIST;
+
+ smp_send(conn, BT_L2CAP_SMP_PAIRING_REQUEST, &req, sizeof(req));
+}
+
void smp_conn_encrypted(void *conn_data, uint8_t encrypt)
{
struct smp_conn *conn = conn_data;
@@ -795,6 +827,11 @@ void smp_conn_encrypted(void *conn_data, uint8_t encrypt)
if (!encrypt)
return;
+ if (conn->addr_type == BDADDR_BREDR) {
+ smp_conn_bredr(conn, encrypt);
+ return;
+ }
+
if (conn->out && conn->remote_key_dist)
return;