1 คะแนน โดย GN⁺ 2025-06-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Android มีการรองรับ USB Ethernet และเมนูตั้งค่า แต่แม้อุปกรณ์ CDC Ethernet จะถูกเคอร์เนลตรวจพบ ก็อาจไม่ถูกเชื่อมต่อไปถึงการตั้งค่าเครือข่าย
  • สาเหตุหลักคือ EthernetTracker ติดตามเฉพาะอินเทอร์เฟซที่ตรงกับ config_ethernet_iface_regex และค่าเริ่มต้น eth\d ตัดอินเทอร์เฟซ CDC อย่าง usb0 ออกไป
  • ไดรเวอร์ CDC Ethernet ของ Linux จะจับอุปกรณ์ EEM, ECM, NCM ด้วย cdc_eem, cdc_ether, cdc_ncm ตามลำดับ และสร้าง usb0 ใน /sys/class/net แต่การตั้งค่าของ Android ยังอยู่ในสถานะปิดใช้งานต่อไป
  • ผู้ใช้ทั่วไปไม่สามารถหลีกเลี่ยงได้ด้วยการตั้งค่า จำเป็นต้องรูทแล้วเปลี่ยนค่า config_ethernet_iface_regex
  • เวลาเลือก USB Ethernet adapter สำหรับ Android จึงต้องมองหาอุปกรณ์ที่ใช้ ไดรเวอร์เฉพาะผู้ผลิต/ชิปเซ็ต ซึ่งสร้างชื่อแบบ ethX แทนอุปกรณ์มาตรฐาน CDC

สรุป: ไม่ใช่ไดรเวอร์เคอร์เนลที่ขวาง แต่เป็นตัวกรองชื่ออินเทอร์เฟซ

  • บริการ EthernetTracker ของ Android ยอมรับเฉพาะอินเทอร์เฟซที่มีชื่อเป็น ethX ว่าเป็น Ethernet interface
  • ไดรเวอร์ CDC Ethernet ของ Linux สร้างชื่ออินเทอร์เฟซเป็น usbX
  • ความต่างของชื่อนี้ทำให้อุปกรณ์ CDC Ethernet ถูกเพิกเฉยในชั้นการตั้งค่า Ethernet และการจัดการเครือข่ายของ Android แม้จะถูกเคอร์เนล Android ตรวจพบแล้วก็ตาม
  • แก้ด้วยการตั้งค่าทั่วไปไม่ได้ ทำได้เพียงรูทแล้วเปลี่ยนค่า config_ethernet_iface_regex

การตรวจสอบการรองรับ Android USB Ethernet ทำได้ยากในแต่ละอุปกรณ์

  • Android มีการรองรับ USB Ethernet adapter และเมนูที่เกี่ยวข้อง
  • การตรวจสอบว่า USB Ethernet chipset ใดทำงานได้บนอุปกรณ์ Android รุ่นใดเป็นเรื่องยาก เพราะผู้ผลิตแทบไม่เผยแพร่รายการที่รองรับ
  • ผู้ใช้จริงมักต้องพึ่งข้อมูลต่อไปนี้
    • USB Ethernet adapter ที่ผู้ผลิตโทรศัพท์ขายเป็นอุปกรณ์เสริมทางการ
    • โพสต์ในฟอรัมจากผู้ใช้เครื่องรุ่นเดียวกันที่ใช้อะแดปเตอร์บางรุ่นสำเร็จ
  • ดูจากการตั้งค่าเคอร์เนลจะพอทราบได้ว่าเคอร์เนลของโทรศัพท์รวม ไดรเวอร์ USB Ethernet ใดไว้บ้าง

