/*
* This source file is part of the EtherCAT Slave Stack Code licensed by Beckhoff Automation GmbH & Co KG, 33415 Verl, Germany.
* The corresponding license agreement applies. This hint shall not be removed.
* https://www.beckhoff.com/media/downloads/slave-stack-code/ethercat_ssc_license.pdf
*/
/**
\addtogroup FoE FileTransfer over EtherCAT
@{
*/
/**
\file foeappl.c
\author EthercatSSC@beckhoff.com
\brief Implementation
This file contains an example how to use the FoE services
\version 5.12
Changes to version V5.11:
V5.12 FOE1: update new interface,move the FoE sample to sampleappl,add FoE application callback functions
Changes to version V5.10:
V5.11 FOE2: FoE_Read() check File name buffer before store the requested file name, add string terminator
V5.11 TEST5: send a FoE busy on a FoE read request
V5.11 TEST9: "add behaviour 0x2020.7 (SDO requests on 0x3006.0 are set to pending until an FoE read request on ""UnlockSdoResp"" is received or in case that no mbx queue is supported when a new mbx request was received)"
Changes to version V5.0:
V5.10 FOE2: Update file handling to support File sizes greater than 0x8000 Bytes (change value of "FOE_MAXDATA")
Changes to version V4.20:
V5.0 FOE3: Add additional file name copy operation to provide name byte swapping
V5.0 FOE5: Add FoE test operation (FOE_SAVE_FILES need to be disabled). On download only the files size is save. On upload a file with incrementing content and the previous downloaded size will be created.
V5.0 FOE6: Save file if MBX 16Bit access is enabled
Changes to version V4.11:
V4.20 FOE 2: Add File store compiler switch
V4.20 FOE 1: Removed FILESUPPORT
V4.11 FOE 1: nFileWriteOffset is now a 32bit variable to extend the maximum file size
Changes to version V3.20:
V4.10 FOE 1-14: Filetransfer over FoE: Files can be read and stored to harddisk
without any filesizelimitation (FILESUPPORT must defined)
*/
/*-----------------------------------------------------------------------------------------
------
------ Includes
------
-----------------------------------------------------------------------------------------*/
#include "ecat_def.h"
#include "ecatslv.h"
#include "ecatfoe.h"
#define _FOEAPPL_ 1
#include "foeappl.h"
#undef _FOEAPPL_
#define _FOEAPPL_ 0
/*ET9300 Project Handler :(#if BOOTSTRAPMODE_SUPPORTED) lines 59 to 61 deleted*/
/*ET9300 Project Handler :(#if TEST_APPLICATION) lines 64 to 66 deleted*/
#include "applInterface.h"
/*-----------------------------------------------------------------------------------------
------
------ internal Types and Defines
------
-----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------
------
------ Module internal function declarations
------
-----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------
------
------ Module internal variable definitions
------
-----------------------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------------------
------
------ Functions
------
-----------------------------------------------------------------------------------------*/
/////////////////////////////////////////////////////////////////////////////////////////
/**
\param pName Pointer to the name of the file
\param nameSize Length of the file name
\param pData Pointer to the response data
\param password Password for the file read
\return size of the data to be sent, busy or an error code
1..FOE_MAXBUSY-101 (size of data to be sent)
FOE_MAXBUSY-100 (0%) (busy)
FOE_MAXBUSY (100%) (busy)
ECAT_FOE_ERRCODE_NOTDEFINED (error)
ECAT_FOE_ERRCODE_NOTFOUND (error)
ECAT_FOE_ERRCODE_ACCESS (error)
ECAT_FOE_ERRCODE_DISKFULL (error)
ECAT_FOE_ERRCODE_ILLEGAL (error)
ECAT_FOE_ERRCODE_PACKENO (error)
ECAT_FOE_ERRCODE_EXISTS (error)
ECAT_FOE_ERRCODE_NOUSER (error)
\brief The function starts a file reading
*////////////////////////////////////////////////////////////////////////////////////////
UINT16 FOE_Read(UINT16 MBXMEM * pName, UINT16 nameSize, UINT16 MBXMEM * pData, UINT32 password)
{
if (pAPPL_FoeRead != NULL)
{
return pAPPL_FoeRead(pName, nameSize, password, u16FoeMaxSendBlockSize, pData);
}
return ECAT_FOE_ERRCODE_NOTDEFINED;
}
/////////////////////////////////////////////////////////////////////////////////////////
/**
\param pName Pointer to the name of the file
\param nameSize Length of the file name
\param password Password for the file read
\return okay, busy or an error code
0 (okay)
ECAT_FOE_ERRCODE_NOTDEFINED (error)
ECAT_FOE_ERRCODE_NOTFOUND (error)
ECAT_FOE_ERRCODE_ACCESS (error)
ECAT_FOE_ERRCODE_DISKFULL (error)
ECAT_FOE_ERRCODE_ILLEGAL (error)
ECAT_FOE_ERRCODE_PACKENO (error)
ECAT_FOE_ERRCODE_EXISTS (error)
ECAT_FOE_ERRCODE_NOUSER (error)
(no busy response shall be returned by this function.
If the slave stack requires some time to handle the incoming data the function FOE_Data() should return busy)
\brief The function starts a file writing
*////////////////////////////////////////////////////////////////////////////////////////
UINT16 FOE_Write(UINT16 MBXMEM * pName, UINT16 nameSize, UINT32 password)
{
if (pAPPL_FoeWrite != NULL)
{
return pAPPL_FoeWrite(pName,nameSize,password);
}
return ECAT_FOE_ERRCODE_NOTDEFINED;
}
/////////////////////////////////////////////////////////////////////////////////////////
/**
\param pData Received file data
\param Size Length of received file data
\return okay, busy or an error code
0 (okay)
FOE_MAXBUSY-100 (0%) (busy)
FOE_MAXBUSY (100%) (busy)
ECAT_FOE_ERRCODE_NOTDEFINED (error)
ECAT_FOE_ERRCODE_NOTFOUND (error)
ECAT_FOE_ERRCODE_ACCESS (error)
ECAT_FOE_ERRCODE_DISKFULL (error)
ECAT_FOE_ERRCODE_ILLEGAL (error)
ECAT_FOE_ERRCODE_PACKENO (error)
ECAT_FOE_ERRCODE_EXISTS (error)
ECAT_FOE_ERRCODE_NOUSER (error)
\brief The function is called to write the next part of a file
*////////////////////////////////////////////////////////////////////////////////////////
UINT16 FOE_Data(UINT16 MBXMEM * pData, UINT16 Size)
{
BOOL bDataFollowing = FALSE;
if(Size == (u16ReceiveMbxSize - MBX_HEADER_SIZE - FOE_HEADER_SIZE) )
{
bDataFollowing = TRUE;
}
if(pAPPL_FoeWriteData != NULL)
{
UINT16 error = 0;
error = pAPPL_FoeWriteData(pData, Size, bDataFollowing);
if (error > 0)
{
return error;
}
else if (bDataFollowing == FALSE)
{
return FOE_ACKFINISHED;
}
return 0;
}
return ECAT_FOE_ERRCODE_NOTDEFINED;
}
/////////////////////////////////////////////////////////////////////////////////////////
/**
\param fileOffset Offset of the next file data to be sent
\param pData Buffer for file data to be sent
\return size of the data to be sent, busy or an error code
0 (all data was sent before)
1..MAX_FILE_SIZE (size of data to be sent)
FOE_MAXBUSY-100 (0%) (busy)
FOE_MAXBUSY (100%) (busy)
ECAT_FOE_ERRCODE_NOTDEFINED (error)
ECAT_FOE_ERRCODE_NOTFOUND (error)
ECAT_FOE_ERRCODE_ACCESS (error)
ECAT_FOE_ERRCODE_DISKFULL (error)
ECAT_FOE_ERRCODE_ILLEGAL (error)
ECAT_FOE_ERRCODE_PACKENO (error)
ECAT_FOE_ERRCODE_EXISTS (error)
ECAT_FOE_ERRCODE_NOUSER (error)
\brief The function is called when the reading of a part of a file is acknowledged
*////////////////////////////////////////////////////////////////////////////////////////
UINT16 FOE_Ack(UINT32 fileOffset, UINT16 MBXMEM * pData)
{
if (pAPPL_FoeReadData != NULL)
{
return pAPPL_FoeReadData(fileOffset, u16FoeMaxSendBlockSize, pData);
}
return ECAT_FOE_ERRCODE_NOTDEFINED;
}
/////////////////////////////////////////////////////////////////////////////////////////
/**
\param done Indicates how much of the busy action is done
\param fileOffset Offset of the next file data to be sent
\param pData Buffer for file data to be sent
\return size of the data to be sent, busy or an error code
0 (all data was sent before)
1..MAX_FILE_SIZE (size of data to be sent)
FOE_MAXBUSY-100 (0%) (busy)
FOE_MAXBUSY (100%) (busy)
ECAT_FOE_ERRCODE_NOTDEFINED (error)
ECAT_FOE_ERRCODE_NOTFOUND (error)
ECAT_FOE_ERRCODE_ACCESS (error)
ECAT_FOE_ERRCODE_DISKFULL (error)
ECAT_FOE_ERRCODE_ILLEGAL (error)
ECAT_FOE_ERRCODE_PACKENO (error)
ECAT_FOE_ERRCODE_EXISTS (error)
ECAT_FOE_ERRCODE_NOUSER (error)
\brief The function is called when the reading of a part of a file should be repeated
*////////////////////////////////////////////////////////////////////////////////////////
UINT16 FOE_Busy(UINT16 done, UINT32 fileOffset, UINT16 MBXMEM * pData)
{
/* send last part again */
return FOE_Ack(fileOffset, pData);
}
/////////////////////////////////////////////////////////////////////////////////////////
/**
\param errorCode error code
\brief The function is called when a file transfer is aborted from the other station
*////////////////////////////////////////////////////////////////////////////////////////
void FOE_Error(UINT32 errorCode)
{
if (pAPPL_FoeError != NULL)
{
pAPPL_FoeError(errorCode);
}
}
/** @} */