int recv_hid()

in uf2tool/tool.c [57:93]


int recv_hid(HID_Dev *pkt, int timeout) {
    uint8_t buf0[EP_SIZE + 1];
    uint8_t *buf;

    pkt->size = 0;
    memset(pkt->buf, 0, sizeof(pkt->buf));

    for (;;) {
        int sz = hid_read_timeout(pkt->dev, buf0, sizeof(buf0), timeout);
        if (sz <= 0) {
            if (timeout < 0)
                fatal("read error");
            return 0;
        }
        buf = buf0;
        if (!*buf)
            buf++; // skip report number if passed

        uint8_t tag = buf[0];
        if (pkt->size && (tag & HF2_FLAG_SERIAL_OUT))
            fatal("invalid serial transfer");
        uint32_t newsize = pkt->size + (tag & HF2_SIZE_MASK);
        if (newsize > sizeof(pkt->buf))
            fatal("too large packet");
        memcpy(pkt->buf + pkt->size, buf + 1, tag & HF2_SIZE_MASK);
        pkt->size = newsize;

        tag &= HF2_FLAG_MASK;
        if (tag != HF2_FLAG_CMDPKT_BODY) {
            pkt->serial = //
                tag == HF2_FLAG_SERIAL_OUT ? 1 : tag == HF2_FLAG_SERIAL_ERR ? 2 : 0;
            return 1;
        }

        timeout = -1; // next read is blocking
    }
}