This source file includes following definitions.
- sco_usrreq
- sco_ctloutput
- sco_connecting
- sco_connected
- sco_disconnected
- sco_newconn
- sco_complete
- sco_linkmode
- sco_input
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 #include <sys/cdefs.h>
34
35
36 #ifdef BLUETOOTH_DEBUG
37 #define PRUREQUESTS
38 #define PRCOREQUESTS
39 #endif
40
41 #include <sys/param.h>
42 #include <sys/domain.h>
43 #include <sys/kernel.h>
44 #include <sys/mbuf.h>
45 #include <sys/proc.h>
46 #include <sys/protosw.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/systm.h>
50
51 #include <netbt/bluetooth.h>
52 #include <netbt/hci.h>
53 #include <netbt/sco.h>
54
55
56
57
58
59
60 static void sco_connecting(void *);
61 static void sco_connected(void *);
62 static void sco_disconnected(void *, int);
63 static void *sco_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
64 static void sco_complete(void *, int);
65 static void sco_linkmode(void *, int);
66 static void sco_input(void *, struct mbuf *);
67
68 static const struct btproto sco_proto = {
69 sco_connecting,
70 sco_connected,
71 sco_disconnected,
72 sco_newconn,
73 sco_complete,
74 sco_linkmode,
75 sco_input,
76 };
77
78 int sco_sendspace = 4096;
79 int sco_recvspace = 4096;
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97 int
98 sco_usrreq(struct socket *up, int req, struct mbuf *m,
99 struct mbuf *nam, struct mbuf *ctl)
100 {
101 struct sco_pcb *pcb = (struct sco_pcb *)up->so_pcb;
102 struct sockaddr_bt *sa;
103 struct mbuf *m0;
104 int err = 0;
105
106 #ifdef notyet
107 DPRINTFN(2, "%s\n", prurequests[req]);
108 #endif
109
110 switch(req) {
111 case PRU_CONTROL:
112 return EOPNOTSUPP;
113
114 #ifdef notyet
115 case PRU_PURGEIF:
116 return EOPNOTSUPP;
117 #endif
118
119 case PRU_ATTACH:
120 if (pcb)
121 return EINVAL;
122
123 err = soreserve(up, sco_sendspace, sco_recvspace);
124 if (err)
125 return err;
126
127 return sco_attach((struct sco_pcb **)&up->so_pcb,
128 &sco_proto, up);
129 }
130
131
132 if (pcb == NULL) {
133 err = EINVAL;
134 goto release;
135 }
136
137 switch(req) {
138 case PRU_DISCONNECT:
139 soisdisconnecting(up);
140 return sco_disconnect(pcb, up->so_linger);
141
142 case PRU_ABORT:
143 sco_disconnect(pcb, 0);
144 soisdisconnected(up);
145
146 case PRU_DETACH:
147 return sco_detach((struct sco_pcb **)&up->so_pcb);
148
149 case PRU_BIND:
150 KASSERT(nam != NULL);
151 sa = mtod(nam, struct sockaddr_bt *);
152
153 if (sa->bt_len != sizeof(struct sockaddr_bt))
154 return EINVAL;
155
156 if (sa->bt_family != AF_BLUETOOTH)
157 return EAFNOSUPPORT;
158
159 return sco_bind(pcb, sa);
160
161 case PRU_CONNECT:
162 KASSERT(nam != NULL);
163 sa = mtod(nam, struct sockaddr_bt *);
164
165 if (sa->bt_len != sizeof(struct sockaddr_bt))
166 return EINVAL;
167
168 if (sa->bt_family != AF_BLUETOOTH)
169 return EAFNOSUPPORT;
170
171 soisconnecting(up);
172 return sco_connect(pcb, sa);
173
174 case PRU_PEERADDR:
175 KASSERT(nam != NULL);
176 sa = mtod(nam, struct sockaddr_bt *);
177 nam->m_len = sizeof(struct sockaddr_bt);
178 return sco_peeraddr(pcb, sa);
179
180 case PRU_SOCKADDR:
181 KASSERT(nam != NULL);
182 sa = mtod(nam, struct sockaddr_bt *);
183 nam->m_len = sizeof(struct sockaddr_bt);
184 return sco_sockaddr(pcb, sa);
185
186 case PRU_SHUTDOWN:
187 socantsendmore(up);
188 break;
189
190 case PRU_SEND:
191 KASSERT(m != NULL);
192 if (m->m_pkthdr.len == 0)
193 break;
194
195 if (m->m_pkthdr.len > pcb->sp_mtu) {
196 err = EMSGSIZE;
197 break;
198 }
199
200 m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
201 if (m0 == NULL) {
202 err = ENOMEM;
203 break;
204 }
205
206 if (ctl)
207 m_freem(ctl);
208
209 sbappendrecord(&up->so_snd, m);
210 return sco_send(pcb, m0);
211
212 case PRU_SENSE:
213 return 0;
214
215 case PRU_RCVD:
216 case PRU_RCVOOB:
217 return EOPNOTSUPP;
218
219 case PRU_LISTEN:
220 return sco_listen(pcb);
221
222 case PRU_ACCEPT:
223 KASSERT(nam != NULL);
224 sa = mtod(nam, struct sockaddr_bt *);
225 nam->m_len = sizeof(struct sockaddr_bt);
226 return sco_peeraddr(pcb, sa);
227
228 case PRU_CONNECT2:
229 case PRU_SENDOOB:
230 case PRU_FASTTIMO:
231 case PRU_SLOWTIMO:
232 case PRU_PROTORCV:
233 case PRU_PROTOSEND:
234 err = EOPNOTSUPP;
235 break;
236
237 default:
238 UNKNOWN(req);
239 err = EOPNOTSUPP;
240 break;
241 }
242
243 release:
244 if (m) m_freem(m);
245 if (ctl) m_freem(ctl);
246 return err;
247 }
248
249
250
251
252 int
253 sco_ctloutput(int req, struct socket *so, int level,
254 int optname, struct mbuf **opt)
255 {
256 struct sco_pcb *pcb = (struct sco_pcb *)so->so_pcb;
257 struct mbuf *m;
258 int err = 0;
259
260 #ifdef notyet
261 DPRINTFN(2, "req %s\n", prcorequests[req]);
262 #endif
263
264 if (pcb == NULL)
265 return EINVAL;
266
267 if (level != BTPROTO_SCO)
268 return ENOPROTOOPT;
269
270 switch(req) {
271 case PRCO_GETOPT:
272 m = m_get(M_WAIT, MT_SOOPTS);
273 m->m_len = sco_getopt(pcb, optname, mtod(m, uint8_t *));
274 if (m->m_len == 0) {
275 m_freem(m);
276 m = NULL;
277 err = ENOPROTOOPT;
278 }
279 *opt = m;
280 break;
281
282 case PRCO_SETOPT:
283 m = *opt;
284 KASSERT(m != NULL);
285 err = sco_setopt(pcb, optname, mtod(m, uint8_t *));
286 m_freem(m);
287 break;
288
289 default:
290 err = ENOPROTOOPT;
291 break;
292 }
293
294 return err;
295 }
296
297
298
299
300
301
302 static void
303 sco_connecting(void *arg)
304 {
305 struct socket *so = arg;
306
307 DPRINTF("Connecting\n");
308 soisconnecting(so);
309 }
310
311 static void
312 sco_connected(void *arg)
313 {
314 struct socket *so = arg;
315
316 DPRINTF("Connected\n");
317 soisconnected(so);
318 }
319
320 static void
321 sco_disconnected(void *arg, int err)
322 {
323 struct socket *so = arg;
324
325 DPRINTF("Disconnected (%d)\n", err);
326
327 so->so_error = err;
328 soisdisconnected(so);
329 }
330
331 static void *
332 sco_newconn(void *arg, struct sockaddr_bt *laddr,
333 struct sockaddr_bt *raddr)
334 {
335 struct socket *so = arg;
336
337 DPRINTF("New Connection\n");
338 so = sonewconn(so, 0);
339 if (so == NULL)
340 return NULL;
341
342 soisconnecting(so);
343 return so->so_pcb;
344 }
345
346 static void
347 sco_complete(void *arg, int num)
348 {
349 struct socket *so = arg;
350
351 while (num-- > 0)
352 sbdroprecord(&so->so_snd);
353
354 sowwakeup(so);
355 }
356
357 static void
358 sco_linkmode(void *arg, int mode)
359 {
360 }
361
362 static void
363 sco_input(void *arg, struct mbuf *m)
364 {
365 struct socket *so = arg;
366
367
368
369
370
371
372
373 while (m->m_pkthdr.len > sbspace(&so->so_rcv))
374 sbdroprecord(&so->so_rcv);
375
376 DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len);
377
378 sbappendrecord(&so->so_rcv, m);
379 sorwakeup(so);
380 }