Example #1
0
    async def _on_event(self, msg):
        found_handshake = False
        jmsg = json.loads(msg)

        if jmsg['tag'] == 'wifi.client.handshake':
            filename = jmsg['data']['file']
            sta_mac = jmsg['data']['station']
            ap_mac = jmsg['data']['ap']
            key = "%s -> %s" % (sta_mac, ap_mac)
            if key not in self._handshakes:
                self._handshakes[key] = jmsg
                s = self.session()
                ap_and_station = self._find_ap_sta_in(sta_mac, ap_mac, s)
                if ap_and_station is None:
                    logging.warning("!!! captured new handshake: %s !!!", key)
                    self._last_pwnd = ap_mac
                    plugins.on('handshake', self, filename, ap_mac, sta_mac)
                else:
                    (ap, sta) = ap_and_station
                    self._last_pwnd = ap[
                        'hostname'] if ap['hostname'] != '' and ap[
                            'hostname'] != '<hidden>' else ap_mac
                    logging.warning(
                        "!!! captured new handshake on channel %d, %d dBm: %s (%s) -> %s [%s (%s)] !!!",
                        ap['channel'], ap['rssi'], sta['mac'], sta['vendor'],
                        ap['hostname'], ap['mac'], ap['vendor'])
                    plugins.on('handshake', self, filename, ap, sta)
                found_handshake = True
            self._update_handshakes(1 if found_handshake else 0)
Example #2
0
    def set_channel(self, channel, verbose=True):
        if self.is_stale():
            logging.debug("recon is stale, skipping set_channel(%d)", channel)
            return

        # if in the previous loop no client stations has been deauthenticated
        # and only association frames have been sent, we don't need to wait
        # very long before switching channel as we don't have to wait for
        # such client stations to reconnect in order to sniff the handshake.
        wait = 0
        if self._epoch.did_deauth:
            wait = self._config['personality']['hop_recon_time']
        elif self._epoch.did_associate:
            wait = self._config['personality']['min_recon_time']

        if channel != self._current_channel:
            if self._current_channel != 0 and wait > 0:
                if verbose:
                    logging.info("waiting for %ds on channel %d ...", wait, self._current_channel)
                else:
                    logging.debug("waiting for %ds on channel %d ...", wait, self._current_channel)
                self.wait_for(wait)
            if verbose and self._epoch.any_activity:
                logging.info("CHANNEL %d", channel)
            try:
                self.run('wifi.recon.channel %d' % channel)
                self._current_channel = channel
                self._epoch.track(hop=True)
                self._view.set('channel', '%d' % channel)

                plugins.on('channel_hop', self, channel)

            except Exception as e:
                logging.error("Error while setting channel (%s)", e)
Example #3
0
 def init_display(self):
     if self._enabled:
         self._implementation.initialize()
         plugins.on('display_setup', self._implementation)
     else:
         logging.warning("display module is disabled")
     self.on_render(self._on_view_rendered)
Example #4
0
    def next_epoch(self):
        was_stale = self.is_stale()
        did_miss = self._epoch.num_missed

        self._epoch.next()

        # after X misses during an epoch, set the status to lonely
        if was_stale:
            logging.warning("agent missed %d interactions -> lonely" % did_miss)
            self.set_lonely()
        # after X times being bored, the status is set to sad
        elif self._epoch.inactive_for >= self._config['personality']['sad_num_epochs']:
            logging.warning("%d epochs with no activity -> sad" % self._epoch.inactive_for)
            self.set_sad()
        # after X times being inactive, the status is set to bored
        elif self._epoch.inactive_for >= self._config['personality']['bored_num_epochs']:
            logging.warning("%d epochs with no activity -> bored" % self._epoch.inactive_for)
            self.set_bored()
        # after X times being active, the status is set to happy / excited
        elif self._epoch.active_for >= self._config['personality']['excited_num_epochs']:
            logging.warning("%d epochs with activity -> excited" % self._epoch.active_for)
            self.set_excited()

        plugins.on('epoch', self, self._epoch.epoch - 1, self._epoch.data())

        if self._epoch.blind_for >= self._config['main']['mon_max_blind_epochs']:
            logging.critical("%d epochs without visible access points -> rebooting ..." % self._epoch.blind_for)
            self._reboot()
            self._epoch.blind_for = 0
