예제 #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;
}
예제 #2
0
static guint bluetooth_listen(void)
{
	GIOChannel *io;
	guint id;
	GError *err = NULL;

	if (option_channel == -1) {
		g_printerr("Bluetooth channel not set\n");
		return 0;
	}

	if (option_packet || option_channel > 31)
		io = l2cap_listen(&err);
	else
		io = rfcomm_listen(&err);

	if (io == NULL) {
		g_printerr("%s\n", err->message);
		g_error_free(err);
		return 0;
	}

	g_print("Bluetooth socket created\n");

	id = g_io_add_watch(io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
							bluetooth_watch, NULL);

	g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
	g_io_channel_set_close_on_unref(io, TRUE);
	g_io_channel_unref(io);

	return id;
}
예제 #3
0
파일: btiotest.c 프로젝트: ghent360/bluez
int main(int argc, char *argv[])
{
	GOptionContext *context;

	context = g_option_context_new(NULL);
	g_option_context_add_main_entries(context, options, NULL);

	if (!g_option_context_parse(context, &argc, &argv, NULL))
		exit(EXIT_FAILURE);

	g_option_context_free(context);

	printf("accept=%d reject=%d discon=%d defer=%d sec=%d update_sec=%d"
		" prio=%d voice=0x%04x\n", opt_accept, opt_reject, opt_disconn,
		opt_defer, opt_sec, opt_update_sec, opt_priority, opt_voice);

	if (opt_psm || opt_cid) {
		if (argc > 1)
			l2cap_connect(opt_dev, argv[1], opt_addr_type,
					opt_psm, opt_cid, opt_disconn,
					opt_sec, opt_priority);
		else
			l2cap_listen(opt_dev, opt_addr_type, opt_psm, opt_cid,
					opt_defer, opt_reject, opt_disconn,
					opt_accept, opt_sec, opt_master);
	}

	if (opt_channel != -1) {
		if (argc > 1)
			rfcomm_connect(opt_dev, argv[1], opt_channel,
							opt_disconn, opt_sec);
		else
			rfcomm_listen(opt_dev, opt_channel, opt_defer,
					opt_reject, opt_disconn, opt_accept,
					opt_sec, opt_master);
	}

	if (opt_sco) {
		if (argc > 1)
			sco_connect(opt_dev, argv[1], opt_disconn, opt_voice);
		else
			sco_listen(opt_dev, opt_defer, opt_reject,
					opt_disconn, opt_accept, opt_voice);
	}

	signal(SIGTERM, sig_term);
	signal(SIGINT, sig_term);

	main_loop = g_main_loop_new(NULL, FALSE);

	g_main_loop_run(main_loop);

	g_main_loop_unref(main_loop);

	printf("Exiting\n");

	exit(EXIT_SUCCESS);
}
예제 #4
0
int main(int argc, char *argv[])
{
	int ctrl_fd, data_fd;
	int client_ctrl, client_data;
	int server_ctrl, server_data;
	char* bdaddr;
	fd_set read_set;
	unsigned char buf[1024];
	ssize_t len;
	int fd_max = 0;
  struct timeval tv;

  (void) signal(SIGINT, terminate);

	/* Check args */
	if (argc >= 1)
		bdaddr = argv[1];

	if (bachk(bdaddr) == -1) {
		printf("usage: %s <ps3-mac-address>\n", *argv);
		return 1;
	}

	if(write_device_class(0, 0x508) < 0)
	{
    printf("failed to set device class\n");
    return 1;
	}

	ctrl_fd = l2cap_listen(CTRL);
	client_ctrl = l2cap_accept(ctrl_fd);

	data_fd = l2cap_listen(DATA);
	client_data = l2cap_accept(data_fd);

	server_ctrl = l2cap_connect(bdaddr, CTRL);
	server_data = l2cap_connect(bdaddr, DATA);

	if(client_ctrl > fd_max)
	{
	  fd_max = client_ctrl;
	}

  if(client_data > fd_max)
  {
    fd_max = client_data;
  }

  if(server_ctrl > fd_max)
  {
    fd_max = server_ctrl;
  }

  if(server_data > fd_max)
  {
    fd_max = server_data;
  }

	while(!done)
	{
		FD_ZERO(&read_set);
		FD_SET(client_ctrl, &read_set);
		FD_SET(client_data, &read_set);
		FD_SET(server_ctrl, &read_set);
		FD_SET(server_data, &read_set);

		tv.tv_sec = 1;
		tv.tv_usec = 0;

		select(fd_max+1, &read_set, NULL, NULL, &tv);

		if (FD_ISSET(client_ctrl, &read_set))
		{
			len = recv(client_ctrl, buf, 1024, MSG_DONTWAIT);
			if (len > 0)
			{
				send(server_ctrl, buf, len, MSG_DONTWAIT);
				if(debug_ctrl)
				{
          printf("CTRL CLIENT > SERVER\n");
          dump(buf, len);
				}
			}
			else
			{
			  printf("connection error from client (control)\n");
			  done = 1;
			}
		}

		if (FD_ISSET(client_data, &read_set))
		{
			len = recv(client_data, buf, 1024, MSG_DONTWAIT);
			if (len > 0)
			{
				send(server_data, buf, len, MSG_DONTWAIT);
        if(debug_data)
        {
          printf("DATA CLIENT > SERVER\n");
          dump(buf, len);
        }
			}
      else
      {
        printf("connection error from client (data)\n");
        done = 1;
      }
		}

		if (FD_ISSET(server_ctrl, &read_set))
		{
			len = recv(server_ctrl, buf, 1024, MSG_DONTWAIT);
			if (len > 0)
			{
				send(client_ctrl, buf, len, MSG_DONTWAIT);
        if(debug_ctrl)
        {
          printf("CTRL SERVER > CLIENT\n");
          dump(buf, len);
        }
			}
      else
      {
        printf("connection error from server (control)\n");
        done = 1;
      }
		}

		if (FD_ISSET(server_data, &read_set))
		{
			len = recv(server_data, buf, 1024, MSG_DONTWAIT);
			if (len > 0)
			{
				send(client_data, buf, len, MSG_DONTWAIT);
        if(debug_data)
        {
          printf("DATA SERVER > CLIENT\n");
          dump(buf, len);
        }
			}
      else
      {
        printf("connection error from server (data)\n");
        done = 1;
      }
		}
	}

  close(server_data);
  printf("%s\n", strerror(errno));
  close(server_ctrl);
  printf("%s\n", strerror(errno));

  close(client_data);
  printf("%s\n", strerror(errno));
  close(client_ctrl);
  printf("%s\n", strerror(errno));

  close(data_fd);
  close(ctrl_fd);

	return 0;
}
예제 #5
0
int main(int argc, char *argv[])
{
    struct sigaction sa;
    bdaddr_t bdaddr = { 0 };
    int ctl, csk, isk, debug, legacy, remote;

    if (argc > 3) {
      debug = atoi(argv[1]);
      legacy = atoi(argv[2]);
      remote = atoi(argv[3]);
    } else {
      std::cerr << argv[0] << " requires 'sixad'. Please run sixad instead" << std::endl;
      return 1;
    }


#if 0
    // Enable all bluetooth adapters
    int hci_ctl;
    if ((hci_ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) >= 0) {
      for (int i=0; i < 4; i++)
      {
        di.dev_id = i;
        if (ioctl(hci_ctl, HCIGETDEVINFO, (void *) &di) == 0)
        {
          if (hci_test_bit(HCI_RAW, &di.flags) && !bacmp(&di.bdaddr, BDADDR_ANY)) {
            int dd = hci_open_dev(di.dev_id);
            hci_read_bd_addr(dd, &di.bdaddr, 1000);
            hci_close_dev(dd);
          }
        }
        cmd_reset(hci_ctl, di.dev_id);
      }
    }
#endif

    open_log("sixad-bin");
    syslog(LOG_INFO, "started");

    ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
    if (ctl < 0) {
        syslog(LOG_ERR, "Can't open HIDP control socket");
        close(ctl);
        return 1;
    }

    if (remote) {
        // BD Remote only

        syslog(LOG_INFO, "BD Remote mode active, hold Enter+Start on your remote now");

        while (!io_canceled()) {
            do_search(ctl, &bdaddr, debug);
            sleep(2);
        }

    } else {
        // Normal behaviour

        csk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_CTRL, L2CAP_LM_MASTER, 10);
        if (csk < 0) {
            syslog(LOG_ERR, "Can't listen on HID control channel");
            close(csk);
            close(ctl);
            return 1;
        }

        isk = l2cap_listen(&bdaddr, L2CAP_PSM_HIDP_INTR, L2CAP_LM_MASTER, 10);
        if (isk < 0) {
            syslog(LOG_ERR, "Can't listen on HID interrupt channel");
            close(isk);
            close(csk);
            close(ctl);
            return 1;
        }

        memset(&sa, 0, sizeof(sa));
        sa.sa_flags = SA_NOCLDSTOP;

        sa.sa_handler = sig_term;
        sigaction(SIGTERM, &sa, NULL);
        sigaction(SIGINT, &sa, NULL);
        sa.sa_handler = sig_hup;
        sigaction(SIGHUP, &sa, NULL);

        sa.sa_handler = SIG_IGN;
        sigaction(SIGCHLD, &sa, NULL);
        sigaction(SIGPIPE, &sa, NULL);

        syslog(LOG_INFO, "sixad started, press the PS button now");

        hid_server(ctl, csk, isk, debug, legacy);

        close(isk);
        close(csk);
    }

    close(ctl);
    syslog(LOG_INFO, "Done");

    return 0;
}
예제 #6
0
/*
 * User Request.
 * up is socket
 * m is either
 *	optional mbuf chain containing message
 *	ioctl command (PRU_CONTROL)
 * nam is either
 *	optional mbuf chain containing an address
 *	ioctl data (PRU_CONTROL)
 *	optionally protocol number (PRU_ATTACH)
 *	message flags (PRU_RCVD)
 * ctl is either
 *	optional mbuf chain containing socket options
 *	optional interface pointer (PRU_CONTROL, PRU_PURGEIF)
 * l is pointer to process requesting action (if any)
 *
 * we are responsible for disposing of m and ctl if
 * they are mbuf chains
 */
