summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/CEH/CmdResult.cpp31
-rw-r--r--source/CEH/CmdResult.h77
-rw-r--r--source/CEH/ProtromRpcInterface.cpp272
-rw-r--r--source/CEH/ProtromRpcInterface.h79
-rw-r--r--source/CEH/ZRpcInterface.cpp142
-rw-r--r--source/CEH/ZRpcInterface.h38
-rw-r--r--source/CEH/a2_commands_impl.cpp122
-rw-r--r--source/CEH/commands_impl.cpp402
-rw-r--r--source/CEH/commands_types.h65
-rw-r--r--source/LCDriver.cpp595
-rw-r--r--source/LCDriver.h824
-rw-r--r--source/LCDriver.rc116
-rw-r--r--source/LCDriver.vcproj966
-rw-r--r--source/LCDriverEntry.cpp45
-rw-r--r--source/LCDriverInterface.cpp55
-rw-r--r--source/LCDriverInterface.h50
-rw-r--r--source/LCDriverMethods.cpp2574
-rw-r--r--source/LCDriverMethods.h265
-rw-r--r--source/LCDriverThread.cpp84
-rw-r--r--source/LCDriverThread.h55
-rw-r--r--source/LCM/Buffers.cpp264
-rw-r--r--source/LCM/Buffers.h83
-rw-r--r--source/LCM/Hash.cpp197
-rw-r--r--source/LCM/Hash.h47
-rw-r--r--source/LCM/Queue.cpp291
-rw-r--r--source/LCM/Queue.h53
-rw-r--r--source/LCM/Timer.cpp267
-rw-r--r--source/LCM/Timer.h97
-rw-r--r--source/LCM/include/c_compiler.h127
-rw-r--r--source/LCM/include/c_system.h34
-rw-r--r--source/LCM/include/error_codes.h740
-rwxr-xr-xsource/LCM/include/t_a2_protocol.h48
-rw-r--r--source/LCM/include/t_basicdefinitions.h286
-rw-r--r--source/LCM/include/t_bulk_protocol.h155
-rw-r--r--source/LCM/include/t_command_protocol.h73
-rw-r--r--source/LCM/include/t_communication_service.h344
-rw-r--r--source/LCM/include/t_protrom_header.h63
-rw-r--r--source/LCM/include/t_protrom_network.h98
-rw-r--r--source/LCM/include/t_protrom_transport.h44
-rw-r--r--source/LCM/include/t_queue.h45
-rw-r--r--source/LCM/include/t_r15_header.h102
-rw-r--r--source/LCM/include/t_r15_network_layer.h309
-rw-r--r--source/LCM/include/t_security_algorithms.h44
-rw-r--r--source/LCM/include/t_time_utilities.h43
-rw-r--r--source/LcmInterface.cpp260
-rw-r--r--source/LcmInterface.h129
-rw-r--r--source/api_wrappers/linux/CCriticalSection.h52
-rw-r--r--source/api_wrappers/linux/CEventObject.cpp66
-rw-r--r--source/api_wrappers/linux/CEventObject.h40
-rw-r--r--source/api_wrappers/linux/CSemaphore.cpp55
-rw-r--r--source/api_wrappers/linux/CSemaphore.h26
-rw-r--r--source/api_wrappers/linux/CSemaphoreQueue.cpp121
-rw-r--r--source/api_wrappers/linux/CSemaphoreQueue.h67
-rw-r--r--source/api_wrappers/linux/CSimpleQueue.h26
-rw-r--r--source/api_wrappers/linux/CThreadWrapper.cpp119
-rw-r--r--source/api_wrappers/linux/CThreadWrapper.h36
-rw-r--r--source/api_wrappers/linux/CWaitableObject.cpp17
-rw-r--r--source/api_wrappers/linux/CWaitableObject.h24
-rw-r--r--source/api_wrappers/linux/CWaitableObjectCollection.cpp67
-rw-r--r--source/api_wrappers/linux/CWaitableObjectCollection.h26
-rw-r--r--source/api_wrappers/linux/LinuxApiWrappers.h20
-rw-r--r--source/api_wrappers/linux/OS.cpp88
-rw-r--r--source/api_wrappers/linux/OS.h107
-rw-r--r--source/api_wrappers/linux/Types.h21
-rw-r--r--source/api_wrappers/windows/WinApiWrappers.h347
-rw-r--r--source/config/a2_command_ids_h.xsl60
-rw-r--r--source/config/a2_commands.xml1259
-rw-r--r--source/config/a2_commands_h.xsl78
-rw-r--r--source/config/a2_commands_impl_h.xsl72
-rw-r--r--source/config/a2_commands_marshal_cpp.xsl236
-rw-r--r--source/config/a2_common.xsl227
-rw-r--r--source/config/command_ids_h.xsl64
-rw-r--r--source/config/commands.xml1165
-rw-r--r--source/config/commands_h.xsl68
-rw-r--r--source/config/commands_impl_h.xsl67
-rw-r--r--source/config/commands_marshal_cpp.xsl211
-rw-r--r--source/config/common.xsl262
-rw-r--r--source/config/lcdriver_error_codes.xml114
-rw-r--r--source/config/lcdriver_error_codes_h.xsl72
-rw-r--r--source/resource.h21
-rw-r--r--source/security_algorithms/SecurityAlgorithms.cpp18
-rw-r--r--source/security_algorithms/SecurityAlgorithms.h20
-rw-r--r--source/security_algorithms/sha/sha2.cpp1064
-rw-r--r--source/security_algorithms/sha/sha2.h197
-rw-r--r--source/utilities/BulkHandler.cpp286
-rw-r--r--source/utilities/BulkHandler.h81
-rw-r--r--source/utilities/CaptiveThreadObject.cpp51
-rw-r--r--source/utilities/CaptiveThreadObject.h57
-rwxr-xr-xsource/utilities/Error.h25
-rw-r--r--source/utilities/Event.h27
-rw-r--r--source/utilities/LockLessQueue.h98
-rw-r--r--source/utilities/Logger.cpp36
-rw-r--r--source/utilities/Logger.h33
-rw-r--r--source/utilities/MemMappedFile.cpp205
-rw-r--r--source/utilities/MemMappedFile.h41
-rw-r--r--source/utilities/ObjectList.h286
-rw-r--r--source/utilities/Serialization.cpp325
-rw-r--r--source/utilities/Serialization.h63
98 files changed, 19314 insertions, 0 deletions
diff --git a/source/CEH/CmdResult.cpp b/source/CEH/CmdResult.cpp
new file mode 100644
index 0000000..2cc9b23
--- /dev/null
+++ b/source/CEH/CmdResult.cpp
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "CmdResult.h"
+#include "Serialization.h"
+
+CmdResult::CmdResult()
+{
+ System_LoaderStartupStatus_Status = 0;
+
+ FileSystem_Properties_Mode = 0;
+ FileSystem_Properties_Size = 0;
+ FileSystem_Properties_MTime = 0;
+ FileSystem_Properties_ATime = 0;
+ FileSystem_Properties_CTime = 0;
+ FileSystem_VolumeProperties_Size = 0;
+ FileSystem_VolumeProperties_Free = 0;
+
+ GeneralResponse_Session = 0;
+
+ Security_GetDomain_WrittenDomain = 0;
+
+ A2_MaxLoaderPacketSize = 0;
+}
+
+CmdResult::~CmdResult()
+{
+}
+
diff --git a/source/CEH/CmdResult.h b/source/CEH/CmdResult.h
new file mode 100644
index 0000000..3fc6f99
--- /dev/null
+++ b/source/CEH/CmdResult.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _CMDRESULT_H_
+#define _CMDRESULT_H_
+
+#include "commands_types.h"
+#include "error_codes.h"
+#include "LCDriver.h"
+#include <vector>
+
+class CmdResult
+{
+public:
+ CmdResult();
+ virtual ~CmdResult();
+
+ //Session id for General Response.
+ uint32 GeneralResponse_Session;
+
+ // Copy of data received in Protrom Protocol
+ std::vector<uint8> ProtromPayloadData;
+
+ //Output data for System_LoaderStartupStatus.
+ uint32 System_LoaderStartupStatus_Status;
+ std::string System_LoaderStartupStatus_LoaderVersion;
+ std::string System_LoaderStartupStatus_ProtocolVersion;
+
+ //Output data for System_SupportedCommands.
+ std::vector<TSupportedCmd> System_SupportedCommands_CmdList;
+
+ //Output data for System_CollectData.
+ std::string System_CollectedData;
+
+ //Output data for Authentication Challenge.
+ std::vector<uint8> System_AuthenticationChallenge_Buffer;
+
+ //Output data for Flash_ListDevices.
+ std::vector<TDevicesInternal> Flash_ListDevices_Devices;
+
+ //Output data for FileSystem_VolumeProperties.
+ std::string FileSystem_VolumeProperties_FSType;
+ uint64 FileSystem_VolumeProperties_Size;
+ uint64 FileSystem_VolumeProperties_Free;
+
+ //Output data for FileSystem_ListDirectory.
+ std::vector<TEntriesInternal> FileSystem_ListDirectory_Entries;
+
+ //Output data for FileSystem_Properties.
+ int FileSystem_Properties_Mode;
+ uint64 FileSystem_Properties_Size;
+ int FileSystem_Properties_MTime;
+ int FileSystem_Properties_ATime;
+ int FileSystem_Properties_CTime;
+
+ //Output data for OTP_ReadBits.
+ std::vector<uint8> OTP_ReadBits_DataBuffer;
+ std::vector<uint8> OTP_ReadBits_StatusBuffer;
+
+ //Output data for ReadGlobalDataUnit.
+ std::vector<uint8> ParameterStorage_ReadGlobalDataUnit_DataBuffer;
+
+ //Output data for Security_GetDomain.
+ int Security_GetDomain_WrittenDomain;
+
+ //Output data for Security_GetProperties.
+ std::vector<uint8> Security_GetProperties_DataBuffer;
+
+ // A2 Protocol Outputs
+ uint32 A2_MaxLoaderPacketSize;
+ std::string A2_LoaderVersion;
+};
+
+#endif // _CMDRESULT_H_
+
diff --git a/source/CEH/ProtromRpcInterface.cpp b/source/CEH/ProtromRpcInterface.cpp
new file mode 100644
index 0000000..aa75334
--- /dev/null
+++ b/source/CEH/ProtromRpcInterface.cpp
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#include "ProtromRpcInterface.h"
+#include "t_protrom_transport.h"
+#include "Serialization.h"
+
+ProtromRpcInterface::ProtromRpcInterface(CmdResult *CmdResult, LcmInterface *LcmInterface)
+{
+ PROTROM_Payload = new uint8[0x10000];
+ cancelDeviceOnResult_ = false;
+ cmdResult_ = CmdResult;
+ lcmInterface_ = LcmInterface;
+ commDevice_ = NULL;
+}
+
+ProtromRpcInterface::~ProtromRpcInterface()
+{
+ ProtromQueue.SignalEvent();
+ delete[] PROTROM_Payload;
+}
+
+ErrorCode_e ProtromRpcInterface::Do_CEH_Callback(CommandData_t *CmdData_p)
+{
+ uint8 *Data_p = (uint8 *)CmdData_p->Payload.Data_p;
+
+ TProtromInfo *pInfo = new TProtromInfo;
+ pInfo->Length = CmdData_p->Payload.Size;
+ pInfo->DataP = new uint8[pInfo->Length];
+ memcpy(pInfo->DataP, Data_p, pInfo->Length);
+
+ int Pdu = *(Data_p + 7); //Get PDU number
+
+ switch (Pdu) {
+ case PROTROM_PDU_RESULT: {
+ pInfo->ReceivedPdu = PROTROM_PDU_RESULT;
+ pInfo->Status = DoneRPC_PROTROM_ResultImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_READY_TO_RECEIVE: {
+ pInfo->ReceivedPdu = PROTROM_PDU_READY_TO_RECEIVE;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_ERROR_DATA: {
+ pInfo->ReceivedPdu = PROTROM_PDU_ERROR_DATA;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+
+ case PROTROM_PDU_SECURITY_DATA_RES: {
+ pInfo->ReceivedPdu = PROTROM_PDU_SECURITY_DATA_RES;
+ pInfo->Status = DoneRPC_PROTROM_ReadSecurityDataImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_DOMAIN_DATA_REQ: {
+ pInfo->ReceivedPdu = PROTROM_PDU_DOMAIN_DATA_REQ;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_DOMAIN_DATA: {
+ pInfo->ReceivedPdu = PROTROM_PDU_DOMAIN_DATA;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_SECURITY_DATA_REQ: {
+ pInfo->ReceivedPdu = PROTROM_PDU_SECURITY_DATA_REQ;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_ROOT_KEY_REQ: {
+ pInfo->ReceivedPdu = PROTROM_PDU_ROOT_KEY_REQ;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_ROOT_KEY_DATA: {
+ pInfo->ReceivedPdu = PROTROM_PDU_ROOT_KEY_DATA;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_PATCH_REQ: {
+ pInfo->ReceivedPdu = PROTROM_PDU_PATCH_REQ;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_PATCH_DATA: {
+ pInfo->ReceivedPdu = PROTROM_PDU_PATCH_DATA;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_PATCH_DATA_FINAL: {
+ pInfo->ReceivedPdu = PROTROM_PDU_PATCH_DATA_FINAL;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_HEADER_OK_SW_REV: {
+ pInfo->ReceivedPdu = PROTROM_PDU_HEADER_OK_SW_REV;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_SW_REV_DATA: {
+ pInfo->ReceivedPdu = PROTROM_PDU_SW_REV_DATA;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_WDOG_RESET: {
+ pInfo->ReceivedPdu = PROTROM_PDU_WDOG_RESET;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+
+ case PROTROM_PDU_DATA_NOT_FOUND: {
+ pInfo->ReceivedPdu = PROTROM_PDU_DATA_NOT_FOUND;
+ pInfo->Status = DoneRPC_PROTROM_ReadyToReceiveImpl(*CmdData_p);
+ }
+ break;
+ }
+
+ ProtromQueue.AddRequest(static_cast<void *>(pInfo));
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e ProtromRpcInterface::DoRPC_PROTROM_ResultPdu(int Status)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ Protrom_SendData_LP_t Data;
+ Protrom_Header_t Header;
+
+ Header.PayloadLength = 2; // PDU + Status
+ Data.Header_p = &Header; // PROTROM header
+ Data.Payload_p = PROTROM_Payload; // pointer to the payload data
+ PROTROM_Payload[0] = 0x04; // Result PDU 0x04.
+ PROTROM_Payload[1] = Status; // Status
+
+ Result = lcmInterface_->CommunicationSend(&Data);
+
+ return Result;
+}
+
+ErrorCode_e ProtromRpcInterface::DoRPC_PROTROM_SendLoaderHeader(unsigned char *pFile, uint32 Size)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ Protrom_SendData_LP_t Data;
+ Protrom_Header_t Header;
+
+ Header.PayloadLength = 1 + (uint16)Size; // PDU + Header payload + padding.
+ Data.Header_p = &Header; // PROTROM header
+ Data.Payload_p = PROTROM_Payload; // pointer to the payload data
+
+ //Copy PDU and header data to Payload
+ PROTROM_Payload[0] = 0x01; //Header PDU 0x01
+
+ memcpy(PROTROM_Payload + 1, pFile, Size); //Copy header data
+
+ Result = lcmInterface_->CommunicationSend(&Data);
+
+ return Result;
+}
+
+ErrorCode_e ProtromRpcInterface::DoRPC_PROTROM_SendLoaderPayload(unsigned char *pFile, uint32 Size)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ Protrom_SendData_LP_t Data;
+ Protrom_Header_t Header;
+
+ Header.PayloadLength = 1 + (uint16)Size; // PDU + Headeer payload.
+ Data.Header_p = &Header; // PROTROM header
+ Data.Payload_p = PROTROM_Payload; // pointer to the payload data
+
+ //Copy PDU and header data to Payload
+ PROTROM_Payload[0] = 0x02; //Payload PDU 0x02
+
+ memcpy(PROTROM_Payload + 1, pFile, Size); //Copy payload data
+
+ Result = lcmInterface_->CommunicationSend(&Data);
+
+ return Result;
+}
+
+ErrorCode_e ProtromRpcInterface::DoRPC_PROTROM_SendLoaderFinalPayload(unsigned char *pFile, uint32 Size)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ Protrom_SendData_LP_t Data;
+ Protrom_Header_t Header;
+
+ Header.PayloadLength = 1 + (uint16)Size; // PDU + Payload.
+ Data.Header_p = &Header; // PROTROM header
+ Data.Payload_p = PROTROM_Payload; // pointer to the payload data
+
+ //Copy PDU and header data to Payload
+ PROTROM_Payload[0] = 0x03; //Final payload PDU 0x03
+
+ memcpy(PROTROM_Payload + 1, pFile, Size);
+
+ Result = lcmInterface_->CommunicationSend(&Data);
+
+ return Result;
+}
+
+ErrorCode_e ProtromRpcInterface::DoRPC_PROTROM_ReadSecurityData(uint8 SecDataId)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ Protrom_SendData_LP_t Data;
+ Protrom_Header_t Header;
+
+ Header.PayloadLength = 2; // PDU + Payload.
+ Data.Header_p = &Header; // PROTROM header
+ Data.Payload_p = PROTROM_Payload; // pointer to the payload data
+
+ //Copy PDU and header data to Payload
+ PROTROM_Payload[0] = 0x08; // Security Data Request PDU 0x08
+ PROTROM_Payload[1] = SecDataId;
+
+ Result = lcmInterface_->CommunicationSend(&Data);
+
+ return Result;
+}
+
+ErrorCode_e ProtromRpcInterface::DoneRPC_PROTROM_ResultImpl(CommandData_t CmdData)
+{
+ uint8 *Payload_p = CmdData.Payload.Data_p + PROTROM_HEADER_LENGTH;
+
+ // skip PDU type
+ Payload_p++;
+
+ if (cancelDeviceOnResult_) {
+ commDevice_->Cancel(lcmInterface_->getLCMContext());
+ }
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e ProtromRpcInterface::DoneRPC_PROTROM_ReadSecurityDataImpl(CommandData_t CmdData)
+{
+ uint8 *Payload_p = CmdData.Payload.Data_p + PROTROM_HEADER_LENGTH;
+ size_t PayloadLength = CmdData.Payload.Size - PROTROM_HEADER_LENGTH - PROTROM_CRC_LENGTH;
+
+ // skip PDU type
+ Payload_p++;
+ PayloadLength--;
+
+ cmdResult_->ProtromPayloadData.clear();
+ cmdResult_->ProtromPayloadData = vector<uint8>(Payload_p, Payload_p + PayloadLength);
+ return E_SUCCESS;
+}
+
+ErrorCode_e ProtromRpcInterface::DoneRPC_PROTROM_ReadyToReceiveImpl(CommandData_t CmdData)
+{
+ return E_SUCCESS;
+}
+
+void ProtromRpcInterface::CancelDeviceOnResult(CommunicationDevice_t *commDevice)
+{
+ cancelDeviceOnResult_ = true;
+ commDevice_ = commDevice;
+}
diff --git a/source/CEH/ProtromRpcInterface.h b/source/CEH/ProtromRpcInterface.h
new file mode 100644
index 0000000..43ed46f
--- /dev/null
+++ b/source/CEH/ProtromRpcInterface.h
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _PROTROMRPCINTERFACE_H_
+#define _PROTROMRPCINTERFACE_H_
+
+#include "CmdResult.h"
+#include "LcmInterface.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "CSimpleQueue.h"
+#endif
+
+/// <summary>
+/// PROTROM command definitions.
+/// </summary>
+typedef enum {
+ PROTROM_PDU_HEADER = 1,
+ PROTROM_PDU_PAYLOAD = 2,
+ PROTROM_PDU_PAYLOAD_FINAL = 3,
+ PROTROM_PDU_RESULT = 4,
+ PROTROM_PDU_READY_TO_RECEIVE = 5,
+ PROTROM_PDU_ERROR_DATA = 6,
+ PROTROM_PDU_SECURITY_DATA_REQ = 8,
+ PROTROM_PDU_SECURITY_DATA_RES = 9,
+ PROTROM_PDU_DOMAIN_DATA_REQ = 43,
+ PROTROM_PDU_DOMAIN_DATA = 44,
+ PROTROM_PDU_ROOT_KEY_REQ = 45,
+ PROTROM_PDU_ROOT_KEY_DATA = 46,
+ PROTROM_PDU_PATCH_REQ = 47,
+ PROTROM_PDU_PATCH_DATA = 48,
+ PROTROM_PDU_PATCH_DATA_FINAL = 49,
+ PROTROM_PDU_HEADER_OK_SW_REV = 51,
+ PROTROM_PDU_SW_REV_DATA = 52,
+ PROTROM_PDU_WDOG_RESET = 53,
+ PROTROM_PDU_DATA_NOT_FOUND = 100
+} PROTROMCommandId_e;
+
+struct TProtromInfo {
+ int ReceivedPdu;
+ void *DataP;
+ uint32 Length;
+ uint8 Status;
+};
+
+class ProtromRpcInterface
+{
+public:
+ ProtromRpcInterface(CmdResult *CmdResult, LcmInterface *LcmInterface);
+ virtual ~ProtromRpcInterface();
+
+ CSimpleQueue ProtromQueue;
+
+ //PROTROM-Protocol
+ ErrorCode_e DoRPC_PROTROM_ResultPdu(int Status);
+ ErrorCode_e DoRPC_PROTROM_SendLoaderHeader(unsigned char *pFile, uint32 Size);
+ ErrorCode_e DoRPC_PROTROM_SendLoaderPayload(unsigned char *pFile, uint32 Size);
+ ErrorCode_e DoRPC_PROTROM_SendLoaderFinalPayload(unsigned char *pFile, uint32 Size);
+ ErrorCode_e DoRPC_PROTROM_ReadSecurityData(uint8 SecDataId);
+
+ ErrorCode_e DoneRPC_PROTROM_ResultImpl(CommandData_t CmdData);
+ ErrorCode_e DoneRPC_PROTROM_ReadSecurityDataImpl(CommandData_t CmdData);
+ ErrorCode_e DoneRPC_PROTROM_ReadyToReceiveImpl(CommandData_t CmdData);
+
+ ErrorCode_e Do_CEH_Callback(CommandData_t *pCmdData);
+
+ void CancelDeviceOnResult(CommunicationDevice_t *commDevice);
+private:
+ uint8 *PROTROM_Payload;
+ bool cancelDeviceOnResult_;
+ CommunicationDevice_t *commDevice_;
+ CmdResult *cmdResult_;
+ LcmInterface *lcmInterface_;
+};
+
+#endif // _PROTROMRPCINTERFACE_H_
diff --git a/source/CEH/ZRpcInterface.cpp b/source/CEH/ZRpcInterface.cpp
new file mode 100644
index 0000000..5476e8f
--- /dev/null
+++ b/source/CEH/ZRpcInterface.cpp
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "ZRpcInterface.h"
+
+ZRpcInterface::ZRpcInterface(CmdResult *CmdResult, LcmInterface *LcmInterface)
+{
+ Z_Payload = 0;
+ cmdResult_ = CmdResult;
+ lcmInterface_ = LcmInterface;
+
+ Z_IndataBuffer = new LockLessQueue(10);
+}
+
+ZRpcInterface::~ZRpcInterface()
+{
+ delete Z_IndataBuffer;
+ delete[] Z_Payload;
+}
+
+ErrorCode_e ZRpcInterface::Do_CEH_Callback(CommandData_t *CmdData_p)
+{
+ ErrorCode_e Status = E_GENERAL_FATAL_ERROR;
+
+ Status = DoneRPC_Z_ReadImpl(*CmdData_p);
+
+ return Status;
+}
+
+ErrorCode_e ZRpcInterface::DoRPC_Z_VersionRequest()
+{
+ ErrorCode_e Result = E_SUCCESS;
+
+ if (Z_Payload != 0) {
+ delete [] Z_Payload;
+ Z_Payload = 0;
+ }
+
+ Z_Payload = new uint8[2];
+ Z_Payload[0] = 0x01;
+ Z_Payload[1] = 0x3F;
+
+ Result = lcmInterface_->CommunicationSend(Z_Payload);
+
+ return Result;
+}
+
+ErrorCode_e ZRpcInterface::DoRPC_Z_SetBaudrate(int Baudrate)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ char Rate;
+
+ switch (Baudrate) {
+ case 9600:
+ Rate = '0';
+ break;
+
+ case 19200:
+ Rate = '1';
+ break;
+
+ case 38400:
+ Rate = '2';
+ break;
+
+ case 57600:
+ Rate = '3';
+ break;
+
+ case 115200:
+ Rate = '4';
+ break;
+
+ case 230400:
+ Rate = '5';
+ break;
+
+ case 460800:
+ Rate = '6';
+ break;
+
+ case 921600:
+ Rate = '7';
+ break;
+
+ case 1625000:
+ Rate = '8';
+ break;
+
+ default :
+ return E_INVALID_INPUT_PARAMETERS;
+ }
+
+ if (Z_Payload != 0) {
+ delete [] Z_Payload;
+ Z_Payload = 0;
+ }
+
+ Z_Payload = new uint8[3];
+
+ Z_Payload[0] = 0x02;
+ Z_Payload[1] = 'S';
+ Z_Payload[2] = Rate;
+
+ Result = lcmInterface_->CommunicationSend(Z_Payload);
+
+ return Result;
+}
+
+ErrorCode_e ZRpcInterface::DoRPC_Z_Exit_Z_Protocol()
+{
+ ErrorCode_e Result = E_SUCCESS;
+
+ if (Z_Payload != 0) {
+ delete [] Z_Payload;
+ Z_Payload = 0;
+ }
+
+ Z_Payload = new uint8[2];
+ Z_Payload[0] = 0x01;
+ Z_Payload[1] = 'Q';
+
+ Result = lcmInterface_->CommunicationSend(Z_Payload);
+
+ return Result;
+}
+
+ErrorCode_e ZRpcInterface::DoneRPC_Z_ReadImpl(CommandData_t CmdData)
+{
+ unsigned char Data_p = *CmdData.Payload.Data_p;
+ bool Full = false;
+
+ Z_IndataBuffer->Push(Data_p, &Full);
+
+ if (Full == true) {
+ return E_GENERAL_FATAL_ERROR;
+ }
+
+ return E_SUCCESS;
+}
diff --git a/source/CEH/ZRpcInterface.h b/source/CEH/ZRpcInterface.h
new file mode 100644
index 0000000..3d630c2
--- /dev/null
+++ b/source/CEH/ZRpcInterface.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _ZRPCINTERFACE_H_
+#define _ZRPCINTERFACE_H_
+
+#include "CmdResult.h"
+#include "LcmInterface.h"
+#include "LockLessQueue.h"
+
+class ZRpcInterface
+{
+public:
+ ZRpcInterface(CmdResult *CmdResult, LcmInterface *LcmInterface);
+ virtual ~ZRpcInterface();
+
+ //Circular buffer for received data when using Z-protocol.
+ LockLessQueue *Z_IndataBuffer;
+
+ //Z-Protocol
+ ErrorCode_e DoRPC_Z_VersionRequest();
+ ErrorCode_e DoRPC_Z_SetBaudrate(int Baudrate);
+ ErrorCode_e DoRPC_Z_Exit_Z_Protocol();
+
+ ErrorCode_e DoneRPC_Z_ReadImpl(CommandData_t CmdData);
+
+ ErrorCode_e Do_CEH_Callback(CommandData_t *pCmdData);
+
+private:
+ //Payload variable for z-protocol
+ uint8 *Z_Payload;
+ CmdResult *cmdResult_;
+ LcmInterface *lcmInterface_;
+};
+
+#endif // _ZRPCINTERFACE_H_
diff --git a/source/CEH/a2_commands_impl.cpp b/source/CEH/a2_commands_impl.cpp
new file mode 100644
index 0000000..6753145
--- /dev/null
+++ b/source/CEH/a2_commands_impl.cpp
@@ -0,0 +1,122 @@
+/*******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+#include "a2_commands_impl.h"
+#include "Serialization.h"
+#include "CmdResult.h"
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_System_ShutdownImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_System_LoaderVersionImpl(uint16 Session, ErrorCode_e Status, int LoaderVersionOutPLSize, const void *LoaderVersionOut)
+{
+ if (0 == Status) {
+ cmdResult_->A2_LoaderVersion = string(static_cast<const char *>(LoaderVersionOut), LoaderVersionOutPLSize);
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_System_LoaderOnLoaderImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_System_ResetImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Flash_VerifySignedHeaderImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Flash_SoftwareBlockAddressImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Flash_ProgramFlashImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Flash_VerifySoftwareFlashImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Flash_EraseFlashImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Flash_SpeedflashImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoRPC_A2_Control_LoaderStartedImpl(uint16 Session, const uint32 MaxLoaderPacketSize)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ cmdResult_->A2_MaxLoaderPacketSize = MaxLoaderPacketSize;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Control_PingImpl(uint16 Session)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoRPC_A2_Control_PongImpl(uint16 Session)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoneRPC_A2_Control_MaxPacketSizeImpl(uint16 Session, const uint16 MaxLoaderPacketSize)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ cmdResult_->A2_MaxLoaderPacketSize = MaxLoaderPacketSize;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::DoRPC_A2_Control_LoaderNotStartedImpl(uint16 Session, uint16 ErrorCode)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
diff --git a/source/CEH/commands_impl.cpp b/source/CEH/commands_impl.cpp
new file mode 100644
index 0000000..f08acb1
--- /dev/null
+++ b/source/CEH/commands_impl.cpp
@@ -0,0 +1,402 @@
+/*******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+#include "commands_impl.h"
+#include "commands_types.h"
+#include "Serialization.h"
+#include "CmdResult.h"
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoRPC_System_LoaderStartUpStatusImpl(uint16 Session, const uint32 Status, const char *LoaderVersion_p, const char *ProtocolVersion_p)
+{
+ cmdResult_->System_LoaderStartupStatus_Status = Status;
+
+ uint32 size = Serialization::get_uint32_le((const void **)&LoaderVersion_p);
+ cmdResult_->System_LoaderStartupStatus_LoaderVersion = string(LoaderVersion_p, size);
+ size = Serialization::get_uint32_le((const void **)&ProtocolVersion_p);
+ cmdResult_->System_LoaderStartupStatus_ProtocolVersion = string(ProtocolVersion_p, size);
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_RebootImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_ShutDownImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_SupportedCommandsImpl(uint16 Session, ErrorCode_e Status, const uint32 CommandCount, SupportedCommand_t Commands[])
+{
+ if (0 == Status) {
+ cmdResult_->System_SupportedCommands_CmdList.clear();
+
+ for (size_t i = 0; i != CommandCount && Commands != NULL; ++i) {
+ TSupportedCmd cmd = { Commands[i].Group, Commands[i].Command, Commands[i].Permitted };
+ cmdResult_->System_SupportedCommands_CmdList.push_back(cmd);
+ }
+ }
+
+ delete[] Commands;
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_ExecuteSoftwareImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_AuthenticateImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoRPC_System_GetControlKeysImpl(uint16 Session)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoRPC_System_GetControlKeysDataImpl(uint16 Session)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+ return E_SUCCESS;
+}
+ErrorCode_e LoaderRpcInterfaceImpl::DoRPC_System_AuthenticationChallengeImpl(uint16 Session, const uint32 ChallengeBlockLength, const void *ChallengeBlock_p)
+{
+ cmdResult_->System_AuthenticationChallenge_Buffer.clear();
+ uint8 *CdbStart = (uint8 *)ChallengeBlock_p;
+ cmdResult_->System_AuthenticationChallenge_Buffer = vector<uint8>(CdbStart, CdbStart + ChallengeBlockLength);
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_CollectDataImpl(uint16 Session, ErrorCode_e Status, const uint32 DataLenght, const void *CollectedData_p)
+{
+
+
+ if (0 == Status) {
+ cmdResult_->System_CollectedData = string((const char *)CollectedData_p, DataLenght);
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_GetProgressStatusImpl(uint16 Session, ErrorCode_e Status, const uint32 ProgressStatus)
+{
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_SetSystemTimeImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_System_SwitchCommunicationDeviceImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Flash_ProcessFileImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Flash_ListDevicesImpl(uint16 Session, ErrorCode_e Status, const uint32 DeviceCount, ListDevice_t Devices[])
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Flash_DumpAreaImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Flash_EraseAreaImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Flash_FlashRawImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_VolumePropertiesImpl(uint16 Session, ErrorCode_e Status, const char *FS_Type_p, const uint64 Size, const uint64 Free)
+{
+
+
+ if (0 == Status) {
+ uint32 size = Serialization::get_uint32_le((const void **)&FS_Type_p);
+ cmdResult_->FileSystem_VolumeProperties_FSType = string(FS_Type_p, size);
+ cmdResult_->FileSystem_VolumeProperties_Size = Size;
+ cmdResult_->FileSystem_VolumeProperties_Free = Free;
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_FormatVolumeImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_ListDirectoryImpl(uint16 Session, ErrorCode_e Status, const uint32 EntriesCount, DirEntry_t Entries[])
+{
+
+
+ if (0 == Status) {
+ cmdResult_->FileSystem_ListDirectory_Entries.clear();
+
+ for (size_t i = 0; i < EntriesCount; i++) {
+ TEntriesInternal directory = {
+ string(Entries[i].Name_p),
+ Entries[i].Size,
+ Entries[i].Mode,
+ Entries[i].Time
+ };
+ cmdResult_->FileSystem_ListDirectory_Entries.push_back(directory);
+
+ delete[] Entries[i].Name_p;
+ }
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ delete[] Entries;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_MoveFileImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_DeleteFileImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_CopyFileImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_CreateDirectoryImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_PropertiesImpl(uint16 Session, ErrorCode_e Status, const uint32 Mode, const uint64 Size, const uint32 MTime, const uint32 ATime, const uint32 CTime)
+{
+
+
+ if (0 == Status) {
+ cmdResult_->FileSystem_Properties_Mode = Mode;
+ cmdResult_->FileSystem_Properties_Size = Size;
+ cmdResult_->FileSystem_Properties_MTime = MTime;
+ cmdResult_->FileSystem_Properties_ATime = ATime;
+ cmdResult_->FileSystem_Properties_CTime = CTime;
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoRPC_File_System_Operations_PropertiesImpl(uint16 SessionOut, const char *TargetPath_p)
+{
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_ChangeAccessImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_File_System_Operations_ReadLoadModulesManifestsImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_OTP_ReadBitsImpl(uint16 Session, ErrorCode_e Status, const uint32 BitsLength, const uint32 DataBitsLength, const void *DataBits_p, const uint32 LockStatusBitsLength, const uint32 LockStatusLength, const void *LockStatus_p) // CommandData_t CmdData)
+{
+
+
+ if (0 == Status && DataBits_p != NULL && LockStatus_p != NULL) {
+ cmdResult_->OTP_ReadBits_DataBuffer.clear();
+ uint8 *BitsP = (uint8 *)DataBits_p;
+ cmdResult_->OTP_ReadBits_DataBuffer = vector<uint8>(BitsP, BitsP + DataBitsLength);
+
+ cmdResult_->OTP_ReadBits_StatusBuffer.clear();
+ BitsP = (uint8 *)LockStatus_p;
+ cmdResult_->OTP_ReadBits_StatusBuffer = vector<uint8>(BitsP, BitsP + LockStatusLength);
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_OTP_SetBitsImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_OTP_WriteAndLockImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_OTP_StoreSecureObjectImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_ParameterStorage_ReadGlobalDataUnitImpl(uint16 Session, ErrorCode_e Status, const uint32 DataBuffLength, const void *DataBuff_p)
+{
+
+
+ if (0 == Status && DataBuff_p != NULL) {
+ cmdResult_->ParameterStorage_ReadGlobalDataUnit_DataBuffer.clear();
+ uint8 *DataP = (uint8 *)DataBuff_p;
+ cmdResult_->ParameterStorage_ReadGlobalDataUnit_DataBuffer = vector<uint8>(DataP, DataP + DataBuffLength);
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_ParameterStorage_WriteGlobalDataUnitImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_ParameterStorage_ReadGlobalDataSetImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_ParameterStorage_WriteGlobalDataSetImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_ParameterStorage_EraseGlobalDataSetImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Security_SetDomainImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Security_GetDomainImpl(uint16 Session, ErrorCode_e Status, const uint32 CurrentDomain)
+{
+ if (0 == Status) {
+ cmdResult_->Security_GetDomain_WrittenDomain = CurrentDomain;
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Security_GetPropertiesImpl(uint16 Session, ErrorCode_e Status, const uint32 DataBuffLength, const void *DataBuff_p)
+{
+ if (0 == Status && DataBuff_p != NULL) {
+ cmdResult_->Security_GetProperties_DataBuffer.clear();
+ uint8 *DataP = (uint8 *)DataBuff_p;
+ cmdResult_->Security_GetProperties_DataBuffer = vector<uint8>(DataP, DataP + DataBuffLength);
+ }
+
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Security_SetPropertiesImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
+
+ErrorCode_e LoaderRpcInterfaceImpl::DoneRPC_Security_BindPropertiesImpl(uint16 Session, ErrorCode_e Status)
+{
+ cmdResult_->GeneralResponse_Session = Session;
+
+ return E_SUCCESS;
+}
diff --git a/source/CEH/commands_types.h b/source/CEH/commands_types.h
new file mode 100644
index 0000000..eec039c
--- /dev/null
+++ b/source/CEH/commands_types.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _COMMANDS_TYPES_H_
+#define _COMMANDS_TYPES_H_
+
+#include "t_basicdefinitions.h"
+#include "LCDriver.h"
+#include <string>
+
+/// <summary>
+/// Description of ME device.
+/// </summary>
+/// <param name="szPath">Absolute device path pointing at the described device.</param>
+/// <param name="iPathSize">Size of pchPath.</param>
+/// <param name="szType">Type of device.</param>
+/// <param name="iTypeSize">Size of pchType.</param>
+/// <param name="uiBlockSize">Size of the smallest addressable unit in the device [Byte].</param>
+/// <param name="uiStart">Offset [Byte] of the start of the device relative its parent's
+/// offset 0 with granularity of its parent's block size.</param>
+/// <param name="uiLength">Length of the device [Byte].</param>
+struct TDevicesInternal {
+ std::string Path;
+ std::string Type;
+ uint64 uiBlockSize;
+ uint64 uiStart;
+ uint64 uiLength;
+
+ operator TDevices() const {
+ TDevices tDevice = {
+ Path.c_str(),
+ Path.length(),
+ Type.c_str(),
+ Type.length(),
+ uiBlockSize,
+ uiStart,
+ uiLength
+ };
+
+ return tDevice;
+ }
+};
+
+struct TEntriesInternal {
+ std::string Name;
+ uint64 uiSize;
+ int iMode;
+ int iTime;
+
+ operator TEntries() const {
+ TEntries tEntry = {
+ Name.c_str(),
+ Name.length(),
+ uiSize,
+ iMode,
+ iTime
+ };
+
+ return tEntry;
+ }
+};
+
+#endif // _COMMANDS_TYPES_H_ \ No newline at end of file
diff --git a/source/LCDriver.cpp b/source/LCDriver.cpp
new file mode 100644
index 0000000..9ce9c25
--- /dev/null
+++ b/source/LCDriver.cpp
@@ -0,0 +1,595 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "LCDriver.h"
+#include "lcdriver_error_codes.h"
+#include "LCDriverInterface.h"
+#include "Error.h"
+
+#define VERIFY_CONTEXT(c) \
+ do { \
+ if ((c) == NULL) \
+ return INTERFACE_OBJECT_POINTER_NULL; \
+ if ((c)->m_pObject == NULL) \
+ return INTERFACE_LC_METHODS_OBJECT_NULL; \
+ } while (0)
+
+#define VERIFY_CONTEXT_STARTED(c) \
+ do { \
+ VERIFY_CONTEXT(c); \
+ if (!(c)->isStarted) \
+ return INTERFACE_CONTEXT_NOT_STARTED; \
+ } while (0)
+
+/************************************************************************************************
+* API functions for LCDriver functionalities
+************************************************************************************************/
+LCDRIVER_API int __cdecl Initialize(LCDContext *pContext, const char *InterfaceId, void *Read_fn, void *Write_fn, void *Cancel_fn, void **Instance, void *Message_fn, const char *LCMLibPath, void *ProgressBar_fn)
+{
+ SetLCMLibPath(LCMLibPath);
+
+ int Result = CreateContext(pContext, InterfaceId);
+
+ if (0 != Result) {
+ return Result;
+ }
+
+ // check if we have context that was previously started
+ if (!(*pContext)->isStarted) {
+ ConfigureCommunicationDevice(*pContext, Read_fn, Write_fn, Cancel_fn);
+ SwitchProtocolFamily(*pContext, R15_PROTOCOL_FAMILY);
+ SetMessageCallback(*pContext, Message_fn);
+ SetProgressCallback(*pContext, ProgressBar_fn);
+
+ return StartContext(*pContext, Instance);
+ } else {
+ return 0;
+ }
+}
+
+LCDRIVER_API void __cdecl SetLCMLibPath(const char *LCMLibPath)
+{
+ LcmInterface::SetLCMLibPath(LCMLibPath);
+}
+
+LCDRIVER_API int __cdecl CreateContext(LCDContext *pContext, const char *InterfaceId)
+{
+ CLockCS CsLock(CLCDriverInterface::InitializationCS);
+
+ CLCDriverInterface *Context = NULL;
+ int ReturnValue = E_SUCCESS;
+
+ // Check pointer to pointer
+ VERIFY(NULL != pContext, INTERFACE_OBJECT_POINTER_TO_POINTER_NULL);
+
+ // Check if CLCDriverInterface already exists
+ VERIFY(NULL == *pContext, INTERFACE_OBJECT_ALREADY_EXISTS);
+
+ // Check context id
+ VERIFY(NULL != InterfaceId, INTERFACE_INTERFACEID_POINTER_NULL);
+
+ // Create new CLCDriverInterface
+ Context = new CLCDriverInterface();
+ VERIFY(NULL != Context, INTERFACE_COULD_NOT_CREATE_IFC_OBJECT);
+
+ strcpy_s(Context->m_szObjectId, InterfaceId);
+
+ // Check in the object list if this particular object has been created earlier.
+ Context->m_pObject = CLCDriverInterface::FindObject(Context->m_szObjectId);
+
+ // An object was found in the list
+ if (Context->m_pObject == NULL) {
+ // Create new CLCDriverMethods
+ Context->m_pObject = new CLCDriverMethods(InterfaceId);
+ VERIFY(NULL != Context->m_pObject, INTERFACE_COULD_NOT_CREATE_OBJECT);
+ }
+
+ // Add the object to the list to increase the reference counter
+ ReturnValue = CLCDriverInterface::AddObject(Context->m_pObject, Context->m_szObjectId);
+ VERIFY(0 == ReturnValue, INTERFACE_COULD_NOT_ADD_OBJECT_TO_LIST);
+
+ *pContext = Context;
+
+ return E_SUCCESS;
+ErrorExit:
+
+ // Delete the CLCDriverInterface
+ if (Context != NULL) {
+ if (Context->m_pObject != NULL) {
+ delete Context->m_pObject;
+ Context->m_pObject = NULL;
+ }
+
+ delete Context;
+ }
+
+ return ReturnValue;
+}
+
+LCDRIVER_API int __cdecl SwitchProtocolFamily(LCDContext Context, TFamily Family)
+{
+ VERIFY_CONTEXT(Context);
+
+ if (Context->isStarted) {
+ return Context->m_pObject->Do_SwitchProtocolFamily(Family);
+ } else {
+ return Context->m_pObject->SetInitialProtocolFamily(Family);
+ }
+}
+
+LCDRIVER_API int __cdecl ConfigureCommunicationDevice(LCDContext Context, void *Read_fn, void *Write_fn, void *Cancel_fn)
+{
+ VERIFY_CONTEXT(Context);
+
+ Context->m_pObject->ConfigureCommunicationDevice(Read_fn, Write_fn, Cancel_fn);
+ return 0;
+}
+
+LCDRIVER_API int __cdecl SetMessageCallback(LCDContext Context, void *Callback_fn)
+{
+ VERIFY_CONTEXT(Context);
+
+ Context->m_pObject->SetMessageCallback(Callback_fn);
+ return 0;
+}
+
+LCDRIVER_API int __cdecl SetProgressCallback(LCDContext Context, void *Callback_fn)
+{
+ VERIFY_CONTEXT(Context);
+
+ Context->m_pObject->SetProgressCallback(Callback_fn);
+ return 0;
+}
+
+LCDRIVER_API int __cdecl StartContext(LCDContext Context, void **Instance)
+{
+ VERIFY_CONTEXT(Context);
+
+ int Result = Context->m_pObject->Do_Initialize(Instance);
+
+ if (0 == Result) {
+ Context->isStarted = true;
+ }
+
+ return Result;
+}
+
+LCDRIVER_API int __cdecl DestroyContext(LCDContext *pContext)
+{
+ LCDContext Context = *pContext;
+ VERIFY_CONTEXT(Context);
+
+ delete Context;
+ *pContext = NULL;
+
+ return 0;
+}
+
+LCDRIVER_API int __cdecl Close(LCDContext Context)
+{
+ return DestroyContext(&Context);
+}
+
+LCDRIVER_API int __cdecl SetTimeouts(LCDContext Context, TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs)
+{
+ VERIFY_CONTEXT(Context);
+
+ return Context->m_pObject->SetPcTimeouts(R15_TOs, LCD_TOs);
+}
+
+LCDRIVER_API int __cdecl GetTimeouts(LCDContext Context, TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs)
+{
+ VERIFY_CONTEXT(Context);
+
+ return Context->m_pObject->GetPcTimeouts(R15_TOs, LCD_TOs);
+}
+
+LCDRIVER_API int __cdecl CancelCurrentLoaderCommand(LCDContext Context)
+{
+ VERIFY_CONTEXT(Context);
+
+ Context->m_pObject->CancelCurrentLoaderCommand();
+
+ return 0;
+}
+
+/************************************************************************************************
+* API functions for loader commands
+************************************************************************************************/
+LCDRIVER_API int __cdecl System_LoaderStartupStatus(LCDContext Context, char *pchVersion, int *piVersionSize, char *pchProtocol, int *piProtocolSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Done_System_LoaderStartupStatus(pchVersion, piVersionSize, pchProtocol, piProtocolSize);
+}
+
+LCDRIVER_API int __cdecl System_Reboot(LCDContext Context, int iMode)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_Reboot(iMode);
+}
+
+LCDRIVER_API int __cdecl System_Shutdown(LCDContext Context)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_Shutdown();
+}
+
+LCDRIVER_API int __cdecl System_SupportedCommands(LCDContext Context, TSupportedCmd *pCmdList, int *piCmdListSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_SupportedCommands(pCmdList, piCmdListSize);
+}
+
+LCDRIVER_API int __cdecl System_CollectData(LCDContext Context, int iType, int *piSize, char *pData)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_CollectData(iType, piSize, pData);
+}
+
+LCDRIVER_API int __cdecl System_ExecuteSoftware(LCDContext Context, const uint32 ExecuteMode, const char *pchDevicePath, int iUseBulk)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_ExecuteSoftware(ExecuteMode, pchDevicePath, iUseBulk);
+}
+
+LCDRIVER_API int __cdecl System_Authenticate(LCDContext Context, int iType, int *piSize, unsigned char *puchdata)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_Authenticate(iType, piSize, puchdata);
+}
+
+LCDRIVER_API int __cdecl System_GetControlKeys(LCDContext Context, TSIMLockKeys *pSIMLockKeys)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Done_System_GetControlKeys(pSIMLockKeys);
+}
+
+LCDRIVER_API int __cdecl System_GetControlKeysData(LCDContext Context, int iDataSize, unsigned char *pSIMLockKeysData)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Done_System_GetControlKeysData(iDataSize, pSIMLockKeysData);
+}
+
+LCDRIVER_API int __cdecl System_AuthenticationChallenge(LCDContext Context, unsigned char *puchChallengeData, int iDataSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Done_System_AuthenticationChallenge(iDataSize, puchChallengeData);
+}
+
+LCDRIVER_API int __cdecl System_SetSystemTime(LCDContext Context, uint32 uiEpochTime)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_SetSystemTime(uiEpochTime);
+}
+
+LCDRIVER_API int __cdecl System_SwitchCommunicationDevice(LCDContext Context, uint32 uiDevice, uint32 uiDeviceParam)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_System_SwitchCommunicationDevice(uiDevice, uiDevice);
+}
+
+LCDRIVER_API int __cdecl Flash_ProcessFile(LCDContext Context, const char *pchPath, const char *pchType, int iUseBulk, int iDeleteBuffers)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Flash_ProcessFile(pchPath, pchType, iUseBulk, iDeleteBuffers);
+}
+
+LCDRIVER_API int __cdecl Flash_ListDevices(LCDContext Context, TDevices *pDevices, int *piDeviceSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Flash_ListDevices(pDevices, piDeviceSize);
+}
+
+LCDRIVER_API int __cdecl Flash_DumpArea(LCDContext Context, const char *pchPathToDump, uint64 uiStart, uint64 uiLength, const char *pchFilePath, uint32 uiRedundantArea, int iUseBulk)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Flash_DumpArea(pchPathToDump, uiStart, uiLength, pchFilePath, uiRedundantArea, iUseBulk);
+}
+
+LCDRIVER_API int __cdecl Flash_EraseArea(LCDContext Context, const char *pchPath, uint64 uiStart, uint64 uiLength)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Flash_EraseArea(pchPath, uiStart, uiLength);
+}
+
+LCDRIVER_API int __cdecl Flash_FlashRaw(LCDContext Context, const char *pchPath, uint64 uiStart, uint64 uiLength, uint32 uiDevice, int iUseBulk, int iDeleteBuffers)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Flash_FlashRaw(pchPath, uiStart, uiLength, uiDevice, iUseBulk, iDeleteBuffers);
+}
+
+LCDRIVER_API int __cdecl FileSystem_VolumeProperties(LCDContext Context, const char *pchDevicePath, char *pchFSType, int *piFSTypeSize, uint64 *puiSize, uint64 *puiFree)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_VolumeProperties(pchDevicePath, pchFSType, piFSTypeSize, puiSize, puiFree);
+}
+
+LCDRIVER_API int __cdecl FileSystem_FormatVolume(LCDContext Context, const char *pchDevicePath)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_FormatVolume(pchDevicePath);
+}
+
+LCDRIVER_API int __cdecl FileSystem_ListDirectory(LCDContext Context, const char *pchPath, TEntries *pEntries, int *piDeviceSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_ListDirectory(pchPath, pEntries, piDeviceSize);
+}
+
+LCDRIVER_API int __cdecl FileSystem_MoveFile(LCDContext Context, const char *pchSourcePath, const char *pchDestinationPath)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_MoveFile(pchSourcePath, pchDestinationPath);
+}
+
+LCDRIVER_API int __cdecl FileSystem_DeleteFile(LCDContext Context, const char *pchTargetPath)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_DeleteFile(pchTargetPath);
+}
+
+LCDRIVER_API int __cdecl FileSystem_CopyFile(LCDContext Context, const char *pchSourcePath, int iSourceUseBulk, const char *pchDestinationPath, int iDestinationUseBulk)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_CopyFile(pchSourcePath, iSourceUseBulk, pchDestinationPath, iDestinationUseBulk);
+}
+
+LCDRIVER_API int __cdecl FileSystem_CreateDirectory(LCDContext Context, const char *pchTargetPath)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_CreateDirectory(pchTargetPath);
+}
+
+LCDRIVER_API int __cdecl FileSystem_Properties(LCDContext Context, const char *pchTargetPath, uint32 *puiMode, uint64 *puiSize, int *piMTime, int *piATime, int *piCTime)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_Properties(pchTargetPath, puiMode, puiSize, piMTime, piATime, piCTime);
+}
+
+LCDRIVER_API int __cdecl FileSystem_ChangeAccess(LCDContext Context, const char *pchTargetPath, int iAccess)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_ChangeAccess(pchTargetPath, iAccess);
+}
+
+LCDRIVER_API int __cdecl FileSystem_ReadLoadModuleManifests(LCDContext Context, const char *pchTargetPath, const char *pchSourcePath)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_FileSystem_ReadLoadModuleManifests(pchTargetPath, pchSourcePath);
+}
+
+LCDRIVER_API int __cdecl OTP_ReadBits(LCDContext Context, int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer, int *piDataBufferSize, unsigned char *puchStatusBuffer, int *piStatusBufferSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_OTP_ReadBits(iOtpId, iBitStart, iBitLength, puchDataBuffer, piDataBufferSize, puchStatusBuffer, piStatusBufferSize);
+}
+
+LCDRIVER_API int __cdecl OTP_SetBits(LCDContext Context, int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_OTP_SetBits(iOtpId, iBitStart, iBitLength, puchDataBuffer);
+}
+
+LCDRIVER_API int __cdecl OTP_WriteAndLock(LCDContext Context, int iOtpId, int iForceWrite)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_OTP_WriteAndLock(iOtpId, iForceWrite);
+}
+
+LCDRIVER_API int __cdecl ParameterStorage_ReadGlobalDataUnit(LCDContext Context, const char *pchGdfsId, int iUnit, unsigned char *puchDataBuffer, int *piSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_ParameterStorage_ReadGlobalDataUnit(pchGdfsId, iUnit, puchDataBuffer, piSize);
+}
+
+LCDRIVER_API int __cdecl ParameterStorage_WriteGlobalDataUnit(LCDContext Context, const char *pchGdfsId, int iUnit, unsigned char *puchDataBuffer, int iSize)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_ParameterStorage_WriteGlobalDataUnit(pchGdfsId, iUnit, puchDataBuffer, iSize);
+}
+
+LCDRIVER_API int __cdecl ParameterStorage_ReadGlobalDataSet(LCDContext Context, const char *pchGdfsId, const char *pchPath, int iUseBulk)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_ParameterStorage_ReadGlobalDataSet(pchGdfsId, pchPath, iUseBulk);
+}
+
+LCDRIVER_API int __cdecl ParameterStorage_WriteGlobalDataSet(LCDContext Context, const char *pchGdfsId, const char *pchPath, int iUseBulk)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_ParameterStorage_WriteGlobalDataSet(pchGdfsId, pchPath, iUseBulk);
+}
+
+LCDRIVER_API int __cdecl ParameterStorage_EraseGlobalDataSet(LCDContext Context, const char *pchGdfsId)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_ParameterStorage_EraseGlobalDataSet(pchGdfsId);
+}
+
+LCDRIVER_API int __cdecl Security_SetDomain(LCDContext Context, int iDomain)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Security_SetDomain(iDomain);
+}
+
+LCDRIVER_API int __cdecl Security_GetDomain(LCDContext Context, int *piWrittenDomain)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Security_GetDomain(piWrittenDomain);
+}
+
+LCDRIVER_API int __cdecl Security_GetProperties(LCDContext Context, int iUnitId, int *piSize, unsigned char *puchDataBuffer)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Security_GetProperties(iUnitId, piSize, puchDataBuffer);
+}
+
+LCDRIVER_API int __cdecl Security_SetProperties(LCDContext Context, int iUnitId, int iSize, unsigned char *puchDataBuffer)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Security_SetProperties(iUnitId, iSize, puchDataBuffer);
+}
+
+LCDRIVER_API int __cdecl Security_BindProperties(LCDContext Context)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Security_BindProperties();
+}
+
+LCDRIVER_API int __cdecl Security_StoreSecureObject(LCDContext Context, const char *pchSourcePath, int iDestination, int iUseBulk)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_OTP_StoreSecureObject(pchSourcePath, iDestination, iUseBulk);
+}
+
+LCDRIVER_API int __cdecl A2_System_Shutdown(LCDContext Context)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_A2_System_Shutdown();
+}
+
+LCDRIVER_API int __cdecl A2_System_LoaderVersion(LCDContext Context, char *pchLoaderVersion, int *piSize, int iTargetCPU)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_A2_System_LoaderVersion(pchLoaderVersion, piSize, iTargetCPU);
+}
+
+LCDRIVER_API int __cdecl A2_System_LoaderOnLoader(LCDContext Context, const char *pchPath, int iPLOffset, int iHLOffset, int iTargetCPU)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_A2_System_LoaderOnLoader(pchPath, iPLOffset, iHLOffset, iTargetCPU);
+}
+
+LCDRIVER_API int __cdecl A2_System_Reset(LCDContext Context, int iTimeout)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_A2_System_Reset(iTimeout);
+}
+
+LCDRIVER_API int __cdecl A2_Flash_ProgramFlash(LCDContext Context, const char *pchPath, int iUseSpeedFlash)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_A2_Flash_ProgramFlash(pchPath, iUseSpeedFlash);
+}
+
+LCDRIVER_API int __cdecl A2_Flash_EraseFlash(LCDContext Context)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_A2_Flash_EraseFlash();
+}
+
+LCDRIVER_API int __cdecl A2_Control_LoaderStarted(LCDContext Context)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Done_A2_Control_LoaderStarted();
+}
+
+LCDRIVER_API int __cdecl SetProtocolFamily(LCDContext Context, const char *pchFamily)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ TFamily newFamily;
+
+ if (0 == strcmp(pchFamily, "R15_FAMILY")) {
+ newFamily = R15_PROTOCOL_FAMILY;
+ } else if (0 == strcmp(pchFamily, "PROTROM_FAMILY")) {
+ newFamily = PROTROM_PROTOCOL_FAMILY;
+ } else if (0 == strcmp(pchFamily, "NOPROT")) {
+ newFamily = Z_PROTOCOL_FAMILY;
+ } else if (0 == strcmp(pchFamily, "A2_FAMILY")) {
+ newFamily = A2_PROTOCOL_FAMILY;
+ } else {
+ return INVALID_INPUT_PARAMETERS;
+ }
+
+ return Context->m_pObject->Do_SwitchProtocolFamily(newFamily);
+}
+
+LCDRIVER_API int __cdecl Z_SetInServiceMode(LCDContext Context, unsigned int *puiChipId)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Z_SetInServiceMode(puiChipId);
+}
+
+LCDRIVER_API int __cdecl Z_SetBaudrate(LCDContext Context, int iBaudrate)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Z_SetBaudrate(iBaudrate);
+}
+
+LCDRIVER_API int __cdecl Z_Exit_Z_Protocol(LCDContext Context)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_Z_Exit_Z_Protocol();
+}
+
+LCDRIVER_API int __cdecl PROTROM_DownloadLoader(LCDContext Context, const char *pchPath, int iPLOffset, int iHLOffset, int iContinueProtRom)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ return Context->m_pObject->Do_PROTROM_DownloadLoader(pchPath, iPLOffset, iHLOffset, iContinueProtRom);
+}
+
+LCDRIVER_API int __cdecl PROTROM_ReadSecurityData(LCDContext Context, unsigned char uiSecDataId, unsigned char *puchDataBuffer, int *piDataLength)
+{
+ VERIFY_CONTEXT_STARTED(Context);
+
+ if (NULL == puchDataBuffer || 0 == piDataLength) {
+ return INVALID_INPUT_PARAMETERS;
+ }
+
+ return Context->m_pObject->Do_PROTROM_ReadSecurityData(uiSecDataId, puchDataBuffer, piDataLength);
+}
diff --git a/source/LCDriver.h b/source/LCDriver.h
new file mode 100644
index 0000000..dd746b7
--- /dev/null
+++ b/source/LCDriver.h
@@ -0,0 +1,824 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _LCDRIVER_H_
+#define _LCDRIVER_H_
+
+#if defined(_WIN32)
+#ifdef LCDRIVER_EXPORTS
+#define LCDRIVER_API __declspec(dllexport)
+#else
+#define LCDRIVER_API __declspec(dllimport)
+#endif
+
+typedef unsigned __int64 uint64;
+typedef unsigned long uint32;
+#elif defined(__linux__)
+#ifdef LCDRIVER_EXPORTS
+#define LCDRIVER_API __attribute__((visibility("default")))
+#else
+#define LCDRIVER_API
+#endif
+
+typedef unsigned long long uint64;
+typedef unsigned int uint32;
+
+#define __cdecl
+#else
+#error "Unknown platform"
+#endif
+
+typedef struct CLCDriverInterface *LCDContext;
+
+/// <summary>
+/// Command information.
+/// </summary>
+/// <param name="iGroup">Command group number.</param>
+/// <param name="iCommand">Command number.</param>
+/// <param name="iPermitted">Permition level.</param>
+typedef struct {
+ int iGroup;
+ int iCommand;
+ int iPermitted;
+} TSupportedCmd;
+
+/// <summary>
+/// Description of ME device.
+/// </summary>
+/// <param name="pchPath">Absolute device path pointing at the described device.</param>
+/// <param name="iPathSize">Size of pchPath.</param>
+/// <param name="pchType">Type of device.</param>
+/// <param name="iTypeSize">Size of pchType.</param>
+/// <param name="uiBlockSize">Size of the smallest addressable unit in the device [Byte].</param>
+/// <param name="uiStart">Offset [Byte] of the start of the device relative its parent's
+/// offset 0 with granularity of its parent's block size.</param>
+/// <param name="uiLength">Length of the device [Byte].</param>
+typedef struct {
+ const char *pchPath;
+ int iPathSize;
+ const char *pchType;
+ int iTypeSize;
+ uint64 uiBlockSize;
+ uint64 uiStart;
+ uint64 uiLength;
+} TDevices;
+
+/// <summary>
+/// Description of filesystem file or directory in ME.
+/// </summary>
+/// <param name="pchName">Name of file or directory.</param>
+/// <param name="iNameSize">Size of pchName.</param>
+/// <param name="uiSize">Size of file or directory.</param>
+/// <param name="iMode">Indicator of file or directory.</param>
+/// <param name="iTime">Time of last modification.</param>
+typedef struct {
+ const char *pchName;
+ int iNameSize;
+ uint64 uiSize;
+ int iMode;
+ int iTime;
+} TEntries;
+
+/// <summary>
+/// 12 SIM lock/unlock keys.
+/// </summary>
+/// <param name="pchNLCKLock">NLCKLock key.</param>
+/// <param name="pchNSLCKLock">NSLCKLock key.</param>
+/// <param name="pchSPLCKLock">SPLCKLock key.</param>
+/// <param name="pchCLCKLock">CLCKLock key.</param>
+/// <param name="pchPCKLock">PCKLock key.</param>
+/// <param name="pchESLCKLock">ESLCKLock key.</param>
+/// <param name="pchNLCKUnLock">NLCKUnLock key.</param>
+/// <param name="pchNSLCKUnLock">NSLCKUnLock key.</param>
+/// <param name="pchSPLCKUnLock">SPLCKUnLock key.</param>
+/// <param name="pchCLCKUnLock">CLCKUnLock key.</param>
+/// <param name="pchPCKUnLock">PCKUnLock key.</param>
+/// <param name="pchESLCKUnLock">ESLCKUnLock key.</param>
+typedef struct {
+ char *pchNLCKLock;
+ char *pchNSLCKLock;
+ char *pchSPLCKLock;
+ char *pchCLCKLock;
+ char *pchPCKLock;
+ char *pchESLCKLock;
+
+ char *pchNLCKUnLock;
+ char *pchNSLCKUnLock;
+ char *pchSPLCKUnLock;
+ char *pchCLCKUnLock;
+ char *pchPCKUnLock;
+ char *pchESLCKUnLock;
+} TSIMLockKeys;
+
+/// <summary>
+/// LCDriver time out.
+/// </summary>
+/// <param name="uiSTO">Startup TimeOut.</param>
+/// <param name="uiRTO">Response TimeOut.</param>
+typedef struct {
+ uint32 uiSTO;
+ uint32 uiRTO;
+} TLCDriverTimeouts;
+
+/// <summary>
+/// R15 protocol time out.
+/// </summary>
+/// <param name="TCACK">Time for command packet acknowledge.</param>
+/// <param name="TBCR">Time for bulk command packet to be recieved.</param>
+/// <param name="TBES">Time for bulk session end. NOTE: Starting from version R1J this timeout is not
+///used in LCM but it stays in LCDriver interface to avoid interface changes.</param>
+/// <param name="TBDR">Time for bulk data packet to be received.</param>
+typedef struct {
+ uint32 TCACK;
+ uint32 TBCR;
+ uint32 TBES;
+ uint32 TBDR;
+} TR15Timeouts;
+
+/// <summary>
+/// Protocol family.
+/// </summary>
+typedef enum {
+ /// <summary>R15 protocol family.</summary>
+ R15_PROTOCOL_FAMILY = 0,
+ /// <summary>A2 protocol family.</summary>
+ A2_PROTOCOL_FAMILY = 1,
+ /// <summary>PROTROM protocol family.</summary>
+ PROTROM_PROTOCOL_FAMILY = 3,
+ /// <summary>Z protocol family.</summary>
+ Z_PROTOCOL_FAMILY = 4
+} TFamily;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+ /// <summary>
+ /// Initializes new instance of the LCD context.
+ ///
+ /// Deprecated.
+ /// Instead of this function please use: SetLCMLibPath, CreateContext, SwitchProtocolFamily, ConfigureCommunicationDevice,
+ /// SetMessageCallback, SetProgressCallback and StartContext. These new functions give separation between creation,
+ /// configuration and startup of the context.
+ /// </summary>
+ /// <param name="pContext">A pointer to a LCDContext where to store the newly created context or to put
+ /// the previously created context if the context with the specified interface id already exists.</param>
+ /// <param name="InterfaceId">A zero terminated string conaining the interface unique ID.</param>
+ /// <param name="Read_fn">A pointer to a communication device read function.</param>
+ /// <param name="Write_fn">A pointer to a communication device write function.</param>
+ /// <param name="Cancel_fn">A pointer to a communication device cancel function.</param>
+ /// <param name="Instance">A pointer to a pointer where to store the adress of the loader communication module instance.</param>
+ /// <param name="Message_fn">A pointer to a message loging function.</param>
+ /// <param name="LCMLibPath">A zero terminated string containing the path to the LCM library.</param>
+ /// <param name="ProgressBar_fn">A pointer to function which receives the progress updates.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl Initialize(LCDContext *pContext, const char *InterfaceId, void *Read_fn, void *Write_fn, void *Cancel_fn, void **Instance, void *Message_fn, const char *LCMLibPath, void *ProgressBar_fn);
+
+ /// <summary>
+ /// Closes the LCD context.
+ ///
+ /// Deprecated.
+ /// Instead of this function please use DestroyContext which properly sets the LCD context to NULL to avoid further usage
+ /// of the destroyed context.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl Close(LCDContext Context);
+
+ /// <summary>
+ /// Sets the global LCM library path.
+ /// </summary>
+ /// <param name="LCMLibPath">A zero terminated string containing the path to the LCM library.</param>
+ LCDRIVER_API void __cdecl SetLCMLibPath(const char *LCMLibPath);
+
+ /// <summary>
+ /// Creates new LCD context with the specified interface ID.
+ /// </summary>
+ /// <param name="pContext">A pointer to a LCDContext where to store the newly created context or to put
+ /// the previously created context if the context with the specified interface id already exists.</param>
+ /// <param name="InterfaceId">A zero terminated string containing the interface unique ID.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl CreateContext(LCDContext *pContext, const char *InterfaceId);
+
+ /// <summary>
+ /// Sets the initial family of not started context, or switches the protocol family of started context.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="Family">New family to be set.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl SwitchProtocolFamily(LCDContext Context, TFamily Family);
+
+ /// <summary>
+ /// Configures the communication device to be used for the context.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="Read_fn">A pointer to a communication device read function.</param>
+ /// <param name="Write_fn">A pointer to a communication device write function.</param>
+ /// <param name="Cancel_fn">A pointer to a communication device cancel function.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl ConfigureCommunicationDevice(LCDContext Context, void *Read_fn, void *Write_fn, void *Cancel_fn);
+
+ /// <summary>
+ /// Sets the callback for message loging.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="Callback_fn">A pointer to a message loging function.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl SetMessageCallback(LCDContext Context, void *Callback_fn);
+
+ /// <summary>
+ /// Sets the callback for progress updates.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="Callback_fn">A pointer to function which receives the progress updates.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl SetProgressCallback(LCDContext Context, void *Callback_fn);
+
+ /// <summary>
+ /// Starts the context. Should be called after the required parameters are previously configured.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="Instance">A pointer to a pointer where to store the adress of the started communication instance.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl StartContext(LCDContext Context, void **Instance);
+
+ /// <summary>
+ /// Destroys the context. Should be called last after we are finished with the context.
+ /// </summary>
+ /// <param name="pContext">Pointer to LCDContext on which to execute the operation.
+ /// LCDContext is set to NULL after this function is called.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl DestroyContext(LCDContext *pContext);
+
+ /// <summary>
+ /// Sets the LCD and R15 protocol timeouts.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="R15_TOs">Pointer to TR15Timeouts structure.</param>
+ /// <param name="LCD_TOs">Pointer to TLCDriverTimeouts structure.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl SetTimeouts(LCDContext Context, TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs);
+
+ /// <summary>
+ /// Gets the LCD and R15 protocol timeouts.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="R15_TOs">Pointer to TR15Timeouts structure.</param>
+ /// <param name="LCD_TOs">Pointer to TLCDriverTimeouts structure.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl GetTimeouts(LCDContext Context, TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs);
+
+ /// <summary>
+ /// Cancels the currently executing command.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <returns>0 if OK, otherwise non-zero.</returns>
+ LCDRIVER_API int __cdecl CancelCurrentLoaderCommand(LCDContext Context);
+
+ /// <summary>
+ /// The Loader Start-up Status command is sent by the ME to notify the host that it has started. The Status parameter indicates in what mode the loader started.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchVersion">Loader version identifier.</param>
+ /// <param name="piVersionSize">Number of allocated bytes for version string.</param>
+ /// <param name="pchProtocol">Protocol version identifier.</param>
+ /// <param name="piProtocolSize">Number of allocated bytes for protocol string.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_LoaderStartupStatus(LCDContext Context, char *pchVersion, int *piVersionSize, char *pchProtocol, int *piProtocolSize);
+
+ /// <summary>
+ /// The Reboot command is used to instruct the loader to reset the ME. Upon receiving this command,
+ /// the loader shuts down in a controlled fashion and restarts the ME. The Mode parameter is used to
+ /// select the mode of reset. The ME does not accept any further communication after a successful
+ /// response from this command has been returned.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iMode">Indicates the mode of reset:
+ /// 0: indicates normal restart.
+ /// 1: indicates restart in service mode.
+ /// 2: indicates restart with JTAG debugging enabled.
+ /// 3: indicates restart in service mode and with JTAG debugging enabled.
+ /// </param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_Reboot(LCDContext Context, int iMode);
+
+ /// <summary>
+ /// The loader shuts down in a controlled fashion and proceeds to shut down the ME itself.
+ /// The ME does not accept any further communication after a successful response from this
+ /// command has been returned.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_Shutdown(LCDContext Context);
+
+ /// <summary>
+ /// The loader returns a list of implemented commands and whether they are permitted to
+ /// execute in the current loader state.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pCmdList">A list with supported commands.</param>
+ /// <param name="piCmdListSize">Number of commands in CmdList.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_SupportedCommands(LCDContext Context, TSupportedCmd *pCmdList, int *piCmdListSize);
+
+ /// <summary>
+ /// This command is used by the loader to extract debug, measurement or flashing status data.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iType">Type of data to be extracted.</param>
+ /// <param name="piSize">Size of the collected data buffer.</param>
+ /// <param name="pData">Buffer to hold the collected data.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_CollectData(LCDContext Context, int iType, int *piSize, char *pData);
+
+ /// <summary>
+ /// Receive, verify and execute software, which can be a signed loader.
+ /// After having sent this command, the ME attempts to read the software
+ /// payload data from the host using the Bulk protocol or from the flash
+ /// file system depending on the selected path. The current loader does not
+ /// respond to communication after this command has been successfully executed.
+ /// If the executed software is another loader, communication can be resumed once the
+ /// Loader Started command has been received. A response of E_OPERATION_CANCELLED
+ /// indicates the operation was canceled.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="ExecuteMode">Execute mode: 1 = execution from specified address, 2 = first load the software then execute. </param>
+ /// <param name="pchDevicePath">Target path. If use bulk the path is on PC, else on ME.</param>
+ /// <param name="iUseBulk">If value = 1 -> source on PC, else source on ME.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_ExecuteSoftware(LCDContext Context, const uint32 ExecuteMode, const char *pchDevicePath, int iUseBulk);
+
+ /// <summary>
+ /// This command is used to escalate the privileges of the operator. Two ways of
+ /// authentication are available by default; control key authentication and certificate based
+ /// authentication. The authentication command sets the loader in a specific
+ /// authentication context when it takes control over the command flow. After
+ /// receiving the authentication command, the loader sends the appropriate request for information to the PC.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iType">Authentication type:0 = control key authentication,1 = certificate authentication.</param>
+ /// <param name="piSize">Size of puchData.</param>
+ /// <param name="puchdata">Data challange. </param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_Authenticate(LCDContext Context, int iType, int *piSize, unsigned char *puchdata);
+
+ /// <summary>
+ /// This command is used by the loader to retrieve the SimLock control keys from the host to authenticate a user.
+ /// The command is used in the authentication context.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pSIMLockKeys">A struct with all lock/unlock keys.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_GetControlKeys(LCDContext Context, TSIMLockKeys *pSIMLockKeys);
+
+ /// <summary>
+ /// This command is used by the loader to retrieve the SimLock control keys data from the host to authenticate a user.
+ /// The command is used in the authentication context.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="SIMLockKeysData">SIMLockKeyData buffer that contain all SIMLock keys.</param>
+ /// <param name="iDataSize">SIMLockKeyData buffer size.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_GetControlKeysData(LCDContext Context, int iDataSize, unsigned char *pSIMLockKeysData);
+
+ /// <summary>
+ /// This command is used by the loader to perform a certificate authentication.
+ /// The command is only used in the authentication context.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="puchChallengeData">Authentication challenge. This challenge must be signed
+ /// using the correct certificate and returned to the loader.</param>
+ /// <param name="iDataSize">Authentication challenge buffer length.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_AuthenticationChallenge(LCDContext Context, unsigned char *puchChallengeData, int iDataSize);
+
+ /// <summary>
+ /// The Set System Time command is used to set the current epoch time for loader
+ /// to configure the real time clock and use it for file system operations.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="uiEpochTime">Number of seconds that have elapsed since January 1, 1970</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_SetSystemTime(LCDContext Context, uint32 uiEpochTime);
+
+ /// <summary>
+ /// This command is used to instruct the Loader to switch to a new communication device.
+ /// </summary>
+ /// <param name="uiDevice">Device ID of the communication device to switch to.</param>
+ /// <param name="uiDeviceParam">Communication device parameters.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl System_SwitchCommunicationDevice(LCDContext Context, uint32 uiDevice, uint32 uiDeviceParam);
+
+ /// <summary>
+ /// This command is used to initiate a flashing session. The type argument is
+ /// used to select the type of file to process and Length parameter
+ /// defines the total size of the file.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchPath">Target path. If iUseBulk = 1, path is on PC.</param>
+ /// <param name="pchType">Type of the opened file.</param>
+ /// <param name="iUseBulk">If to use bulk protocol. If target is on PC iUseBulk shall be 1.</param>
+ /// <param name="iDeleteBuffers">Specify if to delete bulk buffers after finish. 1 -> delete buffers. 0 -> don't delete buffers.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Flash_ProcessFile(LCDContext Context, const char *pchPath, const char *pchType, int iUseBulk, int iDeleteBuffers);
+
+ /// <summary>
+ /// This command is used by the client application program to obtain the device tree.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pDevices">A struct with information about one flash device.</param>
+ /// <param name="piDeviceSize">Number of flash devices, size of pDevices array.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Flash_ListDevices(LCDContext Context, TDevices *pDevices, int *piDeviceSize);
+
+ /// <summary>
+ /// This command is used to initiate a dump session.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchPathToDump">Path to the device to dump.</param>
+ /// <param name="uiStart">Start of the dump relative to the start of the device indicated by Path [Byte].</param>
+ /// <param name="uiLength">Length of the dump [Byte]. Actual length is determined by the device block size.</param>
+ /// <param name="pchFilePath">File path on PC to store dump data to.</param>
+ /// <param name="uiRedundantArea">0-> dump with redundant data, 1-> dump without redundant data.</param>
+ /// <param name="iUseBulk">1-> save dump data on PC, 0-> save dump data on ME.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Flash_DumpArea(LCDContext Context, const char *pchPathToDump, uint64 uiStart, uint64 uiLength, const char *pchFilePath, uint32 uiRedundantArea, int iUseBulk);
+
+ /// <summary>
+ /// This command is used to erase a flash device or part of a flash device.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchPath">Path to the device to erase.</param>
+ /// <param name="uiStart">Start of the erase relative to the start of the device
+ /// indicated by path [Byte]. This must be a multiple of the block size of the device.</param>
+ /// <param name="uiLength">Length of the dump [Byte]. This must be a multiple of the block size of the device.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Flash_EraseArea(LCDContext Context, const char *pchPath, uint64 uiStart, uint64 uiLength);
+
+ /// <summary>
+ /// This command is used to initiate a flashing of raw data.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchPath">Target path. If iUseBulk = 1, path is on PC.</param>
+ /// <param name="uiStart">Address where flashing should start.</param>
+ /// <param name="uiLength">Length of data to be flashed.</param>
+ /// <param name="uiDevice">Device ID number.</param>
+ /// <param name="iUseBulk">If to use bulk protocol. If target is on PC iUseBulk shall be 1.</param>
+ /// <param name="iDeleteBuffers">Specify if to delete bulk buffers after finish. 1 -> delete buffers. 0 -> don't delete buffers.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Flash_FlashRaw(LCDContext Context, const char *pchPath, uint64 uiStart, uint64 uiLength, uint32 uiDevice, int iUseBulk, int iDeleteBuffers);
+
+ /// <summary>
+ /// This command retrieves the properties of the specified file system volume. It is issued by the PC application.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchDevicePath">Path of file system volume.</param>
+ /// <param name="pchFSType">File system type.</param>
+ /// <param name="piFSTypeSize">Size of pchFSType array.</param>
+ /// <param name="puiSize">Total size of the file system [Byte].</param>
+ /// <param name="puiFree">Available space [Byte].</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_VolumeProperties(LCDContext Context, const char *pchDevicePath, char *pchFSType, int *piFSTypeSize, uint64 *puiSize, uint64 *puiFree);
+
+ /// <summary>
+ /// Formats unused file system volume specified in device path. This operation fails if the volume is currently in use.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchDevicePath">Device path of the file system volume.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_FormatVolume(LCDContext Context, const char *pchDevicePath);
+
+ /// <summary>
+ /// List files and directories residing in specified path.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchPath">File system path.</param>
+ /// <param name="pEntries">Struct with file and directory information.</param>
+ /// <param name="piDeviceSize">Number of files or directories, number of element in pEntries array.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_ListDirectory(LCDContext Context, const char *pchPath, TEntries *pEntries, int *piDeviceSize);
+
+ /// <summary>
+ /// This command moves a file from the source path to the destination path if the source and destination differ.
+ /// It also renames a file if the source path and the destination path are the same.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchSourcePath">File system path in ME to source.</param>
+ /// <param name="pchDestinationPath">File system path in ME to destination.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_MoveFile(LCDContext Context, const char *pchSourcePath, const char *pchDestinationPath);
+
+ /// <summary>
+ /// Delete the specified file or directory. The loader only deletes empty directories.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchTargetPath">File system path in ME.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_DeleteFile(LCDContext Context, const char *pchTargetPath);
+
+ /// <summary>
+ /// This command is used to do the following: Copy a file from the PC to the ME. Copy a file between two directories or file systems on the ME.
+ /// Copy a file from the ME to the PC.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchSourcePath">If iSourceUseBulk = 1 -> path on PC, else path on ME.</param>
+ /// <param name="iSourceUseBulk">If = 1 -> source on PC, else source on ME.</param>
+ /// <param name="pchDestinationPath">If iDestinationUseBulk = 1 -> path on PC, else path on ME.</param>
+ /// <param name="iDestinationUseBulk">If = 1 -> destination on PC, else destination on ME.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_CopyFile(LCDContext Context, const char *pchSourcePath, int iSourceUseBulk, const char *pchDestinationPath, int iDestinationUseBulk);
+
+ /// <summary>
+ /// This command is used to create a directory. It is issued by the PC application.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchTargetPath">File system path to target.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_CreateDirectory(LCDContext Context, const char *pchTargetPath);
+
+ /// <summary>
+ /// This command is used to retrieve the properties of a file or directory.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchTargetPath">File system path to target.</param>
+ /// <param name="puiMode">File type and access restrictions descriptor.</param>
+ /// <param name="puiSize">File size [Byte].</param>
+ /// <param name="piMTime">Last modification timestamp.</param>
+ /// <param name="piATime">Last access timestamp.</param>
+ /// <param name="piCTime">Creation timestamp.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_Properties(LCDContext Context, const char *pchTargetPath, uint32 *puiMode, uint64 *puiSize, int *piMTime, int *piATime, int *piCTime);
+
+ /// <summary>
+ /// This command is used to change the access permissions of a specified path.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchTargetPath">File system path to target.</param>
+ /// <param name="iAccess">New access permissions.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_ChangeAccess(LCDContext Context, const char *pchTargetPath, int iAccess);
+
+ /// <summary>
+ /// This command is used to read manifests contained in load modules at the specified path and send the data back over bulk protocol.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchTargetPath">Path on PC to save manifest.</param>
+ /// <param name="pchSourcePath">Load module(s) file system path.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl FileSystem_ReadLoadModuleManifests(LCDContext Context, const char *pchTargetPath, const char *pchSourcePath);
+
+
+ /// <summary>
+ /// This command is used to read the specified bits from the OTP.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iOtpId">OTP area ID.</param>
+ /// <param name="iBitStart">Starting offset [bit].</param>
+ /// <param name="iBitLength">Length of read [bit].</param>
+ /// <param name="puchDataBuffer">Received OTP data.</param>
+ /// <param name="piDataBufferSize">Size of puchDataBuffer.</param>
+ /// <param name="puchStatusBuffer">Lock status for each read bit.</param>
+ /// <param name="piStatusBufferSize">Size of puchStatusBuffer.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl OTP_ReadBits(LCDContext Context, int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer, int *piDataBufferSize, unsigned char *puchStatusBuffer, int *piStatusBufferSize);
+
+ /// <summary>
+ /// This command stores the specified bits in the loader internal OTP structures in RAM, it does not write to OTP.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iOtpId">OTP area ID.</param>
+ /// <param name="iBitStart">Starting offset [bit].</param>
+ /// <param name="iBitLength">Length of write [bit].</param>
+ /// <param name="puchDataBuffer">OTP data to write.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl OTP_SetBits(LCDContext Context, int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer);
+
+ /// <summary>
+ /// This command writes (burns) all data from loader internal OTP structures in RAM into the OTP fuse box.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iOtpId">OTP area ID.</param>
+ /// <param name="iForceWrite">If true: write and lock all lockable areas even if not all bits are received in cache.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl OTP_WriteAndLock(LCDContext Context, int iOtpId, int iForceWrite);
+
+ /// <summary>
+ /// Reads a specified unit from the global data storage area/partition specified by the DevicePath parameter.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchGdfsId">GDFS ID.</param>
+ /// <param name="iUnit">Unit ID to read.</param>
+ /// <param name="puchDataBuffer">Received global data.</param>
+ /// <param name="piSize">Size of puchDataBuffer.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl ParameterStorage_ReadGlobalDataUnit(LCDContext Context, const char *pchGdfsId, int iUnit, unsigned char *puchDataBuffer, int *piSize);
+
+ /// <summary>
+ /// Writes a specified unit to the global data storage area/partition specified by the pchGdfsId parameter.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchGdfsId">GDFS ID.</param>
+ /// <param name="iUnit">Unit ID to write.</param>
+ /// <param name="puchDataBuffer">Global data to write.</param>
+ /// <param name="iSize">Size of puchDataBuffer.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl ParameterStorage_WriteGlobalDataUnit(LCDContext Context, const char *pchGdfsId, int iUnit, unsigned char *puchDataBuffer, int iSize);
+
+ /// <summary>
+ /// Reads the complete global data storage area/partition specified by the pchGdfsId parameter (reads all units at once).
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchGdfsId">GDFS ID.</param>
+ /// <param name="pchPath">If iUseBulk=1 -> path on PC to save data set to. Else path on ME.</param>
+ /// <param name="iUseBulk">1-> save global data on PC, 0-> save global data on ME.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl ParameterStorage_ReadGlobalDataSet(LCDContext Context, const char *pchGdfsId, const char *pchPath, int iUseBulk);
+
+ /// <summary>
+ /// Writes the complete global data storage area/partition specified by the pchGdfsId parameter (writes all units at once).
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchGdfsId">GDFS ID.</param>
+ /// <param name="pchPath">If iUseBulk=1 -> path on PC. Else path on ME</param>
+ /// <param name="iUseBulk">1-> global data source on PC, 0-> global data source on ME.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl ParameterStorage_WriteGlobalDataSet(LCDContext Context, const char *pchGdfsId, const char *pchPath, int iUseBulk);
+
+ /// <summary>
+ /// Erases the complete global data storage area/partition specified by the DevicePath parameter.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchGdfsId">GDFS ID.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl ParameterStorage_EraseGlobalDataSet(LCDContext Context, const char *pchGdfsId);
+
+
+ /// <summary>
+ /// This command is used to set the ME domain.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iDomain">Target domain.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Security_SetDomain(LCDContext Context, int iDomain);
+
+ /// <summary>
+ /// This command is used to get the ME domain.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="piWrittenDomain">The ME current domain.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Security_GetDomain(LCDContext Context, int *piWrittenDomain);
+
+ /// <summary>
+ /// This command is used to read a security data unit (such as a secure static or dynamic data unit).
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iUnitId">Unit ID to read.</param>
+ /// <param name="piSize">Size of puchDataBuffer.</param>
+ /// <param name="puchDataBuffer">The unit data.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Security_GetProperties(LCDContext Context, int iUnitId, int *piSize, unsigned char *puchDataBuffer);
+
+ /// <summary>
+ /// This command is used to write a security data unit (such as a secure static or dynamic data unit).
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iUnitId">Unit ID to write.</param>
+ /// <param name="iSize">Size of puchDataBuffer.</param>
+ /// <param name="puchDataBuffer">The data to write.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Security_SetProperties(LCDContext Context, int iUnitId, int iSize, unsigned char *puchDataBuffer);
+
+ /// <summary>
+ /// This command associates all security data units with the current ME.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Security_BindProperties(LCDContext Context);
+
+ /// <summary>
+ /// This command installs a secure object to the Boot record or OTP area.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchSourcePath">If iUseBulk = 1 -> path on PC, else path on ME.</param>
+ /// <param name="iDestination">Secure object destination address on ME.</param>
+ /// <param name="iUseBulk">Source on PC -> iUseBulk= 1. Source on ME -> iUseBulk= 0.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Security_StoreSecureObject(LCDContext Context, const char *pchSourcePath, int iDestination, int iUseBulk);
+
+ /// <summary>
+ /// The A2 loader shuts down in a controlled fashion and proceeds to shut down the ME itself.
+ /// The ME does not accept any further communication after a successful response from this
+ /// command has been returned.
+ /// </summary>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl A2_System_Shutdown(LCDContext Context);
+
+ /// <summary>
+ /// The PC uses the Loader version command to request version information from the loader
+ /// The response holds the loader version information coded as ASCII characters in the data field
+ /// </summary>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl A2_System_LoaderVersion(LCDContext Context, char *pchLoaderVersion, int *piSize, int iTargetCPU);
+
+ /// <summary>
+ /// The Loader on loader command is used to transfer a new loader to the ME
+ /// When the header or payload has been sent, the loader responds with a GR using status codes.
+ /// </summary>
+ /// <returns> Status of the command.</returns>
+ LCDRIVER_API int __cdecl A2_System_LoaderOnLoader(LCDContext Context, const char *pchPath, int iPLOfset, int iHLOffset, int iTargetCPU);
+
+ /// <summary>
+ /// The Reset command will reset the phone using the watchdog reset functionality of the ARM processor.
+ /// </summary>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl A2_System_Reset(LCDContext Context, int iTimeout);
+
+ /// <summary>
+ /// The Program flash command is sent by the PC to write a block of data into the flash memory.
+ /// The block data is sent in the data field.
+ /// When a complete block has been transmitted the loader verifies the data and responds with a GR using status codes
+ /// </summary>
+ /// <returns> Status of the command.</returns>
+ LCDRIVER_API int __cdecl A2_Flash_ProgramFlash(LCDContext Context, const char *pchPath, int iUseSpeedFlash);
+
+ /// <summary>
+ /// The Erase flash command is used to erase the complete flash memory.
+ /// It checks what type of memory is used in the ME and erases the complete memory including the first memory block.
+ /// If more than one flash is attached, all of them will be erased
+ /// The loader responds with a GR using status codes
+ /// </summary>
+ /// <returns> Status of the command.</returns>
+ LCDRIVER_API int __cdecl A2_Flash_EraseFlash(LCDContext Context);
+
+ /// <summary>
+ /// The loader started message is sent from the ME to the PC as soon as the loader has started executing
+ /// and is ready to receive commands.
+ /// </summary>
+ /// <returns> Status of the command.</returns>
+ LCDRIVER_API int __cdecl A2_Control_LoaderStarted(LCDContext Context);
+
+ /// <summary>
+ /// Set protocol to use.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchFamily">Protocol to use. Valid values: R15_FAMILY, PROTROM_FAMILY, NOPROT</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl SetProtocolFamily(LCDContext Context, const char *pchFamily);
+
+ /// <summary>
+ /// Set ME in service mode and receive chip id.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="puiChipId">Received chip id.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Z_SetInServiceMode(LCDContext Context, unsigned int *puiChipId);
+
+ /// <summary>
+ /// Set communication baudrate when communicating via UART.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="iBaudrate">Baudrate to use. Valid values: 9600, 19200, 38400, 57600, 115200,
+ /// 230400, 460800, 921600, 1625000.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Z_SetBaudrate(LCDContext Context, int iBaudrate);
+
+ /// <summary>
+ /// Exit Z-protocol and start using PROTROM-protocol.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl Z_Exit_Z_Protocol(LCDContext Context);
+
+ /// <summary>
+ /// Download loader using PROTROM-protocol.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="pchPath">Path to loader on PC.</param>
+ /// <param name="iPLOffset">Offset in header to payload length.</param>
+ /// <param name="iHLOffset">Offset in header to header length.</param>
+ /// <param name="iContinueProtRom">1 -> continue use PROTROM-protocol after download the loader. O -> not use PROTROM-protocol after download the loader.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl PROTROM_DownloadLoader(LCDContext Context, const char *pchPath, int iPLOffset, int iHLOffset, int iContinueProtRom);
+
+ /// <summary>
+ /// Send intrinsic request to read security data using PROTROM-protocol.
+ /// </summary>
+ /// <param name="Context">LCD context on which to execute the operation.</param>
+ /// <param name="uiSecDataId">ID of the security data to be read with the intrinsic request.</param>
+ /// <param name="puchDataBuffer">Buffer where the read data will be stored.</param>
+ /// <param name="piDataLength">IN: Length of DataBuffer; OUT: Read data length.</param>
+ /// <returns>Status of the command.</returns>
+ LCDRIVER_API int __cdecl PROTROM_ReadSecurityData(LCDContext Context, unsigned char uiSecDataId, unsigned char *puchDataBuffer, int *piDataLength);
+
+ // Random SIMLock keys generation functions not related to communication
+ LCDRIVER_API int __cdecl Algorithms_SimGeneratorInit(void *Object, int SecurityLevel);
+ LCDRIVER_API int __cdecl Algorithms_SimGeneratorExit(void *Object);
+ LCDRIVER_API int __cdecl Algorithms_SimGeneratorCalculate(void *Object, unsigned char *ByteArray, uint32 ArraySize);
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _LCDRIVER_H_
diff --git a/source/LCDriver.rc b/source/LCDriver.rc
new file mode 100644
index 0000000..ec7b73a
--- /dev/null
+++ b/source/LCDriver.rc
@@ -0,0 +1,116 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "windows.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""windows.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x1fL
+#ifdef _DEBUG
+ FILEFLAGS 0x9L
+#else
+ FILEFLAGS 0x8L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000904b0"
+ BEGIN
+ VALUE "Comments", "Build date: 2011-05-18"
+ VALUE "CompanyName", "STEricsson AB"
+ VALUE "FileDescription", "LCDriver Dynamic Link Library"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "Loader Communication Driver"
+ VALUE "LegalCopyright", "Copyright (C) STEricsson AB 2011"
+ VALUE "OriginalFilename", "LCDriver_CNH1606432.dll"
+ VALUE "PrivateBuild", "http://gerrit.lud.stericsson.com/gerrit/21155"
+ VALUE "ProductName", "CXC 173 0865, LCDriver DLL"
+ VALUE "ProductVersion", "Test Version"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x9, 1200
+ END
+END
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/source/LCDriver.vcproj b/source/LCDriver.vcproj
new file mode 100644
index 0000000..d3906db
--- /dev/null
+++ b/source/LCDriver.vcproj
@@ -0,0 +1,966 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="LCDriver"
+ ProjectGUID="{E195BE97-0727-419C-931E-08C8B99AB884}"
+ RootNamespace="LCDriver"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="..\target"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="0"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/D LITTLE_ENDIAN=1234 /D BIG_ENDIAN=4321 /D BYTE_ORDER=LITTLE_ENDIAN"
+ Optimization="0"
+ AdditionalIncludeDirectories="security_algorithms\sha;.;LCM;LCM\include;autogen;CEH;utilities;security_algorithms;api_wrappers\windows"
+ PreprocessorDefinitions="WIN32;WIN32_LEAN_AND_MEAN;_DEBUG;_WINDOWS;_USRDLL;LCDRIVER_EXPORTS;_MESSAGES;_BULKDEBUG;_TIMERDEBUG;_BUFFERDEBUG;_THREADDEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ CallingConvention="0"
+ CompileAs="2"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)_CNH1606432.dll"
+ AdditionalLibraryDirectories=""
+ GenerateManifest="true"
+ ModuleDefinitionFile=""
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="..\target"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/D LITTLE_ENDIAN=1234 /D BIG_ENDIAN=4321 /D BYTE_ORDER=LITTLE_ENDIAN"
+ AdditionalIncludeDirectories=".;LCM;LCM\include;autogen;CEH;utilities;security_algorithms;api_wrappers\windows;security_algorithms\sha"
+ PreprocessorDefinitions="WIN32;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;_USRDLL;LCDRIVER_EXPORTS"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ OutputFile="$(OutDir)\$(ProjectName)_CNH1606432.dll"
+ Version=""
+ AdditionalLibraryDirectories="security_algorithms"
+ ModuleDefinitionFile=""
+ AddModuleNamesToAssembly=""
+ AssemblyLinkResource=""
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ ValidateIntelliSense="false"
+ OutputDocumentFile="..\target\$(TargetName).xml"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="ReleaseWithDebugMessages|Win32"
+ OutputDirectory="..\target"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="0"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=".;LCM;LCM\include;autogen;CEH;utilities;security_algorithms;api_wrappers\windows"
+ PreprocessorDefinitions="WIN32;WIN32_LEAN_AND_MEAN;NDEBUG;_WINDOWS;_USRDLL;LCDRIVER_EXPORTS;_MESSAGES;_BULKDEBUG;_TIMERDEBUG;_BUFFERDEBUG"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="SecurityAlgorithms.lib"
+ OutputFile="$(OutDir)\$(ProjectName)_CNH1606432.dll"
+ Version=""
+ AdditionalLibraryDirectories="security_algorithms"
+ ModuleDefinitionFile=""
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\LCDriver.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDriverEntry.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDriverInterface.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDriverMethods.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDriverThread.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="api_wrappers"
+ >
+ <File
+ RelativePath=".\api_wrappers\windows\WinApiWrappers.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\LCDriver.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDriverInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDriverMethods.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCDriverThread.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LcmInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="autogen"
+ >
+ <File
+ RelativePath=".\autogen\a2_command_ids.h"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\a2_commands.h"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\a2_commands_impl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\a2_commands_marshal.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\command_ids.h"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\commands.h"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\commands_impl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\commands_marshal.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\autogen\lcdriver_error_codes.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="config"
+ >
+ <File
+ RelativePath=".\config\a2_command_ids_h.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_command_ids.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_command_ids.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_command_ids.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_command_ids.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_command_ids.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_command_ids.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_command_ids.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_command_ids.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_command_ids.h"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\a2_commands.xml"
+ >
+ </File>
+ <File
+ RelativePath=".\config\a2_commands_h.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands.h&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands.h&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands.h&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands.h"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\a2_commands_impl_h.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands_impl.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands_impl.h&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands_impl.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands_impl.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands_impl.h&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands_impl.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands_impl.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands_impl.h&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands_impl.h"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\a2_commands_marshal_cpp.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands_marshal.cpp..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands_marshal.cpp&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands_marshal.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands_marshal.cpp..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands_marshal.cpp&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands_marshal.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating a2_commands_marshal.cpp..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)a2_commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\a2_commands_marshal.cpp&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)a2_commands.xml&quot;"
+ Outputs="autogen\a2_commands_marshal.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\a2_common.xsl"
+ >
+ </File>
+ <File
+ RelativePath=".\config\command_ids_h.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating command_ids.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\command_ids.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\command_ids.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating command_ids.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\command_ids.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\command_ids.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating command_ids.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\command_ids.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\command_ids.h"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\commands.xml"
+ >
+ </File>
+ <File
+ RelativePath=".\config\commands_h.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands.h"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\commands_impl_h.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands_impl.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands_impl.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands_impl.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands_impl.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands_impl.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands_impl.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands_impl.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands_impl.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands_impl.h"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\commands_marshal_cpp.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands_marshal.cpp..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands_marshal.cpp&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands_marshal.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands_marshal.cpp..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands_marshal.cpp&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands_marshal.cpp"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating commands_marshal.cpp..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)commands.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\commands_marshal.cpp&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)commands.xml&quot;"
+ Outputs="autogen\commands_marshal.cpp"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\config\common.xsl"
+ >
+ </File>
+ <File
+ RelativePath=".\config\lcdriver_error_codes.xml"
+ >
+ </File>
+ <File
+ RelativePath=".\config\lcdriver_error_codes_h.xsl"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating lcdriver_error_codes.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)lcdriver_error_codes.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\lcdriver_error_codes.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)lcdriver_error_codes.xml&quot;"
+ Outputs="autogen\lcdriver_error_codes.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating lcdriver_error_codes.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)lcdriver_error_codes.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\lcdriver_error_codes.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)lcdriver_error_codes.xml&quot;"
+ Outputs="autogen\lcdriver_error_codes.h"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="ReleaseWithDebugMessages|Win32"
+ >
+ <Tool
+ Name="VCCustomBuildTool"
+ Description="Generating lcdriver_error_codes.h..."
+ CommandLine="java -classpath ..\lcmodule\tools\xalan-j_2_7_1\xalan.jar org.apache.xalan.xslt.Process -in &quot;$(InputDir)lcdriver_error_codes.xml&quot; -xsl &quot;$(InputPath)&quot; -out &quot;$(ProjectDir)\autogen\lcdriver_error_codes.h&#x0D;&quot;&#x0D;&#x0A;"
+ AdditionalDependencies="&quot;$(InputDir)lcdriver_error_codes.xml&quot;"
+ Outputs="autogen\lcdriver_error_codes.h"
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="LCM"
+ >
+ <File
+ RelativePath=".\LCM\Buffers.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\Buffers.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\Hash.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\Hash.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\Queue.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\Queue.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\Timer.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\Timer.h"
+ >
+ </File>
+ <Filter
+ Name="include"
+ >
+ <File
+ RelativePath=".\LCM\include\c_compiler.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\c_system.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\error_codes.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_a2_protocol.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_basicdefinitions.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_bulk_protocol.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_command_protocol.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_communication_service.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_protrom_header.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_protrom_network.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_protrom_transport.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_queue.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_r15_header.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_r15_network_layer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_security_algorithms.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LCM\include\t_time_utilities.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="security_algorithms"
+ >
+ <File
+ RelativePath=".\security_algorithms\SecurityAlgorithms.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\security_algorithms\SecurityAlgorithms.h"
+ >
+ </File>
+ <File
+ RelativePath=".\security_algorithms\simlockcode.h"
+ >
+ </File>
+ <Filter
+ Name="sha"
+ >
+ <File
+ RelativePath=".\security_algorithms\sha\sha2.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\security_algorithms\sha\sha2.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="CEH"
+ >
+ <File
+ RelativePath=".\CEH\a2_commands_impl.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\CmdResult.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\CmdResult.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\commands_impl.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\commands_types.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\ProtromRpcInterface.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\ProtromRpcInterface.h"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\ZRpcInterface.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\CEH\ZRpcInterface.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="utilities"
+ >
+ <File
+ RelativePath=".\utilities\BulkHandler.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\BulkHandler.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\CaptiveThreadObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\CaptiveThreadObject.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\Error.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\Event.h"
+ >
+ </File>
+ <File
+ RelativePath=".\LcmInterface.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\LockLessQueue.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\Logger.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\Logger.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\MemMappedFile.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\MemMappedFile.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\ObjectList.h"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\Serialization.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\utilities\Serialization.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath=".\LCDriver.rc"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/source/LCDriverEntry.cpp b/source/LCDriverEntry.cpp
new file mode 100644
index 0000000..91bd189
--- /dev/null
+++ b/source/LCDriverEntry.cpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "LCDriverMethods.h"
+#include "Buffers.h"
+
+void destroy(void);
+
+#ifdef _WIN32
+BOOL APIENTRY DllMain(HMODULE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved)
+{
+ switch (ul_reason_for_call) {
+ case DLL_PROCESS_ATTACH:
+ break;
+ case DLL_THREAD_ATTACH:
+ break;
+ case DLL_THREAD_DETACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ destroy();
+ break;
+ }
+
+ return TRUE;
+}
+#else
+void __attribute__((destructor)) DllMain(void)
+{
+ destroy();
+}
+#endif
+
+//***********************************************************************************************
+// Name: destroy()
+// Desc: Destroy any remaining buffer data.
+//**********************************************************************************************/
+void destroy(void)
+{
+ Buffers::ReleaseAllBulkFiles();
+ LcmInterface::CloseLCMLibrary();
+}
diff --git a/source/LCDriverInterface.cpp b/source/LCDriverInterface.cpp
new file mode 100644
index 0000000..adda735
--- /dev/null
+++ b/source/LCDriverInterface.cpp
@@ -0,0 +1,55 @@
+/******************************************************************************
+*
+* File name: LCDriverInterface.cpp
+* Project: LoaderCommunicationDriver
+* Language: Visual C++
+* Description: Interface class.
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+#include "LCDriverInterface.h"
+
+CCriticalSectionObject CLCDriverInterface::InitializationCS;
+CObjectList<CLCDriverMethods> CLCDriverInterface::ObjectList;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CLCDriverInterface::CLCDriverInterface()
+{
+ isStarted = false;
+ m_pObject = NULL;
+ m_szObjectId[0] = '\0';
+}
+
+CLCDriverInterface::~CLCDriverInterface()
+{
+ CLockCS CsLock(InitializationCS);
+
+ // Disconnect from the CLCDriverMethods object
+ if (m_pObject != NULL) {
+ if (ObjectList.Release(m_pObject) == 0) {
+ delete m_pObject;
+ m_pObject = NULL;
+ }
+ }
+}
+
+CLCDriverMethods *CLCDriverInterface::FindObject(const char *interfaceId)
+{
+ return ObjectList.Find(interfaceId);
+}
+
+void CLCDriverInterface::ReleaseObject(CLCDriverMethods *object)
+{
+ ObjectList.Release(object);
+}
+
+int CLCDriverInterface::AddObject(CLCDriverMethods *object, const char *interfaceId)
+{
+ return ObjectList.Add(object, interfaceId);
+}
diff --git a/source/LCDriverInterface.h b/source/LCDriverInterface.h
new file mode 100644
index 0000000..6265b0d
--- /dev/null
+++ b/source/LCDriverInterface.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+*
+* File name: LCDriverInterface.h
+* Project: LCDriver
+* Language: Visual C++
+* Description: Interface class.
+* Revision : R1A
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+#ifndef _CLCDRIVERINTERFACE_H_
+#define _CLCDRIVERINTERFACE_H_
+
+#include "LCDriverMethods.h"
+#include "ObjectList.h"
+
+/// <summary>
+/// Interface class for functions agains loader command.
+/// </summary>
+struct CLCDriverInterface {
+public:
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ CLCDriverInterface();
+
+ /// <summary>
+ /// Destructor.
+ /// </summary>
+ virtual ~CLCDriverInterface();
+
+ // Public data members
+ CLCDriverMethods *m_pObject;
+ char m_szObjectId[25];
+ bool isStarted;
+
+ static CCriticalSectionObject InitializationCS;
+
+ static CLCDriverMethods *FindObject(const char *interfaceId);
+ static void ReleaseObject(CLCDriverMethods *object);
+ static int AddObject(CLCDriverMethods *object, const char *interfaceId);
+private:
+ static CObjectList<CLCDriverMethods> ObjectList;
+};
+
+#endif // _CLCDRIVERINTERFACE_H_
diff --git a/source/LCDriverMethods.cpp b/source/LCDriverMethods.cpp
new file mode 100644
index 0000000..fd07664
--- /dev/null
+++ b/source/LCDriverMethods.cpp
@@ -0,0 +1,2574 @@
+/*********************************************************************************************
+*
+* File name: LCDriverMethods.cpp
+* Project: LoaderCommunicationDriver
+* Language: Visual C++
+* Description: Implementation of all exported methods.
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*********************************************************************************************/
+
+#include "LCDriverMethods.h"
+#include "lcdriver_error_codes.h"
+#include "LCDriverThread.h"
+#include "Error.h"
+#include "LcmInterface.h"
+#include "ZRpcInterface.h"
+#include "ProtromRpcInterface.h"
+#include "commands_impl.h"
+#include "a2_commands_impl.h"
+#include "Event.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#include <cstdlib>
+#endif
+#include <sys/stat.h>
+#include <sys/types.h>
+
+const char *const CLCDriverMethods::BULK_PATH = "/COMM";
+
+// LCM timeouts structure to avoid LCD interface changes after removing bulk session end timeout
+struct LcmR15Timeouts {
+ uint32 TCACK;
+ uint32 TBCR;
+ uint32 TBDR;
+};
+
+extern ListDevice_t Devices[];
+extern uint32 DevicesNumber;
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+/// <summary>
+/// Constructor.
+/// </summary>
+/// <param name="pchInterfaceId">A zero terminated string containing the InterfaceId.</param>
+CLCDriverMethods::CLCDriverMethods(const char *pchInterfaceId):
+ m_EventQueue(256)
+{
+ m_pchId = new char[strlen(pchInterfaceId)+1];
+ strcpy_s(m_pchId, strlen(pchInterfaceId) + 1, pchInterfaceId);
+
+ m_pCommunicationDevice = new CommunicationDevice_t;
+ m_pCmdResult = new CmdResult();
+ m_pLcmInterface = new LcmInterface();
+ m_pZRpcFunctions = new ZRpcInterface(m_pCmdResult, m_pLcmInterface);
+ m_pProtromRpcFunctions = new ProtromRpcInterface(m_pCmdResult, m_pLcmInterface);
+ m_pLoaderRpcFunctions = new LoaderRpcInterfaceImpl(this, m_pCmdResult, m_pLcmInterface);
+ m_pA2LoaderRpcFunctions = new A2LoaderRpcInterfaceImpl(this, m_pCmdResult, m_pLcmInterface);
+
+ m_pTimer = new Timer();
+ m_pHash = new Hash();
+ m_pQueue = new Queue();
+ m_pBuffers = new Buffers();
+ m_pSerialization = new Serialization();
+ m_pLogger = new Logger(m_pLcmInterface->getLCMContext());
+ m_pBulkHandler = new BulkHandler(this, m_pBuffers, m_pLcmInterface, m_pLogger);
+
+ // default values for timeouts
+ m_Timeouts.uiRTO = 0xFFFFFFFF; // Typically 5000
+ m_Timeouts.uiSTO = 0xFFFFFFFF; // Typically 30000 i.e. 30 secs
+
+ m_CurrentProtocolFamily = R15_FAMILY;
+ m_iBulkProtocolMode = BULK_INACTIVE;
+
+ m_ProgressBarUpdate = 0;
+ m_uiBulkLength = 0;
+ m_uiBulkTransferred = 0;
+ m_pMainThread = 0;
+ m_pHashDevice = 0;
+ m_CurrentCEHCallback = 0;
+}
+
+/// <summary>
+/// Destructor.
+/// </summary>
+CLCDriverMethods::~CLCDriverMethods()
+{
+ m_EventQueue.SignalEvent();
+ OS::Sleep(200);
+
+ if (0 != m_pMainThread) {
+ m_pMainThread->EndCaptiveThread();
+ }
+
+ delete m_pMainThread;
+
+ if (0 != m_pLcmInterface) {
+ m_pLcmInterface->CommunicationShutdown();
+ }
+
+ delete m_pLcmInterface;
+ delete m_pCmdResult;
+ delete m_pZRpcFunctions;
+ delete m_pProtromRpcFunctions;
+ delete m_pLoaderRpcFunctions;
+ delete m_pA2LoaderRpcFunctions;
+
+ delete m_pCommunicationDevice;
+ delete m_pTimer;
+ delete m_pBuffers;
+ delete m_pHash;
+ delete m_pQueue;
+ delete m_pSerialization;
+
+ delete m_pLogger;
+ delete m_pBulkHandler;
+ delete[] m_pchId;
+}
+//----------------------------------------
+// Static callback functions for intercept only
+//----------------------------------------
+
+//----------------------------------------
+// Static methods
+//----------------------------------------
+
+ErrorCode_e CLCDriverMethods::TimerInit(void *pObject, uint32 uiTimers)
+{
+ Timer *pTimer = static_cast<Timer *>(pObject);
+ return pTimer->Init(uiTimers);
+}
+
+uint32 CLCDriverMethods::TimerGet(void *pObject, Timer_t *pTimer)
+{
+ Timer *pTimerLocal = static_cast<Timer *>(pObject);
+ return pTimerLocal->Get(pTimer);
+}
+
+ErrorCode_e CLCDriverMethods::TimerRelease(void *pObject, uint32 uiTimerKey)
+{
+ Timer *pTimer = static_cast<Timer *>(pObject);
+ return pTimer->Release(uiTimerKey);
+}
+
+uint32 CLCDriverMethods::TimerReadTime(void *pObject, uint32 uiTimerKey)
+{
+ Timer *pTimer = static_cast<Timer *>(pObject);
+ return pTimer->ReadTime(uiTimerKey);
+}
+
+uint32 CLCDriverMethods::TimerGetSystemTime(void *pObject)
+{
+ Timer *pTimer = static_cast<Timer *>(pObject);
+ return pTimer->GetSystemTime();
+}
+
+//--------------------------------------------
+void CLCDriverMethods::HashCancel(void *pObject, void **ppHashDevice)
+{
+ Hash *pHashObject = static_cast<Hash *>(pObject);
+ pHashObject->Cancel((HashDevice_t **)ppHashDevice);
+}
+
+void CLCDriverMethods::HashCalculate(void *pObject, HashType_e Type, void *pData, const uint32 uiLength, uint8 *pHash, HashCallback_fn fnCallback, void *pParam)
+{
+ Hash *pHashObject = static_cast<Hash *>(pObject);
+ pHashObject->Calculate(Type, pData, uiLength, pHash, fnCallback, pParam);
+}
+
+//----------------------------------------
+
+ErrorCode_e CLCDriverMethods::BuffersInit(void *pObject)
+{
+ Buffers *pBufferObject = static_cast<Buffers *>(pObject);
+ return pBufferObject->Init();
+}
+
+void *CLCDriverMethods::BufferAllocate(void *pObject, int iBufferSize)
+{
+ Buffers *pBufferObject = static_cast<Buffers *>(pObject);
+ return pBufferObject->Allocate(iBufferSize);
+}
+
+ErrorCode_e CLCDriverMethods::BufferRelease(void *pObject, void *pBuffer, int iBufferSize)
+{
+ Buffers *pBufferObject = static_cast<Buffers *>(pObject);
+ return pBufferObject->Release(pBuffer, iBufferSize);
+}
+
+uint32 CLCDriverMethods::BuffersAvailable(void *pObject, int iBufferSize)
+{
+ Buffers *pBufferObject = static_cast<Buffers *>(pObject);
+ return pBufferObject->Available(iBufferSize);
+}
+
+void CLCDriverMethods::BuffersDeinit(void *pObject)
+{
+ Buffers *pBufferObject = static_cast<Buffers *>(pObject);
+ pBufferObject->Deinit();
+}
+
+//----------------------------------------
+
+void CLCDriverMethods::QueueCreate(void *pObject, void **const ppQueue, const uint32 uiMaxLength, void (*pDestroyElement)(void *pElement))
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ pQueueLocal->RCreate(ppQueue, uiMaxLength, pDestroyElement);
+}
+void CLCDriverMethods::QueueDestroy(void *pObject, void **const ppQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ pQueueLocal->RDestroy(ppQueue);
+}
+
+ErrorCode_e CLCDriverMethods::QueueEnqueue(void *pObject, void *const ppQueue, void *const pValue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->REnqueue(ppQueue, pValue);
+}
+
+void *CLCDriverMethods::QueueDequeue(void *pObject, void *const ppQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RDequeue(ppQueue);
+}
+
+QueueCallback_fn CLCDriverMethods::QueueSetCallback(void *pObject, void *const pQueue, const QueueCallbackType_e Type, const QueueCallback_fn fnCallback, void *const pParam)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RSetCallback(pQueue, Type, fnCallback, pParam);
+}
+
+boolean CLCDriverMethods::QueueIsEmpty(void *pObject, const void *const pQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RIsEmpty(pQueue);
+}
+
+boolean CLCDriverMethods::QueueIsMember(void *pObject, const void *const pQueue, void *pValue, boolean(*Match)(void *pValue1, void *pValue2))
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RIsMember(pQueue, pValue, Match);
+}
+
+int CLCDriverMethods::QueueGetNrOfElements(void *pObject, const void *const pQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RGetNrOfElements(pQueue);
+}
+
+void CLCDriverMethods::RQueueCreate(void *pObject, void **const ppQueue, const uint32 uiMaxLength, void (*pDestroyElement)(void *pElement))
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ pQueueLocal->RCreate(ppQueue, uiMaxLength, pDestroyElement);
+}
+
+void CLCDriverMethods::RQueueDestroy(void *pObject, void **const ppQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ pQueueLocal->RDestroy(ppQueue);
+}
+
+ErrorCode_e CLCDriverMethods::RQueueEnqueue(void *pObject, void *const pQueue, void *const pValue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->REnqueue(pQueue, pValue);
+}
+
+void *CLCDriverMethods::RQueueDequeue(void *pObject, void *const pQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RDequeue(pQueue);
+}
+
+QueueCallback_fn CLCDriverMethods::RQueueSetCallback(void *pObject, void *const pQueue, const QueueCallbackType_e Type, const QueueCallback_fn fnCallback, void *const pParam)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RSetCallback(pQueue, Type, fnCallback, pParam);
+}
+
+boolean CLCDriverMethods::RQueueIsEmpty(void *pObject, const void *const pQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RIsEmpty(pQueue);
+}
+
+boolean CLCDriverMethods::RQueueIsMember(void *pObject, const void *const pQueue, void *pValue, boolean(*Match)(void *pValue1, void *pValue2))
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RIsMember(pQueue, pValue, Match);
+}
+
+int CLCDriverMethods::RQueueGetNrOfElements(void *pObject, const void *const pQueue)
+{
+ Queue *pQueueLocal = static_cast<Queue *>(pObject);
+ return pQueueLocal->RGetNrOfElements(pQueue);
+}
+
+//----------------------------------------
+
+ErrorCode_e CLCDriverMethods::CEHCallbackFunction(void *pObject, CommandData_t *pCmdData)
+{
+ CLCDriverMethods *pLcdMethods = static_cast<CLCDriverMethods *>(pObject);
+ return pLcdMethods->m_pLoaderRpcFunctions->Do_CEH_Callback(pCmdData);
+}
+
+ErrorCode_e CLCDriverMethods::CEH_Z_CallbackFunction(void *pObject, CommandData_t *pCmdData)
+{
+ CLCDriverMethods *pLcdMethods = static_cast<CLCDriverMethods *>(pObject);
+ return pLcdMethods->m_pZRpcFunctions->Do_CEH_Callback(pCmdData);
+}
+
+ErrorCode_e CLCDriverMethods::CEH_PROTROM_CallbackFunction(void *pObject, CommandData_t *pCmdData)
+{
+ CLCDriverMethods *pLcdMethods = static_cast<CLCDriverMethods *>(pObject);
+ return pLcdMethods->m_pProtromRpcFunctions->Do_CEH_Callback(pCmdData);
+}
+
+ErrorCode_e CLCDriverMethods::CEH_A2_CallbackFunction(void *pObject, CommandData_t *pCmdData)
+{
+ CLCDriverMethods *pLcdMethods = static_cast<CLCDriverMethods *>(pObject);
+ return pLcdMethods->m_pA2LoaderRpcFunctions->Do_CEH_Callback(pCmdData);
+}
+
+//----------------------------------------
+
+void CLCDriverMethods::BulkCommandReqCallback(void *pObject, uint16 *puiSession, uint32 *puiChunkSize, uint64 *puiOffset, uint32 *puiLength, boolean bAckRead)
+{
+ CLCDriverMethods *pLcdMethods = static_cast<CLCDriverMethods *>(pObject);
+ return pLcdMethods->m_pBulkHandler->HandleCommandRequest(*puiSession, *puiChunkSize, *puiOffset, *puiLength, bAckRead ? true : false);
+}
+
+void CLCDriverMethods::BulkDataReqCallback(void *pObject, uint16 *puiSession, uint32 *puiChunkSize, uint64 *puiOffset, uint32 *puiLength, uint64 *puiTotalLength, uint32 *puiTransferedLength)
+{
+ CLCDriverMethods *pLcdMethods = static_cast<CLCDriverMethods *>(pObject);
+ return pLcdMethods->Do_BulkDataReqCallback(puiSession, puiChunkSize, puiOffset, puiLength, puiTotalLength, puiTransferedLength);
+}
+
+void CLCDriverMethods::BulkDataEndOfDumpCallback(void *pObject)
+{
+ CLCDriverMethods *pLcdMethods = static_cast<CLCDriverMethods *>(pObject);
+ return pLcdMethods->Do_BulkDataEndOfDumpCallback();
+}
+
+////////////////////////////////////////////////////////////////////////
+///
+/// Exported methods
+///
+
+/// <summary>
+/// Initializes LCDriver.
+/// </summary>
+/// <param name="pfnRead">Callback to external Read function.</param>
+/// <param name="pfnWrite">Callback to external Write function.</param>
+/// <param name="pfnCancel">Callback to external Cancel function.</param>
+/// <param name="ppInstance">Method modifies value to point to this instance of m_pGlobalCommunicationLCDriver object.</param>
+/// <param name="pfnMessage">Callback to external Message function for outputting text.</param>
+/// <param name="pchLCMLibPath">Path to LCM module.</param>
+/// <param name="pfnProgressBarCallback">Callback to external ProgressBar function.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Initialize(void **ppInstance)
+{
+#ifdef _MESSAGES
+ m_pBuffers->SetLogger(m_pLogger);
+ m_pQueue->SetLogger(m_pLogger);
+ m_pTimer->SetLogger(m_pLogger);
+ m_pSerialization->SetLogger(m_pLogger);
+#endif
+ int ReturnValue = E_SUCCESS;
+
+ // Setup Command Protocol buffer
+ m_pBuffers->Init();
+
+ BuffersInterface_t BufferFunctions;
+ TimersInterface_t TimerFunctions;
+ QueueInterface_t QueueFunctions;
+
+ // Setup timer struct
+ VERIFY_SUCCESS(SetupTimers(&TimerFunctions));
+
+ // Setup buffer struct
+ VERIFY_SUCCESS(SetupBuffers(&BufferFunctions));
+
+ // Setup queue struct
+ VERIFY_SUCCESS(SetupQueues(&QueueFunctions));
+
+ // Setup hash struct
+ VERIFY_SUCCESS(SetupHash());
+
+ if (NULL == m_pCommunicationDevice->Read || NULL == m_pCommunicationDevice->Write || NULL == m_pCommunicationDevice->Cancel) {
+ VERIFY_SUCCESS(CALLBACKS_NOT_CONFIGURED_CORRECTLY);
+ }
+
+ VERIFY_SUCCESS(m_pLcmInterface->CommunicationInitialize(this, m_CurrentProtocolFamily, m_pHashDevice, m_pCommunicationDevice, m_CurrentCEHCallback, &BufferFunctions, &TimerFunctions, &QueueFunctions));
+ *ppInstance = m_pLcmInterface->getLCMContext();
+
+ // Create main thread
+ if (m_pTimer) {
+ m_pMainThread = new CLCDriverThread(this);
+ } else {
+ VERIFY_SUCCESS(LCDRIVER_THREAD_NOT_STARTED);
+ }
+
+ // Initialize 32 timers for the moment (timer memory only allocated once for all instances)
+ TimerInit(m_pTimer, 32);
+
+ if (R15_FAMILY == m_CurrentProtocolFamily) {
+ m_pMainThread->TimerOn();
+ }
+
+ //Now start LCDriver thread
+ m_pMainThread->ResumeThread();
+
+ m_pLogger->log("LCDriver/LCM started ok!");
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Set up Timers utility class required by LCM.
+/// </summary>
+/// <returns> Status of the command.</returns>
+ErrorCode_e CLCDriverMethods::SetupTimers(TimersInterface_t *pTimerFunctions)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ pTimerFunctions->GetSystemTime_Fn = static_cast<GetSystemTime_t>(TimerGetSystemTime);
+ pTimerFunctions->ReadTime_Fn = static_cast<ReadTime_t>(TimerReadTime);
+ pTimerFunctions->TimerGet_Fn = static_cast<TimerGet_t>(TimerGet);
+ pTimerFunctions->TimerRelease_Fn = static_cast<TimerRelease_t>(TimerRelease);
+ pTimerFunctions->TimersInit_Fn = static_cast<TimersInit_t>(TimerInit);
+ pTimerFunctions->Object_p = m_pTimer;
+ return Result;
+}
+
+/// <summary>
+/// Set up Buffer utility class required by LCM.
+/// </summary>
+/// <returns> Status of the command.</returns>
+ErrorCode_e CLCDriverMethods::SetupBuffers(BuffersInterface_t *pBufferFunctions)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ pBufferFunctions->BufferAllocate_Fn = static_cast<BufferAllocate_t>(BufferAllocate);
+ pBufferFunctions->BufferRelease_Fn = static_cast<BufferRelease_t>(BufferRelease);
+ pBufferFunctions->BuffersAvailable_Fn = static_cast<BuffersAvailable_t>(BuffersAvailable);
+ pBufferFunctions->BuffersDeinit_Fn = static_cast<BuffersDeinit_t>(BuffersDeinit);
+ pBufferFunctions->BuffersInit_Fn = static_cast<BuffersInit_t>(BuffersInit);
+ pBufferFunctions->Object_p = m_pBuffers;
+ return Result;
+}
+
+/// <summary>
+/// Set up Queue utility class required by LCM.
+/// </summary>
+/// <returns> Status of the command.</returns>
+ErrorCode_e CLCDriverMethods::SetupQueues(QueueInterface_t *pQueueFunctions)
+{
+ ErrorCode_e Result = E_SUCCESS;
+ pQueueFunctions->Fifo_GetNrOfElements_Fn = QueueGetNrOfElements;
+ pQueueFunctions->Fifo_IsEmpty_Fn = QueueIsEmpty;
+ pQueueFunctions->Fifo_IsMember_Fn = QueueIsMember;
+ pQueueFunctions->Fifo_SetCallback_Fn = QueueSetCallback;
+ pQueueFunctions->FifoCreate_Fn = QueueCreate;
+ pQueueFunctions->FifoDequeue_Fn = QueueDequeue;
+ pQueueFunctions->FifoDestroy_Fn = QueueDestroy;
+ pQueueFunctions->FifoEnqueue_Fn = QueueEnqueue;
+ pQueueFunctions->RFifo_GetNrOfElements_Fn = RQueueGetNrOfElements;
+ pQueueFunctions->RFifo_IsEmpty_Fn = RQueueIsEmpty;
+ pQueueFunctions->RFifo_IsMember_Fn = RQueueIsMember;
+ pQueueFunctions->RFifo_SetCallback_Fn = RQueueSetCallback;
+ pQueueFunctions->RFifoCreate_Fn = RQueueCreate;
+ pQueueFunctions->RFifoDequeue_Fn = RQueueDequeue;
+ pQueueFunctions->RFifoDestroy_Fn = RQueueDestroy;
+ pQueueFunctions->RFifoEnqueue_Fn = RQueueEnqueue;
+ pQueueFunctions->Object_p = m_pQueue;
+ return Result;
+}
+
+/// <summary>
+/// Set up Hash utility class required by LCM.
+/// </summary>
+/// <returns> Status of the command.</returns>
+ErrorCode_e CLCDriverMethods::SetupHash()
+{
+ m_pHashDevice = new HashDevice_t;
+
+ if (0 == m_pHashDevice) {
+ return E_ALLOCATE_FAILED;
+ }
+
+ m_pHashDevice->Calculate = HashCalculate;
+ m_pHashDevice->Cancel = HashCancel;
+ m_pHashDevice->Object_p = m_pHash;
+ return E_SUCCESS;
+}
+
+void CLCDriverMethods::CancelCurrentLoaderCommand()
+{
+ m_EventQueue.SignalEvent();
+}
+
+/// <summary>
+/// The Loader Start-up Status command is sent by the ME to notify the host that it has started. The Status parameter indicates in what mode the loader started.
+/// </summary>
+/// <param name="pchVersion">Loader version identifier.</param>
+/// <param name="piVersionSize">Number of allocated bytes for version string.</param>
+/// <param name="pchProtocol">Protocol version identifier.</param>
+/// <param name="piProtocolSize">Number of allocated bytes for protocol string.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Done_System_LoaderStartupStatus(char *pchVersion, int *piVersionSize, char *pchProtocol, int *piProtocolSize)
+{
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(WaitForEvent(EVENT_CMD_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_LOADERSTARTUPSTATUS));
+ VERIFY_SUCCESS(m_pCmdResult->System_LoaderStartupStatus_Status);
+
+ //Copy output parameter from RPC class.
+ CopyStringToArray(m_pCmdResult->System_LoaderStartupStatus_LoaderVersion, pchVersion, piVersionSize);
+ CopyStringToArray(m_pCmdResult->System_LoaderStartupStatus_ProtocolVersion, pchProtocol, piProtocolSize);
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piVersionSize = 0;
+ *piProtocolSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// The Reboot command is used to instruct the loader to reset the ME. Upon receiving this command,
+/// the loader shuts down in a controlled fashion and restarts the ME. The Mode parameter is used to
+/// select the mode of reset. The ME does not accept any further communication after a successful
+/// response from this command has been returned.
+/// </summary>
+/// <param name="iMode">Indicates the mode of reset:
+/// 0: indicates normal restart.
+/// 1: indicates restart in service mode.
+/// 2: indicates restart with JTAG debugging enabled.
+/// 3: indicates restart in service mode and with JTAG debugging enabled.
+/// </param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_System_Reboot(int iMode)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_Reboot(uiSessionOut, iMode));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// The loader returns a list of implemented commands and whether they are permitted to
+/// execute in the current loader state.
+/// </summary>
+/// <param name="pCmdList">A list with supported commands.</param>
+/// <param name="piCmdListSize">Number of commands in CmdList.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_System_SupportedCommands(TSupportedCmd *pCmdList, int *piCmdListSize)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_SupportedCommands(uiSessionOut));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_SUPPORTEDCOMMANDS));
+
+ //Copy output parameter from RPC class.
+ *piCmdListSize = static_cast<int>(m_pCmdResult->System_SupportedCommands_CmdList.size());
+ CopyVectorToArray(m_pCmdResult->System_SupportedCommands_CmdList, pCmdList, piCmdListSize);
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piCmdListSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+int CLCDriverMethods::Do_System_CollectData(int iType, int *piSize, char *pData)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_CollectData(uiSessionOut, iType));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_COLLECTDATA));
+
+ //Copy output parameter from RPC class.
+ if (m_pCmdResult->System_CollectedData.length() > static_cast<size_t>(*piSize)) {
+ m_pCmdResult->System_CollectedData.erase(*piSize - 1);
+ }
+
+ strcpy_s(pData, *piSize, m_pCmdResult->System_CollectedData.c_str());
+ *piSize = m_pCmdResult->System_CollectedData.length();
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piSize = 0;
+ *pData = '\0';
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// Receive, verify and execute software, which can be a signed loader.
+/// After having sent this command, the ME attempts to read the software
+/// payload data from the host using the Bulk protocol or from the flash
+/// file system depending on the selected path. The current loader does not
+/// respond to communication after this command has been successfully executed.
+/// If the executed software is another loader, communication can be resumed once the
+/// Loader Started command has been received. A response of E_OPERATION_CANCELLED
+/// indicates the operation was canceled.
+/// </summary>
+/// <param name="pchDevicePath">Target path. If use bulk the path is on PC, else on ME.</param>
+/// <param name="iUseBulk">If value = 1 -> source on PC, else source on ME.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_System_ExecuteSoftware(const uint32 ExecuteMode, const char *pchDevicePath, int iUseBulk)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ if (1 == ExecuteMode) {
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_ExecuteSoftware(uiSessionOut, ExecuteMode, pchDevicePath, 0));
+
+ } else if (2 == ExecuteMode) {
+ if (iUseBulk) {
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ VERIFY_SUCCESS(m_pBuffers->AllocateBulkFile(pchDevicePath));
+ uint64 uiLength = m_pBuffers->GetBulkFileLength();
+ m_uiBulkLength = uiLength;
+ m_uiBulkTransferred = 0;
+ VERIFY_SUCCESS(m_pBulkHandler->Send(pchDevicePath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_ExecuteSoftware(uiSessionOut, ExecuteMode, BULK_PATH, uiLength));
+ //VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_EXECUTESOFTWARE));
+ } else {
+ // TEMPORARY ONLY - QSJOMIK: CURRENTLY WE CANNOT KNOW THE SIZE OF FILE ON AN ME MEMORY CARD IF USEBULK=0 - DO WE NEED A PARAMETER??
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_ExecuteSoftware(uiSessionOut, ExecuteMode, pchDevicePath, 0));
+ //VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_EXECUTESOFTWARE));
+ }
+
+ // reset session counters for this instance of the lcm
+ m_pLcmInterface->CommandResetSessionCounters();
+ } else {
+ ReturnValue = INVALID_EXECUTION_MODE;
+ }
+ //}
+
+ErrorExit:
+
+ if (iUseBulk) {
+ m_pBulkHandler->Finish();
+ m_pBuffers->ReleaseBulkFile();
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to escalate the privileges of the operator. Two ways of
+/// authentication are available by default; control key authentication and certificate based
+/// authentication. The authentication command sets the loader in a specific
+/// authentication context when it takes control over the command flow. After
+/// receiving the authentication command, the loader sends the appropriate request for information to the PC.
+/// </summary>
+/// <param name="iType">Authentication type:0 = control key authentication,1 = certificate authentication.</param>
+/// <param name="piSize">Size of puchData.</param>
+/// <param name="puchdata">Data challange. </param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_System_Authenticate(int iType, int *piSize, unsigned char *puchdata)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_Authenticate(uiSessionOut, iType));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED | EVENT_CMD_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_AUTHENTICATE));
+
+ if (0 != iType) {
+ CopyVectorToArray(m_pCmdResult->System_AuthenticationChallenge_Buffer, puchdata, piSize);
+ }
+
+ErrorExit:
+
+ if (0 != iType && E_SUCCESS != ReturnValue) {
+ *piSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used by the loader to retrieve the SimLock control keys from the host to authenticate a user.
+/// The command is used in the authentication context.
+/// </summary>
+/// <param name="pSIMLockKeys">A struct with all lock/unlock keys.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Done_System_GetControlKeys(TSIMLockKeys *pSIMLockKeys)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoneRPC_System_GetControlKeys(uiSessionOut, E_SUCCESS,
+ pSIMLockKeys->pchNLCKLock, pSIMLockKeys->pchNSLCKLock,
+ pSIMLockKeys->pchSPLCKLock, pSIMLockKeys->pchCLCKLock,
+ pSIMLockKeys->pchPCKLock, pSIMLockKeys->pchESLCKLock,
+ pSIMLockKeys->pchNLCKUnLock, pSIMLockKeys->pchNSLCKUnLock,
+ pSIMLockKeys->pchSPLCKUnLock, pSIMLockKeys->pchCLCKUnLock,
+ pSIMLockKeys->pchPCKLock, pSIMLockKeys->pchESLCKUnLock));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_AUTHENTICATE));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used by the loader to retrieve the SimLock control keys data buffer from the host to authenticate a user.
+/// The command is used in the authentication context.
+/// </summary>
+/// <param name="SIMLockKeysData">SIMLockKeyData buffer that contain all SIMLock keys.</param>
+/// <param name="iDataSize">SIMLockKeyData buffer size.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Done_System_GetControlKeysData(int iDataSize, unsigned char *pSIMLockKeysData)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoneRPC_System_GetControlKeysData(uiSessionOut, E_SUCCESS,
+ iDataSize, pSIMLockKeysData));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_AUTHENTICATE));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used by the loader to perform a certificate authentication.
+/// The command is only used in the authentication context.
+/// </summary>
+/// <param name="puchChallengeData">Authentication challenge. This challenge must be signed
+/// using the correct certificate and returned to the loader.</param>
+/// <param name="iDataSize">Authentication challenge buffer length.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Done_System_AuthenticationChallenge(int iDataSize, unsigned char *puchChallengeData)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoneRPC_System_AuthenticationChallenge(uiSessionOut, E_SUCCESS, iDataSize, puchChallengeData));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_AUTHENTICATE));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// The Set System Time command is used to set the current epoch time for loader
+/// to configure the real time clock and use it for file system operations.
+/// </summary>
+/// <param name="EpochTime">
+/// Number of seconds that have elapsed since January 1, 1970
+/// </param>
+/// <returns>Status of the command.</returns>
+int CLCDriverMethods::Do_System_SetSystemTime(uint32 EpochTime)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_SetSystemTime(uiSessionOut, EpochTime));
+
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_SETSYSTEMTIME));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to instruct the Loader to switch to a new communication device.
+/// </summary>
+/// <param name="Device">
+/// Device ID of the communication device to switch to.
+/// </param>
+/// <param name="DeviceParam">
+/// Communication device parameters.
+/// </param>
+/// <returns>Status of the command.</returns>
+int CLCDriverMethods::Do_System_SwitchCommunicationDevice(uint32 Device, uint32 DeviceParam)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_SwitchCommunicationDevice(uiSessionOut, Device, DeviceParam));
+
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SYSTEM, COMMAND_SYSTEM_SWITCHCOMMUNICATIONDEVICE));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// The loader shuts down in a controlled fashion and proceeds to shut down the ME itself.
+/// The ME does not accept any further communication after a successful response from this
+/// command has been returned.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_System_Shutdown()
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_System_ShutDown(uiSessionOut));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to initiate a flashing session. The type argument is
+/// used to select the type of file to process and Length parameter
+/// defines the total size of the file.
+/// </summary>
+/// <param name="pchPath">Target path. If iUseBulk = 1, path is on PC.</param>
+/// <param name="pchType">Type of the opened file.</param>
+/// <param name="iUseBulk">If to use bulk protocol. If target is on PC iUseBulk shall be 1.</param>
+/// <param name="iDeleteBuffers">Specify whether to delete bulk buffers when finished. 1 -> delete buffers. 0 -> don't delete buffers.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Flash_ProcessFile(const char *pchPath, const char *pchType, int iUseBulk, int iDeleteBuffers)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Do_Flash_ProcessFile - DeleteBuffers = %d", iDeleteBuffers);
+#endif
+
+ if (iUseBulk) {
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ VERIFY_SUCCESS(m_pBuffers->AllocateBulkFile(pchPath));
+ uint64 uiLength = m_pBuffers->GetBulkFileLength();
+ m_uiBulkLength = uiLength;
+ m_uiBulkTransferred = 0;
+ VERIFY_SUCCESS(m_pBulkHandler->Send(pchPath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_ProcessFile(uiSessionOut, uiLength, pchType, BULK_PATH));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_PROCESSFILE));
+ } else {
+ // QSJOMIK: CURRENTLY WE CANNOT KNOW THE SIZE OF FILE ON AN ME MEMORY CARD IF USEBULK=0 - SEND 0 FOR NOW
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_ProcessFile(uiSessionOut, 0, pchType, pchPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_PROCESSFILE));
+ }
+
+ErrorExit:
+
+ if (iUseBulk) {
+ m_pBulkHandler->Finish();
+
+ if (0 != iDeleteBuffers) {
+ m_pBuffers->ReleaseBulkFile();
+ }
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used by the client application program to obtain the device tree.
+/// </summary>
+/// <param name="pDevices">A struct with information about one flash device.</param>
+/// <param name="piDeviceSize">Number of flash devices, size of pDevices array.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Flash_ListDevices(TDevices *pDevices, int *piDeviceSize)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_ListDevices(uiSessionOut));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_LISTDEVICES));
+
+ *piDeviceSize = DevicesNumber;
+
+ for (int i = 0; i < *piDeviceSize; ++i) {
+ pDevices[i].pchPath = Devices[i].Path_p;
+ pDevices[i].pchType = Devices[i].Type_p;
+
+ pDevices[i].iTypeSize = strlen(Devices[i].Type_p);
+ pDevices[i].iPathSize = strlen(Devices[i].Path_p);
+
+ pDevices[i].uiBlockSize = Devices[i].BlockSize;
+ pDevices[i].uiStart = Devices[i].Start;
+ pDevices[i].uiLength = Devices[i].Length;
+ }
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piDeviceSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to initiate a dump session.
+/// </summary>
+/// <param name="pchPathToDump">Path to the device to dump.</param>
+/// <param name="uiStart">Start of the dump relative to the start of the device indicated by Path [Byte].</param>
+/// <param name="uiLength">Length of the dump [Byte]. Actual length is determined by the device block size.</param>
+/// <param name="pchFilePath">File path on PC to store dump data to.</param>
+/// <param name="uiRedundantArea">Include redundant area in the dump.</param>
+/// <param name="iUseBulk">1-> save dump data on PC, 0-> save dump data on ME.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Flash_DumpArea(const char *pchPathToDump, uint64 uiStart, uint64 uiLength, const char *pchFilePath, uint32 uiRedundantArea, int iUseBulk)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ if (iUseBulk) {
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ m_uiBulkLength = uiLength;
+ m_uiBulkTransferred = 0;
+ VERIFY_SUCCESS(m_pBulkHandler->Receive(pchFilePath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_DumpArea(uiSessionOut, pchPathToDump, uiStart, uiLength, BULK_PATH, uiRedundantArea));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_DUMPAREA));
+ } else {
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_DumpArea(uiSessionOut, pchPathToDump, uiStart, uiLength, pchFilePath, uiRedundantArea));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_DUMPAREA));
+ }
+
+ErrorExit:
+
+ if (iUseBulk) {
+ m_pBulkHandler->Finish();
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to erase a flash device or part of a flash device.
+/// </summary>
+/// <param name="pchPath">Path to the device to erase.</param>
+/// <param name="uiStart">Start of the erase relative to the start of the device
+/// indicated by path [Byte]. This must be a multiple of the block size of the device.</param>
+/// <param name="uiLength">Length of the dump [Byte]. This must be a multiple of the block size of the device.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Flash_EraseArea(const char *pchPath, uint64 uiStart, uint64 uiLength)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_EraseArea(uiSessionOut, pchPath, uiStart, uiLength));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_ERASEAREA));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to initiate a flashing of raw data. The type argument is
+/// used to select the type of file to process and Length parameter
+/// defines the total size of the file.
+/// </summary>
+/// <param name="Context">LCD context on which to execute the operation.</param>
+/// <param name="pchPath">Target path. If iUseBulk = 1, path is on PC.</param>
+/// <param name="uiStart">Address where flashing should start.</param>
+/// <param name="uiLength">Length of data to be flashed.</param>
+/// <param name="uiDevice">Device ID number.</param>
+/// <param name="iUseBulk">If to use bulk protocol. If target is on PC iUseBulk shall be 1.</param>
+/// <param name="iDeleteBuffers">Specify if to delete bulk buffers after finish. 1 -> delete buffers. 0 -> don't delete buffers.</param>
+/// <returns>Status of the command.</returns>
+int CLCDriverMethods::Do_Flash_FlashRaw(const char *pchPath, uint64 uiStart, uint64 uiLength, uint32 uiDevice, int iUseBulk, int iDeleteBuffers)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Do_Flash_FlashRaw - DeleteBuffers = %d", iDeleteBuffers);
+#endif
+
+ if (iUseBulk) {
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ VERIFY_SUCCESS(m_pBuffers->AllocateBulkFile(pchPath));
+
+ uint64 uiFileLength = m_pBuffers->GetBulkFileLength();
+ VERIFY((uiLength <= uiFileLength), E_INVALID_INPUT_PARAMETERS);
+
+ m_uiBulkLength = uiLength;
+ m_uiBulkTransferred = 0;
+ VERIFY_SUCCESS(m_pBulkHandler->Send(pchPath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_FlashRaw(uiSessionOut, uiStart, uiLength, uiDevice, BULK_PATH));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_FLASHRAW));
+ } else {
+ // CURRENTLY WE CANNOT KNOW THE SIZE OF FILE ON AN ME MEMORY CARD IF USEBULK=0 - SEND 0 FOR NOW
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Flash_FlashRaw(uiSessionOut, uiStart, 0, uiDevice, pchPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FLASH, COMMAND_FLASH_FLASHRAW));
+ }
+
+ErrorExit:
+
+ if (iUseBulk) {
+ m_pBulkHandler->Finish();
+
+ if (0 != iDeleteBuffers) {
+ m_pBuffers->ReleaseBulkFile();
+ }
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command retrieves the properties of the specified file system volume. It is issued by the PC application.
+/// </summary>
+/// <param name="pchDevicePath">Path of file system volume.</param>
+/// <param name="pchFSType">File system type.</param>
+/// <param name="piFSTypeSize">Size of pchFSType array.</param>
+/// <param name="puiSize">Total size of the file system [Byte].</param>
+/// <param name="puiFree">Available space [Byte].</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_VolumeProperties(const char *pchDevicePath, char *pchFSType, int *piFSTypeSize, uint64 *puiSize, uint64 *puiFree)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_VolumeProperties(uiSessionOut, pchDevicePath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_VOLUMEPROPERTIES));
+
+ //Copy output parameter from RPC class.
+ if (m_pCmdResult->FileSystem_VolumeProperties_FSType.length() > static_cast<size_t>(*piFSTypeSize)) {
+ m_pCmdResult->FileSystem_VolumeProperties_FSType.erase(*piFSTypeSize - 1);
+ }
+
+ strcpy_s(pchFSType, *piFSTypeSize, m_pCmdResult->FileSystem_VolumeProperties_FSType.c_str());
+ *piFSTypeSize = m_pCmdResult->FileSystem_VolumeProperties_FSType.length();
+ *puiSize = m_pCmdResult->FileSystem_VolumeProperties_Size;
+ *puiFree = m_pCmdResult->FileSystem_VolumeProperties_Free;
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *pchFSType = '\0';
+ *piFSTypeSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// Formats unused file system volume specified in device path. This operation fails if the volume is currently in use.
+/// </summary>
+/// <param name="pchDevicePath">Device path of the file system volume.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_FormatVolume(const char *pchDevicePath)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_FormatVolume(uiSessionOut, pchDevicePath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_FORMATVOLUME));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+
+/// <summary>
+/// List files and directories residing in specified path.
+/// </summary>
+/// <param name="pchPath">File system path.</param>
+/// <param name="pEntries">Struct with file and directory information.</param>
+/// <param name="piDeviceSize">Number of files or directories, number of element in pEntries array.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_ListDirectory(const char *pchPath, TEntries *pEntries, int *piDeviceSize)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_ListDirectory(uiSessionOut, pchPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_LISTDIRECTORY));
+
+ //Copy output parameter from RPC class.
+ *piDeviceSize = static_cast<int>(m_pCmdResult->FileSystem_ListDirectory_Entries.size());
+ CopyVectorToArray(m_pCmdResult->FileSystem_ListDirectory_Entries, pEntries, piDeviceSize);
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piDeviceSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command moves a file from the source path to the destination path if the source and destination differ.
+/// It also renames a file if the source path and the destination path are the same.
+/// </summary>
+/// <param name="pchSourcePath">File system path in ME to source.</param>
+/// <param name="pchDestinationPath">File system path in ME to destination.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_MoveFile(const char *pchSourcePath, const char *pchDestinationPath)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_MoveFile(uiSessionOut, pchSourcePath, pchDestinationPath)); // DoRPC_FileSystem_MoveFile(&uiSessionOut, pchSourcePath, pchDestinationPath);
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_MOVEFILE));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Delete the specified file or directory. The loader only deletes empty directories.
+/// </summary>
+/// <param name="pchTargetPath">File system path in ME.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_DeleteFile(const char *pchTargetPath)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_DeleteFile(uiSessionOut, pchTargetPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_DELETEFILE));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to do the following: Copy a file from the PC to the ME. Copy a file between two directories or file systems on the ME.
+/// Copy a file from the ME to the PC.
+/// </summary>
+/// <param name="pchSourcePath">If iSourceUseBulk = 1 -> path on PC, else path on ME.</param>
+/// <param name="iSourceUseBulk">If = 1 -> source on PC, else source on ME.</param>
+/// <param name="pchDestinationPath">If iDestinationUseBulk = 1 -> path on PC, else path on ME.</param>
+/// <param name="iDestinationUseBulk">If = 1 -> destination on PC, else destination on ME.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_CopyFile(const char *pchSourcePath, int iSourceUseBulk, const char *pchDestinationPath, int iDestinationUseBulk)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ if (iSourceUseBulk) { // PC -> ME
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ VERIFY_SUCCESS(m_pBuffers->AllocateBulkFile(pchSourcePath));
+ m_uiBulkLength = m_pBuffers->GetBulkFileLength();
+ m_uiBulkTransferred = 0;
+ VERIFY_SUCCESS(m_pBulkHandler->Send(pchSourcePath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_CopyFile(uiSessionOut, BULK_PATH, pchDestinationPath));
+
+ //Wait for stat command
+ VERIFY_SUCCESS(WaitForEvent(EVENT_CMD_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_PROPERTIES));
+
+ struct stat fileInfo;
+ stat(pchSourcePath, &fileInfo);
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoneRPC_File_System_Operations_Properties(uiSessionOut, E_SUCCESS, fileInfo.st_mode, fileInfo.st_size, (uint32)fileInfo.st_mtime, (uint32)fileInfo.st_atime, (uint32)fileInfo.st_ctime));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_COPYFILE));
+ } else if (iDestinationUseBulk) { // ME -> PC
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ VERIFY_SUCCESS(m_pBulkHandler->Receive(pchDestinationPath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_CopyFile(uiSessionOut, pchSourcePath, BULK_PATH));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_COPYFILE));
+ } else {
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_CopyFile(uiSessionOut, pchSourcePath, pchDestinationPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_COPYFILE));
+ }
+
+ErrorExit:
+
+ if (iSourceUseBulk || iDestinationUseBulk) {
+ m_pBulkHandler->Finish();
+
+ if (iSourceUseBulk) {
+ m_pBuffers->ReleaseBulkFile();
+ }
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to create a directory. It is issued by the PC application.
+/// </summary>
+/// <param name="pchTargetPath">File system path to target.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_CreateDirectory(const char *pchTargetPath)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_CreateDirectory(uiSessionOut, pchTargetPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_CREATEDIRECTORY));
+
+ErrorExit:
+ return ReturnValue;
+}
+/// <summary>
+/// This command is used to retrieve the properties of a file or directory.
+/// </summary>
+/// <param name="pchTargetPath">File system path to target.</param>
+/// <param name="puiMode">File type and access restrictions descriptor.</param>
+/// <param name="puiSize">File size [Byte].</param>
+/// <param name="piMTime">Last modification timestamp.</param>
+/// <param name="piATime">Last access timestamp.</param>
+/// <param name="piCTime">Creation timestamp.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_Properties(const char *pchTargetPath, uint32 *puiMode, uint64 *puiSize, int *piMTime, int *piATime, int *piCTime)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_Properties(uiSessionOut, pchTargetPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_PROPERTIES));
+
+ //Copy output parameter from RPC class.
+ *puiMode = m_pCmdResult->FileSystem_Properties_Mode;
+ *puiSize = m_pCmdResult->FileSystem_Properties_Size;
+ *piMTime = m_pCmdResult->FileSystem_Properties_MTime;
+ *piATime = m_pCmdResult->FileSystem_Properties_ATime;
+ *piCTime = m_pCmdResult->FileSystem_Properties_CTime;
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to change the access permissions of a specified path.
+/// </summary>
+/// <param name="pchTargetPath">File system path to target.</param>
+/// <param name="iAccess">New access permissions.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_ChangeAccess(const char *pchTargetPath, int iAccess)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_ChangeAccess(uiSessionOut, pchTargetPath, iAccess));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_CHANGEACCESS));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to read manifests contained in load modules at the specified path and send the data back over bulk protocol.
+/// </summary>
+/// <param name="pchTargetPath">Path on PC to save manifest.</param>
+/// <param name="pchSourcePath">Load module(s) file system path.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_FileSystem_ReadLoadModuleManifests(const char *pchTargetPath, const char *pchSourcePath)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pBulkHandler->Receive(pchTargetPath));
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_File_System_Operations_ReadLoadModulesManifests(uiSessionOut, pchSourcePath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_FILE_SYSTEM_OPERATIONS, COMMAND_FILE_SYSTEM_OPERATIONS_READLOADMODULESMANIFESTS));
+
+ErrorExit:
+ m_pBulkHandler->Finish();
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to read the specified bits from the OTP.
+/// </summary>
+/// <param name="iOtpId">OTP area ID.</param>
+/// <param name="iBitStart">Starting offset [bit].</param>
+/// <param name="iBitLength">Length of read [bit].</param>
+/// <param name="puchDataBuffer">Received OTP data.</param>
+/// <param name="piDataBufferSize">Size of puchDataBuffer.</param>
+/// <param name="puchStatusBuffer">Lock status for each read bit.</param>
+/// <param name="piStatusBufferSize">Size of puchStatusBuffer.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_OTP_ReadBits(int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer, int *piDataBufferSize , unsigned char *puchStatusBuffer, int *piStatusBufferSize)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_OTP_ReadBits(uiSessionOut, iOtpId, iBitStart, iBitLength));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_OTP, COMMAND_OTP_READBITS));
+
+ //Copy output parameter from RPC class.
+ CopyVectorToArray(m_pCmdResult->OTP_ReadBits_DataBuffer, puchDataBuffer, piDataBufferSize);
+ CopyVectorToArray(m_pCmdResult->OTP_ReadBits_StatusBuffer, puchStatusBuffer, piStatusBufferSize);
+
+ //clean up
+ m_pCmdResult->OTP_ReadBits_DataBuffer.clear();
+ m_pCmdResult->OTP_ReadBits_StatusBuffer.clear();
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piDataBufferSize = 0;
+ *piStatusBufferSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command stores the specified bits in the loader internal OTP structures in RAM, it does not write to OTP.
+/// </summary>
+/// <param name="iOtpId">OTP area ID.</param>
+/// <param name="iBitStart">Starting offset [bit].</param>
+/// <param name="iBitLength">Length of write [bit].</param>
+/// <param name="puchDataBuffer">OTP data to write.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_OTP_SetBits(int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ uint32 Bytes = 0;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ Bytes = (iBitLength + 7) / 8;
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_OTP_SetBits(uiSessionOut, iOtpId, iBitStart, iBitLength, Bytes, puchDataBuffer));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_OTP, COMMAND_OTP_SETBITS));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command writes (burns) all data from loader internal OTP structures in RAM into the OTP fuse box.
+/// </summary>
+/// <param name="iOtpId">OTP area ID.</param>
+/// <param name="iForceWrite">If true: write and lock all lockable areas even if not all bits are received in cache.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_OTP_WriteAndLock(int iOtpId, int iForceWrite)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_OTP_WriteAndLock(uiSessionOut, iOtpId, iForceWrite));
+
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_OTP, COMMAND_OTP_WRITEANDLOCK));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command installs a secure object to the Boot record or OTP area.
+/// </summary>
+/// <param name="pchSourcePath">If iUseBulk = 1 -> path on PC, else path on ME.</param>
+/// <param name="iDestination">Secure object destination address on ME.</param>
+/// <param name="iUseBulk">Source on PC -> iUseBulk= 1. Source on ME -> iUseBulk= 0.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_OTP_StoreSecureObject(const char *pchSourcePath, int iDestination, int iUseBulk)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ if (iUseBulk) {
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+
+ VERIFY_SUCCESS(m_pBuffers->AllocateBulkFile(pchSourcePath));
+ m_uiBulkLength = m_pBuffers->GetBulkFileLength();
+ m_uiBulkTransferred = 0;
+ VERIFY_SUCCESS(m_pBulkHandler->Send(pchSourcePath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_OTP_StoreSecureObject(uiSessionOut, BULK_PATH, iDestination));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_OTP, COMMAND_OTP_STORESECUREOBJECT));
+ } else {
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_OTP_StoreSecureObject(uiSessionOut, pchSourcePath, iDestination));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_OTP, COMMAND_OTP_STORESECUREOBJECT));
+ }
+
+ErrorExit:
+
+ if (iUseBulk) {
+ m_pBulkHandler->Finish();
+ m_pBuffers->ReleaseBulkFile();
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// Reads a specified unit from the global data storage area/partition specified by the DevicePath parameter.
+/// </summary>
+/// <param name="iGdfsId">GDFS ID.</param>
+/// <param name="iUnit">Unit ID to read.</param>
+/// <param name="puchDataBuffer">Received global data.</param>
+/// <param name="piSize">Size of puchDataBuffer.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_ParameterStorage_ReadGlobalDataUnit(const char *pchGdfsId, int iUnit, unsigned char *puchDataBuffer, int *piSize)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_ParameterStorage_ReadGlobalDataUnit(uiSessionOut, pchGdfsId, iUnit));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_PARAMETERSTORAGE, COMMAND_PARAMETERSTORAGE_READGLOBALDATAUNIT));
+
+ //Copy output parameter from RPC class.
+ CopyVectorToArray(m_pCmdResult->ParameterStorage_ReadGlobalDataUnit_DataBuffer, puchDataBuffer, piSize);
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// Writes a specified unit to the global data storage area/partition specified by the DevicePath parameter.
+/// </summary>
+/// <param name="iGdfsId">GDFS ID.</param>
+/// <param name="iUnit">Unit ID to write.</param>
+/// <param name="puchDataBuffer">Global data to write.</param>
+/// <param name="iSize">Size of puchDataBuffer.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_ParameterStorage_WriteGlobalDataUnit(const char *pchGdfsId, int iUnit, const unsigned char *puchDataBuffer, int iSize)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_ParameterStorage_WriteGlobalDataUnit(uiSessionOut, pchGdfsId, iUnit, iSize, (void *)puchDataBuffer));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_PARAMETERSTORAGE, COMMAND_PARAMETERSTORAGE_WRITEGLOBALDATAUNIT));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Reads the complete global data storage area/partition specified by the DevicePath parameter (reads all units at once).
+/// </summary>
+/// <param name="iGdfsId">GDFS ID.</param>
+/// <param name="pchPath">If iUseBulk=1 -> path on PC to save data set to. Else path on ME.</param>
+/// <param name="iUseBulk">1-> save global data on PC, 0-> save global data on ME.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_ParameterStorage_ReadGlobalDataSet(const char *pchGdfsId, const char *pchPath, int iUseBulk)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ if (iUseBulk) {
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ VERIFY_SUCCESS(m_pBulkHandler->Receive(pchPath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_ParameterStorage_ReadGlobalDataSet(uiSessionOut, pchGdfsId, BULK_PATH));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_PARAMETERSTORAGE, COMMAND_PARAMETERSTORAGE_READGLOBALDATASET));
+ } else {
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_ParameterStorage_ReadGlobalDataSet(uiSessionOut, pchGdfsId, pchPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_PARAMETERSTORAGE, COMMAND_PARAMETERSTORAGE_READGLOBALDATASET));
+ }
+
+ErrorExit:
+
+ if (iUseBulk) {
+ m_pBulkHandler->Finish();
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// Writes the complete global data storage area/partition specified by the DevicePath parameter (writes all units at once).
+/// </summary>
+/// <param name="iGdfsId">GDFS ID.</param>
+/// <param name="pchPath">f iUseBulk=1 -> path on PC. Else path on ME</param>
+/// <param name="iUseBulk">1-> Global data source on PC, 0-> global data source on ME.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_ParameterStorage_WriteGlobalDataSet(const char *pchGdfsId, const char *pchPath, int iUseBulk)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ if (iUseBulk) {
+ VERIFY_SUCCESS(m_pBuffers->AllocateBulkFile(pchPath));
+ uint64 uiLength = m_pBuffers->GetBulkFileLength();
+ m_pLcmInterface->BulkSetCallbacks((void *)BulkCommandReqCallback, (void *)BulkDataReqCallback, (void *)BulkDataEndOfDumpCallback);
+ m_uiBulkLength = uiLength;
+ m_uiBulkTransferred = 0;
+ VERIFY_SUCCESS(m_pBulkHandler->Send(pchPath));
+
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_ParameterStorage_WriteGlobalDataSet(uiSessionOut, pchGdfsId, uiLength, BULK_PATH));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_PARAMETERSTORAGE, COMMAND_PARAMETERSTORAGE_WRITEGLOBALDATASET));
+ } else {
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_ParameterStorage_WriteGlobalDataSet(uiSessionOut, pchGdfsId, 0, pchPath));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_PARAMETERSTORAGE, COMMAND_PARAMETERSTORAGE_WRITEGLOBALDATASET));
+ }
+
+ErrorExit:
+
+ if (iUseBulk) {
+ m_pBulkHandler->Finish();
+ m_pBuffers->ReleaseBulkFile();
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// Erases the complete global data storage area/partition specified by the DevicePath parameter.
+/// </summary>
+/// <param name="iGdfsId">GDFS ID.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_ParameterStorage_EraseGlobalDataSet(const char *pchGdfsId)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_ParameterStorage_EraseGlobalDataSet(uiSessionOut, pchGdfsId));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_PARAMETERSTORAGE, COMMAND_PARAMETERSTORAGE_ERASEGLOBALDATASET));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to set the ME domain.
+/// </summary>
+/// <param name="iDomain">Target domain.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Security_SetDomain(int iDomain)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Security_SetDomain(uiSessionOut, iDomain));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SECURITY, COMMAND_SECURITY_SETDOMAIN));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to get the ME domain.
+/// </summary>
+/// <param name="piWrittenDomain">The ME current domain.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Security_GetDomain(int *piWrittenDomain)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Security_GetDomain(uiSessionOut));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SECURITY, COMMAND_SECURITY_GETDOMAIN));
+
+ //Copy output parameter from RPC class.
+ *piWrittenDomain = m_pCmdResult->Security_GetDomain_WrittenDomain;
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to read a security data unit (such as a secure static or dynamic data unit).
+/// </summary>
+/// <param name="iUnitId">Unit ID to read.</param>
+/// <param name="piSize">Size of puchDataBuffer.</param>
+/// <param name="puchDataBuffer">The unit data.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Security_GetProperties(int iUnitId, int *piSize, unsigned char *puchDataBuffer)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Security_GetProperties(uiSessionOut, iUnitId));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SECURITY, COMMAND_SECURITY_GETPROPERTIES));
+
+ //Copy output parameter from RPC class.
+ CopyVectorToArray(m_pCmdResult->Security_GetProperties_DataBuffer, puchDataBuffer, piSize);
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command is used to write a security data unit (such as a secure static or dynamic data unit).
+/// </summary>
+/// <param name="iUnitId">Unit ID to write.</param>
+/// <param name="iSize">Size of puchDataBuffer.</param>
+/// <param name="puchDataBuffer">The data to write.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Security_SetProperties(int iUnitId, int iSize, const unsigned char *puchDataBuffer)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Security_SetProperties(uiSessionOut, iUnitId, iSize, (void *)puchDataBuffer));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SECURITY, COMMAND_SECURITY_SETPROPERTIES));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// This command associates all security data units with the current ME.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Security_BindProperties()
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pLoaderRpcFunctions->DoRPC_Security_BindProperties(uiSessionOut));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_SECURITY, COMMAND_SECURITY_BINDPROPERTIES));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// The A2 loader shuts down in a controlled fashion and proceeds to shut down the ME itself.
+/// The ME does not accept any further communication after a successful response from this
+/// command has been returned.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_A2_System_Shutdown()
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ m_pA2LoaderRpcFunctions->setTargetCpu(1);
+
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_System_Shutdown(uiSessionOut));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// The PC uses the Loader version command to request version information from the loader
+/// The response holds the loader version information coded as ASCII characters in the data field
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_A2_System_LoaderVersion(char *pchLoaderVersion, int *piSize, int iTargetCPU)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ m_pA2LoaderRpcFunctions->setTargetCpu(iTargetCPU);
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_System_LoaderVersion(uiSessionOut));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_SYSTEM, COMMAND_A2_SYSTEM_LOADERVERSION));
+
+ CopyStringToArray(m_pCmdResult->A2_LoaderVersion, pchLoaderVersion, piSize);
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piSize = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// The Protocol version command is sent by the PC to request application protocol version from the loader.
+/// The loader responds with a GR with the protocol version in the response field.
+/// The version is coded as: 1 byte Major version + 1 byte Minor version.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_A2_System_Reset(int iTimeout)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ m_pA2LoaderRpcFunctions->setTargetCpu(1);
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_System_Reset(uiSessionOut, iTimeout));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// The Loader on loader command is used to transfer a new loader to the ME
+/// When the header or payload has been sent, the loader responds with a GR using status codes.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_A2_System_LoaderOnLoader(const char *pchPath, int iPLOffset, int iHLOffset, int iTargetCPU)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ MemMappedFile loaderFile;
+ uint32 loaderSize;
+ uint8 *loaderData = NULL;
+ uint32 LeftToSend;
+ size_t NumberOfPackets;
+ const uint32 PacketSize = m_pCmdResult->A2_MaxLoaderPacketSize - 17;
+ uint32 PayloadOffset;
+ const void *temp;
+ uint32 HL;
+ uint32 HL_Real;
+ uint32 PL;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(loaderFile.LoadFileData(pchPath));
+ loaderSize = static_cast<uint32>(loaderFile.GetFileSize());
+ loaderData = loaderFile.AllocateFileData(0, loaderSize);
+ VERIFY(0 != loaderData, loaderFile.GetError());
+
+ m_pA2LoaderRpcFunctions->setTargetCpu(iTargetCPU);
+
+ // get header length.
+ temp = loaderData + iHLOffset;
+ HL = m_pSerialization->get_uint32_le(&temp);
+ // pad to 8 byte (64 bit) alignments
+ HL_Real = (HL + 7) & ~7;
+
+ // calculate payload length
+ PL = loaderSize - HL_Real;
+
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_System_LoaderOnLoader(uiSessionOut, HL_Real, loaderData));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_SYSTEM, COMMAND_A2_SYSTEM_LOADERONLOADER));
+
+ NumberOfPackets = PL / PacketSize;
+
+ if (NumberOfPackets *PacketSize == PL) {
+ NumberOfPackets--;
+ }
+
+ PayloadOffset = HL_Real;
+
+ if (NumberOfPackets > 0) {
+ m_pA2LoaderRpcFunctions->setMorePackets(1);
+
+ for (size_t i = 0; i < NumberOfPackets; ++i) {
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_System_LoaderOnLoader(uiSessionOut, PacketSize, loaderData + PayloadOffset));
+ PayloadOffset += PacketSize;
+ }
+
+ m_pA2LoaderRpcFunctions->setMorePackets(0);
+ }
+
+ // send last payload package
+ LeftToSend = PL - PayloadOffset + HL_Real;
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_System_LoaderOnLoader(uiSessionOut, LeftToSend, loaderData + PayloadOffset));
+
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_SYSTEM, COMMAND_A2_SYSTEM_LOADERONLOADER));
+
+ErrorExit:
+
+ if (0 != loaderData) {
+ loaderFile.ReleaseFileData(loaderData, 0, loaderSize);
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// The Program flash command is sent by the PC to write a block of data into the flash memory.
+/// The block data is sent in the data field.
+/// When a complete block has been transmitted the loader verifies the data and responds with a GR using status codes
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_A2_Flash_ProgramFlash(const char *pchPath, int iUseSpeedFlash)
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ MemMappedFile softwareFile;
+ uint32 softwareSize;
+ uint8 *softwareData = 0;
+ const void *temp;
+ uint32 headerSize;
+ uint8 *payloadData;
+ uint32 leftToSend;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ softwareFile.LoadFileData(pchPath);
+ softwareSize = static_cast<uint32>(softwareFile.GetFileSize());
+ softwareData = softwareFile.AllocateFileData(0, softwareSize);
+ VERIFY(0 != softwareData, softwareFile.GetError());
+
+ // A2 header length offset = 80
+ temp = softwareData + 80;
+ headerSize = Serialization::get_uint32_le(&temp);
+ headerSize = (headerSize + 7) & ~7;
+
+ payloadData = softwareData + headerSize;
+
+ m_pA2LoaderRpcFunctions->setTargetCpu(2);
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_Flash_VerifySignedHeader(uiSessionOut, headerSize, softwareData));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_FLASH, COMMAND_A2_FLASH_VERIFYSIGNEDHEADER));
+
+ leftToSend = softwareSize - headerSize;
+
+ if (iUseSpeedFlash) {
+ temp = softwareData + 60; // start address is located at byte 60
+ uint32 startAddress = Serialization::get_uint32_le(&temp);
+
+ temp = softwareData + 28; // maximum block size is located at byte 28
+ uint32 subBlockSize = Serialization::get_uint32_le(&temp);
+
+ temp = softwareData + 64; // the software length (end address) is located at byte 64
+ uint32 endAddress = Serialization::get_uint32_le(&temp);
+
+ // speedflash command should be sent to ACC CPU
+ m_pA2LoaderRpcFunctions->setTargetCpu(1);
+
+ // start LCM speedflash mode
+ m_pLcmInterface->A2SpeedflashStart();
+
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_Flash_Speedflash(uiSessionOut, startAddress, endAddress, subBlockSize));
+
+ while (leftToSend) {
+ Serialization::skip_uint32((const void **)&payloadData); //skip start address
+ Serialization::skip_uint32((const void **)&payloadData); //skip block size
+ leftToSend -= 8; // skip start address and block size in the image
+
+ subBlockSize = min(subBlockSize, leftToSend);
+
+ VERIFY_SUCCESS(WaitForEvent(EVENT_SPEEDFLASH, GROUP_A2_FLASH, COMMAND_A2_FLASH_SPEEDFLASH));
+
+ if (0 == leftToSend - subBlockSize) {
+ m_pLcmInterface->A2SpeedflashSetLastBlock();
+ }
+
+ VERIFY_SUCCESS(m_pLcmInterface->A2SpeedflashWriteBlock(payloadData, subBlockSize)); // send sub-block
+
+ payloadData += subBlockSize;
+ leftToSend -= subBlockSize;
+ }
+
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_FLASH, COMMAND_A2_FLASH_SPEEDFLASH));
+ } else {
+ while (leftToSend) {
+ uint32 startAddress = Serialization::get_uint32_le((const void **)&payloadData);
+ uint32 blockSize = Serialization::get_uint32_le((const void **)&payloadData);
+ leftToSend -= 8; // skip start address and block size in the image
+ blockSize = min(blockSize, leftToSend);
+
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_Flash_SoftwareBlockAddress(uiSessionOut, startAddress, blockSize));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_FLASH, COMMAND_A2_FLASH_SOFTWAREBLOCKADDRESS));
+
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_Flash_ProgramFlash(uiSessionOut, blockSize, payloadData));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_FLASH, COMMAND_A2_FLASH_PROGRAMFLASH));
+
+ payloadData += blockSize;
+ leftToSend -= blockSize;
+ }
+ }
+
+ // verify flash command should be sent to APP CPU
+ m_pA2LoaderRpcFunctions->setTargetCpu(2);
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_Flash_VerifySoftwareFlash(uiSessionOut));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_FLASH, COMMAND_A2_FLASH_VERIFYSOFTWAREFLASH));
+
+ErrorExit:
+
+ if (0 != softwareData) {
+ softwareFile.ReleaseFileData(softwareData, 0, softwareSize);
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// The Erase flash command is used to erase the complete flash memory.
+/// It checks what type of memory is used in the ME and erases the complete memory including the first memory block.
+/// If more than one flash is attached, all of them will be erased
+/// The loader responds with a GR using status codes
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_A2_Flash_EraseFlash()
+{
+ uint16 uiSessionOut = 0;
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ m_pA2LoaderRpcFunctions->setTargetCpu(2);
+ VERIFY_SUCCESS(m_pA2LoaderRpcFunctions->DoRPC_A2_Flash_EraseFlash(uiSessionOut));
+ VERIFY_SUCCESS(WaitForEvent(EVENT_GR_RECEIVED, GROUP_A2_FLASH, COMMAND_A2_FLASH_ERASEFLASH));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+int CLCDriverMethods::Done_A2_Control_LoaderStarted()
+{
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ VERIFY_SUCCESS(WaitForEvent(EVENT_CMD_RECEIVED, GROUP_A2_CONTROL, COMMAND_A2_CONTROL_LOADERSTARTED));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Switch protocol family.
+/// </summary>
+/// <param name="family">New protocol family to use.</param>
+/// <returns>Status of the command.</returns>
+int CLCDriverMethods::Do_SwitchProtocolFamily(TFamily family)
+{
+ int ReturnValue = E_SUCCESS;
+ char strMessage[100] = {0};
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ m_pMainThread->TimerOff();
+
+ switch (family) {
+ case R15_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = R15_FAMILY;
+ m_CurrentCEHCallback = static_cast<Do_CEH_Call_t>(CEHCallbackFunction);
+ strcat_s(strMessage, "Do_SetProtocolFamily(R15_FAMILY)");
+ m_pMainThread->TimerOn();
+ break;
+ case PROTROM_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = PROTROM_FAMILY;
+ m_CurrentCEHCallback = static_cast<Do_CEH_Call_t>(CEH_PROTROM_CallbackFunction);
+ strcat_s(strMessage, "Do_SwitchProtocolFamily(PROTROM_FAMILY)");
+ break;
+ case Z_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = Z_FAMILY;
+ m_CurrentCEHCallback = static_cast<Do_CEH_Call_t>(CEH_Z_CallbackFunction);
+ strcat_s(strMessage, "Do_SwitchProtocolFamily(Z_FAMILY)");
+ m_pZRpcFunctions->Z_IndataBuffer->Clear();
+ break;
+ case A2_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = A2_FAMILY;
+ m_CurrentCEHCallback = static_cast<Do_CEH_Call_t>(CEH_A2_CallbackFunction);
+ strcat_s(strMessage, "Do_SwitchProtocolFamily(A2_FAMILY)");
+ //m_pMainThread->TimerOn();
+ break;
+ default:
+ return INVALID_INPUT_PARAMETERS;
+ }
+
+#ifdef _MESSAGES
+ m_pLogger->log(strMessage);
+#endif
+
+ VERIFY_SUCCESS(m_pMainThread->SetLcmFamily(m_CurrentProtocolFamily, m_CurrentCEHCallback));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Set ME in service mode and receive chip id.
+/// </summary>
+/// <param name="puiChipId">Received chip id.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Z_SetInServiceMode(unsigned int *puiChipId)
+{
+ int ReturnValue = E_SUCCESS;
+
+ time_t Start = 0;
+ time_t End = 0;
+ time_t ElapsedTime = 0;
+ bool bEmptyBuffer = false;
+ unsigned char uchReceivedByte;
+ unsigned char rguchReceivedChipId[8];
+ int iCount = 0;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ //Receive a 'z' character.
+ time(&Start);
+ time(&End);
+ ElapsedTime = End - Start;
+
+ while (ElapsedTime < 30) {
+ uchReceivedByte = m_pZRpcFunctions->Z_IndataBuffer->Pop(&bEmptyBuffer);
+
+ if ((bEmptyBuffer == false) && (uchReceivedByte == 'z')) {
+ break;
+ }
+
+ time(&End);
+ ElapsedTime = End - Start;
+ OS::Sleep(2);
+ }
+
+ if (ElapsedTime >= 30) {
+ VERIFY_SUCCESS(TIMEOUT_NO_Z_DETECTED);
+ }
+
+ //Send version request.
+ VERIFY_SUCCESS(m_pZRpcFunctions->DoRPC_Z_VersionRequest());
+
+ //Receive chip id.
+ time(&Start);
+ time(&End);
+ ElapsedTime = End - Start;
+
+ while (ElapsedTime < 30) {
+ uchReceivedByte = m_pZRpcFunctions->Z_IndataBuffer->Pop(&bEmptyBuffer);
+
+ if (bEmptyBuffer == false) {
+ rguchReceivedChipId[iCount++] = uchReceivedByte;
+
+ if (iCount == 8) {
+ break;
+ }
+ }
+
+ time(&End);
+ ElapsedTime = End - Start;
+
+ OS::Sleep(2);
+ }
+
+ if (ElapsedTime >= 30) {
+ VERIFY_SUCCESS(TIMEOUT_NO_CHIP_ID_DETECTED);
+ }
+
+ //Copy chip ID byte 1 and 2
+ *puiChipId = rguchReceivedChipId[0] << 8; //Major byte
+ *puiChipId += rguchReceivedChipId[1]; //Minor byte
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Set communication baudrate when communicating via UART.
+/// </summary>
+/// <param name="iBaudrate">Baudrate to use. Valid values: 9600, 19200, 38400, 57600, 115200,
+/// 230400, 460800, 921600, 1625000.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Z_SetBaudrate(int iBaudrate)
+{
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+ VERIFY_SUCCESS(m_pZRpcFunctions->DoRPC_Z_SetBaudrate(iBaudrate));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Exit Z-protocol and start uing PROTROM-protocol.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_Z_Exit_Z_Protocol()
+{
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ m_pCommunicationDevice->Cancel(m_pLcmInterface->getLCMContext());
+
+ //Send exit z-protocol command.
+ VERIFY_SUCCESS(m_pZRpcFunctions->DoRPC_Z_Exit_Z_Protocol());
+
+ //Change protocol family to PROTROM
+ VERIFY_SUCCESS(Do_SwitchProtocolFamily(PROTROM_PROTOCOL_FAMILY));
+
+ //Receive PROTROM command PDU: PROTROM_PDU_READY_TO_RECEIVE.
+ VERIFY_SUCCESS(WaitForPROTROMResponseOrCancelOrTimeout(PROTROM_PDU_READY_TO_RECEIVE));
+
+ //Send PROTROOM command PDU:PROTROM_PDU_RESULT.
+ VERIFY_SUCCESS(m_pProtromRpcFunctions->DoRPC_PROTROM_ResultPdu(0));
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Download loader using PROTROM-protocol.
+/// </summary>
+/// <param name="pchPath">Path to loader on PC.</param>
+/// <param name="iPLOffset">Offset in header to payload length.</param>
+/// <param name="iHLOffset">Offset in header to header length.</param>
+/// <param name="iContinueProtRom">1 -> continue use PROTROM-protocol after download the loader. O -> not use PROTROM-protocol after download the loader.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::Do_PROTROM_DownloadLoader(const char *pchPath, int iPLOffset, int iHLOffset, int iContinueProtRom)
+{
+ int ReturnValue = E_SUCCESS;
+
+ MemMappedFile loaderFile;
+ uint8 *loaderData;
+ const void *temp;
+ uint32 HL; //Header length.
+ uint32 HL_Real; //Header length + 32 bit alignment padding
+ uint32 PL; //Payload length.
+ const uint32 PacketSize = 64000;
+ size_t NumberOfPackets;
+ uint32 PayloadOffset;
+ uint32 LeftToSend;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ VERIFY_SUCCESS(loaderFile.LoadFileData(pchPath));
+ /* coverity[tainted_data_return] */
+ loaderData = loaderFile.AllocateFileData(0, loaderFile.GetFileSize());
+ VERIFY(0 != loaderData, loaderFile.GetError());
+
+ //Get header length.
+ temp = loaderData + iHLOffset;
+ HL = m_pSerialization->get_uint32_le(&temp);
+ HL_Real = (HL + 3) & ~3; //Pad to 4 byte (32 bit) alignments
+
+ //Get payload length.
+ temp = loaderData + iPLOffset;
+ PL = m_pSerialization->get_uint32_le(&temp);
+
+ VERIFY_SUCCESS(m_pProtromRpcFunctions->DoRPC_PROTROM_SendLoaderHeader(loaderData, HL_Real));
+
+ //Receive PROTROM command PDU: PROTROM_PDU_RESULT.
+ VERIFY_SUCCESS(WaitForPROTROMResponseOrCancelOrTimeout(PROTROM_PDU_RESULT));
+
+ //Download all packet beside one
+ NumberOfPackets = PL / PacketSize;
+
+ if (NumberOfPackets *PacketSize == PL) {
+ NumberOfPackets--;
+ }
+
+ PayloadOffset = HL_Real;
+
+ if (NumberOfPackets > 0) {
+ for (size_t i = 0; i < NumberOfPackets; ++i) {
+ VERIFY_SUCCESS(m_pProtromRpcFunctions->DoRPC_PROTROM_SendLoaderPayload(loaderData + PayloadOffset, PacketSize));
+ PayloadOffset += PacketSize;
+
+ //Receive PROTROM command PDU: PROTROM_PDU_RESULT.
+ VERIFY_SUCCESS(WaitForPROTROMResponseOrCancelOrTimeout(PROTROM_PDU_RESULT));
+ }
+ }
+
+ if (!iContinueProtRom) {
+ m_pProtromRpcFunctions->CancelDeviceOnResult(m_pCommunicationDevice);
+ m_pLcmInterface->CommunicationCancelReceiver(2);
+ }
+
+ //Send last payload package
+ LeftToSend = PL - PayloadOffset + HL_Real;
+
+ VERIFY_SUCCESS(m_pProtromRpcFunctions->DoRPC_PROTROM_SendLoaderFinalPayload(loaderData + PayloadOffset, LeftToSend));
+
+ loaderFile.ReleaseFileData(loaderData, 0, loaderFile.GetFileSize());
+
+ //If downloaded loader continues to use PROTROM protocol.
+ if (0 != iContinueProtRom) {
+ //Receive PROTROM command PDU: PROTROM_PDU_RESULT.
+ VERIFY_SUCCESS(WaitForPROTROMResponseOrCancelOrTimeout(PROTROM_PDU_RESULT));
+
+ //Receive PROTROM command PDU: PROTROM_PDU_READY_TO_RECEIVE.
+ VERIFY_SUCCESS(WaitForPROTROMResponseOrCancelOrTimeout(PROTROM_PDU_READY_TO_RECEIVE));
+
+ //Send result pdu.
+ VERIFY_SUCCESS(m_pProtromRpcFunctions->DoRPC_PROTROM_ResultPdu(0));
+ } else {
+ VERIFY_SUCCESS(WaitForPROTROMResponseOrCancelOrTimeout(PROTROM_PDU_RESULT));
+ }
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/// <summary>
+/// Send intrinsic request to read security data using PROTROM-protocol.
+/// </summary>
+/// <param name="uiSecDataId">ID of the security data to be read with the intrinsic request.</param>
+/// <param name="puchDataBuffer">Buffer where the read data will be stored.</param>
+/// <param name="piDataLength">IN: Length of DataBuffer; OUT: Read data length.</param>
+/// <returns>Status of the command.</returns>
+int CLCDriverMethods::Do_PROTROM_ReadSecurityData(uint8 uiSecDataId, unsigned char *puchDataBuffer, int *piDataLength)
+{
+ int ReturnValue = E_SUCCESS;
+
+ VERIFY_SUCCESS(IsMainThreadAlive());
+
+ VERIFY_SUCCESS(m_pProtromRpcFunctions->DoRPC_PROTROM_ReadSecurityData(uiSecDataId));
+
+ //Receive PROTROM command PDU: PROTROM_PDU_RESULT.
+ VERIFY_SUCCESS(WaitForPROTROMResponseOrCancelOrTimeout(PROTROM_PDU_SECURITY_DATA_RES));
+
+ CopyVectorToArray(m_pCmdResult->ProtromPayloadData, puchDataBuffer, piDataLength);
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ *piDataLength = 0;
+ }
+
+ return ReturnValue;
+}
+
+int CLCDriverMethods::SetInitialProtocolFamily(TFamily family)
+{
+ switch (family) {
+ case R15_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = R15_FAMILY;
+ m_CurrentCEHCallback = CEHCallbackFunction;
+ break;
+ case PROTROM_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = PROTROM_FAMILY;
+ m_CurrentCEHCallback = CEH_PROTROM_CallbackFunction;
+ break;
+ case Z_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = Z_FAMILY;
+ m_CurrentCEHCallback = CEH_Z_CallbackFunction;
+ break;
+ case A2_PROTOCOL_FAMILY:
+ m_CurrentProtocolFamily = A2_FAMILY;
+ m_CurrentCEHCallback = CEH_A2_CallbackFunction;
+ break;
+ default:
+ return INVALID_INPUT_PARAMETERS;
+ }
+
+ return 0;
+}
+
+void CLCDriverMethods::ConfigureCommunicationDevice(void *Read_fn, void *Write_fn, void *Cancel_fn)
+{
+ m_pCommunicationDevice->Read = reinterpret_cast<DeviceRead_fn>(Read_fn);
+ m_pCommunicationDevice->Write = reinterpret_cast<DeviceWrite_fn>(Write_fn);
+ m_pCommunicationDevice->Cancel = reinterpret_cast<DeviceCancel_fn>(Cancel_fn);
+ m_pCommunicationDevice->Context_p = NULL;
+}
+
+void CLCDriverMethods::SetMessageCallback(void *Callback_fn)
+{
+ m_pLogger->setMessageCallback(reinterpret_cast<MessageCallback_t>(Callback_fn));
+}
+
+void CLCDriverMethods::SetProgressCallback(void *Callback_fn)
+{
+ m_ProgressBarUpdate = reinterpret_cast<ProgressBarCallback_t>(Callback_fn);
+}
+
+/// <summary>
+/// Set timeouts used by LCM and LCDriver.
+/// </summary>
+/// <param name="R15_TOs">LCM timeout data.</param>
+/// <param name="LCD_TOs">LCDriver timeout data.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::SetPcTimeouts(TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs)
+{
+ CLockCS TimeoutLock(m_SetTimeoutCS);
+
+ // if null, default values are used
+ if (LCD_TOs != NULL) {
+ m_Timeouts.uiRTO = LCD_TOs->uiRTO;
+ m_Timeouts.uiSTO = LCD_TOs->uiSTO;
+ }
+
+ if (m_CurrentProtocolFamily == R15_FAMILY) {
+ LcmR15Timeouts timeouts;
+ timeouts.TCACK = R15_TOs->TCACK;
+ timeouts.TBCR = R15_TOs->TBCR;
+ timeouts.TBDR = R15_TOs->TBDR;
+ return m_pLcmInterface->CommunicationSetProtocolTimeouts(static_cast<void *>(&timeouts));
+ } else {
+ return E_SUCCESS;
+ }
+}
+
+/// <summary>
+/// Get timeouts used by LCM and LCDriver.
+/// </summary>
+/// <param name="R15_TOs">LCM timeout data.</param>
+/// <param name="LCD_TOs">LCDriver timeout data.</param>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::GetPcTimeouts(TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs)
+{
+ int ReturnValue = E_SUCCESS;
+ LCD_TOs->uiRTO = m_Timeouts.uiRTO;
+ LCD_TOs->uiSTO = m_Timeouts.uiSTO;
+
+ if (m_CurrentProtocolFamily == R15_FAMILY) {
+ LcmR15Timeouts timeouts;
+ ReturnValue = m_pLcmInterface->CommunicationGetProtocolTimeouts(static_cast<void *>(&timeouts));
+
+ if (E_SUCCESS == ReturnValue) {
+ R15_TOs->TCACK = timeouts.TCACK;
+ R15_TOs->TBCR = timeouts.TBCR;
+ R15_TOs->TBDR = timeouts.TBDR;
+ R15_TOs->TBES = 0xFFFFFFFF;
+ }
+ } else {
+ R15_TOs->TBCR = 0;
+ R15_TOs->TBDR = 0;
+ R15_TOs->TBES = 0;
+ R15_TOs->TCACK = 0;
+ }
+
+ return ReturnValue;
+}
+
+/// <summary>
+/// Copies a vector to an array.
+/// </summary>
+/// <param name="Source">Source data.</param>
+/// <param name="pDestination">The destination to write data to.</param>
+/// <param name="piSize">Size of data to write.</param>
+/// <returns> Void.</returns>
+template <class T, class U>
+void CLCDriverMethods::CopyVectorToArray(const vector<T>& Source, U *pDestination, int *piSize)
+{
+ size_t copyLength = *piSize;
+
+ if (Source.size() < copyLength) {
+ copyLength = Source.size();
+ }
+
+ for (size_t i = 0; i < copyLength; i++) {
+ pDestination[i] = Source[i];
+ }
+
+ *piSize = static_cast<int>(copyLength);
+}
+
+void CLCDriverMethods::CopyStringToArray(string &Source, char *pDestination, int *piSize)
+{
+ if (Source.size() > static_cast<size_t>(*piSize)) {
+ // erase part of the string that won't fit in the buffer
+ Source.erase(*piSize - 1);
+ }
+
+ strcpy_s(pDestination, *piSize, Source.c_str());
+ *piSize = Source.size();
+}
+
+/// <summary>
+/// Check whether main thread is alive and perform other checks.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::IsMainThreadAlive()
+{
+ if (0 != m_pMainThread->ThreadIsDying()) {
+ if (m_pMainThread->ThreadIsDying() == 2) {
+ return LCDRIVER_THREAD_KILLED_WITH_SIGNAL_DEATH;
+ } else if (m_pMainThread->ThreadIsDying() == 3) {
+ return LCDRIVER_THREAD_KILLED_WITH_CANCEL;
+ } else {
+ return LCDRIVER_THREAD_KILLED;
+ }
+ }
+
+ return 0;
+}
+
+/// <summary>
+/// Wait for General Response from ME.
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::WaitForEvent(uint32 event, int Group, int Command)
+{
+ int iResult;
+ Event *receivedEvent;
+ CLockCS TimeoutLock(m_SetTimeoutCS);
+
+ m_pLogger->log("WaitForEvent: Entering method. Event = 0x%08x, Timeout = %d", event, m_Timeouts.uiRTO);
+ RemoveResult result = m_EventQueue.RemoveHead(reinterpret_cast<void **>(&receivedEvent), m_Timeouts.uiRTO);
+
+ // always wait for error event
+ event |= EVENT_ERROR;
+
+ if (REMOVE_SUCCESS == result) {
+ switch (receivedEvent->event & event) {
+ case EVENT_GR_RECEIVED:
+ if (receivedEvent->group == Group &&
+ receivedEvent->command == Command) {
+ m_pLogger->log("WaitForEvent: General Response received. Number = %d", receivedEvent->command);
+ iResult = receivedEvent->error;
+ } else {
+ m_pLogger->log("Expected GR command # %d", Command);
+ m_pLogger->log("Expected GR application (group) # %d", Group);
+ m_pLogger->log("Received GR command # %d", receivedEvent->command);
+ m_pLogger->log("Received GR application (group) # %d", receivedEvent->group);
+ iResult = GENERAL_RESPONSE_COMMAND_NUMBER_ERROR;
+ }
+
+ break;
+ case EVENT_CMD_RECEIVED:
+ if ((receivedEvent->group == Group && receivedEvent->command == Command) ||
+ (Group == GROUP_SYSTEM && Command == COMMAND_SYSTEM_AUTHENTICATE)) {
+ m_pLogger->log("WaitForEvent: Expected command received");
+ iResult = 0;
+ } else {
+ m_pLogger->log("WaitForEvent: ERROR Unexpected command received");
+ iResult = COMMAND_NUMBER_ERROR;
+ }
+
+ break;
+ case EVENT_SPEEDFLASH:
+ m_pLogger->log("WaitForEvent: Speedflash request received.");
+ iResult = 0;
+ break;
+ case EVENT_ERROR:
+ iResult = receivedEvent->error;
+ break;
+ default:
+ iResult = UNEXPECTED_EVENT_RECEIVED;
+ break;
+ }
+ } else if (REMOVE_CANCEL == result) {
+ m_pLogger->log("WaitForEvent: Cancel received");
+ iResult = CANCEL_EVENT_RECEIVED;
+ } else if (REMOVE_TIMEOUT == result) {
+ m_pLogger->log("WaitForEvent: Timeout");
+ iResult = TIMEOUT;
+ } else {
+ m_pLogger->log("WaitForEvent: Unknown return value");
+ iResult = UNKNOWN_WAIT_RETURN_VALUE;
+ }
+
+ return iResult;
+}
+
+/// <summary>
+/// Wait for specific Protrom response.
+/// <param name="iReceivePdu">Which PDU to wait for.</param>
+/// </summary>
+/// <returns> Status of the command.</returns>
+int CLCDriverMethods::WaitForPROTROMResponseOrCancelOrTimeout(int iReceivePdu)
+{
+ int iResult;
+ bool Continue = false;
+ TProtromInfo *pInfo = 0;
+ CLockCS TimeoutLock(m_SetTimeoutCS);
+
+ do {
+ Continue = false;
+ m_pLogger->log("WaitForPROTROMResponseOrCancelOrTimeout: WAIT - expected PDU = %d", iReceivePdu);
+
+ RemoveResult result = m_pProtromRpcFunctions->ProtromQueue.RemoveRequest(reinterpret_cast<void **>(&pInfo), m_Timeouts.uiRTO);
+
+ if (REMOVE_SUCCESS == result) {
+ iResult = 0;
+
+ if (pInfo->ReceivedPdu != iReceivePdu) {
+ m_pLogger->log("WaitForPROTROMResponseOrCancelOrTimeout: RECEIVE - unexpected PDU %d", pInfo->ReceivedPdu);
+ Continue = true;
+ } else if (iReceivePdu == PROTROM_PDU_RESULT) {
+ //Check result from PDU_RESULT
+ if (pInfo->Status != 0) {
+ iResult = PROTROM_STATUS_NOT_OK;
+ }
+ }
+
+ delete[](uint8 *)pInfo->DataP;
+ delete pInfo;
+ } else if (REMOVE_CANCEL == result) {
+ m_pLogger->log("WaitForPROTROMResponseOrCancelOrTimeout: CANCEL");
+ iResult = CANCEL_EVENT_RECEIVED;
+ } else if (REMOVE_TIMEOUT == result) {
+ m_pLogger->log("WaitForPROTROMResponseOrCancelOrTimeout: TIMEOUT");
+ iResult = TIMEOUT;
+ } else {
+ m_pLogger->log("WaitForPROTROMResponseOrCancelOrTimeout: UNKNOWN");
+ iResult = UNKNOWN_WAIT_RETURN_VALUE;
+ }
+ } while (Continue);
+
+ return iResult;
+}
+
+void CLCDriverMethods::Do_BulkDataReqCallback(uint16 *Session_p, uint32 *ChunkSize_p, uint64 *Offset_p, uint32 *Length_p, uint64 *TotalLength_p, uint32 *TransferredLength_p)
+{
+ m_uiBulkTransferred += *ChunkSize_p;
+}
+
+void CLCDriverMethods::UpdateBulkProgress()
+{
+ if (NULL != m_ProgressBarUpdate) {
+ m_ProgressBarUpdate(m_pLcmInterface->getLCMContext(), m_uiBulkLength, m_uiBulkTransferred);
+ }
+}
+
+void CLCDriverMethods::Do_BulkDataEndOfDumpCallback()
+{
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: END OF DUMP CALLBACK RECEIVED!");
+#endif
+}
+
+int CLCDriverMethods::MapLcmError(int error)
+{
+ switch (error) {
+ case E_RETRANSMITION_FAILED:
+ return LCM_RETRANSMISSION_ERROR;
+ case E_GENERAL_COMMUNICATION_ERROR:
+ return LCM_DEVICE_WRITE_ERROR;
+ default:
+ return error;
+ }
+}
+
+void CLCDriverMethods::SignalError(int error)
+{
+ Event *event = new Event(EVENT_ERROR, error);
+ m_EventQueue.AddTail(event);
+}
+
+void CLCDriverMethods::AddEvent(Event *newEvent)
+{
+ m_EventQueue.AddTail(newEvent);
+}
diff --git a/source/LCDriverMethods.h b/source/LCDriverMethods.h
new file mode 100644
index 0000000..7e048be
--- /dev/null
+++ b/source/LCDriverMethods.h
@@ -0,0 +1,265 @@
+/*******************************************************************************
+*
+* File name: LCDriverMethods.h
+* Project: LCDriver
+* Language: Visual C++
+* Description: Implementation of all exported methods.
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+#ifndef _LCDRIVERMETHODS_H_
+#define _LCDRIVERMETHODS_H_
+
+#include "Buffers.h"
+#include "Queue.h"
+#include "Timer.h"
+#include "Hash.h"
+#include "Serialization.h"
+#include "Logger.h"
+#include "CmdResult.h"
+#include "LCDriverThread.h"
+#include "BulkHandler.h"
+#include "Event.h"
+
+class LcmInterface;
+class ZRpcInterface;
+class ProtromRpcInterface;
+class LoaderRpcInterfaceImpl;
+class A2LoaderRpcInterfaceImpl;
+
+typedef void (*ProgressBarCallback_t)(void *Communication_p, uint64 TotalLength, uint64 TransferredLength);
+
+/// <summary>
+/// Implementation class.
+/// </summary>
+class CLCDriverMethods
+{
+ friend class CLCDriverThread;
+public:
+ CLCDriverMethods(const char *pchInterfaceId);
+ virtual ~CLCDriverMethods();
+
+ int Do_Initialize(void **ppInstance);
+
+ int SetInitialProtocolFamily(TFamily family);
+ void ConfigureCommunicationDevice(void *Read_fn, void *Write_fn, void *Cancel_fn);
+ void SetMessageCallback(void *Callback_fn);
+ void SetProgressCallback(void *Callback_fn);
+
+ int SetPcTimeouts(TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs);
+ int GetPcTimeouts(TR15Timeouts *R15_TOs, TLCDriverTimeouts *LCD_TOs);
+
+ void CancelCurrentLoaderCommand();
+
+ // Loader methods
+ int Done_System_LoaderStartupStatus(char *pchVersion, int *piVersionSize, char *pchProtocol, int *piProtocolSize);
+ int Do_System_Reboot(int iMode);
+ int Do_System_Shutdown();
+ int Do_System_SupportedCommands(TSupportedCmd *pCmdList, int *piCmdListSize);
+ int Do_System_CollectData(int iType, int *piSize, char *pData);
+ int Do_System_ExecuteSoftware(const uint32 ExecuteMode,const char *pchDevicePath, int iUseBulk);
+ int Do_System_Authenticate(int iType, int *piSize, unsigned char *puchdata);
+ int Done_System_GetControlKeys(TSIMLockKeys *pSIMLockKeys);
+ int Done_System_GetControlKeysData(int iDataSize, unsigned char *pSIMLockKeysData);
+ int Done_System_AuthenticationChallenge(int iDataSize, unsigned char *puchChallengeData);
+ int Do_System_SetSystemTime(uint32 EpochTime);
+ int Do_System_SwitchCommunicationDevice(uint32 Device, uint32 DeviceParam);
+
+ int Do_Flash_ProcessFile(const char *pchPath, const char *pchType, int iUseBulk, int iDeleteBuffers);
+ int Do_Flash_ListDevices(TDevices *pDevices, int *piDeviceSize);
+ int Do_Flash_DumpArea(const char *pchPathToDump, uint64 uiStart, uint64 uiLength, const char *pchFilePath, uint32 RedundantArea, int iUseBulk);
+ int Do_Flash_EraseArea(const char *pchPath, uint64 uiStart, uint64 uiLength);
+ int Do_Flash_FlashRaw(const char *pchPath, uint64 uiStart, uint64 uiLength, uint32 uiDevice, int iUseBulk, int iDeleteBuffers);
+
+ int Do_FileSystem_VolumeProperties(const char *pchDevicePath, char *pchFSType, int *piFSTypeSize, uint64 *puiSize, uint64 *puiFree);
+ int Do_FileSystem_FormatVolume(const char *pchDevicePath);
+ int Do_FileSystem_ListDirectory(const char *pchPath, TEntries *pEntries, int *DeviceSize);
+ int Do_FileSystem_MoveFile(const char *pchSourcePath, const char *pchDestinationPath);
+ int Do_FileSystem_DeleteFile(const char *pchTargetPath);
+ int Do_FileSystem_CopyFile(const char *pchSourcePath, int iSourceUseBulk, const char *pchDestinationPath, int iDestinationUseBulk);
+ int Do_FileSystem_CreateDirectory(const char *pchTargetPath);
+ int Do_FileSystem_Properties(const char *pchTargetPath, uint32 *puiMode, uint64 *puiSize, int *piMTime, int *piATime, int *piCTime);
+ int Do_FileSystem_ChangeAccess(const char *pchTargetPath, int iAccess);
+ int Do_FileSystem_ReadLoadModuleManifests(const char *pchTargetPath, const char *pchSourcePath);
+
+ int Do_OTP_ReadBits(int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer, int *piDataBufferSize , unsigned char *puchStatusBuffer, int *piStatusBufferSize);
+ int Do_OTP_SetBits(int iOtpId, int iBitStart, int iBitLength, unsigned char *puchDataBuffer);
+ int Do_OTP_WriteAndLock(int iOtpId, int iForceWrite);
+ int Do_OTP_StoreSecureObject(const char *pchSourcePath, int iDestination, int iUseBulk);
+
+ int Do_ParameterStorage_ReadGlobalDataUnit(const char *pchGdfsId, int iUnit, unsigned char *puchDataBuffer, int *piSize);
+ int Do_ParameterStorage_WriteGlobalDataUnit(const char *pchGdfsId, int iUnit, const unsigned char *puchDataBuffer, int iSize);
+ int Do_ParameterStorage_ReadGlobalDataSet(const char *pchGdfsId, const char *pchPath, int iUseBulk);
+ int Do_ParameterStorage_WriteGlobalDataSet(const char *pchGdfsId, const char *pchPath, int iUseBulk);
+ int Do_ParameterStorage_EraseGlobalDataSet(const char *pchGdfsId);
+
+ int Do_Security_SetDomain(int iDomain);
+ int Do_Security_GetDomain(int *piWrittenDomain);
+ int Do_Security_GetProperties(int iUnitId, int *piSize, unsigned char *puchDataBuffer);
+ int Do_Security_SetProperties(int iUnitId, int iSize, const unsigned char *puchDataBuffer);
+ int Do_Security_BindProperties();
+
+ // A2 Protocol Methods
+ int Do_A2_System_Shutdown();
+ int Do_A2_System_LoaderVersion(char *pchLoaderVersion, int *piSize, int iTargetCPU);
+ int Do_A2_System_LoaderOnLoader(const char *pchPath, int iPLOffset, int iHLOffset, int iTargetCPU);
+ int Do_A2_System_Reset(int iTimeout);
+
+ int Do_A2_Flash_ProgramFlash(const char *pchPath, int iUseSpeedFlash);
+ int Do_A2_Flash_EraseFlash();
+
+ int Done_A2_Control_LoaderStarted();
+
+ // Z Protocol Methods
+ int Do_Z_SetInServiceMode(unsigned int *puiChipId);
+ int Do_Z_SetBaudrate(int iBaudrate);
+ int Do_Z_Exit_Z_Protocol();
+
+ // PROTROM Protocol Methods
+ int Do_PROTROM_DownloadLoader(const char *pchPath, int iPLOffset, int iHLOffset, int iContinueProtRom);
+ int Do_PROTROM_ReadSecurityData(uint8 uiSecDataId, unsigned char *puchDataBuffer, int *piDataLength);
+
+ int Do_SwitchProtocolFamily(TFamily family);
+
+private:
+ // Members
+ Buffers *m_pBuffers;
+ Queue *m_pQueue;
+ Timer *m_pTimer;
+ Hash *m_pHash;
+ Serialization *m_pSerialization;
+ Logger *m_pLogger;
+ BulkHandler *m_pBulkHandler;
+
+
+ HashDevice_t *m_pHashDevice;
+ CommunicationDevice_t *m_pCommunicationDevice;
+
+ // Utility setup methods
+ ErrorCode_e SetupTimers(TimersInterface_t *pTimerFunctions);
+ ErrorCode_e SetupBuffers(BuffersInterface_t *pBufferFunctions);
+ ErrorCode_e SetupQueues(QueueInterface_t *pQueueFunctions);
+ ErrorCode_e SetupHash();
+
+ CmdResult *m_pCmdResult;
+ LcmInterface *m_pLcmInterface;
+ ZRpcInterface *m_pZRpcFunctions;
+ ProtromRpcInterface *m_pProtromRpcFunctions;
+ LoaderRpcInterfaceImpl *m_pLoaderRpcFunctions;
+ A2LoaderRpcInterfaceImpl *m_pA2LoaderRpcFunctions;
+ CLCDriverThread *m_pMainThread;
+
+ //------------------------------------------
+ // Static methods for support modules: timers, hash, buffers and queue
+ //------------------------------------------
+public:
+ static ErrorCode_e TimerInit(void *pObject, uint32 uiTimers);
+ static uint32 TimerGet(void *pObject, Timer_t *pTimer);
+ static ErrorCode_e TimerRelease(void *pObject, uint32 uiTimerKey);
+ static uint32 TimerReadTime(void *pObject, uint32 uiTimerKey);
+ static uint32 TimerGetSystemTime(void *pObject);
+
+ static void HashCancel(void *pObject, void **ppHashDevice);
+ static void HashCalculate(void *pObject, HashType_e Type, void *pData, const uint32 uiLength, uint8 *pHash, HashCallback_fn fnCallback, void *pParam);
+ static uint32 HashGetLength(void *pObject, HashType_e Type);
+
+ static ErrorCode_e BuffersInit(void *pObject);
+ static void *BufferAllocate(void *pObject, int iBufferSize);
+ static ErrorCode_e BufferRelease(void *pObject, void *pBuffer, int iBufferSize);
+ static uint32 BuffersAvailable(void *pObject, int iBufferSize);
+ static void BuffersDeinit(void *pObject);
+
+ static void QueueCreate(void *pObject, void **const ppQueue, const uint32 uiMaxLength, void (*pDestroyElement)(void *pElement));
+ static void QueueDestroy(void *pObject, void **const ppQueue);
+ static ErrorCode_e QueueEnqueue(void *pObject, void *const ppQueue, void *const pValue);
+ static void *QueueDequeue(void *pObject, void *const ppQueue);
+ static QueueCallback_fn QueueSetCallback(void *pObject, void *const pQueue, const QueueCallbackType_e Type, const QueueCallback_fn fnCallback, void *const pParam);
+ static boolean QueueIsEmpty(void *pObject, const void *const pQueue);
+ static boolean QueueIsMember(void *pObject, const void *const pQueue, void *pValue, boolean(*Match)(void *pValue1, void *pValue2));
+ static int QueueGetNrOfElements(void *pObject, const void *const pQueue);
+ static void RQueueCreate(void *pObject, void **const ppQueue, const uint32 uiMaxLength, void (*pDestroyElement)(void *pElement));
+ static void RQueueDestroy(void *pObject, void **const ppQueue);
+ static ErrorCode_e RQueueEnqueue(void *pObject, void *const pQueue, void *const pValue);
+ static void *RQueueDequeue(void *pObject, void *const pQueue);
+ static QueueCallback_fn RQueueSetCallback(void *pObject, void *const pQueue, const QueueCallbackType_e Type, const QueueCallback_fn fnCallback, void *const pParam);
+ static boolean RQueueIsEmpty(void *pObject, const void *const pQueue);
+ static boolean RQueueIsMember(void *pObject, const void *const pQueue, void *pValue, boolean(*Match)(void *pValue1, void *pValue2));
+ static int RQueueGetNrOfElements(void *pObject, const void *const pQueue);
+
+ //-----------------------------------------
+ // Command Execution Handler callbacks
+ //-----------------------------------------
+ static ErrorCode_e CEHCallbackFunction(void *pObject, CommandData_t *pCmdData);
+ static ErrorCode_e CEH_PROTROM_CallbackFunction(void *pObject, CommandData_t *pCmdData);
+ static ErrorCode_e CEH_Z_CallbackFunction(void *pObject, CommandData_t *pCmdData);
+ static ErrorCode_e CEH_A2_CallbackFunction(void *pObject, CommandData_t *pCmdData);
+
+ //-----------------------------------------
+ // Bulk Transfer Protocol callbacks
+ //-----------------------------------------
+ static void BulkCommandReqCallback(void *pObject, uint16 *puiSession, uint32 *puiChunkSize, uint64 *puiOffset, uint32 *puiLength, boolean bAckRead);
+ void Do_BulkCommandReqCallback(uint16 *puiSession, uint32 *puiChunkSize, uint64 *puiOffset, uint32 *puiLength);
+
+ static void BulkDataReqCallback(void *pObject, uint16 *puiSession, uint32 *puiChunkSize, uint64 *puiOffset, uint32 *puiLength, uint64 *puiTotalLength, uint32 *puiTransferedLength);
+ void Do_BulkDataReqCallback(uint16 *puiSession, uint32 *puiChunkSize, uint64 *puiOffset, uint32 *puiLength, uint64 *puiTotalLength, uint32 *puiTransferedLength);
+
+ static void BulkDataEndOfDumpCallback(void *pObject);
+ void Do_BulkDataEndOfDumpCallback();
+
+ int MapLcmError(int error);
+
+ void SignalError(int error);
+ void AddEvent(Event *event);
+
+ //-----------------------------------------
+ // Other callbacks
+ //-----------------------------------------
+ ProgressBarCallback_t m_ProgressBarUpdate;
+ void UpdateBulkProgress();
+ //-----------------------------------------
+
+private:
+ char *m_pchId;
+
+ static const char *const BULK_PATH;
+ uint64 m_uiBulkLength;
+ uint64 m_uiBulkTransferred;
+
+ CSemaphoreQueue m_EventQueue;
+ CCriticalSectionObject m_GetNextCodeCS;
+
+ CCriticalSectionObject m_SetTimeoutCS;
+ TLCDriverTimeouts m_Timeouts;
+
+ //-----------------------------------------
+ // String and vector copy functions.
+ //-----------------------------------------
+ template<class T, class U>
+ void CopyVectorToArray(const std::vector<T>& Source, U *pDestination, int *piSize);
+
+ void CopyStringToArray(std::string &Source, char *pDestination, int *piSize);
+
+ //-----------------------------------------
+ // Wait functions
+ //-----------------------------------------
+ int WaitForEvent(uint32 event, int Group = 0, int Command = 0);
+ int WaitForPROTROMResponseOrCancelOrTimeout(int iReceivePdu);
+
+ //-----------------------------------------
+ // State variables
+ //-----------------------------------------
+ Family_t m_CurrentProtocolFamily;
+ Do_CEH_Call_t m_CurrentCEHCallback;
+ int m_iBulkProtocolMode;
+
+ //-----------------------------------------
+ // General functions
+ //-----------------------------------------
+ int IsMainThreadAlive();
+};
+
+#endif // _LCDRIVERMETHODS_H_
diff --git a/source/LCDriverThread.cpp b/source/LCDriverThread.cpp
new file mode 100644
index 0000000..4b492ad
--- /dev/null
+++ b/source/LCDriverThread.cpp
@@ -0,0 +1,84 @@
+/*******************************************************************************
+*
+* File name: LCDriverThread.cpp
+* Language: Visual C++
+* Description: Main loop for LCDriver
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File LCDriverThread.cpp
+
+#include "LCDriverThread.h"
+#include "LCDriverMethods.h"
+#include "lcdriver_error_codes.h"
+#include "Event.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#endif
+
+CLCDriverThread::CLCDriverThread(CLCDriverMethods *lcdriverMethods):
+ lcdriverMethods_(lcdriverMethods),
+ timerOn_(false),
+ shutdown_(false)
+{
+}
+
+void CLCDriverThread::MainExecutionLoop()
+{
+ while (!shutdown_) {
+ // Limit the scope of the lock to avoid holding lock while sleeping. This
+ // solves the problem with starvation of other threads trying to lock LCMPollCS.
+ {
+ CLockCS lock(LCMPollCS);
+ lcdriverMethods_->m_pTimer->DoTimerHandler(timerOn_);
+
+ ErrorCode_e ReturnValue = lcdriverMethods_->m_pLcmInterface->CommunicationPoll();
+
+ if (E_SUCCESS != ReturnValue) {
+#ifdef _THREADDEBUG
+ lcdriverMethods_->m_pLogger->log("LCD MainThread: LCM polling ERROR = %d", ReturnValue);
+#endif
+
+ if (R15_FAMILY == lcdriverMethods_->m_CurrentProtocolFamily) {
+ lcdriverMethods_->SignalError(lcdriverMethods_->MapLcmError(ReturnValue));
+ IsDying = LCDRIVER_THREAD_STOPPED_AFTER_LCM_ERROR;
+ break;
+ }
+ }
+ }
+
+ OS::Sleep(1);
+ }
+}
+
+void CLCDriverThread::SignalDeath()
+{
+ CLockCS lock(LCMPollCS);
+ shutdown_ = true;
+}
+
+void CLCDriverThread::TimerOn()
+{
+ CLockCS lock(LCMPollCS);
+ timerOn_ = true;
+}
+
+void CLCDriverThread::TimerOff()
+{
+ CLockCS lock(LCMPollCS);
+ timerOn_ = false;
+}
+
+ErrorCode_e CLCDriverThread::SetLcmFamily(Family_t family, Do_CEH_Call_t CEHCallback)
+{
+ CLockCS lock(LCMPollCS);
+ return lcdriverMethods_->m_pLcmInterface->CommunicationSetFamily(family, CEHCallback);
+}
+
+// End of file LCDriverThread.cpp
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/LCDriverThread.h b/source/LCDriverThread.h
new file mode 100644
index 0000000..3bb2e73
--- /dev/null
+++ b/source/LCDriverThread.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+*
+* File name: LCDriverThread.h
+* Language: Visual C++
+* Description: Active Thread Object class declarations
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File LCDriverThread.h
+
+#ifndef _LCDRIVERTHREAD_H_
+#define _LCDRIVERTHREAD_H_
+
+#include "CaptiveThreadObject.h"
+#include "Timer.h"
+#include "Logger.h"
+#include "t_communication_service.h"
+
+class CLCDriverMethods;
+
+class CLCDriverThread: public CCaptiveThreadObject
+{
+public:
+ CLCDriverThread(CLCDriverMethods *lcdriverMethods);
+
+ void ResumeThread() {
+ Thread.ResumeThread();
+ }
+
+ ErrorCode_e SetLcmFamily(Family_t family, Do_CEH_Call_t CEHCallback);
+
+ void TimerOn();
+ void TimerOff();
+private:
+ void InitializeCaptiveThreadObject() {}
+ void MainExecutionLoop();
+ void SignalDeath();
+private:
+ CLCDriverMethods *lcdriverMethods_;
+
+ bool timerOn_;
+ bool shutdown_;
+
+ CCriticalSectionObject LCMPollCS;
+};
+
+#endif // _LCDRIVERTHREAD_H_
+
+// End of file LCDriverThread.h
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/LCM/Buffers.cpp b/source/LCM/Buffers.cpp
new file mode 100644
index 0000000..6e513bf
--- /dev/null
+++ b/source/LCM/Buffers.cpp
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+/*
+ * \addtogroup ldr_communication_buffer
+ * @{
+ */
+
+/***********************************************************************
+ * Includes
+ **********************************************************************/
+#include "Buffers.h"
+#include "lcdriver_error_codes.h"
+#include "t_r15_network_layer.h"
+#include "Error.h"
+#include <cstdlib>
+using namespace std;
+
+vector<TBulkFile *> Buffers::m_BulkFiles;
+CCriticalSectionObject Buffers::csBulkFiles;
+const uint32 Buffers::MAX_BUFFERS_COUNT = 32;
+
+#define MAX_BUFFER_SIZE BULK_BUFFER_SIZE
+
+TBulkVector::TBulkVector():
+ HeaderBuffer_p(NULL),
+ Data_p(NULL),
+ Offset(0),
+ Length(0),
+ ChunkSize(0)
+{
+}
+
+TBulkVector::~TBulkVector()
+{
+ delete[] HeaderBuffer_p;
+}
+
+TBulkFile::TBulkFile(): refCount(1)
+{
+ iAllSessionsCompleted = 0;
+ pMemMappedFile = 0;
+}
+
+TBulkFile::~TBulkFile()
+{
+ delete pMemMappedFile;
+
+ for (vector<TBulkVector *>::iterator i = bulkVectors.begin(); i != bulkVectors.end(); ++i) {
+ delete *i;
+ }
+}
+
+Buffers::Buffers():
+ buffersCount_(0),
+ logger_(0)
+{
+ m_BulkFile = 0;
+}
+
+Buffers::~Buffers()
+{
+ Deinit();
+}
+
+/***********************************************************************
+ * Definition of internal functions
+ **********************************************************************/
+ErrorCode_e Buffers::Init()
+{
+ return E_SUCCESS;
+}
+
+void *Buffers::Allocate(int Size)
+{
+ void *Buffer_p = 0;
+
+ if (buffersCount_ < MAX_BUFFERS_COUNT) {
+ Buffer_p = static_cast<uint8 *>(new uint8[Size]);
+ ++buffersCount_;
+#ifdef _BUFFERDEBUG
+ PrintF("Buffers: Allocate - Buffer 0x%p", Buffer_p);
+#endif
+ } else {
+#ifdef _BUFFERDEBUG
+ PrintF("Buffers: Allocate - Failed, Count %u", (void *)buffersCount_);
+#endif
+ }
+
+ return Buffer_p;
+}
+
+ErrorCode_e Buffers::Release(void *Buffer_p, int Size)
+{
+#ifdef _BUFFERDEBUG
+ PrintF("Buffers: Release - Buffer 0x%p", Buffer_p);
+#endif
+ delete[] static_cast<uint8 *>(Buffer_p);
+ --buffersCount_;
+ return E_SUCCESS;
+}
+
+uint32 Buffers::Available(int BufferSize)
+{
+#ifdef _BUFFERDEBUG
+ PrintF("Buffers: Available - Available %d", (void *)(MAX_BUFFERS_COUNT - buffersCount_));
+#endif
+ return MAX_BUFFERS_COUNT - buffersCount_;
+}
+
+void Buffers::Deinit()
+{
+#ifdef _BUFFERDEBUG
+
+ if (buffersCount_) {
+ PrintF("Buffers: Deinit - Buffers still allocated %d", (void *)buffersCount_);
+ }
+
+#endif
+}
+
+int Buffers::AllocateBulkFile(string strFile)
+{
+ CLockCS CsLock(csBulkFiles);
+
+ for (vector<TBulkFile *>::iterator i = m_BulkFiles.begin(); i != m_BulkFiles.end(); ++i) {
+ if (strFile.compare((*i)->strFileName) == 0) {
+ m_BulkFile = *i;
+ ++m_BulkFile->refCount;
+ return E_SUCCESS;
+ }
+ }
+
+ TBulkFile *newFile = new TBulkFile;
+ newFile->strFileName = strFile;
+
+ MemMappedFile *file = new MemMappedFile;
+#ifdef _BUFFERDEBUG
+ PrintF("Buffers: LoadFileData %s", (void *)strFile.c_str());
+#endif
+ int iReturn = file->LoadFileData(strFile.c_str());
+
+ if (iReturn) {
+ delete newFile;
+ delete file;
+ return iReturn;
+ }
+
+ newFile->pMemMappedFile = file;
+
+ m_BulkFiles.push_back(newFile);
+ m_BulkFile = newFile;
+
+ return E_SUCCESS;
+}
+
+uint64 Buffers::GetBulkFileLength()
+{
+ return m_BulkFile->pMemMappedFile->GetFileSize();
+}
+
+int Buffers::AllocateBulkVector(TL_BulkVectorList_t *BulkVector_p, uint32 iChunkSize, uint64 lOffset, uint32 iLength)
+{
+ CLockCS CsLock(m_BulkFile->csBulkVectors);
+ int ReturnValue = E_SUCCESS;
+
+ int HeaderBufferSize = HEADER_OFFSET_IN_BUFFER + ALIGNED_HEADER_LENGTH + ALIGNED_BULK_EXTENDED_HEADER_LENGTH;
+ int CurrentHeaderBufferSize = (BulkVector_p->Buffers) * HeaderBufferSize;
+
+ TBulkVector *currentVector = NULL;
+
+ //Check that flash buffers have been initialized.
+ VERIFY(0 != m_BulkFile, BUFFER_BULK_FILE_NOT_ALOCATED);
+
+ currentVector = new TBulkVector();
+ currentVector->HeaderBuffer_p = new uint8[CurrentHeaderBufferSize];
+ currentVector->Data_p = m_BulkFile->pMemMappedFile->AllocateFileData(lOffset, iLength);
+ currentVector->Offset = lOffset;
+ currentVector->Length = iLength;
+ currentVector->ChunkSize = iChunkSize;
+ m_BulkFile->bulkVectors.push_back(currentVector);
+ VERIFY(0 != currentVector->Data_p, m_BulkFile->pMemMappedFile->GetError());
+
+#ifdef _BUFFERDEBUG
+ PrintF("Buffers: AllocateFlashBuffers - Created new bulk vector 0x%p", (void *)currentVector);
+#endif
+
+ for (uint32 i = 0; i < BulkVector_p->Buffers; i++) {
+ uint8 *ChunkHeader_p = currentVector->HeaderBuffer_p + i * HeaderBufferSize;
+ uint8 *ChunkPayload_p = currentVector->Data_p + i * iChunkSize;
+
+ PacketMeta_t *Packet_p = BulkVector_p->Entries[i].Buffer_p;
+ Packet_p->Buffer_p = ChunkHeader_p;
+ Packet_p->ExtendedHeader_p = ChunkHeader_p + (uint64)Packet_p->ExtendedHeader_p;
+ Packet_p->Payload_p = ChunkPayload_p;
+
+ BulkVector_p->Entries[i].Payload_p = ChunkPayload_p;
+ }
+
+ErrorExit:
+
+ if ((0 != currentVector) && (0 == currentVector->Data_p)) {
+ m_BulkFile->bulkVectors.pop_back();
+ delete currentVector;
+ }
+
+ return ReturnValue;
+}
+
+void Buffers::ReleaseBulkVector(TL_BulkVectorList_t *BulkVector_p)
+{
+ CLockCS CsLock(m_BulkFile->csBulkVectors);
+
+ for (vector<TBulkVector *>::iterator i = m_BulkFile->bulkVectors.begin(); i != m_BulkFile->bulkVectors.end(); ++i) {
+ if (BulkVector_p->Offset == (*i)->Offset &&
+ BulkVector_p->Length == (*i)->Length &&
+ BulkVector_p->ChunkSize == (*i)->ChunkSize) {
+ m_BulkFile->pMemMappedFile->ReleaseFileData((*i)->Data_p, (*i)->Offset, (*i)->Length);
+ delete *i;
+ m_BulkFile->bulkVectors.erase(i);
+ break;
+ }
+ }
+}
+
+void Buffers::ReleaseAllBulkFiles()
+{
+ CLockCS CsLock(csBulkFiles);
+
+ for (vector<TBulkFile *>::iterator i = m_BulkFiles.begin(); i != m_BulkFiles.end(); ++i) {
+ delete *i;
+ }
+
+ m_BulkFiles.clear();
+}
+
+void Buffers::ReleaseBulkFile()
+{
+ CLockCS CsLock(csBulkFiles);
+
+ if (0 == m_BulkFile || --m_BulkFile->refCount > 0) {
+ return;
+ }
+
+ // remove bulk file from static list
+ for (vector<TBulkFile *>::iterator i = m_BulkFiles.begin(); i != m_BulkFiles.end(); ++i) {
+ if (m_BulkFile == *i) {
+ m_BulkFiles.erase(i);
+ break;
+ }
+ }
+
+ delete m_BulkFile;
+ m_BulkFile = 0;
+}
+
+void Buffers::PrintF(const char *text, void *pVoid)
+{
+ if (NULL != logger_) {
+ logger_->log(text, pVoid);
+ }
+}
diff --git a/source/LCM/Buffers.h b/source/LCM/Buffers.h
new file mode 100644
index 0000000..2a2f213
--- /dev/null
+++ b/source/LCM/Buffers.h
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _BUFFER_H_
+#define _BUFFER_H_
+
+#include "t_bulk_protocol.h"
+#include "MemMappedFile.h"
+#include "Queue.h"
+#include "Logger.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#endif
+
+#include <string>
+#include <vector>
+
+struct TBulkVector {
+ uint8 *HeaderBuffer_p;
+ uint8 *Data_p;
+ uint64 Offset;
+ uint32 Length;
+ uint32 ChunkSize;
+
+ TBulkVector();
+ ~TBulkVector();
+};
+
+struct TBulkFile {
+ TBulkFile();
+ ~TBulkFile();
+
+ std::string strFileName;
+ std::vector<TBulkVector *> bulkVectors;
+ size_t refCount;
+ int iAllSessionsCompleted;
+ MemMappedFile *pMemMappedFile;
+
+ CCriticalSectionObject csBulkVectors;
+};
+
+class Buffers
+{
+public:
+ Buffers();
+ ~Buffers();
+
+ void SetLogger(Logger *logger) {
+ logger_ = logger;
+ }
+private:
+ //Member variables for Bulk Flash.
+ static std::vector<TBulkFile *> m_BulkFiles;
+ static CCriticalSectionObject csBulkFiles;
+ TBulkFile *m_BulkFile;
+public:
+ ErrorCode_e Init();
+ void *Allocate(int Size);
+ ErrorCode_e Release(void *Buffer_p, int Size);
+ uint32 Available(int BufferSize);
+ void Deinit();
+
+ //Functions for Bulk Flash
+ int AllocateBulkFile(std::string strFile);
+ uint64 GetBulkFileLength();
+
+ int AllocateBulkVector(TL_BulkVectorList_t *BulkVector_p, uint32 iChunkSize, uint64 lOffset, uint32 iLength);
+ void ReleaseBulkVector(TL_BulkVectorList_t *BulkVector_p);
+
+ void ReleaseBulkFile();
+ static void ReleaseAllBulkFiles();
+private:
+ uint32 buffersCount_;
+ Logger *logger_;
+ static const uint32 MAX_BUFFERS_COUNT;
+ void PrintF(const char *text, void *pVoid);
+};
+
+#endif // _BUFFER_H_
diff --git a/source/LCM/Hash.cpp b/source/LCM/Hash.cpp
new file mode 100644
index 0000000..4f5962c
--- /dev/null
+++ b/source/LCM/Hash.cpp
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+/**
+ * \addtogroup ldr_security_algorithms
+ * @{
+ */
+
+/*************************************************************************
+* Includes
+*************************************************************************/
+#include "Hash.h"
+#include "SecurityAlgorithms.h"
+#include <cstdlib>
+#include <cstring>
+
+/***********************************************************************
+ * Declaration of file local functions
+ **********************************************************************/
+/***********************************************************************
+ * Definition of external functions
+ **********************************************************************/
+const uint32 red[16] = {
+ 0,
+ (0x1 << 16) ^(0x1021 << 0), \
+ (0x2 << 16) ^(0x1021 << 1), \
+ (0x3 << 16) ^(0x1021 << 1) ^(0x1021 << 0), \
+ (0x4 << 16) ^(0x1021 << 2), \
+ (0x5 << 16) ^(0x1021 << 2) ^(0x1021 << 0), \
+ (0x6 << 16) ^(0x1021 << 2) ^(0x1021 << 1), \
+ (0x7 << 16) ^(0x1021 << 2) ^(0x1021 << 1) ^(0x1021 << 0), \
+ (0x8 << 16) ^(0x1021 << 3), \
+ (0x9 << 16) ^(0x1021 << 3) ^(0x1021 << 0), \
+ (0xa << 16) ^(0x1021 << 3) ^(0x1021 << 1), \
+ (0xb << 16) ^(0x1021 << 3) ^(0x1021 << 1) ^(0x1021 << 0), \
+ (0xc << 16) ^(0x1021 << 3) ^(0x1021 << 2), \
+ (0xd << 16) ^(0x1021 << 3) ^(0x1021 << 2) ^(0x1021 << 0), \
+ (0xe << 16) ^(0x1021 << 3) ^(0x1021 << 2) ^(0x1021 << 1), \
+ (0xf << 16) ^(0x1021 << 3) ^(0x1021 << 2) ^(0x1021 << 1) ^(0x1021 << 0)
+};
+
+Hash::Hash()
+{
+ m_RequestQueue = new CSemaphoreQueue(16);
+ m_Thread = new CThreadWrapper(WorkerThread, this);
+ m_Thread->ResumeThread();
+}
+
+Hash::~Hash()
+{
+ m_RequestQueue->SignalEvent();
+ m_Thread->WaitToDie();
+ delete m_Thread;
+ delete m_RequestQueue;
+}
+
+/*
+ * Hash device shutdown.
+ *
+ * @param [in] Object_p Initialized buffer context.
+ * @param [in] HashDevice_pp Pointer to hash device descriptor.
+ *
+ * @return none.
+ */
+void Hash::Cancel(HashDevice_t **HashDevice_pp)
+{
+ delete *HashDevice_pp;
+}
+
+#ifdef _WIN32
+unsigned int WINAPI Hash::WorkerThread(void *arg)
+#else
+void *Hash::WorkerThread(void *arg)
+#endif
+{
+ Hash *pThis = (Hash *)arg;
+ HashRequest *request = 0;
+
+ while (true) {
+ RemoveResult result = pThis->m_RequestQueue->RemoveHead(reinterpret_cast<void **>(&request), INFINITE);
+
+ if (REMOVE_SUCCESS != result) {
+ break;
+ }
+
+ switch (request->Type) {
+ case HASH_SHA256:
+ memset(request->Hash_p, 0, SHA256_LENGTH);
+
+ if (request->Length != 0) {
+ SecurityAlgorithms::SHA256(request->Data_p, request->Length, request->Hash_p);
+ }
+
+ break;
+ case HASH_CRC16:
+ memset(request->Hash_p, 0, CRC16_LENGTH);
+
+ if (request->Length != 0) {
+ uint16 CRC16 = crc16(request->Data_p, request->Length, 0);
+ memcpy(request->Hash_p, &CRC16, sizeof(uint16));
+ }
+
+ break;
+ case HASH_SIMPLE_XOR:
+ request->Hash_p[0] = 0;
+
+ if (request->Length != 0) {
+ request->Hash_p[0] = hashxor(request->Data_p, request->Length);
+ }
+
+ break;
+ case HASH_NONE:
+ break;
+ default:
+ // unsupported hash type, nothing to do
+ delete request;
+ continue;
+ }
+
+ request->Callback(request->Data_p, request->Length, request->Hash_p, request->Param_p);
+
+ delete request;
+ }
+
+ return 0;
+}
+
+/**
+ * Asynchronous hashing of data.
+ *
+ * Calculates a hash over the specified block of data, calling the call-
+ * back function on completion. Note that the callback function might
+ * execute in interrupt context, so due care should be taken when
+ * writing it.
+ *
+ * The hashing might be delayed if another operation is currently
+ * running.
+ *
+ * @param [in] Object_p Initialized buffer context.
+ * @param [in] Type Hash type.
+ * @param [in] Data_p Start of the block of data to hash.
+ * @param [in] Length The length in bytes of the block of data to hash.
+ * @param [out] Hash_p Start of the buffer that should hold the hash
+ * value.
+ * @param [in] Callback The function to call when the hash calculation
+ * completes.
+ * @param [in,out] Param_p The value to use as parameter to Param_p.
+ *
+ * @note Hash_p must be large enough to contain the selected hash type.
+ * Use the "HASH"_LENGTH macros when you know beforehand which hash
+ * type to use, or Do_Crypto_GetHashLength() for dynamically selected
+ * hashes.
+ *
+ */
+void Hash::Calculate(HashType_e Type, void *Data_p, uint32 Length, uint8 *Hash_p, HashCallback_fn Callback, void *Param_p)
+{
+ HashRequest *currentRequest = new HashRequest;
+ currentRequest->Type = Type;
+ currentRequest->Data_p = (uint8 *)Data_p;
+ currentRequest->Length = Length;
+ currentRequest->Hash_p = Hash_p;
+ currentRequest->Callback = Callback;
+ currentRequest->Param_p = Param_p;
+
+ m_RequestQueue->AddTail(currentRequest);
+ /* coverity[leaked_storage] */
+}
+
+uint8 Hash::hashxor(const uint8 *Buf_p, uint32 Length)
+{
+ uint8 Value = 0;
+ const uint8 *Stop_p = Buf_p + Length;
+
+ do {
+ Value ^= *Buf_p++;
+ } while (Buf_p < Stop_p);
+
+ return Value;
+}
+
+uint16 Hash::crc16(const uint8 *p, int count, uint16 crc_in)
+{
+ register uint32 crc = crc_in;
+
+ while (--count >= 0) {
+ crc = crc ^(uint8) * p++ << 8;
+ crc ^= red[crc>>16];
+ crc = (crc << 4);
+ crc ^= red[crc>>16];
+ crc = (crc << 4);
+ crc ^= red[crc>>16];
+
+ }
+
+ return (uint16) crc;
+}
diff --git a/source/LCM/Hash.h b/source/LCM/Hash.h
new file mode 100644
index 0000000..e5e5343
--- /dev/null
+++ b/source/LCM/Hash.h
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _HASH_H_
+#define _HASH_H_
+
+#include "t_communication_service.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#endif
+
+struct HashRequest {
+ HashType_e Type;
+ uint8 *Data_p;
+ uint32 Length;
+ uint8 *Hash_p;
+ HashCallback_fn Callback;
+ void *Param_p;
+};
+
+class Hash
+{
+public:
+ Hash();
+ ~Hash();
+ void Cancel(HashDevice_t **HashDevice_pp);
+ void Calculate(HashType_e Type, void *Data_p, const uint32 Length, uint8 *Hash_p, HashCallback_fn Callback, void *Param_p);
+ uint32 GetLength(HashType_e Type);
+private:
+ CThreadWrapper *m_Thread;
+ CSemaphoreQueue *m_RequestQueue;
+
+#ifdef _WIN32
+ static unsigned int WINAPI WorkerThread(void *arg);
+#else
+ static void *WorkerThread(void *arg);
+#endif
+
+ static uint8 hashxor(const uint8 *Buf_p, uint32 Length);
+ static uint16 crc16(const uint8 *p, int count, uint16 crc_in);
+};
+
+#endif // _HASH_H_
diff --git a/source/LCM/Queue.cpp b/source/LCM/Queue.cpp
new file mode 100644
index 0000000..d2ef64e
--- /dev/null
+++ b/source/LCM/Queue.cpp
@@ -0,0 +1,291 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+/*
+ * @addtogroup ldr_utilities
+ * @{
+ * @addtogroup queue
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "Queue.h"
+#include "LCDriverMethods.h"
+#include <cstdlib>
+#include <cstring>
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+typedef struct Queue_s {
+ /* Head index of the buffer. This is where items are inserted.*/
+ uint32 Head;
+ /* Tail index of the buffer. This is where items are removed.*/
+ uint32 Tail;
+ /* Size of the buffer.*/
+ uint32 Size;
+ /* Buffer pointer.*/
+ void **Buffer_pp;
+ /* Empty buffer callback pointer. */
+ void (*EmptyCallback)(const void *const Queue_p, void *Param_p);
+ /* The parameter is used for the empty buffer transition callback.*/
+ void *EmptyParam_p;
+ /* NonEmpty buffer callback pointer. */
+ void (*NonEmptyCallback)(const void *const Queue_p, void *Param_p);
+ /* The parameter used for the non-empty buffer transition callback.*/
+ void *NonEmptyParam_p;
+ /* Pointer to a function for deallocating any resources that are reserved for
+ * the element. This function is provided as an input parameter when the queue
+ * is created.
+ */
+ void (*DestroyElement)(void *Value_p);
+} Queue_t;
+
+Queue::Queue(void)
+{
+ logger_ = NULL;
+}
+
+Queue::~Queue(void)
+{
+}
+
+/*******************************************************************************
+ * Definition of external functions
+ ******************************************************************************/
+void Queue::Create(void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *Element_p))
+{
+ Queue_t *Queue_p = new Queue_t;
+
+ if (Queue_p != 0) {
+ Queue_p->Size = MaxLength;
+ Queue_p->Head = 0;
+ Queue_p->Tail = 0;
+ Queue_p->Buffer_pp = new void*[MaxLength + 1];
+ Queue_p->DestroyElement = DestroyElement;
+ Queue_p->NonEmptyCallback = 0;
+ Queue_p->NonEmptyParam_p = 0;
+ Queue_p->EmptyCallback = 0;
+ Queue_p->EmptyParam_p = 0;
+
+ *Queue_pp = Queue_p;
+
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Create - Queue 0x%p", Queue_p);
+#endif
+ } else {
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Create - Not enough memory Queue 0x%p", 0);
+#endif
+ }
+}
+
+void Queue::Destroy(void **const Queue_pp)
+{
+ Queue_t *Queue_p = (Queue_t *) * Queue_pp;
+ void *Object_p = 0;
+
+ if (NULL != Queue_p->DestroyElement) {
+ Object_p = Dequeue(Queue_p);
+
+ while (0 != Object_p) {
+ Queue_p->DestroyElement(Object_p);
+ Object_p = Dequeue(Queue_p);
+ }
+ }
+
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Destroy - Queue 0x%p", Queue_p);
+#endif
+
+ delete[] Queue_p->Buffer_pp;
+ delete Queue_p;
+ *Queue_pp = NULL;
+}
+
+ErrorCode_e Queue::Enqueue(void *const Queue_p, void *const Object_p)
+{
+ Queue_t *TempQueue_p = (Queue_t *)Queue_p;
+ uint32 Head = (TempQueue_p->Head + 1) % TempQueue_p->Size;
+ boolean NonEmptyCall = (TempQueue_p->Head == TempQueue_p->Tail);
+
+ if (Head != TempQueue_p->Tail) {
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Enqueue - Queue 0x%p", Queue_p);
+ PrintF("Queue: Enqueue - Object 0x%p", Object_p);
+#endif
+ TempQueue_p->Buffer_pp[Head] = Object_p;
+ TempQueue_p->Head = Head;
+
+ if (Head == TempQueue_p->Tail) {
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Enqueue - return E_FAILED_TO_STORE_IN_FIFO, Object 0x%p", Object_p);
+#endif
+ return E_FAILED_TO_STORE_IN_FIFO;
+ }
+
+ if (NonEmptyCall && NULL != TempQueue_p->NonEmptyCallback) {
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Enqueue - Executing NonEmptyCallback Queue 0x%p", Queue_p);
+#endif
+ TempQueue_p->NonEmptyCallback(TempQueue_p, TempQueue_p->NonEmptyParam_p);
+ }
+
+ return E_SUCCESS;
+ } else {
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Enqueue - return E_FAILED_TO_STORE_IN_FIFO, Object 0x%p", Object_p);
+#endif
+ return E_FAILED_TO_STORE_IN_FIFO;
+ }
+}
+
+void *Queue::Dequeue(void *const Queue_p)
+{
+ Queue_t *TempQueue_p = (Queue_t *)Queue_p;
+ uint32 Tail = TempQueue_p->Tail;
+ void *Object_p = NULL;
+
+ if (Tail != TempQueue_p->Head) {
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Dequeue - Queue 0x%p", Queue_p);
+#endif
+ Tail = (Tail + 1) % TempQueue_p->Size;
+ Object_p = TempQueue_p->Buffer_pp[Tail];
+ TempQueue_p->Tail = Tail;
+
+ if (Tail == TempQueue_p->Head && NULL != TempQueue_p->EmptyCallback) {
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Dequeue - Executing EmptyCallback Queue 0x%p", Queue_p);
+#endif
+ TempQueue_p->EmptyCallback(TempQueue_p, TempQueue_p->EmptyParam_p);
+ }
+
+#ifdef _QUEUEDEBUG
+ PrintF("Queue: Dequeue - Object 0x%p", Object_p);
+#endif
+ }
+
+ return Object_p;
+}
+
+QueueCallback_fn Queue::SetCallback(void *const Queue_p,
+ const QueueCallbackType_e Type,
+ const QueueCallback_fn Callback,
+ void *const Param_p)
+{
+ Queue_t *TempQueue_p = (Queue_t *)Queue_p;
+ QueueCallback_fn OldCallback;
+
+ if (Type == QUEUE_EMPTY) {
+ OldCallback = TempQueue_p->EmptyCallback;
+ TempQueue_p->EmptyCallback = Callback;
+ TempQueue_p->EmptyParam_p = Param_p;
+ } else {
+ OldCallback = TempQueue_p->NonEmptyCallback;
+ TempQueue_p->NonEmptyCallback = Callback;
+ TempQueue_p->NonEmptyParam_p = Param_p;
+ }
+
+ return OldCallback;
+}
+
+boolean Queue::IsEmpty(const void *const Queue_p)
+{
+ Queue_t *TempQueue_p = (Queue_t *)Queue_p;
+
+ if (TempQueue_p->Tail == TempQueue_p->Head) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+boolean Queue::IsMember(const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p))
+{
+ Queue_t *TempQueue_p = (Queue_t *)Queue_p;
+
+ for (size_t i = TempQueue_p->Head; i < TempQueue_p->Tail; i++) {
+ if (Match(Value_p, TempQueue_p->Buffer_pp[i])) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+int Queue::GetNrOfElements(const void *const Queue_p)
+{
+ Queue_t *TempQueue_p = (Queue_t *)Queue_p;
+ int Return = 0;
+
+ if (TempQueue_p->Head >= TempQueue_p->Tail) {
+ Return = TempQueue_p->Head - TempQueue_p->Tail;
+ } else {
+ Return = TempQueue_p->Size - (TempQueue_p->Tail - TempQueue_p->Head);
+ }
+
+ return Return;
+}
+
+void Queue::RCreate(void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *))
+{
+ CLockCS QueueLock(QueueCSO);
+ Create(Queue_pp, MaxLength, DestroyElement);
+}
+
+void Queue::RDestroy(void **const Queue_pp)
+{
+ CLockCS QueueLock(QueueCSO);
+ Destroy(Queue_pp);
+}
+
+ErrorCode_e Queue::REnqueue(void *const Queue_p, void *const Value_p)
+{
+ CLockCS QueueLock(QueueCSO);
+ return Enqueue(Queue_p, Value_p);
+}
+
+void *Queue::RDequeue(void *const Queue_p)
+{
+ CLockCS QueueLock(QueueCSO);
+ return Dequeue(Queue_p);
+}
+
+QueueCallback_fn Queue::RSetCallback(void *const Queue_p,
+ const QueueCallbackType_e Type,
+ const QueueCallback_fn Callback,
+ void *const Param_p)
+{
+ CLockCS QueueLock(QueueCSO);
+ return SetCallback(Queue_p, Type, Callback, Param_p);
+}
+
+boolean Queue::RIsEmpty(const void *const Queue_p)
+{
+ CLockCS QueueLock(QueueCSO);
+ return IsEmpty(Queue_p);
+}
+
+boolean Queue::RIsMember(const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p))
+{
+ CLockCS QueueLock(QueueCSO);
+ return IsMember(Queue_p, Value_p, Match);
+}
+
+int Queue::RGetNrOfElements(const void *const Queue_p)
+{
+ CLockCS QueueLock(QueueCSO);
+ return GetNrOfElements(Queue_p);
+}
+
+void Queue::PrintF(const char *text, void *pVoid)
+{
+ if (NULL != logger_) {
+ logger_->log(text, pVoid);
+ }
+}
diff --git a/source/LCM/Queue.h b/source/LCM/Queue.h
new file mode 100644
index 0000000..838fc05
--- /dev/null
+++ b/source/LCM/Queue.h
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _QUEUE_H_
+#define _QUEUE_H_
+
+#include "t_queue.h"
+#include "error_codes.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include <stdio.h>
+#include "LinuxApiWrappers.h"
+#endif
+#include "Logger.h"
+
+class Queue
+{
+public:
+ Queue(void);
+ ~Queue(void);
+
+ void Create(void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *Element_p));
+ void Destroy(void **const Queue_pp);
+ ErrorCode_e Enqueue(void *const Queue_p, void *const Value_p);
+ void *Dequeue(void *const Queue_p);
+ QueueCallback_fn SetCallback(void *const Queue_p, const QueueCallbackType_e Type, const QueueCallback_fn Callback, void *const Param_p);
+ boolean IsEmpty(const void *const Queue_p);
+ boolean IsMember(const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p));
+ int GetNrOfElements(const void *const Queue_p);
+
+ //Reentrant
+ void RCreate(void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *Element_p));
+ void RDestroy(void **const Queue_pp);
+ ErrorCode_e REnqueue(void *const Queue_p, void *const Value_p);
+ void *RDequeue(void *const Queue_p);
+ QueueCallback_fn RSetCallback(void *const Queue_p, const QueueCallbackType_e Type, const QueueCallback_fn Callback, void *const Param_p);
+ boolean RIsEmpty(const void *const Queue_p);
+ boolean RIsMember(const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p));
+ int RGetNrOfElements(const void *const Queue_p);
+
+ void SetLogger(Logger *logger) {
+ logger_ = logger;
+ }
+private:
+ CCriticalSectionObject QueueCSO;
+ Logger *logger_;
+ void PrintF(const char *text, void *pVoid);
+};
+
+#endif // _QUEUE_H_
diff --git a/source/LCM/Timer.cpp b/source/LCM/Timer.cpp
new file mode 100644
index 0000000..8dd19e4
--- /dev/null
+++ b/source/LCM/Timer.cpp
@@ -0,0 +1,267 @@
+/***********************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ **********************************************************************/
+
+/*************************************************************************
+* Includes
+*************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+#include "Timer.h"
+#include "LCDriverMethods.h"
+
+
+/***********************************************************************
+ * Declaration of file local functions
+ **********************************************************************/
+/* Constructor */
+Timer::Timer(void):
+ systemTime_(0),
+ logger_(0)
+{
+ timers_.Timers_p = NULL;
+ timers_.ActiveTimers = 0;
+ timers_.MaxTimers = 0;
+}
+
+/* Destructor */
+Timer::~Timer(void)
+{
+ delete[] timers_.Timers_p;
+}
+/***********************************************************************
+ * Definition of external functions
+ **********************************************************************/
+
+/*
+ * Initialization of the Timers handler.
+ *
+ * @param [in] Timers Numbers of defined timers.
+ *
+ * @retval E_SUCCESS After successful execution.
+ * @retval E_INVALID_INPUT_PARAMETERS If no timer s for initialization.
+ */
+ErrorCode_e Timer::Init(uint32 Timers)
+{
+ /* Check input parameters. */
+ if (0 == Timers) {
+ /* Invalid input parameters! */
+ return E_INVALID_INPUT_PARAMETERS;
+ }
+
+ /* Allocate memory space for timers */
+ timers_.Timers_p = new Timer_t[Timers];
+
+ if (timers_.Timers_p == NULL) {
+ /* Error allocation Timers buffer! */
+ return E_ALLOCATE_FAILED;
+ }
+
+ /* Clear Timers buffer */
+ memset(timers_.Timers_p, 0x00, Timers * sizeof(Timer_t));
+
+ /* Inicialize numbers of defined and activated timers */
+ timers_.MaxTimers = Timers;
+ timers_.ActiveTimers = 0;
+
+ return E_SUCCESS;
+}
+
+/*
+ * Reserve new timer.
+ *
+ * @param [in] Timer_p pointer to the timer data.
+ *
+ * @return Index of reserved timer.
+ * @return Index 0 if no free timers.
+ */
+uint32 Timer::Get(Timer_t *Timer_p)
+{
+ uint32 TimerKey = 0;
+
+ /* Check input parameters */
+ if (0 == Timer_p->Time || NULL == Timer_p->HandleFunction_p) {
+ goto ErrorExit;
+ }
+
+ /* Find free timer */
+ TimerKey = FindFreeTimer();
+
+ if (0 == TimerKey) {
+ goto ErrorExit; // no free timers
+ }
+
+ timers_.ActiveTimers++;
+
+ timers_.Timers_p[TimerKey - 1] = *Timer_p;
+
+#ifdef _TIMERDEBUG
+ logger_->log("Timer: Get - Timer 0x%p", &timers_.Timers_p[TimerKey - 1]);
+#endif
+
+ErrorExit:
+ return TimerKey;
+}
+
+/*
+ * Release reserved timer.
+ *
+ * @param [in] TimerKey Index of reserved timer.
+ *
+ * @retval E_SUCCESS After successful execution.
+ * @retval E_INVALID_INPUT_PARAMETERS If one of the input.
+ * @retval E_NONEXIST_TIMER non exist timer.
+ */
+ErrorCode_e Timer::Release(uint32 TimerKey)
+{
+ ErrorCode_e ReturnValue = E_INVALID_INPUT_PARAMETERS;
+ Timer_t *TimerData_p = NULL;
+
+ /* check input parameters */
+ if ((0 == TimerKey) || (timers_.MaxTimers < TimerKey)) {
+ goto ErrorExit;
+ }
+
+ TimerData_p = &timers_.Timers_p[TimerKey - 1];
+
+ if (NULL != TimerData_p->HandleFunction_p) {
+ /* clear timer data */
+ TimerData_p->Time = 0;
+ TimerData_p->HandleFunction_p = NULL;
+
+ /* first check number of active timers */
+ if (0 < timers_.ActiveTimers) {
+ /* remove timer from active timer counter */
+ timers_.ActiveTimers--;
+ }
+
+ ReturnValue = E_SUCCESS;
+
+#ifdef _TIMERDEBUG
+ logger_->log("Timer: Release - Timer 0x%p", (void *)TimerData_p);
+#endif
+ } else {
+ ReturnValue = E_NONEXIST_TIMER;
+ }
+
+ErrorExit:
+ return ReturnValue;
+}
+
+/*
+ * Read the current time of timer.
+ *
+ * @param [in] TimerKey Index of reserved timer.
+ *
+ * @return Current time of the timer.
+ */
+uint32 Timer::ReadTime(uint32 TimerKey)
+{
+ uint32 Time = 0;
+
+ if (TimerKey == 0 || TimerKey > timers_.MaxTimers) {
+ return Time;
+ }
+
+ Timer_t *TimerData_p = &timers_.Timers_p[TimerKey - 1];
+
+ if (NULL != TimerData_p->HandleFunction_p) {
+ /* get timer data */
+ Time = TimerData_p->Time;
+ }
+
+ return Time;
+}
+
+/*
+ * Get current system time.
+ *
+ * @return System Time.
+ */
+uint32 Timer::GetSystemTime()
+{
+ return static_cast<uint32>(systemTime_);
+}
+
+
+/*
+ * The timer handler method which is polled in the main execution thread.
+ * Checks if there is a timer which time has elapsed and calls its callback,
+ * handle the timers time decrementation.
+ *
+ * @param [in] IsTimerOn Determinates if the timers are active to be handled.
+ *
+ * @return Function doesn't return value.
+ */
+void Timer::DoTimerHandler(bool IsTimerOn)
+{
+ uint32 SearchTimerKey = 0;
+ uint32 TimeIncrement = GetIncrement();
+
+ while (timers_.ActiveTimers > 0 && SearchTimerKey < timers_.MaxTimers) {
+ /* get Timer(SearchTimerKey) data */
+ Timer_t *TimerData_p = &timers_.Timers_p[SearchTimerKey];
+
+ if (NULL != TimerData_p->HandleFunction_p) {
+ /* decrement Time */
+ if (IsTimerOn) {
+ TimerData_p->Time -= min(TimerData_p->Time, TimeIncrement);
+ }
+
+ /* check for elapsed time */
+ if (TimerData_p->Time == 0) {
+#ifdef _TIMERDEBUG
+ logger_->log("Timer: DoTimerHandler - callback handle function Timer 0x%p", TimerData_p);
+#endif
+ TimerData_p->HandleFunction_p(TimerData_p->Param_p, TimerData_p, TimerData_p->Data_p);
+
+ /* Check for periodicals of timer */
+ if (TimerData_p->PeriodicalTime != 0) {
+ /* Set again Timer with periodical time */
+ TimerData_p->Time = TimerData_p->PeriodicalTime;
+ } else {
+ /* release current timer */
+ Release(SearchTimerKey + 1);
+ }
+ }
+ }
+
+ /* next timer for check */
+ SearchTimerKey++;
+ }
+}
+
+/*
+ * Get the difference in time from the last call.
+ *
+ * @return increment the duration of time which should be
+ * substracted from the timers.
+ */
+uint32 Timer::GetIncrement()
+{
+ time_t now = OS::GetSystemTimeInMs();
+ time_t increment = now - systemTime_;
+ systemTime_ = now;
+ return static_cast<uint32>(increment);
+}
+
+/*
+ * Find free timer.
+ *
+ * @retval Timer index if free timer exist.
+ * @retval 0 if no free timer.
+ */
+uint32 Timer::FindFreeTimer()
+{
+ uint32 TimerKey = 0;
+
+ for (size_t i = 0; i != timers_.MaxTimers; ++i) {
+ if (timers_.Timers_p[i].HandleFunction_p == NULL) {
+ TimerKey = i + 1;
+ break;
+ }
+ }
+
+ return TimerKey;
+}
diff --git a/source/LCM/Timer.h b/source/LCM/Timer.h
new file mode 100644
index 0000000..2b395b6
--- /dev/null
+++ b/source/LCM/Timer.h
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+#include "error_codes.h"
+#include "t_time_utilities.h"
+#include "Logger.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#endif
+#include <ctime>
+
+class Timer
+{
+public:
+ Timer();
+ /*
+ * Initialization of the Timers handler.
+ *
+ * @param [in] Timers Numbers of defined timers.
+ *
+ * @retval E_SUCCESS After successful execution.
+ * @retval E_INVALID_INPUT_PARAMETERS If no timer s for initialization.
+ */
+ ErrorCode_e Init(uint32 Timers);
+
+ /*
+ * Reserve new timer.
+ *
+ * @param [in] Timer_p pointer to the timer data.
+ *
+ * @return Index of reserved timer.
+ * @return Index 0 if no free timers.
+ */
+ uint32 Get(Timer_t *Timer_p);
+
+ /*
+ * Release reserved timer.
+ *
+ * @param [in] TimerKey Index of reserved timer.
+ *
+ * @retval E_SUCCESS After successful execution.
+ * @retval E_INVALID_INPUT_PARAMETERS If one of the input.
+ * @retval E_NONEXIST_TIMER non exist timer.
+ */
+ ErrorCode_e Release(uint32 TimerKey);
+
+ /*
+ * Read the current time of timer.
+ *
+ * @param [in] TimerKey Index of reserved timer.
+ *
+ * @return Current time of the timer.
+ */
+ uint32 ReadTime(uint32 TimerKey);
+
+ /**
+ * Get current system time.
+ *
+ * @return System Time.
+ */
+ uint32 GetSystemTime(void);
+
+ /*
+ * The timer handler method which is polled in the main execution thread.
+ * Checks if there is a timer which time has elapsed and calls its callback,
+ * handle the timers time decrementation.
+ *
+ * @param [in] IsTimerOn Determinates if the timers are active to be handled.
+ *
+ * @return Function doesn't return value.
+ */
+ void DoTimerHandler(bool IsTimerOn);
+
+public:
+ ~Timer(void);
+ void SetLogger(Logger *logger) {
+ logger_ = logger;
+ }
+
+private:
+ TimerHeader_t timers_;
+ time_t systemTime_;
+
+ Logger *logger_;
+
+ uint32 GetIncrement();
+ uint32 FindFreeTimer();
+};
+
+#endif // _TIMER_H_
diff --git a/source/LCM/include/c_compiler.h b/source/LCM/include/c_compiler.h
new file mode 100644
index 0000000..77cd673
--- /dev/null
+++ b/source/LCM/include/c_compiler.h
@@ -0,0 +1,127 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+#ifndef _C_COMPILER_H
+#define _C_COMPILER_H
+
+/*************************************************************************
+*
+* HEADER SPECIFICATION
+*
+* $Workfile: c_compiler.h $
+*
+**************************************************************************
+*
+* DESCRIPTION:
+*
+* This file contains macros that determines current compiler
+*
+*
+**************************************************************************
+*
+* REVISION HISTORY:
+*
+* $Log: \KIRND_FuncBlocks_Utilities_003\cnh1606432\dependencies\Utils\c_compiler.h $
+ *
+ * Version: ...\cnh1606432\cnh1606432_r1\7 18 Nov 2009 10:18 (GMT) qsjomik
+ * Overwrite merge.
+ * Compiled with _INTERCEPTCALLBACKS pre-compiler directive.
+ * Stability, Multi-Dut and storing BufferVector updates.
+ * Updated for LCM R1B.
+ * R1A027.
+ *
+ * Version: ...\cnh160692_r1a_dev\3 12 Mar 2002 14:21 (GMT) QCSSTZI
+ * rename p_compiler to c_compiler.
+ *
+ * Version: ...\cnh160692_r1a_dev\2 10 Jan 2002 12:35 (GMT) QCSSTZI
+ * Updated to reflect R4A013 on the old module (cnh1010024)
+ *
+ * Version: ...\cnh1010024_r4a_dev\1 11 Sep 2001 07:34 (GMT) QCSPAAB
+ * Merge to Valentina (R4)
+ *
+ * Version: ...\cnh1010024\1 14 Nov 2000 15:30 (GMT) ECSJENE
+ * Merge to start new dev-branch for the Mia project.
+ *
+ * Version: ...\cnh1010024_r2a_dev\4 05 Oct 2000 06:25 (GMT) ECSSTMA
+ * Macro to remove non_banked directive.
+ *
+ * Version: ...\cnh1010024_r2a_dev\3 19 Sep 2000 12:38 (GMT) QCSLAIS
+ * Compiler warnings work around.
+ *
+ * Version: ...\cnh1010024_r2a_dev\2 22 May 2000 08:25 (GMT) ECSSTMA
+ * Accept LINT as being one among the compilers.
+ *
+ * Version: ...\cnh1010024_r2a_dev\1 16 May 2000 12:19 (GMT) QCSLAIS
+ * Created file compiler.h which determines current compiler and target
+*
+**************************************************************************/
+
+#if defined(__IAR_SYSTEMS_ICC) || defined(__IAR_SYSTEMS_ICC__)
+/* COMPILER IS FROM IAR */
+#if ((__TID__ >> 8) & 0x7f) == 23
+/* TARGET IS Z80 */
+#define COMPILER_IAR_Z80
+#elif ((__TID__ >> 8) & 0x7f) == 90
+/* TARGET IS AVR */
+#define COMPILER_IAR_AVR /* Preferred */
+#define COMPILER_AVR
+#define AT90S
+#elif ((__TID__ >> 8) & 0x7f) == 0x4f
+/* TARGET IS ARM */
+#define COMPILER_IAR_ARM /* Preferred */
+#define COMPILER_ARM
+#define ARM
+#else
+#error Unknown IAR compiler
+#endif
+#elif defined(_WIN32)
+/* TARGET IS Win32 */
+#define COMPILER_MSDEV
+#define __arm
+#define __pcs
+#define __no_init
+#elif defined(__arm)
+/* TARGET IS ARM */
+#define COMPILER_ARM_ARM /* Preferred */
+#define COMPILER_ARM
+#define ARM
+#elif defined(__IAR_SYSTEMS_ASM__)
+#elif defined(_lint)
+#elif defined(__GNUC__)
+#define COMPILER_GNUC
+#else
+#error Unknown compiler
+#endif
+
+/*
+ * Some compiler bug work arounds.
+ */
+
+/*
+ * Avoid ARM compiler error when comparing NULL with a pointer
+ * by defining NULL as NULL pointer.
+ */
+#if defined(COMPILER_ARM_ARM) && !defined(NULL)
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+#endif
+
+/*
+ * Some modules still use the unused banked prefix.
+ */
+#ifndef banked
+#define banked
+#endif
+
+#ifndef non_banked
+#define non_banked
+#endif
+
+#endif // _C_COMPILER_H
diff --git a/source/LCM/include/c_system.h b/source/LCM/include/c_system.h
new file mode 100644
index 0000000..0b058ec
--- /dev/null
+++ b/source/LCM/include/c_system.h
@@ -0,0 +1,34 @@
+#ifndef INCLUSION_GUARD_C_SYSTEM_H
+#define INCLUSION_GUARD_C_SYSTEM_H
+
+/*************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+**************************************************************************
+*
+* DESCRIPTION:
+*
+* System configuration include file. This file must be the first
+* file included by every source (*.c) file in the system
+*
+*************************************************************************/
+
+/*************************************************************************
+* Includes
+*************************************************************************/
+
+#include "c_compiler.h"
+
+//#include "product.h"
+
+/*************************************************************************
+* Types, constants and external variables
+*************************************************************************/
+
+
+
+#endif // INCLUSION_GUARD_C_SYSTEM_H
+
+
+
+
diff --git a/source/LCM/include/error_codes.h b/source/LCM/include/error_codes.h
new file mode 100644
index 0000000..e71d4b4
--- /dev/null
+++ b/source/LCM/include/error_codes.h
@@ -0,0 +1,740 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _ERRORCODE_H
+#define _ERRORCODE_H
+
+
+/**
+ * @addtogroup ldr_LCM
+ * Error codes for internal loader commands.
+ * @{
+ */
+
+/*************************************************************************
+* Includes
+*************************************************************************/
+#include "t_basicdefinitions.h"
+
+#define A2_ERROR_CODES_OFFSET 5000
+/**
+ * Internal loader command error codes. Possible range 0x0000 - 0x0FFE (4094).
+ */
+
+
+/**
+ * Table for Error groups range
+ *
+ * General Fatal 0-50
+ * General non-fatal 51-99
+ *
+ * IO Fatal 100-150
+ * IO non-fatal 151-199
+ *
+ * Communication Fatal 200-250
+ * Communication non-fatal 251-299
+ *
+ * Signature Fatal 300-350
+ * Signature non-fatal 351-399
+ *
+ * Authentication Fatal 400-450
+ * Authentication non-fatal 451-499
+ *
+ * COPS General Fatal 500-550
+ * COPS General non-fatal 551-599
+ *
+ * System Fatal 600-650
+ * System non-fatal 651-699
+ *
+ * Flash Fatal 700-750
+ * Flash non-fatal 751-799
+ *
+ * Parameters Fatal 800-850
+ * Parameters non-fatal 851-899
+ *
+ * File management Fatal 900-950
+ * File management non-fatal 951-999
+ *
+ * Command Auditing and execution Fatal 1000-1050
+ * Command Auditing and execution non-fatal 1051-1099
+ *
+ * Emulation Fatal 1100-1150
+ * Emulation non-fatal 1151-1199
+ *
+ * Timers Fatal 1200-1250
+ * Timers non-fatal 1251-1299
+ *
+ * CABS Fatal 1300-1350
+ * CABS non-fatal 1351-1399
+ *
+ * GDFS Fatal 1400-1450
+ * GDFS non-fatal 1451-1499
+ *
+ * Antirollback Fatal 1500-1550
+ * Antirollback non-fatal 1551-1599
+ *
+ * Memory and Boot Fatal 1600-1650
+ * Memory and Boot non-fatal 1651-1699
+ *
+ * @todo this should be removed and error codes should be remaped.
+ * The same applies to Emulator errors.
+ *
+ * Job Handler Fatal 1700-1750
+ * Job Handler non-fatal 1751-1799
+ *
+ * Emulator Fatal 1800-1850
+ * Emulator non-fatal 1851-1899
+ *
+ * Loader utilities Fatal 1900-1950
+ * Loader utilities non-fatal 1951-1999
+ */
+
+
+typedef enum {
+ E_SUCCESS = 0, /**< Operation successful. */
+ E_GENERAL_FATAL_ERROR = 1, /**< General Failure. */
+ E_ALLOCATE_FAILED = 2, /**< Failed to allocate memory. */
+ E_INVALID_INPUT_PARAMETERS = 51, /**< The expected value into the function was incorrect. */
+ E_INVALID_CURRDATE_STRING_LENGTH = 52, /**< Indicate that the currdate string array variable has invalid length. */
+ E_UNALIGNED_DATA = 53, /**< Indicate that a variable is not aligned. */
+ E_VECTOR_CREATE_FAIL = 100, /**< Failed to create vector in IO Layer. */
+ E_VECTOR_DESTROY_FAIL = 101, /**< Failed to destroy vector in IO Layer. */
+ E_GENERAL_IO_ERROR = 151, /**< Unknown IO error. */
+ E_IO_FAILED_TO_READ = 152, /**< IO failed to read from source. */
+ E_IO_FAILED_TO_WRITE = 153, /**< IO failed to write to destination. */
+ E_IO_FAILED_TO_CLOSE = 154, /**< IO failed to close media. */
+ E_IO_FAILED_TO_OPEN = 155, /**< IO failed to open media. */
+ E_IO_FAILED_TO_GET_LENGTH = 156, /**< IO failed to get length of media. */
+ E_GENERAL_COMMUNICATION_ERROR = 200, /**< General communication error. */
+ E_FAILED_TO_START_BULK_SESSION = 201, /**< Failed to start bulk session. */
+ E_FAILED_TO_CLOSE_BULK_SESSION = 202, /**< Failed to initialize the transport layer. */
+ E_FAILED_TO_FIND_CHUNK_DATA_BLOCK = 203, /**< Failed to find chunk data block. */
+ E_FAILED_TO_INIT_COM_DEVICE = 204, /**< Failed to reinitialize communication device. */
+ E_FAILED_TO_USE_COM_DEVICE = 205, /**< Failed to use communication device. */
+ E_FAILED_TO_ALLOCATE_COMM_BUFFER = 206, /**< Failed to allocate communication buffer. */
+ E_FAILED_TO_FLUSH_RXFIFO = 207, /**< Failed to flush RX FIFO. */
+ E_RETRANSMITION_FAILED = 208, /**< Retransmission failed. After MAX_RESENDS attempt, failed to send packet. */
+ E_COMMAND_NO_ERROR = 209, /**< */
+ E_FAILED_TO_RELEASE_COMM_BUFFER = 210, /**< Failed to release communication buffer. */
+ E_FAILED_TO_INTIALIZE_TIMER_FUNCTIONS = 211, /**< Failed to initialize timer functions. */
+ E_FAILED_TO_INTIALIZE_QUEUE_FUNCTIONS = 212, /**< Failed to initialize queue functions. */
+ E_INVALID_BULK_MODE = 251, /**< Invalid bulk mode. */
+ E_FAILED_TO_FIND_COMM_BUFFER = 252, /**< Failed to find communication buffer. */
+ E_INVALID_TYPE_OF_BUFFER = 253, /**< Invalid type of buffer. */
+ E_COM_DEVICE_BUSY = 254, /**< */
+ E_NOT_FOUND_ELEMENT_IN_RETRANSMISSION_LIST = 255, /**< The element in retransmission list is not found. */
+ E_FAILED_READING_FROM_BULK = 256, /**< Failed to read from bulk. */
+ E_FAILED_WRITING_TO_BULK = 257, /**< Failed to write to bulk. */
+ E_FAILED_TO_GET_UART_DESCRIPTOR = 258, /**< Failed to get UART descriptor. */
+ E_FAILED_TO_GET_USB_DESCRIPTOR = 259, /**< Failed to get USB descriptor. */
+ E_INVALID_BULK_SESSION_ID = 260, /**< Invalid bulk session ID is used. */
+ E_PREVIOUS_BULK_SESSION_IS_NOT_CLOSED = 261, /**< Previous bulk session not closed. */
+ E_INVALID_BULK_PROTOCOL_STATE = 262, /**< Invalid bulk protocol state. */
+ E_UNKNWON_PROPERTY = 351, /**< Unknown property id. */
+ E_CYCLIC_GRAPH = 451, /**< Cyclic graph in services detected. */
+ E_SERVICE_NOT_SUPPORTED = 452, /**< The service is not supported. */
+ E_INCONSISTENCY_IN_SERVICES = 453, /**< Inconsistency in services is detected. */
+ E_SERVICE_IN_USE = 454, /**< The service is in use and can't be stopped. */
+ E_UNREGISTER_BDM_SERVICE_FAILED = 455, /**< Unregistering of Block Device Manager Service failed. */
+ E_UNREGISTER_BAM_SERVICE_FAILED = 456, /**< Unregistering of Boot Area Manager Service failed. */
+ E_UNREGISTER_COPS_SERVICE_FAILED = 457, /**< Unregistering of COPS Data Manager Service failed. */
+ E_UNREGISTER_FS_SERVICE_FAILED = 458, /**< Unregistering of File System Manager Service failed. */
+ E_UNREGISTER_FPD_SERVICE_FAILED = 459, /**< Unregistering of Flash Physical Driver Service failed. */
+ E_UNREGISTER_GD_SERVICE_FAILED = 460, /**< Unregistering of Global Data Manager Service failed. */
+ E_GENERAL_ZIP_ERROR = 551, /**< */
+ E_ZIP_FAILED_TO_CREATE_CONTEXT = 552, /**< */
+ E_ZIP_FAILED_TO_OPEN_FILE = 553, /**< */
+ E_FILESYS_APP_INIT_FAILURE = 600, /**< */
+ E_NO_FILESYSTEM_PROPERTY = 601, /**< */
+ E_UNDEFINED_AUTHENTICATION_TYPE = 602, /**< */
+ E_RTC_TIME_NOT_ACCURATE = 651, /**< */
+ E_RTC_INTIALIZATION_FAILED = 652, /**< */
+ E_DIFFERENT_FLASHLAYOUT = 751, /**< Different flashlayout. */
+ E_EMPTY_FILE_IN_ARCHIVE = 752, /**< Archive contain empty file. */
+ E_UNKNOWN_COMM_DEVICE = 753, /**< Unknown communication device was detected. */
+ E_FLASH_APP_INTERNAL_ERROR = 754, /**< Internal during execution of flash commands. */
+ E_DEVICE_NAME_TOO_LONG = 755, /**< Device name is too long. */
+ E_FLASH_ARCHIVE_MISMATCH = 756, /**< Mismatch between archieve that is flashed and previosly flashed one. */
+ E_UNSUPPORTED_FLASH_TYPE = 757, /**< Flash memory device type is not supported. */
+ E_FPD_NOT_CONFIGURED = 758, /**< Flash physical driver is not configured. */
+ E_INVALID_SIZE_IN_MEMCONF = 759, /**< MEMCONF boot record contain invalid TotalSize field. */
+ E_ARCHIVE_TO_LARGE = 760, /**< Flash archive larger than available space in BDM. */
+ E_PATH_NOT_EXISTS = 951, /**< Path not exist. */
+ E_CLOSE_FILE = 952, /**< Failed to close a file in the file system. */
+ E_INSUFFICENT_SPACE = 953, /**< Not enough memory space for desired operation. */
+ E_REMOVE_FILE = 954, /**< Failed to remove a file from the file system. */
+ E_RENAME_FILE = 955, /**< Failed to rename a file from the file system. */
+ E_CREATE_DIR = 956, /**< Failed to create a new directory in the file system. */
+ E_REMOVE_DIRECTORY = 957, /**< Failed to remove directory. */
+ E_FREE_SPACE = 958, /**< No free space left. */
+ E_ITEM_STAT = 959, /**< Failed to retrieve status data. */
+ E_CLOSE_DIRECTORY = 960, /**< Failed to close a directory in the file system. */
+ E_MOUNT_VOLUME = 961, /**< Failed to mount volume in the file system. */
+ E_READ_DIRECTORY = 962, /**< Failed to read directory in the file system. */
+ E_FS_IO = 963, /**< Input/output error. */
+ E_FS_ARGUMENT_LIST_2BIG = 964, /**< Argument list too long. */
+ E_FS_BAD_FILE_DESC = 965, /**< Bad file descriptor. */
+ E_FS_ACCESS = 966, /**< Permission denied. */
+ E_FS_BAD_ADDRESS = 967, /**< Bad address. */
+ E_FS_FILE_EXIST = 968, /**< File exists. */
+ E_FS_NOT_DIR = 969, /**< Not a directory. */
+ E_FS_IS_DIR = 970, /**< Is a directory. */
+ E_FS_FILE_TOO_LARGE = 971, /**< File too large. */
+ E_FS_READ_ONLY_FS = 972, /**< Read-only file system. */
+ E_FS_OPER_NOT_SUPP = 973, /**< Operation not supported. */
+ E_FS_NAME_TOO_LONG = 974, /**< File name too long. */
+ E_FS_OPERATION_CANCELED = 975, /**< Operation canceled. */
+ E_FS_FAIL = 976, /**< Cannot start operation. */
+ E_FS_INTERNAL = 977, /**< Internal error. */
+ E_FS_NOT_MOUNTED = 978, /**< Volume not mounted. */
+ E_FS_NOT_PERMITED = 979, /**< Operation not permitted. */
+ E_FS_NO_SUCH_FILE_OR_DIR = 980, /**< No such file or directory. */
+ E_FS_NOT_EXIST = 981, /**< Specified FS does not exist. */
+ E_FS_UNKNOWN_ERROR = 982, /**< Error is unknown. */
+ E_FAILED_WRITING_TO_FILE = 983, /**< Failed to write to file. */
+ E_FAILED_READING_FROM_FILE = 984, /**< Failed to read from the specified file. */
+ E_ACCESS_DENIED = 985, /**< The access permission attributes do not allow operation. */
+ E_CANNOT_OPEN_FILE = 986, /**< Can not open the specified file. */
+ E_FAILED_TO_STOP_FS = 987, /**< Can not stop file system. */
+ E_FILE_NAME_TOO_LONG = 988, /**< File name is too long. */
+ E_FAILED_TO_FIND_ELF_SECTION = 989, /**< Can not find elf section. */
+ E_MAX_NUMBER_OF_MOUNTED_VOLUMES_EXCEEDED = 990, /**< Unable to mount volume due to exceeding the maximum number of allowed volumes. */
+ E_NO_MOUNTED_DEVICES_ARE_FOUND = 991, /**< Information message that no mounted devices are found. */
+ E_NOT_FREE_CMD_SPACE = 1000, /**< Index for new command is not founded in execution queue. */
+ E_INVALID_INPUT_PARAMETER = 1001, /**< Invalid input parameter */
+ E_UNSUPPORTED_CMD = 1002, /**< The loader does not support the requested command. */
+ E_UNSUPPORTED_GROUP = 1003, /**< The loader does not support the requested group. */
+ E_INVALID_COMMAND_SIZE = 1051, /**< */
+ E_OVERLOAD_COMMAND_TABLE = 1052, /**< */
+ E_COMMAND_ALREADY_REGISTERED = 1053, /**< */
+ E_AUDITING_FAILED = 1054, /**< Command auditing failed. */
+ E_NONEXIST_TIMER = 1251, /**< */
+ E_FAILED_TO_SET_TIMER = 1252, /**< */
+ E_TIMER_INIT_FAILED = 1253, /**< */
+ E_TIMER_IRQ_CONF_FAILED = 1254, /**< */
+ E_GD_INVALID_UNIT_SIZE = 1351, /**< GD/GDFS: Error in specifying unit size. */
+ E_GD_LL_ILLEGAL_SIZE = 1352, /**< GD/GDFS: Size too large for the block. */
+ E_GD_LL_WRITE_FAILED = 1353, /**< GD/GDFS: Write failed on FLASH device level. */
+ E_GD_LL_ERASE_FAILED = 1354, /**< GD/GDFS: Erase failed on FLASH device level. */
+ E_GD_LL_UNKNOWN_DEVICE = 1355, /**< GD/GDFS: FLASH device unknown. */
+ E_GD_STARTUP_LOG_BLK_MISSING = 1356, /**< GD/GDFS: Logical block not found during start-up scan. */
+ E_GD_STARTUP_DUPLICATE_LOG_BLK = 1357, /**< GD/GDFS: Duplicate instances of same logical block. */
+ E_GD_ERASE_ILLEGAL_BLK_NR = 1358, /**< GD/GDFS: Attempt to erase non-existing physical block. */
+ E_GD_FG_UNIT_NOT_FOUND = 1359, /**< GD/GDFS: Requested unit not found, probably never written or has been deleted. */
+ E_GD_FG_UNIT_SIZE_MISMATCH = 1360, /**< GD/GDFS: Attempt to access a unit outside its beyond its end. */
+ E_GD_FG_ILLEGAL_LOG_BLK_NR = 1361, /**< GD/GDFS: Attempt to access a logical block that does not exist. (Hardware, fatal). */
+ E_GD_FG_ILLEGAL_PHYS_BLK_NR = 1362, /**< GD/GDFS: Attempt to access a physical block that does not exist (internal error). */
+ E_GD_FG_BLK_FULL = 1363, /**< GD/GDFS: Attempted to write more data to a block than could be fitted into one FLASH block. */
+ E_GD_FG_NO_BLK_FREE = 1364, /**< GD/GDFS: Internal error (no free blocks are available). */
+ E_GD_FG_UNIT_CHECKSUM = 1365, /**< GD/GDFS: The checksum or a unit being read is wrong. */
+ E_GD_FG_NOT_DIRECT_BLOCK = 1366, /**< GD/GDFS: Block is not direct. */
+ E_GD_FG_NOT_FREE_BLOCK = 1367, /**< GD/GDFS: For some reason, a free block could not be properly erased. */
+ E_GD_FG_ILLEGAL_SIZE = 1368, /**< GD/GDFS: The size of a unit being written exceeds the maximum limit of a unit. */
+ E_GD_E_FG_FREE_AREA_DIRTY = 1369, /**< GD/GDFS: The startup check found non-FF bytes in unused range within a block. */
+ E_GD_FG_SYNC_FAILED = 1370, /**< GD/GDFS: Failed to synchronize. */
+ E_GD_NOT_OPEN = 1371, /**< GD/GDFS: Tried to access data although GD was in closed state. */
+ E_GD_NOT_ALLOWED = 1372, /**< GD/GDFS: Operation not allowed in the current mode. */
+ E_GD_ALREADY_OPEN = 1373, /**< GD/GDFS: Tried to open or format when GD was already opened. */
+ E_GD_FRONKENSTIENS_PATTERN_MISMATCH = 1374, /**< GD/GDFS: The id mark of the GDVAR file does not match the data in the flash. Fatal and makes GD read only. */
+ E_GD_ILLEGAL_ALIGNMENT = 1375, /**< GD/GDFS: Tried to erase at an address that was not aligned to a flash block boundary. Internal error. */
+ E_GD_ILLEGAL_SIZE = 1376, /**< GD/GDFS: The operation may not be performed with the specified size. Tried to write a to large unit. */
+ E_GD_ACCESS_DENIED = 1377, /**< GD/GDFS: Operation not allowed. Flash device protected. Possible wrong flash driver configuration. */
+ E_GD_ILLEGAL_INDEX = 1378, /**< GD/GDFS: Illegal GD index. */
+ E_GD_MEMORY_ALLOCATION_FAILED = 1379, /**< GD/GDFS: Fatal. Failed to allocate dynamic memory. */
+ E_GD_MISSING_CONFIG = 1380, /**< GD/GDFS: Missing configuration parameter. */
+ E_GD_ILLEGAL_CONFIG = 1381, /**< GD/GDFS: Illegal configuration. */
+ E_GD_TRANSACTION_LOG_CORRUPT = 1382, /**< GD/GDFS: The transaction log used for tracking updates to GD contents is corrupt and prevents roll-back from working properly. */
+ E_GD_NO_DATA_TO_READ = 1399, /**< GD: No data to read. */
+ E_BDM_W_NO_MORE_GC_POSSIBLE = 1451, /**< BDM: No more garbage collection is possible. */
+ E_BDM_UNIT_STARTED = 1452, /**< BDM: Unit has already been started. */
+ E_BDM_UNIT_NOT_STARTED = 1453, /**< BDM: Unit has not yet been started. */
+ E_BDM_NOT_CONFIGURED = 1454, /**< BDM: Has not been configured yet. */
+ E_BDM_STARTUP_FAILED = 1455, /**< BDM: Startup failed. */
+ E_BDM_SHUTDOWN_FAILED = 1456, /**< BDM: Shutdown failed. */
+ E_BDM_WRITE_FAILED = 1457, /**< BDM: An error occurred while writing. */
+ E_BDM_READ_FAILED = 1458, /**< BDM: An error occurred while reading */
+ E_BDM_ERASE_FAILED = 1459, /**< BDM: An error occurred while erasing. */
+ E_BDM_JUNK_FAILED = 1460, /**< BDM: An error occurred while junking. */
+ E_BDM_GC_FAILED = 1461, /**< BDM: An error occurred while garbage collecting. */
+ E_BDM_GET_INFO_FAILED = 1462, /**< BDM: An error occurred while retrieving info about a BDM unit. */
+ E_BDM_WRITE_NOT_SUPPORTED = 1463, /**< BDM: Write not supported. */
+ E_BDM_JUNK_NOT_SUPPORTED = 1464, /**< BDM: Junk not supported. */
+ E_BDM_GC_NOT_SUPPORTED = 1465, /**< BDM: Garbage collection not supported. */
+ E_BDM_SYNC_FAILED = 1466, /**< BDM: Synchronize failed. */
+ E_BDM_NOT_SUPPORTED = 1467, /**< BDM: Function not supported. */
+ E_BDM_PAUSED = 1468, /**< BDM: Paused. */
+ E_BDM_NOT_PAUSED = 1469, /**< BDM: Not paused. */
+ E_BDM_FINDING_BAM_BLOCKS = 1470, /**< BDM: BAM blocks not found. */
+ E_BDM_BAD_PARAM = 1471, /**< BDM: Argument invalid or out of range. */
+ E_BDM_FORMAT_FAILED = 1472, /**< BDM: Formatting failed. */
+ E_BDM_INVALID_UNIT = 1473, /**< BDM: The unit number is out of range. */
+ E_BDM_INVALID_CONFIG = 1474, /**< BDM: Some part of the configuration is invalid. */
+ E_BDM_PRE_FLASH_FINISHED = 1475, /**< BDM: No more preflash blocks can be fetched. */
+ E_BDM_PRE_FLASH_TERMINATE_FAILED = 1476, /**< BDM: Termination of preflash failed. */
+ E_BDM_OUT_OF_MEM = 1477, /**< BDM: Could not allocate enough memory. */
+ E_BDM_XSR_CRITICAL_ERROR = 1481, /**< BDM XSR: Critical error. */
+ E_BDM_XSR_INVALID_PARAMS = 1482, /**< BDM XSR: Invalid parameters. */
+ E_BDM_XSR_PARTITION_NOT_OPENED = 1483, /**< BDM XSR: Could not open partition. */
+ E_BDM_XSR_UNFORMATTED_FLASH = 1484, /**< BDM XSR: Unformatted flash. */
+ E_BDM_XSR_ALLOCATION_ERROR = 1485, /**< BDM XSR: Failed to allocate. */
+ E_BDM_XSR_INVALID_PARTITION = 1486, /**< BDM XSR: Invalid partition. */
+ E_BDM_XSR_READ_ERROR = 1487, /**< BDM XSR: An error occurred while reading. */
+ E_BDM_XSR_WRITE_ERROR = 1488, /**< BDM XSR: An error occurred while writing. */
+ E_BDM_XSR_ERASE_ERROR = 1489, /**< BDM XSR: An error occurred while erasing. */
+ E_BDM_XSR_DEVICE_ERROR = 1490, /**< BDM XSR: Device error. */
+ E_BDM_XSR_GOODBLOCK = 1491, /**< BDM XSR: Good block. */
+ E_BDM_XSR_BADBLOCK = 1492, /**< BDM XSR: Bad block. */
+ E_BAM_NOT_CONFIGURED = 1551, /**< BAM: Is not configured. */
+ E_BAM_ERR_UNSUPPORTED_PAGE_SIZE = 1552, /**< BAM: Unsupported page size. */
+ E_BAM_ERR_ERASING_BLOCK = 1553, /**< BAM: Erase block could not be properly erased. */
+ E_BAM_ERR_OUT_OF_MEMORY = 1554, /**< BAM: Not enough free memory to serve request. */
+ E_BAM_ERR_CHECKING_BADNESS = 1555, /**< BAM: There was a problem checking if a block was bad or not. */
+ E_BAM_ERR_FINDING_BLOCK = 1556, /**< BAM: Reserved block could not be found. */
+ E_BAM_ERR_READING_PAGE = 1557, /**< BAM: An error occurred while reading a page in a block. */
+ E_BAM_ERR_MARKING_BLOCK_BAD = 1558, /**< BAM: A block went bad and BAM could not mark it as bad properly. */
+ E_BAM_ERR_READING_OUTSIDE_BLOCK = 1559, /**< BAM: Read would result in a read beyond end of reserved block. */
+ E_BAM_ERR_UNCORRECTABLE_ERROR = 1560, /**< BAM: An uncorrectable read error occurred while reading block. */
+ E_BAM_ERR_WRITING_PAGE = 1561, /**< BAM: An error occurred while writing a page to a reserved block. */
+ E_BAM_ERR_WRITING_BLOCK = 1562, /**< BAM: An error occurred while writing to a reserved block. */
+ E_BAM_ERR_RESCUING_BLOCK = 1563, /**< BAM: There was a problem rescuing a block that went bad during the request. */
+ E_BAM_ERR_CONFIG_MISSING = 1564, /**< BAM: No configuration was given. */
+ E_BAM_ERR_ALREADY_STARTED = 1565, /**< BAM: Has already been started. */
+ E_BAM_ERR_NOT_STARTED = 1566, /**< BAM: Has not been started yet. */
+ E_BAM_ERR_UNSUPPORTED_OPERATION = 1567, /**< BAM: Requested operation is not supported. */
+ E_BAM_ERR_CORRUPT_STATE = 1568, /**< BAM: Internal state has been corrupted. */
+ E_BAM_ERR_UNSUPPORTED_MEDIA = 1569, /**< BAM: The configured media type is not supported. */
+ E_BAM_ERR_UNSUPPORTED_REDUNDANT_AREA_SIZE = 1570, /**< BAM: Unsupported redundant area size. */
+ E_BAM_ERR_READING_BLOCK = 1571, /**< BAM: Reading block failed. */
+ E_BAM_ERR_SHUTTING_DOWN = 1572, /**< BAM: Shutting down failed. */
+ E_BAM_ERR_UNINITIALIZING = 1573, /**< BAM: An error occurred with uninitializing. */
+ E_BAM_ERR_INVALID_OFFSET = 1574, /**< BAM: Invalid offset. */
+ E_BAM_ERR_INVALID_SIZE = 1575, /**< BAM: Invalid size. */
+ E_BAM_ERR_RETRIEVING_INFO = 1576, /**< BAM: Retrieving info failed. */
+ E_BAM_ERR_INVALID_CONFIG = 1577, /**< BAM: Invalid configuration. */
+ E_BAM_ERR_ERASING_ALL_BLOCKS = 1578, /**< BAM: An error occurred while erasing all blocks. */
+ E_BAM_ERR_BLOCK_MARKED_BAD = 1579, /**< BAM: Block was marked as bad while doing an operation. */
+ E_BAM_ERR_VALIDATING_START_BLOCK = 1580, /**< BAM: Can not assure that start block configuration refers to a block boundary. */
+ E_BAM_ERR_FAILED_TO_GET_MEMORYTECHNOLOGY = 1581, /**< BAM: Unable the query FAM about the memory technology used in the memory we are trying to initialize BAM on. */
+ E_BAM_ERR_BLOCK_RESCUED = 1582, /**< BAM: Block rescue failed. */
+ E_BAM_ERR_DETERMINING_BBM = 1583, /**< BAM: Failed to determine what BBM type configuration has been written to flash. */
+ E_BAM_ERR_SET_ECC_LENGTH = 1584, /**< BAM: Failed to set the length to use with HW ECC acceleration. */
+ E_BAM_ERR_INVALID_BBM_TYPE = 1585, /**< BAM: Invalid BBM type. */
+ E_BAM_ERR_BOOT_BDM_CONFIG_FAILED = 1586, /**< BAM: Failed to configure boot block device management. */
+ E_BAM_ERR_BOOT_BDM_STARTUP_FAILED = 1587, /**< BAM: Failed to startup boot block device management. */
+ E_BAM_ERR_BOOT_BDM_INSTANCE_NOT_FOUND = 1588, /**< BAM: Boot block device management instance not found. */
+ E_BAM_ERR_BOOT_BDM_BLOCKS_NOT_FOUND = 1589, /**< BAM: Boot block device management blocks not found. */
+ E_BAM_ERR_BOOT_BDM_NOT_STARTED = 1590, /**< BAM: Boot block device management not started. Requested operation require BDM to be started. */
+ E_BAM_ERR_UNIT_OUT_OF_RANGE = 1591, /**< BAM: Unit is out of range. */
+ E_BAM_ERR_BDM_STARTUP_FAILED = 1592, /**< BAM: Block device management startup failed. */
+ E_BAM_ERR_BLOCK_NOT_ERASED = 1593, /**< BAM: Block not erased. */
+ E_BAM_ONLD_CRITICAL_ERROR = 1601, /**< BAM ONLD: Critical error. */
+ E_BAM_ONLD_INVALID_PARAMS = 1602, /**< BAM ONLD: Invalid parameters. */
+ E_BAM_ONLD_INITIALISATION_ERROR = 1603, /**< BAM ONLD: Initialisation error. */
+ E_BAM_ONLD_READ_ERROR = 1604, /**< BAM ONLD: An error occurred while reading. */
+ E_BAM_ONLD_WRITE_ERROR = 1605, /**< BAM ONLD: An error occurred while writing. */
+ E_BAM_ONLD_ERASE_ERROR = 1606, /**< BAM ONLD: An error occurred while erasing. */
+ E_BAM_ONLD_DEVICE_ERROR = 1607, /**< BAM ONLD: Device error. */
+ E_BAM_ONLD_GOODBLOCK = 1608, /**< BAM ONLD: Good block. */
+ E_BAM_ONLD_BADBLOCK = 1609, /**< BAM ONLD: Bad block. */
+ E_COPS_MEMORY_ALLOC_FAILED = 1651, /**< COPS: Memory allocation failed. */
+ E_COPS_DATA_TAMPERED = 1652, /**< COPS: Data is tempered. */
+ E_COPS_IMEI_MISSMATCH = 1653, /**< COPS: IMEI missmatch. */
+ E_COPS_OTP_LOCKED = 1654, /**< COPS: OTP is locked. */
+ E_COPS_MAC_FUNCTION_LOCKED_DOWN = 1655, /**< COPS: Function for calculating MAC is locked down. */
+ E_COPS_AUTHENTICATION_FAILED = 1656, /**< COPS: Authentication failed. */
+ E_COPS_DATA_NOT_PRESENT = 1657, /**< COPS: Default Data is not present. */
+ E_COPS_IMEI_UPDATE_NOT_ALLOWED = 1658, /**< COPS: IMEI update is not allowed. */
+ E_COPS_LOCK_PERMANENTLY_DISABLED = 1659, /**< COPS: Locking of SIMLocks is disabled. */
+ E_COPS_NO_ATTEMPTS_LEFT = 1660, /**< COPS: No more attempts for verification left. */
+ E_COPS_INCORRECT_CONTROLKEY = 1661, /**< COPS: Control key is not correct. */
+ E_COPS_TOO_SHORT_CONTROLKEY = 1662, /**< COPS: Control key is too short. */
+ E_COPS_TOO_LONG_CONTROLKEY = 1663, /**< COPS: Control key is too long. */
+ E_COPS_INVALID_CONTROLKEY = 1664, /**< COPS: Control key is not valid. */
+ E_COPS_TIMER_RUNNING = 1665, /**< COPS: Timer is running. */
+ E_COPS_SIM_ERROR = 1666, /**< COPS: SIM error. */
+ E_COPS_LOCKING_FAILED = 1667, /**< COPS: Locking failed. */
+ E_COPS_OTA_UNLOCK_IMEI_MISMATCH = 1668, /**< COPS: OTA unlock IMEI mismatch. */
+ E_COPS_INCORRECT_IMSI = 1669, /**< COPS: Incorrect IMSI. */
+ E_COPS_PARAMETER_ERROR = 1670, /**< COPS: Parameter error. */
+ E_COPS_BUFFER_TOO_SMALL = 1671, /**< COPS: Memory buffer is too small. */
+ E_COPS_FORBIDDEN_PARAMETER_ID = 1672, /**< COPS: Parameter is not allowed. */
+ E_COPS_UNKNOWN_PARAMETER_ID = 1673, /**< COPS: Parameter can not be recognised. */
+ E_COPS_ARGUMENT_ERROR = 1674, /**< COPS: Argument error! */
+ E_COPS_VERIFY_FAILED = 1698, /**< COPS: Failed to verify internal data. */
+ E_COPS_UNDEFINED_ERROR = 1699, /**< COPS: Undefined error. */
+ E_PD_NAND_RESULT_BIT_ERROR_CORRECTED = 1751, /**< PD NAND: A bit error was detected and corrected. */
+ E_PD_NAND_RESULT_UNCORRECTABLE_BIT_ERROR = 1752, /**< PD NAND: An uncorrectable bit error was detected. */
+ E_PD_NAND_RESULT_BAD_PARAMETER = 1753, /**< PD NAND: The function could not perform the requested operation due to a bad parameter. */
+ E_PD_NAND_RESULT_HW_ERROR = 1754, /**< PD NAND: A hardware error occurred. */
+ E_PD_NAND_RESULT_INTERNAL_ERROR = 1755, /**< PD NAND: A module internal error has occurred. The module has reach an unexpected state or request. */
+ E_PD_NAND_RESULT_BUSY = 1756, /**< PD NAND: Busy flag was returned. */
+ E_PD_NAND_RESULT_READING_ERASED_PAGE = 1757, /**< PD NAND: Attempting to read erased page. */
+ E_PD_NAND_RESULT_NUMBER_OF_ITEMS = 1758, /**< PD NAND: Number of valid states of this type. */
+ E_PD_NAND_RESULT_UNDEFINED = 1759, /**< PD NAND: Represents an undefined value of this type. */
+ E_GD_TA_BASE = 1851, /**< GD/TA: TA base. */
+ E_GD_TA_UNKNOWN_PARTITION = 1852, /**< GD/TA: Unknown partition. */
+ E_GD_TA_UNKNOWN_CONFIG = 1853, /**< GD/TA: Unknown configuration. */
+ E_GD_TA_ILLOGICAL_CONFIGURATION = 1854, /**< GD/TA: Ilogical configuration. */
+ E_GD_TA_UNKNOWN_MEMORY_TYPE = 1855, /**< GD/TA: Unknown memory type. */
+ E_GD_TA_WRONG_PARAMETER = 1856, /**< GD/TA: Wrong parameter. */
+ E_GD_TA_OUT_OF_MEMORY = 1857, /**< GD/TA: Out of memory. */
+ E_GD_TA_INVALID_ADRESS = 1858, /**< GD/TA: Invalid adress. */
+ E_GD_TA_UNUSED_ADRESS = 1859, /**< GD/TA: Unused adress. */
+ E_GD_TA_UNIT_NOT_FOUND = 1860, /**< GD/TA: Unit not found. */
+ E_GD_TA_NOT_IMPLEMENTED = 1861, /**< GD/TA: TA is not supported. */
+ E_GD_TA_FAIL = 1862, /**< GD/TA: TA fail. */
+ E_GD_UNKNOWN_UNIT_NAME = 1863, /**< GD: Unknown unit name. */
+ E_GD_LAST = 1864, /**< GD: Last enumeration (last valid + 1). */
+ E_FAILED_TO_STORE_IN_FIFO = 1900, /**< Failed to store data in FIFO. */
+ E_FAILED_TO_SET_COMM_DEVICES = 1951, /**< Failed to set parameters of communications devices. */
+ E_FAILED_TO_STORE_IN_STACK = 1952, /**< Failed to store in stack. */
+ E_ZIP_PARSER_FILE_NOT_FOUND = 1954, /**< The requested file is not found in the specified Zip archive. */
+ E_ELF_FILE_FORMAT = 1955, /**< The requested file is not an elf file. */
+ E_ELF_OPEN_SECTION = 1956, /**< Can not open elf section. */
+ E_NAME_TOO_LONG = 1957, /**< The name of parameter is too long. */
+ E_BOOTRECORDS_MISMATCH = 1958, /**< Error in boot records. */
+ E_BOOTRECORD_EMPTY = 1959, /**< Boot record is empty and operation cannot be executed. */
+ E_INVALID_BOOTRECORD_IMAGE = 1960, /**< Boot record image is not valid. */
+ E_BOOTRECORD_FULL = 1961, /**< Boot record has no space to accept new boot record. */
+ E_BOOTRECORD_NOT_EXIST = 1962, /**< Boot record not exist. */
+ E_BOOTRECORD_WRITE_FAILED = 1963, /**< Writing failed. */
+ E_BOOTRECORD_UNALIGNED_DATA = 1964, /**< Boot record data is unaligned. */
+ E_CONTENT_TYPE = 1965, /**< Content type to long. */
+ E_DEVICE_TYPE = 1966, /**< Device type to long. */
+ E_NUMBER_OF_TARGET_DEVICES = 1967, /**< Number of target devices to big. */
+ E_DESCRIPTION_TOO_LONG = 1968, /**< Description field too long. */
+ E_MODULE_NOT_FOUND = 2000, /**< Testing this module currently not supported in ADbg. */
+ E_MODULE_LIST_EMPTY = 2001, /**< There isn't any module available for testing. */
+ E_CASE_NOT_FOUND = 2002, /**< Specified case can not be found. */
+ E_CASE_LIST_EMPTY = 2003, /**< There isn't any test cases in specified module. */
+ E_INT_GROUP_NOT_FOUND = 2004, /**< Specified internal group can not be found. */
+ E_INT_GROUP_LIST_EMPTY = 2005, /**< There isn't any internal group. */
+ E_INT_FUNCTION_NOT_FOUND = 2006, /**< Specified interface function cannot be found. */
+ E_INT_FUNCTION_LIST_EMPTY = 2007, /**< There isn't any interface function in interface group. */
+ E_PRECONDITION_IS_ALREADY_SET = 2008, /**< Request for setting precondition that is already set. */
+ E_PRECONDITION_IS_NOT_SET = 2009, /**< Request to recover condition that is not changed. */
+ E_INIT_OTP_PD_FAILED = 2100, /**< */
+ E_READING_OTP_FAILED = 2101, /**< */
+ E_WRITTING_OTP_FAILED = 2102, /**< */
+ E_INVALID_CID_VALUE = 2103, /**< */
+ E_INIT_OTP_LD_FAILED = 2104, /**< */
+ E_OTP_AREA_LOCKED = 2105, /**< */
+ E_SEC_APP_PROPERTY_NOT_FOUND = 2251, /**< App property cannot be found. */
+ E_SEC_APP_IMEI_NOT_CHANGABLE = 2252, /**< IMEI not changeable. */
+ E_SEC_APP_OPERATION_DENIED = 2253, /**< Security operation denied. */
+ E_SEC_APP_UNABLE_TO_READ_BS_PARAMETERS = 2254, /**< Incorrect Boot Stage Parameter vector. */
+ E_SEC_APP_ROM_ERROR_CRITICAL = 2255, /**< Critical error in ROM has occurred. */
+ E_SEC_APP_ROM_ERROR = 2256, /**< Unexpected ROM error. */
+ E_SEC_APP_PATCH_EXISTS = 2257, /**< ROM Patch is already installed. */
+ E_SEC_APP_PATCH_REINSTALLED = 2258, /**< ROM Patch in Flash is reinstalled. */
+ E_SEC_APP_ROOTKEY_EXISTS = 2259, /**< ROM Patch is already installed. */
+ E_SEC_APP_ROOTKEY_REINSTALLED = 2260, /**< Root Key is reinstalled. */
+ E_TA_WRONG_PARTITION = 2351, /**< TA: Unknown partition. */
+ E_TA_ILLOGICAL_CONFIGURATION = 2352, /**< TA: Configuration error. */
+ E_TA_UNKNOWN_MEMORY_TYPE = 2353, /**< TA: Unsupported memory type. */
+ E_TA_WRONG_PARAMETER = 2354, /**< TA: Wrong parameter. */
+ E_TA_OUT_OF_MEMORY = 2355, /**< TA: No heap memory left. */
+ E_TA_INVALID_ADRESS = 2356, /**< TA: Invalid address. */
+ E_TA_UNUSED_ADRESS = 2357, /**< TA: Unused address. */
+ E_TA_UNIT_NOT_FOUND = 2358, /**< TA: Unit was not found. */
+ E_TA_WRONG_SIZE = 2359, /**< TA: Wrong size when reading unit. */
+ E_TA_INSUFFICIANT_SPACE = 2360, /**< TA: Not enough space to flush the Trim Area. */
+ E_TA_UNKNOWN_PARTITION = 2361, /**< TA: Unknown partition. */
+ E_TA_FAIL = 2362, /**< TA: Fail. */
+ E_TA_MEDIA_ERROR = 2460, /**< TA: Media error. */
+ E_TA_NOT_CONFIGURED = 2461, /**< TA: Error occurs during configuration. */
+ E_REQUEST_DENIED = 2500, /**< Request for change operation denied. */
+ E_UNDEFINED_CHANGE_OPERATION = 2501, /**< Requested change operation is not supported. */
+ E_PD_CFI_IN_PROGRESS = 2651, /**< PD CFI: The operation is in progress. Additional poll calls must be done. */
+ E_PD_CFI_UNKNOWN_REQUEST = 2652, /**< PD CFI: Type not recognized. */
+ E_PD_CFI_HARDWARE_ERROR = 2653, /**< PD CFI: Operation could not be completed because of a hardware malfunction. */
+ E_PD_CFI_NOT_SUPPORTED = 2654, /**< PD CFI: The driver does not implement the requested function. */
+ E_PD_CFI_PARAMETER_ERROR = 2655, /**< PD CFI: Invalid parameter value. */
+ E_PD_CFI_PROTECTED = 2656, /**< PD CFI: The requested flash address is protected from the requested type of access. */
+ E_PD_CFI_UNSUPPORTED_DEVICE = 2657, /**< PD CFI: Flash devices not supported by this driver. */
+ E_PD_CFI_OPERATION_COMPLETE = 2658, /**< PD CFI: Requested operation was not suspended as it has completed. */
+ E_LOADER_SEC_LIB_CHIP_ID_INVALID = 4000, /**< Invalid input parameters. */
+ E_LOADER_SEC_LIB_INVALID_PARAMETER_TO_FUNC = 4096, /**< Invalid input parameters. */
+ E_LOADER_SEC_LIB_FAILURE = 4120, /**< Failure. */
+ E_LOADER_SEC_LIB_HASH_LIST_HASH_FAILURE = 4121, /**< hash list verification failed. */
+ E_LOADER_SEC_LIB_HEADER_VERIFICATION_FAILURE = 4122, /**< Header verification failed. */
+ E_LOADER_SEC_LIB_HEADER_VERIFIED = 4123, /**< Successful verification of the header */
+ E_LOADER_SEC_LIB_VERIFY_FAILURE = 4124, /**< Unsuccessful verification. */
+ E_LOADER_SEC_LIB_INIT_CALLED_TWICE = 4150, /**< The security library init function has been called 2 times. */
+ E_LOADER_SEC_LIB_MEMORY_RELEASE_FAILED = 4180, /**< Memory release failed. */
+ E_LOADER_SEC_LIB_MEMORY_ALLOCATION_FAILED = 4181, /**< Memory allocation failed. */
+ E_LOADER_SEC_LIB_DATA_BLOCK_EXIST = 4182, /**< Data block exist in the linked list. */
+ E_LOADER_SEC_LIB_DATA_BLOCK_DO_NOT_EXIST = 4183, /**< Data block do not exist in the linked list. */
+ E_LOADER_SEC_LIB_INVALID_AUTHENTICATION_TYPE = 4184, /**< Invalid authentication type. */
+ E_LOADER_SEC_LIB_EXCEEDED_NUMBER_OF_AUTHENTICATION = 4185, /**< Exceeded number of authentication. Loader will be shut downed. */
+ E_LOADER_SEC_LIB_ESB_MAC_INIT_FAILED = 4186, /**< Initialization of ESB block for MAC calculation failed. */
+ E_LOADER_SEC_LIB_ESB_MAC_UPDATE_FAILED = 4187, /**< MAC update with ESB block failed. */
+ E_LOADER_SEC_LIB_ESB_MAC_FINAL_FAILED = 4188, /**< MAC finalize with ESB block failed. */
+ E_LOADER_SEC_LIB_ESB_MAC_NOT_VERIFIED = 4189, /**< MAC verification with ESB block failed. */
+ E_LOADER_SEC_LIB_ESB_DOWNLOCK_FAILED = 4190, /**< ESB downlock failed. */
+ E_LOADER_SEC_LIB_CONTROL_KEY_VERIFICATION_FAILURE = 4191, /**< Control key verification failed. */
+ E_LOADER_SEC_LIB_CA_CERTIFICATE_VERIFICATION_FAILURE = 4192, /**< CA certificate verification failed. */
+ E_LOADER_SEC_LIB_X509_ERROR_IN_CERTIFICATE = 4193, /**< X509 certificate error. */
+ E_LOADER_SEC_LIB_COPS_INIT_FAILED = 4194, /**< COPS initialization failed. */
+ E_LOADER_SEC_LIB_COPS_PROTECT_DATA_INIT_FAILED = 4195, /**< COPS protect data initialization failed. */
+ E_LOADER_SEC_LIB_COPS_DATA_READ_FAILED = 4196, /**< COPS data read failed. */
+ E_LOADER_SEC_LIB_COPS_DATA_WRITE_FAILED = 4197, /**< COPS data write failed. */
+ E_LOADER_SEC_LIB_READ_OTP_FAILED = 4198, /**< Reading OTP data failed. */
+ E_LOADER_SEC_LIB_WRITE_OTP_FAILED = 4199, /**< Writing OTP data failed. */
+ E_LOADER_SEC_LIB_LOCK_OTP_FAILED = 4200, /**< Locking OTP data failed. */
+ E_LOADER_SEC_LIB_UNPACKING_IMEI_FAILED = 4201, /**< Unpacking IMEI data failed. */
+ E_LOADER_SEC_LIB_PACKING_IMEI_FAILED = 4202, /**< Packing IMEI data failed. */
+ E_LOADER_SEC_LIB_OTP_ALREADY_LOCKED = 4203, /**< OTP is already locked. */
+ E_LOADER_SEC_LIB_INVALID_CID_VALUE = 4204, /**< CID value is out of range. */
+ E_LOADER_SEC_LIB_OTP_LOCKBITS_MISSMATCH = 4205, /**< OTP lock bits have different values. */
+ E_LOADER_SEC_LIB_WRITING_BOOTRECORD_FAILED = 4206, /**< Failed to write in boot records. */
+ E_LOADER_SEC_LIB_UNSUPPORTED_NO_DEBUG_HW = 4207, /**< No debug hardware detected. */
+ E_LOADER_SEC_LIB_CHANGE_OPERATION_NOT_SUPPORTED = 4208, /**< Requested change operation is not supported or not allowed. */
+ E_LOADER_SEC_LIB_INVALID_CHANGE_OPERATION = 4209, /**< Invalid change operation. */
+ E_LOADER_SEC_LIB_RWIMEI_NOT_ALLOWED = 4210, /**< Rewriteable IMEI is not allowed to change. */
+ E_LOADER_SEC_LIB_REQUEST_DENIED = 4211, /**< Request for change operation is denied. */
+ E_LOADER_SEC_LIB_BOOT_BLOCK_DO_NOT_EXIST = 4212, /**< Boot record do not exist. */
+ E_LOADER_SEC_LIB_CORRUPTED_DOMAIN_DATA = 4213, /**< Corrupted or do not exist domain data in boot block. */
+ E_LOADER_SEC_LIB_INVALID_DOMAIN = 4214, /**< Invalid domain. */
+ E_FIFO_OVERFLOW = 4300, /**< */
+ E_FIFO_UNDERFLOW = 4301, /**< */
+ E_OBJECT_NULL = 4302, /**< */
+ E_POINTER_NOT_NULL = 4303, /**< */
+ E_UNRECOGNIZED_STATE = 4304, /**< */
+ E_UNKNOWN_MANUFACTURER_ID = 4305, /**< */
+ E_UNKNOWN_DEVICE_ID = 4306, /**< */
+ E_INVALID_A01_FORMAT = 4308, /**< */
+ E_A01_BUFFER_FULL = 4309, /**< */
+ E_CONFIG_FILE_NOT_SPECIFIED = 4350, /**< */
+ A2_E_SUCCESS = 5000, /**< Operation successful. */
+ A2_E_PROP_NOT_SUPPORTED = 5001, /**< The property is not supported. */
+ A2_E_PROP_READ_ONLY = 5002, /**< The property is read only. */
+ A2_E_PROP_INVALID = 5003, /**< The property value is invalid. */
+ A2_E_AUTH_DECLINED = 5004, /**< Authentication declined. The ME is automatically shut down after sending this. */
+ A2_E_AUTH_UNSUPPORTED = 5005, /**< The authentication type is not supported. */
+ A2_E_ALLOCATE_FAILED = 5006, /**< Failed to allocate memory. */
+ A2_E_INVALID_TIME = 5007, /**< Invalid time specified. */
+ A2_E_UNKNWON_PROPERTY = 5008, /**< Unknown property id. */
+ A2_E_START_AAIF_FAILED = 5009, /**< Failed to start the AAIF in the loader on loader. */
+ A2_E_UNSUPPORTED_CMD = 5010, /**< Unsupported command. */
+ A2_E_POINTER_NOT_ALIGNED = 5011, /**< Pointer not aligned. */
+ A2_E_ERROR_WRITING_BOOTRECORD = 5012, /**< Writing of the boot record failed. */
+ A2_E_INVALID_CURRDATE_STRING_LENGTH = 5013, /**< String data length is invalid. */
+ A2_E_NO_COMMAND_GROUPS_DEFINED = 5014, /**< Unknown command group. */
+ A2_E_READ_OTP_FAILED = 5015, /**< Read OTP failed. */
+ A2_E_COMMAND_IS_NOT_IMPLEMENTED = 5016, /**< Specified command is not implemented. */
+ A2_E_FAILED_TO_GET_ASIC_COPS_SETTINGS = 5017, /**< Failed to get ASIC COPS setting. */
+ A2_E_FAILED_TO_SET_PLAT_PROP = 5018, /**< Failed to set platform properties. */
+ A2_E_MEMORY_FAILED = 5019, /**< Memory fail. */
+ A2_E_JTAG_UNLOCK_FAILED = 5020, /**< JTAG unlock fail. */
+ A2_E_AUTOCONFIGURE_FLASH = 5021, /**< */
+ A2_E_E_GET_FIRST_FLASH_DEV = 5022, /**< */
+ A2_E_E_FAILED_INIT_COPS_LIB = 5023, /**< Failed to initialize COPS library. */
+ A2_E_OTP_SECURITY_ERROR = 5024, /**< OTP security error. */
+ A2_E_I2C_BUS_SECURITY_ERROR = 5025, /**< I2C bus security error. */
+ A2_E_GET_STATIC_DATA_FAILED = 5026, /**< Can't get static data. */
+ A2_E_STORE_MAC_TO_BOOTIMAGE_FAILED = 5027, /**< Failed to store MAC in boot image. */
+ A2_E_SEC_GENERAL_COPS_LIB_ERROR = 5028, /**< General COPS error. */
+ A2_E_HASH_VERIFICATION_ERROR = 5029, /**< Hash verification failed. */
+ A2_E_READ_FLASH_FAILED = 5030, /**< Failed to read hash. */
+ A2_E_APP_HANDSHAKE_FAILED = 5031, /**< Processors handshake failed. */
+ A2_E_BOOTIMAGE_MEMCONF_INVALID = 5032, /**< Invalid memconfig in boot image. */
+ A2_E_BOOTIMAGE_SIGNATURE_FAILED = 5033, /**< Boot image signature failed. */
+ A2_E_BOOTIMAGE_FAILED_TO_READ_IMAGE = 5034, /**< Failed to read image. */
+ A2_E_BOOTIMAGE_FAILED_ALLOCATE_MEM = 5035, /**< Failed to allocate memory. */
+ A2_E_BOOTIMAGE_INVALID_PARAM = 5036, /**< Boot image invalid parametars. */
+ A2_E_BOOTIMAGE_INVALID_LENGTH = 5037, /**< Boot image has invalid length. */
+ A2_E_BOOTIMAGE_MACED_HEADER_SIZE_ZERO = 5038, /**< Header size is zero. */
+ A2_E_FLASH_RESULT_DEVICE_PROTECTED = 5039, /**< The flash device was protected. */
+ A2_E_FLASH_RESULT_WRITE_SUSPENDED = 5040, /**< The last write process was suspended. */
+ A2_E_FLASH_RESULT_VOLTAGE_RANGE_ERROR = 5041, /**< The voltage range is invalid. */
+ A2_E_FLASH_RESULT_PROGRAM_ERROR = 5042, /**< Failed to write to the flash device. */
+ A2_E_FLASH_RESULT_ERASE_ERROR = 5043, /**< Failed to erase a block in the flash device. */
+ A2_E_FLASH_RESULT_ERASE_SUSPENDED = 5044, /**< The erase process was suspended. */
+ A2_E_FLASH_RESULT_COMMAND_SEQUENCE_ERROR = 5045, /**< The sequence of the flash commands was invalid. */
+ A2_E_FLASH_RESULT_OPERATION_NOT_SUPPORTED = 5046, /**< Operation was not supported in flashdriver. */
+ A2_E_FLASH_RESULT_INVALID_PARAMETER = 5047, /**< Invalid in-parameter specified when reading/writing to flash. */
+ A2_E_FLASH_RESULT_NO_FLASH_DEVICE = 5048, /**< No flash device was found on the physical address. */
+ A2_E_FLASH_RESULT_CONFIGURATION_ERROR = 5049, /**< Configuration error of flash device. */
+ A2_E_FLASH_RESULT_INVALID_STARTADDRESS = 5050, /**< Invalid start address of the parameter. */
+ A2_E_FLASH_RESULT_INVALID_PHYSICAL_ADDRESS = 5051, /**< Invalid physical address of the parameter. */
+ A2_E_FLASH_RESULT_INVALID_DATALENGTH = 5052, /**< The data length of the parameter is invalid. */
+ A2_E_FLASH_RESULT_GETREGION_ERROR = 5053, /**< Invalid flash region specified. */
+ A2_E_FLASH_RESULT_NULL_POINTER_BUF = 5054, /**< A buffer was NULL. */
+ A2_E_FLASH_RESULT_NAND_READ_FAILED = 5055, /**< Failed to read from the NAND flash. */
+ A2_E_FLASH_RESULT_NAND_PAGE_SIZE_UNSUPPORTED = 5056, /**< The nand page size is unsupported. */
+ A2_E_FLASH_RESULT_WRITE_ERROR = 5057, /**< Failed to write to the flash device. */
+ A2_E_FLASH_RESULT_READ_ID_ERROR = 5058, /**< Failed to read the device ID from the flash device. */
+ A2_E_FLASH_RESULT_HARDWARE_ERROR = 5059, /**< Hardware error in the flash status. */
+ A2_E_FLASH_RESULT_READ_FROM_FLASH = 5060, /**< Failed to read from the flash device. */
+ A2_E_FLASH_RESULT_ADD_NEW_DEVICE = 5061, /**< Failed to add a new instance of a flash device. */
+ A2_E_FLASH_RESULT_OTP_UNSUPPORTED_IN_FLASH = 5062, /**< OTP is not support in the current flash device. */
+ A2_E_FLASH_RESULT_OTP_TOO_SMALL = 5063, /**< The OTP size is to small for the length requested. */
+ A2_E_FLASH_RESULT_OTP_READ_FAILED = 5064, /**< Failed to read the OTP area in the flash device. */
+ A2_E_FLASH_RESULT_INVALID_FLASH_TYPE = 5065, /**< The flash type is unknown. */
+ A2_E_FLASH_RESULT_NAND_FLUSH_ERROR = 5066, /**< Failed to flush the NAND write buffer. */
+ A2_E_FLASH_RESULT_NOR_FLUSH_ERROR = 5067, /**< Failed to flush the NOR write buffer. */
+ A2_E_INVALID_LOL_STATE = 5068, /**< Invalid Loader on loader state. */
+ A2_E_INVALID_STATUS_LOLSTATE = 5069, /**< Invalid loader on loader status. */
+ A2_E_WRITE_STATIC_DATA = 5070, /**< Write static data failed. */
+ A2_E_HEADER_NOT_VERIFIED_YET = 5071, /**< Header is still not verified. */
+ A2_E_ALL_BLOCKS_VERIFIED_FAILED = 5072, /**< Blocks verification failed. */
+ A2_E_HANDSHAKE_WITH_APP_SIDE = 5073, /**< Handshake with App side failed. */
+ A2_E_READ_STATIC_DATA = 5074, /**< Failed to read static data. */
+ A2_E_ENABLE_CLOCK_HARDWARE_FAILED = 5075, /**< Failed to enable clock hardware. */
+ A2_E_ENABLE_BLOCK_HARDWARE_FAILED = 5076, /**< Failed to enable block hardware. */
+ A2_E_NO_HEADER_TO_MAC_IN_BOOT = 5077, /**< Indicates that the loader did not find any header in the bootimage records that could be MAC'ed. */
+ A2_E_MMU_SETUP = 5078, /**< MMU setup failed. */
+ A2_E_INVALID_COMMAND_SIZE = 5079, /**< Invalid command size. */
+ A2_E_HASH_LIST_LENGTH_INVALID = 5080, /**< Invalid hash list length. */
+ A2_E_INVALID_INPUT_PARAMETERS = 5081, /**< Invalid input parameters. */
+ A2_E_FAILED_SETUP_MSL_DRIVER = 5082, /**< MSL driver setup failed. */
+ A2_E_REQUEST_DENIED = 5083, /**< Request denied. */
+ A2_E_ASIC_FUSES_INVALID = 5084, /**< Fuses for the ASIC are invalid. */
+ A2_E_STATIC_DATA_NOT_CHECKED = 5085, /**< Static data is not checked. */
+ A2_E_COPS_DATA_MAN_INIT = 5086, /**< Failed to initialize the cops data man, this can be caused by an corrupt boot image. You probably just need to flash a platform software to get it work. */
+ A2_E_UART_DRIVER_ERROR = 5087, /**< UART driver error. */
+ A2_E_INVALID_DOMAIN_FOR_LOADER_TYPE = 5088, /**< Loader type is not compatible with this domain. */
+ A2_E_FUNCTIONALITY_NOT_IN_PRODUCT = 5089, /**< Functionality not supported. */
+ A2_E_DEFALT_DATA_NOT_FOUND = 5090, /**< Default data can not be found. */
+ A2_E_FAILED_TO_MAC_HEADER = 5091, /**< Failed to send the header to access side to be MAC'ed, could be something wrong with the header. */
+ A2_E_APP_PRELOADER_NOT_STARTED = 5092, /**< App preloader not started. */
+ A2_E_INVALID_DEST_ADDRESS = 5093, /**< Invalid destination address. */
+ A2_E_SYS_APP_INIT_FAILURE = 5094, /**< Failed to initialize the system application. */
+ A2_E_FLASH_APP_INIT_FAILURE = 5095, /**< Failed to initialize the flash application. */
+ A2_E_SIGNATURE_APP_INIT_FAILURE = 5096, /**< Failed to initialize the signature application. */
+ A2_E_RESET_APP_INIT_FAILURE = 5097, /**< Failed to initialize the reset application. */
+ A2_E_INT_SEC_APP_INIT_FAILURE = 5098, /**< Failed to initialize the internal security application. */
+ A2_E_COPS_DATA_MAN_FORMAT = 5099, /**< COPS data man Format. */
+ A2_E_COPS_DATA_MAN_WRITE = 5100, /**< COPS data man write. */
+ A2_E_COPS_DATA_MAN_FLUSH = 5101, /**< Failed to Flush the memory into the security partition. */
+ A2_E_COPS_DATA_MAN_GETBLOCKSIZE = 5102, /**< Failed to get the block size of a unit in the security partition. */
+ A2_E_COPS_DATA_MAN_READBLOCK = 5103, /**< Failed to read an index from the security partition. */
+ A2_E_INVALID_FLASH_VAR_LENGTH = 5104, /**< The bytes left to program should be less than a NAND page. */
+ A2_E_BOOTIMAGE_TOO_BIG = 5105, /**< Boot image is too big. */
+ A2_E_GDFS_APP_INIT_FAILURE = 5106, /**< App GD init failed. */
+ A2_E_FILESYS_APP_INIT_FAILURE = 5107, /**< Failed to initialize the file system. */
+ A2_E_INVALID_SOURCE_DEST_ADDRESS = 5108, /**< Invalid source or destination address. */
+ A2_E_INVALID_RESPONSE_COMMAND = 5109, /**< Invalid Response command number on the internal security command group, was expecting command 0xFF. */
+ A2_E_INVALID_RESP_TO_CMD = 5110, /**< The internal sec command response should have responded to another command. */
+ A2_E_VERIFICATION_OF_WRITTEN_DATA_FAILED = 5111, /**< The data programmed into flash was not the same as the data received! */
+ A2_E_INVALID_NAND_PADMUX_SETTING = 5112, /**< The PADMUX configuration has not been set. */
+ A2_E_FLASH_DRIVER_FAILED_SET_BOOT_ADDR = 5113, /**< Failed to set the start boot address, this address are used to read the static data. */
+ A2_E_FLASH_BOOT_IS_NOT_EMPTY = 5114, /**< if the static data was not found, the flash should be empty! */
+ A2_E_BOOTIMAGE_PMC_NOT_NEEDED = 5115, /**< This error code informs that found boot container holds information that is not PMC protected. */
+ A2_E_UNSUPPORTED_PMC = 5116, /**< The PMC ID is not supported. */
+ A2_E_FSVN_VS_PMC = 5117, /**< The PMC ID is not coordinated with FSVN. */
+ A2_E_WRONG_PMC_START_COUNT = 5118, /**< PMC start count to high or zero. */
+ A2_E_UNSUITABLE_PMC_FOR_LOCATION = 5119, /**< Unsuitable PMC for the location. */
+ A2_E_PMC_MISSING = 5120, /**< The PMC can not be found. */
+ A2_E_VERSION_NOT_ACCEPTED = 5121, /**< FSVN is too low. */
+ A2_E_PMC_OVERFLOWN = 5122, /**< All steps of the PMC are destroyed. */
+ A2_E_PMC_ONCE_REQUIRED = 5123, /**< New version of once protected module attempted to be loaded without ARB flag set. */
+ A2_E_PMC_BAD_N_OF_STEPS = 5124, /**< Unsuitable number of steps within PMC. */
+ A2_E_UNIT_MISSING = 5125, /**< Dynamyc variable is missing. */
+ A2_E_UNIT_TO_BIG = 5126, /**< Dynamyc variable found is to big. */
+ A2_E_PARTMAN_READ_ERROR = 5127, /**< Error reading partition manger status. */
+ A2_E_PARTMAN_INIT_ERROR = 5128, /**< Error initializing partition manger. */
+ A2_E_BOOTIMAGE_INVALID_ALLIGNMENT = 5129, /**< Boot container size is not word alligned. */
+ A2_E_BOOTIMAGE_INSUFFICIENT_CONTAINERS = 5130, /**< Not enough boot containers are allocated. */
+ A2_E_BOOTIMAGE_INVALID_CONTAINER_TYPE = 5131, /**< Invalid boot container type. At this position other type of container is expected. */
+ A2_E_DATA_LENGTH_IS_NOT_ALIGNED = 5132, /**< The data size must be aligned to 512 bytes when reading or writing pages to/from the NAND. */
+ A2_E_LOADER_SWINIT_JTAG_UNLOCK_FAILED = 5133, /**< TEST JTAG EANBLENODEBUG. */
+ A2_E_BOOTIMAGE_RECORD_NOT_FOUND = 5134, /**< Required record is not found in the boot containers. */
+ A2_E_BUFFER_OVERFLOW = 5135, /**< Buffer overflow. */
+ A2_E_BUFFER_NOT_ALLOCATED = 5136, /**< Buffer has not been allocated. */
+ A2_E_WRONG_DATA_SIZE = 5137, /**< Size of data has an unexpected value. */
+ A2_E_NO_STATIC_DATA_IN_BOOTIMAGE = 5138, /**< Static data in boot record is corrupted. */
+ A2_E_NOT_ALLOWED_TO_FLASH = 5139, /**< Not allowed to flash this block. */
+ A2_E_UNABLE_TO_CHANGE_MMU_SETTINGS = 5140, /**< Unable to change MMU settings. */
+ A2_E_INVALID_HW_FOR_LOADER_SETTINGS = 5141, /**< Loader settings are not compatible with loader settings. */
+ A2_E_CABS_START_FAILED = 5142, /**< */
+ A2_E_CABS_READ_ERROR = 5143, /**< */
+ A2_E_CABS_WRITE_ERROR = 5144, /**< */
+ A2_E_ELF_DECODE_GENERAL_ERROR = 5145, /**< */
+ A2_E_ELF_INVALID_PARAMETER = 5146, /**< */
+ A2_E_PARTMAN_INIT_FAILED = 5147, /**< */
+ A2_E_PARTMAN_WRITE_FAILED = 5148, /**< */
+ A2_E_PARTMAN_READ_FAILED = 5149, /**< */
+ A2_E_PARTMAN_ERASE_ERROR = 5150, /**< */
+ A2_E_MBBS_CONFIG_ERROR = 5151, /**< */
+ A2_E_MBBS_READ_ERROR = 5152, /**< */
+ A2_E_MBBS_WRITE_ERROR = 5153, /**< */
+ A2_E_MBBS_ERASE_ERROR = 5154, /**< */
+ A2_E_FLASH_HW_CONFIG = 5155, /**< */
+ A2_E_VSP_IS_NOT_ALLOWED = 5156, /**< Virtual security partition is not allowed in this configuration. */
+ A2_E_VSP_WRITE_STATIC_DATA = 5157, /**< Failed to write static data to virtual security partition. */
+ A2_E_VSP_READ_STATIC_DATA = 5158, /**< Failed to read static data from virtual security partition. */
+ A2_E_VSP_NOT_FORMATED = 5159, /**< Virtual security partition is not initialized. */
+ A2_E_VSP_UNSUPPORTED_UNIT_TYPE = 5160, /**< Unit type is out of range in virtual security partition. */
+ A2_E_GET_DYNAMIC_DATA_FAILED = 5161, /**< Could not get the dynamic data from the security library. */
+ A2_E_FLASH_RESULT_PARTITION_TABLE_FLASHED = 5162, /**< Partition table repaired!! Please load file again. */
+ A2_E_FLASH_RESULT_PARTITION_TABLE_NOT_FLASHED = 5163, /**< Partition table is damaged! */
+ A2_E_FLASH_RESULT_READ_FROM_PARTITION_TABLE = 5164, /**< Partition table is damaged. */
+ A2_E_BOOTIMAGE_PARTITION_RECORD_NOT_FOUND = 5165, /**< Partition table record is not found in the boot containers. */
+ A2_E_CORRUPT_STATIC_DATA_IN_BOOT_BLOCK = 5166, /**< Static data in boot block is corrupt. */
+ A2_E_MBBS_BBM_TYPE_CONFLICT = 5167, /**< MBBS and BBM type conflict. */
+ A2_E_EXECUTION_NOT_PERMITTED = 5168, /**< Execution of this command is not allowed in the current domain with current authentication state. */
+ A2_E_EXECUTION_NOT_PERMITTED_WARNING = 5169, /**< Execution of this command is not allowed in the current domain with current authentication state. */
+ A2_E_UNABLE_TO_INITIALIZE_LCD = 5171, /**< Error during initialization of LCD drivers. */
+ A2_E_LCD_NOT_INITIALIZED = 5172, /**< LCD is not initialized. */
+ A2_E_UNABLE_TO_DISPLAY_DATA_ON_LCD = 5173, /**< Unrecoverable error during BMP image is processed. */
+ A2_E_NETWORK_BUFFER_CORRUPTED = 5174, /**< The network buffer area is corrupted. */
+ A2_E_TOO_MENY_FRAGMENTS = 5200, /**< */
+ A2_E_FAILED_TO_GET_APPLICATION = 5201, /**< */
+ A2_E_SECURITY_LIBRARY_ERROR_BEGIN = 9096, /**< */
+ A2_E_SECURITY_LIBRARY_ERROR_END = 9300, /**< */
+ A2_E_UNSUPPORTED_PROPERTY = 5301, /**< Unsupported file system property. */
+ A2_E_READ_ONLY = 5302, /**< The property is read only. */
+ A2_E_INVALLID_PROPERTY_SPECIFIED = 5303, /**< The specified property value was invalid. */
+ A2_E_ACCESS_DENIED = 5304, /**< The access permission attributes do not allow operation. */
+ A2_E_FORMATTING_FS = 5305, /**< The file system is formatting. */
+ A2_E_PATH_NOT_EXISTS = 5306, /**< The path does not exist. */
+ A2_E_PATH_ALREADY_EXISTS = 5307, /**< The path already exists. */
+ A2_E_PATH_READ_ONLY = 5308, /**< The path is read only. */
+ A2_E_INSUFFICENT_SPACE = 5309, /**< Insufficient space. */
+ A2_E_DIRECTORY_NOT_EMPTY = 5310, /**< The directory is not empty. */
+ A2_E_INVALID_RESTRICTION_SPECIFIED = 5311, /**< Invalid access restrictions specified. */
+ A2_E_NO_FILESYSTEM_PROPERTY = 5312, /**< No file system property. */
+ A2_E_FILE_NOT_EXISTS = 5313, /**< The file does not exist. */
+ A2_E_CHANGE_DIR = 5314, /**< Failed to change directory. */
+ A2_E_CHMOD = 5315, /**< Failed to set new CH mod. */
+ A2_E_GWD = 5316, /**< Failed to get the current directory. */
+ A2_E_OPEN_FILE = 5317, /**< Failed to open a file in the file system. */
+ A2_E_ITEM_STAT = 5318, /**< Failed to read the stat from file. */
+ A2_E_LIST_VOL = 5319, /**< Failed to list volumes. */
+ A2_E_FREE_SPACE = 5320, /**< No free space left. */
+ A2_E_CLOSE_FILE = 5321, /**< Failed to close a file in the filesystem. */
+ A2_E_CLOSE_DIRECTORY = 5322, /**< Failed to close the directory. */
+ A2_E_REMOVE_FILE = 5323, /**< Failed to remove a file from the filesystem. */
+ A2_E_RENAME_FILE = 5324, /**< Failed to rename a file in the filesystem. */
+ A2_E_CREATE_DIR = 5325, /**< Failed to create a new directory in the filesystem. */
+ A2_E_REMOVE_DIRECTORY = 5326, /**< Failed to remove a directory from the file system. */
+ A2_E_WRITE_FILE = 5327, /**< Failed to write a file to the file system. */
+ A2_E_INVALID_SFA_STATE = 5328, /**< The state of the SFA programming is incorrect. */
+ A2_E_READ_FILE = 5329, /**< Failed to read a file from the file system. */
+ A2_E_CORE_SUPERV = 61797, /**< */
+ A2_E_MEM_ALLOC = 66166, /**< */
+ A2_E_GDFS_UNSUPPORTED_PROPERTY = 5401, /**< Unsupported GDFS property. */
+ A2_E_GDFS_READ_ONLY = 5402, /**< The GDFS property is read only. */
+ A2_E_GDFS_PROPERTY_VALUE_INVALID = 5403, /**< The property value is invalid. */
+ A2_E_GDFS_INVALID_START_PROPERTY = 5404, /**< Invalid start property. */
+ A2_E_GDFS_NOT_STARTED = 5405, /**< GDFS has not been started yet. */
+ A2_E_GDFS_FAILED_TO_FORMAT = 5406, /**< Failed to format the GDFS area. */
+ A2_E_GDFS_NOT_FORMATTED = 5407, /**< GDFS is not formatted, as it should be. */
+ A2_E_GDFS_INVALID_BLOCK_UNIT_SPECIFIED = 5408, /**< Invalid Block unit number. */
+ A2_E_GDFS_NO_CONFIGURATION_FOUND = 5409, /**< Could not find any GDFS configuration from the platform software in flash. */
+ A2_E_GDFS_CLOSE = 5410, /**< Failed to close the GDFS area. */
+ A2_E_GDFS_OPEN = 5411, /**< Failed to open the GDFS area. */
+ A2_E_GDFS_INVALID_UNIT_SIZE = 5412, /**< Invalid GDFS UNIT size(size=0). */
+ A2_E_GDFS_WRITE_TO_UNIT_FAILED = 5413, /**< Failed to write to the specified unit. */
+ A2_E_GDFS_FAILED_TO_READ_FROM_UNIT = 5414, /**< Failed to read from the specified unit. */
+ A2_E_GDFS_EMPTY = 5415, /**< Failed read access on an empty GDFS. */
+ A2_E_GENERAL_FATAL_ERROR = 70535, /**< */
+ E_DUMMY_CODE = 80009 /**< */
+} ErrorCode_e;
+
+#endif /* _ERRORCODE_H */
diff --git a/source/LCM/include/t_a2_protocol.h b/source/LCM/include/t_a2_protocol.h
new file mode 100755
index 0000000..23add7e
--- /dev/null
+++ b/source/LCM/include/t_a2_protocol.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef INCLUSION_GUARD_T_A2_PROTOCOL_H
+#define INCLUSION_GUARD_T_A2_PROTOCOL_H
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup a2_family
+ * @{
+ * @addtogroup a2_protocol
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_command_protocol.h" // only for Buffer_t
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+typedef enum {
+ A2_COMMAND, /**< Command type of the packet.*/
+ A2_GENERAL_RESPONSE, /**< General response type of the packet.*/
+ A2_CONTROL_MESSAGE, /**< Control message protocol packet. */
+ A2_SPEEDFLASH_GR /**< Speedflash GR packet. */
+} A2_CommandType_t;
+
+/**
+ * Holds information for the command received from the transport layer.
+ */
+typedef struct A2_CommandData_s {
+ uint8 CommandNr; /**< Number of the command. */
+ uint8 ApplicationNr; /**< Number of the application (command) group. */
+ uint16 SessionNr; /**< Number of the session in which this command
+ was received. */
+ uint8 DestAddress; /**< Destination address ACC = 0x01, APP = 0x02 */
+ A2_CommandType_t Type; /**< Command type. */
+ Buffer_t Payload; /**< Holds the data received with the command.*/
+} A2_CommandData_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif // INCLUSION_GUARD_T_A2_PROTOCOL_H
diff --git a/source/LCM/include/t_basicdefinitions.h b/source/LCM/include/t_basicdefinitions.h
new file mode 100644
index 0000000..4d5b0ee
--- /dev/null
+++ b/source/LCM/include/t_basicdefinitions.h
@@ -0,0 +1,286 @@
+#ifndef INCLUSION_GUARD_T_BASICDEFINITIONS_H
+#define INCLUSION_GUARD_T_BASICDEFINITIONS_H
+
+/******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+*******************************************************************************
+*
+* $Workfile: t_basicdefinitions.h $
+*
+*******************************************************************************
+*
+* DESCRIPTION:
+*
+* Portable types used for a consistent target platform.
+* The name should make it totally clear as to what they are used for.
+*
+* For calculations:
+* -----------------
+* sint8 - signed integer 8 bits
+* uint8 - unsigned integer 8bits
+* sint16 - signed integer 16 bits
+* uint16 - unsigned integer 16 bits
+* sint32 - signed integer 32 bits
+* uint32 - unsigned integer 32 bits
+* MAX and MIN values for all integer types are also supported.
+*
+* Unsigned integer types for other purposes than calculations:
+* ------------------------------------------------------------
+* boolean - TRUE or FALSE
+*
+* Bitfield types to use in packed structs:
+* ----------------------------------------
+* sbitfield - signed bitfield
+* ubitfield - unsigned bitfield
+*
+* Bitmasks:
+* ---------
+* BIT_0 - unsigned integer of values 0x00000001
+* ...
+* BIT_31 - unsigned integer of values 0x80000000
+*
+* Enumeration:
+* ------------
+* TYPEDEF_ENUM - This macro should be used to start the defenition of a enumerated type
+* ENUM8(t) - uint8 enum
+* ENUM16(t) - uint16 enum
+* ENUM32(t) - uint32 enum
+* SIGNED_ENUM8(t) - sint8 enum
+* SIGNED_ENUM16(t) - sint16 enum
+* SIGNED_ENUM32(t) - sint32 enum
+*
+******************************************************************************/
+
+/********************
+* Include files
+*********************/
+
+#include "c_compiler.h"
+#include <limits.h>
+
+/********************
+* Portable data types
+*********************/
+
+#if defined(COMPILER_IAR_ARM) && (__VER__ >= 300)
+#define SINT64_SUPPORTED
+#define UINT64_SUPPORTED
+#define INT64_BASE_TYPE long long
+#elif defined(COMPILER_ARM_ARM)
+#define SINT64_SUPPORTED
+#define UINT64_SUPPORTED
+#define INT64_BASE_TYPE long long
+#elif defined(_WIN32)
+#define SINT64_SUPPORTED
+#define UINT64_SUPPORTED
+#define INT64_BASE_TYPE __int64
+#elif defined(__linux__)
+#define SINT64_SUPPORTED
+#define UINT64_SUPPORTED
+#define INT64_BASE_TYPE long long
+#else
+#error "Unknown platform"
+#endif
+
+
+/** Type definition for a signed 8 bit data entity. */
+typedef signed char sint8;
+/** Type definition for an unsigned 8 bit data entity. */
+typedef unsigned char uint8;
+/** Type definition for a signed 16 bit data entity. */
+typedef signed short sint16;
+/** Type definition for an unsigned 16 bit data entity. */
+typedef unsigned short uint16;
+/** Type definition for a signed 32 bit data entity. */
+typedef signed int sint32;
+/** Type definition for an unsigned 32 bit data entity. */
+#if defined(_WIN32)
+typedef unsigned long uint32;
+#else
+typedef unsigned int uint32;
+#endif
+
+/**
+ * Type definition for a signed 64 bit data entity. Only available if the switch
+ * SINT64_SUPPORTED is defined.
+ */
+#ifdef SINT64_SUPPORTED
+typedef signed INT64_BASE_TYPE sint64;
+#endif
+
+/**
+ * Type definition for an unsigned 64 bit data entity. Only available if the
+ * switch UINT64_SUPPORTED is defined.
+ */
+#ifdef UINT64_SUPPORTED
+typedef unsigned INT64_BASE_TYPE uint64;
+#endif
+
+/*******************
+* MAX and MIN values
+********************/
+/** Minimum value for an entity of type sint8 */
+#define MIN_SINT8 (SCHAR_MIN)
+/** Maximum value for an entity of type sint8 */
+#define MAX_SINT8 (SCHAR_MAX)
+/** Maximum value for an entity of type uint8 */
+#define MAX_UINT8 (UCHAR_MAX)
+/** Minimum value for an entity of type sint16 */
+#define MIN_SINT16 (SHRT_MIN)
+/** Maximum value for an entity of type sint16 */
+#define MAX_SINT16 (SHRT_MAX)
+/** Maximum value for an entity of type uint16 */
+#define MAX_UINT16 (USHRT_MAX)
+/** Minimum value for an entity of type sint32 */
+#define MIN_SINT32 (LONG_MIN)
+/** Maximum value for an entity of type sint32 */
+#define MAX_SINT32 (LONG_MAX)
+/** Maximum value for an entity of type uint32 */
+#define MAX_UINT32 (ULONG_MAX)
+
+
+#ifdef SINT64_SUPPORTED
+/**
+ * Minimum value for an entity of type sint64. Only available if the switch
+ * SINT64_SUPPORTED is defined.
+ */
+#define MIN_SINT64 (-0x8000000000000000)
+/**
+ * Maximum value for an entity of type sint64. Only available if the switch
+ * SINT64_SUPPORTED is defined.
+ */
+#define MAX_SINT64 (0x7fffffffffffffff)
+#endif
+
+#ifdef UINT64_SUPPORTED
+/**
+ * Maximum value for an entity of type uint64. Only available if the switch
+ * UINT64_SUPPORTED is defined.
+ */
+#define MAX_UINT64 (0xffffffffffffffff)
+#endif
+
+/********************
+* boolean: TRUE/FALSE
+*********************/
+/** Type definition for a boolean/logical value */
+typedef uint8 boolean;
+
+#ifndef TRUE
+/** Value representing the boolean/logical value false. */
+#define FALSE 0
+/** Value representing the boolean/logical value true. */
+#define TRUE (!FALSE)
+#endif
+
+/******************************************
+* Portable bitfield definitions
+*******************************************/
+
+#if defined(COMPILER_IAR_AVR) || defined(COMPILER_IAR_ARM) || defined(_WIN32) || defined(COMPILER_ARM_ARM) || defined(COMPILER_GNUC)
+/** Type definition to be used when implementing bit-fields that should hold
+ * signed values.
+ */
+typedef sint8 sbitfield;
+/** Type definition to be used when implementing bit-fields that should hold
+ * unsigned values.
+ */
+typedef uint8 ubitfield;
+#elif defined(_lint)
+typedef signed int sbitfield;
+typedef unsigned int ubitfield;
+#else
+#error Unknown preferred bitfield definition for this compiler
+#endif
+
+/*************************
+* Bit mask definitions
+**************************/
+
+/**
+* This sections defines a set of masks implemented as scalar unsigned values
+* that can be used to mask out bits of a scalar entity. The definitions are
+* named BIT_0 through BIT_31 and each implements the unsigned value of two to
+* the power of the value in the definitions name. E.g. BIT_0 implements the value of 1 while BIT_10 implements the value of 0x0400 (equals 1024 in decimal form).
+*/
+#define BIT_0 0x0001U
+#define BIT_1 0x0002U
+#define BIT_2 0x0004U
+#define BIT_3 0x0008U
+#define BIT_4 0x0010U
+#define BIT_5 0x0020U
+#define BIT_6 0x0040U
+#define BIT_7 0x0080U
+#define BIT_8 0x0100U
+#define BIT_9 0x0200U
+#define BIT_10 0x0400U
+#define BIT_11 0x0800U
+#define BIT_12 0x1000U
+#define BIT_13 0x2000U
+#define BIT_14 0x4000U
+#define BIT_15 0x8000U
+#define BIT_16 0x00010000UL
+#define BIT_17 0x00020000UL
+#define BIT_18 0x00040000UL
+#define BIT_19 0x00080000UL
+#define BIT_20 0x00100000UL
+#define BIT_21 0x00200000UL
+#define BIT_22 0x00400000UL
+#define BIT_23 0x00800000UL
+#define BIT_24 0x01000000UL
+#define BIT_25 0x02000000UL
+#define BIT_26 0x04000000UL
+#define BIT_27 0x08000000UL
+#define BIT_28 0x10000000UL
+#define BIT_29 0x20000000UL
+#define BIT_30 0x40000000UL
+#define BIT_31 0x80000000UL
+
+/*****************************
+* Macro's for fixed size enums
+*
+* Example of use:
+*
+* TYPEDEF_ENUM {
+* Def1,
+* ...,
+* Defn
+* }ENUM8 (MyEnum_t); // Or ENUM16 or ENUM32
+*
+******************************/
+/** This macro should be used to start the definition of an enumerated type. */
+#define TYPEDEF_ENUM enum
+/**
+ * This macro should be used to finalize the definition of an enumerated type
+ * "t" compatible with the uint8 data type described in section 3.1.1.
+ */
+#define ENUM8(t) ;typedef uint8 t
+/**
+ * This macro should be used to finalize the definition of an enumerated type
+ * "t" compatible with the uint16 data type described in section 3.1.1.
+ */
+#define ENUM16(t) ;typedef uint16 t
+/**
+ * This macro should be used to finalize the definition of an enumerated type
+ * "t" compatible with the uint32 data type described in section 3.1.1.
+ */
+#define ENUM32(t) ;typedef uint32 t
+/**
+ * This macro should be used to finalize the definition of an enumerated type
+ * "t" compatible with the sint8 data type described in section 3.1.1.
+ */
+#define SIGNED_ENUM8(t) ;typedef sint8 t
+/**
+ * This macro should be used to finalize the definition of an enumerated type
+ * "t" compatible with the sint16 data type described in section 3.1.1.
+ */
+#define SIGNED_ENUM16(t) ;typedef sint16 t
+/**
+ * This macro should be used to finalize the definition of an enumerated type
+ * "t" compatible with the sint32 data type described in section 3.1.1.
+ */
+#define SIGNED_ENUM32(t) ;typedef sint32 t
+
+#endif // INCLUSION_GUARD_T_BASICDEFINITIONS_H
+
diff --git a/source/LCM/include/t_bulk_protocol.h b/source/LCM/include/t_bulk_protocol.h
new file mode 100644
index 0000000..fabc1a4
--- /dev/null
+++ b/source/LCM/include/t_bulk_protocol.h
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _T_BULK_PROTOCOL_H_
+#define _T_BULK_PROTOCOL_H_
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup r15_family
+ * @{
+ * @addtogroup bulk_protocol
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_basicdefinitions.h"
+#include "t_r15_network_layer.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+/** Maximum bulk processes used in transport layer. */
+#define MAX_BULK_TL_PROCESSES 16
+
+/** Mask for selecting the TYPE bits in type/flags field */
+#define MASK_BULK_COMMAND_SELECT (0x07)
+
+/** Defined bulk error in 32 bits format. */
+#define BULK_ERROR 0xffffffff
+/** Defined bulk error in 64 bits format. */
+#define BULK_ERROR_64 0xffffffffffffffff
+
+/** Defined Callback functions used for bulk transfer in the LCM on PC side. */
+typedef void (*BulkCommandReqCallback_t)(void *Object_p, uint16 *Session_p, uint32 *ChunkSize_p, uint64 *Offset_p, uint32 *Length_p, boolean ACK_Read);
+typedef void(*BulkDataReqCallback_t)(void *Object_p, uint16 *Session_p, uint32 *ChunkSize_p, uint64 *Offset_p, uint32 *Length_p, uint64 *TotalLength_p, uint32 *TransferedLength_p);
+typedef void(*BulkDataEndOfDump_t)(void *Object_p);
+
+
+/** Defined bulk commands. */
+typedef enum {
+ CMD_BULK_STATUS = 0x00, /**< Status packet type command. */
+ CMD_BULK_READ = 0x01, /**< Read packet type command. */
+ CMD_BULK_DATA = 0x02, /**< Data packet type command. */
+ CMD_BULK_WRITE = 0x03 /**< Write packet type command. */
+} TL_BulkCmmands_t;
+
+/** Defined bulk session ID status. */
+typedef enum {
+ BULK_SESSION_INVALID = 0x00, /**< Received packet with invalid session ID.*/
+ BULK_SESSION_NEW = 0x01, /**< Received packet with new session ID.*/
+ BULK_SESSION_CURRENT = 0x02 /**< Received packet with current session ID.*/
+} TL_BulkSessionID_Status_t;
+
+/** States of bulk protocol. */
+TYPEDEF_ENUM {
+ BULK_IDLE_STATE = 0, /**< Idle state. */
+ SEND_READ_REQUEST = 1, /**< Send read request command to PC. */
+ WAIT_CHUNKS = 2, /**< Wait to receive all expected chunks. */
+ SEND_BULK_ACK = 3, /**< Send bulk acknowledge to PC. */
+ WAIT_BULK_ACK_TIMEOUT = 4, /**< Wait timeout for confirmation of bulk
+ ack command. */
+ SEND_WRITE_REQUEST = 5, /**< Send write request command. */
+ WAIT_READ_REQUEST = 6, /**< Wait read request from PC. */
+ SENDING_CHUNKS = 7, /**< Send chunks to PC. */
+ WAIT_BULK_ACK = 8, /**< Wait bulk acknowledge to PC. */
+ WRITE_BULK_FINISH = 9, /**< Bulk acknowledge has been received,
+ finish the write bulk process. */
+ WAIT_WRITE_REQUEST = 10 /**< Wait bulk request command. */
+} ENUM8(TL_BulkProtocolState_t);
+
+/** Defined bulk process states. */
+TYPEDEF_ENUM {
+ BULK_SESSION_IDLE = 0x00, /**< Bulk transfer is closed and ready
+ for starting. */
+ BULK_SESSION_OPEN = 0x01, /**< Bulk transfer is opened. */
+ BULK_SESSION_PROCESSING = 0x02, /**< Processing the bulk transfer. */
+ BULK_SESSION_FINISHED = 0x04, /**< Bulk transfer is finished. */
+} ENUM8(TL_BulkSessionState_t);
+
+/** Bulk session Mode. */
+typedef enum {
+ BULK_RECEIVE = 1, /**< Receiving Mode. */
+ BULK_SEND = 2, /**< Transmitting Mode. */
+ BULK_RS = 3, /**< Receiving and transmitting Mode. */
+} TL_SessionMode_t;
+
+/**
+ * Status of received chunks in the current session.
+ */
+typedef enum {
+ /**< Chunks are being received in order in current session. */
+ VECTOR_NOT_COMPLETE = 0,
+ /**< All chunks for the current session have been received. */
+ VECTOR_COMPLETE = 1,
+ /**< Missing chunk(s) in the current session. */
+ VECTOR_MISSING_CHUNK = 2,
+} TL_BulkVectorStatus_t;
+
+/**
+ * Bulk Vector Entry parameters
+ */
+typedef struct {
+ PacketMeta_t *Buffer_p; /**< Pointer to reserved buffer meta info. */
+ uint8 *Payload_p; /**< Pointer to payload data in reserved
+ buffer. */
+ uint8 *Hash_p; /**< Pointer to calculated payload hash. */
+} TL_BulkVectorEntry_t;
+
+/**
+ * This type defines Bulk Vector parameters
+ */
+typedef struct {
+ /**< Bulk session status. */
+ TL_BulkSessionState_t Status;
+ /**< Requested bulk process(Read or Write). */
+ TL_SessionMode_t Mode;
+ /**< State of bulk protocol state machine. */
+ TL_BulkProtocolState_t State;
+ /**< Current bulk session ID. */
+ uint16 SessionId;
+ /**< Length of the file transfered with bulk transfer. */
+ uint64 TotalLength;
+ /**< Length of payload data transfered with bulk transfer. */
+ uint32 Length;
+ /**< Number of used buffers for bulk transfer. */
+ uint32 Buffers;
+ /**< requested size of payload. */
+ uint32 ChunkSize;
+ /**< Offset in the cuurent opened file.*/
+ uint64 Offset;
+ /**< Length of payload data transfered with bulk transfer. */
+ uint32 TransferedLength;
+ /**< Callback function pointer for bulk command handling.*/
+ void *BulkCommandCallback_p;
+ /**< Callback function pointer for bulk data command handling.*/
+ void *BulkDataCallback_p;
+ /**< Array with information for used buffers. */
+ TL_BulkVectorEntry_t Entries[MAX_BULK_TL_PROCESSES];
+} TL_BulkVectorList_t;
+
+/** Structure for current bulk transfer handling. */
+typedef struct {
+ uint32 TimerKey; /**< Timer Id for current used timer. */
+ TL_BulkVectorList_t *BulkVector_p; /**< Current used bulk vector for bulk
+ transfer.*/
+} BulkHandle_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif /*_T_BULK_PROTOCOL_H_*/
diff --git a/source/LCM/include/t_command_protocol.h b/source/LCM/include/t_command_protocol.h
new file mode 100644
index 0000000..2ca51c6
--- /dev/null
+++ b/source/LCM/include/t_command_protocol.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _T_COMMAND_PROTOCOL_H_
+#define _T_COMMAND_PROTOCOL_H_
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup r15_family
+ * @{
+ * @addtogroup command_protocol
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_basicdefinitions.h"
+#include "error_codes.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+/**
+ * The command type. COMMAND and GENERAL_RESPONSE can be used to
+ * indicate what type of commands to send. The _ACK command types are
+ * used internally to provide end-to-end reliability.
+ */
+typedef enum {
+ COMMAND_TYPE, /**< Command type of the packet.*/
+ COMMAND_ACK, /**< Acknwoledge type of the packet.*/
+ GENERAL_RESPONSE, /**< General response type of the packet.*/
+ GENERAL_RESPONSE_ACK /**< General response acknwoledge type of the packet.*/
+} CommandType_t;
+
+
+/**
+ * Used for storing input and output Payload data.
+ */
+typedef struct Buffer_s {
+ uint32 Size; /**< Size of the buffer in bytes.*/
+ uint8 *Data_p; /**< Data buffer. */
+} Buffer_t;
+
+/**
+ * Used for storing the status of the general response send by the
+ * command and for storing the data that should be send with the
+ * general response.
+ */
+typedef struct Result_s {
+ ErrorCode_e Status; /**< Status send by the general response. */
+ Buffer_t *Response_p; /**< Buffer holding data that should be
+ returned trough the general response */
+} Result_t;
+
+/**
+ * Holds information for the command received from the transport layer.
+ */
+typedef struct CommandData_s {
+ uint8 CommandNr; /**< Number of the command. */
+ uint8 ApplicationNr;/**< Number of the application (command) group. */
+ uint16 SessionNr; /**< Number of the session in which this command
+ was received.*/
+ CommandType_t Type; /**< Command type. */
+ Buffer_t Payload; /**< Holds the data received with the command.*/
+} CommandData_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif /*_T_COMMAND_PROTOCOL_H_*/
diff --git a/source/LCM/include/t_communication_service.h b/source/LCM/include/t_communication_service.h
new file mode 100644
index 0000000..74e72a9
--- /dev/null
+++ b/source/LCM/include/t_communication_service.h
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _INCLUSION_GUARD_T_COMMUNICATION_SERVICE_H_
+#define _INCLUSION_GUARD_T_COMMUNICATION_SERVICE_H_
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ *
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "c_system.h"
+#include "t_basicdefinitions.h"
+#include "error_codes.h"
+#include "t_security_algorithms.h"
+#include "t_command_protocol.h"
+#include "t_queue.h"
+#include "t_time_utilities.h"
+
+#ifndef CFG_ENABLE_LOADER_TYPE
+#ifdef WIN32
+#include <windows.h>
+#endif
+#endif
+
+
+/*******************************************************************************
+ * Types, constants and external variables
+ ******************************************************************************/
+/* Defined protocol families */
+typedef enum {
+ R15_FAMILY = 0, /*< R15 protocol family. */
+ A2_FAMILY = 1, /*< A2 protocol family. */
+#ifndef CFG_ENABLE_LOADER_TYPE
+ TI_FAMILY = 2, /*< TI protocol family. */
+ PROTROM_FAMILY = 3, /*< PROTROM protocol family. */
+ Z_FAMILY = 4 /*< Z protocol family. */
+#endif
+} Family_t;
+
+typedef void (*CommunicationCallback_t)(const void *Data_p, const uint32 Length, void *Param_p);
+typedef void (*HashCallback_t)(void *Data_p, const uint32 Length, uint8 *Hash_p, void *Param_p);
+typedef boolean(*DeviceRead_fn)(void *Data_p, uint32 Length, CommunicationCallback_t Callback_fn, void *Param_p);
+typedef ErrorCode_e(*DeviceWrite_fn)(void *Data_p, uint32 Length, CommunicationCallback_t Callback_fn, void *Param_p);
+typedef ErrorCode_e(*DeviceCancel_fn)(void *Param_p);
+typedef void (*HashDeviceCancel_fn)(void *Object_p, void **Param_p);
+typedef void (*DeviceCalculate_fn)(void *Object_p, HashType_e Type, void *Data_p, const uint32 Length, uint8 *Hash_p, HashCallback_t Callback_fn, void *Param_p);
+
+/** definition of Buffer interface functions */
+typedef ErrorCode_e(*BuffersInit_t)(void *Object_p);
+typedef void *(*BufferAllocate_t)(void *Object_p, int BufferSize);
+typedef ErrorCode_e(*BufferRelease_t)(void *Object_p, void *Buffer_p, int BufferSize);
+typedef uint32(*BuffersAvailable_t)(void *Object_p, int BufferSize);
+typedef void (*BuffersDeinit_t)(void *Object_p);
+
+
+/** definition of Timer interface functions */
+typedef ErrorCode_e(*TimersInit_t)(void *Object_p, uint32 Timers);
+typedef uint32(*TimerGet_t)(void *Object_p, Timer_t *Timer_p);
+typedef ErrorCode_e(*TimerRelease_t)(void *Object_p, uint32 TimerKey);
+typedef uint32(*ReadTime_t)(void *Object_p, uint32 TimerKey);
+typedef uint32(*GetSystemTime_t)(void *Object_p);
+
+/** definition of Queue interface functions */
+typedef void (*FifoCreate_t)(void *Object_p, void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *Element_p));
+typedef void (*FifoDestroy_t)(void *Object_p, void **const Queue_pp);
+typedef ErrorCode_e(*FifoEnqueue_t)(void *Object_p, void *const Queue_p, void *const Value_p);
+typedef void *(*FifoDequeue_t)(void *Object_p, void *const Queue_p);
+typedef QueueCallback_fn(*Fifo_SetCallback_t)(void *Object_p, void *const Queue_p,
+ const QueueCallbackType_e Type,
+ const QueueCallback_fn Callback,
+ void *const Param_p);
+typedef boolean(*Fifo_IsEmpty_t)(void *Object_p, const void *const Queue_p);
+typedef boolean(*Fifo_IsMember_t)(void *Object_p, const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p));
+typedef int (*Fifo_GetNrOfElements_t)(void *Object_p, const void *const Queue_p);
+
+typedef void (*RFifoCreate_t)(void *Object_p, void **const Queue_pp, const uint32 MaxLength, void (*DestroyElement)(void *Element_p));
+typedef void (*RFifoDestroy_t)(void *Object_p, void **const Queue_pp);
+typedef ErrorCode_e(*RFifoEnqueue_t)(void *Object_p, void *const Queue_p, void *const Value_p);
+typedef void *(*RFifoDequeue_t)(void *Object_p, void *const Queue_p);
+typedef QueueCallback_fn(*RFifo_SetCallback_t)(void *Object_p, void *const Queue_p,
+ const QueueCallbackType_e Type,
+ const QueueCallback_fn Callback,
+ void *const Param_p);
+typedef boolean(*RFifo_IsEmpty_t)(void *Object_p, const void *const Queue_p);
+typedef boolean(*RFifo_IsMember_t)(void *Object_p, const void *const Queue_p, void *Value_p, boolean(*Match)(void *Value1_p, void *Value2_p));
+typedef int (*RFifo_GetNrOfElements_t)(void *Object_p, const void *const Queue_p);
+
+typedef ErrorCode_e(*Do_CEH_Call_t)(void *Object_p, CommandData_t *CmdData_p);
+
+
+/** Structure with pointers to buffer interface functions */
+typedef struct {
+ BuffersInit_t BuffersInit_Fn; /**< Pointer to function for Buffers
+ initialization. */
+ BufferAllocate_t BufferAllocate_Fn; /**< Pointer to function for Buffer
+ allocation. */
+ BufferRelease_t BufferRelease_Fn; /**< Pointer to function for Buffer
+ releasing.*/
+ BuffersAvailable_t BuffersAvailable_Fn; /**< Pointer to function for check
+ for available buffers with
+ specified size of buffers. */
+ BuffersDeinit_t BuffersDeinit_Fn; /**< Pointer to function for Buffers
+ de-initialization. */
+ void *Object_p; /**< Pointer for instancing. It is
+ used in the PC application, but
+ in the loaders is always NULL */
+} BuffersInterface_t;
+
+
+/** Structure with pointers to timer interface functions */
+typedef struct {
+ TimersInit_t TimersInit_Fn; /**< Pointer to function for Timers
+ initialization. */
+ TimerGet_t TimerGet_Fn; /**< Pointer to function for creating and
+ starting timer. */
+ TimerRelease_t TimerRelease_Fn; /**< Pointer to function for removing
+ defined timer. */
+ ReadTime_t ReadTime_Fn; /**< Pointer to function for read time from
+ specified timer. */
+ GetSystemTime_t GetSystemTime_Fn; /**< Pointer to function for read curent
+ sytem time. */
+ void *Object_p; /**< Pointer for instancing. It is used in
+ the PC application, but in the loaders
+ is always NULL */
+} TimersInterface_t;
+
+/** Structure with pointers to queue interface functions */
+typedef struct {
+ FifoCreate_t FifoCreate_Fn; /**< Pointer to function
+ for Fifo creating.*/
+ FifoDestroy_t FifoDestroy_Fn; /**< Pointer to function
+ for Fifo destroying.*/
+ FifoEnqueue_t FifoEnqueue_Fn; /**< Pointer to function
+ for enqueue packet in
+ the fifo. */
+ FifoDequeue_t FifoDequeue_Fn; /**< Pointer to function
+ for dequeue packet
+ from the fifo. */
+ Fifo_SetCallback_t Fifo_SetCallback_Fn; /**< Pointer to function
+ for registers an event
+ listener for the
+ specified queue.*/
+ Fifo_IsEmpty_t Fifo_IsEmpty_Fn; /**< Pointer to function
+ for check, is Fifo
+ empty.*/
+ Fifo_IsMember_t Fifo_IsMember_Fn; /**< Pointer to function
+ for Checks if the
+ provided element is
+ member of the fifo*/
+ Fifo_GetNrOfElements_t Fifo_GetNrOfElements_Fn; /**< Pointer to function
+ for reading the number
+ of elements in the
+ Fifo.*/
+
+ RFifoCreate_t RFifoCreate_Fn; /**< Pointer to function
+ for Fifo creating.
+ First all interrupts
+ are disabled,
+ function executed and
+ then all interrupt
+ enabled. */
+ RFifoDestroy_t RFifoDestroy_Fn; /**< Pointer to function
+ for Fifo destroing.
+ First all interrupts
+ are disabled,
+ function executed and
+ then all interrupt
+ enabled. */
+ RFifoEnqueue_t RFifoEnqueue_Fn; /**< Pointer to function
+ for enqueue packet in
+ the fifo. First all
+ interrupts are
+ disabled, function
+ executed and then all
+ interrupt enabled. */
+ RFifoDequeue_t RFifoDequeue_Fn; /**< Pointer to function
+ for dequeue packet
+ from the fifo. First
+ all interrupts are
+ disabled, function
+ executed and then all
+ interrupt enabled. */
+ RFifo_SetCallback_t RFifo_SetCallback_Fn; /**< Pointer to function
+ for setting two
+ callback functions
+ used by the FIFO.
+ First all interrupts
+ are disabled,
+ function executed and
+ then all interrupt
+ enabled. */
+ RFifo_IsEmpty_t RFifo_IsEmpty_Fn; /**< Pointer to function
+ for for check, is Fifo
+ empty. First all
+ interrupts are
+ disabled, function
+ executed and then all
+ interrupt enabled. */
+ RFifo_IsMember_t RFifo_IsMember_Fn; /**< Pointer to function
+ for checks if the
+ provided element is
+ member of the fifo.
+ First all interrupts
+ are disabled,
+ function executed and
+ then all interrupt
+ enabled. */
+ RFifo_GetNrOfElements_t RFifo_GetNrOfElements_Fn; /**< Pointer to function
+ for reading the number
+ of elements in the
+ Fifo. First all
+ interrupts are
+ disabled, function
+ executed and then all
+ interrupt enabled. */
+ void *Object_p; /**<Pointer for instancing.
+ It is used in the PC
+ application, but in the
+ loaders is always NULL.*/
+} QueueInterface_t;
+
+/**
+ * Interface structures for buffers, timers and queue.
+ * Structure contain all interface functions for buffers, timers and
+ * queue manipulating.
+ */
+typedef struct {
+ BuffersInterface_t *BufferFunctions_p; /**< Pointer to buffer interface
+ structure. */
+ QueueInterface_t *QueueFunctions_p; /**< Pointer to queue interface
+ structure. */
+ TimersInterface_t *TimerFunctions_p; /**< Pointer to timers interface
+ structure. */
+} FunctionInterface_t;
+
+/**
+ * Interface structure for communication device.
+ * Structure contain all functions for communication device manipulating.
+ */
+typedef struct {
+ DeviceRead_fn Read; /**< Pointer to function for read data from
+ communication device. */
+ DeviceWrite_fn Write; /**< Pointer to function for write data thru the
+ communication device. */
+ DeviceCancel_fn Cancel; /**< Pointer to function for caneling current
+ communcation with communiation device. */
+ void *Context_p; /**< Pointer to Device description data. */
+} CommunicationDevice_t;
+
+/**
+ * Interface structure for HASH device.
+ * Structure contain all functions for HASH device manipulating.
+ */
+typedef struct {
+ DeviceCalculate_fn Calculate; /**< Pointer to function for calculation. */
+ HashDeviceCancel_fn Cancel; /**< Pointer to function for cancel of
+ calculation. */
+ void *Object_p; /**< Pointer for instancing. It is used in the
+ PC application, but in the loaders is
+ always NULL.*/
+} HashDevice_t;
+
+/**
+ * Holds information about a command that is placed (or will be placed) in
+ * the command execution queue.
+ */
+typedef struct ExecutionContext_s {
+ void *Command_p; /**< Pointer to command register structure
+ containing information for initialization
+ and execution of the command.*/
+ void *LocalState_p; /**< If needed holds information internal to the
+ command, else it is NULL.*/
+ boolean Running; /**< Indicates the state of the command that is
+ registered in the Command Execution Service.*/
+ CommandData_t Received; /**< Holds data for the received command. */
+ Result_t Result; /**< Pointer to structure that holds command
+ status and command data, including payload
+ or output data.*/
+ uint32 Progress; /**< Command completed in percent. */
+} ExecutionContext_t;
+
+
+/** Communication context.*/
+typedef struct {
+ void *Inbound_p; /**< Pointer to structure for
+ handling incomming
+ packets.*/
+ void *Outbound_p; /**< Pointer to structure for
+ handling outgoing
+ packets.*/
+ HashDevice_t *HashDevice_p; /**< Pointer to Hash device
+ descriptor. */
+ CommunicationDevice_t *CommunicationDevice_p; /**< Pointer to Communication
+ device descriptor. */
+ struct FamilyDescriptor_s *Family_p; /**< Pointer to interface
+ structure for protocol
+ family. */
+ void *FamilyContext_p; /**< Pointer to current
+ protocol family context.*/
+ uint8 *BackupCommBuffer_p; /**< Pointer to backup
+ buffer.*/
+ uint32 BackupCommBufferSize; /**< Size of the backup
+ buffer.*/
+ FunctionInterface_t *Functions_p; /**< Pointer to interface
+ functions for buffers,
+ timers and queue.*/
+ Do_CEH_Call_t Do_CEH_Call_Fn; /**< Pointer to calback
+ function for handling
+ commands received thru
+ the LCM.*/
+ void *Object_p; /**< Pointer for instancing.
+ It is used in the PC
+ application, but in the
+ loaders is always NULL.*/
+ HashType_e CurrentFamilyHash; /**< Hashing algorithm that
+ is used by the family
+ which is active at the
+ moment. */
+} Communication_t;
+
+/** Structure for initialization and manipulation of protocol family */
+typedef struct FamilyDescriptor_s {
+ ErrorCode_e(*FamilyInit_fn)(Communication_t *Communication_p);
+ /**< Pointer to Interface function for protocol family initialization. */
+ ErrorCode_e(*FamilyShutdown_fn)(Communication_t *Communication_p);
+ /**< Pointer to Interface function for protocol family de-initialization. */
+ ErrorCode_e(*Process_fn)(Communication_t *Communication_p);
+ /**< Pointer to Pooling function in curren protocol family. */
+ ErrorCode_e(*Send_fn)(Communication_t *Communication_p, void *InputData_p);
+ /**< Pointer to function for sending packets.*/
+ ErrorCode_e(*SetProtocolTimeouts_fn)(Communication_t *Communication_p, void *TimeoutData_p);
+ /**< Pointer to function for setting communication timeouts for current protocol family. */
+ ErrorCode_e(*GetProtocolTimeouts_fn)(Communication_t *Communication_p, void *TimeoutData_p);
+ /**< Pointer to function for getting communication timeouts from current protocol family. */
+} FamilyDescriptor_t;
+
+/** @} */
+#endif // _INCLUSION_GUARD_T_COMMUNICATION_SERVICE_H_
+
diff --git a/source/LCM/include/t_protrom_header.h b/source/LCM/include/t_protrom_header.h
new file mode 100644
index 0000000..63ae6ef
--- /dev/null
+++ b/source/LCM/include/t_protrom_header.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef T_PROTROM_HEADER_H_
+#define T_PROTROM_HEADER_H_
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup protrom_family
+ * @{
+ * @addtogroup ldr_protrom_header
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_basicdefinitions.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+/** Header pattern for the protrom protocol*/
+#define PROTROM_HEADER_PATTERN (0xAA)
+/** Source address in the header*/
+#define PROTROM_SOURCE_ADDRESS (0xEE)
+/** Destination address in the header*/
+#define PROTROM_DESTINATION_ADDRESS (0xEE)
+/** The length of the header */
+#define PROTROM_HEADER_LENGTH 7
+/** Value of the reserved field */
+#define PROTROM_RESERVED_FIELD 0x00
+/** Offset of the header in the buffer */
+#define HEADER_OFFSET_IN_BUFFER 8
+
+/**
+ * Header search results
+ */
+#define NO_PROTROM_HEADER_PATTERN (0x00)
+#define PROTROM_HEADER_PATTERN_MATCH (0x01)
+#define PROTROM_HEADER_PATTERN_CANDIDATE (0x02)
+
+/** Protocol types*/
+typedef enum {
+ PROTO_PROTROM = 0xFB, /**< PROTROM protocol identification number. */
+} Protrom_Protocol_t;
+
+/** Header for command and bulk protocol */
+typedef struct {
+ uint8 HeaderPattern; /**< Header pattern for marking header start.*/
+ uint8 Protocol; /**< Protocol type. */
+ uint8 SourceAddress; /**< Source address. */
+ uint8 DestinationAddress; /**< Destionation address. */
+ uint8 ReservedField; /**< Reserved field. */
+ uint16 PayloadLength; /**< Payload length. */
+} Protrom_Header_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif /*T_PROTROM_HEADER_H_*/
diff --git a/source/LCM/include/t_protrom_network.h b/source/LCM/include/t_protrom_network.h
new file mode 100644
index 0000000..c33deac
--- /dev/null
+++ b/source/LCM/include/t_protrom_network.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef T_PROTROM_NETWORK_H_
+#define T_PROTROM_NETWORK_H_
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup protrom_family
+ * @{
+ * @addtogroup ldr_protrom_network_layer
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_communication_service.h"
+#include "t_protrom_header.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+/** PROTROM protocol ID */
+#define PROTROM_PROTOCOL (0xFB)
+/** PROTROM CRC length */
+#define PROTROM_CRC_LENGTH (2)
+
+/** Defined state of the receiver */
+typedef enum {
+ PROTROM_RECEIVE_HEADER, /**< State for receiving Header.*/
+ PROTROM_RECEIVE_PAYLOAD, /**< State for receiving Payload.*/
+ PROTROM_RECEIVE_ERROR /**< State for error handling.*/
+} Protrom_InboundState_t;
+
+/** Defined state of the transmitter */
+typedef enum {
+ PROTROM_SEND_IDLE, /**< Transmiter idle state.*/
+ PROTROM_SEND_PACKET, /**< Transmiter send packet. */
+ PROTROM_SENDING_PACKET /**< Transmiter is in process sending packet.*/
+} Protrom_OutboundState_t;
+
+/** Structure for the packet meta data type. */
+typedef struct Protrom_Packet {
+ Protrom_Header_t Header; /**< PROTROM header structure. */
+ uint8 *Buffer_p; /**< Temporary buffer for receiving data.*/
+ uint16 CRC; /**< Calculated CRC of received packet. */
+ Communication_t *Communication_p; /**< The communication over which this
+ packet has been/is to be transferred
+ over */
+} Protrom_Packet_t;
+
+/** Structure for handling incoming PROTROM packets.*/
+typedef struct {
+ /**< State of the state machine for handling incoming PROTROM packets. */
+ Protrom_InboundState_t State;
+ /**< Number of requested data for receiving from communication device. */
+ uint32 ReqData;
+ /**< Number of receivied data from communication device. */
+ uint32 RecData;
+ /**< Number of receivied data from backup buffer used for switching the
+ * protocol family. */
+ uint32 RecBackupData;
+ /**< Offset in the buffer for next data that should be received. */
+ uint32 ReqBuffOffset;
+ /**< Temporary pointer to buffer for handling received data.*/
+ uint8 *Target_p;
+ /**< Temporary buffer for receiving data. */
+ uint8 Scratch[PROTROM_HEADER_LENGTH];
+ /** Temporary structure for handling PROTROM packet.*/
+ Protrom_Packet_t *Packet_p;
+} Protrom_Inbound_t;
+
+/** Structure for handling outgoing PROTROM packets.*/
+typedef struct {
+ /**< State of the state machine for handling outgoing PROTROM packets. */
+ Protrom_OutboundState_t State;
+ /** Temporary pointer for handling PROTROM packet.*/
+ Protrom_Packet_t *Packet_p;
+ /**< Boolean value for controling re-entry in transmiter fucntion. */
+ boolean InLoad;
+} Protrom_Outbound_t;
+
+
+/** PROTROM Network context */
+typedef struct {
+ /**< Structure for handling incoming PROTROM packets.*/
+ Protrom_Inbound_t Inbound;
+ /**< Structure for handling outgoing PROTROM packets.*/
+ Protrom_Outbound_t Outbound;
+} Protrom_NetworkContext_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif /*T_NETWORK_LAYER_H_*/
diff --git a/source/LCM/include/t_protrom_transport.h b/source/LCM/include/t_protrom_transport.h
new file mode 100644
index 0000000..20eef29
--- /dev/null
+++ b/source/LCM/include/t_protrom_transport.h
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef INCLUSION_GUARD_T_PROTROM_TRANSPORT_H
+#define INCLUSION_GUARD_T_PROTROM_TRANSPORT_H
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup protrom_family
+ * @{
+ * @addtogroup ldr_protrom_transport_layer
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_basicdefinitions.h"
+#include "t_protrom_network.h"
+
+/*******************************************************************************
+ * Types, constants and external variables
+ ******************************************************************************/
+/** Callback function type for the Protrom protocol handler. */
+typedef ErrorCode_e(* Protrom_Callback_fn)(void *Param_p, uint8 PDU, int PayloadLength, void *Payload_p, Communication_t *Communication_p);
+
+/** Structure for transfer input parameters in PROTROM protocol family */
+typedef struct {
+ Protrom_Header_t *Header_p; /**< Pointer to the PROTROM header structure.*/
+ void *Payload_p; /**< Pointer to the payload data.*/
+} Protrom_SendData_LP_t;
+
+/** Protorm Transport context */
+typedef struct {
+ /**< Callback function pointer for PROTROM protocol handler. */
+ Protrom_Callback_fn Callback;
+} Protrom_TransportContext_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif // INCLUSION_GUARD_T_PROTROM_TRANSPORT_H
+
diff --git a/source/LCM/include/t_queue.h b/source/LCM/include/t_queue.h
new file mode 100644
index 0000000..f6250b6
--- /dev/null
+++ b/source/LCM/include/t_queue.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _T_QUEUE_H_
+#define _T_QUEUE_H_
+
+/**
+ * @addtogroup ldr_utilities
+ * @{
+ * @addtogroup queue
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_basicdefinitions.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+/** type of queue callback functions. */
+typedef enum {
+ QUEUE_EMPTY,
+ QUEUE_NONEMPTY
+} QueueCallbackType_e;
+
+/**
+ * Typedef of callback function used for the queue.
+ * One callback function is used when the fifo is empty,
+ * and another when the fifo is nonempty.
+ * These function are set by calling Do_Fifo_SetCallback.
+ *
+ * @param [in] Queue_p pointer to a valid queue(One that is created using
+ * Do_Fifo_Create).
+ * @param [in] Param_p additional parameters to the function.
+ * @return None.
+ */
+typedef void (*QueueCallback_fn)(const void *const Queue_p, void *Param_p);
+
+/** @} */
+/** @} */
+#endif /*T_QUEUE_H_*/
diff --git a/source/LCM/include/t_r15_header.h b/source/LCM/include/t_r15_header.h
new file mode 100644
index 0000000..55b717b
--- /dev/null
+++ b/source/LCM/include/t_r15_header.h
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _T_R15_HEADER_H_
+#define _T_R15_HEADER_H_
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup r15_family
+ * @{
+ * @addtogroup ldr_r15_header
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_basicdefinitions.h"
+#include "command_ids.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+#define ALIGN_SIZE 512
+
+/** Length of the command packet header.*/
+#define TL_COMMAND_PACKET_HEADER_LENGTH 20
+/** Length of the bulk packet header.*/
+#define TL_BULK_PACKET_HEADER_LENGTH 36
+/** Length of the calculated sha256 hash. */
+#define SHA_256_HASH_LENGTH 32
+/** Header pattern for the loader protocol.*/
+#define HEADER_PATTERN (0xAA)
+/** Extended header pattern of the loader protocol.*/
+#define HEADER_PATTERN_EXTENSION (0xEE)
+/** The length of the header. */
+#define HEADER_LENGTH 16
+/** The length of the command extended header. */
+#define COMMAND_EXTENDED_HEADER_LENGTH 4
+/** The length of the bulk extended header. */
+#define BULK_EXTENDED_HEADER_LENGTH 20
+/** Offset of the header in the buffer. */
+#define HEADER_OFFSET_IN_BUFFER 8
+
+#define ALIGNED_HEADER_LENGTH ALIGN_SIZE
+#define ALIGNED_COMMAND_EXTENDED_HEADER_LENGTH ALIGN_SIZE
+#define ALIGNED_BULK_EXTENDED_HEADER_LENGTH ALIGN_SIZE
+
+/**
+ * Header search results
+ */
+#define NO_HEADER_PATTERN (0x00)
+#define HEADER_PATTERN_MATCH (0x01)
+#define HEADER_PATTERN_CANDIDATE (0x02)
+
+/** Protocol types*/
+typedef enum {
+ PROTO_COMMAND = 0xBC, /**< R15 command protocol identification number. */
+ PROTO_BULK = 0xBD /**< R15 bulk protocol identification number. */
+} R15_Protocol_t;
+
+/** Header for command and bulk protocol */
+typedef struct {
+ uint8 HeaderPattern; /**< Header pattern for marking header start.*/
+ uint8 Protocol; /**< Protocol type. */
+ uint16 HeaderPatternExtension; /**< Header pattern extension.*/
+ uint8 Flags; /**< Flasgs for the header.*/
+ uint8 ExtendedHeaderLength; /**< Extended header length.*/
+ uint8 ExtendedHeaderChecksum; /**< Extended header checksum.*/
+ uint32 PayloadLength; /**< Payload length. */
+ uint32 PayloadChecksum; /**< Payload checksum. */
+ uint8 HeaderChecksum; /**< Header checksum. */
+} R15_Header_t;
+
+
+/**
+ * Extended header for command protocol
+ */
+typedef struct {
+ uint16 SessionState; /**< Session and state for command header */
+ uint8 Command; /**< Specified command */
+ GroupId_e CommandGroup; /**< Specified command group */
+} CommandExtendedHeader_t;
+
+/**
+ * Extended header for bulk protocol
+ */
+typedef struct {
+ uint16 Session; /**< Session for bulk header */
+ uint8 TypeFlags; /**< Flags for data packet */
+ uint8 AcksChunk; /**< Number of acknowledged chunks or chunk identifier */
+ uint32 ChunkSize; /**< The maximum payload size of data packet */
+ uint64 Offset; /**< Offset from where the reading and writing of data should begin*/
+ uint32 Length; /**< How many bytes should be read/write */
+} BulkExtendedHeader_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif /*_T_R15_HEADER_H_*/
diff --git a/source/LCM/include/t_r15_network_layer.h b/source/LCM/include/t_r15_network_layer.h
new file mode 100644
index 0000000..c99d073
--- /dev/null
+++ b/source/LCM/include/t_r15_network_layer.h
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _T_R15_NETWORK_LAYER_H_
+#define _T_R15_NETWORK_LAYER_H_
+/**
+ * @addtogroup ldr_communication_serv
+ * @{
+ * @addtogroup r15_family
+ * @{
+ * @addtogroup ldr_r15_network_layer
+ * @{
+ */
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_communication_service.h"
+#include "t_r15_header.h"
+#include "t_time_utilities.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+/** PROTROM protocol ID*/
+#define PROTROM_PROTOCOL (0xFB)
+/** COMMAND protocol ID*/
+#define COMMAND_PROTOCOL (0xBC)
+/** BULK protocol ID*/
+#define BULK_PROTOCOL (0xBD)
+/** State: Command packet */
+#define COMMAND_PACKAGE (0x0000)
+/** State: Acknowledge packet */
+#define ACK_PACKAGE (0x0001)
+/** State: General response */
+#define GENERAL_RESPONSE_PACKAGE (0x0002)
+/** State: Acknowledge for general response */
+#define ACK_GENERAL_RESPONSE_PACKAGE (0x0003)
+/**
+ * Maximum numbers of used process in transport layer
+ */
+#define MAX_SIZE_RETRANSMISSION_LIST 32
+/** Amount of resends of the same package (until it aborts) */
+#define MAX_RESENDS (0x03)
+
+
+#ifndef CFG_ENABLE_LOADER_TYPE
+/** Acknowledge packet time(mS) out value */
+#define ACK_TIMEOUT_IN_MS 10000
+/** Default time(mS) out for receiving bulk command */
+#define BULK_COMMAND_RECEIVING_TIMEOUT 10000
+/** Default time(mS) out for receiving bulk data. This value is set for UART on 115200kbps! */
+#define BULK_DATA_RECEIVING_TIMEOUT 120000
+
+#else
+/** Acknowledge packet time(mS) out value */
+#define ACK_TIMEOUT_IN_MS (1000)
+/** Default time(mS) out for receiving bulk command */
+#define BULK_COMMAND_RECEIVING_TIMEOUT (1000)
+/** Default time(mS) out for receiving bulk data. This value is set for UART on 115200kbps! */
+#define BULK_DATA_RECEIVING_TIMEOUT (120000)
+#endif
+
+/** Number of pre-allocated buffers */
+#define COMMAND_BUFFER_COUNT 16
+/** Number of pre-allocated buffers */
+#define BULK_BUFFER_COUNT 16
+
+/** Size of a buffer used for commands. */
+#define COMMAND_BUFFER_SIZE 0x00010000
+
+/** Size of a buffer used for bulk transfer,
+ * must be biger than buffer for commands. */
+#define BULK_BUFFER_SIZE 0x00100000
+
+
+/** Mask for clearing the state bits in session/state field */
+#define MASK_CLR_STATE (0xFFFC)
+/** Mask for selecting the state bits in session/state field */
+#define MASK_SELECT_STATE (0x0003)
+/** Mask for selecting the session number in session/state field */
+#define MASK_SELECT_SESSION_NUMBER (0x3FFF)
+/** Mask for selecting session bits */
+#define SESSION_MASK 0xFFFC
+
+/**
+ * Defines all posible types of buffers that can be created (allocated).
+ *
+ * It is used to specified the type of the buffer
+ * when allocating a new buffer. Also it is used when
+ * requesting the number of buffers to specify the buffer type.
+ */
+typedef enum {
+ UNDEFINED_BUFFER = 0, /** Buffer with no specified type.*/
+ COMMAND_BUFFER = 1, /** Command buffer type, used for commands.*/
+ BULK_BUFFER = 2 /** Bulk buffer type, used for bulk transfer.*/
+} BuffersType_t;
+
+/** The enum for buffer Flags values. */
+TYPEDEF_ENUM {
+ BUF_FREE = 0x00000000, /**< No buffer activity */
+ BUF_ALLOCATED = 0x00000001, /**< The buffer is allocated. */
+ BUF_TX_READY = 0x00000002, /**< The buffer is filled with data
+ and is ready to be sent. */
+ BUF_TX_SENDING = 0x00000004, /**< The buffer is sending. */
+ BUF_TX_SENT = 0x00000008, /**< The buffer is sent and wait ACK. */
+ BUF_TX_DONE = 0x00000010, /**< The buffer has been sent and can
+ be deallocated. */
+ BUF_TX_TIMEOUT = 0x00000020, /**< The timeout ocure when buffer is
+ sending. */
+ BUF_RX_READY = 0x00000040, /**< The buffer is filled with
+ received data and is ready for
+ processing. */
+ BUF_HDR_CRC_OK = 0x00000080, /**< Set to true if the CRC has been
+ calculated. */
+ BUF_PAYLOAD_CRC_OK = 0x00000100, /**< Set to true if the CRC has been
+ calculated and is correct. */
+ BUF_ACK_READY = 0x00000200, /**< Set the buffer ready for
+ acknowledge. */
+ BUF_ACKNOWLEDGED = 0x00000400, /**< Set if the buffer is
+ acknowledged. */
+ BUF_CRC_CALC_READY = 0x00000800, /**< Set if the buffer is ready for
+ payload CRC calculating */
+ BUF_CRC_CALCULATING = 0x00001000, /**< Set if the calculating of
+ payload CRC is started */
+ BUF_HEADER_CRC_CALCULATED = 0x00002000, /**< Set if the header CRC is
+ calculated */
+ BUF_PAYLOAD_CRC_CALCULATED = 0x00004000, /**< Set if the payload CRC is
+ calculated */
+} ENUM32(PacketFlags_t);
+
+/** Flags Masks **/
+#define PACKET_ALLOCATION_STATE_MASK (BUF_FREE | BUF_ALLOCATED)
+#define PACKET_TX_STATE_MASK (BUF_TX_READY | BUF_TX_SENDING | BUF_TX_SENT | BUF_TX_DONE | BUF_TX_TIMEOUT)
+#define PACKET_RX_STATE_MASK (BUF_RX_READY | BUF_HDR_CRC_OK | BUF_PAYLOAD_CRC_OK | BUF_ACK_READY | BUF_ACKNOWLEDGED)
+#define PACKET_CRC_STATE_MASK (BUF_CRC_CALC_READY | BUF_CRC_CALCULATING | BUF_PAYLOAD_CRC_CALCULATED | BUF_HEADER_CRC_CALCULATED)
+
+/** Macro for setting a packet state **/
+#define SET_PACKET_FLAGS(packet, mask, flags) \
+ do \
+ { \
+ (packet)->Flags &= ~(mask); \
+ (packet)->Flags |= (mask & flags); \
+ } while (0)
+
+#define CHECK_PACKET_FLAGS(packet, flags) (((flags) == ((packet)->Flags & (flags))) ? TRUE : FALSE)
+
+/** Defined state of the receiver */
+typedef enum {
+ RECEIVE_HEADER, /**< State for receiving Header.*/
+ RECEIVE_EXTENDED_HEADER, /**< State for receiving Extended Header.*/
+ RECEIVE_PAYLOAD, /**< State for receiving Payload.*/
+ RECEIVE_ERROR /**< State for error handling.*/
+} R15_InboundState_t;
+
+/** Defined state of the transmitter */
+typedef enum {
+ SEND_IDLE, /**< Transmiter idle state.*/
+ SEND_HEADER, /**< Transmiter send header and extended header. */
+ SENDING_HEADER, /**< Transmiter is in process sending the header and extended header. */
+ SEND_PAYLOAD, /**< Transmiter send payload. */
+ SENDING_PAYLOAD /**< Transmiter is in process sending payload.*/
+} R15_OutboundState_t;
+
+/**
+ * Command buffer used for sending and receiving commands.
+ */
+typedef struct {
+ uint32 Id; /**< The buffer ID. NOTE: Currently is
+ not used */
+ uint32 Canary0; /**< A canary value. NOTE: Currently is
+ not used */
+ uint8 Payload[COMMAND_BUFFER_SIZE]; /**< The buffer containing the raw packet
+ data. NOTE! The buffer includes all
+ the data that is sent
+ (header, data and CRC) */
+ uint32 Canary1; /**< A canary value. NOTE: Currently is
+ not used */
+} CommandBuffer_t;
+
+/** Structure for the bulk buffer type. */
+typedef struct {
+ uint32 Id; /**< The buffer ID. NOTE: Currently is
+ not used */
+ uint32 Canary0; /**< A canary value. NOTE: Currently is
+ not used */
+ uint8 Payload[BULK_BUFFER_SIZE]; /**< The buffer containing the raw packet
+ data. NOTE! The buffer includes all
+ the data that is sent
+ (header, data and CRC) */
+ uint32 Canary1; /**< A Canary value. NOTE: Currently is
+ not used */
+} BulkBuffer_t;
+
+typedef void (*PacketCallBack_t)(Communication_t *Communication_p, const void *Data_p);
+
+/** Structure for the packet meta data. */
+typedef struct PacketMeta {
+ PacketCallBack_t CallBack_p; /**< Cllback function used after
+ sending packet.*/
+ uint32 Flags; /**< Field is a bit-field. Flags
+ for the Packet state. */
+ int BufferSize; /**< Field contains a Size of the
+ corresponding buffer used in
+ the packet. */
+ R15_Header_t Header; /**< Structure of the header. */
+ uint32 Resend; /**< Resend counter. */
+ Timer_t *Timer_p; /**< Timer data used for
+ sending/reciving packet. */
+ uint8 *ExtendedHeader_p; /**< Pointer to the extended
+ header located in the packet. */
+ uint8 *Payload_p; /**< Pointer to the payload data
+ located in the packet. */
+ uint8 *Buffer_p; /**< Field contains a pointer to
+ the corresponding (type)
+ buffer. */
+ uint32 Canary; /**< Field contains the master
+ Canary value. NOTE: Currently
+ is not used */
+ Communication_t *Communication_p; /**< The communication over which
+ this packet has been/is to be
+ transferred over. */
+ uint8 Hash[SHA_256_HASH_LENGTH]; /**< Field contain calculated hash
+ for payload. */
+} PacketMeta_t;
+
+/** Retransmission context. */
+typedef struct {
+ uint32 Timeout; /**< Defined timeout for retransmission. */
+ uint32 TimerKey; /**< Timer identification number.*/
+ uint32 Key; /**< Generated unique key, used for marking packet for
+ retransmission or removing from
+ retransmission list. */
+ PacketMeta_t *Packet_p; /**< Pointer to the packet for retransmission. */
+} RetransmissionContext_t;
+
+
+/** Structure for handling incoming R15 packets.*/
+typedef struct {
+ /**< State of the state machine for handling incoming R15 packets. */
+ R15_InboundState_t State;
+ /**< Number of requested data for receiving from communication device. */
+ uint32 ReqData;
+ /**< Number of receivied data from communication device. */
+ uint32 RecData;
+ /**< Number of receivied data from backup buffer used for switching the
+ * protocol family. */
+ uint32 RecBackupData;
+ /**< Offset in the buffer for next data that should be received. */
+ uint32 ReqBuffOffset;
+ /**< Temporary pointer to buffer for handling received data.*/
+ uint8 *Target_p;
+ /**< Temporary buffer for receiving data. */
+ uint8 Scratch[ALIGNED_HEADER_LENGTH + ALIGNED_BULK_EXTENDED_HEADER_LENGTH];
+ /** Temporary structure for handling R15 packet.*/
+ R15_Header_t Header;
+ /** Poiter to meta data for allocated buffer for handling R15 packet.*/
+ PacketMeta_t *Packet_p;
+ /** Error flag, purposed for error handling.*/
+ ErrorCode_e LCM_Error;
+} R15_Inbound_t;
+
+
+/** Structure for handling outgoing R15 packets.*/
+typedef struct {
+ /**< State of the state machine for handling outgoing R15 packets. */
+ R15_OutboundState_t State;
+ /** Temporary pointer for handling PROTROM packet.*/
+ PacketMeta_t *Packet_p;
+ /**< Boolean value for controling re-entry in transmiter fucntion. */
+ boolean InLoad;
+ /** Error flag, purposed for error handling.*/
+ ErrorCode_e LCM_Error;
+} R15_Outbound_t;
+
+
+/** R15 Network context */
+typedef struct {
+ PacketMeta_t *MetaInfoList[COMMAND_BUFFER_COUNT+BULK_BUFFER_COUNT];
+ /**< List of meta data for used packets. */
+ RetransmissionContext_t *RetransmissionList[MAX_SIZE_RETRANSMISSION_LIST];
+ /**< List of packet for retransmision */
+ uint32 RetransmissionListCount;
+ /**< Counter for packets retransmision */
+ R15_Inbound_t Inbound;
+ /**< Context for receiver. */
+ R15_Outbound_t Outbound;
+ /**< Context for transmiter. */
+} R15_NetworkContext_t;
+
+/*
+ * XVSZOAN @TODO:
+ *
+ * This structure is only for UART Process File fix.
+ * When we start using ESB block for data verification
+ * structure should be deleted!
+ */
+typedef struct {
+ const uint8 *Data_Packet_p;
+ uint32 Packet_Size;
+ uint32 UART_Device;
+ boolean New_Packed_Arrived;
+} DataBox_t;
+
+/** @} */
+/** @} */
+/** @} */
+#endif /*_T_R15_NETWORK_LAYER_H_*/
diff --git a/source/LCM/include/t_security_algorithms.h b/source/LCM/include/t_security_algorithms.h
new file mode 100644
index 0000000..5bae6c1
--- /dev/null
+++ b/source/LCM/include/t_security_algorithms.h
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _T_SECURITY_ALGORITHMS_H_
+#define _T_SECURITY_ALGORITHMS_H_
+/**
+ * \addtogroup ldr_security_algorithms
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include "t_basicdefinitions.h"
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+/** Defined value for HASH error. */
+#define HASH_ERROR 0xffffffff
+
+/** Length of SHA256 algorithm results */
+#define SHA256_LENGTH 32
+
+/** Length of CRC16 algorithm results */
+#define CRC16_LENGTH 2
+
+/** */
+#define MAX_NR_IN_QUEUE_TOKENS 16
+
+/** */
+typedef void (*HashCallback_fn)(void *Data_p, uint32 Length, uint8 *Hash_p, void *Param_p);
+
+/** Type of hash algorithm */
+typedef enum {
+ HASH_SHA256 = 0x0001, /**< 4LSB SHA-256 algorithm */
+ HASH_CRC16 = 0x0002, /**< CRC16 */
+ HASH_SIMPLE_XOR = 0x0003, /**< 4LSB Simple XOR algorithm */
+ HASH_NONE = 0x0004 /**< Communication is not hash secured */
+} HashType_e;
+
+/** @} */
+#endif /*_T_SECURITY_ALGORITHMS_H_*/
diff --git a/source/LCM/include/t_time_utilities.h b/source/LCM/include/t_time_utilities.h
new file mode 100644
index 0000000..bcc8254
--- /dev/null
+++ b/source/LCM/include/t_time_utilities.h
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _T_TIME_UTILITIES_H_
+#define _T_TIME_UTILITIES_H_
+/**
+ * @addtogroup ldr_time_utilities
+ * @{
+ */
+
+/*******************************************************************************
+ * Types, constants
+ ******************************************************************************/
+
+/** MAX defined timers */
+#define MAX_TIMERS 100
+
+/** defined type of function pointer to the handle function */
+typedef void (*HandleFunction_t)(void *Param_p, void *Timer_p, void *Data_p);
+
+/**
+ * Structure of timer data
+ */
+typedef struct {
+ uint32 Time; /**< Requested for timer time.*/
+ uint32 PeriodicalTime; /**< Requested periodical time for timer.*/
+ HandleFunction_t HandleFunction_p; /**< Callback function*/
+ void *Data_p; /**< Pointer to data. */
+ void *Param_p; /**< Extra parameters. */
+} Timer_t;
+
+/**
+ * Header for buffer of timers
+ */
+typedef struct {
+ uint32 MaxTimers;
+ uint32 ActiveTimers;
+ Timer_t *Timers_p;
+} TimerHeader_t;
+
+/** @} */
+#endif /*_T_TIME_UTILITIES_H_*/
diff --git a/source/LcmInterface.cpp b/source/LcmInterface.cpp
new file mode 100644
index 0000000..5b07ed5
--- /dev/null
+++ b/source/LcmInterface.cpp
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "lcdriver_error_codes.h"
+#include "LcmInterface.h"
+#include "Error.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#include <dlfcn.h>
+#define GetProcAddress dlsym
+#endif
+
+char *LcmInterface::m_pchLCMLibPath = 0;
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+//***********************************************************************************************
+// Name: LcmInterface()
+// Desc: Constructor.
+//**********************************************************************************************/
+LcmInterface::LcmInterface() : m_pCommunication(NULL) , lcmError_(E_SUCCESS)
+{
+}
+
+//***********************************************************************************************
+// Name: ~LcmInterface()
+// Desc: Destructor.
+//**********************************************************************************************/
+LcmInterface::~LcmInterface()
+{
+}
+
+HMODULE LcmInterface::m_hDLL = 0;
+R15BulkInterface_t LcmInterface::R15Bulk;
+R15CommandInterface_t LcmInterface::R15Command;
+A2CommandInterface_t LcmInterface::A2Command;
+CommunicationInterface_t LcmInterface::Communication;
+CCriticalSectionObject LcmInterface::m_CriticalSection;
+
+//***********************************************************************************************
+// Name: RunOnce()
+// Desc: Load LCM module and initialize function pointers once only.
+//**********************************************************************************************/
+int LcmInterface::LoadLCMLibrary()
+{
+ if (m_pchLCMLibPath == NULL) {
+#ifdef _WIN32
+ m_hDLL = LoadLibrary("LCM");
+#else
+ m_hDLL = dlopen("./lcm_linux/liblcm.so.1", RTLD_LAZY);
+#endif
+ } else {
+#ifdef _WIN32
+ m_hDLL = LoadLibrary(m_pchLCMLibPath);
+#else
+ m_hDLL = dlopen(m_pchLCMLibPath, RTLD_LAZY);
+#endif
+ }
+
+ if (m_hDLL == NULL) {
+ return LCM_DLL_LOAD_LOADLIBRARY_ERROR;
+ }
+
+ // Link to all necessary methods in the LCM DLL
+ Communication.Initialize_Fn = (CommunicationInitialize_t)GetProcAddress(m_hDLL, "Do_Communication_Initialize");
+ Communication.Shutdown_Fn = (CommunicationShutdown_t)GetProcAddress(m_hDLL, "Do_Communication_Shutdown");
+ Communication.Poll_Fn = (CommunicationPoll_t)GetProcAddress(m_hDLL, "Do_Communication_Poll");
+ Communication.SetFamily_Fn = (CommunicationSetFamily_t)GetProcAddress(m_hDLL, "Do_Communication_SetFamily");
+ Communication.Send_Fn = (CommunicationSend_t)GetProcAddress(m_hDLL, "Do_Communication_Send");
+ Communication.SetProtocolTimeouts_Fn = (CommunicationSetProtocolTimeouts_t)GetProcAddress(m_hDLL, "Do_Communication_SetProtocolTimeouts");
+ Communication.GetProtocolTimeouts_Fn = (CommunicationGetProtocolTimeouts_t)GetProcAddress(m_hDLL, "Do_Communication_GetProtocolTimeouts");
+ Communication.CancelReceiver_Fn = (CommunicationCancelReceiver_t)GetProcAddress(m_hDLL, "Do_Communication_Cancel_Receiver");
+
+ R15Command.Send_Fn = (R15CommandSend_t)GetProcAddress(m_hDLL, "Do_R15_Command_Send");
+ R15Command.ResetSessionCounters_Fn = (R15CommandResetSessionCounters_t)GetProcAddress(m_hDLL, "Do_R15_Command_ResetSessionCounters");
+
+ R15Bulk.OpenSession_Fn = (R15BulkOpenSession_t)GetProcAddress(m_hDLL, "Do_R15_Bulk_OpenSession");
+ R15Bulk.CreateVector_Fn = (R15BulkCreateVector_t)GetProcAddress(m_hDLL, "Do_R15_Bulk_CreateVector");
+ R15Bulk.DestroyVector_Fn = (R15BulkDestroyVector_t)GetProcAddress(m_hDLL, "Do_R15_Bulk_DestroyVector");
+ R15Bulk.StartSession_Fn = (R15BulkStartSession_t)GetProcAddress(m_hDLL, "Do_R15_Bulk_StartSession");
+ R15Bulk.GetStatusSession_Fn = (R15BulkGetStatusSession_t)GetProcAddress(m_hDLL, "Do_R15_Bulk_GetStatusSession");
+ R15Bulk.CloseSession_Fn = (R15BulkCloseSession_t)GetProcAddress(m_hDLL, "Do_R15_Bulk_CloseSession");
+ R15Bulk.SetCallbacks_Fn = (R15BulkSetCallbacks_t)GetProcAddress(m_hDLL, "Do_R15_Bulk_SetCallbacks");
+
+ A2Command.Send_Fn = (A2CommandSend_t)GetProcAddress(m_hDLL, "Do_A2_Command_Send");
+ A2Command.SpeedflashStart_Fn = (A2SpeedflashStart_t)GetProcAddress(m_hDLL, "Do_A2_Speedflash_Start");
+ A2Command.SpeedflashSetLastBlock_Fn = (A2SpeedflashSetLastBlock_t)GetProcAddress(m_hDLL, "Do_A2_Speedflash_SetLastBlock");
+ A2Command.SpeedflashWriteBlock_Fn = (A2SpeedflashWriteBlock_t)GetProcAddress(m_hDLL, "Do_A2_Speedflash_WriteBlock");
+
+ if (
+ Communication.Initialize_Fn == 0 ||
+ Communication.Shutdown_Fn == 0 ||
+ Communication.Poll_Fn == 0 ||
+ Communication.SetFamily_Fn == 0 ||
+ Communication.Send_Fn == 0 ||
+ Communication.SetProtocolTimeouts_Fn == 0 ||
+ Communication.GetProtocolTimeouts_Fn == 0 ||
+ R15Command.Send_Fn == 0 ||
+ R15Command.ResetSessionCounters_Fn == 0 ||
+ R15Bulk.OpenSession_Fn == 0 ||
+ R15Bulk.CreateVector_Fn == 0 ||
+ R15Bulk.DestroyVector_Fn == 0 ||
+ R15Bulk.StartSession_Fn == 0 ||
+ R15Bulk.GetStatusSession_Fn == 0 ||
+ R15Bulk.CloseSession_Fn == 0 ||
+ R15Bulk.SetCallbacks_Fn == 0 ||
+ A2Command.Send_Fn == 0 ||
+ A2Command.SpeedflashStart_Fn == 0 ||
+ A2Command.SpeedflashSetLastBlock_Fn == 0 ||
+ A2Command.SpeedflashWriteBlock_Fn == 0
+ ) {
+ return LCM_DLL_LOAD_FUNCTION_NOT_FOUND;
+ }
+
+ return E_SUCCESS;
+}
+
+void LcmInterface::SetLCMLibPath(const char *lcmLibPath)
+{
+ size_t pathLength = strlen(lcmLibPath);
+
+ if (0 != m_pchLCMLibPath) {
+ delete[] m_pchLCMLibPath;
+ }
+
+ m_pchLCMLibPath = new char[pathLength + 1];
+ strcpy_s(m_pchLCMLibPath, pathLength + 1, lcmLibPath);
+ m_pchLCMLibPath[pathLength] = '\0';
+}
+
+void LcmInterface::CloseLCMLibrary()
+{
+ if (0 != m_pchLCMLibPath) {
+ delete[] m_pchLCMLibPath;
+ }
+
+#ifdef _WIN32
+ FreeLibrary(m_hDLL);
+#else
+ dlclose(m_hDLL);
+#endif
+}
+
+ErrorCode_e LcmInterface::CommunicationInitialize(void *Object_p, Family_t Family, HashDevice_t *HashDevice_p, CommunicationDevice_t *CommunicationDevice_p, Do_CEH_Call_t CommandCallback_p, BuffersInterface_t *Buffers_p, TimersInterface_t *Timers_p, QueueInterface_t *Queue_p)
+{
+ int ReturnValue = E_SUCCESS;
+
+ if (m_hDLL == NULL) {
+ CLockCS lock(m_CriticalSection);
+
+ if (m_hDLL == NULL) {
+ VERIFY_SUCCESS(LoadLCMLibrary());
+ }
+ }
+
+ ReturnValue = Communication.Initialize_Fn(Object_p, &m_pCommunication, Family, HashDevice_p, CommunicationDevice_p, CommandCallback_p, Buffers_p, Timers_p, Queue_p);
+
+ErrorExit:
+ return static_cast<ErrorCode_e>(ReturnValue);
+}
+
+ErrorCode_e LcmInterface::CommunicationSend(void *InputData_p)
+{
+ return Communication.Send_Fn(m_pCommunication, InputData_p);
+}
+
+ErrorCode_e LcmInterface::CommunicationSetFamily(Family_t family, Do_CEH_Call_t CEHCallback)
+{
+ return Communication.SetFamily_Fn(m_pCommunication, family, CEHCallback);
+}
+
+ErrorCode_e LcmInterface::CommunicationSetProtocolTimeouts(void *TimeoutData_p)
+{
+ return Communication.SetProtocolTimeouts_Fn(m_pCommunication, TimeoutData_p);
+}
+
+ErrorCode_e LcmInterface::CommunicationGetProtocolTimeouts(void *TimeoutData_p)
+{
+ return Communication.GetProtocolTimeouts_Fn(m_pCommunication, TimeoutData_p);
+}
+
+ErrorCode_e LcmInterface::CommunicationShutdown()
+{
+ return Communication.Shutdown_Fn(&m_pCommunication);
+}
+
+ErrorCode_e LcmInterface::CommunicationCancelReceiver(uint8 PacketsBeforeReceiverStop)
+{
+ return Communication.CancelReceiver_Fn(m_pCommunication, PacketsBeforeReceiverStop);
+}
+ErrorCode_e LcmInterface::CommandSend(CommandData_t *CmdData_p)
+{
+ return R15Command.Send_Fn(m_pCommunication, CmdData_p);
+}
+
+ErrorCode_e LcmInterface::CommunicationPoll()
+{
+ return Communication.Poll_Fn(m_pCommunication);
+}
+
+ErrorCode_e LcmInterface::CommandResetSessionCounters()
+{
+ return R15Command.ResetSessionCounters_Fn(m_pCommunication);
+}
+
+void LcmInterface::BulkSetCallbacks(void *BulkCommandCallback_p, void *BulkDataCallback_p, void *BulkDataEndOfDump_p)
+{
+ R15Bulk.SetCallbacks_Fn(m_pCommunication, BulkCommandCallback_p, BulkDataCallback_p, BulkDataEndOfDump_p);
+}
+
+uint32 LcmInterface::BulkOpenSession(const uint16 SessionId, const TL_SessionMode_t Mode, uint32 Length)
+{
+ return R15Bulk.OpenSession_Fn(m_pCommunication, SessionId, Mode, Length);
+}
+
+TL_BulkVectorList_t *LcmInterface::BulkCreateVector(const uint32 BulkVector, uint32 Length, const uint32 BuffSize, TL_BulkVectorList_t *CreatedBulkVector_p)
+{
+ return R15Bulk.CreateVector_Fn(m_pCommunication, BulkVector, Length, BuffSize, CreatedBulkVector_p);
+}
+
+ErrorCode_e LcmInterface::BulkStartSession(TL_BulkVectorList_t *BulkVector_p, const uint64 Offset)
+{
+ return R15Bulk.StartSession_Fn(m_pCommunication, BulkVector_p, Offset);
+}
+
+uint32 LcmInterface::BulkDestroyVector(TL_BulkVectorList_t *BulkVector_p, boolean ReqReleaseBuffer)
+{
+ return R15Bulk.DestroyVector_Fn(m_pCommunication, BulkVector_p, ReqReleaseBuffer);
+}
+
+ErrorCode_e LcmInterface::BulkCloseSession(TL_BulkVectorList_t *BulkVector_p)
+{
+ return R15Bulk.CloseSession_Fn(m_pCommunication, BulkVector_p);
+}
+
+ErrorCode_e LcmInterface::A2CommandSend(A2_CommandData_t *CmdData_p)
+{
+ return A2Command.Send_Fn(m_pCommunication, CmdData_p);
+}
+
+void LcmInterface::A2SpeedflashStart()
+{
+ A2Command.SpeedflashStart_Fn(m_pCommunication);
+}
+
+void LcmInterface::A2SpeedflashSetLastBlock()
+{
+ A2Command.SpeedflashSetLastBlock_Fn(m_pCommunication);
+}
+
+ErrorCode_e LcmInterface::A2SpeedflashWriteBlock(const void *Buffer, const size_t BufferSize)
+{
+ return A2Command.SpeedflashWriteBlock_Fn(m_pCommunication, Buffer, BufferSize);
+}
diff --git a/source/LcmInterface.h b/source/LcmInterface.h
new file mode 100644
index 0000000..074cdda
--- /dev/null
+++ b/source/LcmInterface.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _LCMINTERFACE_H_
+#define _LCMINTERFACE_H_
+
+#include "t_communication_service.h"
+#include "t_bulk_protocol.h"
+#include "t_a2_protocol.h"
+
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+typedef void *HMODULE;
+#endif
+
+typedef ErrorCode_e(*CommunicationInitialize_t)(void *Object_p, Communication_t **Communication_pp, Family_t Family, HashDevice_t *HashDevice_p, CommunicationDevice_t *CommunicationDevice_p, Do_CEH_Call_t CommandCallback_p, BuffersInterface_t *Buffers_p, TimersInterface_t *Timers_p, QueueInterface_t *Queue_p);
+typedef ErrorCode_e(*CommunicationShutdown_t)(Communication_t **Communication_pp);
+typedef ErrorCode_e(*CommunicationPoll_t)(Communication_t *Communication_p);
+typedef ErrorCode_e(*CommunicationSetFamily_t)(Communication_t *Communication_p, Family_t Family, Do_CEH_Call_t CEHCallback);
+typedef ErrorCode_e(*CommunicationSend_t)(Communication_t *Communication_p, void *InputData_p);
+typedef ErrorCode_e(*CommunicationSetProtocolTimeouts_t)(Communication_t *Communication_p, void *TimeoutData_p);
+typedef ErrorCode_e(*CommunicationGetProtocolTimeouts_t)(Communication_t *Communication_p, void *TimeoutData_p);
+typedef ErrorCode_e(*CommunicationCancelReceiver_t)(Communication_t *Communication_p, uint8 PacketsBeforeTransferStop);
+
+typedef ErrorCode_e(*R15CommandSend_t)(Communication_t *Communication_p, CommandData_t *CmdData_p);
+typedef ErrorCode_e(*R15CommandResetSessionCounters_t)(const Communication_t *const Communication_p);
+
+typedef ErrorCode_e(*R15BulkStartSession_t)(Communication_t *Communication_p, TL_BulkVectorList_t *BulkVector_p, const uint64 Offset);
+typedef ErrorCode_e(*R15BulkCloseSession_t)(Communication_t *Communication_p, TL_BulkVectorList_t *BulkVector_p);
+typedef TL_BulkVectorList_t*(*R15BulkCreateVector_t)(const Communication_t *const Communication_p, const uint32 BulkVector, uint32 Length, const uint32 BuffSize, TL_BulkVectorList_t *CreatedBulkVector_p);
+typedef TL_BulkSessionState_t (*R15BulkGetStatusSession_t)(const Communication_t *const Communication_p, const TL_BulkVectorList_t *BulkVector_p);
+typedef uint32(*R15BulkDestroyVector_t)(const Communication_t *const Communication_p, TL_BulkVectorList_t *BulkVector_p, boolean ReqReleaseBuffer);
+typedef uint32(*R15BulkOpenSession_t)(const Communication_t *const Communication_p, const uint16 SessionId, const TL_SessionMode_t Mode, uint32 Length);
+typedef void (*R15BulkSetCallbacks_t)(Communication_t *Communication_p, void *BulkCommandCallback_p, void *BulkDataCallback_p, void *BulkDataEndOfDump_p);
+
+typedef ErrorCode_e(*A2CommandSend_t)(Communication_t *Communication_p, A2_CommandData_t *CmdData_p);
+typedef void (*A2SpeedflashStart_t)(Communication_t *Communication_p);
+typedef void (*A2SpeedflashSetLastBlock_t)(Communication_t *Communication_p);
+typedef ErrorCode_e(*A2SpeedflashWriteBlock_t)(Communication_t *Communication_p, const void *Buffer, const size_t BufferSize);
+
+typedef struct {
+ CommunicationInitialize_t Initialize_Fn;
+ CommunicationShutdown_t Shutdown_Fn;
+ CommunicationPoll_t Poll_Fn;
+ CommunicationSetFamily_t SetFamily_Fn;
+ CommunicationSend_t Send_Fn;
+ CommunicationSetProtocolTimeouts_t SetProtocolTimeouts_Fn;
+ CommunicationGetProtocolTimeouts_t GetProtocolTimeouts_Fn;
+ CommunicationCancelReceiver_t CancelReceiver_Fn;
+} CommunicationInterface_t;
+
+typedef struct {
+ R15CommandSend_t Send_Fn;
+ R15CommandResetSessionCounters_t ResetSessionCounters_Fn;
+} R15CommandInterface_t;
+
+typedef struct {
+ R15BulkStartSession_t StartSession_Fn;
+ R15BulkCloseSession_t CloseSession_Fn;
+ R15BulkCreateVector_t CreateVector_Fn;
+ R15BulkGetStatusSession_t GetStatusSession_Fn;
+ R15BulkDestroyVector_t DestroyVector_Fn;
+ R15BulkOpenSession_t OpenSession_Fn;
+ R15BulkSetCallbacks_t SetCallbacks_Fn;
+} R15BulkInterface_t;
+
+typedef struct {
+ A2CommandSend_t Send_Fn;
+ A2SpeedflashStart_t SpeedflashStart_Fn;
+ A2SpeedflashSetLastBlock_t SpeedflashSetLastBlock_Fn;
+ A2SpeedflashWriteBlock_t SpeedflashWriteBlock_Fn;
+} A2CommandInterface_t;
+
+class LcmInterface
+{
+public:
+ LcmInterface();
+ virtual ~LcmInterface();
+
+ ErrorCode_e CommunicationInitialize(void *Object_p, Family_t Family, HashDevice_t *HashDevice_p, CommunicationDevice_t *CommunicationDevice_p, Do_CEH_Call_t CommandCallback_p, BuffersInterface_t *Buffers_p, TimersInterface_t *Timers_p, QueueInterface_t *Queue_p);
+ ErrorCode_e CommunicationPoll();
+ ErrorCode_e CommunicationSend(void *InputData_p);
+ ErrorCode_e CommunicationSetFamily(Family_t family, Do_CEH_Call_t CEHCallback);
+ ErrorCode_e CommunicationSetProtocolTimeouts(void *TimeoutData_p);
+ ErrorCode_e CommunicationGetProtocolTimeouts(void *TimeoutData_p);
+ ErrorCode_e CommunicationShutdown();
+ ErrorCode_e CommunicationCancelReceiver(uint8 PacketsBeforeReceiverStop);
+
+ ErrorCode_e CommandSend(CommandData_t *CmdData_p);
+ ErrorCode_e CommandResetSessionCounters();
+
+ void BulkSetCallbacks(void *BulkCommandCallback_p, void *BulkDataCallback_p, void *BulkDataEndOfDump_p);
+ uint32 BulkOpenSession(const uint16 SessionId, const TL_SessionMode_t Mode, uint32 Length);
+ TL_BulkVectorList_t *BulkCreateVector(const uint32 BulkVector, uint32 Length, const uint32 BuffSize, TL_BulkVectorList_t *CreatedBulkVector_p);
+ ErrorCode_e BulkStartSession(TL_BulkVectorList_t *BulkVector_p, const uint64 Offset);
+ uint32 BulkDestroyVector(TL_BulkVectorList_t *BulkVector_p, boolean ReqReleaseBuffer);
+ ErrorCode_e BulkCloseSession(TL_BulkVectorList_t *BulkVector_p);
+
+ ErrorCode_e A2CommandSend(A2_CommandData_t *CmdData_p);
+ void A2SpeedflashStart();
+ void A2SpeedflashSetLastBlock();
+ ErrorCode_e A2SpeedflashWriteBlock(const void *Buffer, const size_t BufferSize);
+
+ void *getLCMContext() {
+ return m_pCommunication;
+ }
+private:
+ Communication_t *m_pCommunication;
+ ErrorCode_e lcmError_;
+public:
+ static void SetLCMLibPath(const char *lcmLibPath);
+ static int LoadLCMLibrary();
+ static void CloseLCMLibrary();
+private:
+ static CommunicationInterface_t Communication;
+ static R15CommandInterface_t R15Command;
+ static R15BulkInterface_t R15Bulk;
+ static A2CommandInterface_t A2Command;
+
+ static HMODULE m_hDLL;
+ static char *m_pchLCMLibPath;
+ static CCriticalSectionObject m_CriticalSection;
+};
+
+#endif // _LCMINTERFACE_H_
diff --git a/source/api_wrappers/linux/CCriticalSection.h b/source/api_wrappers/linux/CCriticalSection.h
new file mode 100644
index 0000000..bbe95c4
--- /dev/null
+++ b/source/api_wrappers/linux/CCriticalSection.h
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _CCRITICALSECTION_H
+#define _CCRITICALSECTION_H
+
+#include "pthread.h"
+class CCriticalSectionObject
+{
+ friend class CLockCS;
+public:
+ CCriticalSectionObject() {
+ pthread_mutexattr_init(&recursivem);
+ pthread_mutexattr_settype(&recursivem, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&m_CriticalSection, &recursivem);
+ }
+ ~CCriticalSectionObject() {
+ pthread_mutexattr_destroy(&recursivem);
+ pthread_mutex_destroy(&m_CriticalSection);
+ }
+ inline void Enter() {
+ pthread_mutex_lock(&m_CriticalSection);
+ }
+ inline void Leave() {
+ pthread_mutex_unlock(&m_CriticalSection);
+ }
+private:
+ pthread_mutexattr_t recursivem;
+ mutable pthread_mutex_t m_CriticalSection;
+};
+
+// Basic lock class used to enter and leave the CRITICAL_SECTION private member of a
+// CCriticalSection object. Create a CLock object in scope that needs to be
+// synchronized and pass the shared CCriticalSection object used to synchronize the
+// resource to protect. The destructor calls the Leave method when leaving scope.
+class CLockCS
+{
+public:
+ CLockCS(CCriticalSectionObject &cs) : m_CriticalSectionObject(cs) {
+ m_CriticalSectionObject.Enter();
+ }
+ ~CLockCS() {
+ m_CriticalSectionObject.Leave();
+ }
+private:
+ CCriticalSectionObject &m_CriticalSectionObject;
+};
+
+#endif /* _CCRITICALSECTION_H */
+
diff --git a/source/api_wrappers/linux/CEventObject.cpp b/source/api_wrappers/linux/CEventObject.cpp
new file mode 100644
index 0000000..5f5acda
--- /dev/null
+++ b/source/api_wrappers/linux/CEventObject.cpp
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include <errno.h>
+#include <sys/time.h>
+
+#include "Types.h"
+#include "CEventObject.h"
+#include "OS.h"
+
+// ******************************************************************************
+// Name: CEventObject()
+// Desc: CEventObject constructor which initializes the m_sem member
+// Ret:
+// ******************************************************************************
+CEventObject::CEventObject()
+{
+ sem_init(&m_sem, 0, 0);
+}
+
+// ******************************************************************************
+// Name: ~CEventObject()
+// Desc: CEventObject destructor
+// Ret:
+// ******************************************************************************
+CEventObject::~CEventObject()
+{
+ sem_destroy(&m_sem);
+}
+
+// ******************************************************************************
+// Name: SetEvent()
+// Desc: Sets an event by post-ing the member semaphore m_sem
+// Ret:
+// ******************************************************************************
+void CEventObject::SetEvent()
+{
+ sem_post(&m_sem);
+}
+
+// ******************************************************************************
+// Name: Wait()
+// Desc: implementation of the pure virtual base class member Wait()
+// Ret: WAIT_OBJECT_0 when event occurs, or WAIT_TIMEOUT on timeout
+// ******************************************************************************
+DWORD CEventObject::Wait(DWORD dwTimeout)
+{
+ if (INFINITE == dwTimeout) {
+ sem_wait(&m_sem);
+ return WAIT_OBJECT_0;
+ } else {
+ timespec absolute_time = OS::GetAbsoluteTime(dwTimeout);
+ int ret;
+
+ /* coverity[returned_null] */
+ while (-1 == (ret = sem_timedwait(&m_sem, &absolute_time)) && errno == EINTR);
+
+ if (0 == ret) {
+ return WAIT_OBJECT_0;
+ } else {
+ return WAIT_TIMEOUT;
+ }
+ }
+}
diff --git a/source/api_wrappers/linux/CEventObject.h b/source/api_wrappers/linux/CEventObject.h
new file mode 100644
index 0000000..9c86087
--- /dev/null
+++ b/source/api_wrappers/linux/CEventObject.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+*
+* File name: CEventObjectObject.h
+* Language: Visual C++
+* Description: CEventObjectObject class declarations
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+
+#ifndef _CEVENTOBJECT_H
+#define _CEVENTOBJECT_H
+
+#include <semaphore.h>
+
+#include "Types.h"
+#include "CWaitableObject.h"
+
+//class used to wrap the OS methods for even signaling
+//implements Wait() method used when waiting for event to occur
+
+class CEventObject : public CWaitableObject
+{
+public:
+ CEventObject();
+ virtual ~CEventObject();
+ void SetEvent();
+ void UnsetEvent();
+ DWORD Wait(DWORD dwTimeout = INFINITE);
+private:
+ sem_t m_sem;
+};
+
+#endif /* _CEVENTOBJECT_H */
+
diff --git a/source/api_wrappers/linux/CSemaphore.cpp b/source/api_wrappers/linux/CSemaphore.cpp
new file mode 100644
index 0000000..0246091
--- /dev/null
+++ b/source/api_wrappers/linux/CSemaphore.cpp
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include <errno.h>
+#include <semaphore.h>
+#include <sys/time.h>
+#include "Types.h"
+#include "CSemaphore.h"
+#include "OS.h"
+
+CSemaphore::CSemaphore(unsigned int initial_count)
+{
+ sem_init(&m_semaphore, 0, initial_count);
+}
+
+CSemaphore::~CSemaphore()
+{
+ sem_destroy(&m_semaphore);
+}
+
+bool CSemaphore::Release(unsigned int count)
+{
+ if (!count) {
+ return false;
+ }
+
+ for (unsigned int i = 0; i < count; ++i) {
+ if (sem_post(&m_semaphore)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+DWORD CSemaphore::Wait(DWORD timeout)
+{
+ if (INFINITE == timeout) {
+ sem_wait(&m_semaphore);
+ } else {
+ timespec absoulute_time = OS::GetAbsoluteTime(timeout);
+ int ret;
+
+ /* coverity[returned_null] */
+ while (-1 == (ret = sem_timedwait(&m_semaphore, &absoulute_time)) && errno == EINTR);
+
+ if (0 != ret) {
+ return WAIT_TIMEOUT;
+ }
+ }
+
+ return WAIT_OBJECT_0;
+}
diff --git a/source/api_wrappers/linux/CSemaphore.h b/source/api_wrappers/linux/CSemaphore.h
new file mode 100644
index 0000000..24af4ad
--- /dev/null
+++ b/source/api_wrappers/linux/CSemaphore.h
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _CSEMAPHORE_H
+#define _CSEMAPHORE_H
+
+#include <pthread.h>
+#include <semaphore.h>
+#include "CWaitableObject.h"
+
+class CSemaphore : public CWaitableObject
+{
+public:
+ CSemaphore(unsigned int initial_count = 0);
+ virtual ~CSemaphore();
+ bool Release(unsigned int count = 1);
+ DWORD Wait(DWORD timeout = INFINITE);
+
+private:
+ sem_t m_semaphore;
+};
+
+#endif /* _CSEMAPHORE_H */
+
diff --git a/source/api_wrappers/linux/CSemaphoreQueue.cpp b/source/api_wrappers/linux/CSemaphoreQueue.cpp
new file mode 100644
index 0000000..0a2f573
--- /dev/null
+++ b/source/api_wrappers/linux/CSemaphoreQueue.cpp
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include <pthread.h>
+#include <assert.h>
+#include "Types.h"
+#include "CEventObject.h"
+#include "CSemaphore.h"
+#include "CSemaphoreQueue.h"
+
+CSemaphoreQueue::CSemaphoreQueue(unsigned int MaxCount) : m_MaximumCount(MaxCount)
+{
+ m_pEventObject = new CEventObject();
+ m_pSemaphore = new CSemaphore();
+
+ m_ObjectCollection.Add(m_pEventObject);
+ m_ObjectCollection.Add(m_pSemaphore);
+
+ m_Queue = new void*[MaxCount];
+ m_CurrentHead = 0;
+ m_CurrentTail = 0;
+ m_CurrentCount = 0;
+}
+
+CSemaphoreQueue::~CSemaphoreQueue()
+{
+ delete m_pEventObject;
+ delete m_pSemaphore;
+ delete[] m_Queue;
+}
+
+bool CSemaphoreQueue::AddTail(void *pObject)
+{
+ bool result = false;
+ CLockCS LocalCSLock(m_CSLock);
+ AddToQueueTail(pObject);
+ result = m_pSemaphore->Release(1);
+
+ if (!result) {
+ // Error : use ::GetLastError for cause of error
+ RemoveFromQueueTail(); // Not really necessary but keep,
+ // everything's gone pear-shaped anyway
+ }
+
+ return result;
+}
+
+RemoveResult CSemaphoreQueue::RemoveHead(void **ppObject, size_t mSecTimeout)
+{
+ CWaitableObject *pWaitableObject = m_ObjectCollection.Wait(mSecTimeout);
+
+ if (pWaitableObject == m_pEventObject) {
+ return REMOVE_CANCEL;
+ } else if (pWaitableObject == m_pSemaphore) {
+ CLockCS LocalCSLock(m_CSLock);
+ *ppObject = RemoveFromQueueHead(); // Remove pObject from pObjectQueue head
+ return REMOVE_SUCCESS;
+ } else if (NULL == pWaitableObject) {
+ return REMOVE_TIMEOUT;;
+ } else {
+ // Should never occur
+ assert(false);
+ return REMOVE_CANCEL;;
+ }
+}
+
+void CSemaphoreQueue::SignalEvent()
+{
+ CEventObject *pEvent = m_pEventObject;
+ pEvent->SetEvent();
+}
+
+void CSemaphoreQueue::IncrementHead()
+{
+ ++m_CurrentHead;
+
+ if (m_CurrentHead == m_MaximumCount) {
+ m_CurrentHead = 0;
+ }
+}
+
+void CSemaphoreQueue::IncrementTail()
+{
+ ++m_CurrentTail;
+
+ if (m_CurrentTail == m_MaximumCount) {
+ m_CurrentTail = 0;
+ }
+}
+
+void CSemaphoreQueue::AddToQueueTail(void *pObject)
+{
+ m_Queue[m_CurrentTail] = pObject;
+ IncrementTail();
+}
+
+void *CSemaphoreQueue::RemoveFromQueueHead()
+{
+ void *Object;
+ Object = m_Queue[m_CurrentHead];
+ IncrementHead();
+ return Object;
+}
+
+// Next 2 functions not really necessary - for error case only
+void CSemaphoreQueue::DecrementTail()
+{
+ if (m_CurrentTail == 0) {
+ m_CurrentTail = m_MaximumCount - 1;
+ } else {
+ --m_CurrentTail;
+ }
+}
+
+void CSemaphoreQueue::RemoveFromQueueTail()
+{
+ DecrementTail();
+ m_Queue[m_CurrentTail] = 0;
+}
diff --git a/source/api_wrappers/linux/CSemaphoreQueue.h b/source/api_wrappers/linux/CSemaphoreQueue.h
new file mode 100644
index 0000000..712d697
--- /dev/null
+++ b/source/api_wrappers/linux/CSemaphoreQueue.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _CSEMAPHOREQUEUE_H
+#define _CSEMAPHOREQUEUE_H
+#include "Types.h"
+#include "CEventObject.h"
+#include "CSemaphore.h"
+#include "pthread.h"
+#include "CCriticalSection.h"
+#include "CWaitableObject.h"
+#include "CWaitableObjectCollection.h"
+
+class CSemaphore;
+
+enum RemoveResult {
+ REMOVE_SUCCESS,
+ REMOVE_TIMEOUT,
+ REMOVE_CANCEL
+};
+
+// An object queue implementation using WinAPI's Semaphore.
+// For multi-threaded multi-processor applications with multiple producers and multiple consumers
+class CSemaphoreQueue
+{
+public:
+ CSemaphoreQueue(unsigned int MaxCount);
+ ~CSemaphoreQueue();
+ bool AddTail(void *pObject);
+ RemoveResult RemoveHead(void **ppRequest, size_t mSecTimeout);
+ void SignalEvent();
+private:
+ CEventObject *m_pEventObject;
+ CSemaphore *m_pSemaphore;
+ CCriticalSectionObject m_CSLock;
+ void **m_Queue;
+ const unsigned int m_MaximumCount;
+ unsigned int m_CurrentCount;
+ unsigned int m_CurrentHead;
+ unsigned int m_CurrentTail;
+ void IncrementHead();
+ void IncrementTail();
+ void AddToQueueTail(void *pObject);
+ void *RemoveFromQueueHead();
+ unsigned int GetIndex(CWaitableObject *Object) const;
+ // Next 2 functions not really necessary - for error case only
+ void DecrementTail();
+ void RemoveFromQueueTail();
+ CWaitableObjectCollection m_ObjectCollection;
+};
+
+class CPollQueue : public CSemaphoreQueue
+{
+public:
+ CPollQueue() : CSemaphoreQueue(256) {}
+ RemoveResult RemovePollRequest(void **pTO, int mSecTimeout = INFINITE) {
+ return RemoveHead(pTO, mSecTimeout);
+ }
+ bool AddPollRequest(void *pObject) {
+ return AddTail(pObject);
+ }
+};
+
+#endif /* _CSEMAPHOREQUEUE_H */
+
diff --git a/source/api_wrappers/linux/CSimpleQueue.h b/source/api_wrappers/linux/CSimpleQueue.h
new file mode 100644
index 0000000..18a0478
--- /dev/null
+++ b/source/api_wrappers/linux/CSimpleQueue.h
@@ -0,0 +1,26 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+#ifndef _CSIMPLEQUEUE_H_
+#define _CSIMPLEQUEUE_H_
+
+#include "Types.h"
+#include "CSemaphoreQueue.h"
+
+class CSimpleQueue : public CSemaphoreQueue
+{
+public:
+ CSimpleQueue(): CSemaphoreQueue(256) {}
+ RemoveResult RemoveRequest(void **ppRequest, int mSecTimeout = INFINITE) {
+ return RemoveHead(ppRequest, mSecTimeout);
+ }
+ bool AddRequest(void *pRequest) {
+ return AddTail(pRequest);
+ }
+};
+
+#endif // _CSIMPLEQUEUE_H_
diff --git a/source/api_wrappers/linux/CThreadWrapper.cpp b/source/api_wrappers/linux/CThreadWrapper.cpp
new file mode 100644
index 0000000..3e95da8
--- /dev/null
+++ b/source/api_wrappers/linux/CThreadWrapper.cpp
@@ -0,0 +1,119 @@
+/*******************************************************************************
+*
+* File name: CThreadWrapper.cpp
+* Language: Visual C++
+* Description: CThreadWrapper class definitions
+* The class implements OS independent thread wrapper.
+* The class contains methods for suspending resuming and waiting for threads.
+* The implementations of the methods is linux dependent,
+* but the interface of the functions is same as the appropriate
+* WIN32 implementation.
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+
+#include <string>
+#include <signal.h>
+
+#include "Types.h"
+#include "CThreadWrapper.h"
+#include "CCriticalSection.h"
+
+// ******************************************************************************
+// Name: CThreadWrapper()
+// Desc: CEventObject constructor which initializes the class members
+// Ret:
+// ******************************************************************************
+CThreadWrapper::CThreadWrapper(void*(*pStartAddress)(void *), void *pArgument)
+{
+ m_pStartAddress = pStartAddress;
+ m_pArgument = pArgument;
+ m_tid = (pthread_t)0;
+}
+
+// ******************************************************************************
+// Name: ~CThreadWrapper()
+// Desc: CEventObject destructor
+// Ret:
+// ******************************************************************************
+CThreadWrapper::~CThreadWrapper()
+{
+}
+
+// ******************************************************************************
+// Name: Wait()
+// Desc: Waits for the thread to finish its job
+// Ret: WAIT_OBJECT_0 on success and EAIT_TIMEOUT otherwise
+// ******************************************************************************
+DWORD CThreadWrapper::Wait(DWORD dwMilliseconds)
+{
+ if ((int)m_tid != 0) {
+ return m_ThreadEndedEvt.Wait(dwMilliseconds);
+ } else {
+ return WAIT_OBJECT_0;
+ }
+}
+
+// ******************************************************************************
+// Name: ResumeThread()
+// Desc: Resumes the thread. Should be called after the thread is created
+// Ret:
+// ******************************************************************************
+void CThreadWrapper::ResumeThread()
+{
+ pthread_create(&m_tid, NULL, CThreadWrapper::ThreadFunc, this);
+}
+
+// ******************************************************************************
+// Name: ResumeThread()
+// Desc: Suspends the running thread.
+// Ret:
+// ******************************************************************************
+void CThreadWrapper::SuspendThread()
+{
+ // this will stop all active threads
+ pthread_kill(m_tid, SIGSTOP);
+}
+
+// ******************************************************************************
+// Name: WaitToDie()
+// Desc: Waits 1000ms for thread to die
+// Ret:
+// ******************************************************************************
+void CThreadWrapper::WaitToDie(DWORD dwMilliseconds)
+{
+ CThreadWrapper::Wait(dwMilliseconds);
+}
+// ******************************************************************************
+// Name: ThreadFunc()
+// Desc: Sets event when the thread finishes its job
+// Ret:
+// ******************************************************************************
+void *CThreadWrapper::ThreadFunc(void *arg)
+{
+ CThreadWrapper *pthis = (CThreadWrapper *)arg;
+
+ pthis->m_pStartAddress(pthis->m_pArgument);
+
+ // Thread has finished, set appropriate event here
+ pthis->m_ThreadEndedEvt.SetEvent();
+ pthread_detach(pthread_self());
+ pthis->m_tid = (pthread_t)0;
+ return NULL;
+}
+
+// ******************************************************************************
+// Name: GetThreadId()
+// Desc: Returns the thread ID
+// Ret: Thread ID
+// ******************************************************************************
+DWORD CThreadWrapper::GetThreadId()
+{
+ return (DWORD)m_tid;
+}
diff --git a/source/api_wrappers/linux/CThreadWrapper.h b/source/api_wrappers/linux/CThreadWrapper.h
new file mode 100644
index 0000000..aabadcc
--- /dev/null
+++ b/source/api_wrappers/linux/CThreadWrapper.h
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _CTHREADWRAPPER_H
+#define _CTHREADWRAPPER_H
+
+#include "CWaitableObject.h"
+#include "CEventObject.h"
+#include <pthread.h>
+
+typedef void*(*StartAddress_t)(void *);
+
+class CThreadWrapper : public CWaitableObject
+{
+public:
+ CThreadWrapper(void*(* pStartAddress)(void *), void *pArgument);
+ ~CThreadWrapper();
+ void ResumeThread();
+ void SuspendThread();
+ void WaitToDie(DWORD dwMilliseconds = 1000);
+ DWORD GetThreadId();
+ DWORD Wait(DWORD dwMilliseconds = INFINITE);
+private:
+ pthread_t m_tid;
+ StartAddress_t m_pStartAddress;
+ void *m_pArgument;
+ CEventObject m_ThreadEndedEvt;
+
+protected:
+ static void *ThreadFunc(void *Arg);
+};
+
+#endif /* _CTHREADWRAPPER_H */
+
diff --git a/source/api_wrappers/linux/CWaitableObject.cpp b/source/api_wrappers/linux/CWaitableObject.cpp
new file mode 100644
index 0000000..918dd6f
--- /dev/null
+++ b/source/api_wrappers/linux/CWaitableObject.cpp
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "Types.h"
+#include "CWaitableObject.h"
+
+CWaitableObject::CWaitableObject()
+{
+}
+
+
+CWaitableObject::~CWaitableObject()
+{
+}
+
diff --git a/source/api_wrappers/linux/CWaitableObject.h b/source/api_wrappers/linux/CWaitableObject.h
new file mode 100644
index 0000000..93cd638
--- /dev/null
+++ b/source/api_wrappers/linux/CWaitableObject.h
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _CWAITABLEOBJECT_H
+#define _CWAITABLEOBJECT_H
+
+#include "Types.h"
+
+class CWaitableObject
+{
+public:
+ CWaitableObject();
+ virtual ~CWaitableObject();
+ virtual DWORD Wait(DWORD dwTimeout = INFINITE) = 0;
+private:
+
+};
+
+typedef CWaitableObject *HANDLE;
+
+#endif /* _CWAITABLEOBJECT_H */
+
diff --git a/source/api_wrappers/linux/CWaitableObjectCollection.cpp b/source/api_wrappers/linux/CWaitableObjectCollection.cpp
new file mode 100644
index 0000000..e48fd1c
--- /dev/null
+++ b/source/api_wrappers/linux/CWaitableObjectCollection.cpp
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include <time.h>
+#include <errno.h>
+
+#include "Types.h"
+#include "CWaitableObjectCollection.h"
+#include <assert.h>
+
+CWaitableObjectCollection::CWaitableObjectCollection()
+{
+ m_objs.clear();
+}
+
+CWaitableObjectCollection::~CWaitableObjectCollection()
+{
+ m_objs.clear();
+}
+
+void CWaitableObjectCollection::Add(CWaitableObject *obj)
+{
+ m_objs.push_back(obj);
+}
+
+CWaitableObject *CWaitableObjectCollection::Wait(DWORD dwTimeout)
+{
+ vector<CWaitableObject *>::iterator it;
+ DWORD dwTimePassed = 0;
+ struct timespec ts;
+ struct timespec curr_time, start_time;
+
+ if (-1 == clock_gettime(CLOCK_REALTIME, &start_time)) {
+ return NULL;
+ }
+
+ do {
+ for (it = m_objs.begin(); it != m_objs.end(); ++it) {
+ assert(*it);
+
+ if (WAIT_OBJECT_0 == (*it)->Wait(0)) {
+ return (*it);
+ }
+ }
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 10000000L; // 10 milliseconds
+
+ // There isn't any possiblity of errno returning NULL, mean is not defined. Even if
+ // errno is not defined this is the least thing that we should care for.
+
+ // coverity[returned_null]
+ while (-1 == nanosleep(&ts, &ts) && EINTR == errno);
+
+ if (-1 == clock_gettime(CLOCK_REALTIME, &curr_time)) {
+ return NULL;
+ }
+
+ dwTimePassed = 1000 * (curr_time.tv_sec - start_time.tv_sec) + \
+ (curr_time.tv_nsec - start_time.tv_nsec) / 1000000;
+
+ } while (dwTimePassed < dwTimeout);
+
+ return NULL;
+}
diff --git a/source/api_wrappers/linux/CWaitableObjectCollection.h b/source/api_wrappers/linux/CWaitableObjectCollection.h
new file mode 100644
index 0000000..f5edfa7
--- /dev/null
+++ b/source/api_wrappers/linux/CWaitableObjectCollection.h
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _CWAITABLEOBJECTCOLLECTION_H
+#define _CWAITABLEOBJECTCOLLECTION_H
+
+#include <vector>
+#include "CWaitableObject.h"
+
+using namespace std;
+
+class CWaitableObjectCollection
+{
+public:
+ CWaitableObjectCollection();
+ virtual ~CWaitableObjectCollection();
+ void Add(CWaitableObject *obj);
+ CWaitableObject *Wait(DWORD dwTimeout = INFINITE);
+private:
+ vector<CWaitableObject *>m_objs;
+};
+
+#endif /* _CWAITABLEOBJECTCOLLECTION_H */
+
diff --git a/source/api_wrappers/linux/LinuxApiWrappers.h b/source/api_wrappers/linux/LinuxApiWrappers.h
new file mode 100644
index 0000000..b63b840
--- /dev/null
+++ b/source/api_wrappers/linux/LinuxApiWrappers.h
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _LINUXAPIWRAPPERS_H
+#define _LINUXAPIWRAPPERS_H
+
+#include "Types.h"
+#include "CCriticalSection.h"
+#include "CEventObject.h"
+#include "CSemaphore.h"
+#include "CSemaphoreQueue.h"
+#include "CThreadWrapper.h"
+#include "CWaitableObject.h"
+#include "CWaitableObjectCollection.h"
+#include "OS.h"
+
+#endif /* _LINUXAPIWRAPPERS_H */
+
diff --git a/source/api_wrappers/linux/OS.cpp b/source/api_wrappers/linux/OS.cpp
new file mode 100644
index 0000000..55c82bd
--- /dev/null
+++ b/source/api_wrappers/linux/OS.cpp
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include <time.h>
+#include <errno.h>
+#include "Types.h"
+#include "OS.h"
+
+DWORD OS::ErrorCode = 0;
+
+OS::OS()
+{
+}
+
+OS::~OS()
+{
+}
+
+void OS::Sleep(DWORD dwMilliseconds)
+{
+ struct timespec ts;
+
+ ts.tv_sec = dwMilliseconds / 1000;
+ ts.tv_nsec = (dwMilliseconds % 1000) * 1000000L;
+
+ /* coverity[returned_null] */
+ while (-1 == nanosleep(&ts, &ts) && errno == EINTR);
+}
+
+time_t OS::GetSystemTimeInMs()
+{
+ timespec systemTime;
+ clock_gettime(CLOCK_REALTIME, &systemTime);
+ return (systemTime.tv_sec * 1000) + (systemTime.tv_nsec / 1000000);
+}
+
+timespec OS::GetAbsoluteTime(DWORD dwTimeout)
+{
+ timespec absolute_time;
+ timespec current_time;
+
+ long timeout_nsec;
+
+ clock_gettime(CLOCK_REALTIME, &current_time);
+
+ absolute_time.tv_sec = current_time.tv_sec + (dwTimeout / 1000);
+ timeout_nsec = (dwTimeout % 1000) * 1000000L;
+
+ if ((1000000000 - current_time.tv_nsec) < timeout_nsec) {
+ // overflow will occur!
+ absolute_time.tv_sec++;
+ }
+
+ absolute_time.tv_nsec = (current_time.tv_nsec + timeout_nsec) % 1000000000;
+
+ return absolute_time;
+}
+
+
+char *strcpy_s(char *dst, size_t _Size, const char *src)
+{
+ return strncpy(dst, src, _Size);
+}
+
+int sprintf_s(char *dst, size_t _Size, const char *format, ...)
+{
+ va_list l;
+ int ReturnValue;
+
+ va_start(l, format);
+ ReturnValue = vsnprintf(dst, _Size, format, l);
+ va_end(l);
+
+ return ReturnValue;
+}
+
+char *strncpy_s(char *dst, const char *src, size_t _Size)
+{
+ return strncpy(dst, src, _Size);
+}
+
+int _stricmp(const char *s1, const char *s2)
+{
+ return strcasecmp(s1, s2);
+}
+
diff --git a/source/api_wrappers/linux/OS.h b/source/api_wrappers/linux/OS.h
new file mode 100644
index 0000000..cd219b9
--- /dev/null
+++ b/source/api_wrappers/linux/OS.h
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _OS_H
+#define _OS_H
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include "Types.h"
+
+#include "CWaitableObject.h"
+
+class OS
+{
+public:
+ OS();
+ virtual ~OS();
+
+ static void Sleep(DWORD dwMilliseconds);
+ static time_t GetSystemTimeInMs();
+
+ static DWORD GetErrorCode() {
+ return OS::ErrorCode;
+ }
+ static void SetErrorCode(DWORD dwErrorCode) {
+ OS::ErrorCode = dwErrorCode;
+ }
+
+ static timespec GetAbsoluteTime(DWORD dwTimeout);
+private:
+
+ static DWORD ErrorCode;
+};
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+/*
+ * str manipulation functions used in windows build
+ */
+
+char *strcpy_s(char *dst, size_t _Size, const char *src);
+char *strncpy_s(char *dst, const char *src, size_t _Size);
+int _stricmp(const char *s1, const char *s2);
+int sprintf_s(char *dst, size_t _Size, const char *format, ...);
+
+#define _snprintf snprintf
+
+template <size_t _Size>
+char *strcpy_s(char(&dst)[_Size], const char src[])
+{
+ return strncpy(dst, src, _Size);
+}
+
+template<size_t _Size>
+int sprintf_s(char(&dst)[_Size], const char *format, ...)
+{
+ int ReturnValue;
+ va_list l;
+ va_start(l, format);
+ ReturnValue = vsnprintf(dst, _Size, format, l);
+ va_end(l);
+ return ReturnValue;
+}
+
+template <size_t _Size>
+char *strcat_s(char(&dst)[_Size], const char src[])
+{
+ return strncat(dst, src, _Size);
+}
+
+template <size_t _Size>
+int _ultoa_s(unsigned long value, char(&str)[_Size], int radix)
+{
+ switch (radix) {
+ case 10:
+ return sprintf_s(str, "%ul", value);
+ case 16:
+ return sprintf_s(str, "%ulX", value);
+ default:
+ return -1;
+ }
+}
+
+template<size_t _Size>
+int _snprintf_s(char(&dst)[_Size], size_t _MaxCount, const char *format, ...)
+{
+ int ReturnValue;
+ va_list l;
+ va_start(l, format);
+ ReturnValue = vsnprintf(dst, MAX(_MaxCount, _Size), format, l);
+ va_end(l);
+ return ReturnValue;
+}
+
+template<size_t _Size>
+int vsprintf_s(char(&dst)[_Size], const char *format, va_list l)
+{
+ return vsnprintf(dst, _Size, format, l);
+}
+
+#endif /* _OS_H */
+
diff --git a/source/api_wrappers/linux/Types.h b/source/api_wrappers/linux/Types.h
new file mode 100644
index 0000000..14929b4
--- /dev/null
+++ b/source/api_wrappers/linux/Types.h
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _TYPES_H
+#define _TYPES_H
+
+const unsigned int os_minus_one = ~0;
+#define INFINITE os_minus_one
+
+#define WAIT_OBJECT_0 0
+#define WAIT_TIMEOUT 0x00000102L
+#define WAIT_FAILED (DWORD)0xFFFFFFFF
+
+typedef unsigned int DWORD;
+
+#define WINAPI
+
+#endif /* _TYPES_H */
+
diff --git a/source/api_wrappers/windows/WinApiWrappers.h b/source/api_wrappers/windows/WinApiWrappers.h
new file mode 100644
index 0000000..65fca8b
--- /dev/null
+++ b/source/api_wrappers/windows/WinApiWrappers.h
@@ -0,0 +1,347 @@
+/*******************************************************************************
+*
+* File name: WinApiWrappers.h
+* Language: Visual C++
+* Description: WinAPI encapsulation class declarations
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File WinApiWrappers.h
+
+#ifndef __WINAPIWRAPPERS_H__
+#define __WINAPIWRAPPERS_H__
+
+#pragma once
+
+#include <windows.h>
+#include <process.h>
+#include <assert.h>
+#include <vector>
+using namespace std;
+
+class CWaitableObject
+{
+public:
+ CWaitableObject() {}
+ virtual ~CWaitableObject() {}
+ virtual DWORD Wait(DWORD dwTimeout = INFINITE) = 0;
+private:
+
+};
+
+// Thin encapsulation of WinAPI's CRITICAL_SECTION
+class CCriticalSectionObject
+{
+ friend class CLockCS;
+public:
+ CCriticalSectionObject() {
+ ::InitializeCriticalSection(&m_CriticalSection);
+ }
+ ~CCriticalSectionObject() {
+ ::DeleteCriticalSection(&m_CriticalSection);
+ }
+private:
+ void Enter() {
+ ::EnterCriticalSection(&m_CriticalSection);
+ }
+ void Leave() {
+ ::LeaveCriticalSection(&m_CriticalSection);
+ }
+ CRITICAL_SECTION m_CriticalSection;
+};
+
+// Basic lock class used to enter and leave the CRITICAL_SECTION private member of a
+// CCriticalSection object. Create a CLock object in scope that needs to be
+// synchronized and pass the shared CCriticalSection object used to synchronize the
+// resource to protect. The destructor calls the Leave method when leaving scope.
+class CLockCS
+{
+public:
+ CLockCS(CCriticalSectionObject &cs) : m_CriticalSectionObject(cs) {
+ m_CriticalSectionObject.Enter();
+ }
+ ~CLockCS() {
+ m_CriticalSectionObject.Leave();
+ }
+private:
+ CCriticalSectionObject &m_CriticalSectionObject;
+};
+
+// Thin encapsulation of WinAPI's Events
+class CEventObject : public CWaitableObject
+{
+public:
+ CEventObject() {
+ m_Handle = ::CreateEvent(
+ 0, // LPSECURITY_ATTRIBUTES
+ FALSE, // bManualReset i.e. Use auto-reset functionality
+ FALSE, // bInitialState i.e. In non-signalled state initially
+ 0);
+ } // lpName
+ ~CEventObject() {
+ ::CloseHandle(m_Handle);
+ }
+ void SetEvent() {
+ ::SetEvent(m_Handle);
+ }
+ void UnsetEvent() {
+ ::ResetEvent(m_Handle);
+ }
+ DWORD Wait(DWORD milliseconds = INFINITE) {
+ return ::WaitForSingleObject(m_Handle, milliseconds);
+ }
+ void WaitForAllEvents(HANDLE *pHandles, int iHandles, DWORD msec = INFINITE) {
+ ::WaitForMultipleObjects(
+ iHandles, // Number of objects in handles
+ pHandles,
+ TRUE, // Wait all events
+ msec);
+ } // Wait indefinitely default i.e. INFINITE
+ int WaitForFirstEvent(HANDLE *pHandles, int iHandles, DWORD msec = INFINITE) {
+ ::WaitForMultipleObjects(
+ iHandles, // Number of objects in handles
+ pHandles,
+ FALSE, // Wait for first event object
+ msec);
+ } // Wait indefinitely default i.e. INFINITE
+ HANDLE GetHandle() {
+ return m_Handle;
+ }
+private:
+ HANDLE m_Handle;
+};
+
+// A thin encapsulation of WinAPI's Thread
+class CThreadWrapper
+{
+public:
+ CThreadWrapper(unsigned int (WINAPI *pStartAddress)(void *), void *pArgument) {
+ m_Handle = (HANDLE)_beginthreadex(
+ 0, // LPSECURITY_ATTRIBUTES
+ 0, // dwStackSize - default
+ pStartAddress, // lpStartAddress
+ pArgument, // lpParameter
+ CREATE_SUSPENDED, // dwCreationFlags
+ 0); // lpThreadId
+ }
+ ~CThreadWrapper() {
+ ::CloseHandle(m_Handle);
+ }
+ void ResumeThread() {
+ ::ResumeThread(m_Handle);
+ }
+ void SuspendThread() {
+ ::SuspendThread(m_Handle);
+ }
+ void WaitToDie(DWORD dwMilliseconds = 1000) {
+ ::WaitForSingleObject(m_Handle, dwMilliseconds);
+ }
+private:
+ HANDLE m_Handle;
+ DWORD m_ThreadId;
+};
+
+//class that encapsulates the OS methods for Object signaling
+//it contains functions for registering signal objects.
+//the main function is the wait method which interface is platform independent.
+class CWaitableObjectCollection
+{
+public:
+ CWaitableObjectCollection() {
+ m_objs.clear();
+ }
+
+ virtual ~CWaitableObjectCollection() {
+ m_objs.clear();
+ }
+
+ //adds object to the collection
+ void Add(CWaitableObject *obj) {
+ m_objs.push_back(obj);
+ }
+
+ //waits for multiple objects
+ //this function returns the object that signaled the end of its job
+ //or null if dwTimeout occur
+ CWaitableObject *Wait(DWORD dwTimeout = INFINITE) {
+ vector<CWaitableObject *>::iterator it;
+ DWORD dwTimePassed = 0;
+ DWORD curr_time, start_time;
+
+ start_time = ::GetTickCount();
+
+ do {
+ for (it = m_objs.begin(); it != m_objs.end(); ++it) {
+ assert(*it);
+
+ if ((*it)->Wait(0) == 0) {
+ return (*it);
+ }
+ }
+
+ Sleep(10);
+
+ curr_time = ::GetTickCount();
+
+ dwTimePassed = curr_time - start_time;
+ } while (dwTimePassed < dwTimeout);
+
+ return NULL;
+ }
+private:
+ vector<CWaitableObject *>m_objs;
+};
+
+enum RemoveResult {
+ REMOVE_SUCCESS,
+ REMOVE_TIMEOUT,
+ REMOVE_CANCEL
+};
+
+// An object queue implementation using WinAPI's Semaphore.
+// For multi-threaded multi-processor applications with multiple producers and multiple consumers
+class CSemaphoreQueue
+{
+public:
+ CSemaphoreQueue(unsigned int MaxCount) : m_MaximumCount(MaxCount) {
+ m_Handles[0] = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+ m_Handles[1] = ::CreateSemaphore(NULL, 0, MaxCount, NULL);
+ m_Queue = new void*[MaxCount];
+ m_CurrentHead = 0;
+ m_CurrentTail = 0;
+ m_CurrentCount = 0;
+ }
+
+ ~CSemaphoreQueue() {
+ ::CloseHandle(m_Handles[0]);
+ ::CloseHandle(m_Handles[1]);
+ delete m_Queue;
+ }
+
+ bool AddTail(void *pObject) {
+ bool result;
+ CLockCS LocalCSLock(m_CSLock);
+ AddToQueueTail(pObject);
+ result = ::ReleaseSemaphore(m_Handles[1], 1, 0) ? true : false;
+
+ if (!result) {
+ RemoveFromQueueTail(); // Not really necessary but keep, everything's gone pear-shaped anyway
+ }
+
+ return result;
+ }
+
+ RemoveResult RemoveHead(void **ppObject, int mSecTimeout) {
+ switch (::WaitForMultipleObjects(2, m_Handles, FALSE, mSecTimeout)) {
+ case WAIT_OBJECT_0 + 0:
+ return REMOVE_CANCEL;
+ case WAIT_OBJECT_0 + 1: {
+ CLockCS LocalCSLock(m_CSLock);
+ *ppObject = RemoveFromQueueHead(); // Remove pObject from pObjectQueue head
+ return REMOVE_SUCCESS;
+ }
+ case WAIT_TIMEOUT:
+ return REMOVE_TIMEOUT;
+ default:
+ assert(false);
+ return REMOVE_CANCEL;
+ }
+ }
+
+ void SignalEvent() {
+ ::SetEvent(m_Handles[0]);
+ }
+private:
+ HANDLE m_Handles[2];
+ CCriticalSectionObject m_CSLock;
+ void **m_Queue;
+ const unsigned int m_MaximumCount;
+ unsigned int m_CurrentCount;
+ unsigned int m_CurrentHead;
+ unsigned int m_CurrentTail;
+ void IncrementHead() {
+ ++m_CurrentHead;
+
+ if (m_CurrentHead == m_MaximumCount) {
+ m_CurrentHead = 0;
+ }
+ }
+ void IncrementTail() {
+ ++m_CurrentTail;
+
+ if (m_CurrentTail == m_MaximumCount) {
+ m_CurrentTail = 0;
+ }
+ }
+ void AddToQueueTail(LPVOID pObject) {
+ m_Queue[m_CurrentTail] = pObject;
+ IncrementTail();
+ }
+ void *RemoveFromQueueHead() {
+ void *Object;
+ Object = m_Queue[m_CurrentHead];
+ IncrementHead();
+ return Object;
+ }
+ // Next 2 functions not really necessary - for error case only
+ void DecrementTail() {
+ if (m_CurrentTail == 0) {
+ m_CurrentTail = m_MaximumCount - 1;
+ } else {
+ --m_CurrentTail;
+ }
+ }
+ void RemoveFromQueueTail() {
+ DecrementTail();
+ m_Queue[m_CurrentTail] = 0;
+ }
+};
+
+class CSimpleQueue : public CSemaphoreQueue
+{
+public:
+ CSimpleQueue(): CSemaphoreQueue(256) {}
+ RemoveResult RemoveRequest(void **ppRequest, unsigned int mSecTimeout = INFINITE) {
+ return RemoveHead(ppRequest, mSecTimeout);
+ }
+
+ bool AddRequest(void *pRequest) {
+ return AddTail(pRequest);
+ }
+};
+
+class OS
+{
+public:
+ OS();
+ virtual ~OS();
+
+ static void Sleep(DWORD dwMilliseconds) {
+ ::Sleep(dwMilliseconds);
+ }
+ static time_t GetSystemTimeInMs() {
+ FILETIME systemTime;
+ ::GetSystemTimeAsFileTime(&systemTime);
+ ULARGE_INTEGER time;
+ time.LowPart = systemTime.dwLowDateTime;
+ time.HighPart = systemTime.dwHighDateTime;
+ // file time is in 100 ns intervals, convert to ms
+ return time.QuadPart / 10000;
+ }
+ static DWORD GetErrorCode() {
+ return ::GetLastError();
+ }
+ static void SetErrorCode(DWORD dwErrorCode) {
+ ::SetLastError(dwErrorCode);
+ }
+};
+
+#endif // !defined(__WINAPIWRAPPERS_H__)
+
+// End of file WinApiWrappers.h
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/config/a2_command_ids_h.xsl b/source/config/a2_command_ids_h.xsl
new file mode 100644
index 0000000..d04a32d
--- /dev/null
+++ b/source/config/a2_command_ids_h.xsl
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<import href="a2_common.xsl"/>
+
+<output method="text" indent="no"/>
+<strip-space elements="*"/>
+<param name="target" />
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _A2_COMMAND_IDS_H
+#define _A2_COMMAND_IDS_H
+#include &quot;t_basicdefinitions.h&quot;
+
+typedef enum {
+<apply-templates select="group" mode="id"/>} A2_GroupId_e;
+
+typedef enum {
+<apply-templates select="group/command" mode="id"/>} A2_CommandId_e;
+
+<apply-templates select="typedef" />
+#endif /* _A2_COMMAND_IDS_H */
+</template>
+
+<template match="typedef">typedef struct <value-of select="interface/@name" />_s
+{
+<apply-templates select="value" />}<value-of select="interface/@name" />_t;
+
+</template>
+
+<template match="value">
+<choose>
+<when test="@type='char_array'"> char <text></text><value-of select="@name" />[<text></text><value-of select="@size" />]; /**&lt; <value-of select="text()" /> */
+</when>
+<when test="@type='string'"> char *<text></text><value-of select="@name" />; /**&lt; <value-of select="text()" /> */
+</when>
+<when test="@type='uint32'">
+<text> </text><value-of select="@type" /><text> </text><value-of select="@name" />; /**&lt; <value-of select="text()" /> */
+</when>
+<when test="@type='uint64'">
+<text> </text><value-of select="@type" /><text> </text><value-of select="@name" />; /**&lt; <value-of select="text()" /> */
+</when>
+</choose>
+</template>
+
+<template match="group" mode="id">
+<text> </text><call-template name="groupid" /> = <value-of select="@number" />, /**&lt; <value-of select="@name" /> */
+</template>
+
+<template match="command" mode="id">
+<text> </text><call-template name="commandid" /> = <value-of select="@number" />, /**&lt; <value-of select="@name" /> */
+</template>
+
+</stylesheet>
diff --git a/source/config/a2_commands.xml b/source/config/a2_commands.xml
new file mode 100644
index 0000000..01803a1
--- /dev/null
+++ b/source/config/a2_commands.xml
@@ -0,0 +1,1259 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<?xml-stylesheet type="text/xml" href="a2_command_ids_h.xsl"?>
+<?xml-stylesheet type="text/xml" href="a2_command_marshal.xsl"?>
+<?xml-stylesheet type="text/xml" href="a2_commands_h.xsl"?>
+<?xml-stylesheet type="text/xml" href="a2_commands_impl_h.xsl"?>
+<?xml-stylesheet type="text/xml" href="a2_common.xsl"?>
+
+<commandspec>
+
+ <!--
+ Predefine generic type of data are: uint32, string and buffer.
+ All A2 commands use only one buffer as an input and one buffer as an output parametar.
+ !!!!! IMPORTANT !!!!!
+ All new types of data (structures or vectors of structures) that need to be defined should first be reviewed and approved by:
+ Hans Holmberg (QHANHOL) for loaders, Mikael Sjolen XX for PTK and Daniel Chong for PA.
+ -->
+
+ <group number="1" name="A2 System group">
+ <documentation>
+ A2 System commands group (0x01)
+ </documentation>
+ <interface type="loader" name="A2_System"/>
+
+ <command number="1" name="Shutdown" source="PC">
+ <interface type="loader" name="Shutdown"/>
+ <documentation>
+ The Loader shuts down in a controlled fashion and proceeds to shut down the ME itself.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="2" name="Loader Version" source="PC">
+ <interface type="loader" name="LoaderVersion"/>
+ <documentation>
+ The Loader Version command is sent by the PC to request version information from the loader. The ME responds with a Loader Version information coded as ASCII characters in the data field.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="buffer" name="LoaderVersionOut" length="*">Loader version identifier</value>
+ </output>
+ </command>
+<!--
+ <command number="3" name="Protocol Version" source="PC">
+ <interface type="loader" name="ProtocolVersion"/>
+ <documentation>
+ The Protocol Version command is sent by the PC to request the application protocol version information from the loader. The ME responds with two bytes holding the major and the minor version respectively.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="buffer" name="ProtocolVersionOut" length="*">Protocol version identifier</value>
+ </output>
+ </command>
+
+ <command number="5" name="System Supported Command groups" source="PC">
+ <interface type="loader" name="SupportedCommandGroups"/>
+ <documentation>
+ The Loader returns a list of implemented command groups and whether they are permitted to execute in the current Loader state.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="buffer" name="CommandGroupsOut" length="*">Each byte of the string represents a supported command group.</value>
+ </output>
+ </command>
+
+ <command number="6" name="Get Platform Property" source="PC">
+ <interface type="loader" name="GetPlatformProperty"/>
+ <documentation>
+ This command is sent by the PC to request a Platform Property, by sending a PropertyID in the data field. The ME responds with the Property value.
+ </documentation>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetPropertyIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetPropertyOutLength">The size of the PropertyValue depends on the PropertyID</value>
+ <value type="buffer" name="GetPropertyOut" length="GetPropertyOutLength"/>
+ </output>
+ </command>
+
+ <command number="8" name="Get Memory Property" source="PC">
+ <interface type="loader" name="GetMemoryProperty"/>
+ <documentation>
+ This command is sent by the PC to request a Memory Property. The ME responds with the Memory Property value.
+ </documentation>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetMemPropertyIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetMemPropertyOutLength">The size of the PropertyValue depends on the PropertyID</value>
+ <value type="buffer" name="GetMemPropertyOut" length="GetMemPropertyOutLength"/>
+ </output>
+ </command>
+
+ <command number="9" name="Set Memory Property" source="PC">
+ <interface type="loader" name="SetMemoryProperty"/>
+ <documentation>
+ This command is sent by the PC to set a Memory Property.
+ </documentation>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="SetMemPropertyIn" length="PayloadSize">The MemoryPropertyPayload buffer holds the Memory Propertiy ID and the Memory Property value. The size of the MemoryPropertyValue depends on the PropertyID</value>
+ </input>
+ <output>
+ <value type="uint32" name="SetMemPropertyOutLength">The size of the PropertyValue depends on the PropertyID</value>
+ <value type="buffer" name="SetMemPropertyOut" length="SetMemPropertyOutLength"/>
+ </output>
+ </command>
+
+ <command number="15" name="Read Security Data" source="PC">
+ <interface type="loader" name="ReadSecurityData"/>
+ <documentation>
+ This command is used in a Flashless bridge configuration. It returns the Static data and all dinamic variables cretaed during the signing process.
+ </documentation>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="SecurityDataIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="SecurityDataOutLength"/>
+ <value type="buffer" name="SecurityDataOut" length="SecurityDataOutLength"/>
+ </output>
+ </command>
+-->
+ <command number="17" name="Loader on Loader" source="PC">
+ <interface type="loader" name="LoaderOnLoader"/>
+ <documentation>
+ This command is used to transfer a new Loader to the ME. The data should hold either Header or Payload.
+ </documentation>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="Payload" length="PayloadSize"/>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="19" name="Reset" source="PC">
+ <interface type="loader" name="Reset"/>
+ <documentation>
+ The Reset command is used to instruct the Loader to reset the ME. Upon receiving this command, the Loader shuts down in a controlled fashion and restarts the ME.
+ </documentation>
+ <input>
+ <value type="uint32" name="Timeout">Timeout in ms.</value>
+ </input>
+ <output>
+ </output>
+ </command>
+<!--
+ <command number="20" name="Simlock Authentication Request" source="PC">
+ <interface type="loader" name="SimlockAuthenticationRequest"/>
+ <documentation>
+ This command is sent by the PC to set the SIM Lock Keys.
+ </documentation>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="SIMLockAuthReqIn" length="PayloadSize">There are 12 SIM Lock Keys, each represented with a 16 bytes long string.</value>
+ </input>
+ <output>
+ <value type="uint32" name="SIMLockAuthReqOutLength"/>
+ <value type="buffer" name="SIMLockAuthReqOut" length="SIMLockAuthReqOutLength"/>
+ </output>
+ </command>
+-->
+ </group>
+
+ <group number="2" name="A2 Flash group">
+ <documentation>
+ A2 Flash Commands group (0x02)
+ </documentation>
+
+ <interface type="loader" name="A2_Flash"/>
+
+ <command number="1" name="Verify Signed Header" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="VerifySignedHeader"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="VerifyHeaderIn" length="PayloadSize"/>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="2" name="Software Block Address" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="SoftwareBlockAddress"/>
+ <input>
+ <value type="uint32" name="StartAddress">Start address of the block.</value>
+ <value type="uint32" name="BlockSize">Size of the block.</value>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="3" name="Program Flash" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="ProgramFlash"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="Payload" length="PayloadSize"/>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="4" name="Verify Software Flash" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="VerifySoftwareFlash"/>
+ <input>
+ </input>
+ <output>
+ </output>
+ </command>
+<!--
+ <command number="5" name="Dump Flash Image" flag="true1" source="PC">
+ <documentation>
+ This command is used to readp from the flash. The input parameters buffer holds: Logical Unit number = 4 bits, Start address = 28 bits and End address = 4 bytes.
+ </documentation>
+ <interface type="loader" name="DumpFlashImage"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="DumpFlashImageIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="DumpFlashImageOutLength"/>
+ <value type="buffer" name="DumpFlashImageOut" length="DumpFlashImageOutLength"/>
+ </output>
+ </command>
+
+ <command number="6" name="Read PMC Status" flag="true1" source="PC">
+ <documentation>
+ The Read PMC Status command is used to read the value and status of a Protected Monotonic Counter.
+ </documentation>
+ <interface type="loader" name="ReadPmcStatus"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ReadPmcStatusIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ReadPmcStatusOutLength"/>
+ <value type="buffer" name="ReadPmcStatusOut" length="ReadPmcStatusOutLength"/>
+ </output>
+ </command>
+-->
+ <command number="7" name="Erase Flash" flag="true1" source="PC">
+ <documentation>
+ The Erase flash command is used to erase the complete flash memory.
+ </documentation>
+ <interface type="loader" name="EraseFlash"/>
+ <input>
+ </input>
+ <output>
+ </output>
+ </command>
+<!--
+ <command number="8" name="Program Without Erase Flash" flag="true1" source="PC">
+ <documentation>
+ The Program without erase flash command is sent by the PC to write a block of data into the flash memory, but, to save time, without checking if the flash is empty and without erasing the flash.
+ </documentation>
+ <interface type="loader" name="ProgramWithoutEraseFlash"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ProgramWithoutEraseIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="buffer" name="ProgramWithoutEraseFlashOut" length="*"/>
+ </output>
+ </command>
+
+ <command number="9" name="Dump Physical Flash Image" flag="true1" source="PC">
+ <documentation>
+ The Dump physical flash image command is used to read data from a physical flash location (physical addresses) and send it to the PC.
+ </documentation>
+ <interface type="loader" name="DumpPhysicalFlashImage"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="DumpPhysicalFlashImageIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="DumpPhysicalFlashImageOutLength"/>
+ <value type="buffer" name="DumpPhysicalFlashImageOut" length="DumpPhysicalFlashImageOutLength"/>
+ </output>
+ </command>
+-->
+ <command number="10" name="Speedflash" flag="true1" source="PC">
+ <documentation>
+ The Dump physical flash image command is used to read data from a physical flash location (physical addresses) and send it to the PC.
+ </documentation>
+ <interface type="loader" name="Speedflash"/>
+ <input>
+ <value type="uint32" name="StartAddress">Start address of the block to be flashed</value>
+ <value type="uint32" name="EndAddress">End address of the block to be flashed</value>
+ <value type="uint32" name="SubBlockSize">Size of the single block to be transfered</value>
+ </input>
+ <output>
+ </output>
+ </command>
+<!--
+ <command number="11" name="Write Preflash Image Using Speedflash" flag="true1" source="PC">
+ <documentation>
+ The Write preflash speedflash command is used to write a preflash image to a flash memory.
+ </documentation>
+ <interface type="loader" name="WritePreflashImageUsingSpeedflash"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WritePreflashImageUsingSpeedflashIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WritePreflashImageUsingSpeedflashOutLength"/>
+ <value type="buffer" name="WritePreflashImageUsingSpeedflashOut" length="WritePreflashImageUsingSpeedflashOutLength"/>
+ </output>
+ </command>
+
+ <command number="19" name="Dump Preflash Image" flag="true1" source="PC">
+ <documentation>
+ This command reads all data from flash (both flash page data and corresponding redundant data) and dumps the data in a file from which a preflash image can be created.
+ </documentation>
+ <interface type="loader" name="DumpPreflashImage"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="DumpPreflashImageIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="DumpPreflashImageOutLength"/>
+ <value type="buffer" name="DumpPreflashImageOut" length="DumpPreflashImageOutLength"/>
+ </output>
+ </command>
+
+ <command number="20" name="Write Preflash Image" flag="true1" source="PC">
+ <documentation>
+ This command is used to write a preflashed image to a flash memory.
+ </documentation>
+ <interface type="loader" name="WritePreflashImage"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WritePreflashImageIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WritePreflashImageOutLength"/>
+ <value type="buffer" name="WritePreflashImageOut" length="WritePreflashImageOutLength"/>
+ </output>
+ </command>
+-->
+ </group>
+<!--
+ <group number="3" name="A2 GDFS group">
+ <documentation>
+ A2 GDFS Commands Group (0x03)
+ </documentation>
+ <interface type="loader" name="A2_GDFS"/>
+
+ <command number="1" name="Get GDFS property" flag="true1" source="PC">
+ <documentation>
+ The Get GDFS property command reads a GDFS setting on the access side.
+ </documentation>
+ <interface type="loader" name="GetGdfsPropertyAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetGdfsPropertyAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetGdfsPropertyAccOutLength"/>
+ <value type="buffer" name="GetGdfsPropertyAccOut" length="GetGdfsPropertyAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="2" name="Force start GDFS" flag="true1" source="PC">
+ <documentation>
+ The Force start GDFS command starts GDFS on the access side using the configuration sent in the data field.
+ </documentation>
+ <interface type="loader" name="ForceStartGdfsAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ForceStartGdfsAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ForceStartGdfsAccOutLength"/>
+ <value type="buffer" name="ForceStartGdfsAccOut" length="ForceStartGdfsAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="3" name="Auto start GDFS" flag="true1" source="PC">
+ <documentation>
+ The Auto start GDFS command tries to find the currently used GDFS configuration inside the platform software on the flash.
+ </documentation>
+ <interface type="loader" name="AutoStartGdfsAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="AutoStartGdfsAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="AutoStartGdfsAccOutLength"/>
+ <value type="buffer" name="AutoStartGdfsAccOut" length="AutoStartGdfsAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="4" name="Format GDFS" flag="true1" source="PC">
+ <documentation>
+ The Format GDFS command is sent to the loader to format the GDFS.
+ </documentation>
+ <interface type="loader" name="FormatGdfsAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="FormatGdfsAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="FormatGdfsAccOutLength"/>
+ <value type="buffer" name="FormatGdfsAccOut" length="FormatGdfsAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="5" name="Read GDFS unit" flag="true1" source="PC">
+ <documentation>
+ The Read GDFS unit command retrieves a unit from GDFS on the access side.
+ </documentation>
+ <interface type="loader" name="ReadGdfsUnitAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ReadGdfsUnitAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ReadGdfsUnitAccOutLength"/>
+ <value type="buffer" name="ReadGdfsUnitAccOut" length="ReadGdfsUnitAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="6" name="Read entire GDFS" flag="true1" source="PC">
+ <documentation>
+ The Read entire GDFS command is used to read all GDFS units in the ME on the access side.
+ </documentation>
+ <interface type="loader" name="ReadEntireGdfsAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ReadEntireGdfsAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ReadEntireGdfsAccOutLength"/>
+ <value type="buffer" name="ReadEntireGdfsAccOut" length="ReadEntireGdfsAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="7" name="Write GDFS unit" flag="true1" source="PC">
+ <documentation>
+ The Write GDFS unit command is used to write one or more GDFS units on the access side.
+ </documentation>
+ <interface type="loader" name="WriteGdfsUnitAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WriteGdfsUnitAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WriteGdfsUnitAccOutLength"/>
+ <value type="buffer" name="WriteGdfsUnitAccOut" length="WriteGdfsUnitAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="10" name="Write entire GDFS" flag="true1" source="PC">
+ <documentation>
+ The Write entire GDFS command is used to write all GDFS units on the access side.
+ </documentation>
+ <interface type="loader" name="WriteEntireGdfsAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WriteEntireGdfsAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WriteEntireGdfsAccOutLength"/>
+ <value type="buffer" name="WriteEntireGdfsAccOut" length="WriteEntireGdfsAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="11" name="Dump entire GDFS" flag="true1" source="PC">
+ <documentation>
+ The Dump entire GDFS command is used to dump all GDFS units on the access side.
+ </documentation>
+ <interface type="loader" name="DumpEntireGdfsAcc"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="DumpEntireGdfsAccIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="DumpEntireGdfsAccOutLength"/>
+ <value type="buffer" name="DumpEntireGdfsAccOut" length="DumpEntireGdfsAccOutLength"/>
+ </output>
+ </command>
+
+ <command number="49" name="Get GDFS property" flag="true1" source="PC">
+ <documentation>
+ The Get GDFS property command reads a GDFS setting on the application side.
+ </documentation>
+ <interface type="loader" name="GetGdfsPropertyApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetGdfsPropertyAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetGdfsPropertyAppOutLength"/>
+ <value type="buffer" name="GetGdfsPropertyAppOut" length="GetGdfsPropertyAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="50" name="Force start GDFS" flag="true1" source="PC">
+ <documentation>
+ The Force start GDFS command starts GDFS on the application side using the configuration sent in the data field.
+ </documentation>
+ <interface type="loader" name="ForceStartGdfsApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ForceStartGdfsAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ForceStartGdfsAppOutLength"/>
+ <value type="buffer" name="ForceStartGdfsAppOut" length="ForceStartGdfsAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="51" name="Auto start GDFS" flag="true1" source="PC">
+ <documentation>
+ The Auto start GDFS command tries to find the currently used GDFS configuration inside the platform software on the flash.
+ </documentation>
+ <interface type="loader" name="AutoStartGdfsApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="AutoStartGdfsAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="AutoStartGdfsAppOutLength"/>
+ <value type="buffer" name="AutoStartGdfsAppOut" length="AutoStartGdfsAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="52" name="Format GDFS" flag="true1" source="PC">
+ <documentation>
+ The Format GDFS command is sent to the loader to format the GDFS on the application side.
+ </documentation>
+ <interface type="loader" name="FormatGdfsApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="FormatGdfsAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="FormatGdfsAppOutLength"/>
+ <value type="buffer" name="FormatGdfsAppOut" length="FormatGdfsAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="53" name="Read GDFS unit" flag="true1" source="PC">
+ <documentation>
+ The Read GDFS unit command retrieves a unit from GDFS on the application side.
+ </documentation>
+ <interface type="loader" name="ReadGdfsUnitApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ReadGdfsUnitAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ReadGdfsUnitAppOutLength"/>
+ <value type="buffer" name="ReadGdfsUnitAppOut" length="ReadGdfsUnitAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="54" name="Read entire GDFS" flag="true1" source="PC">
+ <documentation>
+ The Read entire GDFS command is used to read all GDFS units in the ME on the application side.
+ </documentation>
+ <interface type="loader" name="ReadEntireGdfsApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ReadEntireGdfsAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ReadEntireGdfsAppOutLength"/>
+ <value type="buffer" name="ReadEntireGdfsAppOut" length="ReadEntireGdfsAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="55" name="Write GDFS unit" flag="true1" source="PC">
+ <documentation>
+ The Write GDFS unit command is used to write one or more GDFS units on the application side.
+ </documentation>
+ <interface type="loader" name="WriteGdfsUnitApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WriteGdfsUnitAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WriteGdfsUnitAppOutLength"/>
+ <value type="buffer" name="WriteGdfsUnitAppOut" length="WriteGdfsUnitAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="58" name="Write entire GDFS" flag="true1" source="PC">
+ <documentation>
+ The Write entire GDFS command is used to write all GDFS units on the application side.
+ </documentation>
+ <interface type="loader" name="WriteEntireGdfsApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WriteEntireGdfsAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WriteEntireGdfsAppOutLength"/>
+ <value type="buffer" name="WriteEntireGdfsAppOut" length="WriteEntireGdfsAppOutLength"/>
+ </output>
+ </command>
+
+ <command number="59" name="Dump entire GDFS" flag="true1" source="PC">
+ <documentation>
+ The Dump Entire GDFS command is used to dump all GDFS units on the application side.
+ </documentation>
+ <interface type="loader" name="DumpEntireGdfsApp"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="DumpEntireGdfsAppIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="DumpEntireGdfsAppOutLength"/>
+ <value type="buffer" name="DumpEntireGdfsAppOut" length="DumpEntireGdfsAppOutLength"/>
+ </output>
+ </command>
+
+ </group>
+
+ <group number="4" name="File system group">
+ <documentation>
+ A2 File system commands Group (0x04)
+ </documentation>
+ <interface type="loader" name="A2_File_System"/>
+
+ <command number="1" name="Get File System Property" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="GetFileSystemProperty"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetFSPropertyIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetFSPropertyOutLength"/>
+ <value type="buffer" name="GetFSPropertyOut" length="GetFSPropertyOutLength"/>
+ </output>
+ </command>
+
+ <command number="2" name="Force Start File System" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="ForceStartFileSystem"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ForceStartFSIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ForceStartFSOutLength"/>
+ <value type="buffer" name="ForceStartFSOut" length="ForceStartFSOutLength"/>
+ </output>
+ </command>
+
+ <command number="3" name="Set File System Property" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="SetFileSystemProperty"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="SetFSPropertyIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="SetFSPropertyOutLength"/>
+ <value type="buffer" name="SetFSPropertyOut" length="SetFSPropertyOutLength"/>
+ </output>
+ </command>
+
+ <command number="4" name="Copy File" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="CopyFile"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="CopyFileIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="CopyFileOutLength"/>
+ <value type="buffer" name="CopyFileOut" length="CopyFileOutLength"/>
+ </output>
+ </command>
+
+ <command number="5" name="Move File" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="MoveFile"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="MoveFileIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="MoveFileOutLength"/>
+ <value type="buffer" name="MoveFileOut" length="MoveFileOutLength"/>
+ </output>
+ </command>
+
+ <command number="6" name="Rename" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="Rename"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="RenameIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="RenameOutLength"/>
+ <value type="buffer" name="RenameOut" length="RenameOutLength"/>
+ </output>
+ </command>
+
+ <command number="7" name="Delete File" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="DeleteFile"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="DeleteFileIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="DeleteFileOutLength"/>
+ <value type="buffer" name="DeleteFileOut" length="DeleteFileOutLength"/>
+ </output>
+ </command>
+
+ <command number="8" name="Make Directory" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="MakeDirectory"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="MakeDirectoryIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="MakeDirectoryOutLength"/>
+ <value type="buffer" name="MakeDirectoryOut" length="MakeDirectoryOutLength"/>
+ </output>
+ </command>
+
+ <command number="9" name="Change Directory" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="ChangeDirectory"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ChangeDirectoryIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ChangeDirectoryOutLength"/>
+ <value type="buffer" name="ChangeDirectoryOut" length="ChangeDirectoryOutLength"/>
+ </output>
+ </command>
+
+ <command number="10" name="Get Current Directory" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="GetCurrentDirectory"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetCurrentDirectoryIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetCurrentDirectoryOutLength"/>
+ <value type="buffer" name="GetCurrentDirectoryOut" length="GetCurrentDirectoryOutLength"/>
+ </output>
+ </command>
+
+ <command number="11" name="Remove Directory" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="RemoveDirectory"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="RemoveDirectoryIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="RemoveDirectoryOutLength"/>
+ <value type="buffer" name="RemoveDirectoryOut" length="RemoveDirectoryOutLength"/>
+ </output>
+ </command>
+
+ <command number="12" name="List Subdirectories" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="ListSubdirectories"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ListSubdirectoriesIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ListSubdirectoriesOutLength"/>
+ <value type="buffer" name="ListSubdirectoriesOut" length="ListSubdirectoriesOutLength"/>
+ </output>
+ </command>
+
+ <command number="13" name="List Files" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="ListFiles"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ListFilesIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ListFilesOutLength"/>
+ <value type="buffer" name="ListFilesOut" length="ListFilesOutLength"/>
+ </output>
+ </command>
+
+ <command number="14" name="Stat" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="Stat"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="StatIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="StatOutLength"/>
+ <value type="buffer" name="StatOut" length="StatOutLength"/>
+ </output>
+ </command>
+
+ <command number="15" name="Chmod" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="Chmod"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ChmodIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ChmodOutLength"/>
+ <value type="buffer" name="ChmodOut" length="ChmodOutLength"/>
+ </output>
+ </command>
+
+ <command number="16" name="Put File" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="PutFile"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="PutFileIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="PutFileOutLength"/>
+ <value type="buffer" name="PutFileOut" length="PutFileOutLength"/>
+ </output>
+ </command>
+
+ <command number="17" name="Get File" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="GetFile"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetFileIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetFileOutLength"/>
+ <value type="buffer" name="GetFileOut" length="GetFileOutLength"/>
+ </output>
+ </command>
+
+ <command number="18" name="List Volumes" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="ListVolumes"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="ListVolumesIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="ListVolumesOutLength"/>
+ <value type="buffer" name="ListVolumesOut" length="ListVolumesOutLength"/>
+ </output>
+ </command>
+
+ <command number="19" name="Format Volume" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="FormatVolume"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="FormatVolumeIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="FormatVolumeOutLength"/>
+ <value type="buffer" name="FormatVolumeOut" length="FormatVolumeOutLength"/>
+ </output>
+ </command>
+
+ <command number="20" name="Get Free Space" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="GetFreeSpace"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="GetFreeSpaceIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="GetFreeSpaceOutLength"/>
+ <value type="buffer" name="GetFreeSpaceOut" length="GetFreeSpaceOutLength"/>
+ </output>
+ </command>
+
+ <command number="21" name="Verify Signed Archive Header" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="VerifySignedArchiveHeader"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="VerifySignedArchiveHeaderIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="VerifySignedArchiveHeaderOutLength"/>
+ <value type="buffer" name="VerifySignedArchiveHeaderOut" length="VerifySignedArchiveHeaderOutLength"/>
+ </output>
+ </command>
+
+ <command number="22" name="Verify Signed Archive Data" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="VerifySignedArchiveData"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="VerifySignedArchiveDataIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="VerifySignedArchiveDataOutLength"/>
+ <value type="buffer" name="VerifySignedArchiveDataOut" length="VerifySignedArchiveDataOutLength"/>
+ </output>
+ </command>
+
+ </group>
+
+ <group number="5" name="Signature group">
+ <documentation>
+ A2 Signature Commands Group (0x05)
+ </documentation>
+ <interface type="loader" name="A2_Signature"/>
+
+ <command number="1" name="Set Control Keys" flag="true1" source="PC">
+ <documentation>
+ This command is used to write the SIM Lock control keys.
+ </documentation>
+ <interface type="loader" name="SetControlKeys"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="SetControlKeysIn" length="PayloadSize">There are 12 SIM Lock Keys, each represented with a 16 bytes long string.</value>
+ </input>
+ <output>
+ <value type="uint32" name="SetControlKeysOutLength"/>
+ <value type="buffer" name="SetControlKeysOut" length="SetControlKeysOutLength"/>
+ </output>
+ </command>
+
+ <command number="2" name="Set Platform Property" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+
+ <interface type="loader" name="SetPlatformProperty"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="SetPlatformPropertyIn" length="PayloadSize">The SetPlatformPropertyIn buffer holds the Platform Property ID and the Platform property value. The size of the Platform Property ID is 4 bytes and the size of the Platform Property Value depends on the PropertyID</value>
+ </input>
+ <output>
+ <value type="uint32" name="SetPlatformPropertyOutLength"/>
+ <value type="buffer" name="SetPlatformPropertyOut" length="SetPlatformPropertyOutLength"/>
+ </output>
+ </command>
+
+ <command number="3" name="Write and Lock OTP" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="WriteAndLockOTP"/>
+ <input>
+ <value type="uint32" name="WriteAndLockOTPLength">The length of Write And Lock OTP command buffer</value>
+ <value type="buffer" name="WriteAndLockOTPBuffer" length="WriteAndLockOTPLength">The buffer with Write And Lock OTP command application data</value>
+ </input>
+ <output>
+ <value type="uint32" name="WriteAndLockOTPOutLength"/>
+ <value type="buffer" name="WriteAndLockOTPOut" length="WriteAndLockOTPOutLength"/>
+ </output>
+ </command>
+
+ <command number="4" name="Write Default Data" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="WriteDefaultData"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WriteDefaultDataIn" length="PayloadSize">The WriteDefaultDataIn buffer holds the Unit number,the Unit size and Unit data</value>
+ </input>
+ <output>
+ <value type="uint32" name="WriteDefaultDataOutLength"/>
+ <value type="buffer" name="WriteDefaultDataOut" length="WriteDefaultDataOutLength"/>
+ </output>
+ </command>
+
+ <command number="5" name="Write Full Signature" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="WriteFullSignature"/>
+ <input>
+ <value type="uint32" name="WriteFullSignatureLength">The length of Write Full Signature command buffer</value>
+ <value type="buffer" name="WriteFullSignatureBuffer" length="WriteFullSignatureLength">The buffer with Write Full Signature command application data</value>
+ </input>
+ <output>
+ <value type="uint32" name="WriteFullSignOutLength"/>
+ <value type="buffer" name="WriteFullSignOut" length="WriteFullSignOutLength"/>
+ </output>
+ </command>
+
+ <command number="6" name="Write CID" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="WriteCID"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WriteCIDIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WriteCIDOutLength"/>
+ <value type="buffer" name="WriteCIDOut" length="WriteCIDOutLength"/>
+ </output>
+ </command>
+
+ <command number="7" name="Write Test Signature" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="WriteTestSignature"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="WriteTestSignIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="WriteTestSignOutLength"/>
+ <value type="buffer" name="WriteTestSignOut" length="WriteTestSignOutLength"/>
+ </output>
+ </command>
+
+ <command number="8" name="Erase Security Data" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="EraseSecurityData"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="EraseSecDataIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="EraseSecDataOutLength"/>
+ <value type="buffer" name="EraseSecDataOut" length="EraseSecDataOutLength"/>
+ </output>
+ </command>
+
+ <command number="9" name="Key Sharing Stage 1 Request" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="KeySharingStage1Request"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="KeySharStage1ReqIn" length="PayloadSize">The KeySharStage1ReqIn buffer holds the Version (1 byte), the ID (4 bytes) and Random Value (24 bytes)</value>
+ </input>
+ <output>
+ <value type="uint32" name="KeySharStage1ReqOutLength"/>
+ <value type="buffer" name="KeySharStage1ReqOut" length="KeySharStage1ReqOutLength"/>
+ </output>
+ </command>
+
+ <command number="10" name="Key Sharing Stage 2 Request" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="KeySharingStage2Request"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="KeySharStage2ReqIn" length="PayloadSize">The KeySharStage2ReqIn buffer holds the ID (4 bytes), the Cipher (1 byte), the CertificateLength (4 bytes) and Certificate (CertificateLength)</value>
+ </input>
+ <output>
+ <value type="uint32" name="KeySharStage2ReqOutLength"/>
+ <value type="buffer" name="KeySharStage2ReqOut" length="KeySharStage2ReqOutLength"/>
+ </output>
+ </command>
+
+ <command number="11" name="Key Sharing Stage 3 Request" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="KeySharingStage3Request"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="KeySharStage3ReqIn" length="PayloadSize">The KeySharStage3ReqIn buffer holds the ID (4 bytes), C2 (16 bytes) and MAC (20 bytes).</value>
+ </input>
+ <output>
+ <value type="uint32" name="KeySharStage3ReqOutLength"/>
+ <value type="buffer" name="KeySharStage3ReqOut" length="KeySharStage3ReqOutLength"/>
+ </output>
+ </command>
+
+ <command number="12" name="DRM Secure Storage Request" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="DRMSecureStorageRequest"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="DRMSecStorReqIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="DRMSecStorReqOutLength"/>
+ <value type="buffer" name="DRMSecStorReqOut" length="DRMSecStorReqOutLength"/>
+ </output>
+ </command>
+
+ <command number="14" name="Verify Control Keys" flag="true1" source="PC">
+ <documentation>
+ This command is used to compare received SIM Lock keys against the SIM Lock keys stored in the ME.
+ </documentation>
+ <interface type="loader" name="VerifyControlKeys"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="VerifyControlKeysIn" length="PayloadSize">There are 12 SIM Lock Keys, each represented with a 16 bytes long string.</value>
+ </input>
+ <output>
+ <value type="uint32" name="VerifyControlKeysOutLength"/>
+ <value type="buffer" name="VerifyControlKeysOut" length="VerifyControlKeysOutLength"/>
+ </output>
+ </command>
+
+ <command number="16" name="Secure Storage Request" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="SecureStorageRequest"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="SecStorReqIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="SecStorReqOutLength"/>
+ <value type="buffer" name="SecStorReqOut" length="SecStorReqOutLength"/>
+ </output>
+ </command>
+
+ </group>
+
+ <group number="7" name="Reset group">
+ <documentation>
+ A2 Reset Commands group (0x07)
+ </documentation>
+
+ <interface type="loader" name="A2_Reset"/>
+
+ <command number="1" name="Init Request" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="InitRequest"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="InitRequestIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="InitRequestOutLength"/>
+ <value type="buffer" name="InitRequestOut" length="InitRequestOutLength"/>
+ </output>
+ </command>
+
+ <command number="2" name="Update Request" flag="true1" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="UpdateRequest"/>
+ <input>
+ <value type="uint32" name="PayloadSize">Application packet length</value>
+ <value type="buffer" name="UpdateRequestIn" length="PayloadSize"/>
+ </input>
+ <output>
+ <value type="uint32" name="UpdateRequestOutLength"/>
+ <value type="buffer" name="UpdateRequestOut" length="UpdateRequestOutLength"/>
+ </output>
+ </command>
+
+ </group>
+-->
+ <group number="16" name="Control message">
+ <documentation>
+ A2 Control message (0x10)
+ </documentation>
+ <interface type="loader" name="A2_Control"/>
+
+ <command number="1" name="Loader Started" source="ME">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="LoaderStarted"/>
+ <input>
+ <value type="uint32" name="MaxLoaderPacketSize"/>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="2" name="Ping" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="Ping"/>
+ <input>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="3" name="Pong" source="ME">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="Pong"/>
+ <input>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="4" name="Max Packet Size" source="PC">
+ <documentation>
+ </documentation>
+ <interface type="loader" name="MaxPacketSize"/>
+ <input>
+ </input>
+ <output>
+ <value type="uint16" name="MaxPacketSize"/>
+ </output>
+ </command>
+
+ <command number="5" name="Loader Not Started" source="ME">
+ <interface type="loader" name="LoaderNotStarted"/>
+ <documentation>
+ </documentation>
+ <input>
+ <value type="uint16" name="ErrorCode"/>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ </group>
+</commandspec>
diff --git a/source/config/a2_commands_h.xsl b/source/config/a2_commands_h.xsl
new file mode 100644
index 0000000..230083d
--- /dev/null
+++ b/source/config/a2_commands_h.xsl
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<import href="a2_common.xsl"/>
+
+<output method="text" indent="no"/>
+<strip-space elements="*"/>
+<param name="target" />
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _A2_COMMANDS_H_
+#define _A2_COMMANDS_H_
+
+#include &quot;LCDriver.h&quot;
+#include &quot;LcmInterface.h&quot;
+#include &quot;t_basicdefinitions.h&quot;
+#include &quot;CmdResult.h&quot;
+//#include &quot;error_codes.h&quot;
+//#include &quot;t_a2_protocol.h&quot;
+//#include "a2_command_ids.h"
+
+class CLCDriverMethods;
+
+class A2LoaderRpcInterface
+{
+public:
+ A2LoaderRpcInterface(CLCDriverMethods* lcdMethods, CmdResult* cmdResult, LcmInterface* lcmInterface):
+ lcdMethods_(lcdMethods),
+ cmdResult_(cmdResult),
+ lcmInterface_(lcmInterface),
+ targetCpu_(0),
+ morePackets_(0)
+ {
+ }
+
+ virtual ~A2LoaderRpcInterface()
+ {
+ }
+<apply-templates select="group"/>
+public:
+ void setTargetCpu(uint8 targetCpu) { targetCpu_ = targetCpu; }
+ void setMorePackets(uint8 morePackets) { morePackets_ = morePackets; }
+protected:
+ CLCDriverMethods* lcdMethods_;
+ CmdResult* cmdResult_;
+ LcmInterface* lcmInterface_;
+ uint8 targetCpu_;
+ uint8 morePackets_;
+};
+
+#endif /* _A2_COMMANDS_H_ */
+</template>
+
+<template match="group/command">
+<if test="contains(@source, &apos;ME&apos;)">
+<call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)"/>
+ <with-param name="ref" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)"/>
+ <with-param name="direction" select="input"/>
+ <with-param name="source" select="&apos;ME&apos;"/>
+</call-template>
+</if>
+<if test="contains(@source, &apos;PC&apos;)">
+<call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)"/>
+ <with-param name="ref" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)"/>
+ <with-param name="direction" select="output"/>
+ <with-param name="source" select="&apos;PC&apos;"/>
+</call-template>
+</if>
+</template>
+</stylesheet>
diff --git a/source/config/a2_commands_impl_h.xsl b/source/config/a2_commands_impl_h.xsl
new file mode 100644
index 0000000..6fb1631
--- /dev/null
+++ b/source/config/a2_commands_impl_h.xsl
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" >
+
+<import href="a2_common.xsl"/>
+
+<output method="text"/>
+<strip-space elements="*"/>
+<param name="target" />
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _A2_COMMANDS_IMPL_H_
+#define _A2_COMMANDS_IMPL_H_
+
+#include &quot;a2_commands.h&quot;
+#include &quot;a2_command_ids.h&quot;
+#include &quot;LCDriver.h&quot;
+#include &quot;LcmInterface.h&quot;
+#include &quot;error_codes.h&quot;
+
+class CLCDriverMethods;
+
+class A2LoaderRpcInterfaceImpl : public A2LoaderRpcInterface
+{
+public:
+ A2LoaderRpcInterfaceImpl(CLCDriverMethods* lcdMethods, CmdResult* cmdResult, LcmInterface* lcmInterface):
+ A2LoaderRpcInterface(lcdMethods, cmdResult, lcmInterface)
+ {
+ }
+
+ ~A2LoaderRpcInterfaceImpl()
+ {
+ }
+
+ ErrorCode_e Do_CEH_Callback(CommandData_t* pCmdData);
+<apply-templates select="group" />
+};
+
+#endif /* _A2_COMMANDS_IMPL_H_ */
+</template>
+
+<template match="group/documentation">
+ /*
+ * <value-of select="normalize-space(.)"/>
+ */
+</template>
+
+<template match="group/command">
+ <if test="contains(@source, &apos;PC&apos;)">
+ <call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)" />
+ <with-param name="ref" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)" />
+ <with-param name="direction" select="input" />
+ <with-param name="source" select="&apos;PC&apos;" />
+ </call-template>
+ </if>
+ <if test="contains(@source, &apos;ME&apos;)">
+ <call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)" />
+ <with-param name="ref" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)" />
+ <with-param name="direction" select="output" />
+ <with-param name="source" select="&apos;ME&apos;" />
+ </call-template>
+ </if>
+</template>
+
+</stylesheet>
diff --git a/source/config/a2_commands_marshal_cpp.xsl b/source/config/a2_commands_marshal_cpp.xsl
new file mode 100644
index 0000000..a30be7b
--- /dev/null
+++ b/source/config/a2_commands_marshal_cpp.xsl
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<import href="a2_common.xsl"/>
+
+<output method="text"/>
+<strip-space elements="*"/>
+<param name="target"/>
+
+<template match="group/documentation" mode="marshal">
+/*
+ * <value-of select="normalize-space(.)"/>
+ */
+</template>
+
+<template match="group/documentation" mode="unmarshal">
+ /*
+ * <value-of select="normalize-space(.)"/>
+ */
+</template>
+
+<template name="unmarshal">
+ <param name="name"/>
+ <param name="direction"/>
+
+ <choose>
+ <when test="name($direction)='output'">
+ /* Command <value-of select="../@name"/> / <value-of select="@name"/> (<value-of select="../@number"/> / <value-of select="@number"/>) */
+ case A2_COMMAND(FALSE, <call-template name="groupid"><with-param name="path" select=".."/></call-template>, <call-template name="commandid"/>):
+ {
+<apply-templates select="input/value" mode="deserialize_size" /><if test="count(input/value) > 0"> if (0 != PayloadSize)
+ {
+<apply-templates select="input/value" mode="deserialize" /> }
+</if> ReturnValue = <value-of select="$name" />(Session<apply-templates select="input/value" mode="call" />);<apply-templates select="input/value" mode="clean"/>
+ }
+ break;
+ </when>
+ <when test="name($direction)='input'">
+ /* Response to <value-of select="../@name"/> / <value-of select="@name"/> (<value-of select="../@number"/> / <value-of select="@number"/>) */
+ case A2_COMMAND(TRUE, <call-template name="groupid"><with-param name="path" select=".."/></call-template>, <call-template name="commandid"/>):
+ {
+<if test="../@number != 16"> ResponseStatus = (ErrorCode_e)Serialization::get_uint16_le(&amp;Data_p);
+ PayloadSize -= 2;</if><text>
+</text>
+<apply-templates select="output/value" mode="deserialize_size" />
+<if test="count(output/value) > 0"><if test="../@number != 16"> if (E_SUCCESS == ResponseStatus)</if>
+ {
+<apply-templates select="output/value" mode="deserialize" /> }</if>
+ ReturnValue = <value-of select="$name" />(Session<if test="../@number != 16">, ResponseStatus</if><apply-templates select="output/value" mode="call"><with-param name="continue" select="'true'" /></apply-templates>);<apply-templates select="output/value" mode="clean"/>
+ }
+ break;
+ </when>
+ </choose>
+</template>
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+
+#include "Serialization.h"
+#include "a2_commands_impl.h"
+#include "t_a2_protocol.h"
+//#include "a2_custom_commands.h" //when customer commands will be implemented
+#include "LCDriverMethods.h"
+
+#define A2_COMMAND(response, group, id) ((((int)(response)) &lt;&lt; 30) | (((int)(group)) &lt;&lt; 16) | ((int)(id)))
+#define A2_COMMANDDATA(TypeP,ApplicationP,CommandP,SessionP,SizeP) \
+ memset((uint8*)&amp;CmdData, 0x00, sizeof(A2_CommandData_t)); \
+ CmdData.Type = TypeP; \
+ CmdData.ApplicationNr = ApplicationP; \
+ CmdData.CommandNr = CommandP; \
+ CmdData.SessionNr = SessionP; \
+ CmdData.Payload.Size = SizeP; \
+ CmdData.Payload.Data_p = NULL; \
+ if(SizeP != 0)\
+ { \
+ CmdData.Payload.Data_p = (uint8*)malloc(sizeof(ErrorCode_e) + SizeP); \
+ if(NULL == CmdData.Payload.Data_p) \
+ { \
+ return E_ALLOCATE_FAILED; \
+ }\
+ }
+
+#define A2_COMMANDDATAOUT(TypeP,ApplicationP,CommandP,SessionP,SizeP,TargetCPU) \
+ memset((uint8*)&amp;CmdData, 0x00, sizeof(A2_CommandData_t)); \
+ CmdData.Type = TypeP; \
+ CmdData.ApplicationNr = ApplicationP; \
+ CmdData.CommandNr = CommandP; \
+ CmdData.SessionNr = SessionP; \
+ CmdData.Payload.Size = SizeP; \
+ CmdData.Payload.Data_p = NULL; \
+ CmdData.DestAddress = TargetCPU; \
+ if(SizeP != 0) \
+ { \
+ CmdData.Payload.Data_p = (uint8*)malloc(SizeP); \
+ if(NULL == CmdData.Payload.Data_p) \
+ { \
+ return E_ALLOCATE_FAILED; \
+ } \
+ }
+
+ErrorCode_e A2LoaderRpcInterfaceImpl::Do_CEH_Callback(CommandData_t* pCmdData)
+{
+ A2_CommandData_t* CmdData_p = (A2_CommandData_t*)pCmdData;
+ ErrorCode_e ReturnValue = E_GENERAL_FATAL_ERROR;
+ ErrorCode_e ResponseStatus = E_GENERAL_FATAL_ERROR;
+ boolean response = FALSE;
+ const void *Data_p = CmdData_p-&gt;Payload.Data_p;
+ uint32 PayloadSize = CmdData_p-&gt;Payload.Size;
+ uint16 Session = CmdData_p-&gt;SessionNr;
+
+ if (A2_GENERAL_RESPONSE == CmdData_p-&gt;Type)
+ {
+ // skip fields already handled by LCM: command group, 0xFF, more packets and original command
+ Data_p = ((uint8*)Data_p) + 4;
+ PayloadSize -= 4;
+ response = TRUE;
+ }
+ else if (A2_COMMAND == CmdData_p-&gt;Type)
+ {
+ // skip fields already handled by LCM: command group, command and more packets fields
+ Data_p = ((uint8*)Data_p) + 3;
+ PayloadSize -= 3;
+ response = FALSE;
+ }
+ else if (A2_CONTROL_MESSAGE == CmdData_p-&gt;Type)
+ {
+ // skip control message ID
+ Data_p = ((uint8*)Data_p) + 1;
+ PayloadSize -= 1;
+ response = FALSE;
+ }
+ else if (A2_SPEEDFLASH_GR == CmdData_p->Type)
+ {
+ uint16 Status = Serialization::get_uint16_le(&amp;Data_p);
+ lcdMethods_-&gt;AddEvent(new Event(EVENT_SPEEDFLASH, Status));
+ return E_SUCCESS;
+ }
+ else
+ {
+ return E_GENERAL_FATAL_ERROR;
+ }
+
+ switch(A2_COMMAND(response, CmdData_p-&gt;ApplicationNr, CmdData_p-&gt;CommandNr))
+ {
+<apply-templates select="group" mode="unmarshal"/>
+ default:
+ {
+ return E_COMMAND_NO_ERROR; // Do_CustomCEH_Call(CmdData_p); // when customer commands will be implemented
+ }
+ }
+
+ if (response)
+ {
+ lcdMethods_-&gt;AddEvent(new Event(EVENT_GR_RECEIVED, ResponseStatus, CmdData_p-&gt;ApplicationNr, CmdData_p-&gt;CommandNr));
+ }
+ else
+ {
+ lcdMethods_-&gt;AddEvent(new Event(EVENT_CMD_RECEIVED, 0, CmdData_p-&gt;ApplicationNr, CmdData_p-&gt;CommandNr));
+ }
+
+ return ReturnValue;
+}
+<apply-templates select="group" mode="marshal"/>
+</template>
+
+<template match="group/command" mode="marshal">
+<if test="contains(@source, &apos;PC&apos;)">
+ErrorCode_e <value-of select="concat('A2LoaderRpcInterface::DoRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name)" />(uint16 SessionOut<apply-templates select="input/value" mode="declare" />)
+{
+ ErrorCode_e Answer;
+ A2_CommandData_t CmdData;
+ void *Data_p;
+ uint32 PLSize = 3;
+<apply-templates select="input/value" mode="serialize_size"/>
+ A2_COMMANDDATAOUT(A2_COMMAND, <call-template name="groupidmain"/>, <call-template name="commandid"/>, SessionOut, PLSize, targetCpu_);
+ Data_p = CmdData.Payload.Data_p;
+
+ // set command group and command
+ Serialization::put_uint8(&amp;Data_p, <call-template name="groupidmain"/>);
+ Serialization::put_uint8(&amp;Data_p, <call-template name="commandid"/>);
+ // set more packets
+ Serialization::put_uint8(&amp;Data_p, morePackets_);
+
+<apply-templates select="input/value" mode="serialize"/>
+ Answer = lcmInterface_->A2CommandSend(&amp;CmdData);
+
+ if(NULL != CmdData.Payload.Data_p)
+ free(CmdData.Payload.Data_p);
+ return Answer;
+}
+</if>
+<if test="contains(@source, &apos;ME&apos;)">
+ErrorCode_e <value-of select="concat('A2LoaderRpcInterface::DoneRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name)" />(uint16 Session<apply-templates select="output/value" mode="declare"><with-param name="continue" select="'true'" /></apply-templates>)
+{
+ ErrorCode_e Answer;
+ A2_CommandData_t CmdData;
+ void *Data_p;
+ uint32 PLSize = 0;
+<apply-templates select="output/value" mode="serialize_size_declaration" />
+<apply-templates select="output/value" mode="serialize_size"/>
+ A2_COMMANDDATA(A2_GENERAL_RESPONSE, <call-template name="groupidmain"/>, <call-template name="commandid"/>, Session, PLSize);
+ Data_p = CmdData.Payload.Data_p;
+
+<apply-templates select="output/value" mode="serialize"/>
+ Answer = lcmInterface_->A2CommandSend(&amp;CmdData);
+
+ if(NULL != CmdData.Payload.Data_p)
+ free(CmdData.Payload.Data_p);
+ return Answer;
+}
+</if>
+</template>
+
+<template match="group/command" mode="unmarshal">
+ <if test="contains(@source, &apos;PC&apos;)">
+ <call-template name="unmarshal">
+ <with-param name="name" select="concat('DoneRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name, 'Impl')" />
+ <with-param name="direction" select="input"/>
+ </call-template>
+ </if>
+ <if test="contains(@source, &apos;ME&apos;)">
+ <call-template name="unmarshal">
+ <with-param name="name" select="concat('DoRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name, 'Impl')" />
+ <with-param name="direction" select="output"/>
+ </call-template>
+ </if>
+</template>
+
+</stylesheet>
diff --git a/source/config/a2_common.xsl b/source/config/a2_common.xsl
new file mode 100644
index 0000000..721b8cd
--- /dev/null
+++ b/source/config/a2_common.xsl
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<template name="groupidmain">
+<param name="path" select="../." />
+<value-of select="concat('GROUP_', translate($path/interface[@type='loader']/@name,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'))" />
+</template>
+
+<template name="groupid">
+<param name="path" select="." />
+<value-of select="concat('GROUP_', translate($path/interface[@type='loader']/@name,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'))" />
+</template>
+
+<template name="commandid">
+<param name="path" select="." />
+<value-of select="translate(concat('COMMAND_', $path/../interface[@type='loader']/@name, '_', $path/interface[@type='loader']/@name),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
+</template>
+
+<template match="value" mode="deserialize">
+<choose>
+<when test="@type='uint16'"><text> </text><value-of select="@name" /> = Serialization::get_uint16_le(&amp;Data_p);
+</when>
+<when test="@type='uint32'"><text> </text><value-of select="@name" /> = Serialization::get_uint32_le(&amp;Data_p);
+</when>
+<when test="@type='uint64'"><text> </text><value-of select="@name" /> = Serialization::get_uint64_le(&amp;Data_p);
+</when>
+<when test="@type='string'"><text> </text><value-of select="@name" /> = Serialization::skip_str(&amp;Data_p);
+</when>
+<when test="@type='buffer' and @length!='*'"><text> </text><value-of select="@name" /> = Data_p;
+<text> </text>Serialization::skip_block(&amp;Data_p, <value-of select="@length" />);
+</when>
+<when test="@type='buffer' and @length='*'"><text> </text><value-of select="@name" /> = Data_p;
+<text> </text>Serialization::skip_block(&amp;Data_p, <value-of select="@name" />PLSize);
+</when>
+</choose>
+</template>
+
+<template match="value" mode="deserialize_size">
+<choose>
+<when test="@type='uint16'"> uint16 <value-of select="@name" /> = 0;
+</when>
+<when test="@type='uint32'"> uint32 <value-of select="@name" /> = 0;
+</when>
+<when test="@type='uint64'"> uint64 <value-of select="@name" /> = 0;
+</when>
+<when test="@type='string'"> const char *<value-of select="@name" /> = NULL;
+</when>
+<when test="@type='buffer' and @length!='*'"> const void *<value-of select="@name" /> = NULL;
+</when>
+<when test="@type='buffer' and @length='*'"> const void *<value-of select="@name" /> = NULL;
+ uint32 <value-of select="@name" />PLSize = PayloadSize;
+</when>
+</choose>
+</template>
+
+<template match="value" mode="serialize">
+<choose>
+<when test="@type='uint16'"> Serialization::put_uint16_le(&amp;Data_p, <value-of select="@name" />);
+</when>
+<when test="@type='uint32' and @name!='PayloadSize'"> Serialization::put_uint32_le(&amp;Data_p, <value-of select="@name" />);
+</when>
+<when test="@type='uint64'"> Serialization::put_uint64_le(&amp;Data_p, <value-of select="@name" />);
+</when>
+<when test="@type='string'"> Serialization::put_uint32_le(&amp;Data_p, PLSize<value-of select="@name" />);
+ Serialization::put_block(&amp;Data_p, <value-of select="@name" />, PLSize<value-of select="@name" />);
+</when>
+<when test="@type='buffer' and @length='*'"> Serialization::put_block(&amp;Data_p, <value-of select="@name" />, <value-of select="@name" />PLSize);
+</when>
+<when test="@type='buffer' and @length!='*'"> Serialization::put_block(&amp;Data_p, <value-of select="@name" />, <value-of select="@length" />);
+</when>
+</choose>
+</template>
+
+<template match="value" mode="serialize_size">
+<choose>
+<when test="@type='uint16'"> PLSize += sizeof(uint16);
+</when>
+<when test="@type='uint32' and @name!='PayloadSize'"> PLSize += sizeof(uint32);
+</when>
+<when test="@type='uint64'"> PLSize += sizeof(uint64);
+</when>
+<when test="@type='buffer' and @length!='*'"> PLSize += <value-of select="@length" />;
+</when>
+</choose>
+</template>
+
+<template match="value" mode="serialize_size_declaration">
+<choose>
+<when test="@type='string'"> uint32 PLSize<value-of select="@name" /> = 0;
+</when>
+</choose>
+</template>
+
+<template match="value" mode="perm">
+<if test="position() > 1">, </if><value-of select="@ref" />
+</template>
+
+<template match="value" mode="auth">
+<if test="position() > 1">, </if><value-of select="@ref" />
+</template>
+
+<template match="value" mode="permnumber">
+<if test="position() = last()"><value-of select="position()" /></if>
+</template>
+
+<template match="value" mode="authnumber">
+<if test="position() = last()"><value-of select="position()" /></if>
+</template>
+
+<template match="value" mode="clean">
+<choose>
+<when test="@type='string'"></when>
+</choose>
+</template>
+
+<template match="value" mode="document">
+ * @param [in] <value-of select="@name" /><text> </text><value-of select="text()" />
+</template>
+
+<template match="value" mode="declare">
+<param name="continue" select="'false'" />
+<if test="($continue = 'true') or (position() > 0)">, </if>
+<choose>
+<when test="@type='uint16'">const uint16 <value-of select="@name" /></when>
+<when test="@type='uint32'">const uint32 <value-of select="@name" /></when>
+<when test="@type='uint64'">const uint64 <value-of select="@name" /></when>
+<when test="@type='string'">const char *<value-of select="@name" /></when>
+<when test="@type='buffer' and @length='*'">int <value-of select="@name" />PLSize, const void *<value-of select="@name" /></when>
+<when test="@type='buffer' and @length!='*'">const void *<value-of select="@name" /></when>
+</choose>
+</template>
+
+<template match="input" mode="declare">
+</template>
+
+<template match="value" mode="call">
+<param name="continue" select="'false'" />
+<if test="($continue = 'true') or (position() > 0)">, </if>
+<choose>
+<when test="@type='uint16'">
+<value-of select="@name" />
+</when>
+<when test="@type='uint32'">
+<value-of select="@name" />
+</when>
+<when test="@type='uint64'">
+<value-of select="@name" />
+</when>
+<when test="@type='string'">
+<value-of select="@name" />
+</when>
+<when test="@type='buffer' and @length='*'">
+<value-of select="@name" />PLSize, <value-of select="@name" />
+</when>
+<when test="@type='buffer' and @length!='*'">
+<value-of select="@name" />
+</when>
+</choose>
+</template>
+
+<template match="group/documentation">
+ /*
+ * <value-of select="normalize-space(.)"/>
+ */
+</template>
+
+<template name="prototype">
+<param name="name" />
+<param name="direction" />
+<param name="source" />
+<param name="ref" />
+<choose>
+ <when test="name($direction)='output' and contains(@source, 'PC')">
+ /**
+ * <value-of select="normalize-space(./documentation/text())"/>
+ * \see <value-of select="$ref"/>
+ * Call source: <value-of select="$source"/>
+ * @param [in] SessionOut Output session.<apply-templates select="input/value" mode="document" />
+ *
+ * @return ErrorCode_e ...
+ */
+ ErrorCode_e <value-of select="$name"/>(uint16 SessionOut<apply-templates select="input" mode="declare"/><apply-templates select="input/value" mode="declare"/>);
+ </when>
+ <when test="name($direction)='output' and contains(@source, 'ME')">
+ /**
+ * <value-of select="normalize-space(./documentation/text())"/>
+ * \see <value-of select="$ref"/>
+ * Call source: <value-of select="$source"/>
+ * @param [in] Session Input session.<apply-templates select="input/value" mode="document" />
+ *
+ * @return ErrorCode_e ...
+ */
+ ErrorCode_e <value-of select="$name"/>(uint16 Session<apply-templates select="input/value" mode="declare"/>);
+ </when>
+ <when test="name($direction)='input' and contains(@source, 'PC')">
+ /**
+ * Response to \see <value-of select="$ref"/>
+ * Call source: <value-of select="$source"/>
+ * @param [in] Session Transfered input session.
+ * @param [in] Status Completion status code.<apply-templates select="output/value" mode="document" />
+ *
+ * @return ErrorCode_e ...
+ */
+ ErrorCode_e <value-of select="$name"/>(uint16 Session<if test="../@number != 16">, ErrorCode_e Status</if><apply-templates select="output/value" mode="declare">
+ <with-param name="continue" select="'true'" />
+ </apply-templates>);
+ </when>
+ <when test="name($direction)='input' and contains(@source, 'ME')">
+ /**
+ * Response to \see <value-of select="$ref"/>
+ * Call source: <value-of select="$source"/>
+ * @param [in] Session Transfered input session.
+ *
+ * @return ErrorCode_e ...
+ */
+ ErrorCode_e <value-of select="$name"/>(uint16 Session<apply-templates select="output/value" mode="declare">
+ <with-param name="continue" select="'true'" />
+ </apply-templates>);
+ </when>
+</choose>
+</template>
+
+</stylesheet>
diff --git a/source/config/command_ids_h.xsl b/source/config/command_ids_h.xsl
new file mode 100644
index 0000000..02e26b8
--- /dev/null
+++ b/source/config/command_ids_h.xsl
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<import href="common.xsl"/>
+
+<output method="text" indent="no"/>
+<strip-space elements="*"/>
+<param name="target" />
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _COMMAND_IDS_H
+#define _COMMAND_IDS_H
+#include &quot;t_basicdefinitions.h&quot;
+
+typedef enum {
+<apply-templates select="group" mode="id"/>} GroupId_e;
+
+typedef enum {
+<apply-templates select="group/command" mode="id"/>} CommandId_e;
+
+<apply-templates select="typedef" />
+#endif /* _COMMAND_IDS_H */
+</template>
+
+<template match="typedef">typedef struct <value-of select="interface/@name" />_s
+{
+<apply-templates select="value" />}<value-of select="interface/@name" />_t;
+
+</template>
+
+<template match="value">
+<choose>
+<when test="@type='char_array'"> char <text></text><value-of select="@name" />[<text></text><value-of select="@size" />]; /**&lt; <value-of select="text()" /> */
+</when>
+<when test="@type='string'"> char *<text></text><value-of select="@name" />; /**&lt; <value-of select="text()" /> */
+</when>
+<when test="@type='uint32'">
+<text> </text><value-of select="@type" /><text> </text><value-of select="@name" />; /**&lt; <value-of select="text()" /> */
+</when>
+<when test="@type='uint64'">
+<text> </text><value-of select="@type" /><text> </text><value-of select="@name" />; /**&lt; <value-of select="text()" /> */
+</when>
+</choose>
+</template>
+
+<template match="group" mode="id">
+<if test="interface/@name != 'ADbg'">
+<text> </text><call-template name="groupid" /> = <value-of select="@number" />, /**&lt; <value-of select="@name" /> */
+</if>
+</template>
+
+<template match="command" mode="id">
+<if test="@ADbg!='true'">
+<text> </text><call-template name="commandid" /> = <value-of select="@number" />, /**&lt; <value-of select="@name" /> */
+</if>
+</template>
+
+</stylesheet>
diff --git a/source/config/commands.xml b/source/config/commands.xml
new file mode 100644
index 0000000..a762055
--- /dev/null
+++ b/source/config/commands.xml
@@ -0,0 +1,1165 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<?xml-stylesheet type="text/xml" href="command_ids_h.xsl"?>
+<?xml-stylesheet type="text/xml" href="commands_marshal.xsl"?>
+<?xml-stylesheet type="text/xml" href="commands_h.xsl"?>
+<?xml-stylesheet type="text/xml" href="commands_impl_h.xsl"?>
+
+<commandspec>
+
+ <typedef>
+ <interface type="loader" name="SupportedCommand"/>
+ <value type="uint32" name="Group">Application Group number</value>
+ <value type="uint32" name="Command">Command number</value>
+ <value type="uint32" name="Permitted">Permission value</value>
+ </typedef>
+
+ <typedef>
+ <interface type="loader" name="ListDevice"/>
+ <value type="char_array" name="Path_p" size="256">Absolute device path pointing of the described device</value>
+ <value type="char_array" name="Type_p" size="256">Type of the device</value>
+ <value type="uint64" name="BlockSize">Size of the smallest addressable unit in the device in bytes</value>
+ <value type="uint64" name="Start">Offset in bytes of the start of the device relative to its parents offset 0 with a granularity of its parents block size</value>
+ <value type="uint64" name="Length">Length of the device in bytes</value>
+ </typedef>
+
+ <typedef>
+ <interface type="loader" name="DirEntry"/>
+ <value type="string" name="Name_p">Name of file or directory</value>
+ <value type="uint64" name="Size">Size of file or directory</value>
+ <value type="uint32" name="Mode">Indicator if it is file or directory</value>
+ <value type="uint32" name="Time">Time of last modification</value>
+ </typedef>
+
+ <typedef>
+ <interface type="loader" name="Cipher"/>
+ <value type="string" name="Name_p">supported ciphers</value>
+ </typedef>
+
+ <AuthenticationList>
+ <value number="1" name="A1">A1</value>
+ <value number="2" name="CA">CA</value>
+ </AuthenticationList>
+
+ <PermissionList>
+ <value number="0" name="ServiceModeLevel">ServiceModeLevel</value>
+ <value number="1" name="FlashModeLevel">FlashModeLevel</value>
+ <value number="64" name="AdvanceServiceModeLevel">AdvanceServiceModeLevel</value>
+ <value number="65" name="LimitedProductionModeLevel">LimitedProductionModeLevel</value>
+ <value number="66" name="VeryLimitedProductionModeLevel">VeryLimitedProductionModeLevel</value>
+ <value number="127" name="ProductionModeLevel">ProductionModeLevel</value>
+ </PermissionList>
+
+ <!--
+ Predefine generic type of data are: uint32, string and buffer.
+ !!!!! IMPORTANT !!!!!
+ All new types of data (structures or vectors of structures) that need to be defined should first be reviewed and approved by:
+ Hans Holmberg (QHANHOL) for loaders, Mikael Sjolen XX for PTK and Daniel Chong for PA.
+ -->
+
+ <group number="1" name="System application">
+ <documentation>
+ System commands group (0x01)
+ </documentation>
+ <interface type="loader" name="System"/>
+
+ <command number="1" name="Loader Start-up Status" ADbg="false" source="ME">
+ <interface type="loader" name="LoaderStartUpStatus"/>
+ <documentation>
+ The Loader Start-up Status command is sent by the ME to notify the host that it has started. The Status parameter indicates in what mode the Loader started.
+ </documentation>
+ <input>
+ <value type="uint32" name="Status">0 = started successfully, 1 = failed to start (lack of permissions), 2 = software module failed to initialize</value>
+ <value type="string" name="LoaderVersion_p">Loader version identifier</value>
+ <value type="string" name="ProtocolVersion_p">Protocol version identifier</value>
+ </input>
+ <output>
+ </output>
+ </command>
+
+ <command number="3" name="System Reboot" ADbg="false" source="PC">
+ <interface type="loader" name="Reboot"/>
+ <documentation>
+ The Reboot command is used to instruct the Loader to reset the ME. Upon receiving this command, the Loader shuts down in a controlled fashion and restarts the ME. The Mode parameter is used to select the mode of reset.
+ </documentation>
+ <input>
+ <value type="uint32" name="Mode">0 = normal restart, 1 = restart in service mode, 2 = restart with JTAG debugging enabled, 3 = restart in service mode and with JTAG debugging enabled</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="4" name="System Shutdown" ADbg="false" source="PC">
+ <interface type="loader" name="ShutDown"/>
+ <documentation>
+ The Loader shuts down in a controlled fashion and proceeds to shut down the ME itself.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="5" name="System Supported Command" ADbg="false" source="PC">
+ <interface type="loader" name="SupportedCommands"/>
+ <documentation>
+ The Loader returns a list of implemented commands and whether they are permitted to execute in the current Loader state. Further fine-grained permission controls might also deny execution of a specific command.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="uint32" name="CommandCount">Number of implemented commands</value>
+ <value type="SupportedCommand" name="Commands" length="CommandCount">An array of command identifiers. The Permitted field indicates whether the command can be executed at the current time (non-zero value means allowed)</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="6" name="System Execute Software" ADbg="false" source="PC">
+ <interface type="loader" name="ExecuteSoftware"/>
+ <documentation>
+ Receive, verify and execute software, which can be a signed Loader. After having sent this command, the ME will attempt to read the software payload data from the host using the Bulk protocol or from the flash file system depending on the selected path.
+ </documentation>
+ <input>
+ <value type="uint32" name="ExecuteMode">Execute mode: 1 = execution from specified address, 2 = first load the software then execute.</value>
+ <value type="string" name="SourcePath_p">File system or Bulk id path</value>
+ <value type="uint64" name="Length">Total length of the execute software file</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="7" name="System Authenticate" ADbg="false" source="PC">
+ <interface type="loader" name="Authenticate"/>
+ <documentation>
+ This command is used to escalate the privileges of the operator. Two modes of authentication are available by default; Control Key authentication and Certificate based authentication. The authentication command sets the loader in a specific authentication context when it takes control over the command flow. After receiving the authentication command, the Loader will send the appropriate request for information to the PC.
+ </documentation>
+ <input>
+ <value type="uint32" name="Type">Authentication type: 0 = Control Key authentication, 1 = Certificate authentication.</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="8" name="System Get Control Keys" ADbg="false" source="ME">
+ <interface type="loader" name="GetControlKeys"/>
+ <documentation>
+ This command is used by the Loader to retrieve the SimLock Control Keys from the host in order to authenticate a user. The command is used in authentication context.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="string" name="NLCKLock_p"/>
+ <value type="string" name="NSLCKLock_p"/>
+ <value type="string" name="SPLCKLock_p"/>
+ <value type="string" name="CLCKLock_p"/>
+ <value type="string" name="PCKLock_p"/>
+ <value type="string" name="ESLCKLock_p"/>
+ <value type="string" name="NLCKUnlock_p"/>
+ <value type="string" name="NSLCKUnlock_p"/>
+ <value type="string" name="SPLCKUnlock_p"/>
+ <value type="string" name="CLCKUnlock_p"/>
+ <value type="string" name="PCKUnlock_p"/>
+ <value type="string" name="ESLCKUnlock_p"/>
+ </output>
+ </command>
+
+ <command number="9" name="System Authentication Challenge" ADbg="false" source="ME">
+ <interface type="loader" name="AuthenticationChallenge"/>
+ <documentation>
+ This command is used by the Loader to perform a certificate authentication. The command is only used in authentication context.
+ </documentation>
+ <input>
+ <value type="uint32" name="ChallengeBlockLength">Authentication Challenge buffer length</value>
+ <value type="buffer" name="ChallengeBlock_p" length="ChallengeBlockLength">Authentication Challenge that must be signed using the correct certificate and returned to the Loader</value>
+ </input>
+ <output>
+ <value type="uint32" name="ResponseBlockLength">Updated authentication challenge buffer length</value>
+ <value type="buffer" name="ResponseBlock_p" length="ResponseBlockLength">Signed authentication challenge together with the requested permissions.</value>
+ </output>
+ </command>
+
+ <command number="10" name="System Collect Data" ADbg="false" source="PC">
+ <interface type="loader" name="CollectData"/>
+ <documentation>
+ This command is used to collect printouts (debug data) and measurements results.
+ </documentation>
+ <input>
+ <value type="uint32" name="Type">Type of requested data.</value>
+ </input>
+ <output>
+ <value type="uint32" name="DataLenght">Length of output buffer.</value>
+ <value type="buffer" name="CollectedData_p" length="DataLenght">Output data buffer. Contain debug data (printouts) or measurement data.</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="11" name="System Get Progress Status" ADbg="false" source="PC">
+ <interface type="loader" name="GetProgressStatus"/>
+ <documentation>
+ This command is used by the Loader to get the minimal progress status from all running commands.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="uint32" name="ProgressStatus">Command progress status presented in percent.</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="12" name="Set System Time" ADbg="false" source="PC">
+ <interface type="loader" name="SetSystemTime"/>
+ <documentation>
+ The Set System Time command is used to instruct the Loader to use real world time and date during its run time. Upon receiving this command, the Loader sets internal Real Time Clock. This command can be issued more then once by PC tool.
+ </documentation>
+ <input>
+ <value type="uint32" name="EpochTime">Number of seconds since January 1, 1970 (midnight UTC/GMT).</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="13" name="Switch Communication Device" ADbg="false" source="PC" supportedcmdtype="longrunning">
+ <interface type="loader" name="SwitchCommunicationDevice"/>
+ <documentation>
+ This command is used to instruct the Loader to switch to a new communication device.
+ </documentation>
+ <input>
+ <value type="uint32" name="Device">Communication device number to switch to.</value>
+ <value type="uint32" name="DeviceParam">Communication device parameters.</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="14" name="System Get Control Keys Data" ADbg="false" source="ME">
+ <interface type="loader" name="GetControlKeysData"/>
+ <documentation>
+ This command is used by the Loader to retrieve the SimLock Control Keys data buffer from the host in order to authenticate a user. The command is used in authentication context.
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="uint32" name="iDataSize">Length of output buffer.</value>
+ <value type="buffer" length="iDataSize" name="SIMLockKeysData_p">Data buffer with all SIMLock keys.</value>
+ </output>
+ </command>
+ </group>
+
+ <group number="2" name="Flash application">
+ <documentation>
+ Flash Commands group (0x02)
+ </documentation>
+
+ <interface type="loader" name="Flash"/>
+
+ <command number="1" name="Process File" ADbg="false" source="PC">
+ <documentation>
+ This command is used to initiate a flashing session. The Type argument is used to select the type of file to process and Length parameter defines the total size of the file.
+ </documentation>
+ <interface type="loader" name="ProcessFile"/>
+ <input>
+ <value type="uint64" name="Length">Total length of the opened file</value>
+ <value type="string" name="Type_p">Type of the opened file. Currently the only supported type is x-empflash/flasharchive </value>
+ <value type="string" name="SourcePath_p">File system or Bulk id path</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="2" name="List Devices" ADbg="false" source="PC">
+ <documentation>
+ The Loader returns a list of detected block devices. A block device can be a physical device ( flash0 , mmc0 , usb0 ), a logical device ( cabs0 , mbbs0 ) or a file system volume ( boot , sys ). Together they form paths on the form /flash0/mbbs0 or /flash1/cabs1/vfat .
+ </documentation>
+ <interface type="loader" name="ListDevices"/>
+ <input>
+ </input>
+ <output>
+ <value type="uint32" name="DeviceCount">Indicates the number of returned devices</value>
+ <value type="ListDevice" name="Devices" length="DeviceCount">Absolute device path, Type of the device, Block Size, Start address of the device, Length of the device</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="3" name="Dump Area" ADbg="false" source="PC">
+ <documentation>
+ This command is used to initiate a Dump session.
+ </documentation>
+ <interface type="loader" name="DumpArea"/>
+ <input>
+ <value type="string" name="Path_p">Path to the device to dump.</value>
+ <value type="uint64" name="Start">Start of the dump relative to the start of the device indicated by Path in bytes. Actual start is determined by the Mode parameter.</value>
+ <value type="uint64" name="Length">Length of the dump in bytes. Actual length is determined by the Mode parameter.</value>
+ <value type="string" name="TargetPath_p">File system or bulk id path.</value>
+ <value type="uint32" name="RedundantArea">If set to 0 dump flash including redundant area, if set to 1 dump flash without redundant area.</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="4" name="Erase Area" ADbg="false" source="PC">
+ <documentation>
+ This command is used to erase a flash device or part of a flash device.
+ </documentation>
+ <interface type="loader" name="EraseArea"/>
+ <input>
+ <value type="string" name="Path_p">Path to the device to erase.</value>
+ <value type="uint64" name="Start">Start of the dump relative to the start of the device indicated by Path in bytes. This must be a multiple of the block size of the device.</value>
+ <value type="uint64" name="Length">Length of the dump in bytes. This must be a multiple of the block size of the device.</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="5" name="Flash RAW" ADbg = "false" source="PC">
+ <documentation>
+ This command is used to flash raw flash image.
+ </documentation>
+ <interface type="loader" name="FlashRaw" />
+ <input>
+ <value type="uint64" name="Start">Address where RAW image should be written. This must be a multiple of the block size of the device.</value>
+ <value type="uint64" name="Length">Length of RAW data in bytes</value>
+ <value type="uint32" name="Device">Target flash device.[0,1]</value>
+ <value type="string" name="SourcePath_p">Bulk id path</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref ="A1"/>
+ <value ref ="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ </group>
+
+ <group number="3" name="File system operations">
+ <documentation>
+ File System Commands Group (0x03)
+ </documentation>
+ <interface type="loader" name="File_System_Operations"/>
+ <command number="2" name="Volume Properties" ADbg="false" source="PC">
+ <documentation>
+ Retrieve properties of the specified file system volume
+ </documentation>
+ <interface type="loader" name="VolumeProperties"/>
+ <input>
+ <value type="string" name="DevicePath_p">Path of file system volume</value>
+ </input>
+ <output>
+ <value type="string" name="FS_Type_p">File system type</value>
+ <value type="uint64" name="Size">Total size of the file system (in bytes)</value>
+ <value type="uint64" name="Free">Available space (in bytes)</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="3" name="Format Volume" ADbg="false" source="PC">
+ <documentation>
+ Formats an unmounted file system volume. This operation fails if the volume is currently in use.
+ </documentation>
+
+ <interface type="loader" name="FormatVolume"/>
+ <input>
+ <value type="string" name="DevicePath_p">Device path of the file system volume</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="4" name="List Directory" ADbg="false" source="PC">
+ <documentation>
+ List files and directories residing in a specified path
+ </documentation>
+ <interface type="loader" name="ListDirectory"/>
+ <input>
+ <value type="string" name="Path_p">File system path</value>
+ </input>
+ <output>
+ <value type="uint32" name="EntriesCount">Number of directory entries</value>
+ <value type="DirEntry" name="Entries" length="EntriesCount">Name and Size of file or directory, Mode as indicator if it is file or directory, Time of last modification</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="5" name="Move File" ADbg="false" source="PC">
+ <documentation>
+ Moves or renames a file.
+ </documentation>
+ <interface type="loader" name="MoveFile"/>
+ <input>
+ <value type="string" name="SourcePath_p">File system path (source)</value>
+ <value type="string" name="DestinationPath_p">File system path (destination)</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="6" name="Delete File" ADbg="false" source="PC">
+ <documentation>
+ Deletes the specified file or directory. The Loader will only delete empty directories.
+ </documentation>
+ <interface type="loader" name="DeleteFile"/>
+ <input>
+ <value type="string" name="TargetPath_p">File system path</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="7" name="Copy File" ADbg="false" source="PC">
+ <documentation>
+ Copies a file from the PC to the ME, between two directories or file systems on the ME or from the ME to the PC.
+ </documentation>
+ <interface type="loader" name="CopyFile"/>
+ <input>
+ <value type="string" name="SourcePath_p">File system or bulk id path (source)</value>
+ <value type="string" name="DestinationPath_p">File system or bulk id path (destination)</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="8" name="Create Directory" ADbg="false" source="PC">
+ <documentation>
+ Creates a directory
+ </documentation>
+ <interface type="loader" name="CreateDirectory"/>
+ <input>
+ <value type="string" name="TargetPath_p">File system path</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="9" name="Properties (Stat)" ADbg="false" source="PC,ME">
+ <documentation>
+ Retrieves the properties of a file or directory
+ </documentation>
+ <interface type="loader" name="Properties"/>
+ <input>
+ <value type="string" name="TargetPath_p">File system path</value>
+ </input>
+ <output>
+ <value type="uint32" name="Mode">File Type and Access restrictions descriptor (see 5.1)</value>
+ <value type="uint64" name="Size">File size in bytes</value>
+ <value type="uint32" name="MTime">Last modification time stamp</value>
+ <value type="uint32" name="ATime">Last access time stamp</value>
+ <value type="uint32" name="CTime">Creation time stamp</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="10" name="Change Access (Chmod)" ADbg="false" source="PC">
+ <documentation>
+ Changes the access permissions of a path
+ </documentation>
+ <interface type="loader" name="ChangeAccess"/>
+ <input>
+ <value type="string" name="TargetPath_p">File system path</value>
+ <value type="uint32" name="Access">New access permissions</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="11" name="Read Load Modules Manifests" ADbg="false" source="PC">
+ <documentation>
+ Read all manifests in elf files and send it to PC
+ </documentation>
+ <interface type="loader" name="ReadLoadModulesManifests"/>
+ <input>
+ <value type="string" name="TargetPath_p">File system path</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ </group>
+
+ <group number="4" name="OTP">
+ <documentation>
+ OTP handling commands Group (0x04)
+ </documentation>
+ <interface type="loader" name="OTP"/>
+
+ <command number="1" name="Read Bits" ADbg="false" source="PC">
+ <documentation>
+ Reads the specified bits from the OTP
+ </documentation>
+ <interface type="loader" name="ReadBits"/>
+ <input>
+ <value type="uint32" name="OTP_id">Indicates which OTP memory is to be read</value>
+ <value type="uint32" name="Start">Starting offset in bits</value>
+ <value type="uint32" name="Length">Length of read in bits</value>
+ </input>
+ <output>
+ <value type="uint32" name="BitsLength">Length of read bits</value>
+ <value type="uint32" name="DataBitsLength">Length of the DataBits buffer</value>
+ <value type="buffer" name="DataBits_p" length="DataBitsLength">A left-adjusted buffer of the read data. Padded with zeroes. Length of returned value (in bytes), equal to floor((Length + 7) / 8). </value>
+ <value type="uint32" name="LockStatusBitsLength">Length of the LockStatus of read bits</value>
+ <value type="uint32" name="LockStatusLength">Length of the LockStatus buffer</value>
+ <value type="buffer" name="LockStatus_p" length="LockStatusLength">A left-adjusted buffer of the lock status of each read bit. Padded with zeroes. Length of returned value (in bytes), equal to floor((Length + 7) / 8). </value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="2" name="Set Bits" flagbitsset="trueset" ADbg="false" source="PC">
+ <documentation>
+ Writes and locks the specified bits in the OTP
+ </documentation>
+ <interface type="loader" name="SetBits"/>
+ <input>
+ <value type="uint32" name="OTP_id">Indicates which OTP memory is to be read</value>
+ <value type="uint32" name="Start">Starting offset in bits</value>
+ <value type="uint32" name="BitsLength">Length of write in bits</value>
+ <value type="uint32" name="DataBitsLength">Length of DataBits buffer</value>
+ <value type="buffer" name="DataBits_p" length="DataBitsLength">Left-adjusted byte buffer containing the data to be written. Only Length bits will be written.</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="3" name="Write and Lock OTP" flagbitsset="trueset" ADbg="false" source="PC">
+ <documentation>
+ Writes and locks the specified bits in the OTP
+ </documentation>
+ <interface type="loader" name="WriteAndLock"/>
+ <input>
+ <value type="uint32" name="OTP_id">Indicates which OTP memory is to be written and locked</value>
+ <value type="uint32" name="ForceWrite">If = 0 - Write only complete lockable areas. If != 0 Write complete lockable areas even if not all bit are received in cache. </value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="4" name="Store Secure Object" flagbitsset="trueset" ADbg="false" source="PC">
+ <documentation>
+ Installs Secure objects into OTP or Flash
+ </documentation>
+ <interface type="loader" name="StoreSecureObject"/>
+ <input>
+ <value type="string" name="SourcePath">File system or bulk id path</value>
+ <value type="uint32" name="SecureObjectDestination">Secure Object destination address</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ </group>
+
+ <group number="5" name="Parameter Storage">
+ <documentation>
+ Parameter Storage Commands Group (0x05)
+ </documentation>
+ <interface type="loader" name="ParameterStorage"/>
+
+ <command number="1" name="Read Global Data Unit" ADbg="false" source="PC">
+ <documentation>
+ Reads the specified unit from Global Data area
+ </documentation>
+ <interface type="loader" name="ReadGlobalDataUnit"/>
+ <input>
+ <value type="string" name="DevicePath_p">GD storage area to read from (gdfs, trim area)</value>
+ <value type="uint32" name="Unit_id">Unit id to read</value>
+ </input>
+ <output>
+ <value type="uint32" name="DataBuffLength">Length of the Data buffer</value>
+ <value type="buffer" name="DataBuff_p" length="DataBuffLength">The read data</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="2" name="Write Global Data Unit" ADbg="false" source="PC">
+ <documentation>
+ Writes the specified unit to Global Data area
+ </documentation>
+ <interface type="loader" name="WriteGlobalDataUnit"/>
+ <input>
+ <value type="string" name="DevicePath_p">GD storage area to write to (gdfs, trim area)</value>
+ <value type="uint32" name="Unit_id">Unit id to write</value>
+ <value type="uint32" name="DataBuffLength">Length of the Data buffer</value>
+ <value type="buffer" name="DataBuff_p" length="DataBuffLength">The data to write</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="3" name="Read Global Data Set" ADbg="false" source="PC">
+ <documentation>
+ Reads a complete Global Data area
+ </documentation>
+ <interface type="loader" name="ReadGlobalDataSet"/>
+ <input>
+ <value type="string" name="DevicePath_p">GD storage area to read (gdfs, trim area)</value>
+ <value type="string" name="TargetPath_p">File system or bulk id path indicating the destination of the read operation</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="4" name="Write Global Data Set" ADbg="false" source="PC">
+ <documentation>
+ Writes a complete Global Data area
+ </documentation>
+ <interface type="loader" name="WriteGlobalDataSet"/>
+ <input>
+ <value type="string" name="DevicePath_p">GD storage area to write (gdfs, trim area)</value>
+ <value type="uint64" name="DataLength">Data Length when is used bulk transfer </value>
+ <value type="string" name="SourcePath_p">File system or bulk id path indicating the source of the write operation</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="5" name="Erase Global Data Set" ADbg="false" source="PC">
+ <documentation>
+ Erases a complete Global Data area
+ </documentation>
+ <interface type="loader" name="EraseGlobalDataSet"/>
+ <input>
+ <value type="string" name="DevicePath_p">GD storage area to erase (gdfs, trim area)</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ </group>
+
+ <group number="6" name="Security">
+ <documentation>
+ Security settings Commands Group (0x06)
+ </documentation>
+ <interface type="loader" name="Security"/>
+
+ <command number="1" name="Set Domain" ADbg="false" source="PC">
+ <documentation>
+ Set the ME domain
+ </documentation>
+ <interface type="loader" name="SetDomain"/>
+ <input>
+ <value type="uint32" name="Domain">Target domain</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="2" name="Get Domain" ADbg="false" source="PC">
+ <documentation>
+ Get the ME domain
+ </documentation>
+ <interface type="loader" name="GetDomain"/>
+ <input>
+ </input>
+ <output>
+ <value type="uint32" name="CurrentDomain">The ME Domain</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="3" name="Get Properties" ADbg="false" source="PC">
+ <documentation>
+ Reads a security data unit (such as a secure static or dynamic data unit)
+ </documentation>
+ <interface type="loader" name="GetProperties"/>
+ <input>
+ <value type="uint32" name="Unit_id">Unit id to read</value>
+ </input>
+ <output>
+ <value type="uint32" name="DataBuffLength">Length of the Data buffer</value>
+ <value type="buffer" name="DataBuff_p" length="DataBuffLength">The unit data</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="4" name="Set Properties" ADbg="false" source="PC">
+ <documentation>
+ Writes a security data unit (such as a secure static or dynamic data unit)
+ </documentation>
+ <interface type="loader" name="SetProperties"/>
+ <input>
+ <value type="uint32" name="Unit_id">Unit id to write</value>
+ <value type="uint32" name="DataBuffLength">Length of the Data buffer</value>
+ <value type="buffer" name="DataBuff_p" length="DataBuffLength">The data to write</value>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="5" name="Bind Properties" ADbg="false" source="PC">
+ <documentation>
+ Associates all security data units with the current ME
+ </documentation>
+ <interface type="loader" name="BindProperties"/>
+ <input>
+ </input>
+ <output>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ </group>
+
+ <group number="8" name="ADbg application">
+ <documentation>
+ ADbg test suite (automatic test tool)
+ </documentation>
+
+ <interface type="loader" name="ADbg"/>
+
+ <command number="1" name="List all modules, test cases and its parameters " flag="true" ADbg="true" source="PC">
+ <interface type="loader" name="ListCase"/>
+ <documentation>
+ List all modules, test cases and its parameters
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="uint32" name="CmdDataLength"/>
+ <value type="buffer" name="CmdDataPayLoad_p" length="CmdDataLength">CmdData</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="2" name="List all modules, interface groups, interface functions and its parameters " flag="true" ADbg="true" source="PC">
+ <interface type="loader" name="ListInterface"/>
+ <documentation>
+ List all modules, interface groups, interface functions and its parameters
+ </documentation>
+ <input>
+ </input>
+ <output>
+ <value type="uint32" name="CmdDataLength"/>
+ <value type="buffer" name="CmdDataPayLoad_p" length="CmdDataLength">CmdData</value>
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="3" name="Set test case precondition " flag="true" ADbg="true" source="PC">
+ <interface type="loader" name="SetPrecondition"/>
+ <documentation>
+ Set test case precondition
+ </documentation>
+ <input>
+ <value type="uint32" name="ModuleId">ModuleId</value>
+ <value type="uint32" name="IntGroupId">IntGroupId</value>
+ <value type="uint32" name="IntFunctionId">IntFunctionId</value>
+ <value type="uint32" name="RecoveryFlag">RecoveryFlag</value>
+ <value type="uint32" name="PreconditionLength"/>
+ <value type="buffer" name="Precondition_p" length="PreconditionLength">Precondition_p</value>
+ </input>
+ <output>
+
+
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="4" name="Recovery test case condition " flag="true" ADbg="true" source="PC">
+ <interface type="loader" name="RecoveryCondition"/>
+ <documentation>
+ Recovery test case condition
+ </documentation>
+ <input>
+ <value type="uint32" name="ModuleId">ModuleId</value>
+ <value type="uint32" name="IntGroupId">IntGroupId</value>
+ <value type="uint32" name="IntFunctionId">IntFunctionId</value>
+ </input>
+ <output>
+
+
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ <command number="5" name="Run test case " flag="true" ADbg="true" source="PC">
+ <interface type="loader" name="Run"/>
+ <documentation>
+ Run test case
+ </documentation>
+ <input>
+ <value type="uint32" name="ModuleId">ModuleId</value>
+ <value type="uint32" name="CaseId">CaseId</value>
+ <value type="uint32" name="PreconditionLength"/>
+ <value type="buffer" name="Precondition_p" length="PreconditionLength">Precondition_p</value>
+ </input>
+ <output>
+ <value type="uint32" name="AssertStatus"/>
+
+ </output>
+ <authentication depandancy="or" factory="TRUE" rd="TRUE" product="TRUE" service="TRUE">
+ <value ref="A1"/>
+ <value ref="CA"/>
+ </authentication>
+ <permissions>
+ <value ref="ServiceModeLevel"/>
+ <value ref="FlashModeLevel"/>
+ <value ref="AdvanceServiceModeLevel"/>
+ <value ref="ProductionModeLevel"/>
+ <value ref="LimitedProductionModeLevel"/>
+ <value ref="VeryLimitedProductionModeLevel"/>
+ </permissions>
+ </command>
+
+ </group>
+</commandspec>
diff --git a/source/config/commands_h.xsl b/source/config/commands_h.xsl
new file mode 100644
index 0000000..36a2356
--- /dev/null
+++ b/source/config/commands_h.xsl
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="2.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<import href="common.xsl"/>
+
+<output method="text" indent="no"/>
+<strip-space elements="*"/>
+<param name="target" />
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _COMMANDS_H_
+#define _COMMANDS_H_
+
+#include &quot;LCDriver.h&quot;
+#include &quot;LcmInterface.h&quot;
+#include &quot;t_basicdefinitions.h&quot;
+#include &quot;CmdResult.h&quot;
+
+class CLCDriverMethods;
+
+class LoaderRpcInterface
+{
+public:
+ LoaderRpcInterface(CLCDriverMethods* lcdMethods, CmdResult* cmdResult, LcmInterface* lcmInterface):
+ cmdResult_(cmdResult),
+ lcmInterface_(lcmInterface),
+ lcdMethods_(lcdMethods)
+ {
+ }
+
+ virtual ~LoaderRpcInterface()
+ {
+ }
+<apply-templates select="group"/>
+protected:
+ CLCDriverMethods* lcdMethods_;
+ CmdResult* cmdResult_;
+ LcmInterface* lcmInterface_;
+};
+
+#endif /* _COMMANDS_H_ */
+</template>
+
+<template match="group/command">
+<if test="(contains(@source, &apos;ME&apos;)) and (@ADbg!='true')">
+<call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)"/>
+ <with-param name="ref" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)"/>
+ <with-param name="direction" select="input"/>
+ <with-param name="source" select="&apos;ME&apos;"/>
+</call-template>
+</if>
+<if test="(contains(@source, &apos;PC&apos;)) and (@ADbg!='true')">
+<call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)"/>
+ <with-param name="ref" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)"/>
+ <with-param name="direction" select="output"/>
+ <with-param name="source" select="&apos;PC&apos;"/>
+</call-template>
+</if>
+</template>
+</stylesheet>
diff --git a/source/config/commands_impl_h.xsl b/source/config/commands_impl_h.xsl
new file mode 100644
index 0000000..afbe846
--- /dev/null
+++ b/source/config/commands_impl_h.xsl
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform" >
+
+<import href="common.xsl"/>
+
+<output method="text"/>
+<strip-space elements="*"/>
+<param name="target" />
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _COMMANDS_IMPL_H_
+#define _COMMANDS_IMPL_H_
+
+#include &quot;commands.h&quot;
+#include &quot;command_ids.h&quot;
+#include &quot;LCDriver.h&quot;
+#include &quot;LcmInterface.h&quot;
+#include &quot;error_codes.h&quot;
+
+class LoaderRpcInterfaceImpl : public LoaderRpcInterface
+{
+public:
+ LoaderRpcInterfaceImpl(CLCDriverMethods* lcdMethods, CmdResult* CmdResult, LcmInterface* LcmInterface):
+ LoaderRpcInterface(lcdMethods, CmdResult, LcmInterface) {}
+ ~LoaderRpcInterfaceImpl() {}
+
+ ErrorCode_e Do_CEH_Callback(CommandData_t * pCmdData);
+<apply-templates select="group" />
+};
+
+#endif /* _COMMANDS_IMPL_H_ */
+</template>
+
+<template match="group/documentation">
+<if test="../interface/@name != 'ADbg'">
+ /*
+ * <value-of select="normalize-space(.)"/>
+ */
+</if>
+</template>
+
+<template match="group/command">
+ <if test="(contains(@source, &apos;PC&apos;)) and (@ADbg!=&apos;true&apos;)">
+ <call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)" />
+ <with-param name="ref" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)" />
+ <with-param name="direction" select="input" />
+ <with-param name="source" select="&apos;PC&apos;" />
+ </call-template>
+ </if>
+ <if test="(contains(@source, &apos;ME&apos;)) and (@ADbg!=&apos;true&apos;)">
+ <call-template name="prototype">
+ <with-param name="name" select="concat(&apos;DoRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name, &apos;Impl&apos;)" />
+ <with-param name="ref" select="concat(&apos;DoneRPC_&apos;, ../interface[@type=&apos;loader&apos;]/@name, &apos;_&apos;, ./interface[@type=&apos;loader&apos;]/@name)" />
+ <with-param name="direction" select="output" />
+ <with-param name="source" select="&apos;ME&apos;" />
+ </call-template>
+ </if>
+</template>
+
+</stylesheet>
diff --git a/source/config/commands_marshal_cpp.xsl b/source/config/commands_marshal_cpp.xsl
new file mode 100644
index 0000000..14a1c3e
--- /dev/null
+++ b/source/config/commands_marshal_cpp.xsl
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<import href="common.xsl"/>
+
+<output method="text"/>
+<strip-space elements="*"/>
+<param name="target"/>
+
+<template match="group/documentation" mode="marshal">
+<if test="../interface/@name != 'ADbg'">
+/*
+ * <value-of select="normalize-space(.)"/>
+ */
+</if>
+</template>
+
+<template match="group/documentation" mode="unmarshal">
+<if test="../interface/@name != 'ADbg'">
+ /*
+ * <value-of select="normalize-space(.)"/>
+ */
+</if>
+</template>
+
+<template name="unmarshal">
+ <param name="name"/>
+ <param name="direction"/>
+
+ <choose>
+ <when test="name($direction)='output'">
+ /* Command <value-of select="../@name"/> / <value-of select="@name"/> (<value-of select="../@number"/> / <value-of select="@number"/>) */
+ case COMMAND(FALSE, <call-template name="groupid"><with-param name="path" select=".."/></call-template>, <call-template name="commandid"/>):
+ {
+<apply-templates select="input/value" mode="deserialize_size" /><apply-templates select="input/value" mode="deserialize" /> ReturnValue = <value-of select="$name" />(Session<apply-templates select="input/value" mode="call" />);<apply-templates select="input/value" mode="clean"/>
+ }
+ break;
+ </when>
+ <when test="name($direction)='input'">
+ /* Response to <value-of select="../@name"/> / <value-of select="@name"/> (<value-of select="../@number"/> / <value-of select="@number"/>) */
+ case COMMAND(TRUE, <call-template name="groupid"><with-param name="path" select=".."/></call-template>, <call-template name="commandid"/>):
+ {
+<apply-templates select="output/value" mode="deserialize_size" /> ResponseStatus = (ErrorCode_e)Serialization::get_uint32_le(&amp;Data_p);<if test="count(output/value) > 0">
+ if (E_SUCCESS == ResponseStatus)
+ {
+<apply-templates select="output/value" mode="deserialize" /> }</if>
+ ReturnValue = <value-of select="$name" />(Session, ResponseStatus<apply-templates select="output/value" mode="call"><with-param name="continue" select="'true'" /></apply-templates>);<apply-templates select="output/value" mode="clean"/>
+ }
+ break;
+ </when>
+ </choose>
+</template>
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;string.h&gt;
+
+#include "t_command_protocol.h"
+#include "commands.h"
+//#include "custom_commands.h" // when customer commands will be implemented
+#include "command_ids.h"
+#include "commands_impl.h"
+#include "error_codes.h"
+#include "Serialization.h"
+#include "t_r15_network_layer.h"
+#include "Event.h"
+#include "LCDriverMethods.h"
+
+#define COMMAND(response, group, id) ((((int)(response)) &lt;&lt; 30) | (((int)(group)) &lt;&lt; 16) | ((int)(id)))
+#define COMMANDDATA(TypeP,ApplicationP,CommandP,SessionP,SizeP) \
+ memset((uint8*)&amp;CmdData, 0x00, sizeof(CommandData_t)); \
+ CmdData.Type = TypeP; \
+ CmdData.ApplicationNr = ApplicationP; \
+ CmdData.CommandNr = CommandP; \
+ CmdData.SessionNr = SessionP; \
+ CmdData.Payload.Size = SizeP; \
+ CmdData.Payload.Data_p = NULL; \
+ if(SizeP != 0)\
+ {\
+ CmdData.Payload.Data_p = (uint8 *)malloc(sizeof(ErrorCode_e)+SizeP); \
+ if(NULL == CmdData.Payload.Data_p) \
+ { \
+ return E_ALLOCATE_FAILED; \
+ }\
+ }
+
+#define COMMANDDATAOUT(TypeP,ApplicationP,CommandP,SessionP,SizeP) \
+ memset((uint8*)&amp;CmdData, 0x00, sizeof(CommandData_t)); \
+ CmdData.Type = TypeP; \
+ CmdData.ApplicationNr = ApplicationP; \
+ CmdData.CommandNr = CommandP; \
+ CmdData.SessionNr = SessionP; \
+ CmdData.Payload.Size = SizeP; \
+ CmdData.Payload.Data_p = NULL; \
+ if(SizeP != 0)\
+ {\
+ CmdData.Payload.Data_p = (uint8 *)malloc( SizeP); \
+ if(NULL == CmdData.Payload.Data_p) \
+ { \
+ return E_ALLOCATE_FAILED; \
+ }\
+ }
+
+ ErrorCode_e LoaderRpcInterfaceImpl::Do_CEH_Callback(CommandData_t *CmdData_p)
+ {
+ ErrorCode_e ReturnValue = E_GENERAL_FATAL_ERROR;
+ ErrorCode_e ResponseStatus = E_GENERAL_FATAL_ERROR;
+ boolean response = FALSE;
+ const void *Data_p = CmdData_p-&gt;Payload.Data_p;
+ uint16 Session = CmdData_p-&gt;SessionNr;
+
+ if (CmdData_p-&gt;Type == GENERAL_RESPONSE_PACKAGE)
+ {
+ response = TRUE;
+ }
+ else
+ {
+ response = FALSE;
+ }
+
+ Session = CmdData_p-&gt;SessionNr;
+
+ switch(COMMAND(response, CmdData_p-&gt;ApplicationNr, CmdData_p-&gt;CommandNr))
+ {
+<apply-templates select="group" mode="unmarshal"/>
+ default:
+ {
+ return E_COMMAND_NO_ERROR; // Do_CustomCEH_Call(CmdData_p); // when customer commands will be implemented
+ }
+ }
+
+ if (response)
+ {
+ lcdMethods_-&gt;AddEvent(new Event(EVENT_GR_RECEIVED, ResponseStatus, CmdData_p-&gt;ApplicationNr, CmdData_p-&gt;CommandNr));
+ }
+ else
+ {
+ lcdMethods_-&gt;AddEvent(new Event(EVENT_CMD_RECEIVED, 0, CmdData_p-&gt;ApplicationNr, CmdData_p-&gt;CommandNr));
+ }
+
+ return ReturnValue;
+ }
+<apply-templates select="group" mode="marshal"/>
+</template>
+
+<template match="group/command" mode="marshal">
+<if test="(contains(@source, &apos;PC&apos;)) and (@ADbg!='true')">
+ErrorCode_e <value-of select="concat('LoaderRpcInterface::DoRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name)" />(uint16 SessionOut<apply-templates select="input/value" mode="declare" />)
+{
+ ErrorCode_e Answer;
+ CommandData_t CmdData;
+ void *Data_p;
+ uint32 PLSize = 0;
+<apply-templates select="input/value" mode="serialize_size_declaration" />
+<apply-templates select="input/value" mode="serialize_size"/>
+ COMMANDDATAOUT(COMMAND_TYPE, <call-template name="groupidmain"/>, <call-template name="commandid"/>, SessionOut, PLSize);
+ Data_p = CmdData.Payload.Data_p;
+<apply-templates select="input/value" mode="serialize"/>
+ Answer = lcmInterface_->CommandSend(&amp;CmdData);
+
+ if(NULL != CmdData.Payload.Data_p)
+ free(CmdData.Payload.Data_p);
+ return Answer;
+}
+</if>
+<if test="(contains(@source, &apos;ME&apos;)) and (@ADbg!='true')">
+ErrorCode_e <value-of select="concat('LoaderRpcInterface::DoneRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name)" />(uint16 Session, ErrorCode_e Status<apply-templates select="output/value" mode="declare"><with-param name="continue" select="'true'" /></apply-templates>)
+{
+ ErrorCode_e Answer;
+ CommandData_t CmdData;
+ void *Data_p;
+ uint32 PLSize = 0;
+<apply-templates select="output/value" mode="serialize_size_declaration" />
+ PLSize += sizeof(ErrorCode_e);
+<apply-templates select="output/value" mode="serialize_size"/>
+ COMMANDDATA(GENERAL_RESPONSE, <call-template name="groupidmain"/>, <call-template name="commandid"/>, Session, PLSize);
+ Data_p = CmdData.Payload.Data_p;
+
+ Serialization::put_uint32_le(&amp;Data_p, Status);
+<apply-templates select="output/value" mode="serialize"/>
+ Answer = lcmInterface_->CommandSend(&amp;CmdData);
+
+ if(NULL != CmdData.Payload.Data_p)
+ free(CmdData.Payload.Data_p);
+ return Answer;
+}
+</if>
+</template>
+
+<template match="group/command" mode="unmarshal">
+ <if test="(contains(@source, &apos;PC&apos;)) and (@ADbg!='true')">
+ <call-template name="unmarshal">
+ <with-param name="name" select="concat('DoneRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name, 'Impl')" />
+ <with-param name="direction" select="input"/>
+ </call-template>
+ </if>
+ <if test="(contains(@source, &apos;ME&apos;)) and (@ADbg!='true')">
+ <call-template name="unmarshal">
+ <with-param name="name" select="concat('DoRPC_', ../interface[@type='loader']/@name, '_', ./interface[@type='loader']/@name, 'Impl')" />
+ <with-param name="direction" select="output"/>
+ </call-template>
+ </if>
+</template>
+
+</stylesheet>
diff --git a/source/config/common.xsl b/source/config/common.xsl
new file mode 100644
index 0000000..2072c81
--- /dev/null
+++ b/source/config/common.xsl
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<template name="groupidmain">
+<param name="path" select="../." />
+<value-of select="concat('GROUP_', translate($path/interface[@type='loader']/@name,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'))" />
+</template>
+
+<template name="groupid">
+<param name="path" select="." />
+<value-of select="concat('GROUP_', translate($path/interface[@type='loader']/@name,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ'))" />
+</template>
+
+<template name="commandid">
+<param name="path" select="." />
+<value-of select="translate(concat('COMMAND_', $path/../interface[@type='loader']/@name, '_', $path/interface[@type='loader']/@name),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
+</template>
+
+<template match="value" mode="deserialize">
+<choose>
+<when test="@type='uint32'"><text> </text><value-of select="@name" /> = Serialization::get_uint32_le(&amp;Data_p);
+</when>
+<when test="@type='uint64'"><text> </text><value-of select="@name" /> = Serialization::get_uint64_le(&amp;Data_p);
+</when>
+<when test="@type='string'"><text> </text><value-of select="@name" /> = Serialization::skip_str(&amp;Data_p);
+</when>
+<when test="@type='buffer' and @length!='*'"><text> </text><value-of select="@name" /> = Data_p;
+<text> </text>Serialization::skip_block(&amp;Data_p, <value-of select="@length" />);
+</when>
+<when test="@type='SupportedCommand' and @length!='*'"><text> </text><value-of select="@name" /> = Serialization::get_supportedcommands(&amp;Data_p, <value-of select="@length" />);
+</when>
+<when test="@type='ListDevice' and @length!='*'"><text> </text><value-of select="@name" /> = Serialization::get_devices(&amp;Data_p, <value-of select="@length" />);
+</when>
+<when test="@type='DirEntry' and @length!='*'"><text> </text><value-of select="@name" /> = Serialization::get_direntries(&amp;Data_p, <value-of select="@length" />);
+</when>
+<when test="@type='Cipher' and @length!='*'"><text> </text><value-of select="@name" /> = Data_p;
+<text> </text>Serialization::skip_str(&amp;Data_p);
+</when>
+</choose>
+</template>
+
+<template match="value" mode="deserialize_size">
+<choose>
+<when test="@type='uint32'"> uint32 <value-of select="@name" /> = 0;
+</when>
+<when test="@type='uint64'"> uint64 <value-of select="@name" /> = 0;
+</when>
+<when test="@type='string'"> const char *<value-of select="@name" /> = NULL;
+</when>
+<when test="@type='buffer' and @length!='*'"> const void *<value-of select="@name" /> = NULL;
+</when>
+<when test="@type='SupportedCommand' and @length!='*'"> SupportedCommand_t *<value-of select="@name" /> = NULL;
+</when>
+<when test="@type='ListDevice' and @length!='*'"> ListDevice_t *<value-of select="@name" /> = NULL;
+</when>
+<when test="@type='DirEntry' and @length!='*'"> DirEntry_t *<value-of select="@name" /> = NULL;
+</when>
+<when test="@type='Cipher' and @length!='*'"> Cipher_t *<value-of select="@name" /> = NULL;
+</when>
+</choose>
+</template>
+
+<template match="value" mode="serialize">
+<choose>
+<when test="@type='uint32'"> Serialization::put_uint32_le(&amp;Data_p, <value-of select="@name" />);
+</when>
+<when test="@type='uint64'"> Serialization::put_uint64_le(&amp;Data_p, <value-of select="@name" />);
+</when>
+<when test="@type='string'"> Serialization::put_uint32_le(&amp;Data_p, PLSize<value-of select="@name" />);
+ Serialization::put_block(&amp;Data_p, <value-of select="@name" />, PLSize<value-of select="@name" />);
+</when>
+<when test="@type='buffer' and @length='*'"> Serialization::put_block(&amp;Data_p, <value-of select="@name" />, <value-of select="@name" />PLSize);
+</when>
+<when test="@type='buffer' and @length!='*'"> Serialization::put_block(&amp;Data_p, <value-of select="@name" />, <value-of select="@length" />);
+</when>
+<when test="@type='SupportedCommand' and @length!='*'"> Serialization::put_block(&amp;Data_p, <value-of select="@name" />, PLSize<value-of select="@name" />);
+</when>
+<when test="@type='ListDevice' and @length!='*'"> Serialization::serialize_device_entries(&amp;Data_p, <value-of select="@name" />, <value-of select="@length" />);<!--put_block(&amp;Data_p, <value-of select="@name" />, PLSize<value-of select="@name" />);-->
+</when>
+<when test="@type='DirEntry' and @length!='*'"> Serialization::serialize_directory_entries(&amp;Data_p, <value-of select="@name" />, <value-of select="@length" />);<!--put_block(&amp;Data_p, <value-of select="@name" />, PLSize<value-of select="@name" />);-->
+</when>
+<when test="@type='Cipher' and @length!='*'"> Serialization::put_block(&amp;Data_p, <value-of select="@name" />, PLSize<value-of select="@name" />);
+</when>
+</choose>
+</template>
+
+<template match="value" mode="serialize_size">
+<choose>
+<when test="@type='uint32'"> PLSize += sizeof(uint32);
+</when>
+<when test="@type='uint64'"> PLSize += sizeof(uint64);
+</when>
+<when test="@type='string'"> PLSize += sizeof(uint32);
+ PLSize<value-of select="@name" /> = strlen(<value-of select="@name" />);
+ PLSize += PLSize<value-of select="@name" />;
+</when>
+<when test="@type='buffer' and @length!='*'"> PLSize += <value-of select="@length" />;
+</when>
+<when test="@type='SupportedCommand' and @length!='*'"> PLSize += PLSize<value-of select="@name" /> = <value-of select="@length" /> * sizeof(SupportedCommand_t);
+</when>
+<when test="@type='ListDevice' and @length!='*'"> PLSize += Serialization::get_device_entries_len(<value-of select="@name" />, <value-of select="@length" />); <!--PLSize<value-of select="@name" /> = <value-of select="@length" /> * sizeof(DirEntry_t);-->
+</when>
+<when test="@type='DirEntry' and @length!='*'"> PLSize += Serialization::get_directory_entries_len(<value-of select="@name" />, <value-of select="@length" />); <!--PLSize<value-of select="@name" /> = <value-of select="@length" /> * sizeof(DirEntry_t);-->
+</when>
+<when test="@type='Cipher' and @length!='*'"> PLSize += PLSize<value-of select="@name" /> = <value-of select="@length" /> * sizeof(Cipher_t);
+</when>
+</choose>
+</template>
+
+<template match="value" mode="serialize_size_declaration">
+<choose>
+<when test="@type='string'"> uint32 PLSize<value-of select="@name" /> = 0;
+</when>
+<when test="@type='SupportedCommand'"> uint32 PLSize<value-of select="@name" /> = 0;
+</when>
+<when test="@type='Cipher'"> uint32 PLSize<value-of select="@name" /> = 0;
+</when>
+</choose>
+</template>
+
+<template match="value" mode="perm">
+<if test="position() > 1">, </if><value-of select="@ref" />
+</template>
+
+<template match="value" mode="auth">
+<if test="position() > 1">, </if><value-of select="@ref" />
+</template>
+
+<template match="value" mode="permnumber">
+<if test="position() = last()"><value-of select="position()" /></if>
+</template>
+
+<template match="value" mode="authnumber">
+<if test="position() = last()"><value-of select="position()" /></if>
+</template>
+
+<template match="value" mode="clean">
+<choose>
+<when test="@type='string'"></when>
+</choose>
+</template>
+
+<template match="value" mode="document">
+ * @param [in] <value-of select="@name" /><text> </text><value-of select="text()" />
+</template>
+
+<template match="value" mode="declare">
+<param name="continue" select="'false'" />
+<if test="($continue = 'true') or (position() > 0)">, </if>
+<choose>
+<when test="@type='uint32'">const uint32 <value-of select="@name" /></when>
+<when test="@type='uint64'">const uint64 <value-of select="@name" /></when>
+<when test="@type='string'">const char *<value-of select="@name" /></when>
+<when test="@type='buffer' and @length='*'">int <value-of select="@name" />Length, const void *<value-of select="@name" /></when>
+<when test="@type='buffer' and @length!='*'">const void *<value-of select="@name" /></when>
+<when test="@type='SupportedCommand' and @length!='*'">SupportedCommand_t *<value-of select="@name" /></when>
+<when test="@type='ListDevice' and @length!='*'">ListDevice_t *<value-of select="@name" /></when>
+<when test="@type='DirEntry' and @length!='*'">DirEntry_t *<value-of select="@name" /></when>
+<when test="@type='Cipher' and @length!='*'">Cipher_t *<value-of select="@name" /></when>
+</choose>
+</template>
+
+<template match="input" mode="declare">
+</template>
+
+<template match="value" mode="call">
+<param name="continue" select="'false'" />
+<if test="($continue = 'true') or (position() > 0)">, </if>
+<choose>
+<when test="@type='uint32'">
+<value-of select="@name" />
+</when>
+<when test="@type='uint64'">
+<value-of select="@name" />
+</when>
+<when test="@type='string'">
+<value-of select="@name" />
+</when>
+<when test="@type='buffer' and @length='*'">
+<value-of select="@name" />Length, <value-of select="@name" />
+</when>
+<when test="@type='buffer' and @length!='*'">
+<value-of select="@name" />
+</when>
+<when test="@type='SupportedCommand' and @length='*'">
+<value-of select="@name" />Count, <value-of select="@name" />
+</when>
+<when test="@type='SupportedCommand' and @length!='*'">
+<value-of select="@name" />
+</when>
+<when test="@type='ListDevice' and @length='*'">
+<value-of select="@name" />Count, <value-of select="@name" />
+</when>
+<when test="@type='ListDevice' and @length!='*'">
+<value-of select="@name" />
+</when>
+<when test="@type='DirEntry' and @length='*'">
+<value-of select="@name" />Count, <value-of select="@name" />
+</when>
+<when test="@type='DirEntry' and @length!='*'">
+<value-of select="@name" />
+</when>
+</choose>
+</template>
+
+<template match="group/documentation">
+<if test="../interface/@name != 'ADbg'">
+ /*
+ * <value-of select="normalize-space(.)"/>
+ */
+</if>
+</template>
+
+<template name="prototype">
+<param name="name" />
+<param name="direction" />
+<param name="source" />
+<param name="ref" />
+<choose>
+ <when test="name($direction)='output' and contains(@source, 'PC')">
+ /**
+ * <value-of select="normalize-space(./documentation/text())"/>
+ * \see <value-of select="$ref"/>
+ * Call source: <value-of select="$source"/>
+ * @param [in] SessionOut Output session.<apply-templates select="input/value" mode="document" />
+ *
+ * @return ErrorCode_e ...
+ */
+ ErrorCode_e <value-of select="$name"/>(uint16 SessionOut<apply-templates select="input" mode="declare"/><apply-templates select="input/value" mode="declare"/>);
+ </when>
+ <when test="name($direction)='output' and contains(@source, 'ME')">
+ /**
+ * <value-of select="normalize-space(./documentation/text())"/>
+ * \see <value-of select="$ref"/>
+ * Call source: <value-of select="$source"/>
+ * @param [in] Session Input session.<apply-templates select="input/value" mode="document" />
+ *
+ * @return ErrorCode_e ...
+ */
+ ErrorCode_e <value-of select="$name"/>(uint16 Session<apply-templates select="input/value" mode="declare"/>);
+ </when>
+ <when test="name($direction)='input'">
+ /**
+ * Response to \see <value-of select="$ref"/>
+ * Call source: <value-of select="$source"/>
+ * @param [in] Session Transfered input session.
+ * @param [in] Status Completion status code.<apply-templates select="output/value" mode="document" />
+ *
+ * @return ErrorCode_e ...
+ */
+ ErrorCode_e <value-of select="$name"/>(uint16 Session, ErrorCode_e Status<apply-templates select="output/value" mode="declare">
+ <with-param name="continue" select="'true'" />
+ </apply-templates>);
+ </when>
+</choose>
+</template>
+
+</stylesheet>
diff --git a/source/config/lcdriver_error_codes.xml b/source/config/lcdriver_error_codes.xml
new file mode 100644
index 0000000..a68d939
--- /dev/null
+++ b/source/config/lcdriver_error_codes.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<commandspec>
+ <status>
+ <!--
+ * General Fatal 10001-10025
+ * General Non-Fatal 10026-10050
+ -->
+ <value number="10001" name="TIMEOUT" fatal="false" short="Timeout event occured.">Timeout for previously sent request has occured. Request could be Protrom Command, Bulk transfer, or R15 Command.</value>
+ <value number="10002" name="INVALID_INPUT_PARAMETERS" fatal="false" short="Invalid parameter during Context initialization.">Invalid parameter found during executing LCDriver initialization functions. Failed to initialize Context.</value>
+
+ <!--
+ * Interface Fatal 10051-10075
+ * Interface Non-Fatal 10076-10100
+ -->
+ <value number="10051" name="INTERFACE_COULD_NOT_ADD_OBJECT_TO_LIST" fatal="true" short="Failed to create context for connected device.">Failed to add the LCDriver context for the new device in the devices list. Try to reconnect the device, if the problem is still present report it.</value>
+ <value number="10052" name="INTERFACE_COULD_NOT_CREATE_OBJECT" fatal="true" short="Failed to create loader interface.">Failed to create interface for loader methods, possibly not enough memory to perform the operation. Try to reconnect the device, if the problem is still present report it.</value>
+ <value number="10053" name="INTERFACE_UNKNOWN_EXECPTION_WHILE_ADDING_OBJECT" fatal="true" short="Failed to create context for connected device.">Unknown exception occured while trying to create context for the connected device. Try to reconnect the device, if the problem is still present report it.</value>
+ <value number="10054" name="INTERFACE_COULD_NOT_CREATE_IFC_OBJECT" fatal="true" short="Failed to create context for connected device.">Failed to create LCDriver context for the connected device, possibly not enough memory to perform the operation. Try to reconnect the device, if the problem is still present report it.</value>
+ <value number="10055" name="INTERFACE_OBJECT_POINTER_TO_POINTER_NULL" fatal="true" short="Invalid pointer to interface.">Tried to create LCDriver interface with invalid pointer.</value>
+ <value number="10056" name="INTERFACE_OBJECT_POINTER_NULL" fatal="true" short="Invalid pointer to LCDriver context.">Tried to configure device with invalid pointer to LCDriver interface. Create the LCDriver interface for the conneceted device and try to configure the device later. If the problem is still present report it.</value>
+ <value number="10076" name="INTERFACE_OBJECT_ALREADY_EXISTS" fatal="false" short="LCDriver interface for the device already exists.">The context for the device was previously created.</value>
+ <value number="10077" name="INTERFACE_LC_METHODS_OBJECT_NULL" fatal="false" short="Interface for loader methods is not created.">Tried to execute loader method without creating loader method interface. Create the interface first and retry the same operation. If the problem is still present report it.</value>
+ <value number="10078" name="INTERFACE_INTERFACEID_POINTER_NULL" fatal="false" short="Failed to create LCDriver context.">Tried to create LCDriver context with invalid ID for the context. Try to create context with different context ID, if the problem is still present report it.</value>
+ <value number="10079" name="INTERFACE_CONTEXT_NOT_STARTED" fatal="false" short="LCDriver context is not started.">Tried to call loader method before starting the LCDriver context. Try to start the context before calling loader methods, if the problem is still present report it.</value>
+
+ <!--
+ * System Thread Fatal 10101-10125
+ * System Thread Non-Fatal 10126-10150
+ -->
+ <value number="10126" name="LCDRIVER_THREAD_UNKNOWN_EXCEPTION" fatal="false" short="Unexpexted exit of LCDriver thread.">The LCDriver thread exited in unexpected way. The error is not recognized, if the problem persists report it.</value>
+
+ <!--
+ * Bulk Fatal 10151-10175
+ * Bulk Non-Fatal 10176-10200
+ -->
+ <value number="10176" name="BULK_VECTOR_ID_ERROR" fatal="false" short="Failed to start bulk session.">Failed to open bulk session due to invalid Bulk Vector ID.</value>
+ <value number="10177" name="BULK_ALREADY_IN_PROGRESS" fatal="false" short="Bulk transfer is already in progress.">Bulk transfer is already in progress. Parallel bulk transfers are not supported</value>
+
+ <!--
+ * Hardware Fatal 10201-10225
+ * Hardware Non-Fatal 10226-10250
+ -->
+ <value number="10201" name="PROTROM_STATUS_NOT_OK" fatal="true" short="ROM Code Failure.">Error occured while communicating the ROM code. Possibly there is some security issue with the used SW/HW.</value>
+ <value number="10226" name="TIMEOUT_NO_CHIP_ID_DETECTED" fatal="false" short="Failed to initialize HW.">The HW failed to respond during the initialization sequence. Try with other HW, if the problem still exist report it, otherwise probably it faulty HW.</value>
+ <value number="10227" name="TIMEOUT_NO_Z_DETECTED" fatal="false" short="Failed to start HW initialization.">The HW initialization failed to start. Try with other HW, if the problem still exist report it, otherwise probably it faulty HW.</value>
+
+ <!--
+ * Loader Command Execution Fatal 10251-10275
+ * Loader Command Execution Non-Fatal 10276-10300
+ -->
+ <value number="10276" name="PARALLEL_COMMAND_EXECUTION_NOT_SUPPORTED" fatal="false" short="Command execution failed.">Failed to execute command because there is other active command. Try to execute command again. If the problem persists probably there is some blocked command. Restart the HW.</value>
+ <value number="10277" name="CALLBACKS_NOT_CONFIGURED_CORRECTLY" fatal="false" short="Communication driver configuration failure.">Callbacks for communication decvice are not configured. Try to configure device driver callbacks. If the problem persists report it.</value>
+ <value number="10278" name="GENERAL_RESPONSE_COMMAND_NUMBER_ERROR" fatal="false" short="Failure during command execution.">Recived response for command other than it was expected. Probably there is communication error. Restart the HW, if the problem persists report it.</value>
+ <value number="10279" name="COMMAND_NUMBER_ERROR" fatal="false" short="Failure during command execution.">Command received from ME other than it was expected. Probably there is communication error. Restart the HW, if the problem persists report it.</value>
+ <value number="10280" name="CANCEL_EVENT_RECEIVED" fatal="false" short="Operation execution is canceled.">Canceled execution of active command/communication due to reciving of cancel event.</value>
+ <value number="10281" name="UNEXPECTED_EVENT_RECEIVED" fatal="false" short="Unexpected event during execution.">Unexpected event was received during command execution.</value>
+ <value number="10282" name="INVALID_EXECUTION_MODE" fatal="false" short="Invalid execution mode.">Unexpected event was received during command execution.</value>
+
+ <!--
+ * Buffers Fatal 10301-10325
+ * Buffers Non-Fatal 10326-10350
+ -->
+ <value number="10326" name="BUFFER_BULK_FILE_NOT_ALOCATED" fatal="false" short="Bulk transfer failed.">Failed to load file from local HDD in RAM. Command execution failed.</value>
+
+ <!--
+ * IO File Fatal 10351-10375
+ * IO File Non-Fatal 10376-10400
+ -->
+ <value number="10376" name="FILE_OPENING_ERROR" fatal="false" short="Failed to open file.">Failed to open the file with the given path. Check if the file path is correct.</value>
+ <value number="10377" name="FILE_CREATE_MAPPING_ERROR" fatal="false" short="Failed to load the file in RAM.">Mapping of the file in RAM failed. Try to execute command again, if problem persist try to restart the HW.</value>
+ <value number="10378" name="FILE_MAPPING_VIEW_ERROR" fatal="false" short="Reading of file failed.">Failed to create desired view on RAM area of the mapped file. Try to execute command again, if problem persist try to restart the HW.</value>
+ <value number="10379" name="FILE_FAILED_TO_GET_SIZE" fatal="false" short="Failed to load the file in RAM.">Failed to read file description. Try to execute command again, if problem persist try to restart the HW.</value>
+ <value number="10379" name="FILE_READ_INVALID_OFFSET" fatal="false" short="Invalid data offset requested.">Invalid file offset requested. Try to execute command again, if problem persist try to restart the HW.</value>
+ <value number="10380" name="FILE_READ_ERROR" fatal="false" short="Failed to read from file.">Failed to read data from file. Try to execute command again, if problem persist try to restart the HW.</value>
+
+ <!--
+ * LCM DLL Fatal 10401-10425
+ * LCM DLL Non-Fatal 10426-10450
+ -->
+ <value number="10401" name="LCM_DLL_LOAD_LOADLIBRARY_ERROR" fatal="true" short="Failed to load LCM library.">Loading of dependant library failed. Make sure that it is placed on correct location.</value>
+ <value number="10402" name="LCM_DLL_LOAD_FUNCTION_NOT_FOUND" fatal="true" short="Failed to import LCM functionality.">Some of dependend functions was not found in the given LCM library. Make sure that the version that is used is compatible.</value>
+
+ <!--
+ * Exceptions Fatal 10451-10475
+ * Exceptions Non-Fatal 10476-10500
+ -->
+ <value number="10451" name="UNKNOWN_EXCEPTION" fatal="true" short="Unknown error has stopped the operation.">The active operation was stopped by uknown exception. Repeat the failure procedure, if the problem persists report it.</value>
+ <value number="10476" name="UNKNOWN_WAIT_RETURN_VALUE" fatal="false" short="Operation execution failed.">The activity didn't complete properly. Unhandled event was recieved during execution of command/activity.</value>
+ <value number="10477" name="UNKNOWN_BULK_TRANSFER_EXCEPTION" fatal="false" short="Bulk transfer failed.">The transfer of bulk data was interrpted by unknown exception. Data was not transferred successfuly.</value>
+ <value number="10478" name="UNKNOWN_INTERFACE_EXCEPTION" fatal="false" short="LCDriver context operation failed.">Failed to perform desired operation on the LCDriver context due to unknown exception.</value>
+
+ <!--
+ * LCDriver Thread Fatal 10501-10525
+ * LCDriver Thread Non-Fatal 10526-10550
+ -->
+ <value number="10526" name="LCDRIVER_THREAD_KILLED" fatal="false" short="LCDriver thread stopped.">Execution of LCDriver thread has stopped because the thread was killed with unknown reason.</value>
+ <value number="10527" name="LCDRIVER_THREAD_KILLED_WITH_CANCEL" fatal="false" short="LCDriver thread stopped.">Execution of LCDriver thread has stopped because the thread was killed by cancel event.</value>
+ <value number="10528" name="LCDRIVER_THREAD_KILLED_WITH_SIGNAL_DEATH" fatal="false" short="LCDriver thread stopped.">Execution of LCDriver thread has stopped with shutdown request.</value>
+ <value number="10529" name="LCDRIVER_THREAD_NOT_STARTED" fatal="false" short="Failed to start LCDriver thread.">Starting of LCDriver thread has failed. An error has occured during initialization. Reconnect the device, if the problem persist report it.</value>
+ <value number="10530" name="LCDRIVER_THREAD_STOPPED_AFTER_LCM_ERROR" fatal="false" short="LCDriver thread stopped after receiving LCM error.">LCDriver thread must be stopped due to unrecoverable error state in the LCM. Reconnect the device, if the problem persist report it.</value>
+
+ <!--
+ * LCM Communication Fatal 10551-10575
+ * LCM Communication Non-Fatal 10576-10600
+ -->
+ <value number="10551" name="LCM_RETRANSMISSION_ERROR" fatal="true" short="LCM failed to send packet.">Maximum number of packet retransmission attempts failed. Further communication of device is not possible. Reconnect the device, if the problem persist report it.</value>
+ <value number="10552" name="LCM_DEVICE_WRITE_ERROR" fatal="true" short="LCM failed to write data on communication device.">LCM failed to get response from communication device. Further communication of device is not possible. Reconnect the device, if the problem persist report it.</value>
+
+ </status>
+</commandspec>
diff --git a/source/config/lcdriver_error_codes_h.xsl b/source/config/lcdriver_error_codes_h.xsl
new file mode 100644
index 0000000..55fc0b1
--- /dev/null
+++ b/source/config/lcdriver_error_codes_h.xsl
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+-->
+<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
+
+<output method="text"/>
+<strip-space elements="*"/>
+<param name="target"/>
+
+<template match="/commandspec">/* $Copyright ST-Ericsson 2010$ */
+/* NOTE: This is an automatically generated file. DO NOT EDIT! */
+
+#ifndef _LCDRIVERERRORCODE_H
+#define _LCDRIVERERRORCODE_H
+
+/**
+ * Error codes for LCDriver.
+ */
+
+/**
+ * Table for Error groups range
+ *
+ * General Fatal 10001-10025
+ * General Non-Fatal 10026-10050
+ *
+ * Interface Fatal 10051-10075
+ * Interface Non-Fatal 10076-10100
+ *
+ * System Thread Fatal 10101-10125
+ * System Thread Non-Fatal 10126-10150
+ *
+ * Bulk Fatal 10151-10175
+ * Bulk Non-Fatal 10176-10200
+ *
+ * Hardware Fatal 10201-10225
+ * Hardware Non-Fatal 10226-10250
+ *
+ * Loader Command Execution Fatal 10251-10275
+ * Loader Command Execution Non-Fatal 10276-10300
+ *
+ * Buffers Fatal 10301-10325
+ * Buffers Non-Fatal 10326-10350
+ *
+ * IO File Fatal 10351-10375
+ * IO File Non-Fatal 10376-10400
+ *
+ * LCM DLL Fatal 10401-10425
+ * LCM DLL Non-Fatal 10426-10450
+ *
+ * Exceptions Fatal 10451-10475
+ * Exceptions Non-Fatal 10476-10500
+ *
+ * LCDriver Thread Fatal 10501-10525
+ * LCDriver Thread Non-Fatal 10526-10550
+ *
+ */
+<apply-templates select="status"/>
+#endif /* _LCDRIVERERRORCODE_H */
+</template>
+
+<template match="status">
+typedef enum {
+<apply-templates select="value"/>} InternalErrorCodes_e;
+</template>
+
+<template match="value">
+ <text> </text><value-of select="@name"/> = <value-of select="@number"/><if test="position() != last()">,</if> /** <value-of select="@short"/> */
+</template>
+
+</stylesheet>
diff --git a/source/resource.h b/source/resource.h
new file mode 100644
index 0000000..26db1bd
--- /dev/null
+++ b/source/resource.h
@@ -0,0 +1,21 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by LCDriver.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/source/security_algorithms/SecurityAlgorithms.cpp b/source/security_algorithms/SecurityAlgorithms.cpp
new file mode 100644
index 0000000..1d92e57
--- /dev/null
+++ b/source/security_algorithms/SecurityAlgorithms.cpp
@@ -0,0 +1,18 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+#include "SecurityAlgorithms.h"
+#include "sha2.h"
+
+int SecurityAlgorithms::SHA256(unsigned char *pData, unsigned long ulDataLen, unsigned char *pDigest)
+{
+ SHA256_CTX c256;
+ SHA256_Init(&c256);
+ SHA256_Update(&c256, pData, ulDataLen);
+ SHA256_Final(pDigest, &c256);
+
+ return 0;
+}
diff --git a/source/security_algorithms/SecurityAlgorithms.h b/source/security_algorithms/SecurityAlgorithms.h
new file mode 100644
index 0000000..51dbcde
--- /dev/null
+++ b/source/security_algorithms/SecurityAlgorithms.h
@@ -0,0 +1,20 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+#ifndef _SECURITYALGORITHMS_H_
+#define _SECURITYALGORITHMS_H_
+
+class SecurityAlgorithms
+{
+public:
+ static int SHA256(unsigned char *pData, unsigned long ulDataLen, unsigned char *pDigest);
+private:
+ SecurityAlgorithms();
+ ~SecurityAlgorithms();
+};
+
+#endif // _SECURITYALGORITHMS_H_
diff --git a/source/security_algorithms/sha/sha2.cpp b/source/security_algorithms/sha/sha2.cpp
new file mode 100644
index 0000000..af0fb8d
--- /dev/null
+++ b/source/security_algorithms/sha/sha2.cpp
@@ -0,0 +1,1064 @@
+/*
+ * FILE: sha2.c
+ * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
+ */
+
+#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
+#include <assert.h> /* assert() */
+#include "sha2.h"
+
+/*
+ * ASSERT NOTE:
+ * Some sanity checking code is included using assert(). On my FreeBSD
+ * system, this additional code can be removed by compiling with NDEBUG
+ * defined. Check your own systems manpage on assert() to see how to
+ * compile WITHOUT the sanity checking code on your system.
+ *
+ * UNROLLED TRANSFORM LOOP NOTE:
+ * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
+ * loop version for the hash transform rounds (defined using macros
+ * later in this file). Either define on the command line, for example:
+ *
+ * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
+ *
+ * or define below:
+ *
+ * #define SHA2_UNROLL_TRANSFORM
+ *
+ */
+
+
+/*** SHA-256/384/512 Machine Architecture Definitions *****************/
+/*
+ * BYTE_ORDER NOTE:
+ *
+ * Please make sure that your system defines BYTE_ORDER. If your
+ * architecture is little-endian, make sure it also defines
+ * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
+ * equivilent.
+ *
+ * If your system does not define the above, then you can do so by
+ * hand like this:
+ *
+ * #define LITTLE_ENDIAN 1234
+ * #define BIG_ENDIAN 4321
+ *
+ * And for little-endian machines, add:
+ *
+ * #define BYTE_ORDER LITTLE_ENDIAN
+ *
+ * Or for big-endian machines:
+ *
+ * #define BYTE_ORDER BIG_ENDIAN
+ *
+ * The FreeBSD machine this was written on defines BYTE_ORDER
+ * appropriately by including <sys/types.h> (which in turn includes
+ * <machine/endian.h> where the appropriate definitions are actually
+ * made).
+ */
+#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
+#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
+#endif
+
+/*
+ * Define the followingsha2_* types to types of the correct length on
+ * the native archtecture. Most BSD systems and Linux define u_intXX_t
+ * types. Machines with very recent ANSI C headers, can use the
+ * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
+ * during compile or in the sha.h header file.
+ *
+ * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
+ * will need to define these three typedefs below (and the appropriate
+ * ones in sha.h too) by hand according to their system architecture.
+ *
+ * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
+ * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef uint8_t sha2_byte; /* Exactly 1 byte */
+typedef uint32_t sha2_word32; /* Exactly 4 bytes */
+typedef uint64_t sha2_word64; /* Exactly 8 bytes */
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef u_int8_t sha2_byte; /* Exactly 1 byte */
+typedef u_int32_t sha2_word32; /* Exactly 4 bytes */
+typedef u_int64_t sha2_word64; /* Exactly 8 bytes */
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+/* NOTE: Most of these are in sha2.h */
+#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
+#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
+#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
+
+
+/*** ENDIAN REVERSAL MACROS *******************************************/
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define REVERSE32(w,x) { \
+ sha2_word32 tmp = (w); \
+ tmp = (tmp >> 16) | (tmp << 16); \
+ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
+}
+#define REVERSE64(w,x) { \
+ sha2_word64 tmp = (w); \
+ tmp = (tmp >> 32) | (tmp << 32); \
+ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
+ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
+ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
+ ((tmp & 0x0000ffff0000ffffULL) << 16); \
+}
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+/*
+ * Macro for incrementally adding the unsigned 64-bit integer n to the
+ * unsigned 128-bit integer (represented using a two-element array of
+ * 64-bit words):
+ */
+#define ADDINC128(w,n) { \
+ (w)[0] += (sha2_word64)(n); \
+ if ((w)[0] < (n)) { \
+ (w)[1]++; \
+ } \
+}
+
+/*
+ * Macros for copying blocks of memory and for zeroing out ranges
+ * of memory. Using these macros makes it easy to switch from
+ * using memset()/memcpy() and using bzero()/bcopy().
+ *
+ * Please define either SHA2_USE_MEMSET_MEMCPY or define
+ * SHA2_USE_BZERO_BCOPY depending on which function set you
+ * choose to use:
+ */
+#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
+/* Default to memset()/memcpy() if no option is specified */
+#define SHA2_USE_MEMSET_MEMCPY 1
+#endif
+#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
+/* Abort with an error if BOTH options are defined */
+#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
+#endif
+
+#ifdef SHA2_USE_MEMSET_MEMCPY
+#define MEMSET_BZERO(p,l) memset((p), 0, (l))
+#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
+#endif
+#ifdef SHA2_USE_BZERO_BCOPY
+#define MEMSET_BZERO(p,l) bzero((p), (l))
+#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
+#endif
+
+
+/*** THE SIX LOGICAL FUNCTIONS ****************************************/
+/*
+ * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
+ *
+ * NOTE: The naming of R and S appears backwards here (R is a SHIFT and
+ * S is a ROTATION) because the SHA-256/384/512 description document
+ * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
+ * same "backwards" definition.
+ */
+/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
+#define R(b,x) ((x) >> (b))
+/* 32-bit Rotate-right (used in SHA-256): */
+#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
+/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
+#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
+
+/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+/* Four of six logical functions used in SHA-256: */
+#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
+#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
+#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
+#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
+
+/* Four of six logical functions used in SHA-384 and SHA-512: */
+#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
+#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
+#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
+#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
+
+/*** INTERNAL FUNCTION PROTOTYPES *************************************/
+/* NOTE: These should not be accessed directly from outside this
+ * library -- they are intended for private internal visibility/use
+ * only.
+ */
+void SHA512_Last(SHA512_CTX*);
+void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
+void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
+
+
+/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
+/* Hash constant words K for SHA-256: */
+const static sha2_word32 K256[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
+ 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
+ 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
+ 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
+ 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
+ 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
+ 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
+ 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
+ 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
+ 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
+ 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
+ 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
+ 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Initial hash value H for SHA-256: */
+const static sha2_word32 sha256_initial_hash_value[8] = {
+ 0x6a09e667UL,
+ 0xbb67ae85UL,
+ 0x3c6ef372UL,
+ 0xa54ff53aUL,
+ 0x510e527fUL,
+ 0x9b05688cUL,
+ 0x1f83d9abUL,
+ 0x5be0cd19UL
+};
+
+/* Hash constant words K for SHA-384 and SHA-512: */
+const static sha2_word64 K512[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
+ 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
+ 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
+ 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
+ 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
+ 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
+ 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
+ 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
+ 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
+ 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
+ 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
+ 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
+ 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
+ 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
+ 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
+ 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
+ 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
+ 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
+ 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
+ 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
+ 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
+ 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+
+/* Initial hash value H for SHA-384 */
+const static sha2_word64 sha384_initial_hash_value[8] = {
+ 0xcbbb9d5dc1059ed8ULL,
+ 0x629a292a367cd507ULL,
+ 0x9159015a3070dd17ULL,
+ 0x152fecd8f70e5939ULL,
+ 0x67332667ffc00b31ULL,
+ 0x8eb44a8768581511ULL,
+ 0xdb0c2e0d64f98fa7ULL,
+ 0x47b5481dbefa4fa4ULL
+};
+
+/* Initial hash value H for SHA-512 */
+const static sha2_word64 sha512_initial_hash_value[8] = {
+ 0x6a09e667f3bcc908ULL,
+ 0xbb67ae8584caa73bULL,
+ 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL,
+ 0x510e527fade682d1ULL,
+ 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL,
+ 0x5be0cd19137e2179ULL
+};
+
+/*
+ * Constant used by SHA256/384/512_End() functions for converting the
+ * digest to a readable hexadecimal character string:
+ */
+static const char *sha2_hex_digits = "0123456789abcdef";
+
+
+/*** SHA-256: *********************************************************/
+void SHA256_Init(SHA256_CTX* context) {
+ if (context == (SHA256_CTX*)0) {
+ return;
+ }
+ MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
+ MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
+ context->bitcount = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-256 round macros: */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
+ REVERSE32(*data++, W256[j]); \
+ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+ K256[j] + W256[j]; \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+ j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \
+ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
+ K256[j] + (W256[j] = *data++); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+ j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND256(a,b,c,d,e,f,g,h) \
+ s0 = W256[(j+1)&0x0f]; \
+ s0 = sigma0_256(s0); \
+ s1 = W256[(j+14)&0x0f]; \
+ s1 = sigma1_256(s1); \
+ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
+ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
+ j++
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+ sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
+ sha2_word32 T1, *W256;
+ int j;
+
+ W256 = (sha2_word32*)context->buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->state[0];
+ b = context->state[1];
+ c = context->state[2];
+ d = context->state[3];
+ e = context->state[4];
+ f = context->state[5];
+ g = context->state[6];
+ h = context->state[7];
+
+ j = 0;
+ do {
+ /* Rounds 0 to 15 (unrolled): */
+ ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
+ ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
+ ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
+ ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
+ ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
+ ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
+ ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
+ ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
+ } while (j < 16);
+
+ /* Now for the remaining rounds to 64: */
+ do {
+ ROUND256(a,b,c,d,e,f,g,h);
+ ROUND256(h,a,b,c,d,e,f,g);
+ ROUND256(g,h,a,b,c,d,e,f);
+ ROUND256(f,g,h,a,b,c,d,e);
+ ROUND256(e,f,g,h,a,b,c,d);
+ ROUND256(d,e,f,g,h,a,b,c);
+ ROUND256(c,d,e,f,g,h,a,b);
+ ROUND256(b,c,d,e,f,g,h,a);
+ } while (j < 64);
+
+ /* Compute the current intermediate hash value */
+ context->state[0] += a;
+ context->state[1] += b;
+ context->state[2] += c;
+ context->state[3] += d;
+ context->state[4] += e;
+ context->state[5] += f;
+ context->state[6] += g;
+ context->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+ sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
+ sha2_word32 T1, T2, *W256;
+ int j;
+
+ W256 = (sha2_word32*)context->buffer;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->state[0];
+ b = context->state[1];
+ c = context->state[2];
+ d = context->state[3];
+ e = context->state[4];
+ f = context->state[5];
+ g = context->state[6];
+ h = context->state[7];
+
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Copy data while converting to host byte order */
+ REVERSE32(*data++,W256[j]);
+ /* Apply the SHA-256 compression function to update a..h */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+ /* Apply the SHA-256 compression function to update a..h with copy */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+ T2 = Sigma0_256(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W256[(j+1)&0x0f];
+ s0 = sigma0_256(s0);
+ s1 = W256[(j+14)&0x0f];
+ s1 = sigma1_256(s1);
+
+ /* Apply the SHA-256 compression function to update a..h */
+ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
+ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
+ T2 = Sigma0_256(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 64);
+
+ /* Compute the current intermediate hash value */
+ context->state[0] += a;
+ context->state[1] += b;
+ context->state[2] += c;
+ context->state[3] += d;
+ context->state[4] += e;
+ context->state[5] += f;
+ context->state[6] += g;
+ context->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
+ unsigned int freespace, usedspace;
+
+ if (len == 0) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
+
+ usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = SHA256_BLOCK_LENGTH - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+ context->bitcount += freespace << 3;
+ len -= freespace;
+ data += freespace;
+ SHA256_Transform(context, (sha2_word32*)context->buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+ context->bitcount += len << 3;
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= SHA256_BLOCK_LENGTH) {
+ /* Process as many complete blocks as we can */
+ SHA256_Transform(context, (sha2_word32*)data);
+ context->bitcount += SHA256_BLOCK_LENGTH << 3;
+ len -= SHA256_BLOCK_LENGTH;
+ data += SHA256_BLOCK_LENGTH;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(context->buffer, data, len);
+ context->bitcount += len << 3;
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+
+void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
+ sha2_word32 *d = (sha2_word32*)digest;
+ unsigned int usedspace;
+
+ /* Sanity check: */
+ assert(context != (SHA256_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha2_byte*)0) {
+ usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(context->bitcount,context->bitcount);
+#endif
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ context->buffer[usedspace++] = 0x80;
+
+ if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
+ } else {
+ if (usedspace < SHA256_BLOCK_LENGTH) {
+ MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA256_Transform(context, (sha2_word32*)context->buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+ }
+ } else {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *context->buffer = 0x80;
+ }
+ /* Set the bit count: */
+ *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+
+ /* Final transform: */
+ SHA256_Transform(context, (sha2_word32*)context->buffer);
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < 8; j++) {
+ REVERSE32(context->state[j],context->state[j]);
+ *d++ = context->state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Clean up state data: */
+ MEMSET_BZERO(context, sizeof(context));
+ usedspace = 0;
+}
+
+char *SHA256_End(SHA256_CTX* context, char buffer[]) {
+ sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA256_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA256_Final(digest, context);
+
+ for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+ *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha2_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(context));
+ }
+ MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
+ SHA256_CTX context;
+
+ SHA256_Init(&context);
+ SHA256_Update(&context, data, len);
+ return SHA256_End(&context, digest);
+}
+
+
+/*** SHA-512: *********************************************************/
+void SHA512_Init(SHA512_CTX* context) {
+ if (context == (SHA512_CTX*)0) {
+ return;
+ }
+ MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
+ context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+#ifdef SHA2_UNROLL_TRANSFORM
+
+/* Unrolled SHA-512 round macros: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
+ REVERSE64(*data++, W512[j]); \
+ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+ K512[j] + W512[j]; \
+ (d) += T1, \
+ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
+ j++
+
+
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \
+ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
+ K512[j] + (W512[j] = *data++); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+ j++
+
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+
+#define ROUND512(a,b,c,d,e,f,g,h) \
+ s0 = W512[(j+1)&0x0f]; \
+ s0 = sigma0_512(s0); \
+ s1 = W512[(j+14)&0x0f]; \
+ s1 = sigma1_512(s1); \
+ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
+ (d) += T1; \
+ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
+ j++
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+ sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
+ sha2_word64 T1, *W512 = (sha2_word64*)context->buffer;
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->state[0];
+ b = context->state[1];
+ c = context->state[2];
+ d = context->state[3];
+ e = context->state[4];
+ f = context->state[5];
+ g = context->state[6];
+ h = context->state[7];
+
+ j = 0;
+ do {
+ ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
+ ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
+ ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
+ ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
+ ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
+ ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
+ ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
+ ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
+ } while (j < 16);
+
+ /* Now for the remaining rounds up to 79: */
+ do {
+ ROUND512(a,b,c,d,e,f,g,h);
+ ROUND512(h,a,b,c,d,e,f,g);
+ ROUND512(g,h,a,b,c,d,e,f);
+ ROUND512(f,g,h,a,b,c,d,e);
+ ROUND512(e,f,g,h,a,b,c,d);
+ ROUND512(d,e,f,g,h,a,b,c);
+ ROUND512(c,d,e,f,g,h,a,b);
+ ROUND512(b,c,d,e,f,g,h,a);
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ context->state[0] += a;
+ context->state[1] += b;
+ context->state[2] += c;
+ context->state[3] += d;
+ context->state[4] += e;
+ context->state[5] += f;
+ context->state[6] += g;
+ context->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = 0;
+}
+
+#else /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+ sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
+ sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
+ int j;
+
+ /* Initialize registers with the prev. intermediate value */
+ a = context->state[0];
+ b = context->state[1];
+ c = context->state[2];
+ d = context->state[3];
+ e = context->state[4];
+ f = context->state[5];
+ g = context->state[6];
+ h = context->state[7];
+
+ j = 0;
+ do {
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert TO host byte order */
+ REVERSE64(*data++, W512[j]);
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
+#else /* BYTE_ORDER == LITTLE_ENDIAN */
+ /* Apply the SHA-512 compression function to update a..h with copy */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
+#endif /* BYTE_ORDER == LITTLE_ENDIAN */
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 16);
+
+ do {
+ /* Part of the message block expansion: */
+ s0 = W512[(j+1)&0x0f];
+ s0 = sigma0_512(s0);
+ s1 = W512[(j+14)&0x0f];
+ s1 = sigma1_512(s1);
+
+ /* Apply the SHA-512 compression function to update a..h */
+ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
+ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
+ T2 = Sigma0_512(a) + Maj(a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + T1;
+ d = c;
+ c = b;
+ b = a;
+ a = T1 + T2;
+
+ j++;
+ } while (j < 80);
+
+ /* Compute the current intermediate hash value */
+ context->state[0] += a;
+ context->state[1] += b;
+ context->state[2] += c;
+ context->state[3] += d;
+ context->state[4] += e;
+ context->state[5] += f;
+ context->state[6] += g;
+ context->state[7] += h;
+
+ /* Clean up */
+ a = b = c = d = e = f = g = h = T1 = T2 = 0;
+}
+
+#endif /* SHA2_UNROLL_TRANSFORM */
+
+void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
+ unsigned int freespace, usedspace;
+
+ if (len == 0) {
+ /* Calling with no data is valid - we do nothing */
+ return;
+ }
+
+ /* Sanity check: */
+ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
+
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ if (usedspace > 0) {
+ /* Calculate how much free space is available in the buffer */
+ freespace = SHA512_BLOCK_LENGTH - usedspace;
+
+ if (len >= freespace) {
+ /* Fill the buffer completely and process it */
+ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
+ ADDINC128(context->bitcount, freespace << 3);
+ len -= freespace;
+ data += freespace;
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
+ } else {
+ /* The buffer is not yet full */
+ MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
+ ADDINC128(context->bitcount, len << 3);
+ /* Clean up: */
+ usedspace = freespace = 0;
+ return;
+ }
+ }
+ while (len >= SHA512_BLOCK_LENGTH) {
+ /* Process as many complete blocks as we can */
+ SHA512_Transform(context, (sha2_word64*)data);
+ ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
+ len -= SHA512_BLOCK_LENGTH;
+ data += SHA512_BLOCK_LENGTH;
+ }
+ if (len > 0) {
+ /* There's left-overs, so save 'em */
+ MEMCPY_BCOPY(context->buffer, data, len);
+ ADDINC128(context->bitcount, len << 3);
+ }
+ /* Clean up: */
+ usedspace = freespace = 0;
+}
+
+void SHA512_Last(SHA512_CTX* context) {
+ unsigned int usedspace;
+
+ usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* Convert FROM host byte order */
+ REVERSE64(context->bitcount[0],context->bitcount[0]);
+ REVERSE64(context->bitcount[1],context->bitcount[1]);
+#endif
+ if (usedspace > 0) {
+ /* Begin padding with a 1 bit: */
+ context->buffer[usedspace++] = 0x80;
+
+ if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+ /* Set-up for the last transform: */
+ MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+ } else {
+ if (usedspace < SHA512_BLOCK_LENGTH) {
+ MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+ }
+ /* Do second-to-last transform: */
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
+
+ /* And set-up for the last transform: */
+ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
+ }
+ } else {
+ /* Prepare for final transform: */
+ MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+
+ /* Begin padding with a 1 bit: */
+ *context->buffer = 0x80;
+ }
+ /* Store the length of input data (in bits): */
+ *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
+ *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
+
+ /* Final transform: */
+ SHA512_Transform(context, (sha2_word64*)context->buffer);
+}
+
+void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
+ sha2_word64 *d = (sha2_word64*)digest;
+
+ /* Sanity check: */
+ assert(context != (SHA512_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha2_byte*)0) {
+ SHA512_Last(context);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < 8; j++) {
+ REVERSE64(context->state[j],context->state[j]);
+ *d++ = context->state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Zero out state data */
+ MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA512_End(SHA512_CTX* context, char buffer[]) {
+ sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA512_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA512_Final(digest, context);
+
+ for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
+ *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha2_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(context));
+ }
+ MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
+ SHA512_CTX context;
+
+ SHA512_Init(&context);
+ SHA512_Update(&context, data, len);
+ return SHA512_End(&context, digest);
+}
+
+
+/*** SHA-384: *********************************************************/
+void SHA384_Init(SHA384_CTX* context) {
+ if (context == (SHA384_CTX*)0) {
+ return;
+ }
+ MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
+ context->bitcount[0] = context->bitcount[1] = 0;
+}
+
+void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
+ SHA512_Update((SHA512_CTX*)context, data, len);
+}
+
+void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
+ sha2_word64 *d = (sha2_word64*)digest;
+
+ /* Sanity check: */
+ assert(context != (SHA384_CTX*)0);
+
+ /* If no digest buffer is passed, we don't bother doing this: */
+ if (digest != (sha2_byte*)0) {
+ SHA512_Last((SHA512_CTX*)context);
+
+ /* Save the hash data for output: */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ {
+ /* Convert TO host byte order */
+ int j;
+ for (j = 0; j < 6; j++) {
+ REVERSE64(context->state[j],context->state[j]);
+ *d++ = context->state[j];
+ }
+ }
+#else
+ MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
+#endif
+ }
+
+ /* Zero out state data */
+ MEMSET_BZERO(context, sizeof(context));
+}
+
+char *SHA384_End(SHA384_CTX* context, char buffer[]) {
+ sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
+ int i;
+
+ /* Sanity check: */
+ assert(context != (SHA384_CTX*)0);
+
+ if (buffer != (char*)0) {
+ SHA384_Final(digest, context);
+
+ for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
+ *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
+ *buffer++ = sha2_hex_digits[*d & 0x0f];
+ d++;
+ }
+ *buffer = (char)0;
+ } else {
+ MEMSET_BZERO(context, sizeof(context));
+ }
+ MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+ return buffer;
+}
+
+char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
+ SHA384_CTX context;
+
+ SHA384_Init(&context);
+ SHA384_Update(&context, data, len);
+ return SHA384_End(&context, digest);
+}
diff --git a/source/security_algorithms/sha/sha2.h b/source/security_algorithms/sha/sha2.h
new file mode 100644
index 0000000..d7f6110
--- /dev/null
+++ b/source/security_algorithms/sha/sha2.h
@@ -0,0 +1,197 @@
+/*
+ * FILE: sha2.h
+ * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
+ *
+ * Copyright (c) 2000-2001, Aaron D. Gifford
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
+ */
+
+#ifndef __SHA2_H__
+#define __SHA2_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Import u_intXX_t size_t type definitions from system headers. You
+ * may need to change this, or define these things yourself in this
+ * file.
+ */
+#include <sys/types.h>
+
+#ifdef SHA2_USE_INTTYPES_H
+
+#include <inttypes.h>
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+
+/*** SHA-256/384/512 Various Length Definitions ***********************/
+#define SHA256_BLOCK_LENGTH 64
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_BLOCK_LENGTH 128
+#define SHA384_DIGEST_LENGTH 48
+#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_BLOCK_LENGTH 128
+#define SHA512_DIGEST_LENGTH 64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+
+
+/*** SHA-256/384/512 Context Structures *******************************/
+/* NOTE: If your architecture does not define either u_intXX_t types or
+ * uintXX_t (from inttypes.h), you may need to define things by hand
+ * for your system:
+ */
+typedef unsigned char u_int8_t; /* 1-byte (8-bits) */
+typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */
+#ifndef LINUX_64
+typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */
+#endif
+
+/*
+ * Most BSD systems already define u_intXX_t types, as does Linux.
+ * Some systems, however, like Compaq's Tru64 Unix instead can use
+ * uintXX_t types defined by very recent ANSI C standards and included
+ * in the file:
+ *
+ * #include <inttypes.h>
+ *
+ * If you choose to use <inttypes.h> then please define:
+ *
+ * #define SHA2_USE_INTTYPES_H
+ *
+ * Or on the command line during compile:
+ *
+ * cc -DSHA2_USE_INTTYPES_H ...
+ */
+#ifdef SHA2_USE_INTTYPES_H
+
+typedef struct _SHA256_CTX {
+ uint32_t state[8];
+ uint64_t bitcount;
+ uint8_t buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX {
+ uint64_t state[8];
+ uint64_t bitcount[2];
+ uint8_t buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+#else /* SHA2_USE_INTTYPES_H */
+
+typedef struct _SHA256_CTX {
+ u_int32_t state[8];
+ u_int64_t bitcount;
+ u_int8_t buffer[SHA256_BLOCK_LENGTH];
+} SHA256_CTX;
+typedef struct _SHA512_CTX {
+ u_int64_t state[8];
+ u_int64_t bitcount[2];
+ u_int8_t buffer[SHA512_BLOCK_LENGTH];
+} SHA512_CTX;
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+typedef SHA512_CTX SHA384_CTX;
+
+
+/*** SHA-256/384/512 Function Prototypes ******************************/
+#ifndef NOPROTO
+#ifdef SHA2_USE_INTTYPES_H
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
+void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
+void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
+void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+
+#else /* SHA2_USE_INTTYPES_H */
+
+void SHA256_Init(SHA256_CTX *);
+void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t);
+void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
+char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
+char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+
+void SHA384_Init(SHA384_CTX*);
+void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t);
+void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
+char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+
+void SHA512_Init(SHA512_CTX*);
+void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t);
+void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
+char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+
+#endif /* SHA2_USE_INTTYPES_H */
+
+#else /* NOPROTO */
+
+void SHA256_Init();
+void SHA256_Update();
+void SHA256_Final();
+char* SHA256_End();
+char* SHA256_Data();
+
+void SHA384_Init();
+void SHA384_Update();
+void SHA384_Final();
+char* SHA384_End();
+char* SHA384_Data();
+
+void SHA512_Init();
+void SHA512_Update();
+void SHA512_Final();
+char* SHA512_End();
+char* SHA512_Data();
+
+#endif /* NOPROTO */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __SHA2_H__ */
diff --git a/source/utilities/BulkHandler.cpp b/source/utilities/BulkHandler.cpp
new file mode 100644
index 0000000..9dc9169
--- /dev/null
+++ b/source/utilities/BulkHandler.cpp
@@ -0,0 +1,286 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+#include "BulkHandler.h"
+#include "LCDriverMethods.h"
+#include "Buffers.h"
+#include "LcmInterface.h"
+#include "Logger.h"
+#include "Error.h"
+#include "lcdriver_error_codes.h"
+#include <string>
+#include <cstdio>
+using namespace std;
+
+/// <summary>
+/// BulkHandler constructor
+/// </summary>
+BulkHandler::BulkHandler(CLCDriverMethods *methods, Buffers *buffers, LcmInterface *lcmInterface, Logger *logger):
+ m_Methods(methods),
+ m_ReceiveQueue(32),
+ m_pBuffers(buffers),
+ m_pLcmInterface(lcmInterface),
+ m_pLogger(logger),
+ m_State(BULK_INACTIVE),
+ m_pFileWriteThread(0),
+ m_pBulkVector(0)
+{
+}
+
+/// <summary>
+/// BulkHandler destructor
+/// </summary>
+BulkHandler::~BulkHandler()
+{
+ TL_BulkVectorList_t *bulkVector = 0;
+
+ while (true) {
+ RemoveResult result = m_ReceiveQueue.RemoveHead(reinterpret_cast<void **>(&bulkVector), 0);
+
+ if (REMOVE_TIMEOUT == result) {
+ break;
+ } else if (REMOVE_CANCEL == result) {
+ continue;
+ }
+
+ m_pLcmInterface->BulkDestroyVector(bulkVector, true);
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Vector destroyed BulkVector = 0x%x", m_pBulkVector);
+#endif
+ }
+}
+
+int BulkHandler::Send(const string &sourceFile)
+{
+ if (BULK_INACTIVE != m_State) {
+ return BULK_ALREADY_IN_PROGRESS;
+ }
+
+ m_sFilePath = sourceFile;
+ m_State = BULK_TX;
+ return 0;
+}
+
+int BulkHandler::Receive(const string &destinationFile)
+{
+ if (BULK_INACTIVE != m_State) {
+ return BULK_ALREADY_IN_PROGRESS;
+ }
+
+ m_sFilePath = destinationFile;
+
+ // truncate the file for receiving
+ FILE *file = fopen(m_sFilePath.c_str(), "wb");
+
+ if (!file) {
+ return FILE_OPENING_ERROR;
+ }
+
+ fclose(file);
+
+ m_State = BULK_RX;
+
+ // start bulk file write thread
+ m_pFileWriteThread = new CThreadWrapper(FileWriteThreadFunction, this);
+ m_pFileWriteThread->ResumeThread();
+
+ return 0;
+}
+
+void BulkHandler::Finish()
+{
+ if (BULK_RX == m_State) {
+ m_State = BULK_INACTIVE;
+ m_ReceiveQueue.SignalEvent();
+ m_pFileWriteThread->WaitToDie(INFINITE);
+ } else {
+ m_State = BULK_INACTIVE;
+ }
+}
+
+void BulkHandler::HandleCommandRequest(uint16 session, uint32 chunkSize, uint64 offset, uint32 length, bool acknowledge)
+{
+ switch (SELECT_COMMAND(m_State, acknowledge)) {
+ case BULK_WRITE_REQUEST:
+ HandleWriteRequest(session, chunkSize, offset, length);
+ break;
+ case BULK_READ_REQUEST:
+ HandleReadRequest(session, chunkSize, offset, length);
+ break;
+ case BULK_RX_SESSION_END:
+ HandleRxSessionEnd(session, chunkSize, offset, length);
+ break;
+ case BULK_TX_SESSION_END:
+ HandleTxSessionEnd(session, chunkSize, offset, length);
+ break;
+ default:
+ break;
+ }
+}
+
+void BulkHandler::HandleWriteRequest(uint16 session, uint32 chunkSize, uint64 offset, uint32 length)
+{
+ int ReturnValue = E_SUCCESS;
+
+ uint32 VectorID = m_pLcmInterface->BulkOpenSession(session, BULK_RECEIVE, length);
+ VERIFY(BULK_ERROR != VectorID, BULK_VECTOR_ID_ERROR);
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Session opened with VectorID = %u", VectorID);
+#endif
+ m_pBulkVector = m_pLcmInterface->BulkCreateVector(VectorID, length, chunkSize, NULL);
+ VERIFY_SUCCESS(m_pLcmInterface->BulkStartSession(m_pBulkVector, offset));
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Session %u started with BulkVector = 0x%x", session, m_pBulkVector);
+#endif
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ m_Methods->SignalError(ReturnValue);
+ }
+}
+
+void BulkHandler::HandleReadRequest(uint16 session, uint32 chunkSize, uint64 offset, uint32 length)
+{
+ int ReturnValue = E_SUCCESS;
+
+ uint32 VectorID = m_pLcmInterface->BulkOpenSession(session, BULK_SEND, length);
+ VERIFY(BULK_ERROR != VectorID, BULK_VECTOR_ID_ERROR);
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Session opened with VectorID = %u", VectorID);
+#endif
+ m_pBulkVector = m_pLcmInterface->BulkCreateVector(VectorID, length, chunkSize, NULL);
+
+ VERIFY_SUCCESS(m_pBuffers->AllocateBulkVector(m_pBulkVector, chunkSize, offset, length));
+ VERIFY_SUCCESS(m_pLcmInterface->BulkStartSession(m_pBulkVector, offset));
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Session %u started with BulkVector = 0x%x", session, m_pBulkVector);
+#endif
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ m_Methods->SignalError(ReturnValue);
+ }
+}
+
+void BulkHandler::HandleRxSessionEnd(uint16 session, uint32 chunkSize, uint64 offset, uint32 length)
+{
+ int ReturnValue = E_SUCCESS;
+
+ m_ReceiveQueue.AddTail(m_pBulkVector);
+
+ VERIFY_SUCCESS(m_pLcmInterface->BulkCloseSession(m_pBulkVector));
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Session closed Session = %u", session);
+#endif
+
+ m_Methods->UpdateBulkProgress();
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ m_Methods->SignalError(ReturnValue);
+ }
+}
+
+void BulkHandler::HandleTxSessionEnd(uint16 session, uint32 chunkSize, uint64 offset, uint32 length)
+{
+ int ReturnValue = E_SUCCESS;
+
+ m_pBuffers->ReleaseBulkVector(m_pBulkVector);
+
+ VERIFY_SUCCESS(m_pLcmInterface->BulkDestroyVector(m_pBulkVector, false));
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Vector destroyed BulkVector = 0x%x", m_pBulkVector);
+#endif
+
+ m_Methods->UpdateBulkProgress();
+
+ErrorExit:
+
+ if (E_SUCCESS != ReturnValue) {
+ m_Methods->SignalError(ReturnValue);
+ }
+}
+
+void BulkHandler::FlushReceiveQueue()
+{
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Flush receive queue");
+#endif
+ TL_BulkVectorList_t *bulkVector = 0;
+
+ while (true) {
+ RemoveResult result = m_ReceiveQueue.RemoveHead(reinterpret_cast<void **>(&bulkVector), 0);
+
+ if (REMOVE_TIMEOUT == result) {
+ break;
+ } else if (REMOVE_CANCEL == result) {
+ continue;
+ }
+
+ WriteBulkVector(bulkVector);
+
+ m_pLcmInterface->BulkDestroyVector(bulkVector, true);
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Vector destroyed BulkVector = 0x%x", bulkVector);
+#endif
+ }
+}
+
+void BulkHandler::WriteBulkVector(TL_BulkVectorList_t *bulkVector)
+{
+ FILE *file = fopen(m_sFilePath.c_str(), "ab");
+
+ if (file) {
+ for (size_t i = 0; i != bulkVector->Buffers; ++i) {
+ uint32 currentChunkSize = bulkVector->ChunkSize;
+
+ if (i + 1 == bulkVector->Buffers) { //lastchunk
+ currentChunkSize = bulkVector->Length - (i * bulkVector->ChunkSize);
+ }
+
+ fwrite(bulkVector->Entries[i].Payload_p, currentChunkSize, 1, file);
+ }
+
+ fclose(file);
+#ifdef _BULKDEBUG
+ m_pLogger->log("BULK: Vector written BulkVector = 0x%x", m_pBulkVector);
+#endif
+ }
+}
+
+#ifdef _WIN32
+unsigned int WINAPI BulkHandler::FileWriteThreadFunction(void *arg)
+#else
+void *BulkHandler::FileWriteThreadFunction(void *arg)
+#endif
+{
+ BulkHandler *pThis = static_cast<BulkHandler *>(arg);
+
+ TL_BulkVectorList_t *bulkVector = 0;
+
+ while (true) {
+ RemoveResult result = pThis->m_ReceiveQueue.RemoveHead(reinterpret_cast<void **>(&bulkVector), INFINITE);
+
+ if (REMOVE_SUCCESS == result) {
+ pThis->WriteBulkVector(bulkVector);
+
+ pThis->m_pLcmInterface->BulkDestroyVector(bulkVector, true);
+#ifdef _BULKDEBUG
+ pThis->m_pLogger->log("BULK: Vector destroyed BulkVector = 0x%x", bulkVector);
+#endif
+ } else {
+ break;
+ }
+ }
+
+ pThis->FlushReceiveQueue();
+
+ return 0;
+}
diff --git a/source/utilities/BulkHandler.h b/source/utilities/BulkHandler.h
new file mode 100644
index 0000000..71147ab
--- /dev/null
+++ b/source/utilities/BulkHandler.h
@@ -0,0 +1,81 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+#ifndef _BULK_HANDLER_H_
+#define _BULK_HANDLER_H_
+
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#endif
+#include "Buffers.h"
+#include "LcmInterface.h"
+#include "Logger.h"
+#include <string>
+
+class CLCDriverMethods;
+
+/// <summary>
+/// Bulk handler state.
+/// </summary>
+enum BulkState {
+ BULK_INACTIVE,
+ BULK_RX,
+ BULK_TX
+};
+
+#define SESSION_END_MASK (1 << 4)
+#define SELECT_COMMAND(state, acknowledge) (state | (((uint32)acknowledge) << 4))
+
+enum BulkCommand {
+ BULK_WRITE_REQUEST = BULK_RX,
+ BULK_READ_REQUEST = BULK_TX,
+ BULK_RX_SESSION_END = BULK_WRITE_REQUEST | SESSION_END_MASK,
+ BULK_TX_SESSION_END = BULK_READ_REQUEST | SESSION_END_MASK
+};
+
+/// <summary>
+/// Bulk Buffer class used to manipulate
+/// the bulk buffers linear list filled
+/// with bulk chunks data
+/// </summary>
+class BulkHandler
+{
+public:
+ BulkHandler(CLCDriverMethods *methods, Buffers *buffers, LcmInterface *lcmInterface, Logger *logger);
+ ~BulkHandler();
+
+ int Receive(const std::string &sourceFile);
+ int Send(const std::string &destinationFile);
+ void Finish();
+ void HandleCommandRequest(uint16 session, uint32 chunkSize, uint64 offset, uint32 length, bool acknowledge);
+private:
+ CLCDriverMethods *m_Methods;
+ Buffers *m_pBuffers;
+ LcmInterface *m_pLcmInterface;
+ Logger *m_pLogger;
+ BulkState m_State;
+ TL_BulkVectorList_t *m_pBulkVector;
+ std::string m_sFilePath;
+ CSemaphoreQueue m_ReceiveQueue;
+ CThreadWrapper *m_pFileWriteThread;
+private:
+ void HandleReadRequest(uint16 session, uint32 chunkSize, uint64 offset, uint32 length);
+ void HandleWriteRequest(uint16 session, uint32 chunkSize, uint64 offset, uint32 length);
+ void HandleRxSessionEnd(uint16 session, uint32 chunkSize, uint64 offset, uint32 length);
+ void HandleTxSessionEnd(uint16 session, uint32 chunkSize, uint64 offset, uint32 length);
+#ifdef _WIN32
+ static unsigned int WINAPI FileWriteThreadFunction(void *arg);
+#else
+ static void *FileWriteThreadFunction(void *arg);
+#endif
+ void FlushReceiveQueue();
+ void WriteBulkVector(TL_BulkVectorList_t *bulkVector);
+};
+
+#endif
diff --git a/source/utilities/CaptiveThreadObject.cpp b/source/utilities/CaptiveThreadObject.cpp
new file mode 100644
index 0000000..e9eb472
--- /dev/null
+++ b/source/utilities/CaptiveThreadObject.cpp
@@ -0,0 +1,51 @@
+/*******************************************************************************
+*
+* File name: CaptiveThreadObject.cpp
+* Language: Visual C++
+* Description: Captive Thread Object class definitions
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File CaptiveThreadObject.cpp
+
+#include "CaptiveThreadObject.h"
+
+CCaptiveThreadObject::CCaptiveThreadObject()
+ : IsDying(0),
+#pragma warning(disable: 4355) // 'this' used before initialized but ok as thread starts in inactive state
+ Thread(ThreadEntry, this)
+{
+}
+#pragma warning(default: 4355)
+
+CCaptiveThreadObject::~CCaptiveThreadObject()
+{
+}
+
+void CCaptiveThreadObject::EndCaptiveThread()
+{
+ IsDying++;
+ SignalDeath();
+ Thread.WaitToDie();
+}
+
+
+// ThreadEntry - Entry point, executed by captive thread
+#ifdef _WIN32
+unsigned int WINAPI CCaptiveThreadObject::ThreadEntry(void *arg)
+#else
+void *CCaptiveThreadObject::ThreadEntry(void *arg)
+#endif
+{
+ CCaptiveThreadObject *pThis = static_cast<CCaptiveThreadObject *>(arg);
+ pThis->InitializeCaptiveThreadObject();
+ pThis->MainExecutionLoop();
+ return 0;
+}
+// End of file CaptiveThreadObject.cpp
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/utilities/CaptiveThreadObject.h b/source/utilities/CaptiveThreadObject.h
new file mode 100644
index 0000000..12b7b32
--- /dev/null
+++ b/source/utilities/CaptiveThreadObject.h
@@ -0,0 +1,57 @@
+/*******************************************************************************
+*
+* File name: CaptiveThreadObject.h
+* Language: Visual C++
+* Description: Captive Thread Object class declarations
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File CaptiveThreadObject.h
+
+#ifndef __CAPTIVE_THREAD_OBJECT_H__
+#define __CAPTIVE_THREAD_OBJECT_H__
+
+#pragma once
+
+#if defined(WIN32)
+#include <windows.h>
+#include "WinApiWrappers.h"
+#elif defined(__linux__)
+#include "LinuxApiWrappers.h"
+#else
+#error "Unknown target"
+#endif
+
+// CCaptiveThreadObject owns the captive thread
+class CCaptiveThreadObject
+{
+public:
+ CCaptiveThreadObject();
+ virtual ~CCaptiveThreadObject();
+ void EndCaptiveThread();
+ int ThreadIsDying() {
+ return IsDying;
+ }
+protected:
+ virtual void InitializeCaptiveThreadObject() = 0;
+ virtual void MainExecutionLoop() = 0;
+
+ virtual void SignalDeath() = 0;
+#ifdef _WIN32
+ static unsigned int WINAPI ThreadEntry(void *arg);
+#else
+ static void *ThreadEntry(void *arg);
+#endif
+ int IsDying;
+ CThreadWrapper Thread;
+};
+
+#endif
+
+// End of file CaptiveThreadObject.h
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/utilities/Error.h b/source/utilities/Error.h
new file mode 100755
index 0000000..0693287
--- /dev/null
+++ b/source/utilities/Error.h
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _ERROR_H_
+#define _ERROR_H_
+
+#define VERIFY(Condition, ErrorCode)\
+ do\
+ {\
+ if(!(Condition))\
+ {\
+ ReturnValue = (ErrorCode);\
+ goto ErrorExit;\
+ }\
+ } while(0)
+
+#define VERIFY_SUCCESS(ErrorCode)\
+ do\
+ {\
+ ReturnValue = (ErrorCode);\
+ VERIFY(E_SUCCESS == ReturnValue, ReturnValue);\
+ } while (0)
+
+#endif // _ERROR_H_
diff --git a/source/utilities/Event.h b/source/utilities/Event.h
new file mode 100644
index 0000000..36d8f3a
--- /dev/null
+++ b/source/utilities/Event.h
@@ -0,0 +1,27 @@
+/******************************************************************************
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+******************************************************************************/
+
+#ifndef _EVENT_H_
+#define _EVENT_H_
+
+enum {
+ EVENT_GR_RECEIVED = 0x00000001,
+ EVENT_CMD_RECEIVED = 0x00000002,
+ EVENT_SPEEDFLASH = 0x00000004,
+ EVENT_ERROR = 0x00000008
+};
+
+struct Event {
+ Event(uint32 ev, uint32 err, uint8 gr = 0, uint8 cmd = 0):
+ event(ev), error(err), group(gr), command(cmd) {}
+ uint32 event;
+ uint32 error;
+ uint8 group;
+ uint8 command;
+};
+
+#endif // _EVENT_H_
diff --git a/source/utilities/LockLessQueue.h b/source/utilities/LockLessQueue.h
new file mode 100644
index 0000000..6f54bda
--- /dev/null
+++ b/source/utilities/LockLessQueue.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _LOCKLESSQUEUE_H_
+#define _LOCKLESSQUEUE_H_
+
+/// <summary>
+/// Class for store received data in Z-protocol in a lockless queue.
+/// </summary>
+class LockLessQueue
+{
+ unsigned char *m_puchQueue;
+ unsigned int m_uiHead;
+ unsigned int m_uiTail;
+ unsigned int m_uiSize;
+ unsigned int m_uiMask;
+
+public:
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ /// <param name="uiSize">Size of buffer = 2^uiSize.</param>
+ LockLessQueue(unsigned int uiSize): m_uiHead(0), m_uiTail(0) {
+ m_uiSize = 1 << uiSize;
+ m_uiMask = m_uiSize - 1;
+ m_puchQueue = new unsigned char[m_uiSize];
+ }
+
+ /// <summary>
+ /// Constructor. Default buffer size to 2^20.
+ /// </summary>
+ LockLessQueue(): m_uiHead(0), m_uiTail(0) {
+ m_uiSize = 1 << 20;
+ m_uiMask = m_uiSize - 1;
+ m_puchQueue = new unsigned char[m_uiSize];
+ }
+
+ /// <summary>
+ /// Destructor.
+ /// </summary>
+ ~LockLessQueue() {
+ if (m_puchQueue != 0) {
+ delete [] m_puchQueue;
+ }
+ }
+
+ /// <summary>
+ /// Store one byte in buffer queue.
+ /// </summary>
+ /// <param name="uchData">Data to store in buffer.</param>
+ /// <param name="pbFull">Status of buffer, true = full buffer.</param>
+ void Push(unsigned char uchData, bool *pbFull) {
+ unsigned int uiHead = m_uiHead;
+ uiHead = uiHead & m_uiMask; //(Head++) & m_uiMask -> This does the required roll over to zero at the end of the array.
+ uiHead++;
+
+ if (uiHead == m_uiTail) {
+ *pbFull = true;
+ } else {
+ m_puchQueue[uiHead] = uchData;
+ m_uiHead = uiHead;
+ *pbFull = false;
+ }
+ }
+
+
+ /// <summary>
+ /// Take out one byte from buffer queue.
+ /// </summary>
+ /// <param name="pbEmpty">Status of buffer. pbEmpty = true -> buffer is empty.</param>
+ /// <returns> One byte data from buffer queue.</returns>
+ unsigned char Pop(bool *pbEmpty) {
+ unsigned char uchPopData = 0;
+ unsigned int uiTail = m_uiTail;
+
+ if (m_uiHead != uiTail) {
+ uiTail = (uiTail + 1) & m_uiMask; //This does the required roll over to zero at the end of the array.
+ m_uiTail = uiTail;
+ uchPopData = m_puchQueue[uiTail];
+ *pbEmpty = false;
+ } else {
+ *pbEmpty = true;
+ }
+
+ return uchPopData;
+ }
+
+ /// <summary>
+ /// Reset buffer queue.
+ /// </summary>
+ void Clear() {
+ m_uiTail = m_uiHead;
+ }
+};
+
+#endif // _LOCKLESSQUEUE_H_
diff --git a/source/utilities/Logger.cpp b/source/utilities/Logger.cpp
new file mode 100644
index 0000000..d0370d6
--- /dev/null
+++ b/source/utilities/Logger.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "Logger.h"
+using namespace std;
+
+#ifdef _WIN32
+#define flockfile _lock_file
+#define funlockfile _unlock_file
+#else
+#include <cstddef>
+#include "OS.h"
+#endif
+
+Logger::Logger(const void *communication): communication_(communication), messageCallback_(0)
+{
+}
+
+void Logger::log(const char *format, ...)
+{
+#ifdef _MESSAGES
+
+ if (0 != messageCallback_) {
+ CLockCS lock(criticalSection_);
+ va_list args;
+ char message[1024];
+ va_start(args, format);
+ vsprintf_s(message, format, args);
+ va_end(args);
+ messageCallback_(communication_, strlen(message), message);
+ }
+
+#endif
+}
diff --git a/source/utilities/Logger.h b/source/utilities/Logger.h
new file mode 100644
index 0000000..2388bb4
--- /dev/null
+++ b/source/utilities/Logger.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#ifndef _LOGGER_H_
+#define _LOGGER_H_
+
+#include "t_basicdefinitions.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#endif
+
+typedef void (*MessageCallback_t)(const void *Communication_p, uint32 MessageLength, const char *MessageText);
+
+class Logger
+{
+public:
+ Logger(const void *communication);
+
+ void log(const char *format, ...);
+ void setMessageCallback(MessageCallback_t messageCallback) {
+ messageCallback_ = messageCallback;
+ }
+private:
+ CCriticalSectionObject criticalSection_;
+ const void *communication_;
+ MessageCallback_t messageCallback_;
+};
+
+#endif // _LOGGER_H_ \ No newline at end of file
diff --git a/source/utilities/MemMappedFile.cpp b/source/utilities/MemMappedFile.cpp
new file mode 100644
index 0000000..287c5b9
--- /dev/null
+++ b/source/utilities/MemMappedFile.cpp
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+
+#include "lcdriver_error_codes.h"
+#include "MemMappedFile.h"
+#if defined(_WIN32)
+#include <windows.h>
+#elif defined(__linux__)
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <string.h>
+using namespace std;
+#else
+#error "Unknown target"
+#endif
+
+MemMappedFile::MemMappedFile(uint32 alignmentLength):
+ size_(0),
+ isMapped_(false),
+ mappedData_(0),
+ error_(0),
+ alignmentLength_(alignmentLength),
+#ifdef _WIN32
+ handle_(INVALID_HANDLE_VALUE),
+ memmap_(INVALID_HANDLE_VALUE)
+#else
+ descriptor_(-1)
+#endif
+{
+}
+
+MemMappedFile::~MemMappedFile()
+{
+#ifdef _WIN32
+
+ if (0 != mappedData_) {
+ UnmapViewOfFile(mappedData_);
+ }
+
+ if (INVALID_HANDLE_VALUE != memmap_) {
+ CloseHandle(memmap_);
+ }
+
+ if (INVALID_HANDLE_VALUE != handle_) {
+ CloseHandle(handle_);
+ }
+
+#else
+
+ if (0 != mappedData_) {
+ munmap(mappedData_, size_);
+ }
+
+ if (-1 != descriptor_) {
+ close(descriptor_);
+ }
+
+#endif
+}
+
+int MemMappedFile::LoadFileData(const char *path)
+{
+ path_ = path;
+#ifdef _WIN32
+ handle_ = CreateFile(path_.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (INVALID_HANDLE_VALUE == handle_) {
+ return FILE_OPENING_ERROR;
+ }
+
+ size_ = ::GetFileSize(handle_, NULL);
+
+ if (0 == size_) {
+ return 0;
+ }
+
+ memmap_ = CreateFileMapping(handle_, NULL, PAGE_READONLY, 0, 0, NULL);
+
+ if (INVALID_HANDLE_VALUE == memmap_) {
+ return FILE_CREATE_MAPPING_ERROR;
+ }
+
+ mappedData_ = static_cast<uint8 *>(MapViewOfFile(memmap_, FILE_MAP_READ, 0, 0, 0));
+
+ if (0 != mappedData_) {
+ isMapped_ = true;
+ volatile char tmp;
+
+ for (uint64 i = 0; i < size_; i += 4096) {
+ tmp = mappedData_[i];
+ }
+ } else {
+ isMapped_ = false;
+ CloseHandle(memmap_);
+ memmap_ = INVALID_HANDLE_VALUE;
+ }
+
+#else
+ descriptor_ = open(path_.c_str(), O_RDONLY);
+
+ if (-1 == descriptor_) {
+ return FILE_OPENING_ERROR;
+ }
+
+ struct stat fileStat;
+
+ if (0 != fstat(descriptor_, &fileStat)) {
+ return FILE_FAILED_TO_GET_SIZE;
+ }
+
+ size_ = fileStat.st_size;
+
+ mappedData_ = static_cast<uint8 *>(mmap(0, size_, PROT_READ, MAP_PRIVATE | MAP_POPULATE, descriptor_, 0));
+
+ if (MAP_FAILED != mappedData_) {
+ isMapped_ = true;
+ } else {
+ isMapped_ = false;
+ }
+
+#endif
+ return 0;
+}
+
+uint8 *MemMappedFile::AllocateFileData(uint64 offset, uint64 size)
+{
+ if (size_ < offset + size) {
+ error_ = FILE_READ_INVALID_OFFSET;
+ return 0;
+ }
+
+ uint32 alignedSize = (static_cast<uint32>(size) + (alignmentLength_ - 1)) & (~(alignmentLength_ - 1));
+
+ if (isMapped_) {
+ if (size_ < offset + alignedSize) {
+ uint8 *data = new uint8[alignedSize];
+ memcpy(data, mappedData_ + offset, static_cast<size_t>(size));
+ return data;
+ } else {
+ return mappedData_ + offset;
+ }
+ } else {
+ // file is not memory mapped fall back to plain read
+ uint32 readSize = static_cast<uint32>(size);
+ uint8 *data = new uint8[alignedSize];
+#ifdef _WIN32
+ LARGE_INTEGER liOffset;
+ liOffset.QuadPart = offset;
+
+ if (!SetFilePointerEx(handle_, liOffset, NULL, FILE_BEGIN)) {
+ delete[] data;
+ error_ = FILE_READ_INVALID_OFFSET;
+ return 0;
+ }
+
+ uint32 bytesRead;
+
+ if (ReadFile(handle_, data, readSize, (LPDWORD)&bytesRead, NULL) && bytesRead == size) {
+ return data;
+ } else {
+ delete[] data;
+ error_ = FILE_READ_ERROR;
+ return 0;
+ }
+
+#else
+
+ if (-1 == lseek64(descriptor_, offset, SEEK_SET)) {
+ delete[] data;
+ error_ = FILE_READ_INVALID_OFFSET;
+ return 0;
+ }
+
+ if (readSize == (uint32)read(descriptor_, data, readSize)) {
+ return data;
+ } else {
+ delete[] data;
+ error_ = FILE_READ_ERROR;
+ return 0;
+ }
+
+#endif
+ }
+}
+
+void MemMappedFile::ReleaseFileData(uint8 *data, uint64 offset, uint64 size)
+{
+ uint32 alignedSize = (static_cast<uint32>(size) + (alignmentLength_ - 1)) & (~(alignmentLength_ - 1));
+ if (!isMapped_ || size_ < offset + alignedSize) {
+ delete[] data;
+ }
+}
+
+uint64 MemMappedFile::GetFileSize()
+{
+ return size_;
+}
+
+int MemMappedFile::GetError()
+{
+ return error_;
+}
diff --git a/source/utilities/MemMappedFile.h b/source/utilities/MemMappedFile.h
new file mode 100644
index 0000000..8cc63f5
--- /dev/null
+++ b/source/utilities/MemMappedFile.h
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _MEMMAPPEDFILE_H_
+#define _MEMMAPPEDFILE_H_
+
+#include "t_basicdefinitions.h"
+#include <string>
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+class MemMappedFile
+{
+public:
+ MemMappedFile(uint32 alignmentLength = 512);
+ ~MemMappedFile();
+
+ uint8 *AllocateFileData(uint64 offset, uint64 size);
+ void ReleaseFileData(uint8 *data, uint64 offset, uint64 size);
+ uint64 GetFileSize();
+ int LoadFileData(const char *path);
+ int GetError();
+private:
+ std::string path_;
+ uint64 size_;
+ bool isMapped_;
+ uint32 alignmentLength_;
+ uint8 *mappedData_;
+ int error_;
+#ifdef _WIN32
+ HANDLE handle_;
+ HANDLE memmap_;
+#else
+ int descriptor_;
+#endif
+};
+
+#endif // _MEMMAPPEDFILE_H_
diff --git a/source/utilities/ObjectList.h b/source/utilities/ObjectList.h
new file mode 100644
index 0000000..6151104
--- /dev/null
+++ b/source/utilities/ObjectList.h
@@ -0,0 +1,286 @@
+/*******************************************************************************
+*
+* File name: ObjectList.h
+* Language: Visual C++
+* Description: Template class for manage list of object
+*
+*
+* Copyright (C) ST-Ericsson SA 2011
+* License terms: 3-clause BSD license
+*
+*******************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File ObjectList.h
+
+#ifndef __OBJECT_LIST_H__
+#define __OBJECT_LIST_H__
+
+#pragma once
+#if defined(_WIN32)
+#include "WinApiWrappers.h"
+#elif defined(__linux__)
+#include "LinuxApiWrappers.h"
+#include <stdio.h>
+#include <stdlib.h>
+#else
+#error "Unknown target"
+#endif
+
+#define ID_STRING_LEN 25
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Template class CObjectList
+
+template < class TemplateClass > class CObjectList
+{
+public:
+ CObjectList();
+ virtual ~CObjectList();
+
+ int Add(TemplateClass *pObject, const char *szObjectId, int nSubPart = -1);
+ TemplateClass *Find(const char *szObjectId, int nSubPart = -1);
+ int Release(TemplateClass *pObject);
+ int GetNumberOfInstances(TemplateClass *pObject);
+
+protected:
+ struct TObjectList {
+ TemplateClass *pObject;
+ char szObjectId[ 25 + 1 ];
+ int nSubPart;
+ int nCounter;
+ TObjectList *pNextObject;
+ } *m_pObjectList;
+ CCriticalSectionObject m_CriticalSectionObject;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// CObjectList()
+// Constructor
+//
+template < class TemplateClass >
+CObjectList< TemplateClass >::CObjectList()
+{
+ m_pObjectList = NULL;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ~CObjectList()
+// Destructor
+//
+template < class TemplateClass >
+CObjectList< TemplateClass >::~CObjectList()
+{
+ CLockCS Lock(m_CriticalSectionObject);
+ TObjectList *pCurrentObject;
+
+ // Delete all object that is left.
+ while (m_pObjectList != NULL) {
+ pCurrentObject = m_pObjectList;
+ m_pObjectList = pCurrentObject->pNextObject;
+ free(pCurrentObject);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Add()
+// FUNCTION
+// Add() -- Add object ID to the object list
+//
+// INPUT
+// szId - ID of the object
+// pObject - Object to be assigned to the ID
+//
+// RESULT
+// 0: Success
+// 1: ID string is to long
+// -1: Unable to expand the list.
+// -2: SubParts doesn't match each other.
+//
+// NOTES
+// If no record with the same ID string exist, a new record will be added and the object pointer will be set.
+// If a record with the same ID string already exists in the array, the instance counter will be incremented.
+//
+
+template < class TemplateClass >
+int CObjectList< TemplateClass >::Add(TemplateClass *pObject, const char *szObjectId, int nSubPart)
+{
+ CLockCS Lock(m_CriticalSectionObject);
+ TObjectList *pCurrentObject;
+
+ if (m_pObjectList == NULL) {
+ m_pObjectList = (TObjectList *)malloc(sizeof(TObjectList));
+
+ if (m_pObjectList == NULL) {
+ return -1;
+ }
+
+ m_pObjectList->pObject = pObject;
+ strcpy_s(m_pObjectList->szObjectId, szObjectId);
+ m_pObjectList->nSubPart = nSubPart;
+ m_pObjectList->nCounter = 1;
+ m_pObjectList->pNextObject = NULL;
+ } else { // Is the object allready created ?
+ pCurrentObject = m_pObjectList;
+
+ while (((strcmp(pCurrentObject->szObjectId, szObjectId) != 0) || (pCurrentObject->nSubPart != nSubPart)) && (pCurrentObject->pNextObject != NULL)) {
+ pCurrentObject = pCurrentObject->pNextObject;
+ }
+
+ if ((_stricmp(pCurrentObject->szObjectId, szObjectId) == 0) && (pCurrentObject->nSubPart = nSubPart)) {
+ pCurrentObject->nCounter++; // Found the object!
+ } else {
+ // Add a new object to the end of the list.
+ pCurrentObject->pNextObject = (TObjectList *)malloc(sizeof(TObjectList));
+
+ if (pCurrentObject->pNextObject == NULL) {
+ return -1;
+ }
+
+ pCurrentObject->pNextObject->pObject = pObject;
+ strcpy_s(pCurrentObject->pNextObject->szObjectId, szObjectId);
+ pCurrentObject->pNextObject->nSubPart = nSubPart;
+ pCurrentObject->pNextObject->nCounter = 1;
+ pCurrentObject->pNextObject->pNextObject = NULL;
+ }
+ }
+
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Release()
+// FUNCTION
+// Release() -- Release reference to object from the object list
+//
+// INPUT
+// pObject - Object to release
+//
+// RESULT
+// The number of instances left for this object.
+// If negative the object doesn't exist in the list.
+//
+// NOTES
+// The instance counter for the entry is decremented.
+// If the instance counter reaches 0, the entry will be deleted from the list.
+//
+
+template < class TemplateClass >
+int CObjectList< TemplateClass >::Release(TemplateClass *pObject)
+{
+ CLockCS Lock(m_CriticalSectionObject);
+ TObjectList *pCurrentObject, *pLastObject;
+
+ // Find the right object to delete.
+ if (m_pObjectList != NULL) {
+ pCurrentObject = m_pObjectList;
+ pLastObject = NULL;
+
+ while ((pCurrentObject->pObject != pObject) && (pCurrentObject->pNextObject != NULL)) {
+ pLastObject = pCurrentObject;
+ pCurrentObject = pCurrentObject->pNextObject;
+ }
+
+ if (pCurrentObject->pObject == pObject) {
+ if (pCurrentObject->nCounter > 1) {
+ pCurrentObject->nCounter--;
+ return pCurrentObject->nCounter;
+ } else {
+ // Remove the current record in the global object table.
+ if (pLastObject == NULL) {
+ m_pObjectList = pCurrentObject->pNextObject;
+ } else {
+ pLastObject->pNextObject = pCurrentObject->pNextObject;
+ }
+
+ free(pCurrentObject);
+ return 0;
+ }
+ } else {
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Find()
+// FUNCTION
+// Find() -- Search for an object ID in the object list
+//
+// INPUT
+// szObjectId - ID of object
+//
+// RESULT
+// The object pointer to the object assigned to the ID or
+// NULL if the ID was not found
+//
+
+template < class TemplateClass >
+TemplateClass *CObjectList< TemplateClass >::Find(const char *szObjectId, int nSubPart)
+{
+ CLockCS Lock(m_CriticalSectionObject);
+ TObjectList *pCurrentObject;
+
+ // Find the right object
+ if (m_pObjectList != NULL) {
+ pCurrentObject = m_pObjectList;
+
+ while (((strcmp(pCurrentObject->szObjectId, szObjectId) != 0) || (pCurrentObject->nSubPart != nSubPart)) && (pCurrentObject->pNextObject != NULL)) {
+ pCurrentObject = pCurrentObject->pNextObject;
+ }
+
+ if ((_stricmp(pCurrentObject->szObjectId, szObjectId) == 0) && (pCurrentObject->nSubPart = nSubPart)) {
+ return pCurrentObject->pObject;
+ } else {
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// GetNumberOfInstances()
+// FUNCTION
+// GetNumberOfInstances() -- Search for an object ID in the object list
+//
+// INPUT
+// szObjectId - ID of object
+//
+// RESULT
+// The number of instances of the object assigned to the ID.
+// 0 if the ID was not found.
+//
+
+template < class TemplateClass >
+int CObjectList< TemplateClass >::GetNumberOfInstances(TemplateClass *pObject)
+{
+ CLockCS Lock(m_CriticalSectionObject);
+ TObjectList *pCurrentObject;
+
+ // Find the right object
+ if (m_pObjectList != NULL) {
+ pCurrentObject = m_pObjectList;
+
+ while ((pCurrentObject->pObject != pObject) && (pCurrentObject->pNextObject != NULL)) {
+ pCurrentObject = pCurrentObject->pNextObject;
+ }
+
+ if (pCurrentObject->pObject == pObject) {
+ return pCurrentObject->nCounter;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+}
+
+#endif
+
+// End of file ObjectList.h
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/source/utilities/Serialization.cpp b/source/utilities/Serialization.cpp
new file mode 100644
index 0000000..b4daa21
--- /dev/null
+++ b/source/utilities/Serialization.cpp
@@ -0,0 +1,325 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+/*
+ * @addtogroup ldr_utilities
+ * @{
+ * @addtogroup serialization
+ * @{
+ */
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+#include <cstdlib>
+#include <cstring>
+#include "Serialization.h"
+#include "LCDriverMethods.h"
+#include "command_ids.h"
+
+ListDevice_t Devices[MAX_NO_OF_DEVICES];
+uint32 DevicesNumber = 0;
+
+Serialization::Serialization(): logger_(0)
+{
+}
+
+Serialization::~Serialization()
+{
+}
+
+/*******************************************************************************
+ * Definition of external functions
+ ******************************************************************************/
+
+void Serialization::get_block(const void **data_pp, void *target_p, uint32 length)
+{
+ memcpy(target_p, *data_pp, length);
+ *(const uint8 **)data_pp += length;
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tget_block\tLength=%i", (void *)length);
+#endif
+}
+
+SupportedCommand_t *Serialization::get_supportedcommands(const void **data_pp, uint32 CommandsCount)
+{
+ SupportedCommand_t *SupportedCommands = new SupportedCommand_t[CommandsCount];
+
+ for (uint32 i = 0; i < CommandsCount; i++) {
+ SupportedCommands[i].Group = get_uint32_le(data_pp);
+ SupportedCommands[i].Command = get_uint32_le(data_pp);
+ SupportedCommands[i].Permitted = get_uint32_le(data_pp);
+ }
+
+ return SupportedCommands;
+}
+
+ListDevice_t *Serialization::get_devices(const void **data_pp, uint32 DevicesCount)
+{
+ size_t size = 0;
+ const char *str;
+
+ DevicesNumber = DevicesCount;
+
+ for (uint32 i = 0; i < DevicesCount; i++) {
+ str = skip_str(data_pp);
+ size = get_uint32_le((const void **)&str);
+ memset(Devices[i].Path_p, 0, 256);
+ memcpy(Devices[i].Path_p, str, size);
+ Devices[i].Path_p[size] = '\0';
+
+ str = skip_str(data_pp);
+ size = get_uint32_le((const void **)&str);
+ memset(Devices[i].Type_p, 0, 256);
+ memcpy(Devices[i].Type_p, str, size);
+ Devices[i].Type_p[size] = '\0';
+
+ Devices[i].BlockSize = get_uint64_le(data_pp);
+ Devices[i].Start = get_uint64_le(data_pp);
+ Devices[i].Length = get_uint64_le(data_pp);
+ }
+
+ return Devices;
+}
+
+DirEntry_t *Serialization::get_direntries(const void **data_pp, uint32 DirectoriesCount)
+{
+ DirEntry_t *Direntries = new DirEntry_t[DirectoriesCount];
+ size_t size = 0;
+ const char *str;
+
+ for (uint32 i = 0; i < DirectoriesCount; i++) {
+ str = skip_str(data_pp);
+ size = get_uint32_le((const void **)&str);
+ Direntries[i].Name_p = new char[size + 1];
+ memcpy(Direntries[i].Name_p, str, size);
+ Direntries[i].Name_p[size] = '\0';
+
+ Direntries[i].Size = get_uint64_le(data_pp);
+ Direntries[i].Mode = get_uint32_le(data_pp);
+ Direntries[i].Time = get_uint32_le(data_pp);
+ }
+
+ return Direntries;
+}
+
+uint8 Serialization::get_uint8(const void **data_pp)
+{
+ const uint8 *d = *(const uint8 **)data_pp;
+ *(const uint8 **)data_pp += sizeof(uint8);
+#ifdef _SERIALIZATIONDEBUG
+ unsigned char v = d[0];
+ PrintF("Serialization\tget_uint8\tReturned val=0x%x", (void *)v);
+#endif
+ return d[0];
+}
+uint16 Serialization::get_uint16_le(const void **data_pp)
+{
+ const uint8 *d = *(const uint8 **)data_pp;
+ *(const uint8 **)data_pp += sizeof(uint16);
+#ifdef _SERIALIZATIONDEBUG
+ unsigned short v = (d[1] << 8) | d[0];
+ PrintF("Serialization\tget_uint16_le\tReturned val=0x%x", (void *)v);
+#endif
+ return (d[1] << 8) | d[0];
+}
+uint16 Serialization::get_uint16_be(const void **data_pp)
+{
+ const uint8 *d = *(const uint8 **)data_pp;
+ *(const uint8 **)data_pp += sizeof(uint16);
+#ifdef _SERIALIZATIONDEBUG
+ unsigned short v = (d[0] << 8) | d[1];
+ PrintF("Serialization\tget_uint16_be\tReturned val=0x%x", (void *)v);
+#endif
+ return (d[0] << 8) | d[1];
+}
+uint32 Serialization::get_uint32_le(const void **data_pp)
+{
+ const uint8 *d = *(const uint8 **) data_pp;
+ *(const uint8 **)data_pp += sizeof(uint32);
+#ifdef _SERIALIZATIONDEBUG
+ unsigned int v = ((d[3] << 8 | d[2]) << 8 | d[1]) << 8 | d[0];
+ PrintF("Serialization\tget_uint32_le\tReturned val=0x%x", (void *)v);
+#endif
+ return ((d[3] << 8 | d[2]) << 8 | d[1]) << 8 | d[0];
+}
+
+uint64 Serialization::get_uint64_le(const void **data_pp)
+{
+ const uint8 *d = *(const uint8 **) data_pp;
+ *(const uint8 **)data_pp += sizeof(uint64);
+#ifdef _SERIALIZATIONDEBUG
+ uint64 v = (((((((uint64)d[7] << 8 | d[6]) << 8 | d[5]) << 8 | d[4]) << 8 | d[3]) << 8 | d[2]) << 8 | d[1]) << 8 | d[0];
+ PrintF("Serialization\tget_uint64_le\tReturned val=0x%x", (void *)v);
+#endif
+ return (((((((uint64)d[7] << 8 | d[6]) << 8 | d[5]) << 8 | d[4]) << 8 | d[3]) << 8 | d[2]) << 8 | d[1]) << 8 | d[0];
+}
+
+uint32 Serialization::get_uint32_be(const void **data_pp)
+{
+ const uint8 *d = *(const uint8 **) data_pp;
+ *(const uint8 **)data_pp += sizeof(uint32);
+#ifdef _SERIALIZATIONDEBUG
+ unsigned int v = ((d[0] << 8 | d[1]) << 8 | d[2]) << 8 | d[3];
+ PrintF("Serialization\tget_uint32_be\tReturned val=0x%x", (void *)v);
+#endif
+ return ((d[0] << 8 | d[1]) << 8 | d[2]) << 8 | d[3];
+}
+
+void Serialization::put_block(void **data_pp, const void *source_p, uint32 length)
+{
+ if (length > 0) {
+ memcpy(*data_pp, source_p, length);
+ *(const uint8 **)data_pp += length;
+ }
+
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_block\tLength=%i", (void *)length);
+#endif
+}
+
+void Serialization::put_string(void **data_pp, const void *source_p, uint32 length)
+{
+ if (length > 0) {
+ memcpy(*data_pp, &length, sizeof(uint32));
+ *(const uint8 **)data_pp += sizeof(uint32);
+ memcpy(*data_pp, source_p, length);
+ *(const uint8 **)data_pp += length;
+ }
+}
+
+void Serialization::put_uint8(void **data_pp, uint8 v)
+{
+ **(uint8 **) data_pp = v;
+ *(uint8 **) data_pp += sizeof(uint8);
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_uint8\tInput val=0x%x", (void *)v);
+#endif
+}
+
+void Serialization::put_uint16_le(void **data_pp, uint16 v)
+{
+ uint8 *d = *(uint8 **) data_pp;
+ d[0] = v & 0xff;
+ d[1] = v >> 8;
+ *(uint8 **)data_pp += sizeof(uint16);
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_uint16_le\tInput val=0x%x", (void *)v);
+#endif
+}
+
+void Serialization::put_uint16_be(void **data_pp, uint16 v)
+{
+ uint8 *d = *(uint8 **) data_pp;
+ d[1] = v & 0xff;
+ d[0] = v >> 8;
+ *(uint8 **)data_pp += sizeof(uint16);
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_uint16_be\tInput val=0x%x", (void *)v);
+#endif
+}
+
+void Serialization::put_uint32_le(void **data_pp, uint32 v)
+{
+ uint8 *d = *(uint8 **) data_pp;
+ uint8 *v_p = (uint8 *)&v;
+ d[0] = v_p[0];
+ d[1] = v_p[1];
+ d[2] = v_p[2];
+ d[3] = v_p[3];
+ *(uint8 **)data_pp += sizeof(uint32);
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_uint32_le\tInput val=0x%x", (void *)v);
+#endif
+}
+
+void Serialization::put_uint32_be(void **data_pp, uint32 v)
+{
+ uint8 *d = *(uint8 **) data_pp;
+ uint8 *v_p = (uint8 *)&v;
+ d[3] = v_p[0];
+ d[2] = v_p[1];
+ d[1] = v_p[2];
+ d[0] = v_p[3];
+ *(uint8 **)data_pp += sizeof(uint32);
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_uint32_be\tInput val=0x%x", (void *)v);
+#endif
+}
+
+void Serialization::put_uint64_le(void **data_pp, uint64 v)
+{
+ uint8 *d = *(uint8 **) data_pp;
+ uint8 *v_p = (uint8 *)&v;
+ d[0] = v_p[0];
+ d[1] = v_p[1];
+ d[2] = v_p[2];
+ d[3] = v_p[3];
+ d[4] = v_p[4];
+ d[5] = v_p[5];
+ d[6] = v_p[6];
+ d[7] = v_p[7];
+ *(uint8 **)data_pp += sizeof(uint32);
+ *(uint8 **)data_pp += sizeof(uint32);
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_uint64_le\tInput val=0x%x", (void *)v);
+#endif
+}
+
+void Serialization::put_uint64_be(void **data_pp, uint64 v)
+{
+ uint8 *d = *(uint8 **) data_pp;
+ uint8 *v_p = (uint8 *)&v;
+ d[7] = v_p[0];
+ d[6] = v_p[1];
+ d[5] = v_p[2];
+ d[4] = v_p[3];
+ d[3] = v_p[4];
+ d[2] = v_p[5];
+ d[1] = v_p[6];
+ d[0] = v_p[7];
+ *(uint8 **)data_pp += sizeof(uint32);
+ *(uint8 **)data_pp += sizeof(uint32);
+#ifdef _SERIALIZATIONDEBUG
+ PrintF("Serialization\tput_uint64_be\tInput val=0x%x", (void *)v);
+#endif
+}
+
+void Serialization::skip_uint8(const void **data_pp)
+{
+ *(const uint8 **)data_pp += sizeof(uint8);
+}
+
+void Serialization::skip_uint16(const void **data_pp)
+{
+ *(const uint8 **)data_pp += sizeof(uint16);
+}
+
+void Serialization::skip_uint32(const void **data_pp)
+{
+ *(const uint8 **)data_pp += sizeof(uint32);
+}
+
+void Serialization::skip_block(const void **data_pp, uint32 length)
+{
+ *(const uint8 **)data_pp += length;
+}
+
+char *Serialization::skip_str(const void **data_pp)
+{
+ char *Result_p = NULL;
+ uint32 StrLength;
+
+ Result_p = *(char **)data_pp;
+ StrLength = get_uint32_le(data_pp);
+ *(char **)data_pp += StrLength;
+ return Result_p;
+}
+
+void Serialization::PrintF(const char *text, void *pVoid)
+{
+ if (NULL != logger_) {
+ logger_->log(text, pVoid);
+ }
+}
diff --git a/source/utilities/Serialization.h b/source/utilities/Serialization.h
new file mode 100644
index 0000000..7556c1b
--- /dev/null
+++ b/source/utilities/Serialization.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (C) ST-Ericsson SA 2011
+ * License terms: 3-clause BSD license
+ ******************************************************************************/
+#ifndef _SERIALIZATION_H_
+#define _SERIALIZATION_H_
+
+#include "t_basicdefinitions.h"
+#include "command_ids.h"
+#ifdef _WIN32
+#include "WinApiWrappers.h"
+#else
+#include "LinuxApiWrappers.h"
+#endif
+#include "Logger.h"
+#include "LCDriver.h"
+#include "commands_types.h"
+
+const uint32 MAX_NO_OF_DEVICES = 1024;
+
+class Serialization
+{
+public:
+ Serialization(void);
+ ~Serialization(void);
+
+ static void put_block(void **data_pp, const void *source_p, uint32 length);
+ static void put_string(void **data_pp, const void *source_p, uint32 length);
+
+ static uint8 get_uint8(const void **data_pp);
+ static uint16 get_uint16_le(const void **data_pp);
+ static uint16 get_uint16_be(const void **data_pp);
+ static uint32 get_uint32_le(const void **data_pp);
+ static uint32 get_uint32_be(const void **data_pp);
+ static uint64 get_uint64_le(const void **data_pp);
+ static void put_uint8(void **data_pp, uint8 v);
+ static void put_uint16_le(void **data_pp, uint16 v);
+ static void put_uint16_be(void **data_pp, uint16 v);
+ static void put_uint32_le(void **data_pp, uint32 v);
+ static void put_uint32_be(void **data_pp, uint32 v);
+ static void put_uint64_le(void **data_pp, uint64 v);
+ static void put_uint64_be(void **data_pp, uint64 v);
+ static void skip_uint8(const void **data_pp);
+ static void skip_uint16(const void **data_pp);
+ static void skip_uint32(const void **data_pp);
+ static void get_block(const void **data_pp, void *target_p, uint32 length);
+ static void skip_block(const void **data_pp, uint32 length);
+ static char *skip_str(const void **data_pp);
+
+ static SupportedCommand_t *get_supportedcommands(const void **data_pp, uint32 CommandsCount);
+ static ListDevice_t *get_devices(const void **data_pp, uint32 DevicesCount);
+ static DirEntry_t *get_direntries(const void **data_pp, uint32 DirectoriesCount);
+
+public:
+ void SetLogger(Logger *logger) {
+ logger_ = logger;
+ }
+private:
+ Logger *logger_;
+ void PrintF(const char *text, void *pVoid);
+};
+
+#endif // _SERIALIZATION_H_