Skip to content

Commit

Permalink
Fix nasa#441, cf delete files during error when tx
Browse files Browse the repository at this point in the history
Fix nasa#441, Update to handle error during tx.
1. For polling, the file gets moved or deleted to pervent infinite loop
2. For others, the file does not get deleted.
  • Loading branch information
Anh D Van committed May 17, 2024
1 parent 12eff1c commit e187427
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 26 deletions.
1 change: 1 addition & 0 deletions config/default_cf_tblstruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ typedef struct CF_ConfigTable
uint16 outgoing_file_chunk_size; /**< \brief maximum size of outgoing file data chunk in a PDU.
* Limited by CF_MAX_PDU_SIZE minus the PDU header(s) */
char tmp_dir[CF_FILENAME_MAX_PATH]; /**< \brief directory to put temp files */
char fail_dir[CF_FILENAME_MAX_PATH]; /**< \brief fail directory */
} CF_ConfigTable_t;

#endif
126 changes: 100 additions & 26 deletions fsw/src/cf_cfdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1604,9 +1604,7 @@ void CF_CFDP_CycleEngine(void)
*-----------------------------------------------------------------*/
void CF_CFDP_ResetTransaction(CF_Transaction_t *txn, int keep_history)
{
char * filename;
char destination[OS_MAX_PATH_LEN];
osal_status_t status = OS_ERROR;

CF_Channel_t *chan = &CF_AppData.engine.channels[txn->chan_num];
CF_Assert(txn->chan_num < CF_NUM_CHANNELS);

Expand All @@ -1624,31 +1622,10 @@ void CF_CFDP_ResetTransaction(CF_Transaction_t *txn, int keep_history)
if (OS_ObjectIdDefined(txn->fd))
{
CF_WrappedClose(txn->fd);

if (!txn->keep)
{
if (CF_CFDP_IsSender(txn))
{
/* If move directory is defined attempt move */
if (CF_AppData.config_table->chan[txn->chan_num].move_dir[0] != 0)
{
filename = strrchr(txn->history->fnames.src_filename, '/');
if (filename != NULL)
{
snprintf(destination, sizeof(destination), "%s%s",
CF_AppData.config_table->chan[txn->chan_num].move_dir, filename);
status = OS_mv(txn->history->fnames.src_filename, destination);
}
}

if (status != OS_SUCCESS)
{
OS_remove(txn->history->fnames.src_filename);
}
}
else
{
OS_remove(txn->history->fnames.dst_filename);
}
CF_CFDP_HandleNotKeepFile(txn);
}
}

Expand Down Expand Up @@ -1845,3 +1822,100 @@ void CF_CFDP_DisableEngine(void)
CFE_SB_DeletePipe(chan->pipe);
}
}

/*----------------------------------------------------------------
*
* Application-scope internal function
* See description in cf_cfdp.h for argument/return detail
*
*-----------------------------------------------------------------*/
bool CF_CFDP_IsPollingDir(const char * src_file, uint8 chan_num)
{
bool return_code = false;
char src_dir[CF_FILENAME_MAX_LEN] = "\0";
CF_ChannelConfig_t *cc;
CF_PollDir_t * pd;
int i;

char * last_slash = strrchr(src_file, '/');
if(last_slash != NULL)
{
strncpy(src_dir, src_file, last_slash - src_file);
}

cc = &CF_AppData.config_table->chan[chan_num];
for (i = 0; i < CF_MAX_POLLING_DIR_PER_CHAN; ++i)
{
pd = &cc->polldir[i];
if(strcmp(src_dir, pd->src_dir) == 0)
{
return_code = true;
break;
}
}

return return_code;
}

/*----------------------------------------------------------------
*
* Application-scope internal function
* See description in cf_cfdp.h for argument/return detail
*
*-----------------------------------------------------------------*/
void CF_CFDP_HandleNotKeepFile(CF_Transaction_t *txn)
{
/* Sender */
if (CF_CFDP_IsSender(txn))
{
if(!CF_TxnStatus_IsError(txn->history->txn_stat))
{
/* If move directory is defined attempt move */
CF_CFDP_MoveFile(txn->history->fnames.src_filename, CF_AppData.config_table->chan[txn->chan_num].move_dir);
}
else
{
/* file inside an polling directory */
if(CF_CFDP_IsPollingDir(txn->history->fnames.src_filename, txn->chan_num))
{
/* If fail directory is defined attempt move */
CF_CFDP_MoveFile(txn->history->fnames.src_filename, CF_AppData.config_table->fail_dir);
}
}
}
/* Not Sender */
else
{
OS_remove(txn->history->fnames.dst_filename);
}
}


/*----------------------------------------------------------------
*
* Application-scope internal function
* See description in cf_cfdp.h for argument/return detail
*
*-----------------------------------------------------------------*/
void CF_CFDP_MoveFile(const char *src, const char *dest_dir)
{
osal_status_t status = OS_ERROR;
char * filename;
char destination[OS_MAX_PATH_LEN];

if(dest_dir[0] != 0)
{
filename = strrchr(src, '/');
if (filename != NULL)
{
snprintf(destination, sizeof(destination), "%s%s",
dest_dir, filename);
status = OS_mv(src, destination);
}
}

if (status != OS_SUCCESS)
{
OS_remove(src);
}
}
30 changes: 30 additions & 0 deletions fsw/src/cf_cfdp.h
Original file line number Diff line number Diff line change
Expand Up @@ -703,4 +703,34 @@ void CF_CFDP_ProcessPollingDirectories(CF_Channel_t *chan);
*/
CF_CListTraverse_Status_t CF_CFDP_DoTick(CF_CListNode_t *node, void *context);

/************************************************************************/
/** @brief Check if source file came from polling directory
*
*
* @par Assumptions, External Events, and Notes:
*
* @retval true/false
*/
bool CF_CFDP_IsPollingDir(const char * src_file, uint8 chan_num);

/************************************************************************/
/** @brief Remove/Move file after transaction
*
* This helper is used to handle "not keep" file option after a transaction.
*
* @par Assumptions, External Events, and Notes:
*
*/
void CF_CFDP_HandleNotKeepFile(CF_Transaction_t *txn);

/************************************************************************/
/** @brief Move File
*
* This helper is used to move a file.
*
* @par Assumptions, External Events, and Notes:
*
*/
void CF_CFDP_MoveFile(const char *src, const char *dest_dir);

#endif /* !CF_CFDP_H */
1 change: 1 addition & 0 deletions fsw/tables/cf_def_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,6 @@ CF_ConfigTable_t CF_config_table = {
.move_dir = ""}},
480, /* outgoing_file_chunk_size */
"/cf/tmp", /* temporary file directory */
"/cf/fail", /* Stores failed tx file for "polling directory" */
};
CFE_TBL_FILEDEF(CF_config_table, CF.config_table, CF config table, cf_def_config.tbl)

0 comments on commit e187427

Please sign in to comment.