import asyncio from unittest.mock import AsyncMock from pm3py.core.protocol import Cmd from pm3py.core.transport import PM3Response from pm3py.core.hf import HFCommands def test_hf_tune(): t = AsyncMock() hf = HFCommands(t) # MEASURE (mode 2) returns the voltage as a uint16 mV; 15485 mV = 0x3C7D t.send_ng.return_value = PM3Response(cmd=Cmd.MEASURE_ANTENNA_TUNING_HF, status=0, reason=0, ng=True, data=b"\x7d\x3c") result = asyncio.get_event_loop().run_until_complete(hf.tune()) assert result["voltage_mV"] == 15485 assert result["voltage_V"] == 15.485 # Firmware requires the START(1)/MEASURE(2)/STOP(3) mode-byte sequence modes = [call.args[1] for call in t.send_ng.call_args_list] assert modes == [bytes([1]), bytes([2]), bytes([3])] def test_hf_dropfield(): t = AsyncMock() hf = HFCommands(t) result = asyncio.get_event_loop().run_until_complete(hf.dropfield()) assert result["status"] == 0 # Firmware CMD_HF_DROPFIELD sends no reply -> must be fire-and-forget t.send_ng_no_response.assert_awaited_once() assert t.send_ng_no_response.call_args.args[0] == Cmd.HF_DROPFIELD t.send_ng.assert_not_called() def test_hf_sniff(): t = AsyncMock() hf = HFCommands(t) # Firmware replies with a uint16 sample count (1234 = 0x04D2) t.send_ng.return_value = PM3Response(cmd=Cmd.HF_SNIFF, status=0, reason=0, ng=True, data=b"\xd2\x04") result = asyncio.get_event_loop().run_until_complete( hf.sniff(samples_to_skip=5, triggers_to_skip=6, skip_mode=1, skip_ratio=2)) assert result["samples"] == 1234 assert result["status"] == 0 # Always sends the full 10-byte PACKED {u32 u32 u8 u8} struct payload = t.send_ng.call_args.args[1] assert payload == b"\x05\x00\x00\x00\x06\x00\x00\x00\x01\x02"