# Simulates the VZNLSDK Xilinx discovery: sends the exact 35-byte search # request, then parses the virtual camera's response exactly the way # _ParseXilinxDeviceInfo does, printing each validation step. import socket import struct import sys import time UDP_PORT = 6789 TARGET = ("127.0.0.1", UDP_PORT) # Exact 35-byte search request from VzXilinxDeviceEnumrator.cpp s_szRequest[] search_req = bytes([ 0xe1, 0xe2, 0xe3, 0xe4, # preamble 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, # serial (broadcast) 0x53, 0x42, # "SB" start 0x00, 0x02, # htons(SearchDev) = 2 0x00, 0x00, 0x00, 0x00, # reserve 0x00, 0x17, # htons(23) group length 0x00, 0x00, 0x00, 0x00, # CRC 0x00, 0x00, # command type 0x00, 0x00, # command length 0x00, 0x00, # command seq 0x01, # data byte 0x45, 0x42, # "EB" end ]) print(f"Search request: {len(search_req)} bytes") sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(3.0) sock.bind(("127.0.0.1", 0)) # recv port 0 (OS-assigned), like the SDK local_port = sock.getsockname()[1] print(f"Bound local port {local_port}") sock.sendto(search_req, TARGET) print(f"Sent search to {TARGET}") try: data, addr = sock.recvfrom(4096) except socket.timeout: print("TIMEOUT: no response received") sys.exit(1) print(f"Received {len(data)} bytes from {addr}") print(f"Raw hex: {data.hex()}\n") fail = 0 def ok(cond, label): global fail mark = "OK" if cond else "*** FAIL ***" if not cond: fail += 1 print(f" {mark}: {label}") # ---- Parse exactly like _ParseXilinxDeviceInfo ---- preamble = struct.unpack("= 68, f"shCommandLen-14 = {remain} >= sizeof(SVzXilinxDeviceInfo)=68") if remain >= 68: # Try to read 68-byte SVzXilinxDeviceInfo if len(data) >= 36 + 68: dev = data[36:104] print(f" INFO: devInfo size = {len(dev)}") productType = dev[0] verCode = struct.unpack("= 104, "buffer has all 68 devInfo bytes") else: ok(False, f"buffer too short for devInfo ({len(data)} < 104)") # tail handling pos = 36 + 68 remain2 = len(data) - pos print(f" INFO: bytes after devInfo = {remain2}") if remain2 == 2: # SDK reads shPackageEnd via native LE but NEVER validates its value # (_ParseXilinxDeviceInfo returns true once the devInfo is parsed). pkgEnd = struct.unpack("