- Messages
- 181
- Points
- 28
Here is the code for SADPTools python version. Works on any OS with python installed and prettytable
Explanation:
SadpTools work in the way that it sends UDP packet to broadcast address on certain port. That broadcast address and port is listened by devices that run HIK_SERVER and they respond back.
The byte array representation in ASCII string :
The Uuid can be different.
You can use this code in your integrations with hikvision devices for Device Descovery:
One example c# Disovery BackgroundService:
Cheers
import socket
import os
import xml.etree.ElementTree as ET
from prettytable import PrettyTable
def send_udp_broadcast(packet, port, broadcast_ip, local_ip):
"""Send a UDP broadcast packet."""
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as sock:
sock.bind((local_ip, port))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.sendto(packet, (broadcast_ip, port))
def listen_for_responses(port):
"""Listen for UDP packets and populate the table with device info."""
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) as sock:
sock.bind(("", port))
seen_devices = {} # To keep track of seen devices
while True:
data, _ = sock.recvfrom(24000)
root = ET.fromstring(data.decode('utf-8'))
# Extract information from the XML
device_info = {tag: root.find(tag).text for tag in ["MAC", "DeviceDescription", "DeviceSN", "IPv4Address", "DHCP"]}
# Update device info
seen_devices[device_info['MAC']] = [device_info[key] for key in ["IPv4Address", "DeviceDescription", "DeviceSN", "DHCP"]]
# Display the information
display_info(seen_devices)
def display_info(seen_devices):
"""Display the device information in a table format."""
# Clear the terminal
os.system('clear' if os.name == 'posix' else 'cls') # Clear screen command for different OS
table = PrettyTable()
table.field_names = ["IPV4", "MAC", "Description", "Serial Number", "DHCP"]
for mac, info in seen_devices.items():
table.add_row([info[0], mac, info[1], info[2], info[3]])
print(table)
def get_local_ip():
"""Get the local IP address."""
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
try:
sock.connect(('10.255.255.255', 1))
local_ip = sock.getsockname()[0]
except Exception:
local_ip = '127.0.0.1'
return local_ip
if __name__ == '__main__':
packet = bytes([0x3c, 0x3f, 0x78, 0x6d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x3c, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x3e, 0x3c, 0x55, 0x75, 0x69, 0x64, 0x3e, 0x37, 0x34, 0x46, 0x31, 0x45, 0x44, 0x33, 0x37, 0x2d, 0x35, 0x45, 0x38, 0x32, 0x2d, 0x34, 0x33, 0x45, 0x38, 0x2d, 0x39, 0x41, 0x36, 0x31, 0x2d, 0x36, 0x36, 0x46, 0x43, 0x44, 0x33, 0x32, 0x39, 0x32, 0x36, 0x45, 0x32, 0x3c, 0x2f, 0x55, 0x75, 0x69, 0x64, 0x3e, 0x3c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3e, 0x69, 0x6e, 0x71, 0x75, 0x69, 0x72, 0x79, 0x3c, 0x2f, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3e, 0x3c, 0x2f, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x3e])
broadcast_ip = "239.255.255.250"
port = 37020
local_ip = get_local_ip()
send_udp_broadcast(packet, port, broadcast_ip, local_ip)
listen_for_responses(port)
Explanation:
SadpTools work in the way that it sends UDP packet to broadcast address on certain port. That broadcast address and port is listened by devices that run HIK_SERVER and they respond back.
The byte array representation in ASCII string :
<?xml version="1.0" encoding="utf-8"?><Probe><Uuid>74F1ED37-5E82-43E8-9A61-66FCD32926E2</Uuid><Types>inquiry</Types></Probe>
The Uuid can be different.
You can use this code in your integrations with hikvision devices for Device Descovery:
One example c# Disovery BackgroundService:
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Xml.Linq;
namespace ProxyApi.Controllers
{
public class HikvisionBroadcast
{
private static Socket _udpSocket;
private static readonly byte[] packet = new byte[]
{
0x3c, 0x3f, 0x78, 0x6d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e,
0x30, 0x22, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x22, 0x75, 0x74, 0x66,
0x2d, 0x38, 0x22, 0x3f, 0x3e, 0x3c, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x3e, 0x3c, 0x55, 0x75, 0x69,
0x64, 0x3e, 0x37, 0x34, 0x46, 0x31, 0x45, 0x44, 0x33, 0x37, 0x2d, 0x35, 0x45, 0x38, 0x32, 0x2d,
0x34, 0x33, 0x45, 0x38, 0x2d, 0x39, 0x41, 0x36, 0x31, 0x2d, 0x36, 0x36, 0x46, 0x43, 0x44, 0x33,
0x32, 0x39, 0x32, 0x36, 0x45, 0x32, 0x3c, 0x2f, 0x55, 0x75, 0x69, 0x64, 0x3e, 0x3c, 0x54, 0x79,
0x70, 0x65, 0x73, 0x3e, 0x69, 0x6e, 0x71, 0x75, 0x69, 0x72, 0x79, 0x3c, 0x2f, 0x54, 0x79, 0x70,
0x65, 0x73, 0x3e, 0x3c, 0x2f, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x3e
};
public HikvisionBroadcast()
{
InitializeSocket();
}
private void InitializeSocket()
{
if (_udpSocket == null)
{
_udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_udpSocket.EnableBroadcast = true;
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("SADP: Broadcast started");
Console.ResetColor();
}
}
public List<object> BroadcastAndReceive()
{
_udpSocket.SendTo(packet, new IPEndPoint(IPAddress.Parse("239.255.255.250"), 37020));
List<object> responses = new List<object>();
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] receiveBuffer = new byte[4096];
DateTime endTime = DateTime.Now.AddSeconds(5);
while (DateTime.Now < endTime)
{
if (_udpSocket.Poll(1000000, SelectMode.SelectRead))
{
int length = _udpSocket.ReceiveFrom(receiveBuffer, ref remoteEndPoint);
var parsedData = ParseReceivedData(receiveBuffer.Take(length).ToArray());
if (parsedData != null)
{
responses.Add(parsedData);
}
}
}
return responses;
}
private object ParseReceivedData(byte[] data)
{
try
{
string responseString = Encoding.UTF8.GetString(data);
XDocument xmlDoc = XDocument.Parse(responseString);
var deviceInfo = new
{
Activated = xmlDoc.Root.Element("Activated")?.Value ?? "N/A",
DeviceDescription = xmlDoc.Root.Element("DeviceDescription")?.Value ?? "N/A",
DeviceSN = xmlDoc.Root.Element("DeviceSN")?.Value ?? "N/A",
IPv4Address = xmlDoc.Root.Element("IPv4Address")?.Value ?? "N/A",
IPv4SubnetMask = xmlDoc.Root.Element("IPv4SubnetMask")?.Value ?? "N/A",
CommandPort = xmlDoc.Root.Element("CommandPort")?.Value ?? "N/A",
HttpPort = xmlDoc.Root.Element("HttpPort")?.Value ?? "N/A",
IPv4Gateway = xmlDoc.Root.Element("IPv4Gateway")?.Value ?? "N/A",
DHCP = xmlDoc.Root.Element("DHCP")?.Value ?? "N/A",
MAC = xmlDoc.Root.Element("MAC")?.Value ?? "N/A"
};
return deviceInfo;
}
catch (Exception)
{
// Error parsing XML or extracting data.
return null;
}
}
}
}
Cheers