Licklider Transmission Protocol (CCSDS 734.1-B) for reliable DTN links
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

irmin: flatten Schema API — remove Struct/Map/Repr submodules

-564
-19
test/interop/python/dune
··· 1 - (test 2 - (name test) 3 - (libraries ltp csvt alcotest) 4 - (deps 5 - (source_tree traces) 6 - (source_tree scripts))) 7 - 8 - ; Regenerate traces: REGEN_TRACES=1 dune build @regen-traces 9 - 10 - (rule 11 - (alias regen-traces) 12 - (enabled_if 13 - (= %{env:REGEN_TRACES=0} 1)) 14 - (deps 15 - (source_tree scripts)) 16 - (action 17 - (chdir 18 - scripts 19 - (run ./generate.sh))))
-268
test/interop/python/scripts/generate.py
··· 1 - #!/usr/bin/env python3 2 - """Generate LTP interop traces for ocaml-ltp. 3 - 4 - Oracle: Python (no deps needed -- pure RFC implementation) 5 - Install: no dependencies 6 - 7 - Tests SDNV encoding (RFC 6256) and LTP segment encoding (RFC 5326). 8 - 9 - SDNV encoding (RFC 6256): MSB continuation bit (1=more, 0=last), 10 - 7 payload bits per byte, big-endian. 11 - 12 - LTP segment format (RFC 5326 Section 3): 13 - - Control byte: version(4 high bits) | type_code(4 low bits) 14 - - Session ID: originator(SDNV) + session_number(SDNV) 15 - - Extension counts: hdr_count(4 high) | trl_count(4 low) 16 - - Header extensions (if any) 17 - - Content (depends on segment type) 18 - - Trailer extensions (if any) 19 - 20 - Traces are committed to git. Only re-run when changing inputs 21 - or upgrading the oracle. 22 - """ 23 - import os 24 - import sys 25 - import struct 26 - 27 - 28 - # {1 SDNV codec (RFC 6256)} 29 - 30 - def encode_sdnv(n): 31 - """Encode a non-negative integer as an SDNV (RFC 6256).""" 32 - if n == 0: 33 - return b'\x00' 34 - result = [] 35 - while n > 0: 36 - result.append(n & 0x7F) 37 - n >>= 7 38 - result.reverse() 39 - for i in range(len(result) - 1): 40 - result[i] |= 0x80 41 - return bytes(result) 42 - 43 - 44 - def decode_sdnv(buf, off=0): 45 - """Decode an SDNV from buf at offset. Returns (value, new_offset).""" 46 - value = 0 47 - while off < len(buf): 48 - byte = buf[off] 49 - value = (value << 7) | (byte & 0x7F) 50 - off += 1 51 - if byte & 0x80 == 0: 52 - return value, off 53 - raise ValueError("truncated SDNV") 54 - 55 - 56 - # {1 LTP segment builder (RFC 5326)} 57 - 58 - # Segment type codes 59 - TYPE_RED_DATA = 0 60 - TYPE_RED_CHECKPOINT = 1 61 - TYPE_RED_CHECKPOINT_EORP = 2 62 - TYPE_RED_CHECKPOINT_EORP_EOB = 3 63 - TYPE_GREEN_DATA = 4 64 - TYPE_GREEN_EOB = 7 65 - TYPE_REPORT = 8 66 - TYPE_REPORT_ACK = 9 67 - TYPE_CANCEL_FROM_SENDER = 12 68 - TYPE_CANCEL_ACK_TO_SENDER = 13 69 - TYPE_CANCEL_FROM_RECEIVER = 14 70 - TYPE_CANCEL_ACK_TO_RECEIVER = 15 71 - 72 - 73 - def encode_nibbles(high, low): 74 - """Encode two 4-bit values into a single byte.""" 75 - return bytes([(high & 0x0F) << 4 | (low & 0x0F)]) 76 - 77 - 78 - def encode_extension(tag, value): 79 - """Encode a single LTP extension TLV.""" 80 - return bytes([tag]) + encode_sdnv(len(value)) + value 81 - 82 - 83 - def encode_segment(type_code, originator, session_number, 84 - content, header_exts=None, trailer_exts=None): 85 - """Build a complete LTP segment.""" 86 - header_exts = header_exts or [] 87 - trailer_exts = trailer_exts or [] 88 - 89 - buf = bytearray() 90 - # Control byte: version 0 | type_code 91 - buf += encode_nibbles(0, type_code) 92 - # Session ID 93 - buf += encode_sdnv(originator) 94 - buf += encode_sdnv(session_number) 95 - # Extension counts 96 - buf += encode_nibbles(len(header_exts), len(trailer_exts)) 97 - # Header extensions 98 - for tag, val_ in header_exts: 99 - buf += encode_extension(tag, val_) 100 - # Content 101 - buf += content 102 - # Trailer extensions 103 - for tag, val_ in trailer_exts: 104 - buf += encode_extension(tag, val_) 105 - 106 - return bytes(buf) 107 - 108 - 109 - def encode_data_content(client_service_id, block_offset, data, 110 - checkpoint_serial=None, report_serial=None): 111 - """Encode data segment content (RFC 5326 Section 3.2.1).""" 112 - buf = bytearray() 113 - buf += encode_sdnv(client_service_id) 114 - buf += encode_sdnv(block_offset) 115 - buf += encode_sdnv(len(data)) 116 - if checkpoint_serial is not None: 117 - buf += encode_sdnv(checkpoint_serial) 118 - buf += encode_sdnv(report_serial if report_serial is not None else 0) 119 - buf += data 120 - return bytes(buf) 121 - 122 - 123 - def encode_report_content(report_serial, checkpoint_serial, 124 - upper_bound, lower_bound, claims): 125 - """Encode report segment content (RFC 5326 Section 3.2.4).""" 126 - buf = bytearray() 127 - buf += encode_sdnv(report_serial) 128 - buf += encode_sdnv(checkpoint_serial) 129 - buf += encode_sdnv(upper_bound) 130 - buf += encode_sdnv(lower_bound) 131 - buf += encode_sdnv(len(claims)) 132 - for offset, length in claims: 133 - buf += encode_sdnv(offset) 134 - buf += encode_sdnv(length) 135 - return bytes(buf) 136 - 137 - 138 - def encode_report_ack_content(report_serial): 139 - """Encode report ack content.""" 140 - return encode_sdnv(report_serial) 141 - 142 - 143 - def encode_cancel_content(reason_code): 144 - """Encode cancel segment content (single byte reason code).""" 145 - return bytes([reason_code]) 146 - 147 - 148 - # {1 SDNV test vectors} 149 - 150 - sdnv_vectors = [ 151 - ("zero", 0), 152 - ("one", 1), 153 - ("max_single_byte", 127), 154 - ("min_two_byte", 128), 155 - ("byte_255", 255), 156 - ("byte_256", 256), 157 - ("max_two_byte", 16383), 158 - ("min_three_byte", 16384), 159 - ("medium", 1000000), 160 - ("uint32_max", 2**32 - 1), 161 - ("large_40bit", 0x1234567890), 162 - ("int64_max", 2**63 - 1), 163 - ] 164 - 165 - 166 - # {1 LTP segment test vectors} 167 - 168 - def make_segment_vectors(): 169 - vectors = [] 170 - 171 - # Green data segment (type 4) 172 - payload = b"Hello, LTP!" 173 - content = encode_data_content(1, 0, payload) 174 - seg = encode_segment(TYPE_GREEN_DATA, 10, 1000, content) 175 - vectors.append(("green_data_simple", seg)) 176 - 177 - # Green EOB (type 7) 178 - payload = b"\xde\xad\xbe\xef" 179 - content = encode_data_content(2, 512, payload) 180 - seg = encode_segment(TYPE_GREEN_EOB, 42, 99, content) 181 - vectors.append(("green_eob", seg)) 182 - 183 - # Red checkpoint (type 1) 184 - payload = b"checkpoint data" 185 - content = encode_data_content(1, 0, payload, 186 - checkpoint_serial=5, report_serial=0) 187 - seg = encode_segment(TYPE_RED_CHECKPOINT, 1, 100, content) 188 - vectors.append(("red_checkpoint", seg)) 189 - 190 - # Red checkpoint EORP+EOB (type 3) 191 - payload = b"final red" 192 - content = encode_data_content(3, 256, payload, 193 - checkpoint_serial=10, report_serial=2) 194 - seg = encode_segment(TYPE_RED_CHECKPOINT_EORP_EOB, 1, 200, content) 195 - vectors.append(("red_checkpoint_eorp_eob", seg)) 196 - 197 - # Report segment (type 8) with claims 198 - content = encode_report_content( 199 - report_serial=7, 200 - checkpoint_serial=5, 201 - upper_bound=1024, 202 - lower_bound=0, 203 - claims=[(0, 512), (600, 200)] 204 - ) 205 - seg = encode_segment(TYPE_REPORT, 1, 100, content) 206 - vectors.append(("report_two_claims", seg)) 207 - 208 - # Report segment with single claim, large offsets 209 - content = encode_report_content( 210 - report_serial=1, 211 - checkpoint_serial=1, 212 - upper_bound=100000, 213 - lower_bound=50000, 214 - claims=[(50000, 50000)] 215 - ) 216 - seg = encode_segment(TYPE_REPORT, 99, 5555, content) 217 - vectors.append(("report_large_offsets", seg)) 218 - 219 - # Report ack (type 9) 220 - content = encode_report_ack_content(7) 221 - seg = encode_segment(TYPE_REPORT_ACK, 1, 100, content) 222 - vectors.append(("report_ack", seg)) 223 - 224 - # Cancel from sender (type 12), reason=Rlexc (2) 225 - content = encode_cancel_content(2) 226 - seg = encode_segment(TYPE_CANCEL_FROM_SENDER, 1, 100, content) 227 - vectors.append(("cancel_sender_rlexc", seg)) 228 - 229 - # Cancel from receiver (type 14), reason=User_cancelled (0) 230 - content = encode_cancel_content(0) 231 - seg = encode_segment(TYPE_CANCEL_FROM_RECEIVER, 5, 42, content) 232 - vectors.append(("cancel_receiver_user", seg)) 233 - 234 - # Cancel ack to sender (type 13) 235 - seg = encode_segment(TYPE_CANCEL_ACK_TO_SENDER, 1, 100, b"") 236 - vectors.append(("cancel_ack_to_sender", seg)) 237 - 238 - # Cancel ack to receiver (type 15) 239 - seg = encode_segment(TYPE_CANCEL_ACK_TO_RECEIVER, 5, 42, b"") 240 - vectors.append(("cancel_ack_to_receiver", seg)) 241 - 242 - return vectors 243 - 244 - 245 - # {1 Main} 246 - 247 - def main(): 248 - trace_dir = os.path.join(os.path.dirname(__file__), "..", "traces") 249 - os.makedirs(trace_dir, exist_ok=True) 250 - 251 - # Write SDNV traces 252 - with open(os.path.join(trace_dir, "sdnv.csv"), "w") as f: 253 - f.write("name,value,encoded_hex\n") 254 - for name, value in sdnv_vectors: 255 - encoded = encode_sdnv(value) 256 - f.write(f"{name},{value},{encoded.hex()}\n") 257 - print(f"Wrote {trace_dir}/sdnv.csv") 258 - 259 - # Write segment traces 260 - with open(os.path.join(trace_dir, "segments.csv"), "w") as f: 261 - f.write("name,segment_hex\n") 262 - for name, seg_bytes in make_segment_vectors(): 263 - f.write(f"{name},{seg_bytes.hex()}\n") 264 - print(f"Wrote {trace_dir}/segments.csv") 265 - 266 - 267 - if __name__ == "__main__": 268 - main()
-6
test/interop/python/scripts/generate.sh
··· 1 - #!/bin/bash 2 - set -euo pipefail 3 - SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 4 - 5 - cd "$SCRIPT_DIR" 6 - python3 generate.py
-246
test/interop/python/test.ml
··· 1 - (** Python interop tests for ocaml-ltp. 2 - 3 - Tests SDNV encoding (RFC 6256) and LTP segment encoding (RFC 5326) 4 - against a Python reference implementation. 5 - 6 - Traces generated by: Python (pure RFC 6256 / RFC 5326 implementation) 7 - Regenerate: REGEN_TRACES=1 dune build @regen-traces *) 8 - 9 - let trace path = Filename.concat "traces" path 10 - 11 - (* {1 Hex Helpers} *) 12 - 13 - let hex_to_string hex = 14 - let len = String.length hex / 2 in 15 - String.init len (fun i -> 16 - let digit c = 17 - if c >= '0' && c <= '9' then Char.code c - Char.code '0' 18 - else if c >= 'a' && c <= 'f' then Char.code c - Char.code 'a' + 10 19 - else Char.code c - Char.code 'A' + 10 20 - in 21 - Char.chr ((digit hex.[i * 2] lsl 4) lor digit hex.[(i * 2) + 1])) 22 - 23 - let string_to_hex s = 24 - let buf = Buffer.create (String.length s * 2) in 25 - String.iter 26 - (fun c -> Buffer.add_string buf (Printf.sprintf "%02x" (Char.code c))) 27 - s; 28 - Buffer.contents buf 29 - 30 - (* {1 SDNV Trace Type} *) 31 - 32 - type sdnv_row = { name : string; value : string; encoded_hex : string } 33 - 34 - let sdnv_codec = 35 - Csvt.( 36 - Row.( 37 - obj (fun name value encoded_hex -> { name; value; encoded_hex }) 38 - |> col "name" string ~enc:(fun r -> r.name) 39 - |> col "value" string ~enc:(fun r -> r.value) 40 - |> col "encoded_hex" string ~enc:(fun r -> r.encoded_hex))) 41 - 42 - let sdnv_codec = Csvt.Row.finish sdnv_codec 43 - 44 - (* {1 Segment Trace Type} *) 45 - 46 - type segment_row = { name : string; segment_hex : string } 47 - 48 - let segment_codec = 49 - Csvt.( 50 - Row.( 51 - obj (fun name segment_hex -> { name; segment_hex }) 52 - |> col "name" string ~enc:(fun r -> r.name) 53 - |> col "segment_hex" string ~enc:(fun r -> r.segment_hex) 54 - |> finish)) 55 - 56 - (* {1 SDNV Tests} *) 57 - 58 - let load_sdnv_rows () = 59 - match Csvt.decode_file sdnv_codec (trace "sdnv.csv") with 60 - | Ok rows -> rows 61 - | Error e -> Alcotest.failf "CSV decode: %a" Csvt.pp_error e 62 - 63 - let test_sdnv_encode row () = 64 - let value = Int64.of_string row.value in 65 - let encoded = Ltp.encode_sdnv value in 66 - let got_hex = string_to_hex encoded in 67 - Alcotest.(check string) (row.name ^ ": encode") row.encoded_hex got_hex 68 - 69 - let test_sdnv_decode row () = 70 - let ref_bytes = hex_to_string row.encoded_hex in 71 - match Ltp.decode_sdnv ref_bytes 0 with 72 - | Error e -> Alcotest.failf "%s: decode failed: %s" row.name e 73 - | Ok (decoded, off) -> 74 - let expected = Int64.of_string row.value in 75 - Alcotest.(check int64) (row.name ^ ": value") expected decoded; 76 - Alcotest.(check int) 77 - (row.name ^ ": consumed all bytes") 78 - (String.length ref_bytes) off 79 - 80 - (* {1 Segment Tests} *) 81 - 82 - let load_segment_rows () = 83 - match Csvt.decode_file segment_codec (trace "segments.csv") with 84 - | Ok rows -> rows 85 - | Error e -> Alcotest.failf "CSV decode: %a" Csvt.pp_error e 86 - 87 - let test_segment_decode row () = 88 - let ref_bytes = hex_to_string row.segment_hex in 89 - match Ltp.decode_segment ref_bytes with 90 - | Error e -> Alcotest.failf "%s: decode failed: %a" row.name Ltp.pp_error e 91 - | Ok seg -> 92 - (* Re-encode and compare to reference *) 93 - let re_encoded = Ltp.encode_segment seg in 94 - let got_hex = string_to_hex re_encoded in 95 - Alcotest.(check string) 96 - (row.name ^ ": decode-reencode roundtrip") 97 - row.segment_hex got_hex 98 - 99 - let test_segment_encode row () = 100 - (* Decode the reference to get the segment, then encode and compare *) 101 - let ref_bytes = hex_to_string row.segment_hex in 102 - match Ltp.decode_segment ref_bytes with 103 - | Error e -> Alcotest.failf "%s: decode failed: %a" row.name Ltp.pp_error e 104 - | Ok seg -> 105 - let encoded = Ltp.encode_segment seg in 106 - let got_hex = string_to_hex encoded in 107 - Alcotest.(check string) 108 - (row.name ^ ": encode exact bytes") 109 - row.segment_hex got_hex 110 - 111 - let test_segment_fields row () = 112 - let ref_bytes = hex_to_string row.segment_hex in 113 - match Ltp.decode_segment ref_bytes with 114 - | Error e -> Alcotest.failf "%s: decode failed: %a" row.name Ltp.pp_error e 115 - | Ok seg -> ( 116 - (* Verify key fields based on test vector name *) 117 - match row.name with 118 - | "green_data_simple" -> ( 119 - Alcotest.(check bool) "is green" true (Ltp.is_green_segment seg); 120 - Alcotest.(check int64) "originator" 10L seg.session_id.originator; 121 - Alcotest.(check int64) "session number" 1000L seg.session_id.number; 122 - match seg.content with 123 - | Ltp.Data ds -> 124 - Alcotest.(check int64) "client_service_id" 1L ds.client_service_id; 125 - Alcotest.(check int64) "block_offset" 0L ds.block_offset; 126 - Alcotest.(check string) "data" "Hello, LTP!" ds.data 127 - | _ -> Alcotest.fail "expected Data content") 128 - | "green_eob" -> ( 129 - Alcotest.(check bool) "is eob" true (Ltp.is_eob seg); 130 - Alcotest.(check bool) "is green" true (Ltp.is_green_segment seg); 131 - match seg.content with 132 - | Ltp.Data ds -> 133 - Alcotest.(check int64) "block_offset" 512L ds.block_offset 134 - | _ -> Alcotest.fail "expected Data content") 135 - | "red_checkpoint" -> ( 136 - Alcotest.(check bool) "is checkpoint" true (Ltp.is_checkpoint seg); 137 - Alcotest.(check bool) "is red" true (Ltp.is_red_segment seg); 138 - match seg.content with 139 - | Ltp.Data ds -> 140 - Alcotest.(check (option int64)) 141 - "checkpoint_serial" (Some 5L) ds.checkpoint_serial; 142 - Alcotest.(check (option int64)) 143 - "report_serial" (Some 0L) ds.report_serial; 144 - Alcotest.(check string) "data" "checkpoint data" ds.data 145 - | _ -> Alcotest.fail "expected Data content") 146 - | "red_checkpoint_eorp_eob" -> ( 147 - Alcotest.(check bool) "is eorp" true (Ltp.is_eorp seg); 148 - Alcotest.(check bool) "is eob" true (Ltp.is_eob seg); 149 - match seg.content with 150 - | Ltp.Data ds -> 151 - Alcotest.(check int64) "block_offset" 256L ds.block_offset; 152 - Alcotest.(check (option int64)) 153 - "checkpoint_serial" (Some 10L) ds.checkpoint_serial; 154 - Alcotest.(check (option int64)) 155 - "report_serial" (Some 2L) ds.report_serial; 156 - Alcotest.(check string) "data" "final red" ds.data 157 - | _ -> Alcotest.fail "expected Data content") 158 - | "report_two_claims" -> ( 159 - match seg.content with 160 - | Ltp.Report rs -> 161 - Alcotest.(check int64) "report_serial" 7L rs.report_serial; 162 - Alcotest.(check int64) "checkpoint_serial" 5L rs.checkpoint_serial; 163 - Alcotest.(check int64) "upper_bound" 1024L rs.upper_bound; 164 - Alcotest.(check int64) "lower_bound" 0L rs.lower_bound; 165 - Alcotest.(check int) "claims" 2 (List.length rs.claims); 166 - let c0 = List.nth rs.claims 0 in 167 - Alcotest.(check int64) "claim0.offset" 0L c0.offset; 168 - Alcotest.(check int64) "claim0.length" 512L c0.length; 169 - let c1 = List.nth rs.claims 1 in 170 - Alcotest.(check int64) "claim1.offset" 600L c1.offset; 171 - Alcotest.(check int64) "claim1.length" 200L c1.length 172 - | _ -> Alcotest.fail "expected Report content") 173 - | "report_large_offsets" -> ( 174 - match seg.content with 175 - | Ltp.Report rs -> 176 - Alcotest.(check int64) "upper_bound" 100000L rs.upper_bound; 177 - Alcotest.(check int64) "lower_bound" 50000L rs.lower_bound; 178 - Alcotest.(check int) "claims" 1 (List.length rs.claims); 179 - let c0 = List.nth rs.claims 0 in 180 - Alcotest.(check int64) "claim0.offset" 50000L c0.offset; 181 - Alcotest.(check int64) "claim0.length" 50000L c0.length 182 - | _ -> Alcotest.fail "expected Report content") 183 - | "report_ack" -> ( 184 - match seg.content with 185 - | Ltp.Report_ack ra -> 186 - Alcotest.(check int64) "report_serial" 7L ra.report_serial 187 - | _ -> Alcotest.fail "expected Report_ack content") 188 - | "cancel_sender_rlexc" -> ( 189 - Alcotest.(check int) 190 - "segment_type" 12 191 - (Ltp.segment_type_to_int seg.segment_type); 192 - match seg.content with 193 - | Ltp.Cancel cs -> 194 - Alcotest.(check int) 195 - "reason" 2 196 - (Ltp.cancel_reason_to_int cs.reason) 197 - | _ -> Alcotest.fail "expected Cancel content") 198 - | "cancel_receiver_user" -> ( 199 - Alcotest.(check int) 200 - "segment_type" 14 201 - (Ltp.segment_type_to_int seg.segment_type); 202 - match seg.content with 203 - | Ltp.Cancel cs -> 204 - Alcotest.(check int) 205 - "reason" 0 206 - (Ltp.cancel_reason_to_int cs.reason) 207 - | _ -> Alcotest.fail "expected Cancel content") 208 - | "cancel_ack_to_sender" -> ( 209 - Alcotest.(check int) 210 - "segment_type" 13 211 - (Ltp.segment_type_to_int seg.segment_type); 212 - match seg.content with 213 - | Ltp.Cancel_ack () -> () 214 - | _ -> Alcotest.fail "expected Cancel_ack content") 215 - | "cancel_ack_to_receiver" -> ( 216 - Alcotest.(check int) 217 - "segment_type" 15 218 - (Ltp.segment_type_to_int seg.segment_type); 219 - match seg.content with 220 - | Ltp.Cancel_ack () -> () 221 - | _ -> Alcotest.fail "expected Cancel_ack content") 222 - | name -> Alcotest.failf "unknown test vector: %s" name) 223 - 224 - (* {1 Test Runner} *) 225 - 226 - let () = 227 - let sdnv_rows = load_sdnv_rows () in 228 - let segment_rows = load_segment_rows () in 229 - let sdnv_cases f = 230 - List.map 231 - (fun (r : sdnv_row) -> Alcotest.test_case r.name `Quick (f r)) 232 - sdnv_rows 233 - in 234 - let seg_cases f = 235 - List.map 236 - (fun (r : segment_row) -> Alcotest.test_case r.name `Quick (f r)) 237 - segment_rows 238 - in 239 - Alcotest.run "ltp-interop-python" 240 - [ 241 - ("sdnv-encode", sdnv_cases test_sdnv_encode); 242 - ("sdnv-decode", sdnv_cases test_sdnv_decode); 243 - ("segment-decode", seg_cases test_segment_decode); 244 - ("segment-encode", seg_cases test_segment_encode); 245 - ("segment-fields", seg_cases test_segment_fields); 246 - ]
-13
test/interop/python/traces/sdnv.csv
··· 1 - name,value,encoded_hex 2 - zero,0,00 3 - one,1,01 4 - max_single_byte,127,7f 5 - min_two_byte,128,8100 6 - byte_255,255,817f 7 - byte_256,256,8200 8 - max_two_byte,16383,ff7f 9 - min_three_byte,16384,818000 10 - medium,1000000,bd8440 11 - uint32_max,4294967295,8fffffff7f 12 - large_40bit,78187493520,82a3a2d9f110 13 - int64_max,9223372036854775807,ffffffffffffffff7f
-12
test/interop/python/traces/segments.csv
··· 1 - name,segment_hex 2 - green_data_simple,040a87680001000b48656c6c6f2c204c545021 3 - green_eob,072a630002840004deadbeef 4 - red_checkpoint,0101640001000f0500636865636b706f696e742064617461 5 - red_checkpoint_eorp_eob,0301814800038200090a0266696e616c20726564 6 - report_two_claims,0801640007058800000200840084588148 7 - report_large_offsets,0863ab33000101868d2083865001838650838650 8 - report_ack,0901640007 9 - cancel_sender_rlexc,0c01640002 10 - cancel_receiver_user,0e052a0000 11 - cancel_ack_to_sender,0d016400 12 - cancel_ack_to_receiver,0f052a00