Beispiel #1
0
static void process_remote(struct device_settings settings, const char *mac, int modes)
{
    int br;
    bool msg = true;
    unsigned char buf[128];

    int last_time_action = get_time();

    while (!io_canceled()) {
        br = read(isk, buf, sizeof(buf));
        if (msg) {
            syslog(LOG_INFO, "Connected 'PLAYSTATION(R)3 Remote (%s)'", mac);
            msg = false;
        }

        if (settings.timeout.enabled) {
            int current_time = get_time();
            if (was_active()) {
                last_time_action = current_time;
                set_active(false);
            } else if (current_time-last_time_action >= settings.timeout.timeout) {
                syslog(LOG_INFO, "Remote was not in use, and timeout reached, disconneting...");
                sig_term(0);
                break;
            }
        }

        if (br < 0) {
            break;
        } else if (br==13 && buf[0]==0xa1 && buf[1]==0x01) { //only continue if we've got a Remote
            if (settings.joystick.enabled) do_joystick(ufd->js, buf, settings.joystick);
            if (settings.remote.enabled) do_remote(ufd->mk, buf, modes);
            if (settings.input.enabled) do_input(ufd->mk, buf, settings.input);
        } else {
            if (debug) syslog(LOG_ERR, "Non-Remote packet received and ignored (0x%02x|0x%02x|0x%02x)", buf[0], buf[1], buf[2]);
        }
    }

    if (debug) syslog(LOG_ERR, "Read loop was broken on the Remote process");
}
Beispiel #2
0
int main(int argc, char *argv[])
{
    struct pollfd p[3];
    struct timespec timeout;
    struct device_settings settings;
    struct sigaction sa;
    sigset_t sigs;
    short events;

    if (argc < 3) {
        std::cout << "Running " << argv[0] << " requires 'sixad'. Please run sixad instead" << std::endl;
        return 1;
    }

    const char *mac = argv[1];
    debug = atoi(argv[2]);

    open_log("sixad-remote");
    settings = init_values(mac);
    settings.joystick.axis = false;
    settings.joystick.sbuttons = false;
    settings.joystick.accel = false;
    settings.joystick.speed = false;
    settings.joystick.pos = false;;
    settings.led.enabled = false;
    settings.rumble.enabled = false;

    ufd = uinput_open(DEV_TYPE_REMOTE, mac, settings);

    if (ufd->js < 0 || ufd->mk < 0) {
        return 1;
    } else if (ufd->js == 0 && ufd->mk == 0) {
        syslog(LOG_ERR, "remote config has no joystick or input mode selected - please choose one!");
        return 1;
    }

    int modes = 0;
    if (settings.remote.numeric) modes |= REMOTE_KEYMODE_NUMBERIC;
    if (settings.remote.dvd) modes |= REMOTE_KEYMODE_DVD;
    if (settings.remote.directional) modes |= REMOTE_KEYMODE_DIRECTIONAL;
    if (settings.remote.multimedia) modes |= REMOTE_KEYMODE_MULTIMEDIA;

    sigfillset(&sigs);
//    sigdelset(&sigs, SIGCHLD);
//    sigdelset(&sigs, SIGPIPE);
//    sigdelset(&sigs, SIGTERM);
//    sigdelset(&sigs, SIGINT);
//    sigdelset(&sigs, SIGHUP);

    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_IGN;
    sigaction(SIGCHLD, &sa, NULL);
    sigaction(SIGPIPE, &sa, NULL);

    if (debug) syslog(LOG_INFO, "Press any to activate");

    p[0].fd = 0;
    p[0].events = POLLIN | POLLERR | POLLHUP;

    p[1].fd = 1;
    p[1].events = POLLIN | POLLERR | POLLHUP;

    p[2].fd = ufd->mk ? ufd->mk : ufd->js;
    p[2].events = POLLIN | POLLERR | POLLHUP;

    while (!io_canceled()) {
        int i, idx = 3;
        for (i = 0; i < idx; i++)
            p[i].revents = 0;

        timeout.tv_sec = 1;
        timeout.tv_nsec = 0;

        if (ppoll(p, idx, &timeout, &sigs) < 1)
            continue;

        if (p[1].revents & POLLIN) {
            process_remote(settings, mac, modes);
        }

        events = p[0].revents | p[1].revents | p[2].revents;

        if (events & (POLLERR | POLLHUP)) {
            break;
        }
    }

    if (debug) syslog(LOG_INFO, "Closing uinput...");

    if (settings.joystick.enabled) {
        uinput_close(ufd->js, debug);
    }
    if (settings.remote.enabled || settings.input.enabled) {
        uinput_close(ufd->mk, debug);
    }
    
    delete ufd;

    shutdown(isk, SHUT_RDWR);
    shutdown(csk, SHUT_RDWR);

    if (debug) syslog(LOG_INFO, "Done");

    return 0;
}
Beispiel #3
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;
}