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); }
err_t bt_spp_init(void) { struct l2cap_pcb *l2cappcb; struct rfcomm_pcb *rfcommpcb; struct sdp_record *record; if((l2cappcb = l2cap_new()) == NULL) { LWIP_DEBUGF(BT_SPP_DEBUG, ("bt_spp_init: Could not alloc L2CAP PCB for SDP_PSM\n")); return ERR_MEM; } l2cap_connect_ind(l2cappcb, SDP_PSM, bt_connect_ind); if((l2cappcb = l2cap_new()) == NULL) { LWIP_DEBUGF(BT_SPP_DEBUG, ("bt_spp_init: Could not alloc L2CAP PCB for RFCOMM_PSM\n")); return ERR_MEM; } l2cap_connect_ind(l2cappcb, RFCOMM_PSM, bt_connect_ind); LWIP_DEBUGF(RFCOMM_DEBUG, ("bt_spp_init: Allocate RFCOMM PCB for CN 0\n")); if((rfcommpcb = rfcomm_new(NULL)) == NULL) { LWIP_DEBUGF(BT_SPP_DEBUG, ("bt_spp_init: Could not alloc RFCOMM PCB for channel 0\n")); return ERR_MEM; } rfcomm_listen(rfcommpcb, 0, rfcomm_accept); LWIP_DEBUGF(RFCOMM_DEBUG, ("bt_spp_init: Allocate RFCOMM PCB for CN 1\n")); if((rfcommpcb = rfcomm_new(NULL)) == NULL) { LWIP_DEBUGF(BT_SPP_DEBUG, ("lap_init: Could not alloc RFCOMM PCB for channel 1\n")); return ERR_MEM; } rfcomm_listen(rfcommpcb, 1, rfcomm_accept); if((record = sdp_record_new((u8_t *)spp_service_record, sizeof(spp_service_record))) == NULL) { LWIP_DEBUGF(BT_SPP_DEBUG, ("bt_spp_init: Could not alloc SDP record\n")); return ERR_MEM; } else { sdp_register_service(record); } LWIP_DEBUGF(BT_SPP_DEBUG, ("SPP initialized\n")); return ERR_OK; }
/* * 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 rfcomm_usrreq(struct socket *up, int req, struct mbuf *m, struct mbuf *nam, struct mbuf *ctl, struct lwp *l) { struct rfcomm_dlc *pcb = up->so_pcb; struct sockaddr_bt *sa; struct mbuf *m0; int err = 0; DPRINTFN(2, "%s\n", prurequests[req]); switch (req) { case PRU_CONTROL: return EPASSTHROUGH; case PRU_PURGEIF: return EOPNOTSUPP; case PRU_ATTACH: if (up->so_lock == NULL) { mutex_obj_hold(bt_lock); up->so_lock = bt_lock; solock(up); } KASSERT(solocked(up)); if (pcb != NULL) return EINVAL; /* * Since we have nothing to add, we attach the DLC * structure directly to our PCB pointer. */ err = soreserve(up, rfcomm_sendspace, rfcomm_recvspace); if (err) return err; err = rfcomm_attach((struct rfcomm_dlc **)&up->so_pcb, &rfcomm_proto, up); if (err) return err; err = rfcomm_rcvd(up->so_pcb, sbspace(&up->so_rcv)); if (err) { rfcomm_detach((struct rfcomm_dlc **)&up->so_pcb); return err; } return 0; } if (pcb == NULL) { err = EINVAL; goto release; } switch(req) { case PRU_DISCONNECT: soisdisconnecting(up); return rfcomm_disconnect(pcb, up->so_linger); case PRU_ABORT: rfcomm_disconnect(pcb, 0); soisdisconnected(up); /* fall through to */ case PRU_DETACH: return rfcomm_detach((struct rfcomm_dlc **)&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 rfcomm_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 rfcomm_connect(pcb, sa); case PRU_PEERADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return rfcomm_peeraddr(pcb, sa); case PRU_SOCKADDR: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return rfcomm_sockaddr(pcb, sa); case PRU_SHUTDOWN: socantsendmore(up); break; case PRU_SEND: KASSERT(m != NULL); if (ctl) /* no use for that */ m_freem(ctl); m0 = m_copypacket(m, M_DONTWAIT); if (m0 == NULL) return ENOMEM; sbappendstream(&up->so_snd, m); return rfcomm_send(pcb, m0); case PRU_SENSE: return 0; /* (no release) */ case PRU_RCVD: return rfcomm_rcvd(pcb, sbspace(&up->so_rcv)); case PRU_RCVOOB: return EOPNOTSUPP; /* (no release) */ case PRU_LISTEN: return rfcomm_listen(pcb); case PRU_ACCEPT: KASSERT(nam != NULL); sa = mtod(nam, struct sockaddr_bt *); nam->m_len = sizeof(struct sockaddr_bt); return rfcomm_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; }