cb44af511eca6e029931733e0d769403ed36f3e9
[o-du/l2.git] / src / rlog / rl_rlog.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /********************************************************************20**
20
21      Name:     Radisys Logging Framework
22      Type:     C source file
23      Desc:     This file contains logging framework implementation.
24      File:     rl_rlog.c
25
26 *********************************************************************21*/
27 /**********************************************************************
28  @ description: This is source file which has implementaion of logging 
29  framework.
30 ************************************************************************/
31
32 #include "envopt.h"
33 #include "envdep.h"
34 #include "rl_interface.h"
35
36 #include <stdio.h>
37 #include <unistd.h>
38 #include <sys/socket.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <sys/resource.h>
42 #include <fcntl.h>
43 #include <sys/time.h>
44 #include <time.h>
45 #include <stdarg.h>
46 #include <string.h>
47 #include <netinet/in.h>
48 #include <execinfo.h> 
49 #include <dlfcn.h>
50 #include <dirent.h>
51 #include <pthread.h>
52 #include "rl_rlog.h"
53 #include "rl_platform.h"
54 #include "gen.h"
55 #include "ssi.h"
56 #include "ss_msg.h"
57 #include "ss_task.h"
58
59 #include "gen.x"
60 #include "ssi.x"
61
62 #include "ss_queue.h"
63 #include "ss_queue.x"
64 #include "ss_task.x"
65 #include "ss_msg.x"
66 #include "cm_inet.h"
67 #include "cm_inet.x"
68
69 #include "rl_interface.h"
70 #include "rl_soc.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 U16 g_prevLogOffset=0;
77 #endif
78 #ifndef RLOG_ENABLE_TEXT_LOGGING 
79 static volatile U32 g_rlogPositionIndex=0;
80 U32 gIpType = CM_IPV4ADDR_TYPE; 
81 #endif
82
83 ///////////////////////////////////////////////////////////////////////////////////////////////////
84 //                              Default variable initilization
85 ///////////////////////////////////////////////////////////////////////////////////////////////////
86
87 /* global file pointer */
88 FILE* g_fp = NULL; 
89
90 /* L2 Logging */
91 #ifndef RLOG_ENABLE_TEXT_LOGGING 
92
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 U32    g_logBufLenRcvdFromL2 = 0;
99 U32    g_l2LogBufLen = 0;
100 U32    startL2Logging = 0;
101 U32    g_l2logBuffPos = 0;
102 /* end */
103 #endif /* Binary Logging */
104
105 /* number of times log function is called */
106 int  g_nWrites = 0;     
107
108 /* Socke descriptor if remote client is connected */
109 int g_nCliSocket = 0;
110
111 /* Default log level Error */
112 #ifdef DISABLE_RLOG
113 int g_logLevel = 1;
114 #else
115 int g_logLevel = L_MAX_LOG_LEVEL;
116 #endif
117 /* MAX Log Files 1 */
118 U8 g_nMaxLogFiles = 1; 
119
120 /* Max File Size limit for each log file */
121 U32 g_uiMaxFileSizeLimit = MAX_FILE_SIZE; 
122
123 /* Default circular buffer size 100Kb*/
124 U32 g_cirMaxBufferSize = RLOG_MAX_CIRBUF_SIZE; 
125
126 /* Default mask for each module is disabled */
127 U32 g_modMask = 0; 
128
129 /* Remote Logging port */
130 static U32 g_nLogPort = RLOG_REMOTE_LOGGING_PORT;
131
132 /* Current File Number index */
133 int  g_nCurrFileIdx = 0; 
134
135 /* Remote logging flag */
136 static U8 g_bRemoteLoggingDisabled=1;
137
138 /* Global file descriptor for L2 & L3 */
139 static int g_fd;
140
141 /* L2 Buffer */
142 char g_l2Buf[RLOG_MAX_CIRBUF_SIZE];
143
144 #ifdef RLOG_USE_CIRCULAR_BUFFER
145 /* List of thread data pointers */
146 THREAD_DATA* g_pCirList[RLOG_MAX_THREADS];
147
148 /* Number of threads registered */
149 static int g_nThreadsRegistered;
150
151 /* Mutex to protect circular buffers */
152 pthread_mutex_t g_logmutex, g_condmutex;
153 pthread_cond_t g_cond;
154
155 U8 g_writeCirBuf = 0;
156
157 static int thread_signalled;
158 #endif
159
160 /* TTI Count */
161 static U32 numTtiTicks;
162 /* Console input handling parameters */
163 static int g_kIdx, g_action, g_storeKeys;
164 static char g_keyBuf[32];
165
166 /* Standard C library, timezone */
167 extern char *tzname[2];
168 ///////////////////////////////////////////////////////////////////////////////
169 //                  FUNCTION DECLARATIONS                                          //
170 ///////////////////////////////////////////////////////////////////////////////
171 #if defined(RLOG_ENABLE_TEXT_LOGGING) 
172 static struct tm* getTime(int* microseconds);
173 static void getLogTimeStr(char* ts);
174 #else
175 #endif
176 void initGlbDataAtL2(void);
177 void createNewLogFile(void);
178 void createL2LogFile(void);
179 void* rLogServer(void* arg);
180 void closeConnection(int sockfd);
181 void storeTimeDelimeter(FILE* fp);
182 void rlCatchSegViolation(int sig);
183 void flushData(int sig);
184 void* cirBufReaderThread(void* arg);
185 void readCircularBuffers(void);
186 void userAction(void);
187 void handleSigIO(int sig);
188 void rlPrintConfiguration(void);
189 THREAD_DATA* rlRegisterThread(const char* taskName);
190 extern void (*rlSigHandler)(int);
191 /* L2 Logging */
192 void rlInitL2Log(void);
193 U32 g_rlogWriteCount = 0;
194 U32 g_maxRlogCount   = 50;
195 U32 g_logsDropCnt    = 0;
196 RLLogCntLmt g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
197
198 #ifndef RLOG_ENABLE_TEXT_LOGGING 
199 void readL2LogBuff(void);
200 S16 rlValidateL2LogBuf(void);
201 void  rlSetL2LogBuf(U8 *l2LogBuf,U32 l2logLen);
202 void rlResetL2LogBuf(void);
203 #endif
204
205
206 #ifndef RLOG_ENABLE_TEXT_LOGGING
207 EndianType getCPU_Endian(Void);
208 void storeFileHeader(FILE* fp);
209 void saveLogDataFromCpul(const void* buf, U16 len);
210 void saveLogData(const void* buf, U16 len, U32 g_rlogWritePosIndex);
211 void sendToPostProcessor(const void* buf, U16 len);
212 void getLogTimeStr(char* ts);
213 #endif
214 ///////////////////////////////////////////////////////////////////////////////////////////////////
215 // @param[in] modMask - bit mask for any particular module.
216 // Sets or clears bit for the particular module. If mask value is zero all bits are cleared.
217 ///////////////////////////////////////////////////////////////////////////////////////////////////
218 void rlSetModuleMask(U32 modMask)
219 {
220         g_modMask =  (modMask == 0 ) ? 0 : (g_modMask ^ modMask);
221 }
222
223 ///////////////////////////////////////////////////////////////////////////////////////////////////
224 // @param[in] - maxFileSize - Maximum file size in MB.
225 // @brief This function sets the limit to log file size.
226 ///////////////////////////////////////////////////////////////////////////////////////////////////
227 void rlSetLogFileSizeLimit(U32 maxFileSize)
228 {
229         g_uiMaxFileSizeLimit = (maxFileSize == 0) ? MAX_FILE_SIZE : maxFileSize*1048576;
230 }
231
232 ///////////////////////////////////////////////////////////////////////////////////////////////////
233 //
234 //
235 ///////////////////////////////////////////////////////////////////////////////////////////////////
236 void rlSetNumOfLogFiles(U8 nMaxFiles)
237 {
238         if( nMaxFiles > RLOG_MAX_FILES || nMaxFiles == 0 ) {
239                 g_nMaxLogFiles = RLOG_MAX_FILES;
240                 return;
241         }
242
243         g_nMaxLogFiles = nMaxFiles;
244 }
245
246 ///////////////////////////////////////////////////////////////////////////////////////////////////
247 //
248 // @brief 1-> enable remote logging, 0-> disable remote logging
249 ///////////////////////////////////////////////////////////////////////////////////////////////////
250 void rlSetRemoteLoggingFlag(S32 flag)
251 {
252         g_bRemoteLoggingDisabled = !flag;
253 }
254
255 ///////////////////////////////////////////////////////////////////////////////////////////////////
256 // @param[in] port - Server port
257 // @brief Use this API to configure port for remote logging application.
258 ///////////////////////////////////////////////////////////////////////////////////////////////////
259 void rlSetLogPort(U32 port)
260 {
261         g_nLogPort = port;
262 }
263
264 ///////////////////////////////////////////////////////////////////////////////////////////////////
265 // @param[in] enable_core - 1 Enables core file generation 0 - disable
266 // This enables or disables core file generation
267 ///////////////////////////////////////////////////////////////////////////////////////////////////
268 void rlEnableDisableCore(S32 enable_core)
269 {
270         struct rlimit core_limits;
271         core_limits.rlim_cur = core_limits.rlim_max = enable_core ? RLIM_INFINITY : 0;
272         setrlimit(RLIMIT_CORE, &core_limits);
273 }
274
275 ///////////////////////////////////////////////////////////////////////////////////////////////////
276 //
277 //
278 ///////////////////////////////////////////////////////////////////////////////////////////////////
279 void rlSetLogPath(const char* logDir)
280 {
281         strncpy(g_logDir, logDir, MAX_FILENAME_LEN);
282 }
283
284 ///////////////////////////////////////////////////////////////////////////////////////////////////
285 //
286 //
287 ///////////////////////////////////////////////////////////////////////////////////////////////////
288 void rlSetLogFile(const char* fileName)
289 {
290         strncpy(g_fileName, fileName, MAX_FILENAME_LEN);
291 }
292
293 ///////////////////////////////////////////////////////////////////////////////////////////////////
294 //
295 //
296 ///////////////////////////////////////////////////////////////////////////////////////////////////
297 void rlSetLogLevel(R_LOG_LEVEL logLevel)
298 {
299         g_logLevel = logLevel + 1;
300 }
301
302 ///////////////////////////////////////////////////////////////////////////////////////////////////
303 // @param[in] bufSize - Circulaer buffer size in multiples of 1Kb or 1024 bytes.
304 // This function is called to set circular buffer size for each thread.
305 ///////////////////////////////////////////////////////////////////////////////////////////////////
306 void rlSetCircularBufferSize(U32 bufSize)
307 {
308         g_cirMaxBufferSize = bufSize*1024;
309    g_cirMaxBufferSize = (g_cirMaxBufferSize/50) * 50;
310 }
311
312 ///////////////////////////////////////////////////////////////////////////////////////////////////
313 //
314 //
315 ///////////////////////////////////////////////////////////////////////////////////////////////////
316 void rlPrintConfiguration(void)
317 {
318         fprintf(stderr, "Log File:\t\t[%s]\n", g_fileName);
319         fprintf(stderr, "Log level:\t\t[%s]\n", g_logStr[g_logLevel-1]);
320 #ifndef ALIGN_64BIT 
321         fprintf(stderr, "Module Mask:\t\t[%ld]\n", g_modMask);
322         fprintf(stderr, "File Size Limit:\t[%ld]\n", g_uiMaxFileSizeLimit);
323 #else
324         fprintf(stderr, "Module Mask:\t\t[%d]\n", g_modMask);
325         fprintf(stderr, "File Size Limit:\t[%d]\n", g_uiMaxFileSizeLimit);
326 #endif
327         fprintf(stderr, "Maximum Log Files:\t[%d]\n", g_nMaxLogFiles);
328         fprintf(stderr, "Time Zone:\t\t[%s]\n", tzname[0]);
329
330 #ifdef RLOG_ENABLE_TEXT_LOGGING
331         fprintf(stderr, "Binary Logging:\t\t[Disabled]\n");
332         fprintf(stderr, "Remote Logging:\t\t[Disabled]\n");
333         fprintf(stderr, "Console Logging:\t[%s]\n", (g_fp==stderr) ? "Enabled" : "Disabled" );
334 #else
335         fprintf(stderr, "Console Logging:\t[Disabled]\n");
336         fprintf(stderr, "Binary Logging:\t\t[Enabled]\n");
337         fprintf(stderr, "Remote Logging:\t\t[%s]\n", g_bRemoteLoggingDisabled ? "Disabled" : "Enabled");
338 #ifndef ALIGN_64BIT 
339         fprintf(stderr, "Remote Logging Port:\t[%ld]\n", g_nLogPort);
340 #else
341         fprintf(stderr, "Remote Logging Port:\t[%d]\n", g_nLogPort);
342 #endif
343 #ifdef RLOG_USE_CIRCULAR_BUFFER
344         fprintf(stderr, "Circular Buffer:\t[Enabled]\n");
345 #ifndef ALIGN_64BIT 
346         fprintf(stderr, "Circular BufferSize:\t[Actual:%ld][Derived:%ld]\n", 
347                         g_cirMaxBufferSize/1024, g_cirMaxBufferSize);
348 #else
349         fprintf(stderr, "Circular BufferSize:\t[Actual:%d][Derived:%d]\n", 
350                         g_cirMaxBufferSize/1024, g_cirMaxBufferSize);
351 #endif
352 #else
353         fprintf(stderr, "Circular Buffer:\t[Disabled]\n");
354 #endif  /* RLOG_USE_CIRCULAR_BUFFER */
355 #endif /* RLOG_ENABLE_TEXT_LOGGING */
356
357 }
358
359 #ifdef RLOG_USE_CIRCULAR_BUFFER
360
361 #ifdef RLOG_USE_TTI_LOGGING
362 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
363 { \
364         g_nWrites = 0; \
365         logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));\
366
367 #else
368 #define CHECK_FILE_SIZE
369 #endif /* RLOG_USE_TTI_LOGGING */
370
371 #else /* RLOG_USE_CIRCULAR_BUFFER */
372
373 #ifdef RLOG_USE_TTI_LOGGING
374 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
375 { \
376         if( g_fp && ftell(g_fp) > g_uiMaxFileSizeLimit ) { \
377                 createNewLogFile(); \
378         }\
379         g_nWrites = 0; \
380         logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));\
381
382 #else
383 #define CHECK_FILE_SIZE if( ++g_nWrites == 200 ) \
384 { \
385         if( g_fp && ( (U32)(ftell(g_fp)) > g_uiMaxFileSizeLimit) ) { \
386                 createNewLogFile(); \
387         }\
388         g_nWrites = 0; \
389
390 #endif /* RLOG_USE_TTI_LOGGING */
391 #endif /*  RLOG_USE_CIRCULAR_BUFFER */
392
393
394 #ifdef RLOG_USE_CIRCULAR_BUFFER
395
396 #define CHECK_CIRFILE_SIZE if( g_fp && ftell(g_fp) > g_uiMaxFileSizeLimit ) \
397         createNewLogFile(); 
398
399 ///////////////////////////////////////////////////////////////////////////////////////////////////
400 // @param[in] tasName - Name of registering thread / task
401 // This function registers the thread for writing logs. It creates thread specific buffers.
402 ///////////////////////////////////////////////////////////////////////////////////////////////////
403 THREAD_DATA* rlRegisterThread(const char* taskName)
404 {
405         THREAD_DATA* pThrData = (THREAD_DATA*) rlCalloc(sizeof(THREAD_DATA));
406
407         if( pThrData == NULL ) {
408                 fprintf(stderr, "Failed to allocate memory for thread %s\n", taskName);
409                 _exit(0);
410         }
411
412         pthread_mutex_lock(&g_logmutex);
413
414         /* Allocate circular buffer */
415         pThrData->logBuff = (U8*) rlAlloc(g_cirMaxBufferSize);
416
417         if( pThrData->logBuff == NULL ) {
418 #ifndef ALIGN_64BIT
419                 fprintf(stderr, "Failed to allocate memory [%ld] for thread %s\n",g_cirMaxBufferSize, taskName);
420 #else
421                 fprintf(stderr, "Failed to allocate memory [%d] for thread %s\n",g_cirMaxBufferSize, taskName);
422 #endif
423                 _exit(0);
424         }
425
426         /* store task name */
427         strcpy(pThrData->szTaskName, taskName);
428
429         //rlSetThreadSpecificData(pThrData);
430
431         pThrData->listIndex = g_nThreadsRegistered++;
432
433         /* Store this pointerin global list, to access it later */
434         g_pCirList[pThrData->listIndex]  = pThrData;
435
436         pthread_mutex_unlock(&g_logmutex);
437
438 #ifdef RLOG_DEBUG_MODE
439 #ifndef ALIGN_64BIT
440         fprintf(stderr, "rlRegisterThread: allocated CIRCULAR BUFFER of size [%ld]\n", g_cirMaxBufferSize);
441 #else
442         fprintf(stderr, "rlRegisterThread: allocated CIRCULAR BUFFER of size [%d]\n", g_cirMaxBufferSize);
443 #endif
444         fprintf(stderr, "rlRegisterThread: Total registered threads [%d]\n", g_nThreadsRegistered);
445 #endif
446
447         return pThrData;
448 }
449
450 ///////////////////////////////////////////////////////////////////////////////////////////////////
451 // @param[in] arg - Thread argument
452 //      This thread wakes up periodically and transfer logs from thread specific buffer into file system.
453 // If buffer is going to be full, this thread is signalled asynchrounously to read buffered logs.
454 ///////////////////////////////////////////////////////////////////////////////////////////////////
455 void* cirBufReaderThread(void* arg)
456 {
457         struct timespec timeout;
458         int retCode;
459
460 #ifdef RLOG_DEBUG_MODE
461         fprintf(stderr, "Circular Buffer Reader thread started\n");
462 #endif
463
464         while(1)
465         {
466                 /*this thread is not active and waiting to timeout */
467                 thread_signalled = 0;
468
469                 /* set the thread timeout */
470                 timeout.tv_sec = time(NULL) + RLOG_CIRBUF_READ_INTERVAL;
471                 timeout.tv_nsec = 0;
472
473                 /* wait for 120 seconds time interval to read buffer */
474                 retCode = pthread_cond_timedwait(&g_cond, &g_condmutex, &timeout);
475
476                 /* this means, this thread is already active, no need to give any other signal to wake up */
477                 thread_signalled = 1;
478
479 #ifdef RLOG_DEBUG_MODE
480                 //if(retCode == 0) fprintf(stderr, "cirBufReaderThread: I am signalled to read data\n");
481 #endif
482
483                 /* If someone has given signal or there is timeout */
484                 if( retCode == 0 || retCode  == ETIMEDOUT ){
485                         readCircularBuffers();
486                         continue;
487                 }
488
489                 readCircularBuffers();
490
491 #ifdef RLOG_DEBUG_MODE
492                 fprintf(stderr, "System is exiting ??");
493                 perror("cirBufReaderThread");
494 #endif
495                 break;
496         }
497
498         return NULL;
499 }
500
501 ///////////////////////////////////////////////////////////////////////////////////////////////////
502 //
503 //
504 ///////////////////////////////////////////////////////////////////////////////////////////////////
505 void readCircularBuffers()
506 {
507    U32 i, writerPos;
508
509    /* Check if process is L2. If L2 then return from here */
510    if (SFndProcId() == TENB_L2_PROC_ID) 
511    {
512       return;
513    }
514
515    g_writeCirBuf = 1;
516    /* Before reading circular buffers, store delimiter */
517    //storeTimeDelimeter(g_fp);
518
519    /* lock the mutex */
520    pthread_mutex_lock(&g_logmutex);
521
522    for(i=0; i < g_nThreadsRegistered; i++) 
523    {
524       THREAD_DATA* pThrData = g_pCirList[i];
525
526       if( pThrData == NULL )
527          continue;
528
529       writerPos = pThrData->logBufLen;
530
531 #ifdef RLOG_DEBUG_MODE
532       //fprintf(stderr, "Thread [%ld] WritePos:[%ld] ReadPos:[%ld]\n", i+1, writerPos, pThrData->logReadPos);
533 #endif
534
535       if( pThrData->logReadPos < writerPos  )
536       {
537          /* Calculate the delta data to be read from buffer */
538          int dataLen = writerPos - pThrData->logReadPos;
539
540          /* Write the data into file */
541          if( fwrite(pThrData->logBuff+pThrData->logReadPos,1, dataLen, g_fp) == -1 ) 
542          {
543 #ifdef RLOG_DEBUG_MODE
544             fprintf(stderr, "Failed to write data len %d\n", dataLen);
545 #endif
546             createNewLogFile();
547             continue;
548          }
549          /* reset log read position to last known position */
550          pThrData->logReadPos = writerPos;
551       }
552       else if ( pThrData->logReadPos > writerPos ) 
553       {
554          /* Calculate the remaining data left in the buffer */
555          int dataLen = g_cirMaxBufferSize -  pThrData->logReadPos;                      
556
557          /* Write from last know position till end */
558          if( fwrite(pThrData->logBuff+pThrData->logReadPos, 1, dataLen, g_fp) == -1 )
559          {
560 #ifdef RLOG_DEBUG_MODE
561             fprintf(stderr, "Failed to write data len %d\n", dataLen);
562 #endif
563             createNewLogFile();
564             continue;
565          }
566
567          /* Write from 0 to len position */
568          if( fwrite(pThrData->logBuff, 1, writerPos, g_fp) == -1 )
569          {
570 #ifdef RLOG_DEBUG_MODE
571             fprintf(stderr, "Failed to write data len %d\n", dataLen);
572 #endif
573             createNewLogFile();
574             continue;
575          }
576
577          /* reset log read position to last known position */
578          pThrData->logReadPos = writerPos;
579       }
580    }
581
582    /* unlock the mutex */
583    pthread_mutex_unlock(&g_logmutex);
584
585    /* after reading circular buffers also store delimiter */
586    //storeTimeDelimeter(g_fp);
587
588    CHECK_CIRFILE_SIZE
589
590       g_writeCirBuf = 0;
591 }
592
593 #endif
594
595 #ifndef RLOG_ENABLE_TEXT_LOGGING
596 ///////////////////////////////////////////////////////////////////////////////////////////////////
597 //
598 //
599 ///////////////////////////////////////////////////////////////////////////////////////////////////
600 EndianType getCPU_Endian(Void)
601 {
602     unsigned short x;
603     unsigned char c;
604  
605     x = 0x0001;;
606     c = *(unsigned char *)(&x);
607
608         return ( c == 0x01 ) ? little_endian : big_endian;
609 }
610
611 ///////////////////////////////////////////////////////////////////////////////////////////////////
612 //
613 //
614 ///////////////////////////////////////////////////////////////////////////////////////////////////
615 void storeFileHeader(FILE* fp)
616 {
617         FILE_HEADER fileHdr;
618
619         memset(&fileHdr, 0, sizeof(FILE_HEADER));
620
621         fileHdr.endianType = getCPU_Endian();
622         fileHdr.dummy32 = 2818049;
623         fileHdr.END_MARKER = 0xFFFF;
624         strncpy(fileHdr.szTimeZone, tzname[0], RLOG_TIME_ZONE_LEN);
625    
626    fileHdr.time_sec = time(NULL);
627         if( fwrite((const void*)&fileHdr, 1, sizeof(FILE_HEADER), fp) ==  -1 )
628         {
629 #ifdef RLOG_DEBUG_MODE
630                 fprintf(stderr, "Failed to write file header\n");
631 #endif
632                 createNewLogFile();
633         }
634 }
635 #endif
636
637 ///////////////////////////////////////////////////////////////////////////////////////////////////
638 // @param[in] fileName - Log File Name
639 // @brief This function creates a log file. If log file name is stdout & text  logging is enabled,
640 // file  pointer is  initialized to  standard output. This  function also  creates thread on which 
641 // remote application can connect & receive binary logs. If circular buffer is enabled, it creates 
642 // thread key, which is used to store & retrieve thread specific buffers and data.
643 ///////////////////////////////////////////////////////////////////////////////////////////////////
644 void rlInitLog(U8 type)
645 {
646 #ifdef SS_RBUF    
647         /* Initilize the signal handler */
648         rlSigHandler = &rlCatchSegViolation;
649 #else
650         signal(SIGSEGV, rlCatchSegViolation);
651         signal(SIGBUS, rlCatchSegViolation);
652         signal(SIGINT, flushData);
653 #endif
654 /* set rate limit count for L3 Logs */
655    g_maxRlogCount = RLOG_LIMIT_L3_COUNT;
656
657 #ifdef RLOG_DEBUG_MODE
658         rlPrintConfiguration();
659 #endif /* RLOG_DEBUG_MODE */
660
661 #if RLOG_ALLOW_CONSOLE_LOGS
662         if( !strcmp(g_fileName, "stdout")) {
663                 g_fp = stderr;
664                 return;
665         }
666 #endif
667
668 #ifndef RLOG_ENABLE_TEXT_LOGGING
669         {
670       printf("\n IP Type before reader thread spawn [%d]\n",type);
671         /* Allocate circular buffer */
672       gIpType = type;
673                 pthread_t tid;
674                 if( pthread_create(&tid, NULL, &rLogServer, NULL) != 0 ) {
675                         fprintf(stderr, "Failed to initialize log server thread\n");
676                         _exit(0);
677                 }
678         }
679
680         rlInitPlatformSpecific();
681
682 #ifdef RLOG_USE_CIRCULAR_BUFFER
683         {
684                 pthread_t tid;
685                 pthread_mutex_init(&g_logmutex, NULL);
686                 if( pthread_create(&tid, NULL, &cirBufReaderThread, NULL) != 0 ) {
687                         fprintf(stderr, "Failed to initialize log server thread\n");
688                         _exit(0);
689                 }
690 /* Initialize single circular buffer for all threads */
691    g_pSingCirBuff = rlRegisterThread("DUMMY");
692 }
693
694 #endif
695 #endif
696
697         createNewLogFile();
698 }
699
700
701 //////////////////////////////////////////////////////////////////////////
702 //  @Function    : rlInitL2Log 
703 //  @Discription : This will be trigigered from cl init function to
704 //                 allocate buffer from shared memory and to intialize
705 //                 the buffer
706 //  @in          : void
707 //  @out         : void
708 //////////////////////////////////////////////////////////////////////////
709 void rlInitL2Log(void)
710 {
711
712 /* set rate limit count for L3 Logs */
713    g_maxRlogCount = RLOG_LIMIT_L2_COUNT;
714
715 #ifndef RLOG_ENABLE_TEXT_LOGGING 
716 /* Initialise memory to write logs in L2. This is soc specific 
717    function present in soc file. */ 
718    rlInitL2SocSpecific();
719
720 #else
721
722 /* This is used to initialize global variable at L2 */
723    initGlbDataAtL2();
724    createL2LogFile();
725
726 #endif /* Binary Logging */
727 }
728
729
730 #ifndef RLOG_ENABLE_TEXT_LOGGING
731 ///////////////////////////////////////////////////////////////////////////////////////////////////
732 // @param[in] arg - Input thread argument - IP Address type.
733 // @brief This is log server thread which listens on configred port. This allows user to connect to
734 // log server and view log data live.
735 ///////////////////////////////////////////////////////////////////////////////////////////////////
736 void*   rLogServer(void* arg)
737 {
738   CmInetCmnSockAddr serv_addr;
739   CmInetCmnSockAddr cli_addr;
740   int sockfd;
741   int newsockfd;
742   int clilen = 0;
743   int domain = AF_INET;
744   memset((void*)&serv_addr, 0, sizeof(serv_addr));
745
746
747   if(gIpType == CM_IPV4ADDR_TYPE)
748   {
749 #ifndef ALIGN_64BIT
750      printf("Initializing RLOG for IPV4- %ld\n",gIpType);
751 #else
752      printf("Initializing RLOG for IPV4- %d\n",gIpType);
753 #endif
754      clilen = serv_addr.len = sizeof(struct sockaddr_in);
755      domain = AF_INET;
756      serv_addr.type = CM_IPV4ADDR_TYPE;
757      serv_addr.u.addr.sin_family = AF_INET;
758      serv_addr.u.addr.sin_addr.s_addr = INADDR_ANY;
759      serv_addr.u.addr.sin_port = htons(g_nLogPort);
760   }
761   else
762   {
763 #ifndef ALIGN_64BIT
764      printf("Initializing RLOG for IPV6 - %ld\n",gIpType);
765 #else
766      printf("Initializing RLOG for IPV6 - %d\n",gIpType);
767 #endif
768 #ifdef IPV6_SUPPORTED   
769      if(gIpType == CM_IPV6ADDR_TYPE)
770      {
771         clilen =  serv_addr.len = sizeof(struct sockaddr_in6);
772         domain = AF_INET6;
773         serv_addr.type = CM_IPV6ADDR_TYPE;
774         serv_addr.u.addr6.sin6_family = AF_INET6;
775         serv_addr.u.addr6.sin6_addr = in6addr_any;
776         serv_addr.u.addr6.sin6_port = htons(g_nLogPort);
777      }
778 #endif
779   }
780         if( (sockfd = socket(domain, SOCK_STREAM, 0)) < 0 ) {
781                 fprintf(stderr, "RLOG: Failed to create socket\n");
782                 _exit(0);
783         }
784
785         if( bind(sockfd, (struct sockaddr*)&(serv_addr.u),serv_addr.len) < 0 ) {
786                 fprintf(stderr, "RLOG: Error in Binding\n");
787                 perror("RLOG");
788                 _exit(0);
789         }
790
791         listen(sockfd, 5);
792
793         while(1)
794         {
795                 newsockfd = accept(sockfd, (struct sockaddr*)&(cli_addr.u), (socklen_t *) &clilen);     
796                 if( newsockfd < 0 ) {
797                         fprintf(stderr, "RLOG: Error on accept\n");
798                         perror("RLOG");
799                         return 0;
800                 }
801
802                 /* If remote logging is disabled or there is already 1 client connected */
803                 if( g_bRemoteLoggingDisabled || g_nCliSocket ) {
804                         /* close the new connection and proceed */
805                         closeConnection(newsockfd);
806                         continue;
807                 } 
808
809                 g_nCliSocket = newsockfd;
810         }
811
812         return 0;
813 }
814
815 ///////////////////////////////////////////////////////////////////////////////////////////////////
816 //
817 //
818 ///////////////////////////////////////////////////////////////////////////////////////////////////
819 void closeConnection(int sockfd)
820 {
821         shutdown(sockfd, SHUT_RDWR);
822         close(sockfd);
823 }
824
825 #endif
826
827 ///////////////////////////////////////////////////////////////////////////////////////////////////
828 //
829 //
830 ///////////////////////////////////////////////////////////////////////////////////////////////////
831 void  handleSigIO(int sig)
832 {
833         char ch;
834
835         if( read(0, &ch, 1) <= 0 )
836                 return;
837
838         rlHandleConInput(ch);
839 }
840
841 ///////////////////////////////////////////////////////////////////////////////////////////////////
842 //
843 //
844 ///////////////////////////////////////////////////////////////////////////////////////////////////
845 int rlHandleConInput(char ch)
846 {
847         if( ch == RLOG_CTRL_L ) {
848                 g_storeKeys = 1;
849                 g_action = RLOG_SET_LOGLEVEL;
850                 fprintf(stderr, "\nEnter new log level:");
851                 return 1;
852         }
853
854         if( ch == RLOG_CTRL_Y ) {
855                 g_storeKeys = 1;
856                 g_action = RLOG_SET_MODMASK;
857                 fprintf(stderr, "\nEnter module number:");
858                 return 1;
859         }
860
861         if( ch == RLOG_ENTER_KEY && g_action ) {
862                 g_keyBuf[g_kIdx] = '\0';  
863                 userAction();
864                 return 1;
865         }
866
867         if( g_storeKeys ) { 
868                 g_keyBuf[g_kIdx] = ch;
869                 g_kIdx +=1;
870         }
871
872         return 0;
873 }
874
875 ///////////////////////////////////////////////////////////////////////////////////////////////////
876 //
877 //
878 ///////////////////////////////////////////////////////////////////////////////////////////////////
879 void userAction()
880 {
881         unsigned int val = atol(g_keyBuf);
882
883         switch( g_action )
884         {
885                 case RLOG_SET_LOGLEVEL:
886                         {
887                                 if( val >= L_MAX_LOG_LEVEL )
888                                         fprintf(stderr, "Invalid log level\n");
889                                 else 
890                                 {
891                                         if( val > L_FATAL ) 
892                                         {
893                                                 rlSetLogLevel((R_LOG_LEVEL)val);
894                                                 fprintf(stderr, "New Log level is %s\n", g_logStr[val]);
895                                         }
896                                         else
897                                                 fprintf(stderr, "Log level below L_ERROR is not allowed\n");
898                                 }
899                         }       
900                         break;
901
902                 case RLOG_SET_MODMASK:
903                         {
904                                 rlSetModuleMask(val);
905                                 fprintf(stderr, "Toggled log mask %d\n", val);
906                         }
907                         break;
908         }
909
910         g_action = 0;
911         g_kIdx= 0; 
912         g_storeKeys = 0;
913 }
914
915 ///////////////////////////////////////////////////////////////////////////////////////////////////
916 //
917 //
918 ///////////////////////////////////////////////////////////////////////////////////////////////////
919 void rlCatchSegViolation(int sig)
920 {
921         int i, nStrLen, nDepth;
922
923         void    *stackTraceBuf[RLOG_MAX_STACK_DEPTH];
924         const char* sFileNames[RLOG_MAX_STACK_DEPTH];
925         const char* sFunctions[RLOG_MAX_STACK_DEPTH];
926
927         char **strings; char buf[RLOG_MAX_STACK_DEPTH*128]={0};
928 #ifdef T2K_MEM_LEAK_DBG
929    DumpT2kMemLeakInfoToFile();
930 #endif
931 #ifdef SSI_STATIC_MEM_LEAK_DETECTION
932    DumpStaticMemLeakFiles();
933 #endif
934
935         nDepth = backtrace(stackTraceBuf, RLOG_MAX_STACK_DEPTH);
936
937
938         strings = (char**) backtrace_symbols(stackTraceBuf, nDepth);
939
940         for(i = 0, nStrLen=0; i < nDepth; i++)
941         {
942                 sFunctions[i] = (strings[i]);
943                 sFileNames[i] = "unknown file";
944
945 #ifndef RLOG_ENABLE_TEXT_LOGGING
946            logLevS(L_SIGSEGV, L_FATAL, strings[i]);
947 #endif
948       printf("BT[%d] : len [%ld]: %s\n",i, (PTR)strlen(sFunctions[i]),strings[i]);
949                 sprintf(buf+nStrLen, "   in Function %s (from %s)\n", sFunctions[i], sFileNames[i]);
950                 nStrLen += strlen(sFunctions[i]) + strlen(sFileNames[i]) + 15;
951         }
952
953 #ifdef RLOG_ENABLE_TEXT_LOGGING
954         logLevS(g_logStr[L_FATAL], "RLOG", "NULL", 0, FMTSTR RLOG_SEGFAULT_STR, buf);
955         fflush(g_fp);
956 #else
957         logLevS(L_SIGSEGV, L_FATAL, buf);
958 #endif
959
960         flushData(SIGSEGV);
961 }
962
963 ///////////////////////////////////////////////////////////////////////////////////////////////////
964 //
965 //
966 ///////////////////////////////////////////////////////////////////////////////////////////////////
967 void flushData(int sig)
968 {
969 #ifdef RLOG_USE_CIRCULAR_BUFFER
970         readCircularBuffers();
971 #endif
972    g_rlogWriteCount = 0;
973
974         fclose(g_fp);
975
976         if(SIGSEGV == sig)
977         {
978            signal(sig, SIG_DFL);
979            kill(getpid(), sig);
980         }
981         else
982         {
983            exit(0);
984         }
985
986         return;
987 }
988
989 ///////////////////////////////////////////////////////////////////////////////////////////////////
990 //
991 //
992 ///////////////////////////////////////////////////////////////////////////////////////////////////
993
994 #ifdef RLOG_ENABLE_TEXT_LOGGING 
995
996 #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
998 ///////////////////////////////////////////////////////////////////////////////////////////////////
999 //
1000 //
1001 ///////////////////////////////////////////////////////////////////////////////////////////////////
1002 void logLevS(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR str, ...)
1003 {
1004         int microseconds=0;
1005
1006         struct tm* tm = getTime(&microseconds);
1007    if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, str);
1008
1009         CHECK_FILE_SIZE
1010 }
1011
1012 ///////////////////////////////////////////////////////////////////////////////////////////////////
1013 //
1014 //
1015 ///////////////////////////////////////////////////////////////////////////////////////////////////
1016 void logLevH(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, PSTR hexdump, int hexlen, ...)
1017 {
1018         int microseconds=0;
1019         char szHex[MAX_LOG_BUF_SIZE*3];
1020
1021         struct tm* tm = getTime(&microseconds);
1022         hextostr(szHex, hexdump, hexlen);
1023         if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, szHex);
1024
1025         CHECK_FILE_SIZE
1026 }
1027
1028 ///////////////////////////////////////////////////////////////////////////////////////////////////
1029 //
1030 //
1031 ///////////////////////////////////////////////////////////////////////////////////////////////////
1032 void logLevE(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, R_SPL_ARG splType,
1033                 U32 splVal, U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1034 {
1035         int microseconds=0;
1036
1037         struct tm* tm = getTime(&microseconds);
1038         if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, g_splStr[splType], splVal, 
1039                         arg1, arg2, arg3, arg4);
1040
1041         CHECK_FILE_SIZE
1042 }
1043 ///////////////////////////////////////////////////////////////////////////////////////////////////
1044 //
1045 //
1046 ///////////////////////////////////////////////////////////////////////////////////////////////////
1047 void logLev0(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, ...)
1048 {
1049         int microseconds=0;
1050
1051         struct tm* tm = getTime(&microseconds);
1052         if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel);
1053
1054         CHECK_FILE_SIZE
1055 }
1056
1057 ///////////////////////////////////////////////////////////////////////////////////////////////////
1058 //
1059 //
1060 ///////////////////////////////////////////////////////////////////////////////////////////////////
1061 void logLev1(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32 arg1, ...)
1062 {
1063         int microseconds=0;
1064
1065         struct tm* tm = getTime(&microseconds);
1066         if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1);
1067
1068         CHECK_FILE_SIZE
1069 }
1070
1071 ///////////////////////////////////////////////////////////////////////////////////////////////////
1072 //
1073 //
1074 ///////////////////////////////////////////////////////////////////////////////////////////////////
1075 void logLev2(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, U32 arg1, U32 arg2, ...)
1076 {
1077         int microseconds=0;
1078
1079         struct tm* tm = getTime(&microseconds);
1080         if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2);
1081
1082         CHECK_FILE_SIZE
1083 }
1084
1085 ///////////////////////////////////////////////////////////////////////////////////////////////////
1086 //
1087 //
1088 ///////////////////////////////////////////////////////////////////////////////////////////////////
1089 void logLev3(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, 
1090                 U32 arg1, U32 arg2, U32 arg3, ...)
1091 {
1092         int microseconds=0;
1093
1094         struct tm* tm = getTime(&microseconds);
1095         if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2, arg3);
1096
1097         CHECK_FILE_SIZE
1098 }
1099
1100 ///////////////////////////////////////////////////////////////////////////////////////////////////
1101 //
1102 //
1103 ///////////////////////////////////////////////////////////////////////////////////////////////////
1104 void logLev4(PSTR strLogLevel, PSTR modName, PSTR file, int lineno, PSTR fmtStr, 
1105                 U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1106 {
1107         int microseconds=0;
1108
1109         struct tm* tm = getTime(&microseconds);
1110         if (tm) fprintf(g_fp, fmtStr, TIME_PARAMS, modName, file, lineno, strLogLevel, arg1, arg2, arg3, arg4);
1111
1112         CHECK_FILE_SIZE
1113 }
1114
1115 ///////////////////////////////////////////////////////////////////////////////////////////////////
1116 //
1117 //
1118 ///////////////////////////////////////////////////////////////////////////////////////////////////
1119 void logLevN(int logLevel, const char* modName, const char* file, int lineno, const char* fmtStr, ...)
1120 {
1121         va_list argList;
1122         char szTime[RLOG_MAX_TIME_STAMP];
1123         char szLog1[MAX_LOG_LEN], szLog2[MAX_LOG_LEN];
1124
1125         getLogTimeStr(szTime);
1126         snprintf(szLog1, MAX_LOG_LEN, "[%s][%s]%s:%d\n%s:", szTime, modName, file, lineno, g_logStr[logLevel]);
1127
1128         va_start(argList,fmtStr);
1129         vsnprintf(szLog2, MAX_LOG_LEN, fmtStr, argList);
1130         va_end(argList);
1131
1132         fprintf(g_fp, "%s%s",szLog1, szLog2);
1133
1134         CHECK_FILE_SIZE
1135 }
1136 #else /* BINARY LOGGING */ 
1137
1138 #define RLOG_SAVE_TIME(_logTime) _logTime.ms_tti=numTtiTicks;
1139
1140 void saveLogDataFromCpul(const void* buf, U16 len)
1141 {
1142 #ifdef RLOG_USE_CIRCULAR_BUFFER
1143    THREAD_DATA* p = (THREAD_DATA*) g_pSingCirBuff;
1144
1145    if( (p->logBufLen+len) > g_cirMaxBufferSize )
1146    {
1147       S32 tempLen = g_cirMaxBufferSize - p->logBufLen;
1148       S32 remlen = len-tempLen;
1149       if ((tempLen < 0) || (remlen < 0))
1150       {
1151          RETVOID;
1152       }
1153                 if(remlen == 0)
1154                 {
1155                         g_rlogPositionIndex = 0;
1156          g_prevLogOffset = 0; 
1157                 }
1158                 else
1159                 {
1160                         g_rlogPositionIndex = remlen/50;
1161                 }
1162
1163       /* we are unlikely to hit this condition, but to prevent corruption of binary logs */
1164       /* we cannot write the data, if we write, data will be corrected forever */
1165       if( remlen > p->logReadPos ) 
1166       {
1167          fprintf(stderr, "cannot write data.retune buffer parameters\n");
1168          return;
1169       }
1170                 if( (p->logReadPos -  remlen) < RLOG_READ_POS_THRESHOLD && !thread_signalled ) 
1171       {
1172                         pthread_cond_signal(&g_cond); /* this will wakeup thread */
1173                 }
1174
1175
1176       /* Copy data till end of the buffer */
1177       memcpy(p->logBuff+p->logBufLen, buf, tempLen);
1178       /* Copy remaining data from the start of buffer */
1179       memcpy(p->logBuff, ((const U8 *)buf)+tempLen, remlen);
1180       /* Store buffer length position */
1181       p->logBufLen = len-tempLen;
1182    }
1183    else
1184    {
1185       /* if reader is far behind and writer is reaching reader position, diff < 5Kb */
1186       /* its time to wakeup thread if reader has not read much of data */
1187       if( p->logReadPos > p->logBufLen && (p->logReadPos - p->logBufLen) < RLOG_READ_POS_THRESHOLD && !thread_signalled ) 
1188          pthread_cond_signal(&g_cond); /* this will wakeup thread */
1189
1190                 g_rlogPositionIndex += (len/50);
1191       memcpy(p->logBuff+p->logBufLen, buf, len);
1192       p->logBufLen += len;
1193    }
1194 #else 
1195    /* Directly write received buffer in cpuh log file */
1196    if( fwrite((const void*)buf, 1, len, g_fp) == -1 ) 
1197    {
1198 #ifdef RLOG_DEBUG_MODE
1199       fprintf(stderr, "Failed to write log data in file\n");
1200       perror("LOG");
1201 #endif
1202       createNewLogFile();
1203    }
1204 #endif
1205
1206 }
1207
1208 void saveLogData(const void* buf, U16 len, U32 g_rlogWritePosIndex)
1209 {
1210
1211    ++g_rlogWriteCount ;
1212
1213    if((1 == g_writeCirBuf) || 
1214          ((g_rlLogCntLimit == RL_LOG_COUNT_LIMIT_START) && 
1215           (g_rlogWriteCount > g_maxRlogCount)) || 
1216          (len > RLOG_FIXED_LENGTH_BUFFER_SIZE))
1217    {
1218       g_rlogPositionIndex --;
1219       g_logsDropCnt++;
1220       return;
1221    }
1222
1223    /* check for if L2 is going to store logs */
1224    if (SFndProcId() == TENB_L2_PROC_ID) 
1225    {
1226       if((g_l2LogBufLen + RLOG_FIXED_LENGTH_BUFFER_SIZE) < L2LOG_BUFF_BLOCK_SIZE - sizeof(g_l2LogBufLen) )
1227       {
1228          /* copying logs in shared buffer */
1229          memcpy(g_l2LogBufStartPtr, buf, len);
1230
1231          g_l2LogBufStartPtr += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1232          /* increasing total log length with L2 log length */
1233          g_l2LogBufLen += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1234       }
1235       return;
1236    }
1237 #ifdef RLOG_USE_CIRCULAR_BUFFER
1238    U32 logWritePointerPosition;
1239    THREAD_DATA* p = (THREAD_DATA*) g_pSingCirBuff;
1240
1241    /* if buffer is about to full, write till end and continue writing from begining */
1242    if( ((g_rlogWritePosIndex+1) * RLOG_FIXED_LENGTH_BUFFER_SIZE) > g_cirMaxBufferSize ) 
1243    {
1244       /* setting this flag to 1 to avoid other threads
1245          to write in same circular buffer */
1246       g_writeCirBuf = 1;
1247       /* Start globalPositionIndex again */
1248       g_rlogPositionIndex = 0;
1249
1250       /* if reader has not read initial data, minmum buffer size should be 100Kb */
1251       if( p->logReadPos < RLOG_READ_POS_THRESHOLD && !thread_signalled ) {
1252          pthread_cond_signal(&g_cond); /* this will wakeup thread */
1253       }
1254
1255       /* we are unlikely to hit this condition, but to prevent corruption of binary logs */
1256       /* we cannot write the data, if we write, data will be corrected forever */
1257       if( RLOG_FIXED_LENGTH_BUFFER_SIZE > p->logReadPos ) {
1258          fprintf(stderr, "cannot write data.retune buffer parameters\n");
1259          return;
1260       }
1261
1262       /* Copy data from the start of buffer */
1263       memcpy(p->logBuff, buf, len);
1264       /* Store buffer length position */
1265       p->logBufLen = RLOG_FIXED_LENGTH_BUFFER_SIZE;
1266       g_prevLogOffset = 0;
1267       /* setting this flag to 0 so that other threads
1268          will start writing in circular buffer */
1269       g_writeCirBuf = 0;
1270    }
1271    else 
1272    {
1273       /* if reader is far behind and writer is reaching reader position, diff < 5Kb */
1274       /* its time to wakeup thread if reader has not read much of data */
1275       if( p->logReadPos > p->logBufLen && (p->logReadPos - p->logBufLen) < RLOG_READ_POS_THRESHOLD ) 
1276          pthread_cond_signal(&g_cond); /* this will wakeup thread */
1277
1278       logWritePointerPosition = (g_rlogWritePosIndex * RLOG_FIXED_LENGTH_BUFFER_SIZE) + g_prevLogOffset;
1279
1280       memcpy(p->logBuff+logWritePointerPosition, buf, len);
1281       p->logBufLen += RLOG_FIXED_LENGTH_BUFFER_SIZE;
1282    }
1283 #else /* !RLOG_USE_CIRCULAR_BUFFER */
1284    if( fwrite((const void*)buf, 1, RLOG_FIXED_LENGTH_BUFFER_SIZE, g_fp) == -1 ) 
1285    {
1286 #ifdef RLOG_DEBUG_MODE
1287       fprintf(stderr, "Failed to write log data in file\n");
1288       perror("LOG");
1289 #endif
1290       createNewLogFile();
1291    }
1292 #endif /* RLOG_USE_CIRCULAR_BUFFER */
1293
1294    CHECK_FILE_SIZE
1295
1296       /* If post processor connected send logs */
1297       if( g_nCliSocket &&  send(g_nCliSocket, buf, RLOG_FIXED_LENGTH_BUFFER_SIZE, 0 ) == -1 ) {
1298          closeConnection(g_nCliSocket);
1299          g_nCliSocket = 0;
1300       }
1301
1302 #ifdef RLOG_DEBUG_MODE_2
1303    {
1304       static int maxlen = 0;
1305       if(len > maxlen) {
1306          maxlen = len;
1307          fprintf(stderr, "MAX BUFFER SIZE is binary mode is [%d]\n", maxlen);
1308       }
1309    }
1310 #endif
1311
1312 }
1313
1314 #if 0
1315 void storeTimeDelimeter(FILE* fp)
1316 {
1317    LOGDATA logData;
1318    logData.logId = L_TIME_DELIMITER;
1319    logData.argType = 0;
1320    logData.logLevel = 0;
1321    logData.numOfArgs = 0;
1322    logData.len = 0;
1323 }
1324 #endif
1325 void sendToPostProcessor(const void* buf, U16 len)
1326 {
1327    if( send(g_nCliSocket, buf, len, 0 ) == -1 ) {
1328       perror("ERROR Sending");
1329       closeConnection(g_nCliSocket);
1330       g_nCliSocket = 0;
1331    }
1332 }
1333 void logLevS( LOGID logId, R_LOG_LEVEL logLevel, const char* str, ...)
1334 {
1335    ARGDATA arg; U16 bufsize;
1336
1337
1338    RLOG_SAVE_TIME(arg.logData.logTime);
1339
1340    arg.logData.logId = logId;
1341    arg.logData.argType = LOG_ARG_STR;
1342    arg.logData.logLevel = logLevel;
1343    arg.logData.numOfArgs = 1;
1344    arg.logData.len = strlen(str);
1345
1346    memcpy(arg.buf, (const void*)str, arg.logData.len);
1347    bufsize = sizeof(LOGDATA)+arg.logData.len;
1348
1349    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1350 }
1351
1352 void logLevH( LOGID logId, R_LOG_LEVEL logLevel, PSTR hex, int hexlen, ...)
1353 {
1354    ARGDATA arg;
1355    int bufsize;
1356
1357    RLOG_SAVE_TIME(arg.logData.logTime);
1358
1359    arg.logData.logId = logId;
1360    arg.logData.argType = LOG_ARG_HEX;
1361    arg.logData.logLevel = logLevel;
1362    arg.logData.numOfArgs = 1;
1363    arg.logData.len = hexlen;
1364
1365    memcpy(arg.buf, (const void*)hex, hexlen);
1366    bufsize = sizeof(LOGDATA)+arg.logData.len;
1367
1368    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1369 }
1370 void logLevE(LOGID logId, R_LOG_LEVEL logLevel, R_SPL_ARG splType, U32 splVal, U32 arg1, U32 arg2,
1371       U32 arg3, U32 arg4, ...)
1372 {
1373    SPL_ARGDATA arg;
1374    int bufsize;
1375
1376    RLOG_SAVE_TIME(arg.logData.logTime);
1377
1378    arg.logData.logId = logId;
1379    arg.logData.argType = LOG_ARG_SPL;
1380    arg.logData.logLevel = logLevel;
1381    if( arg1 ) {
1382       arg.logData.numOfArgs = (arg2 == 0 ) ? 1 : (arg3==0 ? 2 : (arg4==0 ? 3 : 4));
1383    } else {
1384       arg.logData.numOfArgs = 0;
1385    }
1386
1387    arg.logData.len  = sizeof(u_int8_t) + sizeof(U32) + (sizeof(U32)*arg.logData.numOfArgs);
1388
1389    arg.splEnum = splType;
1390    arg.splArg = splVal;
1391    arg.arg1 = arg1;
1392    arg.arg2 = arg2;
1393    arg.arg3 = arg3;
1394    arg.arg4 = arg4;
1395
1396    bufsize = sizeof(LOGDATA)+arg.logData.len;
1397
1398    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1399 }
1400
1401 void logLev0( LOGID logId, R_LOG_LEVEL logLevel, ...)
1402 {
1403    //LOGDATA logData;
1404    ARG4DATA arg;
1405
1406    RLOG_SAVE_TIME(arg.logData.logTime);
1407
1408    arg.logData.logId = logId;
1409    arg.logData.argType = LOG_ARG_STR;
1410    arg.logData.logLevel = logLevel;
1411    arg.logData.numOfArgs = 0;
1412    arg.logData.len = 0;
1413
1414    saveLogData((const void*)&arg, sizeof(LOGDATA),g_rlogPositionIndex++);       
1415 }
1416
1417 void logLev1( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, ...)
1418 {
1419    ARG4DATA arg;
1420    int bufsize;
1421
1422    RLOG_SAVE_TIME(arg.logData.logTime);
1423
1424    arg.logData.logId = logId;
1425    arg.logData.argType = LOG_ARG_INT;
1426    arg.logData.logLevel = logLevel;
1427    arg.logData.numOfArgs = 1;
1428    arg.logData.len = sizeof(U32);
1429
1430    arg.arg1 = arg1;
1431    bufsize = sizeof(LOGDATA)+arg.logData.len;
1432
1433    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1434 }
1435 void logLev2( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, ...)
1436 {
1437    ARG4DATA arg;
1438    int bufsize;
1439
1440    RLOG_SAVE_TIME(arg.logData.logTime);
1441
1442    arg.logData.logId = logId;
1443    arg.logData.argType = LOG_ARG_INT;
1444    arg.logData.logLevel = logLevel;
1445    arg.logData.numOfArgs = 2;
1446    arg.logData.len =  2 * sizeof(U32);
1447
1448    arg.arg1 = arg1;
1449    arg.arg2 = arg2;
1450
1451    bufsize = sizeof(LOGDATA)+arg.logData.len;
1452
1453    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1454 }
1455 void logLev3( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, ...)
1456 {
1457    ARG4DATA arg;
1458    int bufsize;
1459
1460    RLOG_SAVE_TIME(arg.logData.logTime);
1461
1462    arg.logData.logId = logId;
1463    arg.logData.argType = LOG_ARG_INT;
1464    arg.logData.logLevel = logLevel;
1465    arg.logData.numOfArgs = 3;
1466    arg.logData.len = 3 * sizeof(U32);
1467
1468    arg.arg1 = arg1;
1469    arg.arg2 = arg2;
1470    arg.arg3 = arg3;
1471
1472    bufsize = sizeof(LOGDATA)+arg.logData.len;
1473
1474    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1475 }
1476 void logLev4( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1477 {
1478    ARG4DATA arg;
1479
1480    RLOG_SAVE_TIME(arg.logData.logTime);
1481
1482    arg.logData.logId = logId;
1483    arg.logData.argType = LOG_ARG_INT;
1484    arg.logData.logLevel = logLevel;
1485    arg.logData.numOfArgs = 4;
1486    arg.logData.len = 4 * sizeof(U32);
1487
1488    arg.arg1 = arg1;
1489    arg.arg2 = arg2;
1490    arg.arg3 = arg3;
1491    arg.arg4 = arg4;
1492
1493    saveLogData((const void*)&arg, sizeof(ARG4DATA),g_rlogPositionIndex++);      
1494 }
1495
1496 #endif /* BINARY LOGGING */
1497
1498 #if defined(RLOG_ENABLE_TEXT_LOGGING) 
1499 struct tm* getTime(int* microseconds)
1500 {
1501 #ifndef SS_LINUX
1502    struct timespec ptime;
1503 #else
1504    struct timeval ptime;
1505 #endif
1506
1507 #ifndef SS_LINUX
1508    clock_gettime(CLOCK_REALTIME, &ptime);
1509    *microseconds = ptime.tv_nsec / 1000;
1510 #else
1511    gettimeofday(&ptime, NULL);
1512    *microseconds = ptime.tv_usec;
1513 #endif
1514
1515    /* Obtain the time of day, and convert it to a tm struct. --*/
1516    return localtime (&ptime.tv_sec);
1517 }
1518 #elif !defined(RLOG_USE_TTI_LOGGING)
1519 static void getLogTime(LOGTIME* logTime)
1520 {
1521 #ifndef SS_LINUX
1522    struct timespec ptime;
1523 #else
1524    struct timeval ptime;
1525 #endif
1526
1527 #ifndef SS_LINUX
1528    clock_gettime(CLOCK_REALTIME, &ptime);
1529    logTime->ms_tti = ptime.tv_nsec / 1000;
1530 #else
1531    gettimeofday(&ptime, NULL);
1532    logTime->ms_tti = ptime.tv_usec/1000;
1533 #endif
1534
1535    logTime->tv_sec = ptime.tv_sec;
1536 }
1537
1538 #endif
1539
1540 void getLogTimeStr(char* ts)
1541 {
1542 #ifndef SS_LINUX
1543    struct timespec ptime;
1544 #else
1545    struct timeval ptime;
1546 #endif
1547    struct tm* tm;
1548    int microseconds;
1549
1550 #ifndef SS_LINUX
1551    clock_gettime(CLOCK_REALTIME, &ptime);
1552    microseconds = ptime.tv_nsec / 1000;
1553 #else
1554    gettimeofday(&ptime, NULL);
1555    microseconds = ptime.tv_usec/1000;
1556 #endif
1557
1558    /* Obtain the time of day, and convert it to a tm struct. --*/
1559    tm = localtime (&ptime.tv_sec);
1560
1561    if (tm) sprintf(ts,"%d_%d_%d_%d_%d_%d.%03d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, 
1562          tm->tm_hour, tm->tm_min,tm->tm_sec,microseconds);
1563 }
1564 ///////////////////////////////////////////////////////////////////////////////////////////////////
1565 //
1566 //
1567 ///////////////////////////////////////////////////////////////////////////////////////////////////
1568
1569 void rlEnaBleBufferedIO(void)
1570 {
1571    setvbuf (g_fp, NULL, _IOFBF, 1024 );
1572 }
1573
1574 void createNewLogFile()
1575 {
1576    FILE *fp, *prev_fp = g_fp;
1577    char curTime[RLOG_MAX_TIME_STAMP]; int fd;
1578    char *temptr;
1579    /* Fix for CR ccpu00143040 */
1580    DIR *dir = NULLP;
1581
1582    /* get current time, when file is created */
1583    getLogTimeStr(curTime); 
1584    temptr = strchr(curTime, '.');
1585    if (temptr != NULLP)
1586    {
1587       *temptr = 0;
1588    }
1589    /* Fix for CR ccpu00143040 */
1590    dir  = opendir(g_logDir);
1591    if ( dir == NULLP )
1592    { 
1593       mkdir(g_logDir, O_RDWR);
1594    }
1595    else
1596    {
1597       closedir(dir);
1598    }
1599    /* remove old file from system */
1600    if( g_fileList[g_nCurrFileIdx][0] != '\0' )
1601       unlink(g_fileList[g_nCurrFileIdx]);
1602
1603 #ifdef RLOG_ENABLE_TEXT_LOGGING
1604    /* create file name, Example-> dbglog_2013_08_11_15_30_00 */
1605    snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.txt",g_logDir, g_fileName, curTime );
1606    fp = fopen(g_fileList[g_nCurrFileIdx], "w+");
1607 #else
1608    snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.bin",g_logDir, g_fileName, curTime );
1609    fp = fopen(g_fileList[g_nCurrFileIdx], "ab+");
1610 #endif
1611
1612    if( fp == NULL ) {
1613       fprintf(stderr, "Failed to open log file %s\n", g_fileList[g_nCurrFileIdx]);
1614       return;
1615    }
1616
1617    fd = fileno(fp);
1618
1619    g_fp = fp;
1620    g_fd = fd;
1621
1622    if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1623       fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1624    }
1625
1626 #ifdef RLOG_ENABLE_TEXT_LOGGING
1627    setvbuf ( fp , NULL, _IOLBF, 1024 );
1628 #else
1629    setvbuf ( fp , NULL, _IONBF, 1024 );
1630 #endif
1631
1632 #ifndef RLOG_ENABLE_TEXT_LOGGING
1633    storeFileHeader(fp);
1634 #endif
1635
1636    if( prev_fp != NULL )
1637       fclose(prev_fp);
1638
1639    if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1640       g_nCurrFileIdx = 0;
1641
1642 #ifndef RLOG_ENABLE_TEXT_LOGGING
1643 #ifdef RLOG_USE_TTI_LOGGING
1644    logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));
1645 #endif
1646 #endif
1647 }
1648
1649 void createL2LogFile()
1650 {
1651    FILE *fp, *prev_fp = g_fp;
1652    int fd;
1653    char file[MAX_FILENAME_LEN];
1654
1655    strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1656    strncpy(g_fileName, "dbglog_l2", MAX_FILENAME_LEN);
1657    snprintf(file, sizeof(file), "%s/%s.txt", g_logDir, g_fileName);
1658
1659    fp = fopen(file, "w+");
1660    if( fp == NULL) {
1661       printf("Failed to open file %s", file);
1662       _exit(0);
1663    }
1664
1665    printf("Created L2 bin file FD=%s\n", g_fileName);
1666
1667    setvbuf (fp , NULL, _IONBF, 1024 );
1668
1669    fd = fileno(fp);
1670
1671    g_fp = fp;
1672    g_fd = fd;
1673
1674    if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1675       fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1676    }
1677
1678    setvbuf ( fp , NULL, _IOLBF, 1024 );
1679
1680    if( prev_fp != NULL )
1681       fclose(prev_fp);
1682
1683    if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1684       g_nCurrFileIdx = 0;
1685
1686
1687 }
1688
1689 //////////////////////////////////////////////////////////////////////////
1690 //  @Function    : rlUdateRlogTti
1691 //  @Discription : This function will be called every 10 ms whenever 
1692 //                 application layer update the tti count
1693 //  @in          : void
1694 //  @out         : void
1695 //////////////////////////////////////////////////////////////////////////
1696 void rlUpdateRlogTti(Void)
1697 {
1698 #ifndef RLOG_ENABLE_TEXT_LOGGING
1699 #ifdef RLOG_USE_TTI_LOGGING
1700    logLev1(L_TIME_TTI_UPDT, L_ALWAYS, (U32)time(NULL));
1701 #endif
1702 #endif
1703 }
1704
1705 /* This function processes log buffer received from L2
1706    mBuf is Received from L2 through SPstTsk. This function
1707    extracts buffer pointer and logLen and then these logs 
1708    written to L3 log buffer/file. 
1709    This function is called in application layer when EVTL2LOGBUF
1710    event is recieved from ssi
1711 */
1712
1713 #ifdef ANSI
1714 PUBLIC Void rlProcessLogBufFromL2
1715 (
1716  void *mBuf
1717  )
1718 #else
1719 PUBLIC Void rlProcessLogBufFromL2(mBuf)
1720    void *mBuf;
1721 #endif
1722 {
1723 #ifndef RLOG_ENABLE_TEXT_LOGGING 
1724    U32 logLength;
1725    Data* logPtr;
1726    startL2Logging = 1;
1727    if(mBuf == NULL)
1728    {
1729       printf("NULL MBUF received \n");
1730       RETVOID;
1731    }
1732    /* Get Buffer pointer and length. This is SOC specific function which
1733       will extract Log-Buffer pointer and length from mBuf */
1734    rlGetL2LogBufPtr(mBuf, &logLength,&logPtr);
1735    rlSetL2LogBuf(logPtr,logLength);
1736    readL2LogBuff();
1737 #endif
1738    RETVOID;
1739 }
1740
1741 /* This function will get tick from RLC/CL and will process logs
1742    according to tick threshold. Tick threshold is SOC specific */
1743 PUBLIC Void rlProcessTicks(void)
1744 {
1745    static U32 rlogTickCount;
1746    numTtiTicks++;
1747    if(++rlogTickCount >= RLOGTICKSCNTTOPRCL2LOGS)
1748    {
1749       rlogTickCount = 0;
1750       rlResetLogRateLmt(); /* Resetting rlog write count to 0 */ 
1751
1752       /* Tick count reached configured ticks to send L2 logs,
1753          Send existing log buffer to Application and create 
1754          new log buffer to write logs */
1755       if (SFndProcId() == TENB_L2_PROC_ID) 
1756       {
1757 #ifndef RLOG_ENABLE_TEXT_LOGGING
1758          processL2LogBuff(); /* This processing of log buffer is done on L2 only 
1759                                 This is SOC specific function and use to send
1760                                 log buffers to L3 and reset buffer pointer to 
1761                                 write logs */
1762 #else
1763      /* Write functions specific to Text logging in cpul */
1764 #endif                                
1765       }
1766       else
1767       {
1768          /* L3 specific functions */
1769       }
1770    }
1771    RETVOID;
1772 }
1773
1774 #ifndef RLOG_ENABLE_TEXT_LOGGING 
1775 //////////////////////////////////////////////////////////////////////////
1776 //  @Function    : readL2LogBuff 
1777 //  @Description : This function first validates received Log Buffer and
1778 //                 length from L2 and then writes L2 log buffer into L3 
1779 //                 circular buffer. After reading it invalidates cache and
1780 //                 also resets global Log buffer pointer and lenth variable.
1781 //  @in          : void
1782 //  @out         : void
1783 //////////////////////////////////////////////////////////////////////////
1784
1785 PUBLIC Void readL2LogBuff(void)
1786 {
1787    /* Validate global buffer pointer and length */
1788    U8 ret;
1789    ret = rlValidateL2LogBuf();
1790    if(ret != ROK)
1791    {
1792       printf(" Validation failed for log buffer/len \n");
1793       return;
1794    }
1795    g_writeCirBuf = 1;
1796    saveLogDataFromCpul(g_logBufRcvdFromL2 , g_logBufLenRcvdFromL2 );
1797    /* TODO: Write SOC Specific function to invalidate cache */
1798    rlInvalidateL2LogsInCache(g_logBufRcvdFromL2 - sizeof(g_logBufLenRcvdFromL2) , (g_logBufLenRcvdFromL2 + sizeof(g_logBufLenRcvdFromL2)));
1799    rlResetL2LogBuf();
1800    g_writeCirBuf = 0;
1801    RETVOID; 
1802 }
1803
1804 //////////////////////////////////////////////////////////////////////////
1805 //  @Function    : rlStopLogCountLimit
1806 //  @Description : This function validates L2 Log buffer,length, and start
1807 //                 L2 logging flag.
1808 //  @in          : void
1809 //  @out         : void
1810 //////////////////////////////////////////////////////////////////////////
1811
1812 #ifdef ANSI
1813 PUBLIC S16 rlValidateL2LogBuf(void)
1814 #else
1815 PUBLIC S16 rlValidateL2LogBuf(void)
1816 #endif
1817 {
1818    S16 ret = ROK;
1819    if(g_logBufRcvdFromL2 == NULL)
1820    {
1821       printf("Log-Buffer received from L2 is NULL \n");
1822       ret = RFAILED;
1823    }
1824    if(g_logBufLenRcvdFromL2 == 0)
1825    {
1826       printf("Log-Buffer Length received from L2 is 0 \n");
1827       ret = RFAILED;
1828    }
1829    if(startL2Logging == 0)
1830    {
1831       printf("startL2Logging flag is still inactive \n");
1832       ret = RFAILED;
1833    }
1834
1835    return(ret);
1836 }
1837
1838 //////////////////////////////////////////////////////////////////////////
1839 //  @Function    : rlStopLogCountLimit
1840 //  @Description : This function set global log Buffer pointer & length  
1841 //  @in          : l2LogBuf  -  Log Buffer to be set in global pointer
1842 //                 l2LogLen  -  Log length to be set in global lenth
1843 //  @out         : void 
1844 //////////////////////////////////////////////////////////////////////////
1845
1846 #ifdef ANSI
1847 PUBLIC void rlSetL2LogBuf
1848 (
1849 U8 *l2LogBuf,
1850 U32 l2logLen
1851 )
1852 #else
1853 PUBLIC void rlSetL2LogBuf(l2LogBuf,l2logLen)
1854 U8 *l2LogBuf;
1855 U32 l2logLen;
1856 #endif
1857 {
1858    g_logBufRcvdFromL2      = l2LogBuf;
1859    g_logBufLenRcvdFromL2   = l2logLen;
1860 }
1861
1862 //////////////////////////////////////////////////////////////////////////
1863 //  @Function    : rlStopLogCountLimit
1864 //  @Description : This function flushes global log Buffer pointer & length  
1865 //  @in          : void
1866 //  @out         : void
1867 //////////////////////////////////////////////////////////////////////////
1868
1869 #ifdef ANSI
1870 PUBLIC void rlResetL2LogBuf
1871 (
1872 void
1873 )
1874 #else
1875 PUBLIC void rlResetL2LogBuf(void)
1876 #endif
1877 {
1878    g_logBufRcvdFromL2      = NULL;
1879    g_logBufLenRcvdFromL2   = 0;
1880 }
1881
1882 #endif
1883
1884 //////////////////////////////////////////////////////////////////////////
1885 //  @Function    : rlStartLogCountLimit
1886 //  @Discription : This function will be called by EnbApp after Cell is UP.
1887 //                 This function start the log cnt limit. i.e Number of logs
1888 //                 getting logged into curcular will be restricted to 100 logs.
1889 //  @in          : void
1890 //  @out         : void
1891 //////////////////////////////////////////////////////////////////////////
1892
1893 void rlStartLogCountLimit(Void)
1894 {
1895    g_rlogWriteCount = 0;
1896    g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_START;
1897    printf("Start Log Restriction\n");
1898 }
1899
1900 //////////////////////////////////////////////////////////////////////////
1901 //  @Function    : rlStopLogCountLimit
1902 //  @Discription : This function will be called by EnbApp after Cell Shutdown
1903 //                 is triggered. This will enable to get all logs of shutdown.
1904 //                 This function stops the log cnt limit. i.e Restricition on
1905 //                 Number of logs getting logged into curcular will be removed
1906 //  @in          : void
1907 //  @out         : void
1908 //////////////////////////////////////////////////////////////////////////
1909
1910 void rlStopLogCountLimit(Void)
1911 {
1912    printf("Stop Log Restriction\n");
1913    g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
1914 }
1915
1916 //////////////////////////////////////////////////////////////////////////
1917 //  @Function    : rlResetLogRateLmt
1918 //  @Discription : This function will be called every 10 ms whenever 
1919 //                 application layer update the tti count. To reset the 
1920 //                 log rate control. And Enable logging for next 10 ms
1921 //  @in          : void
1922 //  @out         : void
1923 //////////////////////////////////////////////////////////////////////////
1924
1925 void rlResetLogRateLmt(void)
1926 {
1927     g_rlogWriteCount = 0;
1928     g_logsDropCnt = 0;
1929 }
1930
1931 void initGlbDataAtL2(void)
1932 {
1933    strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1934 }
1935
1936 /**********************************************************************
1937          End of file
1938 **********************************************************************/