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; }
int os_usbsend(usbdevice* kb, const uchar* out_msg, int is_recv, const char* file, int line){ int res; if(kb->fwversion >= 0x120){ struct usbdevfs_bulktransfer transfer; memset(&transfer, 0, sizeof(transfer)); transfer.ep = (kb->fwversion >= 0x130) ? 4 : 3; transfer.len = MSG_SIZE; transfer.timeout = 5000; transfer.data = (void*)out_msg; res = ioctl(kb->handle, USBDEVFS_BULK, &transfer); } else { struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0300, 0x03, MSG_SIZE, 5000, (void*)out_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 written"); return 0; } else if(res != MSG_SIZE) ckb_warn_fn("Wrote %d bytes (expected %d)\n", file, line, res, MSG_SIZE); return res; }
int os_usbsend(usbdevice* kb, const uchar* out_msg, int is_recv, const char* file, int line){ int res; if(kb->fwversion >= 0x120 && !is_recv){ struct usbdevfs_bulktransfer transfer; memset(&transfer, 0, sizeof(transfer)); transfer.ep = (kb->fwversion >= 0x130 && kb->fwversion < 0x200) ? 4 : 3; transfer.len = MSG_SIZE; transfer.timeout = 5000; transfer.data = (void*)out_msg; res = ioctl(kb->handle - 1, USBDEVFS_BULK, &transfer); } else { struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, kb->epcount - 1, MSG_SIZE, 5000, (void*)out_msg }; res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer); } if(res <= 0){ ckb_err_fn("%s\n", file, line, res ? strerror(errno) : "No data written"); if(res == -1 && errno == ETIMEDOUT) return -1; else return 0; } else if(res != MSG_SIZE) ckb_warn_fn("Wrote %d bytes (expected %d)\n", file, line, res, MSG_SIZE); #ifdef DEBUG_USB char converted[MSG_SIZE*3 + 1]; for(int i=0;i<MSG_SIZE;i++) sprintf(&converted[i*3], "%02x ", out_msg[i]); ckb_warn_fn("Sent %s\n", file, line, converted); #endif return res; }
int os_usbrecv(usbdevice* kb, uchar* in_msg, const char* file, int line){ int res; // This is what CUE does, but it doesn't seem to work on linux. /*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 - 1, USBDEVFS_BULK, &transfer); } else {*/ struct usbdevfs_ctrltransfer transfer = { 0xa1, 0x01, 0x0300, kb->epcount - 1, MSG_SIZE, 5000, in_msg }; res = ioctl(kb->handle - 1, USBDEVFS_CONTROL, &transfer); //} if(res <= 0){ ckb_err_fn("%s\n", file, line, res ? strerror(errno) : "No data read"); if(res == -1 && errno == ETIMEDOUT) return -1; else return 0; } else if(res != MSG_SIZE) ckb_warn_fn("Read %d bytes (expected %d)\n", file, line, res, MSG_SIZE); return res; }
int os_usbrecv(usbdevice* kb, uchar* in_msg, const char* file, int line){ CFIndex length = MSG_SIZE; kern_return_t res = (*kb->handle)->getReport(kb->handle, kIOHIDReportTypeFeature, 0, in_msg, &length, 5000, 0, 0, 0); kb->lastresult = res; if(IS_TEMP_FAILURE(res)){ ckb_warn_fn("Got return value 0x%x (continuing)\n", file, line, res); return -1; } else if(res != kIOReturnSuccess){ ckb_err_fn("Got return value 0x%x\n", file, line, res); return 0; } if(length != MSG_SIZE) ckb_err_fn("Read %d bytes (expected %d)\n", file, line, (int)length, MSG_SIZE); return length; }
int os_usbsend(usbdevice* kb, const uchar* out_msg, int is_recv, const char* file, int line){ // Firmware versions above 1.20 use Output instead of Feature reports for improved performance // It doesn't work well when receiving data, however (Not sure why...linux doesn't have that problem) IOHIDReportType type = (kb->fwversion >= 0x120 && !is_recv ? kIOHIDReportTypeOutput : kIOHIDReportTypeFeature); kern_return_t res = (*kb->handle)->setReport(kb->handle, type, 0, out_msg, MSG_SIZE, 5000, 0, 0, 0); kb->lastresult = res; if(IS_TEMP_FAILURE(res)){ ckb_warn_fn("Got return value 0x%x (continuing)\n", file, line, res); return -1; } else if(res != kIOReturnSuccess){ ckb_err_fn("Got return value 0x%x\n", file, line, res); return 0; } return MSG_SIZE; }