วิธีค้นหาการตั้งค่าเคอร์เนลของโทรศัพท์

  • Android ทำงานบนเคอร์เนล Linux และการตั้งค่าเคอร์เนลเป็นตัวกำหนดฟีเจอร์กับไดรเวอร์ฮาร์ดแวร์ที่รองรับ
  • อุปกรณ์ที่ออกหลัง Android 11 ใช้ Android Common Kernel และ GKI kernel เป็นฐาน
    • Google เป็นผู้ build เคอร์เนล ส่วนผู้ผลิตใส่องค์ประกอบเฉพาะอุปกรณ์ไว้ใน kernel modules
    • ตรวจสอบการตั้งค่าได้ที่ arch/$ARCH/configs/gki_defconfig ใน repository เคอร์เนล Android
    • อุปกรณ์ ARM 64 บิต เช่น ตรวจสอบที่ arch/arm64/configs/gki_defconfig
  • ตรวจสอบเวอร์ชันเคอร์เนลและสถาปัตยกรรมได้จาก ADB ด้วย uname -a
    • ตัวอย่าง output มีเวอร์ชันเคอร์เนล 4.19.113-26203352 และสถาปัตยกรรม aarch64
  • ในกรณี Samsung Galaxy S20 ที่เปิดตัวพร้อม Android 10 แม้จะอัปเกรดเป็น Android 13 แล้ว เคอร์เนลยังคงอิง Linux 4.19
    • ซอร์สของอุปกรณ์ Samsung หาได้ที่ opensource.samsung.com
    • ใน build_kernel.sh ของซอร์ส Samsung สามารถหาชื่อไฟล์ตั้งค่าเคอร์เนล เช่น vendor/x1q_usa_singlex_defconfig ได้
  • ถ้าโชคดี การตั้งค่าที่ใช้ build จริงจะอยู่เป็นไฟล์บีบอัดใน /proc/config.gz
    • บันทึกได้ด้วย adb shell zcat /proc/config.gz > my_kernel_config
    • ถ้าไม่มี จะขึ้น zcat: /proc/config.gz: No such file or directory และต้องตรวจสอบซอร์สเคอร์เนลของผู้ผลิต

ตรวจสอบการรองรับไดรเวอร์ USB Ethernet

  • การตั้งค่าเคอร์เนลที่เกี่ยวกับ USB Ethernet มักขึ้นต้นด้วย USB_NET
  • ตรวจสอบในไฟล์ตั้งค่าเคอร์เนลได้ดังนี้
grep USB_NET my_kernel_config
  • ตัวอย่างการตั้งค่ามีไดรเวอร์เครือข่าย USB หลายตัวรวมอยู่
    • CONFIG_USB_NET_DRIVERS=y
    • CONFIG_USB_NET_AX8817X=y
    • CONFIG_USB_NET_AX88179_178A=y
    • CONFIG_USB_NET_CDCETHER=y
    • CONFIG_USB_NET_CDC_EEM=y
    • CONFIG_USB_NET_CDC_NCM=y
  • ค่าการตั้งค่าแบ่งวิธีรวมไดรเวอร์
    • y: ไดรเวอร์ถูกฝังในเคอร์เนล และรองรับชิปเซ็ตนั้นแน่นอน
    • m: ไดรเวอร์ถูก build เป็น module และอาจโหลดได้หากผู้ผลิตไม่ได้ละไว้
    • is not set: ไดรเวอร์ไม่ได้ถูกฝังและไม่ได้เป็น module จึงมีโอกาสสูงว่าจะใช้ไม่ได้
  • ตรวจสอบรายการตั้งค่าและชิปเซ็ตที่สอดคล้องกันได้จาก drivers/net/usb/Kconfig ใน kernel tree
  • ผู้ผลิตมักไม่ระบุว่า USB Ethernet adapter บางรุ่นใช้ชิปเซ็ตใด ทำให้ยังแยกแยะได้ยาก

CDC Ethernet ทำหน้าที่อะไร

  • CDC ย่อมาจาก Communications Device Class เป็นชุดมาตรฐานที่ผู้ผลิตอุปกรณ์ USB สามารถทำตามได้
  • มาตรฐานที่เกี่ยวกับ CDC Ethernet มี 3 แบบ
    • EEM: Ethernet Emulation Model, การใช้งานเรียบง่ายที่สุดและรองรับได้ง่ายในอุปกรณ์ประสิทธิภาพต่ำ
    • ECM: Ethernet Control Model, การใช้งานทั้งฝั่ง host และ device ซับซ้อนกว่า แต่สัญญาว่าจะมีประสิทธิภาพดีกว่า EEM
    • NCM: Network Control Model, รุ่นต่อจาก ECM ที่สัญญาว่าจะให้ความเร็วสูงกว่า
  • เป้าหมายของมาตรฐาน CDC คือให้อุปกรณ์หลากหลายชนิดใช้ไดรเวอร์ร่วมจากระบบปฏิบัติการได้
  • Linux implements ทั้งฝั่ง host และฝั่ง device ของ CDC Ethernet
    • บนอุปกรณ์อย่าง Raspberry Pi ที่มีพอร์ต USB OTG เคอร์เนลสามารถทำให้พอร์ตนี้ดูเหมือน Ethernet adapter ได้
    • วิธีนี้ทำให้อุปกรณ์อย่าง embedded router, firewall, VPN gateway ดูเหมือน Ethernet adapter ทั่วไปในมุมของ host
  • Linux, Windows, macOS มีไดรเวอร์อุปกรณ์ CDC Ethernet รวมอยู่ แต่ iOS ไม่มี

