int hidpp10_request_command(int fd, union hidpp10_message *msg) { union hidpp10_message read_buffer; union hidpp10_message expected_header; union hidpp10_message expected_error_recv = ERROR_MSG(msg, RECEIVER_IDX); union hidpp10_message expected_error_dev = ERROR_MSG(msg, msg->msg.device_idx); int ret; __u8 hidpp_err = 0; /* create the expected header */ expected_header = *msg; switch (msg->msg.sub_id) { case SET_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_SHORT; break; case GET_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_SHORT; break; case SET_LONG_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_LONG; break; case GET_LONG_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_LONG; break; } pr_dbg("sending: "); pr_buffer(msg->data, SHORT_MESSAGE_LENGTH); #if DEBUG_LVL > 1 pr_dbg(" expected_header: "); pr_buffer(expected_header.data, SHORT_MESSAGE_LENGTH); pr_dbg(" expected_error_recv: "); pr_buffer(expected_error_recv.data, SHORT_MESSAGE_LENGTH); pr_dbg(" expected_error_dev: "); pr_buffer(expected_error_dev.data, SHORT_MESSAGE_LENGTH); #endif /* Send the message to the Device */ ret = hidpp10_write_command(fd, msg->data, SHORT_MESSAGE_LENGTH); if (ret) goto out_err; /* * Now read the answers from the device: * loop until we get the actual answer or an error code. */ do { ret = read(fd, read_buffer.data, LONG_MESSAGE_LENGTH); #if DEBUG_LVL > 2 printf(" *** received: "); pr_buffer(read_buffer.data, ret); #endif /* actual answer */ if (!memcmp(read_buffer.data, expected_header.data, 4)) break; /* error */ if (!memcmp(read_buffer.data, expected_error_recv.data, 5) || !memcmp(read_buffer.data, expected_error_dev.data, 5)) { hidpp_err = read_buffer.msg.parameters[1]; pr_dbg(" HID++ error from the %s (%d): %s (%02x)\n", read_buffer.msg.device_idx == RECEIVER_IDX ? "receiver" : "device", read_buffer.msg.device_idx, hidpp_errors[hidpp_err] ? hidpp_errors[hidpp_err] : "Undocumented error code", hidpp_err); break; } } while (ret > 0); if (ret < 0) { printf(" USB error: %d\n", errno); perror("write"); goto out_err; } if (!hidpp_err) { pr_dbg(" received: "); pr_buffer(read_buffer.data, ret); /* copy the answer for the caller */ *msg = read_buffer; } ret = hidpp_err; out_err: return ret; }
int hidpp10_request_command(struct hidpp10_device *dev, union hidpp10_message *msg) { struct ratbag_device *device = dev->ratbag_device; struct ratbag *ratbag = device->ratbag; union hidpp10_message read_buffer; union hidpp10_message expected_header; union hidpp10_message expected_error_dev = ERROR_MSG(msg, msg->msg.device_idx); int ret; uint8_t hidpp_err = 0; /* create the expected header */ expected_header = *msg; switch (msg->msg.sub_id) { case SET_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_SHORT; break; case GET_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_SHORT; break; case SET_LONG_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_LONG; break; case GET_LONG_REGISTER_REQ: expected_header.msg.report_id = REPORT_ID_LONG; break; } log_buf_raw(ratbag, "sending: ", msg->data, SHORT_MESSAGE_LENGTH); log_buf_raw(ratbag, " expected_header: ", expected_header.data, SHORT_MESSAGE_LENGTH); log_buf_raw(ratbag, " expected_error_dev: ", expected_error_dev.data, SHORT_MESSAGE_LENGTH); /* Send the message to the Device */ ret = hidpp10_write_command(dev, msg->data, SHORT_MESSAGE_LENGTH); if (ret) goto out_err; /* * Now read the answers from the device: * loop until we get the actual answer or an error code. */ do { ret = ratbag_hidraw_read_input_report(device, read_buffer.data, LONG_MESSAGE_LENGTH); /* Overwrite the return device index with ours. The kernel * sets our device index on write, but gives us the real * device index on reply. Overwrite it with our index so the * messages are easier to check and compare. */ read_buffer.msg.device_idx = msg->msg.device_idx; log_buf_raw(ratbag, " *** received: ", read_buffer.data, ret); /* actual answer */ if (!memcmp(read_buffer.data, expected_header.data, 4)) break; /* error */ if (!memcmp(read_buffer.data, expected_error_dev.data, 5)) { hidpp_err = read_buffer.msg.parameters[1]; log_raw(ratbag, " HID++ error from the %s (%d): %s (%02x)\n", read_buffer.msg.device_idx == RECEIVER_IDX ? "receiver" : "device", read_buffer.msg.device_idx, hidpp_errors[hidpp_err] ? hidpp_errors[hidpp_err] : "Undocumented error code", hidpp_err); break; } } while (ret > 0); if (ret < 0) { log_error(ratbag, " USB error: %s (%d)\n", strerror(-ret), -ret); perror("write"); goto out_err; } if (!hidpp_err) { log_buf_raw(ratbag, " received: ", read_buffer.data, ret); /* copy the answer for the caller */ *msg = read_buffer; } ret = hidpp_err; out_err: return ret; }