Initial commit for Bronze release
[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 void sendToPostProcessor(const void* buf, U16 len)
1315 {
1316    if( send(g_nCliSocket, buf, len, 0 ) == -1 ) {
1317       perror("ERROR Sending");
1318       closeConnection(g_nCliSocket);
1319       g_nCliSocket = 0;
1320    }
1321 }
1322 void logLevS( LOGID logId, R_LOG_LEVEL logLevel, const char* str, ...)
1323 {
1324    ARGDATA arg; U16 bufsize;
1325
1326
1327    RLOG_SAVE_TIME(arg.logData.logTime);
1328
1329    arg.logData.logId = logId;
1330    arg.logData.argType = LOG_ARG_STR;
1331    arg.logData.logLevel = logLevel;
1332    arg.logData.numOfArgs = 1;
1333    arg.logData.len = strlen(str);
1334
1335    memcpy(arg.buf, (const void*)str, arg.logData.len);
1336    bufsize = sizeof(LOGDATA)+arg.logData.len;
1337
1338    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1339 }
1340
1341 void logLevH( LOGID logId, R_LOG_LEVEL logLevel, PSTR hex, int hexlen, ...)
1342 {
1343    ARGDATA arg;
1344    int bufsize;
1345
1346    RLOG_SAVE_TIME(arg.logData.logTime);
1347
1348    arg.logData.logId = logId;
1349    arg.logData.argType = LOG_ARG_HEX;
1350    arg.logData.logLevel = logLevel;
1351    arg.logData.numOfArgs = 1;
1352    arg.logData.len = hexlen;
1353
1354    memcpy(arg.buf, (const void*)hex, hexlen);
1355    bufsize = sizeof(LOGDATA)+arg.logData.len;
1356
1357    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1358 }
1359 void logLevE(LOGID logId, R_LOG_LEVEL logLevel, R_SPL_ARG splType, U32 splVal, U32 arg1, U32 arg2,
1360       U32 arg3, U32 arg4, ...)
1361 {
1362    SPL_ARGDATA arg;
1363    int bufsize;
1364
1365    RLOG_SAVE_TIME(arg.logData.logTime);
1366
1367    arg.logData.logId = logId;
1368    arg.logData.argType = LOG_ARG_SPL;
1369    arg.logData.logLevel = logLevel;
1370    if( arg1 ) {
1371       arg.logData.numOfArgs = (arg2 == 0 ) ? 1 : (arg3==0 ? 2 : (arg4==0 ? 3 : 4));
1372    } else {
1373       arg.logData.numOfArgs = 0;
1374    }
1375
1376    arg.logData.len  = sizeof(u_int8_t) + sizeof(U32) + (sizeof(U32)*arg.logData.numOfArgs);
1377
1378    arg.splEnum = splType;
1379    arg.splArg = splVal;
1380    arg.arg1 = arg1;
1381    arg.arg2 = arg2;
1382    arg.arg3 = arg3;
1383    arg.arg4 = arg4;
1384
1385    bufsize = sizeof(LOGDATA)+arg.logData.len;
1386
1387    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1388 }
1389
1390 void logLev0( LOGID logId, R_LOG_LEVEL logLevel, ...)
1391 {
1392    //LOGDATA logData;
1393    ARG4DATA arg;
1394
1395    RLOG_SAVE_TIME(arg.logData.logTime);
1396
1397    arg.logData.logId = logId;
1398    arg.logData.argType = LOG_ARG_STR;
1399    arg.logData.logLevel = logLevel;
1400    arg.logData.numOfArgs = 0;
1401    arg.logData.len = 0;
1402
1403    saveLogData((const void*)&arg, sizeof(LOGDATA),g_rlogPositionIndex++);       
1404 }
1405
1406 void logLev1( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, ...)
1407 {
1408    ARG4DATA arg;
1409    int bufsize;
1410
1411    RLOG_SAVE_TIME(arg.logData.logTime);
1412
1413    arg.logData.logId = logId;
1414    arg.logData.argType = LOG_ARG_INT;
1415    arg.logData.logLevel = logLevel;
1416    arg.logData.numOfArgs = 1;
1417    arg.logData.len = sizeof(U32);
1418
1419    arg.arg1 = arg1;
1420    bufsize = sizeof(LOGDATA)+arg.logData.len;
1421
1422    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1423 }
1424 void logLev2( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, ...)
1425 {
1426    ARG4DATA arg;
1427    int bufsize;
1428
1429    RLOG_SAVE_TIME(arg.logData.logTime);
1430
1431    arg.logData.logId = logId;
1432    arg.logData.argType = LOG_ARG_INT;
1433    arg.logData.logLevel = logLevel;
1434    arg.logData.numOfArgs = 2;
1435    arg.logData.len =  2 * sizeof(U32);
1436
1437    arg.arg1 = arg1;
1438    arg.arg2 = arg2;
1439
1440    bufsize = sizeof(LOGDATA)+arg.logData.len;
1441
1442    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1443 }
1444 void logLev3( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, ...)
1445 {
1446    ARG4DATA arg;
1447    int bufsize;
1448
1449    RLOG_SAVE_TIME(arg.logData.logTime);
1450
1451    arg.logData.logId = logId;
1452    arg.logData.argType = LOG_ARG_INT;
1453    arg.logData.logLevel = logLevel;
1454    arg.logData.numOfArgs = 3;
1455    arg.logData.len = 3 * sizeof(U32);
1456
1457    arg.arg1 = arg1;
1458    arg.arg2 = arg2;
1459    arg.arg3 = arg3;
1460
1461    bufsize = sizeof(LOGDATA)+arg.logData.len;
1462
1463    saveLogData((const void*)&arg, bufsize,g_rlogPositionIndex++);       
1464 }
1465 void logLev4( LOGID logId, R_LOG_LEVEL logLevel, U32 arg1, U32 arg2, U32 arg3, U32 arg4, ...)
1466 {
1467    ARG4DATA arg;
1468
1469    RLOG_SAVE_TIME(arg.logData.logTime);
1470
1471    arg.logData.logId = logId;
1472    arg.logData.argType = LOG_ARG_INT;
1473    arg.logData.logLevel = logLevel;
1474    arg.logData.numOfArgs = 4;
1475    arg.logData.len = 4 * sizeof(U32);
1476
1477    arg.arg1 = arg1;
1478    arg.arg2 = arg2;
1479    arg.arg3 = arg3;
1480    arg.arg4 = arg4;
1481
1482    saveLogData((const void*)&arg, sizeof(ARG4DATA),g_rlogPositionIndex++);      
1483 }
1484
1485 #endif /* BINARY LOGGING */
1486
1487 #if defined(RLOG_ENABLE_TEXT_LOGGING) 
1488 struct tm* getTime(int* microseconds)
1489 {
1490 #ifndef SS_LINUX
1491    struct timespec ptime;
1492 #else
1493    struct timeval ptime;
1494 #endif
1495
1496 #ifndef SS_LINUX
1497    clock_gettime(CLOCK_REALTIME, &ptime);
1498    *microseconds = ptime.tv_nsec / 1000;
1499 #else
1500    gettimeofday(&ptime, NULL);
1501    *microseconds = ptime.tv_usec;
1502 #endif
1503
1504    /* Obtain the time of day, and convert it to a tm struct. --*/
1505    return localtime (&ptime.tv_sec);
1506 }
1507 #elif !defined(RLOG_USE_TTI_LOGGING)
1508 static void getLogTime(LOGTIME* logTime)
1509 {
1510 #ifndef SS_LINUX
1511    struct timespec ptime;
1512 #else
1513    struct timeval ptime;
1514 #endif
1515
1516 #ifndef SS_LINUX
1517    clock_gettime(CLOCK_REALTIME, &ptime);
1518    logTime->ms_tti = ptime.tv_nsec / 1000;
1519 #else
1520    gettimeofday(&ptime, NULL);
1521    logTime->ms_tti = ptime.tv_usec/1000;
1522 #endif
1523
1524    logTime->tv_sec = ptime.tv_sec;
1525 }
1526
1527 #endif
1528
1529 void getLogTimeStr(char* ts)
1530 {
1531 #ifndef SS_LINUX
1532    struct timespec ptime;
1533 #else
1534    struct timeval ptime;
1535 #endif
1536    struct tm* tm;
1537    int microseconds;
1538
1539 #ifndef SS_LINUX
1540    clock_gettime(CLOCK_REALTIME, &ptime);
1541    microseconds = ptime.tv_nsec / 1000;
1542 #else
1543    gettimeofday(&ptime, NULL);
1544    microseconds = ptime.tv_usec/1000;
1545 #endif
1546
1547    /* Obtain the time of day, and convert it to a tm struct. --*/
1548    tm = localtime (&ptime.tv_sec);
1549
1550    if (tm) sprintf(ts,"%d_%d_%d_%d_%d_%d.%03d", tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, 
1551          tm->tm_hour, tm->tm_min,tm->tm_sec,microseconds);
1552 }
1553 ///////////////////////////////////////////////////////////////////////////////////////////////////
1554 //
1555 //
1556 ///////////////////////////////////////////////////////////////////////////////////////////////////
1557
1558 void rlEnaBleBufferedIO(void)
1559 {
1560    setvbuf (g_fp, NULL, _IOFBF, 1024 );
1561 }
1562
1563 void createNewLogFile()
1564 {
1565    FILE *fp, *prev_fp = g_fp;
1566    char curTime[RLOG_MAX_TIME_STAMP]; int fd;
1567    char *temptr;
1568    /* Fix for CR ccpu00143040 */
1569    DIR *dir = NULLP;
1570
1571    /* get current time, when file is created */
1572    getLogTimeStr(curTime); 
1573    temptr = strchr(curTime, '.');
1574    if (temptr != NULLP)
1575    {
1576       *temptr = 0;
1577    }
1578    /* Fix for CR ccpu00143040 */
1579    dir  = opendir(g_logDir);
1580    if ( dir == NULLP )
1581    { 
1582       mkdir(g_logDir, O_RDWR);
1583    }
1584    else
1585    {
1586       closedir(dir);
1587    }
1588    /* remove old file from system */
1589    if( g_fileList[g_nCurrFileIdx][0] != '\0' )
1590       unlink(g_fileList[g_nCurrFileIdx]);
1591
1592 #ifdef RLOG_ENABLE_TEXT_LOGGING
1593    /* create file name, Example-> dbglog_2013_08_11_15_30_00 */
1594    snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.txt",g_logDir, g_fileName, curTime );
1595    fp = fopen(g_fileList[g_nCurrFileIdx], "w+");
1596 #else
1597    snprintf(g_fileList[g_nCurrFileIdx],MAX_FILENAME_LEN, "%s/%s_%s.bin",g_logDir, g_fileName, curTime );
1598    fp = fopen(g_fileList[g_nCurrFileIdx], "ab+");
1599 #endif
1600
1601    if( fp == NULL ) {
1602       fprintf(stderr, "Failed to open log file %s\n", g_fileList[g_nCurrFileIdx]);
1603       return;
1604    }
1605
1606    fd = fileno(fp);
1607
1608    g_fp = fp;
1609    g_fd = fd;
1610
1611    if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1612       fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1613    }
1614
1615 #ifdef RLOG_ENABLE_TEXT_LOGGING
1616    setvbuf ( fp , NULL, _IOLBF, 1024 );
1617 #else
1618    setvbuf ( fp , NULL, _IONBF, 1024 );
1619 #endif
1620
1621 #ifndef RLOG_ENABLE_TEXT_LOGGING
1622    storeFileHeader(fp);
1623 #endif
1624
1625    if( prev_fp != NULL )
1626       fclose(prev_fp);
1627
1628    if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1629       g_nCurrFileIdx = 0;
1630
1631 #ifndef RLOG_ENABLE_TEXT_LOGGING
1632 #ifdef RLOG_USE_TTI_LOGGING
1633    logLev1(L_TIME_REFERENCE, L_ALWAYS, (U32)time(NULL));
1634 #endif
1635 #endif
1636 }
1637
1638 void createL2LogFile()
1639 {
1640    FILE *fp, *prev_fp = g_fp;
1641    int fd;
1642    char file[MAX_FILENAME_LEN];
1643
1644    strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1645    strncpy(g_fileName, "dbglog_l2", MAX_FILENAME_LEN);
1646    snprintf(file, sizeof(file), "%s/%s.txt", g_logDir, g_fileName);
1647
1648    fp = fopen(file, "w+");
1649    if( fp == NULL) {
1650       printf("Failed to open file %s", file);
1651       _exit(0);
1652    }
1653
1654    printf("Created L2 bin file FD=%s\n", g_fileName);
1655
1656    setvbuf (fp , NULL, _IONBF, 1024 );
1657
1658    fd = fileno(fp);
1659
1660    g_fp = fp;
1661    g_fd = fd;
1662
1663    if( fcntl(g_fd, F_SETFL, fcntl(g_fd, F_GETFL, 0) | O_NONBLOCK | O_ASYNC ) == -1 ) {
1664       fprintf(stderr, "RLOG: Cannot enable Buffer IO or make file non-blocking\n");
1665    }
1666
1667    setvbuf ( fp , NULL, _IOLBF, 1024 );
1668
1669    if( prev_fp != NULL )
1670       fclose(prev_fp);
1671
1672    if( ++g_nCurrFileIdx == g_nMaxLogFiles )
1673       g_nCurrFileIdx = 0;
1674
1675
1676 }
1677
1678 //////////////////////////////////////////////////////////////////////////
1679 //  @Function    : rlUdateRlogTti
1680 //  @Discription : This function will be called every 10 ms whenever 
1681 //                 application layer update the tti count
1682 //  @in          : void
1683 //  @out         : void
1684 //////////////////////////////////////////////////////////////////////////
1685 void rlUpdateRlogTti(Void)
1686 {
1687 #ifndef RLOG_ENABLE_TEXT_LOGGING
1688 #ifdef RLOG_USE_TTI_LOGGING
1689    logLev1(L_TIME_TTI_UPDT, L_ALWAYS, (U32)time(NULL));
1690 #endif
1691 #endif
1692 }
1693
1694 /* This function processes log buffer received from L2
1695    mBuf is Received from L2 through SPstTsk. This function
1696    extracts buffer pointer and logLen and then these logs 
1697    written to L3 log buffer/file. 
1698    This function is called in application layer when EVTL2LOGBUF
1699    event is recieved from ssi
1700 */
1701
1702 #ifdef ANSI
1703 PUBLIC Void rlProcessLogBufFromL2
1704 (
1705  void *mBuf
1706  )
1707 #else
1708 PUBLIC Void rlProcessLogBufFromL2(mBuf)
1709    void *mBuf;
1710 #endif
1711 {
1712 #ifndef RLOG_ENABLE_TEXT_LOGGING 
1713    U32 logLength;
1714    Data* logPtr;
1715    startL2Logging = 1;
1716    if(mBuf == NULL)
1717    {
1718       printf("NULL MBUF received \n");
1719       RETVOID;
1720    }
1721    /* Get Buffer pointer and length. This is SOC specific function which
1722       will extract Log-Buffer pointer and length from mBuf */
1723    rlGetL2LogBufPtr(mBuf, &logLength,&logPtr);
1724    rlSetL2LogBuf(logPtr,logLength);
1725    readL2LogBuff();
1726 #endif
1727    RETVOID;
1728 }
1729
1730 /* This function will get tick from RLC/CL and will process logs
1731    according to tick threshold. Tick threshold is SOC specific */
1732 PUBLIC Void rlProcessTicks(void)
1733 {
1734    static U32 rlogTickCount;
1735    numTtiTicks++;
1736    if(++rlogTickCount >= RLOGTICKSCNTTOPRCL2LOGS)
1737    {
1738       rlogTickCount = 0;
1739       rlResetLogRateLmt(); /* Resetting rlog write count to 0 */ 
1740
1741       /* Tick count reached configured ticks to send L2 logs,
1742          Send existing log buffer to Application and create 
1743          new log buffer to write logs */
1744       if (SFndProcId() == TENB_L2_PROC_ID) 
1745       {
1746 #ifndef RLOG_ENABLE_TEXT_LOGGING
1747          processL2LogBuff(); /* This processing of log buffer is done on L2 only 
1748                                 This is SOC specific function and use to send
1749                                 log buffers to L3 and reset buffer pointer to 
1750                                 write logs */
1751 #else
1752      /* Write functions specific to Text logging in cpul */
1753 #endif                                
1754       }
1755       else
1756       {
1757          /* L3 specific functions */
1758       }
1759    }
1760    RETVOID;
1761 }
1762
1763 #ifndef RLOG_ENABLE_TEXT_LOGGING 
1764 //////////////////////////////////////////////////////////////////////////
1765 //  @Function    : readL2LogBuff 
1766 //  @Description : This function first validates received Log Buffer and
1767 //                 length from L2 and then writes L2 log buffer into L3 
1768 //                 circular buffer. After reading it invalidates cache and
1769 //                 also resets global Log buffer pointer and lenth variable.
1770 //  @in          : void
1771 //  @out         : void
1772 //////////////////////////////////////////////////////////////////////////
1773
1774 PUBLIC Void readL2LogBuff(void)
1775 {
1776    /* Validate global buffer pointer and length */
1777    U8 ret;
1778    ret = rlValidateL2LogBuf();
1779    if(ret != ROK)
1780    {
1781       printf(" Validation failed for log buffer/len \n");
1782       return;
1783    }
1784    g_writeCirBuf = 1;
1785    saveLogDataFromCpul(g_logBufRcvdFromL2 , g_logBufLenRcvdFromL2 );
1786    /* TODO: Write SOC Specific function to invalidate cache */
1787    rlInvalidateL2LogsInCache(g_logBufRcvdFromL2 - sizeof(g_logBufLenRcvdFromL2) , (g_logBufLenRcvdFromL2 + sizeof(g_logBufLenRcvdFromL2)));
1788    rlResetL2LogBuf();
1789    g_writeCirBuf = 0;
1790    RETVOID; 
1791 }
1792
1793 //////////////////////////////////////////////////////////////////////////
1794 //  @Function    : rlStopLogCountLimit
1795 //  @Description : This function validates L2 Log buffer,length, and start
1796 //                 L2 logging flag.
1797 //  @in          : void
1798 //  @out         : void
1799 //////////////////////////////////////////////////////////////////////////
1800
1801 #ifdef ANSI
1802 PUBLIC S16 rlValidateL2LogBuf(void)
1803 #else
1804 PUBLIC S16 rlValidateL2LogBuf(void)
1805 #endif
1806 {
1807    S16 ret = ROK;
1808    if(g_logBufRcvdFromL2 == NULL)
1809    {
1810       printf("Log-Buffer received from L2 is NULL \n");
1811       ret = RFAILED;
1812    }
1813    if(g_logBufLenRcvdFromL2 == 0)
1814    {
1815       printf("Log-Buffer Length received from L2 is 0 \n");
1816       ret = RFAILED;
1817    }
1818    if(startL2Logging == 0)
1819    {
1820       printf("startL2Logging flag is still inactive \n");
1821       ret = RFAILED;
1822    }
1823
1824    return(ret);
1825 }
1826
1827 //////////////////////////////////////////////////////////////////////////
1828 //  @Function    : rlStopLogCountLimit
1829 //  @Description : This function set global log Buffer pointer & length  
1830 //  @in          : l2LogBuf  -  Log Buffer to be set in global pointer
1831 //                 l2LogLen  -  Log length to be set in global lenth
1832 //  @out         : void 
1833 //////////////////////////////////////////////////////////////////////////
1834
1835 #ifdef ANSI
1836 PUBLIC void rlSetL2LogBuf
1837 (
1838 U8 *l2LogBuf,
1839 U32 l2logLen
1840 )
1841 #else
1842 PUBLIC void rlSetL2LogBuf(l2LogBuf,l2logLen)
1843 U8 *l2LogBuf;
1844 U32 l2logLen;
1845 #endif
1846 {
1847    g_logBufRcvdFromL2      = l2LogBuf;
1848    g_logBufLenRcvdFromL2   = l2logLen;
1849 }
1850
1851 //////////////////////////////////////////////////////////////////////////
1852 //  @Function    : rlStopLogCountLimit
1853 //  @Description : This function flushes global log Buffer pointer & length  
1854 //  @in          : void
1855 //  @out         : void
1856 //////////////////////////////////////////////////////////////////////////
1857
1858 #ifdef ANSI
1859 PUBLIC void rlResetL2LogBuf
1860 (
1861 void
1862 )
1863 #else
1864 PUBLIC void rlResetL2LogBuf(void)
1865 #endif
1866 {
1867    g_logBufRcvdFromL2      = NULL;
1868    g_logBufLenRcvdFromL2   = 0;
1869 }
1870
1871 #endif
1872
1873 //////////////////////////////////////////////////////////////////////////
1874 //  @Function    : rlStartLogCountLimit
1875 //  @Discription : This function will be called by EnbApp after Cell is UP.
1876 //                 This function start the log cnt limit. i.e Number of logs
1877 //                 getting logged into curcular will be restricted to 100 logs.
1878 //  @in          : void
1879 //  @out         : void
1880 //////////////////////////////////////////////////////////////////////////
1881
1882 void rlStartLogCountLimit(Void)
1883 {
1884    g_rlogWriteCount = 0;
1885    g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_START;
1886    printf("Start Log Restriction\n");
1887 }
1888
1889 //////////////////////////////////////////////////////////////////////////
1890 //  @Function    : rlStopLogCountLimit
1891 //  @Discription : This function will be called by EnbApp after Cell Shutdown
1892 //                 is triggered. This will enable to get all logs of shutdown.
1893 //                 This function stops the log cnt limit. i.e Restricition on
1894 //                 Number of logs getting logged into curcular will be removed
1895 //  @in          : void
1896 //  @out         : void
1897 //////////////////////////////////////////////////////////////////////////
1898
1899 void rlStopLogCountLimit(Void)
1900 {
1901    printf("Stop Log Restriction\n");
1902    g_rlLogCntLimit = RL_LOG_COUNT_LIMIT_STOP;
1903 }
1904
1905 //////////////////////////////////////////////////////////////////////////
1906 //  @Function    : rlResetLogRateLmt
1907 //  @Discription : This function will be called every 10 ms whenever 
1908 //                 application layer update the tti count. To reset the 
1909 //                 log rate control. And Enable logging for next 10 ms
1910 //  @in          : void
1911 //  @out         : void
1912 //////////////////////////////////////////////////////////////////////////
1913
1914 void rlResetLogRateLmt(void)
1915 {
1916     g_rlogWriteCount = 0;
1917     g_logsDropCnt = 0;
1918 }
1919
1920 void initGlbDataAtL2(void)
1921 {
1922    strncpy(g_logDir, "/root/", MAX_FILENAME_LEN);
1923 }
1924
1925 /**********************************************************************
1926          End of file
1927 **********************************************************************/