From 20c365e1cd2ea9fc403b754b6019480b3d6a4fdf Mon Sep 17 00:00:00 2001
From: sp3nx0r <sp3nx0r@gmail.com>
Date: Thu, 3 Oct 2019 06:46:20 -0500
Subject: [PATCH 1/7] resolve conflict, adjust getopts args, add /etc/motd to
 backup

---
 scripts/update_pwnagotchi.sh | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/scripts/update_pwnagotchi.sh b/scripts/update_pwnagotchi.sh
index 97b8a89..734ed4c 100644
--- a/scripts/update_pwnagotchi.sh
+++ b/scripts/update_pwnagotchi.sh
@@ -13,13 +13,14 @@ function usage() {
     cat <<EOF
 
  usage: $0 [OPTIONS]
- 
+ Note: This should be run from the pwnagotchi itself!
+
    Options:
       -v        # Version to update to, can be a branch or commit. (default: master)
       -u        # Url to clone from. (default: https://github.com/evilsocket/pwnagotchi)
       -m        # Mode to restart to. (Supported: ${SUPPORTED_RESTART_MODES[*]}; default: auto)
-      -b        # Backup the current pwnagotchi config and hostname references.
-      -r        # Restore the current pwnagotchi config and hostname references. (-b will be enabled.)
+      -b        # Backup the current pwnagotchi config and hostname references, then overwrite with defaults.
+      -r        # Restore the current pwnagotchi config and hostname references after upgrade. (-b will be enabled.)
       -h        # Shows this help.
 
 EOF
@@ -41,11 +42,7 @@ function test_github() {
     fi
 }
 
-echo "[+] Checking prerequisites."
-test_root
-test_github
-
-while getopts ":v:u:m:b:r:h" o; do
+while getopts "v:u:m:brh" o; do
   case "${o}" in
     v)
       VERSION="${OPTARG}"
@@ -58,15 +55,15 @@ while getopts ":v:u:m:b:r:h" o; do
         MODE="${OPTARG}"
       else
         usage
-      fi      
-      ;;      
+      fi
+      ;;
     b)
       BACKUPCONFIG=1
       ;;
     r)
-      BACKUPCONFIG=1    
+      BACKUPCONFIG=1
       RESTORECONFIG=1
-      ;;      
+      ;;
     h)
       usage
       ;;
@@ -77,6 +74,10 @@ while getopts ":v:u:m:b:r:h" o; do
 done
 shift $((OPTIND-1))
 
+echo "[+] Checking prerequisites."
+test_root
+test_github
+
 # clean up old files, clone master, set checkout to commit if needed.
 echo "[+] Cloning to $GIT_FOLDER..."
 rm $GIT_FOLDER -rf
@@ -85,27 +86,30 @@ cd $GIT_FOLDER
 if [ $VERSION != "master" ]; then
     git checkout $VERSION -q
 fi
-echo "[+] Installing $(git log -1 --format="%h")"
 
-echo "[+] Updating..."
 if [ $BACKUPCONFIG -eq 1 ]; then
     echo "[+] Creating backup of config.yml and hostname references"
     mv /root/pwnagotchi/config.yml /root/config.bak -f
     mv /etc/hosts /root/hosts.bak -f
     mv /etc/hostname /root/hostname.bak -f
+    mv /etc/motd /etc/motd.bak -f
     mv /etc/network/interfaces /root/interfaces.bak -f
 fi
