01304 827609 info@use-ip.co.uk Find us

FAQ SadpTools / Integration / Source Code / Example of usage

trempa92

Well-Known Member
Messages
74
Points
8
Here is the code for SADPTools python version. Works on any OS with python installed and prettytable

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
 
Back
Top