Example #5
0
    def update(self, force=False, new_data={}):
        for key, val in new_data.items():
            self.set(key, val)

        with self._lock:
            if self._frozen:
                return

            state = self._state
            changes = state.changes(ignore=self._ignore_changes)
            if force or len(changes):
                self._canvas = Image.new('1', (self._width, self._height), WHITE)
                drawer = ImageDraw.Draw(self._canvas)

                plugins.on('ui_update', self)

                for key, lv in state.items():
                    lv.draw(self._canvas, drawer)

                web.update_frame(self._canvas)

                for cb in self._render_cbs:
                    cb(self._canvas)

                self._state.reset()
Example #6
0
 def set_access_points(self, aps):
     self._access_points = aps
     plugins.on('wifi_update', self, aps)
     self._epoch.observe(
         aps,
         self._advertiser.peers() if self._advertiser is not None else ())
     return self._access_points
Example #7
0
    def update(self, force=False, new_data={}, with_lock=True):
        for key, val in new_data.items():
            self.set(key, val)

        maybe_lock = self._lock if with_lock else nullcontext()

        with maybe_lock:
            if self._frozen:
                return

            state = self._state
            changes = state.changes(ignore=self._ignore_changes)
            min_changes = 2 if self._config['ui']['fps'] == 0.0 else 0
            if force or len(changes) > min_changes:
                logging.debug("Update screen because %s", 'it was forced.' if force else f"{changes} triggered it.")
                self._canvas = Image.new('1', (self._width, self._height), WHITE)
                drawer = ImageDraw.Draw(self._canvas)

                plugins.on('ui_update', self)

                for key, lv in state.items():
                    lv.draw(self._canvas, drawer)

                if self._config['ui']['web']['dark']:
                    print(self._canvas.mode)
                    self._canvas = ImageOps.invert(self._canvas.convert('L')).convert('1')

                web.update_frame(self._canvas)

                for cb in self._render_cbs:
                    cb(self._canvas)

                self._state.reset()
Example #8
0
 def on_handshake(self, agent, filename, access_point, client_station):
     display = agent.view()
     result = subprocess.run(('/usr/bin/aircrack-ng ' + filename +
                              ' | grep "1 handshake" | awk \'{print $2}\''),
                             shell=True,
                             stdout=subprocess.PIPE)
     result = result.stdout.decode('utf-8').translate(
         {ord(c): None
          for c in string.whitespace})
     if not result:
         logging.info('[quickdic] No handshake')
     else:
         logging.info('[quickdic] Handshake confirmed')
         result2 = subprocess.run(
             ('aircrack-ng -w `echo ' + self.options['wordlist_folder'] +
              '*.txt | sed \'s/ /,/g\'` -l ' + filename +
              '.cracked -q -b ' + result + ' ' + filename + ' | grep KEY'),
             shell=True,
             stdout=subprocess.PIPE)
         result2 = result2.stdout.decode('utf-8').strip()
         logging.info('[quickdic] %s', result2)
         if result2 != "KEY NOT FOUND":
             key = re.search(r'\[(.*)\]', result2)
             pwd = str(key.group(1))
             self.text_to_set = "Cracked password: " + pwd
             display.update(force=True)
             plugins.on('cracked', access_point, pwd)