+
+echo "[+] Installing $(git log -1 --format="%h")"
 rm /root/pwnagotchi -rf # ensures old files are removed
 rsync -aPq $GIT_FOLDER/sdcard/boot/*   /boot/
 rsync -aPq $GIT_FOLDER/sdcard/rootfs/* /
 cd /tmp
 rm $GIT_FOLDER -rf
+
 if [ $RESTORECONFIG -eq 1 ]; then
     echo "[+] Restoring backup of config.yml and hostname references"
     mv /root/config.yml.bak /root/pwnagotchi/config.yml -f
     mv /root/hosts.bak /etc/hosts -f
     mv /root/hostname.bak /etc/hostname -f
     mv /root/interfaces.bak /etc/network/interfaces -f
+    mv /etc/motd.bak /etc/motd -f
 fi
 
 echo "[+] Restarting pwnagotchi in $MODE mode. $( screen -X -S pwnagotchi quit)"

From bbe5540c43014f5fe26c8dc6f7ab225e2608d904 Mon Sep 17 00:00:00 2001
From: Simone Margaritelli <evilsocket@gmail.com>
Date: Thu, 3 Oct 2019 23:24:48 +0200
Subject: [PATCH 2/7] plugins are now enabled by config.yml or custom.yml
 (closes #114)

---
 sdcard/rootfs/root/pwnagotchi/config.yml               | 10 ++++++++--
 sdcard/rootfs/root/pwnagotchi/scripts/main.py          |  7 +++----
 .../pwnagotchi/scripts/pwnagotchi/plugins/__init__.py  |  5 ++---
 .../scripts/pwnagotchi/plugins/default/example.py      |  1 -
 .../scripts/pwnagotchi/plugins/default/gps.py          |  1 -
 .../scripts/pwnagotchi/plugins/default/memtemp.py      |  1 -
 .../scripts/pwnagotchi/plugins/default/twitter.py      |  1 -
 .../scripts/pwnagotchi/plugins/default/ups_lite.py     |  1 -
 8 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/sdcard/rootfs/root/pwnagotchi/config.yml b/sdcard/rootfs/root/pwnagotchi/config.yml
index 28f2770..5d786c5 100644
--- a/sdcard/rootfs/root/pwnagotchi/config.yml
+++ b/sdcard/rootfs/root/pwnagotchi/config.yml
@@ -3,7 +3,11 @@ main:
     # currently implemented: en (default), de, nl, it
     lang: en
     # custom plugins path, if null only default plugins with be loaded
-    plugins: null
+    custom_plugins:
+    # which plugins to load and enable
+    plugins:
+        - gps
+        - twitter
     # monitor interface to use
     iface: mon0
     # command to run to bring the mon interface up in case it's not up already
@@ -15,7 +19,9 @@ main:
     # if true, will not restart the wifi module
     no_restart: false
     # access points to ignore
-    whitelist: []
+    whitelist:
+        - EXAMPLE_NETWORK
+        - ANOTHER_EXAMPLE_NETWORK
     # if not null, filter access points by this regular expression
     filter: null
     # cryptographic key for identity
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/main.py b/sdcard/rootfs/root/pwnagotchi/scripts/main.py
index cba98d5..ac5bacd 100755
--- a/sdcard/rootfs/root/pwnagotchi/scripts/main.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/main.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python3
-import os
 import argparse
 import time
 import logging
@@ -33,9 +32,9 @@ args = parser.parse_args()
 config = utils.load_config(args)
 utils.setup_logging(args, config)
 
-plugins.load_from_path(plugins.default_path)
-if 'plugins' in config['main'] and config['main']['plugins'] is not None:
-    plugins.load_from_path(config['main']['plugins'])
+plugins.load_from_path(plugins.default_path, enabled=config['main']['plugins'])
+if 'custom_plugins' in config['main'] and config['main']['custom_plugins'] is not None:
+    plugins.load_from_path(config['main']['custom_plugins'], enabled=config['main']['plugins'])
 
 plugins.on('loaded')
 
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/__init__.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/__init__.py
index bcb89f8..89afe10 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/__init__.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/__init__.py
@@ -27,14 +27,13 @@ def load_from_file(filename):
     return plugin_name, instance
 
 
-def load_from_path(path):
+def load_from_path(path, enabled=()):
     global loaded
-
     for filename in glob.glob(os.path.join(path, "*.py")):
         name, plugin = load_from_file(filename)
         if name in loaded:
             raise Exception("plugin %s already loaded from %s" % (name, plugin.__file__))
-        elif not plugin.__enabled__:
+        elif name not in enabled:
             # print("plugin %s is not enabled" % name)
             pass
         else:
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/example.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/example.py
index 4166e4a..b425d6e 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/example.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/example.py
@@ -3,7 +3,6 @@ __version__ = '1.0.0'
 __name__ = 'hello_world'
 __license__ = 'GPL3'
 __description__ = 'An example plugin for pwnagotchi that implements all the available callbacks.'
-__enabled__ = False  # IMPORTANT: set this to True to enable your plugin.
 
 import logging
 
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/gps.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/gps.py
index cd292ea..f7aa56e 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/gps.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/gps.py
@@ -3,7 +3,6 @@ __version__ = '1.0.0'
 __name__ = 'gps'
 __license__ = 'GPL3'
 __description__ = 'Save GPS coordinates whenever an handshake is captured.'
-__enabled__ = True  # set to false if you just don't use GPS
 
 import logging
 import json
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/memtemp.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/memtemp.py
index 2b1fc3d..4ef823b 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/memtemp.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/memtemp.py
@@ -7,7 +7,6 @@ __version__ = '1.0.0'
 __name__ = 'memtemp'
 __license__ = 'GPL3'
 __description__ = 'A plugin that will add a memory and temperature indicator'
-__enabled__ = False
 
 import struct
 
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/twitter.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/twitter.py
index 0c7d8d9..03aa251 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/twitter.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/twitter.py
@@ -3,7 +3,6 @@ __version__ = '1.0.0'
 __name__ = 'twitter'
 __license__ = 'GPL3'
 __description__ = 'This plugin creates tweets about the recent activity of pwnagotchi'
-__enabled__ = True
 
 import logging
 from pwnagotchi.voice import Voice
diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/ups_lite.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/ups_lite.py
index 7ddcecd..d9a37d2 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/ups_lite.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/ups_lite.py
@@ -12,7 +12,6 @@ __version__ = '1.0.0'
 __name__ = 'ups_lite'
 __license__ = 'GPL3'
 __description__ = 'A plugin that will add a voltage indicator for the UPS Lite v1.1'
-__enabled__ = False
 
 import struct
 

From 2749079d256655bfad6b744a38d3cb22e1620f69 Mon Sep 17 00:00:00 2001
From: dipsylala <marcus.watson@loumiaconsulting.com>
Date: Thu, 3 Oct 2019 22:28:19 +0100
Subject: [PATCH 3/7] Friend status is positioned based on %age of screen
 height

It takes it's queue from the bottom line and places text above it.
Tested on WaveShare v2 and Inkyphat.
---
 sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py
index f86b88f..ca748a0 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/ui/view.py
@@ -86,8 +86,8 @@ class View(object):
 
             'face': Text(value=faces.SLEEP, position=face_pos, color=BLACK, font=fonts.Huge),
 
-            'friend_face': Text(value=None, position=(0, 90), font=fonts.Bold, color=BLACK),
-            'friend_name': Text(value=None, position=(40, 93), font=fonts.BoldSmall, color=BLACK),
+            'friend_face': Text(value=None, position=(0, (self._height * 0.88) - 15 ), font=fonts.Bold, color=BLACK),
+            'friend_name': Text(value=None, position=(40,(self._height * 0.88) - 13 ), font=fonts.BoldSmall, color=BLACK),
 
             'name': Text(value='%s>' % 'pwnagotchi', position=name_pos, color=BLACK, font=fonts.Bold),
 

From d58e416edea2a5545d7fa9eeea4e71174b07a7c2 Mon Sep 17 00:00:00 2001
From: sp3nx0r <sp3nx0r@gmail.com>
Date: Thu, 3 Oct 2019 16:35:06 -0500
Subject: [PATCH 4/7] markdown style formatting, adding content to configure

---
 docs/about.md     | 10 +++-------
 docs/configure.md | 39 ++++++++++++++++++++++-----------------
 docs/dev.md       |  3 ++-
 docs/faq.md       |  2 +-
 docs/index.md     |  2 +-
 docs/install.md   |  9 +++------
 docs/plugins.md   |  3 +--
 docs/usage.md     | 41 ++++++++++++++++++-----------------------
 8 files changed, 51 insertions(+), 58 deletions(-)

diff --git a/docs/about.md b/docs/about.md
index 8f141ad..e5f0f37 100644
--- a/docs/about.md
+++ b/docs/about.md
@@ -1,10 +1,6 @@
-## About the Project
+# About the Project
 
-[Pwnagotchi](https://twitter.com/pwnagotchi) is an "AI" that learns from the WiFi environment and instruments 
-[bettercap](https://www.bettercap.org/) in order to maximize the WPA key material that's being captured either passively
- or by performing deauthentication and association attakcs. This material is collected as pcap files containing any form 
- of handshake supported by [hashcat](https://hashcat.net/hashcat/), including [PMKIDs](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/), 
-full and half WPA handshakes.
+[Pwnagotchi](https://twitter.com/pwnagotchi) is an "AI" that learns from the WiFi environment and instruments [bettercap](https://www.bettercap.org/) in order to maximize the WPA key material that's being captured either passively or by performing deauthentication and association attakcs. This material is collected as pcap files containing any form  of handshake supported by [hashcat](https://hashcat.net/hashcat/), including [PMKIDs](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/), full and half WPA handshakes.
 
 ![handshake](https://i.imgur.com/pdA4vCZ.png)
 
@@ -20,4 +16,4 @@ If instead you just want to use your own parameters and save battery and CPU cyc
 
 ## License
 
-`pwnagotchi` is made with ♥  by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.
\ No newline at end of file
+`pwnagotchi` is made with ♥  by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.
diff --git a/docs/configure.md b/docs/configure.md
index 98cd01c..fbefe70 100644
--- a/docs/configure.md
+++ b/docs/configure.md
@@ -1,7 +1,6 @@
-### Connecting to your Pwnagotchi
+# Connecting to your Pwnagotchi
 
-Once you wrote the image file on the SD card, there're a few steps you'll have to follow in order to configure your unit properly, first, start with connecting the USB cable to the 
-data port of the Raspberry Pi and the RPi to your computer. After a few seconds the board will boot and you will see a new Ethernet interface on your host computer.
+Once you wrote the image file on the SD card, there're a few steps you'll have to follow in order to configure your unit properly, first, start with connecting the USB cable to the data port of the Raspberry Pi and the RPi to your computer. After a few seconds the board will boot and you will see a new Ethernet interface on your host computer.
 
 You'll need to configure it with a static IP address:
 
@@ -26,26 +25,32 @@ Moreover, it is recommended that you copy your SSH public key among the unit's a
 ssh-copy-id -i ~/.ssh/id_rsa.pub pi@10.0.0.2
 ```
 
-### Configuration
+## Configuration
 
-You can now set a new name for your unit by [changing the hostname](https://geek-university.com/raspberry-pi/change-raspberry-pis-hostname/). Create the `/root/custom.yml` file (either via SSH or by direclty editing the SD card contents from a computer) that will override 
-the [default configuration](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml) with your custom values.
+You can now set a new name for your unit by [changing the hostname](https://geek-university.com/raspberry-pi/change-raspberry-pis-hostname/). Create the `/root/custom.yml` file (either via SSH or by direclty editing the SD card contents from a computer) that will override the [default configuration](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml) with your custom values.
+
+## Language Selection
 
 For instance, you can change `main.lang` to one of the supported languages:
 
-* **english** (default)
-* german
-* dutch
-* greek
-* macedonian
-* italian
-* french
+- **english** (default)
+- german
+- dutch
+- greek
+- macedonian
+- italian
+- french
 
-The set the type of display you want to use via `ui.display.type` (if your display does not work after changing this setting, you might need to complete remove power from the Raspberry and make a clean boot).
+## Display Selection
+
+Set the type of display you want to use via `ui.display.type` (if your display does not work after changing this setting, you might need to completely remove power from the Raspberry and make a clean boot).
 
 You can configure the refresh interval of the display via `ui.fps`, we advise to use a slow refresh to not shorten the lifetime of your display. The default value is 0, which will only refresh when changes are made to the screen.
 
-### Host Connection Share
+## Host Connection Share
 
-If you connect to the unit via `usb0` (thus using the data port), you might want to use the `scripts/linux_connection_share.sh` or 
- `scripts/macos_connection_share.sh` script to bring the interface up on your end and share internet connectivity from another interface, so you can update the unit and generally download things from the internet on it.
\ No newline at end of file
+If you connect to the unit via `usb0` (thus using the data port), you might want to use the `scripts/linux_connection_share.sh` or `scripts/macos_connection_share.sh` script to bring the interface up on your end and share internet connectivity from another interface, so you can update the unit and generally download things from the internet on it. Note this script takes as inputs the two interfaces and shouldn't be run without arguments.
+
+## Troubleshooting
+
+If your network connection keeps flapping on your device connecting to your pwnagotchi, check if `usb0` (or equivalent) device is being controlled by NetworkManager. You can check this via `nmcli dev status`.
diff --git a/docs/dev.md b/docs/dev.md
index 5a4df64..09d2a46 100644
--- a/docs/dev.md
+++ b/docs/dev.md
@@ -1,4 +1,4 @@
-## Software
+# Software
 
 - Raspbian + [nexmon patches](https://re4son-kernel.com/re4son-pi-kernel/) for monitor mode, or any Linux with a monitor mode enabled interface (if you tune config.yml).
 
@@ -21,6 +21,7 @@ usage: ./scripts/create_sibling.sh [OPTIONS]
     -d           # Only run dependencies checks
     -h           # Show this help
 ```
+
 ## Adding a Language
 
 If you want to add a language use the `language.sh` script. If you want to add for example the language **italian** you would type:
diff --git a/docs/faq.md b/docs/faq.md
index ed4a1f3..ff19087 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -10,4 +10,4 @@ Because Python sucks and TF is huge.
 
 ## Why ...?
 
-Because!
\ No newline at end of file
+Because!
diff --git a/docs/index.md b/docs/index.md
index 3c23b8c..36e97f8 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -16,4 +16,4 @@
 
 ## License
 
-`pwnagotchi` is made with ♥  by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.
\ No newline at end of file
+`pwnagotchi` is made with ♥  by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.
diff --git a/docs/install.md b/docs/install.md
index 4081e95..6902979 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -1,7 +1,6 @@
 # Installation
 
-The project has been developed to run on a Raspberry Pi 0 W configured as an [USB Ethernet gadget](https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget/ethernet-gadget) device in order to connect to it via USB. 
-However, given the proper configuration tweaks, any GNU/Linux computer with a WiFi interface that supports monitor mode could be used.
+The project has been developed to run on a Raspberry Pi 0 W configured as an [USB Ethernet gadget](https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget/ethernet-gadget) device in order to connect to it via USB. However, given the proper configuration tweaks, any GNU/Linux computer with a WiFi interface that supports monitor mode could be used.
 
 ## Required Hardware
 
@@ -34,9 +33,7 @@ Color displays have a much slower refresh rate, in some cases it can take up to
 
 The easiest way to create a new Pwnagotchi is downloading the latest stable image from [our release page](https://github.com/evilsocket/pwnagotchi/releases) and write it to your SD card. You will need to use an image writing tool to install the image you have downloaded on your SD card.
 
-[balenaEtcher](https://www.balena.io/etcher/) is a graphical SD card writing tool that works on Mac OS, Linux and Windows, 
-and is the easiest option for most users. balenaEtcher also supports writing images directly from the zip file, 
-without any unzipping required. To write your image with balenaEtcher:
+[balenaEtcher](https://www.balena.io/etcher/) is a graphical SD card writing tool that works on Mac OS, Linux and Windows, and is the easiest option for most users. balenaEtcher also supports writing images directly from the zip file, without any unzipping required. To write your image with balenaEtcher:
 
 - Download the latest [Pwnagotchi .img file](https://github.com/evilsocket/pwnagotchi/releases).
 - Download [balenaEtcher](https://www.balena.io/etcher/) and install it.
@@ -45,4 +42,4 @@ without any unzipping required. To write your image with balenaEtcher:
 - Select the SD card you wish to write your image to.
 - Review your selections and click 'Flash!' to begin writing data to the SD card.
 
-Your SD card is now ready for the first boot!
\ No newline at end of file
+Your SD card is now ready for the first boot!
diff --git a/docs/plugins.md b/docs/plugins.md
index 512c872..0038df9 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -1,8 +1,7 @@
 # Plugins
 
 Pwnagotchi has a simple plugins system that you can use to customize your unit and its behaviour. You can place your plugins anywhere
-as python files and then edit the `config.yml` file (`main.plugins` value) to point to their containing folder. Check the [plugins folder](https://github.com/evilsocket/pwnagotchi/tree/master/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/) for a list of default
-plugins and all the callbacks that you can define for your own customizations.
+as python files and then edit the `config.yml` file (`main.plugins` value) to point to their containing folder. Check the [plugins folder](https://github.com/evilsocket/pwnagotchi/tree/master/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/) for a list of default plugins and all the callbacks that you can define for your own customizations.
 
 Here's as an example the GPS plugin:
 
diff --git a/docs/usage.md b/docs/usage.md
index e23dc68..8883cb7 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -1,4 +1,6 @@
-### User Interface
+# Usage
+
+## User Interface
 
 The UI is available either via display if installed, or via http://pwnagotchi.local:8080/ if you connect to the unit via `usb0` and set a static address on the network interface (change `pwnagotchi` with the hostname of your unit).
 
@@ -10,7 +12,7 @@ The UI is available either via display if installed, or via http://pwnagotchi.lo
 * **PWND**: Number of handshakes captured in this session and number of unique networks we own at least one handshake of, from the beginning.
 * **AUTO**: This indicates that the algorithm is running with AI disabled (or still loading), it disappears once the AI dependencies have been bootrapped and the neural network loaded.
 
-### Training the AI
+## Training the AI
 
 At its core Pwnagotchi is a very simple creature: we could summarize its main algorithm as:
 
@@ -27,7 +29,7 @@ while True:
         for client in ap.clients:
             # deauthenticate the client to get its half or full handshake
             deauthenticate(client)
-    
+
     wait_for_loot()
 ```
 
@@ -73,14 +75,11 @@ personality:
     sad_num_epochs: 25
 ```
 
-There is no optimal set of parameters for every situation: when the unit is moving (during a walk for instance) smaller timeouts and RSSI thresholds might be preferred
-in order to quickly remove routers that are not in range anymore, while when stationary in high density areas (like an office) other parameters might be better. 
-The role of the AI is to observe what's going on at the WiFi level, and adjust those parameters in order to maximize the cumulative reward of that loop / epoch.
+There is no optimal set of parameters for every situation: when the unit is moving (during a walk for instance) smaller timeouts and RSSI thresholds might be preferred in order to quickly remove routers that are not in range anymore, while when stationary in high density areas (like an office) other parameters might be better. The role of the AI is to observe what's going on at the WiFi level, and adjust those parameters in order to maximize the cumulative reward of that loop / epoch.
 
-#### Reward Function
+## Reward Function
 
-After each iteration of the main loop (an `epoch`), the reward, a score that represents how well the parameters performed, is computed as 
-(an excerpt from `pwnagotchi/ai/reward.py`):
+After each iteration of the main loop (an `epoch`), the reward, a score that represents how well the parameters performed, is computed as (an excerpt from `pwnagotchi/ai/reward.py`):
 
 ```python
 # state contains the information of the last epoch
@@ -107,15 +106,13 @@ reward = h + a + c + b + i + m
 
 By maximizing this reward value, the AI learns over time to find the set of parameters that better perform with the current environmental conditions.
 
+## BetterCAP's Web UI
 
-### BetterCAP's Web UI
-
-Moreover, given that the unit is running bettercap with API and Web UI, you'll be able to use the unit as a WiFi penetration testing portable station
-by accessing `http://pwnagotchi.local/`.
+Moreover, given that the unit is running bettercap with API and Web UI, you'll be able to use the unit as a WiFi penetration testing portable station by accessing `http://pwnagotchi.local/`.
 
 ![webui](https://raw.githubusercontent.com/bettercap/media/master/ui-events.png)
 
-### Update your Pwnagotchi
+## Update your Pwnagotchi
 
 You can use the `scripts/update_pwnagotchi.sh` script to update to the most recent version of pwnagotchi.
 
@@ -132,7 +129,7 @@ usage: ./update_pwnagitchi.sh [OPTIONS]
 
 ```
 
-### Backup your Pwnagotchi
+## Backup your Pwnagotchi
 
 You can use the `scripts/backup.sh` script to backup the important files of your unit.
 
@@ -140,12 +137,10 @@ You can use the `scripts/backup.sh` script to backup the important files of your
 usage: ./scripts/backup.sh HOSTNAME backup.zip
 ```
 
-### Random Info
-
-- **On a rpi0w, it'll take approximately 30 minutes to load the AI**.
-- `/var/log/pwnagotchi.log` is your friend.
-- if connected to a laptop via usb data port, with internet connectivity shared, magic things will happen.
-- checkout the `ui.video` section of the `config.yml` - if you don't want to use a display, you can connect to it with the browser and a cable.
-- If you get `[FAILED] Failed to start Remount Root and Kernel File Systems.` while booting pwnagotchi, make sure
-the `PARTUUID`s for `rootfs` and `boot` partitions are the same in `/etc/fstab`. Use `sudo blkid` to find those values when you are using `create_sibling.sh`.
+## Random Info
 
+* **On a rpi0w, it'll take approximately 30 minutes to load the AI**.
+* `/var/log/pwnagotchi.log` is your friend.
+* if connected to a laptop via usb data port, with internet connectivity shared, magic things will happen.
+* checkout the `ui.video` section of the `config.yml` - if you don't want to use a display, you can connect to it with the browser and a cable.
+* If you get `[FAILED] Failed to start Remount Root and Kernel File Systems.` while booting pwnagotchi, make sure the `PARTUUID`s for `rootfs` and `boot` partitions are the same in `/etc/fstab`. Use `sudo blkid` to find those values when you are using `create_sibling.sh`.

From 703f334f6e7666d186fd696f4e7e8d44009f36bc Mon Sep 17 00:00:00 2001
From: waxwing <katherine.snyder@socraticarts.com>
Date: Thu, 3 Oct 2019 17:38:49 -0400
Subject: [PATCH 5/7] minor copyediting for typos

---
 docs/about.md | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/docs/about.md b/docs/about.md
index 8f141ad..816b6c5 100644
--- a/docs/about.md
+++ b/docs/about.md
@@ -1,23 +1,23 @@
 ## About the Project
 
-[Pwnagotchi](https://twitter.com/pwnagotchi) is an "AI" that learns from the WiFi environment and instruments 
-[bettercap](https://www.bettercap.org/) in order to maximize the WPA key material that's being captured either passively
- or by performing deauthentication and association attakcs. This material is collected as pcap files containing any form 
- of handshake supported by [hashcat](https://hashcat.net/hashcat/), including [PMKIDs](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/), 
+[Pwnagotchi](https://twitter.com/pwnagotchi) is an [A2C](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752)-based "AI" leveraging [bettercap](https://www.bettercap.org/) that learns from its surrounding WiFi environment in order to maximize the WPA key material it captures (either passively, or by performing deauthentication and association attacks). This material is collected as PCAP files containing any form of handshake supported by [hashcat](https://hashcat.net/hashcat/), including [PMKIDs](https://www.evilsocket.net/2019/02/13/Pwning-WiFi-networks-with-bettercap-and-the-PMKID-client-less-attack/), 
 full and half WPA handshakes.
 
 ![handshake](https://i.imgur.com/pdA4vCZ.png)
 
-Instead of playing [Super Mario or Atari games](https://becominghuman.ai/getting-mario-back-into-the-gym-setting-up-super-mario-bros-in-openais-gym-8e39a96c1e41?gi=c4b66c3d5ced), pwnagotchi will tune over time [its own parameters](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml#L54), effectively learning to get better at pwning WiFi things. **Keep in mind:** unlike the usual RL simulations, pwnagotchi learns over time (where a single epoch can last from a few seconds to minutes, depending on how many access points and client stations are visible), do not expect it to perform amazingly well at the beginning, as it'll be exploring several combinations of parameters ... but listen to it when it's bored, bring it with you and have it observe new networks and capture new handshakes and you'll see :)
+Instead of merely playing [Super Mario or Atari games](https://becominghuman.ai/getting-mario-back-into-the-gym-setting-up-super-mario-bros-in-openais-gym-8e39a96c1e41?gi=c4b66c3d5ced) like most reinforcement learning based "AI" *(yawn)*, Pwnagotchi tunes [its own parameters](https://github.com/evilsocket/pwnagotchi/blob/master/sdcard/rootfs/root/pwnagotchi/config.yml#L54) over time to **get better at pwning WiFi things** in the environments you expose it to. 
 
-Multiple units can talk to each other, advertising their own presence using a parasite protocol I've built on top of the existing dot11 standard, by broadcasting custom information elements. Over time, two or more units learn to cooperate if they detect each other's presence, by dividing the available channels among them.
+**Keep in mind:** Unlike the usual RL simulations, Pwnagotchi actually learns over time. Time for a Pwnagotchi is measured in epochs; a single epoch can last from a few seconds to minutes, depending on how many access points and client stations are visible. Do not expect your Pwnagotchi to perform amazingly well at the very beginning, as it will be [exploring](https://hackernoon.com/intuitive-rl-intro-to-advantage-actor-critic-a2c-4ff545978752) several combinations of [key parameters](https://github.com/evilsocket/pwnagotchi/blob/master/docs/usage.md#training-the-ai) to determine ideal adjustments for pwning the particular environment you are exposing it to during its beginning epochs ... but **definitely listen to your pwnagotchi when it tells you it's bored!** Bring it into novel WiFi environments with you and have it observe new networks and capture new handshakes—and you'll see. :)
+
+Multiple units within close physical proximity can "talk" to each other, advertising their own presence to each other by broadcasting custom information elements using a parasite protocol I've built on top of the existing dot11 standard. Over time, two or more units trained together will learn to cooperate upon detecting each other's presence by dividing the available channels among them for optimal pwnage.
 
 ![peers](https://i.imgur.com/Ywr5aqx.png)
 
-Depending on the status of the unit, several states and states transitions are configurable and represented on the display as different moods, expressions and sentences.
+[Depending on the status of the unit](), several states and states transitions are configurable and represented on the display as different moods, expressions and sentences. Pwnagotchi speaks [many languages](https://github.com/evilsocket/pwnagotchi/blob/master/docs/configure.md#configuration), too!
+
+Of course, it is possible to run your Pwnagotchi with the AI disabled (configurable in `config.yml`). Why might you want to do this? Perhaps you simply want to use your own fixed parameters (instead of letting the AI decide for you), or maybe you want to save battery and CPU cycles, or maybe it's just you have strong concerns about aiding and abetting baby Skynet. Whatever your particular reasons may be: an AI-disabled Pwnagotchi is still a simple and very effective automated deauther, WPA handshake sniffer, and portable [bettercap](https://www.bettercap.org/) + [webui](https://github.com/evilsocket/pwnagotchi/blob/master/docs/usage.md#bettercaps-web-ui) dedicated hardware.
 
-If instead you just want to use your own parameters and save battery and CPU cycles, you can disable the AI in `config.yml` and enjoy an automated deauther, WPA handshake sniffer and portable bettercap + webui dedicated hardware.
 
 ## License
 
-`pwnagotchi` is made with ♥  by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.
\ No newline at end of file
+`pwnagotchi` is made with ♥  by [@evilsocket](https://twitter.com/evilsocket) and the [amazing dev team](https://github.com/evilsocket/pwnagotchi/graphs/contributors). It's released under the GPL3 license.

From 5fc0d69fda33e2ddbb754c296b99f5d3e927e22e Mon Sep 17 00:00:00 2001
From: Simone Margaritelli <evilsocket@gmail.com>
Date: Thu, 3 Oct 2019 23:46:54 +0200
Subject: [PATCH 6/7] fix

---
 .../pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py
index 48ea525..f783d20 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py
@@ -60,12 +60,12 @@ def on_internet_available(display, config, log):
         handshake_paths = [os.path.join(handshake_dir, filename) for filename in handshake_filenames]
         handshake_new = set(handshake_paths) - set(ALREADY_UPLOADED)
 
-        if handhake_new:
+        if handshake_new:
             logging.info("Internet connectivity detected.\
                           Uploading new handshakes to wpa-sec.stanev.org")
 
             for idx, handshake in enumerate(handshake_new):
-                display.set('status', f"Uploading handshake to wpa-sec.stanev.org ({idx + 1}/{len(handshake_new})")
+                display.set('status', "Uploading handshake to wpa-sec.stanev.org ({idx + 1}/{len(handshake_new})")
                 display.update(force=True)
                 try:
                     _upload_to_wpasec(handshake)

From 3a3c5911cbb465d16e7e4ba5628a1ef302e112c3 Mon Sep 17 00:00:00 2001
From: Simone Margaritelli <evilsocket@gmail.com>
Date: Thu, 3 Oct 2019 23:49:58 +0200
Subject: [PATCH 7/7] fix

---
 .../pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py   | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py
index f783d20..64df84e 100644
--- a/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py
+++ b/sdcard/rootfs/root/pwnagotchi/scripts/pwnagotchi/plugins/default/wpa-sec.py
@@ -3,7 +3,6 @@ __version__ = '1.0.0'
 __name__ = 'wpa_sec'
 __license__ = 'GPL3'
 __description__ = 'This plugin automatically uploades handshakes to https://wpa-sec.stanev.org'
-__enabled__ = False
 
 import os
 import logging
@@ -13,6 +12,7 @@ READY = False
 API_KEY = None
 ALREADY_UPLOADED = None
 
+
 # INSTALLATION:
 ## apt-get install libcurl4-openssl-dev
 ## https://github.com/ZerBea/hcxtools.git
@@ -51,6 +51,7 @@ def _upload_to_wpasec(path):
         logging.error(f"WPA_SEC: Error while uploading {path}")
         raise os_e
 
+
 # called in manual mode when there's internet connectivity
 def on_internet_available(display, config, log):
     if READY: