Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
/*
 * \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);
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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;
}