1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: Radisys Logging Framework
23 Desc: This file contains logging framework implementation.
26 *********************************************************************21*/
27 /**********************************************************************
28 @ description: This is source file which has implementaion of logging
30 ************************************************************************/
35 #include "rl_interface.h"
38 #include <sys/socket.h>
39 #include <sys/types.h>
41 #include <sys/resource.h>
47 #include <netinet/in.h>
53 #include "rl_platform.h"
69 #include "rl_interface.h"
71 char g_fileName[MAX_FILENAME_LEN];
72 char g_logDir[MAX_FILENAME_LEN];
73 char g_fileList[RLOG_MAX_FILES][MAX_FILENAME_LEN];
74 #ifdef RLOG_USE_CIRCULAR_BUFFER
75 static THREAD_DATA *g_pSingCirBuff = NULL;
76 static uint16_t g_prevLogOffset=0;
78 #ifndef RLOG_ENABLE_TEXT_LOGGING
79 static volatile uint32_t g_rlogPositionIndex=0;
80 uint32_t gIpType = CM_IPV4ADDR_TYPE;
83 ///////////////////////////////////////////////////////////////////////////////////////////////////
84 // Default variable initilization
85 ///////////////////////////////////////////////////////////////////////////////////////////////////
87 /* global file pointer */
91 #ifndef RLOG_ENABLE_TEXT_LOGGING
93 Data *g_l2rlogBuf = NULLP;
94 Data *g_l2LogBufStartPtr = NULLP;
95 Data *g_l2LogBufBasePtr = NULLP;
96 Data *g_logBufRcvdFromL2 = NULLP;
97 Data *g_l2LogBaseBuff = NULLP;
98 uint32_t g_logBufLenRcvdFromL2 = 0;
99 uint32_t g_l2LogBufLen = 0;
100 uint32_t startL2Logging = 0;
101 uint32_t g_l2logBuffPos = 0;
103 #endif /* Binary Logging */
105 /* number of times log function is called */
108 /* Socke descriptor if remote client is connected */
109 int g_nCliSocket = 0;
111 /* Default log level Error */
115 int g_logLevel = L_MAX_LOG_LEVEL;
117 /* MAX Log Files 1 */
118 uint8_t g_nMaxLogFiles = 1;
120 /* Max File Size limit for each log file */
121 uint32_t g_uiMaxFileSizeLimit = MAX_FILE_SIZE;
123 /* Default circular buffer size 100Kb*/
124 uint32_t g_cirMaxBufferSize = RLOG_MAX_CIRBUF_SIZE;
126 /* Default mask for each module is disabled */
127 uint32_t g_modMask = 0;
128 /* Remote Logging port */
129 static uint32_t g_nLogPort = RLOG_REMOTE_LOGGING_PORT;
131 /* Current File Number index */
132 int g_nCurrFileIdx = 0;
134 /* Remote logging flag */
135 static uint8_t g_bRemoteLoggingDisabled=1;
137 /* Global file descriptor for L2 & L3 */
141 char g_l2Buf[RLOG_MAX_CIRBUF_SIZE];
143 #ifdef RLOG_USE_CIRCULAR_BUFFER
144 /* List of thread data pointers */
145 THREAD_DATA* g_pCirList[RLOG_MAX_THREADS];
147 /* Number of threads registered */
148 static int g_nThreadsRegistered;
150 /* Mutex to protect circular buffers */
151 pthread_mutex_t g_logmutex, g_condmutex;
152 pthread_cond_t g_cond;
154 uint8_t g_writeCirBuf = 0;
156 static int thread_signalled;
160 static uint32_t numTtiTicks;
161 /* Console input handling parameters */
162 static int g_kIdx, g_action, g_storeKeys;
163 static char g_keyBuf[32];
165 /* Standard C library, timezone */
167 ///////////////////////////////////////////////////////////////////////////////
168 // FUNCTION DECLARATIONS //
169 ///////////////////////////////////////////////////////////////////////////////
170 #if defined(RLOG_ENABLE_TEXT_LOGGING)
171 static struct tm* getTime(int* microseconds);
172 static void getLogTimeStr(char* ts);
175 void initGlbDataAtL2(void);
176 void createNewLogFile(void);
177 void createL2LogFile(void);
178 void* rLogServer(void* arg);
179 void closeConnection(int sockfd);
180 void storeTimeDelimeter(FILE* fp);
181 void rlCatchSegViolation(int sig);
182 void flushData(int sig);
183 void* cirBufReaderThread(void* arg);
184 void readCircularBuffers(void);
185 void userAction(void);
186 void handleSigIO(int sig);
187 void rlPrintConfiguration(void);
188 THREAD_DATA* rlRegisterThread(const char* taskName);
189 void (*rlSigHandler)(int);
191 void rlInitL2Log(void);
192 uint32_t g_rlogWriteCount = 0;
193 uint32_t g_maxRlogCount = 50;
194 uint32_t g_logsDropCnt = 0;
195 RLLogCntLmt g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
197 #ifndef RLOG_ENABLE_TEXT_LOGGING
198 void readL2LogBuff(void);
199 S16 rlValidateL2LogBuf(void);
200 void rlSetL2LogBuf(uint8_t *l2LogBuf,uint32_t l2logLen);
201 void rlResetL2LogBuf(void);
205 #ifndef RLOG_ENABLE_TEXT_LOGGING
206 EndianType getCPU_Endian(Void);
207 void storeFileHeader(FILE* fp);
208 void saveLogDataFromCpul(const void* buf, uint16_t len);
209 void saveLogData(const void* buf, uint16_t len, uint32_t g_rlogWritePosIndex);
210 void sendToPostProcessor(const void* buf, uint16_t len);
211 void getLogTimeStr(char* ts);
213 ///////////////////////////////////////////////////////////////////////////////////////////////////
214 // @param[in] modMask - bit mask for any particular module.
215 // Sets or clears bit for the particular module. If mask value is zero all bits are cleared.
216 ///////////////////////////////////////////////////////////////////////////////////////////////////
217 void rlSetModuleMask(uint32_t modMask)
219 g_modMask = (modMask == 0 ) ? 0 : (g_modMask ^ modMask);
222 ///////////////////////////////////////////////////////////////////////////////////////////////////
223 // @param[in] - maxFileSize - Maximum file size in MB.
224 // @brief This function sets the limit to log file size.
225 ///////////////////////////////////////////////////////////////////////////////////////////////////
226 void rlSetLogFileSizeLimit(uint32_t maxFileSize)
228 g_uiMaxFileSizeLimit = (maxFileSize == 0) ? MAX_FILE_SIZE : maxFileSize*1048576;
231 ///////////////////////////////////////////////////////////////////////////////////////////////////
234 ///////////////////////////////////////////////////////////////////////////////////////////////////
235 void rlSetNumOfLogFiles(uint8_t nMaxFiles)
237 if( nMaxFiles > RLOG_MAX_FILES || nMaxFiles == 0 ) {
238 g_nMaxLogFiles = RLOG_MAX_FILES;
242 g_nMaxLogFiles = nMaxFiles;
245 ///////////////////////////////////////////////////////////////////////////////////////////////////
247 // @brief 1-> enable remote logging, 0-> disable remote logging
248 ///////////////////////////////////////////////////////////////////////////////////////////////////
249 void rlSetRemoteLoggingFlag(S32 flag)
251 g_bRemoteLoggingDisabled = !flag;
254 ///////////////////////////////////////////////////////////////////////////////////////////////////
255 // @param[in] port - Server port
256 // @brief Use this API to configure port for remote logging application.
257 ///////////////////////////////////////////////////////////////////////////////////////////////////
258 void rlSetLogPort(uint32_t port)
263 ///////////////////////////////////////////////////////////////////////////////////////////////////
264 // @param[in] enable_core - 1 Enables core file generation 0 - disable
265 // This enables or disables core file generation
266 ///////////////////////////////////////////////////////////////////////////////////////////////////
267 void rlEnableDisableCore(S32 enable_core)
269 struct rlimit core_limits;
270 core_limits.rlim_cur = core_limits.rlim_max = enable_core ? RLIM_INFINITY : 0;
271 setrlimit(RLIMIT_CORE, &core_limits);
274 ///////////////////////////////////////////////////////////////////////////////////////////////////
277 ///////////////////////////////////////////////////////////////////////////////////////////////////
278 void rlSetLogPath(const char* logDir)
280 strncpy(g_logDir, logDir, MAX_FILENAME_LEN);
283 ///////////////////////////////////////////////////////////////////////////////////////////////////
286 ///////////////////////////////////////////////////////////////////////////////////////////////////
287 void rlSetLogFile(const char* fileName)
289 strncpy(g_fileName, fileName, MAX_FILENAME_LEN);
292 ///////////////////////////////////////////////////////////////////////////////////////////////////
295 ///////////////////////////////////////////////////////////////////////////////////////////////////
296 void rlSetLogLevel(R_LOG_LEVEL logLevel)
298 g_logLevel = logLevel + 1;
301 ///////////////////////////////////////////////////////////////////////////////////////////////////
302 // @param[in] bufSize - Circulaer buffer size in multiples of 1Kb or 1024 bytes.
303 // This function is called to set circular buffer size for each thread.
304 ///////////////////////////////////////////////////////////////////////////////////////////////////
305 void rlSetCircularBufferSize(uint32_t bufSize)
307 g_cirMaxBufferSize = bufSize*1024;
308 g_cirMaxBufferSize = (g_cirMaxBufferSize/50) * 50;
311 ///////////////////////////////////////////////////////////////////////////////////////////////////
314 ///////////////////////////////////////////////////////////////////////////////////////////////////
315 void rlPrintConfiguration(void)
317 fprintf(stderr, "Log File:\t\t[%s]\n", g_fileName);
318 fprintf(stderr, "Log level:\t\t[%s]\n", g_logStr[g_logLevel-1]);
320 fprintf(stderr, "Module Mask:\t\t[%ld]\n", g_modMask);
321 fprintf(stderr, "File Size Limit:\t[%ld]\n", g_uiMaxFileSizeLimit);
323 fprintf(stderr, "Module Mask:\t\t[%d]\n", g_modMask);
324 fprintf(stderr, "File Size Limit:\t[%d]\n", g_uiMaxFileSizeLimit);
326 fprintf(stderr, "Maximum Log Files:\t[%d]\n", g_nMaxLogFiles);
327 fprintf(stderr, "Time Zone:\t\t[%s]\n", tzname[0]);
329 #ifdef RLOG_ENABLE_TEXT_LOGGING
330 fprintf(stderr, "Binary Logging:\t\t[Disabled]\n");
331 fprintf(stderr, "Remote Logging:\t\t[Disabled]\n");
332 fprintf(stderr, "Console Logging:\t[%s]\n", (g_fp==stderr) ? "Enabled" : "Disabled" );
334 fprintf(stderr, "Console Logging:\t[Disabled]\n");
335 fprintf(stderr, "Binary Logging:\t\t[Enabled]\n");
336 fprintf(stderr, "Remote Logging:\t\t[%s]\n", g_bRemoteLoggingDisabled ? "Disabled" : "Enabled");
338 fprintf(stderr, "Remote Logging Port:\t[%ld]\n", g_nLogPort);
340 fprintf(stderr, "Remote Logging Port:\t[%d]\n", g_nLogPort);
342 #ifdef RLOG_USE_CIRCULAR_BUFFER
343 fprintf(stderr, "Circular Buffer:\t[Enabled]\n");
345 fprintf(stderr, "Circular BufferSize:\t[Actual:%ld][Derived:%ld]\n",
346 g_cirMaxBufferSize/1024, g_cirMaxBufferSize);
348 fprintf(stderr, "Circular BufferSize:\t[Actual:%d][Derived:%d]\n",
349 g_cirMaxBufferSize/1024, g_cirMaxBufferSize);
352 fprintf(stderr, "Circular Buffer:\t[Disabled]\n");
353 #endif /* RLOG_USE_CIRCULAR_BUFFER */
354 #endif /* RLOG_ENABLE_TEXT_LOGGING */
358 #ifdef RLOG_USE_CIRCULAR_BUFFER
360 #ifdef RLOG_USE_TTI_LOGGING
361 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
364 logLev1(L_TIME_REFERENCE, L_ALWAYS, (uint32_t)time(NULL));\
367 #define CHECK_FILE_SIZE
368 #endif /* RLOG_USE_TTI_LOGGING */
370 #else /* RLOG_USE_CIRCULAR_BUFFER */
372 #ifdef RLOG_USE_TTI_LOGGING
373 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
375 if( g_fp && ftell(g_fp) > g_uiMaxFileSizeLimit ) { \
376 createNewLogFile(); \
379 logLev1(L_TIME_REFERENCE, L_ALWAYS, (uint32_t)time(NULL));\
382 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
384 if( g_fp && ( (uint32_t)(ftell(g_fp)) > g_uiMaxFileSizeLimit) ) { \
385 createNewLogFile(); \
389 #endif /* RLOG_USE_TTI_LOGGING */
390 #endif /* RLOG_USE_CIRCULAR_BUFFER */
393 #ifdef RLOG_USE_CIRCULAR_BUFFER
395 #define CHECK_CIRFILE_SIZE if( g_fp && ftell(g_fp) > g_uiMaxFileSizeLimit ) \
398 ///////////////////////////////////////////////////////////////////////////////////////////////////
399 // @param[in] tasName - Name of registering thread / task
400 // This function registers the thread for writing logs. It creates thread specific buffers.
401 ///////////////////////////////////////////////////////////////////////////////////////////////////
402 THREAD_DATA* rlRegisterThread(const char* taskName)
404 THREAD_DATA* pThrData = (THREAD_DATA*) rlCalloc(sizeof(THREAD_DATA));
406 if( pThrData == NULL ) {
407 fprintf(stderr, "Failed to allocate memory for thread %s\n", taskName);
411 pthread_mutex_lock(&g_logmutex);
413 /* Allocate circular buffer */
414 pThrData->logBuff = (uint8_t*) rlAlloc(g_cirMaxBufferSize);
416 if( pThrData->logBuff == NULL ) {
418 fprintf(stderr, "Failed to allocate memory [%ld] for thread %s\n",g_cirMaxBufferSize, taskName);
420 fprintf(stderr, "Failed to allocate memory [%d] for thread %s\n",g_cirMaxBufferSize, taskName);
425 /* store task name */
426 strcpy(pThrData->szTaskName, taskName);
428 //rlSetThreadSpecificData(pThrData);
430 pThrData->listIndex = g_nThreadsRegistered++;
432 /* Store this pointerin global list, to access it later */
433 g_pCirList[pThrData->listIndex] = pThrData;
435 pthread_mutex_unlock(&g_logmutex);
437 #ifdef RLOG_DEBUG_MODE
439 fprintf(stderr, "rlRegisterThread: allocated CIRCULAR BUFFER of size [%ld]\n", g_cirMaxBufferSize);
441 fprintf(stderr, "rlRegisterThread: allocated CIRCULAR BUFFER of size [%d]\n", g_cirMaxBufferSize);
443 fprintf(stderr, "rlRegisterThread: Total registered threads [%d]\n", g_nThreadsRegistered);
449 ///////////////////////////////////////////////////////////////////////////////////////////////////
450 // @param[in] arg - Thread argument
451 // This thread wakes up periodically and transfer logs from thread specific buffer into file system.
452 // If buffer is going to be full, this thread is signalled asynchrounously to read buffered logs.
453 ///////////////////////////////////////////////////////////////////////////////////////////////////
454 void* cirBufReaderThread(void* arg)
456 struct timespec timeout;
459 #ifdef RLOG_DEBUG_MODE
460 fprintf(stderr, "Circular Buffer Reader thread started\n");
465 /*this thread is not active and waiting to timeout */
466 thread_signalled = 0;
468 /* set the thread timeout */
469 timeout.tv_sec = time(NULL) + RLOG_CIRBUF_READ_INTERVAL;
472 /* wait for 120 seconds time interval to read buffer */
473 retCode = pthread_cond_timedwait(&g_cond, &g_condmutex, &timeout);
475 /* this means, this thread is already active, no need to give any other signal to wake up */
476 thread_signalled = 1;
478 #ifdef RLOG_DEBUG_MODE
479 //if(retCode == 0) fprintf(stderr, "cirBufReaderThread: I am signalled to read data\n");
482 /* If someone has given signal or there is timeout */
483 if( retCode == 0 || retCode == ETIMEDOUT ){
484 readCircularBuffers();
488 readCircularBuffers();
490 #ifdef RLOG_DEBUG_MODE
491 fprintf(stderr, "System is exiting ??");
492 perror("cirBufReaderThread");
500 ///////////////////////////////////////////////////////////////////////////////////////////////////
503 ///////////////////////////////////////////////////////////////////////////////////////////////////
504 void readCircularBuffers()
506 uint32_t i, writerPos;
508 /* Check if process is L2. If L2 then return from here */
509 if (SFndProcId() == TENB_L2_PROC_ID)
515 /* Before reading circular buffers, store delimiter */
516 //storeTimeDelimeter(g_fp);
519 pthread_mutex_lock(&g_logmutex);
521 for(i=0; i < g_nThreadsRegistered; i++)
523 THREAD_DATA* pThrData = g_pCirList[i];
525 if( pThrData == NULL )
528 writerPos = pThrData->logBufLen;
530 #ifdef RLOG_DEBUG_MODE
531 //fprintf(stderr, "Thread [%ld] WritePos:[%ld] ReadPos:[%ld]\n", i+1, writerPos, pThrData->logReadPos);
534 if( pThrData->logReadPos < writerPos )
536 /* Calculate the delta data to be read from buffer */
537 int dataLen = writerPos - pThrData->logReadPos;
539 /* Write the data into file */
540 if( fwrite(pThrData->logBuff+pThrData->logReadPos,1, dataLen, g_fp) == -1 )
542 #ifdef RLOG_DEBUG_MODE
543 fprintf(stderr, "Failed to write data len %d\n", dataLen);
548 /* reset log read position to last known position */
549 pThrData->logReadPos = writerPos;
551 else if ( pThrData->logReadPos > writerPos )
553 /* Calculate the remaining data left in the buffer */
554 int dataLen = g_cirMaxBufferSize - pThrData->logReadPos;
556 /* Write from last know position till end */
557 if( fwrite(pThrData->logBuff+pThrData->logReadPos, 1, dataLen, g_fp) == -1 )
559 #ifdef RLOG_DEBUG_MODE
560 fprintf(stderr, "Failed to write data len %d\n", dataLen);
566 /* Write from 0 to len position */
567 if( fwrite(pThrData->logBuff, 1, writerPos, g_fp) == -1 )
569 #ifdef RLOG_DEBUG_MODE
570 fprintf(stderr, "Failed to write data len %d\n", dataLen);
576 /* reset log read position to last known position */
577 pThrData->logReadPos = writerPos;
581 /* unlock the mutex */
582 pthread_mutex_unlock(&g_logmutex);
584 /* after reading circular buffers also store delimiter */
585 //storeTimeDelimeter(g_fp);
594 #ifndef RLOG_ENABLE_TEXT_LOGGING
595 ///////////////////////////////////////////////////////////////////////////////////////////////////
598 ///////////////////////////////////////////////////////////////////////////////////////////////////
599 EndianType getCPU_Endian(Void)
605 c = *(unsigned char *)(&x);
607 return ( c == 0x01 ) ? little_endian : big_endian;
610 ///////////////////////////////////////////////////////////////////////////////////////////////////
613 ///////////////////////////////////////////////////////////////////////////////////////////////////
614 void storeFileHeader(FILE* fp)
618 memset(&fileHdr, 0, sizeof(FILE_HEADER));
620 fileHdr.endianType = getCPU_Endian();
621 fileHdr.dummy32 = 2818049;
622 fileHdr.END_MARKER = 0xFFFF;
623 strncpy(fileHdr.szTimeZone, tzname[0], RLOG_TIME_ZONE_LEN);
625 fileHdr.time_sec = time(NULL);
626 if( fwrite((const void*)&fileHdr, 1, sizeof(FILE_HEADER), fp) == -1 )
628 #ifdef RLOG_DEBUG_MODE
629 fprintf(stderr, "Failed to write file header\n");
636 ///////////////////////////////////////////////////////////////////////////////////////////////////
637 // @param[in] fileName - Log File Name
638 // @brief This function creates a log file. If log file name is stdout & text logging is enabled,
639 // file pointer is initialized to standard output. This function also creates thread on which
640 // remote application can connect & receive binary logs. If circular buffer is enabled, it creates
641 // thread key, which is used to store & retrieve thread specific buffers and data.
642 ///////////////////////////////////////////////////////////////////////////////////////////////////
643 void rlInitLog(uint8_t type)
646 /* Initilize the signal handler */
647 rlSigHandler = &rlCatchSegViolation;
649 signal(SIGSEGV, rlCatchSegViolation);
650 signal(SIGBUS, rlCatchSegViolation);
651 signal(SIGINT, flushData);
653 /* set rate limit count for L3 Logs */
654 g_maxRlogCount = RLOG_LIMIT_L3_COUNT;
656 #ifdef RLOG_DEBUG_MODE
657 rlPrintConfiguration();
658 #endif /* RLOG_DEBUG_MODE */
660 #if RLOG_ALLOW_CONSOLE_LOGS
661 if( !strcmp(g_fileName, "stdout")) {
667 #ifndef RLOG_ENABLE_TEXT_LOGGING
669 printf("\n IP Type before reader thread spawn [%d]\n",type);
670 /* Allocate circular buffer */
673 if( pthread_create(&tid, NULL, &rLogServer, NULL) != 0 ) {
674 fprintf(stderr, "Failed to initialize log server thread\n");
679 rlInitPlatformSpecific();
681 #ifdef RLOG_USE_CIRCULAR_BUFFER
684 pthread_mutex_init(&g_logmutex, NULL);
685 if( pthread_create(&tid, NULL, &cirBufReaderThread, NULL) != 0 ) {
686 fprintf(stderr, "Failed to initialize log server thread\n");
689 /* Initialize single circular buffer for all threads */
690 g_pSingCirBuff = rlRegisterThread("DUMMY");
700 //////////////////////////////////////////////////////////////////////////
701 // @Function : rlInitL2Log
702 // @Discription : This will be trigigered from cl init function to
703 // allocate buffer from shared memory and to intialize
707 //////////////////////////////////////////////////////////////////////////
708 void rlInitL2Log(void)
711 /* set rate limit count for L3 Logs */
712 g_maxRlogCount = RLOG_LIMIT_L2_COUNT;
714 #ifndef RLOG_ENABLE_TEXT_LOGGING
715 /* Initialise memory to write logs in L2. This is soc specific
716 function present in soc file. */
717 rlInitL2SocSpecific();
721 /* This is used to initialize global variable at L2 */
725 #endif /* Binary Logging */
729 #ifndef RLOG_ENABLE_TEXT_LOGGING
730 ///////////////////////////////////////////////////////////////////////////////////////////////////
731 // @param[in] arg - Input thread argument - IP Address type.
732 // @brief This is log server thread which listens on configred port. This allows user to connect to
733 // log server and view log data live.
734 ///////////////////////////////////////////////////////////////////////////////////////////////////
735 void* rLogServer(void* arg)
737 CmInetCmnSockAddr serv_addr;
738 CmInetCmnSockAddr cli_addr;
742 int domain = AF_INET;
743 memset(&serv_addr, 0, sizeof(serv_addr));
746 if(gIpType == CM_IPV4ADDR_TYPE)
749 printf("Initializing RLOG for IPV4- %ld\n",gIpType);
751 printf("Initializing RLOG for IPV4- %d\n",gIpType);
753 clilen = serv_addr.len = sizeof(struct sockaddr_in);
755 serv_addr.type = CM_IPV4ADDR_TYPE;
756 serv_addr.u.addr.sin_family = AF_INET;
757 serv_addr.u.addr.sin_addr.s_addr = INADDR_ANY;
758 serv_addr.u.addr.sin_port = htons(g_nLogPort);
763 printf("Initializing RLOG for IPV6 - %ld\n",gIpType);
765 printf("Initializing RLOG for IPV6 - %d\n",gIpType);
767 #ifdef IPV6_SUPPORTED
768 if(gIpType == CM_IPV6ADDR_TYPE)
770 clilen = serv_addr.len = sizeof(struct sockaddr_in6);
772 serv_addr.type = CM_IPV6ADDR_TYPE;
773 serv_addr.u.addr6.sin6_family = AF_INET6;
774 serv_addr.u.addr6.sin6_addr = in6addr_any;
775 serv_addr.u.addr6.sin6_port = htons(g_nLogPort);
779 if( (sockfd = socket(domain, SOCK_STREAM, 0)) < 0 ) {
780 fprintf(stderr, "RLOG: Failed to create socket\n");
784 if( bind(sockfd, (struct sockaddr*)&(serv_addr.u),serv_addr.len) < 0 ) {
785 fprintf(stderr, "RLOG: Error in Binding\n");
794 newsockfd = accept(sockfd, (struct sockaddr*)&(cli_addr.u), (socklen_t *) &clilen);
795 if( newsockfd < 0 ) {
796 fprintf(stderr, "RLOG: Error on accept\n");
801 /* If remote logging is disabled or there is already 1 client connected */
802 if( g_bRemoteLoggingDisabled || g_nCliSocket ) {
803 /* close the new connection and proceed */
804 closeConnection(newsockfd);
808 g_nCliSocket = newsockfd;
814 ///////////////////////////////////////////////////////////////////////////////////////////////////
817 ///////////////////////////////////////////////////////////////////////////////////////////////////
818 void closeConnection(int sockfd)
820 shutdown(sockfd, SHUT_RDWR);
826 ///////////////////////////////////////////////////////////////////////////////////////////////////
829 ///////////////////////////////////////////////////////////////////////////////////////////////////
830 void handleSigIO(int sig)
834 if( read(0, &ch, 1) <= 0 )
837 rlHandleConInput(ch);
840 ///////////////////////////////////////////////////////////////////////////////////////////////////
843 ///////////////////////////////////////////////////////////////////////////////////////////////////
844 int rlHandleConInput(char ch)
846 if( ch == RLOG_CTRL_L ) {
848 g_action = RLOG_SET_LOGLEVEL;
849 fprintf(stderr, "\nEnter new log level:");
853 if( ch == RLOG_CTRL_Y ) {
855 g_action = RLOG_SET_MODMASK;
856 fprintf(stderr, "\nEnter module number:");
860 if( ch == RLOG_ENTER_KEY && g_action ) {
861 g_keyBuf[g_kIdx] = '\0';
867 g_keyBuf[g_kIdx] = ch;
874 ///////////////////////////////////////////////////////////////////////////////////////////////////
877 ///////////////////////////////////////////////////////////////////////////////////////////////////
880 unsigned int val = atol(g_keyBuf);
884 case RLOG_SET_LOGLEVEL:
886 if( val >= L_MAX_LOG_LEVEL )
887 fprintf(stderr, "Invalid log level\n");
892 rlSetLogLevel((R_LOG_LEVEL)val);
893 fprintf(stderr, "New Log level is %s\n", g_logStr[val]);
896 fprintf(stderr, "Log level below L_ERROR is not allowed\n");
901 case RLOG_SET_MODMASK:
903 rlSetModuleMask(val);
904 fprintf(stderr, "Toggled log mask %d\n", val);
914 ///////////////////////////////////////////////////////////////////////////////////////////////////
917 ///////////////////////////////////////////////////////////////////////////////////////////////////
918 void rlCatchSegViolation(int sig)
920 int i, nStrLen, nDepth;
922 void *stackTraceBuf[RLOG_MAX_STACK_DEPTH];
923 const char* sFileNames[RLOG_MAX_STACK_DEPTH];
924 const char* sFunctions[RLOG_MAX_STACK_DEPTH];
926 char **strings; char buf[RLOG_MAX_STACK_DEPTH*128]={0};
927 #ifdef T2K_MEM_LEAK_DBG
928 DumpT2kMemLeakInfoToFile();
930 #ifdef SSI_STATIC_MEM_LEAK_DETECTION
931 DumpStaticMemLeakFiles();
934 nDepth = backtrace(stackTraceBuf, RLOG_MAX_STACK_DEPTH);
937 strings = (char**) backtrace_symbols(stackTraceBuf, nDepth);
939 for(i = 0, nStrLen=0; i < nDepth; i++)
941 sFunctions[i] = (strings[i]);
942 sFileNames[i] = "unknown file";
944 #ifndef RLOG_ENABLE_TEXT_LOGGING
945 logLevS(L_SIGSEGV, L_FATAL, strings[i]);
947 printf("BT[%d] : len [%ld]: %s\n",i, (PTR)strlen(sFunctions[i]),strings[i]);
948 sprintf(buf+nStrLen, " in Function %s (from %s)\n", sFunctions[i], sFileNames[i]);
949 nStrLen += strlen(sFunctions[i]) + strlen(sFileNames[i]) + 15;
952 #ifdef RLOG_ENABLE_TEXT_LOGGING
953 logLevS(g_logStr[L_FATAL], "RLOG", "NULL", 0, FMTSTR RLOG_SEGFAULT_STR, buf);
956 logLevS(L_SIGSEGV, L_FATAL, buf);
962 ///////////////////////////////////////////////////////////////////////////////////////////////////
965 ///////////////////////////////////////////////////////////////////////////////////////////////////
966 void flushData(int sig)
968 #ifdef RLOG_USE_CIRCULAR_BUFFER
969 readCircularBuffers();
971 g_rlogWriteCount = 0;
977 signal(sig, SIG_DFL);
988 ///////////////////////////////////////////////////////////////////////////////////////////////////
991 ///////////////////////////////////////////////////////////////////////////////////////////////////
993 #ifdef RLOG_ENABLE_TEXT_LOGGING
995 #define TIME_PARAMS tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900,tm->tm_hour, tm->tm_min,tm->tm_sec,microseconds
997 ///////////////////////////////////////////////////////////////////////////////////////////////////
1000 ///////////////////////////////////////////////////////////////////////////////////////////////////
1001 void logLevS(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR str, ...)
1005 struct tm* tm = getTime(µseconds);
1006 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, str);
1011 ///////////////////////////////////////////////////////////////////////////////////////////////////
1014 ///////////////////////////////////////////////////////////////////////////////////////////////////
1015 void logLevH(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR hexdump, int hexlen, ...)
1018 char szHex[MAX_LOG_BUF_SIZE*3];
1020 struct tm* tm = getTime(µseconds);
1021 hextostr(szHex, hexdump, hexlen);
1022 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, szHex);
1027 ///////////////////////////////////////////////////////////////////////////////////////////////////
1030 ///////////////////////////////////////////////////////////////////////////////////////////////////
1031 void logLevE(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, R_SPL_ARG splType,
1032 uint32_t splVal, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, ...)
1036 struct tm* tm = getTime(µseconds);
1037 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, g_splStr[splType], splVal,
1038 arg1, arg2, arg3, arg4);
1042 ///////////////////////////////////////////////////////////////////////////////////////////////////
1045 ///////////////////////////////////////////////////////////////////////////////////////////////////
1046 void logLev0(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, ...)
1050 struct tm* tm = getTime(µseconds);
1051 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel);
1056 ///////////////////////////////////////////////////////////////////////////////////////////////////
1059 ///////////////////////////////////////////////////////////////////////////////////////////////////
1060 void logLev1(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, uint32_t arg1, ...)
1064 struct tm* tm = getTime(µseconds);
1065 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1);
1070 ///////////////////////////////////////////////////////////////////////////////////////////////////
1073 ///////////////////////////////////////////////////////////////////////////////////////////////////
1074 void logLev2(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, uint32_t arg1, uint32_t arg2, ...)
1078 struct tm* tm = getTime(µseconds);
1079 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2);
1084 ///////////////////////////////////////////////////////////////////////////////////////////////////
1087 ///////////////////////////////////////////////////////////////////////////////////////////////////
1088 void logLev3(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr,
1089 uint32_t arg1, uint32_t arg2, uint32_t arg3, ...)
1093 struct tm* tm = getTime(µseconds);
1094 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2, arg3);
1099 ///////////////////////////////////////////////////////////////////////////////////////////////////
1102 ///////////////////////////////////////////////////////////////////////////////////////////////////
1103 void logLev4(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr,
1104 uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, ...)
1108 struct tm* tm = getTime(µseconds);
1109 if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2, arg3, arg4);
1114 ///////////////////////////////////////////////////////////////////////////////////////////////////
1117 ///////////////////////////////////////////////////////////////////////////////////////////////////
1118 void logLevN(int logLevel, const char* modName, const char* file, int lineno, const char* fmtStr, ...)
1121 char szTime[RLOG_MAX_TIME_STAMP];
1122 char szLog1[MAX_LOG_LEN], szLog2[MAX_LOG_LEN];
1124 getLogTimeStr(szTime);
1125 snprintf(szLog1, MAX_LOG_LEN, "[%s][%s]%s:%d\n%s:", szTime, modName, file, lineno, g_logStr[logLevel]);
1127 va_start(argList,fmtStr);
1128 vsnprintf(szLog2, MAX_LOG_LEN, fmtStr, argList);
1131 fprintf(g_fp, "%s%s",szLog1, szLog2);
1135 #else /* BINARY LOGGING */
1137 #define RLOG_SAVE_TIME(_logTime) _logTime.ms_tti=numTtiTicks;
1139 void saveLogDataFromCpul(const void* buf, uint16_t len)
1141 #ifdef RLOG_USE_CIRCULAR_BUFFER
1142 THREAD_DATA* p = (THREAD_DATA*) g_pSingCirBuff;
1144 if( (p->logBufLen+len) > g_cirMaxBufferSize )
1146 S32 tempLen = g_cirMaxBufferSize - p->logBufLen;
1147 S32 remlen = len-tempLen;
1148 if ((tempLen < 0) || (remlen < 0))
1154 g_rlogPositionIndex = 0;
1155 g_prevLogOffset = 0;
1159 g_rlogPositionIndex = remlen/50;
1162 /* we are unlikely to hit this condition, but to prevent corruption of binary logs */
1163 /* we cannot write the data, if we write, data will be corrected forever */
1164 if( remlen > p->logReadPos )
1166 fprintf(stderr, "cannot write data.retune buffer parameters\n");
1169 if( (p->logReadPos - remlen) < RLOG_READ_POS_THRESHOLD && !thread_signalled )
1171 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1175 /* Copy data till end of the buffer */
1176 memcpy(p->logBuff+p->logBufLen, buf, tempLen);
1177 /* Copy remaining data from the start of buffer */
1178 memcpy(p->logBuff, ((const uint8_t *)buf)+tempLen, remlen);
1179 /* Store buffer length position */
1180 p->logBufLen = len-tempLen;
1184 /* if reader is far behind and writer is reaching reader position, diff < 5Kb */
1185 /* its time to wakeup thread if reader has not read much of data */
1186 if( p->logReadPos > p->logBufLen && (p->logReadPos - p->logBufLen) < RLOG_READ_POS_THRESHOLD && !thread_signalled )
1187 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1189 g_rlogPositionIndex += (len/50);
1190 memcpy(p->logBuff+p->logBufLen, buf, len);
1191 p->logBufLen += len;
1194 /* Directly write received buffer in cpuh log file */
1195 if( fwrite((const void*)buf, 1, len, g_fp) == -1 )
1197 #ifdef RLOG_DEBUG_MODE
1198 fprintf(stderr, "Failed to write log data in file\n");
1207 void saveLogData(const void* buf, uint16_t len, uint32_t g_rlogWritePosIndex)
1210 ++g_rlogWriteCount ;
1212 if((1 == g_writeCirBuf) ||
1213 ((g_rlLogCntLimit == RL_LOG_COUNT_LIMIT_START) &&
1214 (g_rlogWriteCount > g_maxRlogCount)) ||
1215 (len > RLOG_FIXED_LENGTH_BUFFER_SIZE))
1217 g_rlogPositionIndex --;
1222 /* check for if L2 is going to store logs */
1223 if (SFndProcId() == TENB_L2_PROC_ID)
1225 if((g_l2LogBufLen + RLOG_FIXED_LENGTH_BUFFER_SIZE) < L2LOG_BUFF_BLOCK_SIZE - sizeof(g_l2LogBufLen) )
1227 /* copying logs in shared buffer */
1228 memcpy(g_l2LogBufStartPtr, buf, len);
1230 g_l2LogBufStartPtr += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1231 /* increasing total log length with L2 log length */
1232 g_l2LogBufLen += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1236 #ifdef RLOG_USE_CIRCULAR_BUFFER
1237 uint32_t logWritePointerPosition;
1238 THREAD_DATA* p = (THREAD_DATA*) g_pSingCirBuff;
1240 /* if buffer is about to full, write till end and continue writing from begining */
1241 if( ((g_rlogWritePosIndex+1) * RLOG_FIXED_LENGTH_BUFFER_SIZE) > g_cirMaxBufferSize )
1243 /* setting this flag to 1 to avoid other threads
1244 to write in same circular buffer */
1246 /* Start globalPositionIndex again */
1247 g_rlogPositionIndex = 0;
1249 /* if reader has not read initial data, minmum buffer size should be 100Kb */
1250 if( p->logReadPos < RLOG_READ_POS_THRESHOLD && !thread_signalled ) {
1251 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1254 /* we are unlikely to hit this condition, but to prevent corruption of binary logs */
1255 /* we cannot write the data, if we write, data will be corrected forever */
1256 if( RLOG_FIXED_LENGTH_BUFFER_SIZE > p->logReadPos ) {
1257 fprintf(stderr, "cannot write data.retune buffer parameters\n");
1261 /* Copy data from the start of buffer */
1262 memcpy(p->logBuff, buf, len);
1263 /* Store buffer length position */
1264 p->logBufLen = RLOG_FIXED_LENGTH_BUFFER_SIZE;
1265 g_prevLogOffset = 0;
1266 /* setting this flag to 0 so that other threads
1267 will start writing in circular buffer */
1272 /* if reader is far behind and writer is reaching reader position, diff < 5Kb */
1273 /* its time to wakeup thread if reader has not read much of data */
1274 if( p->logReadPos > p->logBufLen && (p->logReadPos - p->logBufLen) < RLOG_READ_POS_THRESHOLD )
1275 pthread_cond_signal(&g_cond); /* this will wakeup thread */
1277 logWritePointerPosition = (g_rlogWritePosIndex * RLOG_FIXED_LENGTH_BUFFER_SIZE) + g_prevLogOffset;
1279 memcpy(p->logBuff+logWritePointerPosition, buf, len);
1280 p->logBufLen += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1282 #else /* !RLOG_USE_CIRCULAR_BUFFER */
1283 if( fwrite((const void*)buf, 1, RLOG_FIXED_LENGTH_BUFFER_SIZE, g_fp) == -1 )
1285 #ifdef RLOG_DEBUG_MODE
1286 fprintf(stderr, "Failed to write log data in file\n");
1291 #endif /* RLOG_USE_CIRCULAR_BUFFER */
1295 /* If post processor connected send logs */
1296 if( g_nCliSocket && send(g_nCliSocket, buf, RLOG_FIXED_LENGTH_BUFFER_SIZE, 0 ) == -1 ) {
1297 closeConnection(g_nCliSocket);
1301 #ifdef RLOG_DEBUG_MODE_2
1303 static int maxlen = 0;
1306 fprintf(stderr, "MAX BUFFER SIZE is binary mode is [%d]\n", maxlen);
1313 void sendToPostProcessor(const void* buf, uint16_t len)
1315 if( send(g_nCliSocket, buf, len, 0 ) == -1 ) {
1316 perror("ERROR Sending");
1317 closeConnection(g_nCliSocket);
1321 void logLevS( LOGID logId, R_LOG_LEVEL logLevel, const char* str, ...)
1323 ARGDATA arg; uint16_t bufsize;
1326 RLOG_SAVE_TIME(arg.logData.logTime);
1328 arg.logData.logId = logId;
1329 arg.logData.argType = LOG_ARG_STR;
1330 arg.logData.logLevel = logLevel;
1331 arg.logData.numOfArgs = 1;
1332 arg.logData.len = strlen(str);
1334 memcpy(arg.buf, (const void*)str, arg.logData.len);
1335 bufsize = sizeof(LOGDATA)+arg.logData.len;
1337 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1340 void logLevH( LOGID logId, R_LOG_LEVEL logLevel, PSTR hex, int hexlen, ...)
1345 RLOG_SAVE_TIME(arg.logData.logTime);
1347 arg.logData.logId = logId;
1348 arg.logData.argType = LOG_ARG_HEX;
1349 arg.logData.logLevel = logLevel;
1350 arg.logData.numOfArgs = 1;
1351 arg.logData.len = hexlen;
1353 memcpy(arg.buf, (const void*)hex, hexlen);
1354 bufsize = sizeof(LOGDATA)+arg.logData.len;
1356 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1358 void logLevE(LOGID logId, R_LOG_LEVEL logLevel, R_SPL_ARG splType, uint32_t splVal, uint32_t arg1, uint32_t arg2,
1359 uint32_t arg3, uint32_t arg4, ...)
1364 RLOG_SAVE_TIME(arg.logData.logTime);
1366 arg.logData.logId = logId;
1367 arg.logData.argType = LOG_ARG_SPL;
1368 arg.logData.logLevel = logLevel;
1370 arg.logData.numOfArgs = (arg2 == 0 ) ? 1 : (arg3==0 ? 2 : (arg4==0 ? 3 : 4));
1372 arg.logData.numOfArgs = 0;
1375 arg.logData.len = sizeof(u_int8_t) + sizeof(uint32_t) + (sizeof(uint32_t)*arg.logData.numOfArgs);
1377 arg.splEnum = splType;
1378 arg.splArg = splVal;
1384 bufsize = sizeof(LOGDATA)+arg.logData.len;
1386 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1389 void logLev0( LOGID logId, R_LOG_LEVEL logLevel, ...)
1394 RLOG_SAVE_TIME(arg.logData.logTime);
1396 arg.logData.logId = logId;
1397 arg.logData.argType = LOG_ARG_STR;
1398 arg.logData.logLevel = logLevel;
1399 arg.logData.numOfArgs = 0;
1400 arg.logData.len = 0;
1402 saveLogData((const void*)&arg, sizeof(LOGDATA),g_rlogPositionIndex++);
1405 void logLev1( LOGID logId, R_LOG_LEVEL logLevel, uint32_t arg1, ...)
1410 RLOG_SAVE_TIME(arg.logData.logTime);
1412 arg.logData.logId = logId;
1413 arg.logData.argType = LOG_ARG_INT;
1414 arg.logData.logLevel = logLevel;
1415 arg.logData.numOfArgs = 1;
1416 arg.logData.len = sizeof(uint32_t);
1419 bufsize = sizeof(LOGDATA)+arg.logData.len;
1421 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1423 void logLev2( LOGID logId, R_LOG_LEVEL logLevel, uint32_t arg1, uint32_t arg2, ...)
1428 RLOG_SAVE_TIME(arg.logData.logTime);
1430 arg.logData.logId = logId;
1431 arg.logData.argType = LOG_ARG_INT;
1432 arg.logData.logLevel = logLevel;
1433 arg.logData.numOfArgs = 2;
1434 arg.logData.len = 2 * sizeof(uint32_t);
1439 bufsize = sizeof(LOGDATA)+arg.logData.len;
1441 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1443 void logLev3( LOGID logId, R_LOG_LEVEL logLevel, uint32_t arg1, uint32_t arg2, uint32_t arg3, ...)
1448 RLOG_SAVE_TIME(arg.logData.logTime);
1450 arg.logData.logId = logId;
1451 arg.logData.argType = LOG_ARG_INT;
1452 arg.logData.logLevel = logLevel;
1453 arg.logData.numOfArgs = 3;
1454 arg.logData.len = 3 * sizeof(uint32_t);
1460 bufsize = sizeof(LOGDATA)+arg.logData.len;
1462 saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);
1464 void logLev4( LOGID logId, R_LOG_LEVEL logLevel, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, ...)
1468 RLOG_SAVE_TIME(arg.logData.logTime);
1470 arg.logData.logId = logId;
1471 arg.logData.argType = LOG_ARG_INT;
1472 arg.logData.logLevel = logLevel;
1473 arg.logData.numOfArgs = 4;
1474 arg.logData.len = 4 * sizeof(uint32_t);
1481 saveLogData((const void*)&arg, sizeof(ARG4DATA),g_rlogPositionIndex++);
1484 #endif /* BINARY LOGGING */
1486 #if defined(RLOG_ENABLE_TEXT_LOGGING)
1487 struct tm* getTime(int* microseconds)
1490 struct timespec ptime;
1492 struct timeval ptime;
1496 clock_gettime(CLOCK_REALTIME, &ptime);
1497 *microseconds = ptime.tv_nsec / 1000;
1499 gettimeofday(&ptime, NULL);
1500 *microseconds = ptime.tv_usec;
1503 /* Obtain the time of day, and convert it to a tm struct. --*/
1504 return localtime (&ptime.tv_sec);
1506 #elif !defined(RLOG_USE_TTI_LOGGING)
1507 static void getLogTime(LOGTIME* logTime)
1510 struct timespec ptime;
1512 struct timeval ptime;
1516 clock_gettime(CLOCK_REALTIME, &ptime);
1517 logTime->ms_tti = ptime.tv_nsec / 1000;
1519 gettimeofday(&ptime, NULL);
1520 logTime->ms_tti = ptime.tv_usec/1000;
1523 logTime->tv_sec = ptime.tv_sec;
1528 void getLogTimeStr(char* ts)
1531 struct timespec ptime;
1533 struct timeval ptime;
1539 clock_gettime(CLOCK_REALTIME, &ptime);
1540 microseconds = ptime.tv_nsec / 1000;
1542 gettimeofday(&ptime, NULL);
1543 microseconds = ptime.tv_usec/1000;
1546 /* Obtain the time of day, and convert it to a tm struct. --*/
1547 tm = localtime (&ptime.tv_sec);
1549 if (tm) sprintf(ts,"%d_%d_%d_%d_%d_%d.%03d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
1550 tm->tm_hour, tm->tm_min,tm->tm_sec,microseconds);
1552 ///////////////////////////////////////////////////////////////////////////////////////////////////
1555 ///////////////////////////////////////////////////////////////////////////////////////////////////
1557 void rlEnaBleBufferedIO(void)
1559 setvbuf (g_fp, NULL, _IOFBF, 1024 );
1562 void createNewLogFile()
1564 FILE *fp, *prev_fp = g_fp;
1565 char curTime[RLOG_MAX_TIME_STAMP]; int fd;
1567 /* Fix for CR ccpu00143040 */
1570 /* get current time, when file is created */
1571 getLogTimeStr(curTime);
1572 temptr = strchr(curTime, '.');
1573 if (temptr != NULLP)
1577 /* Fix for CR ccpu00143040 */
1578 dir = opendir(g_logDir);
1581 mkdir(g_logDir, O_RDWR);
1587 /* remove old file from system */
1588 if( g_fileList[g_nCurrFileIdx][0] != '\0' )
1589 unlink(g_fileList[g_nCurrFileIdx]);
1591 #ifdef RLOG_ENABLE_TEXT_LOGGING
1592 /* create file name, Example-> dbglog_2013_08_11_15_30_00 */
1593 snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.txt",g_logDir, g_fileName, curTime );
1594 fp = fopen(g_fileList[g_nCurrFileIdx], "w+");
1596 snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.bin",g_logDir, g_fileName, curTime );
1597 fp = fopen(g_fileList[g_nCurrFileIdx], "ab+");
1601 fprintf(stderr, "Failed to open log file %s\n", g_fileList[g_nCurrFileIdx]);
1610 if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1611 fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1614 #ifdef RLOG_ENABLE_TEXT_LOGGING
1615 setvbuf ( fp , NULL, _IOLBF, 1024 );
1617 setvbuf ( fp , NULL, _IONBF, 1024 );
1620 #ifndef RLOG_ENABLE_TEXT_LOGGING
1621 storeFileHeader(fp);
1624 if( prev_fp != NULL )
1627 if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1630 #ifndef RLOG_ENABLE_TEXT_LOGGING
1631 #ifdef RLOG_USE_TTI_LOGGING
1632 logLev1(L_TIME_REFERENCE, L_ALWAYS, (uint32_t)time(NULL));
1637 void createL2LogFile()
1639 FILE *fp, *prev_fp = g_fp;
1641 char file[MAX_FILENAME_LEN];
1643 strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1644 strncpy(g_fileName, "dbglog_l2", MAX_FILENAME_LEN);
1645 snprintf(file, sizeof(file), "%s/%s.txt", g_logDir, g_fileName);
1647 fp = fopen(file, "w+");
1649 printf("Failed to open file %s", file);
1653 printf("Created L2 bin file FD=%s\n", g_fileName);
1655 setvbuf (fp , NULL, _IONBF, 1024 );
1662 if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1663 fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1666 setvbuf ( fp , NULL, _IOLBF, 1024 );
1668 if( prev_fp != NULL )
1671 if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1677 //////////////////////////////////////////////////////////////////////////
1678 // @Function : rlUdateRlogTti
1679 // @Discription : This function will be called every 10 ms whenever
1680 // application layer update the tti count
1683 //////////////////////////////////////////////////////////////////////////
1684 void rlUpdateRlogTti(Void)
1686 #ifndef RLOG_ENABLE_TEXT_LOGGING
1687 #ifdef RLOG_USE_TTI_LOGGING
1688 logLev1(L_TIME_TTI_UPDT, L_ALWAYS, (uint32_t)time(NULL));
1693 /* This function processes log buffer received from L2
1694 mBuf is Received from L2 through SPstTsk. This function
1695 extracts buffer pointer and logLen and then these logs
1696 written to L3 log buffer/file.
1697 This function is called in application layer when EVTL2LOGBUF
1698 event is recieved from ssi
1702 Void rlProcessLogBufFromL2
1707 Void rlProcessLogBufFromL2(mBuf)
1711 #ifndef RLOG_ENABLE_TEXT_LOGGING
1717 printf("NULL MBUF received \n");
1720 /* Get Buffer pointer and length. This is SOC specific function which
1721 will extract Log-Buffer pointer and length from mBuf */
1722 rlGetL2LogBufPtr(mBuf, &logLength,&logPtr);
1723 rlSetL2LogBuf(logPtr,logLength);
1729 /* This function will get tick from RLC/CL and will process logs
1730 according to tick threshold. Tick threshold is SOC specific */
1731 Void rlProcessTicks(void)
1733 static uint32_t rlogTickCount;
1735 if(++rlogTickCount >= RLOGTICKSCNTTOPRCL2LOGS)
1738 rlResetLogRateLmt(); /* Resetting rlog write count to 0 */
1740 /* Tick count reached configured ticks to send L2 logs,
1741 Send existing log buffer to Application and create
1742 new log buffer to write logs */
1743 if (SFndProcId() == TENB_L2_PROC_ID)
1745 #ifndef RLOG_ENABLE_TEXT_LOGGING
1746 processL2LogBuff(); /* This processing of log buffer is done on L2 only
1747 This is SOC specific function and use to send
1748 log buffers to L3 and reset buffer pointer to
1751 /* Write functions specific to Text logging in cpul */
1756 /* L3 specific functions */
1762 #ifndef RLOG_ENABLE_TEXT_LOGGING
1763 //////////////////////////////////////////////////////////////////////////
1764 // @Function : readL2LogBuff
1765 // @Description : This function first validates received Log Buffer and
1766 // length from L2 and then writes L2 log buffer into L3
1767 // circular buffer. After reading it invalidates cache and
1768 // also resets global Log buffer pointer and lenth variable.
1771 //////////////////////////////////////////////////////////////////////////
1773 Void readL2LogBuff(void)
1775 /* Validate global buffer pointer and length */
1777 ret = rlValidateL2LogBuf();
1780 printf(" Validation failed for log buffer/len \n");
1784 saveLogDataFromCpul(g_logBufRcvdFromL2 , g_logBufLenRcvdFromL2 );
1785 /* TODO: Write SOC Specific function to invalidate cache */
1786 rlInvalidateL2LogsInCache(g_logBufRcvdFromL2 - sizeof(g_logBufLenRcvdFromL2) , (g_logBufLenRcvdFromL2 + sizeof(g_logBufLenRcvdFromL2)));
1792 //////////////////////////////////////////////////////////////////////////
1793 // @Function : rlStopLogCountLimit
1794 // @Description : This function validates L2 Log buffer,length, and start
1798 //////////////////////////////////////////////////////////////////////////
1801 S16 rlValidateL2LogBuf(void)
1803 S16 rlValidateL2LogBuf(void)
1807 if(g_logBufRcvdFromL2 == NULL)
1809 printf("Log-Buffer received from L2 is NULL \n");
1812 if(g_logBufLenRcvdFromL2 == 0)
1814 printf("Log-Buffer Length received from L2 is 0 \n");
1817 if(startL2Logging == 0)
1819 printf("startL2Logging flag is still inactive \n");
1826 //////////////////////////////////////////////////////////////////////////
1827 // @Function : rlStopLogCountLimit
1828 // @Description : This function set global log Buffer pointer & length
1829 // @in : l2LogBuf - Log Buffer to be set in global pointer
1830 // l2LogLen - Log length to be set in global lenth
1832 //////////////////////////////////////////////////////////////////////////
1841 void rlSetL2LogBuf(l2LogBuf,l2logLen)
1846 g_logBufRcvdFromL2 = l2LogBuf;
1847 g_logBufLenRcvdFromL2 = l2logLen;
1850 //////////////////////////////////////////////////////////////////////////
1851 // @Function : rlStopLogCountLimit
1852 // @Description : This function flushes global log Buffer pointer & length
1855 //////////////////////////////////////////////////////////////////////////
1858 void rlResetL2LogBuf
1863 void rlResetL2LogBuf(void)
1866 g_logBufRcvdFromL2 = NULL;
1867 g_logBufLenRcvdFromL2 = 0;
1872 //////////////////////////////////////////////////////////////////////////
1873 // @Function : rlStartLogCountLimit
1874 // @Discription : This function will be called by EnbApp after Cell is UP.
1875 // This function start the log cnt limit. i.e Number of logs
1876 // getting logged into curcular will be restricted to 100 logs.
1879 //////////////////////////////////////////////////////////////////////////
1881 void rlStartLogCountLimit(Void)
1883 g_rlogWriteCount = 0;
1884 g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_START;
1885 printf("Start Log Restriction\n");
1888 //////////////////////////////////////////////////////////////////////////
1889 // @Function : rlStopLogCountLimit
1890 // @Discription : This function will be called by EnbApp after Cell Shutdown
1891 // is triggered. This will enable to get all logs of shutdown.
1892 // This function stops the log cnt limit. i.e Restricition on
1893 // Number of logs getting logged into curcular will be removed
1896 //////////////////////////////////////////////////////////////////////////
1898 void rlStopLogCountLimit(Void)
1900 printf("Stop Log Restriction\n");
1901 g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
1904 //////////////////////////////////////////////////////////////////////////
1905 // @Function : rlResetLogRateLmt
1906 // @Discription : This function will be called every 10 ms whenever
1907 // application layer update the tti count. To reset the
1908 // log rate control. And Enable logging for next 10 ms
1911 //////////////////////////////////////////////////////////////////////////
1913 void rlResetLogRateLmt(void)
1915 g_rlogWriteCount = 0;
1919 void initGlbDataAtL2(void)
1921 strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1924 /**********************************************************************
1926 **********************************************************************/