เคอร์เนล Android ตรวจพบอุปกรณ์ CDC

  • การตั้งค่าเคอร์เนลของ Samsung Galaxy S20 รวมการรองรับมาตรฐาน CDC Ethernet ทั้งสามแบบ
    • CONFIG_USB_NET_CDCETHER=y
    • CONFIG_USB_NET_CDC_EEM=y
    • CONFIG_USB_NET_CDC_NCM=y
  • เคอร์เนล Google GKI ดูเหมือนจะไม่รวม ECM และ NCM แต่รวม EEM เป็น module
  • อุปกรณ์ที่ตั้งค่าพอร์ต OTG เป็น Ethernet gadget ทำงานได้บน Mac, Ubuntu, Windows แต่บน Galaxy S20 การตั้งค่า Android Ethernet ยังคงปิดใช้งาน
  • เมื่อตรวจสอบ /sys/class/net บน Android จะเห็น usb0 ปรากฏเมื่อเชื่อมต่ออุปกรณ์ CDC
adb shell ls /sys/class/net
  • จาก output ของ ifconfig usb0 ยืนยันได้ว่าไดรเวอร์ถูกจับเป็นตระกูล CDC
    • โหมด EEM: Driver cdc_eem
    • โหมด ECM: Driver cdc_ether
    • โหมด NCM: Driver cdc_ncm
  • ทั้งสามกรณี อินเทอร์เฟซถูกตรวจพบ แต่ยังอยู่ในสถานะ down และการตั้งค่า Android Ethernet ไม่ถูกเปิดใช้งาน

regex ของ EthernetTracker กรอง usb0 ทิ้ง

  • ในระดับเคอร์เนล อุปกรณ์ CDC Ethernet ถูกตรวจพบตามปกติ ดังนั้นปัญหาอยู่ที่ ชั้นจัดการเครือข่ายของ Android เหนือเคอร์เนล
  • เมื่อตามโค้ด Java ที่เกี่ยวกับ Ethernet ในซอร์ส Android จะพบ EthernetTracker.java เป็นบริการที่เกี่ยวข้อง
  • EthernetTracker รับการแจ้งเตือนอินเทอร์เฟซเครือข่ายใหม่จากเคอร์เนลผ่าน socket Netlink แล้วตัดสินว่าเป็น Ethernet interface ที่ถูกต้องหรือไม่
  • การตัดสินความถูกต้องทำโดยตรวจว่าชื่ออินเทอร์เฟซตรงกับ regex mIfaceMatch หรือไม่
private boolean isValidEthernetInterface(String iface) {
    return iface.matches(mIfaceMatch) || isValidTestInterface(iface);
}
  • mIfaceMatch มาจาก resource config_ethernet_iface_regex
  • ค่าเริ่มต้นในซอร์ส Android เป็นดังนี้
<string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>
  • eth\d เป็น regex ที่ให้ผ่านเฉพาะชื่อที่มี eth ตามด้วยตัวเลข
  • อุปกรณ์ CDC Ethernet เริ่มด้วย usb เช่น usb0 จึงไม่ถูก EthernetTracker ติดตาม
  • การตั้งค่านี้เปลี่ยนด้วยการตั้งค่าผู้ใช้ไม่ได้ แก้ได้ผ่านการรูทเท่านั้น

