⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsdiag.c

📁 free sources for gsm
💻 C
📖 第 1 页 / 共 3 页
字号:
   Check for valid packet length.
  --------------------------------*/
  if (pkt_len != req->filename_info.len         + 
                 sizeof(req->filename_info.len) +
                 sizeof(req->creation_date)     +
                 sizeof(req->attribs))
  {
      return (diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len));
  }

  FS_DIAG_VALIDATE_ACCESS( SET_ATTRIB, (const char *)req->filename_info.name );

  rsp = (fsdiag_rsp_pkt_type *) diagpkt_alloc (DIAG_FS_OP_F, rsp_len);
                                
  /*---------------------------------------------------------------
   Since not all attributes will be externally settable via DIAG, 
   we need to get the existing attributes to set them back.
  ---------------------------------------------------------------*/
  if (req->creation_date == 0xFFFFFFFF) 
  {
    fs_get_attribs_rsp_type get_rsp;

    fs_get_file_attributes((const char *)req->filename_info.name,
                           NULL,
                           (fs_rsp_msg_type *) &get_rsp);

    if (get_rsp.status == FS_OKAY_S)
    {
      req->creation_date = get_rsp.creation_date;
    }
    else
    {
      rsp->fs_status = fs_rsp.set_attribs.status;
      return (rsp);
    }
  }

  fs_set_file_attributes(
    (const char *)req->filename_info.name, /* Absolute dir name  */
    (fs_attribute_mask_type) req->attribs.attribute_mask,
    (fs_file_date_type) req->creation_date,
    (fs_buffering_option_type) req->attribs.buffering_option,
    (fs_cleanup_option_type) req->attribs.cleanup_option,
    NULL,
    &fs_rsp);
  
  rsp->fs_status = fs_rsp.set_attribs.status;
    
  return (rsp);

} /* fsdiag_set_attrib */
      
      

/*===========================================================================

FUNCTION FSDIAG_READ
DESCRIPTION
  This function handles FS read commands in DIAG.

============================================================================*/
static PACKED void *fsdiag_read (
  fsdiag_read_req_type *req,
  word pkt_len
)
{                                                                         
  fs_rsp_msg_type            fs_rsp;  /* Response from FS task             */
  fsdiag_data_block_type *data_ptr;  /* Pointer to data block in packet   */
  
  static byte      next_seq_num = 0;  /* Expected next seqeunce number.    */
  static fs_file_position_type last_pos = 0xFFFFFFFF;
  word             expected_pkt_len;  /* Used to calculate packet length   */
  fsdiag_rsp_pkt_type *rsp;
  word rsp_len = FPOS(fsdiag_rsp_pkt_type, fs_rsp);                      
  
  /* Keep progress stats
  */
  static dword           read_so_far;      
  static dword     total_file_length;

  fs_rsp.any.status = FS_FAIL_S; /* Init to be a generic failure. */

  /* Do all error checking first
  */
  if (req->seq_num == 0) 
  {

    FS_DIAG_VALIDATE_ACCESS( READ, (const char *)req->filename_info.name );

    /*--------------------------------
     Check for valid packet length.
    --------------------------------*/
    expected_pkt_len = 
      sizeof(req->seq_num)           + 
      sizeof(req->filename_info.len) + 
      req->filename_info.len;

    if (pkt_len != expected_pkt_len) 
    {
      return (diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len));
    }
  }
  else if (next_seq_num == req->seq_num)
  {
    /*--------------------------------
     Check for valid packet length.
    --------------------------------*/
    expected_pkt_len = sizeof(req->seq_num);

    if (pkt_len != expected_pkt_len) 
    {
      fsdiag_cleanup();
      next_seq_num = 0;

      return (diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len));
    }
  }
  else /* Bad sequence number */
  {
    if (req->seq_num == (next_seq_num - 1) || 
        ((req->seq_num - next_seq_num) >= 254) ) // Trying a retry
    {
      // Set the next sequence number to the current seq number 
      next_seq_num = req->seq_num;

      /* Reset the file position to last successful. */
      fs_seek (fsdiag_handle, FS_SEEK_SET, last_pos, NULL, &fs_rsp);

      if (fs_rsp.seek.status != FS_OKAY_S)
      {
        fsdiag_cleanup();
        next_seq_num = 0;

        return (diagpkt_err_rsp(DIAG_BAD_PARM_F, req, pkt_len));
      }
    }
    else 
    {
      fsdiag_cleanup();
      next_seq_num = 0;

      return (diagpkt_err_rsp(DIAG_BAD_PARM_F, req, pkt_len));
    }
  } /* if seq num 0 */

    /*--------------------------------------
   Allocate max size, then shorten later.
  --------------------------------------*/
  rsp = (fsdiag_rsp_pkt_type *)
    diagpkt_alloc(DIAG_FS_OP_F, rsp_len + FSIZ(fsdiag_rsp_type, read));
                                
  rsp->fs_rsp.read.seq_num = req->seq_num;

  /* Initialize to success */
  fs_rsp.any.status = FS_OKAY_S;

  /*-------------------------------------------------
    Check if this is to start a new file 
    transfer, or continue an old one.
  -------------------------------------------------*/
