Re-organized sub-directory by category
[staging/basesystem.git] / service / system / logger_service / server / src / ss_logger_error_event_cfg.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 ///////////////////////////////////////////////////////////////////////////////
18 /// \ingroup  tag_SS_LoggerService
19 /// \brief    This file supports error event logging configuration.
20 ///
21 ///////////////////////////////////////////////////////////////////////////////
22 #include <string.h>
23 #include <native_service/frameworkunified_framework_if.h>
24 #include <system_service/ss_logger_service.h>
25 #include <system_service/ss_services.h>
26 #include <system_service/ss_templates.h>
27 #include <vector>
28 #include "loggerservicedebug_loggerservicelog.h"
29 #include "ss_logger_error_event_cfg.h"
30
31 enum ARTIFACT_BIT {
32   ARTIFACT_BIT_NONE = 0x00000000,
33   ARTIFACT_BIT_LOGGERSERVICE_DEBUG_LOG = 1 << (UI_32) eArtifactIdInterfaceunifiedDebugLog,
34   ARTIFACT_BIT_TRANSMIT_LOG = 1 << (UI_32) eArtifactIdTransmitLog,
35   ARTIFACT_BIT_PERFORMANCE_LOG = 1 << (UI_32) eArtifactIdPerformanceLog,
36   ARTIFACT_BIT_BOOT_MICRO_LOG = 1 << (UI_32) eArtifactIdBootMicroLog,
37   ARTIFACT_BIT_SYSTEM_DATA_LOG = 1 << (UI_32) eArtifactIdSystemDataCsv,
38   ARTIFACT_BIT_SHOW_MEM_TXT = 1 << (UI_32) eArtifactIdShowMemTxt,
39   ARTIFACT_BIT_PROCESS_CORE = 1 << (UI_32) eArtifactIdProcessCore,
40   ARTIFACT_BIT_DEBUG_DUMP_LOG = 1 << (UI_32) eArtifactIdDebugDumpLog,
41   ARTIFACT_BIT_KERNEL_LOG = 1 << (UI_32) eArtifactIdKernelLog,
42   ARTIFACT_BIT_KERNEL_BOOT_LOG = 1 << (UI_32) eArtifactIdKernelBootLog,
43   ARTIFACT_BIT_DRINITIAL_LOG = 1 << (UI_32) eArtifactIdDRInitialLog,
44   ARTIFACT_BIT_DRLOCATION_LOG = 1 << (UI_32) eArtifactIdDRLocationLog,
45   ARTIFACT_BIT_CHLM_MC_LOGS = 1 << (UI_32) eArtifactIdCpuHighLoadMonteCarloLogs,
46   ARTIFACT_BIT_METACORE_LOGS = 1 << (UI_32) eArtifactIdMetaCoreLogs,
47   ARTIFACT_BIT_SCREEN_SHOT = 1 << (UI_32) eArtifactIdScreenShot,
48   ARTIFACT_BIT_CMS_LOGS = 1 << (UI_32) eArtifactIdCmsLogs,
49   ARTIFACT_BIT_INTERNAL_DTC_LOG = 1 << (UI_32) eArtifactIDInternalDTC,
50   ARTIFACT_BIT_CLEAR_ALL_LOG = 1 << (UI_32) eArtifactIdClearAllLog,
51   ARTIFACT_BIT_NAVI_LOG = 1 << (UI_32) eArtifactIdNaviLog,
52   ARTIFACT_BIT_DEBUG_FOLDER_CONTENT = 1
53       << (UI_32) eArtifactIdDebugFolderContent,
54   ARTIFACT_BIT_DEBUG_FOLDER2_CONTENT = 1
55       << (UI_32) eArtifactIdDebugFolder2Content,
56   ARTIFACT_BIT_COM_LOG = 1 << (UI_32) eArtifactIdComDebugLog,
57   ARTIFACT_BIT_PSTORE_LOG = 1 << (UI_32) eArtifactIdPstoreLog
58 };
59
60 //////////////////////////////////////////////////////////////////////////////////////////
61 /////  Definition for Logging Artifact Filepaths
62 //////////////////////////////////////////////////////////////////////////////////////////
63 const char LAF_DEBUG_FOLDER[] = "/nv/BS/ss/logger_service/rwdata";
64 const char LAF_DEBUG_FOLDER2[] = "/nv/BS/ss/logger_service/rwdata/log2";
65 const char LAF_MONTECARLO_FN[] = "/tmp/MonteCarlo";
66 const char LAF_METACORE_FN[] = "/tmp/MetaCore";
67 const char LAF_CMS_FN[] = "/tmp/cms";
68 const char LAF_INT_DTC_FN[] = "/tmp/dtc_error.log";
69 const char LAF_LOGGERSERVICELOG_COM[] = "/ramd/BS/ss/logger_service/rwdata/frameworkunifiedlog/communication";
70 const char LAF_KERNEL_BOOT_FN[] = "/ramd/BS/ss/logger_service/rwdata/frameworkunifiedlog/kernelboot.log";
71 const char LAF_PSTORELOG[] = "/dev/pstore";
72
73 #define ARTIFACT_BIT_ALL_OUTPUT_LOG  (ARTIFACT_BIT_LOGGERSERVICE_DEBUG_LOG |  \
74               ARTIFACT_BIT_DEBUG_DUMP_LOG |  \
75               ARTIFACT_BIT_SYSTEM_DATA_LOG |  \
76               ARTIFACT_BIT_SHOW_MEM_TXT |  \
77               ARTIFACT_BIT_COM_LOG |    \
78               ARTIFACT_BIT_KERNEL_LOG |    \
79                 ARTIFACT_BIT_KERNEL_BOOT_LOG  | \
80               ARTIFACT_BIT_SCREEN_SHOT |  \
81               ARTIFACT_BIT_TRANSMIT_LOG |  \
82               ARTIFACT_BIT_PERFORMANCE_LOG |  \
83               ARTIFACT_BIT_DRINITIAL_LOG |  \
84               ARTIFACT_BIT_DRLOCATION_LOG |  \
85               ARTIFACT_BIT_CHLM_MC_LOGS |  \
86               ARTIFACT_BIT_INTERNAL_DTC_LOG |  \
87               ARTIFACT_BIT_METACORE_LOGS |      \
88               ARTIFACT_BIT_PSTORE_LOG)
89
90 TLoggingArtifactCfg CErrorEventCfg::m_loggerErrorEventCfgTbl[eErrorEventTypeMaxValue] = {
91     { eErrorEventTypeProcessCrash, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
92         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
93
94     { eErrorEventTypeProcessExit, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
95         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
96
97     { eErrorEventTypeHeartBeatFailure, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
98         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
99
100     { eErrorEventTypeSystemLowMemory, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
101         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
102
103     { eErrorEventTypeUserInvokedUserForceReset, { ARTIFACT_BIT_ALL_OUTPUT_LOG,
104     (EVENT_BIT_NONE) } },
105
106     { eErrorEventTypeUserInvokedCollectAllLogs, { ARTIFACT_BIT_ALL_OUTPUT_LOG,
107     (EVENT_BIT_POPUP | EVENT_BIT_CAN_NOTIFICATION) } },
108
109     { eErrorEventTypeUserInvokedCollectScreenShot, { (ARTIFACT_BIT_NONE
110         | ARTIFACT_BIT_SCREEN_SHOT),
111
112     (EVENT_BIT_POPUP | EVENT_BIT_CAN_NOTIFICATION) } },
113
114     { eErrorEventTypeUserInvokedCollectInterfaceunifiedLogs, { ARTIFACT_BIT_ALL_OUTPUT_LOG,
115     (EVENT_BIT_POPUP | EVENT_BIT_CAN_NOTIFICATION) } },
116
117     { eErrorEventTypeUserInvokedCollectDevLogs, { ARTIFACT_BIT_ALL_OUTPUT_LOG,
118     (EVENT_BIT_NONE) }
119     },
120
121     { eErrorEventTypeBootMicroReset, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
122         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
123
124     { eErrorEventTypeEelExport, { ARTIFACT_BIT_ALL_OUTPUT_LOG,
125     (EVENT_BIT_POPUP | EVENT_BIT_CAN_NOTIFICATION) } },
126
127     { eErrorEventTypeInterfaceunifiedEmmcLogs, { (ARTIFACT_BIT_DEBUG_FOLDER_CONTENT
128         | ARTIFACT_BIT_DEBUG_FOLDER2_CONTENT),
129
130     (EVENT_BIT_POPUP | EVENT_BIT_CAN_NOTIFICATION) } },
131
132     { eErrorEventTypeDiagEvent, { ARTIFACT_BIT_ALL_OUTPUT_LOG,
133     (EVENT_BIT_DIAG) } },
134
135     { eErrorEventTypeCanEvent, { ARTIFACT_BIT_ALL_OUTPUT_LOG,
136     (EVENT_BIT_CAN_NOTIFICATION) } },
137
138     { eErrorEventTypeDtcEvent, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
139         | ARTIFACT_BIT_NAVI_LOG),
140
141     (EVENT_BIT_CAN_NOTIFICATION) } },
142
143     { eErrorEventTypeModConnFailed, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
144         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
145
146     { eErrorEventTypeStartRespFailed, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
147         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
148
149     { eErrorEventTypeModuleInvokedResetRequest, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
150         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
151
152     { eErrorEventTypeModuleInvokedCollectDebugLogs,
153         { (ARTIFACT_BIT_ALL_OUTPUT_LOG | ARTIFACT_BIT_NAVI_LOG),
154             (EVENT_BIT_NONE) } },
155
156     { eErrorEventTypeUserInvokedClearLogs, { (ARTIFACT_BIT_NONE
157         | ARTIFACT_BIT_CLEAR_ALL_LOG), (EVENT_BIT_NONE) } },
158
159     { eErrorEventTypeUserInvokedCollectNaviLog, { (ARTIFACT_BIT_NONE
160         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
161
162     { eErrorEventTypeGroupRelaunch, { (ARTIFACT_BIT_ALL_OUTPUT_LOG
163         | ARTIFACT_BIT_NAVI_LOG), (EVENT_BIT_NONE) } },
164
165     { eErrorEventTypeReserved1, { (ARTIFACT_BIT_NONE), (EVENT_BIT_NONE) } },
166
167     { eErrorEventTypeReserved2, { (ARTIFACT_BIT_NONE), (EVENT_BIT_NONE) } },
168
169     { eErrorEventTypeReserved3, { (ARTIFACT_BIT_NONE), (EVENT_BIT_NONE) } } };
170
171 TLoggingArtifact CErrorEventCfg::m_loggerErrorArtifactCfgTbl[eArtifactIdMaxValue] = {  // LCOV_EXCL_BR_LINE 11:Unexpected branch
172     /*Artifact ID    Owner    Timeout Callback Type    Path CallBack Function    Delete tmp artifact*/
173     { eArtifactIdInterfaceunifiedDebugLog, { SERVICE_LOGGER, 5000, { eCbTypeFunction, "", SSLogger_SendtoSelf }, TRUE } },
174     { eArtifactIdTransmitLog, { SERVICE_LOGGER, 5000, { eCbTypeFunction, "", SSLogger_SendtoSelf }, TRUE } },
175     { eArtifactIdPerformanceLog, { SERVICE_LOGGER, 5, { eCbTypeFunction, "", SSLogger_SendtoSelf }, FALSE } },
176     { eArtifactIdBootMicroLog, { SERVICE_SYSMANAGER, 1000, { eCbTypeFunction, "", SSLogger_SendtoSM }, TRUE } },
177     { eArtifactIdSystemDataCsv, { SERVICE_SYSMANAGER, 5000, { eCbTypeFunction, "", SSLogger_SendtoSM }, TRUE } },
178     { eArtifactIdShowMemTxt, { SERVICE_SYSMANAGER, 8000, { eCbTypeFunction, "", SSLogger_SendtoSM }, TRUE } },
179     { eArtifactIdProcessCore, { SERVICE_SYSMANAGER, 5000, { eCbTypeFunction, "", SSLogger_SendtoSM }, TRUE } },
180     { eArtifactIdDebugDumpLog, { SERVICE_SYSMANAGER, 4000, { eCbTypeFunction, "", SSLogger_SendtoSM }, TRUE } },
181     { eArtifactIdScreenShot, { SERVICE_LOGGER, 1100, { eCbTypeFunction, "", SSLogger_SendtoSelf }, TRUE } },
182     { eArtifactIdDebugFolderContent, { SERVICE_LOGGER, 50000, { eCbTypePath, LAF_DEBUG_FOLDER, NULL }, FALSE } },
183     { eArtifactIdDebugFolder2Content, { SERVICE_LOGGER, 50000, { eCbTypePath, LAF_DEBUG_FOLDER2, NULL }, FALSE } },
184     { eArtifactIdKernelLog, { SERVICE_LOGGER, 5000, { eCbTypeFunction, "", SSLogger_SendtoSelf }, TRUE } },
185     { eArtifactIdKernelBootLog, { SERVICE_LOGGER, 5000, { eCbTypePath, LAF_KERNEL_BOOT_FN, NULL }, FALSE } },
186     { eArtifactIdDRInitialLog, { SERVICE_LOGGER, 500, { eCbTypeFunction, "", SSLogger_SendtoSelf }, TRUE } },
187     { eArtifactIdDRLocationLog, { SERVICE_LOGGER, 500, { eCbTypeFunction, "", SSLogger_SendtoSelf }, TRUE } },
188     { eArtifactIdCpuHighLoadMonteCarloLogs, { SERVICE_LOGGER, 50, { eCbTypePath, LAF_MONTECARLO_FN, NULL }, TRUE } },
189     { eArtifactIdMetaCoreLogs, { SERVICE_LOGGER, 50, { eCbTypePath, LAF_METACORE_FN, NULL }, TRUE } },
190     { eArtifactIdCmsLogs, { SERVICE_LOGGER, 500, { eCbTypePath, LAF_CMS_FN, NULL }, TRUE } },
191     { eArtifactIDInternalDTC, { SERVICE_LOGGER, 500, { eCbTypePath, LAF_INT_DTC_FN, NULL }, TRUE } },
192     { eArtifactIdComDebugLog, { SERVICE_LOGGER, 500, { eCbTypePath, LAF_LOGGERSERVICELOG_COM, NULL }, FALSE } },
193     { eArtifactIdPstoreLog, { SERVICE_LOGGER, 50, { eCbTypePath, LAF_PSTORELOG, NULL }, FALSE } },
194     { eArtifactIdClearAllLog, { SERVICE_LOGGER, 500, { eCbTypeFunction, "", SSLogger_SendtoSelf }, FALSE } },
195     { eArtifactIdNaviLog, { SERVICE_LOGGER, 5000, { eCbTypeFunction, "", SSLogger_SendtoSelf }, FALSE } },
196 };  // LCOV_EXCL_BR_LINE 11:Unexpected branch
197
198 CErrorEventCfg::CErrorEventCfg() {
199   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
200   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
201 }
202
203 CErrorEventCfg::~CErrorEventCfg() {  // LCOV_EXCL_START 14:globle instance
204   AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
205   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
206   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
207 }
208 // LCOV_EXCL_STOP
209
210 EFrameworkunifiedStatus CErrorEventCfg::Initialize(CLoggerCfg* p_logger_cfg) {
211   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
212   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
213   UI_32 l_cnt;
214
215   m_ext_log_num = 0;
216   ExternalLogList ext_log = p_logger_cfg->GetExternalLogList();
217
218   for (l_cnt = 0; l_cnt < eArtifactIdMaxValue; l_cnt++) {
219     EArtifactId l_artifactId = m_loggerErrorArtifactCfgTbl[l_cnt].ArtifactId;
220     TLoggingArtifactInformation l_artifactInformation =
221         m_loggerErrorArtifactCfgTbl[l_cnt].Information;
222     m_errorArtifactMap[l_artifactId] = l_artifactInformation;  // LCOV_EXCL_BR_LINE 11:Unexpected branch
223   }
224   for (l_cnt = 0; l_cnt < eErrorEventTypeMaxValue; l_cnt++) {
225     EErrorEventType l_eventType = m_loggerErrorEventCfgTbl[l_cnt].ErrorType;
226     TLoggingErrorEventInformation l_errorEvtInformation =
227         m_loggerErrorEventCfgTbl[l_cnt].Information;
228     m_errorEventTypeToArtifactBitMaskMap[l_eventType] = l_errorEvtInformation;
229   }
230
231   // Set external log info
232   if (ext_log.num > 0) {
233     if (ext_log.num <= ext_log.max) {
234       m_ext_log_num = ext_log.num;
235     } else {
236       m_ext_log_num = ext_log.max;
237     }
238
239     for (UI_32 i = 0; i < m_ext_log_num; i++) {
240       EArtifactId l_artifactId = (EArtifactId) (eArtifactIdMaxValue + i);
241       TLoggingArtifactInformation artifact_info;
242       artifact_info.Cb.Function = NULL;
243       artifact_info.Cb.Path = ext_log.p_info[i].path;
244       artifact_info.Cb.Type = eCbTypePath;
245       artifact_info.OwnerServiceName = SERVICE_LOGGER;
246       artifact_info.Remove = ext_log.p_info[i].remove;
247       artifact_info.RequestTimeoutMs = 5000;
248       m_errorArtifactMap[l_artifactId] = artifact_info;
249     }
250   }
251
252   l_eStatus = (EFrameworkunifiedStatus) ValidateConfiguration();
253   LOG_STATUS_IF_ERRORED(l_eStatus, "ValidateConfiguration()");  // LCOV_EXCL_BR_LINE 5:macro
254
255   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
256   return (l_eStatus);
257 }
258
259 UI_32 CErrorEventCfg::ValidateConfiguration(void) {
260   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
261
262   UI_32 l_return = 0;
263
264   if ((eArtifactIdMaxValue + m_ext_log_num) != m_errorArtifactMap.size()) {  // LCOV_EXCL_BR_LINE 6:Be sure not to exceed the eArtifactIdMaxValue
265     // LCOV_EXCL_START 6:Be sure not to exceed the eArtifactIdMaxValue
266     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
267     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
268            "Artifact map size mismatch: Expected: %d, Found: %d",
269            (eArtifactIdMaxValue + m_ext_log_num), m_errorArtifactMap.size());
270     l_return |= 1;
271     // LCOV_EXCL_STOP
272   }
273   if (eErrorEventTypeMaxValue != m_errorEventTypeToArtifactBitMaskMap.size()) {  // LCOV_EXCL_BR_LINE 6:Be sure not to exceed the eErrorEventTypeMaxValue
274     // LCOV_EXCL_START 6:Be sure not to exceed the eErrorEventTypeMaxValue
275     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
276     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
277            "Error event map size mismatch: Expected: %d, Found: %d",
278            eErrorEventTypeMaxValue, m_errorEventTypeToArtifactBitMaskMap.size());
279     l_return |= 4;
280     // LCOV_EXCL_STOP
281   }
282
283   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
284   return (l_return);
285 }
286
287 void CErrorEventCfg::GetArtifactRequestVec(
288     EErrorEventType f_eventType,
289     std::vector<TLoggingArtifact> &f_refArtifactRequestVec) {
290   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
291   ARTIFACT_BIT_MASK l_artifactRequestBits = 0;
292   ARTIFACT_BIT l_artifactBit;
293   TLoggingArtifact l_artifact;
294   UI_32 l_artifactId;
295
296   f_refArtifactRequestVec.clear();
297
298   if (f_eventType < eErrorEventTypeMaxValue) {
299     l_artifactRequestBits = m_errorEventTypeToArtifactBitMaskMap[f_eventType]
300         .ArtifactBitMask;
301   }
302
303   if (l_artifactRequestBits > 0) {
304     for (l_artifactId = 0; l_artifactId < eArtifactIdMaxValue; l_artifactId++) {
305       l_artifactBit = (ARTIFACT_BIT) (1 << l_artifactId);
306       if ((l_artifactRequestBits & l_artifactBit) > 0) {
307         l_artifact.ArtifactId = (EArtifactId) l_artifactId;
308         l_artifact.Information = m_errorArtifactMap[l_artifact.ArtifactId];
309         f_refArtifactRequestVec.push_back(l_artifact);
310       }
311     }
312
313     // Set external log info
314     if (m_ext_log_num > 0) {
315       for (l_artifactId = 0; l_artifactId < m_ext_log_num; l_artifactId++) {
316         l_artifact.ArtifactId = (EArtifactId) (eArtifactIdMaxValue + l_artifactId);
317         l_artifact.Information = m_errorArtifactMap[l_artifact.ArtifactId];
318         f_refArtifactRequestVec.push_back(l_artifact);
319       }
320     }
321   }
322
323   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
324 }
325
326 EVENT_BIT_MASK CErrorEventCfg::GetEventsForErrorEvent(
327     EErrorEventType f_eventType) {
328   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
329   EVENT_BIT_MASK l_events = EVENT_BIT_NONE;
330   if (f_eventType < eErrorEventTypeMaxValue) {  // LCOV_EXCL_BR_LINE 6:Be sure not to exceed the eErrorEventTypeMaxValue
331     l_events = m_errorEventTypeToArtifactBitMaskMap[f_eventType].EventBitMask;
332   }
333   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-");
334   return (l_events);
335 }  // LCOV_EXCL_BR_LINE 10:the last line