123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767 |
- /**
- * MIT License
- *
- * Copyright (c) 2018 Infineon Technologies AG
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE
- *
- * \file
- *
- * \brief This file contains a light weight logger implementation.
- *
- * \addtogroup grLogger
- * @{
- *
- */
- #include <stdio.h>
- #include "optiga/common/Logger.h"
- #include "optiga/pal/pal_os_timer.h"
- /// @cond hidden
- /*****************************************************************************
- * Defines
- *****************************************************************************/
- //If ENABLE_UARTLOG is defined, assign UartWriteData as log writer
- #ifdef ENABLE_UARTLOG
- #include "Uart.h"
- pFWriteData pfWriter = (pFWriteData)UartWriteData;
- #else
- //The function does nothing
- static int32_t WriteData(uint32_t PdwHandle, const uint8_t* PprgbBuf, uint32_t PdwDataLen)
- {
- //lint --e{715} suppress "The parameters are not used as this is filler function"
- return 1;
- }
- pFWriteData pfWriter = (pFWriteData)WriteData;
- #endif
- /*****************************************************************************
- * Common Functions
- *****************************************************************************/
- /**
- * Convert Byte to Hex String
- *
- */
- void ConvUint8ToHexString (uint8_t* PprgbHexByteArray, uint8_t* PprgbHexString, \
- uint32_t dwNoOfBytes, uint8_t PbIsSpaceReq)
- {
- //lint --e{818} suppress "PprgbHexString is modified in function"
- uint32_t dwLoop = 0;
- uint8_t bNibble = 0, bHexByte = 0;
- do
- {
- if((NULL == PprgbHexByteArray) || (NULL == PprgbHexString))
- {
- return;
- }
- for (dwLoop = 0; dwLoop < dwNoOfBytes; dwLoop++)
- {
- bHexByte = PprgbHexByteArray[dwLoop];
- /*Convert Byte to HexString */
- bNibble = (bHexByte & 0xF0)>>4;
- if (bNibble > 0x09)
- PprgbHexString [0] = bNibble + 0x37;
- else
- PprgbHexString [0] = bNibble + 0x30;
- bNibble = bHexByte & 0x0F;
- if (bNibble > 0x09)
- PprgbHexString [1] = bNibble + 0x37;
- else
- PprgbHexString [1] = bNibble + 0x30;
- if(PbIsSpaceReq)
- {
- PprgbHexString [2] = ' ';
- PprgbHexString += 3;
- }
- else
- {
- PprgbHexString += 2;
- }
- }
- *PprgbHexString = 0x00;
- } while(0);
- }
- /**
- * Convert Uint32 to Hex String
- *
- */
- void ConvUint32ToHexString (uint32_t dwVal, uint8_t* PprgbHexString)
- {
- uint8_t rgbByteArray [5];
- do
- {
- if(NULL == PprgbHexString)
- {
- return;
- }
- rgbByteArray [0] = (uint8_t)(dwVal >> 24);
- rgbByteArray [1] = (uint8_t)((dwVal & 0x00FF0000) >> 16);
- rgbByteArray [2] = (uint8_t)((dwVal & 0x0000FF00) >> 8);
- rgbByteArray [3] = (uint8_t)((dwVal & 0x000000FF));
- ConvUint8ToHexString(rgbByteArray, PprgbHexString, 4, 0);
- } while(0);
- }
- /**
- * Convert Uint32 to Decimal String
- *
- */
- void ConvUint32ToDecString (uint32_t dwVal, uint8_t* PprgbDecStr, \
- uint8_t bExpStrLen, uint8_t bFillChar)
- {
- uint8_t rgbTempStr [12] = {0};
- uint8_t bCount;
- do
- {
- if(NULL ==PprgbDecStr)
- {
- return;
- }
- bCount = 0;
- for (;;)
- {
- rgbTempStr [bCount] = (dwVal % 10) + 0x30;
- dwVal = dwVal / 10;
- bCount++;
- if(0x00 == dwVal)
- {
- break;
- }
- }
- while(bExpStrLen > bCount)
- {
- *PprgbDecStr = bFillChar;
- PprgbDecStr++;
- bExpStrLen--;
- }
- bCount--;
- for(;;)
- {
- *PprgbDecStr = rgbTempStr[bCount];
- PprgbDecStr++;
- if(0x00 == bCount)
- {
- break;
- }
- bCount--;
- }
- *PprgbDecStr = 0x00;
- } while(0);
- }
- /*****************************************************************************
- * Static functions
- *****************************************************************************/
- #ifdef ENABLE_LOG
- /**
- * Return current system time in milliseconds as a string
- *
- */
- static void GetSystemDateTime(char_t *pszSystemTime)
- {
- uint32_t dwTimeInMilliSecs = 0;
- if(pszSystemTime == NULL)
- {
- return;
- }
- dwTimeInMilliSecs = pal_os_timer_get_time_in_milliseconds();
- ConvUint32ToDecString (dwTimeInMilliSecs, (uint8_t *)pszSystemTime, 10, '0');
- }
- /**
- * Perform packet analysis. This is specific to IFX I2C protocol
- *
- */
- static void DumpPacketAnalysis(uint8_t* prgbBuf, uint16_t wLen, bool_t fDirection)
- {
- uint16_t wOffset = 0, wFrameLength, wTemp;
- uint8_t bFctr, bPctr, bTemp, bAckNumber;
- char_t pszTemp[256];
- bool_t bControlFrame = TRUE;
- //for packet analysis there must be minimum 5 bytes
- if(wLen < 5)
- {
- return;
- }
- if(prgbBuf == NULL)
- {
- return;
- }
- //0 for send
- if(fDirection == TX_DIRECTION)
- {
- wOffset = 1;
- CONSOLE_LOGSTRINGLINE("->->->->-> Packet Analysis ->->->->->");
- }
- else
- {
- CONSOLE_LOGSTRINGLINE("<-<-<-<-<- Packet Analysis <-<-<-<-<-");
- }
- do
- {
- //frame type
- bFctr = *(prgbBuf+wOffset);
- bAckNumber = bFctr & 0x03;
- if(bFctr & 0x80)
- {
- CONSOLE_LOGSTRINGLINE("Frame type: Control frame");
- }
- else
- {
- bControlFrame = FALSE;
- CONSOLE_LOGSTRINGLINE("Frame type: Data frame");
- }
- //seq counter 0110 0000 = 0x60
- bTemp = ((bFctr & 0x60) >> 5);
- switch(bTemp)
- {
- case 0x00:
- CONSOLE_LOGSTRING("Seq Counter: Ack for ");
- ConvUint32ToDecString((uint32_t)bAckNumber,(uint8_t*)pszTemp, 0, '0');
- CONSOLE_LOGSTRINGLINE(pszTemp);
- break;
- case 0x01:
- CONSOLE_LOGSTRING("Seq Counter: Nak for ");
- ConvUint32ToDecString((uint32_t)bAckNumber,(uint8_t*)pszTemp, 0, '0');
- CONSOLE_LOGSTRINGLINE(pszTemp);
- break;
- case 0x02:
- CONSOLE_LOGSTRINGLINE("Seq Counter: Re-synch");
- break;
- default:
- CONSOLE_LOGSTRINGLINE("************************** Seq Counter: RFU ***********************");
- }
- //frame number 0000 1100 = 0x60
- bTemp = ((bFctr & 0x0C) >> 2);
- CONSOLE_LOGSTRING("Frame number: ");
- ConvUint32ToDecString((uint32_t)bTemp,(uint8_t*)pszTemp, 0, '0');
- CONSOLE_LOGSTRINGLINE(pszTemp);
- //ack number
- CONSOLE_LOGSTRING("Ack number: ");
- ConvUint32ToDecString((uint32_t)bAckNumber,(uint8_t*)pszTemp, 0, '0');
- CONSOLE_LOGSTRINGLINE(pszTemp);
- //Frame length:
- wOffset++;
- wFrameLength = ((uint16_t)*(prgbBuf + wOffset) << 8) | (uint16_t)*(prgbBuf + wOffset + 1);
- CONSOLE_LOGSTRING("Frame length: ");
- ConvUint32ToDecString((uint32_t)wFrameLength,(uint8_t*)pszTemp, 0, '0');
- CONSOLE_LOGSTRINGLINE(pszTemp);
- wOffset += 2;
- //N/w and transport info not present for control frame
- if(bControlFrame)
- {
- break;
- }
- //channel info
- bPctr = *(prgbBuf+wOffset);
- bTemp = bPctr >> 4;
- CONSOLE_LOGSTRING("Channel info: ");
- ConvUint32ToDecString((uint32_t)bTemp,(uint8_t*)pszTemp, 0, '0');
- CONSOLE_LOGSTRINGLINE(pszTemp);
- bTemp = bPctr & 0x07;
- switch(bTemp)
- {
- case 0x00:
- CONSOLE_LOGSTRINGLINE("Chaining info: Single packet");
- break;
- case 0x01:
- CONSOLE_LOGSTRINGLINE("Chaining info: First packet");
- break;
- case 0x02:
- CONSOLE_LOGSTRINGLINE("Chaining info: Intermediate packet");
- break;
- case 0x04:
- CONSOLE_LOGSTRINGLINE("Chaining info: Last packet");
- break;
- case 0x07:
- CONSOLE_LOGSTRINGLINE("********************* Chaining info: Chaining error ********************* ");
- break;
- default:
- CONSOLE_LOGSTRINGLINE("********************* Chaining info: RFU***********************");
- }
- wOffset += 1;
- //exclude till offset and checksum
- wTemp = wOffset+2;
- if(wLen > wTemp)
- {
- wTemp = wLen - wTemp;
- }
- else
- {
- // no data bytes
- break;
- }
- if(fDirection == TX_DIRECTION)
- {
- CONSOLE_LOGSTRING("Command data : ");
- }
- else
- {
- CONSOLE_LOGSTRING("Response data : ");
- }
- Util_DumpHex((prgbBuf+wOffset), wTemp);
- CONSOLE_LOGSTRINGLINE(" ");
- }while(0);
- //0 for send
- if(fDirection == TX_DIRECTION)
- {
- CONSOLE_LOGSTRINGLINE("->->->->-> Packet Analysis ->->->->->");
- }
- else
- {
- CONSOLE_LOGSTRINGLINE("<-<-<-<-<- Packet Analysis <-<-<-<-<-");
- }
- }
- #endif
- /*****************************************************************************
- * Exposed Logging APIs
- *****************************************************************************/
- /**
- * Logs a New Line
- */
- void Util_NewLine(uint32_t PdwUartPort)
- {
- uint8_t rgbcrlf [2] = {0x0D, 0x0A};
- //lint --e{534} The return value is not used*/
- pfWriter(PdwUartPort, rgbcrlf, 2);
- }
- /**
- * Logs a string with new line
- */
- void Util_LogStringLine(uint32_t PdwUartPort, const char_t *pszString)
- {
- if(pszString == NULL)
- {
- return;
- }
- //lint --e{534} The return value is not used*/
- pfWriter(PdwUartPort, (uint8_t *)pszString, strlen(pszString));
- Util_NewLine(PdwUartPort);
- }
- /**
- * Logs a string
- */
- void Util_LogString(uint32_t PdwUartPort, const char_t *PpszString)
- {
- if(PpszString == NULL)
- {
- return;
- }
- //lint --e{534} The return value is not used*/
- pfWriter(PdwUartPort, (uint8_t *)PpszString, strlen(PpszString));
- }
- #ifdef ENABLE_LOG
- /**
- * Logs a byte array
- */
- void Util_LogArray(uint8_t* prgbBuf, uint16_t wLen, bool_t fDirection, bool_t fDumpPacketAnalysis)
- {
- char_t szTemp[50];
- if(prgbBuf == NULL)
- {
- return;
- }
- memset(szTemp,0, 50);
- GetSystemDateTime(szTemp);
- //lint --e{534} The return value is not used*/
- pfWriter(CONSOLE_PORT, (uint8_t*)szTemp, strlen(szTemp));
- //lint --e{534} The return value is not used*/
- pfWriter(CONSOLE_PORT, (uint8_t*)" ", 1);
- if(fDirection == TX_DIRECTION)
- {
- //lint --e{534} The return value is not used*/
- pfWriter(CONSOLE_PORT, (uint8_t*)">> ", 4);
- }
- else
- {
- //lint --e{534} The return value is not used*/
- pfWriter(CONSOLE_PORT, (uint8_t*)"<< ", 4);
- }
- Util_DumpHex(prgbBuf, wLen);
- Util_NewLine(CONSOLE_PORT);
- if(fDumpPacketAnalysis)
- {
- DumpPacketAnalysis(prgbBuf, wLen, fDirection);
- }
- return;
- }
- #endif
- /**
- * Logs a four byte value
- */
- void Util_LogInt(uint32_t PdwUartPort, const char_t *pszMsg, uint32_t dwValue)
- {
- uint8_t rgbString [12] = {0};
- if(pszMsg == NULL)
- {
- return;
- }
- Util_LogString(PdwUartPort, pszMsg);
- Util_LogString(PdwUartPort, " 0x");
- ConvUint32ToHexString((uint32_t)dwValue, rgbString);
- Util_LogString(PdwUartPort, (char_t*)rgbString);
- Util_LogString(PdwUartPort, "(");
- ConvUint32ToDecString((uint32_t)dwValue, rgbString, 0, '0');
- Util_LogString(PdwUartPort, (char_t*)rgbString);
- Util_LogStringLine(PdwUartPort, ")");
- }
- /**
- * Logs an array in hex format
- */
- void Util_DumpHex(uint8_t* prgbBuf, uint16_t wLen)
- {
- uint16_t wIndex;
- uint8_t rgbHexString[5];
- if(prgbBuf == NULL)
- {
- return;
- }
- for(wIndex = 0; wIndex < wLen; wIndex++)
- {
- ConvUint8ToHexString ((uint8_t*)(prgbBuf+wIndex), rgbHexString, 1, 1);
- //lint --e{534} The return value is not used*/
- pfWriter(CONSOLE_PORT, rgbHexString, 3);
- }
- }
- /*****************************************************************************
- * Level based logging Exposed APIs
- *****************************************************************************/
- /// @endcond
- #ifdef ENABLE_LOG
- //This is second log writer
- pFWriteData2 pfWriter2 = NULL;
- //This is the arguement to be passed to pfWriter.It refers to the handle to writer context/structure.
- void* pHandle = NULL;
- //Stores the level of Logging
- static uint32_t dwLevelEnabler = (uint32_t)((1<<eInfo)|(1<<eWarning)|(1<<eError));
- //Store the layer type of Logging
- static uint32_t dwLayerEnabler = 0;
- /**
- * \brief This structure contains Logging information
- */
- typedef struct sLogMessage {
- ///Message to be logged
- char_t* pzStringMessage;
- ///Message Type
- eLogLayer eLogMsgLayer;
- ///Message Level
- eLogLevel eLogMsgLevel;
- }sLogMessage;
- /**
- * Sets the state of the Logging Level.
- *
- * \param[in] eLevel Logging Level
- * \param[in] eValue Set value
- */
- void Util_SetLogLevelState(eLogLevel PeLevel,eSetState PeValue)
- {
- //Validate Level
- if((eInfo <= PeLevel)&&(eError >= PeLevel))
- {
- switch(PeValue)
- {
- case eEnable:
- {
- dwLevelEnabler |= (uint32_t)(1<<PeLevel);
- break;
- }
- case eDisable:
- {
- dwLevelEnabler &= (uint32_t)(~(1<<PeLevel));
- break;
- }
- case eInvalid:
- default:
- break;
- }
- }
- }
- /**
- * Returns the current state of Logging level.
- *
- * \param[in] eLevel Logging Level
- *
- * \retval #eSetState
- */
- eSetState Util_GetLogLevelState(eLogLevel PeLevel)
- {
- //Validate Level
- if((eInfo <= PeLevel)&&(eError >= PeLevel))
- return (((dwLevelEnabler)&(1<<PeLevel))?eEnable:eDisable);
- else
- return eInvalid;
- }
- /**
- * Sets the state of the Logging Layer.
- *
- * \param[in] eLayer Logging Layer
- * \param[in] eValue Set value
- */
- void Util_SetLogLayerState(eLogLayer PeLayer,eSetState PeValue)
- {
- //Validate Layer
- if((eHS <= PeLayer)&&(eTL >= PeLayer))
- {
- switch(PeValue)
- {
- case eEnable:
- {
- dwLayerEnabler |= (uint32_t)(1<<PeLayer);
- break;
- }
- case eDisable:
- {
- dwLayerEnabler &= (uint32_t)(~(1<<PeLayer));
- break;
- }
- case eInvalid:
- default:
- break;
- }
- }
- }
- /**
- * Returns the current state of the Logging Layer.
- *
- * \param[in] eLayer Logging Level
- *
- * \retval #eSetState
- */
- eSetState Util_GetLogLayerState(eLogLayer PeLayer)
- {
- //Validate Layer
- if((eHS <= PeLayer)&&(eTL >= PeLayer))
- return (((dwLayerEnabler)&(1<<PeLayer))?eEnable:eDisable);
- else
- return eInvalid;
- }
- /**
- * Sets the Log Writer and handle.
- *
- * \param[in] pWriter function pointer to pFWriteData2
- * \param[in] pHdl Handle to writer context/structure
- *
- */
- void Util_SetLogWriter(pFWriteData2 pWriter,void* pHdl)
- {
- pfWriter2 = pWriter;
- pHandle = pHdl;
- }
- /**
- * \brief Logs a message.
- */
- static void Util_WriteMessage(sLogMessage* psLogMessage)
- {
- char_t charBuffer[103];
- char timeString[9]; // space for "HH:MM:SS\0"
- char_t* szMsgLevel[eError] = {LOGGER_LEVEL_INFO,
- LOGGER_LEVEL_WARNING,
- LOGGER_LEVEL_ERROR};
- char_t* szMsgType[eTL] = {LOGGER_TYPE_HANDSHAKE,
- LOGGER_TYPE_RECORDLAYER,
- LOGGER_TYPE_TRANSPORTLAYER};
- GetSystemDateTime(timeString);
- #ifndef WIN32
- sprintf(charBuffer,LOG_FORMAT,timeString,szMsgLevel[psLogMessage->eLogMsgLevel -1 ],
- szMsgType[psLogMessage->eLogMsgLayer -1 ],psLogMessage->pzStringMessage,"\n");
- #else
- sprintf_s(charBuffer,103,LOG_FORMAT,timeString,szMsgLevel[psLogMessage->eLogMsgLevel -1 ],
- szMsgType[psLogMessage->eLogMsgLayer -1 ],psLogMessage->pzStringMessage,"\n");
- #endif
- pfWriter2(pHandle,(uint8_t*)charBuffer,strlen(charBuffer));
- }
- /**
- * Logs a message with type and level information and content of the buffer.
- * Currently the message cannot be greater than 80 bytes.This will be upgraded in future
- *
- * \param[in] pzMsg Message to be logged
- * \param[in] eLayer Logging Layer
- * \param[in] eLevel Logging Level
- * \param[in] PrgbBuffer Pointer to the buffer to be logged
- * \param[in] wLen Length message to be logged
- *
- */
- void Util_LogMsgArray(char* pzMsg, uint8_t* PrgbBuffer, uint16_t wLen, eLogLayer eLayer, eLogLevel eLevel)
- {
- sLogMessage sLogMes;
- uint16_t wCount = wLen;
- uint8_t bBytes = 25;
- uint8_t * prgbbuf = PrgbBuffer;
- eSetState eCurrentState = Util_GetLogLevelState(eLevel);
- uint8_t rgbHexString[100];
- do
- {
- if((NULL==pHandle)||(NULL ==pfWriter2) || (eEnable != eCurrentState) || (PrgbBuffer == NULL))
- {
- break;
- }
- sLogMes.eLogMsgLevel = eLevel;
- sLogMes.eLogMsgLayer = eLayer;
- sLogMes.pzStringMessage = pzMsg;
- Util_WriteMessage(&sLogMes);
- while(wCount > 0)
- {
- if(wCount < 25)
- {
- bBytes = (uint8_t)wCount;
- }
- ConvUint8ToHexString ((uint8_t*)(prgbbuf), rgbHexString, bBytes, 1);
- pfWriter2(pHandle, rgbHexString, (bBytes*3));
- prgbbuf+= bBytes;
- wCount-=bBytes;
- }
- pfWriter2(pHandle, (uint8_t *)"\n", 1);
- }while (0);
- }
- /**
- * Logs a message with type and level information.
- * Currently the message cannot be greater than 80 bytes.This will be upgraded in future
- *
- * \param[in] pzMsg Message to be logged
- * \param[in] eLayer Logging Layer
- * \param[in] eLevel Logging Level
- *
- */
- void Util_LogMessage(char* pzMsg, eLogLayer eLayer, eLogLevel eLevel)
- {
- sLogMessage sLogMes;
- eSetState eCurrentState = Util_GetLogLevelState(eLevel);
- do
- {
- if((NULL==pHandle)||(NULL ==pfWriter2) || (eEnable != eCurrentState))
- {
- break;
- }
- sLogMes.eLogMsgLevel = eLevel;
- sLogMes.eLogMsgLayer = eLayer;
- sLogMes.pzStringMessage = pzMsg;
- Util_WriteMessage(&sLogMes);
- }while (0);
- }
- /**
- * Logs a 4 byte debug value with type and level information.
- *
- * Currently the message cannot be greater than 80 bytes.This will be upgraded in future
- * \param[in] dwDBValue 4 byte value to be logged
- * \param[in] eLayer Logging Layer
- * \param[in] eLevel Logging Level
- *
- */
- void Util_LogDebugVal(uint32_t dwDBValue, eLogLayer eLayer, eLogLevel eLevel)
- {
- uint8_t rgbString [12];
- if((NULL!=pHandle)&&(NULL !=pfWriter2))
- {
- ConvUint32ToHexString(dwDBValue, rgbString);
- Util_LogMessage((char_t*)rgbString,eLayer,eLevel);
- }
- }
- #endif //#ENABLE_LOG
- /**
- * @}
- */
|