Ejemplo n.º 1
0
/*
 * listen for our device
 */
static int
bthidev_listen(struct bthidev_softc *sc)
{
	struct sockaddr_bt sa;
	int err;

	memset(&sa, 0, sizeof(sa));
	sa.bt_len = sizeof(sa);
	sa.bt_family = AF_BLUETOOTH;
	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);

	/*
	 * Listen on control PSM
	 */
	err = l2cap_attach(&sc->sc_ctl_l, &bthidev_ctl_proto, sc);
	if (err)
		return err;

	err = l2cap_setopt(sc->sc_ctl_l, &sc->sc_mode);
	if (err)
		return err;

	sa.bt_psm = sc->sc_ctlpsm;
	err = l2cap_bind(sc->sc_ctl_l, &sa);
	if (err)
		return err;

	err = l2cap_listen(sc->sc_ctl_l);
	if (err)
		return err;

	/*
	 * Listen on interrupt PSM
	 */
	err = l2cap_attach(&sc->sc_int_l, &bthidev_int_proto, sc);
	if (err)
		return err;

	err = l2cap_setopt(sc->sc_int_l, &sc->sc_mode);
	if (err)
		return err;

	sa.bt_psm = sc->sc_intpsm;
	err = l2cap_bind(sc->sc_int_l, &sa);
	if (err)
		return err;

	err = l2cap_listen(sc->sc_int_l);
	if (err)
		return err;

	sc->sc_state = BTHID_WAIT_CTL;
	return 0;
}
Ejemplo n.º 2
0
static void
bthidev_ctl_connected(void *arg)
{
	struct sockaddr_bt sa;
	struct bthidev_softc *sc = arg;
	int err;

	if (sc->sc_state != BTHID_WAIT_CTL)
		return;

	KASSERT(sc->sc_ctl != NULL);
	KASSERT(sc->sc_int == NULL);

	if (sc->sc_flags & BTHID_CONNECTING) {
		/* initiate connect on interrupt PSM */
		err = l2cap_attach(&sc->sc_int, &bthidev_int_proto, sc);
		if (err)
			goto fail;

		err = l2cap_setopt(sc->sc_int, &sc->sc_mode);
		if (err)
			goto fail;

		memset(&sa, 0, sizeof(sa));
		sa.bt_len = sizeof(sa);
		sa.bt_family = AF_BLUETOOTH;
		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);

		err = l2cap_bind(sc->sc_int, &sa);
		if (err)
			goto fail;

		sa.bt_psm = sc->sc_intpsm;
		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
		err = l2cap_connect(sc->sc_int, &sa);
		if (err)
			goto fail;
	}

	sc->sc_state = BTHID_WAIT_INT;
	return;

fail:
	l2cap_detach(&sc->sc_ctl);
	sc->sc_ctl = NULL;

	aprint_error_dev(sc->sc_dev, "connect failed (%d)\n", err);
}
Ejemplo n.º 3
0
/*
 * l2cap_ctloutput(request, socket, level, optname, opt)
 *
 *	Apply configuration commands to channel. This corresponds to
 *	"Reconfigure Channel Request" in the L2CAP specification.
 */
int
l2cap_ctloutput(int req, struct socket *so, int level,
		int optname, struct mbuf **opt)
{
	struct l2cap_channel *pcb = so->so_pcb;
	struct mbuf *m;
	int err = 0;

#ifdef notyet			/* XXX */
	DPRINTFN(2, "%s\n", prcorequests[req]);
#endif

	if (pcb == NULL)
		return EINVAL;

	if (level != BTPROTO_L2CAP) {
		err = EINVAL;
		if (req == PRCO_SETOPT && *opt)
			m_free(*opt);
	} else switch(req) {
	case PRCO_GETOPT:
		m = m_get(M_WAIT, MT_SOOPTS);
		m->m_len = l2cap_getopt(pcb, optname, mtod(m, void *));
		if (m->m_len == 0) {
			m_freem(m);
			m = NULL;
			err = ENOPROTOOPT;
		}
		*opt = m;
		break;

	case PRCO_SETOPT:
		m = *opt;
		err = l2cap_setopt(pcb, optname, m);
		m_freem(m);
		break;

	default:
		err = ENOPROTOOPT;
		break;
	}

	return err;
}
Ejemplo n.º 4
0
/*
 * start connecting to our device
 */
static int
bthidev_connect(struct bthidev_softc *sc)
{
	struct sockaddr_bt sa;
	int err;

	if (sc->sc_attempts++ > 0)
		aprint_verbose_dev(sc->sc_dev, "connect (#%d)\n", sc->sc_attempts);

	memset(&sa, 0, sizeof(sa));
	sa.bt_len = sizeof(sa);
	sa.bt_family = AF_BLUETOOTH;

	err = l2cap_attach_pcb(&sc->sc_ctl, &bthidev_ctl_proto, sc);
	if (err) {
		aprint_error_dev(sc->sc_dev, "l2cap_attach failed (%d)\n", err);
		return err;
	}

	err = l2cap_setopt(sc->sc_ctl, &sc->sc_mode);
	if (err) {
		aprint_error_dev(sc->sc_dev, "l2cap_setopt failed (%d)\n", err);
		return err;
	}

	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
	err = l2cap_bind_pcb(sc->sc_ctl, &sa);
	if (err) {
		aprint_error_dev(sc->sc_dev, "l2cap_bind_pcb failed (%d)\n", err);
		return err;
	}

	sa.bt_psm = sc->sc_ctlpsm;
	bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
	err = l2cap_connect_pcb(sc->sc_ctl, &sa);
	if (err) {
		aprint_error_dev(sc->sc_dev, "l2cap_connect_pcb failed (%d)\n", err);
		return err;
	}

	sc->sc_state = BTHID_WAIT_CTL;
	return 0;
}