ข้ามไปยังเนื้อหา

การระบุประเภทการเขียนของอุปกรณ์

เมื่อคุณทราบประเภทโปรโตคอลของอุปกรณ์แล้ว คุณอาจยังต้องระบุว่าจะใช้ฟังก์ชันเขียนใดโดยเฉพาะ โดยเฉพาะอุปกรณ์ HID ที่มีเมธอดการเขียนสองแบบซึ่งมุ่งไปยังกลไกการถ่ายโอน USB ที่ต่างกัน


device.write() ส่งข้อมูลโดยใช้การถ่ายโอนแบบ bulk หรือ interrupt บนเอนด์พอยต์ HID ที่เลือกไว้ในปัจจุบันของอุปกรณ์ นี่คือเส้นทางการเขียนมาตรฐานและใช้ได้กับอุปกรณ์ส่วนใหญ่

ใช้ device.write() เมื่อ:

  • อุปกรณ์ส่งและรับ report ที่มีความยาวคงที่ผ่านการถ่ายโอนแบบ interrupt
  • การดักจับใน Wireshark แสดงการถ่ายโอนแบบ URB_INTERRUPT
  • อุปกรณ์ไม่ได้ใช้ HID Report ID บนเอนด์พอยต์ที่เลือก (ซึ่งต้องใช้ zero padding — ดูด้านล่าง)
var packet = [];
packet[0] = 0xEC;
packet[1] = 0x40;
packet[2] = channel;
packet = packet.concat(RGBData);
device.write(packet, 65);

device.send_report() ส่งข้อมูลโดยใช้การถ่ายโอนแบบ control ประเภท HID SET_REPORT ซึ่งมุ่งไปยังกลไก HID feature report แทนเอนด์พอยต์แบบ interrupt

ใช้ device.send_report() เมื่อ:

  • การดักจับใน Wireshark แสดงการถ่ายโอนแบบ URB_CONTROL พร้อมคำขอ SET_REPORT (รหัสคำขอ 0x09)
  • device.write() ส่งคืนข้อผิดพลาด “incorrect function” บนทุกเอนด์พอยต์
  • อุปกรณ์ใช้ HID Feature report สำหรับอินเทอร์เฟซคำสั่งอย่างชัดเจน
device.send_report([0x07, 0x03, 0x06, 0x01, 0x00], 65);

ฟังก์ชันอ่านที่คู่กันสำหรับ feature report คือ device.get_report() ซึ่งจะส่งการถ่ายโอนแบบ control ประเภท GET_REPORT ใช้ฟังก์ชันนี้เมื่อคุณต้องการอ่านการกำหนดค่ากลับผ่านกลไก feature report เดียวกัน


หากคุณไม่แน่ใจ ให้เริ่มจาก device.write() ซึ่งใช้ได้กับอุปกรณ์ HID ส่วนใหญ่ หากคุณได้รับข้อผิดพลาด “incorrect function” ให้เปลี่ยนไปใช้ device.send_report() หากล้มเหลวทั้งสองแบบ ให้ตรวจสอบว่าคุณได้เลือกเอนด์พอยต์ที่ถูกต้องแล้ว

อาการสิ่งที่ควรลอง
ทำงานตามที่คาดไว้เสร็จเรียบร้อย
ข้อผิดพลาด “Incorrect function”เปลี่ยนไปใช้ device.send_report()
ข้อผิดพลาด “Access is denied”เอนด์พอยต์ไม่ถูกต้อง — ดู การเลือกเอนด์พอยต์
ไม่มีข้อผิดพลาด แต่อุปกรณ์ไม่ตอบสนองเอนด์พอยต์ไม่ถูกต้อง หรือประเภทอุปกรณ์ไม่ถูกต้อง

อุปกรณ์ HID บางรุ่นต้องการให้ไบต์แรกของทุกแพ็กเก็ตเป็น 0x00 ซึ่งเกิดขึ้นเมื่ออุปกรณ์ไม่มี Report ID กำหนดไว้สำหรับเอนด์พอยต์ที่เลือก — ไดรเวอร์ HID จะตัดไบต์ 0 ออกก่อนส่งข้อมูลไปยังอุปกรณ์ คุณจึงต้องเลื่อนทุกอย่างไปหนึ่งตำแหน่งเพื่อชดเชย

สัญญาณที่บ่งบอกว่าคุณต้องใช้ zero padding:

  • การดักจับใน Wireshark แสดงไบต์คำสั่งที่มีความหมายตัวแรกอยู่ที่ออฟเซ็ต 1 ไม่ใช่ออฟเซ็ต 0
  • หากไม่มีไบต์ศูนย์ อุปกรณ์จะเพิกเฉยต่อแพ็กเก็ตหรือให้ผลลัพธ์ที่ผิดเพี้ยน

วิธีใช้งาน:

// Without zero padding (packet size 64)
packet[0] = 0xEC; // command
packet[1] = 0x40;
device.write(packet, 64);
// With zero padding (packet size 65)
packet[0] = 0x00; // padding byte — consumed by HID driver
packet[1] = 0xEC; // command now at offset 1
packet[2] = 0x40;
device.write(packet, 65);

หลักการง่าย ๆ คือ หากการดักจับใน Wireshark แสดงแพ็กเก็ตขนาด 64 ไบต์ แต่ device.write(packet, 64) ใช้ไม่ได้ ให้ลอง device.write(packet, 65) โดยกำหนด packet[0] = 0x00 และเลื่อนไบต์อื่นทั้งหมดขึ้นไปหนึ่งตำแหน่ง


ฟังก์ชันฝั่งการอ่านที่เทียบเท่ากันก็แบ่งในลักษณะเดียวกัน:

เมธอดการเขียนเมธอดการอ่านที่คู่กันประเภทการถ่ายโอน
device.write()device.read()Bulk / Interrupt
device.send_report()device.get_report()Control (GET_REPORT)

สำหรับการอ่าน input report โดยเฉพาะ (ไม่ใช่ feature report) ให้ใช้ device.input_report() ดูรายละเอียดได้ที่ การสื่อสารขั้นสูง