#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: bt_proto.c,v 1.17 2023/08/07 13:31:54 riastradh Exp $");
#include <sys/param.h>
#include <sys/domain.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/systm.h>
#include <net/route.h>
#include <netbt/bluetooth.h>
#include <netbt/hci.h>
#include <netbt/l2cap.h>
#include <netbt/rfcomm.h>
#include <netbt/sco.h>
DOMAIN_DEFINE(btdomain);
static void bt_init(void);
PR_WRAP_CTLOUTPUT(hci_ctloutput)
PR_WRAP_CTLOUTPUT(sco_ctloutput)
PR_WRAP_CTLOUTPUT(l2cap_ctloutput)
PR_WRAP_CTLOUTPUT(rfcomm_ctloutput)
#define hci_ctloutput hci_ctloutput_wrapper
#define sco_ctloutput sco_ctloutput_wrapper
#define l2cap_ctloutput l2cap_ctloutput_wrapper
#define rfcomm_ctloutput rfcomm_ctloutput_wrapper
static const struct protosw btsw[] = {
{
.pr_type = SOCK_RAW,
.pr_domain = &btdomain,
.pr_protocol = BTPROTO_HCI,
.pr_flags = (PR_ADDR | PR_ATOMIC),
.pr_init = hci_init,
.pr_ctloutput = hci_ctloutput,
.pr_usrreqs = &hci_usrreqs,
},
{
.pr_type = SOCK_SEQPACKET,
.pr_domain = &btdomain,
.pr_protocol = BTPROTO_SCO,
.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC | PR_LISTEN),
.pr_ctloutput = sco_ctloutput,
.pr_usrreqs = &sco_usrreqs,
},
{
.pr_type = SOCK_SEQPACKET,
.pr_domain = &btdomain,
.pr_protocol = BTPROTO_L2CAP,
.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC | PR_LISTEN),
.pr_ctloutput = l2cap_ctloutput,
.pr_usrreqs = &l2cap_usrreqs,
.pr_init = l2cap_init,
},
{
.pr_type = SOCK_STREAM,
.pr_domain = &btdomain,
.pr_protocol = BTPROTO_RFCOMM,
.pr_flags = (PR_CONNREQUIRED | PR_LISTEN | PR_WANTRCVD),
.pr_ctloutput = rfcomm_ctloutput,
.pr_usrreqs = &rfcomm_usrreqs,
.pr_init = rfcomm_init,
},
};
struct domain btdomain = {
.dom_family = AF_BLUETOOTH,
.dom_name = "bluetooth",
.dom_init = bt_init,
.dom_protosw = btsw,
.dom_protoswNPROTOSW = &btsw[__arraycount(btsw)],
};
kmutex_t *bt_lock;
static void
bt_init(void)
{
}
MODULE(MODULE_CLASS_DRIVER, netbt, NULL);
static int
netbt_modcmd(modcmd_t cmd, void *aux)
{
switch (cmd) {
case MODULE_CMD_INIT:
bt_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
return 0;
case MODULE_CMD_FINI:
return EBUSY;
default:
return ENOTTY;
}
}