Bluetooth fixes by Iain Hibbert:

- Enable listening and incoming connections for SCO links.
This commit is contained in:
tron 2006-07-26 10:20:56 +00:00
parent 1b42d7e7dc
commit b504a17332
3 changed files with 86 additions and 12 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: hci_link.c,v 1.2 2006/07/26 10:10:06 tron Exp $ */
/* $NetBSD: hci_link.c,v 1.3 2006/07/26 10:20:56 tron Exp $ */
/*-
* Copyright (c) 2005 Iain Hibbert.
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.2 2006/07/26 10:10:06 tron Exp $");
__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.3 2006/07/26 10:20:56 tron Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -159,15 +159,24 @@ hci_acl_close(struct hci_link *link, int err)
}
/*
* Incoming ACL connection. For now, we accept all connections but it
* would be better to check the L2CAP listen list and only accept when
* there is a listener available.
* Incoming ACL connection.
*
* For now, we accept all connections but it would be better to check
* the L2CAP listen list and only accept when there is a listener
* available.
*
* There should not be a link to the same bdaddr already, we check
* anyway though its left unhandled for now.
*/
struct hci_link *
hci_acl_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
{
struct hci_link *link;
link = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
if (link != NULL)
return NULL;
link = hci_link_alloc(unit);
if (link != NULL) {
link->hl_state = HCI_LINK_WAIT_CONNECT;
@ -565,11 +574,68 @@ hci_acl_complete(struct hci_link *link, int num)
*/
/*
* Incoming SCO Connection. Not yet implemented
* Incoming SCO Connection. We check the list for anybody willing
* to take it.
*/
struct hci_link *
hci_sco_newconn(struct hci_unit *unit, bdaddr_t *bdaddr)
{
struct sockaddr_bt laddr, raddr;
struct sco_pcb *pcb, *new;
struct hci_link *sco, *acl;
memset(&laddr, 0, sizeof(laddr));
laddr.bt_len = sizeof(laddr);
laddr.bt_family = AF_BLUETOOTH;
bdaddr_copy(&laddr.bt_bdaddr, &unit->hci_bdaddr);
memset(&raddr, 0, sizeof(raddr));
raddr.bt_len = sizeof(raddr);
raddr.bt_family = AF_BLUETOOTH;
bdaddr_copy(&raddr.bt_bdaddr, bdaddr);
/*
* There should already be an ACL link up and running before
* the controller sends us SCO connection requests, but you
* never know..
*/
acl = hci_link_lookup_bdaddr(unit, bdaddr, HCI_LINK_ACL);
if (acl == NULL || acl->hl_state != HCI_LINK_OPEN)
return NULL;
LIST_FOREACH(pcb, &sco_pcb, sp_next) {
if ((pcb->sp_flags & SP_LISTENING) == 0)
continue;
new = (*pcb->sp_proto->newconn)(pcb->sp_upper, &laddr, &raddr);
if (new == NULL)
continue;
/*
* Ok, got new pcb so we can start a new link and fill
* in all the details.
*/
bdaddr_copy(&new->sp_laddr, &unit->hci_bdaddr);
bdaddr_copy(&new->sp_raddr, bdaddr);
sco = hci_link_alloc(unit);
if (sco == NULL) {
sco_detach(&new);
return NULL;
}
sco->hl_type = HCI_LINK_SCO;
bdaddr_copy(&sco->hl_bdaddr, bdaddr);
sco->hl_link = hci_acl_open(unit, bdaddr);
KASSERT(sco->hl_link == acl);
sco->hl_sco = new;
new->sp_link = sco;
new->sp_mtu = unit->hci_max_sco_size;
return sco;
}
return NULL;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sco.h,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */
/* $NetBSD: sco.h,v 1.2 2006/07/26 10:20:56 tron Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@ -54,6 +54,7 @@ struct sco_pcb {
};
LIST_HEAD(sco_pcb_list, sco_pcb);
extern struct sco_pcb_list sco_pcb;
/* sp_flags */
#define SP_LISTENING (1<<0) /* is listening pcb */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sco_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $ */
/* $NetBSD: sco_socket.c,v 1.2 2006/07/26 10:20:56 tron Exp $ */
/*-
* Copyright (c) 2006 Itronix Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.1 2006/06/19 15:44:45 gdamore Exp $");
__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.2 2006/07/26 10:20:56 tron Exp $");
#include <sys/param.h>
#include <sys/domain.h>
@ -204,6 +204,9 @@ sco_usrreq(struct socket *up, int req, struct mbuf *m,
case PRU_RCVOOB:
return EOPNOTSUPP; /* (no release) */
case PRU_LISTEN:
return sco_listen(pcb);
case PRU_ACCEPT:
KASSERT(nam);
sa = mtod(nam, struct sockaddr_bt *);
@ -211,7 +214,6 @@ sco_usrreq(struct socket *up, int req, struct mbuf *m,
return sco_peeraddr(pcb, sa);
case PRU_CONNECT2:
case PRU_LISTEN:
case PRU_SENDOOB:
case PRU_FASTTIMO:
case PRU_SLOWTIMO:
@ -315,10 +317,15 @@ sco_disconnected(void *arg, int err)
static void *
sco_newconn(void *arg, struct sockaddr_bt *laddr, struct sockaddr_bt *raddr)
{
// struct socket *so = arg;
struct socket *so = arg;
DPRINTF("New Connection");
so = sonewconn(so, 0);
if (so == NULL)
return NULL;
soisconnecting(so);
return so->so_pcb;
}
static void