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