274 lines
9.5 KiB
C#
274 lines
9.5 KiB
C#
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
using System.Windows.Forms;
|
|
using Tmds.MDns;
|
|
using static robospot_camera_finder.MainForm;
|
|
|
|
namespace robospot_camera_finder
|
|
{
|
|
public partial class MainForm : Form
|
|
{
|
|
private readonly ServiceBrowser browser = new();
|
|
|
|
private BindingList<Camera> all_cameras = new();
|
|
|
|
public static string cam_username = "admin";
|
|
public static string cam_password = "RoboSpot10";
|
|
|
|
private static string browse_scope = "_rtsp._tcp";
|
|
|
|
bool is_browsing = false;
|
|
|
|
public class Camera
|
|
{
|
|
public Camera(string name, string ip, string location, string serial)
|
|
{
|
|
camera_name = name;
|
|
camera_ip = ip;
|
|
camera_location = location;
|
|
camera_serial = serial;
|
|
}
|
|
|
|
public Camera() { }
|
|
|
|
public string camera_name { get; set; }
|
|
|
|
public string camera_ip { get; set; }
|
|
|
|
public string camera_location { get; set; }
|
|
|
|
public string camera_serial { get; set; }
|
|
}
|
|
|
|
public MainForm()
|
|
{
|
|
InitializeComponent();
|
|
|
|
bool got_proper_ip = false;
|
|
foreach (var net_interface in NetworkInterface.GetAllNetworkInterfaces())
|
|
{
|
|
IPInterfaceProperties prop = net_interface.GetIPProperties();
|
|
foreach (var ip in prop.UnicastAddresses)
|
|
{
|
|
if (ip.Address.ToString().StartsWith("10."))
|
|
{
|
|
if (ip.IPv4Mask.ToString() == "255.0.0.0")
|
|
{
|
|
got_proper_ip = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!got_proper_ip)
|
|
{
|
|
DialogResult open_netsettings = MessageBox.Show("No Ethernet interface on the 10.0.0.0/8 subnet found. Cameras might not be detected. Do you want to open network settings ?", "Wrong IP configuration", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
|
|
if (open_netsettings == DialogResult.Yes)
|
|
{
|
|
ProcessStartInfo startInfo = new ProcessStartInfo("NCPA.cpl");
|
|
startInfo.UseShellExecute = true;
|
|
|
|
Process.Start(startInfo);
|
|
}
|
|
}
|
|
|
|
lbMain.DataSource = all_cameras;
|
|
lbMain.DisplayMember = "camera_name";
|
|
lbMain.ValueMember = "camera_ip";
|
|
|
|
browser.ServiceAdded += (sender, args) =>
|
|
{
|
|
ServiceAdded(sender, args);
|
|
};
|
|
|
|
browser.ServiceChanged += (sender, args) =>
|
|
{
|
|
ServiceAdded(sender, args);
|
|
};
|
|
|
|
browser.ServiceRemoved += (sender, args) =>
|
|
{
|
|
if (browser.IsBrowsing)
|
|
{
|
|
ServiceRemoved(sender, args);
|
|
}
|
|
};
|
|
|
|
browse(true);
|
|
}
|
|
|
|
private void browse(bool browse_needed)
|
|
{
|
|
if (browse_needed)
|
|
{
|
|
if (!browser.IsBrowsing)
|
|
{
|
|
browser.StartBrowse(browse_scope);
|
|
is_browsing = true;
|
|
toolStripStatusDisco.Text = "Discovery : Started";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (browser.IsBrowsing)
|
|
{
|
|
browser.StopBrowse();
|
|
is_browsing = false;
|
|
toolStripStatusDisco.Text = "Discovery : Stopped";
|
|
}
|
|
}
|
|
|
|
startToolStripMenuItem.Enabled = !browser.IsBrowsing;
|
|
stopToolStripMenuItem.Enabled = browser.IsBrowsing;
|
|
}
|
|
|
|
private void ServiceAdded(object sender, ServiceAnnouncementEventArgs args)
|
|
{
|
|
foreach (var cam_addr in args.Announcement.Addresses)
|
|
{
|
|
if (cam_addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
|
{
|
|
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + cam_addr + "/stw-cgi/system.cgi?msubmenu=deviceinfo&action=view");
|
|
request.Credentials = new NetworkCredential(MainForm.cam_username, MainForm.cam_password);
|
|
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
|
string text;
|
|
using (var sr = new StreamReader(response.GetResponseStream())) { text = sr.ReadToEnd(); }
|
|
string[] resp_lines = text.Split('\n');
|
|
string location_line = Array.Find(resp_lines, line => line.Trim().StartsWith("DeviceLocation="));
|
|
string serial_line = Array.Find(resp_lines, line => line.Trim().StartsWith("SerialNumber="));
|
|
string location = "";
|
|
string serial = "";
|
|
if (location_line != null)
|
|
{
|
|
location = location_line.Substring("DeviceLocation=".Length).Trim();
|
|
}
|
|
if (serial_line != null)
|
|
{
|
|
serial = serial_line.Substring("SerialNumber=".Length).Trim();
|
|
}
|
|
|
|
Camera new_camera = new Camera("Camera " + cam_addr + " - " + location + " - " + serial, cam_addr.ToString(), location, serial);
|
|
|
|
add_camera(new_camera);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void add_camera(Camera new_camera)
|
|
{
|
|
if (all_cameras.Count == 0)
|
|
{
|
|
all_cameras.Add(new_camera);
|
|
}
|
|
else
|
|
{
|
|
Camera find_cam = all_cameras.FirstOrDefault(cam => cam.camera_serial == new_camera.camera_serial);
|
|
|
|
if (find_cam != null)
|
|
{
|
|
int i = all_cameras.IndexOf(find_cam);
|
|
all_cameras[i] = new_camera;
|
|
}
|
|
else
|
|
{
|
|
all_cameras.Add(new_camera);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ServiceRemoved(object sender, ServiceAnnouncementEventArgs args)
|
|
{
|
|
foreach (var cam_ip in args.Announcement.Addresses)
|
|
{
|
|
if (cam_ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
|
{
|
|
foreach (var camera in all_cameras)
|
|
{
|
|
if (cam_ip.ToString() == camera.camera_ip)
|
|
{
|
|
all_cameras.Remove(camera);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
|
|
{
|
|
browser.StopBrowse();
|
|
}
|
|
|
|
private void lbMain_MouseDoubleClick(object sender, MouseEventArgs e)
|
|
{
|
|
if (lbMain.SelectedItem != null)
|
|
{
|
|
toolStripStatusLabel.Text = "Loading camera...";
|
|
Camera camera = all_cameras.FirstOrDefault<Camera>(cam => cam.camera_ip.ToString() == lbMain.SelectedValue.ToString());
|
|
Form viewer = new StreamViewer(lbMain.GetItemText(lbMain.SelectedItem), lbMain.SelectedValue.ToString(), camera, this);
|
|
viewer.Show();
|
|
toolStripStatusLabel.Text = "";
|
|
}
|
|
}
|
|
|
|
private void startToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
browse(true);
|
|
}
|
|
|
|
private void stopToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
browse(false);
|
|
}
|
|
|
|
private void forceReloadToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
DialogResult result = MessageBox.Show("Are you sure you want to clear discovered cameras and restart the discovery process ?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
|
if (result == DialogResult.Yes)
|
|
{
|
|
browse(false);
|
|
all_cameras.Clear();
|
|
browse(true);
|
|
}
|
|
}
|
|
|
|
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
string json = "";
|
|
OpenFileDialog openFile = new OpenFileDialog();
|
|
openFile.Filter = "json file (*.json)|*.json";
|
|
openFile.RestoreDirectory = true;
|
|
|
|
if (openFile.ShowDialog() == DialogResult.OK)
|
|
{
|
|
json = File.ReadAllText(openFile.FileName);
|
|
|
|
List<Camera> cameras_in_file = JsonSerializer.Deserialize<List<Camera>>(json);
|
|
|
|
foreach (Camera new_camera in cameras_in_file)
|
|
{
|
|
add_camera(new_camera);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
string json = JsonSerializer.Serialize<BindingList<Camera>>(all_cameras, new JsonSerializerOptions
|
|
{
|
|
WriteIndented = true
|
|
});
|
|
SaveFileDialog saveFile = new SaveFileDialog();
|
|
saveFile.Filter = "json file (*.json)|*.json";
|
|
saveFile.RestoreDirectory = true;
|
|
|
|
if (saveFile.ShowDialog() == DialogResult.OK)
|
|
{
|
|
File.WriteAllText(saveFile.FileName, json);
|
|
}
|
|
}
|
|
}
|
|
} |