diff --git a/artifacts/iqpilot_hephaestusd_private/manifest.json b/artifacts/iqpilot_hephaestusd_private/manifest.json index ca0bc89..80bdbbd 100644 --- a/artifacts/iqpilot_hephaestusd_private/manifest.json +++ b/artifacts/iqpilot_hephaestusd_private/manifest.json @@ -16,27 +16,27 @@ }, "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "9368086c4cdd6cf46b6a6d0a1e1e83fdc7e7dff8d3bd67a42b3bffa91b45dc26", + "sha256": "e79be61e50cd0830197f44f8a6840b86a74b8059da45da65a4696587168ac466", "size": 135536 }, "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "291789f912304c72cd1e0da955bd58fa903cd99e7d6504e6c3c51d39befaf6e8", + "sha256": "ebfeedba6cc5cac6dca1cf8125879fcb2d6afdbaec31a98dd46c3d346f55c982", "size": 67664 }, "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "c47ec079040efee31673f55752a6215b3a8908c63c8373625ce5cb4cb1177aff", + "sha256": "11ffe8f261b78990aa743b43aed3a5534105da848be1450026090ae873ad0a2e", "size": 204624 }, "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "a0d5710938b32e56f2fc55c86ff8947787a3ebeb43850a94a90202c3773ff74e", + "sha256": "e62a6438c18b231f83cc873ac8170a64e670c8912ffba13edf47f163886aef19", "size": 69752 }, "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "ff345aa71ac599bdd16747368ceb92fae7b5b35657f81466fc0660b76d44aa22", + "sha256": "07195ca6d4e1ff26441e860d954e9c79e3da608244d110bfa62b3aa0818a79dc", "size": 203072 }, "python/iqpilot_private/konn3kt/flockd/__init__.py": { @@ -46,12 +46,12 @@ }, "python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "2aa26e4bc71870f639fca6e8e273deb59f50cf6a6d963ba77ce0949c65a52d63", + "sha256": "d18b8d67100f5906339dde577bc14f567168ff62e1b9166c011af853c016191e", "size": 202168 }, "python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "96b47ec40dd7e3430cebf3979b4fdfb0096e80029b40da6445cdf44dbcdb8917", + "sha256": "1a601a0de826fb41fadb3cef9e8b8645d99e41507befc36e87d077d49efd3025", "size": 68080 }, "python/iqpilot_private/konn3kt/hephaestus/__init__.py": { @@ -61,67 +61,67 @@ }, "python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip": { "mode": 420, - "sha256": "f12e44b7a986616d6b3c4e127e4eeae793e346f31d5b821ad9c44249e4731ebd", + "sha256": "c3063f3d380627f604b0ae1cdd20fbfdfa7b64d212c86f20abd470230af8e169", "size": 2100238 }, "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "4ac192d102bde18d9b3215ff637e1c316a08eb0eb00c595c07eaa07284d1f28c", + "sha256": "57dbd02e130361d33c8a52635261ce85f3a91c577b70d5fad8a0e9e7557f9d46", "size": 268064 }, "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "6f2dccd9f85db9d4948ddb31f62b6059d9359f7f16df6d55455b05c6ae4f37b7", - "size": 340584 + "sha256": "1febeeb24421c82a64416a7ab04def21d57a39acf0caaf2103b4ebfbae655fc2", + "size": 406216 }, "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "abb3eb9033205d1c2903b619dbbab7e3de10b859493239c35533b75d00bc3305", + "sha256": "42656c3b54f6392e2311e4039296e4906558fd8c63ba6be04b157445b96d38c9", "size": 68048 }, "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "a631270d167cbd9a67db6111de57e5d6ddcdd554706fd9fd919d8f116733bf66", + "sha256": "acdf51e90428e4487f0daf6e0e43110ef5fc1c7705d16aa3b9880618030f41f3", "size": 335728 }, "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "c5c4f480275ddc00e2d7d44aee76808f2b4184b6a6354ef2e757d8b3a7ae8e44", + "sha256": "95afe64579cac0148c3de23867a333651dfed4606c218208dcf37b40a1cc6450", "size": 271680 }, "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "a9d9fdfcd6f154e093ed1cc678bf9a1e12c7a3e475a358c19941af7777c40807", + "sha256": "fd983039accfaa30abf3d46f41c70241d1c3fcf4e21a1de7d3270ab9fce9b03c", "size": 134408 }, "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "d3468f09df47814c161937306c776df5fe9a6a6d819859a596f7e33be6d253e8", + "sha256": "cc299f0d560bbd611cab099923bb1817229df3cbc15cef22d6909091e9de826b", "size": 3581928 }, "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "c7cf16d3b2297deafd87c53c8b61031d2af84ff04848bab34d9dde37ba939ed5", + "sha256": "0dbcb5d9ec1af832bcaceaa3ae96a4785a432778c1fb3cdc8b74e62b5d915158", "size": 136448 }, "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "113890a2fa588f0c3d6d0c6723aef63adb58fc3ad5355174effe5ac2d3d6d364", + "sha256": "cabf37e151994a223f890627c0128990e56505bc704108f050d2422e118a273a", "size": 68136 }, "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "e97f1650766b15b231657afd6530c019d09352dfa0d96deb2643893acf56efa4", + "sha256": "10af02f5daf288e465bcaa64509972a1a0b268f779b1c12c58bf63c79e52eb96", "size": 67840 }, "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "7be8a68c56f6ff37ef887b87275c78e517065995243e88d1ab6a10f3b028abe5", + "sha256": "855f128d248c94fbd00f550f7dd388ccf1a487935d7f11cac00e5240b526d674", "size": 135648 }, "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "2a1f6cbb8794a29a55decf6d04915e752360eac7701ed55c826355bb348e39a6", + "sha256": "8de50d50308777ff9dc22d4d5232cba38f2f332207313999ec8aaa67e5004f4e", "size": 269568 }, "python/iqpilot_private/konn3kt/uploaderd/__init__.py": { @@ -131,7 +131,7 @@ }, "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": { "mode": 493, - "sha256": "613141bdba6cabaf47fa07b438fe964e90796b7e0309c8f0fbfa60b6bf54e6ad", + "sha256": "11d16de5d29a37f64351acabfa6372966447a88cd7d799580a6f2f1fa745c15a", "size": 204184 }, "runtime": { @@ -171,25 +171,25 @@ } }, "signatures": { - "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "nSuJmlS6Uu7Z2hCUfo8ia0v3TtLy0k7vXuUtkRteuXr283FbjSL/SAnGZtotLam9QqWcKUZiX5AY7iKRxdJRDA==", - "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "b4kzh2Ih+crCs71fFdIku1vWUarJheL2EFkX9K85ppio/t27Vml4wjdRXt6G9ImEIwXb0FwZQ5TO290oTS81DQ==", - "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "Y4Z6VxELzmD2+MZKv/Uk7mE03ZFxxjXFiV21zHXbGTTQ8x+3OWSs+c43kfEFO7+Y0GRLAV/pFVdS4TJotL1bCA==", - "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "uKdDonv7l3RV5Rk0p18w2B7OFo56b61Gdzj4Q2HCa4MkjzVv81Pe7kf+2AbRXJ+tV74P1Xg/S4uFYH9B03D7Cw==", - "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "+HMqTUeIHFUo9Fr7/yzkI9tQ+/uCJI1dH06oRDg1xgU8YjuiI8XUZCpgsUR4nMn7O497qiCdL5TfiYJw/0j/AQ==", - "python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so": "EOxdzTbj5/I7gOu48kM3Z0G54cJ1pII4tikrDqYhVSFRiJopUPtjb2IAG/Lg0D6kwZaIzbkEVpRKq707MF2BAw==", - "python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so": "fZ8UhZhwmPn4IMxudbJkmrCsBj/A+EOH4cdzT8Vb75kI7SD9V5rR7gRCPFuVEL1nQ6lnlF2QW4Osmik2WOqeDA==", - "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "bptAbc1grlaQ8cQoR1RZ1p5GKEvnHUGOpyRoCmkK2xW2HMRD9YmY+t7HrARFfr14Bkp0dgdVKswzZWa6aUR3Cg==", - "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "4Q9ZzJhFaTqnaj66o+CHE/vtjY9qWOHO7UFYZrxs3uQdUaeIO5JUkXHtr4Fl7mDrZy0zaT8hL+R6g7zj8VLCCg==", - "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "bzGWFkSPQg9xj1Rl8jBkGx3coMF6srLe509MLng4gQMqo8hHHWZTFI3235UsSJCkbnPjOolUWzVLtbDp5bMmDQ==", - "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "pIB/KThS9GZ+HYf+SSd14rxawltaKKAZ1cFyYRPWpAnpEZ4q/Vz7G2o6bdEZ2r8bJsfBMMkzyPLRJQwpX0jODQ==", - "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "FEbOGV+d8BvV4yurjBNz74nK0CT+yQSReXPRliMt9uuMNLKVuRMlUibmgD63sx7tv0hz7Z49VwYYZVlwEPNrDw==", - "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "x17n17jSDgrTCCphHNWZQ4ibHMGITtrhaDK1wBmWFqj6uzr3cWWXV6THxNJy4qbj9/yHVLICGNuW7wIOb0tzDQ==", - "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "ldjMNYlSmOa3XjWrcqlDMrNybvFZ3T9aVVZevwt9TYxVgUrz/5qMui7KIAPdEins39c4fu0jayqM/1V0kjsUCA==", - "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "Cvq80OZLZ0rIywx1RjkV5cd6jKnpL0Rq9evyOxGqYwc0xGCGL1t2YqsoiyyODMeMphEdvdK+w+OMBge6OGk1DQ==", - "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "17P0y74P0Ug92QlhioE6XJJ6p3tz8atS5Wp2SihaQZfnERG8CCjQ6RjVBSwINdvJuU05sGexOlb29Cjebc92DQ==", - "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "wcXjEUKfLHopsy91qnShxa8/1D6wChOsFZcOkPnA0b61vPY7ceKlVMXcv+ECr35BiMsW4gHQG9MSMoyXo1ZJAw==", - "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "8nTnxWCYCQ2mtzd8JL8kcRLsU6JrKVrfMNfI84ovoejxH7kAXCM6d3f1u6TFNPqrQjlIFlc1AyUoL7UoFsQJCA==", - "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "fs6ZLA1aFyUMWRpeSduc0nnv4cJjb3OIdxmUGaCr58D5GAGBSOOUQszzMWDwrEOCQ0JOsW27TM3VmliIhP1cBA==", - "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "YleZT+ZmBpdryTlsH4k+yoLYhyIJ1DMPYnEC8L2ixxJejAjcUBmn2GjXFSS+7JzK6g8aokV6NswVSqbuIVOJDQ==" + "python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so": "1DjE26Z6yX6VuP+Jx/DxxS2PjWXSXLd+bS1RgYEo9WNOEHENVDv1xeoyXjFmrXe6/QTILJpv+LnqWegfVSnFBQ==", + "python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so": "ytsUI7NI3t/9m+zEfMCbXVCIggeKSk8lnTrVYWQr0uryX5tTtQXyR+f+rIPSZWzzHu80z3GE0jmnQEEN2m6XCA==", + "python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so": "Y57ZaVfeeB1Mnu4vFIQNSZIuob+jmBkuuZ86Zc0sOWvqgkE8gT41pivlipr/R/du5+HSqXvTv/iuQS8ekTBpCg==", + "python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so": "PGjuQc316L/r8sSGF0Hg5EnFWj/Bhk27UYBgGvQ8xxLvoVJIkRKVJ/ZFLFZo6rdEWrd0GQECUYeR9ewU6ufFAA==", + "python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so": "CVrgu0dEypYq6IIA38Lh/w4KKVNpP5+dfV0dkOpDA4UkyH2IoX3Wiywpz3o1jfjrSXE3oiPdk52qRE+pzLLxDQ==", + "python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so": "+grQAam3UiFIBqGcvuAI+7aYW6UCU83YLlxCkPoo6YaX9SitDVqQk6bNQwqxYUzuUZ2s8BdhlbgseTuImRZMBw==", + "python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so": "yhxeGAidy3Auu+i2wZgxD1bK18VeWknYuQQpeiylNyWNfzN/xPUDGFyyV0CpNY3FqEqH8LcHLzsa8Bz4JTbWDw==", + "python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so": "OX/9GfQQf/krppHPChnXqvvHCs+8LqdpnRtRxJ9AYeqRLwNMrTgCSLOsU3YGlHiF78U5jIldNdkr4aOGBHRVAg==", + "python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so": "n06LgyR6cPqHLaGsiEXlSFiNKFkT3S14mPEz+xtLw0y3bAuNod5Jpp6KiVuoTcVdzHjXPFWwYLgqbtDxSZe/BQ==", + "python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so": "JJ8eaFR2wkJW4/gw31a35LvyHLKTLfPwFwIC3cE5Y4AYbLkrVuVbizPefhUrcFMF0ZxzjQulU0YNAL7EMbzOAA==", + "python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so": "Vr/pX91mN1D0Qcl9PNJiT2DUq9LxP13qjO5g7Ve/KDPwAqL9nKJXeAqbhKXIqFyRHp82PAHKaVhHsF39QtLRAA==", + "python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so": "yjHeFmvqDWSEXIft0n93zTSZemP4L9hmXZtauDFL7bRnGHMnTVvrq7olJJoXvQITVGyGzDl+BuDF5pjOKau+AQ==", + "python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so": "7sVJ5qadF1T48RP8FlwynsJEC0w6OtN+BGBf93YABFXgYDPY/YAMm5aAicR6YmGvgkFqtfCf5g8ozdrz5fIuBg==", + "python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so": "54+MaaeOIEbj+uZrcphTbHQ8K1jm4gRe2JYZyYNkwxPcT6dkcWLM6NZiNVzXiD6Ph87hTxUbecJnhVeT80pDAw==", + "python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so": "xJnkGTaVVWne7p83UhTU2C/miZg4XR7pLrd6A7j7TvetRCFvQPxyuAeFi5lJsKKwhaWV3dInGZcVWrGV+kV0AA==", + "python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so": "P+LVQJc3vD5Z9i/jxNxziNbgCiGrI+5P9saUGHMPMKUoWhVEBAAVU8xuVyd6GjSd8M5VrximPVrJyMCE9fEfAw==", + "python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so": "vfDMFKWuTD2XSE7JF/qmHxcOXgdXRZN9fi3FTSffmr6t22Tz0N7v8MwVayiPKrYNt2gHixFZ9aAkvF2SC+yDBg==", + "python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so": "Orgr5aTB5g3NRH8AdsuNkpcmIfSQDBFHzegDN875SxuvHuCOfsVVYgx2TtRiT0wqSR9hlQQwhelyRHRQjcMCAQ==", + "python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so": "tZNbbDyMxkFOcrvWCEBQz6ZTGdLZVesuz0dbUMO1OBaSYAG4MRBQ5y9fZwRQZAvcEa+NMlNZK2SGoC6r5BxgDA==", + "python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so": "sgYjdE7ZRvdKlehs1/h3z/n14fksR+Z+KhCzi0BvFPcbMcx0Pod/L42IQeEDfcQfoFBURPNoI1OTwWc31H/NAQ==" } } diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so index b555f05..86354b6 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/archive_codec.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so index 94c7f2d..dd2ce74 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_keys.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so index ddd256d..30328ba 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/backup_orchestrator.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so index 2962b80..33eb180 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/cbc_vault.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so index e71528d..a165100 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/backups/imahelper.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so index 6c42f82..5713e2e 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/flockd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so index 15f5c24..c4be8a7 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/flockd/signatures.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip index f6d7ebd..ffe4834 100644 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/_vendor/localapi_runtime.zip differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so index a06bc41..24d362d 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_auth.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so index f3610cb..520fa34 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_gatt.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so index e3064a9..9240a8d 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_rpc_dispatch.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so index b780b96..a8bee2a 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/ble_transportd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so index 05e776f..ea41b12 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/bt_gamepad.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so index 1e6fc15..3be2eb0 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/cloud_routes.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so index ccf44a7..27b8f0a 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/hephaestusd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so index b8d315b..ee371a8 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/kwp2000.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so index cdccd5b..2cf1d2e 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/manage_hephaestusd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so index f8ff1b0..bbf3047 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/motd.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so index 48c82ad..9eb411b 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/tp20.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so index bae9d3a..5c6e64c 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/hephaestus/vw_pq_flasher.cpython-312-aarch64-linux-gnu.so differ diff --git a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so index 43f2db2..1e5ca44 100755 Binary files a/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so and b/artifacts/iqpilot_hephaestusd_private/python/iqpilot_private/konn3kt/uploaderd/iquploaderd.cpython-312-aarch64-linux-gnu.so differ diff --git a/iqdbc_repo/iqdbc/car/volkswagen/carcontroller.py b/iqdbc_repo/iqdbc/car/volkswagen/carcontroller.py index ba5c3ab..8aec2a5 100644 --- a/iqdbc_repo/iqdbc/car/volkswagen/carcontroller.py +++ b/iqdbc_repo/iqdbc/car/volkswagen/carcontroller.py @@ -245,6 +245,9 @@ class CarController(CarControllerBase): self.leadDistanceBars = 0 self.lead_distance_bars_last = None self.distance_bar_frame = 0 + self.mlb_hud_text = 0 + self.mlb_hud_text_frame = 0 + self.mlb_set_speed_last = 0 self.speed_limit_last = 0 self.speed_limit_changed_timer = 0 self.blinkerActive = None @@ -280,6 +283,19 @@ class CarController(CarControllerBase): return float(np.interp(v_ego, [0.4, 3.5, 4.0], [0.8, 0.95, 1.0])) return 1.0 + def _mlb_acc_hud_text(self, hud_control, set_speed: float) -> int: + # ACC_02 primary display text, briefly surfaced on a follow distance or set speed change + if hud_control.leadDistanceBars != self.lead_distance_bars_last: + self.mlb_hud_text_frame = self.frame + self.mlb_hud_text = self.CCP.ACC_HUD_TEXT_DISTANCE.get(hud_control.leadDistanceBars, self.CCP.ACC_HUD_TEXTS["none"]) + elif set_speed != self.mlb_set_speed_last and hud_control.speedVisible: + self.mlb_hud_text_frame = self.frame + self.mlb_hud_text = self.CCP.ACC_HUD_TEXTS["setSpeed"] + elif self.frame - self.mlb_hud_text_frame >= self.CCP.ACC_HUD_TEXT_STEP: + self.mlb_hud_text = self.CCP.ACC_HUD_TEXTS["none"] + self.mlb_set_speed_last = set_speed + return self.mlb_hud_text + def _should_spam_mqb_a0_resume(self, CS, enabled: bool) -> bool: return bool( enabled and @@ -429,8 +445,9 @@ class CarController(CarControllerBase): can_sends.append(self.CCS.create_blinker_control(self.packer_pt, self.CAN.pt, CS.ea_hud_stock_values, CS.ea_control_stock_values, left_blinker, right_blinker, self.hide_ea_error)) - if self.CP.openpilotLongitudinalControl and self.CCS == mqbcan and not self.acc_counter_seeded and CS.acc_stock_counters: - for name in ("ACC_02", "ACC_06", "ACC_07", "ACC_10"): + if self.CP.openpilotLongitudinalControl and self.CCS in (mqbcan, mlbcan) and not self.acc_counter_seeded and CS.acc_stock_counters: + seed_msgs = ("ACC_01", "ACC_02") if self.CCS is mlbcan else ("ACC_02", "ACC_06", "ACC_07", "ACC_10") + for name in seed_msgs: addr = self.packer_pt.dbc.name_to_msg[name].address self.packer_pt.counters[addr] = (CS.acc_stock_counters[name] + 1) % 16 self.acc_counter_seeded = True @@ -499,6 +516,8 @@ class CarController(CarControllerBase): self.long_deviation, self.long_jerklimit, eBrakeActive, esp_starting_override=esp_starting_override, esp_stopping_override=esp_stopping_override, )) + elif self.CCS == mlbcan: + can_sends.extend(self.CCS.create_acc_accel_control(self.packer_pt, self.CAN.pt, accel, acc_control, stopping)) else: accel = apply_pq_stopping_accel(self.CP.carFingerprint, accel, stopping) @@ -577,7 +596,10 @@ class CarController(CarControllerBase): acc_hud_status = self.CCS.acc_hud_status_value(CS.out.cruiseState.available, CS.out.accFaulted, CC.longActive, CC.cruiseControl.override) set_speed = hud_control.setSpeed * CV.MS_TO_KPH decel = dVisual(self.CCS, CS) - can_sends.append(self.CCS.create_acc_hud_control(self.packer_pt, self.CAN.pt, acc_hud_status, set_speed, leadDistance, self.leadDistanceBars, fcw_alert, hud_control.leadVisible, self.unavailable, decel, d_unresponsive)) + hud_kwargs = {"hud_text": self._mlb_acc_hud_text(hud_control, set_speed)} if self.CCS is mlbcan else {} + can_sends.append(self.CCS.create_acc_hud_control(self.packer_pt, self.CAN.pt, acc_hud_status, set_speed, leadDistance, + self.leadDistanceBars, fcw_alert, hud_control.leadVisible, self.unavailable, + decel, d_unresponsive, **hud_kwargs)) if self.CP.flags & VolkswagenFlags.PQ: iq_lvbs_commander.update_turn_signals(self, CC, CS, can_sends) diff --git a/iqdbc_repo/iqdbc/car/volkswagen/carstate.py b/iqdbc_repo/iqdbc/car/volkswagen/carstate.py index bb35a8c..d4a44e9 100644 --- a/iqdbc_repo/iqdbc/car/volkswagen/carstate.py +++ b/iqdbc_repo/iqdbc/car/volkswagen/carstate.py @@ -675,9 +675,12 @@ class CarState(CarStateBase): else: ret.gearShifter = GearShifter.drive - # ACC okay but disabled (1), ACC ready (2), a radar visibility or other fault/disruption (6 or 7) - # currently regulating speed (3), driver accel override (4), brake only (5) - if self.CP.carFingerprint == CAR.PORSCHE_MACAN_MK1: + cruise_main_switch = bool(pt_cp.vl["LS_01"]["LS_Hauptschalter"]) + if not self.CP.pcmCruise: + ret.cruiseState.available = cruise_main_switch + ret.cruiseState.enabled = False + ret.accFaulted = False + elif self.CP.carFingerprint == CAR.PORSCHE_MACAN_MK1: ret.cruiseState.available = ext_cp.vl["ACC_05"]["ACC_Status_ACC"] in (2, 3, 4, 5) ret.cruiseState.enabled = ext_cp.vl["ACC_05"]["ACC_Status_ACC"] in (3, 4, 5) ret.accFaulted = ext_cp.vl["ACC_05"]["ACC_Status_ACC"] in (6, 7) @@ -687,6 +690,12 @@ class CarState(CarStateBase): ret.cruiseState.speed = ext_cp.vl["ACC_02"]["ACC_Wunschgeschw_02"] * CV.KPH_TO_MS ret.accFaulted = pt_cp.vl["TSK_02"]["TSK_Status"] in (3,) + ret.cruiseState.nonAdaptive = bool(pt_cp.vl["LS_01"]["LS_Limiter"]) + if not self.CP.pcmCruise: + self.acc_stock_counters["ACC_01"] = int(ext_cp.vl["ACC_01"]["COUNTER"]) + self.acc_stock_counters["ACC_02"] = int(ext_cp.vl["ACC_02"]["COUNTER"]) + self.esp_hold_confirmation = bool(pt_cp.vl["ESP_02"]["ESP_Stillstandsflag"]) + self.parse_mlb_mqb_steering_state(ret, pt_cp) self._update_mlb_iq_alc_state(pt_cp) @@ -728,9 +737,10 @@ class CarState(CarStateBase): ret.cruiseState.standstill = self.CP.pcmCruise and self.esp_hold_confirmation ret.standstill = ret.vEgoRaw == 0 - ret.cruiseFaultLateralMode = False - ret.lateralAvailable = ret.cruiseState.available - ret.blockPcmEnable = False + allow_lat_only = self._params.get_bool("AllowLateralWhenLongUnavailable") and self._params.get_bool("AolEnabled") + ret.cruiseFaultLateralMode = allow_lat_only and ret.accFaulted and cruise_main_switch + ret.lateralAvailable = ret.cruiseState.available or ret.cruiseFaultLateralMode + ret.blockPcmEnable = ret.cruiseFaultLateralMode self.cruise_faulted = ret.accFaulted self.frame += 1 diff --git a/iqdbc_repo/iqdbc/car/volkswagen/interface.py b/iqdbc_repo/iqdbc/car/volkswagen/interface.py index 85a4a9b..e86118c 100644 --- a/iqdbc_repo/iqdbc/car/volkswagen/interface.py +++ b/iqdbc_repo/iqdbc/car/volkswagen/interface.py @@ -91,6 +91,7 @@ class CarInterface(CarInterfaceBase): safety_configs = [get_safety_config(structs.CarParams.SafetyModel.volkswagenMlb)] ret.enableBsm = 0x30F in fingerprint[0] # SWA_01 ret.networkLocation = NetworkLocation.gateway + ret.transmissionType = TransmissionType.automatic ret.dashcamOnly = False elif ret.flags & (VolkswagenFlags.MEB | VolkswagenFlags.MQB_EVO): diff --git a/iqdbc_repo/iqdbc/car/volkswagen/mlbcan.py b/iqdbc_repo/iqdbc/car/volkswagen/mlbcan.py index aee56e2..6f57105 100644 --- a/iqdbc_repo/iqdbc/car/volkswagen/mlbcan.py +++ b/iqdbc_repo/iqdbc/car/volkswagen/mlbcan.py @@ -1,4 +1,11 @@ -from iqdbc.car.volkswagen.mqbcan import (volkswagen_mqb_meb_checksum, xor_checksum, create_lka_hud_control as mqb_create_lka_hud_control) +from iqdbc.car.volkswagen.mqbcan import (volkswagen_mqb_meb_checksum, xor_checksum, + acc_control_value as mqb_acc_control_value, + acc_hud_status_value as mqb_acc_hud_status_value, + create_lka_hud_control as mqb_create_lka_hud_control) + +# ACC_01.ACC_Sollbeschleunigung one increment above range max, "no acceleration request" +ACC_INACTIVE_ACCEL = 3.01 + def create_hca_steering_control(packer, bus, apply_steer, HCA_Status): values = { @@ -11,8 +18,10 @@ def create_hca_steering_control(packer, bus, apply_steer, HCA_Status): return packer.make_can_msg("HCA_01", bus, values) -def create_lka_hud_control(packer, bus, ldw_stock_values, enabled, steering_pressed, hud_alert, hud_control, entering=False, special_mode=False, special_active=False): - return mqb_create_lka_hud_control(packer, bus, ldw_stock_values, enabled, steering_pressed, hud_alert, hud_control, entering, special_mode, special_active) +def create_lka_hud_control(packer, bus, ldw_stock_values, enabled, steering_pressed, hud_alert, hud_control, + entering=False, special_mode=False, special_active=False): + return mqb_create_lka_hud_control(packer, bus, ldw_stock_values, enabled, steering_pressed, hud_alert, hud_control, + entering, special_mode, special_active) def create_acc_buttons_control(packer, bus, gra_stock_values, cancel=False, resume=False, set_button=False): @@ -32,23 +41,57 @@ def create_acc_buttons_control(packer, bus, gra_stock_values, cancel=False, resu return packer.make_can_msg("LS_01", bus, values) -def acc_control_value(main_switch_on, long_active, cruiseOverride): - return 0 +def acc_control_value(main_switch_on, long_active, cruiseOverride, accFaulted): + # ACC_01.ACC_Status_ACC uses the same enum as MQB ACC_06: 0 off, 2 standby, 3 active, 4 driver override, 6 fault + return mqb_acc_control_value(main_switch_on, long_active, cruiseOverride, accFaulted) def acc_hud_status_value(main_switch_on, acc_faulted, longActive, longOverride): - return 0 + return mqb_acc_hud_status_value(main_switch_on, acc_faulted, longActive, longOverride) -def create_acc_accel_control(packer, bus, acc_type, accel, acc_control, stopping, starting, esp_hold, comfortBand, jerkLimit): - values = {} - return [packer.make_can_msg("ACC_05", bus, values)] +def create_acc_accel_control(packer, bus, accel, acc_control, stopping): + acc_enabled = acc_control in (3, 4) + + acc_01_values = { + "ACC_Status_ACC": acc_control, + "ACC_Sollbeschleunigung": accel if acc_enabled else ACC_INACTIVE_ACCEL, + "ACC_zul_Regelabw_unten": 0.2, + "ACC_zul_Regelabw_oben": 0.2, + "ACC_neg_Sollbeschl_Grad": 4.0 if acc_enabled else 0, + "ACC_pos_Sollbeschl_Grad": 4.0 if acc_enabled else 0, + "ACC_Dynamik": 3, + "ACC_Anhalten": stopping if acc_enabled else False, + "ACC_Minimale_Bremsung": 0, + } + + return [packer.make_can_msg("ACC_01", bus, acc_01_values)] -def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, leadDistance, distanceBars, fcw_alert, leadVisible, unavailable, decel, d_unresponsive): - values = {} +def create_acc_hud_control(packer, bus, acc_hud_status, set_speed, leadDistance, distanceBars, fcw_alert, leadVisible, + unavailable, decel, d_unresponsive, hud_text=0): + engaged = acc_hud_status in (3, 4) + priodisp = 0 if fcw_alert else 1 if (acc_hud_status == 4 or decel or leadVisible) else 2 if (acc_hud_status in (3, 2)) else 0 + leadDistanceBars = distanceBars + 1 if distanceBars in (1, 2, 3) else 2 + + values = { + "ACC_Status_Anzeige": acc_hud_status, + "ACC_Wunschgeschw_02": set_speed if set_speed < 250 else 327.36, + "ACC_Gesetzte_Zeitluecke": leadDistanceBars, + "ACC_Anzeige_Zeitluecke": 1 if engaged else 0, + "ACC_Tachokranz": 1 if engaged else 0, + "ACC_Display_Prio": priodisp, + "ACC_Abstandsindex": leadDistance if leadVisible else 0, + "ACC_Relevantes_Objekt": 2 if fcw_alert else (1 if leadVisible else 0), # lead car: 1 green, 2 red, 0 off + "ACC_Status_Prim_Anz": 2 if fcw_alert else (1 if engaged else 0), # ACC symbol: 1 green, 2 red, 0 off + "ACC_Optischer_Fahrerhinweis": 1 if fcw_alert else 0, + "ACC_Akustik": 1 if (fcw_alert or d_unresponsive) else 0, + "ACC_Texte_Primaeranz": hud_text, + } + return packer.make_can_msg("ACC_02", bus, values) + def volkswagen_mlb_checksum(address: int, sig, d: bytearray) -> int: xor_starting_value = { 0x109: 0x08, # ACC_01 diff --git a/iqdbc_repo/iqdbc/car/volkswagen/values.py b/iqdbc_repo/iqdbc/car/volkswagen/values.py index d6aa955..cff8bce 100644 --- a/iqdbc_repo/iqdbc/car/volkswagen/values.py +++ b/iqdbc_repo/iqdbc/car/volkswagen/values.py @@ -2,7 +2,7 @@ from collections import defaultdict, namedtuple from dataclasses import dataclass, field from enum import Enum, IntFlag, StrEnum -from iqdbc.car import ACCELERATION_DUE_TO_GRAVITY, Bus, CanBusBase, CarSpecs, DbcDict, PlatformConfig, Platforms, structs, uds +from iqdbc.car import ACCELERATION_DUE_TO_GRAVITY, Bus, CanBusBase, CarSpecs, DbcDict, DT_CTRL, PlatformConfig, Platforms, structs, uds from iqdbc.car.lateral import CurvatureSteeringLimits from iqdbc.can import CANDefine from iqdbc.car.common.conversions import Conversions as CV @@ -204,6 +204,7 @@ class CarControllerParams: self.STEER_DRIVER_ALLOWANCE = 60 # Driver intervention threshold 0.6 Nm self.STEER_DELTA_UP = 9 # Max HCA reached in 0.66s (STEER_MAX / (50Hz * 0.66)) self.STEER_DELTA_DOWN = 10 # Min HCA reached in 0.60s (STEER_MAX / (50Hz * 0.60)) + self.ACC_HUD_TEXT_STEP = int(2.0 / DT_CTRL) # ACC_02 primary display text dwell time if CP.carFingerprint == CAR.PORSCHE_MACAN_MK1: self.shifter_values = can_define.dv["Getriebe_03"]["GE_Waehlhebel"] @@ -219,6 +220,13 @@ class CarControllerParams: Button(structs.CarState.ButtonEvent.Type.gapAdjustCruise, "LS_01", "LS_Verstellung_Zeitluecke", [1, 2, 3]), ] + # ACC_02.ACC_Texte_Primaeranz, primary ACC display text at the bottom of the cluster + self.ACC_HUD_TEXTS = { + "none": 0, + "setSpeed": 21, + } + self.ACC_HUD_TEXT_DISTANCE = {1: 2, 2: 3, 3: 4, 4: 5} # follow distance bars to display text + else: self.STEER_DRIVER_ALLOWANCE = 80 # Driver intervention threshold 0.8 Nm self.STEER_DELTA_UP = 4 # Max HCA reached in 1.50s (STEER_MAX / (50Hz * 1.50)) diff --git a/iqdbc_repo/iqdbc/dbc/vw_mlb.dbc b/iqdbc_repo/iqdbc/dbc/vw_mlb.dbc index 2f5f4b7..052bc1e 100644 --- a/iqdbc_repo/iqdbc/dbc/vw_mlb.dbc +++ b/iqdbc_repo/iqdbc/dbc/vw_mlb.dbc @@ -35,7 +35,7 @@ BS_: BU_: Airbag_D4 EPB_D4 ESP_D4 Gateway_D4C7 Getriebe_AL551_951_D4_C7 Getriebe_DL501_C7 Getriebe_VL381_C7 LWS_D4 Motor_EDC17_D4 Motor_ME17_BY Motor_MED17_SIMOS8_D4 Motor_Slave_D4 QSP_D4 SAK_C7 SCR_C7 SCU_D4 BO_ 265 ACC_01: 8 Gateway_B8 - SG_ ACC_01_CHK : 0|8@1+ (1,0) [0|255] "" Magnetic_Ride_LB,Motor_MLB_AU48_AU416_Diesel,Motor_MLB_B8_Q5_Otto,Motor_MLB_Q5_Hybrid + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" Magnetic_Ride_LB,Motor_MLB_AU48_AU416_Diesel,Motor_MLB_B8_Q5_Otto,Motor_MLB_Q5_Hybrid SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" Magnetic_Ride_LB,Motor_MLB_AU48_AU416_Diesel,Motor_MLB_B8_Q5_Otto,Motor_MLB_Q5_Hybrid SG_ ACC_zul_Regelabw_unten : 16|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Motor_MLB_AU48_AU416_Diesel,Motor_MLB_B8_Q5_Otto,Motor_MLB_Q5_Hybrid SG_ ACC_Sollbeschleunigung : 24|11@1+ (0.005,-7.22) [-7.22|3.01] "Unit_MeterPerSeconSquar" Magnetic_Ride_LB,Motor_MLB_AU48_AU416_Diesel,Motor_MLB_B8_Q5_Otto,Motor_MLB_Q5_Hybrid @@ -48,7 +48,7 @@ BO_ 265 ACC_01: 8 Gateway_B8 SG_ ACC_Minimale_Bremsung : 63|1@1+ (1,0) [0|1] "" Motor_MLB_AU48_AU416_Diesel,Motor_MLB_B8_Q5_Otto,Motor_MLB_Q5_Hybrid BO_ 780 ACC_02: 8 Gateway_D4C7 - SG_ ACC_02_CHK : 0|8@1+ (1,0) [0|255] "" HUD_C7,Kombi_D4 + SG_ CHECKSUM : 0|8@1+ (1,0) [0|255] "" HUD_C7,Kombi_D4 SG_ COUNTER : 8|4@1+ (1,0) [0|15] "" HUD_C7,Kombi_D4 SG_ ACC_Wunschgeschw_02 : 12|10@1+ (0.32,0) [0.00|326.72] "Unit_KiloMeterPerHour" HUD_C7,Kombi_D4 SG_ ACC_Status_Prim_Anz : 22|2@1+ (1.0,0.0) [0.0|3] "" HUD_C7,Kombi_D4 diff --git a/iqdbc_repo/iqdbc/safety/modes/volkswagen_common.h b/iqdbc_repo/iqdbc/safety/modes/volkswagen_common.h index f2a5ac7..a8223b5 100644 --- a/iqdbc_repo/iqdbc/safety/modes/volkswagen_common.h +++ b/iqdbc_repo/iqdbc/safety/modes/volkswagen_common.h @@ -100,7 +100,7 @@ void can_set_checksum(CANPacket_t *packet); #define MSG_MOTOR_03 0x105U // RX from ECU, for driver throttle input and brake switch status #define MSG_TSK_02 0x10CU // RX from ECU, for ACC status from drivetrain coordinator #define MSG_ACC_05 0x10DU // RX from radar, for ACC status -#define MSG_ACC_01 0x109U // RX from radar, for ACC status (Audi B8) +#define MSG_ACC_01 0x109U // TX by OP, ACC control instructions to the drivetrain coordinator static void volkswagen_common_init(void) { volkswagen_set_button_prev = false; diff --git a/iqdbc_repo/iqdbc/safety/modes/volkswagen_mlb.h b/iqdbc_repo/iqdbc/safety/modes/volkswagen_mlb.h index 3460f03..958d3ed 100644 --- a/iqdbc_repo/iqdbc/safety/modes/volkswagen_mlb.h +++ b/iqdbc_repo/iqdbc/safety/modes/volkswagen_mlb.h @@ -9,6 +9,9 @@ static safety_config volkswagen_mlb_init(uint16_t param) { static const CanMsg VOLKSWAGEN_MLB_STOCK_TX_MSGS[] = {{MSG_HCA_01, 0, 8, .check_relay = true}, {MSG_LDW_02, 0, 8, .check_relay = true}, {MSG_LS_01, 0, 4, .check_relay = false}, {MSG_LS_01, 2, 4, .check_relay = false}}; + static const CanMsg VOLKSWAGEN_MLB_LONG_TX_MSGS[] = {{MSG_HCA_01, 0, 8, .check_relay = true}, {MSG_LDW_02, 0, 8, .check_relay = true}, + {MSG_ACC_01, 0, 8, .check_relay = true}, {MSG_ACC_02, 0, 8, .check_relay = true}}; + static RxCheck volkswagen_mlb_rx_checks[] = { // TODO: implement checksum validation {.msg = {{MSG_ESP_03, 0, 8, 50U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, @@ -19,10 +22,17 @@ static safety_config volkswagen_mlb_init(uint16_t param) { {.msg = {{MSG_LS_01, 0, 4, 10U, .ignore_checksum = true, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, }; - SAFETY_UNUSED(param); volkswagen_common_init(); - return BUILD_SAFETY_CFG(volkswagen_mlb_rx_checks, VOLKSWAGEN_MLB_STOCK_TX_MSGS); +#ifdef ALLOW_DEBUG + volkswagen_longitudinal = GET_FLAG(param, FLAG_VOLKSWAGEN_LONG_CONTROL); + volkswagen_allow_long_accel_with_gas_pressed = GET_FLAG(param, FLAG_VOLKSWAGEN_ALLOW_LONG_ACCEL_WITH_GAS_PRESSED); +#else + SAFETY_UNUSED(param); +#endif + + return volkswagen_longitudinal ? BUILD_SAFETY_CFG(volkswagen_mlb_rx_checks, VOLKSWAGEN_MLB_LONG_TX_MSGS) : \ + BUILD_SAFETY_CFG(volkswagen_mlb_rx_checks, VOLKSWAGEN_MLB_STOCK_TX_MSGS); } static void volkswagen_mlb_rx_hook(const CANPacket_t *msg) { @@ -44,6 +54,27 @@ static void volkswagen_mlb_rx_hook(const CANPacket_t *msg) { } if (msg->addr == MSG_LS_01) { + // If using openpilot longitudinal, the stock ACC coordinator is relayed out, so the stalk main + // switch is the only remaining source of truth. Enter controls on falling edge of Set or Resume. + // Signal: LS_01.LS_Hauptschalter + // Signal: LS_01.LS_Tip_Setzen + // Signal: LS_01.LS_Tip_Wiederaufnahme + if (volkswagen_longitudinal) { + acc_main_on = GET_BIT(msg, 12U); + + bool set_button = GET_BIT(msg, 16U); + bool resume_button = GET_BIT(msg, 19U); + if ((volkswagen_set_button_prev && !set_button) || (volkswagen_resume_button_prev && !resume_button)) { + controls_allowed = acc_main_on; + } + volkswagen_set_button_prev = set_button; + volkswagen_resume_button_prev = resume_button; + + if (!acc_main_on) { + controls_allowed = false; + } + } + // Always exit controls on rising edge of Cancel // Signal: LS_01.LS_Abbrechen if (GET_BIT(msg, 13U)) { @@ -64,7 +95,7 @@ static void volkswagen_mlb_rx_hook(const CANPacket_t *msg) { brake_pressed = volkswagen_brake_pedal_switch || volkswagen_brake_pressure_detected; - if (msg->addr == MSG_TSK_02) { + if ((msg->addr == MSG_TSK_02) && !volkswagen_longitudinal) { // When using stock ACC, enter controls on rising edge of stock ACC engage, exit on disengage // Always exit controls on main switch off // Signal: TSK_02.TSK_Status @@ -80,7 +111,7 @@ static void volkswagen_mlb_rx_hook(const CANPacket_t *msg) { if (msg->bus == 2U) { // TODO: See if there's a bus-agnostic TSK message we can use instead - if (msg->addr == MSG_ACC_05) { + if ((msg->addr == MSG_ACC_05) && !volkswagen_longitudinal) { // When using stock ACC, enter controls on rising edge of stock ACC engage, exit on disengage // Always exit controls on main switch off // Signal: ACC_05.ACC_Status_ACC @@ -123,6 +154,17 @@ static bool volkswagen_mlb_tx_hook(const CANPacket_t *msg) { } } + // Safety check for ACC_01 acceleration request + // Signal: ACC_01.ACC_Sollbeschleunigung (acceleration in m/s^2, scale 0.005, offset -7.22) + // To avoid floating point math, scale upward and compare to pre-scaled safety m/s^2 boundaries + if (msg->addr == MSG_ACC_01) { + int desired_accel = ((((msg->data[4] & 0x07U) << 8) | msg->data[3]) * 5U) - 7220U; + + if (volkswagen_iq_long_accel_check(desired_accel)) { + tx = false; + } + } + // FORCE CANCEL: ensuring that only the cancel button press is sent when controls are off. // This avoids unintended engagements while still allowing resume spam if ((msg->addr == MSG_LS_01) && !controls_allowed) { diff --git a/iqdbc_repo/iqdbc/safety/tests/common.py b/iqdbc_repo/iqdbc/safety/tests/common.py index fdae10d..935fcb7 100644 --- a/iqdbc_repo/iqdbc/safety/tests/common.py +++ b/iqdbc_repo/iqdbc/safety/tests/common.py @@ -926,12 +926,12 @@ class SafetyTest(SafetyTestBase): if attr.startswith('TestSubaru') and current_test == 'TestVolkswagenMqbLongSafety': tx = list(filter(lambda m: m[0] not in [0x122, ], tx)) - # Volkswagen MQB and Honda Nidec ACC HUD messages overlap - if attr == 'TestVolkswagenMqbLongSafety' and current_test.startswith('TestHondaNidec'): + # Volkswagen MQB/MLB and Honda Nidec ACC HUD messages overlap + if attr in ('TestVolkswagenMqbLongSafety', 'TestVolkswagenMlbLongSafety') and current_test.startswith('TestHondaNidec'): tx = list(filter(lambda m: m[0] not in [0x30c, ], tx)) - # Volkswagen MQB and Honda Bosch Radarless ACC HUD messages overlap - if attr == 'TestVolkswagenMqbLongSafety' and current_test.startswith('TestHondaBoschRadarless'): + # Volkswagen MQB/MLB and Honda Bosch Radarless ACC HUD messages overlap + if attr in ('TestVolkswagenMqbLongSafety', 'TestVolkswagenMlbLongSafety') and current_test.startswith('TestHondaBoschRadarless'): tx = list(filter(lambda m: m[0] not in [0x30c, ], tx)) # TODO: Temporary, should be fixed in panda firmware, safety_honda.h diff --git a/iqdbc_repo/iqdbc/safety/tests/test_volkswagen_mlb.py b/iqdbc_repo/iqdbc/safety/tests/test_volkswagen_mlb.py index de7baaa..a1fce49 100755 --- a/iqdbc_repo/iqdbc/safety/tests/test_volkswagen_mlb.py +++ b/iqdbc_repo/iqdbc/safety/tests/test_volkswagen_mlb.py @@ -1,17 +1,24 @@ #!/usr/bin/env python3 import unittest +import numpy as np from iqdbc.car.structs import CarParams from iqdbc.safety.tests.libsafety import libsafety_py import iqdbc.safety.tests.common as common from iqdbc.safety.tests.common import CANPackerSafety +from iqdbc.car.volkswagen.values import VolkswagenSafetyFlags + +MAX_ACCEL = 2.0 +MIN_ACCEL = -3.5 MSG_LH_EPS_03 = 0x9F # RX from EPS, for driver steering torque +MSG_ACC_01 = 0x109 # TX by OP, ACC acceleration request to the drivetrain coordinator MSG_ESP_03 = 0x103 # RX from ABS, for wheel speeds MSG_MOTOR_03 = 0x105 # RX from ECU, for driver throttle input and driver brake input MSG_ESP_05 = 0x106 # RX from ABS, for brake light state MSG_LS_01 = 0x10B # TX by OP, ACC control buttons for cancel/resume MSG_TSK_02 = 0x10C # RX from ECU, for ACC status from drivetrain coordinator MSG_HCA_01 = 0x126 # TX by OP, Heading Control Assist steering torque +MSG_ACC_02 = 0x30C # TX by OP, ACC HUD data to the instrument cluster MSG_LDW_02 = 0x397 # TX by OP, Lane line recognition and text alerts @@ -72,10 +79,16 @@ class TestVolkswagenMlbSafetyBase(common.CarSafetyTest, common.DriverTorqueSteer return self.packer.make_can_msg_safety("HCA_01", 0, values) # Cruise control buttons - def _ls_01_msg(self, cancel=0, resume=0, _set=0, bus=2): - values = {"LS_Abbrechen": cancel, "LS_Tip_Setzen": _set, "LS_Tip_Wiederaufnahme": resume} + def _ls_01_msg(self, cancel=0, resume=0, _set=0, main_switch=1, bus=2): + values = {"LS_Abbrechen": cancel, "LS_Tip_Setzen": _set, "LS_Tip_Wiederaufnahme": resume, + "LS_Hauptschalter": main_switch} return self.packer.make_can_msg_safety("LS_01", bus, values) + # Acceleration request to drivetrain coordinator + def _acc_01_msg(self, accel): + values = {"ACC_Sollbeschleunigung": accel} + return self.packer.make_can_msg_safety("ACC_01", 0, values) + # Verify brake_pressed is true if either the switch or pressure threshold signals are true def test_redundant_brake_signals(self): test_combinations = [(True, True, True), (True, True, False), (True, False, True), (False, False, False)] @@ -137,5 +150,63 @@ class TestVolkswagenMlbStockSafety(TestVolkswagenMlbSafetyBase): self.assertFalse(self.safety.get_controls_allowed(), "controls allowed after cancel") +class TestVolkswagenMlbLongSafety(TestVolkswagenMlbSafetyBase): + TX_MSGS = [[MSG_HCA_01, 0], [MSG_LDW_02, 0], [MSG_ACC_01, 0], [MSG_ACC_02, 0]] + FWD_BLACKLISTED_ADDRS = {2: [MSG_HCA_01, MSG_LDW_02, MSG_ACC_01, MSG_ACC_02]} + FWD_BUS_LOOKUP = {0: 2, 2: 0} + RELAY_MALFUNCTION_ADDRS = {0: (MSG_HCA_01, MSG_LDW_02, MSG_ACC_01, MSG_ACC_02)} + INACTIVE_ACCEL = 3.01 + + def setUp(self): + self.packer = CANPackerSafety("vw_mlb") + self.safety = libsafety_py.libsafety + safety_param = VolkswagenSafetyFlags.LONG_CONTROL | VolkswagenSafetyFlags.ALLOW_LONG_ACCEL_WITH_GAS_PRESSED + self.safety.set_safety_hooks(CarParams.SafetyModel.volkswagenMlb, safety_param) + self.safety.init_tests() + + # stock cruise controls are entirely bypassed under openpilot longitudinal control + def test_disable_control_allowed_from_cruise(self): + pass + + def test_enable_control_allowed_from_cruise(self): + pass + + def test_cruise_engaged_prev(self): + pass + + def test_set_and_resume_buttons(self): + for button in ["set", "resume"]: + # ACC main switch must be on, engage on falling edge + self.safety.set_controls_allowed(0) + self._rx(self._ls_01_msg(_set=(button == "set"), resume=(button == "resume"), main_switch=0, bus=0)) + self.assertFalse(self.safety.get_controls_allowed(), f"controls allowed on {button} with main switch off") + self._rx(self._ls_01_msg(main_switch=0, bus=0)) + self._rx(self._ls_01_msg(_set=(button == "set"), resume=(button == "resume"), bus=0)) + self.assertFalse(self.safety.get_controls_allowed(), f"controls allowed on {button} rising edge") + self._rx(self._ls_01_msg(bus=0)) + self.assertTrue(self.safety.get_controls_allowed(), f"controls not allowed on {button} falling edge") + + def test_main_switch(self): + # Disable as soon as the ACC main switch turns off + self._rx(self._ls_01_msg(bus=0)) + self.safety.set_controls_allowed(1) + self._rx(self._ls_01_msg(main_switch=0, bus=0)) + self.assertFalse(self.safety.get_controls_allowed(), "controls allowed after ACC main switch off") + + def test_accel_safety_check(self): + for controls_allowed in [True, False]: + for accel in np.concatenate((np.arange(MIN_ACCEL - 2, MAX_ACCEL + 2, 0.03), [0, self.INACTIVE_ACCEL])): + accel = round(accel, 2) + is_inactive_accel = accel == self.INACTIVE_ACCEL + send = (controls_allowed and MIN_ACCEL <= accel <= MAX_ACCEL) or is_inactive_accel + self.safety.set_controls_allowed(controls_allowed) + self.assertEqual(send, self._tx(self._acc_01_msg(accel)), (controls_allowed, accel)) + + def test_accel_allowed_with_gas_pressed(self): + self._rx(self._user_gas_msg(1)) + self.safety.set_controls_allowed(True) + self.assertTrue(self._tx(self._acc_01_msg(0.5))) + + if __name__ == "__main__": unittest.main() diff --git a/iqpilot/iq_maps/orchestrator.py b/iqpilot/iq_maps/orchestrator.py index fbe60d0..b8af353 100755 --- a/iqpilot/iq_maps/orchestrator.py +++ b/iqpilot/iq_maps/orchestrator.py @@ -121,19 +121,13 @@ def _install_signal_handlers() -> None: signal.signal(signal.SIGTERM, _handle_shutdown_signal) -class _QuietSpinner: - def update(self, *args, **kwargs) -> None: - pass - - def close(self, *args, **kwargs) -> None: - pass - - def ensure_vendor_runtime() -> None: + # verify-only: a hash-mismatched binary is quarantined, never replaced from + # the network — the updater restores the checked-in one try: - VendorMapdInstaller(_QuietSpinner()).check_and_download() + VendorMapdInstaller().verify() except Exception: - cloudlog.exception("iq_maps: vendor runtime install/download failed") + cloudlog.exception("iq_maps: vendor runtime verification failed") params = Params() mem_params = Params("/dev/shm/params") if platform.system() != "Darwin" else params diff --git a/iqpilot/iq_maps/update_vendor_version.py b/iqpilot/iq_maps/update_vendor_version.py index 7573559..13391ec 100755 --- a/iqpilot/iq_maps/update_vendor_version.py +++ b/iqpilot/iq_maps/update_vendor_version.py @@ -2,8 +2,10 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -Maintainer utility: pin a new pfeiferj/mapd release tag and refresh the checked-in -binary hash. Not used at runtime. +Maintainer utility: pin a new mapd release tag and refresh the checked-in binary +hash. Not used at runtime. Binaries come from the gitlvb teal/mapd CI (built +against teal/gomsgq) — drop the artifact at third_party/mapd_pfeiferj/mapd, then +run this so the hash pin moves in the same commit. """ import argparse import os diff --git a/iqpilot/iq_maps/vendor_mapd_installer.py b/iqpilot/iq_maps/vendor_mapd_installer.py index 96090d4..3c41800 100755 --- a/iqpilot/iq_maps/vendor_mapd_installer.py +++ b/iqpilot/iq_maps/vendor_mapd_installer.py @@ -2,36 +2,30 @@ """ Copyright © IQ.Lvbs, apart of Project Teal Lvbs, All Rights Reserved, licensed under https://konn3kt.com/tos -Provisions the `mapd` routing binary authored by Jacob Pfeifer (github.com/pfeiferj/mapd). -The binary itself is his work; this module only fetches, verifies and stages it on-device. +Verifies the vendored `mapd` routing binary authored by Jacob Pfeifer +(github.com/pfeiferj/mapd), built from the gitlvb teal/mapd fork against +teal/gomsgq. The only accepted binary is the checked-in one matching the pinned +hash; nothing is ever downloaded at runtime. Jacob's stock release build embeds +a 15-reader msgq header layout — on this fork (NUM_READERS=32) its registration +writes land inside other processes' reader slots, so a wrong binary is +quarantined rather than left where manager could start it. """ import hashlib -import logging import os -import stat -import time -from pathlib import Path +import sys -import requests - -from cereal import messaging from openpilot.common.basedir import BASEDIR from openpilot.common.params import Params from openpilot.common.spinner import Spinner -from openpilot.system.hardware.hw import Paths -from openpilot.system.version import is_prebuilt -from openpilot.iqpilot.iq_maps import VENDOR_MAPD_BIN_DIR, VENDOR_MAPD_PATH +from openpilot.common.swaglog import cloudlog +from openpilot.iqpilot.iq_maps import VENDOR_MAPD_PATH import openpilot.system.sentry as sentry -VENDOR_RELEASE_TAG = "v2.0.6" -VENDOR_RELEASE_URL = f"https://github.com/pfeiferj/mapd/releases/download/{VENDOR_RELEASE_TAG}/mapd" +VENDOR_RELEASE_TAG = "v2.0.6-iq1" _VERSION_PARAM = "MapdVersion" _HASH_FILE = os.path.join(BASEDIR, "iqpilot", "iq_maps", "tests", "mapd_hash") -_HTTP_TIMEOUT_S = 60 -_FETCH_ATTEMPTS = 5 -_NET_PROBE_ATTEMPTS = 10 -_NET_PROBE_INTERVAL_S = 2 +QUARANTINE_PATH = VENDOR_MAPD_PATH + ".quarantined" def sha256_of_file(path: str) -> str: @@ -48,45 +42,58 @@ def stamp_vendor_version(version: str, params: Params | None = None) -> None: class VendorMapdInstaller: - def __init__(self, spinner_ref: Spinner): + def __init__(self, spinner_ref: Spinner | None = None, params: Params | None = None): self._spinner = spinner_ref - self._params = Params() + self._params = params if params is not None else Params() - # --- externally consumed surface ----------------------------------------- def get_installed_version(self) -> str: return str(self._params.get(_VERSION_PARAM) or "") - @staticmethod - def ensure_directories_exist() -> None: - for directory in (Paths.mapd_root(), VENDOR_MAPD_BIN_DIR): - os.makedirs(directory, exist_ok=True) + def verify(self) -> bool: + """True iff the on-disk binary matches the pinned hash; quarantines a wrong one.""" + expected = self._expected_hash() + if not expected: + cloudlog.error("iq_maps: pinned mapd hash missing, vendor binary cannot be verified") + return False - def check_and_download(self) -> None: - if not self._binary_up_to_date(): - self._provision() - - def non_prebuilt_install(self) -> None: - if self._on_metered_link(): - self._say("Metered connection detected — offline maps engine will not download here.") - time.sleep(5) - return + if not os.path.isfile(VENDOR_MAPD_PATH): + # the binary is a tracked file: the updater/bundle restores it + self._say("Offline maps engine missing; it will be restored by the next update.") + self._params.remove(_VERSION_PARAM) + return False try: - self.ensure_directories_exist() - if self._binary_up_to_date(): - self._say("Offline maps engine already present and current.") - time.sleep(0.1) - return + current = sha256_of_file(VENDOR_MAPD_PATH) + except OSError: + cloudlog.exception("iq_maps: vendor mapd unreadable") + return False - if self._block_until_online(): - self._say(f"Retrieving offline maps engine [{self.get_installed_version() or 'none'}] -> [{VENDOR_RELEASE_TAG}]") - time.sleep(0.1) - self._provision() - self._spinner.close() - except Exception as exc: # noqa: BLE001 - self._announce_failure(exc) + if current == expected: + stamp_vendor_version(VENDOR_RELEASE_TAG, self._params) + try: + os.remove(QUARANTINE_PATH) + except OSError: + pass + self._say(f"Offline maps engine verified [{VENDOR_RELEASE_TAG}]") + return True + + # a foreign binary — e.g. a stock release download from the retired fetch + # path — must never run: quarantine it where manager can't start it + cloudlog.error(f"iq_maps: vendor mapd hash {current[:12]} != pinned {expected[:12]}, quarantining") + self._say("Offline maps engine failed verification; quarantined until the next update.") + try: + os.replace(VENDOR_MAPD_PATH, QUARANTINE_PATH) + except OSError: + cloudlog.exception("iq_maps: vendor mapd quarantine failed") + return False + self._params.remove(_VERSION_PARAM) + try: + raise RuntimeError(f"vendor mapd hash mismatch quarantined: {current}") + except RuntimeError as exc: + sentry.init(sentry.SentryProject.SELFDRIVE) + sentry.capture_exception(exc) + return False - # --- internal ------------------------------------------------------------ def _expected_hash(self) -> str: try: with open(_HASH_FILE) as f: @@ -94,88 +101,13 @@ class VendorMapdInstaller: except OSError: return "" - def _binary_up_to_date(self) -> bool: - if not os.path.exists(VENDOR_MAPD_PATH): - return False - if self.get_installed_version() != VENDOR_RELEASE_TAG: - return False - reference = self._expected_hash() - if not reference: - return True - try: - return sha256_of_file(VENDOR_MAPD_PATH) == reference - except OSError: - return False - - def _provision(self) -> None: - self.ensure_directories_exist() - if self._retrieve_binary(): - stamp_vendor_version(VENDOR_RELEASE_TAG, self._params) - - def _retrieve_binary(self) -> bool: - staging = Path(f"{VENDOR_MAPD_PATH}.part") - last_error: Exception | None = None - for attempt in range(1, _FETCH_ATTEMPTS + 1): - try: - with requests.get(VENDOR_RELEASE_URL, stream=True, timeout=_HTTP_TIMEOUT_S) as resp: - resp.raise_for_status() - with open(staging, "wb") as out: - for chunk in resp.iter_content(chunk_size=1 << 16): - out.write(chunk) - out.flush() - os.fsync(out.fileno()) - os.chmod(staging, os.lstat(staging).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) - staging.replace(VENDOR_MAPD_PATH) - return True - except requests.exceptions.RequestException as exc: - last_error = exc - self._say(f"offline maps fetch attempt {attempt}/{_FETCH_ATTEMPTS} did not complete ({exc})") - time.sleep(0.5) - staging.unlink(missing_ok=True) - logging.error("offline maps engine could not be fetched after %d attempts: %s", _FETCH_ATTEMPTS, last_error) - return False - - def _on_metered_link(self) -> bool: - sm = messaging.SubMaster(["deviceState"]) - return bool(sm["deviceState"].networkMetered) - - def _block_until_online(self) -> bool: - for i in range(1, _NET_PROBE_ATTEMPTS + 1): - self._say(f"Waiting for a usable network connection... [{i}/{_NET_PROBE_ATTEMPTS}]") - if self._link_reachable(): - return True - time.sleep(_NET_PROBE_INTERVAL_S) - return False - - @staticmethod - def _link_reachable() -> bool: - try: - requests.head(VENDOR_RELEASE_URL, timeout=10, allow_redirects=True) - return True - except requests.exceptions.RequestException as exc: - logging.debug("network probe failed: %s", exc) - return False - - def _announce_failure(self, exc: Exception) -> None: - for remaining in range(5, 0, -1): - self._say(f"Offline maps engine unavailable; navigation stays online-only. Boot continues in {remaining}s...") - time.sleep(1) - logging.exception("vendor mapd install failed") - sentry.init(sentry.SentryProject.SELFDRIVE) - sentry.capture_exception(exc) - def _say(self, text: str) -> None: - self._spinner.update(text) + if self._spinner is not None: + self._spinner.update(text) if __name__ == "__main__": spinner = Spinner() - installer = VendorMapdInstaller(spinner) - installer.ensure_directories_exist() - if is_prebuilt(): - spinner.update(f"[DEBUG] Prebuilt build; vendor mapd install skipped. " - f"target [{VENDOR_RELEASE_TAG}], param [{installer.get_installed_version()}]") - stamp_vendor_version(VENDOR_RELEASE_TAG) - else: - spinner.update(f"Verifying vendor mapd install. prebuilt [{is_prebuilt()}]") - installer.non_prebuilt_install() + ok = VendorMapdInstaller(spinner).verify() + spinner.close() + sys.exit(0 if ok else 1) diff --git a/selfdrive/modeld/models/prebuilt_check.json b/selfdrive/modeld/models/prebuilt_check.json index 6d0839d..29388de 100644 --- a/selfdrive/modeld/models/prebuilt_check.json +++ b/selfdrive/modeld/models/prebuilt_check.json @@ -4,6 +4,6 @@ "dmonitoring_model_metadata.pkl": "31a86ab7a92dc0af088b15787a440dd3b210aa662e445a15145900e559a1b5c3", "dmonitoring_model_tinygrad.pkl": "806c0ea75df6bf6dfeb81b832314c68e31df5865a52d0359e6eeb76d93ad2b52" }, - "signature": "e1eeb5ce45774a816c8da2394e6ee35ebf700b71dff345e0141dbab8ff592349" + "signature": "64740782bfd5b1720978aab24a2b1b37c99542f97db3c8637227c7412bb30bbf" } } diff --git a/selfdrive/modeld/prebuilt_models.py b/selfdrive/modeld/prebuilt_models.py index 73a16de..00ab888 100644 --- a/selfdrive/modeld/prebuilt_models.py +++ b/selfdrive/modeld/prebuilt_models.py @@ -29,10 +29,12 @@ def _file_sha256(path: Path) -> str: @functools.lru_cache(maxsize=1) def _tinygrad_digest() -> str: h = hashlib.sha256() - # mirror the SConscript glob: no hidden files/dirs (also excludes .git, which differs per clone), no pycache + # mirror the SConscript glob: no hidden files/dirs (also excludes .git, which differs per clone), no pycache. + # 'weights' holds untracked/gitignored model weights (e.g. iqvd yolov8n .safetensors) present on dev machines + # but absent from a clean CI/device clone — hashing them makes the signature unreproducible (false STALE). def _included(p: Path) -> bool: rel = p.relative_to(TINYGRAD_DIR).parts - return p.is_file() and '__pycache__' not in rel and not any(part.startswith('.') for part in rel) + return p.is_file() and '__pycache__' not in rel and 'weights' not in rel and not any(part.startswith('.') for part in rel) files = sorted(p for p in TINYGRAD_DIR.rglob('*') if _included(p)) for p in files: h.update(str(p.relative_to(BASEDIR)).encode()) diff --git a/system/hardware/fan_controller.py b/system/hardware/fan_controller.py index 73ee05f..e4560bf 100755 --- a/system/hardware/fan_controller.py +++ b/system/hardware/fan_controller.py @@ -6,7 +6,11 @@ class FanController: def __init__(self) -> None: self.last_ignition = False - def update(self, cur_temp: float, ignition: bool) -> int: + def update(self, cur_temp: float, ignition: bool, max_cool: bool = False) -> int: + if max_cool: + self.last_ignition = ignition + return 100 + if cur_temp < 70.0: fan_pwr_out = 0 elif cur_temp > 85.0: diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index 8a9a7e0..e63186b 100755 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -432,8 +432,6 @@ def hardware_thread(end_event, hw_queue) -> None: all_comp_temp = all_temp_filter.update(max(temp_sources)) msg.deviceState.maxTempC = all_comp_temp - msg.deviceState.fanSpeedPercentDesired = fan_controller.update(all_comp_temp, onroad_conditions["ignition"]) - is_offroad_for_5_min = (started_ts is None) and ((not started_seen) or (off_ts is None) or (time.monotonic() - off_ts > 60 * 5)) if is_offroad_for_5_min and offroad_comp_temp > OFFROAD_DANGER_TEMP: # if device is offroad and already hot without the extra onroad load, @@ -447,6 +445,10 @@ def hardware_thread(end_event, hw_queue) -> None: elif current_band.max_temp is not None and all_comp_temp > current_band.max_temp: thermal_status = list(THERMAL_BANDS.keys())[band_idx + 1] + # the car is running but temperature is blocking the start, so cool as fast as we can + max_cool = (started_ts is None) and onroad_conditions["ignition"] and thermal_status >= ThermalStatus.red + msg.deviceState.fanSpeedPercentDesired = fan_controller.update(all_comp_temp, onroad_conditions["ignition"], max_cool) + # **** starting logic **** startup_conditions["up_to_date"] = True diff --git a/system/hardware/tests/test_fan_controller.py b/system/hardware/tests/test_fan_controller.py index 854564b..5b4fa9b 100644 --- a/system/hardware/tests/test_fan_controller.py +++ b/system/hardware/tests/test_fan_controller.py @@ -41,6 +41,13 @@ class TestFanController: self.wind_up(controller, True) assert controller.update(100, True) == 100 + @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) + def test_max_cool(self, mocker, controller_class): + controller = patched_controller(mocker, controller_class) + self.wind_down(controller) + assert controller.update(80, True, True) == 100 + assert controller.update(80, False, True) == 100 + @pytest.mark.parametrize("controller_class", ALL_CONTROLLERS) def test_windup_speed(self, mocker, controller_class): controller = patched_controller(mocker, controller_class) diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index e1b17c8..cf40ba3 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -85,8 +85,13 @@ def affine_irq(val, action): @lru_cache def get_device_type(): # lru_cache and cache can cause memory leaks when used in classes - with open("/sys/firmware/devicetree/base/model") as f: - model = f.read().strip('\x00') + try: + with open("/sys/firmware/devicetree/base/model") as f: + model = f.read().strip('\x00') + except FileNotFoundError: + # off-device (e.g. the prebuilt build container fakes /TICI but has no + # devicetree); import must not crash. Not a real device type. + return "unknown" return model.split('comma ')[-1] class Tici(HardwareBase): diff --git a/third_party/mapd_pfeiferj/mapd b/third_party/mapd_pfeiferj/mapd index cae2b40..815891c 100755 Binary files a/third_party/mapd_pfeiferj/mapd and b/third_party/mapd_pfeiferj/mapd differ