Example #9
0
    def get_access_points(self):
        whitelist = self._config['main']['whitelist']
        restrict_to = self._config['main']['restrict_to']
        aps = []
        try:
            s = self.session()
            plugins.on("unfiltered_ap_list", self, s['wifi']['aps'])
            for ap in s['wifi']['aps']:
                if ap['encryption'] == '' or ap['encryption'] == 'OPEN':
                    continue
                elif len(restrict_to) > 0 and \
                        (ap['mac'].lower() in restrict_to or
                         ap['mac'][:8].lower() in restrict_to):
                    if self._filter_included(ap):
                        aps.append(ap)
                elif len(restrict_to) > 0:
                    # Fall through for above case
                    # We are restricting aps and this one is not wanted
                    continue
                elif ap['hostname'] not in whitelist \
                        and ap['mac'].lower() not in whitelist \
                        and ap['mac'][:8].lower() not in whitelist:
                    if self._filter_included(ap):
                        aps.append(ap)
        except Exception as e:
            logging.exception("Error while getting acces points (%s)", e)

        aps.sort(key=lambda ap: ap['channel'])
        return self.set_access_points(aps)
Example #10
0
    def on_internet_available(self, agent):
        with self.lock:
            logging.debug("[update] internet connectivity is available (ready %s)" % self.ready)

            if not self.ready:
                return

            if self.status.newer_then_hours(self.options['interval']):
                logging.debug("[update] last check happened less than %d hours ago" % self.options['interval'])
                return

            logging.info("[update] checking for updates ...")

            display = agent.view()
            prev_status = display.get('status')

            try:
                display.update(force=True, new_data={'status': 'Checking for updates ...'})

                to_install = []
                to_check = [
                    ('bettercap/bettercap', parse_version('bettercap -version'), True, 'bettercap'),
                    ('evilsocket/pwngrid', parse_version('pwngrid -version'), True, 'pwngrid-peer'),
                    ('evilsocket/pwnagotchi', pwnagotchi.__version__, False, 'pwnagotchi')
                ]

                for repo, local_version, is_native, svc_name in to_check:
                    info = check(local_version, repo, is_native)
                    if info['url'] is not None:
                        logging.warning(
                            "update for %s available (local version is '%s'): %s" % (
                                repo, info['current'], info['url']))
                        info['service'] = svc_name
                        to_install.append(info)

                num_updates = len(to_install)
                num_installed = 0

                if num_updates > 0:
                    if self.options['install']:
                        for update in to_install:
                            plugins.on('updating')
                            if install(display, update):
                                num_installed += 1
                    else:
                        prev_status = '%d new update%c available!' % (num_updates, 's' if num_updates > 1 else '')

                logging.info("[update] done")

                self.status.update()

                if num_installed > 0:
                    display.update(force=True, new_data={'status': 'Rebooting ...'})
                    pwnagotchi.reboot()

            except Exception as e:
                logging.error("[update] %s" % e)

            display.update(force=True, new_data={'status': prev_status if prev_status is not None else ''})
Example #11
0
    def set_training(self, training, for_epochs=0):
        self._is_training = training
        self._training_epochs = for_epochs

        if training:
            plugins.on('ai_training_start', self, for_epochs)
        else:
            plugins.on('ai_training_end', self)
Example #12
0
 def set_lonely(self):
     if not self._has_support_network_for(1.0):
         logging.info("unit is lonely")
         self._view.on_lonely()
         plugins.on('lonely', self)
     else:
         logging.info("unit is grateful instead of lonely")
         self.set_grateful()
