def _handle_async(self): """ Handles async (usually sensor) messages form sphero, It calls the a parser function which will call any regstered callback for each type of data """ id_code = ord(self.bluetooth.receive(1)) length_msb = ord(self.bluetooth.receive(1)) length_lsb = ord(self.bluetooth.receive(1)) length = (length_msb << 8) + length_lsb array = self._read(length, offset=3) array[0] = id_code array[1] = length_msb array[2] = length_lsb checksum = check_sum(array[0:-1]) if array[-1] != checksum: eprint("Malfromed Packet, recieved: {0} expected: {1}".format( array[-1], checksum)) return else: data = array[3:-1] tocall = self._asyn_func.get(id_code, nothing) thread = threading.Thread(target=tocall, args=(data, )) thread.start() return
def connect(self, address=None, suppress_exceptions=False): """ Returns True if a connection is successfully made, False otherwise. `address` is bluetooth address, that must be set previously or given as a keyword argument. If `suppress_exceptions` is set to `True` exceptions thrown by the bluetooth library will be suppressed, and the function will return false. If there is a current connection it is closed before an attempt to connect is made. """ if address is not None: self.address = address if self.address is None: return False self.close() try: self._socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM) self._socket.connect((self.address, self.port)) return True except bluetooth.BluetoothError as error: if self._socket is not None: self._socket.close() self._socket = None if suppress_exceptions: eprint(error.message) return False else: raise BluetoothException(error.message) return False
def _handle_acknowledge(self): """ Parses response packets from sphero. Response added to a response dictionary as a Response tuple where tuple[0] indicates success and tuple[1] is the data, the thread waiting on the response is alerted to it via an event registered in the response_event_lookup dictionary, and is responsible for parsing the data. all access should be done with the response_lock. """ msrp = ord(self.bluetooth.receive(1)) seq = ord(self.bluetooth.receive(1)) length = ord(self.bluetooth.receive(1)) if length == 0xff: pass # raise Exception("NOt Implemented _MSRP: {0}".format(_msrp)) # TODO cover oxff cases array = self._read(length, offset=3) array[0] = msrp array[1] = seq array[2] = length checksum = check_sum(array[0:-1]) if array[-1] != checksum: eprint("Malfromed Packet, recieved: {0} expected: {1}".format( array[-1], checksum)) return else: event = None with self._response_lock: if seq in self._response_event_lookup: event = self._response_event_lookup[seq] del self._response_event_lookup[seq] else: return if msrp == 0: self._responses[seq] = Response(True, array[3:length + 3 - 1]) else: self._responses[seq] = Response( False, _MSRP.get(msrp, "UNKNOWN ERROR")) event.set()
def _recieve_loop(self): """ recieves data from sphero and parses it""" packet = bytearray(2) while self.bluetooth.is_connected(): # state one try: # bytearray needs ord packet[0] = 0 while packet[0] != _SOP1: packet[0] = ord(self.bluetooth.receive(1)) # state two packet[1] = ord(self.bluetooth.receive(1)) packet_type = packet[1] if packet_type == _ACKNOWLEDGMENT: # Sync Packet self._handle_acknowledge() elif packet_type == _ASYNC: self._handle_async() else: eprint("Malformed Packet") except Exception as error: continue