Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netbt Handle some ``Quality of Service'' configuration o...
details: https://anonhg.NetBSD.org/src/rev/e40f386af259
branches: trunk
changeset: 771700:e40f386af259
user: plunky <plunky%NetBSD.org@localhost>
date: Tue Nov 29 13:16:27 2011 +0000
description:
Handle some ``Quality of Service'' configuration options, to
help devices requesting them blindly succeed in connecting.
should fix a problem analysed by Nat Sloss on current-users
diffstat:
sys/netbt/l2cap_signal.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 110 insertions(+), 2 deletions(-)
diffs (151 lines):
diff -r 4faed2f42700 -r e40f386af259 sys/netbt/l2cap_signal.c
--- a/sys/netbt/l2cap_signal.c Tue Nov 29 13:16:26 2011 +0000
+++ b/sys/netbt/l2cap_signal.c Tue Nov 29 13:16:27 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: l2cap_signal.c,v 1.14 2011/07/27 10:25:09 plunky Exp $ */
+/* $NetBSD: l2cap_signal.c,v 1.15 2011/11/29 13:16:27 plunky Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_signal.c,v 1.14 2011/07/27 10:25:09 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_signal.c,v 1.15 2011/11/29 13:16:27 plunky Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -59,6 +59,8 @@
static void l2cap_recv_info_req(struct mbuf *, struct hci_link *);
static int l2cap_send_signal(struct hci_link *, uint8_t, uint8_t, uint16_t, void *);
static int l2cap_send_command_rej(struct hci_link *, uint8_t, uint16_t, ...);
+static void l2cap_qos_btoh(l2cap_qos_t *, void *);
+static void l2cap_qos_htob(void *, l2cap_qos_t *);
/*
* process incoming signal packets (CID 0x0001). Can contain multiple
@@ -518,6 +520,57 @@
break;
case L2CAP_OPT_QOS:
+ if (rp.result == L2CAP_UNKNOWN_OPTION)
+ break;
+
+ if (opt.length != L2CAP_OPT_QOS_SIZE)
+ goto reject;
+
+ /*
+ * We don't actually support QoS, but an incoming
+ * config request is merely advising us of their
+ * outgoing traffic flow, so be nice.
+ */
+ m_copydata(m, 0, L2CAP_OPT_QOS_SIZE, &val);
+ switch (val.qos.service_type) {
+ case L2CAP_QOS_NO_TRAFFIC:
+ /*
+ * "No traffic" means they don't plan to send
+ * any data and the fields should be ignored.
+ */
+ chan->lc_iqos = l2cap_default_qos;
+ chan->lc_iqos.service_type = L2CAP_QOS_NO_TRAFFIC;
+ break;
+
+ case L2CAP_QOS_BEST_EFFORT:
+ /*
+ * "Best effort" is the default, and we may
+ * choose to ignore the fields, try to satisfy
+ * the parameters while giving no response, or
+ * respond with the settings we will try to
+ * meet.
+ */
+ l2cap_qos_btoh(&chan->lc_iqos, &val.qos);
+ break;
+
+ case L2CAP_QOS_GUARANTEED:
+ default:
+ /*
+ * Anything else we don't support, so make a
+ * counter-offer with the current settings.
+ */
+ if (len + sizeof(opt) + L2CAP_OPT_QOS_SIZE > sizeof(buf))
+ goto reject;
+
+ rp.result = L2CAP_UNACCEPTABLE_PARAMS;
+ memcpy(buf + len, &opt, sizeof(opt));
+ len += sizeof(opt);
+ l2cap_qos_htob(buf + len, &chan->lc_iqos);
+ len += L2CAP_OPT_QOS_SIZE;
+ break;
+ }
+ break;
+
default:
/* ignore hints */
if (opt.type & L2CAP_OPT_HINT_BIT)
@@ -688,6 +741,27 @@
goto discon;
case L2CAP_OPT_QOS:
+ if (opt.length != L2CAP_OPT_QOS_SIZE)
+ goto discon;
+
+ /*
+ * This may happen even if we haven't sent a
+ * QoS request, where they need to state their
+ * preferred incoming traffic flow.
+ * We don't support anything, but copy in the
+ * parameters if no action is good enough.
+ */
+ m_copydata(m, 0, L2CAP_OPT_QOS_SIZE, &val);
+ switch (val.qos.service_type) {
+ case L2CAP_QOS_NO_TRAFFIC:
+ case L2CAP_QOS_BEST_EFFORT:
+ l2cap_qos_btoh(&chan->lc_oqos, &val.qos);
+ break;
+
+ case L2CAP_QOS_GUARANTEED:
+ default:
+ goto discon;
+ }
break;
default:
@@ -1130,3 +1204,37 @@
return l2cap_send_signal(link, L2CAP_CONNECT_RSP, ident, sizeof(cp), &cp);
}
+
+/*
+ * copy in QoS buffer to host
+ */
+static void
+l2cap_qos_btoh(l2cap_qos_t *qos, void *buf)
+{
+ l2cap_qos_t *src = buf;
+
+ qos->flags = src->flags;
+ qos->service_type = src->service_type;
+ qos->token_rate = le32toh(src->token_rate);
+ qos->token_bucket_size = le32toh(src->token_bucket_size);
+ qos->peak_bandwidth = le32toh(src->peak_bandwidth);
+ qos->latency = le32toh(src->latency);
+ qos->delay_variation = le32toh(src->delay_variation);
+}
+
+/*
+ * copy out host QoS to buffer
+ */
+static void
+l2cap_qos_htob(void *buf, l2cap_qos_t *qos)
+{
+ l2cap_qos_t *dst = buf;
+
+ dst->flags = qos->flags;
+ dst->service_type = qos->service_type;
+ dst->token_rate = htole32(qos->token_rate);
+ dst->token_bucket_size = htole32(qos->token_bucket_size);
+ dst->peak_bandwidth = htole32(qos->peak_bandwidth);
+ dst->latency = htole32(qos->latency);
+ dst->delay_variation = htole32(qos->delay_variation);
+}
Home |
Main Index |
Thread Index |
Old Index