Example #13
0
    def _init_display(self):
        if self.is_inky():
            logging.info("initializing inky display")
            from pwnagotchi.ui.inkyphat.inkyphatfast import InkyPHATFast
            self._display = InkyPHATFast(self._display_color)
            self._display.set_border(InkyPHATFast.BLACK)
            self._render_cb = self._inky_render

        elif self.is_papirus():
            logging.info("initializing papirus display")
            from pwnagotchi.ui.papirus.epd import EPD
            os.environ['EPD_SIZE'] = '2.0'
            self._display = EPD()
            self._display.clear()
            self._render_cb = self._papirus_render

        elif self.is_waveshare_v1():
            if self._display_color == 'black':
                logging.info(
                    "initializing waveshare v1 display in monochromatic mode")
                from pwnagotchi.ui.waveshare.v1.epd2in13 import EPD
                self._display = EPD()
                self._display.init(self._display.lut_full_update)
                self._display.Clear(0xFF)
                self._display.init(self._display.lut_partial_update)
                self._render_cb = self._waveshare_render

            else:
                logging.info("initializing waveshare v1 display 3-color mode")
                from pwnagotchi.ui.waveshare.v1.epd2in13bc import EPD
                self._display = EPD()
                self._display.init()
                self._display.Clear()
                self._render_cb = self._waveshare_bc_render

        elif self.is_waveshare_v2():
            logging.info("initializing waveshare v2 display")
            from pwnagotchi.ui.waveshare.v2.waveshare import EPD
            self._display = EPD()
            self._display.init(self._display.FULL_UPDATE)
            self._display.Clear(WHITE)
            self._display.init(self._display.PART_UPDATE)
            self._render_cb = self._waveshare_render

        elif self.is_oledhat():
            logging.info("initializing oledhat display")
            from pwnagotchi.ui.waveshare.oledhat.epd import EPD
            self._display = EPD()
            self._display.init()
            self._display.Clear()
            self._render_cb = self._oledhat_render

        else:
            logging.critical("unknown display type %s" % self._display_type)

        plugins.on('display_setup', self._display)

        self.on_render(self._on_view_rendered)
Example #14
0
 def set_angry(self, factor):
     if not self._has_support_network_for(factor):
         logging.warning("%d epochs with no activity -> angry",
                         self._epoch.inactive_for)
         self._view.on_angry()
         plugins.on('angry', self)
     else:
         logging.info("unit is grateful instead of angry")
         self.set_grateful()
Example #15
0
    def _event_poller(self):
        self._load_recovery_data()

        self.run('events.clear')

        while True:
            time.sleep(1)

            new_shakes = 0

            logging.debug("polling events ...")

            try:
                s = self.session()
                self._update_uptime(s)

                self._update_advertisement(s)
                self._update_peers()
                self._update_counters()

                for h in [
                        e for e in self.events()
                        if e['tag'] == 'wifi.client.handshake'
                ]:
                    filename = h['data']['file']
                    sta_mac = h['data']['station']
                    ap_mac = h['data']['ap']
                    key = "%s -> %s" % (sta_mac, ap_mac)

                    if key not in self._handshakes:
                        self._handshakes[key] = h
                        new_shakes += 1
                        ap_and_station = self._find_ap_sta_in(
                            sta_mac, ap_mac, s)
                        if ap_and_station is None:
                            logging.warning(
                                "!!! captured new handshake: %s !!!", key)
                            self._last_pwnd = ap_mac
                            plugins.on('handshake', self, filename, ap_mac,
                                       sta_mac)
                        else:
                            (ap, sta) = ap_and_station
                            self._last_pwnd = ap[
                                'hostname'] if ap['hostname'] != '' and ap[
                                    'hostname'] != '<hidden>' else ap_mac
                            logging.warning(
                                "!!! captured new handshake on channel %d, %d dBm: %s (%s) -> %s [%s (%s)] !!!",
                                ap['channel'], ap['rssi'], sta['mac'],
                                sta['vendor'], ap['hostname'], ap['mac'],
                                ap['vendor'])
                            plugins.on('handshake', self, filename, ap, sta)

            except Exception as e:
                logging.error("error: %s", e)

            finally:
                self._update_handshakes(new_shakes)
Example #16
0
 def set_sad(self):
     factor = self._epoch.inactive_for / self._config['personality']['sad_num_epochs']
     if not self._has_support_network_for(factor):
         logging.warning("%d epochs with no activity -> sad" % self._epoch.inactive_for)
         self._view.on_sad()
         plugins.on('sad', self)
     else:
         logging.info("unit is grateful instead of sad")
         self.set_grateful()
