xref: /dragonfly/sys/netbt/bt_proto.c (revision 8bc4b666)
10a9108ebSHasso Tepper /* $OpenBSD: bt_proto.c,v 1.4 2007/06/24 20:55:27 uwe Exp $ */
20a9108ebSHasso Tepper 
30a9108ebSHasso Tepper /*
40a9108ebSHasso Tepper  * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
50a9108ebSHasso Tepper  *
60a9108ebSHasso Tepper  * Permission to use, copy, modify, and distribute this software for any
70a9108ebSHasso Tepper  * purpose with or without fee is hereby granted, provided that the above
80a9108ebSHasso Tepper  * copyright notice and this permission notice appear in all copies.
90a9108ebSHasso Tepper  *
100a9108ebSHasso Tepper  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
110a9108ebSHasso Tepper  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
120a9108ebSHasso Tepper  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
130a9108ebSHasso Tepper  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
140a9108ebSHasso Tepper  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
150a9108ebSHasso Tepper  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
160a9108ebSHasso Tepper  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
170a9108ebSHasso Tepper  */
180a9108ebSHasso Tepper 
190a9108ebSHasso Tepper #include <sys/param.h>
200a9108ebSHasso Tepper #include <sys/domain.h>
210a9108ebSHasso Tepper #include <sys/protosw.h>
220a9108ebSHasso Tepper #include <sys/socket.h>
230a9108ebSHasso Tepper #include <sys/socketvar.h>
240a9108ebSHasso Tepper #include <sys/queue.h>
250a9108ebSHasso Tepper #include <sys/kernel.h>
260a9108ebSHasso Tepper #include <sys/mbuf.h>
270a9108ebSHasso Tepper #include <sys/sysctl.h>
280a9108ebSHasso Tepper #include <sys/bus.h>
290a9108ebSHasso Tepper #include <sys/malloc.h>
300a9108ebSHasso Tepper #include <net/if.h>
310a9108ebSHasso Tepper 
320a9108ebSHasso Tepper #include <netbt/bluetooth.h>
330a9108ebSHasso Tepper #include <netbt/hci.h>
340a9108ebSHasso Tepper #include <netbt/l2cap.h>
350a9108ebSHasso Tepper #include <netbt/rfcomm.h>
360a9108ebSHasso Tepper #include <netbt/sco.h>
370a9108ebSHasso Tepper 
380a9108ebSHasso Tepper MALLOC_DEFINE(M_BLUETOOTH, "Bluetooth", "Bluetooth system memory");
390a9108ebSHasso Tepper 
400a9108ebSHasso Tepper extern struct pr_usrreqs hci_usrreqs;
410a9108ebSHasso Tepper 
420a9108ebSHasso Tepper static int
netbt_modevent(module_t mod,int type,void * data)430a9108ebSHasso Tepper netbt_modevent(module_t mod, int type, void *data)
440a9108ebSHasso Tepper {
450a9108ebSHasso Tepper 	switch (type) {
460a9108ebSHasso Tepper 	case MOD_LOAD:
470a9108ebSHasso Tepper 		break;
480a9108ebSHasso Tepper 	case MOD_UNLOAD:
490a9108ebSHasso Tepper 		return EBUSY;
500a9108ebSHasso Tepper 		break;
510a9108ebSHasso Tepper 	default:
520a9108ebSHasso Tepper 		break;
530a9108ebSHasso Tepper 	}
540a9108ebSHasso Tepper 	return 0;
550a9108ebSHasso Tepper }
560a9108ebSHasso Tepper 
570a9108ebSHasso Tepper static moduledata_t netbt_mod = {
580a9108ebSHasso Tepper 	"netbt",
590a9108ebSHasso Tepper 	netbt_modevent,
600a9108ebSHasso Tepper 	NULL
610a9108ebSHasso Tepper };
620a9108ebSHasso Tepper 
630a9108ebSHasso Tepper DECLARE_MODULE(netbt, netbt_mod, SI_SUB_EXEC, SI_ORDER_ANY);
643d0fe62dSAlexander Polakov MODULE_VERSION(netbt, 1);
650a9108ebSHasso Tepper 
660a9108ebSHasso Tepper struct domain btdomain;
670a9108ebSHasso Tepper 
680a9108ebSHasso Tepper struct protosw btsw[] = {
690a9108ebSHasso Tepper 	{ /* raw HCI commands */
700a9108ebSHasso Tepper 		.pr_type = SOCK_RAW,
710a9108ebSHasso Tepper 		.pr_domain = &btdomain,
720a9108ebSHasso Tepper 		.pr_protocol = BTPROTO_HCI,
730a9108ebSHasso Tepper 		.pr_flags = (PR_ADDR | PR_ATOMIC),
740a9108ebSHasso Tepper 		.pr_input = 0,
750a9108ebSHasso Tepper 		.pr_output = 0,
760a9108ebSHasso Tepper 		.pr_ctlinput = 0,
770a9108ebSHasso Tepper 		.pr_ctloutput = hci_ctloutput,
78716da958SSepherosa Ziehau 		.pr_ctlport = NULL,
790a9108ebSHasso Tepper 		.pr_init = 0,
800a9108ebSHasso Tepper 		.pr_drain = 0,
810a9108ebSHasso Tepper 		.pr_usrreqs = &hci_usrreqs
820a9108ebSHasso Tepper 	},
830a9108ebSHasso Tepper 	{ /* HCI SCO data (audio) */
840a9108ebSHasso Tepper 		.pr_type = SOCK_SEQPACKET,
850a9108ebSHasso Tepper 		.pr_domain = &btdomain,
860a9108ebSHasso Tepper 		.pr_protocol = BTPROTO_SCO,
870a9108ebSHasso Tepper 		.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
880a9108ebSHasso Tepper 		.pr_input = 0,
890a9108ebSHasso Tepper 		.pr_output = 0,
900a9108ebSHasso Tepper 		.pr_ctlinput = 0,
910a9108ebSHasso Tepper 		.pr_ctloutput = sco_ctloutput,
92716da958SSepherosa Ziehau 		.pr_ctlport = NULL,
930a9108ebSHasso Tepper 		.pr_init = 0,
940a9108ebSHasso Tepper 		.pr_drain = 0,
950a9108ebSHasso Tepper 		.pr_usrreqs = &sco_usrreqs
960a9108ebSHasso Tepper 
970a9108ebSHasso Tepper 	},
980a9108ebSHasso Tepper 	{ /* L2CAP Connection Oriented */
990a9108ebSHasso Tepper 		.pr_type = SOCK_SEQPACKET,
1000a9108ebSHasso Tepper 		.pr_domain = &btdomain,
1010a9108ebSHasso Tepper 		.pr_protocol = BTPROTO_L2CAP,
1020a9108ebSHasso Tepper 		.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
1030a9108ebSHasso Tepper 		.pr_input = 0,
1040a9108ebSHasso Tepper 		.pr_output = 0,
1050a9108ebSHasso Tepper 		.pr_ctlinput = 0,
1060a9108ebSHasso Tepper 		.pr_ctloutput = l2cap_ctloutput,
107716da958SSepherosa Ziehau 		.pr_ctlport = NULL,
1080a9108ebSHasso Tepper 		.pr_init = 0,
1090a9108ebSHasso Tepper 		.pr_drain = 0,
1100a9108ebSHasso Tepper 		.pr_usrreqs = &l2cap_usrreqs
1110a9108ebSHasso Tepper 	},
1120a9108ebSHasso Tepper 	{ /* RFCOMM */
1130a9108ebSHasso Tepper 		.pr_type = SOCK_STREAM,
1140a9108ebSHasso Tepper 		.pr_domain = &btdomain,
1150a9108ebSHasso Tepper 		.pr_protocol = BTPROTO_RFCOMM,
1160a9108ebSHasso Tepper 		.pr_flags = (PR_CONNREQUIRED | PR_WANTRCVD),
1170a9108ebSHasso Tepper 		.pr_input = 0,
1180a9108ebSHasso Tepper 		.pr_output = 0,
1190a9108ebSHasso Tepper 		.pr_ctlinput = 0,
1200a9108ebSHasso Tepper 		.pr_ctloutput = rfcomm_ctloutput,
121716da958SSepherosa Ziehau 		.pr_ctlport = NULL,
1220a9108ebSHasso Tepper 		.pr_init = 0,
1230a9108ebSHasso Tepper 		.pr_drain = 0,
1240a9108ebSHasso Tepper 		.pr_usrreqs = &rfcomm_usrreqs
1250a9108ebSHasso Tepper 	},
1260a9108ebSHasso Tepper };
1270a9108ebSHasso Tepper 
1280a9108ebSHasso Tepper static void
netbt_dispose(struct mbuf * m)1290a9108ebSHasso Tepper netbt_dispose(struct mbuf* m)
1300a9108ebSHasso Tepper {
1315179415aSSascha Wildner 	zdestroy(l2cap_pdu_pool);
1325179415aSSascha Wildner 	zdestroy(l2cap_req_pool);
1335179415aSSascha Wildner 	zdestroy(rfcomm_credit_pool);
1340a9108ebSHasso Tepper }
1350a9108ebSHasso Tepper 
1360a9108ebSHasso Tepper static void
netbt_init(void)1370a9108ebSHasso Tepper netbt_init(void)
1380a9108ebSHasso Tepper {
1395179415aSSascha Wildner 	l2cap_pdu_pool = zinit("l2cap_pdu", sizeof(struct l2cap_pdu), 1,
1403091de50SMatthew Dillon 			       ZONE_DESTROYABLE);
1415179415aSSascha Wildner 	if (l2cap_pdu_pool == NULL)
1425179415aSSascha Wildner 		goto fail;
1435179415aSSascha Wildner 	l2cap_req_pool = zinit("l2cap_req", sizeof(struct l2cap_req), 1,
1443091de50SMatthew Dillon 			       ZONE_DESTROYABLE);
1455179415aSSascha Wildner 	if (l2cap_req_pool == NULL)
1465179415aSSascha Wildner 		goto fail;
1475179415aSSascha Wildner 	rfcomm_credit_pool = zinit("rfcomm_credit",
1483091de50SMatthew Dillon 				   sizeof(struct rfcomm_credit), 1,
1493091de50SMatthew Dillon 				   ZONE_DESTROYABLE);
1505179415aSSascha Wildner 	if (rfcomm_credit_pool == NULL)
1515179415aSSascha Wildner 		goto fail;
1525179415aSSascha Wildner 	return;
1535179415aSSascha Wildner fail:
1540a9108ebSHasso Tepper 	netbt_dispose(NULL);
1550a9108ebSHasso Tepper 	panic("Can't create vm_zones");
1560a9108ebSHasso Tepper }
1570a9108ebSHasso Tepper 
1580a9108ebSHasso Tepper struct domain btdomain = {
1590a9108ebSHasso Tepper 	.dom_family = AF_BLUETOOTH,
1600a9108ebSHasso Tepper 	.dom_name = "bluetooth",
1610a9108ebSHasso Tepper 	.dom_init = netbt_init,
1620a9108ebSHasso Tepper 	.dom_externalize = NULL,
1630a9108ebSHasso Tepper 	.dom_dispose = netbt_dispose,
1640a9108ebSHasso Tepper 	.dom_protosw = btsw,
165c157ff7aSSascha Wildner 	.dom_protoswNPROTOSW = &btsw[NELEM(btsw)],
1660a9108ebSHasso Tepper 	.dom_next = SLIST_ENTRY_INITIALIZER,
167*8bc4b666SAaron LI 	.dom_rtattach = NULL,
168*8bc4b666SAaron LI 	.dom_rtoffset = 0,
1690a9108ebSHasso Tepper 	.dom_maxrtkey = sizeof(struct sockaddr_bt),
170*8bc4b666SAaron LI 	.dom_ifattach = NULL,
171*8bc4b666SAaron LI 	.dom_ifdetach = NULL,
1720a9108ebSHasso Tepper };
1730a9108ebSHasso Tepper 
1740a9108ebSHasso Tepper DOMAIN_SET(bt);
1759ce3a983SHasso Tepper SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RD, 0,
1769ce3a983SHasso Tepper     "Bluetooth Protocol Family");
1779ce3a983SHasso Tepper 
1789ce3a983SHasso Tepper /* HCI sysctls */
1799ce3a983SHasso Tepper SYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RD, 0,
1809ce3a983SHasso Tepper     "Host Controller Interface");
1819ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, sendspace, CTLFLAG_RW, &hci_sendspace,
1829ce3a983SHasso Tepper     0, "Socket Send Buffer Size");
1839ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, recvspace, CTLFLAG_RW, &hci_recvspace,
1849ce3a983SHasso Tepper     0, "Socket Receive Buffer Size");
1859ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, acl_expiry, CTLFLAG_RW,
1869ce3a983SHasso Tepper     &hci_acl_expiry, 0, "ACL Connection Expiry Time");
1879ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, memo_expiry, CTLFLAG_RW,
1889ce3a983SHasso Tepper     &hci_memo_expiry, 0, "Memo Expiry Time");
1899ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, eventq_max, CTLFLAG_RW,
1909ce3a983SHasso Tepper     &hci_eventq_max, 0, "Max Event queue length");
1919ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, aclrxq_max, CTLFLAG_RW,
1929ce3a983SHasso Tepper     &hci_aclrxq_max, 0, "Max ACL rx queue length");
1939ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, scorxq_max, CTLFLAG_RW,
1949ce3a983SHasso Tepper     &hci_scorxq_max, 0, "Max SCO rx queue length");
1959ce3a983SHasso Tepper 
1969ce3a983SHasso Tepper /* L2CAP sysctls */
1979ce3a983SHasso Tepper SYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RD, 0,
1980ca0cd25SSascha Wildner     "Logical Link Control & Adaptation Protocol");
1999ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, sendspace, CTLFLAG_RW,
2009ce3a983SHasso Tepper     &l2cap_sendspace, 0, "Socket Send Buffer Size");
2019ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, recvspace, CTLFLAG_RW,
2029ce3a983SHasso Tepper     &l2cap_recvspace, 0, "Socket Receive Buffer Size");
2039ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, rtx, CTLFLAG_RW,
2049ce3a983SHasso Tepper     &l2cap_response_timeout, 0, "Response Timeout");
2059ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, ertx, CTLFLAG_RW,
2069ce3a983SHasso Tepper     &l2cap_response_extended_timeout, 0, "Extended Response Timeout");
2079ce3a983SHasso Tepper 
2089ce3a983SHasso Tepper /* RFCOMM sysctls */
2099ce3a983SHasso Tepper SYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RD, 0,
2109ce3a983SHasso Tepper     "Serial Cable Emulation");
2119ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, sendspace, CTLFLAG_RW,
2129ce3a983SHasso Tepper     &rfcomm_sendspace, 0, "Socket Send Buffer Size");
2139ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, recvspace, CTLFLAG_RW,
2149ce3a983SHasso Tepper     &rfcomm_recvspace, 0, "Socket Receive Buffer Size");
2159ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mtu_default, CTLFLAG_RW,
2169ce3a983SHasso Tepper     &rfcomm_mtu_default, 0, "Default MTU");
2179ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, ack_timeout, CTLFLAG_RW,
2189ce3a983SHasso Tepper     &rfcomm_ack_timeout, 0, "Acknowledgement Timer");
2199ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mcc_timeout, CTLFLAG_RW,
2209ce3a983SHasso Tepper     &rfcomm_mcc_timeout, 0, "Response Timeout for Multiplexer Control Channel");
2219ce3a983SHasso Tepper 
2229ce3a983SHasso Tepper /* SCO sysctls */
2239ce3a983SHasso Tepper SYSCTL_NODE(_net_bluetooth, OID_AUTO, sco, CTLFLAG_RD, 0, "SCO data");
2249ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, sendspace, CTLFLAG_RW, &sco_sendspace,
2259ce3a983SHasso Tepper     0, "Socket Send Buffer Size");
2269ce3a983SHasso Tepper SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, recvspace, CTLFLAG_RW, &sco_recvspace,
2279ce3a983SHasso Tepper     0, "Socket Receive Buffer Size");
2280a9108ebSHasso Tepper 
2290a9108ebSHasso Tepper static void
netisr_netbt_setup(void * dummy __unused)2300a9108ebSHasso Tepper netisr_netbt_setup(void *dummy __unused)
2310a9108ebSHasso Tepper {
232c3c96e44SMatthew Dillon 	netisr_register(NETISR_BLUETOOTH, btintr, NULL);
2330a9108ebSHasso Tepper }
2340a9108ebSHasso Tepper 
2350a9108ebSHasso Tepper SYSINIT(netbt_setup, SI_BOOT2_KLD, SI_ORDER_ANY, netisr_netbt_setup, NULL);
236