Discover camera in DHCP mode

We always set our cameras to a persistent static IP address on 192.168.x.x and connect them directly to the NIC also addressed statically within the same subnet.
However, when we have to replace a camera, it comes out of the box configured with DHCP on 169.254.x.x and Aravis cannot see it (arv-tool-0.8 says no devices are connected).
If I change the IP configuration on the NIC to the known subnet (169.254.x.x) it can then see the camera and i can set the persistent IP, change the NIC address back and move on.
The Basler Pylon software that comes with the camera and runs on Windows does this somehow without having to change the NIC address. Is there something I’m missing? Does Aravis provide a method for camera discovery (via broadcast maybe) that i’m unaware of? Can I plug in a camera with DHCP default address and detect it and set the persistent IP from Aravis without having to mess with the NIC’s addressing?

Thanks so much!
-Brian

arv-tool-0.8 --debug=all
[11:47:00.577] 🅸 interface> [GvDiscoverSocket::new] Add interface 127.0.0.1 (127.0.0.1)
[11:47:00.578] 🅸 interface> [GvDiscoverSocket::new] Add interface 192.168.1.1 (192.168.1.255)
[11:47:00.578] 🅸 interface> [GvDiscoverSocket::new] Add interface 172.28.18.82 (172.28.18.255)
No device found

i suppose i should mention we are running on Gentoo with no Avahi daemon. When we were previously running on Windows, the eBus Player always had a way to discover and address cameras that were outside of the current subnet for the NIC. Is this available in Aravis? and if so, is it possible we’re missing a configuration on our Linux image?
Thanks.

Aravis does not see devices configured with a wrong subnet with respect to the NIC it is connected to because aravis binds its listening socket to the NIC address.

A possible solution would be to bind the socket to INADDR_ANY and use SO_BINDTODEVICE socket option. This would allow aravis to receive any discovery acknowledge packets on any interface. Something like that in arv_gv_interface.c:

                any_address = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
                any_socket_address = g_inet_socket_address_new (any_address, 0);
		g_socket_bind (discover_socket->socket, any_socket_address, FALSE, &error);
                g_object_unref (any_socket_address);
                g_object_unref (any_address);

                interface_name = arv_network_interface_get_name (iface_iter->data);
                socket_fd = g_socket_get_fd(discover_socket->socket);
                setsockopt (socket_fd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen (interface_name));

Using the same logic in arv_gv_device.c and arv_gv_stream.c, I think it should be possible to control and stream from an incorrectly configured device.

I don’t if this work with Windows though.

Emmanuel.

Thanks Emmanuel.
I will continue to look into this with your suggestion.
Just to be clear, i’m not trying to control and stream from the misconfigurated camera, but instead just be able to detect it and change its IP address configuration so that it is no longer misconfigured.
What is the expected procedure for this?
Is it just to change the interface configuration from static to DHCP so that we can detect the camera, then change its (the camera) IP address to the static subnet and then reconfigure the interface back to the preferred static subnet?

Thanks so much!
-Brian

This came up a few times already (IIRC, but can’t find much now) ,since all manufacturer’s tools I have seen do discover camers on foreign subnet: e.g. this comment by Emmanuel from 2017 says about arv-tool:

The address parameter is used as a filter on the discovered devices. It does not allow to access a device that doesn’t answer to a discovery command, just like arv-viewer.

And then, this recent commit 8c17c4b called “gv: option to allow broadcast discovery ack” — is it relevant to the issue?

It may help, but that is not enough. I have created a new draft pull request with the code I have mentioned in my previous comment. The pull request is incomplete as the change is only implemented in the gv_interface code. The same should be done in gv_device and gv_stream.