Module Name: src
Committed By: tls
Date: Sun Aug 10 06:56:23 UTC 2014
Modified Files:
src/sys/netbt [tls-earlyentropy]: bluetooth.h bt_proto.c hci.h
hci_ioctl.c hci_link.c hci_socket.c hci_unit.c l2cap.h
l2cap_lower.c l2cap_socket.c l2cap_upper.c rfcomm.h rfcomm_dlc.c
rfcomm_session.c rfcomm_socket.c rfcomm_upper.c sco.h sco_socket.c
sco_upper.c
Log Message:
Rebase.
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.11.28.1 src/sys/netbt/bluetooth.h
cvs rdiff -u -r1.12 -r1.12.36.1 src/sys/netbt/bt_proto.c
cvs rdiff -u -r1.35 -r1.35.26.1 src/sys/netbt/hci.h
cvs rdiff -u -r1.10 -r1.10.32.1 src/sys/netbt/hci_ioctl.c
cvs rdiff -u -r1.23 -r1.23.26.1 src/sys/netbt/hci_link.c
cvs rdiff -u -r1.20 -r1.20.28.1 src/sys/netbt/hci_socket.c
cvs rdiff -u -r1.13 -r1.13.26.1 src/sys/netbt/hci_unit.c
cvs rdiff -u -r1.10 -r1.10.28.1 src/sys/netbt/l2cap.h
cvs rdiff -u -r1.9 -r1.9.54.1 src/sys/netbt/l2cap_lower.c
cvs rdiff -u -r1.10 -r1.10.2.1 src/sys/netbt/l2cap_socket.c
cvs rdiff -u -r1.11 -r1.11.36.1 src/sys/netbt/l2cap_upper.c
cvs rdiff -u -r1.9 -r1.9.36.1 src/sys/netbt/rfcomm.h \
src/sys/netbt/sco_upper.c
cvs rdiff -u -r1.7 -r1.7.26.1 src/sys/netbt/rfcomm_dlc.c
cvs rdiff -u -r1.18 -r1.18.26.1 src/sys/netbt/rfcomm_session.c
cvs rdiff -u -r1.11 -r1.11.2.1 src/sys/netbt/rfcomm_socket.c
cvs rdiff -u -r1.13 -r1.13.36.1 src/sys/netbt/rfcomm_upper.c
cvs rdiff -u -r1.3 -r1.3.54.1 src/sys/netbt/sco.h
cvs rdiff -u -r1.12 -r1.12.2.1 src/sys/netbt/sco_socket.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/netbt/bluetooth.h
diff -u src/sys/netbt/bluetooth.h:1.11 src/sys/netbt/bluetooth.h:1.11.28.1
--- src/sys/netbt/bluetooth.h:1.11 Wed Apr 27 00:36:48 2011
+++ src/sys/netbt/bluetooth.h Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: bluetooth.h,v 1.11 2011/04/27 00:36:48 rmind Exp $ */
+/* $NetBSD: bluetooth.h,v 1.11.28.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -103,6 +103,8 @@ struct sockaddr_bt {
#ifdef _KERNEL
+#include <sys/protosw.h>
+
#include <sys/mallocvar.h>
MALLOC_DECLARE(M_BLUETOOTH);
@@ -120,6 +122,13 @@ struct btproto {
void (*input)(void *, struct mbuf *);
};
+extern const struct pr_usrreqs hci_usrreqs;
+extern const struct pr_usrreqs sco_usrreqs;
+extern const struct pr_usrreqs l2cap_usrreqs;
+extern const struct pr_usrreqs rfcomm_usrreqs;
+
+extern kmutex_t *bt_lock;
+
/*
* Debugging stuff
*/
@@ -147,8 +156,6 @@ extern int bluetooth_debug;
# define UNKNOWN(x) ((void)0)
#endif /* BLUETOOTH_DEBUG */
-extern kmutex_t *bt_lock;
-
#endif /* _KERNEL */
#endif /* _NETBT_BLUETOOTH_H_ */
Index: src/sys/netbt/bt_proto.c
diff -u src/sys/netbt/bt_proto.c:1.12 src/sys/netbt/bt_proto.c:1.12.36.1
--- src/sys/netbt/bt_proto.c:1.12 Sun Sep 13 18:45:11 2009
+++ src/sys/netbt/bt_proto.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: bt_proto.c,v 1.12 2009/09/13 18:45:11 pooka Exp $ */
+/* $NetBSD: bt_proto.c,v 1.12.36.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bt_proto.c,v 1.12 2009/09/13 18:45:11 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bt_proto.c,v 1.12.36.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/domain.h>
@@ -62,17 +62,7 @@ PR_WRAP_CTLOUTPUT(rfcomm_ctloutput)
#define l2cap_ctloutput l2cap_ctloutput_wrapper
#define rfcomm_ctloutput rfcomm_ctloutput_wrapper
-PR_WRAP_USRREQ(hci_usrreq)
-PR_WRAP_USRREQ(sco_usrreq)
-PR_WRAP_USRREQ(l2cap_usrreq)
-PR_WRAP_USRREQ(rfcomm_usrreq)
-
-#define hci_usrreq hci_usrreq_wrapper
-#define sco_usrreq sco_usrreq_wrapper
-#define l2cap_usrreq l2cap_usrreq_wrapper
-#define rfcomm_usrreq rfcomm_usrreq_wrapper
-
-const struct protosw btsw[] = {
+static const struct protosw btsw[] = {
{ /* raw HCI commands */
.pr_type = SOCK_RAW,
.pr_domain = &btdomain,
@@ -80,7 +70,7 @@ const struct protosw btsw[] = {
.pr_flags = (PR_ADDR | PR_ATOMIC),
.pr_init = hci_init,
.pr_ctloutput = hci_ctloutput,
- .pr_usrreq = hci_usrreq,
+ .pr_usrreqs = &hci_usrreqs,
},
{ /* HCI SCO data (audio) */
.pr_type = SOCK_SEQPACKET,
@@ -88,7 +78,7 @@ const struct protosw btsw[] = {
.pr_protocol = BTPROTO_SCO,
.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC | PR_LISTEN),
.pr_ctloutput = sco_ctloutput,
- .pr_usrreq = sco_usrreq,
+ .pr_usrreqs = &sco_usrreqs,
},
{ /* L2CAP Connection Oriented */
.pr_type = SOCK_SEQPACKET,
@@ -96,7 +86,7 @@ const struct protosw btsw[] = {
.pr_protocol = BTPROTO_L2CAP,
.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC | PR_LISTEN),
.pr_ctloutput = l2cap_ctloutput,
- .pr_usrreq = l2cap_usrreq,
+ .pr_usrreqs = &l2cap_usrreqs,
.pr_init = l2cap_init,
},
{ /* RFCOMM */
@@ -105,7 +95,7 @@ const struct protosw btsw[] = {
.pr_protocol = BTPROTO_RFCOMM,
.pr_flags = (PR_CONNREQUIRED | PR_LISTEN | PR_WANTRCVD),
.pr_ctloutput = rfcomm_ctloutput,
- .pr_usrreq = rfcomm_usrreq,
+ .pr_usrreqs = &rfcomm_usrreqs,
.pr_init = rfcomm_init,
},
};
Index: src/sys/netbt/hci.h
diff -u src/sys/netbt/hci.h:1.35 src/sys/netbt/hci.h:1.35.26.1
--- src/sys/netbt/hci.h:1.35 Sat Sep 17 08:23:36 2011
+++ src/sys/netbt/hci.h Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: hci.h,v 1.35 2011/09/17 08:23:36 plunky Exp $ */
+/* $NetBSD: hci.h,v 1.35.26.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -54,7 +54,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: hci.h,v 1.35 2011/09/17 08:23:36 plunky Exp $
+ * $Id: hci.h,v 1.35.26.1 2014/08/10 06:56:23 tls Exp $
* $FreeBSD: src/sys/netgraph/bluetooth/include/ng_hci.h,v 1.6 2005/01/07 01:45:43 imp Exp $
*/
@@ -2536,7 +2536,7 @@ extern SIMPLEQ_HEAD(hci_unit_list, hci_u
void hci_event(struct mbuf *, struct hci_unit *);
/* hci_ioctl.c */
-int hci_ioctl(unsigned long, void *, struct lwp *);
+int hci_ioctl_pcb(unsigned long, void *);
/* hci_link.c */
struct hci_link *hci_acl_open(struct hci_unit *, bdaddr_t *);
@@ -2567,13 +2567,12 @@ void hci_memo_free(struct hci_memo *);
/* hci_socket.c */
void hci_drop(void *);
void hci_init(void);
-int hci_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
int hci_ctloutput(int, struct socket *, struct sockopt *);
void hci_mtap(struct mbuf *, struct hci_unit *);
/* hci_unit.c */
-struct hci_unit *hci_attach(const struct hci_if *, device_t, uint16_t);
-void hci_detach(struct hci_unit *);
+struct hci_unit *hci_attach_pcb(const struct hci_if *, device_t, uint16_t);
+void hci_detach_pcb(struct hci_unit *);
int hci_enable(struct hci_unit *);
void hci_disable(struct hci_unit *);
struct hci_unit *hci_unit_lookup(const bdaddr_t *);
Index: src/sys/netbt/hci_ioctl.c
diff -u src/sys/netbt/hci_ioctl.c:1.10 src/sys/netbt/hci_ioctl.c:1.10.32.1
--- src/sys/netbt/hci_ioctl.c:1.10 Mon Nov 22 19:56:51 2010
+++ src/sys/netbt/hci_ioctl.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: hci_ioctl.c,v 1.10 2010/11/22 19:56:51 plunky Exp $ */
+/* $NetBSD: hci_ioctl.c,v 1.10.32.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_ioctl.c,v 1.10 2010/11/22 19:56:51 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_ioctl.c,v 1.10.32.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/domain.h>
@@ -132,7 +132,7 @@ hci_dump(void)
#endif
int
-hci_ioctl(unsigned long cmd, void *data, struct lwp *l)
+hci_ioctl_pcb(unsigned long cmd, void *data)
{
struct btreq *btr = data;
struct hci_unit *unit;
@@ -225,7 +225,7 @@ hci_ioctl(unsigned long cmd, void *data,
break;
case SIOCSBTFLAGS: /* set unit flags (privileged) */
- err = kauth_authorize_device(l->l_cred,
+ err = kauth_authorize_device(curlwp->l_cred,
KAUTH_DEVICE_BLUETOOTH_SETPRIV, unit, KAUTH_ARG(cmd),
btr, NULL);
if (err)
@@ -253,7 +253,7 @@ hci_ioctl(unsigned long cmd, void *data,
break;
case SIOCSBTPOLICY: /* set unit link policy (privileged) */
- err = kauth_authorize_device(l->l_cred,
+ err = kauth_authorize_device(curlwp->l_cred,
KAUTH_DEVICE_BLUETOOTH_SETPRIV, unit, KAUTH_ARG(cmd),
btr, NULL);
if (err)
@@ -265,7 +265,7 @@ hci_ioctl(unsigned long cmd, void *data,
break;
case SIOCSBTPTYPE: /* set unit packet types (privileged) */
- err = kauth_authorize_device(l->l_cred,
+ err = kauth_authorize_device(curlwp->l_cred,
KAUTH_DEVICE_BLUETOOTH_SETPRIV, unit, KAUTH_ARG(cmd),
btr, NULL);
if (err)
@@ -281,7 +281,7 @@ hci_ioctl(unsigned long cmd, void *data,
break;
case SIOCZBTSTATS: /* get & reset unit statistics */
- err = kauth_authorize_device(l->l_cred,
+ err = kauth_authorize_device(curlwp->l_cred,
KAUTH_DEVICE_BLUETOOTH_SETPRIV, unit, KAUTH_ARG(cmd),
btr, NULL);
if (err)
@@ -297,7 +297,7 @@ hci_ioctl(unsigned long cmd, void *data,
* sent to USB bluetooth controllers that are not an
* integer number of frame sizes, the USB bus locks up.
*/
- err = kauth_authorize_device(l->l_cred,
+ err = kauth_authorize_device(curlwp->l_cred,
KAUTH_DEVICE_BLUETOOTH_SETPRIV, unit, KAUTH_ARG(cmd),
btr, NULL);
if (err)
Index: src/sys/netbt/hci_link.c
diff -u src/sys/netbt/hci_link.c:1.23 src/sys/netbt/hci_link.c:1.23.26.1
--- src/sys/netbt/hci_link.c:1.23 Wed Jul 27 10:25:09 2011
+++ src/sys/netbt/hci_link.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: hci_link.c,v 1.23 2011/07/27 10:25:09 plunky Exp $ */
+/* $NetBSD: hci_link.c,v 1.23.26.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.23 2011/07/27 10:25:09 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.23.26.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -799,7 +799,7 @@ hci_sco_newconn(struct hci_unit *unit, b
sco = hci_link_alloc(unit, bdaddr, HCI_LINK_SCO);
if (sco == NULL) {
- sco_detach(&new);
+ sco_detach_pcb(&new);
return NULL;
}
Index: src/sys/netbt/hci_socket.c
diff -u src/sys/netbt/hci_socket.c:1.20 src/sys/netbt/hci_socket.c:1.20.28.1
--- src/sys/netbt/hci_socket.c:1.20 Sun Jan 30 17:23:23 2011
+++ src/sys/netbt/hci_socket.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: hci_socket.c,v 1.20 2011/01/30 17:23:23 plunky Exp $ */
+/* $NetBSD: hci_socket.c,v 1.20.28.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.20 2011/01/30 17:23:23 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.20.28.1 2014/08/10 06:56:23 tls Exp $");
/* load symbolic names */
#ifdef BLUETOOTH_DEBUG
@@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: hci_socket.c
#include <sys/domain.h>
#include <sys/kauth.h>
#include <sys/kernel.h>
+#include <sys/kmem.h>
#include <sys/mbuf.h>
#include <sys/proc.h>
#include <sys/protosw.h>
@@ -352,7 +353,7 @@ hci_cmdwait_flush(struct socket *so)
* This came from userland, so check it out.
*/
static int
-hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr)
+hci_send_pcb(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr)
{
struct hci_unit *unit;
struct mbuf *m0;
@@ -425,206 +426,352 @@ bad:
return err;
}
-/*
- * User Request.
- * up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally, protocol number (PRU_ATTACH)
- * ctl is optional mbuf chain containing socket options
- * l is pointer to process requesting action (if any)
- *
- * we are responsible for disposing of m and ctl if
- * they are mbuf chains
- */
-int
-hci_usrreq(struct socket *up, int req, struct mbuf *m,
- struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
+static int
+hci_attach(struct socket *so, int proto)
+{
+ struct hci_pcb *pcb;
+ int error;
+
+ KASSERT(so->so_pcb == NULL);
+
+ if (so->so_lock == NULL) {
+ mutex_obj_hold(bt_lock);
+ so->so_lock = bt_lock;
+ solock(so);
+ }
+ KASSERT(solocked(so));
+
+ error = soreserve(so, hci_sendspace, hci_recvspace);
+ if (error) {
+ return error;
+ }
+
+ pcb = kmem_zalloc(sizeof(struct hci_pcb), KM_SLEEP);
+ pcb->hp_cred = kauth_cred_dup(curlwp->l_cred);
+ pcb->hp_socket = so;
+
+ /*
+ * Set default user filter. By default, socket only passes
+ * Command_Complete and Command_Status Events.
+ */
+ hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter);
+ hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter);
+ hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter);
+
+ LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next);
+ so->so_pcb = pcb;
+
+ return 0;
+}
+
+static void
+hci_detach(struct socket *so)
+{
+ struct hci_pcb *pcb;
+
+ pcb = (struct hci_pcb *)so->so_pcb;
+ KASSERT(pcb != NULL);
+
+ if (so->so_snd.sb_mb != NULL)
+ hci_cmdwait_flush(so);
+
+ if (pcb->hp_cred != NULL)
+ kauth_cred_free(pcb->hp_cred);
+
+ so->so_pcb = NULL;
+ LIST_REMOVE(pcb, hp_next);
+ kmem_free(pcb, sizeof(*pcb));
+}
+
+static int
+hci_accept(struct socket *so, struct mbuf *nam)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+hci_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
{
- struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb;
+ struct hci_pcb *pcb = so->so_pcb;
struct sockaddr_bt *sa;
- int err = 0;
- DPRINTFN(2, "%s\n", prurequests[req]);
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
- switch(req) {
- case PRU_CONTROL:
- mutex_enter(bt_lock);
- err = hci_ioctl((unsigned long)m, (void *)nam, l);
- mutex_exit(bt_lock);
- return err;
-
- case PRU_PURGEIF:
- return EOPNOTSUPP;
-
- case PRU_ATTACH:
- if (up->so_lock == NULL) {
- mutex_obj_hold(bt_lock);
- up->so_lock = bt_lock;
- solock(up);
- }
- KASSERT(solocked(up));
- if (pcb)
- return EINVAL;
- err = soreserve(up, hci_sendspace, hci_recvspace);
- if (err)
- return err;
-
- pcb = malloc(sizeof(struct hci_pcb), M_PCB, M_NOWAIT | M_ZERO);
- if (pcb == NULL)
- return ENOMEM;
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
- up->so_pcb = pcb;
- pcb->hp_socket = up;
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
- if (l != NULL)
- pcb->hp_cred = kauth_cred_dup(l->l_cred);
+ bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr);
- /*
- * Set default user filter. By default, socket only passes
- * Command_Complete and Command_Status Events.
- */
- hci_filter_set(HCI_EVENT_COMMAND_COMPL, &pcb->hp_efilter);
- hci_filter_set(HCI_EVENT_COMMAND_STATUS, &pcb->hp_efilter);
- hci_filter_set(HCI_EVENT_PKT, &pcb->hp_pfilter);
+ if (bdaddr_any(&sa->bt_bdaddr))
+ pcb->hp_flags |= HCI_PROMISCUOUS;
+ else
+ pcb->hp_flags &= ~HCI_PROMISCUOUS;
- LIST_INSERT_HEAD(&hci_pcb, pcb, hp_next);
+ return 0;
+}
- return 0;
- }
+static int
+hci_listen(struct socket *so, struct lwp *l)
+{
+ KASSERT(solocked(so));
- /* anything after here *requires* a pcb */
- if (pcb == NULL) {
- err = EINVAL;
- goto release;
- }
+ return EOPNOTSUPP;
+}
- switch(req) {
- case PRU_DISCONNECT:
- bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY);
+static int
+hci_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
+{
+ struct hci_pcb *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
- /* XXX we cannot call soisdisconnected() here, as it sets
- * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
- * that soisconnected() does not clear these and if you
- * try to reconnect this socket (which is permitted) you
- * get a broken pipe when you try to write any data.
- */
- up->so_state &= ~SS_ISCONNECTED;
- break;
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
- case PRU_ABORT:
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- if (up->so_snd.sb_mb != NULL)
- hci_cmdwait_flush(up);
-
- if (pcb->hp_cred != NULL)
- kauth_cred_free(pcb->hp_cred);
-
- up->so_pcb = NULL;
- LIST_REMOVE(pcb, hp_next);
- free(pcb, M_PCB);
- return 0;
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
+ if (hci_unit_lookup(&sa->bt_bdaddr) == NULL)
+ return EADDRNOTAVAIL;
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
+ bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr);
+ soisconnected(so);
+ return 0;
+}
- bdaddr_copy(&pcb->hp_laddr, &sa->bt_bdaddr);
+static int
+hci_connect2(struct socket *so, struct socket *so2)
+{
+ KASSERT(solocked(so));
- if (bdaddr_any(&sa->bt_bdaddr))
- pcb->hp_flags |= HCI_PROMISCUOUS;
- else
- pcb->hp_flags &= ~HCI_PROMISCUOUS;
+ return EOPNOTSUPP;
+}
- return 0;
+static int
+hci_disconnect(struct socket *so)
+{
+ struct hci_pcb *pcb = so->so_pcb;
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
+ bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY);
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
+ /* XXX we cannot call soisdisconnected() here, as it sets
+ * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
+ * that soisconnected() does not clear these and if you
+ * try to reconnect this socket (which is permitted) you
+ * get a broken pipe when you try to write any data.
+ */
+ so->so_state &= ~SS_ISCONNECTED;
+ return 0;
+}
- if (hci_unit_lookup(&sa->bt_bdaddr) == NULL)
- return EADDRNOTAVAIL;
+static int
+hci_shutdown(struct socket *so)
+{
+ KASSERT(solocked(so));
- bdaddr_copy(&pcb->hp_raddr, &sa->bt_bdaddr);
- soisconnected(up);
- return 0;
+ socantsendmore(so);
+ return 0;
+}
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
+static int
+hci_abort(struct socket *so)
+{
+ KASSERT(solocked(so));
- memset(sa, 0, sizeof(struct sockaddr_bt));
- nam->m_len =
- sa->bt_len = sizeof(struct sockaddr_bt);
- sa->bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr);
- return 0;
+ soisdisconnected(so);
+ hci_detach(so);
+ return 0;
+}
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
+static int
+hci_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
+{
+ int err;
+ mutex_enter(bt_lock);
+ err = hci_ioctl_pcb(cmd, nam);
+ mutex_exit(bt_lock);
+ return err;
+}
- memset(sa, 0, sizeof(struct sockaddr_bt));
- nam->m_len =
- sa->bt_len = sizeof(struct sockaddr_bt);
- sa->bt_family = AF_BLUETOOTH;
- bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr);
- return 0;
+static int
+hci_stat(struct socket *so, struct stat *ub)
+{
+ KASSERT(solocked(so));
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
+ return 0;
+}
- case PRU_SEND:
- sa = NULL;
- if (nam) {
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt)) {
- err = EINVAL;
- goto release;
- }
+static int
+hci_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb;
+ struct sockaddr_bt *sa;
- if (sa->bt_family != AF_BLUETOOTH) {
- err = EAFNOSUPPORT;
- goto release;
- }
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ memset(sa, 0, sizeof(struct sockaddr_bt));
+ nam->m_len =
+ sa->bt_len = sizeof(struct sockaddr_bt);
+ sa->bt_family = AF_BLUETOOTH;
+ bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_raddr);
+ return 0;
+}
+
+static int
+hci_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ struct hci_pcb *pcb = (struct hci_pcb *)so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ memset(sa, 0, sizeof(struct sockaddr_bt));
+ nam->m_len =
+ sa->bt_len = sizeof(struct sockaddr_bt);
+ sa->bt_family = AF_BLUETOOTH;
+ bdaddr_copy(&sa->bt_bdaddr, &pcb->hp_laddr);
+ return 0;
+}
+
+static int
+hci_rcvd(struct socket *so, int flags, struct lwp *l)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+hci_recvoob(struct socket *so, struct mbuf *m, int flags)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+hci_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct lwp *l)
+{
+ struct hci_pcb *pcb = so->so_pcb;
+ struct sockaddr_bt * sa = NULL;
+ int err = 0;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+
+ if (control) /* have no use for this */
+ m_freem(control);
+
+ if (nam) {
+ sa = mtod(nam, struct sockaddr_bt *);
+
+ if (sa->bt_len != sizeof(struct sockaddr_bt)) {
+ err = EINVAL;
+ goto release;
+ }
+
+ if (sa->bt_family != AF_BLUETOOTH) {
+ err = EAFNOSUPPORT;
+ goto release;
}
+ }
+
+ return hci_send_pcb(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr));
+
+release:
+ if (m)
+ m_freem(m);
+
+ return err;
+}
+
+static int
+hci_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
+{
+ KASSERT(solocked(so));
+
+ if (m)
+ m_freem(m);
+ if (control)
+ m_freem(control);
+
+ return EOPNOTSUPP;
+}
+
+static int
+hci_purgeif(struct socket *so, struct ifnet *ifp)
+{
+
+ return EOPNOTSUPP;
+}
- if (ctl) /* have no use for this */
- m_freem(ctl);
+/*
+ * User Request.
+ * up is socket
+ * m is optional mbuf chain containing message
+ * nam is optional mbuf chain containing an address
+ * ctl is optional mbuf chain containing socket options
+ * l is pointer to process requesting action (if any)
+ *
+ * we are responsible for disposing of m and ctl
+ */
+static int
+hci_usrreq(struct socket *up, int req, struct mbuf *m,
+ struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
+{
+ struct hci_pcb *pcb = up->so_pcb;
+ int err = 0;
- return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr));
+ DPRINTFN(2, "%s\n", prurequests[req]);
+ KASSERT(req != PRU_ATTACH);
+ KASSERT(req != PRU_DETACH);
+ KASSERT(req != PRU_ACCEPT);
+ KASSERT(req != PRU_BIND);
+ KASSERT(req != PRU_LISTEN);
+ KASSERT(req != PRU_CONNECT);
+ KASSERT(req != PRU_CONNECT2);
+ KASSERT(req != PRU_DISCONNECT);
+ KASSERT(req != PRU_SHUTDOWN);
+ KASSERT(req != PRU_ABORT);
+ KASSERT(req != PRU_CONTROL);
+ KASSERT(req != PRU_SENSE);
+ KASSERT(req != PRU_PEERADDR);
+ KASSERT(req != PRU_SOCKADDR);
+ KASSERT(req != PRU_RCVD);
+ KASSERT(req != PRU_RCVOOB);
+ KASSERT(req != PRU_SEND);
+ KASSERT(req != PRU_SENDOOB);
+ KASSERT(req != PRU_PURGEIF);
- case PRU_SENSE:
- return 0; /* (no sense - Doh!) */
+ /* anything after here *requires* a pcb */
+ if (pcb == NULL) {
+ err = EINVAL;
+ goto release;
+ }
- case PRU_RCVD:
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_ACCEPT:
- case PRU_CONNECT2:
- case PRU_LISTEN:
- case PRU_SENDOOB:
+ switch(req) {
case PRU_FASTTIMO:
case PRU_SLOWTIMO:
case PRU_PROTORCV:
@@ -849,3 +996,49 @@ hci_mtap(struct mbuf *m, struct hci_unit
}
}
}
+
+PR_WRAP_USRREQS(hci)
+
+#define hci_attach hci_attach_wrapper
+#define hci_detach hci_detach_wrapper
+#define hci_accept hci_accept_wrapper
+#define hci_bind hci_bind_wrapper
+#define hci_listen hci_listen_wrapper
+#define hci_connect hci_connect_wrapper
+#define hci_connect2 hci_connect2_wrapper
+#define hci_disconnect hci_disconnect_wrapper
+#define hci_shutdown hci_shutdown_wrapper
+#define hci_abort hci_abort_wrapper
+#define hci_ioctl hci_ioctl_wrapper
+#define hci_stat hci_stat_wrapper
+#define hci_peeraddr hci_peeraddr_wrapper
+#define hci_sockaddr hci_sockaddr_wrapper
+#define hci_rcvd hci_rcvd_wrapper
+#define hci_recvoob hci_recvoob_wrapper
+#define hci_send hci_send_wrapper
+#define hci_sendoob hci_sendoob_wrapper
+#define hci_purgeif hci_purgeif_wrapper
+#define hci_usrreq hci_usrreq_wrapper
+
+const struct pr_usrreqs hci_usrreqs = {
+ .pr_attach = hci_attach,
+ .pr_detach = hci_detach,
+ .pr_accept = hci_accept,
+ .pr_bind = hci_bind,
+ .pr_listen = hci_listen,
+ .pr_connect = hci_connect,
+ .pr_connect2 = hci_connect2,
+ .pr_disconnect = hci_disconnect,
+ .pr_shutdown = hci_shutdown,
+ .pr_abort = hci_abort,
+ .pr_ioctl = hci_ioctl,
+ .pr_stat = hci_stat,
+ .pr_peeraddr = hci_peeraddr,
+ .pr_sockaddr = hci_sockaddr,
+ .pr_rcvd = hci_rcvd,
+ .pr_recvoob = hci_recvoob,
+ .pr_send = hci_send,
+ .pr_sendoob = hci_sendoob,
+ .pr_purgeif = hci_purgeif,
+ .pr_generic = hci_usrreq,
+};
Index: src/sys/netbt/hci_unit.c
diff -u src/sys/netbt/hci_unit.c:1.13 src/sys/netbt/hci_unit.c:1.13.26.1
--- src/sys/netbt/hci_unit.c:1.13 Sat Sep 17 08:23:37 2011
+++ src/sys/netbt/hci_unit.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: hci_unit.c,v 1.13 2011/09/17 08:23:37 plunky Exp $ */
+/* $NetBSD: hci_unit.c,v 1.13.26.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_unit.c,v 1.13 2011/09/17 08:23:37 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_unit.c,v 1.13.26.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/conf.h>
@@ -81,7 +81,7 @@ static const uint8_t hci_cmds_v10[HCI_CO
static void hci_intr (void *);
struct hci_unit *
-hci_attach(const struct hci_if *hci_if, device_t dev, uint16_t flags)
+hci_attach_pcb(const struct hci_if *hci_if, device_t dev, uint16_t flags)
{
struct hci_unit *unit;
@@ -120,7 +120,7 @@ hci_attach(const struct hci_if *hci_if,
}
void
-hci_detach(struct hci_unit *unit)
+hci_detach_pcb(struct hci_unit *unit)
{
mutex_enter(bt_lock);
Index: src/sys/netbt/l2cap.h
diff -u src/sys/netbt/l2cap.h:1.10 src/sys/netbt/l2cap.h:1.10.28.1
--- src/sys/netbt/l2cap.h:1.10 Sun Feb 6 18:50:59 2011
+++ src/sys/netbt/l2cap.h Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: l2cap.h,v 1.10 2011/02/06 18:50:59 plunky Exp $ */
+/* $NetBSD: l2cap.h,v 1.10.28.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -54,7 +54,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: l2cap.h,v 1.10 2011/02/06 18:50:59 plunky Exp $
+ * $Id: l2cap.h,v 1.10.28.1 2014/08/10 06:56:23 tls Exp $
* $FreeBSD: src/sys/netgraph/bluetooth/include/l2cap.h,v 1.4 2005/08/31 18:13:23 emax Exp $
*/
@@ -458,19 +458,18 @@ int l2cap_send_disconnect_req(struct l2c
int l2cap_send_connect_rsp(struct hci_link *, uint8_t, uint16_t, uint16_t, uint16_t);
/* l2cap_socket.c */
-int l2cap_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
int l2cap_ctloutput(int, struct socket *, struct sockopt *);
/* l2cap_upper.c */
-int l2cap_attach(struct l2cap_channel **, const struct btproto *, void *);
-int l2cap_bind(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_sockaddr(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_connect(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_peeraddr(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_disconnect(struct l2cap_channel *, int);
-int l2cap_detach(struct l2cap_channel **);
-int l2cap_listen(struct l2cap_channel *);
-int l2cap_send(struct l2cap_channel *, struct mbuf *);
+int l2cap_attach_pcb(struct l2cap_channel **, const struct btproto *, void *);
+int l2cap_bind_pcb(struct l2cap_channel *, struct sockaddr_bt *);
+int l2cap_sockaddr_pcb(struct l2cap_channel *, struct sockaddr_bt *);
+int l2cap_connect_pcb(struct l2cap_channel *, struct sockaddr_bt *);
+int l2cap_peeraddr_pcb(struct l2cap_channel *, struct sockaddr_bt *);
+int l2cap_disconnect_pcb(struct l2cap_channel *, int);
+void l2cap_detach_pcb(struct l2cap_channel **);
+int l2cap_listen_pcb(struct l2cap_channel *);
+int l2cap_send_pcb(struct l2cap_channel *, struct mbuf *);
int l2cap_setopt(struct l2cap_channel *, const struct sockopt *);
int l2cap_getopt(struct l2cap_channel *, struct sockopt *);
Index: src/sys/netbt/l2cap_lower.c
diff -u src/sys/netbt/l2cap_lower.c:1.9 src/sys/netbt/l2cap_lower.c:1.9.54.1
--- src/sys/netbt/l2cap_lower.c:1.9 Tue Aug 5 13:08:31 2008
+++ src/sys/netbt/l2cap_lower.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: l2cap_lower.c,v 1.9 2008/08/05 13:08:31 plunky Exp $ */
+/* $NetBSD: l2cap_lower.c,v 1.9.54.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_lower.c,v 1.9 2008/08/05 13:08:31 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_lower.c,v 1.9.54.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -150,7 +150,7 @@ failed:
}
/*
- * Start another L2CAP packet on its way. This is called from l2cap_send
+ * Start another L2CAP packet on its way. This is called from l2cap_send_pcb
* (when no PDU is pending) and hci_acl_start (when PDU has been placed on
* device queue). Thus we can have more than one PDU waiting at the device
* if space is available but no single channel will hog the link.
Index: src/sys/netbt/l2cap_socket.c
diff -u src/sys/netbt/l2cap_socket.c:1.10 src/sys/netbt/l2cap_socket.c:1.10.2.1
--- src/sys/netbt/l2cap_socket.c:1.10 Thu Aug 29 17:49:21 2013
+++ src/sys/netbt/l2cap_socket.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: l2cap_socket.c,v 1.10 2013/08/29 17:49:21 rmind Exp $ */
+/* $NetBSD: l2cap_socket.c,v 1.10.2.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.10 2013/08/29 17:49:21 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.10.2.1 2014/08/10 06:56:23 tls Exp $");
/* load symbolic names */
#ifdef BLUETOOTH_DEBUG
@@ -82,63 +82,326 @@ static const struct btproto l2cap_proto
int l2cap_sendspace = 4096;
int l2cap_recvspace = 4096;
+static int
+l2cap_attach(struct socket *so, int proto)
+{
+ int error;
+
+ KASSERT(so->so_pcb == NULL);
+
+ if (so->so_lock == NULL) {
+ mutex_obj_hold(bt_lock);
+ so->so_lock = bt_lock;
+ solock(so);
+ }
+ KASSERT(solocked(so));
+
+ /*
+ * For L2CAP socket PCB we just use an l2cap_channel structure
+ * since we have nothing to add..
+ */
+ error = soreserve(so, l2cap_sendspace, l2cap_recvspace);
+ if (error)
+ return error;
+
+ return l2cap_attach_pcb((struct l2cap_channel **)&so->so_pcb,
+ &l2cap_proto, so);
+}
+
+static void
+l2cap_detach(struct socket *so)
+{
+ KASSERT(so->so_pcb != NULL);
+ l2cap_detach_pcb((struct l2cap_channel **)&so->so_pcb);
+ KASSERT(so->so_pcb == NULL);
+}
+
+static int
+l2cap_accept(struct socket *so, struct mbuf *nam)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return l2cap_peeraddr_pcb(pcb, sa);
+}
+
+static int
+l2cap_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
+
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
+
+ return l2cap_bind_pcb(pcb, sa);
+}
+
+static int
+l2cap_listen(struct socket *so, struct lwp *l)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ return l2cap_listen_pcb(pcb);
+}
+
+static int
+l2cap_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
+
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
+
+ soisconnecting(so);
+ return l2cap_connect_pcb(pcb, sa);
+}
+
+static int
+l2cap_connect2(struct socket *so, struct socket *so2)
+{
+ KASSERT(solocked(so));
+
+ if (so->so_pcb == NULL)
+ return EINVAL;
+
+ return EOPNOTSUPP;
+}
+
+static int
+l2cap_disconnect(struct socket *so)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ soisdisconnecting(so);
+ return l2cap_disconnect_pcb(pcb, so->so_linger);
+}
+
+static int
+l2cap_shutdown(struct socket *so)
+{
+ KASSERT(solocked(so));
+
+ socantsendmore(so);
+ return 0;
+}
+
+static int
+l2cap_abort(struct socket *so)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ l2cap_disconnect_pcb(pcb, 0);
+ soisdisconnected(so);
+ l2cap_detach(so);
+ return 0;
+}
+
+static int
+l2cap_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
+{
+ return EPASSTHROUGH;
+}
+
+static int
+l2cap_stat(struct socket *so, struct stat *ub)
+{
+ KASSERT(solocked(so));
+
+ return 0;
+}
+
+static int
+l2cap_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return l2cap_peeraddr_pcb(pcb, sa);
+}
+
+static int
+l2cap_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return l2cap_sockaddr_pcb(pcb, sa);
+}
+
+static int
+l2cap_rcvd(struct socket *so, int flags, struct lwp *l)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+l2cap_recvoob(struct socket *so, struct mbuf *m, int flags)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+l2cap_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct lwp *l)
+{
+ struct l2cap_channel *pcb = so->so_pcb;
+ struct mbuf *m0;
+ int error = 0;
+
+ KASSERT(solocked(so));
+ KASSERT(m != NULL);
+
+ if (control)
+ m_freem(control);
+
+ if (pcb == NULL) {
+ error = EINVAL;
+ goto release;
+ }
+
+ if (m->m_pkthdr.len == 0)
+ goto release;
+
+ if (m->m_pkthdr.len > pcb->lc_omtu) {
+ error = EMSGSIZE;
+ goto release;
+ }
+
+ m0 = m_copypacket(m, M_DONTWAIT);
+ if (m0 == NULL) {
+ error = ENOMEM;
+ goto release;
+ }
+
+ sbappendrecord(&so->so_snd, m);
+ return l2cap_send_pcb(pcb, m0);
+
+release:
+ if (m)
+ m_freem(m);
+
+ return error;
+}
+
+static int
+l2cap_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
+{
+ KASSERT(solocked(so));
+
+ if (m)
+ m_freem(m);
+ if (control)
+ m_freem(control);
+
+ return EOPNOTSUPP;
+}
+
+static int
+l2cap_purgeif(struct socket *so, struct ifnet *ifp)
+{
+
+ return EOPNOTSUPP;
+}
+
/*
* User Request.
* up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally protocol number (PRU_ATTACH)
- * message flags (PRU_RCVD)
+ * m is optional mbuf chain containing message
* ctl is either
* optional mbuf chain containing socket options
- * optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
* l is pointer to process requesting action (if any)
*
* we are responsible for disposing of m and ctl if
* they are mbuf chains
*/
-int
+static int
l2cap_usrreq(struct socket *up, int req, struct mbuf *m,
struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
{
struct l2cap_channel *pcb = up->so_pcb;
- struct sockaddr_bt *sa;
- struct mbuf *m0;
int err = 0;
DPRINTFN(2, "%s\n", prurequests[req]);
-
- switch (req) {
- case PRU_CONTROL:
- return EPASSTHROUGH;
-
- case PRU_PURGEIF:
- return EOPNOTSUPP;
-
- case PRU_ATTACH:
- if (up->so_lock == NULL) {
- mutex_obj_hold(bt_lock);
- up->so_lock = bt_lock;
- solock(up);
- }
- KASSERT(solocked(up));
- if (pcb != NULL)
- return EINVAL;
- /*
- * For L2CAP socket PCB we just use an l2cap_channel structure
- * since we have nothing to add..
- */
- err = soreserve(up, l2cap_sendspace, l2cap_recvspace);
- if (err)
- return err;
-
- return l2cap_attach((struct l2cap_channel **)&up->so_pcb,
- &l2cap_proto, up);
- }
+ KASSERT(req != PRU_ATTACH);
+ KASSERT(req != PRU_DETACH);
+ KASSERT(req != PRU_ACCEPT);
+ KASSERT(req != PRU_BIND);
+ KASSERT(req != PRU_LISTEN);
+ KASSERT(req != PRU_CONNECT);
+ KASSERT(req != PRU_CONNECT2);
+ KASSERT(req != PRU_DISCONNECT);
+ KASSERT(req != PRU_SHUTDOWN);
+ KASSERT(req != PRU_ABORT);
+ KASSERT(req != PRU_CONTROL);
+ KASSERT(req != PRU_SENSE);
+ KASSERT(req != PRU_PEERADDR);
+ KASSERT(req != PRU_SOCKADDR);
+ KASSERT(req != PRU_RCVD);
+ KASSERT(req != PRU_RCVOOB);
+ KASSERT(req != PRU_SEND);
+ KASSERT(req != PRU_SENDOOB);
+ KASSERT(req != PRU_PURGEIF);
if (pcb == NULL) {
err = EINVAL;
@@ -146,98 +409,6 @@ l2cap_usrreq(struct socket *up, int req,
}
switch(req) {
- case PRU_DISCONNECT:
- soisdisconnecting(up);
- return l2cap_disconnect(pcb, up->so_linger);
-
- case PRU_ABORT:
- l2cap_disconnect(pcb, 0);
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- return l2cap_detach((struct l2cap_channel **)&up->so_pcb);
-
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- return l2cap_bind(pcb, sa);
-
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- soisconnecting(up);
- return l2cap_connect(pcb, sa);
-
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return l2cap_peeraddr(pcb, sa);
-
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return l2cap_sockaddr(pcb, sa);
-
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
-
- case PRU_SEND:
- KASSERT(m != NULL);
- if (m->m_pkthdr.len == 0)
- break;
-
- if (m->m_pkthdr.len > pcb->lc_omtu) {
- err = EMSGSIZE;
- break;
- }
-
- m0 = m_copypacket(m, M_DONTWAIT);
- if (m0 == NULL) {
- err = ENOMEM;
- break;
- }
-
- if (ctl) /* no use for that */
- m_freem(ctl);
-
- sbappendrecord(&up->so_snd, m);
- return l2cap_send(pcb, m0);
-
- case PRU_SENSE:
- return 0; /* (no release) */
-
- case PRU_RCVD:
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_LISTEN:
- return l2cap_listen(pcb);
-
- case PRU_ACCEPT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return l2cap_peeraddr(pcb, sa);
-
- case PRU_CONNECT2:
- case PRU_SENDOOB:
case PRU_FASTTIMO:
case PRU_SLOWTIMO:
case PRU_PROTORCV:
@@ -376,7 +547,7 @@ l2cap_linkmode(void *arg, int new)
if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH))
|| ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT))
|| ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE)))
- l2cap_disconnect(so->so_pcb, 0);
+ l2cap_disconnect_pcb(so->so_pcb, 0);
}
static void
@@ -396,3 +567,49 @@ l2cap_input(void *arg, struct mbuf *m)
sbappendrecord(&so->so_rcv, m);
sorwakeup(so);
}
+
+PR_WRAP_USRREQS(l2cap)
+
+#define l2cap_attach l2cap_attach_wrapper
+#define l2cap_detach l2cap_detach_wrapper
+#define l2cap_accept l2cap_accept_wrapper
+#define l2cap_bind l2cap_bind_wrapper
+#define l2cap_listen l2cap_listen_wrapper
+#define l2cap_connect l2cap_connect_wrapper
+#define l2cap_connect2 l2cap_connect2_wrapper
+#define l2cap_disconnect l2cap_disconnect_wrapper
+#define l2cap_shutdown l2cap_shutdown_wrapper
+#define l2cap_abort l2cap_abort_wrapper
+#define l2cap_ioctl l2cap_ioctl_wrapper
+#define l2cap_stat l2cap_stat_wrapper
+#define l2cap_peeraddr l2cap_peeraddr_wrapper
+#define l2cap_sockaddr l2cap_sockaddr_wrapper
+#define l2cap_rcvd l2cap_rcvd_wrapper
+#define l2cap_recvoob l2cap_recvoob_wrapper
+#define l2cap_send l2cap_send_wrapper
+#define l2cap_sendoob l2cap_sendoob_wrapper
+#define l2cap_purgeif l2cap_purgeif_wrapper
+#define l2cap_usrreq l2cap_usrreq_wrapper
+
+const struct pr_usrreqs l2cap_usrreqs = {
+ .pr_attach = l2cap_attach,
+ .pr_detach = l2cap_detach,
+ .pr_accept = l2cap_accept,
+ .pr_bind = l2cap_bind,
+ .pr_listen = l2cap_listen,
+ .pr_connect = l2cap_connect,
+ .pr_connect2 = l2cap_connect2,
+ .pr_disconnect = l2cap_disconnect,
+ .pr_shutdown = l2cap_shutdown,
+ .pr_abort = l2cap_abort,
+ .pr_ioctl = l2cap_ioctl,
+ .pr_stat = l2cap_stat,
+ .pr_peeraddr = l2cap_peeraddr,
+ .pr_sockaddr = l2cap_sockaddr,
+ .pr_rcvd = l2cap_rcvd,
+ .pr_recvoob = l2cap_recvoob,
+ .pr_send = l2cap_send,
+ .pr_sendoob = l2cap_sendoob,
+ .pr_purgeif = l2cap_purgeif,
+ .pr_generic = l2cap_usrreq,
+};
Index: src/sys/netbt/l2cap_upper.c
diff -u src/sys/netbt/l2cap_upper.c:1.11 src/sys/netbt/l2cap_upper.c:1.11.36.1
--- src/sys/netbt/l2cap_upper.c:1.11 Mon Jan 4 19:20:05 2010
+++ src/sys/netbt/l2cap_upper.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: l2cap_upper.c,v 1.11 2010/01/04 19:20:05 plunky Exp $ */
+/* $NetBSD: l2cap_upper.c,v 1.11.36.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.11 2010/01/04 19:20:05 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.11.36.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -52,13 +52,13 @@ __KERNEL_RCSID(0, "$NetBSD: l2cap_upper.
*/
/*
- * l2cap_attach(handle, btproto, upper)
+ * l2cap_attach_pcb(handle, btproto, upper)
*
* attach new l2cap_channel to handle, populate
* with reasonable defaults
*/
int
-l2cap_attach(struct l2cap_channel **handle,
+l2cap_attach_pcb(struct l2cap_channel **handle,
const struct btproto *proto, void *upper)
{
struct l2cap_channel *chan;
@@ -102,12 +102,12 @@ l2cap_attach(struct l2cap_channel **hand
}
/*
- * l2cap_bind(l2cap_channel, sockaddr)
+ * l2cap_bind_pcb(l2cap_channel, sockaddr)
*
* set local address of channel
*/
int
-l2cap_bind(struct l2cap_channel *chan, struct sockaddr_bt *addr)
+l2cap_bind_pcb(struct l2cap_channel *chan, struct sockaddr_bt *addr)
{
if (chan->lc_lcid != L2CAP_NULL_CID)
@@ -118,12 +118,12 @@ l2cap_bind(struct l2cap_channel *chan, s
}
/*
- * l2cap_sockaddr(l2cap_channel, sockaddr)
+ * l2cap_sockaddr_pcb(l2cap_channel, sockaddr)
*
* get local address of channel
*/
int
-l2cap_sockaddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
+l2cap_sockaddr_pcb(struct l2cap_channel *chan, struct sockaddr_bt *addr)
{
memcpy(addr, &chan->lc_laddr, sizeof(struct sockaddr_bt));
@@ -131,7 +131,7 @@ l2cap_sockaddr(struct l2cap_channel *cha
}
/*
- * l2cap_connect(l2cap_channel, sockaddr)
+ * l2cap_connect_pcb(l2cap_channel, sockaddr)
*
* Initiate a connection to destination. This corresponds to
* "Open Channel Request" in the L2CAP specification and will
@@ -144,7 +144,7 @@ l2cap_sockaddr(struct l2cap_channel *cha
* proto->connecting(upper)
*/
int
-l2cap_connect(struct l2cap_channel *chan, struct sockaddr_bt *dest)
+l2cap_connect_pcb(struct l2cap_channel *chan, struct sockaddr_bt *dest)
{
struct hci_unit *unit;
int err;
@@ -209,12 +209,12 @@ fail:
}
/*
- * l2cap_peeraddr(l2cap_channel, sockaddr)
+ * l2cap_peeraddr_pcb(l2cap_channel, sockaddr)
*
* get remote address of channel
*/
int
-l2cap_peeraddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
+l2cap_peeraddr_pcb(struct l2cap_channel *chan, struct sockaddr_bt *addr)
{
memcpy(addr, &chan->lc_raddr, sizeof(struct sockaddr_bt));
@@ -222,7 +222,7 @@ l2cap_peeraddr(struct l2cap_channel *cha
}
/*
- * l2cap_disconnect(l2cap_channel, linger)
+ * l2cap_disconnect_pcb(l2cap_channel, linger)
*
* Initiate L2CAP disconnection. This corresponds to
* "Close Channel Request" in the L2CAP specification
@@ -235,7 +235,7 @@ l2cap_peeraddr(struct l2cap_channel *cha
* the queue.
*/
int
-l2cap_disconnect(struct l2cap_channel *chan, int linger)
+l2cap_disconnect_pcb(struct l2cap_channel *chan, int linger)
{
int err = 0;
@@ -260,12 +260,12 @@ l2cap_disconnect(struct l2cap_channel *c
}
/*
- * l2cap_detach(handle)
+ * l2cap_detach_pcb(handle)
*
* Detach l2cap channel from handle & close it down
*/
-int
-l2cap_detach(struct l2cap_channel **handle)
+void
+l2cap_detach_pcb(struct l2cap_channel **handle)
{
struct l2cap_channel *chan;
@@ -288,11 +288,10 @@ l2cap_detach(struct l2cap_channel **hand
*/
free(chan, M_BLUETOOTH);
- return 0;
}
/*
- * l2cap_listen(l2cap_channel)
+ * l2cap_listen_pcb(l2cap_channel)
*
* Use this channel as a listening post (until detached). This will
* result in calls to:
@@ -309,7 +308,7 @@ l2cap_detach(struct l2cap_channel **hand
* You cannot use this channel for anything else subsequent to this call
*/
int
-l2cap_listen(struct l2cap_channel *chan)
+l2cap_listen_pcb(struct l2cap_channel *chan)
{
struct l2cap_channel *used, *prev = NULL;
uint32_t psm;
@@ -373,7 +372,7 @@ l2cap_listen(struct l2cap_channel *chan)
}
/*
- * l2cap_send(l2cap_channel, mbuf)
+ * l2cap_send_pcb(l2cap_channel, mbuf)
*
* Output SDU on channel described by channel. This corresponds
* to "Send Data Request" in the L2CAP specification. The upper
@@ -395,7 +394,7 @@ l2cap_listen(struct l2cap_channel *chan)
* B-Frame header and start sending if we are not already
*/
int
-l2cap_send(struct l2cap_channel *chan, struct mbuf *m)
+l2cap_send_pcb(struct l2cap_channel *chan, struct mbuf *m)
{
l2cap_hdr_t *hdr;
int plen;
Index: src/sys/netbt/rfcomm.h
diff -u src/sys/netbt/rfcomm.h:1.9 src/sys/netbt/rfcomm.h:1.9.36.1
--- src/sys/netbt/rfcomm.h:1.9 Sun Sep 13 18:45:11 2009
+++ src/sys/netbt/rfcomm.h Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: rfcomm.h,v 1.9 2009/09/13 18:45:11 pooka Exp $ */
+/* $NetBSD: rfcomm.h,v 1.9.36.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -55,7 +55,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: rfcomm.h,v 1.9 2009/09/13 18:45:11 pooka Exp $
+ * $Id: rfcomm.h,v 1.9.36.1 2014/08/10 06:56:23 tls Exp $
* $FreeBSD: src/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h,v 1.4 2005/01/11 01:39:53 emax Exp $
*/
@@ -404,20 +404,19 @@ int rfcomm_session_send_mcc(struct rfcom
void rfcomm_init(void);
/* rfcomm_socket.c */
-int rfcomm_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
int rfcomm_ctloutput(int, struct socket *, struct sockopt *);
/* rfcomm_upper.c */
-int rfcomm_attach(struct rfcomm_dlc **, const struct btproto *, void *);
-int rfcomm_bind(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_sockaddr(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_connect(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_peeraddr(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_disconnect(struct rfcomm_dlc *, int);
-int rfcomm_detach(struct rfcomm_dlc **);
-int rfcomm_listen(struct rfcomm_dlc *);
-int rfcomm_send(struct rfcomm_dlc *, struct mbuf *);
-int rfcomm_rcvd(struct rfcomm_dlc *, size_t);
+int rfcomm_attach_pcb(struct rfcomm_dlc **, const struct btproto *, void *);
+int rfcomm_bind_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
+int rfcomm_sockaddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
+int rfcomm_connect_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
+int rfcomm_peeraddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
+int rfcomm_disconnect_pcb(struct rfcomm_dlc *, int);
+void rfcomm_detach_pcb(struct rfcomm_dlc **);
+int rfcomm_listen_pcb(struct rfcomm_dlc *);
+int rfcomm_send_pcb(struct rfcomm_dlc *, struct mbuf *);
+int rfcomm_rcvd_pcb(struct rfcomm_dlc *, size_t);
int rfcomm_setopt(struct rfcomm_dlc *, const struct sockopt *);
int rfcomm_getopt(struct rfcomm_dlc *, struct sockopt *);
Index: src/sys/netbt/sco_upper.c
diff -u src/sys/netbt/sco_upper.c:1.9 src/sys/netbt/sco_upper.c:1.9.36.1
--- src/sys/netbt/sco_upper.c:1.9 Mon Jan 4 19:20:05 2010
+++ src/sys/netbt/sco_upper.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: sco_upper.c,v 1.9 2010/01/04 19:20:05 plunky Exp $ */
+/* $NetBSD: sco_upper.c,v 1.9.36.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.9 2010/01/04 19:20:05 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.9.36.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -53,12 +53,12 @@ __KERNEL_RCSID(0, "$NetBSD: sco_upper.c,
struct sco_pcb_list sco_pcb = LIST_HEAD_INITIALIZER(sco_pcb);
/*
- * sco_attach(handle, proto, upper)
+ * sco_attach_pcb(handle, proto, upper)
*
* Attach a new instance of SCO pcb to handle
*/
int
-sco_attach(struct sco_pcb **handle,
+sco_attach_pcb(struct sco_pcb **handle,
const struct btproto *proto, void *upper)
{
struct sco_pcb *pcb;
@@ -82,12 +82,12 @@ sco_attach(struct sco_pcb **handle,
}
/*
- * sco_bind(pcb, sockaddr)
+ * sco_bind_pcb(pcb, sockaddr)
*
* Bind SCO pcb to local address
*/
int
-sco_bind(struct sco_pcb *pcb, struct sockaddr_bt *addr)
+sco_bind_pcb(struct sco_pcb *pcb, struct sockaddr_bt *addr)
{
if (pcb->sp_link != NULL || pcb->sp_flags & SP_LISTENING)
@@ -98,12 +98,12 @@ sco_bind(struct sco_pcb *pcb, struct soc
}
/*
- * sco_sockaddr(pcb, sockaddr)
+ * sco_sockaddr_pcb(pcb, sockaddr)
*
* Copy local address of PCB to sockaddr
*/
int
-sco_sockaddr(struct sco_pcb *pcb, struct sockaddr_bt *addr)
+sco_sockaddr_pcb(struct sco_pcb *pcb, struct sockaddr_bt *addr)
{
memset(addr, 0, sizeof(struct sockaddr_bt));
@@ -114,12 +114,12 @@ sco_sockaddr(struct sco_pcb *pcb, struct
}
/*
- * sco_connect(pcb, sockaddr)
+ * sco_connect_pcb(pcb, sockaddr)
*
* Initiate a SCO connection to the destination address.
*/
int
-sco_connect(struct sco_pcb *pcb, struct sockaddr_bt *dest)
+sco_connect_pcb(struct sco_pcb *pcb, struct sockaddr_bt *dest)
{
hci_add_sco_con_cp cp;
struct hci_unit *unit;
@@ -177,12 +177,12 @@ sco_connect(struct sco_pcb *pcb, struct
}
/*
- * sco_peeraddr(pcb, sockaddr)
+ * sco_peeraddr_pcb(pcb, sockaddr)
*
* Copy remote address of SCO pcb to sockaddr
*/
int
-sco_peeraddr(struct sco_pcb *pcb, struct sockaddr_bt *addr)
+sco_peeraddr_pcb(struct sco_pcb *pcb, struct sockaddr_bt *addr)
{
memset(addr, 0, sizeof(struct sockaddr_bt));
@@ -193,12 +193,12 @@ sco_peeraddr(struct sco_pcb *pcb, struct
}
/*
- * sco_disconnect(pcb, linger)
+ * sco_disconnect_pcb(pcb, linger)
*
* Initiate disconnection of connected SCO pcb
*/
int
-sco_disconnect(struct sco_pcb *pcb, int linger)
+sco_disconnect_pcb(struct sco_pcb *pcb, int linger)
{
hci_discon_cp cp;
struct hci_link *sco;
@@ -222,12 +222,12 @@ sco_disconnect(struct sco_pcb *pcb, int
}
/*
- * sco_detach(handle)
+ * sco_detach_pcb(handle)
*
* Detach SCO pcb from handle and clear up
*/
-int
-sco_detach(struct sco_pcb **handle)
+void
+sco_detach_pcb(struct sco_pcb **handle)
{
struct sco_pcb *pcb;
@@ -235,26 +235,22 @@ sco_detach(struct sco_pcb **handle)
pcb = *handle;
*handle = NULL;
- if (pcb == NULL)
- return EINVAL;
-
if (pcb->sp_link != NULL) {
- sco_disconnect(pcb, 0);
+ sco_disconnect_pcb(pcb, 0);
pcb->sp_link = NULL;
}
LIST_REMOVE(pcb, sp_next);
free(pcb, M_BLUETOOTH);
- return 0;
}
/*
- * sco_listen(pcb)
+ * sco_listen_pcb(pcb)
*
* Mark pcb as a listener.
*/
int
-sco_listen(struct sco_pcb *pcb)
+sco_listen_pcb(struct sco_pcb *pcb)
{
if (pcb->sp_link != NULL)
@@ -265,7 +261,7 @@ sco_listen(struct sco_pcb *pcb)
}
/*
- * sco_send(pcb, mbuf)
+ * sco_send_pcb(pcb, mbuf)
*
* Send data on SCO pcb.
*
@@ -275,7 +271,7 @@ sco_listen(struct sco_pcb *pcb)
* we can drop a record from the socket buffer.
*/
int
-sco_send(struct sco_pcb *pcb, struct mbuf *m)
+sco_send_pcb(struct sco_pcb *pcb, struct mbuf *m)
{
hci_scodata_hdr_t *hdr;
int plen;
Index: src/sys/netbt/rfcomm_dlc.c
diff -u src/sys/netbt/rfcomm_dlc.c:1.7 src/sys/netbt/rfcomm_dlc.c:1.7.26.1
--- src/sys/netbt/rfcomm_dlc.c:1.7 Sun Aug 21 14:20:34 2011
+++ src/sys/netbt/rfcomm_dlc.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: rfcomm_dlc.c,v 1.7 2011/08/21 14:20:34 plunky Exp $ */
+/* $NetBSD: rfcomm_dlc.c,v 1.7.26.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_dlc.c,v 1.7 2011/08/21 14:20:34 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_dlc.c,v 1.7.26.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -84,14 +84,14 @@ rfcomm_dlc_newconn(struct rfcomm_session
* a note of the best address and BDADDR_ANY matches in order to find
* the oldest and most specific match.
*/
- l2cap_sockaddr(rs->rs_l2cap, &laddr);
- l2cap_peeraddr(rs->rs_l2cap, &raddr);
+ l2cap_sockaddr_pcb(rs->rs_l2cap, &laddr);
+ l2cap_peeraddr_pcb(rs->rs_l2cap, &raddr);
chan = RFCOMM_CHANNEL(dlci);
new = NULL;
any = best = NULL;
LIST_FOREACH(ls, &rfcomm_session_listen, rs_next) {
- l2cap_sockaddr(ls->rs_l2cap, &addr);
+ l2cap_sockaddr_pcb(ls->rs_l2cap, &addr);
if (addr.bt_psm != laddr.bt_psm)
continue;
Index: src/sys/netbt/rfcomm_session.c
diff -u src/sys/netbt/rfcomm_session.c:1.18 src/sys/netbt/rfcomm_session.c:1.18.26.1
--- src/sys/netbt/rfcomm_session.c:1.18 Wed Jul 27 10:25:09 2011
+++ src/sys/netbt/rfcomm_session.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: rfcomm_session.c,v 1.18 2011/07/27 10:25:09 plunky Exp $ */
+/* $NetBSD: rfcomm_session.c,v 1.18.26.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.18 2011/07/27 10:25:09 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.18.26.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -185,7 +185,7 @@ rfcomm_session_alloc(struct rfcomm_sessi
SIMPLEQ_INIT(&rs->rs_credits);
LIST_INIT(&rs->rs_dlcs);
- err = l2cap_attach(&rs->rs_l2cap, &rfcomm_session_proto, rs);
+ err = l2cap_attach_pcb(&rs->rs_l2cap, &rfcomm_session_proto, rs);
if (err) {
free(rs, M_BLUETOOTH);
return NULL;
@@ -199,7 +199,7 @@ rfcomm_session_alloc(struct rfcomm_sessi
if (laddr->bt_psm == L2CAP_PSM_ANY)
laddr->bt_psm = L2CAP_PSM_RFCOMM;
- (void)l2cap_bind(rs->rs_l2cap, laddr);
+ (void)l2cap_bind_pcb(rs->rs_l2cap, laddr);
LIST_INSERT_HEAD(list, rs, rs_next);
@@ -250,7 +250,7 @@ rfcomm_session_free(struct rfcomm_sessio
/* Goodbye! */
LIST_REMOVE(rs, rs_next);
- l2cap_detach(&rs->rs_l2cap);
+ l2cap_detach_pcb(&rs->rs_l2cap);
callout_destroy(&rs->rs_timeout);
free(rs, M_BLUETOOTH);
}
@@ -271,13 +271,13 @@ rfcomm_session_lookup(struct sockaddr_bt
if (rs->rs_state == RFCOMM_SESSION_CLOSED)
continue;
- l2cap_sockaddr(rs->rs_l2cap, &addr);
+ l2cap_sockaddr_pcb(rs->rs_l2cap, &addr);
if (bdaddr_same(&src->bt_bdaddr, &addr.bt_bdaddr) == 0)
if (bdaddr_any(&src->bt_bdaddr) == 0)
continue;
- l2cap_peeraddr(rs->rs_l2cap, &addr);
+ l2cap_peeraddr_pcb(rs->rs_l2cap, &addr);
if (addr.bt_psm != dest->bt_psm)
continue;
@@ -499,7 +499,7 @@ rfcomm_session_complete(void *arg, int c
*/
if (rs->rs_state == RFCOMM_SESSION_CLOSED) {
if (SIMPLEQ_EMPTY(&rs->rs_credits))
- l2cap_disconnect(rs->rs_l2cap, 0);
+ l2cap_disconnect_pcb(rs->rs_l2cap, 0);
}
}
@@ -853,7 +853,7 @@ rfcomm_session_recv_ua(struct rfcomm_ses
case RFCOMM_SESSION_WAIT_DISCONNECT: /* We sent DISC */
callout_stop(&rs->rs_timeout);
rs->rs_state = RFCOMM_SESSION_CLOSED;
- l2cap_disconnect(rs->rs_l2cap, 0);
+ l2cap_disconnect_pcb(rs->rs_l2cap, 0);
break;
default:
@@ -1510,7 +1510,7 @@ rfcomm_session_send_frame(struct rfcomm_
DPRINTFN(5, "dlci %d type %2.2x (%d bytes, fcs=%#2.2x)\n",
dlci, type, m->m_pkthdr.len, fcs);
- return l2cap_send(rs->rs_l2cap, m);
+ return l2cap_send_pcb(rs->rs_l2cap, m);
}
/*
@@ -1610,7 +1610,7 @@ rfcomm_session_send_uih(struct rfcomm_se
/*
* UIH frame ready to go..
*/
- err = l2cap_send(rs->rs_l2cap, m0);
+ err = l2cap_send_pcb(rs->rs_l2cap, m0);
if (err)
goto fail;
Index: src/sys/netbt/rfcomm_socket.c
diff -u src/sys/netbt/rfcomm_socket.c:1.11 src/sys/netbt/rfcomm_socket.c:1.11.2.1
--- src/sys/netbt/rfcomm_socket.c:1.11 Thu Aug 29 17:49:21 2013
+++ src/sys/netbt/rfcomm_socket.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: rfcomm_socket.c,v 1.11 2013/08/29 17:49:21 rmind Exp $ */
+/* $NetBSD: rfcomm_socket.c,v 1.11.2.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.11 2013/08/29 17:49:21 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.11.2.1 2014/08/10 06:56:23 tls Exp $");
/* load symbolic names */
#ifdef BLUETOOTH_DEBUG
@@ -81,73 +81,332 @@ static const struct btproto rfcomm_proto
int rfcomm_sendspace = 4096;
int rfcomm_recvspace = 4096;
+static int
+rfcomm_attach(struct socket *so, int proto)
+{
+ int error;
+
+ KASSERT(so->so_pcb == NULL);
+
+ if (so->so_lock == NULL) {
+ mutex_obj_hold(bt_lock);
+ so->so_lock = bt_lock;
+ solock(so);
+ }
+ KASSERT(solocked(so));
+
+ /*
+ * Since we have nothing to add, we attach the DLC
+ * structure directly to our PCB pointer.
+ */
+ error = soreserve(so, rfcomm_sendspace, rfcomm_recvspace);
+ if (error)
+ return error;
+
+ error = rfcomm_attach_pcb((struct rfcomm_dlc **)&so->so_pcb,
+ &rfcomm_proto, so);
+ if (error)
+ return error;
+
+ error = rfcomm_rcvd_pcb(so->so_pcb, sbspace(&so->so_rcv));
+ if (error) {
+ rfcomm_detach_pcb((struct rfcomm_dlc **)&so->so_pcb);
+ return error;
+ }
+ return 0;
+}
+
+static void
+rfcomm_detach(struct socket *so)
+{
+ KASSERT(so->so_pcb != NULL);
+ rfcomm_detach_pcb((struct rfcomm_dlc **)&so->so_pcb);
+ KASSERT(so->so_pcb == NULL);
+}
+
+static int
+rfcomm_accept(struct socket *so, struct mbuf *nam)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return rfcomm_peeraddr_pcb(pcb, sa);
+}
+
+static int
+rfcomm_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
+
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
+
+ return rfcomm_bind_pcb(pcb, sa);
+}
+
+static int
+rfcomm_listen(struct socket *so, struct lwp *l)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ return rfcomm_listen_pcb(pcb);
+}
+
+static int
+rfcomm_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
+
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
+
+ soisconnecting(so);
+ return rfcomm_connect_pcb(pcb, sa);
+}
+
+static int
+rfcomm_connect2(struct socket *so, struct socket *so2)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ return EOPNOTSUPP;
+}
+
+static int
+rfcomm_disconnect(struct socket *so)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ soisdisconnecting(so);
+ return rfcomm_disconnect_pcb(pcb, so->so_linger);
+}
+
+static int
+rfcomm_shutdown(struct socket *so)
+{
+ KASSERT(solocked(so));
+
+ socantsendmore(so);
+ return 0;
+}
+
+static int
+rfcomm_abort(struct socket *so)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ rfcomm_disconnect_pcb(pcb, 0);
+ soisdisconnected(so);
+ rfcomm_detach(so);
+ return 0;
+}
+
+static int
+rfcomm_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
+{
+ return EPASSTHROUGH;
+}
+
+static int
+rfcomm_stat(struct socket *so, struct stat *ub)
+{
+ KASSERT(solocked(so));
+
+ return 0;
+}
+
+static int
+rfcomm_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return rfcomm_peeraddr_pcb(pcb, sa);
+}
+
+static int
+rfcomm_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return rfcomm_sockaddr_pcb(pcb, sa);
+}
+
+static int
+rfcomm_rcvd(struct socket *so, int flags, struct lwp *l)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ return rfcomm_rcvd_pcb(pcb, sbspace(&so->so_rcv));
+}
+
+static int
+rfcomm_recvoob(struct socket *so, struct mbuf *m, int flags)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+rfcomm_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct lwp *l)
+{
+ struct rfcomm_dlc *pcb = so->so_pcb;
+ int err = 0;
+ struct mbuf *m0;
+
+ KASSERT(solocked(so));
+ KASSERT(m != NULL);
+
+ if (control) /* no use for that */
+ m_freem(control);
+
+ if (pcb == NULL) {
+ err = EINVAL;
+ goto release;
+ }
+
+ m0 = m_copypacket(m, M_DONTWAIT);
+ if (m0 == NULL) {
+ err = ENOMEM;
+ goto release;
+ }
+
+ sbappendstream(&so->so_snd, m);
+ return rfcomm_send_pcb(pcb, m0);
+
+release:
+ m_freem(m);
+ return err;
+}
+
+static int
+rfcomm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
+{
+ KASSERT(solocked(so));
+
+ if (m)
+ m_freem(m);
+ if (control)
+ m_freem(control);
+
+ return EOPNOTSUPP;
+}
+
+static int
+rfcomm_purgeif(struct socket *so, struct ifnet *ifp)
+{
+
+ return EOPNOTSUPP;
+}
+
/*
* User Request.
* up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally protocol number (PRU_ATTACH)
- * message flags (PRU_RCVD)
+ * m is optional mbuf chain containing message
* ctl is either
* optional mbuf chain containing socket options
- * optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
* l is pointer to process requesting action (if any)
*
* we are responsible for disposing of m and ctl if
* they are mbuf chains
*/
-int
+static int
rfcomm_usrreq(struct socket *up, int req, struct mbuf *m,
struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
{
struct rfcomm_dlc *pcb = up->so_pcb;
- struct sockaddr_bt *sa;
- struct mbuf *m0;
int err = 0;
DPRINTFN(2, "%s\n", prurequests[req]);
-
- switch (req) {
- case PRU_CONTROL:
- return EPASSTHROUGH;
-
- case PRU_PURGEIF:
- return EOPNOTSUPP;
-
- case PRU_ATTACH:
- if (up->so_lock == NULL) {
- mutex_obj_hold(bt_lock);
- up->so_lock = bt_lock;
- solock(up);
- }
- KASSERT(solocked(up));
- if (pcb != NULL)
- return EINVAL;
- /*
- * Since we have nothing to add, we attach the DLC
- * structure directly to our PCB pointer.
- */
- err = soreserve(up, rfcomm_sendspace, rfcomm_recvspace);
- if (err)
- return err;
-
- err = rfcomm_attach((struct rfcomm_dlc **)&up->so_pcb,
- &rfcomm_proto, up);
- if (err)
- return err;
-
- err = rfcomm_rcvd(up->so_pcb, sbspace(&up->so_rcv));
- if (err) {
- rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);
- return err;
- }
-
- return 0;
- }
+ KASSERT(req != PRU_ATTACH);
+ KASSERT(req != PRU_DETACH);
+ KASSERT(req != PRU_ACCEPT);
+ KASSERT(req != PRU_BIND);
+ KASSERT(req != PRU_LISTEN);
+ KASSERT(req != PRU_CONNECT);
+ KASSERT(req != PRU_CONNECT2);
+ KASSERT(req != PRU_DISCONNECT);
+ KASSERT(req != PRU_SHUTDOWN);
+ KASSERT(req != PRU_ABORT);
+ KASSERT(req != PRU_CONTROL);
+ KASSERT(req != PRU_SENSE);
+ KASSERT(req != PRU_PEERADDR);
+ KASSERT(req != PRU_SOCKADDR);
+ KASSERT(req != PRU_RCVD);
+ KASSERT(req != PRU_RCVOOB);
+ KASSERT(req != PRU_SEND);
+ KASSERT(req != PRU_SENDOOB);
+ KASSERT(req != PRU_PURGEIF);
if (pcb == NULL) {
err = EINVAL;
@@ -155,92 +414,6 @@ rfcomm_usrreq(struct socket *up, int req
}
switch(req) {
- case PRU_DISCONNECT:
- soisdisconnecting(up);
- return rfcomm_disconnect(pcb, up->so_linger);
-
- case PRU_ABORT:
- rfcomm_disconnect(pcb, 0);
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- return rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);
-
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- return rfcomm_bind(pcb, sa);
-
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- soisconnecting(up);
- return rfcomm_connect(pcb, sa);
-
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return rfcomm_peeraddr(pcb, sa);
-
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return rfcomm_sockaddr(pcb, sa);
-
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
-
- case PRU_SEND:
- KASSERT(m != NULL);
-
- if (ctl) /* no use for that */
- m_freem(ctl);
-
- m0 = m_copypacket(m, M_DONTWAIT);
- if (m0 == NULL)
- return ENOMEM;
-
- sbappendstream(&up->so_snd, m);
-
- return rfcomm_send(pcb, m0);
-
- case PRU_SENSE:
- return 0; /* (no release) */
-
- case PRU_RCVD:
- return rfcomm_rcvd(pcb, sbspace(&up->so_rcv));
-
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_LISTEN:
- return rfcomm_listen(pcb);
-
- case PRU_ACCEPT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return rfcomm_peeraddr(pcb, sa);
-
- case PRU_CONNECT2:
- case PRU_SENDOOB:
case PRU_FASTTIMO:
case PRU_SLOWTIMO:
case PRU_PROTORCV:
@@ -386,7 +559,7 @@ rfcomm_linkmode(void *arg, int new)
if (((mode & RFCOMM_LM_AUTH) && !(new & RFCOMM_LM_AUTH))
|| ((mode & RFCOMM_LM_ENCRYPT) && !(new & RFCOMM_LM_ENCRYPT))
|| ((mode & RFCOMM_LM_SECURE) && !(new & RFCOMM_LM_SECURE)))
- rfcomm_disconnect(so->so_pcb, 0);
+ rfcomm_disconnect_pcb(so->so_pcb, 0);
}
/*
@@ -411,3 +584,49 @@ rfcomm_input(void *arg, struct mbuf *m)
sbappendstream(&so->so_rcv, m);
sorwakeup(so);
}
+
+PR_WRAP_USRREQS(rfcomm)
+
+#define rfcomm_attach rfcomm_attach_wrapper
+#define rfcomm_detach rfcomm_detach_wrapper
+#define rfcomm_accept rfcomm_accept_wrapper
+#define rfcomm_bind rfcomm_bind_wrapper
+#define rfcomm_listen rfcomm_listen_wrapper
+#define rfcomm_connect rfcomm_connect_wrapper
+#define rfcomm_connect2 rfcomm_connect2_wrapper
+#define rfcomm_disconnect rfcomm_disconnect_wrapper
+#define rfcomm_shutdown rfcomm_shutdown_wrapper
+#define rfcomm_abort rfcomm_abort_wrapper
+#define rfcomm_ioctl rfcomm_ioctl_wrapper
+#define rfcomm_stat rfcomm_stat_wrapper
+#define rfcomm_peeraddr rfcomm_peeraddr_wrapper
+#define rfcomm_sockaddr rfcomm_sockaddr_wrapper
+#define rfcomm_rcvd rfcomm_rcvd_wrapper
+#define rfcomm_recvoob rfcomm_recvoob_wrapper
+#define rfcomm_send rfcomm_send_wrapper
+#define rfcomm_sendoob rfcomm_sendoob_wrapper
+#define rfcomm_purgeif rfcomm_purgeif_wrapper
+#define rfcomm_usrreq rfcomm_usrreq_wrapper
+
+const struct pr_usrreqs rfcomm_usrreqs = {
+ .pr_attach = rfcomm_attach,
+ .pr_detach = rfcomm_detach,
+ .pr_accept = rfcomm_accept,
+ .pr_bind = rfcomm_bind,
+ .pr_listen = rfcomm_listen,
+ .pr_connect = rfcomm_connect,
+ .pr_connect2 = rfcomm_connect2,
+ .pr_disconnect = rfcomm_disconnect,
+ .pr_shutdown = rfcomm_shutdown,
+ .pr_abort = rfcomm_abort,
+ .pr_ioctl = rfcomm_ioctl,
+ .pr_stat = rfcomm_stat,
+ .pr_peeraddr = rfcomm_peeraddr,
+ .pr_sockaddr = rfcomm_sockaddr,
+ .pr_rcvd = rfcomm_rcvd,
+ .pr_recvoob = rfcomm_recvoob,
+ .pr_send = rfcomm_send,
+ .pr_sendoob = rfcomm_sendoob,
+ .pr_purgeif = rfcomm_purgeif,
+ .pr_generic = rfcomm_usrreq,
+};
Index: src/sys/netbt/rfcomm_upper.c
diff -u src/sys/netbt/rfcomm_upper.c:1.13 src/sys/netbt/rfcomm_upper.c:1.13.36.1
--- src/sys/netbt/rfcomm_upper.c:1.13 Mon Jan 4 19:20:05 2010
+++ src/sys/netbt/rfcomm_upper.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: rfcomm_upper.c,v 1.13 2010/01/04 19:20:05 plunky Exp $ */
+/* $NetBSD: rfcomm_upper.c,v 1.13.36.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -32,12 +32,12 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.13 2010/01/04 19:20:05 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.13.36.1 2014/08/10 06:56:23 tls Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
-#include <sys/proc.h>
+#include <sys/kmem.h>
#include <sys/socketvar.h>
#include <sys/systm.h>
@@ -56,12 +56,12 @@ __KERNEL_RCSID(0, "$NetBSD: rfcomm_upper
*/
/*
- * rfcomm_attach(handle, proto, upper)
+ * rfcomm_attach_pcb(handle, proto, upper)
*
* attach a new RFCOMM DLC to handle, populate with reasonable defaults
*/
int
-rfcomm_attach(struct rfcomm_dlc **handle,
+rfcomm_attach_pcb(struct rfcomm_dlc **handle,
const struct btproto *proto, void *upper)
{
struct rfcomm_dlc *dlc;
@@ -70,9 +70,7 @@ rfcomm_attach(struct rfcomm_dlc **handle
KASSERT(proto != NULL);
KASSERT(upper != NULL);
- dlc = malloc(sizeof(struct rfcomm_dlc), M_BLUETOOTH, M_NOWAIT | M_ZERO);
- if (dlc == NULL)
- return ENOMEM;
+ dlc = kmem_zalloc(sizeof(struct rfcomm_dlc), KM_SLEEP);
dlc->rd_state = RFCOMM_DLC_CLOSED;
dlc->rd_mtu = rfcomm_mtu_default;
@@ -98,12 +96,12 @@ rfcomm_attach(struct rfcomm_dlc **handle
}
/*
- * rfcomm_bind(dlc, sockaddr)
+ * rfcomm_bind_pcb(dlc, sockaddr)
*
* bind DLC to local address
*/
int
-rfcomm_bind(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
+rfcomm_bind_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
{
if (dlc->rd_state != RFCOMM_DLC_CLOSED)
@@ -114,12 +112,12 @@ rfcomm_bind(struct rfcomm_dlc *dlc, stru
}
/*
- * rfcomm_sockaddr(dlc, sockaddr)
+ * rfcomm_sockaddr_pcb(dlc, sockaddr)
*
* return local address
*/
int
-rfcomm_sockaddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
+rfcomm_sockaddr_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
{
memcpy(addr, &dlc->rd_laddr, sizeof(struct sockaddr_bt));
@@ -127,12 +125,12 @@ rfcomm_sockaddr(struct rfcomm_dlc *dlc,
}
/*
- * rfcomm_connect(dlc, sockaddr)
+ * rfcomm_connect_pcb(dlc, sockaddr)
*
* Initiate connection of RFCOMM DLC to remote address.
*/
int
-rfcomm_connect(struct rfcomm_dlc *dlc, struct sockaddr_bt *dest)
+rfcomm_connect_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *dest)
{
struct rfcomm_session *rs;
int err = 0;
@@ -169,7 +167,7 @@ rfcomm_connect(struct rfcomm_dlc *dlc, s
rs->rs_flags |= RFCOMM_SESSION_INITIATOR;
rs->rs_state = RFCOMM_SESSION_WAIT_CONNECT;
- err = l2cap_connect(rs->rs_l2cap, &dlc->rd_raddr);
+ err = l2cap_connect_pcb(rs->rs_l2cap, &dlc->rd_raddr);
if (err) {
rfcomm_session_free(rs);
return err;
@@ -186,7 +184,7 @@ rfcomm_connect(struct rfcomm_dlc *dlc, s
if (rfcomm_dlc_lookup(rs, dlc->rd_dlci))
return EBUSY;
- l2cap_sockaddr(rs->rs_l2cap, &dlc->rd_laddr);
+ l2cap_sockaddr_pcb(rs->rs_l2cap, &dlc->rd_laddr);
/*
* attach the DLC to the session and start it off
@@ -202,12 +200,12 @@ rfcomm_connect(struct rfcomm_dlc *dlc, s
}
/*
- * rfcomm_peeraddr(dlc, sockaddr)
+ * rfcomm_peeraddr_pcb(dlc, sockaddr)
*
* return remote address
*/
int
-rfcomm_peeraddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
+rfcomm_peeraddr_pcb(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
{
memcpy(addr, &dlc->rd_raddr, sizeof(struct sockaddr_bt));
@@ -215,12 +213,12 @@ rfcomm_peeraddr(struct rfcomm_dlc *dlc,
}
/*
- * rfcomm_disconnect(dlc, linger)
+ * rfcomm_disconnect_pcb(dlc, linger)
*
* disconnect RFCOMM DLC
*/
int
-rfcomm_disconnect(struct rfcomm_dlc *dlc, int linger)
+rfcomm_disconnect_pcb(struct rfcomm_dlc *dlc, int linger)
{
struct rfcomm_session *rs = dlc->rd_session;
int err = 0;
@@ -270,12 +268,12 @@ rfcomm_disconnect(struct rfcomm_dlc *dlc
}
/*
- * rfcomm_detach(handle)
+ * rfcomm_detach_pcb(handle)
*
* detach RFCOMM DLC from handle
*/
-int
-rfcomm_detach(struct rfcomm_dlc **handle)
+void
+rfcomm_detach_pcb(struct rfcomm_dlc **handle)
{
struct rfcomm_dlc *dlc = *handle;
@@ -298,14 +296,12 @@ rfcomm_detach(struct rfcomm_dlc **handle
dlc->rd_flags |= RFCOMM_DLC_DETACH;
else {
callout_destroy(&dlc->rd_timeout);
- free(dlc, M_BLUETOOTH);
+ kmem_free(dlc, sizeof(*dlc));
}
-
- return 0;
}
/*
- * rfcomm_listen(dlc)
+ * rfcomm_listen_pcb(dlc)
*
* This DLC is a listener. We look for an existing listening session
* with a matching address to attach to or else create a new one on
@@ -313,7 +309,7 @@ rfcomm_detach(struct rfcomm_dlc **handle
* available for the session.
*/
int
-rfcomm_listen(struct rfcomm_dlc *dlc)
+rfcomm_listen_pcb(struct rfcomm_dlc *dlc)
{
struct rfcomm_session *rs;
struct rfcomm_dlc *used;
@@ -336,7 +332,7 @@ rfcomm_listen(struct rfcomm_dlc *dlc)
return EADDRNOTAVAIL;
LIST_FOREACH(rs, &rfcomm_session_listen, rs_next) {
- l2cap_sockaddr(rs->rs_l2cap, &addr);
+ l2cap_sockaddr_pcb(rs->rs_l2cap, &addr);
if (addr.bt_psm != dlc->rd_laddr.bt_psm)
continue;
@@ -353,7 +349,7 @@ rfcomm_listen(struct rfcomm_dlc *dlc)
rs->rs_state = RFCOMM_SESSION_LISTEN;
- err = l2cap_listen(rs->rs_l2cap);
+ err = l2cap_listen_pcb(rs->rs_l2cap);
if (err) {
rfcomm_session_free(rs);
return err;
@@ -386,14 +382,14 @@ rfcomm_listen(struct rfcomm_dlc *dlc)
}
/*
- * rfcomm_send(dlc, mbuf)
+ * rfcomm_send_pcb(dlc, mbuf)
*
* Output data on DLC. This is streamed data, so we add it
* to our buffer and start the DLC, which will assemble
* packets and send them if it can.
*/
int
-rfcomm_send(struct rfcomm_dlc *dlc, struct mbuf *m)
+rfcomm_send_pcb(struct rfcomm_dlc *dlc, struct mbuf *m)
{
if (dlc->rd_txbuf != NULL) {
@@ -410,7 +406,7 @@ rfcomm_send(struct rfcomm_dlc *dlc, stru
}
/*
- * rfcomm_rcvd(dlc, space)
+ * rfcomm_rcvd_pcb(dlc, space)
*
* Indicate space now available in receive buffer
*
@@ -419,7 +415,7 @@ rfcomm_send(struct rfcomm_dlc *dlc, stru
* buffer after that.
*/
int
-rfcomm_rcvd(struct rfcomm_dlc *dlc, size_t space)
+rfcomm_rcvd_pcb(struct rfcomm_dlc *dlc, size_t space)
{
KASSERT(dlc != NULL);
Index: src/sys/netbt/sco.h
diff -u src/sys/netbt/sco.h:1.3 src/sys/netbt/sco.h:1.3.54.1
--- src/sys/netbt/sco.h:1.3 Wed Aug 6 15:01:24 2008
+++ src/sys/netbt/sco.h Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: sco.h,v 1.3 2008/08/06 15:01:24 plunky Exp $ */
+/* $NetBSD: sco.h,v 1.3.54.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -65,20 +65,18 @@ struct sockopt;
/* sco_socket.c */
extern int sco_sendspace;
extern int sco_recvspace;
-int sco_usrreq(struct socket *, int, struct mbuf *,
- struct mbuf *, struct mbuf *, struct lwp *);
int sco_ctloutput(int, struct socket *, struct sockopt *);
/* sco_upper.c */
-int sco_attach(struct sco_pcb **, const struct btproto *, void *);
-int sco_bind(struct sco_pcb *, struct sockaddr_bt *);
-int sco_sockaddr(struct sco_pcb *, struct sockaddr_bt *);
-int sco_connect(struct sco_pcb *, struct sockaddr_bt *);
-int sco_peeraddr(struct sco_pcb *, struct sockaddr_bt *);
-int sco_disconnect(struct sco_pcb *, int);
-int sco_detach(struct sco_pcb **);
-int sco_listen(struct sco_pcb *);
-int sco_send(struct sco_pcb *, struct mbuf *);
+int sco_attach_pcb(struct sco_pcb **, const struct btproto *, void *);
+int sco_bind_pcb(struct sco_pcb *, struct sockaddr_bt *);
+int sco_sockaddr_pcb(struct sco_pcb *, struct sockaddr_bt *);
+int sco_connect_pcb(struct sco_pcb *, struct sockaddr_bt *);
+int sco_peeraddr_pcb(struct sco_pcb *, struct sockaddr_bt *);
+int sco_disconnect_pcb(struct sco_pcb *, int);
+void sco_detach_pcb(struct sco_pcb **);
+int sco_listen_pcb(struct sco_pcb *);
+int sco_send_pcb(struct sco_pcb *, struct mbuf *);
int sco_setopt(struct sco_pcb *, const struct sockopt *);
int sco_getopt(struct sco_pcb *, struct sockopt *);
Index: src/sys/netbt/sco_socket.c
diff -u src/sys/netbt/sco_socket.c:1.12 src/sys/netbt/sco_socket.c:1.12.2.1
--- src/sys/netbt/sco_socket.c:1.12 Thu Aug 29 17:49:21 2013
+++ src/sys/netbt/sco_socket.c Sun Aug 10 06:56:23 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: sco_socket.c,v 1.12 2013/08/29 17:49:21 rmind Exp $ */
+/* $NetBSD: sco_socket.c,v 1.12.2.1 2014/08/10 06:56:23 tls Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.12 2013/08/29 17:49:21 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.12.2.1 2014/08/10 06:56:23 tls Exp $");
/* load symbolic names */
#ifdef BLUETOOTH_DEBUG
@@ -78,56 +78,321 @@ static const struct btproto sco_proto =
int sco_sendspace = 4096;
int sco_recvspace = 4096;
+static int
+sco_attach(struct socket *so, int proto)
+{
+ int error;
+
+ KASSERT(so->so_pcb == NULL);
+
+ if (so->so_lock == NULL) {
+ mutex_obj_hold(bt_lock);
+ so->so_lock = bt_lock;
+ solock(so);
+ }
+ KASSERT(solocked(so));
+
+ error = soreserve(so, sco_sendspace, sco_recvspace);
+ if (error) {
+ return error;
+ }
+ return sco_attach_pcb((struct sco_pcb **)&so->so_pcb, &sco_proto, so);
+}
+
+static void
+sco_detach(struct socket *so)
+{
+ KASSERT(so->so_pcb != NULL);
+ sco_detach_pcb((struct sco_pcb **)&so->so_pcb);
+ KASSERT(so->so_pcb == NULL);
+}
+
+static int
+sco_accept(struct socket *so, struct mbuf *nam)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return sco_peeraddr_pcb(pcb, sa);
+}
+
+static int
+sco_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
+
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
+
+ return sco_bind_pcb(pcb, sa);
+}
+
+static int
+sco_listen(struct socket *so, struct lwp *l)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ return sco_listen_pcb(pcb);
+}
+
+static int
+sco_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(nam != NULL);
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ if (sa->bt_len != sizeof(struct sockaddr_bt))
+ return EINVAL;
+
+ if (sa->bt_family != AF_BLUETOOTH)
+ return EAFNOSUPPORT;
+
+ soisconnecting(so);
+ return sco_connect_pcb(pcb, sa);
+}
+
+static int
+sco_connect2(struct socket *so, struct socket *so2)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ return EOPNOTSUPP;
+}
+
+static int
+sco_disconnect(struct socket *so)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ soisdisconnecting(so);
+ return sco_disconnect_pcb(pcb, so->so_linger);
+}
+
+static int
+sco_shutdown(struct socket *so)
+{
+ KASSERT(solocked(so));
+
+ socantsendmore(so);
+ return 0;
+}
+
+static int
+sco_abort(struct socket *so)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+
+ KASSERT(solocked(so));
+
+ if (pcb == NULL)
+ return EINVAL;
+
+ sco_disconnect_pcb(pcb, 0);
+ soisdisconnected(so);
+ sco_detach(so);
+ return 0;
+}
+
+static int
+sco_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
+{
+ return EOPNOTSUPP;
+}
+
+static int
+sco_stat(struct socket *so, struct stat *ub)
+{
+ KASSERT(solocked(so));
+
+ return 0;
+}
+
+static int
+sco_peeraddr(struct socket *so, struct mbuf *nam)
+{
+ struct sco_pcb *pcb = (struct sco_pcb *)so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return sco_peeraddr_pcb(pcb, sa);
+}
+
+static int
+sco_sockaddr(struct socket *so, struct mbuf *nam)
+{
+ struct sco_pcb *pcb = (struct sco_pcb *)so->so_pcb;
+ struct sockaddr_bt *sa;
+
+ KASSERT(solocked(so));
+ KASSERT(pcb != NULL);
+ KASSERT(nam != NULL);
+
+ sa = mtod(nam, struct sockaddr_bt *);
+ nam->m_len = sizeof(struct sockaddr_bt);
+ return sco_sockaddr_pcb(pcb, sa);
+}
+
+static int
+sco_rcvd(struct socket *so, int flags, struct lwp *l)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+sco_recvoob(struct socket *so, struct mbuf *m, int flags)
+{
+ KASSERT(solocked(so));
+
+ return EOPNOTSUPP;
+}
+
+static int
+sco_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+ struct mbuf *control, struct lwp *l)
+{
+ struct sco_pcb *pcb = so->so_pcb;
+ int err = 0;
+ struct mbuf *m0;
+
+ KASSERT(solocked(so));
+ KASSERT(m != NULL);
+
+ if (control) /* no use for that */
+ m_freem(control);
+
+ if (pcb == NULL) {
+ err = EINVAL;
+ goto release;
+ }
+
+ if (m->m_pkthdr.len == 0)
+ goto release;
+
+ if (m->m_pkthdr.len > pcb->sp_mtu) {
+ err = EMSGSIZE;
+ goto release;
+ }
+
+ m0 = m_copypacket(m, M_DONTWAIT);
+ if (m0 == NULL) {
+ err = ENOMEM;
+ goto release;
+ }
+
+ sbappendrecord(&so->so_snd, m);
+ return sco_send_pcb(pcb, m0);
+
+release:
+ m_freem(m);
+ return err;
+}
+
+static int
+sco_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
+{
+ KASSERT(solocked(so));
+
+ if (m)
+ m_freem(m);
+ if (control)
+ m_freem(control);
+
+ return EOPNOTSUPP;
+}
+
+static int
+sco_purgeif(struct socket *so, struct ifnet *ifp)
+{
+
+ return EOPNOTSUPP;
+}
+
/*
* User Request.
* up is socket
- * m is either
- * optional mbuf chain containing message
- * ioctl command (PRU_CONTROL)
- * nam is either
- * optional mbuf chain containing an address
- * ioctl data (PRU_CONTROL)
- * optionally, protocol number (PRU_ATTACH)
+ * m is optional mbuf chain containing message
+ * nam is optional mbuf chain containing an address
* ctl is optional mbuf chain containing socket options
* l is pointer to process requesting action (if any)
*
* we are responsible for disposing of m and ctl if
* they are mbuf chains
*/
-int
+static int
sco_usrreq(struct socket *up, int req, struct mbuf *m,
struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
{
- struct sco_pcb *pcb = (struct sco_pcb *)up->so_pcb;
- struct sockaddr_bt *sa;
- struct mbuf *m0;
+ struct sco_pcb *pcb = up->so_pcb;
int err = 0;
DPRINTFN(2, "%s\n", prurequests[req]);
-
- switch(req) {
- case PRU_CONTROL:
- return EOPNOTSUPP;
-
- case PRU_PURGEIF:
- return EOPNOTSUPP;
-
- case PRU_ATTACH:
- if (up->so_lock == NULL) {
- mutex_obj_hold(bt_lock);
- up->so_lock = bt_lock;
- solock(up);
- }
- KASSERT(solocked(up));
- if (pcb)
- return EINVAL;
- err = soreserve(up, sco_sendspace, sco_recvspace);
- if (err)
- return err;
-
- return sco_attach((struct sco_pcb **)&up->so_pcb,
- &sco_proto, up);
- }
+ KASSERT(req != PRU_ATTACH);
+ KASSERT(req != PRU_DETACH);
+ KASSERT(req != PRU_ACCEPT);
+ KASSERT(req != PRU_BIND);
+ KASSERT(req != PRU_LISTEN);
+ KASSERT(req != PRU_CONNECT);
+ KASSERT(req != PRU_CONNECT2);
+ KASSERT(req != PRU_DISCONNECT);
+ KASSERT(req != PRU_SHUTDOWN);
+ KASSERT(req != PRU_ABORT);
+ KASSERT(req != PRU_CONTROL);
+ KASSERT(req != PRU_SENSE);
+ KASSERT(req != PRU_PEERADDR);
+ KASSERT(req != PRU_SOCKADDR);
+ KASSERT(req != PRU_RCVD);
+ KASSERT(req != PRU_RCVOOB);
+ KASSERT(req != PRU_SEND);
+ KASSERT(req != PRU_SENDOOB);
+ KASSERT(req != PRU_PURGEIF);
/* anything after here *requires* a pcb */
if (pcb == NULL) {
@@ -136,98 +401,6 @@ sco_usrreq(struct socket *up, int req, s
}
switch(req) {
- case PRU_DISCONNECT:
- soisdisconnecting(up);
- return sco_disconnect(pcb, up->so_linger);
-
- case PRU_ABORT:
- sco_disconnect(pcb, 0);
- soisdisconnected(up);
- /* fall through to */
- case PRU_DETACH:
- return sco_detach((struct sco_pcb **)&up->so_pcb);
-
- case PRU_BIND:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- return sco_bind(pcb, sa);
-
- case PRU_CONNECT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
-
- if (sa->bt_len != sizeof(struct sockaddr_bt))
- return EINVAL;
-
- if (sa->bt_family != AF_BLUETOOTH)
- return EAFNOSUPPORT;
-
- soisconnecting(up);
- return sco_connect(pcb, sa);
-
- case PRU_PEERADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return sco_peeraddr(pcb, sa);
-
- case PRU_SOCKADDR:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return sco_sockaddr(pcb, sa);
-
- case PRU_SHUTDOWN:
- socantsendmore(up);
- break;
-
- case PRU_SEND:
- KASSERT(m != NULL);
- if (m->m_pkthdr.len == 0)
- break;
-
- if (m->m_pkthdr.len > pcb->sp_mtu) {
- err = EMSGSIZE;
- break;
- }
-
- m0 = m_copypacket(m, M_DONTWAIT);
- if (m0 == NULL) {
- err = ENOMEM;
- break;
- }
-
- if (ctl) /* no use for that */
- m_freem(ctl);
-
- sbappendrecord(&up->so_snd, m);
- return sco_send(pcb, m0);
-
- case PRU_SENSE:
- return 0; /* (no sense - Doh!) */
-
- case PRU_RCVD:
- case PRU_RCVOOB:
- return EOPNOTSUPP; /* (no release) */
-
- case PRU_LISTEN:
- return sco_listen(pcb);
-
- case PRU_ACCEPT:
- KASSERT(nam != NULL);
- sa = mtod(nam, struct sockaddr_bt *);
- nam->m_len = sizeof(struct sockaddr_bt);
- return sco_peeraddr(pcb, sa);
-
- case PRU_CONNECT2:
- case PRU_SENDOOB:
case PRU_FASTTIMO:
case PRU_SLOWTIMO:
case PRU_PROTORCV:
@@ -365,3 +538,49 @@ sco_input(void *arg, struct mbuf *m)
sbappendrecord(&so->so_rcv, m);
sorwakeup(so);
}
+
+PR_WRAP_USRREQS(sco)
+
+#define sco_attach sco_attach_wrapper
+#define sco_detach sco_detach_wrapper
+#define sco_accept sco_accept_wrapper
+#define sco_bind sco_bind_wrapper
+#define sco_listen sco_listen_wrapper
+#define sco_connect sco_connect_wrapper
+#define sco_connect2 sco_connect2_wrapper
+#define sco_disconnect sco_disconnect_wrapper
+#define sco_shutdown sco_shutdown_wrapper
+#define sco_abort sco_abort_wrapper
+#define sco_ioctl sco_ioctl_wrapper
+#define sco_stat sco_stat_wrapper
+#define sco_peeraddr sco_peeraddr_wrapper
+#define sco_sockaddr sco_sockaddr_wrapper
+#define sco_rcvd sco_rcvd_wrapper
+#define sco_recvoob sco_recvoob_wrapper
+#define sco_send sco_send_wrapper
+#define sco_sendoob sco_sendoob_wrapper
+#define sco_purgeif sco_purgeif_wrapper
+#define sco_usrreq sco_usrreq_wrapper
+
+const struct pr_usrreqs sco_usrreqs = {
+ .pr_attach = sco_attach,
+ .pr_detach = sco_detach,
+ .pr_accept = sco_accept,
+ .pr_bind = sco_bind,
+ .pr_listen = sco_listen,
+ .pr_connect = sco_connect,
+ .pr_connect2 = sco_connect2,
+ .pr_disconnect = sco_disconnect,
+ .pr_shutdown = sco_shutdown,
+ .pr_abort = sco_abort,
+ .pr_ioctl = sco_ioctl,
+ .pr_stat = sco_stat,
+ .pr_peeraddr = sco_peeraddr,
+ .pr_sockaddr = sco_sockaddr,
+ .pr_rcvd = sco_rcvd,
+ .pr_recvoob = sco_recvoob,
+ .pr_send = sco_send,
+ .pr_sendoob = sco_sendoob,
+ .pr_purgeif = sco_purgeif,
+ .pr_generic = sco_usrreq,
+};