xref: /dflybsd-src/sys/netbt/bt_proto.c (revision 6b47f3ea0add18fe433924e96d23c8a42f668f93)
1  /* $OpenBSD: bt_proto.c,v 1.4 2007/06/24 20:55:27 uwe Exp $ */
2  
3  /*
4   * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
5   *
6   * Permission to use, copy, modify, and distribute this software for any
7   * purpose with or without fee is hereby granted, provided that the above
8   * copyright notice and this permission notice appear in all copies.
9   *
10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17   */
18  
19  #include <sys/param.h>
20  #include <sys/domain.h>
21  #include <sys/protosw.h>
22  #include <sys/socket.h>
23  #include <sys/socketvar.h>
24  #include <sys/queue.h>
25  #include <sys/kernel.h>
26  #include <sys/mbuf.h>
27  #include <sys/sysctl.h>
28  #include <sys/bus.h>
29  #include <sys/malloc.h>
30  #include <net/if.h>
31  
32  #include <netbt/bluetooth.h>
33  #include <netbt/hci.h>
34  #include <netbt/l2cap.h>
35  #include <netbt/rfcomm.h>
36  #include <netbt/sco.h>
37  
38  MALLOC_DEFINE(M_BLUETOOTH, "Bluetooth", "Bluetooth system memory");
39  
40  extern struct pr_usrreqs hci_usrreqs;
41  
42  static int
43  netbt_modevent(module_t mod, int type, void *data)
44  {
45  	switch (type) {
46  	case MOD_LOAD:
47  		break;
48  	case MOD_UNLOAD:
49  		return EBUSY;
50  		break;
51  	default:
52  		break;
53  	}
54  	return 0;
55  }
56  
57  static moduledata_t netbt_mod = {
58  	"netbt",
59  	netbt_modevent,
60  	NULL
61  };
62  
63  DECLARE_MODULE(netbt, netbt_mod, SI_SUB_EXEC, SI_ORDER_ANY);
64  MODULE_VERSION(netbt, 1);
65  
66  struct domain btdomain;
67  
68  struct protosw btsw[] = {
69  	{ /* raw HCI commands */
70  		.pr_type = SOCK_RAW,
71  		.pr_domain = &btdomain,
72  		.pr_protocol = BTPROTO_HCI,
73  		.pr_flags = (PR_ADDR | PR_ATOMIC),
74  		.pr_input = 0,
75  		.pr_output = 0,
76  		.pr_ctlinput = 0,
77  		.pr_ctloutput = hci_ctloutput,
78  		.pr_ctlport = NULL,
79  		.pr_init = 0,
80  		.pr_drain = 0,
81  		.pr_usrreqs = &hci_usrreqs
82  	},
83  	{ /* HCI SCO data (audio) */
84  		.pr_type = SOCK_SEQPACKET,
85  		.pr_domain = &btdomain,
86  		.pr_protocol = BTPROTO_SCO,
87  		.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
88  		.pr_input = 0,
89  		.pr_output = 0,
90  		.pr_ctlinput = 0,
91  		.pr_ctloutput = sco_ctloutput,
92  		.pr_ctlport = NULL,
93  		.pr_init = 0,
94  		.pr_drain = 0,
95  		.pr_usrreqs = &sco_usrreqs
96  
97  	},
98  	{ /* L2CAP Connection Oriented */
99  		.pr_type = SOCK_SEQPACKET,
100  		.pr_domain = &btdomain,
101  		.pr_protocol = BTPROTO_L2CAP,
102  		.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
103  		.pr_input = 0,
104  		.pr_output = 0,
105  		.pr_ctlinput = 0,
106  		.pr_ctloutput = l2cap_ctloutput,
107  		.pr_ctlport = NULL,
108  		.pr_init = 0,
109  		.pr_drain = 0,
110  		.pr_usrreqs = &l2cap_usrreqs
111  	},
112  	{ /* RFCOMM */
113  		.pr_type = SOCK_STREAM,
114  		.pr_domain = &btdomain,
115  		.pr_protocol = BTPROTO_RFCOMM,
116  		.pr_flags = (PR_CONNREQUIRED | PR_WANTRCVD),
117  		.pr_input = 0,
118  		.pr_output = 0,
119  		.pr_ctlinput = 0,
120  		.pr_ctloutput = rfcomm_ctloutput,
121  		.pr_ctlport = NULL,
122  		.pr_init = 0,
123  		.pr_drain = 0,
124  		.pr_usrreqs = &rfcomm_usrreqs
125  	},
126  };
127  
128  static void
129  netbt_dispose(struct mbuf* m)
130  {
131  	zdestroy(l2cap_pdu_pool);
132  	zdestroy(l2cap_req_pool);
133  	zdestroy(rfcomm_credit_pool);
134  }
135  
136  static void
137  netbt_init(void)
138  {
139  	l2cap_pdu_pool = zinit("l2cap_pdu", sizeof(struct l2cap_pdu), 1,
140  			       ZONE_DESTROYABLE);
141  	if (l2cap_pdu_pool == NULL)
142  		goto fail;
143  	l2cap_req_pool = zinit("l2cap_req", sizeof(struct l2cap_req), 1,
144  			       ZONE_DESTROYABLE);
145  	if (l2cap_req_pool == NULL)
146  		goto fail;
147  	rfcomm_credit_pool = zinit("rfcomm_credit",
148  				   sizeof(struct rfcomm_credit), 1,
149  				   ZONE_DESTROYABLE);
150  	if (rfcomm_credit_pool == NULL)
151  		goto fail;
152  	return;
153  fail:
154  	netbt_dispose(NULL);
155  	panic("Can't create vm_zones");
156  }
157  
158  struct domain btdomain = {
159  	.dom_family = AF_BLUETOOTH,
160  	.dom_name = "bluetooth",
161  	.dom_init = netbt_init,
162  	.dom_externalize = NULL,
163  	.dom_dispose = netbt_dispose,
164  	.dom_protosw = btsw,
165  	.dom_protoswNPROTOSW = &btsw[NELEM(btsw)],
166  	.dom_next = SLIST_ENTRY_INITIALIZER,
167  	.dom_rtattach = NULL,
168  	.dom_rtoffset = 0,
169  	.dom_maxrtkey = sizeof(struct sockaddr_bt),
170  	.dom_ifattach = NULL,
171  	.dom_ifdetach = NULL,
172  };
173  
174  DOMAIN_SET(bt);
175  SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RD, 0,
176      "Bluetooth Protocol Family");
177  
178  /* HCI sysctls */
179  SYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RD, 0,
180      "Host Controller Interface");
181  SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, sendspace, CTLFLAG_RW, &hci_sendspace,
182      0, "Socket Send Buffer Size");
183  SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, recvspace, CTLFLAG_RW, &hci_recvspace,
184      0, "Socket Receive Buffer Size");
185  SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, acl_expiry, CTLFLAG_RW,
186      &hci_acl_expiry, 0, "ACL Connection Expiry Time");
187  SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, memo_expiry, CTLFLAG_RW,
188      &hci_memo_expiry, 0, "Memo Expiry Time");
189  SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, eventq_max, CTLFLAG_RW,
190      &hci_eventq_max, 0, "Max Event queue length");
191  SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, aclrxq_max, CTLFLAG_RW,
192      &hci_aclrxq_max, 0, "Max ACL rx queue length");
193  SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, scorxq_max, CTLFLAG_RW,
194      &hci_scorxq_max, 0, "Max SCO rx queue length");
195  
196  /* L2CAP sysctls */
197  SYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RD, 0,
198      "Logical Link Control & Adaptation Protocol");
199  SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, sendspace, CTLFLAG_RW,
200      &l2cap_sendspace, 0, "Socket Send Buffer Size");
201  SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, recvspace, CTLFLAG_RW,
202      &l2cap_recvspace, 0, "Socket Receive Buffer Size");
203  SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, rtx, CTLFLAG_RW,
204      &l2cap_response_timeout, 0, "Response Timeout");
205  SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, ertx, CTLFLAG_RW,
206      &l2cap_response_extended_timeout, 0, "Extended Response Timeout");
207  
208  /* RFCOMM sysctls */
209  SYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RD, 0,
210      "Serial Cable Emulation");
211  SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, sendspace, CTLFLAG_RW,
212      &rfcomm_sendspace, 0, "Socket Send Buffer Size");
213  SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, recvspace, CTLFLAG_RW,
214      &rfcomm_recvspace, 0, "Socket Receive Buffer Size");
215  SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mtu_default, CTLFLAG_RW,
216      &rfcomm_mtu_default, 0, "Default MTU");
217  SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, ack_timeout, CTLFLAG_RW,
218      &rfcomm_ack_timeout, 0, "Acknowledgement Timer");
219  SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mcc_timeout, CTLFLAG_RW,
220      &rfcomm_mcc_timeout, 0, "Response Timeout for Multiplexer Control Channel");
221  
222  /* SCO sysctls */
223  SYSCTL_NODE(_net_bluetooth, OID_AUTO, sco, CTLFLAG_RD, 0, "SCO data");
224  SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, sendspace, CTLFLAG_RW, &sco_sendspace,
225      0, "Socket Send Buffer Size");
226  SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, recvspace, CTLFLAG_RW, &sco_recvspace,
227      0, "Socket Receive Buffer Size");
228  
229  static void
230  netisr_netbt_setup(void *dummy __unused)
231  {
232  	netisr_register(NETISR_BLUETOOTH, btintr, NULL);
233  }
234  
235  SYSINIT(netbt_setup, SI_BOOT2_KLD, SI_ORDER_ANY, netisr_netbt_setup, NULL);
236