summaryrefslogtreecommitdiff
path: root/emulator/bthost.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-12-17 14:36:53 +0200
committerJohan Hedberg <johan.hedberg@intel.com>2014-12-17 14:42:26 +0200
commitca95433e207dd231c22ec8a15a6b13fbce477618 (patch)
tree721b67f00325de503c13402587b24c111f80c699 /emulator/bthost.c
parentf68a9934844fe80a0b5c86274faf59847c7b8b95 (diff)
downloadbluez-ca95433e207dd231c22ec8a15a6b13fbce477618.tar.gz
emulator: Improve L2CAP info request support in bthost
Diffstat (limited to 'emulator/bthost.c')
-rw-r--r--emulator/bthost.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 44c01d340..ef06c6035 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -47,6 +47,12 @@
#define acl_handle(h) (h & 0x0fff)
#define acl_flags(h) (h >> 12)
+#define L2CAP_FEAT_FIXED_CHAN 0x00000080
+#define L2CAP_FC_SIG_BREDR 0x02
+#define L2CAP_FC_SMP_BREDR 0x80
+#define L2CAP_IT_FEAT_MASK 0x0002
+#define L2CAP_IT_FIXED_CHAN 0x0003
+
/* RFCOMM setters */
#define RFCOMM_ADDR(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
#define RFCOMM_CTRL(type, pf) (((type & 0xef) | (pf << 4)))
@@ -1450,16 +1456,41 @@ static bool l2cap_info_req(struct bthost *bthost, struct btconn *conn,
uint8_t ident, const void *data, uint16_t len)
{
const struct bt_l2cap_pdu_info_req *req = data;
- struct bt_l2cap_pdu_info_rsp rsp;
+ uint64_t fixed_chan;
+ uint16_t type;
+ uint8_t buf[12];
+ struct bt_l2cap_pdu_info_rsp *rsp = (void *) buf;
if (len < sizeof(*req))
return false;
- rsp.type = req->type;
- rsp.result = cpu_to_le16(0x0001); /* Not Supported */
+ memset(buf, 0, sizeof(buf));
+ rsp->type = req->type;
- l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_INFO_RSP, ident, &rsp,
- sizeof(rsp));
+ type = le16_to_cpu(req->type);
+
+ switch (type) {
+ case L2CAP_IT_FEAT_MASK:
+ rsp->result = 0x0000;
+ put_le32(L2CAP_FEAT_FIXED_CHAN, rsp->data);
+ l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_INFO_RSP, ident,
+ rsp, sizeof(*rsp) + 4);
+ break;
+ case L2CAP_IT_FIXED_CHAN:
+ rsp->result = 0x0000;
+ fixed_chan = L2CAP_FC_SIG_BREDR;
+ if (bthost->sc && bthost->le)
+ fixed_chan |= L2CAP_FC_SMP_BREDR;
+ put_le64(fixed_chan, rsp->data);
+ l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_INFO_RSP, ident,
+ rsp, sizeof(*rsp) + sizeof(fixed_chan));
+ break;
+ default:
+ rsp->result = cpu_to_le16(0x0001); /* Not Supported */
+ l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_INFO_RSP, ident,
+ rsp, sizeof(*rsp));
+ break;
+ }
return true;
}