14#include "isobus/utility/platform_endianness.hpp"
15#include "isobus/utility/system_timing.hpp"
16#include "isobus/utility/to_string.hpp"
24#include <unordered_map>
29 languageCommandInterface(clientSource, partner),
30 partnerControlFunction(partner),
31 myControlFunction(clientSource),
32 txFlags(static_cast<std::uint32_t>(
TransmitFlags::NumberFlags), process_flags, this)
63#if !defined CAN_STACK_DISABLE_THREADS && !defined ARDUINO
92 LOG_DEBUG(
"[VT]: Requested object pool deletion from volatile VT memory.");
101#if !defined CAN_STACK_DISABLE_THREADS && !defined ARDUINO
111 LOG_INFO(
"[VT]: VT Client connection has been terminated.");
117 LOG_INFO(
"[VT]:VT Client connection restart requested. Client will now terminate and reinitialize.");
118#if !defined CAN_STACK_DISABLE_THREADS && !defined ARDUINO
121 bool workerNeeded =
false;
228 LOG_DEBUG(
"[AUX-N] Removed auxiliary input with ID: " +
229 isobus::to_string(
static_cast<int>(auxiliaryInputID)));
237 LOG_WARNING(
"[AUX-N] Auxiliary input with ID '" +
238 isobus::to_string(
static_cast<int>(auxiliaryInputID)) +
239 "' has not been registered. Ignoring update");
257 functionObjectID(functionObjectID), inputObjectID(inputObjectID), functionType(functionType)
268 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::HideShowObjectCommand),
269 static_cast<std::uint8_t
>(objectID & 0xFF),
270 static_cast<std::uint8_t
>(objectID >> 8),
271 static_cast<std::uint8_t
>(command),
281 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::EnableDisableObjectCommand),
282 static_cast<std::uint8_t
>(objectID & 0xFF),
283 static_cast<std::uint8_t
>(objectID >> 8),
284 static_cast<std::uint8_t
>(command),
294 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::SelectInputObjectCommand),
295 static_cast<std::uint8_t
>(objectID & 0xFF),
296 static_cast<std::uint8_t
>(objectID >> 8),
297 static_cast<std::uint8_t
>(option),
307 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ESCCommand),
320 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ControlAudioSignalCommand),
322 static_cast<std::uint8_t
>(frequency_hz & 0xFF),
323 static_cast<std::uint8_t
>(frequency_hz >> 8),
324 static_cast<std::uint8_t
>(duration_ms & 0xFF),
325 static_cast<std::uint8_t
>(duration_ms >> 8),
326 static_cast<std::uint8_t
>(offTimeDuration_ms & 0xFF),
327 static_cast<std::uint8_t
>(offTimeDuration_ms >> 8) };
333 constexpr std::uint8_t MAX_VOLUME_PERCENT = 100;
335 if (volume_percent > MAX_VOLUME_PERCENT)
337 volume_percent = MAX_VOLUME_PERCENT;
338 LOG_WARNING(
"[VT]: Cannot try to set audio volume greater than 100 percent. Value will be capped at 100.");
341 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::SetAudioVolumeCommand),
354 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeChildLocationCommand),
355 static_cast<std::uint8_t
>(parentObjectID & 0xFF),
356 static_cast<std::uint8_t
>(parentObjectID >> 8),
357 static_cast<std::uint8_t
>(objectID & 0xFF),
358 static_cast<std::uint8_t
>(objectID >> 8),
359 relativeXPositionChange,
360 relativeYPositionChange,
367 const std::vector<std::uint8_t> buffer = {
368 static_cast<std::uint8_t
>(Function::ChangeChildPositionCommand),
369 static_cast<std::uint8_t
>(parentObjectID & 0xFF),
370 static_cast<std::uint8_t
>(parentObjectID >> 8),
371 static_cast<std::uint8_t
>(objectID & 0xFF),
372 static_cast<std::uint8_t
>(objectID >> 8),
373 static_cast<std::uint8_t
>(xPosition & 0xFF),
374 static_cast<std::uint8_t
>(xPosition >> 8),
375 static_cast<std::uint8_t
>(yPosition & 0xFF),
376 static_cast<std::uint8_t
>(yPosition >> 8),
383 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeSizeCommand),
384 static_cast<std::uint8_t
>(objectID & 0xFF),
385 static_cast<std::uint8_t
>(objectID >> 8),
386 static_cast<std::uint8_t
>(newWidth & 0xFF),
387 static_cast<std::uint8_t
>(newWidth >> 8),
388 static_cast<std::uint8_t
>(newHeight & 0xFF),
389 static_cast<std::uint8_t
>(newHeight >> 8),
396 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeBackgroundColourCommand),
397 static_cast<std::uint8_t
>(objectID & 0xFF),
398 static_cast<std::uint8_t
>(objectID >> 8),
409 const std::vector<std::uint8_t> buffer = {
410 static_cast<std::uint8_t
>(Function::ChangeNumericValueCommand),
411 static_cast<std::uint8_t
>(objectID & 0xFF),
412 static_cast<std::uint8_t
>(objectID >> 8),
414 static_cast<std::uint8_t
>(value & 0xFF),
415 static_cast<std::uint8_t
>((value >> 8) & 0xFF),
416 static_cast<std::uint8_t
>((value >> 16) & 0xFF),
417 static_cast<std::uint8_t
>((value >> 24) & 0xFF),
426 if (
nullptr != value)
428 std::vector<std::uint8_t> buffer;
429 buffer.resize(5 + stringLength);
430 buffer[0] =
static_cast<std::uint8_t
>(Function::ChangeStringValueCommand);
431 buffer[1] =
static_cast<std::uint8_t
>(objectID & 0xFF);
432 buffer[2] =
static_cast<std::uint8_t
>(objectID >> 8);
433 buffer[3] =
static_cast<std::uint8_t
>(stringLength & 0xFF);
434 buffer[4] =
static_cast<std::uint8_t
>(stringLength >> 8);
435 for (std::uint16_t i = 0; i < stringLength; i++)
437 buffer[5 + i] = value[i];
442 buffer.push_back(0xFF);
456 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeEndPointCommand),
457 static_cast<std::uint8_t
>(objectID & 0xFF),
458 static_cast<std::uint8_t
>(objectID >> 8),
459 static_cast<std::uint8_t
>(width_px & 0xFF),
460 static_cast<std::uint8_t
>(width_px >> 8),
461 static_cast<std::uint8_t
>(height_px & 0xFF),
462 static_cast<std::uint8_t
>(height_px >> 8),
463 static_cast<std::uint8_t
>(direction) };
469 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeFontAttributesCommand),
470 static_cast<std::uint8_t
>(objectID & 0xFF),
471 static_cast<std::uint8_t
>(objectID >> 8),
473 static_cast<std::uint8_t
>(size),
482 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeLineAttributesCommand),
483 static_cast<std::uint8_t
>(objectID & 0xFF),
484 static_cast<std::uint8_t
>(objectID >> 8),
486 static_cast<std::uint8_t
>(width),
487 static_cast<std::uint8_t
>(lineArtBitmask & 0xFF),
488 static_cast<std::uint8_t
>(lineArtBitmask >> 8),
495 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeFillAttributesCommand),
496 static_cast<std::uint8_t
>(objectID & 0xFF),
497 static_cast<std::uint8_t
>(objectID >> 8),
498 static_cast<std::uint8_t
>(fillType),
500 static_cast<std::uint8_t
>(fillPatternObjectID & 0xFF),
501 static_cast<std::uint8_t
>(fillPatternObjectID >> 8),
508 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeActiveMaskCommand),
509 static_cast<std::uint8_t
>(workingSetObjectID & 0xFF),
510 static_cast<std::uint8_t
>(workingSetObjectID >> 8),
511 static_cast<std::uint8_t
>(newActiveMaskObjectID & 0xFF),
512 static_cast<std::uint8_t
>(newActiveMaskObjectID >> 8),
521 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeSoftKeyMaskCommand),
522 static_cast<std::uint8_t
>(type),
523 static_cast<std::uint8_t
>(dataOrAlarmMaskObjectID & 0xFF),
524 static_cast<std::uint8_t
>(dataOrAlarmMaskObjectID >> 8),
525 static_cast<std::uint8_t
>(newSoftKeyMaskObjectID & 0xFF),
526 static_cast<std::uint8_t
>(newSoftKeyMaskObjectID >> 8),
534 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeAttributeCommand),
535 static_cast<std::uint8_t
>(objectID & 0xFF),
536 static_cast<std::uint8_t
>(objectID >> 8),
538 static_cast<std::uint8_t
>(value & 0xFF),
539 static_cast<std::uint8_t
>((value >> 8) & 0xFF),
540 static_cast<std::uint8_t
>((value >> 16) & 0xFF),
541 static_cast<std::uint8_t
>((value >> 24) & 0xFF) };
547 static_assert(
sizeof(float) == 4,
"Float must be 4 bytes");
548 std::array<std::uint8_t,
sizeof(float)> floatBytes = { 0 };
549 memcpy(floatBytes.data(), &value,
sizeof(
float));
553 std::reverse(floatBytes.begin(), floatBytes.end());
556 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeAttributeCommand),
557 static_cast<std::uint8_t
>(objectID & 0xFF),
558 static_cast<std::uint8_t
>(objectID >> 8),
569 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangePriorityCommand),
570 static_cast<std::uint8_t
>(alarmMaskObjectID & 0xFF),
571 static_cast<std::uint8_t
>(alarmMaskObjectID >> 8),
572 static_cast<std::uint8_t
>(priority),
582 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeListItemCommand),
583 static_cast<std::uint8_t
>(objectID & 0xFF),
584 static_cast<std::uint8_t
>(objectID >> 8),
586 static_cast<std::uint8_t
>(newObjectID & 0xFF),
587 static_cast<std::uint8_t
>(newObjectID >> 8),
595 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::LockUnlockMaskCommand),
596 static_cast<std::uint8_t
>(
state),
597 static_cast<std::uint8_t
>(objectID & 0xFF),
598 static_cast<std::uint8_t
>(objectID >> 8),
599 static_cast<std::uint8_t
>(timeout_ms & 0xFF),
600 static_cast<std::uint8_t
>(timeout_ms >> 8),
608 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ExecuteMacroCommand),
609 static_cast<std::uint8_t
>(objectID & 0xFF),
610 static_cast<std::uint8_t
>(objectID >> 8),
621 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangeObjectLabelCommand),
622 static_cast<std::uint8_t
>(objectID & 0xFF),
623 static_cast<std::uint8_t
>(objectID >> 8),
624 static_cast<std::uint8_t
>(labelStringObjectID & 0xFF),
625 static_cast<std::uint8_t
>(labelStringObjectID >> 8),
627 static_cast<std::uint8_t
>(graphicalDesignatorObjectID & 0xFF),
628 static_cast<std::uint8_t
>(graphicalDesignatorObjectID >> 8) };
634 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangePolygonPointCommand),
635 static_cast<std::uint8_t
>(objectID & 0xFF),
636 static_cast<std::uint8_t
>(objectID >> 8),
638 static_cast<std::uint8_t
>(newXValue & 0xFF),
639 static_cast<std::uint8_t
>(newXValue >> 8),
640 static_cast<std::uint8_t
>(newYValue & 0xFF),
641 static_cast<std::uint8_t
>(newYValue >> 8) };
647 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ChangePolygonScaleCommand),
648 static_cast<std::uint8_t
>(objectID & 0xFF),
649 static_cast<std::uint8_t
>(objectID >> 8),
650 static_cast<std::uint8_t
>(widthAttribute & 0xFF),
651 static_cast<std::uint8_t
>(widthAttribute >> 8),
652 static_cast<std::uint8_t
>(heightAttribute & 0xFF),
653 static_cast<std::uint8_t
>(heightAttribute >> 8),
660 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::SelectColourMapCommand),
661 static_cast<std::uint8_t
>(objectID & 0xFF),
662 static_cast<std::uint8_t
>(objectID >> 8),
673 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::ExecuteExtendedMacroCommand),
674 static_cast<std::uint8_t
>(objectID & 0xFF),
675 static_cast<std::uint8_t
>(objectID >> 8),
686 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::SelectActiveWorkingSet),
687 static_cast<std::uint8_t
>(NAMEofWorkingSetMasterForDesiredWorkingSet & 0xFF),
688 static_cast<std::uint8_t
>((NAMEofWorkingSetMasterForDesiredWorkingSet >> 8) & 0xFF),
689 static_cast<std::uint8_t
>((NAMEofWorkingSetMasterForDesiredWorkingSet >> 16) & 0xFF),
690 static_cast<std::uint8_t
>((NAMEofWorkingSetMasterForDesiredWorkingSet >> 24) & 0xFF),
691 static_cast<std::uint8_t
>((NAMEofWorkingSetMasterForDesiredWorkingSet >> 32) & 0xFF),
692 static_cast<std::uint8_t
>((NAMEofWorkingSetMasterForDesiredWorkingSet >> 40) & 0xFF),
693 static_cast<std::uint8_t
>((NAMEofWorkingSetMasterForDesiredWorkingSet >> 48) & 0xFF),
694 static_cast<std::uint8_t
>((NAMEofWorkingSetMasterForDesiredWorkingSet >> 56) & 0xFF) };
700 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
701 static_cast<std::uint8_t
>(objectID & 0xFF),
702 static_cast<std::uint8_t
>(objectID >> 8),
704 static_cast<std::uint8_t
>(xPosition & 0xFF),
705 static_cast<std::uint8_t
>(xPosition >> 8),
706 static_cast<std::uint8_t
>(yPosition & 0xFF),
707 static_cast<std::uint8_t
>(yPosition >> 8) };
713 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
714 static_cast<std::uint8_t
>(objectID & 0xFF),
715 static_cast<std::uint8_t
>(objectID >> 8),
717 static_cast<std::uint8_t
>(xOffset & 0xFF),
718 static_cast<std::uint8_t
>(xOffset >> 8),
719 static_cast<std::uint8_t
>(yOffset & 0xFF),
720 static_cast<std::uint8_t
>(yOffset >> 8) };
726 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
727 static_cast<std::uint8_t
>(objectID & 0xFF),
728 static_cast<std::uint8_t
>(objectID >> 8),
739 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
740 static_cast<std::uint8_t
>(objectID & 0xFF),
741 static_cast<std::uint8_t
>(objectID >> 8),
752 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
753 static_cast<std::uint8_t
>(objectID & 0xFF),
754 static_cast<std::uint8_t
>(objectID >> 8),
756 static_cast<std::uint8_t
>(lineAttributesObjectID & 0xFF),
757 static_cast<std::uint8_t
>(lineAttributesObjectID >> 8),
765 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
766 static_cast<std::uint8_t
>(objectID & 0xFF),
767 static_cast<std::uint8_t
>(objectID >> 8),
769 static_cast<std::uint8_t
>(fillAttributesObjectID & 0xFF),
770 static_cast<std::uint8_t
>(fillAttributesObjectID >> 8),
778 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
779 static_cast<std::uint8_t
>(objectID & 0xFF),
780 static_cast<std::uint8_t
>(objectID >> 8),
782 static_cast<std::uint8_t
>(fontAttributesObjectID & 0xFF),
783 static_cast<std::uint8_t
>(fontAttributesObjectID >> 8),
791 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
792 static_cast<std::uint8_t
>(objectID & 0xFF),
793 static_cast<std::uint8_t
>(objectID >> 8),
795 static_cast<std::uint8_t
>(width & 0xFF),
796 static_cast<std::uint8_t
>(width >> 8),
797 static_cast<std::uint8_t
>(height & 0xFF),
798 static_cast<std::uint8_t
>(height >> 8) };
804 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
805 static_cast<std::uint8_t
>(objectID & 0xFF),
806 static_cast<std::uint8_t
>(objectID >> 8),
808 static_cast<std::uint8_t
>(xOffset & 0xFF),
809 static_cast<std::uint8_t
>(xOffset >> 8),
810 static_cast<std::uint8_t
>(yOffset & 0xFF),
811 static_cast<std::uint8_t
>(yOffset >> 8) };
817 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
818 static_cast<std::uint8_t
>(objectID & 0xFF),
819 static_cast<std::uint8_t
>(objectID >> 8),
821 static_cast<std::uint8_t
>(xOffset & 0xFF),
822 static_cast<std::uint8_t
>(xOffset >> 8),
823 static_cast<std::uint8_t
>(yOffset & 0xFF),
824 static_cast<std::uint8_t
>(yOffset >> 8) };
830 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
831 static_cast<std::uint8_t
>(objectID & 0xFF),
832 static_cast<std::uint8_t
>(objectID >> 8),
834 static_cast<std::uint8_t
>(width & 0xFF),
835 static_cast<std::uint8_t
>(width >> 8),
836 static_cast<std::uint8_t
>(height & 0xFF),
837 static_cast<std::uint8_t
>(height >> 8) };
843 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
844 static_cast<std::uint8_t
>(objectID & 0xFF),
845 static_cast<std::uint8_t
>(objectID >> 8),
847 static_cast<std::uint8_t
>(width & 0xFF),
848 static_cast<std::uint8_t
>(width >> 8),
849 static_cast<std::uint8_t
>(height & 0xFF),
850 static_cast<std::uint8_t
>(height >> 8) };
858 if ((numberOfPoints > 0) &&
859 (
nullptr != listOfXOffsetsRelativeToCursor) &&
860 (
nullptr != listOfYOffsetsRelativeToCursor))
863 const std::uint16_t messageLength = (9 + (4 * numberOfPoints));
864 std::vector<std::uint8_t> buffer;
865 buffer.resize(messageLength);
866 buffer[0] =
static_cast<std::uint8_t
>(Function::GraphicsContextCommand);
867 buffer[1] =
static_cast<std::uint8_t
>(objectID & 0xFF);
868 buffer[2] =
static_cast<std::uint8_t
>(objectID >> 8);
870 buffer[4] = numberOfPoints;
871 for (std::uint16_t i = 0; i < numberOfPoints; i += 4)
873 buffer[5 + i] =
static_cast<std::uint8_t
>(listOfXOffsetsRelativeToCursor[0] & 0xFF);
874 buffer[6 + i] =
static_cast<std::uint8_t
>((listOfXOffsetsRelativeToCursor[0] >> 8) & 0xFF);
875 buffer[7 + i] =
static_cast<std::uint8_t
>(listOfYOffsetsRelativeToCursor[0] & 0xFF);
876 buffer[8 + i] =
static_cast<std::uint8_t
>((listOfYOffsetsRelativeToCursor[0] >> 8) & 0xFF);
887 if ((
nullptr != value) &&
890 std::uint16_t messageLength = (6 + textLength);
891 std::vector<std::uint8_t> buffer;
892 buffer.resize(messageLength);
893 buffer[0] =
static_cast<std::uint8_t
>(Function::GraphicsContextCommand);
894 buffer[1] =
static_cast<std::uint8_t
>(objectID & 0xFF);
895 buffer[2] =
static_cast<std::uint8_t
>(objectID >> 8);
897 buffer[4] =
static_cast<std::uint8_t
>(transparent);
898 buffer[5] = textLength;
899 memcpy(&buffer[6], value, textLength);
903 buffer.push_back(0xFF);
912 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
913 static_cast<std::uint8_t
>(objectID & 0xFF),
914 static_cast<std::uint8_t
>(objectID >> 8),
916 static_cast<std::uint8_t
>(xAttribute & 0xFF),
917 static_cast<std::uint8_t
>(xAttribute >> 8),
918 static_cast<std::uint8_t
>(yAttribute & 0xFF),
919 static_cast<std::uint8_t
>(yAttribute >> 8) };
925 static_assert(
sizeof(float) == 4,
"Float must be 4 bytes");
926 std::array<std::uint8_t,
sizeof(float)> floatBytes = { 0 };
927 memcpy(floatBytes.data(), &zoom,
sizeof(
float));
931 std::reverse(floatBytes.begin(), floatBytes.end());
934 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
935 static_cast<std::uint8_t
>(objectID & 0xFF),
936 static_cast<std::uint8_t
>(objectID >> 8),
947 static_assert(
sizeof(float) == 4,
"Float must be 4 bytes");
948 std::array<std::uint8_t,
sizeof(float)> floatBytes = { 0 };
949 memcpy(floatBytes.data(), &zoom,
sizeof(
float));
953 std::reverse(floatBytes.begin(), floatBytes.end());
956 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
957 static_cast<std::uint8_t
>(objectID & 0xFF),
958 static_cast<std::uint8_t
>(objectID >> 8),
960 static_cast<std::uint8_t
>(xAttribute & 0xFF),
961 static_cast<std::uint8_t
>(xAttribute >> 8),
962 static_cast<std::uint8_t
>(yAttribute & 0xFF),
963 static_cast<std::uint8_t
>(yAttribute >> 8),
973 constexpr std::uint16_t MAX_WIDTH_HEIGHT = 32767;
976 if ((width <= MAX_WIDTH_HEIGHT) &&
977 (height <= MAX_WIDTH_HEIGHT))
979 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
980 static_cast<std::uint8_t
>(objectID & 0xFF),
981 static_cast<std::uint8_t
>(objectID >> 8),
983 static_cast<std::uint8_t
>(width & 0xFF),
984 static_cast<std::uint8_t
>(width >> 8),
985 static_cast<std::uint8_t
>(height & 0xFF),
986 static_cast<std::uint8_t
>(height >> 8) };
994 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
995 static_cast<std::uint8_t
>(graphicsContextObjectID & 0xFF),
996 static_cast<std::uint8_t
>(graphicsContextObjectID >> 8),
998 static_cast<std::uint8_t
>(objectID & 0xFF),
999 static_cast<std::uint8_t
>(objectID >> 8),
1007 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
1008 static_cast<std::uint8_t
>(graphicsContextObjectID & 0xFF),
1009 static_cast<std::uint8_t
>(graphicsContextObjectID >> 8),
1011 static_cast<std::uint8_t
>(objectID & 0xFF),
1012 static_cast<std::uint8_t
>(objectID >> 8),
1020 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GraphicsContextCommand),
1021 static_cast<std::uint8_t
>(graphicsContextObjectID & 0xFF),
1022 static_cast<std::uint8_t
>(graphicsContextObjectID >> 8),
1024 static_cast<std::uint8_t
>(objectID & 0xFF),
1025 static_cast<std::uint8_t
>(objectID >> 8),
1033 const std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::GetAttributeValueMessage),
1034 static_cast<std::uint8_t
>(objectID & 0xFF),
1035 static_cast<std::uint8_t
>(objectID >> 8),
1066 bool retVal =
false;
1205 bool retVal =
false;
1227 if ((
nullptr != pool) &&
1256 if ((
nullptr != pool) &&
1257 (0 != pool->size()))
1284 std::uint32_t originalDataMaskDimensions_px,
1285 std::uint32_t originalSoftKyeDesignatorHeight_px)
1289 objectPools[poolIndex].autoScaleDataMaskOriginalDimension = originalDataMaskDimensions_px;
1290 objectPools[poolIndex].autoScaleSoftKeyDesignatorOriginalHeight = originalSoftKyeDesignatorHeight_px;
1295 if ((
nullptr != value) &&
1296 (0 != poolTotalSize))
1368 LOG_ERROR(
"[VT]: Ready to upload pool, but VT server has timed out. Disconnecting.");
1385 std::uint32_t totalPoolSize = 0;
1389 totalPoolSize += pool.objectPoolSize;
1404 LOG_ERROR(
"[VT]: Get Memory Response Timeout");
1423 LOG_ERROR(
"[VT]: Get Number Softkeys Response Timeout");
1442 LOG_ERROR(
"[VT]: Get Text Font Data Response Timeout");
1461 LOG_ERROR(
"[VT]: Get Hardware Response Timeout");
1471 LOG_ERROR(
"[VT]: Get Versions Timeout");
1487 LOG_ERROR(
"[VT]: Get Versions Response Timeout");
1497 LOG_ERROR(
"[VT]: Send Load Version Timeout");
1501 constexpr std::uint8_t VERSION_LABEL_LENGTH = 7;
1502 std::array<std::uint8_t, VERSION_LABEL_LENGTH> tempVersionBuffer;
1505 tempVersionBuffer[0] =
' ';
1506 tempVersionBuffer[1] =
' ';
1507 tempVersionBuffer[2] =
' ';
1508 tempVersionBuffer[3] =
' ';
1509 tempVersionBuffer[4] =
' ';
1510 tempVersionBuffer[5] =
' ';
1511 tempVersionBuffer[6] =
' ';
1513 for (std::size_t i = 0; ((i < VERSION_LABEL_LENGTH) && (i <
objectPools[0].versionLabel.size())); i++)
1515 tempVersionBuffer[i] =
objectPools[0].versionLabel[i];
1531 LOG_ERROR(
"[VT]: Load Version Response Timeout");
1541 LOG_ERROR(
"[VT]: Send Store Version Timeout");
1545 constexpr std::uint8_t VERSION_LABEL_LENGTH = 7;
1546 std::array<std::uint8_t, VERSION_LABEL_LENGTH> tempVersionBuffer;
1549 tempVersionBuffer[0] =
' ';
1550 tempVersionBuffer[1] =
' ';
1551 tempVersionBuffer[2] =
' ';
1552 tempVersionBuffer[3] =
' ';
1553 tempVersionBuffer[4] =
' ';
1554 tempVersionBuffer[5] =
' ';
1555 tempVersionBuffer[6] =
' ';
1557 for (std::size_t i = 0; ((i < VERSION_LABEL_LENGTH) && (i <
objectPools[0].versionLabel.size())); i++)
1559 tempVersionBuffer[i] =
objectPools[0].versionLabel[i];
1575 LOG_ERROR(
"[VT]: Store Version Response Timeout");
1582 bool allPoolsProcessed =
true;
1596 for (std::uint32_t i = 0; i <
objectPools.size(); i++)
1598 if (((
nullptr !=
objectPools[i].objectPoolDataPointer) ||
1604 allPoolsProcessed =
false;
1621 if (transmitSuccessful)
1636 LOG_DEBUG(
"[VT]: Object pool %u uploaded.", i + 1);
1643 LOG_ERROR(
"[VT]: An object pool failed to upload. Resetting connection to VT.");
1649 allPoolsProcessed =
false;
1655 LOG_WARNING(
"[VT]: An object pool was supplied with an invalid size or pointer. Ignoring it.");
1660 if (allPoolsProcessed)
1681 LOG_ERROR(
"[VT]: Get End of Object Pool Response Timeout");
1692 LOG_ERROR(
"[VT]: Status Timeout");
1700 constexpr std::uint32_t VT_STATE_MACHINE_RETRY_TIMEOUT_MS = 5000;
1707 LOG_INFO(
"[VT]: Resetting Failed VT Connection");
1739 if (
state == previousStateMachineState)
1757 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::DeleteObjectPoolCommand),
1770 static constexpr std::uint8_t SUPPORTED_VT_VERSION = 0x06;
1772 std::uint8_t bitmask = (initializing ? 0x01 : 0x00);
1774 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::WorkingSetMaintenanceMessage),
1776 SUPPORTED_VT_VERSION,
1787 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetMemoryMessage),
1789 static_cast<std::uint8_t
>(requiredMemory & 0xFF),
1790 static_cast<std::uint8_t
>((requiredMemory >> 8) & 0xFF),
1791 static_cast<std::uint8_t
>((requiredMemory >> 16) & 0xFF),
1792 static_cast<std::uint8_t
>((requiredMemory >> 24) & 0xFF),
1800 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetNumberOfSoftKeysMessage),
1813 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetTextFontDataMessage),
1826 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetHardwareMessage),
1839 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetSupportedWidecharsMessage),
1852 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetWindowMaskDataMessage),
1865 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetSupportedObjectsMessage),
1878 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::GetVersionsMessage),
1891 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::StoreVersionCommand),
1904 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::LoadVersionCommand),
1917 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::DeleteVersionCommand),
1930 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::ExtendedDeleteVersionCommand),
1943 std::array<std::uint8_t, 33> buffer;
1944 buffer[0] =
static_cast<std::uint8_t
>(Function::ExtendedStoreVersionCommand);
1945 memcpy(&buffer[1], versionLabel.data(), 32);
1951 std::array<std::uint8_t, 33> buffer;
1952 buffer[0] =
static_cast<std::uint8_t
>(Function::ExtendedLoadVersionCommand);
1953 memcpy(&buffer[1], versionLabel.data(), 32);
1959 std::array<std::uint8_t, 33> buffer;
1960 buffer[0] =
static_cast<std::uint8_t
>(Function::ExtendedDeleteVersionCommand);
1961 memcpy(&buffer[1], versionLabel.data(), 32);
1967 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::EndOfObjectPoolMessage),
1980 constexpr std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = { 0x01,
1999 std::vector<std::uint8_t> buffer = {
static_cast<std::uint8_t
>(Function::PreferredAssignmentCommand), 0 };
2009 std::uint8_t errorCode = 0;
2018 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::AuxiliaryAssignmentTypeTwoCommand),
2019 static_cast<std::uint8_t
>(functionObjectID),
2020 static_cast<std::uint8_t
>(functionObjectID >> 8),
2031 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::AuxiliaryInputTypeTwoMaintenanceMessage),
2049 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::AuxiliaryInputStatusTypeTwoEnableCommand),
2050 static_cast<std::uint8_t
>(objectID),
2051 static_cast<std::uint8_t
>(objectID >> 8),
2052 static_cast<std::uint8_t
>(isEnabled ? 0x01 : 0x00),
2053 static_cast<std::uint8_t
>(invalidObjectID ? 0x01 : 0x00),
2070 bool retVal =
false;
2074 (
state.hasInteraction &&
2078 state.lastStatusUpdate = SystemTiming::get_timestamp_ms();
2080 std::uint8_t operatingState = 0;
2083 operatingState |= 0x01;
2084 if (
state.hasInteraction)
2086 operatingState |= 0x02;
2089 if (
state.controlLocked)
2091 operatingState |= 0x04;
2092 if (
state.hasInteraction)
2094 operatingState |= 0x08;
2097 state.hasInteraction =
false;
2100 const std::array<std::uint8_t, CAN_DATA_LENGTH> buffer = {
static_cast<std::uint8_t
>(Function::AuxiliaryInputTypeTwoStatusMessage),
2101 static_cast<std::uint8_t
>(objectID),
2102 static_cast<std::uint8_t
>(objectID >> 8),
2103 static_cast<std::uint8_t
>(
state.value1),
2104 static_cast<std::uint8_t
>(
state.value1 >> 8),
2105 static_cast<std::uint8_t
>(
state.value2),
2106 static_cast<std::uint8_t
>(
state.value2 >> 8),
2139 for (std::size_t i = 0; i <
objectPools.size(); i++)
2149 (
nullptr != parent))
2153 bool transmitSuccessful =
false;
2155 switch (flagToProcess)
2163 if (transmitSuccessful)
2175 if (transmitSuccessful)
2189 if (
false == transmitSuccessful)
2191 vtClient->
txFlags.set_flag(flag);
2199 if ((
nullptr != parentPointer) &&
2206 case static_cast<std::uint32_t
>(CANLibParameterGroupNumber::Acknowledge):
2210 std::uint32_t targetParameterGroupNumber = message.
get_uint24_at(5);
2211 if (
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ECUtoVirtualTerminal) == targetParameterGroupNumber)
2213 LOG_ERROR(
"[VT]: The VT Server is NACK-ing our VT messages. Disconnecting.");
2220 case static_cast<std::uint32_t
>(CANLibParameterGroupNumber::VirtualTerminalToECU):
2224 case static_cast<std::uint8_t
>(Function::SoftKeyActivationMessage):
2232 std::uint8_t transactionNumber = 0xF;
2241 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2242 static_cast<std::uint8_t
>(Function::SoftKeyActivationMessage),
2244 static_cast<std::uint8_t
>(objectID),
2245 static_cast<std::uint8_t
>(objectID >> 8),
2246 static_cast<std::uint8_t
>(parentObjectID),
2247 static_cast<std::uint8_t
>(parentObjectID >> 8),
2253 buffer[7] =
static_cast<std::uint8_t
>(transactionNumber << 4 | 0x0F);
2260 case static_cast<std::uint8_t
>(Function::ButtonActivationMessage):
2268 std::uint8_t transactionNumber = 0xF;
2277 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2278 static_cast<std::uint8_t
>(Function::ButtonActivationMessage),
2280 static_cast<std::uint8_t
>(objectID),
2281 static_cast<std::uint8_t
>(objectID >> 8),
2282 static_cast<std::uint8_t
>(parentObjectID),
2283 static_cast<std::uint8_t
>(parentObjectID >> 8),
2289 buffer[7] =
static_cast<std::uint8_t
>(transactionNumber << 4 | 0x0F);
2296 case static_cast<std::uint8_t
>(Function::PointingEventMessage):
2303 std::uint8_t transactionNumber = 0xF;
2323 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2324 static_cast<std::uint8_t
>(Function::PointingEventMessage),
2325 static_cast<std::uint8_t
>(xPosition),
2326 static_cast<std::uint8_t
>(xPosition >> 8),
2327 static_cast<std::uint8_t
>(yPosition),
2328 static_cast<std::uint8_t
>(yPosition >> 8),
2336 buffer[5] =
static_cast<std::uint8_t
>((transactionNumber << 4) | touchState);
2341 buffer[5] = touchState;
2347 case static_cast<std::uint8_t
>(Function::VTSelectInputObjectMessage):
2350 bool objectSelected = (0x01 == message.
get_uint8_at(3));
2351 bool objectOpenForInput =
true;
2358 std::uint8_t transactionNumber = 0xF;
2367 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2368 static_cast<std::uint8_t
>(Function::VTSelectInputObjectMessage),
2369 static_cast<std::uint8_t
>(objectID),
2370 static_cast<std::uint8_t
>(objectID >> 8),
2371 static_cast<std::uint8_t
>(objectSelected ? 0x01 : 0x00),
2380 buffer[4] = (objectOpenForInput ? 0x01 : 0x00);
2384 buffer[7] =
static_cast<std::uint8_t
>(transactionNumber << 4 | 0x0F);
2391 case static_cast<std::uint8_t
>(Function::VTESCMessage):
2394 std::uint8_t errorCode = message.
get_uint8_at(3) & 0x1F;
2398 std::uint8_t transactionNumber = 0xF;
2408 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2409 static_cast<std::uint8_t
>(Function::VTESCMessage),
2410 static_cast<std::uint8_t
>(objectID),
2411 static_cast<std::uint8_t
>(objectID >> 8),
2416 static_cast<std::uint8_t
>((transactionNumber << 4) | 0x0F),
2423 case static_cast<std::uint8_t
>(Function::VTChangeNumericValueMessage):
2427 std::uint8_t transactionNumber = 0xF;
2437 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2438 static_cast<std::uint8_t
>(Function::VTChangeNumericValueMessage),
2439 static_cast<std::uint8_t
>(objectID),
2440 static_cast<std::uint8_t
>(objectID >> 8),
2442 static_cast<std::uint8_t
>(value),
2443 static_cast<std::uint8_t
>(value >> 8),
2444 static_cast<std::uint8_t
>(value >> 16),
2445 static_cast<std::uint8_t
>(value >> 24),
2449 buffer[3] =
static_cast<std::uint8_t
>(transactionNumber << 4 | 0x0F);
2455 case static_cast<std::uint8_t
>(Function::VTChangeActiveMaskMessage):
2460 bool maskOrChildHasErrors = message.
get_bool_at(3, 3);
2472 maskOrChildHasErrors,
2477 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2478 static_cast<std::uint8_t
>(Function::VTChangeActiveMaskMessage),
2479 static_cast<std::uint8_t
>(maskObjectID),
2480 static_cast<std::uint8_t
>(maskObjectID >> 8),
2491 case static_cast<std::uint8_t
>(Function::VTChangeSoftKeyMaskMessage):
2497 bool maskOrChildHasErrors = message.
get_bool_at(5, 3);
2505 maskOrChildHasErrors,
2510 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2511 static_cast<std::uint8_t
>(Function::VTChangeSoftKeyMaskMessage),
2512 static_cast<std::uint8_t
>(dataOrAlarmMaskID),
2513 static_cast<std::uint8_t
>(dataOrAlarmMaskID >> 8),
2514 static_cast<std::uint8_t
>(softKeyMaskID),
2515 static_cast<std::uint8_t
>(softKeyMaskID >> 8),
2524 case static_cast<std::uint8_t
>(Function::VTChangeStringValueMessage):
2528 std::string value = std::string(message.
get_data().begin() + 4, message.
get_data().begin() + 4 + stringLength);
2533 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2534 static_cast<std::uint8_t
>(Function::VTChangeStringValueMessage),
2537 static_cast<std::uint8_t
>(objectID),
2538 static_cast<std::uint8_t
>(objectID >> 8),
2547 case static_cast<std::uint8_t
>(Function::VTOnUserLayoutHideShowMessage):
2563 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer;
2580 case static_cast<std::uint8_t
>(Function::VTControlAudioSignalTerminationMessage):
2586 std::uint8_t transactionNumber = 0xF;
2591 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
2592 static_cast<std::uint8_t
>(Function::VTControlAudioSignalTerminationMessage),
2593 static_cast<std::uint8_t
>(terminated ? 0x01 : 0x00),
2594 static_cast<std::uint8_t
>((transactionNumber << 4) | 0x0F),
2606 case static_cast<std::uint8_t
>(Function::PreferredAssignmentCommand):
2610 LOG_ERROR(
"[AUX-N]: Preferred Assignment Error - Auxiliary Input Unit(s) (NAME or Model Identification Code) not valid");
2614 LOG_ERROR(
"[AUX-N]: Preferred Assignment Error - Function Object ID(S) not valid");
2618 LOG_ERROR(
"[AUX-N]: Preferred Assignment Error - Input Object ID(s) not valid");
2622 LOG_ERROR(
"[AUX-N]: Preferred Assignment Error - Duplicate Object ID of Auxiliary Function");
2626 LOG_ERROR(
"[AUX-N]: Preferred Assignment Error - Other");
2632 LOG_ERROR(
"[AUX-N]: Auxiliary Function Object ID of faulty assignment: " + isobus::to_string(faultyObjectID));
2636 LOG_DEBUG(
"[AUX-N]: Preferred Assignment OK");
2642 case static_cast<std::uint8_t
>(Function::AuxiliaryAssignmentTypeTwoCommand):
2647 bool storeAsPreferred = message.
get_bool_at(9, 7);
2648 std::uint8_t functionType = (message.
get_uint8_at(9) & 0x1F);
2652 bool hasError =
false;
2653 bool isAlreadyAssigned =
false;
2660 aux.functions.clear();
2662 LOG_INFO(
"[AUX-N] Unassigned all functions");
2668 for (
auto iter = aux.functions.begin(); iter != aux.functions.end();)
2670 if (iter->functionObjectID == functionObjectID)
2672 aux.functions.erase(iter);
2673 if (storeAsPreferred)
2677 LOG_INFO(
"[AUX-N] Unassigned function " + isobus::to_string(
static_cast<int>(functionObjectID)) +
" from input " + isobus::to_string(
static_cast<int>(inputObjectID)));
2690 return aux.name == isoName;
2697 auto location = std::find(result->functions.begin(), result->functions.end(), assignment);
2698 if (location == std::end(result->functions))
2700 result->functions.push_back(assignment);
2701 if (storeAsPreferred)
2705 LOG_INFO(
"[AUX-N]: Assigned function " + isobus::to_string(
static_cast<int>(functionObjectID)) +
" to input " + isobus::to_string(
static_cast<int>(inputObjectID)));
2710 isAlreadyAssigned =
true;
2711 LOG_WARNING(
"[AUX-N]: Unable to store preferred assignment due to missing auxiliary input device with name: " + isobus::to_string(isoName));
2717 LOG_WARNING(
"[AUX-N]: Unable to store preferred assignment due to unsupported function type: " + isobus::to_string(functionType));
2723 LOG_WARNING(
"[AUX-N]: Unable to store preferred assignment due to missing auxiliary input device with name: " + isobus::to_string(isoName));
2730 LOG_WARNING(
"[AUX-N]: Received AuxiliaryAssignmentTypeTwoCommand with wrong data length: " + isobus::to_string(message.
get_data_length()) +
" but expected 14.");
2735 case static_cast<std::uint8_t
>(Function::AuxiliaryInputTypeTwoStatusMessage):
2753 auto result = std::find_if(aux.functions.begin(), aux.functions.end(), [&inputObjectID](
const AssignedAuxiliaryFunction &assignment) {
2754 return assignment.inputObjectID == inputObjectID;
2756 if (aux.functions.end() != result)
2764 case static_cast<std::uint8_t
>(Function::AuxiliaryInputStatusTypeTwoEnableCommand):
2768 auto result = std::find_if(parentVT->
ourAuxiliaryInputs.begin(), parentVT->
ourAuxiliaryInputs.end(), [&inputObjectID](
const std::pair<std::uint16_t, AuxiliaryInputState> &input) {
2769 return input.first == inputObjectID;
2772 if (!isInvalidObjectID)
2774 result->second.enabled = shouldEnable;
2780 case static_cast<std::uint8_t
>(Function::VTStatusMessage):
2791 case static_cast<std::uint8_t
>(Function::GetMemoryMessage):
2805 LOG_ERROR(
"[VT]: Connection Failed Not Enough Memory");
2811 case static_cast<std::uint8_t
>(Function::GetNumberOfSoftKeysMessage):
2824 case static_cast<std::uint8_t
>(Function::GetTextFontDataMessage):
2836 case static_cast<std::uint8_t
>(Function::GetHardwareMessage):
2864 case static_cast<std::uint8_t
>(Function::GetVersionsResponse):
2869 const std::uint8_t numberOfLabels = message.
get_uint8_at(1);
2870 constexpr std::size_t LABEL_LENGTH = 7;
2872 if (numberOfLabels > 0)
2875 bool labelMatched =
false;
2876 const std::size_t remainingLength = (2 + (LABEL_LENGTH * numberOfLabels));
2880 for (std::uint_fast8_t i = 0; i < numberOfLabels; i++)
2882 char tempStringLabel[8] = { 0 };
2883 tempStringLabel[0] = message.
get_uint8_at(2 + (LABEL_LENGTH * i));
2884 tempStringLabel[1] = message.
get_uint8_at(3 + (LABEL_LENGTH * i));
2885 tempStringLabel[2] = message.
get_uint8_at(4 + (LABEL_LENGTH * i));
2886 tempStringLabel[3] = message.
get_uint8_at(5 + (LABEL_LENGTH * i));
2887 tempStringLabel[4] = message.
get_uint8_at(6 + (LABEL_LENGTH * i));
2888 tempStringLabel[5] = message.
get_uint8_at(7 + (LABEL_LENGTH * i));
2889 tempStringLabel[6] = message.
get_uint8_at(8 + (LABEL_LENGTH * i));
2890 tempStringLabel[7] =
'\0';
2891 std::string labelDecoded(tempStringLabel);
2892 std::string tempActualLabel(parentVT->
objectPools[0].versionLabel);
2895 while (tempActualLabel.size() < LABEL_LENGTH)
2897 tempActualLabel.push_back(
' ');
2900 if (tempActualLabel.size() > LABEL_LENGTH)
2902 tempActualLabel.resize(LABEL_LENGTH);
2905 if (tempActualLabel == labelDecoded)
2907 labelMatched =
true;
2909 LOG_INFO(
"[VT]: VT Server has a matching label for " + isobus::to_string(labelDecoded) +
". It will be loaded and upload will be skipped.");
2914 LOG_INFO(
"[VT]: VT Server has a label for " + isobus::to_string(labelDecoded) +
". This version will be deleted.");
2915 const std::array<std::uint8_t, 7> deleteBuffer = {
2916 static_cast<std::uint8_t
>(labelDecoded[0]),
2917 static_cast<std::uint8_t
>(labelDecoded[1]),
2918 static_cast<std::uint8_t
>(labelDecoded[2]),
2919 static_cast<std::uint8_t
>(labelDecoded[3]),
2920 static_cast<std::uint8_t
>(labelDecoded[4]),
2921 static_cast<std::uint8_t
>(labelDecoded[5]),
2922 static_cast<std::uint8_t
>(labelDecoded[6])
2926 LOG_WARNING(
"[VT]: Failed to send the delete version message for label " + isobus::to_string(labelDecoded));
2932 LOG_INFO(
"[VT]: No version label from the VT matched. Client will upload the pool and store it instead.");
2938 LOG_WARNING(
"[VT]: Get Versions Response length is not long enough. Message ignored.");
2943 LOG_INFO(
"[VT]: No version label from the VT matched. Client will upload the pool and store it instead.");
2949 LOG_WARNING(
"[VT]: Get Versions Response ignored!");
2954 case static_cast<std::uint8_t
>(Function::LoadVersionCommand):
2960 LOG_INFO(
"[VT]: Loaded object pool version from VT non-volatile memory with no errors.");
2968 LOG_DEBUG(
"[AUX-N]: Sent preferred assignments after LoadVersionCommand.");
2972 LOG_WARNING(
"[AUX-N]: Failed to send preferred assignments after LoadVersionCommand.");
2981 LOG_WARNING(
"[VT]: Load Versions Response error: File system error or corruption.");
2985 LOG_WARNING(
"[VT]: Load Versions Response error: Insufficient memory.");
2989 LOG_WARNING(
"[VT]: Load Versions Response error: Any other error.");
2993 LOG_WARNING(
"[VT]: Switching to pool upload instead.");
2999 LOG_WARNING(
"[VT]: Load Versions Response ignored!");
3004 case static_cast<std::uint8_t
>(Function::StoreVersionCommand):
3012 LOG_INFO(
"[VT]: Stored object pool with no error.");
3019 LOG_WARNING(
"[VT]: Store Versions Response error: Version label is not correct.");
3023 LOG_WARNING(
"[VT]: Store Versions Response error: Insufficient memory.");
3027 LOG_WARNING(
"[VT]: Store Versions Response error: Any other error.");
3033 LOG_WARNING(
"[VT]: Store Versions Response ignored!");
3038 case static_cast<std::uint8_t
>(Function::DeleteVersionCommand):
3042 LOG_INFO(
"[VT]: Delete Version Response OK!");
3048 LOG_WARNING(
"[VT]: Delete Version Response error: Version label is not correct, or unknown.");
3052 LOG_WARNING(
"[VT]: Delete Version Response error: Any other error.");
3058 case static_cast<std::uint8_t
>(Function::EndOfObjectPoolMessage):
3063 bool vtRanOutOfMemory = message.
get_bool_at(1, 1);
3065 std::uint16_t parentObjectIDOfFaultyObject = message.
get_uint16_at(2);
3066 std::uint16_t objectIDOfFaultyObject = message.
get_uint16_at(4);
3067 std::uint8_t objectPoolErrorBitmask = message.
get_uint8_at(6);
3069 if ((!anyErrorInPool) &&
3070 (0 == objectPoolErrorBitmask))
3075 objectPool.scaledObjectPool.clear();
3079 if (!parentVT->
objectPools[0].versionLabel.empty())
3092 LOG_DEBUG(
"[AUX-N]: Sent preferred assignments after EndOfObjectPoolMessage.");
3096 LOG_WARNING(
"[AUX-N]: Failed to send preferred assignments after EndOfObjectPoolMessage.");
3103 LOG_ERROR(
"[VT]: Error in end of object pool message." +
3104 std::string(
"Faulty Object ") +
3105 isobus::to_string(
static_cast<int>(objectIDOfFaultyObject)) +
3106 std::string(
" Faulty Object Parent ") +
3107 isobus::to_string(
static_cast<int>(parentObjectIDOfFaultyObject)) +
3108 std::string(
" Pool error bitmask value ") +
3109 isobus::to_string(
static_cast<int>(objectPoolErrorBitmask)));
3110 if (vtRanOutOfMemory)
3112 LOG_ERROR(
"[VT]: Ran out of memory");
3116 LOG_ERROR(
"[VT]: Reported other errors in EOM response");
3123 case static_cast<std::uint8_t
>(Function::HideShowObjectCommand):
3124 case static_cast<std::uint8_t
>(Function::EnableDisableObjectCommand):
3125 case static_cast<std::uint8_t
>(Function::SelectInputObjectCommand):
3126 case static_cast<std::uint8_t
>(Function::ESCCommand):
3127 case static_cast<std::uint8_t
>(Function::ControlAudioSignalCommand):
3128 case static_cast<std::uint8_t
>(Function::SetAudioVolumeCommand):
3129 case static_cast<std::uint8_t
>(Function::ChangeChildLocationCommand):
3130 case static_cast<std::uint8_t
>(Function::ChangeChildPositionCommand):
3131 case static_cast<std::uint8_t
>(Function::ChangeSizeCommand):
3132 case static_cast<std::uint8_t
>(Function::ChangeBackgroundColourCommand):
3133 case static_cast<std::uint8_t
>(Function::ChangeNumericValueCommand):
3134 case static_cast<std::uint8_t
>(Function::ChangeStringValueCommand):
3135 case static_cast<std::uint8_t
>(Function::ChangeEndPointCommand):
3136 case static_cast<std::uint8_t
>(Function::ChangeFontAttributesCommand):
3137 case static_cast<std::uint8_t
>(Function::ChangeLineAttributesCommand):
3138 case static_cast<std::uint8_t
>(Function::ChangeFillAttributesCommand):
3139 case static_cast<std::uint8_t
>(Function::ChangeActiveMaskCommand):
3140 case static_cast<std::uint8_t
>(Function::ChangeSoftKeyMaskCommand):
3141 case static_cast<std::uint8_t
>(Function::ChangeAttributeCommand):
3142 case static_cast<std::uint8_t
>(Function::ChangePriorityCommand):
3143 case static_cast<std::uint8_t
>(Function::ChangeListItemCommand):
3144 case static_cast<std::uint8_t
>(Function::DeleteObjectPoolCommand):
3145 case static_cast<std::uint8_t
>(Function::LockUnlockMaskCommand):
3146 case static_cast<std::uint8_t
>(Function::ExecuteMacroCommand):
3147 case static_cast<std::uint8_t
>(Function::ChangeObjectLabelCommand):
3148 case static_cast<std::uint8_t
>(Function::ChangePolygonPointCommand):
3149 case static_cast<std::uint8_t
>(Function::ChangePolygonScaleCommand):
3150 case static_cast<std::uint8_t
>(Function::GraphicsContextCommand):
3151 case static_cast<std::uint8_t
>(Function::GetAttributeValueMessage):
3152 case static_cast<std::uint8_t
>(Function::SelectColourMapCommand):
3153 case static_cast<std::uint8_t
>(Function::ExecuteExtendedMacroCommand):
3154 case static_cast<std::uint8_t
>(Function::SelectActiveWorkingSet):
3166 case static_cast<std::uint8_t
>(Function::UnsupportedVTFunctionMessage):
3168 std::uint8_t unsupportedFunction = message.
get_uint8_at(1);
3173 LOG_WARNING(
"[VT]: Server indicated VT Function '%llu' is unsupported, caching it", unsupportedFunction);
3178 std::uint8_t unsupportedFunction = message.
get_uint8_at(0);
3179 LOG_WARNING(
"[VT]: Server sent function '%llu' which we do not support", unsupportedFunction);
3180 std::array<std::uint8_t, CAN_DATA_LENGTH> buffer{
3181 static_cast<std::uint8_t
>(Function::UnsupportedVTFunctionMessage),
3182 unsupportedFunction,
3197 case static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ECUtoVirtualTerminal):
3201 case static_cast<std::uint8_t
>(Function::AuxiliaryInputTypeTwoMaintenanceMessage):
3203 std::uint16_t modelIdentificationCode = message.
get_uint16_at(1);
3209 return aux.modelIdentificationCode == modelIdentificationCode;
3215 LOG_INFO(
"[AUX-N]: New auxiliary input device with name: " +
3216 isobus::to_string(inputDevice.name) +
3217 " and model identification code: " +
3218 isobus::to_string(modelIdentificationCode));
3236 LOG_WARNING(
"[VT]: VT-ECU Client message invalid");
3242 std::shared_ptr<InternalControlFunction>,
3243 std::shared_ptr<ControlFunction> destinationControlFunction,
3245 void *parentPointer)
3247 if ((
nullptr != parentPointer) &&
3248 (
static_cast<std::uint32_t
>(CANLibParameterGroupNumber::ECUtoVirtualTerminal) == parameterGroupNumber) &&
3249 (
nullptr != destinationControlFunction))
3268 std::uint32_t bytesOffset,
3269 std::uint32_t numberOfBytesNeeded,
3270 std::uint8_t *chunkBuffer,
3271 void *parentPointer)
3273 bool retVal =
false;
3275 if ((
nullptr != parentPointer) &&
3276 (
nullptr != chunkBuffer) &&
3277 (0 != numberOfBytesNeeded))
3280 std::uint32_t poolIndex = std::numeric_limits<std::uint32_t>::max();
3281 bool usingExternalCallback =
false;
3284 for (std::uint32_t i = 0; i < parentVTClient->
objectPools.size(); i++)
3289 usingExternalCallback = parentVTClient->
objectPools[i].useDataCallback;
3295 if ((std::numeric_limits<std::uint32_t>::max() != poolIndex) &&
3296 (bytesOffset + numberOfBytesNeeded) <= parentVTClient->
objectPools[poolIndex].objectPoolSize + 1)
3299 if ((0 != parentVTClient->
objectPools[poolIndex].autoScaleDataMaskOriginalDimension) && (0 != parentVTClient->
objectPools[poolIndex].autoScaleSoftKeyDesignatorOriginalHeight))
3303 if (0 == bytesOffset)
3305 chunkBuffer[0] =
static_cast<std::uint8_t
>(Function::ObjectPoolTransferMessage);
3306 memcpy(&chunkBuffer[1], &parentVTClient->
objectPools[poolIndex].scaledObjectPool[bytesOffset], numberOfBytesNeeded - 1);
3311 memcpy(chunkBuffer, &parentVTClient->
objectPools[poolIndex].scaledObjectPool[bytesOffset - 1], numberOfBytesNeeded);
3316 if (usingExternalCallback)
3319 if (0 == bytesOffset)
3321 chunkBuffer[0] =
static_cast<std::uint8_t
>(Function::ObjectPoolTransferMessage);
3322 retVal = parentVTClient->
objectPools[poolIndex].dataCallback(callbackIndex, bytesOffset, numberOfBytesNeeded - 1, &chunkBuffer[1], parentVTClient);
3327 retVal = parentVTClient->
objectPools[poolIndex].dataCallback(callbackIndex, bytesOffset - 1, numberOfBytesNeeded, chunkBuffer, parentVTClient);
3334 if (0 == bytesOffset)
3336 chunkBuffer[0] =
static_cast<std::uint8_t
>(Function::ObjectPoolTransferMessage);
3337 memcpy(&chunkBuffer[1], &parentVTClient->
objectPools[poolIndex].objectPoolDataPointer[bytesOffset], numberOfBytesNeeded - 1);
3342 memcpy(chunkBuffer, &parentVTClient->
objectPools[poolIndex].objectPoolDataPointer[bytesOffset - 1], numberOfBytesNeeded);
3353 bool retVal =
false;
3357 if ((0 != objectPool.autoScaleDataMaskOriginalDimension) &&
3358 (0 != objectPool.autoScaleSoftKeyDesignatorOriginalHeight))
3374 if (
nullptr != objectPool.objectPoolDataPointer)
3376 objectPool.scaledObjectPool.resize(objectPool.objectPoolSize);
3377 memcpy(&objectPool.scaledObjectPool[0], objectPool.objectPoolDataPointer, objectPool.objectPoolSize);
3379 else if (
nullptr != objectPool.objectPoolVectorPointer)
3381 objectPool.scaledObjectPool.resize(objectPool.objectPoolVectorPointer->size());
3382 std::copy(objectPool.objectPoolVectorPointer->begin(), objectPool.objectPoolVectorPointer->end(), objectPool.scaledObjectPool.begin());
3384 else if (objectPool.useDataCallback)
3386 objectPool.scaledObjectPool.resize(objectPool.objectPoolSize);
3388 for (std::uint32_t i = 0; i < objectPool.objectPoolSize; i++)
3390 retVal &= objectPool.dataCallback(i, i, 1, &objectPool.scaledObjectPool[i],
this);
3400 auto poolIterator = objectPool.scaledObjectPool.begin();
3402 while ((poolIterator != objectPool.scaledObjectPool.end()) &&
3408 static_cast<float>(
get_softkey_x_axis_pixels()) /
static_cast<float>(objectPool.autoScaleSoftKeyDesignatorOriginalHeight),
3414 static_cast<float>(
get_number_x_pixels()) /
static_cast<float>(objectPool.autoScaleDataMaskOriginalDimension),
3423 LOG_DEBUG(
"[VT]: Resized an object: " +
3424 isobus::to_string(
static_cast<int>((*poolIterator)) | (
static_cast<int>((*poolIterator + 1))) << 8) +
3426 isobus::to_string(
static_cast<int>((*(poolIterator + 2)))) +
3428 isobus::to_string(
static_cast<int>(objectSize)));
3433 LOG_ERROR(
"[VT]: Failed to resize an object: " +
3434 isobus::to_string(
static_cast<int>((*poolIterator)) | (
static_cast<int>((*poolIterator + 1))) << 8) +
3436 isobus::to_string(
static_cast<int>((*poolIterator + 2))) +
3438 isobus::to_string(
static_cast<int>(objectSize)));
3440 poolIterator += objectSize;
3448 bool retVal =
false;
3503 retVal =
static_cast<FontSize>(
static_cast<std::uint8_t
>(originalFont) - 1);
3510 static constexpr float SCALE_FACTOR_POSITIVE_FUDGE = 1.05f;
3511 static constexpr float SCALE_FACTOR_NEGATIVE_FUDGE = 0.95f;
3514 if (scaleFactor > SCALE_FACTOR_POSITIVE_FUDGE || scaleFactor < SCALE_FACTOR_NEGATIVE_FUDGE)
3516 const std::unordered_map<FontSize, std::map<float, FontSize, std::greater<float>>> FONT_SCALING_MAPPER{
3699 auto iterator = FONT_SCALING_MAPPER.find(originalFont);
3700 if (iterator != FONT_SCALING_MAPPER.end())
3702 for (
auto &pair : iterator->second)
3704 if (scaleFactor >= pair.first)
3706 retVal = pair.second;
3712 if (retVal == originalFont)
3715 LOG_ERROR(
"[VT]: Unable to scale font type " + isobus::to_string(
static_cast<int>(originalFont)) +
3716 " with scale factor " + isobus::to_string(scaleFactor) +
". Returning original font.");
3724 std::uint32_t retVal = 0;
3875 LOG_ERROR(
"[VT]: Cannot autoscale object pool due to unknown object minimum length - type " + isobus::to_string(
static_cast<int>(type)));
3887 switch (currentObjectType)
3891 const std::uint32_t sizeOfChildObjects = (buffer[7] * 6);
3892 const std::uint32_t sizeOfMacros = (buffer[8] * 2);
3893 const std::uint32_t sizeOfLanguageCodes = (buffer[9] * 2);
3894 retVal += (sizeOfLanguageCodes + sizeOfChildObjects + sizeOfMacros);
3900 const std::uint32_t sizeOfChildObjects = (buffer[6] * 6);
3901 const std::uint32_t sizeOfMacros = (buffer[7] * 2);
3902 retVal += (sizeOfChildObjects + sizeOfMacros);
3909 const std::uint32_t sizeOfChildObjects = (buffer[8] * 6);
3910 const std::uint32_t sizeOfMacros = (buffer[9] * 2);
3911 retVal += (sizeOfChildObjects + sizeOfMacros);
3917 const std::uint32_t sizeOfChildObjects = (buffer[4] * 2);
3918 const std::uint32_t sizeOfMacros = (buffer[5] * 2);
3919 retVal += (sizeOfChildObjects + sizeOfMacros);
3925 const std::uint32_t sizeOfChildObjects = (buffer[5] * 6);
3926 const std::uint32_t sizeOfMacros = (buffer[6] * 2);
3927 retVal += (sizeOfChildObjects + sizeOfMacros);
3933 const std::uint32_t sizeOfChildObjects = (buffer[11] * 6);
3934 const std::uint32_t sizeOfMacros = (buffer[12] * 2);
3935 retVal += (sizeOfChildObjects + sizeOfMacros);
3941 const std::uint32_t sizeOfMacros = (buffer[12] * 2);
3942 retVal += sizeOfMacros;
3948 const std::uint32_t sizeOfValue = buffer[16];
3949 const std::uint32_t sizeOfMacros = (buffer[18 + sizeOfValue] * 2);
3950 retVal += (sizeOfValue + sizeOfMacros);
3956 const std::uint32_t sizeOfMacros = (buffer[37] * 2);
3957 retVal += sizeOfMacros;
3963 const std::uint32_t sizeOfMacros = (buffer[12] * 2);
3964 const std::uint32_t sizeOfListObjectIDs = (buffer[10] * 2);
3965 retVal += (sizeOfMacros + sizeOfListObjectIDs);
3971 const std::uint32_t sizeOfValue = (
static_cast<uint16_t
>(buffer[14]) |
static_cast<uint16_t
>(buffer[15] << 8));
3972 const std::uint32_t sizeOfMacros = (buffer[16 + sizeOfValue] * 2);
3973 retVal += (sizeOfMacros + sizeOfValue);
3979 const std::uint32_t sizeOfMacros = (buffer[28] * 2);
3980 retVal += sizeOfMacros;
3986 const std::uint32_t sizeOfMacros = (buffer[11] * 2);
3987 const std::uint32_t sizeOfListObjectIDs = (buffer[10] * 2);
3988 retVal += (sizeOfMacros + sizeOfListObjectIDs);
3994 const std::uint32_t sizeOfMacros = (buffer[10] * 2);
3995 retVal += sizeOfMacros;
4001 const std::uint32_t sizeOfMacros = (buffer[12] * 2);
4002 retVal += sizeOfMacros;
4008 const std::uint32_t sizeOfMacros = (buffer[14] * 2);
4009 retVal += sizeOfMacros;
4015 const std::uint32_t sizeOfPoints = (buffer[12] * 4);
4016 const std::uint32_t sizeOfMacros = (buffer[13] * 2);
4017 retVal += (sizeOfMacros + sizeOfPoints);
4023 const std::uint32_t sizeOfMacros = (buffer[20] * 2);
4024 retVal += sizeOfMacros;
4030 const std::uint32_t sizeOfMacros = (buffer[23] * 2);
4031 retVal += sizeOfMacros;
4037 const std::uint32_t sizeOfMacros = (buffer[26] * 2);
4038 retVal += sizeOfMacros;
4044 const std::uint32_t sizeOfMacros = (buffer[16] * 2);
4045 const std::uint32_t sizeOfRawData = (
static_cast<std::uint32_t
>(buffer[12]) |
4046 (
static_cast<std::uint32_t
>(buffer[13]) << 8) |
4047 (
static_cast<std::uint32_t
>(buffer[14]) << 16) |
4048 (
static_cast<std::uint32_t
>(buffer[15]) << 24));
4049 retVal += (sizeOfRawData + sizeOfMacros);
4066 const std::uint32_t sizeOfValue = (
static_cast<uint16_t
>(buffer[3]) |
static_cast<uint16_t
>(buffer[4]) << 8);
4067 retVal += sizeOfValue;
4075 const std::uint32_t sizeOfMacros = (buffer[7] * 2);
4076 retVal += sizeOfMacros;
4082 const std::uint32_t sizeOfValidationString = buffer[4];
4083 const std::uint32_t sizeOfMacros = (buffer[5 + sizeOfValidationString] * 2);
4084 retVal += (sizeOfMacros + sizeOfValidationString);
4090 const std::uint32_t numberOfCodePlanes = buffer[5];
4091 retVal += (numberOfCodePlanes * 2);
4097 const std::uint32_t numberOfMacroBytes = (
static_cast<std::uint16_t
>(buffer[3]) | (
static_cast<std::uint16_t
>(buffer[4]) << 8));
4098 retVal += numberOfMacroBytes;
4104 const std::uint32_t numberIndexes = (
static_cast<std::uint16_t
>(buffer[3]) | (
static_cast<std::uint16_t
>(buffer[4]) << 8));
4105 retVal += numberIndexes;
4111 const std::uint32_t sizeOfReferences = (buffer[14] * 2);
4112 const std::uint32_t numberObjects = (buffer[15] * 6);
4113 const std::uint32_t sizeOfMacros = (buffer[16] * 2);
4114 retVal += (sizeOfMacros + numberObjects + sizeOfReferences);
4120 const std::uint32_t numberObjects = (buffer[8] * 2);
4121 const std::uint32_t sizeOfMacros = (buffer[9] * 2);
4122 retVal += (sizeOfMacros + numberObjects);
4128 const std::uint32_t sizeOfLabeledObjects = ((
static_cast<uint16_t
>(buffer[4]) |
static_cast<uint16_t
>(buffer[5]) << 8) * 7);
4129 retVal += sizeOfLabeledObjects;
4135 const std::uint32_t sizeOfObjects = (buffer[12] * 2);
4136 retVal += sizeOfObjects;
4142 const std::uint32_t sizeOfObjects = (buffer[15] * 6);
4143 const std::uint32_t sizeOfMacros = (buffer[16] * 2);
4144 retVal += (sizeOfMacros + sizeOfObjects);
4151 const std::uint32_t sizeOfObjects = (buffer[5] * 6);
4152 retVal += sizeOfObjects;
4159 const std::uint32_t sizeOfObjects = (buffer[6] * 6);
4160 retVal += sizeOfObjects;
4166 LOG_ERROR(
"[VT]: Cannot autoscale object pool due to unknown object total length - type " + isobus::to_string(
static_cast<int>(buffer[2])));
4175 auto width =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[3]) | (
static_cast<std::uint16_t
>(buffer[4]) << 8))) * scaleFactor);
4176 auto height =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[5]) | (
static_cast<std::uint16_t
>(buffer[6]) << 8))) * scaleFactor);
4177 buffer[3] = (width & 0xFF);
4178 buffer[4] = (width >> 8);
4179 buffer[5] = (height & 0xFF);
4180 buffer[6] = (height >> 8);
4185 bool retVal =
false;
4193 const std::uint8_t childrenToFollow = buffer[6];
4195 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4197 auto childX =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[10 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[11 + (6 * i)]) << 8))) * scaleFactor);
4198 auto childY =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[12 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[13 + (6 * i)]) << 8))) * scaleFactor);
4199 buffer[10 + (6 * i)] = (childX & 0xFF);
4200 buffer[11 + (6 * i)] = (childX >> 8);
4201 buffer[12 + (6 * i)] = (childY & 0xFF);
4202 buffer[13 + (6 * i)] = (childY >> 8);
4210 const std::uint8_t childrenToFollow = buffer[8];
4212 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4214 auto childX =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[12 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[13 + (6 * i)]) << 8))) * scaleFactor);
4215 auto childY =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[14 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[15 + (6 * i)]) << 8))) * scaleFactor);
4216 buffer[12 + (6 * i)] = (childX & 0xFF);
4217 buffer[13 + (6 * i)] = (childX >> 8);
4218 buffer[14 + (6 * i)] = (childY & 0xFF);
4219 buffer[15 + (6 * i)] = (childY >> 8);
4227 std::uint8_t childrenToFollow = buffer[8];
4234 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4236 auto childX =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[12 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[13 + (6 * i)]) << 8))) * scaleFactor);
4237 auto childY =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[14 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[15 + (6 * i)]) << 8))) * scaleFactor);
4238 buffer[12 + (6 * i)] = (childX & 0xFF);
4239 buffer[13 + (6 * i)] = (childX >> 8);
4240 buffer[14 + (6 * i)] = (childY & 0xFF);
4241 buffer[15 + (6 * i)] = (childY >> 8);
4249 std::uint8_t childrenToFollow = buffer[11];
4255 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4257 auto childWidth =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[15 + (6 * i)]) | (
static_cast<std::uint16_t
>(buffer[16 + (6 * i)]) << 8))) * scaleFactor);
4258 auto childHeight =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[17 + (6 * i)]) | (
static_cast<std::uint16_t
>(buffer[18 + (6 * i)]) << 8))) * scaleFactor);
4259 buffer[15 + (6 * i)] = (childWidth & 0xFF);
4260 buffer[16 + (6 * i)] = (childWidth >> 8);
4261 buffer[17 + (6 * i)] = (childHeight & 0xFF);
4262 buffer[18 + (6 * i)] = (childHeight >> 8);
4270 auto width =
static_cast<std::uint16_t
>((
static_cast<std::uint16_t
>(buffer[4]) | (
static_cast<std::uint16_t
>(buffer[5]) << 8)));
4273 buffer[4] = (width & 0xFF);
4274 buffer[5] = (width >> 8);
4298 auto width =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[5]) | (
static_cast<std::uint16_t
>(buffer[6]) << 8))) * scaleFactor);
4299 auto height =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[7]) | (
static_cast<std::uint16_t
>(buffer[8]) << 8))) * scaleFactor);
4300 buffer[5] = (width & 0xFF);
4301 buffer[6] = (width >> 8);
4302 buffer[7] = (height & 0xFF);
4303 buffer[8] = (height >> 8);
4310 const std::uint8_t numberOfPoints = buffer[12];
4316 for (std::uint_fast8_t i = 0; i < numberOfPoints; i++)
4318 auto xPosition =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[14 + (4 * i)]) | (
static_cast<std::uint16_t
>(buffer[15 + (4 * i)]) << 8))) * scaleFactor);
4319 auto yPosition =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[16 + (4 * i)]) | (
static_cast<std::uint16_t
>(buffer[17 + (4 * i)]) << 8))) * scaleFactor);
4320 buffer[14 + (4 * i)] = (xPosition & 0xFF);
4321 buffer[15 + (4 * i)] = (xPosition >> 8);
4322 buffer[16 + (4 * i)] = (yPosition & 0xFF);
4323 buffer[17 + (4 * i)] = (yPosition >> 8);
4333 auto width =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[3]) | (
static_cast<std::uint16_t
>(buffer[4]) << 8))) * scaleFactor);
4334 buffer[3] = (width & 0xFF);
4335 buffer[4] = (width >> 8);
4345 auto width =
static_cast<std::uint16_t
>(((
static_cast<std::uint16_t
>(buffer[12]) | (
static_cast<std::uint16_t
>(buffer[13]) << 8))) * scaleFactor);
4346 buffer[12] = (width & 0xFF);
4347 buffer[13] = (width >> 8);
4354 std::uint8_t childrenToFollow = buffer[15];
4360 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4362 auto childX =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[20 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[21 + (6 * i)]) << 8))) * scaleFactor);
4363 auto childY =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[22 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[23 + (6 * i)]) << 8))) * scaleFactor);
4364 buffer[20 + (6 * i)] = (childX & 0xFF);
4365 buffer[21 + (6 * i)] = (childX >> 8);
4366 buffer[22 + (6 * i)] = (childY & 0xFF);
4367 buffer[23 + (6 * i)] = (childY >> 8);
4375 const std::uint8_t childrenToFollow = buffer[5];
4377 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4379 auto childX =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[9 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[10 + (6 * i)]) << 8))) * scaleFactor);
4380 auto childY =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[11 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[12 + (6 * i)]) << 8))) * scaleFactor);
4381 buffer[9 + (6 * i)] = (childX & 0xFF);
4382 buffer[10 + (6 * i)] = (childX >> 8);
4383 buffer[11 + (6 * i)] = (childY & 0xFF);
4384 buffer[12 + (6 * i)] = (childY >> 8);
4401 std::uint8_t childrenToFollow = buffer[5];
4403 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4405 auto childX =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[8 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[9 + (6 * i)]) << 8))) * scaleFactor);
4406 auto childY =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[10 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[11 + (6 * i)]) << 8))) * scaleFactor);
4407 buffer[8 + (6 * i)] = (childX & 0xFF);
4408 buffer[9 + (6 * i)] = (childX >> 8);
4409 buffer[10 + (6 * i)] = (childY & 0xFF);
4410 buffer[11 + (6 * i)] = (childY >> 8);
4418 std::uint8_t childrenToFollow = buffer[6];
4420 for (std::uint_fast8_t i = 0; i < childrenToFollow; i++)
4422 auto childX =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[9 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[10 + (6 * i)]) << 8))) * scaleFactor);
4423 auto childY =
static_cast<std::int16_t
>(((
static_cast<std::int16_t
>(buffer[11 + (6 * i)]) | (
static_cast<std::int16_t
>(buffer[12 + (6 * i)]) << 8))) * scaleFactor);
4424 buffer[9 + (6 * i)] = (childX & 0xFF);
4425 buffer[10 + (6 * i)] = (childX >> 8);
4426 buffer[11 + (6 * i)] = (childY & 0xFF);
4427 buffer[12 + (6 * i)] = (childY >> 8);
4435 LOG_DEBUG(
"[VT]: Skipping resize of non-resizable object type " +
4436 isobus::to_string(
static_cast<int>(type)));
4444 LOG_DEBUG(
"[VT]: Skipping resize of non-resizable object type " +
4445 isobus::to_string(
static_cast<int>(type)));
4467 LOG_WARNING(
"[VT]: Server response to a command timed out");
4479 LOG_ERROR(
"[VT]: Cannot send command, not connected");
4495 std::uint8_t functionCode = data[0];
4517 bool alreadyReplaced =
false;
4520 bool matchesFunctionCode = (it->at(0) == data[0]);
4521 if (matchesFunctionCode)
4523 if (!alreadyReplaced)
4526 alreadyReplaced =
true;
4539 return alreadyReplaced;
4564#if !defined CAN_STACK_DISABLE_THREADS && !defined ARDUINO
4572 std::this_thread::sleep_for(std::chrono::milliseconds(50));
Defines some PGNs that are used in the library or are very common.
The main class that manages the ISOBUS stack including: callbacks, Name to Address management,...
A class that acts as a logging sink. The intent is that someone could make their own derived class of...
CANPriority
Defines all the CAN frame priorities that can be encoded in a frame ID.
@ Priority3
Priority highest - 3 (Control messages priority)
@ Priority5
Priority highest - 5.
std::uint32_t get_parameter_group_number() const
Returns the PGN encoded in the identifier.
A class that represents a generic CAN message of arbitrary length.
const std::vector< std::uint8_t > & get_data() const
Gets a reference to the data in the CAN message.
std::uint32_t get_data_length() const
Returns the length of the data in the CAN message.
std::uint32_t get_uint24_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a right-aligned 24-bit integer from the buffer (returned as a uint32_t) at a specific index....
std::shared_ptr< ControlFunction > get_source_control_function() const
Gets the source control function that the message is from.
std::uint8_t get_uint8_at(const std::uint32_t index) const
Get a 8-bit unsigned byte from the buffer at a specific index. A 8-bit unsigned byte can hold a value...
std::uint16_t get_uint16_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 16-bit unsigned integer from the buffer at a specific index. A 16-bit unsigned integer can hold...
CANIdentifier get_identifier() const
Returns the identifier of the message.
bool get_bool_at(const std::uint32_t byteIndex, const std::uint8_t bitIndex, const std::uint8_t length=1) const
Get a bit-boolean from the buffer at a specific index.
std::uint32_t get_uint32_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 32-bit unsigned integer from the buffer at a specific index. A 32-bit unsigned integer can hold...
std::shared_ptr< ControlFunction > get_destination_control_function() const
Gets the destination control function that the message is to.
std::uint64_t get_uint64_at(const std::uint32_t index, const ByteFormat format=ByteFormat::LittleEndian) const
Get a 64-bit unsigned integer from the buffer at a specific index. A 64-bit unsigned integer can hold...
void add_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
This is how you register a callback for any PGN destined for the global address (0xFF)
static CANNetworkManager CANNetwork
Static singleton of the one network manager. Use this to access stack functionality.
void remove_global_parameter_group_number_callback(std::uint32_t parameterGroupNumber, CANLibCallback callback, void *parent)
This is how you remove a callback for any PGN destined for the global address (0xFF)
bool send_can_message(std::uint32_t parameterGroupNumber, const std::uint8_t *dataBuffer, std::uint32_t dataLength, std::shared_ptr< InternalControlFunction > sourceControlFunction, std::shared_ptr< ControlFunction > destinationControlFunction=nullptr, CANIdentifier::CANPriority priority=CANIdentifier::CANPriority::PriorityDefault6, TransmitCompleteCallback txCompleteCallback=nullptr, void *parentPointer=nullptr, DataChunkCallback frameChunkCallback=nullptr)
This is the main way to send a CAN message of any length.
bool get_initialized() const
Returns if initialize has been called yet.
void initialize()
Initializes the interface.
A struct for storing information of a function assigned to an auxiliary input.
std::uint16_t inputObjectID
The object ID assigned on the auxiliary inputs end.
AssignedAuxiliaryFunction(std::uint16_t functionObjectID, std::uint16_t inputObjectID, AuxiliaryTypeTwoFunctionType functionType)
Constructs a AssignedAuxiliaryFunction, sets default values.
bool operator==(const AssignedAuxiliaryFunction &other) const
Allows easy comparison of two AssignedAuxiliaryFunction objects.
AuxiliaryTypeTwoFunctionType functionType
The type of function.
std::uint16_t functionObjectID
The object ID of the function present in our object pool.
An client interface for interacting with a virtual terminal (VT) server.
bool send_change_font_attributes(std::uint16_t objectID, std::uint8_t colour, FontSize size, std::uint8_t type, std::uint8_t styleBitfield)
Sends the change font attributes command.
bool send_extended_load_version(std::array< std::uint8_t, 32 > versionLabel) const
Sends the extended load version message.
HideShowObjectCommand
Enumerates the states that can be sent with a hide/show object command.
EventDispatcher< VTUserLayoutHideShowEvent > & get_vt_user_layout_hide_show_event_dispatcher()
The event dispatcher for when a user-layout object is hidden or shown.
bool send_set_graphics_cursor(std::uint16_t objectID, std::int16_t xPosition, std::int16_t yPosition)
Sends the set graphics cursor command.
EventDispatcher< VTChangeActiveMaskEvent > changeActiveMaskEventDispatcher
A list of all change active mask callbacks.
bool get_support_pointing_device_with_pointing_message() const
Returns if the VT server supports a pointing device with pointing message.
bool send_pan_and_zoom_viewport(std::uint16_t objectID, std::int16_t xAttribute, std::int16_t yAttribute, float zoom)
Sends the pan and zoom viewport command.
bool send_change_polygon_scale(std::uint16_t objectID, std::uint16_t widthAttribute, std::uint16_t heightAttribute)
Sends the change polygon scale command.
bool get_support_drag_operation() const
Returns if the VT supports the drag operation.
void process_command_queue()
Tries to send all messages in the queue.
bool send_auxiliary_input_maintenance() const
Send the auxiliary control type 2 maintenance message.
static void process_standard_object_height_and_width(std::uint8_t *buffer, float scaleFactor)
Resizes the most common VT object format by some scale factor.
@ SetLineAttributesObjectID
Sets the line attribute object ID.
@ SetBackgroundColour
Sets the background colour.
@ EraseRectangle
Erases a rectangle.
@ MoveGraphicsCursor
Moves the cursor relative to current location.
@ DrawPoint
Draws a point.
@ PanViewport
Pans viewport.
@ SetGraphicsCursor
Sets the graphics cursor x/y attributes.
@ SetForegroundColour
Sets the foreground colour.
@ PanAndZoomViewport
Pan and zooms the viewport.
@ DrawVTObject
Draws a VT object.
@ ZoomViewport
Zooms the viewport.
@ CopyViewportToPictureGraphic
Copies the viewport to picture graphic object.
@ ChangeViewportSize
Changes the viewport size.
@ CopyCanvasToPictureGraphic
Copies the canvas to picture graphic object.
@ SetFontAttributesObjectID
Sets the font attribute object ID.
@ SetFillAttributesObjectID
Sets the fill attribute object ID.
@ DrawClosedEllipse
Draws a closed ellipse.
@ DrawRectangle
Draws a rectangle.
@ DrawPolygon
Draws polygon.
std::uint8_t get_active_working_set_master_address() const
Returns the active working set master's address.
bool commandAwaitingResponse
Determines if we are currently waiting for a response to a command.
bool get_support_intermediate_coordinates_during_drag_operations() const
Returns if the VT supports the intermediate coordinates during a drag operation.
bool send_set_font_attributes_object_id(std::uint16_t objectID, std::uint16_t fontAttributesObjectID)
Sends the set fill attributes object ID command.
std::uint8_t connectedVTVersion
The VT server's supported max version.
CurrentObjectPoolUploadState currentObjectPoolState
The current upload state of the object pool being processed.
std::shared_ptr< PartneredControlFunction > get_partner_control_function() const
Returns the control function of the VT server with which this VT client communicates.
void initialize(bool spawnThread)
This function starts the state machine. Call this once you have supplied 1 or more object pool and ar...
std::vector< ObjectPoolDataStruct > objectPools
A container to hold all object pools that have been assigned to the interface.
EventDispatcher< AuxiliaryFunctionEvent > & get_auxiliary_function_event_dispatcher()
The event dispatcher for for when a change in auxiliary input for a function is received.
EventDispatcher< VTChangeStringValueEvent > changeStringValueEventDispatcher
A list of all change string value callbacks.
bool send_store_version(std::array< std::uint8_t, 7 > versionLabel) const
Sends the store version message.
bool send_set_foreground_colour(std::uint16_t objectID, std::uint8_t colour)
Sends the set foreground colour command.
std::uint8_t currentCommandFunctionCode
The VT server's current command function code.
MaskType
The types of object pool masks.
std::uint16_t yPixels
The y pixel dimension as reported by the VT server.
EventDispatcher< VTKeyEvent > softKeyEventDispatcher
A list of all soft key event callbacks.
LanguageCommandInterface languageCommandInterface
Used to determine the language and unit systems in use by the VT server.
bool send_change_child_position(std::uint16_t objectID, std::uint16_t parentObjectID, std::uint16_t xPosition, std::uint16_t yPosition)
Sends the change child position command.
EventDispatcher< VTESCMessageEvent > & get_vt_esc_message_event_dispatcher()
The event dispatcher for when an ESC message is received, e.g. an open object input is closed.
bool send_change_polygon_point(std::uint16_t objectID, std::uint8_t pointIndex, std::uint16_t newXValue, std::uint16_t newYValue)
Sends change polygon point command.
bool replace_command(const std::vector< std::uint8_t > &data)
Replaces the first message in the queue with the same function-code and priority, and removes the res...
Mutex commandQueueMutex
A mutex to protect the command queue.
void set_auxiliary_input_model_identification_code(std::uint16_t modelIdentificationCode)
Set the model identification code of our auxiliary input device.
bool send_select_active_working_set(std::uint64_t NAMEofWorkingSetMasterForDesiredWorkingSet)
Sends the select active working set command.
bool send_get_supported_widechars() const
Sends the get supported widechars message.
EventDispatcher< VTPointingEvent > pointingEventDispatcher
A list of all pointing event callbacks.
bool send_draw_point(std::uint16_t objectID, std::int16_t xOffset, std::int16_t yOffset)
Sends the draw point command.
static std::uint32_t get_minimum_object_length(VirtualTerminalObjectType type)
Returns the minimum length that the specified object could possibly require in bytes.
EventDispatcher< VTChangeNumericValueEvent > changeNumericValueEventDispatcher
A list of all change numeric value callbacks.
bool send_get_supported_objects() const
Sends the get supported objects message.
bool send_enable_disable_object(std::uint16_t objectID, EnableDisableObjectCommand command)
Sends an enable/disable object command.
void worker_thread_function()
The worker thread will execute this function when it runs, if applicable.
void set_object_pool(std::uint8_t poolIndex, const std::uint8_t *pool, std::uint32_t size, std::string version="")
Assigns an object pool to the client using a buffer and size.
GraphicMode supportedGraphicsMode
The graphics mode reported by the VT server.
StateMachineState
The internal state machine state of the VT client, mostly just public so tests can access it.
@ SendLoadVersion
Sending the load version command.
@ WaitForEndOfObjectPoolResponse
Client is waiting for the end of object pool response message.
@ WaitForGetNumberSoftKeysResponse
Client is waiting for a response to the "get number of soft keys" message.
@ WaitForGetVersionsResponse
Client is waiting for a response to the "get versions" message.
@ SendEndOfObjectPool
Client is sending the end of object pool message.
@ Connected
Client is connected to the VT server and the application layer is in control.
@ SendGetVersions
If a version label was specified, check to see if the VT has that version already.
@ SendGetTextFontData
Client is sending the "get text font data" message.
@ SendGetMemory
Client is sending the "get memory" message to see if VT has enough memory available.
@ SendGetHardware
Client is sending the "get hardware" message.
@ SendWorkingSetMasterMessage
Client is sending the working state master message.
@ WaitForGetMemoryResponse
Client is waiting for a response to the "get memory" message.
@ UploadObjectPool
Client is uploading the object pool.
@ SendGetNumberSoftkeys
Client is sending the "get number of soft keys" message.
@ WaitForStoreVersionResponse
Client is waiting for a response to the store version command.
@ ReadyForObjectPool
Client needs an object pool before connection can continue.
@ WaitForGetHardwareResponse
Client is waiting for a response to the "get hardware" message.
@ WaitForLoadVersionResponse
Client is waiting for the VT to respond to the "Load Version" command.
@ SendStoreVersion
Sending the store version command.
@ WaitForGetTextFontDataResponse
Client is waiting for a response to the "get text font data" message.
@ Failed
Client could not connect to the VT due to an error.
@ Disconnected
VT is not connected, and is not trying to connect yet.
@ WaitForPartnerVTStatusMessage
VT client is initialized, waiting for a VT server to come online.
std::uint32_t lastVTStatusTimestamp_ms
The timestamp of the last VT status message.
std::uint8_t smallFontSizesBitfield
The small font sizes supported by the VT server.
bool send_select_colour_map_or_palette(std::uint16_t objectID)
Sends the select colour map or palette command.
std::uint16_t get_visible_soft_key_mask() const
Returns the current soft key mask displayed by the VT server.
std::uint16_t get_number_x_pixels() const
Returns the number of x pixels in the data mask area.
bool send_change_object_label(std::uint16_t objectID, std::uint16_t labelStringObjectID, std::uint8_t fontType, std::uint16_t graphicalDesignatorObjectID)
Sends the change object label command.
bool send_extended_get_versions() const
Sends the get extended versions message.
bool get_support_touchscreen_with_pointing_message() const
Returns if the VT server supports a touchscreen with pointing message.
std::uint8_t softKeyYAxisPixels
The size of a soft key Y dimension as reported by the VT server.
static void process_flags(std::uint32_t flag, void *parent)
Processes the internal Tx flags.
bool send_change_list_item(std::uint16_t objectID, std::uint8_t listIndex, std::uint16_t newObjectID)
Sends the change list item command.
AlarmMaskPriority
The allowable priorities of an alarm mask.
EventDispatcher< VTKeyEvent > buttonEventDispatcher
A list of all button event callbacks.
bool send_zoom_viewport(std::uint16_t objectID, float zoom)
Sends the zoom viewport command.
bool is_function_unsupported(Function function) const
Extract from the cache whether a VT does not support a specific function.
bool send_set_audio_volume(std::uint8_t volume_percent)
Sends the set audio volume command.
void update_auxiliary_input(const std::uint16_t auxiliaryInputID, const std::uint16_t value1, const std::uint16_t value2, const bool controlLocked=false)
Update the state of an auxiliary input. This should be called when the value of an auxiliary input ch...
bool send_change_string_value(std::uint16_t objectID, uint16_t stringLength, const char *value)
Sends the change string value command.
EventDispatcher< VTESCMessageEvent > escMessageEventDispatcher
A list of all ESC event callbacks.
bool send_execute_extended_macro(std::uint16_t objectID)
Sends the execute extended macro command.
std::uint16_t get_number_y_pixels() const
Returns the number of y pixels in the data mask area.
VirtualTerminalClient(std::shared_ptr< PartneredControlFunction > partner, std::shared_ptr< InternalControlFunction > clientSource)
The constructor for a VirtualTerminalClient.
std::uint8_t activeWorkingSetMasterAddress
The active working set master address.
LineDirection
Enumerates the different line directions that can be used when changing an endpoint of an object.
bool get_auxiliary_input_learn_mode_enabled() const
Get whether the VT has enabled the learn mode for the auxiliary input.
bool is_vt_version_supported(VTVersion value) const
Returns whether the VT version is supported by the VT server.
FontStyleBits
Enumerates the font style options that can be encoded in a font style bitfield.
std::uint16_t xPixels
The x pixel dimension as reported by the VT server.
std::uint8_t get_number_virtual_softkeys() const
Returns the number of virtual softkeys reported by the VT server.
KeyActivationCode
The different key activation codes that a button press can generate.
@ ButtonPressedOrLatched
Button is pressed.
@ ButtonPressAborted
Press was aborted (user navigated away from the button and did not release it)
std::uint16_t activeWorkingSetDataMaskObjectID
The active working set data mask object ID.
bool send_copy_viewport_to_picture_graphic(std::uint16_t graphicsContextObjectID, std::uint16_t objectID)
Sends the copy viewport to picture graphic command.
bool firstTimeInState
Stores if the current update cycle is the first time a state machine state has been processed.
static FontSize remap_font_to_scale(FontSize originalFont, float scaleFactor)
Remaps a font to some other font based on a scale factor This is not a one-size-fits-all solution,...
GraphicMode
Enumerates the various VT server graphics modes.
@ TwoHundredFiftySixColour
256 Colour mode (8 bit)
std::uint16_t activeWorkingSetSoftKeyMaskObjectID
The active working set's softkey mask object ID.
bool get_support_simultaneous_activation_buttons_and_softkeys() const
Returns if the VT server supports simultaneous activation of buttons and softkeys.
bool send_change_fill_attributes(std::uint16_t objectID, FillType fillType, std::uint8_t colour, std::uint16_t fillPatternObjectID)
Sends the change fill attributes command.
std::uint8_t softKeyXAxisPixels
The size of a soft key X dimension as reported by the VT server.
void set_object_pool_scaling(std::uint8_t poolIndex, std::uint32_t originalDataMaskDimensions_px, std::uint32_t originalSoftKyeDesignatorHeight_px)
Configures an object pool to be automatically scaled to match the target VT server.
bool send_get_memory(std::uint32_t requiredMemory) const
Sends the get memory message.
std::vector< std::vector< std::uint8_t > > commandQueue
A queue of commands to send to the VT server.
static bool process_internal_object_pool_upload_callback(std::uint32_t callbackIndex, std::uint32_t bytesOffset, std::uint32_t numberOfBytesNeeded, std::uint8_t *chunkBuffer, void *parentPointer)
The data callback passed to the network manger's send function for the transport layer messages.
bool send_hide_show_object(std::uint16_t objectID, HideShowObjectCommand command)
Sends a hide/show object command.
bool send_pan_viewport(std::uint16_t objectID, std::int16_t xAttribute, std::int16_t yAttribute)
Sends the pan viewport command.
bool send_change_size_command(std::uint16_t objectID, std::uint16_t newWidth, std::uint16_t newHeight)
Sends the change size command.
std::uint16_t ourModelIdentificationCode
The model identification code of this input device.
bool send_change_softkey_mask(MaskType type, std::uint16_t dataOrAlarmMaskObjectID, std::uint16_t newSoftKeyMaskObjectID)
Sends the change softkey mask command.
std::uint32_t lastCommandTimestamp_ms
The timestamp of the last command sent.
void add_auxiliary_input_object_id(const std::uint16_t auxiliaryInputID)
Add a new auxiliary input to be managed by this virtual terminal object.
bool send_change_viewport_size(std::uint16_t objectID, std::uint16_t width, std::uint16_t height)
Sends the change viewport size command.
bool get_is_connected() const
Check whether the client is connected to the VT server.
std::uint16_t get_visible_data_mask() const
Returns the current data mask displayed by the VT server.
EventDispatcher< VTKeyEvent > & get_vt_soft_key_event_dispatcher()
The event dispatcher for when a soft key is pressed or released.
@ InProgress
The object pool upload is in progress.
@ Success
The object pool was uploaded.
@ Failed
The pool upload has failed.
@ Uninitialized
The object pool upload has not been started.
static void process_callback(std::uint32_t parameterGroupNumber, std::uint32_t dataLength, std::shared_ptr< InternalControlFunction > sourceControlFunction, std::shared_ptr< ControlFunction > destinationControlFunction, bool successful, void *parentPointer)
The callback passed to the network manager's send function to know when a Tx is completed.
bool send_change_priority(std::uint16_t alarmMaskObjectID, AlarmMaskPriority priority)
Sends the change priority command.
EventDispatcher< VTAudioSignalTerminationEvent > audioSignalTerminationEventDispatcher
A list of all control audio signal termination callbacks.
FontSize
Enumerates the different font sizes.
@ Size64x96
64x96 Font size
@ Size16x24
16x24 Font size
@ Size16x16
16x16 Font size
@ Size48x64
48x64 Font size
@ Size64x64
64x64 Font size
@ Size24x32
24x32 Font size
@ Size32x48
32x48 Font size
@ Size128x128
128x128 Font size
@ Size96x128
96x128 Font size
@ Size32x32
32x32 Font size
@ Size128x192
128x192 Font size
@ Size12x16
12x16 Font size
bool get_is_initialized() const
Returns if the client has been initialized.
bool send_lock_unlock_mask(MaskLockState state, std::uint16_t objectID, std::uint16_t timeout_ms)
Sends the lock unlock mask command.
EventDispatcher< VTChangeSoftKeyMaskEvent > changeSoftKeyMaskEventDispatcher
A list of all change soft key mask callbacks.
static constexpr std::uint32_t AUXILIARY_MAINTENANCE_TIMEOUT_MS
The delay between auxiliary maintenance messages.
VTVersion get_connected_vt_version() const
Returns the VT version supported supported by the VT server.
static std::uint32_t get_number_bytes_in_object(std::uint8_t *buffer)
Returns the total number of bytes in the VT object located at the specified memory location.
EventDispatcher< VTUserLayoutHideShowEvent > userLayoutHideShowEventDispatcher
A list of all user layout hide/show callbacks.
std::map< std::uint16_t, AuxiliaryInputState > ourAuxiliaryInputs
The inputs on this auxiliary input device.
bool send_auxiliary_functions_preferred_assignment() const
Send the preferred auxiliary control type 2 assignment command.
bool send_load_version(std::array< std::uint8_t, 7 > versionLabel) const
Sends the load version message.
void update()
Periodic Update Function (worker thread may call this)
bool send_execute_macro(std::uint16_t objectID)
Sends the execute macro command.
static bool get_is_object_scalable(VirtualTerminalObjectType type)
Returns if the specified object type can be scaled.
EventDispatcher< VTChangeStringValueEvent > & get_vt_change_string_value_event_dispatcher()
The event dispatcher for when a string value is changed.
EventDispatcher< VTPointingEvent > & get_vt_pointing_event_dispatcher()
The event dispatcher for when a pointing event is "pressed or released".
std::shared_ptr< InternalControlFunction > myControlFunction
The internal control function the client uses to send from.
void remove_auxiliary_input_object_id(const std::uint16_t auxiliaryInputID)
Remove an auxiliary input from the pool of managed auxiliary inputs.
bool resize_object(std::uint8_t *buffer, float scaleFactor, VirtualTerminalObjectType type)
Resizes a single VT object by some scale factor.
std::uint32_t lastWorkingSetMaintenanceTimestamp_ms
The timestamp from the last time we sent the maintenance message.
std::uint8_t busyCodesBitfield
The VT server's busy codes.
TransmitFlags
Flags used as a retry mechanism for sending important messages.
@ SendWorkingSetMaintenance
Flag to send the working set maintenenace message.
@ NumberFlags
The number of flags in this enum.
@ SendAuxiliaryMaintenance
Flag to send the auxiliary maintenance message.
bool send_draw_closed_ellipse(std::uint16_t objectID, std::uint16_t width, std::uint16_t height)
Sends the draw closed ellipse message.
EventDispatcher< VTAudioSignalTerminationEvent > & get_vt_control_audio_signal_termination_event_dispatcher()
The event dispatcher for when an audio signal is terminated.
Function
Enumerates the multiplexor byte values for VT commands.
bool queue_command(const std::vector< std::uint8_t > &data, bool replace=false)
Tries to send a command to the VT server, and queues it if it fails.
bool send_get_attribute_value(std::uint16_t objectID, std::uint8_t attributeID)
Sends the get attribute value message.
bool send_end_of_object_pool() const
Sends the end of object pool message.
bool get_any_pool_needs_scaling() const
Returns if any object pool had scaling configured.
EventDispatcher< AuxiliaryFunctionEvent > auxiliaryFunctionEventDispatcher
A list of all auxiliary function callbacks.
bool get_has_adjustable_volume_output() const
Returns if the VT server supports adjustable volume output.
bool sendWorkingSetMaintenance
Used internally to enable and disable cyclic sending of the working set maintenance message.
FillType
Enumerates the different fill types for an object.
bool send_draw_polygon(std::uint16_t objectID, std::uint8_t numberOfPoints, const std::int16_t *listOfXOffsetsRelativeToCursor, const std::int16_t *listOfYOffsetsRelativeToCursor)
Sends the draw polygon command.
static constexpr std::uint64_t AUXILIARY_INPUT_STATUS_DELAY
The delay between the auxiliary input status messages, in milliseconds.
bool send_ESC()
Sends the ESC message (Escape)
void update_auxiliary_input_status()
Send the auxiliary control type 2 status message for all inputs if applicable.
bool send_draw_text(std::uint16_t objectID, bool transparent, std::uint8_t textLength, const char *value)
Sends the draw text command.
bool shouldTerminate
Used to determine if the client should exit and join the worker thread.
bool send_change_line_attributes(std::uint16_t objectID, std::uint8_t colour, std::uint8_t width, std::uint16_t lineArtBitmask)
Sends the change line attributes command.
void register_object_pool_data_chunk_callback(std::uint8_t poolIndex, std::uint32_t poolTotalSize, DataChunkCallback value, std::string version="")
Assigns an object pool to the client where the client will get data in chunks during upload.
AuxiliaryTypeTwoFunctionType
Enumerates the various auxiliary input function types.
@ QuadratureBooleanMomentary
Two Quadrature mounted Three-position switches (returns to centre position) (Momentary Single Pole,...
bool get_font_size_supported(FontSize value) const
Returns if the selected font is supported.
std::uint8_t numberVirtualSoftkeysPerSoftkeyMask
The number of virtual softkeys per softkey mask as reported by the VT server.
std::uint8_t hardwareFeaturesBitfield
The reported hardware features from the VT server.
bool send_extended_store_version(std::array< std::uint8_t, 32 > versionLabel) const
Sends the extended store version message.
ESCMessageErrorCode
Enumerates the errors that can be present in an ESC message.
@ NoInputFieldOpen
No input field is open.
@ OtherError
Error is not one of the above.
bool get_multiple_frequency_audio_output() const
Returns if the VT server supports multiple frequency audio output.
bool get_font_style_supported(FontStyleBits value) const
Returns if the selected font style is supported.
void restart_communication()
Halts communication with the VT gracefully and restarts it.
EventDispatcher< VTChangeNumericValueEvent > & get_vt_change_numeric_value_event_dispatcher()
The event dispatcher for when a numeric value is changed in an input object.
bool send_move_graphics_cursor(std::uint16_t objectID, std::int16_t xOffset, std::int16_t yOffset)
Sends the move graphics cursor command.
std::vector< std::uint8_t > unsupportedFunctions
Holds the functions unsupported by the server.
bool send_set_line_attributes_object_id(std::uint16_t objectID, std::uint16_t lineAttributeobjectID)
Sends the set line attributes object id.
void set_state(StateMachineState value)
Sets the state machine state and updates the associated timestamp.
bool send_set_background_colour(std::uint16_t objectID, std::uint8_t colour)
Sends the set background colour command.
static constexpr std::uint32_t WORKING_SET_MAINTENANCE_TIMEOUT_MS
The delay between working set maintenance messages.
bool send_change_endpoint(std::uint16_t objectID, std::uint16_t width_px, std::uint16_t height_px, LineDirection direction)
Sends the change endpoint command, which changes the end of an output line.
bool send_delete_object_pool() const
Sends the delete object pool message.
bool send_command(const std::vector< std::uint8_t > &data)
Sends a command to the VT server.
bool send_draw_vt_object(std::uint16_t graphicsContextObjectID, std::uint16_t VTObjectID)
Sends the draw VT object command.
GraphicMode get_graphic_mode() const
Returns the graphics mode supported by the VT server.
StateMachineState state
The current client state machine state.
std::uint8_t numberPhysicalSoftkeys
The number of physical softkeys supported by the VT server.
ProcessingFlags txFlags
A retry mechanism for internal Tx messages.
EventDispatcher< VTChangeActiveMaskEvent > & get_vt_change_active_mask_event_dispatcher()
The event dispatcher for when the active mask is changed.
std::vector< AssignedAuxiliaryInputDevice > assignedAuxiliaryInputDevices
A container to hold all auxiliary input devices known.
bool send_change_numeric_value(std::uint16_t objectID, std::uint32_t value)
Sends the change numeric value command.
SelectInputObjectOptions
Enumerates the states that can be sent with a select input object options command.
bool sendAuxiliaryMaintenance
Used internally to enable and disable cyclic sending of the auxiliary maintenance message.
bool send_change_background_colour(std::uint16_t objectID, std::uint8_t colour)
Sends the change background colour command.
FontSize get_font_or_next_smallest_font(FontSize originalFont) const
Returns the closest font to the one you passed in, in decending order.
bool send_select_input_object(std::uint16_t objectID, SelectInputObjectOptions option)
Sends a select input object command.
EventDispatcher< VTKeyEvent > & get_vt_button_event_dispatcher()
The event dispatcher for when a button is pressed or released.
bool send_draw_rectangle(std::uint16_t objectID, std::uint16_t width, std::uint16_t height)
Sends the draw rectangle command.
bool send_auxiliary_function_assignment_response(std::uint16_t functionObjectID, bool hasError, bool isAlreadyAssigned) const
Send the auxiliary control type 2 assignment reponse message.
bool send_get_number_of_softkeys() const
Sends the get number of softkeys message.
std::thread * workerThread
The worker thread that updates this interface.
MaskLockState
Denotes the lock/unlock state of a mask. Used to freeze/unfreeze rendering of a mask.
std::shared_ptr< InternalControlFunction > get_internal_control_function() const
Returns the internal control function being used by the client.
bool scale_object_pools()
Iterates through each object pool and scales each object in the pool automatically.
bool send_set_fill_attributes_object_id(std::uint16_t objectID, std::uint16_t fillAttributeobjectID)
Sends the fill attributes object id.
void terminate()
Terminates the client and joins the worker thread if applicable.
bool send_get_window_mask_data() const
Sends the get window mask data message.
bool send_get_text_font_data() const
Sends the get text font data message.
std::uint8_t get_softkey_y_axis_pixels() const
Returns the number of Y axis pixels in a softkey.
bool send_draw_line(std::uint16_t objectID, std::int16_t xOffset, std::int16_t yOffset)
Sends the draw line command.
bool send_copy_canvas_to_picture_graphic(std::uint16_t graphicsContextObjectID, std::uint16_t objectID)
Sends the copy canvas to picture graphic command.
bool send_extended_delete_version(std::array< std::uint8_t, 32 > versionLabel) const
Sends the extended delete version message.
std::uint8_t get_number_physical_softkeys() const
Returns the number of physical softkeys reported by the VT server.
std::uint32_t stateMachineTimestamp_ms
Timestamp from the last state machine update.
std::shared_ptr< PartneredControlFunction > partnerControlFunction
The partner control function this client will send to.
bool initialized
Stores the client initialization state.
bool send_erase_rectangle(std::uint16_t objectID, std::uint16_t width, std::uint16_t height)
Sends the erase rectangle command.
static void process_rx_message(const CANMessage &message, void *parentPointer)
Processes a CAN message destined for any VT client.
static constexpr std::uint32_t VT_STATUS_TIMEOUT_MS
The max allowable time between VT status messages before its considered offline.
bool send_change_child_location(std::uint16_t objectID, std::uint16_t parentObjectID, std::uint8_t relativeXPositionChange, std::uint8_t relativeYPositionChange)
Sends the change child location command.
std::uint8_t get_softkey_x_axis_pixels() const
Returns the number of X axis pixels in a softkey.
std::uint32_t lastAuxiliaryMaintenanceTimestamp_ms
The timestamp from the last time we sent the maintenance message.
std::uint32_t lastObjectPoolIndex
The last object pool index that was processed.
std::uint8_t fontStylesBitfield
The text font capabilities supported by the VT server.
bool send_delete_version(std::array< std::uint8_t, 7 > versionLabel) const
Sends the delete version message.
EventDispatcher< VTSelectInputObjectEvent > & get_vt_select_input_object_event_dispatcher()
The event dispatcher for when an input object event is triggered.
EventDispatcher< VTSelectInputObjectEvent > selectInputObjectEventDispatcher
A list of all select input object callbacks.
bool send_get_versions() const
Sends the get versions message.
bool send_change_active_mask(std::uint16_t workingSetObjectID, std::uint16_t newActiveMaskObjectID)
Sends the change active mask command.
static constexpr std::uint64_t AUXILIARY_INPUT_STATUS_DELAY_INTERACTION
The delay between the auxiliary input status messages when the input is interacted with,...
EventDispatcher< VTChangeSoftKeyMaskEvent > & get_vt_change_soft_key_mask_event_dispatcher()
The event dispatcher for when the soft key mask is changed.
bool send_get_hardware() const
Sends the get hardware message.
VTVersion
The different VT versions that a client or server might support.
@ Version3
Client or server supports all of VT version 3.
@ Version4
Client or server supports all of VT version 4.
@ Version5
Client or server supports all of VT version 5.
@ Version2OrOlder
Client or server supports VT version 2 or lower.
@ ReservedOrUnknown
Reserved value, not to be used.
@ Version6
Client or server supports all of VT version 6.
bool get_support_simultaneous_activation_physical_keys() const
Returns if the VT server supports simultaneous activation of physical keys.
bool send_auxiliary_input_status_enable_response(std::uint16_t objectID, bool isEnabled, bool hasError) const
Send the auxiliary input status type 2 enable response.
std::uint8_t largeFontSizesBitfield
The large font sizes supported by the VT server.
bool send_working_set_maintenance(bool initializing) const
Sends the working set maintenance message.
bool send_control_audio_signal(std::uint8_t activations, std::uint16_t frequency_hz, std::uint16_t duration_ms, std::uint16_t offTimeDuration_ms)
Sends the control audio signal command.
bool send_working_set_master() const
Sends the working set master message.
bool send_change_attribute(std::uint16_t objectID, std::uint8_t attributeID, std::uint32_t value)
Sends the change attribute command.
bool send_message_to_vt(const std::uint8_t *dataBuffer, std::uint32_t dataLength, CANIdentifier::CANPriority priority=CANIdentifier::CANPriority::Priority5) const
Sends a message to the VT server.
~VirtualTerminalClient()
The destructor for the VirtualTerminalClient.
EnableDisableObjectCommand
Enumerates the states that can be sent with an enable/disable object command.
A class to manage a client connection to a ISOBUS virtual terminal display.
This namespace encompasses all of the ISO11783 stack's functionality to reduce global namespace pollu...
constexpr std::uint8_t NULL_CAN_ADDRESS
The NULL CAN address defined by J1939 and ISO11783.
constexpr std::uint16_t NULL_OBJECT_ID
Special ID used to indicate no object.
constexpr std::uint8_t CAN_DATA_LENGTH
The length of a classical CAN frame.
constexpr std::uint64_t DEFAULT_NAME
An invalid NAME used as a default.
VirtualTerminalObjectType
The types of objects in an object pool by object type byte value.
@ ExternalReferenceNAME
Used to identify the WS Master of a Working Set that can be referenced.
@ OutputPolygon
Used to output a polygon.
@ FontAttributes
Used to group font based attributes. Can only be referenced by other objects.
@ WorkingSet
Top level object that describes an implement’s ECU or group of ECUs.
@ NumberVariable
Used to store a 32-bit unsigned integer value.
@ WindowMask
Top level object that contains other objects. The Window Mask is activated by the VT.
@ Container
Used to group objects.
@ AuxiliaryInputType1
The Auxiliary Input Type 1 object defines the designator, key number, and function type for an auxili...
@ PictureGraphic
Used to output a picture graphic (bitmap).
@ ObjectLabelRefrenceList
Used to specify an object label.
@ Macro
Special object that contains a list of commands that can be executed in response to an event.
@ ObjectPointer
Used to reference another object.
@ OutputList
Used to output a list item.
@ DataMask
Top level object that contains other objects. A Data Mask is activated by a Working Set to become the...
@ OutputEllipse
Used to output an ellipse or circle.
@ OutputString
Used to output a character string.
@ StringVariable
Used to store a fixed length string value.
@ InputNumber
Used to input an integer or float numeric.
@ OutputArchedBarGraph
Used to output an arched bar graph.
@ AuxiliaryFunctionType1
The Auxiliary Function Type 1 object defines the designator and function type for an Auxiliary Functi...
@ InputString
Used to input a character string.
@ AuxiliaryControlDesignatorType2
Used to reference Auxiliary Input Type 2 object or Auxiliary Function Type 2 object.
@ OutputRectangle
Used to output a rectangle or square.
@ Button
Used to describe a Button control.
@ Key
Used to describe a Soft Key.
@ FillAttributes
Used to group fill based attributes. Can only be referenced by other objects.
@ ExtendedInputAttributes
Used to specify a list of valid WideChars. Can only be referenced by Input Field Objects.
@ GraphicsContext
Used to output a graphics context.
@ OutputMeter
Used to output a meter.
@ ExternalObjectPointer
Used to reference an object in another Working Set.
@ AlarmMask
Top level object that contains other objects. Describes an alarm display.
@ SoftKeyMask
Top level object that contains Key objects.
@ OutputNumber
Used to output an integer or float numeric.
@ InputList
Used to select an item from a pre-defined list.
@ AuxiliaryInputType2
The Auxiliary Input Type 2 object defines the designator, key number, and function type for an Auxili...
@ AuxiliaryFunctionType2
The Auxiliary Function Type 2 object defines the designator and function type for an Auxiliary Functi...
@ LineAttributes
Used to group line based attributes. Can only be referenced by other objects.
@ OutputLine
Used to output a line.
@ ExternalObjectDefinition
Used to list the objects that may be referenced from another Working Set.
@ Animation
The Animation object is used to display simple animations.
@ KeyGroup
Top level object that contains Key objects.
@ InputBoolean
Used to input a TRUE/FALSE type input.
@ OutputLinearBarGraph
Used to output a linear bar graph.
@ ColourMap
Used to specify a colour table object.
@ InputAttributes
Used to specify a list of valid characters. Can only be referenced by input field objects.
bool(*)(std::uint32_t callbackIndex, std::uint32_t bytesOffset, std::uint32_t numberOfBytesNeeded, std::uint8_t *chunkBuffer, void *parentPointer) DataChunkCallback
A callback to get chunks of data for transfer by a protocol.
AcknowledgementType
The types of acknowledgement that can be sent in the Ack PGN.
@ Negative
"NACK" Indicates the request was not completed or we do not support the PGN
An object for storing information regarding an object pool upload.
std::uint32_t objectPoolSize
The size of the object pool.
std::uint32_t autoScaleSoftKeyDesignatorOriginalHeight
The original height of a soft key designator as designed in the pool (in pixels)
const std::uint8_t * objectPoolDataPointer
A pointer to an object pool.
std::string versionLabel
An optional version label that will be used to load/store the pool to the VT. 7 character max!
bool useDataCallback
Determines if the client will use callbacks to get the data in chunks.
DataChunkCallback dataCallback
A callback used to get data in chunks as an alternative to loading the whole pool at once.
const std::vector< std::uint8_t > * objectPoolVectorPointer
A pointer to an object pool (vector format)
bool uploaded
The upload state of this pool.
std::uint32_t autoScaleDataMaskOriginalDimension
The original length or width of this object pool's data mask area (in pixels)