Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not restored after entering IDLE during TX #30

Open
viaSeunghyun opened this issue Oct 17, 2023 · 0 comments
Open

Not restored after entering IDLE during TX #30

viaSeunghyun opened this issue Oct 17, 2023 · 0 comments

Comments

@viaSeunghyun
Copy link

          @viaSeunghyun with the implementation the sockets are unidirectional. On one end of the socket is opened for sending, the other for receiving. The socket `/run/e32.data` is waiting - `recvfrom` for clients to `sendto` it. In this case the socket `/run/e32.rx.data` which the `e32rx` program has bound is waiting for the `e32` program to `sendto`. This is because `e32rx` has registered the `/run/e32.rx.data` socket. When the `e32` receives data it will loop through all registered sockets and `sendto` data with the source as the `/run/e32.data` socket.

The problem we have here - at least I think - is that the e32tx has registered the socket /run/e32.tx.data for acknowledging transmissions but it's not listening on the socket after transmissions. Since the /run/e32.tx.data socket is registered when the e32 receives data it will try to send the data that it receives to it. But the e32tx program isn't recvfrom on this socket so the e32 program is blocked waiting to send the datagram. This is why I mentioned we should 1) not register /run/e32.tx.data or 2) we should recvfrom it. This would involve asynchronous I/O like using the poll system call. This is why 1 makes more sense. Because the Unix domain sockets are connectionless the /run/e32.tx.data serves a second purpose. That is when the client sends something to the e32 socket of /run/e32.data it can write back to that socket to acknowledge it was sent. It is this dual purpose nature that is confusing and be changed.

Regardless, this problem you have found is addressed, a change could be implemented to at least timeout when the e32 does a loop through the registered sockets and timeout if it cannot sendto a registered socket.

When writing, the clients if they have both tx and rx clients then it needs a way to be able to recvfrom all the registered sockets in any order. If the client has two sockets it cannot be blocked waiting recvfrom on socket 1 when socket 2 has data. This makes the implementation of clients challenging. Hence, the poll system call. Again, in this case the client realistically should only have a single socket open for receiving and not two. Since here the e32tx socket is intended to be for acknowledgement and not for receiving data. Also, it was intended to run and close the socket and not be in a loop.

The code looks quite good. However, in this section:

        try:
            (msg, address) = self.client_sock_rx.recvfrom(59)
            print(f"received from {address} {len(msg)} bytes with {msg}")

            self.rx_buffer += msg

            # to not block we would have to self.client_sock_tx.recvfrom()

        except BlockingIOError:
            # print(f"no received this time")
            pass
        pass

The e32 is also sending data to self.client_sock_tx since it was registered. If you were to recvfrom it after you recvfrom the rx it would work. But as mentioned this is pointless.

Thus, could you remove the following section so that received data will not be sent to

        if debug:
            print(f"Registering Socket {self.client_sock_tx_path} to {self.driver_sock_path}")

        self.client_sock_tx.sendto(b'', self.driver_sock_path)
        (msg, address) = self.client_sock_tx.recvfrom(10)

        if len(msg) != 1 or msg[0] != 0:
            print("Unable to Register TX Client")
            raise LoRa.Ebyte_Exception.DriverConnectionError
        else:
            if debug:
                print("TX Client Registered")

This way there is no registered socket for the transmitting side.

Again, the problem here is that the /run/e32.tx.data socket is registered for both TX acknowledgement and receiving data. Since the tx socket it's not being listened on it is blocking the e32 program. I need some time to think about the best path forward here.

Originally posted by @lloydroc in #29 (comment)

@viaSeunghyun viaSeunghyun changed the title @viaSeunghyun with the implementation the sockets are unidirectional. On one end of the socket is opened for sending, the other for receiving. The socket /run/e32.data is waiting - recvfrom for clients to sendto it. In this case the socket /run/e32.rx.data which the e32rx program has bound is waiting for the e32 program to sendto. This is because e32rx has registered the /run/e32.rx.data socket. When the e32 receives data it will loop through all registered sockets and sendto data with the source as the /run/e32.data socket. Not restored after entering IDLE during TX Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant