การระบุประเภทการเขียนของอุปกรณ์
เมื่อคุณทราบประเภทโปรโตคอลของอุปกรณ์แล้ว คุณอาจยังต้องระบุว่าจะใช้ฟังก์ชันเขียนใดโดยเฉพาะ โดยเฉพาะอุปกรณ์ HID ที่มีเมธอดการเขียนสองแบบซึ่งมุ่งไปยังกลไกการถ่ายโอน USB ที่ต่างกัน
device.write
หัวข้อที่มีชื่อว่า “device.write”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
หัวข้อที่มีชื่อว่า “device.send_report”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” | เอนด์พอยต์ไม่ถูกต้อง — ดู การเลือกเอนด์พอยต์ |
| ไม่มีข้อผิดพลาด แต่อุปกรณ์ไม่ตอบสนอง | เอนด์พอยต์ไม่ถูกต้อง หรือประเภทอุปกรณ์ไม่ถูกต้อง |
Zero Padding
หัวข้อที่มีชื่อว่า “Zero Padding”อุปกรณ์ HID บางรุ่นต้องการให้ไบต์แรกของทุกแพ็กเก็ตเป็น 0x00 ซึ่งเกิดขึ้นเมื่ออุปกรณ์ไม่มี Report ID กำหนดไว้สำหรับเอนด์พอยต์ที่เลือก — ไดรเวอร์ HID จะตัดไบต์ 0 ออกก่อนส่งข้อมูลไปยังอุปกรณ์ คุณจึงต้องเลื่อนทุกอย่างไปหนึ่งตำแหน่งเพื่อชดเชย
สัญญาณที่บ่งบอกว่าคุณต้องใช้ zero padding:
- การดักจับใน Wireshark แสดงไบต์คำสั่งที่มีความหมายตัวแรกอยู่ที่ออฟเซ็ต 1 ไม่ใช่ออฟเซ็ต 0
- หากไม่มีไบต์ศูนย์ อุปกรณ์จะเพิกเฉยต่อแพ็กเก็ตหรือให้ผลลัพธ์ที่ผิดเพี้ยน
วิธีใช้งาน:
// Without zero padding (packet size 64)packet[0] = 0xEC; // commandpacket[1] = 0x40;device.write(packet, 64);
// With zero padding (packet size 65)packet[0] = 0x00; // padding byte — consumed by HID driverpacket[1] = 0xEC; // command now at offset 1packet[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() ดูรายละเอียดได้ที่ การสื่อสารขั้นสูง