ความย้อนแย้งที่ต้องเลี่ยงอุปกรณ์มาตรฐาน

  • CDC Ethernet เป็นมาตรฐานสำหรับอุปกรณ์เครือข่าย USB แต่บน Android เส้นทางการใช้งานจริงถูกขวางด้วย regex ของชื่ออินเทอร์เฟซ
  • เคอร์เนล GKI รุ่นใหม่ก็ดูเหมือนจะรวมการรองรับ EEM adapter ไว้ แต่ชื่อ usb0 ไม่ตรงกับ regex จึงไม่ถูกส่งขึ้นไปยังการตั้งค่าเครือข่ายของ Android
  • เวลาเลือก USB Ethernet adapter สำหรับ Android ควรมองหาอุปกรณ์ที่สร้างอินเทอร์เฟซ ethX ด้วยไดรเวอร์เฉพาะผู้ผลิต/ชิปเซ็ต แทนที่จะเป็นอุปกรณ์มาตรฐาน CDC
  • แนวทางแพตช์ที่เป็นไปได้คือเปลี่ยน config_ethernet_iface_regex เป็นอย่าง (eth|usb)\d

1 ความคิดเห็น

 
GN⁺ 2025-06-09
ความคิดเห็นจาก Hacker News
  • ผมเขียนบทความนี้หลังจากสัปดาห์ที่ต้องลำบากกับการต่อ อุปกรณ์ Android กับอะแดปเตอร์ CDC Ethernet ในที่ทำงานเก่า
    หลังจากนั้นมีบางคนบอกว่าถ้ากลับบิตบางตัวของ MAC address เคอร์เนลจะตั้งชื่อเป็น ethX แทน usbX แต่ผมไม่ได้ลองเองหรืออัปเดตบทความ เพราะย้ายไปที่ทำงานอื่นแล้ว และอุปกรณ์ Android ก็ไม่ได้เป็นส่วนสำคัญในชีวิตประจำวันอีกต่อไป
    แน่นอนว่าวิธีนี้จะมีประโยชน์ก็ต่อเมื่อคุณควบคุม MAC address ของอุปกรณ์ CDC ได้โดยตรง เช่น กรณีที่อุปกรณ์ Linux อีกตัวแกล้งทำตัวเป็นอะแดปเตอร์ CDC เป็นต้น
  • เป็น บทความเจาะลึก ที่น่าสนใจ
    ลองค้นซอร์สดูแล้ว ในเดือนตุลาคม 2023 regex ถูกเปลี่ยนจาก eth\\d เป็นแค่ * ดังนั้นดูเหมือนว่าปัญหานี้น่าจะได้รับการแก้แล้ว: https://android-review.googlesource.com/c/platform/packages/...
    ในคำอธิบายระบุว่า “ค่าเริ่มต้นจะรวมทั้งอินเทอร์เฟซชื่อ usb\d+ และ eth%d บน Android U+” โดย U+ ตรงนี้ดูเหมือนจะเป็นเวอร์ชัน 14: https://en.wikipedia.org/wiki/Android_version_history
  • ดูจากประวัติ commit ของ LineageOS ปัญหานี้เคยถูกแก้แล้ว[0] จากนั้นถูก revert เพราะปัญหาความเข้ากันได้[1] แล้วก็ยกเลิกการ revert อีกครั้ง[2] แต่ดูเหมือนจะใช้ได้เฉพาะกับ Android เวอร์ชันล่าสุดเท่านั้น
    ถ้าผมอ่าน commit ถูกต้อง มีคนฝั่ง Google เข้ามาเกี่ยวข้องด้วย ดังนั้นตอนนี้มันอาจเข้าไปอยู่ใน build ทางการของ Google แล้วก็ได้
    [0] https://github.com/LineageOS/android_packages_modules_Connec...
    [1] https://github.com/LineageOS/android_packages_modules_Connec...
    [2] https://github.com/LineageOS/android_packages_modules_Connec...
    • ในฝั่ง Lineage ผมเคยไปเจอเรื่องนั้นเมื่อสักพักก่อน แล้วทำ https://review.lineageos.org/c/LineageOS/android_packages_mo... ขึ้นมา
      แต่ไม่มีใครทดสอบ และผมก็ไม่มีวิธีตรวจสอบเอง ตอนนี้เลยอยู่ในสถานะพักไว้ มักจะมีทั้งสิ่งที่ใครบางคนรายงานมา กับสิ่งที่ใครบางคนบังเอิญหยิบขึ้นมา แต่สุดท้ายก็ยังต้องอาศัยการทดสอบจากผู้ใช้จริง
  • ถ้าเป็นความจริงที่บริการ EthernetTracker ของ Android รู้จักเฉพาะอินเทอร์เฟซที่ชื่อ ethX นี่เป็นการออกแบบที่โง่ที่สุดเท่าที่เคยได้ยินมา
    Linux distribution แก้ปัญหานี้ไปแล้วตั้งแต่ยุค 2000 ตอนนั้นก็เห็นชัดแล้วว่า driver ของอุปกรณ์บางตัวตั้ง prefix ชื่ออุปกรณ์ตามใจตัวเอง จึงต้องตรวจสอบระบบเพื่อดูว่าเป็นอุปกรณ์ชนิดไหน
    ความสม่ำเสมอก็มีประโยชน์อยู่ เลยมีเครื่องมือหลายตัวสำหรับเปลี่ยนชื่ออินเทอร์เฟซ และทุกวันนี้ Linux distribution ส่วนใหญ่ใช้ udev ทำให้เป็นอัตโนมัติ ภายในก็แค่เรียก SIOCSIFNAME ioctl ของเคอร์เนลเท่านั้น เคอร์เนลรุ่นใหม่ยังมีฟีเจอร์ที่ถ้าเปลี่ยนชื่อเป็น "wlan*"—จริง ๆ คือ "wlan%d"—ก็จะจัดสรรหมายเลขใหม่ต่อท้าย "wifi" ให้อัตโนมัติด้วย
    • สงสัยว่าจะสมเหตุสมผลไหมถ้าใช้ NetworkManager บน Android แล้วให้ UI ตั้งค่าไร้สายของ Android ทำงานเหมือน GUI ของ NetworkManager
    • เพราะอุปกรณ์ usbX บางตัวควรให้โมดูลอื่นใช้งาน แต่ไม่อยากต้องมาจัดการรายการนั้น เลยเลือกไปใช้แค่ ethX แทน
  • เรื่องโง่คล้าย ๆ กันเกิดขึ้นตอนพยายามต่อ อุปกรณ์ USB serial เข้ากับสมาร์ตโฟน Android
    พอต่อแล้วดูเหมือนจะทำงานได้ แต่ถ้าจะสร้างแอปที่ใช้อินเทอร์เฟซ USB serial นั้นกลับทำไม่ได้ พอขุดลงไปจะพบว่าไม่มีสิทธิ์เข้าถึงอุปกรณ์ serial อย่าง /dev/ttyACM0
    การรองรับ serial มีอยู่ในเคอร์เนลแล้ว แต่โปรแกรมผู้ใช้เข้าถึงไม่ได้ถ้าไม่ root
    พอขุดต่อไปอีกจะพบว่า Android มีความสามารถเข้าถึง USB จาก user space ที่คล้ายกับ libusb หรืออาจสร้างบน libusb ดังนั้นโปรแกรม Android จึงเปิดอุปกรณ์ USB แบบ “raw” ได้ แต่เปิดอุปกรณ์ serial USB ไม่ได้

