chrizog / someipy

A Python Library implementing the SOME/IP Protocol
https://chrizog.github.io/someipy/
GNU General Public License v3.0
28 stars 7 forks source link

ServiceDiscoveryProtocol can not receive unicast datagram #15

Closed dayangshanbaoye closed 1 month ago

dayangshanbaoye commented 1 month ago

I created an ServiceDiscoveryProtocol instance with params, and attach it with an ServerServiceInstance.

The wired thing is this ServiceDiscoveryProtocol can not receive unicast datagram, though it can receive multicast datagrams. It seems that sd.unicast_transport is not working

from wireshark or CANoe, i'm sure that the unicast datagram [subscribe event group message from 172.16.64.43] has been sent out

snippets from service_discovery.py ############################################################## loop = asyncio.get_running_loop() sd.unicasttransport, = await loop.create_datagram_endpoint( lambda: DatagramAdapter(target=sd), sock=create_udp_socket(unicast_ip, sd_port), ) get_logger(_logger_name).debug("unicast_transport: {sd.unicast_transport}") sd.mcasttransport, = await loop.create_datagram_endpoint( lambda: DatagramAdapter(target=sd), sock=create_rcv_multicast_socket(multicast_group_ip, sd_port, unicast_ip), ) get_logger(_logger_name).debug("mcast_transport: {sd.mcast_transport}") ##############################################################

chrizog commented 1 month ago

Hi, maybe the issue lies outside the library. Are you sure the netmask is configured correctly on sender and especially on receiver side? Maybe the IP packet is dropped by the OS.

dayangshanbaoye commented 1 month ago

I solved this problem by using self.unicast_transport other than self.sender_socket. Which means:

  1. delete this line in ServiceDiscoveryProtocol object, which is defined in service_discovery.py

    self.sender_socket = create_udp_socket(interface_ip, sd_port)

  2. replace sender_socket with unicast_transport in both send_multicast and send_unicast. def send_multicast(self, buffer: bytes) -> None:

    self.sender_socket.sendto(buffer, (self.multicast_ip, self.sd_port))

    **self.unicast_transport**.sendto(buffer, (self.multicast_ip, self.sd_port))

    def send_unicast(self, buffer: bytes, dest_ip: ipaddress.IPv4Address) -> None:

    self.sender_socket.sendto(buffer, (str(dest_ip), self.sd_port))

    **self.unicast_transport**.sendto(buffer, (str(dest_ip), self.sd_port))

    But I'm not clear why would this happen, maybe you can have a check

chrizog commented 1 month ago

Can you please describe your testing environment? Are you using Windows or Linux and which exact versions? Which Python version are you using? In the issue you wrote that the receiving is not working. I don't understand why you need to change the sockets used for sending then in the second comment if the reception of packets is not working. If you can give some more details about the setup, I hope I can support you with the issue. Thanks!

dayangshanbaoye commented 1 month ago

I'm using windows, and the python version is 3.12.4. The scenario looks like this. I create a Server Service Instance, with IP 172.16.66.79, it will create a Service Discovery at the same time.

Then I change the code as I mention, the failed one works as well. Also I can see the Service Discovery sends out subscribe ack to the real ECU.

One more thing, with you origin code, I see the same process would create the same socket twice [for example, 172.16.66.79:30490], which can be seen by cmd command: netstat -aon

chrizog commented 1 month ago

@dayangshanbaoye I could not recreate the issue that you had. I am also using Windows 11 and Python 3.12.4 in combination with a Raspberry Pi. But you are right, the additional socket "sender_socket" is not needed. I believe it's a leftover which I used to ensure the source IP address was correct. However, this is already solved by passing a socket to the asyncio create_datagram_endpoint call. I merged the change to master. It would be great if you can test it again. You can build the pip package from local source by using "pip install -e ." or "pip3 install -e .". If it works, please leave a comment, so I could close the issue. Thanks for your investigations!

dayangshanbaoye commented 1 month ago

I was on a vacation for last week, and I'll close this issue as you have completed it in issue #16.