Exemplo n.º 1
0
/*
 * get/set socket options
 */
int
sco_ctloutput(int req, struct socket *so, struct sockopt *sopt)
{
	struct sco_pcb *pcb = (struct sco_pcb *)so->so_pcb;
	int err = 0;

	DPRINTFN(2, "req %s\n", prcorequests[req]);

	if (pcb == NULL)
		return EINVAL;

	if (sopt->sopt_level != BTPROTO_SCO)
		return ENOPROTOOPT;

	switch(req) {
	case PRCO_GETOPT:
		err = sco_getopt(pcb, sopt);
		break;

	case PRCO_SETOPT:
		err = sco_setopt(pcb, sopt);
		break;

	default:
		err = ENOPROTOOPT;
		break;
	}

	return err;
}
Exemplo n.º 2
0
static int
btsco_open(void *hdl, int flags)
{
	struct sockaddr_bt sa;
	struct btsco_softc *sc = hdl;
	struct sockopt sopt;
	int err, timo;

	DPRINTF("%s flags 0x%x\n", sc->sc_name, flags);
	/* flags FREAD & FWRITE? */

	if (sc->sc_sco != NULL || sc->sc_sco_l != NULL)
		return EIO;

	KASSERT(mutex_owned(bt_lock));

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

	if (sc->sc_flags & BTSCO_LISTEN) {
		err = sco_attach_pcb(&sc->sc_sco_l, &btsco_sco_proto, sc);
		if (err)
			goto done;

		err = sco_bind_pcb(sc->sc_sco_l, &sa);
		if (err) {
			sco_detach_pcb(&sc->sc_sco_l);
			goto done;
		}

		err = sco_listen_pcb(sc->sc_sco_l);
		if (err) {
			sco_detach_pcb(&sc->sc_sco_l);
			goto done;
		}

		timo = 0;	/* no timeout */
	} else {
		err = sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc);
		if (err)
			goto done;

		err = sco_bind_pcb(sc->sc_sco, &sa);
		if (err) {
			sco_detach_pcb(&sc->sc_sco);
			goto done;
		}

		bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
		err = sco_connect_pcb(sc->sc_sco, &sa);
		if (err) {
			sco_detach_pcb(&sc->sc_sco);
			goto done;
		}

		timo = BTSCO_TIMEOUT;
	}

	sc->sc_state = BTSCO_WAIT_CONNECT;
	while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT)
		err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo);

	switch (sc->sc_state) {
	case BTSCO_CLOSED:		/* disconnected */
		err = sc->sc_err;

		/* fall through to */
	case BTSCO_WAIT_CONNECT:	/* error */
		if (sc->sc_sco != NULL)
			sco_detach_pcb(&sc->sc_sco);

		if (sc->sc_sco_l != NULL)
			sco_detach_pcb(&sc->sc_sco_l);

		break;

	case BTSCO_OPEN:		/* hurrah */
		sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0);
		(void)sco_getopt(sc->sc_sco, &sopt);
		(void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu));
		sockopt_destroy(&sopt);
		break;

	default:
		UNKNOWN(sc->sc_state);
		break;
	}

done:
	DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n",
			err, sc->sc_state, sc->sc_mtu);
	return err;
}