#include #include #include #include #include #include #include #include using std::cout, std::cerr, std::endl, std::hex, std::setw, std::setfill, std::ios; struct __attribute__ ((packed)) lamp_array_attributes_report { const uint8_t report_id = 1; uint16_t lamp_count; uint32_t bounding_box_width_in_micrometers; uint32_t bounding_box_height_in_micrometers; uint32_t bounding_box_depth_in_micrometers; uint32_t lamp_array_kind; uint32_t min_update_interval_in_microseconds; }; struct __attribute__ ((packed)) lamp_attributes_request_report { const uint8_t report_id = 2; uint16_t lamp_id; }; struct __attribute__ ((packed)) lamp_attributes_response_report { const uint8_t report_id = 3; uint16_t lamp_id; uint32_t position_x_in_micrometers; uint32_t position_y_in_micrometers; uint32_t position_z_in_micrometers; uint32_t update_latency_in_microseconds; uint32_t lamp_purpose; uint8_t red_level_count; uint8_t green_level_count; uint8_t blue_level_count; uint8_t intensity_level_count; uint8_t is_programmable; uint8_t input_binding; }; struct __attribute__ ((packed)) lamp_multi_update_report { const uint8_t report_id = 4; uint8_t lamp_count; uint8_t lamp_update_flags; uint16_t lamp_id[8]; struct { uint8_t red_update_channel; uint8_t green_update_channel; uint8_t blue_update_channel; uint8_t intensity_update_channel; } update_channels[8]; }; struct __attribute__ ((packed)) lamp_range_update_report { const uint8_t report_id = 5; uint8_t lamp_update_flags; uint16_t lamp_id_start; uint16_t lamp_id_end; uint8_t red_update_channel; uint8_t green_update_channel; uint8_t blue_update_channel; uint8_t intensity_update_channel; }; struct __attribute__ ((packed)) lamp_array_control_report { const uint8_t report_id = 6; uint8_t autonomous_mode; }; int main(int argc, char *argv[]) { if (argc < 2) { cout << "Usage: " << argv[0] << "" << endl; return EXIT_SUCCESS; } int hidraw = open(argv[1], O_WRONLY|O_NONBLOCK); if (hidraw < 0) { cerr << "main: open(\"" << argv[1] << "\", O_WRONLY|O_NONBLOCK) failed." << endl; return hidraw; } struct hidraw_report_descriptor report_descriptor; int result = ioctl(hidraw, HIDIOCGRDESCSIZE, &report_descriptor.size); if (result < 0) { cerr << "main: ioctl(hidraw, HIDIOCGRDESCSIZE, &report_descriptor.size) failed." << endl; close(hidraw); return result; } result = ioctl(hidraw, HIDIOCGRDESC, &report_descriptor); if (result < 0) { cerr << "main: ioctl(hidraw, HIDIOCGRDESC, &report_descriptor) failed." << endl; close(hidraw); return result; } ios default_cout_state(nullptr); default_cout_state.copyfmt(cout); cout << "Report descriptor:" << endl; cout << hex << setfill('0'); for (int i = 0; i < report_descriptor.size; ++i) { if (i % 8 != 7 && i != report_descriptor.size - 1) { cout << setw(2) << (int)report_descriptor.value[i] << " "; } else { cout << setw(2) << (int)report_descriptor.value[i] << endl; } } cout << endl; cout.copyfmt(default_cout_state); struct lamp_array_attributes_report lamp_array_attributes_report; result = ioctl(hidraw, HIDIOCGFEATURE(sizeof(struct lamp_array_attributes_report)), &lamp_array_attributes_report); if (result < 0) { cerr << "ioctl(hidraw, HIDIOCGFEATURE(sizeof(struct lamp_array_attributes_report)) failed." << endl; close(hidraw); return result; } cout << "lamp count: " << lamp_array_attributes_report.lamp_count << endl; cout << "bounding box depth: " << lamp_array_attributes_report.bounding_box_depth_in_micrometers << endl; cout << "bounding box height: " << lamp_array_attributes_report.bounding_box_height_in_micrometers << endl; cout << "bounding box width: " << lamp_array_attributes_report.bounding_box_width_in_micrometers << endl; cout << endl; cout << "Attributes Report:" << endl; cout << hex << setfill('0'); for (int i = 0; i < sizeof(struct lamp_array_attributes_report); ++i) { if (i % 8 != 7 && i != sizeof(struct lamp_array_attributes_report) - 1) { cout << setw(2) << (int)((uint8_t *)&lamp_array_attributes_report)[i] << " "; } else { cout << setw(2) << (int)((uint8_t *)&lamp_array_attributes_report)[i] << endl; } } cout.copyfmt(default_cout_state); struct lamp_array_control_report lamp_array_control_report; lamp_array_control_report.autonomous_mode = 0; result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_array_control_report)), &lamp_array_control_report); if (result < 0) { cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_array_control_report)), lamp_array_control_report) failed." << endl; close(hidraw); return result; } struct lamp_range_update_report lamp_range_update_report; lamp_range_update_report.red_update_channel = 0xff; lamp_range_update_report.green_update_channel = 0xff; lamp_range_update_report.blue_update_channel = 0xff; lamp_range_update_report.intensity_update_channel = 0xff; lamp_range_update_report.lamp_update_flags = 0x01; lamp_range_update_report.lamp_id_start = 0; lamp_range_update_report.lamp_id_end = lamp_array_attributes_report.lamp_count - 1; result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), &lamp_range_update_report); if (result < 0) { cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_range_update_report)), lamp_range_update_report) failed." << endl; close(hidraw); return result; } struct lamp_multi_update_report lamp_multi_update_report; lamp_multi_update_report.lamp_count = 3; lamp_multi_update_report.lamp_id[0] = 0; lamp_multi_update_report.update_channels[0].red_update_channel = 0xff; lamp_multi_update_report.update_channels[0].green_update_channel = 0; lamp_multi_update_report.update_channels[0].blue_update_channel = 0; lamp_multi_update_report.update_channels[0].intensity_update_channel = 0xff; lamp_multi_update_report.lamp_id[1] = 1; lamp_multi_update_report.update_channels[1].red_update_channel = 0; lamp_multi_update_report.update_channels[1].green_update_channel = 0xff; lamp_multi_update_report.update_channels[1].blue_update_channel = 0; lamp_multi_update_report.update_channels[1].intensity_update_channel = 0xff; lamp_multi_update_report.lamp_id[2] = 2; lamp_multi_update_report.update_channels[2].red_update_channel = 0; lamp_multi_update_report.update_channels[2].green_update_channel = 0; lamp_multi_update_report.update_channels[2].blue_update_channel = 0xff; lamp_multi_update_report.update_channels[2].intensity_update_channel = 0xff; lamp_multi_update_report.lamp_update_flags = 0x01; result = ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), &lamp_multi_update_report); if (result < 0) { cerr << "main: ioctl(hidraw, HIDIOCSFEATURE(sizeof(struct lamp_multi_update_report)), lamp_multi_update_report) failed." << endl; close(hidraw); return result; } close(hidraw); return EXIT_SUCCESS; }