static int ymodem_send_file()

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;
}