/* * 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; }
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; }
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); }
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; }
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; }
/* * 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; }