HomeKit Accessory Protocol (HAP) for OCaml
0
fork

Configure Feed

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

fix(lint): resolve E305 module naming convention across packages

Rename CamelCase internal modules to Snake_case per OCaml convention:
- ocaml-hap: TlvType→Tlv_type, HapError→Hap_error, CharType→Char_type
- ocaml-cookeio: SameSite→Same_site, DateParser→Date_parser
- ocaml-claudeio: PreToolUse→Pre_tool_use, PostToolUse→Post_tool_use,
UserPromptSubmit→User_prompt_submit, SubagentStop→Subagent_stop,
PreCompact→Pre_compact (wire format strings preserved)
- irmin: StringMap→String_map, PathSet→Path_set
- ocaml-block: ReadOnly→Read_only, WithCrc→With_crc

+58 -55
+38 -35
lib/hap.ml
··· 81 81 end 82 82 83 83 (* TLV types for HAP *) 84 - module TlvType = struct 84 + module Tlv_type = struct 85 85 let method_ = 0x00 86 86 let identifier = 0x01 87 87 let salt = 0x02 ··· 100 100 end 101 101 102 102 (* HAP errors *) 103 - module HapError = struct 103 + module Hap_error = struct 104 104 let unknown = 0x01 105 105 let authentication = 0x02 106 106 let backoff = 0x03 ··· 256 256 let sub_tlv = 257 257 Tlv.( 258 258 empty 259 - |> add TlvType.identifier controller_id 260 - |> add TlvType.public_key controller_kp.public 261 - |> add TlvType.signature signature 259 + |> add Tlv_type.identifier controller_id 260 + |> add Tlv_type.public_key controller_kp.public 261 + |> add Tlv_type.signature signature 262 262 |> encode) 263 263 in 264 264 let encrypted = ··· 266 266 ~aad:"" sub_tlv 267 267 in 268 268 Tlv.( 269 - empty |> add TlvType.state "\x05" 270 - |> add TlvType.encrypted_data encrypted 269 + empty |> add Tlv_type.state "\x05" 270 + |> add Tlv_type.encrypted_data encrypted 271 271 |> encode) 272 272 273 273 (* Verify M6 accessory response and return pairing info *) 274 274 let verify_m6 ~session_key_bytes ~enc_key (controller_kp : Ed25519.keypair) 275 275 controller_id m6 = 276 - let enc_data = Tlv.get_exn TlvType.encrypted_data m6 in 276 + let enc_data = Tlv.get_exn Tlv_type.encrypted_data m6 in 277 277 let* decrypted = 278 278 chacha20_poly1305_decrypt ~key:enc_key ~nonce:"\x00\x00\x00\x00PS-Msg06" 279 279 ~aad:"" enc_data 280 280 in 281 281 let sub_tlv = Tlv.decode decrypted in 282 - let accessory_id = Tlv.get_exn TlvType.identifier sub_tlv in 283 - let accessory_ltpk = Tlv.get_exn TlvType.public_key sub_tlv in 284 - let accessory_sig = Tlv.get_exn TlvType.signature sub_tlv in 282 + let accessory_id = Tlv.get_exn Tlv_type.identifier sub_tlv in 283 + let accessory_ltpk = Tlv.get_exn Tlv_type.public_key sub_tlv in 284 + let accessory_sig = Tlv.get_exn Tlv_type.signature sub_tlv in 285 285 let accessory_x = 286 286 hkdf_sha512 ~salt:"Pair-Setup-Accessory-Sign-Salt" ~ikm:session_key_bytes 287 287 ~info:"Pair-Setup-Accessory-Sign-Info" ~length:32 ··· 314 314 ~content_type:"application/pairing+tlv8" ~body:m5 315 315 in 316 316 let m6 = Tlv.decode m6_body in 317 - match Tlv.get TlvType.error m6 with 317 + match Tlv.get Tlv_type.error m6 with 318 318 | Some e -> 319 319 Error (`Msg (Printf.sprintf "Pair setup M6 error: %d" (Char.code e.[0]))) 320 320 | None -> verify_m6 ~session_key_bytes ~enc_key controller_kp controller_id m6 ··· 328 328 let n_len = (Z.numbits Srp.n + 7) / 8 in 329 329 let m3 = 330 330 Tlv.( 331 - empty |> add TlvType.state "\x03" 332 - |> add TlvType.public_key (Srp.bytes_of_z ~pad:n_len big_a) 333 - |> add TlvType.proof m1_proof |> encode) 331 + empty |> add Tlv_type.state "\x03" 332 + |> add Tlv_type.public_key (Srp.bytes_of_z ~pad:n_len big_a) 333 + |> add Tlv_type.proof m1_proof 334 + |> encode) 334 335 in 335 336 let* m4_body = 336 337 http_post ~net ~clock ~sw ~ip ~port ~path:"/pair-setup" 337 338 ~content_type:"application/pairing+tlv8" ~body:m3 338 339 in 339 340 let m4 = Tlv.decode m4_body in 340 - match Tlv.get TlvType.error m4 with 341 + match Tlv.get Tlv_type.error m4 with 341 342 | Some e -> 342 343 Error (`Msg (Printf.sprintf "Pair setup M4 error: %d" (Char.code e.[0]))) 343 344 | None -> 344 - let m2_proof = Tlv.get_exn TlvType.proof m4 in 345 + let m2_proof = Tlv.get_exn Tlv_type.proof m4 in 345 346 if 346 347 not 347 348 (Srp.Client.verify_proof srp_client ~m1:m1_proof ~m2:m2_proof ··· 362 363 Log.info (fun f -> f "Starting pair setup with %s:%d" ip port); 363 364 let m1 = 364 365 Tlv.( 365 - empty |> add TlvType.state "\x01" |> add TlvType.method_ "\x00" |> encode) 366 + empty |> add Tlv_type.state "\x01" 367 + |> add Tlv_type.method_ "\x00" 368 + |> encode) 366 369 in 367 370 let* m2_body = 368 371 http_post ~net ~clock ~sw ~ip ~port ~path:"/pair-setup" 369 372 ~content_type:"application/pairing+tlv8" ~body:m1 370 373 in 371 374 let m2 = Tlv.decode m2_body in 372 - match Tlv.get TlvType.error m2 with 375 + match Tlv.get Tlv_type.error m2 with 373 376 | Some e -> 374 377 Error (`Msg (Printf.sprintf "Pair setup error: %d" (Char.code e.[0]))) 375 378 | None -> 376 - let salt = Tlv.get_exn TlvType.salt m2 in 377 - let big_b_bytes = Tlv.get_exn TlvType.public_key m2 in 379 + let salt = Tlv.get_exn Tlv_type.salt m2 in 380 + let big_b_bytes = Tlv.get_exn Tlv_type.public_key m2 in 378 381 let big_b = Srp.z_of_bytes big_b_bytes in 379 382 Log.info (fun f -> 380 383 f "Received M2, salt=%d bytes, B=%d bytes" (String.length salt) ··· 392 395 let sub_tlv = 393 396 Tlv.( 394 397 empty 395 - |> add TlvType.identifier pairing.controller_id 396 - |> add TlvType.signature signature 398 + |> add Tlv_type.identifier pairing.controller_id 399 + |> add Tlv_type.signature signature 397 400 |> encode) 398 401 in 399 402 let encrypted = ··· 401 404 ~aad:"" sub_tlv 402 405 in 403 406 Tlv.( 404 - empty |> add TlvType.state "\x03" 405 - |> add TlvType.encrypted_data encrypted 407 + empty |> add Tlv_type.state "\x03" 408 + |> add Tlv_type.encrypted_data encrypted 406 409 |> encode) 407 410 408 411 (* Derive session keys from shared secret *) ··· 436 439 ~content_type:"application/pairing+tlv8" ~body:m3 437 440 in 438 441 let m4 = Tlv.decode m4_body in 439 - match Tlv.get TlvType.error m4 with 442 + match Tlv.get Tlv_type.error m4 with 440 443 | Some e -> 441 444 Error (`Msg (Printf.sprintf "Pair verify M4 error: %d" (Char.code e.[0]))) 442 445 | None -> derive_session_keys ~pairing ~ip ~port ~shared ··· 448 451 ~aad:"" enc_data 449 452 in 450 453 let sub_tlv = Tlv.decode decrypted in 451 - let accessory_id = Tlv.get_exn TlvType.identifier sub_tlv in 452 - let accessory_sig = Tlv.get_exn TlvType.signature sub_tlv in 454 + let accessory_id = Tlv.get_exn Tlv_type.identifier sub_tlv in 455 + let accessory_sig = Tlv.get_exn Tlv_type.signature sub_tlv in 453 456 if accessory_id <> pairing.accessory_id then 454 457 Error (`Msg "Accessory ID mismatch") 455 458 else ··· 467 470 let kp = X25519.generate () in 468 471 let m1 = 469 472 Tlv.( 470 - empty |> add TlvType.state "\x01" 471 - |> add TlvType.public_key kp.public 473 + empty |> add Tlv_type.state "\x01" 474 + |> add Tlv_type.public_key kp.public 472 475 |> encode) 473 476 in 474 477 let* m2_body = ··· 476 479 ~content_type:"application/pairing+tlv8" ~body:m1 477 480 in 478 481 let m2 = Tlv.decode m2_body in 479 - match Tlv.get TlvType.error m2 with 482 + match Tlv.get Tlv_type.error m2 with 480 483 | Some e -> 481 484 Error (`Msg (Printf.sprintf "Pair verify M2 error: %d" (Char.code e.[0]))) 482 485 | None -> 483 - let accessory_pk = Tlv.get_exn TlvType.public_key m2 in 484 - let enc_data = Tlv.get_exn TlvType.encrypted_data m2 in 486 + let accessory_pk = Tlv.get_exn Tlv_type.public_key m2 in 487 + let enc_data = Tlv.get_exn Tlv_type.encrypted_data m2 in 485 488 let* shared = 486 489 X25519.shared_secret ~secret:kp.secret ~public:accessory_pk 487 490 in ··· 915 918 (** {1 High-level control} *) 916 919 917 920 (* HAP characteristic type UUIDs (short form) *) 918 - module CharType = struct 921 + module Char_type = struct 919 922 let on = "25" (* 00000025-0000-1000-8000-0026BB765291 *) 920 923 end 921 924 ··· 939 942 (fun (svc : Hap_json.service) -> 940 943 List.find_map 941 944 (fun (chr : Hap_json.characteristic) -> 942 - if String.lowercase_ascii chr.type_ = CharType.on then 945 + if String.lowercase_ascii chr.type_ = Char_type.on then 943 946 Some (acc.aid, chr.iid) 944 947 else None) 945 948 svc.characteristics)
+2 -2
lib/hap.mli
··· 210 210 end 211 211 212 212 (** TLV type codes. *) 213 - module TlvType : sig 213 + module Tlv_type : sig 214 214 val method_ : int 215 215 (** Pairing method (0x00). *) 216 216 ··· 258 258 end 259 259 260 260 (** HAP error codes. *) 261 - module HapError : sig 261 + module Hap_error : sig 262 262 val unknown : int 263 263 (** Unknown error (0x01). *) 264 264
+18 -18
test/test_hap.ml
··· 50 50 (* TLV type constants tests *) 51 51 52 52 let test_tlv_type_constants () = 53 - Alcotest.(check int) "method" 0x00 Hap.TlvType.method_; 54 - Alcotest.(check int) "identifier" 0x01 Hap.TlvType.identifier; 55 - Alcotest.(check int) "salt" 0x02 Hap.TlvType.salt; 56 - Alcotest.(check int) "public_key" 0x03 Hap.TlvType.public_key; 57 - Alcotest.(check int) "proof" 0x04 Hap.TlvType.proof; 58 - Alcotest.(check int) "encrypted_data" 0x05 Hap.TlvType.encrypted_data; 59 - Alcotest.(check int) "state" 0x06 Hap.TlvType.state; 60 - Alcotest.(check int) "error" 0x07 Hap.TlvType.error; 61 - Alcotest.(check int) "signature" 0x0a Hap.TlvType.signature 53 + Alcotest.(check int) "method" 0x00 Hap.Tlv_type.method_; 54 + Alcotest.(check int) "identifier" 0x01 Hap.Tlv_type.identifier; 55 + Alcotest.(check int) "salt" 0x02 Hap.Tlv_type.salt; 56 + Alcotest.(check int) "public_key" 0x03 Hap.Tlv_type.public_key; 57 + Alcotest.(check int) "proof" 0x04 Hap.Tlv_type.proof; 58 + Alcotest.(check int) "encrypted_data" 0x05 Hap.Tlv_type.encrypted_data; 59 + Alcotest.(check int) "state" 0x06 Hap.Tlv_type.state; 60 + Alcotest.(check int) "error" 0x07 Hap.Tlv_type.error; 61 + Alcotest.(check int) "signature" 0x0a Hap.Tlv_type.signature 62 62 63 63 (* HAP error constants tests *) 64 64 65 65 let test_hap_error_constants () = 66 - Alcotest.(check int) "unknown" 0x01 Hap.HapError.unknown; 67 - Alcotest.(check int) "authentication" 0x02 Hap.HapError.authentication; 68 - Alcotest.(check int) "backoff" 0x03 Hap.HapError.backoff; 69 - Alcotest.(check int) "max_peers" 0x04 Hap.HapError.max_peers; 70 - Alcotest.(check int) "max_tries" 0x05 Hap.HapError.max_tries; 71 - Alcotest.(check int) "unavailable" 0x06 Hap.HapError.unavailable; 72 - Alcotest.(check int) "busy" 0x07 Hap.HapError.busy 66 + Alcotest.(check int) "unknown" 0x01 Hap.Hap_error.unknown; 67 + Alcotest.(check int) "authentication" 0x02 Hap.Hap_error.authentication; 68 + Alcotest.(check int) "backoff" 0x03 Hap.Hap_error.backoff; 69 + Alcotest.(check int) "max_peers" 0x04 Hap.Hap_error.max_peers; 70 + Alcotest.(check int) "max_tries" 0x05 Hap.Hap_error.max_tries; 71 + Alcotest.(check int) "unavailable" 0x06 Hap.Hap_error.unavailable; 72 + Alcotest.(check int) "busy" 0x07 Hap.Hap_error.busy 73 73 74 74 let suite = 75 75 ( "hap", ··· 79 79 Alcotest.test_case "TLV roundtrip" `Quick test_tlv_roundtrip; 80 80 Alcotest.test_case "TLV long value" `Quick test_tlv_long_value; 81 81 Alcotest.test_case "category names" `Quick test_category_names; 82 - Alcotest.test_case "TlvType constants" `Quick test_tlv_type_constants; 83 - Alcotest.test_case "HapError constants" `Quick test_hap_error_constants; 82 + Alcotest.test_case "Tlv_type constants" `Quick test_tlv_type_constants; 83 + Alcotest.test_case "Hap_error constants" `Quick test_hap_error_constants; 84 84 ] )