int hidpp10_get_firmare_information(struct hidpp10_device *dev, uint8_t *major_out, uint8_t *minor_out, uint8_t *build_out) { unsigned idx = dev->index; union hidpp10_message firmware_information = CMD_DEVICE_FIRMWARE_INFORMATION(idx, FIRMWARE_INFO_ITEM_FW_NAME_AND_VERSION(1)); union hidpp10_message build_information = CMD_DEVICE_FIRMWARE_INFORMATION(idx, FIRMWARE_INFO_ITEM_FW_BUILD_NUMBER(1)); int res; uint8_t maj, min, build; log_raw(dev->ratbag_device->ratbag, "Fetching firmware information\n"); /* * This may fail on some devices * => we can not retrieve their FW version through HID++ 1.0. */ res = hidpp10_request_command(dev, &firmware_information); if (res) return res; maj = firmware_information.msg.string[1]; min = firmware_information.msg.string[2]; res = hidpp10_request_command(dev, &build_information); if (res) return res; build = hidpp10_get_unaligned_u16(&build_information.msg.string[1]); *major_out = maj; *minor_out = min; *build_out = build; return 0; }
int hidpp10_open_lock(struct hidpp10_device *device) { union hidpp10_message open_lock = CMD_DEVICE_CONNECTION_DISCONNECTION(0x00, CONNECT_DEVICES_OPEN_LOCK, 0x08); return hidpp10_request_command(device, &open_lock); }
static int hidpp10_get_device_info(int fd, struct unifying_device *dev) { unsigned idx = dev->index; union hidpp10_message pairing_information = CMD_PAIRING_INFORMATION(idx, DEVICE_PAIRING_INFORMATION); union hidpp10_message device_name = CMD_PAIRING_INFORMATION(idx, DEVICE_NAME); union hidpp10_message firmware_information = CMD_DEVICE_FIRMWARE_INFORMATION(idx, FIRMWARE_INFO_ITEM_FW_NAME_AND_VERSION(1)); union hidpp10_message build_information = CMD_DEVICE_FIRMWARE_INFORMATION(idx, FIRMWARE_INFO_ITEM_FW_BUILD_NUMBER(1)); int name_size; int res, i; res = hidpp10_request_command(fd, &pairing_information); if (res) return -1; dev->report_interval = pairing_information.msg.string[2]; dev->wpid = (pairing_information.msg.string[3] << 8) | pairing_information.msg.string[4]; dev->device_type = pairing_information.msg.string[7]; res = hidpp10_request_command(fd, &device_name); if (res) return -1; name_size = device_name.msg.string[1]; memcpy(dev->name, &device_name.msg.string[2], sizeof(device_name.msg.string)); dev->name[MIN(name_size, sizeof(dev->name) - 1)] = '\0'; /* * This may fail on some devices * => we can not retrieve their FW version through HID++ 1.0. */ res = hidpp10_request_command(fd, &firmware_information); if (res) return 0; dev->fw_major = firmware_information.msg.string[1]; dev->fw_minor = firmware_information.msg.string[2]; res = hidpp10_request_command(fd, &build_information); if (res) return 0; dev->build = (build_information.msg.string[1] << 8) | build_information.msg.string[2]; return 0; }
int hidpp10_toggle_individual_feature(int fd, struct unifying_device *dev, int feature_bit_r0, int feature_bit_r2) { unsigned idx = dev->index; union hidpp10_message mode = CMD_ENABLE_INDIVIDUAL_FEATURES(idx, GET_REGISTER_REQ); int res; /* first read the current values */ res = hidpp10_request_command(fd, &mode); if (res) return -1; /* toggle bits of r0 */ if (feature_bit_r0 >= 0) mode.msg.parameters[0] ^= 1U << feature_bit_r0; /* toggle bits of r2 */ if (feature_bit_r2 >= 0) mode.msg.parameters[2] ^= 1U << feature_bit_r2; /* now write back the change */ mode.msg.sub_id = SET_REGISTER_REQ; res = hidpp10_request_command(fd, &mode); return res; }
int hidpp10_set_hidpp_notifications(struct hidpp10_device *dev, uint8_t reporting_flags_r0, uint8_t reporting_flags_r2) { unsigned idx = dev->index; union hidpp10_message notifications = CMD_HIDPP_NOTIFICATIONS(idx, SET_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Setting HID++ notifications\n"); notifications.msg.parameters[0] = reporting_flags_r0; notifications.msg.parameters[2] = reporting_flags_r2; res = hidpp10_request_command(dev, ¬ifications); return res; }
int hidpp10_get_usb_refresh_rate(struct hidpp10_device *dev, uint16_t *rate) { unsigned idx = dev->index; union hidpp10_message refresh = CMD_USB_REFRESH_RATE(idx, GET_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Fetching USB refresh rate\n"); res = hidpp10_request_command(dev, &refresh); if (res) return res; *rate = 1000/refresh.msg.parameters[0]; return 0; }
int hidpp10_get_pairing_information_device_name(struct hidpp10_device *dev, char *name, size_t *name_size) { unsigned int idx = dev->index; union hidpp10_message device_name = CMD_PAIRING_INFORMATION(idx, DEVICE_NAME); int res; log_raw(dev->ratbag_device->ratbag, "Fetching device name\n"); res = hidpp10_request_command(dev, &device_name); if (res) return -1; *name_size = min(*name_size, device_name.msg.string[1]); strncpy_safe(name, (char*)&device_name.msg.string[2], *name_size); return 0; }
int hidpp10_set_led_status(struct hidpp10_device *dev, const bool led[4]) { unsigned idx = dev->index; union hidpp10_message led_status = CMD_LED_STATUS(idx, SET_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Setting LED status\n"); /* each led is 4-bits, 0x1 == off, 0x2 == on */ led_status.msg.parameters[0] |= led[0] ? 0x02 : 0x01; /* running man logo */ led_status.msg.parameters[0] |= led[1] ? 0x20 : 0x10; /* lowest */ led_status.msg.parameters[1] |= led[2] ? 0x02 : 0x01; /* middle */ led_status.msg.parameters[1] |= led[3] ? 0x20 : 0x10; /* highest */ res = hidpp10_request_command(dev, &led_status); return res; }
static int hidpp10_read_memory(struct hidpp10_device *dev, uint8_t page, uint16_t offset, uint8_t bytes[16]) { unsigned idx = dev->index; union hidpp10_message readmem = CMD_READ_MEMORY(idx, page, offset/2); int res; log_raw(dev->ratbag_device->ratbag, "Reading memory page %d, offset %#x\n", page, offset); res = hidpp10_request_command(dev, &readmem); if (res) return res; memcpy(bytes, readmem.msg.string, sizeof(readmem.msg.string)); return 0; }
int hidpp10_get_individual_features(struct hidpp10_device *dev, uint8_t *feature_bit_r0, uint8_t *feature_bit_r2) { unsigned idx = dev->index; union hidpp10_message features = CMD_ENABLE_INDIVIDUAL_FEATURES(idx, GET_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Fetching individual features\n"); res = hidpp10_request_command(dev, &features); if (res) return res; *feature_bit_r0 = features.msg.parameters[0]; *feature_bit_r2 = features.msg.parameters[2]; return 0; }
int hidpp10_get_optical_sensor_settings(struct hidpp10_device *dev, uint8_t *surface_reflectivity) { unsigned idx = dev->index; union hidpp10_message sensor = CMD_OPTICAL_SENSOR_SETTINGS(idx, GET_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Fetching optical sensor settings\n"); res = hidpp10_request_command(dev, &sensor); if (res) return res; *surface_reflectivity = sensor.msg.parameters[0]; /* Don't know what the other values are */ return 0; }
int hidpp10_set_individual_feature(struct hidpp10_device *dev, uint8_t feature_bit_r0, uint8_t feature_bit_r2) { unsigned idx = RECEIVER_IDX; union hidpp10_message mode = CMD_ENABLE_INDIVIDUAL_FEATURES(idx, SET_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Setting individual features\n"); if (dev) mode.msg.device_idx = dev->index; mode.msg.parameters[0] = feature_bit_r0; mode.msg.parameters[1] = feature_bit_r2; res = hidpp10_request_command(dev, &mode); return res; }
int hidpp10_get_current_resolution(struct hidpp10_device *dev, uint16_t *xres, uint16_t *yres) { unsigned idx = dev->index; union hidpp10_message resolution = CMD_CURRENT_RESOLUTION(idx, GET_LONG_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Fetching current resolution\n"); res = hidpp10_request_command(dev, &resolution); if (res) return res; /* resolution is in 50dpi multiples */ *xres = hidpp10_get_unaligned_u16le(&resolution.data[4]) * 50; *yres = hidpp10_get_unaligned_u16le(&resolution.data[6]) * 50; return 0; }
int hidpp10_get_pairing_information(struct hidpp10_device *dev, uint8_t *report_interval, uint16_t *wpid, uint8_t *device_type) { unsigned int idx = dev->index; union hidpp10_message pairing_information = CMD_PAIRING_INFORMATION(idx, DEVICE_PAIRING_INFORMATION); int res; log_raw(dev->ratbag_device->ratbag, "Fetching pairing information\n"); res = hidpp10_request_command(dev, &pairing_information); if (res) return -1; *report_interval = pairing_information.msg.string[2]; *wpid = hidpp10_get_unaligned_u16(&pairing_information.msg.string[3]); *device_type = pairing_information.msg.string[7]; return 0; }
int hidpp10_get_led_status(struct hidpp10_device *dev, bool led[4]) { unsigned idx = dev->index; union hidpp10_message led_status = CMD_LED_STATUS(idx, GET_REGISTER_REQ); int res; log_raw(dev->ratbag_device->ratbag, "Fetching LED status\n"); res = hidpp10_request_command(dev, &led_status); if (res) return res; /* each led is 4-bits, 0x1 == off, 0x2 == on */ led[0] = !!(led_status.msg.parameters[0] & 0x02); /* running man logo */ led[1] = !!(led_status.msg.parameters[0] & 0x20); /* lowest */ led[2] = !!(led_status.msg.parameters[1] & 0x02); /* middle */ led[3] = !!(led_status.msg.parameters[1] & 0x20); /* highest */ return 0; }
int hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile) { unsigned idx = dev->index; union hidpp10_message profile = CMD_PROFILE(idx, GET_REGISTER_REQ); int res; int8_t page; log_raw(dev->ratbag_device->ratbag, "Fetching current profile\n"); res = hidpp10_request_command(dev, &profile); if (res) return res; page = profile.msg.parameters[0]; /* FIXME: my mouse is always 0 */ *current_profile = page; /* FIXME: my mouse appears to be on page 5, but with the offset of * 3, it's actually profile 2. not sure how to change this */ *current_profile = 2; return 0; }
int hidpp10_disconnect(int fd, int idx) { union hidpp10_message disconnect = CMD_DEVICE_CONNECTION_DISCONNECTION(idx + 1, CONNECT_DEVICES_DISCONNECT, 0x00); return hidpp10_request_command(fd, &disconnect); }
int hidpp10_open_lock(int fd) { union hidpp10_message open_lock = CMD_DEVICE_CONNECTION_DISCONNECTION(0x00, CONNECT_DEVICES_OPEN_LOCK, 0x08); return hidpp10_request_command(fd, &open_lock); }