in system/ymodem/ymodem.c [336:539]
static int ymodem_send_file(FAR struct ymodem_ctx_s *ctx)
{
uint16_t crc;
int retries;
int ret;
ymodem_debug("waiting handshake\n");
for (retries = 0; retries < MAX_RETRIES; retries++)
{
ret = ymodem_recv_cmd(ctx, CRC);
if (ret >= 0)
{
break;
}
}
if (retries >= MAX_RETRIES)
{
ymodem_debug("waiting handshake error\n");
return -ETIMEDOUT;
}
ymodem_debug("ymodem send file start\n");
send_start:
ctx->packet_type = YMODEM_FILENAME_PACKET;
ret = ctx->packet_handler(ctx);
if (ret < 0)
{
goto send_last;
}
ymodem_debug("sendfile filename:%s filelength:%zu\n",
ctx->file_name, ctx->file_length);
sprintf((FAR char *)ctx->data, "%s%c%zu", ctx->file_name,
'\0', ctx->file_length);
ctx->header[0] = SOH;
ctx->header[1] = 0x00;
ctx->header[2] = 0xff;
ctx->packet_size = YMODEM_PACKET_SIZE;
crc = crc16(ctx->data, ctx->packet_size);
ctx->data[ctx->packet_size] = crc >> 8;
ctx->data[ctx->packet_size + 1] = crc;
send_name:
ret = ymodem_send_buffer(ctx, ctx->header, 3 + ctx->packet_size + 2);
if (ret < 0)
{
ymodem_debug("send name packet error\n");
return ret;
}
ret = ymodem_recv_cmd(ctx, ACK);
if (ret == -EAGAIN)
{
ymodem_debug("send name packet recv NAK, need send again\n");
goto send_name;
}
if (ret < 0)
{
ymodem_debug("send name packet, recv error cmd\n");
return ret;
}
ret = ymodem_recv_cmd(ctx, CRC);
if (ret == -EAGAIN)
{
ymodem_debug("send name packet recv NAK, need send again\n");
goto send_name;
}
if (ret < 0)
{
ymodem_debug("send name packet, recv error cmd\n");
return ret;
}
ctx->packet_type = YMODEM_DATA_PACKET;
send_packet:
if (ctx->file_length <= YMODEM_PACKET_SIZE)
{
ctx->header[0] = SOH;
ctx->packet_size = YMODEM_PACKET_SIZE;
}
else if (ctx->custom_size != 0)
{
ctx->header[0] = STC;
ctx->packet_size = ctx->custom_size;
}
else
{
ctx->header[0] = STX;
ctx->packet_size = YMODEM_PACKET_1K_SIZE;
}
ymodem_debug("packet_size is %zu\n", ctx->packet_size);
ctx->header[1]++;
ctx->header[2]--;
ret = ctx->packet_handler(ctx);
if (ret < 0)
{
return ret;
}
crc = crc16(ctx->data, ctx->packet_size);
ctx->data[ctx->packet_size] = crc >> 8;
ctx->data[ctx->packet_size + 1] = crc;
send_packet_again:
ret = ymodem_send_buffer(ctx, ctx->header, 3 + ctx->packet_size + 2);
if (ret < 0)
{
ymodem_debug("send data packet error\n");
return ret;
}
ret = ymodem_recv_cmd(ctx, ACK);
if (ret == -EAGAIN)
{
ymodem_debug("send data packet recv NAK, need send again\n");
goto send_packet_again;
}
if (ret < 0)
{
ymodem_debug("send data packet, recv error\n");
return ret;
}
if (ctx->file_length != 0)
{
ymodem_debug("The remain bytes sent are %zu\n", ctx->file_length);
goto send_packet;
}
send_eot:
ctx->header[0] = EOT;
ret = ymodem_send_buffer(ctx, ctx->header, 1);
if (ret < 0)
{
ymodem_debug("send EOT error\n");
return ret;
}
ret = ymodem_recv_cmd(ctx, ACK);
if (ret == -EAGAIN)
{
ymodem_debug("send EOT recv NAK, need send again\n");
goto send_eot;
}
if (ret < 0)
{
ymodem_debug("send EOT, recv ACK error\n");
return ret;
}
ret = ymodem_recv_cmd(ctx, CRC);
if (ret == -EAGAIN)
{
ymodem_debug("send EOT recv NAK, need send again\n");
goto send_eot;
}
if (ret < 0)
{
ymodem_debug("send EOT, recv CRC error\n");
return ret;
}
goto send_start;
send_last:
ctx->header[0] = SOH;
ctx->header[1] = 0x00;
ctx->header[2] = 0xff;
ctx->packet_type = YMODEM_DATA_PACKET;
ctx->packet_size = YMODEM_PACKET_SIZE;
memset(ctx->data, 0, YMODEM_PACKET_SIZE);
crc = crc16(ctx->data, ctx->packet_size);
ctx->data[ctx->packet_size] = crc >> 8;
ctx->data[ctx->packet_size + 1] = crc;
send_last_again:
ret = ymodem_send_buffer(ctx, ctx->header, 3 + ctx->packet_size + 2);
if (ret < 0)
{
ymodem_debug("send last packet error\n");
return ret;
}
ret = ymodem_recv_cmd(ctx, ACK);
if (ret == -EAGAIN)
{
ymodem_debug("send last packet, need send again\n");
goto send_last_again;
}
if (ret < 0)
{
ymodem_debug("send last packet, recv error\n");
return ret;
}
return 0;
}