- บริการ EthernetTracker ของ Android รู้จักเฉพาะอินเทอร์เฟซเครือข่ายที่มีชื่อเป็น
ethX เท่านั้น
- ไดรเวอร์ CDC Ethernet ของ Linux จะสร้างชื่ออินเทอร์เฟซเป็น
usbX
- ด้วยเหตุนี้ อุปกรณ์ CDC Ethernet มาตรฐานจึง ไม่ถูกเปิดใช้งานอัตโนมัติ บน Android
- หากต้องการแก้ปัญหานี้ ผู้ใช้ต้อง รูตเครื่องและเปลี่ยนค่า
config_ethernet_iface_regex ด้วยตนเอง
- ในทางปฏิบัติ วิธีที่เป็นจริงได้มากกว่าคือใช้ ผลิตภัณฑ์ที่ใช้ชิปเซ็ตบางรุ่น ซึ่งมีไดรเวอร์เฉพาะจากผู้ขาย แทนที่จะใช้อะแดปเตอร์ USB Ethernet มาตรฐาน
บทนำและภาพรวมของปัญหา
- สาเหตุหลักที่ CDC Ethernet ใช้งานไม่ได้บนอุปกรณ์ Android คือ กฎการตั้งชื่ออินเทอร์เฟซ
- ในระดับระบบ Android รองรับอะแดปเตอร์ USB Ethernet อยู่แล้ว แต่มีข้อจำกัดในเงื่อนไขที่ทำให้เมนู Ethernet ถูกเปิดใช้งาน
- การหาข้อมูลว่าชิปเซ็ตใดเข้ากันได้ทำได้ยาก และในทางปฏิบัติก็มักต้องพึ่งพา "ข่าวลือ" ระหว่างผู้ใช้
- แม้ Android จะอิงกับเคอร์เนล Linux แต่ก็ไม่ได้หมายความว่าทุกอย่างถูกกำหนดด้วยการตั้งค่าเคอร์เนลเพียงอย่างเดียว
การตั้งค่า USB debugging และ ADB
- จำเป็นต้อง เปิดใช้ USB debugging และติดตั้ง ADB บนอุปกรณ์ Android
- หากต้องการทดสอบอะแดปเตอร์เครือข่าย ต้องสลับ ADB ไปเป็น โหมดเครือข่ายผ่าน Wi-Fi
- สามารถใช้คำสั่งเพื่อตรวจสอบ เวอร์ชันเคอร์เนลและสถาปัตยกรรม ปัจจุบันได้
วิธีตรวจสอบเวอร์ชันและการตั้งค่าของเคอร์เนล
- โทรศัพท์รุ่นใหม่ (Android 11 ขึ้นไป) ใช้โครงสร้างเคอร์เนลแบบ GKI(Generic Kernel Image)
- Google เป็นผู้บิลด์เคอร์เนลหลัก และผู้ผลิตจะเพิ่มเฉพาะโมดูล
- สามารถดูไฟล์ตั้งค่าเคอร์เนลที่เกี่ยวข้อง (
gki_defconfig) เพื่อทราบความสามารถที่รองรับได้
- โทรศัพท์รุ่นเก่าต้องตรวจสอบไฟล์ defconfig จากซอร์สเคอร์เนลที่ผู้ผลิตแยกเผยแพร่ให้ในแต่ละราย
- ถ้าโชคดี อาจตรวจสอบการตั้งค่าของเคอร์เนลที่กำลังใช้งานอยู่ได้โดยตรงจากพาธ
/proc/config.gz
วิธีตรวจสอบอะแดปเตอร์ USB Ethernet ที่รองรับ
- ค่าการตั้งค่าเคอร์เนลที่เกี่ยวข้องส่วนใหญ่อยู่ในรูปแบบ
CONFIG_USB_NET_XXX
- ถ้าเป็น
y คือบิวด์มาในตัว, m คือบิวด์เป็นโมดูล (น่าจะใช้งานได้), is not set คือไม่รองรับ
- สามารถดูคำอธิบายของค่าการตั้งค่าแต่ละตัวได้ในไฟล์
drivers/net/usb/Kconfig
- อย่างไรก็ตาม ข้อมูลชิปเซ็ตของอะแดปเตอร์ก็มักยังไม่ถูกระบุไว้อย่างชัดเจน
CDC Ethernet (Communications Device Class) และกรณีการใช้งานบน Android
- CDC เป็นมาตรฐานเครือข่ายผ่าน USB ที่รองรับ โปรโตคอลหลากหลายแบบ เช่น EEM/ECM/NCM
- บน Linux, Windows และ macOS อุปกรณ์ CDC Ethernet มาตรฐาน จะถูกตรวจพบอัตโนมัติโดยไม่ต้องมีไดรเวอร์เพิ่มเติม
- ตัว Android เองก็มีการบิลด์ไดรเวอร์ที่เกี่ยวข้องไว้แล้วในระดับเคอร์เนล
- ตัวอย่าง: อุปกรณ์ Samsung ที่ตั้งค่า
CONFIG_USB_NET_CDCETHER, EEM, NCM เป็น y ทั้งหมด
- แต่ถึงอย่างนั้น เมนู Ethernet ก็ยังคงไม่ถูกเปิดใช้งาน
ตรรกะการติดตามอินเทอร์เฟซเครือข่ายของ Android
- Android ใช้คลาส EthernetTracker.java ในการตรวจจับอินเทอร์เฟซเครือข่าย
- เมื่อมีอินเทอร์เฟซใหม่ปรากฏขึ้น EthernetTracker จะทำการจับคู่ตามรูปแบบชื่อ (regular expression)
- เกณฑ์การจับคู่นี้มาจากรีซอร์ส
config_ethernet_iface_regex
- ค่าเริ่มต้นคือ
eth\\d (ยอมรับเฉพาะอินเทอร์เฟซเครือข่ายที่ขึ้นต้นด้วย eth และตามด้วยตัวเลข)
- ชื่อที่เคอร์เนลสร้างขึ้น (
usb0) ไม่ตรงกับรูปแบบนี้ จึง ถูกมองข้ามทั้งในการติดตามและการเปิดใช้งาน
ข้อจำกัดของการแก้ปัญหาและบทสรุป
- regular expression สำหรับการตั้งชื่อนี้ ผู้ใช้ไม่สามารถเปลี่ยนเองได้โดยตรง (ทำไม่ได้หากไม่รูต)
- ผลคือผลิตภัณฑ์ CDC Ethernet มาตรฐาน แม้จะเชื่อมต่อแล้ว ก็ไม่สามารถใช้งานจากเมนูเครือข่ายได้
- ในทางกลับกัน จะใช้ได้เฉพาะอะแดปเตอร์บางรุ่นที่ถูกลงทะเบียนโดยตรงผ่านไดรเวอร์ของผู้ขายหรือชิปเซ็ต
- ต่อให้ Google ใส่โค้ดรองรับมาตรฐาน เช่นโมดูล EEM ไว้ในเคอร์เนล ก็ยังใช้งานจริงไม่ได้
- ทั้งที่จริงแล้วเป็นปัญหาง่าย ๆ ที่แก้ได้ด้วยการเปลี่ยน regular expression เป็นอย่างน้อย
(eth|usb)\\d แต่ปัจจุบันก็ยังคงเป็นเช่นเดิม
สรุป
- สาเหตุหลัก: ไม่ใช่เพราะ Android เมินมาตรฐาน CDC Ethernet แต่เป็นเพราะ ชื่ออินเทอร์เฟซเครือข่ายไม่ตรงกับ regular expression (
eth\\d) จึงไม่ถูกเปิดใช้งาน
- วิธีแก้แบบอ้อม: ต้อง รูตโทรศัพท์แล้วเปลี่ยนค่า
config_ethernet_iface_regex เป็น (eth|usb)\\d หรือค่าใกล้เคียง
- ตัวเลือกที่ใช้งานได้จริง: แทนที่จะเลือกอะแดปเตอร์ที่รองรับ USB CDC มาตรฐาน ควรเลือกผลิตภัณฑ์ที่มีการผูกกับไดรเวอร์ตามชิปเซ็ตอย่างชัดเจน
- ปัญหาเชิงโครงสร้าง: นี่เป็นตัวอย่างที่แสดงให้เห็นว่าการขาดนโยบายการตั้งชื่อในซอฟต์แวร์ชั้นบน ส่งผลเป็นข้อจำกัดเชิงระบบทั้งในด้านการมองเห็นของผู้ใช้และความเข้ากันได้กับมาตรฐาน
1 ความคิดเห็น
ความเห็นจาก Hacker News
ethXให้เอง แต่เจ้าตัวยังไม่ได้ทดสอบด้วยตัวเองหรืออัปเดตข้อมูลนี้ลงในโพสต์ และปัจจุบันก็แทบไม่ได้ใช้อุปกรณ์ Android แล้ว พร้อมเสริมว่าวิธีนี้ใช้ได้ก็ต่อเมื่อสามารถควบคุม MAC address ได้เท่านั้นeth\dเป็น*ซึ่งคาดว่าแก้ปัญหานี้ได้ พร้อมแนบลิงก์การเปลี่ยนโค้ดที่เกี่ยวข้อง และอธิบายว่า Android U+ (น่าจะเป็นเวอร์ชัน 14) รวมทั้งusb\d+และeth%dไว้ในค่าเริ่มต้นแล้วusbX" จากนั้นจึงถูกนำกลับมาใช้อีกครั้งโดยรองรับเฉพาะ Android V+ (เวอร์ชันใหม่) พร้อมแนบลิงก์เกี่ยวกับ rollback และลิงก์การใช้งานจริงขั้นสุดท้ายEthernetTrackerของ Android ยอมรับเฉพาะอินเทอร์เฟซที่ตั้งชื่อเป็นethXโดยอธิบายว่าดิสทริบิวชันลินุกซ์แก้ปัญหาแบบนี้ได้ตั้งแต่ยุค 2000 แล้ว ในอดีตไดรเวอร์จำนวนมากมักใช้ prefix ชื่อตามใจตัวเอง ทำให้ต้องไล่ตรวจทั้งระบบอย่างยุ่งยาก ทุกวันนี้ดิสทริบิวชันลินุกซ์จะเปลี่ยนชื่อ network interface อัตโนมัติด้วยเครื่องมืออย่างudevและกระบวนการนี้ทำงานผ่านการเรียกSIOCSIFNAME ioctlของเคอร์เนล พร้อมเสริมว่าเคอร์เนลรุ่นใหม่ยังมีความสะดวกที่สามารถใส่เลขอัตโนมัติให้ชื่ออย่างwlan*หรือwlan%dได้ด้วยifupจะล้มเหลว และ UI ของ Android ก็ไม่แสดงสถานะนี้เลย ต้องไปดูdmesgจึงจะเห็นปัญหา ไม่แน่ใจว่าสิ่งนี้ใช้กับอุปกรณ์ CDC ด้วยหรือไม่ แต่จากประสบการณ์ USB Ethernet dongle จำนวนมากใช้ชิปเซ็ตของ Realtek หรือ Kawasaki และมีกรณีที่ต้องใช้เฟิร์มแวร์อยู่บ้าง ผู้แสดงความเห็นคาดว่าการเปลี่ยนแปลงฝั่ง Android นี้น่าจะเกิดขึ้นไม่นาน เพราะบนอุปกรณ์ดีบัก vanilla AOSP ตนเคยใช้ USB network dongle ได้ดีอยู่แล้ว จึงสงสัยว่าอาจเป็นเรื่องธรรมเนียมการตั้งชื่อของฝั่งเคอร์เนลหรือไดรเวอร์ CDC มากกว่า สรุปคือควรใส่ใจทั้งชิปเซ็ตของ dongle และการต้องใช้เฟิร์มแวร์หรือไม่