int
l2cap_usrreq(struct socket *up, int req, struct mbuf *m,
    struct mbuf *nam, struct mbuf *ctl, struct proc *p)
{
	struct l2cap_channel *pcb = up->so_pcb;
	struct sockaddr_bt *sa;
	struct mbuf *m0;
	int err = 0;

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

	switch (req) {
	case PRU_CONTROL:
		return EPASSTHROUGH;

#ifdef notyet			/* XXX */
	case PRU_PURGEIF:
		return EOPNOTSUPP;
#endif

	case PRU_ATTACH:
		/* XXX solock() and bt_lock fiddling in NetBSD */
		if (pcb != NULL)
			return EINVAL;
		/*
		 * For L2CAP socket PCB we just use an l2cap_channel structure
		 * since we have nothing to add..
		 */
		err = soreserve(up, l2cap_sendspace, l2cap_recvspace);
		if (err)
			return err;

		return l2cap_attach((struct l2cap_channel **)&up->so_pcb,
					&l2cap_proto, up);
	}

	if (pcb == NULL) {
		err = EINVAL;
		goto release;
	}

	switch(req) {
	case PRU_DISCONNECT:
		soisdisconnecting(up);
		return l2cap_disconnect(pcb, up->so_linger);

	case PRU_ABORT:
		l2cap_disconnect(pcb, 0);
		soisdisconnected(up);
		/* fall through to */
	case PRU_DETACH:
		return l2cap_detach((struct l2cap_channel **)&up->so_pcb);

	case PRU_BIND:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		return l2cap_bind(pcb, sa);

	case PRU_CONNECT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);