Example #17
0
    def check_inbox(self, agent):
        logging.debug("[grid] Checking mailbox...")
        messages = grid.inbox()
        self.total_messages = len(messages)
        self.unread_messages = len([m for m in messages if m['seen_at'] is None])

        if self.unread_messages:
            plugins.on('unread_inbox', self.unread_messages)
            logging.debug(f"[grid] unread:{self.unread_messages} total:{self.total_messages}")
            agent.view().on_unread_messages(self.unread_messages, self.total_messages)
Example #18
0
 def set_bored(self):
     factor = self._epoch.inactive_for / self._config['personality'][
         'bored_num_epochs']
     if not self._has_support_network_for(factor):
         logging.warning("%d epochs with no activity -> bored" %
                         self._epoch.inactive_for)
         self._view.on_bored()
         plugins.on('bored', self)
     else:
         self.set_grateful()
Example #19
0
 def custom_get_access_points(self):
     aps = []
     try:
         s = self.agent.session()
         plugins.on("unfiltered_ap_list", self.agent, s['wifi']['aps'])
         for ap in s['wifi']['aps']:
             if ap['encryption'] == '' or ap['encryption'] == 'OPEN':
                 continue
             if self.is_whitelisted(ap):
                 aps.append(ap)
     except Exception as e:
         logging.exception(f"Error while getting access points ({e})")
     aps.sort(key=lambda ap: ap['channel'])
     return self.agent.set_access_points(aps)
Example #20
0
    def get_access_points(self):
        whitelist = self._config['main']['whitelist']
        aps = []
        try:
            s = self.session()
            plugins.on("unfiltered_ap_list", self, s['wifi']['aps'])
            for ap in s['wifi']['aps']:
                if ap['hostname'] not in whitelist:
                    if self._filter_included(ap):
                        aps.append(ap)
        except Exception as e:
            logging.exception("error")

        aps.sort(key=lambda ap: ap['channel'])
        return self.set_access_points(aps)
Example #21
0
    def on_ai_policy(self, new_params):
        plugins.on('ai_policy', self, new_params)
        logging.info("[ai] setting new policy:")
        for name, value in new_params.items():
            if name in self._config['personality']:
                curr_value = self._config['personality'][name]
                if curr_value != value:
                    logging.info("[ai] ! %s: %s -> %s" % (name, curr_value, value))
                    self._config['personality'][name] = value
            else:
                logging.error("[ai] param %s not in personality configuration!" % name)

        self.run('set wifi.ap.ttl %d' % self._config['personality']['ap_ttl'])
        self.run('set wifi.sta.ttl %d' % self._config['personality']['sta_ttl'])
        self.run('set wifi.rssi.min %d' % self._config['personality']['min_rssi'])
Example #22
0
    def next_epoch(self):
        logging.debug("agent.next_epoch()")

        was_stale = self.is_stale()
        did_miss = self._epoch.num_missed

        self._epoch.next()

        # after X misses during an epoch, set the status to lonely or angry
        if was_stale:
            factor = did_miss / self._config['personality'][
                'max_misses_for_recon']
            if factor >= 2.0:
                self.set_angry(factor)
            else:
                logging.warning("agent missed %d interactions -> lonely" %
                                did_miss)
                self.set_lonely()
        # after X times being bored, the status is set to sad or angry
        elif self._epoch.inactive_for >= self._config['personality'][
                'sad_num_epochs']:
            factor = self._epoch.inactive_for / self._config['personality'][
                'sad_num_epochs']
            if factor >= 2.0:
                self.set_angry(factor)
            else:
                self.set_sad()
        # after X times being inactive, the status is set to bored
        elif self._epoch.inactive_for >= self._config['personality'][
                'bored_num_epochs']:
            self.set_bored()
        # after X times being active, the status is set to happy / excited
        elif self._epoch.active_for >= self._config['personality'][
                'excited_num_epochs']:
            self.set_excited()
        elif self._epoch.active_for >= 5 and self._has_support_network_for(
                5.0):
            self.set_grateful()

        plugins.on('epoch', self, self._epoch.epoch - 1, self._epoch.data())

        if self._epoch.blind_for >= self._config['main'][
                'mon_max_blind_epochs']:
            logging.critical(
                "%d epochs without visible access points -> rebooting ..." %
                self._epoch.blind_for)
            self._reboot()
            self._epoch.blind_for = 0