USB serial เป็นเพียงโปรโตคอลที่อยู่บน USB เท่านั้น และในทางปฏิบัติก็ใกล้เคียงกับชุดโปรโตคอลกึ่ง proprietary อย่าง FTDI ฯลฯ มากกว่า มีไลบรารีที่ทำได้ครึ่ง ๆ กลาง ๆ สำหรับ Android ซึ่ง implement โปรโตคอลเหล่านี้ใน user space อยู่บ้าง ดังนั้นท้ายที่สุดจึงเข้าถึงอุปกรณ์ USB serial บางตัวได้
ในเบราว์เซอร์ Android Chrome น่าจะเปิดอุปกรณ์ USB แบบ raw ผ่าน WebUSB ได้ แต่ WebSerial มีโอกาสสูงว่าจะใช้ไม่ได้ด้วยเหตุผลเดียวกัน
สุดท้ายสิ่งที่น่าประหลาดใจก็คือ ถ้าเป็นแบบนั้นแล้วจะเปิดการรองรับ USB serial ไว้ในเคอร์เนลทำไม น่าจะเพื่อ debug หรือเปล่า

  • ตราบใดที่ไม่ได้ root โทรศัพท์แล้วเปลี่ยนค่า config_ethernet_iface_regex ก็ไม่มีทางหลีกเลี่ยงปัญหานี้ได้
    นี่เป็นอีกเหตุผลหนึ่งที่ทำให้ สิทธิ์ root สำคัญบนอุปกรณ์ที่ผมเป็นเจ้าของ
    • อย่างไรก็ตาม “การ root” จะตัดฟีเจอร์ความปลอดภัยจำนวนมากของ Android ออกไป แทนที่แอปจะมีเฉพาะ permission ที่จำเป็น มันสามารถมี permission ทั้งหมดในฐานะ root ได้ จึงกลายเป็น ช่องโหว่ด้านความปลอดภัย ขนาดใหญ่
      https://www.reddit.com/r/GrapheneOS/comments/13264di/is_root...
    • การที่สามารถ bypass/redirect ทราฟฟิกเครือข่ายได้ตามใจ อาจเป็นเหตุผลสำคัญที่สุดที่ไม่ควรปล่อยให้มี สิทธิ์ superuser อยู่ใน user space
      ผมสนับสนุนการกดดันให้ OEM อนุญาตการปลดล็อก bootloader แต่เฉพาะบน Android อย่างน้อยก็แทบคิดไม่ออกว่ามี use case ของ root แบบไหนที่สมเหตุสมผลพอจะแลกกับการขยาย attack surface อย่างมหาศาลได้
  • Android น่าหงุดหงิดตรงที่ไม่สามารถเชื่อมต่อหลายเครือข่ายพร้อมกันได้
    เช่น สถานการณ์ที่ใช้ Wi‑Fi ที่ไม่มีอินเทอร์เน็ตและไม่ได้ประกาศ default route พร้อมกับเครือข่าย cellular ในเวลาเดียวกัน Linux ก็ทำได้ Windows ก็ทำได้ แต่ Android ปฏิเสธอย่างดื้อดึง
    หลาย variant ถึงกับปฏิเสธที่จะคงการเชื่อมต่อกับ Wi‑Fi ที่ไม่มีอินเทอร์เน็ตไว้ หรือไม่ก็พาผู้ใช้เข้าสู่ขั้นตอนที่ชวนสับสน ถ้าเขียนแอปเองก็มี API ที่ทำให้ทำได้เฉพาะภายในแอป แต่ผู้ใช้ทั่วไปไม่มีทางทำให้เป็นพฤติกรรมทั้งระบบได้
    • iOS ก็เหมือนกัน เวลาเชื่อมต่อกับกล้องติดรถยนต์เพื่อดาวน์โหลดวิดีโอ ผ่านไปสักพักจะมีป๊อปอัปประมาณว่า “ตรวจไม่พบอินเทอร์เน็ต จะสลับไปใช้ cellular ไหม?”
      แม้กดให้เชื่อมต่อต่อไปก็ไม่มีวิธีปิด และสุดท้าย iOS ก็จะตัดสินเองว่ามันรู้ดีกว่า แล้วเชื่อมต่อกลับไปยังเครือข่าย CarPlay
    • ถ้าถือโทรศัพท์ Android ฝั่งตะวันตกไปจีนแผ่นดินใหญ่จะยิ่งน่าหงุดหงิด เพราะมันตัดสินว่ามีอินเทอร์เน็ตหรือไม่จากการพยายามเชื่อมต่อบริการของ Google
      เมื่อเชื่อมต่อ Wi‑Fi ท้องถิ่น แน่นอนว่ามันผ่าน Great Firewall ไม่ได้ และทุกครั้งก็จะมี prompt ถามว่าจะคงการเชื่อมต่อที่ไม่มีอินเทอร์เน็ตไว้หรือไม่
    • เวลาต่ออินเทอร์เน็ตไม่ได้จะหงุดหงิดมาก เพราะใช้โทรศัพท์ทำ diagnostics ไม่ได้ เนื่องจากมันไม่ยอมเกาะ Wi‑Fi ที่ไม่มีอินเทอร์เน็ตต่อไป
      DNS ของ Android ก็เละเทะเช่นกัน ถ้าไม่ตั้งค่าหลายตัว มันจะพยายามไม่ใช้ DNS ที่ DHCP ให้มา และแม้ทำแบบนั้นแล้ว DNS ภายในบางตัวก็ยังถูกปฏิเสธไม่ให้ resolve
    • ผมสงสัยว่า Windows ก็ทำไม่ได้เหมือนกันหรือเปล่า ใน Windows ถึงจะมี wireless adapter 2 ตัว ก็ไม่สามารถเชื่อมต่อ Wi‑Fi 2 เครือข่ายที่ต่างกันผ่าน GUI ได้ ผมยังไม่ได้ลองผ่าน terminal
  • ต้องตรวจสอบ ข้อกำหนดของ firmware ด้วย อุปกรณ์บางตัวถูก enumerate ได้ แต่ถ้าไม่มี firmware ที่ต้องใช้ ก็จะล้มเหลวตอน ifup
    แน่นอนว่า Android UI จัดการสถานการณ์นี้ไม่ได้ และมีแค่ dmesg เท่านั้นที่บอกได้ว่าเกิดอะไรขึ้น ไม่แน่ใจว่าอุปกรณ์ CDC ต้องใช้สิ่งนี้ด้วยหรือไม่ แต่ผมจำได้ว่า adapter ที่ใช้ชิป Realtek หรือ Kawasaki หลายตัวเป็นแบบนั้น
    อย่างไรก็ตาม การเปลี่ยนแปลงของ Android นี้อาจค่อนข้างใหม่ เพราะเมื่อก่อนผมใช้ dongle เครือข่าย USB กับอุปกรณ์ debug ที่ใช้ AOSP “stock” 100% อยู่บ่อย ๆ หรือไม่ก็อาจเป็นการเปลี่ยนแปลงในเคอร์เนล หรือเป็นพฤติกรรมเฉพาะของไดรเวอร์ CDC ที่ตั้งชื่ออุปกรณ์เป็น usb* ก็ได้ แค่เลือก chipset ของ dongle อย่างระวัง และตรวจให้แน่ใจว่าไม่ต้องใช้ firmware ก็พอ
  • เป็นเส้นทาง debugging ที่ยอดเยี่ยมมาก ผมชอบ flow ที่ regex ตัวเดียวที่ถูกมองข้าม ทำให้ทั้งคลาสของอุปกรณ์พังลง
    แปลกดีที่เมื่อเร็ว ๆ นี้ผมเจอเรื่องที่มีโครงสร้างคล้ายกันมากในบริบทที่ต่างออกไปโดยสิ้นเชิง คือระบบ alignment/escalation ของ OpenAI ผมพยายาม trigger การ escalation routing อย่างเป็นทางการ (SR-Route_Breach_1stOrder) ภายในตรรกะ recursive ของ GPT-4 พร้อมเอกสารและ log ครบถ้วน แต่ถึงโครงสร้างจะดูสมเหตุสมผล สุดท้ายก็ได้แต่คำตอบที่ไม่เป็นมนุษย์
    พูดอีกอย่างคือ escalation ของผมเหมือนไม่ match กับ regex ของ internal interface ภายในระบบ
    ผมสรุปเคสทั้งหมดไว้ที่นี่: https://news.ycombinator.com/item?id=44221458
    ถ้าสนใจเรื่องขอบเขตเชิงโครงสร้างและสัญญา interface ที่มองไม่เห็น ก็อยากฟังความคิดเห็น
  • แปลกมาก ผมมี USB Ethernet adapter อยู่ประมาณ 15 ตัว และทุกตัวทำงานได้ดี
    แน่ใจว่ามี chipset หลายแบบปนกัน ทั้ง Realtek และ AXIS หรือคล้าย ๆ กัน ถ้าเลือกผลิตภัณฑ์ที่ไม่ต้องใช้ไดรเวอร์บน Linux ก็มักจะใช้ได้ดีแทบทุกระบบปฏิบัติการหรือ BIOS
    • แก้ไขแล้วในปี 2023: https://news.ycombinator.com/item?id=44219502
    • ผมกำลังจะมาบอกว่า Ethernet adapter ใน Thunderbolt/USB dock ของผมก็ทำงานได้ดีไม่มีปัญหาทั้งบน Pixel 5 และ Pixel 9