硬件输入后端(ESP32 HID)
除了软件注入,Gomaton 还有一条硬件出手后端:决策(找图 / YOLO / OCR / LLM 算坐标)不变,只把最后的 touch 从软件注入换成一块 ESP32-S3 当 USB HID 设备,直接在手机上产生真实触摸。
定位:硬件后端是"软件注入被某些 ROM 堵死时"的兜底,以及测试用途。能软件注入的机器,无线控制仍走设备端 agent。用途限自有设备自动化 / 兼容性兜底 / 测试。
从命令到真手指
关键不在板子发了什么,而在它汇入了哪条路。板子并不是"模拟点击",而是声明自己是一块触摸屏;手机内核把它的报告和内建触摸屏的报告丢进同一条流水线。
真手指 控制端 (server / curl)
│ 物理接触 │ HTTP /tap?x=0.5&y=0.5 (WiFi/热点)
▼ ▼
电容触摸屏芯片 ESP32 板子
(ft5435_ts) 解析命令 → 组装 HID 报告
│ I²C 上报坐标 │ USB HID 报告 [标志,触点号,X,Y,触点数]
└────────────────┬────────────────┘
▼
┌─────────────────────────────────────────┐
│ 手机内核 · input 子系统 │ ← 两条路在这里合流
│ /dev/input/eventX (ABS_MT 触摸事件) │ 往上,系统再也分不出
└─────────────────────────────────────────┘ 是手指还是板子
│ 同一种触摸事件
▼
Android 输入框架 (InputReader → InputDispatcher)
│ MotionEvent ACTION_DOWN / UP
▼
前台 App 收到点击 → 按钮被按下
这一句是关键:从合流点(内核 input 子系统)往上,App、系统、风控看到的都是一次标准触摸事件——没有"这是外接设备"的标记,和手指一模一样。这也是市面成熟 HID 方案的同一套机制:声明 HID 描述符 → 发报告 → 目标机内核转成输入事件。
一次 tap 拆开来
| 步骤 | 发生了什么 |
|---|---|
| ① 控制端发命令 | server / 浏览器 / curl 通过 WiFi 发 /tap?x=0.5&y=0.5(坐标归一化 0~1) |
| ② 板子翻译 | 把 tap(0.5,0.5) 拆成两帧:手指按下 + 手指抬起;坐标乘到 0~32767 |
| ③ 组装报告 | 按触摸屏描述符格式拼成字节 [标志 · 触点号 · X · Y · 触点数] |
| ④ USB 送出 | 经原生 USB 口用 HID 中断传输发给作为 USB 主机的手机(OTG) |
| ⑤ 内核转事件 | 手机 hid-multitouch 驱动认得格式,生成 /dev/input 的 ABS_MT 触摸事件 |
| ⑥ App 收到点击 | Android 变成 MotionEvent 分给前台窗口,按钮响应 |
报告里到底是什么
以 tap 0.5 0.5 的"按下"帧为例(单指):
| 字节 | 字段 | 值 | 含义 |
|---|---|---|---|
| 0 | 标志位 | 0x03 | Tip Switch(接触)+ In Range(悬停)= 手指按着 |
| 1 | 触点号 | 0x00 | 第 0 根手指(多指时区分是哪根) |
| 2–3 | X 坐标 | 0x00 0x40 | 16384 = 0.5 × 32767(小端) |
| 4–5 | Y 坐标 | 0x00 0x40 | 同上,屏幕正中 |
| 6 | 触点数 | 0x01 | 这一帧有 1 根手指在屏上 |
紧接着的"抬起"帧只是把标志位与触点数清零。滑动就是按下后连发一串坐标递增的帧再抬起;双指缩放就是每帧带两组触点。
命令接口(HTTP GET)
板子在同一个端口上自动识别 HTTP 与裸文本命令;坐标一律 0.0~1.0。
| 动作 | 接口 |
|---|---|
| 点击 / 双击 / 长按 | /tap?x=&y= /doubletap?x=&y= /longpress?x=&y=[&ms=800] |
| 滑动 | /swipe?n=5[&dir=down|up|left|right][&ms=400][&gap=500] 或 /swipe?x1=&y1=&x2=&y2= |
| 拖动 | /down?x=&y= /move?x=&y= /up |
| 双指缩放 | /pinch?x=&y=&dir=in|out[&ms=400] |
| 实体 / 媒体键 | /key?name=back|home|recents|volup|voldown|mute|play|power… |
| 英文打字 | /text?s=hello+world(中文打不了,走软件输入法) |
| 测活 | /ping |
板子没配 WiFi 时会自开热点(SSID = 配置的 name,IP 192.168.4.1),电脑 / 手机连上即可发命令;配了 WiFi 就连路由。
现状与取舍(真机实测)
| 传输 | 手机看到 | 结论 |
|---|---|---|
| USB OTG(多点 digitizer) | 真手指、多指 | ✅ 已实锤(小米 5X / A8.1:点击 / 双击 / 长按 / 滑动 / 双指缩放全灵);描述符用 Win8 合规多点格式 |
| 蓝牙 BLE HID | —— | ❌ 三形态(触摸 / 绝对鼠标 / 相对鼠标)该 ROM 都不路由 BLE HID 输入;且 ESP32-S3 无经典蓝牙 → 无可用无线通道 |
| Consumer 媒体键 | 返回 / 主页 / 音量 | ⚠️ 逐 ROM,小米 5X / A8.1 不认;这类机型的返回 / 主页应改用触摸(导航栏坐标或手势) |
能做 / 不能做:凡手指能做的全能做(单指已通、双指缩放已封);实体键 + 英文打字靠键盘 / Consumer HID(逐 ROM);中文输入打不了(走软件输入法);看屏(截图 / 控件树 / OCR)板子管不了,感知仍靠手机自己的 agent。
无线真触摸的成熟解是设备端软件 agent(手机内注入 + WiFi),不是这块板;板子只做"软件被封时的 USB 兜底"。固件与描述符见仓库
agent-esp32S3/(otg/src/main.cpp的描述符与tap()/swipe(),命令层common/netcmd.h)。