diff options
author | Uwe Stuehler <uwe@cvs.openbsd.org> | 2008-02-24 21:42:04 +0000 |
---|---|---|
committer | Uwe Stuehler <uwe@cvs.openbsd.org> | 2008-02-24 21:42:04 +0000 |
commit | e1b76e90d81c71953efdcba2e828cdeae87cd7a9 (patch) | |
tree | 4fbe5c12daf4e8df7f96a44483b0b9ee24b05a46 | |
parent | 0f57bfa559ae850def03153006105883b91d362e (diff) |
Handle "QOS" L2CAP configuration request option, enabling L2CAP
connections to Sony Ericsson W880i mobile phones
-rw-r--r-- | sys/netbt/l2cap_signal.c | 47 |
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) |