···113113114114(* {1 Binary helpers} *)
115115116116-let get_u8 s i = Char.code (String.get s i)
116116+let u8 s i = Char.code (String.get s i)
117117118118-let get_u16_be s i =
119119- let b0 = get_u8 s i in
120120- let b1 = get_u8 s (i + 1) in
118118+let u16_be s i =
119119+ let b0 = u8 s i in
120120+ let b1 = u8 s (i + 1) in
121121 (b0 lsl 8) lor b1
122122123123-let get_u32_be s i =
124124- let b0 = get_u8 s i in
125125- let b1 = get_u8 s (i + 1) in
126126- let b2 = get_u8 s (i + 2) in
127127- let b3 = get_u8 s (i + 3) in
123123+let u32_be s i =
124124+ let b0 = u8 s i in
125125+ let b1 = u8 s (i + 1) in
126126+ let b2 = u8 s (i + 2) in
127127+ let b3 = u8 s (i + 3) in
128128 (b0 lsl 24) lor (b1 lsl 16) lor (b2 lsl 8) lor b3
129129130130-let get_var_uint_be s off len =
130130+let var_uint_be s off len =
131131 let rec aux acc i =
132132- if i >= len then acc else aux ((acc lsl 8) lor get_u8 s (off + i)) (i + 1)
132132+ if i >= len then acc else aux ((acc lsl 8) lor u8 s (off + i)) (i + 1)
133133 in
134134 aux 0 0
135135···206206 let hdr_len = min_header_len + vcfc_len in
207207 if len < hdr_len then Error (Truncated { need = hdr_len; have = len })
208208 else
209209- let b0 = get_u8 buf 0 in
209209+ let b0 = u8 buf 0 in
210210 let tfvn = (b0 lsr 4) land 0xF in
211211 if tfvn <> tfvn_uslp then Error (Invalid_version tfvn)
212212 else
213213 let scid_hi = b0 land 0xF in
214214- let b1 = get_u8 buf 1 in
215215- let b2 = get_u8 buf 2 in
214214+ let b1 = u8 buf 1 in
215215+ let b2 = u8 buf 2 in
216216 let scid_mid = b1 in
217217 let scid_lo = (b2 lsr 4) land 0xF in
218218 let scid_val = (scid_hi lsl 12) lor (scid_mid lsl 4) lor scid_lo in
219219 let src_or_dest = if (b2 lsr 3) land 1 = 0 then Source else Dest in
220220 let vcid_hi = b2 land 0x7 in
221221- let b3 = get_u8 buf 3 in
221221+ let b3 = u8 buf 3 in
222222 let vcid_lo = (b3 lsr 5) land 0x7 in
223223 let vcid_val = (vcid_hi lsl 3) lor vcid_lo in
224224 if vcid_val > 63 then Error (Invalid_vcid vcid_val)
···227227 if map_id_val > 15 then Error (Invalid_map_id map_id_val)
228228 else
229229 let eofph = b3 land 1 = 1 in
230230- let frame_len = get_u16_be buf 4 in
231231- let b6 = get_u8 buf 6 in
230230+ let frame_len = u16_be buf 4 in
231231+ let b6 = u8 buf 6 in
232232 let bypass_flag = (b6 lsr 7) land 1 = 1 in
233233 let prot_ctrl_cmd = (b6 lsr 6) land 1 = 1 in
234234 let ocf_flag = (b6 lsr 3) land 1 = 1 in
235235 let vcfc_len_field = b6 land 0x7 in
236236- let vcfc =
237237- if vcfc_len > 0 then get_var_uint_be buf 7 vcfc_len else 0
238238- in
236236+ let vcfc = if vcfc_len > 0 then var_uint_be buf 7 vcfc_len else 0 in
239237 Ok
240238 {
241239 tfvn;
···254252255253(* {1 Frame decoding} *)
256254255255+let verify_fecf ~compute buf fecf_off fecf_val =
256256+ let expected = compute (String.sub buf 0 fecf_off) in
257257+ if expected <> fecf_val then
258258+ Error
259259+ (Fecf_mismatch
260260+ { expected = Int64.of_int expected; actual = Int64.of_int fecf_val })
261261+ else Ok ()
262262+263263+let make_frame header insert_zone data ocf fecf =
264264+ Ok { header; insert_zone; data; ocf; fecf }
265265+257266let decode ?(vcfc_len = 0) ?(insert_zone_len = 0) ?(expect_ocf = false)
258267 ?(expect_fecf = No_fecf) ?(check_fecf = true) buf =
259268 let buf_len = String.length buf in
···289298 let data_off = hdr_len + insert_zone_len in
290299 let data = String.sub buf data_off data_len in
291300 let ocf_off = data_off + data_len in
292292- let ocf =
293293- if ocf_size > 0 then Some (get_u32_be buf ocf_off) else None
294294- in
301301+ let ocf = if ocf_size > 0 then Some (u32_be buf ocf_off) else None in
295302 let fecf_off = ocf_off + ocf_size in
296303 match expect_fecf with
297297- | No_fecf -> Ok { header; insert_zone; data; ocf; fecf = None }
304304+ | No_fecf -> make_frame header insert_zone data ocf None
298305 | Crc16 ->
299299- let fecf_val = get_u16_be buf fecf_off in
306306+ let fecf_val = u16_be buf fecf_off in
307307+ let fecf = Some (Int64.of_int fecf_val) in
300308 if check_fecf then
301301- let expected = compute_crc16 (String.sub buf 0 fecf_off) in
302302- if expected <> fecf_val then
303303- Error
304304- (Fecf_mismatch
305305- {
306306- expected = Int64.of_int expected;
307307- actual = Int64.of_int fecf_val;
308308- })
309309- else
310310- Ok
311311- {
312312- header;
313313- insert_zone;
314314- data;
315315- ocf;
316316- fecf = Some (Int64.of_int fecf_val);
317317- }
318318- else
319319- Ok
320320- {
321321- header;
322322- insert_zone;
323323- data;
324324- ocf;
325325- fecf = Some (Int64.of_int fecf_val);
326326- }
309309+ match
310310+ verify_fecf ~compute:compute_crc16 buf fecf_off fecf_val
311311+ with
312312+ | Error e -> Error e
313313+ | Ok () -> make_frame header insert_zone data ocf fecf
314314+ else make_frame header insert_zone data ocf fecf
327315 | Crc32 ->
328328- let fecf_val = get_u32_be buf fecf_off in
316316+ let fecf_val = u32_be buf fecf_off in
317317+ let fecf = Some (Int64.of_int fecf_val) in
329318 if check_fecf then
330330- let expected = compute_crc32 (String.sub buf 0 fecf_off) in
331331- if expected <> fecf_val then
332332- Error
333333- (Fecf_mismatch
334334- {
335335- expected = Int64.of_int expected;
336336- actual = Int64.of_int fecf_val;
337337- })
338338- else
339339- Ok
340340- {
341341- header;
342342- insert_zone;
343343- data;
344344- ocf;
345345- fecf = Some (Int64.of_int fecf_val);
346346- }
347347- else
348348- Ok
349349- {
350350- header;
351351- insert_zone;
352352- data;
353353- ocf;
354354- fecf = Some (Int64.of_int fecf_val);
355355- })
319319+ match
320320+ verify_fecf ~compute:compute_crc32 buf fecf_off fecf_val
321321+ with
322322+ | Error e -> Error e
323323+ | Ok () -> make_frame header insert_zone data ocf fecf
324324+ else make_frame header insert_zone data ocf fecf)
356325357326(* {1 Frame encoding} *)
358327···649618650619(* {1 CLCW Integration} *)
651620652652-let get_clcw frame =
621621+let find_clcw frame =
653622 match frame.ocf with None -> None | Some word -> Some (Clcw.decode word)
654623655624let set_clcw frame clcw =
+41-4
lib/uslp.mli
···3131(** Spacecraft Identifier (16 bits, 0-65535). *)
32323333val scid : int -> scid option
3434+3435val scid_exn : int -> scid
3636+(** Like {!scid} but raises [Invalid_argument]. *)
3737+3538val scid_to_int : scid -> int
3939+(** Extract the underlying integer. *)
36403741type vcid = private int
3842(** Virtual Channel Identifier (6 bits, 0-63). *)
39434044val vcid : int -> vcid option
4545+4146val vcid_exn : int -> vcid
4747+(** Like {!vcid} but raises [Invalid_argument]. *)
4848+4249val vcid_to_int : vcid -> int
5050+(** Extract the underlying integer. *)
43514452type map_id = private int
4553(** Multiplexer Access Point Identifier (4 bits, 0-15). *)
46544755val map_id : int -> map_id option
5656+4857val map_id_exn : int -> map_id
5858+(** Like {!map_id} but raises [Invalid_argument]. *)
5959+4960val map_id_to_int : map_id -> int
6161+(** Extract the underlying integer. *)
50625163(** {1 Types} *)
5264···8395(** USLP Transfer Frame. *)
84968597val equal_header : header -> header -> bool
9898+8699val equal : t -> t -> bool
100100+(** Structural equality for frames. *)
101101+87102val pp_header : Format.formatter -> header -> unit
103103+(** Pretty-print a USLP header. *)
104104+88105val pp : Format.formatter -> t -> unit
106106+(** Pretty-print a USLP frame. *)
107107+89108val pp_src_or_dest : Format.formatter -> src_or_dest -> unit
109109+(** Pretty-print a source/destination indicator. *)
9011091111(** {1 Errors} *)
92112···100120 | Invalid_vcfc_len of int
101121102122val pp_error : Format.formatter -> error -> unit
123123+(** Pretty-print a decode error. *)
103124104125(** {1 Encoding/Decoding} *)
105126···116137 @param insert_zone_len Insert zone length (default: 0)
117138 @param expect_ocf Whether OCF is present (default: false)
118139 @param expect_fecf FECF type (default: No_fecf)
119119- @param check_fecf Whether to verify FECF (default: true) *)
140140+ @param check_fecf Whether to verify FECF (default: true). *)
120141121142val encode :
122143 ?insert_zone_len:int -> ?with_ocf:bool -> ?fecf:fecf_type -> t -> string
123144(** [encode frame] encodes a USLP frame to a string.
124145 @param insert_zone_len Insert zone length to reserve (default: 0)
125146 @param with_ocf Whether to include OCF (default: false)
126126- @param fecf FECF type (default: No_fecf) *)
147147+ @param fecf FECF type (default: No_fecf). *)
127148128149val encoded_len :
129150 ?insert_zone_len:int -> ?with_ocf:bool -> ?fecf:fecf_type -> t -> int
···164185165186(** {1 CLCW Integration} *)
166187167167-val get_clcw : t -> (Clcw.t, Clcw.error) result option
168168-(** [get_clcw frame] extracts and decodes the CLCW from the OCF if present. *)
188188+val find_clcw : t -> (Clcw.t, Clcw.error) result option
189189+(** [find_clcw frame] extracts and decodes the CLCW from the OCF if present. *)
169190170191val set_clcw : t -> Clcw.t -> t
171192(** [set_clcw frame clcw] sets the OCF to the encoded CLCW. *)
···212233val of_packed_header :
213234 packed_header ->
214235 (header, [ `Invalid_scid | `Invalid_vcid | `Invalid_map_id ]) result
236236+(** Convert a packed header to a validated header. *)
215237216238val equal_packed_header : packed_header -> packed_header -> bool
239239+(** Structural equality for packed headers. *)
217240218241(** {1 Wire Codec} *)
219242220243val codec : packed_header Wire.Codec.t
244244+221245val struct_ : Wire.struct_
246246+(** Wire struct definition for a USLP header. *)
247247+222248val module_ : Wire.module_
249249+(** Wire module definition for USLP. *)
223250224251(** {1 Wire Parse/Encode} *)
225252226253val wire_size : int
254254+227255val decode_bytes : bytes -> (packed_header, Wire.parse_error) result
256256+(** Decode a packed header from bytes. *)
257257+228258val decode_string : string -> (packed_header, Wire.parse_error) result
259259+(** Decode a packed header from a string. *)
260260+229261val encode_string : packed_header -> string
262262+(** Encode a packed header to a string. *)
263263+230264val encode_bytes : packed_header -> bytes
265265+(** Encode a packed header to bytes. *)
231266232267(** {1 FFI Code Generation} *)
233268234269val c_stubs : unit -> string
270270+235271val ml_stubs : unit -> string
272272+(** Generate OCaml FFI stub code. *)