		if (sa->bt_len != sizeof(struct sockaddr_bt))
			return EINVAL;

		if (sa->bt_family != AF_BLUETOOTH)
			return EAFNOSUPPORT;

		soisconnecting(up);
		return l2cap_connect(pcb, sa);

	case PRU_PEERADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return l2cap_peeraddr(pcb, sa);

	case PRU_SOCKADDR:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return l2cap_sockaddr(pcb, sa);

	case PRU_SHUTDOWN:
		socantsendmore(up);
		break;

	case PRU_SEND:
		KASSERT(m != NULL);
		if (m->m_pkthdr.len == 0)
			break;

		if (m->m_pkthdr.len > pcb->lc_omtu) {
			err = EMSGSIZE;
			break;
		}

		m0 = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
		if (m0 == NULL) {
			err = ENOMEM;
			break;
		}

		if (ctl)	/* no use for that */
			m_freem(ctl);

		sbappendrecord(&up->so_snd, m);
		return l2cap_send(pcb, m0);

	case PRU_SENSE:
		return 0;		/* (no release) */

	case PRU_RCVD:
	case PRU_RCVOOB:
		return EOPNOTSUPP;	/* (no release) */

	case PRU_LISTEN:
		return l2cap_listen(pcb);

	case PRU_ACCEPT:
		KASSERT(nam != NULL);
		sa = mtod(nam, struct sockaddr_bt *);
		nam->m_len = sizeof(struct sockaddr_bt);
		return l2cap_peeraddr(pcb, sa);

	case PRU_CONNECT2:
	case PRU_SENDOOB:
	case PRU_FASTTIMO:
	case PRU_SLOWTIMO:
	case PRU_PROTORCV:
	case PRU_PROTOSEND:
		err = EOPNOTSUPP;
		break;

	default:
		UNKNOWN(req);
		err = EOPNOTSUPP;
		break;
	}

release:
	if (m) m_freem(m);
	if (ctl) m_freem(ctl);
	return err;
}