You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ADB Pull数据包格式正确性排查及传输卡顿问题咨询

ADB Pull数据包格式正确性排查及传输卡顿问题咨询

我现在在基于开源USB栈的嵌入式RTOS系统上开发ADB文件拉取(pull)功能,参考ADB协议文档实现后遇到了奇怪的卡顿问题:执行adb.exe pull /data/adbd C:/work/时,命令卡在55%的进度(目标文件大小118284字节),换成6MB的大文件测试,会直接卡在1%左右——仔细看了下,两个场景都是卡在传输了约65536字节的节点。

捕获的关键数据包交互

我用Wireshark抓了PC和设备的交互包,核心流程如下:

1. PC发送RECV请求

0000  1b 00 10 c0 05 7c 01 98 ff ff 00 00 00 00 09 00   .....|..........
0010  00 02 00 37 00 02 03 12 00 00 00 52 45 43 56 0a   ...7.......RECV.
0020  00 00 00 2f 64 61 74 61 2f 61 64 62 64            .../data/adbd

2. 设备响应的初始OKAY+文件大小

0000  1b 00 e0 ba 9b 55 01 98 ff ff 00 00 00 00 09 00   .....U..........
0010  01 02 00 37 00 81 03 18 00 00 00 4f 4b 41 59 02   ...7.......OKAY.
0020  00 00 00 cf 00 00 00 00 00 00 00 00 00 00 00 b0   ................
0030  b4 be a6                                          ...

3. PC发送WRTE指令请求数据

0000  1b 00 e0 ba 9b 55 01 98 ff ff 00 00 00 00 09 00   .....U..........
0010  01 02 00 37 00 81 03 18 00 00 00 57 52 54 45 02   ...7.......WRTE.
0020  00 00 00 cf 00 00 00 08 00 00 00 1b 01 00 00 a8   ................
0030  ad ab ba                                          ...

4. 设备发送的第一个DATA数据包

0000  1b 00 e0 ba 9b 55 01 98 ff ff 00 00 00 00 09 00   .....U..........
0010  01 02 00 37 00 81 03 20 08 00 00 7f 45 4c 46 01   ...7... ....ELF.
0020  01 01 00 03 00 00 00 00 00 00 00 02 00 08 00 01   ................
0030  00 00 00 b0 1c 40 00 34 00 00 00 e4 c8 01 00 05   .....@.4........

Wireshark显示该包总长度2107字节,其中有效数据2080字节,和我设置的分块大小一致。

5. 设备发送的DONE数据包及后续交互

0000  1b 00 e0 ba 9b 55 01 98 ff ff 00 00 00 00 09 00   .....U..........
0010  01 02 00 37 00 81 03 08 00 00 00 44 4f 4e 45 00   ...7.......DONE.
0020  00 00 00                                          ...

从抓包来看,设备已经发送了全部文件内容和DONE指令,但PC端始终卡在进度条,也没有发送CLSE指令关闭会话。

核心疑问

  • 我设备返回的初始OKAY+文件大小数据包格式是否正确?
  • 设备发送的DATA分块数据包是否符合ADB协议要求?
  • 为什么PC端在接收约65536字节后就卡住,不发送后续WRTE请求,也不发送CLSE指令?
  • ADB Pull流程中,正确的数据包交互格式应该是怎样的?

我的代码实现(发送数据分块的核心函数)

void usbd_adb_send_sync_data_chunk(uint8_t *buf, uint32_t data_size)
{
    if (!buf || data_size == 0) {
        return;
    }

    if (data_size > sizeof(tx_packet.payload)) {
        USB_LOG_ERR("SYNC DATA chunk too large: %u\n", data_size);
        return;
    }

    tx_packet.msg.command = A_WRTE;
    tx_packet.msg.arg0 = ADB_SYNC_LOALID;
    tx_packet.msg.arg1 = remoteid;
    tx_packet.msg.data_length = data_size;
    memcpy(tx_packet.payload, buf, data_size);

    usbd_adb_send_msg(&tx_packet);
    return;
}

static void adbd_send_file_data(void)
{
    int rc;
    static uint32_t tot = 0;

    rc = read(g_usbd_adbd->fd, file_buf, ADB_FILE_BUF_SIZE);
    if (rc > 0) {
        usbd_adb_send_sync_data_chunk(file_buf, (uint32_t)rc);
        tot += rc;
    } else {
        g_usbd_adbd->state = SYNC_FILE_DONE;
        usbd_adb_send_sync_done();
        if (g_usbd_adbd->fd >= 0) {
            close(g_usbd_adbd->fd);
        }
        g_usbd_adbd->fd = -1;
        printf("total = %d, rc: %d, sent done\n", tot, rc);
        tot = 0;
    }
}

另外我还发现,24KB左右的小文件可以正常传输完成,PC会正常发送CLSE指令,只有超过64KB的文件才会出现这个问题,感觉和ADB协议中单个DATA包的最大理论大小(65536字节)有关,但我明明是分2080字节的小块发送的,实在搞不懂哪里出问题了。

火山引擎 最新活动