Example #23
0
    def update(self, force=False):
        with self._lock:
            changes = self._state.changes(ignore=self._ignore_changes)
            if force or len(changes):
                self._canvas = Image.new('1', (self._width, self._height), WHITE)
                drawer = ImageDraw.Draw(self._canvas)

                plugins.on('ui_update', self)

                for key, lv in self._state.items():
                    lv.draw(self._canvas, drawer)

                for cb in self._render_cbs:
                    cb(self._canvas)

                self._state.reset()
Example #24
0
    def associate(self, ap, throttle=0):
        if self.is_stale():
            logging.debug(f"Recon is stale, skipping assoc({ap['mac']}).")
            return

        if self._config['personality']['associate'] and self._should_interact(ap['mac']):
            self._view.on_assoc(ap)

            try:
                logging.info(f"Sending association frame to {ap['hostname']} ({ap['mac']} {ap['vendor']}) on channel {ap['channel']} [{len(ap['clients'])} clients], {ap['rssi']} dBm...")
                self.run(f"wifi.assoc {ap['mac']}")
                self._epoch.track(assoc=True)
            except Exception as e:
                self._on_error(ap['mac'], e)

            plugins.on('association', self, ap)
            if throttle > 0:
                time.sleep(throttle)
            self._view.on_normal()
Example #25
0
    def deauth(self, ap, sta, throttle=0):
        if self.is_stale():
            logging.debug(f"Recon is stale, skipping deauth({sta['mac']}).")
            return

        if self._config['personality']['deauth'] and self._should_interact(sta['mac']):
            self._view.on_deauth(sta)

            try:
                logging.info(f"Deauthing {sta['mac']} ({sta['vendor']}) from {ap['hostname']} ({ap['mac']} {ap['vendor']}) on channel {ap['channel']}, {ap['rssi']} dBm...")
                self.run(f"wifi.deauth {sta['mac']}")
                self._epoch.track(deauth=True)
            except Exception as e:
                self._on_error(sta['mac'], e)

            plugins.on('deauthentication', self, ap, sta)
            if throttle > 0:
                time.sleep(throttle)
            self._view.on_normal()
Example #26
0
    def get_access_points(self):
        whitelist = self._config['main']['whitelist']
        aps = []
        try:
            s = self.session()
            plugins.on("unfiltered_ap_list", self, s['wifi']['aps'])
            for ap in s['wifi']['aps']:
                if ap['encryption'] == '' or ap['encryption'] == 'OPEN':
                    continue
                elif ap['hostname'] not in whitelist \
                        and ap['mac'].lower() not in whitelist \
                        and ap['mac'][:8].lower() not in whitelist:
                    if self._filter_included(ap):
                        aps.append(ap)
        except Exception as e:
            logging.exception("Error while getting acces points (%s)", e)

        aps.sort(key=lambda ap: ap['channel'])
        return self.set_access_points(aps)