do
{
  if (req->seq_num == 0) 
  {
    /*---------------------------------------------
     Initialize local vars.
    ---------------------------------------------*/
    fsdiag_cleanup();

    total_file_length = 0;
    read_so_far       = 0;

    /*----------------------------
     Open file for writing.
    ----------------------------*/
    fs_open((const char *)req->filename_info.name, FS_OA_READONLY, NULL, NULL, &fs_rsp);
   
    /* Save handle for subsequent reads */
    if ((fsdiag_handle = fs_rsp.open.handle) == NULL || 
        fs_rsp.any.status != FS_OKAY_S) 
    {
      fsdiag_cleanup();
      next_seq_num = 0;

      rsp->fs_status = fs_rsp.open.status;

      break;
    }
    else
    {
      last_pos = 0;
    }

    /*-----------------------------------------------
     Save file name info for possible cleanup later
    -----------------------------------------------*/
    memcpy (fsdiag_filename, 
            (void *) req->filename_info.name,
            req->filename_info.len);

    /*-------------------------------------------
     Store operation for open file for cleanup.
    -------------------------------------------*/
    fsdiag_op = FSDIAG_READ;

    /*--------------------
     Record total length
    --------------------*/
    fs_file_size(fsdiag_filename, NULL, &fs_rsp);

    if (fs_rsp.file_size.status != FS_OKAY_S) 
    {
      fsdiag_cleanup();
      next_seq_num = 0;
      
      rsp->fs_status = fs_rsp.file_size.status;

      break;
    }
    
    rsp->fs_rsp.read.data.begin.total_length = 
      total_file_length = fs_rsp.file_size.size;

    /*----------------------------------------
      Update response length when successful
    ----------------------------------------*/
    rsp_len += sizeof(rsp->fs_rsp.read.data.begin.total_length);

    /*----------------------------------------
      Set pointer to beginning of data block
    ----------------------------------------*/
    data_ptr = (fsdiag_data_block_type*) 
               &rsp->fs_rsp.read.data.begin.block;

  }
  else /* Seqeunce num != 0 */
  {
    data_ptr = (fsdiag_data_block_type*) 
                 &rsp->fs_rsp.read.data.block;
  }
  
  /* Record position prior to this read. */
  fs_tell (fsdiag_handle, NULL, &fs_rsp);
  
  if (fs_rsp.tell.status == FS_OKAY_S)
  {
    last_pos = fs_rsp.tell.position;
    
    /* Go ahead and read. */
    fs_read(fsdiag_handle,
            (void*)&data_ptr->data,
            FSDIAG_MAX_FILE_BLOCK_SIZE,
            NULL,
            &fs_rsp);
  }
  
  rsp->fs_status = fs_rsp.any.status;
  
  if (fs_rsp.any.status != FS_OKAY_S) 
  {
    fsdiag_cleanup();
    next_seq_num = 0;
  }
  else
  {
    data_ptr->len = (word) fs_rsp.read.count;

    /*-------------------------------------------------------------- 
      Calculate response length.  It already has the value for the 
      preliminary data such as status, so just add block length. 
    --------------------------------------------------------------*/
    rsp_len += FPOS(fsdiag_read_rsp_type, data) +
               data_ptr->len                    +
               sizeof(data_ptr->len);

    read_so_far += data_ptr->len;

    /*----------------------------------------------------------
      Check if we read an expected amount, and determine if we 
      need more blocks to complete the transfer. 
    ----------------------------------------------------------*/
    if (read_so_far < total_file_length)
    {
      rsp->fs_rsp.read.more = TRUE;
      
      /* Must handle sequence number rollover */
      next_seq_num = (next_seq_num == 0xFF) ? 1 : next_seq_num + 1;
    }
    else
    {
      rsp->fs_rsp.read.more = FALSE;
    }
  
    if (rsp->fs_rsp.read.more == FALSE)
    {
      fsdiag_cleanup();
      next_seq_num = 0;
    }
  }

} while(0);

  diagpkt_shorten(rsp, rsp_len);

  return (rsp);
} /* fsdiag_read */
      
      

