Attempt to sync and get version
| 371 | |
| 372 | // Attempt to sync and get version |
| 373 | DiagnosticResponse ArduinoInterface::attemptToSync(std::string& versionString, SerialIO& port) { |
| 374 | char buffer[10]; |
| 375 | |
| 376 | // Send 'Version' Request |
| 377 | buffer[0] = SPECIAL_ABORT_CHAR; |
| 378 | buffer[1] = COMMAND_RESET; // Reset |
| 379 | buffer[2] = COMMAND_VERSION; |
| 380 | |
| 381 | unsigned long size = port.write(&buffer[0], 3); |
| 382 | if (size != 3) { |
| 383 | // Couldn't write to device |
| 384 | port.closePort(); |
| 385 | return DiagnosticResponse::drPortError; |
| 386 | } |
| 387 | |
| 388 | memset(buffer, 0, sizeof buffer); |
| 389 | int counterNoData = 0; |
| 390 | int counterData = 0; |
| 391 | int bytesRead = 0; |
| 392 | |
| 393 | // Keep a rolling buffer looking for the 1Vxxx response |
| 394 | std::chrono::time_point<std::chrono::steady_clock> startTime = std::chrono::steady_clock::now(); |
| 395 | for (;;) { |
| 396 | const auto timePassed = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - startTime).count(); |
| 397 | |
| 398 | // Timeout after 8 seconds |
| 399 | if (timePassed >= 8) |
| 400 | return DiagnosticResponse::drPortError; |
| 401 | |
| 402 | size = port.read(&buffer[4], 1); |
| 403 | bytesRead += size; |
| 404 | // Was something read? |
| 405 | if (size) { |
| 406 | |
| 407 | if (buffer[0] == '1' && buffer[1] == 'V' && (buffer[2] >= '1' && buffer[2] <= '9') && (buffer[3] == ',' || buffer[3] == '.') && (buffer[4] >= '0' && buffer[4] <= '9')) { |
| 408 | |
| 409 | // Success |
| 410 | port.purgeBuffers(); |
| 411 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 412 | port.purgeBuffers(); |
| 413 | versionString = &buffer[1]; |
| 414 | return DiagnosticResponse::drOK; |
| 415 | } |
| 416 | else { |
| 417 | if (bytesRead) bytesRead--; |
| 418 | } |
| 419 | |
| 420 | // Move backwards |
| 421 | for (int a = 0; a < 4; a++) buffer[a] = buffer[a + 1]; |
| 422 | |
| 423 | if (counterData++ > 2048) { |
| 424 | port.closePort(); |
| 425 | return DiagnosticResponse::drErrorMalformedVersion; |
| 426 | } |
| 427 | } |
| 428 | else { |
| 429 | std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
| 430 | if (counterNoData++ > 120) { |
nothing calls this directly
no test coverage detected