Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 60 additions & 7 deletions script/pn532_cli_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ def on_exec(self, args: argparse.Namespace):
print(f"Config Gen2 Magic ISO15693 tag {CY}{'Success' if resp else 'Fail'}{C0}")


@hf_15.command("esetuid")
@hf_15.command("eSetUid")
class HF15ESetUid(DeviceRequiredUnit):
def args_parser(self) -> ArgumentParserNoExit:
parser = ArgumentParserNoExit()
Expand All @@ -927,8 +927,8 @@ def args_parser(self) -> ArgumentParserNoExit:

def on_exec(self, args: argparse.Namespace):
if args.u is None:
print("usage: hf 15 esetuid [-h] -u <hex> [-s SLOT]")
print("hf 15 esetuid: error: the following arguments are required: -u")
print("usage: hf 15 eSetUid [-h] -u <hex> [-s SLOT]")
print("hf 15 eSetUid: error: the following arguments are required: -u")
return
uid = args.u
if not re.match(r"^[a-fA-F0-9]{16}$", uid):
Expand All @@ -944,7 +944,7 @@ def on_exec(self, args: argparse.Namespace):
)


@hf_15.command("esetblock")
@hf_15.command("eSetBlock")
class HF15ESetBlock(DeviceRequiredUnit):
# add parameter -b <hex> to set block data(4 bytes)
def args_parser(self) -> ArgumentParserNoExit:
Expand Down Expand Up @@ -980,7 +980,60 @@ def on_exec(self, args: argparse.Namespace):
f"Set Slot {args.slot} block {args.b} to {block} {CY}{'Success' if resp else 'Fail'}{C0}"
)

@hf_15.command("eSetDump")
class HF15ESetDump(DeviceRequiredUnit):
def args_parser(self) -> ArgumentParserNoExit:
parser = ArgumentParserNoExit()
parser.description = "Set dump data of ISO15693 Emulation"
parser.add_argument(
"--json",
type=str,
required=False,
metavar="<file>",
help="JSON file to load dump data",
)
parser.add_argument(
"--bin",
type=str,
required=False,
metavar="<file>",
help="BIN file to load dump data",
)
parser.add_argument(
"-s", "--slot", default=1, type=int, help="Emulator slot(1-8)"
)
return parser

def on_exec(self, args: argparse.Namespace):
if not args.json and not args.bin:
print("Please choose either json file or bin file")
return

data = b""
if args.json:
if not os.path.exists(args.json):
print(f"File {args.json} not exists")
return
with open(args.json, "r") as f:
dump_data = json.load(f)
if "blocks" in dump_data:
for block in range(len(dump_data["blocks"])):
if str(block) in dump_data["blocks"]:
data += bytes.fromhex(dump_data["blocks"][str(block)])
else:
data += b'\x00\x00\x00\x00'
elif args.bin:
if not os.path.exists(args.bin):
print(f"File {args.bin} not exists")
return
with open(args.bin, "rb") as f:
data = f.read()

resp = self.cmd.hf_15_eset_dump(args.slot - 1, data)
print(
f"Set Slot {args.slot} dump data {CY}{'Success' if resp else 'Fail'}{C0}"
)

@hf_15.command("eSetwriteprotect")
class HF15ESetWriteProtect(DeviceRequiredUnit):
# add parameter -b <hex> to set block data(4 bytes)
Expand Down Expand Up @@ -1257,7 +1310,7 @@ def get_block0(self, uid, args):
return
return str_to_bytes(block0)

@hf_mf.command("esetuid")
@hf_mf.command("eSetUid")
class HfMfESetUid(DeviceRequiredUnit):
def args_parser(self) -> ArgumentParserNoExit:
parser = ArgumentParserNoExit()
Expand All @@ -1276,8 +1329,8 @@ def args_parser(self) -> ArgumentParserNoExit:

def on_exec(self, args: argparse.Namespace):
if args.u is None:
print("usage: hf mf esetuid [-h] -u <hex>")
print("hf mf esetuid: error: the following arguments are required: -u")
print("usage: hf mf eSetUid [-h] -u <hex>")
print("hf mf eSetUid: error: the following arguments are required: -u")
return
uid = bytes.fromhex(args.u)
if len(uid) not in [4, 7]:
Expand Down
11 changes: 11 additions & 0 deletions script/pn532_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,17 @@ def hf_15_eset_block(self, slot, index, data: bytes):
resp_set = self.upload_data_block(type = 0x03, slot = slot + 0x1A, index = index, data = data)
resp_save = self.hf_15_esave(slot)
return resp_set and resp_save

def hf_15_eset_dump(self, slot, bin_data):
"""
Set the whole dump for 15 emulator
"""
for block_index in range(0, len(bin_data), 4):
block_data = bin_data[block_index:block_index + 4]
resp = self.upload_data_block(type=0x03, slot=slot + 0x1A, index=block_index // 4, data=block_data)
print(f"Set block {block_index // 4:02d} {block_data.hex()}: {resp}")
resp_save = self.hf_15_esave(slot)
return resp_save

def hf_15_eset_resv_eas_afi_dsfid(self, slot, data):
"""
Expand Down
7 changes: 4 additions & 3 deletions script/pn532_com.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ def open(self, port) -> "Pn532Com":
raise OpenFailException(error)
assert self.serial_instance is not None
try:
self.serial_instance.dtr = True # must make dtr enable
self.serial_instance.dtr = False
self.serial_instance.rts = False
except Exception:
# not all serial support dtr, e.g. virtual serial over BLE
print("Failed to set DTR/RTS")
pass
self.serial_instance.timeout = THREAD_BLOCKING_TIMEOUT
# clear variable
Expand All @@ -83,7 +84,7 @@ def open(self, port) -> "Pn532Com":
threading.Thread(target=self.thread_data_receive).start()
threading.Thread(target=self.thread_data_transfer).start()
threading.Thread(target=self.thread_check_timeout).start()
time.sleep(0.01)

self.set_normal_mode()
time.sleep(0.01)
is_pn532killer = self.is_pn532killer()
Expand Down
1 change: 1 addition & 0 deletions script/pn532_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class Pn532KillerCommand(enum.IntEnum):
"HF15Gen2Config",
"HF15ESetUid",
"HF15ESetBlock",
"HF15ESetDump",
"HF15ESetWriteProtect",
"HF15ESetResvEasAfiDsfid",
"HfMfESetUid",
Expand Down