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()
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))
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
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
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