static int l2cap_bluez_connect(const char * bdaddr_src, const char * bdaddr_dest, unsigned short psm, int options, int user, L2CAP_ABS_CONNECT_CALLBACK connect_callback, L2CAP_ABS_CLOSE_CALLBACK close_callback) { int fd; struct sockaddr_l2 addr; if(channels.nb == sizeof(channels.channels) / sizeof(*channels.channels)) { fprintf(stderr, "no space left for the l2cap connection (out)\n"); return -1; } if ((fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, BTPROTO_L2CAP)) == -1) { perror("socket"); return -1; } if(l2cap_bluez_setsockopt(fd, options) < 0) { close(fd); return -1; } memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; str2ba(bdaddr_src, &addr.l2_bdaddr); bind(fd, (struct sockaddr *)&addr, sizeof(addr)); memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; addr.l2_psm = htobs(psm); str2ba(bdaddr_dest, &addr.l2_bdaddr); if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { if(errno != EINPROGRESS) { perror("connect"); close(fd); return -1; } } int channel = channels.nb; channels.channels[channel].fd = fd; bacpy(&channels.channels[channel].ba_dst, &addr.l2_bdaddr); channels.channels[channel].psm = psm; channels.channels[channel].user = user; channels.channels[channel].connect_callback = connect_callback; channels.channels[channel].close_callback = close_callback; GE_AddSource(fd, channel, NULL, l2cap_bluez_connect_channel, l2cap_bluez_connect_channel); ++channels.nb; return channel; }
int usb_init(int usb_number, e_controller_type type) { int ret = -1; int dev_i; struct usb_state* state = usb_states+usb_number; if(!controller[type].vendor || !controller[type].product) { gprintf(_("no pass-through device is needed\n")); return 0; } usb_state_indexes[usb_number] = usb_number; memset(state, 0x00, sizeof(*state)); state->joystick_id = -1; state->type = type; state->ack = 1; if(!ctx) { ret = libusb_init(&ctx); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_init: %s.\n", libusb_strerror(ret)); return -1; } } if(!devs) { cnt = libusb_get_device_list(ctx, &devs); if(cnt < 0) { fprintf(stderr, "libusb_get_device_list: %s.\n", libusb_strerror(cnt)); return -1; } } for(dev_i=0; dev_i<cnt; ++dev_i) { struct libusb_device_descriptor desc; ret = libusb_get_device_descriptor(devs[dev_i], &desc); if(!ret) { if(desc.idVendor == controller[type].vendor && desc.idProduct == controller[type].product) { libusb_device_handle* devh; ret = libusb_open(devs[dev_i], &devh); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_open: %s.\n", libusb_strerror(ret)); return -1; } else { ret = libusb_reset_device(devh); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_reset_device: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } #if defined(LIBUSB_API_VERSION) || defined(LIBUSBX_API_VERSION) libusb_set_auto_detach_kernel_driver(devh, 1); #else #ifndef WIN32 ret = libusb_kernel_driver_active(devh, 0); if(ret == 1) { ret = libusb_detach_kernel_driver(devh, 0); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_detach_kernel_driver: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } } else if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_kernel_driver_active: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } #endif #endif int config; ret = libusb_get_configuration(devh, &config); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_get_configuration: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } if(config != controller[state->type].configuration) { ret = libusb_set_configuration(devh, controller[state->type].configuration); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_set_configuration: %s.\n", libusb_strerror(ret)); libusb_close(devh); return -1; } } ret = libusb_claim_interface(devh, controller[state->type].interface); if(ret != LIBUSB_SUCCESS) { fprintf(stderr, "libusb_claim_interface: %s.\n", libusb_strerror(ret)); libusb_close(devh); } else { state->devh = devh; ++nb_opened; #ifndef WIN32 const struct libusb_pollfd** pfd_usb = libusb_get_pollfds(ctx); int poll_i; for (poll_i=0; pfd_usb[poll_i] != NULL; ++poll_i) { GE_AddSource(pfd_usb[poll_i]->fd, usb_number, usb_handle_events, usb_handle_events, usb_close); } free(pfd_usb); #endif if(state->type == C_TYPE_XONE_PAD && adapter_get(usb_number)->status) { //if the authentication was already performed, activate the controller //warning: make sure not to make any libusb async io before this! unsigned char activate[] = { 0x05, 0x20, 0x00, 0x01, 0x00 }; usb_send_interrupt_out_sync(usb_number, activate, sizeof(activate)); unsigned char activate_rumble[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 }; usb_send_interrupt_out_sync(usb_number, activate_rumble, sizeof(activate_rumble)); } // register joystick state->joystick_id = GE_RegisterJoystick(controller[state->type].name, NULL); int i; for(i = 0; i < controller[state->type].endpoints.in.reports.nb; ++i) { usb_states[usb_number].reports[i].report_id = controller[state->type].endpoints.in.reports.elements[i].report_id; } return 0; } } } } } return -1; }
/* * \brief Add a serial port as an event source. * * \param id the instance id */ void serial_add_source(int id) { GE_AddSource(serials[id].fd, id, serial_callback, NULL, serial_close); }
static void l2cap_bluez_add_source(int channel, int user, L2CAP_ABS_READ_CALLBACK read_callback, L2CAP_ABS_PACKET_CALLBACK packet_callback, L2CAP_ABS_CLOSE_CALLBACK close_callback) { channels.channels[channel].user = user; GE_AddSource(channels.channels[channel].fd, channels.channels[channel].user, read_callback, NULL, close_callback); }
static int l2cap_bluez_listen(int user, unsigned short psm, int options, L2CAP_ABS_LISTEN_ACCEPT_CALLBACK read_callback, L2CAP_ABS_CLOSE_CALLBACK close_callback) { struct sockaddr_l2 loc_addr = { 0 }; int fd; if(listen_channels.nb == sizeof(listen_channels.channels) / sizeof(*listen_channels.channels)) { fprintf(stderr, "no space left for listening psm 0x%04x\n", psm); return -1; } // allocate socket if((fd = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) < 0) { perror("socket"); return -1; } l2cap_bluez_setsockopt(fd, options); // bind socket to port psm of the first available // bluetooth adapter loc_addr.l2_family = AF_BLUETOOTH; loc_addr.l2_bdaddr = *BDADDR_ANY; loc_addr.l2_psm = htobs(psm); if(bind(fd, (struct sockaddr *) &loc_addr, sizeof(loc_addr)) < 0) { if(errno == EADDRINUSE) { fprintf(stderr, "bind: Address already device use\n"); fprintf(stderr, "please stop the bluetooth service\n"); } else { perror("bind"); } close(fd); return -1; } // put socket into listening mode if(listen(fd, 10) < 0) { perror("listen"); close(fd); return -1; } int channel = listen_channels.nb; listen_channels.channels[channel].fd = fd; listen_channels.channels[channel].accept_callback = read_callback; listen_channels.channels[channel].close_callback = close_callback; GE_AddSource(listen_channels.channels[channel].fd, channel, l2cap_bluez_connect_accept, NULL, l2cap_bluez_connect_accept); ++listen_channels.nb; gprintf("listening on psm: 0x%04x\n", psm); return channel; }