common_library: gettid is multiple declaration in cl_error
[staging/basesystem.git] / video_in_hal / systemservice / logger_service / server / src / udp_writer.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    TODO
20 ///
21 ///////////////////////////////////////////////////////////////////////////////
22 #include "readerWriter/writer/udp_writer.h"
23 #include <sys/socket.h>
24 #include <arpa/inet.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <inttypes.h>
28 #ifdef AGL_STUB
29 #include <other_service/PosixBasedOS001ClockCycleApi.h>
30 #else
31 #include <sys/syspage.h>
32 #include <sys/neutrino.h>
33 #endif
34 #include <native_service/ns_logger_if.h>
35 #include <string>
36 #include <algorithm>
37
38 #define TIME_UNTIL_UDP_START   (UI_32)25
39
40 namespace ReaderWriter {
41
42 CUdpWriter::CUdpWriter()
43     : m_SocketHandle(-1),
44       m_IPAddress(""),
45       m_index(0),
46       m_port(REMOTE_IP_PORT),
47       m_InitialTimeElapsed(FALSE) {
48   std::memset(&m_oSAInfo, 0, sizeof(sockaddr_in));
49   std::memset(&m_buffer[0], 0, UDP_CACHED_BLOCK_SIZE);
50 }
51
52 CUdpWriter::~CUdpWriter() {
53   if (m_SocketHandle != -1) {
54     this->Close();
55   }
56 }
57
58 EFrameworkunifiedStatus CUdpWriter::Initialize(CLoggerCfg* f_pLoggerCfg, std::string f_Name1,
59                                   UI_32 f_size1, std::string f_Name2,
60                                   UI_32 f_size2) {
61   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
62   this->m_pLoggerCfg = f_pLoggerCfg;
63   this->m_IPAddress = f_Name1;
64   if (NULL == f_pLoggerCfg) { // LCOV_EXCL_BR_LINE 200: f_pLoggerCfg can not be null
65     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
66     l_eStatus = eFrameworkunifiedStatusNullPointer;  // LCOV_EXCL_LINE 200: f_pLoggerCfg can not be null
67   } else if ((f_pLoggerCfg->IsUDPLoggingEnabled())) {
68     if (m_IPAddress.length() > 0) {
69       this->m_port = f_size1;
70       l_eStatus = this->Open();
71       LOG_STATUS_IF_ERRORED(
72           l_eStatus,
73           "this->Open() failed. UDP logging disabled. Enable via Engineering Menu.");
74       // Continue without UDP Logging;
75       l_eStatus = eFrameworkunifiedStatusOK;
76     } else {
77       l_eStatus = eFrameworkunifiedStatusInvldParam;
78     }
79   } else {
80     this->m_SocketHandle = -1;
81   }
82   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "-: %d", l_eStatus);
83   return (l_eStatus);
84 }
85
86 BOOL CUdpWriter::IsOpen(void) {
87   BOOL l_ret = (-1 != m_SocketHandle) ? TRUE : FALSE;
88   if (TRUE == l_ret) {
89 #ifdef AGL_STUB
90     UI_32 l_elapsed = ((UI_32)((F_64)ClockCycle()/1000000));
91 #else
92     UI_32 l_elapsed = ((UI_32) ((F_64) ClockCycle()
93         / (F_64) (SYSPAGE_ENTRY(qtime)->cycles_per_sec)));
94 #endif
95     // check if 20 Seconds have elapsed since startup
96     if (TIME_UNTIL_UDP_START <= l_elapsed) {
97       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__,
98              "%d seconds elapsed. Starting UDP logging", l_elapsed);
99       m_InitialTimeElapsed = TRUE;
100       l_ret = TRUE;
101
102     } else {
103       FRAMEWORKUNIFIEDLOG(
104           ZONE_INFO,
105           __FUNCTION__,
106           "Time before starting UDP not yet elapsed. Waiting for %d more seconds",
107           (TIME_UNTIL_UDP_START - l_elapsed));
108       usleep((TIME_UNTIL_UDP_START - l_elapsed)*1000);
109       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "Starting UDP now!");
110     }
111   }
112   return l_ret;
113 }
114
115 EFrameworkunifiedStatus CUdpWriter::Open() {
116   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
117   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusFail;
118   if ((m_IPAddress.length() > 0)) {
119     int l_SocketOption = 1;
120     // Set the domain using the classes domain value.
121     m_oSAInfo.sin_family = AF_INET;
122     m_oSAInfo.sin_addr.s_addr = inet_addr(OWN_ADDRESS);  // m_IPAddress.c_str()); // "192.168.1.2");//htonl(INADDR_ANY);
123     m_oSAInfo.sin_port = htons(this->m_port);
124     if (FALSE == this->m_pLoggerCfg->IsUDPLoggingEnabled()) {
125       this->Close();
126       l_eStatus = eFrameworkunifiedStatusFail;
127     } else if (this->m_SocketHandle != -1) {
128       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__,
129              " Info. socket already opened. No action required");
130       l_eStatus = eFrameworkunifiedStatusOK;
131     } else if (-1 == (this->m_SocketHandle = socket(AF_INET, SOCK_DGRAM, 0))) {
132       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
133              " Error. socket(AF_INET, SOCK_DGRAM, 0) returned -1. errno: %s",
134              strerror(errno));
135       errno = 0;
136       l_eStatus = eFrameworkunifiedStatusDbExecuteFail;
137     } else if (setsockopt(m_SocketHandle, SOL_SOCKET, SO_REUSEADDR,
138                           &l_SocketOption, sizeof(l_SocketOption)) == -1) {
139       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
140              "setsockopt(SO_REUSEADDR) failed.errno: %s", strerror(errno));
141       errno = 0;
142       l_eStatus = eFrameworkunifiedStatusDbResultError;
143     }
144 #ifdef AGL_STUB
145     else if (setsockopt(m_SocketHandle, SOL_SOCKET, SO_REUSEADDR ,  // LCOV_EXCL_BR_LINE 6: the same calls will get the same return  // NOLINT (readability/braces)
146             &l_SocketOption, sizeof(l_SocketOption)) == -1)
147 #else
148     else if (setsockopt(m_SocketHandle, SOL_SOCKET, SO_REUSEPORT,  // NOLINT (readability/braces)
149                         &l_SocketOption, sizeof(l_SocketOption)) == -1)
150 #endif
151         {
152       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
153              "setsockopt(SO_REUSEPORT) failed. errno: %s", strerror(errno));
154       errno = 0;
155       l_eStatus = eFrameworkunifiedStatusDbResultError;
156     } else if (setsockopt(m_SocketHandle, SOL_SOCKET, SO_DONTROUTE,
157                           &l_SocketOption, sizeof(l_SocketOption)) == -1) {
158       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
159              "setsockopt(SO_DONTROUTE) failed. errno: %s", strerror(errno));
160       errno = 0;
161       l_eStatus = eFrameworkunifiedStatusDbResultError;
162     } else if (INADDR_NONE == m_oSAInfo.sin_addr.s_addr) {
163       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error. Invalid local address.");
164       l_eStatus = eFrameworkunifiedStatusDbRecNotFound;
165     } else if (0
166         != bind(this->m_SocketHandle, (const struct sockaddr *) &m_oSAInfo,
167                 sizeof(m_oSAInfo))) {
168       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
169              " Error. bind() returned not zero. errno: %s", strerror(errno));
170       errno = 0;
171       l_eStatus = eFrameworkunifiedStatusSemUnlockFail;
172     } else {
173       m_oSAInfo.sin_addr.s_addr = inet_addr(m_IPAddress.c_str());
174       if (INADDR_NONE == m_oSAInfo.sin_addr.s_addr) {
175         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error. Invalid target address.");
176         l_eStatus = eFrameworkunifiedStatusFault;
177       } else {
178         l_eStatus = eFrameworkunifiedStatusOK;
179       }
180     }
181
182     if (eFrameworkunifiedStatusOK != l_eStatus) {
183       this->Close();
184       m_SocketHandle = -1;
185     }
186   }
187   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "- : %d", l_eStatus);
188   return (l_eStatus);
189 }
190
191 EFrameworkunifiedStatus CUdpWriter::WriteData(UI_8 *f_data, UI_32 f_length,
192                                  SI_32 &f_bytesWritten) {
193   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
194   UI_8 l_retry = SEND_RETRY_VALUE;
195   if (this->m_SocketHandle == -1) {
196     l_eStatus = eFrameworkunifiedStatusInvldParam;
197   } else {
198     while ((0 != l_retry)
199         && ((f_bytesWritten >= 0) && ((UI_32) f_bytesWritten != f_length))) {
200       SI_32 l_bytesWritten = (SI_32)(sendto(m_SocketHandle, &f_data[f_bytesWritten],
201                                     f_length - f_bytesWritten, 0,
202                                     (const struct sockaddr *) &m_oSAInfo,
203                                     sizeof(m_oSAInfo)));
204       f_bytesWritten += l_bytesWritten;
205       l_eStatus = (l_bytesWritten >= 0) ? eFrameworkunifiedStatusOK : eFrameworkunifiedStatusFail;
206       if (eFrameworkunifiedStatusOK != l_eStatus) {
207         FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "l_retry: %d, errno: %s", l_retry,
208                strerror(errno));
209         errno = 0;
210         l_retry--;
211         usleep(100);
212       } else {
213         l_retry = SEND_RETRY_VALUE;
214       }
215     }
216   }
217   return (l_eStatus);
218 }
219
220 EFrameworkunifiedStatus CUdpWriter::Write(UI_8* f_data, UI_32 f_length,
221                              SI_32& f_bytesWritten) {
222   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
223   f_bytesWritten = 0;
224   if ((f_data == NULL)) {
225     l_eStatus = eFrameworkunifiedStatusNullPointer;
226   } else if ((-1 == m_SocketHandle)) {
227     l_eStatus = eFrameworkunifiedStatusFail;
228   }
229
230   if (eFrameworkunifiedStatusOK == l_eStatus) {
231     if (f_length > UDP_MAX_LENGTH) {
232       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error. Possible memory corruption.");
233       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Error. Length(%d) bigger than cache. ",
234              f_length);
235     } else {
236       UI_32 l_remainingIndex = 0;
237
238       while (l_remainingIndex != f_length) {
239         UI_32 l_offset = (UDP_CACHED_BLOCK_SIZE - this->m_index);
240         l_offset = std::min(l_offset, (f_length - l_remainingIndex));
241         (void) std::memcpy(&this->m_buffer[this->m_index],
242                            &f_data[l_remainingIndex], l_offset);
243         l_remainingIndex += l_offset;
244         this->m_index += l_offset;
245         if (this->m_index == UDP_CACHED_BLOCK_SIZE) {
246           (void) this->FlushCache();
247           this->m_index = 0;
248         }
249       }
250       f_bytesWritten = f_length;
251     }
252   }
253   return (l_eStatus);
254 }
255 void CUdpWriter::Close() {
256   if (m_SocketHandle != -1) {
257     (void) close(m_SocketHandle);
258     m_SocketHandle = -1;
259   }
260 }
261
262 EFrameworkunifiedStatus CUdpWriter::UpdateLoggingParameters(void) {
263   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "+");
264   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
265   if (this->m_pLoggerCfg != NULL) {
266     BOOL l_enabled = this->m_pLoggerCfg->IsUDPLoggingEnabled();
267     if ((TRUE == l_enabled) && (m_SocketHandle == -1)) {
268       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Info. Opening UDP.");
269       l_eStatus = this->Open();
270     } else if (((FALSE == l_enabled) && (m_SocketHandle != -1))) {
271       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, " Info. Closing UDP.");
272       l_eStatus = eFrameworkunifiedStatusOK;
273       this->Close();
274     } else {
275     }
276   }
277   FRAMEWORKUNIFIEDLOG(ZONE_FUNC, __FUNCTION__, "- :%d", l_eStatus);
278   return (l_eStatus);
279 }
280
281 EFrameworkunifiedStatus CUdpWriter::FlushCache(void) {
282   EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK;
283   SI_32 l_written = 0;
284   SI_32 l_writtenTotal = 0;
285   while (((l_writtenTotal >= 0) && ((UI_32) l_writtenTotal < this->m_index))
286       && (eFrameworkunifiedStatusOK == l_eStatus)) {
287     l_eStatus = this->WriteData(&this->m_buffer[l_writtenTotal],
288                                 this->m_index - l_writtenTotal, l_written);
289     l_writtenTotal += l_written;
290     l_written = 0;
291   }
292   this->m_index = 0;
293   return l_eStatus;
294 }
295 }  // namespace ReaderWriter