This source file includes following definitions.
- rfcomm_usrreq
- rfcomm_ctloutput
- rfcomm_connecting
- rfcomm_connected
- rfcomm_disconnected
- rfcomm_newconn
- rfcomm_complete
- rfcomm_linkmode
- rfcomm_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
34
35 #include <sys/cdefs.h>
36
37
38 #ifdef BLUETOOTH_DEBUG
39 #define PRUREQUESTS
40 #define PRCOREQUESTS
41 #endif
42
43 #include <sys/param.h>
44 #include <sys/domain.h>
45 #include <sys/kernel.h>
46 #include <sys/mbuf.h>
47 #include <sys/proc.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/systm.h>
52
53 #include <netbt/bluetooth.h>
54 #include <netbt/hci.h>
55 #include <netbt/rfcomm.h>
56
57
58
59
60
61
62
63 static void rfcomm_connecting(void *);
64 static void rfcomm_connected(void *);
65 static void rfcomm_disconnected(void *, int);
66 static void *rfcomm_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
67 static void rfcomm_complete(void *, int);
68 static void rfcomm_linkmode(void *, int);
69 static void rfcomm_input(void *, struct mbuf *);
70
71 static const struct btproto rfcomm_proto = {
72 rfcomm_connecting,
73 rfcomm_connected,
74 rfcomm_disconnected,
75 rfcomm_newconn,
76 rfcomm_complete,
77 rfcomm_linkmode,
78 rfcomm_input,
79 };
80
81
82 int rfcomm_sendspace = 4096;
83 int rfcomm_recvspace = 4096;
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 int
105 rfcomm_usrreq(struct socket *up, int req, struct mbuf *m,
106 struct mbuf *nam, struct mbuf *ctl)
107 {
108 struct rfcomm_dlc *pcb = up->so_pcb;
109 struct sockaddr_bt *sa;
110 struct mbuf *m0;
111 int err = 0;
112
113 #ifdef notyet
114 DPRINTFN(2, "%s\n", prurequests[req]);
115 #endif
116
117 switch (req) {
118 case PRU_CONTROL:
119 return EPASSTHROUGH;
120
121 #ifdef notyet
122 case PRU_PURGEIF:
123 return EOPNOTSUPP;
124 #endif
125
126 case PRU_ATTACH:
127 if (pcb != NULL)
128 return EINVAL;
129
130
131
132
133
134 err = rfcomm_attach((struct rfcomm_dlc **)&up->so_pcb,
135 &rfcomm_proto, up);
136 if (err)
137 return err;
138
139 err = soreserve(up, rfcomm_sendspace, rfcomm_recvspace);
140 if (err)
141 return err;
142
143 err = rfcomm_rcvd(up->so_pcb, sbspace(&up->so_rcv));
144 if (err)
145 return err;
146
147 return 0;
148 }
149
150 if (pcb == NULL) {
151 err = EINVAL;
152 goto release;
153 }
154
155 switch(req) {
156 case PRU_DISCONNECT:
157 soisdisconnecting(up);
158 return rfcomm_disconnect(pcb, up->so_linger);
159
160 case PRU_ABORT:
161 rfcomm_disconnect(pcb, 0);
162 soisdisconnected(up);
163
164 case PRU_DETACH:
165 return rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb);
166
167 case PRU_BIND:
168 KASSERT(nam != NULL);
169 sa = mtod(nam, struct sockaddr_bt *);
170
171 if (sa->bt_len != sizeof(struct sockaddr_bt))
172 return EINVAL;
173
174 if (sa->bt_family != AF_BLUETOOTH)
175 return EAFNOSUPPORT;
176
177 return rfcomm_bind(pcb, sa);
178
179 case PRU_CONNECT:
180 KASSERT(nam != NULL);
181 sa = mtod(nam, struct sockaddr_bt *);
182
183 if (sa->bt_len != sizeof(struct sockaddr_bt))
184 return EINVAL;
185
186 if (sa->bt_family != AF_BLUETOOTH)
187 return EAFNOSUPPORT;
188
189 soisconnecting(up);
190 return rfcomm_connect(pcb, sa);
191
192 case PRU_PEERADDR:
193 KASSERT(nam != NULL);
194 sa = mtod(nam, struct sockaddr_bt *);
195 nam->m_len = sizeof(struct sockaddr_bt);
196 return rfcomm_peeraddr(pcb, sa);
197
198 case PRU_SOCKADDR:
199 KASSERT(nam != NULL);
200 sa = mtod(nam, struct sockaddr_bt *);
201 nam->m_len = sizeof(struct sockaddr_bt);
202 return rfcomm_sockaddr(pcb, sa);
203
204 case PRU_SHUTDOWN:
205 socantsendmore(up);
206 break;
207
208 case PRU_SEND:
209 KASSERT(m != NULL);
210
211 if (ctl)
212 m_freem(ctl);
213
214 m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
215 if (m0 == NULL)
216 return ENOMEM;
217
218 sbappendstream(&up->so_snd, m);
219
220 return rfcomm_send(pcb, m0);
221
222 case PRU_SENSE:
223 return 0;
224
225 case PRU_RCVD:
226 return rfcomm_rcvd(pcb, sbspace(&up->so_rcv));
227
228 case PRU_RCVOOB:
229 return EOPNOTSUPP;
230
231 case PRU_LISTEN:
232 return rfcomm_listen(pcb);
233
234 case PRU_ACCEPT:
235 KASSERT(nam != NULL);
236 sa = mtod(nam, struct sockaddr_bt *);
237 nam->m_len = sizeof(struct sockaddr_bt);
238 return rfcomm_peeraddr(pcb, sa);
239
240 case PRU_CONNECT2:
241 case PRU_SENDOOB:
242 case PRU_FASTTIMO:
243 case PRU_SLOWTIMO:
244 case PRU_PROTORCV:
245 case PRU_PROTOSEND:
246 err = EOPNOTSUPP;
247 break;
248
249 default:
250 UNKNOWN(req);
251 err = EOPNOTSUPP;
252 break;
253 }
254
255 release:
256 if (m) m_freem(m);
257 if (ctl) m_freem(ctl);
258 return err;
259 }
260
261
262
263
264
265 int
266 rfcomm_ctloutput(int req, struct socket *so, int level,
267 int optname, struct mbuf **opt)
268 {
269 struct rfcomm_dlc *pcb = so->so_pcb;
270 struct mbuf *m;
271 int err = 0;
272
273 #ifdef notyet
274 DPRINTFN(2, "%s\n", prcorequests[req]);
275 #endif
276
277 if (pcb == NULL)
278 return EINVAL;
279
280 if (level != BTPROTO_RFCOMM)
281 return ENOPROTOOPT;
282
283 switch(req) {
284 case PRCO_GETOPT:
285 m = m_get(M_WAIT, MT_SOOPTS);
286 m->m_len = rfcomm_getopt(pcb, optname, mtod(m, void *));
287 if (m->m_len == 0) {
288 m_freem(m);
289 m = NULL;
290 err = ENOPROTOOPT;
291 }
292 *opt = m;
293 break;
294
295 case PRCO_SETOPT:
296 m = *opt;
297 KASSERT(m != NULL);
298 err = rfcomm_setopt(pcb, optname, mtod(m, void *));
299 m_freem(m);
300 break;
301
302 default:
303 err = ENOPROTOOPT;
304 break;
305 }
306
307 return err;
308 }
309
310
311
312
313
314
315 static void
316 rfcomm_connecting(void *arg)
317 {
318
319
320 KASSERT(arg != NULL);
321 DPRINTF("Connecting\n");
322 }
323
324 static void
325 rfcomm_connected(void *arg)
326 {
327 struct socket *so = arg;
328
329 KASSERT(so != NULL);
330 DPRINTF("Connected\n");
331 soisconnected(so);
332 }
333
334 static void
335 rfcomm_disconnected(void *arg, int err)
336 {
337 struct socket *so = arg;
338
339 KASSERT(so != NULL);
340 DPRINTF("Disconnected\n");
341
342 so->so_error = err;
343 soisdisconnected(so);
344 }
345
346 static void *
347 rfcomm_newconn(void *arg, struct sockaddr_bt *laddr,
348 struct sockaddr_bt *raddr)
349 {
350 struct socket *so = arg;
351
352 DPRINTF("New Connection\n");
353 so = sonewconn(so, 0);
354 if (so == NULL)
355 return NULL;
356
357 soisconnecting(so);
358
359 return so->so_pcb;
360 }
361
362
363
364
365
366
367 static void
368 rfcomm_complete(void *arg, int length)
369 {
370 struct socket *so = arg;
371
372 sbdrop(&so->so_snd, length);
373 sowwakeup(so);
374 }
375
376
377
378
379
380
381 static void
382 rfcomm_linkmode(void *arg, int new)
383 {
384 struct socket *so = arg;
385 int mode;
386
387 DPRINTF("auth %s, encrypt %s, secure %s\n",
388 (new & RFCOMM_LM_AUTH ? "on" : "off"),
389 (new & RFCOMM_LM_ENCRYPT ? "on" : "off"),
390 (new & RFCOMM_LM_SECURE ? "on" : "off"));
391
392 (void)rfcomm_getopt(so->so_pcb, SO_RFCOMM_LM, &mode);
393 if (((mode & RFCOMM_LM_AUTH) && !(new & RFCOMM_LM_AUTH))
394 || ((mode & RFCOMM_LM_ENCRYPT) && !(new & RFCOMM_LM_ENCRYPT))
395 || ((mode & RFCOMM_LM_SECURE) && !(new & RFCOMM_LM_SECURE)))
396 rfcomm_disconnect(so->so_pcb, 0);
397 }
398
399
400
401
402 static void
403 rfcomm_input(void *arg, struct mbuf *m)
404 {
405 struct socket *so = arg;
406
407 KASSERT(so != NULL);
408
409 if (m->m_pkthdr.len > sbspace(&so->so_rcv)) {
410 printf("%s: %d bytes dropped (socket buffer full)\n",
411 __func__, m->m_pkthdr.len);
412 m_freem(m);
413 return;
414 }
415
416 DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len);
417
418 sbappendstream(&so->so_rcv, m);
419 sorwakeup(so);
420 }