Esempio n. 1
0
int os_usbrecv(usbdevice* kb, uchar* in_msg, const char* file, int line){
    DELAY_MEDIUM(kb);
    int res;
    if(kb->fwversion >= 0x130){
        struct usbdevfs_bulktransfer transfer;
        memset(&transfer, 0, sizeof(transfer));
        transfer.ep = 0x84;
        transfer.len = MSG_SIZE;
        transfer.timeout = 5000;
        transfer.data = in_msg;
        res = ioctl(kb->handle, USBDEVFS_BULK, &transfer);
    } else {
        struct usbdevfs_ctrltransfer transfer = { 0xa1, 0x01, 0x0300, 0x03, MSG_SIZE, 5000, in_msg };
        res = ioctl(kb->handle, USBDEVFS_CONTROL, &transfer);
    }
    if(res <= 0){
        if(res == -1 && errno == ETIMEDOUT){
            ckb_warn_fn("%s (continuing)\n", file, line, strerror(errno));
            return -1;
        }
        ckb_err_fn("%s\n", file, line, res ? strerror(errno) : "No data read");
        return 0;
    } else if(res != MSG_SIZE)
        ckb_warn_fn("Read %d bytes (expected %d)\n", file, line, res, MSG_SIZE);
    return res;
}
Esempio n. 2
0
File: usb.c Progetto: gtjoseph/ckb
int _usbrecv(usbdevice* kb, const uchar* out_msg, uchar* in_msg, const char* file, int line){
    // Try a maximum of 3 times
    for(int try = 0; try < 5; try++){
        // Send the output message
        DELAY_SHORT(kb);
        int res = os_usbsend(kb, out_msg, 1, file, line);
        if(res == 0)
            return 0;
        else if(res == -1){
            // Retry on temporary failure
            if(reset_stop)
                return 0;
            DELAY_LONG(kb);
            continue;
        }
        // Wait for the response
        DELAY_MEDIUM(kb);
        res = os_usbrecv(kb, in_msg, file, line);
        if(res == 0)
            return 0;
        else if(res != -1)
            return res;
        if(reset_stop || hwload_mode != 2)
            return 0;
        DELAY_LONG(kb);
    }
    // Give up
    ckb_err_fn("Too many send/recv failures. Dropping.\n", file, line);
    return 0;
}

int closeusb(usbdevice* kb){
    pthread_mutex_lock(imutex(kb));
    if(kb->handle){
        int index = INDEX_OF(kb, keyboard);
        ckb_info("Disconnecting %s%d\n", devpath, index);
        os_inputclose(kb);
        updateconnected();
        // Close USB device
        os_closeusb(kb);
    } else
        updateconnected();
    rmdevpath(kb);

    // Wait for thread to close
    pthread_mutex_unlock(imutex(kb));
    pthread_mutex_unlock(dmutex(kb));
    pthread_join(kb->thread, 0);
    pthread_mutex_lock(dmutex(kb));

    // Delete the profile and the control path
    if(!kb->vtable)
        return 0;
    kb->vtable->freeprofile(kb);
    memset(kb, 0, sizeof(usbdevice));
    return 0;
}