/*===========================================================================

FUNCTION FSDIAG_WRITE
DESCRIPTION
  This function handles FS write commands in DIAG.
  
============================================================================*/
static PACKED void *fsdiag_write (
  fsdiag_write_req_type *req,
  word pkt_len
)
{
  fs_open_xparms_type fs_open_xparms; /* Open and truncate parms          */
  fs_rsp_msg_type     fs_rsp;         /* Response from FS task            */
  fsdiag_data_block_type *data_ptr;  /* Pointer to data block in packet  */
  static byte next_seq_num = 0;       /* Expected next seqeunce number.   */
  word expected_pkt_len;              /* Used to calculate packet length  */
  fsdiag_rsp_pkt_type *rsp;
  word rsp_len = FPOS(fsdiag_rsp_pkt_type, fs_rsp) + 
                 sizeof(fsdiag_write_rsp_type);
                                                                           
  /*--------------------------------------------------- 
   Keep progress stats for multiple packet operations 
  ---------------------------------------------------*/
  static dword written_so_far;
  static dword total_file_length;

  /*------------------------------
   Do all error checking first
  ------------------------------*/
  if (req->seq_num == 0) 
  {
    FS_DIAG_VALIDATE_ACCESS( WRITE,
       (const char *)req->block.begin.var_len_buf.name_info.name );

    /*--------------------------------
     Check for valid packet length.
    --------------------------------*/
    data_ptr = (fsdiag_data_block_type *) 
      &(req->block.begin.var_len_buf.raw_data[ 
        req->block.begin.var_len_buf.name_info.len + 
        sizeof (req->block.begin.var_len_buf.name_info.len)]);

    expected_pkt_len = 
      sizeof(req->seq_num)                               + 
      sizeof(req->more)                                  +
      sizeof(req->block.begin.mode)                      + 
      sizeof(req->block.begin.total_length)              +
      sizeof(req->block.begin.attrib)                    + 
      sizeof(req->block.begin.var_len_buf.name_info.len) +
      req->block.begin.var_len_buf.name_info.len         + 
      sizeof(data_ptr->len)                                  +
      data_ptr->len;

    if (pkt_len != expected_pkt_len) 
    {
      next_seq_num = 0;
      return( diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len) );
    }
  } /* Sequence number == 0 */
  else if (next_seq_num == req->seq_num)
  {
    /*----------------------------------------
      Assign data_ptr to request data block 
    ----------------------------------------*/
    data_ptr = &req->block.subseq;
      
    /*--------------------------------
     Check for valid packet length.
    --------------------------------*/
    expected_pkt_len = sizeof(req->seq_num)          +
                       sizeof(req->more)             +
                       sizeof(req->block.subseq.len) + 
                       req->block.subseq.len;

    if (pkt_len != expected_pkt_len) 
    {
      next_seq_num = 0;
      return( diagpkt_err_rsp(DIAG_BAD_LEN_F, req, pkt_len) );
    }
  }
  else /* Bad sequence number */
  {
    fsdiag_cleanup();
    next_seq_num = 0;
    
    return( diagpkt_err_rsp(DIAG_BAD_PARM_F, req, pkt_len) );
  }
                                      
  rsp = (fsdiag_rsp_pkt_type *)diagpkt_alloc(DIAG_FS_OP_F, rsp_len);

  rsp->fs_rsp.write.seq_num = req->seq_num;

  /*------------------------------------------------------------------
    For starters, check if this is to start a new file transfer, or 
    continue an old one.  Also, verify packet length.
  ------------------------------------------------------------------*/
  do
  {
    if (req->seq_num == 0) 
    {
      /*--------------------------------------------------- 
        Make sure the length of the data block is valid.
      ---------------------------------------------------*/
      if (data_ptr->len > FSDIAG_MAX_FILE_BLOCK_SIZE)
      {
        fs_rsp.any.status = FS_PARAMETER_ERROR_S;
        break;
      }
  
      /*------------------------------------------------------
        We are starting a new file.  Clean up any old files.
      ------------------------------------------------------*/
      fsdiag_cleanup();
        
      total_file_length = 0;
      written_so_far = 0;
      next_seq_num = 0;
      
      /*----------------------------------------------
       Set default attributes for new file.
       External device may change attributes later.
      ----------------------------------------------*/                 
      fs_open_xparms.create.attribute_mask   = 
        (fs_attribute_mask_type) req->block.begin.attrib.attribute_mask;
  
      fs_open_xparms.create.cleanup_option   = 
        (fs_cleanup_option_type) req->block.begin.attrib.cleanup_option;
  
      fs_open_xparms.create.buffering_option = 
        (fs_buffering_option_type) req->block.begin.attrib.buffering_option;
  
      /*----------------------------
       Open file for writing.
      ----------------------------*/
      fs_open((const char *)req->block.begin.var_len_buf.name_info.name, 
              FS_OA_CREATE, 
              &fs_open_xparms, 
              NULL, 
              &fs_rsp);
     
      /*----------------------------------------------
       If overwrite option is specified, recover by 
       removing file and re-opening.
      ----------------------------------------------*/
      if (fs_rsp.open.status == FS_FILE_ALREADY_EXISTS_S &&
          req->block.begin.mode == FSDIAG_OVERWRITE) 
      {
        fs_remove((const char *)req->block.begin.var_len_buf.name_info.name, 
                  NULL, 
                  &fs_rsp);
  
        if (fs_rsp.rmfile.status == FS_OKAY_S)
        {
          /* Now try again */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -