diff --git a/on-host/Cargo.lock b/on-host/Cargo.lock
index 60e357f7de4b15fef5924d1090740904a68dc210..9f0f7bf2ecbd0cb8e850161bcff85e624ec5c1f0 100644
--- a/on-host/Cargo.lock
+++ b/on-host/Cargo.lock
@@ -4,71 +4,63 @@ version = 3
 
 [[package]]
 name = "addr2line"
-version = "0.21.0"
+version = "0.24.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375"
 dependencies = [
  "gimli",
 ]
 
 [[package]]
-name = "adler"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
-
-[[package]]
-name = "aho-corasick"
-version = "1.1.3"
+name = "adler2"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
-dependencies = [
- "memchr",
-]
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
 
 [[package]]
 name = "anstream"
-version = "0.6.13"
+version = "0.6.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
+checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
 dependencies = [
  "anstyle",
  "anstyle-parse",
  "anstyle-query",
  "anstyle-wincon",
  "colorchoice",
+ "is_terminal_polyfill",
  "utf8parse",
 ]
 
 [[package]]
 name = "anstyle"
-version = "1.0.6"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
 
 [[package]]
 name = "anstyle-parse"
-version = "0.2.3"
+version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
 dependencies = [
  "utf8parse",
 ]
 
 [[package]]
 name = "anstyle-query"
-version = "1.0.2"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
 dependencies = [
  "windows-sys 0.52.0",
 ]
 
 [[package]]
 name = "anstyle-wincon"
-version = "3.0.2"
+version = "3.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
 dependencies = [
  "anstyle",
  "windows-sys 0.52.0",
@@ -82,31 +74,31 @@ dependencies = [
  "csv",
  "log",
  "miette",
+ "serde",
  "serialport",
  "simple_logger",
  "skyward_mavlink",
- "tdl-core",
 ]
 
 [[package]]
 name = "autocfg"
-version = "1.1.0"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
 
 [[package]]
 name = "backtrace"
-version = "0.3.69"
+version = "0.3.74"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
 dependencies = [
  "addr2line",
- "cc",
  "cfg-if",
  "libc",
  "miniz_oxide",
  "object",
  "rustc-demangle",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -118,12 +110,6 @@ dependencies = [
  "backtrace",
 ]
 
-[[package]]
-name = "beef"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1"
-
 [[package]]
 name = "bitflags"
 version = "1.3.2"
@@ -132,9 +118,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.5.0"
+version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
 [[package]]
 name = "byteorder"
@@ -142,12 +128,6 @@ version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
 
-[[package]]
-name = "cc"
-version = "1.0.90"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
-
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -156,9 +136,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "clap"
-version = "4.5.3"
+version = "4.5.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "949626d00e063efc93b6dca932419ceb5432f99769911c0b995f7e884c778813"
+checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3"
 dependencies = [
  "clap_builder",
  "clap_derive",
@@ -166,9 +146,9 @@ dependencies = [
 
 [[package]]
 name = "clap_builder"
-version = "4.5.2"
+version = "4.5.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
+checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b"
 dependencies = [
  "anstream",
  "anstyle",
@@ -178,9 +158,9 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.5.3"
+version = "4.5.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90239a040c80f5e14809ca132ddc4176ab33d5e17e49691793296e3fcb34d72f"
+checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -190,15 +170,15 @@ dependencies = [
 
 [[package]]
 name = "clap_lex"
-version = "0.7.0"
+version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
+checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
 
 [[package]]
 name = "colorchoice"
-version = "1.0.0"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
 
 [[package]]
 name = "colored"
@@ -212,15 +192,15 @@ dependencies = [
 
 [[package]]
 name = "core-foundation-sys"
-version = "0.8.6"
+version = "0.8.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
+checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
 
 [[package]]
 name = "crc-any"
-version = "2.4.4"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c01a5e1f881f6fb6099a7bdf949e946719fd4f1fefa56264890574febf0eb6d0"
+checksum = "a62ec9ff5f7965e4d7280bd5482acd20aadb50d632cf6c1d74493856b011fa73"
 
 [[package]]
 name = "csv"
@@ -254,25 +234,19 @@ dependencies = [
 
 [[package]]
 name = "errno"
-version = "0.3.8"
+version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
 dependencies = [
  "libc",
  "windows-sys 0.52.0",
 ]
 
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
 [[package]]
 name = "gimli"
-version = "0.28.1"
+version = "0.31.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
+checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64"
 
 [[package]]
 name = "heck"
@@ -305,23 +279,29 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
 
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
 [[package]]
 name = "itoa"
-version = "1.0.10"
+version = "1.0.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
+checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
 
 [[package]]
 name = "lazy_static"
-version = "1.4.0"
+version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
 
 [[package]]
 name = "libc"
-version = "0.2.153"
+version = "0.2.159"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
 
 [[package]]
 name = "libudev"
@@ -345,48 +325,15 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.4.13"
+version = "0.4.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
 
 [[package]]
 name = "log"
-version = "0.4.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
-
-[[package]]
-name = "logos"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "161971eb88a0da7ae0c333e1063467c5b5727e7fb6b710b8db4814eade3a42e8"
-dependencies = [
- "logos-derive",
-]
-
-[[package]]
-name = "logos-codegen"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e31badd9de5131fdf4921f6473d457e3dd85b11b7f091ceb50e4df7c3eeb12a"
-dependencies = [
- "beef",
- "fnv",
- "lazy_static",
- "proc-macro2",
- "quote",
- "regex-syntax",
- "syn",
-]
-
-[[package]]
-name = "logos-derive"
-version = "0.14.0"
+version = "0.4.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c2a69b3eb68d5bd595107c9ee58d7e07fe2bb5e360cc85b0f084dedac80de0a"
-dependencies = [
- "logos-codegen",
-]
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
 
 [[package]]
 name = "mach2"
@@ -424,9 +371,9 @@ dependencies = [
 
 [[package]]
 name = "memchr"
-version = "2.7.1"
+version = "2.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
 name = "miette"
@@ -461,11 +408,11 @@ dependencies = [
 
 [[package]]
 name = "miniz_oxide"
-version = "0.7.2"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
+checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
 dependencies = [
- "adler",
+ "adler2",
 ]
 
 [[package]]
@@ -498,9 +445,9 @@ dependencies = [
 
 [[package]]
 name = "num-traits"
-version = "0.2.18"
+version = "0.2.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
 dependencies = [
  "autocfg",
 ]
@@ -516,24 +463,24 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.32.2"
+version = "0.36.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
 name = "owo-colors"
-version = "4.0.0"
+version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f"
+checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.30"
+version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
+checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
 
 [[package]]
 name = "powerfmt"
@@ -543,9 +490,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.79"
+version = "1.0.86"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
 dependencies = [
  "unicode-ident",
 ]
@@ -561,55 +508,26 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.35"
+version = "1.0.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
 dependencies = [
  "proc-macro2",
 ]
 
-[[package]]
-name = "regex"
-version = "1.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-automata",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-automata"
-version = "0.4.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
-dependencies = [
- "aho-corasick",
- "memchr",
- "regex-syntax",
-]
-
-[[package]]
-name = "regex-syntax"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
-
 [[package]]
 name = "rustc-demangle"
-version = "0.1.23"
+version = "0.1.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
 
 [[package]]
 name = "rustix"
-version = "0.38.32"
+version = "0.38.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
+checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
 dependencies = [
- "bitflags 2.5.0",
+ "bitflags 2.6.0",
  "errno",
  "libc",
  "linux-raw-sys",
@@ -618,9 +536,9 @@ dependencies = [
 
 [[package]]
 name = "ryu"
-version = "1.0.17"
+version = "1.0.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
 
 [[package]]
 name = "scopeguard"
@@ -630,9 +548,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
 
 [[package]]
 name = "serde"
-version = "1.0.197"
+version = "1.0.210"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
+checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
 dependencies = [
  "serde_derive",
 ]
@@ -648,9 +566,9 @@ dependencies = [
 
 [[package]]
 name = "serde_derive"
-version = "1.0.197"
+version = "1.0.210"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
+checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -701,18 +619,17 @@ dependencies = [
 
 [[package]]
 name = "serialport"
-version = "4.3.0"
+version = "4.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828"
+checksum = "3ba776acc8c373b9175829206229366273225436845c04f9c20aab8099960e2e"
 dependencies = [
- "bitflags 2.5.0",
+ "bitflags 2.6.0",
  "cfg-if",
  "core-foundation-sys",
  "io-kit-sys",
  "libudev",
  "mach2",
  "nix",
- "regex",
  "scopeguard",
  "unescaper",
  "winapi",
@@ -733,9 +650,9 @@ dependencies = [
 [[package]]
 name = "skyward_mavlink"
 version = "0.1.0"
-source = "git+https://git.skywarder.eu/avn/swd/mavlink/mavlink-skyward-lib.git?branch=main#afdea9432a5844b1591c0fb90c17612cc7ea878c"
+source = "git+https://git.skywarder.eu/avn/swd/mavlink/mavlink-skyward-lib.git?branch=main#7abedf9773b3ebce9d14687d13544f40fad5577f"
 dependencies = [
- "bitflags 2.5.0",
+ "bitflags 2.6.0",
  "mavlink-bindgen",
  "mavlink-core",
  "num-derive",
@@ -752,15 +669,15 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
 
 [[package]]
 name = "strsim"
-version = "0.11.0"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
 name = "supports-color"
-version = "3.0.0"
+version = "3.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9829b314621dfc575df4e409e79f9d6a66a3bd707ab73f23cb4aa3a854ac854f"
+checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77"
 dependencies = [
  "is_ci",
 ]
@@ -779,37 +696,15 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2"
 
 [[package]]
 name = "syn"
-version = "2.0.53"
+version = "2.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
+checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
 dependencies = [
  "proc-macro2",
  "quote",
  "unicode-ident",
 ]
 
-[[package]]
-name = "tdl-core"
-version = "0.1.0"
-source = "git+ssh://git@git.skywarder.eu/federico.lolli/tdl.git?branch=main#487bd1b0373915c8840ae51f283010f78b054d78"
-dependencies = [
- "logos",
- "miette",
- "serde",
- "tdl-private-macros",
- "thiserror",
-]
-
-[[package]]
-name = "tdl-private-macros"
-version = "0.1.0"
-source = "git+ssh://git@git.skywarder.eu/federico.lolli/tdl.git?branch=main#487bd1b0373915c8840ae51f283010f78b054d78"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "terminal_size"
 version = "0.3.0"
@@ -842,18 +737,18 @@ dependencies = [
 
 [[package]]
 name = "thiserror"
-version = "1.0.58"
+version = "1.0.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
+checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.58"
+version = "1.0.64"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
+checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -862,9 +757,9 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.3.34"
+version = "0.3.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
+checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
 dependencies = [
  "deranged",
  "itoa",
@@ -885,9 +780,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
 
 [[package]]
 name = "time-macros"
-version = "0.2.17"
+version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
+checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
 dependencies = [
  "num-conv",
  "time-core",
@@ -895,18 +790,18 @@ dependencies = [
 
 [[package]]
 name = "unescaper"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0adf6ad32eb5b3cadff915f7b770faaac8f7ff0476633aa29eb0d9584d889d34"
+checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815"
 dependencies = [
  "thiserror",
 ]
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.12"
+version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
 
 [[package]]
 name = "unicode-linebreak"
@@ -916,15 +811,15 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
 
 [[package]]
 name = "unicode-width"
-version = "0.1.11"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
 
 [[package]]
 name = "utf8parse"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
 name = "winapi"
@@ -963,7 +858,7 @@ version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
 dependencies = [
- "windows-targets 0.52.4",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
@@ -983,17 +878,18 @@ dependencies = [
 
 [[package]]
 name = "windows-targets"
-version = "0.52.4"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm 0.52.4",
- "windows_aarch64_msvc 0.52.4",
- "windows_i686_gnu 0.52.4",
- "windows_i686_msvc 0.52.4",
- "windows_x86_64_gnu 0.52.4",
- "windows_x86_64_gnullvm 0.52.4",
- "windows_x86_64_msvc 0.52.4",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
 ]
 
 [[package]]
@@ -1004,9 +900,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
 [[package]]
 name = "windows_aarch64_gnullvm"
-version = "0.52.4"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
 [[package]]
 name = "windows_aarch64_msvc"
@@ -1016,9 +912,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
 [[package]]
 name = "windows_aarch64_msvc"
-version = "0.52.4"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
 [[package]]
 name = "windows_i686_gnu"
@@ -1028,9 +924,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
 [[package]]
 name = "windows_i686_gnu"
-version = "0.52.4"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
 [[package]]
 name = "windows_i686_msvc"
@@ -1040,9 +942,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
 [[package]]
 name = "windows_i686_msvc"
-version = "0.52.4"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
 [[package]]
 name = "windows_x86_64_gnu"
@@ -1052,9 +954,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
 [[package]]
 name = "windows_x86_64_gnu"
-version = "0.52.4"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
@@ -1064,9 +966,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
 [[package]]
 name = "windows_x86_64_gnullvm"
-version = "0.52.4"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
 [[package]]
 name = "windows_x86_64_msvc"
@@ -1076,6 +978,6 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 
 [[package]]
 name = "windows_x86_64_msvc"
-version = "0.52.4"
+version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/on-host/Cargo.toml b/on-host/Cargo.toml
index c114893e1a322b6da060c6cd9293f050acc32034..6b93b1d545675c9d2c4d3ce414a041b479851057 100644
--- a/on-host/Cargo.toml
+++ b/on-host/Cargo.toml
@@ -12,17 +12,18 @@ csv = "1.3.0"
 log = "0.4.20"
 serialport = "4.3.0"
 simple_logger = { version = "4.3.3", features = ["colors"] }
+serde = { version = "1.0.210", features = ["derive"] }
 
 [dependencies.skyward_mavlink]
 git = "https://git.skywarder.eu/avn/swd/mavlink/mavlink-skyward-lib.git"
 branch = "main"
 features = ["serde", "lyra"]
 
-[dependencies.tdl-core]
-git = "ssh://git@git.skywarder.eu/federico.lolli/tdl.git"
-branch = "main"
-optional = true
+# [dependencies.tdl-core]
+# git = "ssh://git@git.skywarder.eu/federico.lolli/tdl.git"
+# branch = "main"
+# optional = true
 
 [features]
 default = []
-tdl = ["dep:tdl-core"]
+# tdl = ["dep:tdl-core"]
diff --git a/on-host/src/cli.rs b/on-host/src/cli.rs
index a782b74f51ea2dcd263499540310357994e34b33..53b8f94e1c3f63ade55296e0c26aae359180c2fc 100644
--- a/on-host/src/cli.rs
+++ b/on-host/src/cli.rs
@@ -8,14 +8,35 @@ use clap::{
     Parser,
 };
 
-#[cfg(feature = "tdl")]
+// #[cfg(feature = "tdl")]
+// #[derive(Debug, Parser)]
+// #[command(styles=get_styles())]
+// pub struct Cli {
+//     /// The mode to use
+//     #[clap(subcommand)]
+//     pub mode: ModeFile,
+
+//     /// The serial port to use
+//     #[clap(short, long, value_name = "PORT")]
+//     pub port: Option<String>,
+
+//     /// baud rate
+//     #[clap(short, long, default_value = "115200")]
+//     pub baud_rate: u32,
+
+//     /// disable SYNC MODE (wait for a sync signal from the device before proceding)
+//     #[clap(short, long)]
+//     pub no_sync: bool,
+
+//     /// The log level
+//     #[clap(short, long)]
+//     pub verbose: bool,
+// }
+
+// #[cfg(not(feature = "tdl"))]
 #[derive(Debug, Parser)]
 #[command(styles=get_styles())]
 pub struct Cli {
-    /// The mode to use
-    #[clap(subcommand)]
-    pub mode: ModeFile,
-
     /// The serial port to use
     #[clap(short, long, value_name = "PORT")]
     pub port: Option<String>,
@@ -28,63 +49,46 @@ pub struct Cli {
     #[clap(short, long)]
     pub no_sync: bool,
 
-    /// The log level
-    #[clap(short, long)]
-    pub verbose: bool,
-}
+    /// The low rate telemetry CSV file to read from
+    #[clap(value_name = "LOW_RATE_FILE")]
+    pub low_rate_file: PathBuf,
 
-#[cfg(not(feature = "tdl"))]
-#[derive(Debug, Parser)]
-#[command(styles=get_styles())]
-pub struct Cli {
-    /// The serial port to use
-    #[clap(short, long, value_name = "PORT")]
-    pub port: Option<String>,
-
-    /// baud rate
-    #[clap(short, long, default_value = "115200")]
-    pub baud_rate: u32,
-
-    /// disable SYNC MODE (wait for a sync signal from the device before proceding)
-    #[clap(short, long)]
-    pub no_sync: bool,
-
-    /// The CSV file to read from
-    //#[clap(value_name = "CSV_FILE")]
-    pub csv_file: PathBuf,
+    /// The high rate telemetry CSV file to read from
+    #[clap(value_name = "HIGH_RATE_FILE")]
+    pub high_rate_file: PathBuf,
 
     /// The log level
     #[clap(short, long)]
     pub verbose: bool,
 }
 
-#[cfg(feature = "tdl")]
-#[derive(Debug, Parser)]
-pub enum ModeFile {
-    /// build mavlink packets from a TDL file
-    Tdl {
-        /// The TDL file to read from
-        tdl_file: PathBuf,
-
-        /// initial GPS latitude
-        #[clap(short = 'n', long, value_name = "LAT")]
-        lat: f64,
-
-        /// initial GPS longitude
-        #[clap(short = 'e', long, value_name = "LON")]
-        lon: f64,
-
-        /// initial GPS altitude
-        #[clap(short = 'u', long, value_name = "ALT")]
-        alt: f64,
-    },
-
-    /// parse mavlink packets from a CSV file
-    Csv {
-        /// The CSV file to read from
-        csv_file: PathBuf,
-    },
-}
+// #[cfg(feature = "tdl")]
+// #[derive(Debug, Parser)]
+// pub enum ModeFile {
+//     /// build mavlink packets from a TDL file
+//     Tdl {
+//         /// The TDL file to read from
+//         tdl_file: PathBuf,
+
+//         /// initial GPS latitude
+//         #[clap(short = 'n', long, value_name = "LAT")]
+//         lat: f64,
+
+//         /// initial GPS longitude
+//         #[clap(short = 'e', long, value_name = "LON")]
+//         lon: f64,
+
+//         /// initial GPS altitude
+//         #[clap(short = 'u', long, value_name = "ALT")]
+//         alt: f64,
+//     },
+
+//     /// parse mavlink packets from a CSV file
+//     Csv {
+//         /// The CSV file to read from
+//         csv_file: PathBuf,
+//     },
+// }
 
 pub fn get_styles() -> Styles {
     Styles::styled()
diff --git a/on-host/src/csv.rs b/on-host/src/csv.rs
deleted file mode 100644
index 4595661078866c6a6d4f4cd9a457875ca7868b5b..0000000000000000000000000000000000000000
--- a/on-host/src/csv.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use std::io::Read;
-
-use skyward_mavlink::lyra::MavMessage;
-
-/// Read PAYLOAD_FLIGHT_TM messages from a CSV file
-pub fn read_packets_from_csv(csv_reader: impl Read) -> std::io::Result<Vec<MavMessage>> {
-    let mut packets = Vec::new();
-    let mut rdr = csv::Reader::from_reader(csv_reader);
-    for result in rdr.deserialize() {
-        packets.push(MavMessage::ROCKET_FLIGHT_TM(result?));
-    }
-    Ok(packets)
-}
diff --git a/on-host/src/main.rs b/on-host/src/main.rs
index 74caf9839a1317a177d39b694e119eb70340851b..ce76fa676efdee0aeaca7648a12d0df1405e0dce 100644
--- a/on-host/src/main.rs
+++ b/on-host/src/main.rs
@@ -1,8 +1,8 @@
 mod cli;
-mod csv;
 mod packet;
-#[cfg(feature = "tdl")]
-mod tdl;
+// #[cfg(feature = "tdl")]
+// mod tdl;
+mod tm;
 mod utils;
 
 use std::{
@@ -14,17 +14,18 @@ use std::{
 use clap::Parser;
 use log::{debug, error, info};
 use miette::{Context, IntoDiagnostic, Result};
+use packet::TimedMessage;
 use serialport::SerialPort;
 use skyward_mavlink::{
     lyra::MavMessage,
     mavlink::{write_v1_msg, MavHeader},
 };
+use tm::{read_high_rate_telemetry, read_low_rate_telemetry};
 
-#[cfg(feature = "tdl")]
-use crate::cli::ModeFile;
+// #[cfg(feature = "tdl")]
+// use crate::cli::ModeFile;
 use crate::{
     cli::Cli,
-    csv::read_packets_from_csv,
     packet::PacketSequence,
     utils::{get_first_stm32_serial_port, print_stats},
 };
@@ -107,32 +108,42 @@ fn main() -> Result<()> {
     Ok(())
 }
 
-#[cfg(feature = "tdl")]
-fn get_packets(args: &Cli) -> Result<Vec<MavMessage>> {
-    let packets: Vec<MavMessage> = match &args.mode {
-        ModeFile::Csv { csv_file } => {
-            info!("reading from csv file {}", csv_file.display());
-            read_packets_from_csv(File::open(csv_file).into_diagnostic()?).into_diagnostic()?
-        }
-        ModeFile::Tdl {
-            tdl_file,
-            lat,
-            lon,
-            alt,
-        } => {
-            info!("reading from tdl file {}", tdl_file.display());
-            tdl::generate_packets_from_tdl(tdl_file, *lat, *lon, *alt)?
-        }
-    };
-    debug!("collected {} packets", packets.len());
-    Ok(packets)
-}
-
-#[cfg(not(feature = "tdl"))]
-fn get_packets(args: &Cli) -> Result<Vec<MavMessage>> {
-    info!("reading from csv file {}", args.csv_file.display());
-    let packets =
-        read_packets_from_csv(File::open(&args.csv_file).into_diagnostic()?).into_diagnostic()?;
+// #[cfg(feature = "tdl")]
+// fn get_packets(args: &Cli) -> Result<Vec<MavMessage>> {
+//     let packets: Vec<MavMessage> = match &args.mode {
+//         ModeFile::Csv { csv_file } => {
+//             info!("reading from csv file {}", csv_file.display());
+//             read_packets_from_csv(File::open(csv_file).into_diagnostic()?).into_diagnostic()?
+//         }
+//         ModeFile::Tdl {
+//             tdl_file,
+//             lat,
+//             lon,
+//             alt,
+//         } => {
+//             info!("reading from tdl file {}", tdl_file.display());
+//             tdl::generate_packets_from_tdl(tdl_file, *lat, *lon, *alt)?
+//         }
+//     };
+//     debug!("collected {} packets", packets.len());
+//     Ok(packets)
+// }
+
+// #[cfg(not(feature = "tdl"))]
+fn get_packets(args: &Cli) -> Result<Vec<TimedMessage>> {
+    info!(
+        "reading low rate telemetry from file {}",
+        args.low_rate_file.display()
+    );
+    info!(
+        "reading high rate telemetry from file {}",
+        args.high_rate_file.display()
+    );
+    let lrtf = File::open(&args.low_rate_file).into_diagnostic()?;
+    let hrtf = File::open(&args.high_rate_file).into_diagnostic()?;
+    let mut packets = read_low_rate_telemetry(lrtf).into_diagnostic()?;
+    packets.extend(read_high_rate_telemetry(hrtf).into_diagnostic()?);
+    packets.sort();
     debug!("collected {} packets", packets.len());
     Ok(packets)
 }
diff --git a/on-host/src/packet.rs b/on-host/src/packet.rs
index 3300b3aa7dd082a95e6bd11f48a84c004e125931..3d4a945282c3cfa64a7f52ceb5430d4e050ddb1e 100644
--- a/on-host/src/packet.rs
+++ b/on-host/src/packet.rs
@@ -1,32 +1,43 @@
 use std::time::{Duration, Instant};
 
-use skyward_mavlink::{lyra::MavMessage, mavlink::Message};
+use skyward_mavlink::lyra::MavMessage;
 
-pub trait TimedMessage: Message {
-    fn timestamp(&self) -> Option<u64>;
+#[derive(Debug, Clone, PartialEq)]
+pub struct TimedMessage {
+    timestamp: u64,
+    msg: MavMessage,
 }
 
-impl TimedMessage for MavMessage {
-    fn timestamp(&self) -> Option<u64> {
-        match self {
-            MavMessage::PAYLOAD_FLIGHT_TM(data) => Some(data.timestamp),
-            MavMessage::ROCKET_FLIGHT_TM(data) => Some(data.timestamp),
-            MavMessage::ACK_TM(_) => None,
-            _ => None,
-        }
+impl PartialOrd for TimedMessage {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Eq for TimedMessage {}
+
+impl Ord for TimedMessage {
+    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+        self.timestamp.cmp(&other.timestamp)
+    }
+}
+
+impl TimedMessage {
+    pub fn new(timestamp: u64, msg: MavMessage) -> Self {
+        Self { timestamp, msg }
     }
 }
 
 pub struct PacketSequence {
-    packets: Vec<MavMessage>,
+    packets: Vec<TimedMessage>,
     index: usize,
     delta_from_start: u64,
     start_instant: Option<Instant>,
 }
 
-impl From<Vec<MavMessage>> for PacketSequence {
-    fn from(value: Vec<MavMessage>) -> Self {
-        let delta_from_start = value[0].timestamp().unwrap();
+impl From<Vec<TimedMessage>> for PacketSequence {
+    fn from(value: Vec<TimedMessage>) -> Self {
+        let delta_from_start = value[0].timestamp;
         Self {
             packets: value,
             index: 0,
@@ -52,7 +63,7 @@ impl PacketSequence {
         }
 
         // get time delta from the start
-        let next_timestamp = self.packets[self.index].timestamp().unwrap();
+        let next_timestamp = self.packets[self.index].timestamp;
         let time_delta = next_timestamp - self.delta_from_start;
 
         // get the instant the first packet was sent or set it if it's the first packet
@@ -67,6 +78,6 @@ impl PacketSequence {
             self.start_instant = Some(Instant::now());
         }
         self.index += 1;
-        self.packets.get(self.index - 1)
+        self.packets.get(self.index - 1).map(|x| &x.msg)
     }
 }
diff --git a/on-host/src/tm.rs b/on-host/src/tm.rs
new file mode 100644
index 0000000000000000000000000000000000000000..86abc2466f88d0a48bba7aa2470781b7769e6787
--- /dev/null
+++ b/on-host/src/tm.rs
@@ -0,0 +1,65 @@
+use std::io::{Read, Result};
+
+use serde::Deserialize;
+use skyward_mavlink::lyra::{MavMessage, ROCKET_FLIGHT_TM_DATA, ROCKET_STATS_TM_DATA};
+
+use crate::packet::TimedMessage;
+
+#[derive(Debug, Deserialize)]
+struct Lrtm {
+    timestamp: u64,
+    latitude: f64,
+    longitude: f64,
+    altitude: f64,
+}
+
+#[derive(Debug, Deserialize)]
+struct Hrtm {
+    timestamp: u64,
+    n: f64,
+    e: f64,
+    d: f64,
+    vn: f64,
+    ve: f64,
+    vd: f64,
+}
+
+/// Read low rate telemetry data from a CSV file
+pub fn read_low_rate_telemetry(reader: impl Read) -> Result<Vec<TimedMessage>> {
+    let mut packets = Vec::new();
+    let mut rdr = csv::Reader::from_reader(reader);
+    for result in rdr.deserialize() {
+        let r: Lrtm = result?;
+        let msg_data = ROCKET_STATS_TM_DATA {
+            ref_lat: r.latitude as f32,
+            ref_lon: r.longitude as f32,
+            ref_alt: r.altitude as f32,
+            ..Default::default()
+        };
+        let mav_msg = MavMessage::ROCKET_STATS_TM(msg_data);
+        packets.push(TimedMessage::new(r.timestamp, mav_msg));
+    }
+    Ok(packets)
+}
+
+/// Read high rate telemtry data from a CSV file
+pub fn read_high_rate_telemetry(reader: impl Read) -> Result<Vec<TimedMessage>> {
+    let mut packets = Vec::new();
+    let mut rdr = csv::Reader::from_reader(reader);
+    for result in rdr.deserialize() {
+        let r: Hrtm = result?;
+        let msg_data = ROCKET_FLIGHT_TM_DATA {
+            timestamp: r.timestamp,
+            nas_n: r.n as f32,
+            nas_e: r.e as f32,
+            nas_d: r.d as f32,
+            nas_vn: r.vn as f32,
+            nas_ve: r.ve as f32,
+            nas_vd: r.vd as f32,
+            ..Default::default()
+        };
+        let mav_msg = MavMessage::ROCKET_FLIGHT_TM(msg_data);
+        packets.push(TimedMessage::new(r.timestamp, mav_msg));
+    }
+    Ok(packets)
+}