Example #27
0
    def associate(self, ap, throttle=0):
        if self.is_stale():
            logging.debug("recon is stale, skipping assoc(%s)", ap['mac'])
            return

        if self._config['personality']['associate'] and self._should_interact(ap['mac']):
            self._view.on_assoc(ap)

            try:
                logging.info("sending association frame to %s (%s %s) on channel %d [%d clients], %d dBm...",
                    ap['hostname'], ap['mac'], ap['vendor'], ap['channel'], len(ap['clients']), ap['rssi'])
                self.run('wifi.assoc %s' % ap['mac'])
                self._epoch.track(assoc=True)
            except Exception as e:
                self._on_error(ap['mac'], e)

            plugins.on('association', self, ap)
            if throttle > 0:
                time.sleep(throttle)
            self._view.on_normal()
Example #28
0
    def deauth(self, ap, sta, throttle=0):
        if self.is_stale():
            logging.debug("recon is stale, skipping deauth(%s)", sta['mac'])
            return

        if self._config['personality']['deauth'] and self._should_interact(sta['mac']):
            self._view.on_deauth(sta)

            try:
                logging.info("deauthing %s (%s) from %s (%s %s) on channel %d, %d dBm ...",
                    sta['mac'], sta['vendor'], ap['hostname'], ap['mac'], ap['vendor'], ap['channel'], ap['rssi'])
                self.run('wifi.deauth %s' % sta['mac'])
                self._epoch.track(deauth=True)
            except Exception as e:
                self._on_error(sta['mac'], e)

            plugins.on('deauthentication', self, ap, sta)
            if throttle > 0:
                time.sleep(throttle)
            self._view.on_normal()
Example #29
0
    def _init_display(self):
        if self._is_inky():
            logging.info("initializing inky display")
            from inky import InkyPHAT
            self._display = InkyPHAT(self._display_color)
            self._display.set_border(InkyPHAT.BLACK)
            self._render_cb = self._inky_render

        elif self._is_papirus():
            logging.info("initializing papirus display")
            from pwnagotchi.ui.papirus.epd import EPD
            os.environ['EPD_SIZE'] = '2.0'
            self._display = EPD()
            self._display.clear()
            self._render_cb = self._papirus_render

        elif self._is_waveshare1():
            logging.info("initializing waveshare v1 display")
            from pwnagotchi.ui.waveshare.v1.epd2in13 import EPD
            self._display = EPD()
            self._display.init(self._display.lut_full_update)
            self._display.Clear(0xFF)
            self._display.init(self._display.lut_partial_update)
            self._render_cb = self._waveshare_render

        elif self._is_waveshare2():
            logging.info("initializing waveshare v2 display")
            from pwnagotchi.ui.waveshare.v2.waveshare import EPD
            self._display = EPD()
            self._display.init(self._display.FULL_UPDATE)
            self._display.Clear(WHITE)
            self._display.init(self._display.PART_UPDATE)
            self._render_cb = self._waveshare_render

        else:
            logging.critical("unknown display type %s" % self._display_type)

        plugins.on('display_setup', self._display)

        self.on_render(self._on_view_rendered)
Example #30
0
    def _adv_poller(self):
        while True:
            logging.debug("polling pwngrid-peer for peers ...")

            try:
                grid_peers = grid.peers()
                new_peers = {}

                self._closest_peer = None
                for obj in grid_peers:
                    peer = Peer(obj)
                    new_peers[peer.identity()] = peer
                    if self._closest_peer is None:
                        self._closest_peer = peer

                # check who's gone
                to_delete = []
                for ident, peer in self._peers.items():
                    if ident not in new_peers:
                        self._view.on_lost_peer(peer)
                        plugins.on('peer_lost', self, peer)
                        to_delete.append(ident)

                for ident in to_delete:
                    del self._peers[ident]

                for ident, peer in new_peers.items():
                    # check who's new
                    if ident not in self._peers:
                        self._peers[ident] = peer
                        self._view.on_new_peer(peer)
                        plugins.on('peer_detected', self, peer)
                    # update the rest
                    else:
                        self._peers[ident].update(peer)

            except Exception as e:
                logging.exception("error while polling pwngrid-peer")

            time.sleep(1)