def frame_rcvd_raw(self, frame_bytes): '''Callback for each received message.''' # Sanity check packet length. if len(frame_bytes) < 14: logger.warning(self.port.lbl + ': Packet too short.') return if len(frame_bytes) > 1550: logger.warning(self.port.lbl + ': Packet too long.') return # Update the received-data count. with self.batch_lock: self.rcvd_count += 1 self.batch_rxbytes += len(frame_bytes) # Parse Ethernet frame into components. assert len(frame_bytes) > 14 assert len(frame_bytes) < 1550 mac_dst = frame_bytes[0:6] mac_src = frame_bytes[6:12] etype = frame_bytes[12:14] payload = frame_bytes[14:] # Reject messages from our own source address. # (Network drivers may echo broadcast packets.) if (mac_src == self.port.mac): return # Reject messages that aren't for us. if (mac_dst != self.MAC_BCAST) and (mac_dst != self.port.mac): return # Handle message based on Ethertype: if (etype == self.ETYPE_BEAT): if self.LOG_VERBOSE: logger.info(self.port.lbl + ': Got heartbeat from ' + ethernet_utils.mac2str(mac_src)) self.frame_rcvd_beat(mac_src, self._decode_string(payload)) elif (etype == self.ETYPE_CHAT): if self.LOG_VERBOSE: logger.info(self.port.lbl + ': Got chat from ' + ethernet_utils.mac2str(mac_src)) self.frame_rcvd_chat(mac_src, self._decode_string(payload)) elif (etype == self.ETYPE_DATA): if self.LOG_VERBOSE: logger.info(self.port.lbl + ': Got data from ' + ethernet_utils.mac2str(mac_src)) else: [etype_int] = unpack('>H', etype) logger.info(self.port.lbl + ': Unrecognized EtherType 0x%04X' % etype_int)
def connect(self, port_obj): '''Connect to specified port object.''' # Connect and start both worker threads. self.port = port_obj self._heartbeat_run = True self._heartbeat_thread.start() self._auto_data_thread.start() self._auto_text_thread.start() self.batch_timer.start(125) # 8 updates/sec # Update and launch GUI. self.setWindowTitle('Chat: ' + port_obj.lbl) self.txt_macaddr.setText(ethernet_utils.mac2str(port_obj.mac)) self.txt_username.setText(port_obj.lbl) self.username = port_obj.lbl self.show()
def frame_rcvd_chat(self, mac_src, msg_str): '''Received chat message, update displayed list.''' # Inspect message contents. if len(msg_str) == 0: logger.error(self.port.lbl + ': Invalid chat message.') return if not msg_str.endswith('\n'): msg_str += '\n' # Format message (including sender information) if mac_src in self.rcvd_macs.keys(): lbl_src = self.rcvd_macs[mac_src] else: lbl_src = ethernet_utils.mac2str(mac_src) msg_txt = 'From ' + lbl_src + ':\n' + msg_str # Queue this message for next GUI update. with self.batch_lock: self.batch_msgs.append(msg_txt)
def _format_address(self, mac_src, label=''): if label: return ethernet_utils.mac2str(mac_src) + ' (%s)' % label else: return ethernet_utils.mac2str(mac_src)