IQ.Pilot Release Commit @ ab07000
This commit is contained in:
@@ -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=="
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
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)
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
"dmonitoring_model_metadata.pkl": "31a86ab7a92dc0af088b15787a440dd3b210aa662e445a15145900e559a1b5c3",
|
||||
"dmonitoring_model_tinygrad.pkl": "806c0ea75df6bf6dfeb81b832314c68e31df5865a52d0359e6eeb76d93ad2b52"
|
||||
},
|
||||
"signature": "e1eeb5ce45774a816c8da2394e6ee35ebf700b71dff345e0141dbab8ff592349"
|
||||
"signature": "64740782bfd5b1720978aab24a2b1b37c99542f97db3c8637227c7412bb30bbf"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
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):
|
||||
|
||||
BIN
third_party/mapd_pfeiferj/mapd
vendored
BIN
third_party/mapd_pfeiferj/mapd
vendored
Binary file not shown.
Reference in New Issue
Block a user