@@ -38,6 +38,20 @@ DiagnosticsService::~DiagnosticsService() {
3838}
3939
4040void DiagnosticsService::loop () {
41+
42+ if (ftpUpload && ftpUpload->isActive ()) {
43+ ftpUpload->loop ();
44+ }
45+
46+ if (ftpUpload) {
47+ if (ftpUpload->isActive ()) {
48+ ftpUpload->loop ();
49+ } else {
50+ MO_DBG_DEBUG (" Deinit FTP upload" );
51+ ftpUpload.reset ();
52+ }
53+ }
54+
4155 auto notification = getDiagnosticsStatusNotification ();
4256 if (notification) {
4357 context.initiateRequest (std::move (notification));
@@ -51,10 +65,12 @@ void DiagnosticsService::loop() {
5165 MO_DBG_DEBUG (" Call onUpload" );
5266 onUpload (location.c_str (), startTime, stopTime);
5367 uploadIssued = true ;
68+ uploadFailure = false ;
5469 } else {
5570 MO_DBG_ERR (" onUpload must be set! (see setOnUpload). Will abort" );
5671 retries = 0 ;
5772 uploadIssued = false ;
73+ uploadFailure = true ;
5874 }
5975 }
6076
@@ -88,6 +104,11 @@ void DiagnosticsService::loop() {
88104 nextTry += retryInterval;
89105 }
90106 retries--;
107+
108+ if (retries == 0 ) {
109+ MO_DBG_DEBUG (" end upload routine (no more retry)" );
110+ uploadFailure = true ;
111+ }
91112 }
92113 }
93114 } // end if (uploadIssued)
@@ -96,10 +117,26 @@ void DiagnosticsService::loop() {
96117
97118// timestamps before year 2021 will be treated as "undefined"
98119std::string DiagnosticsService::requestDiagnosticsUpload (const char *location, unsigned int retries, unsigned int retryInterval, Timestamp startTime, Timestamp stopTime) {
99- if (onUpload == nullptr ) // maybe add further plausibility checks
120+ if (onUpload == nullptr ) {
100121 return std::string{};
101-
122+ }
123+
124+ std::string fileName;
125+ if (refreshFilename) {
126+ fileName = refreshFilename ();
127+ } else {
128+ fileName = " diagnostics.log" ;
129+ }
130+
131+ this ->location .reserve (strlen (location) + 1 + fileName.size ());
132+
102133 this ->location = location;
134+
135+ if (!this ->location .empty () && this ->location .back () != ' /' ) {
136+ this ->location .append (" /" );
137+ }
138+ this ->location .append (fileName.c_str ());
139+
103140 this ->retries = retries;
104141 this ->retryInterval = retryInterval;
105142 this ->startTime = startTime;
@@ -146,16 +183,14 @@ std::string DiagnosticsService::requestDiagnosticsUpload(const char *location, u
146183 }
147184#endif
148185
149- std::string fileName;
150- if (refreshFilename) {
151- fileName = refreshFilename ();
152- } else {
153- fileName = " diagnostics.log" ;
154- }
155186 return fileName;
156187}
157188
158189DiagnosticsStatus DiagnosticsService::getDiagnosticsStatus () {
190+ if (uploadFailure) {
191+ return DiagnosticsStatus::UploadFailed;
192+ }
193+
159194 if (uploadIssued) {
160195 if (uploadStatusInput != nullptr ) {
161196 switch (uploadStatusInput ()) {
@@ -255,7 +290,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
255290 fwVersion.empty () ? " " : " - v. " , fwVersion.c_str (),
256291 jsonDate);
257292
258- if (ret < 0 || ret >= diagPreambleSize) {
293+ if (ret < 0 || ( size_t ) ret >= diagPreambleSize) {
259294 MO_DBG_ERR (" snprintf: %i" , ret);
260295 this ->ftpUploadStatus = UploadStatus::UploadFailed;
261296 free (diagPreamble);
@@ -306,13 +341,13 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
306341 context.getConnection ().getLastConnected () / 1000UL ,
307342 context.getConnection ().getLastRecv () / 1000UL ,
308343 connector1 ? " \n cId1_hasTx=" : " " , connector1 ? (connector1Tx ? " 1" : " 0" ) : " " ,
309- connector1 ? " \n cId1_txActive=" : " " , connector1Tx ? (connector1Tx->isActive () ? " 1" : " 0" ) : " " ,
310- connector1 ? " \n cId1_hasStarted =" : " " , connector1Tx ? (connector1Tx->getStartSync ().isRequested () ? " 1" : " 0" ) : " " ,
311- connector1 ? " \n cId1_hasStopped =" : " " , connector1Tx ? (connector1Tx->getStopSync ().isRequested () ? " 1" : " 0" ) : " " ,
312- connector2 ? " \n cId1_hasTx =" : " " , connector2 ? (connector2Tx ? " 1" : " 0" ) : " " ,
313- connector2 ? " \n cId1_txActive =" : " " , connector2Tx ? (connector2Tx->isActive () ? " 1" : " 0" ) : " " ,
314- connector2 ? " \n cId1_hasStarted =" : " " , connector2Tx ? (connector2Tx->getStartSync ().isRequested () ? " 1" : " 0" ) : " " ,
315- connector2 ? " \n cId1_hasStopped =" : " " , connector2Tx ? (connector2Tx->getStopSync ().isRequested () ? " 1" : " 0" ) : " " ,
344+ connector1Tx ? " \n cId1_txActive=" : " " , connector1Tx ? (connector1Tx->isActive () ? " 1" : " 0" ) : " " ,
345+ connector1Tx ? " \n cId1_txHasStarted =" : " " , connector1Tx ? (connector1Tx->getStartSync ().isRequested () ? " 1" : " 0" ) : " " ,
346+ connector1Tx ? " \n cId1_txHasStopped =" : " " , connector1Tx ? (connector1Tx->getStopSync ().isRequested () ? " 1" : " 0" ) : " " ,
347+ connector2 ? " \n cId2_hasTx =" : " " , connector2 ? (connector2Tx ? " 1" : " 0" ) : " " ,
348+ connector2Tx ? " \n cId2_txActive =" : " " , connector2Tx ? (connector2Tx->isActive () ? " 1" : " 0" ) : " " ,
349+ connector2Tx ? " \n cId2_txHasStarted =" : " " , connector2Tx ? (connector2Tx->getStartSync ().isRequested () ? " 1" : " 0" ) : " " ,
350+ connector2Tx ? " \n cId2_txHasStopped =" : " " , connector2Tx ? (connector2Tx->getStopSync ().isRequested () ? " 1" : " 0" ) : " " ,
316351 MO_ENABLE_CONNECTOR_LOCK,
317352 MO_ENABLE_FILE_INDEX,
318353 MO_ENABLE_V201
@@ -334,6 +369,8 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
334369 diagFileList.emplace_back (fname);
335370 return 0 ;
336371 });
372+
373+ MO_DBG_DEBUG (" discovered %zu files" , diagFileList.size ());
337374 }
338375
339376 if (ret >= 0 && (size_t )ret + diagPostambleLen < diagPostambleSize) {
@@ -356,7 +393,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
356393 written += writeLen;
357394 }
358395
359- if (written < size && diagReaderHasData) {
396+ if (written < size && diagReaderHasData && diagnosticsReader ) {
360397 size_t writeLen = diagnosticsReader ((char *)buf, size);
361398 if (writeLen == 0 ) {
362399 diagReaderHasData = false ;
@@ -391,8 +428,10 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
391428 diagFileList.pop_front ();
392429 continue ;
393430 }
394- if (ret2 + written > size) {
395- // heading doesn't fit anymore, return with a bit unused buffer space and print heading the next time
431+ if (ret2 + written > size || // heading doesn't fit anymore, return with a bit unused buffer space and print heading the next time
432+ ret2 + written == size) { // filling the buffer up exactly would mean that no file payload is written and this head gets printed again
433+
434+ MO_DBG_DEBUG (" upload diag chunk (%zuB)" , written);
396435 return written;
397436 }
398437
@@ -401,7 +440,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
401440 }
402441
403442 file->seek (diagFilesFrontTransferred);
404- size_t writeLen = file->read ((char *)buf, size - written);
443+ size_t writeLen = file->read ((char *)buf + written , size - written);
405444
406445 if (writeLen < size - written) {
407446 diagFileList.pop_front ();
@@ -413,6 +452,7 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
413452 }
414453 }
415454
455+ MO_DBG_DEBUG (" upload diag chunk (%zuB)" , written);
416456 return written;
417457 },
418458 [this , onClose] (MO_FtpCloseReason reason) -> void {
@@ -428,7 +468,9 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
428468 free (diagPostamble);
429469 diagFileList.clear ();
430470
431- onClose ();
471+ if (onClose) {
472+ onClose ();
473+ }
432474 });
433475
434476 if (this ->ftpUpload ) {
@@ -448,3 +490,24 @@ void DiagnosticsService::setDiagnosticsReader(std::function<size_t(char *buf, si
448490void DiagnosticsService::setFtpServerCert (const char *cert) {
449491 this ->ftpServerCert = cert;
450492}
493+
494+ #if !defined(MO_CUSTOM_DIAGNOSTICS)
495+
496+ #if MO_PLATFORM == MO_PLATFORM_ARDUINO && defined(ESP32) && MO_ENABLE_MBEDTLS
497+
498+ std::unique_ptr<DiagnosticsService> MicroOcpp::makeDefaultDiagnosticsService (Context& context, std::shared_ptr<FilesystemAdapter> filesystem) {
499+
500+ }
501+
502+ #elif MO_ENABLE_MBEDTLS
503+
504+ std::unique_ptr<DiagnosticsService> MicroOcpp::makeDefaultDiagnosticsService (Context& context, std::shared_ptr<FilesystemAdapter> filesystem) {
505+ std::unique_ptr<DiagnosticsService> diagService = std::unique_ptr<DiagnosticsService>(new DiagnosticsService (context));
506+
507+ diagService->setDiagnosticsReader (nullptr , nullptr , filesystem); // report the built-in MO defaults
508+
509+ return diagService;
510+ }
511+
512+ #endif // MO_PLATFORM
513+ #endif // !defined(MO_CUSTOM_DIAGNOSTICS)
0 commit comments