summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Stuehler <uwe@cvs.openbsd.org>2008-02-24 21:42:04 +0000
committerUwe Stuehler <uwe@cvs.openbsd.org>2008-02-24 21:42:04 +0000
commite1b76e90d81c71953efdcba2e828cdeae87cd7a9 (patch)
tree4fbe5c12daf4e8df7f96a44483b0b9ee24b05a46
parent0f57bfa559ae850def03153006105883b91d362e (diff)
Handle "QOS" L2CAP configuration request option, enabling L2CAP
connections to Sony Ericsson W880i mobile phones
-rw-r--r--sys/netbt/l2cap_signal.c47
1 files changed, 46 insertions, 1 deletions
diff --git a/sys/netbt/l2cap_signal.c b/sys/netbt/l2cap_signal.c
index a5874b14baa..d0377e1d698 100644
--- a/sys/netbt/l2cap_signal.c
+++ b/sys/netbt/l2cap_signal.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: l2cap_signal.c,v 1.3 2008/02/24 21:34:48 uwe Exp $ */
+/* $OpenBSD: l2cap_signal.c,v 1.4 2008/02/24 21:42:03 uwe Exp $ */
/* $NetBSD: l2cap_signal.c,v 1.9 2007/11/10 23:12:23 plunky Exp $ */
/*-
@@ -520,6 +520,51 @@ l2cap_recv_config_req(struct mbuf *m, struct hci_link *link)
break;
case L2CAP_OPT_QOS:
+ if (rp.result == L2CAP_UNKNOWN_OPTION)
+ break;
+
+ if (opt.length != L2CAP_OPT_QOS_SIZE)
+ goto reject;
+
+ m_copydata(m, 0, L2CAP_OPT_QOS_SIZE, (caddr_t)&val);
+ if (val.qos.service_type == L2CAP_QOS_NO_TRAFFIC ||
+ val.qos.service_type == L2CAP_QOS_BEST_EFFORT)
+ /*
+ * In accordance with the spec, we choose to
+ * ignore the fields an provide no response.
+ */
+ break;
+
+ if (len + sizeof(opt) + L2CAP_OPT_QOS_SIZE > sizeof(buf))
+ goto reject;
+
+ if (val.qos.service_type != L2CAP_QOS_GUARANTEED) {
+ /*
+ * Instead of sending an "unacceptable
+ * parameters" response, treat this as an
+ * unknown option and include the option
+ * value in the response.
+ */
+ rp.result = L2CAP_UNKNOWN_OPTION;
+ } else {
+ /*
+ * According to the spec, we must return
+ * specific values for wild card parameters.
+ * I don't know what to return without lying,
+ * so return "unacceptable parameters" and
+ * specify the preferred service type as
+ * "Best Effort".
+ */
+ rp.result = L2CAP_UNACCEPTABLE_PARAMS;
+ val.qos.service_type = L2CAP_QOS_BEST_EFFORT;
+ }
+
+ memcpy(buf + len, &opt, sizeof(opt));
+ len += sizeof(opt);
+ memcpy(buf + len, &val, L2CAP_OPT_QOS_SIZE);
+ len += L2CAP_OPT_QOS_SIZE;
+ break;
+
default:
/* ignore hints */
if (opt.type & L2CAP_OPT_HINT_BIT)