int main(int argc, char *argv[]) { bdaddr_t src, dst; int opt, sk, dev_id; if (argc < 2) { usage(); exit(0); } bacpy(&src, BDADDR_ANY); dev_id = hci_get_route(&src); if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) { printf("Cannot find any local adapter\n"); exit(-1); } while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) { switch (opt) { case 'i': if (!strncmp(optarg, "hci", 3)) hci_devba(atoi(optarg + 3), &src); else str2ba(optarg, &src); break; case 'h': default: usage(); exit(0); } } printf("Connecting ... \n"); if (bachk(argv[optind]) < 0) { printf("Invalid argument\n"); exit(1); } str2ba(argv[optind], &dst); sk = l2cap_connect(&src, &dst); if (sk < 0) exit(1); if (avdtp_discover(sk) < 0) exit(1); return 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); }
/* * start connecting to our device */ int bthidev_connect(struct bthidev_softc *sc) { struct sockaddr_bt sa; int err; if (sc->sc_attempts++ > 0) printf("%s: connect (#%d)\n", sc->sc_btdev.sc_dev.dv_xname, sc->sc_attempts); memset(&sa, 0, sizeof(sa)); sa.bt_len = sizeof(sa); sa.bt_family = AF_BLUETOOTH; err = l2cap_attach(&sc->sc_ctl, &bthidev_ctl_proto, sc); if (err) { printf("%s: l2cap_attach failed (%d)\n", sc->sc_btdev.sc_dev.dv_xname, err); return err; } err = l2cap_setlinkmode(sc->sc_ctl, sc->sc_mode); if (err) return err; bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); err = l2cap_bind(sc->sc_ctl, &sa); if (err) { printf("%s: l2cap_bind failed (%d)\n", sc->sc_btdev.sc_dev.dv_xname, err); return err; } sa.bt_psm = sc->sc_ctlpsm; bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); err = l2cap_connect(sc->sc_ctl, &sa); if (err) { printf("%s: l2cap_connect failed (%d)\n", sc->sc_btdev.sc_dev.dv_xname, err); return err; } sc->sc_state = BTHID_WAIT_CTL; return 0; }
int avdtp_connect(avdtp_t *avdtp, bdaddr_t *bdaddr, uint8_t seid) { struct avdtp_session *session; int sk; if (!avdtp) return -EIO; session = avdtp; bacpy(&session->dst, bdaddr); sk = l2cap_connect(&session->src, &session->dst, AVDTP_PSM, NULL); if (sk < 0) return -EIO; session->ssk = sk; return 0; }
static GIOChannel *bluetooth_connect(GObexTransportType transport) { GIOChannel *io; GError *err = NULL; if (option_dest == NULL || option_channel < 0) return NULL; if (option_channel > 31) io = l2cap_connect(transport, &err); else io = rfcomm_connect(transport, &err); if (io != NULL) return io; g_printerr("%s\n", err->message); g_error_free(err); return NULL; }
/* * 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(&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) return err; bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); err = l2cap_bind(sc->sc_ctl, &sa); if (err) { aprint_error_dev(sc->sc_dev, "l2cap_bind failed (%d)\n", err); return err; } sa.bt_psm = sc->sc_ctlpsm; bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); err = l2cap_connect(sc->sc_ctl, &sa); if (err) { aprint_error_dev(sc->sc_dev, "l2cap_connect failed (%d)\n", err); return err; } sc->sc_state = BTHID_WAIT_CTL; return 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; }
/* * 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; }