def getsocketopt(self, option):
        """
        Returns the value of the given socket option.

        Args:
            option (:class:`.SocketOption`): the socket option to get its value.

        Returns:
            Bytearray: the value of the socket option.

        Raises:
            TimeoutException: if the socket option response is not received in the configured timeout.
            ValueError: if the option to set is ``None``.
            XBeeException: if the connection with the XBee device is not open.
            XBeeSocketException: if the socket option response status is not ``SUCCESS``.
        """
        if option is None:
            raise ValueError("Option to get cannot be None")
        if not self.__xbee_device.is_open():
            raise XBeeException("XBee device must be open")

        # If the socket is not created, create it first.
        if self.__socket_id is None:
            self.__create_socket()

        # Create, send and check the socket option packet.
        option_packet = SocketOptionRequestPacket(
            self.__xbee_device.get_next_frame_id(), self.__socket_id, option)
        response_packet = self.__xbee_device.send_packet_sync_and_get_response(
            option_packet, timeout=self.__get_timeout())
        self.__check_response(response_packet)

        # Return the option data.
        return response_packet.option_data
    def close(self):
        """
        Closes the socket.

        Raises:
            TimeoutException: if the close response is not received in the configured timeout.
            XBeeException: if the connection with the XBee device is not open.
            XBeeSocketException: if the close status is not ``SUCCESS``.
        """
        if self.__socket_id is None or (not self.__connected
                                        and not self.__source_port):
            return
        if not self.__xbee_device.is_open():
            raise XBeeException("XBee device must be open")

        close_packet = SocketClosePacket(
            self.__xbee_device.get_next_frame_id(), self.__socket_id)
        response_packet = self.__xbee_device.send_packet_sync_and_get_response(
            close_packet, timeout=self.__get_timeout())
        self.__check_response(response_packet)

        self.__connected = False
        self.__socket_id = None
        self.__source_port = None
        self.__data_received = bytearray()
        self.__data_received_from_dict = OrderedDict()
        self.__unregister_state_callback()
        self.__unregister_data_received_callback()
        self.__unregister_data_received_from_callback()
Exemple #3
0
    def __prepare_device(self):
        """
        Performs the local XBee configuration before sending the ZDO command. This saves the
        current AO value and sets it to 1.
        """
        if not self.__configure_ao:
            return

        if not self._xbee.is_remote():
            xb = self._xbee
        else:
            xb = self._xbee.get_local_xbee_device()

        try:
            self.__saved_ao = xb.get_api_output_mode_value()

            # Do not configure AO if it is already
            if utils.is_bit_enabled(self.__saved_ao[0], 0):
                self.__saved_ao = None
                return

            value = APIOutputModeBit.calculate_api_output_mode_value(self._xbee.get_protocol(),
                                                                     {APIOutputModeBit.EXPLICIT})
            xb.set_api_output_mode_value(value)

        except XBeeException as e:
            raise XBeeException("Could not prepare XBee for ZDO: " + str(e))
Exemple #4
0
    def __send(self, data, send_all=True):
        """
        Sends data to the socket. The socket must be connected to a remote
        socket. Depending on the value of `send_all`, the method will raise an
        exception or return the number of bytes sent when there is an error
        sending a data packet.

        Args:
            data (Bytearray): The data to send.
            send_all (Boolean): `True` to raise an exception when there is an
                error sending a data packet. `False` to return the number of
                bytes sent when there is an error sending a data packet.

        Raises:
            TimeoutException: If the send status response is not received in
                the configured timeout.
            ValueError: If the data to send is `None`.
            ValueError: If the number of bytes to send is `0`.
            XBeeException: If the connection with the XBee device is not open.
            XBeeSocketException: If the socket is not valid.
            XBeeSocketException: If the send status is not `SUCCESS`.
            XBeeSocketException: If the socket is not open.
        """
        if data is None:
            raise ValueError("Data to send cannot be None")
        if len(data) == 0:
            raise ValueError("The number of bytes to send must be at least 1")
        if self.__socket_id is None:
            raise XBeeSocketException(status=SocketStatus.BAD_SOCKET)
        if not self.__xbee.is_open():
            raise XBeeException("XBee device must be open")
        if not self.__connected:
            raise XBeeSocketException(message="Socket is not connected")

        sent_bytes = None if send_all else 0

        # Send as many packets as needed to deliver all the provided data.
        for chunk in self.__split_payload(data):
            send_packet = SocketSendPacket(self.__xbee.get_next_frame_id(),
                                           self.__socket_id, chunk)
            try:
                response_packet = self.__xbee.send_packet_sync_and_get_response(
                    send_packet, timeout=self.__get_timeout())
                self.__check_response(response_packet)
            except (TimeoutException, XBeeSocketException) as exc:
                # Raise the exception only if 'send_all' flag is set, otherwise
                # return the number of bytes sent.
                if send_all:
                    raise exc
                return sent_bytes
            # Increase the number of bytes sent.
            if not send_all:
                sent_bytes += len(chunk)
        # Return the number of bytes sent.
        return sent_bytes
Exemple #5
0
    def sendto(self, data, address):
        """
        Sends data to the socket. The socket should not be connected to a
        remote socket, since the destination socket is specified by `address`.

        Args:
            data (Bytearray): The data to send.
            address (Tuple): The address of the destination socket. It must be
                a pair `(host, port)` where `host` is the domain name or string
                representation of an IPv4 and `port` is the numeric port value.

        Returns:
            Integer: The number of bytes sent.

        Raises:
            TimeoutException: If the send status response is not received in
                the configured timeout.
            ValueError: If the data to send is `None`.
            ValueError: If the number of bytes to send is `0`.
            XBeeException: If the connection with the XBee device is not open.
            XBeeSocketException: If the socket is already open.
            XBeeSocketException: If the send status is not `SUCCESS`.
        """
        if data is None:
            raise ValueError("Data to send cannot be None")
        if len(data) == 0:
            raise ValueError("The number of bytes to send must be at least 1")
        if not self.__xbee.is_open():
            raise XBeeException("XBee device must be open")
        if self.__connected:
            raise XBeeSocketException(message="Socket is already connected")

        sent_bytes = 0

        # If the socket is not created, create it first.
        if self.__socket_id is None:
            self.__create_socket()
        # Send as many packets as needed to deliver all the provided data.
        for chunk in self.__split_payload(data):
            send_packet = SocketSendToPacket(self.__xbee.get_next_frame_id(),
                                             self.__socket_id,
                                             IPv4Address(address[0]),
                                             address[1], chunk)
            response_packet = self.__xbee.send_packet_sync_and_get_response(
                send_packet, timeout=self.__get_timeout())
            self.__check_response(response_packet)
            sent_bytes += len(chunk)
        # Return the number of bytes sent.
        return sent_bytes
Exemple #6
0
    def __init__(self, xbee_device, ip_protocol=IPProtocol.TCP):
        """
        Class constructor. Instantiates a new XBee socket object for the given
        XBee device.

        Args:
            xbee_device (:class:`.XBeeDevice`): XBee device of the socket.
            ip_protocol (:class:`.IPProtocol`): protocol of the socket.

        Raises:
            ValueError: if `xbee_device` is `None` or if `xbee_device` is not
                an instance of `CellularDevice`.
            ValueError: if `ip_protocol` is `None`.
            XBeeException: if the connection with the XBee device is not open.
        """
        if xbee_device is None:
            raise ValueError("XBee device cannot be None")
        if not isinstance(xbee_device, CellularDevice):
            raise ValueError("XBee device must be a Cellular device")
        if ip_protocol is None:
            raise ValueError("IP protocol cannot be None")
        if not xbee_device.is_open():
            raise XBeeException("XBee device must be open")

        # Initialize internal vars.
        self.__xbee = xbee_device
        self.__ip_protocol = ip_protocol
        self.__socket_id = None
        self.__connected = False
        self.__src_port = None
        self.__is_listening = False
        self.__backlog = None
        self.__timeout = self.__DEFAULT_TIMEOUT
        self.__data_received = bytearray()
        self.__data_received_lock = threading.Lock()
        self.__data_received_from_dict = OrderedDict()
        self.__data_received_from_dict_lock = threading.Lock()
        # Initialize socket callbacks.
        self.__socket_state_cb = None
        self.__data_received_cb = None
        self.__data_received_from_cb = None