Setting up Packet Radio on a Raspberry Pi (4 thru Zero-W) running Raspbian Buster, Stretch or Jessie

KI6ZHD
dranch at trinityos.com

05/31/21.1
 
This document is intended for new users to both Raspberry Pi SBC computers and the Raspbian based Linux operating system. This doc will help the user create a reliable device that operates as an AX.25 / APRS packet radio system with GPS support. This guide is focused around the Raspbian Linux distribution. This document tries to support any specific quirks around the Buster or (10.0) version of Raspbian as well as the Stretch, Jessie, and Wheezy (non-SystemD based) versions. This document includes optimizations for improved SD card life and OS security hardening for supporting direct connections to the Internet. This setup is also directly manageable via Wifi via say a smartphone/tablet for off-Internet maintenance as well.

     +---------------------------------------------------------------------------------+
     | Raspbian Buster: Support for this new OS is well on it's way but isn't 100%     |
     |                  complete for the advanced topics like supporting Wifi AP       |
     |                  emulation support, etc.                                        |
     +---------------------------------------------------------------------------------+


Index:



0. Intro to setting up a Raspberry Pi and understanding it's quirks


Welcome to the world of the Raspberry Pi, Amateur Radio, and all the possibilities.  No doubt
there is an overwhelming amount of options and many people new to the Raspberry Pi, Linux, etc.
will get confused where to start.  This document hopes to provide some guidance here with a
specific application in mind (see the intro at the beginning of this document of it's goals).

Before you get started, a few thoughts:

   - SD cards: Only use quality, name brand SD cards in your Pi.  It will save you from countless amount 
     lost time, anger of "stability issues with Raspberry Pis" and the overall setup will last 
     a LOT longer (but it won't last forever without backups).

   - Power Supply: Only use a quality USB power supply and not just some old cellphone charger you had laying around 
     the house.  The official Rpi PS is a 5.1volt (not 5.0v) @ 2.5Amp supply with a thick, short and
     quality made USB cable for many reasons. The new Rpi v4 supply is now 3.0Amp.  Random USB power 
     bricks and cables will not work in your favor.. especially when the Rpi is under load.   If you 
     want to run your Raspberry Pi from a 12v battery, I've had good luck with these inexpensive UBEC 
     DC to DC power bridges:
   - Operating System: Install the Raspbian version of the Linux operating system OS on it :: 
     This NEWEST Raspbian version to be specific

       - I *highly* recommend you run Raspbian OS "Buster" (or it's older version "Stretch").  I do NOT
         recommend any older versions  of Raspbian as they no longer receive security patches.  Every 
         OS version has a support lifetime for patches, etc. so I would recommend you get the newest version
         to get the longest support life.  There are always exceptions to this choice say for people wanting 
         a non non-SystemD enabled OS like Devuan but that's up to you

         This specific document focuses on the use of the Raspberry Pi focused OS based on Debian Buster
         though there is details for supporting other OS versions like Stretch release.   These newest 
         versions of the OS resolves many of the previously seen SystemD issues that were found in the 
         Jessie version.  If you you're starting out with a pre-imaged microSD card which was supported 
         Raspberry Pi kit and /etc/os-release doesn't show "debian 10.x", please consider just upgrading 
         the image to Buster or whatever is newest.  It's easy to do as long as you have a micro-SD card 
         reader on an already functioning Windows, Linux, or Mac machine, follow these instructions:

            https://www.raspberrypi.org/documentation/installation/installing-images/


        - Why run the Raspberry Pi OS (aka was called Raspbian) vs other available OSes?  Yes, there are 
          other alternative Linux OSes that run on the Raspberry Pi but *none* of them match the support 
          and bug fix cadence of this Raspberry Pi OS / Raspbian for Raspberry Pi hardware.  You also might 
          find other pre-made Rpi images from various people for say the DVMega project or other things and 
          I say you should give them a try.  Going this approach makes it so easy to just try new software 
          stuff by just swapping out different micro-SD flash cards.  Do be wary though...  

           - What is the providence of these images?  Are these pre-made images using the official 
             Raspbian OS to benefit from the patches and security?  
           - Were those images built and and secured properly?  
           - Are these image publishers trustworthy?  


        A quick list of alternative distros (you can find many more here: https://elinux.org/RPi_Distributions ):
        ---------------------------------------------------------------------------------------------------------
        Arch Linux : More of a advanced Linux distributions for experienced Linux users

        Debian : This is the basis for Raspberry Pi OS but without many of the useful tools like
                 rasp-config, vcgencmd, and the customized Linux kernel for the Broadcom SOC

        Devuan : This is debian but not using the SystemD system

        Fedora : A general desktop focused distro

        FreeBSD : FreeBSD for the Raspberry Pi OS

        Gentoo Linux : More of ab advanced Linux distributions for experienced Linux users

        Kali Linux : An advanced security toolkit focused Linux distribution

        OpenSuse: A general desktop focused distro

        RaspBSD : FreeBSD for the Raspberry Pi OS

        Risc OS: A non-Linux kernel based distro

        SARPi / Slackware: A general desktop focused distro

        Ubuntu : A general desktop focused distro

        Windows IOT : A stripped down base Windows kernel for IOT functions


        There are also other purpose built "appliance" images but I wouldn't call them Linux distributions:  
        ---------------------------------------------------------------------------------------------------
           - Kodi media player needs: OSMC, OpenElec
           - Retro gaming needs: Batocera, BMC64, Lakka, RetroPie
           - Home automation needs: Domoticz


        Pre-built HAM images:
        ---------------------
        - There are some good alternative / pre-configured images that you might consider.  Many of them are 
          not properly maintained IMHO and are getting quite old.  The benefit of using one of these images 
          is that much of the work to get all the packages installed and configured is already done for you.   
          Some even have tools to help with the configuration.  


        .. but a word of Warning on pre-built HAM images:
        -------------------------------------------------
        I once downloaded a RPI packet radio image from a trustworthy HAM and yet noticed some strange log 
        entries and behavior.  I then did some security investigation and it turns out his Rpi been 
        compromised before he imaged it and then published that image on the Internet!  When I proved this 
        compromise to the image owner, he was shocked and immediately took it down.  It was totally not 
        intended by him but it happened regardless.  There is no free lunch when it comes to easy to install vs. 
        good security here but I bet 95% of the Rpi images out there are good.  Just watch for that last 5%.


   - Security: 
      - If this Rpi setup is going to be directly connected to the Internet, PLEASE keep the OS patched 
        every week (ideally every day) and disable the "pi" account, install an IPTABLES firewall on it.  
        Don't expose say SSH (port 22) and other services directly to the Internet if you can help it.  
        If you do need to offer external SSH, at least change the answering port from say TCP/22 to 
        something like TCP/5353.  It's been said that you should NOT use any port number that includes 
        "22" as the common portscaners will look for that.  

         - Another good idea is to ONLY use SSH keys (ideally with passphrases) and disable all password
           authentication if you can compared to just using accounts with passwords.  These few steps alone 
           greatly reduces your security attack surface.


  - Safe Shutdown: 
    I recommend to connect a shutdown button so it's easy to turn off your Raspberry Pi safely.  You *MUST NOT* 
    just unplug the Raspberry Pi's power cord when you want to turn it off.  If you do this, you *will* 
    eventually corrupt the OS on the SD.  Adding a shutdown button is very easy and only takes two wires, a 
    resistor, a momentary button, and setting up a simple script).  This is covered in this doc.


I could go on and on here in the intro but I won't.  Instead, that's what the following chapters in
this document is for!  Good luck with the project and if you're new to Linux.. take your time.  There 
is lots to learn and it can be intimidating at times.  Do as much research on Google before becoming too 
frustrated.  At that point, feel free to email me or join some of the various help lists like the 
excellent Raspberry_Pi_4-Ham_RADIO@yahoogroups.com list.   There are lots of helpful and patient Linux 
HAMs there that are ready to help.

Anyway.. let's get down to it!


1. Differences in Raspberry Pi hardware versions, downloading the SD image and installing it


I first want to highlight the key differences between the Rpi v1, v2, v3, v3+ and now 4 versions of 
the board.  I generally recommend people to either start with the v4 or v3+ due to many of it's 
substantial improvements for the same price UNLESS they have specific power consumption needs:

   - Boards: Overview of the big differences from generation to generation.  Read from the bottom up understanding
     the RPi v1 capabilities and then read about each newer generation with all of it's improvements:
     -----------------------------------------------------------------------------------------------------
     - Rpi 400
          - A faster Raspberry Pi 4 within a complete keyboard.  I personally don't see this device being 
            useful with this particular amateur radio project but it might be interesting for some people.
          - This is essentially a 1.8Ghz Rpi4 (stock clock is sped up from 1.5Ghz) with 4GB yet everything 
            else is the same except:
               - one less USB 2.0 slot (used by the keyboard)
               - No DSI display or CSI2 camera ribbon connections

     - Rpi4 / CM4 Compute module
          - The Rpi4-compute model departs from the previous sparse offerings and now has much of the same functionality 
            as the regular Rpi4-B (even Wifi, BT, and Gigabit Ethernet) with these notable changes:
             - PCI-Express: Instead of a pair of USB 3.3gen1 ports found on the Rpi4; the CM4+CM4 I/O board offers a 
                            PCIe 2.0 x1 slot on the CM4 I/O board
             - Wifi: This board now has a a u.FL external antenna jack 
             - Storage: Offers 0, 8, 16, or 32GB of eMMC onboard storage (faster than the CM3+ eMMC support)
             - I/O to Compute Module 4 I/O (CM4IO board): This module uses a new connector type to get external I/O
               (No more SO-DIMM connector)

             - CM4IO expansion board offers:
                 - PCIe 2.0 1x slot
                 - POE-capable Gigabit Ethernet with IEEE 1588 timing support
                 - 2 USB 2.0 ports
                 - An 8pin header for two more USB 2.0 ports
                 - A real-time clock with battery backup
                 - 2 full sized HDMI video ports (instead of the original Rpi4 micro-HDMI ports)
                 - 4pin 12v fan header connector (has PWM and TACH)
                 - 2x analog A2D inputs (AIN0 and AIN1) via a MXL7704 chip
                 - A 4pin PSU outbound power connector (similar to a classic 3.5" floppy power connector)
                 - 12-24v DC barrel-style power connector
          
     - Rpi4 Model B:
          - The Rpi4 has a new USB controller that's directly connected to the SOC Chip via a PCI-Express 
            instead of the previous slow USB 2.0 (480Mbps) link for much improved USB support
          - The Raspberry Pi 4 now has two USB 3.0 (now named USB 3.2 Gen 1) ports and two USB 2.0
            ports each served from their own controllers
          - The Rpi4 now has a true wire-speed wired Gigabit Ethernet via a connection directly from the SOC chip
          - The Rpi4 has added four ADDITIONAL serial port UARTS (but enabling them requires taking other functionality away)
          - The Rpi4 has Bluetooth 5.0 support
          - The Rpi4 has a newer generation video chip supporting dual HDMI displays
          - The Rpi4 now can come in 1GB, 2GB, 4GB, and 8GB of RAM 
          - The Rpi4 now uses a USB-C connector for power in as well as OTG USB support
          - The Rpi4 has newer generation CPU cores that are clocked faster 
          - The Rpi4 now places all Broadcom firmware on a dedicate EEPROM chip (no longer on the SD card)

     - Rpi3+
          - The Rpi3 now offers a Gigabit Ethernet (1000Mbps) port which is substantially faster 
            than the previous generation board's FastEthernet (100Mbps) but it's still on a shared USB bus
          - The Rpi3+ has dual-band 2.4Ghz and 5.0Ghz Wifi-5 802.11AC Wifi
          - The Rpi3+ has Bluetooth 4.2 support
          - The Rpi3+ adds support for Power over Ethernet (PoE) when an additional HaT board is connected
          - The Rpi3+ has CPU cores that are clocked faster 

     - Rpi3:
          - The Rpi3 adds 2.4Ghz 802.11n Wifi 
          - The Rpi3 adds Bluetooth 4.1 support
          - The Rpi3 now has 64bit processors
          - The Rpi3 has newer generation CPU cores that are clocked faster 

     - Rpi2
          - The Rpi2 now has 1GB of RAM
          - Now has a 40pin GPIO header
          - The Rpi2 now has four CPU cores and each are clocked faster 

     - Rpi1 or RPi1+
          - Has a 40pin GPIO header instead of the 26pin header
          - Has 4 USB 2.0 ports instead of 2
          - MicroSD friction-slot instead of larger SD card
          - Better power regulators which lowers the power consumption

     - Rpi0w or Rpi0
          - Cheapest and smallest Rpi available with the same CPU and performance as a Rpi1
          - Has 1 USB 2.0 ports via a micro-USB OTG port (requires an adapter cable)
          - Rpi0w has Wifi and BT
          - The Bluetooth support on the Rpi0w has hardware flow control wired in so it can
            can go considerably faster than say the Rpi3 which doesn't have the flow control lines
          - 40pin GPIO header being installed is optional 
          - No wired Ethernet port


   Much deep details on the improvements in various categories
   -----------------------------------------------------------

   - CPU Cores:
     ----------
        400, CM4, Rpi 4, 3B/A+, CM3, 3, and 2 : Four ARM cores
        Rpi Zero-W, Zero and v1 A/B           : One ARM core


   - CPU core technologies
     ---------------------

        Clocking frequencies:
        ---------------------
        400          : 1.8Ghz per core (initial benchmarks say this is 18% faster than a Rpi4)
        CM4, 4       : 1.5Ghz per core
        3B+,3A+      : 1.4Ghz per core (below 70 degrees C and 1.2Ghz when above 70 degrees C)
        CM3+         : 1.2Ghz per core
        3            : 1.2Ghz per core
        Zero, Zero W : 1.0Ghz on a single core
        2 v1.2       : 900Mhz per core (underclocked)
        2 v1.1       : 900Mhz per core
        1,1+         : 700Mhz on a single core


        CPU Generation:
        ---------------
        400,CM4             : Cortex-A72   ARM8-A cores (BCM2711C0T 28nm SOC chip
                              - Other than a higher clock rate, it's unclear what else is new here
        4                   : Cortex-A72   ARM8-A cores (BCM2711B0T 28nm SOC chip; similar generation 
                              to the Qualcomm Snapdragon 650, Snapdragon 652)
        Rpi 3A+/B+,CM3+     : Cortex-A53   ARM8 cores   (BCM2837B0 SOC 40nm chip)
        Rpi 2 v1.2          : Cortex-A53   ARM8 cores   (BCM2837   SOC 40nm chip)
        Rpi 2 v1.1          : Cortex-A7    ARM7 cores   (BCM2836   SOC 40nm chip)
        Rpi Zero W          : ARM1176JZF-S ARM6L core   (BCM2835   SOC 40nm chip)
        Rpi 1 A/B and +     : ARM1176JZF-S ARM6L core   (BCM2835   SOC 40nm chip)


        CPU Cache details:
        ------------------
        400, CM4, Rpi4 cores       : 32KB level 1 cache and   1MB Level 2 cache memory
        Rpi 3B+, 3A+, and 3 cores  : 32KB Level 1 cache and 512KB Level 2 cache memory
        Rpi 2 v1.2 cores           : 32KB Level 1 cache and 512KB Level 2 cache memory
        Rpi 2 v1.1 cores           : 16KB Level 1 cache and 256KB Level 2 cache memory 
        Rpi 1,+, Zero,Zero-W cores : 16KB Level 1 cache and 128KB Level 2 cache memory 


        CPU Instruction details
        -----------------------
        400, CM4, Rpi 4     * Cortex-A72 have a 15-instruction pipeline depth
                            : Support for out-of-order instruction execution

        Rpi CM3+,3+,2 v1.2  * Cortex-A53 have a  8-instruction pipeline depth
         

        Thoughts on CPU performance differences
        ---------------------------------------
        400, CM4, Rpi4: Each of the Rpi 4 A72 cores are said to offer a 300% performance increase over the previous A53 
                   based ARM cores due to the technology points mentioned above.  How is this possible?  The Rpi v3's 
                   Cortex A72 CPUs improved pipeline depth and out-of-order instruction execution abilities make a 
                   big difference.  This means that if the two CPUs were running at the same clock speed Cortex-A72 
                   processors would still run significantly faster (and use more power) compared to their RPI3+ / 
                   RPI3 A53-powered ancestors.

        Older   The 3B+ A53 CPU cores have a 30% performance improvement in the CPU instruction set performance 
        gen:    PER CORE compared to the Raspberry Pi 2 v1.1's Cortex-A7 4-core ARM7 cores.  These points alone 
                show the substantial performance increase over the years and remember: count the cores.  For the 
                older v3B+: that's 30% better performance x 4 cores or 120% faster than the first-gen Rpi2!

        Oldest  The Rpi Zero-W, Older non-wireless Zero, v1-B, and v1-A boards use the old and obsolete ARM 
        gen:    ARM1176JZF-S CPU with the ARM v6L CPU instruction set.  While this CPU is still supported in 
                the Raspbian distro, many other ARM-enabled Linux distributions have DROPPED support for it.  
                Those ARM6L CPUs are substantially slower and is less efficient than even a Raspberry Pi v2.  
                Raspbian is one of the last Linux distros to actively maintain this old CPU and instruction set.
                I generally only recommend people to use the Rpi 0-W if you need the lowest lower power consumption 
                or the smallest physical footprint.  Don't get me wrong, I think the Zero-W is a great little 
                board but it's very old technology wise compared to it's other Raspberry Pi cousins.  


        64 vs 32bit:
        ------------
        400, CM4, Rpi 4, 3B+, 3A+, 3 : 64bit cores
        Rpi 2, Zero W, Zero, v1 A/B  : 32bit cores

           The four cores on the 4, 3B+, and 3 now support 64bit.  The Raspbian Buster through Jessie (8.0) 
           kernels does support 64bit but the distros packages and binaries remain built only for 
           32bit CPUs as there there is questionable speed vs bloat benefit.  The Raspberry Pi v2, 
           Zero W, and v1 only offer 32bit cores.  Please remember that even though a CPU is 64bit, 
           it doesn't necessarily gain you much unless you have LOT more memory to compensate for 
           the 2x larger data space requirements.  A little board like an Rpi used to not have a lot 
           of RAM so didn't make much sense.  

           See the "OS Version" section below about 32bit and 64bit OS distributions.


           64 vs 32bit kernel support:
           ---------------------------
           https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md

           /boot/kernel.img supports 32bit-only and is used by RPi 1B, 1A, A+, B+, 2B (first version), Zero, 
              Zero (with camera), Zero Wireless, ComputeModule1 
              BCM2835

           /boot/kernel7.img supports 32bit-only and is used by the RPi2B2, RPi3B, ComputeModule3 and ComputeModule3L
              BCM2836 (RPi2) and BCM2837 (RPi3)

           /boot/kernel7l.img supports 32bit-only and is used by the RPi4
              BCM2711

           /boot/kernel8.img supports 64bit and can be used by the Pi4, Pi3, and Pi2B rev1.2 boards
              BCM2837 (RPi3) or BCM2711 (RPi4)



   - RAM Size
     --------
        400                : 4GB of RAM
        CM4                : 1, 2, 4, or 8GB of RAM versions  (1GB version discontinued in favor of 2GB being baseline))
        4 (2nd gen)        : 2, 4, or 8GB of RAM versions  (1GB version discontinued in favor of 2GB being baseline))
        4                  : 1, 2, or 4GB of RAM versions
        CM3+,3B+/A+,v3,v2  : 1GB   of RAM 
        Zero, Zero-W, +, 1 : 512MB of RAM
        1A+,1A             : 256MB of RAM


   - RAM technology and clocking:
     ----------------------------
        The RAM on the 3A+, 3B+, 3, and Zero-W is clocked 50Mhz faster than the Rpi v2 and v1

           400, CM4, 4             : 3200Mhz LP DDR4-2400 RAM
           CM3+, 3A+/B+            :  500Mhz LP DDR2 RAM
           3 / Zero-W, Zero        :  450Mhz DDR2 RAM
           v2, 1+, 1               :  400Mhz DDR2 RAM

        https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md


   - GPU technology:
     ---------------
           400, CM4, 4               * Video Core VI GPU
                                     - Openly ES 3.0 graphics
                                     - Supports H.265 (4KP60 decode) in hardware
                                     - Supports H.264 (1080p60 decode, 1080p30 encode)

      CM3+,3+, 3, 2, 1+, 1           : Video Core IV CPU
                                     - Openly ES 2.0


   - GPU Clocking:
     -------------
        The GPU video chip used on all Raspberry Pi models is the VideoCore IV but the Rpi 3B+, 3 and Zero 
        W run 50Mhz faster:

           400, CM4, 4     : 500Mhz
           3+,             : 400Mhz
           3, Zero-W, Zero : 300Mhz
           v2, v1          : 250Mhz



   - HDMI Display details
     --------------------
           CM4                     * Two full sized HDMI ports with the same display connectivity as the Rpi4 via the 
                                     optional I/O board; no direct video connections on the CM4 itself

           400, 4                  : Two micro-HDMI 2.0 ports for dual displays
                                      - dual displays can run at max 4Kp30 (3840 x 2160) resolution
                                      - single display can run at max 4Kp60 (3840 x 2160) resolution
                                        with the other display at 1080p
                                      : 4Kp60 hardware decode of H.265 (HEVC) video
                                      : 1080p60 hardware decode and 1080p30 hardware encode of H.264 (AVC) video
                                      : There have been reports that different HDMI display resolutions 
                                        might interfere with the 2.4Ghz wifi radio.  More research is being 
                                        done here

           3+, 3, 2, 1+, 1         : One HDMI 1.3 port (full sized connector) running at
                                     max 2560 x 1600 resolution

           
   - Composite Video
     ---------------
        400                        : No composite video output available

        CM4                        : Composite video support is on the 14pin header on the CM4IO board

        4, 3+, 3, 2, 1+            : Composite video via the TRRS audio connection
 
        1                          : Composite video via RCA connector

    
   - MIPI DSI display output
     -----------------------
        400                        : No ribbon connections available

        CM4IO                      : 2x MIPI DSI output display 22pin via the optional CM4IO board
                                     no direct connections on the CM4 itself

        All Pi versions            : on-board two-lane MIPI DSI output display port
                                     except the Zero-W, Zero which doesn't have the DSI output port

   - MIPI CSI-2 camera input
     -----------------------
        400                        : No ribbon connections available

        CM4IO                      : 2x CSI-2 camera input - 22pin ribbon connections
                                     no direct connections on the CM4 itself

        4, 3+, 3, 2, 1+            : one 22pin ribbon connection to an external camera

        All Pi versions            : on-board two-lane MIPI DSI display port
                                   : two-lane MIPI CSI camera port
                                     except the Zero-W, Zero which doesn't have the DSI port


   - Wireless Wifi networking:
     -------------------------
        CM4 (Compute)     : Same Wifi support as the Rpi4 but it offers an electrically switchable u.FL connector
                           for external antenna support

        400,CM4,4,3A+,3B+ * dual-band 2.4Ghz and 5.0Ghz Wifi-5 aka support for 802.11 B/G/N/AC(Wave1) 
                            300Mbps Wifi using the Cypress CYW43455 chip with a new (superior) on-board Proant 
                            resonance cavity antenna design 
                          : Various reports gives the Rpi v4 Wifi connection running on the 5.0Ghz band
                            a 20% speed improvement over the Rpi v3+
                          : no U.FL external antenna solder pads available except on the CM4

        4                 : There have been reports that different HDMI display resolutions might interfere with 
                            the 2.4Ghz wifi radio.  More research is being done here

        3                 : single band 2.4Ghz 802.11N 150Mbps Wifi via the Broadcom BCM43438 chip that's independent
                            of the USB bus so there is less network I/O contention here 
                          : uses the older ceramic "chip" antenna design 
                          : has U.FL external solder pads

        Zero W            : single band 2.4Ghz 802.11N 150Mbps Wifi : new (superior) antenna design w/ 
                            has U.FL external antenna solder pads

        v2, 1+, 1         : No wireless
        

        More details on the Wifi:
        -------------------------
        400,CM4,4,3A+/3B+ - 2.4Ghz and 5.0Ghz 802.11AC Wifi via a Cypress CYW43455 chip
                          - Uses a similar antenna design as the Zero W which is evidently
                            significantly better than the ceramic chip antenna used on the Rpi3.  
                            Unfortunately, this board removes the u.fl solder pads which could be 
                            used to add an external Wifi antenna
                    
           v3 and Zero W  - 2.4Ghz only 802.11N  Wifi via the Broadcom BCM43438 chip
                          - the Zero W uses a new antenna design which is evidently
                            significantly better than the antenna used on the 3.  Unfortunately,
                            it also removes the u.fl solder pads which could be used to add 
                            an external Wifi antenna


   - Wired Ethernet Connectivity:
     ----------------------------
        400, 4, 3B+          : Gigabit Ethernet (1000Mbps)  

        400                  : The 400 doesn't include any link or activity LEDs on the connector (bad!)

        CM4                  : CM4 has the Ethernet chip onboard the CM4 but the RJ45 and magnetics are on the 
                               optional CM4IO board)

        3, 2, 1+, 1          : Fast Ethernet    ( 100Mbps)

        3A+, Zero, Zero-W,1A : No wired Ethernet option
   
        CM4           * In addition to supporting Gigabit Ethernet, this support supports the in-band 
                        IEEE-1588 timing standard

        CM4, 4        * Gigabit Ethernet (1000Mbps) using the Broadcom BCM54213 chip connected directly to 
                        the Broadcom ASIC providing near wire-speed performance (945Mbps - 5 times that of an 
                        Rpi 3B+)
                      - RJ45 and USB connections are flipped to opposite sides compared to previous Rpi
                        versions
                      - Power over Ethernet (PoE) support is available via the use of a PoE HAT board
                      - The CM4 compute module has the Gigabit Ethernet MAC and part of the PHY on the actual
                        module but the connector and magnetics are on the optional I/O board

                         NOTE: Neither the PCIe slot or FAN connector will function when the setup is powered 
                               via PoE

        3B+           - Gigabit Ethernet (1000Mbps) using the Microchip LAN7515 chipset.  
                        Performance is significantly limited due to still being connected via a shared 480Mbps 
                        USB2.0 bus (roughly 330Mbps throughput max)

                      - The new 3B+ also supports Power over Ethernet (PoE) with the
                        addition of a PoE HAT board.  It's also worth noting that the
                        PXE LAN booting feature is now enabled by default on this new board

        3, 2, 1+, 1   - Fast Ethernet (100Mbps) using the SMSC LAN951x chipset (Rpi 3 and 2B)


   - Bluetooth (BT) connectivity:
     ----------------------------
        400, CM4            * Same Bluetooth support as the Rpi4 but it offers an electrically switchable u.FL connector
                              for external antenna support

        4                   - BT v5.0 with BT-Low Energy (LE) support on the 2.4Ghz spectrum
                              via a Cypress CYW43455 chip : quadruple the range and roughly double the speed

        3A+, 3B+            - BT v4.2 with BT-Low Energy (LE) support on the 2.4Ghz spectrum
                              via a Cypress CYW43455 chip

        v3 and Zero W       - BT v4.1 24Mbps with BT-Low Energy (LE) support on the 2.4Ghz spectrum
                              via the Broadcom BCM43438 chip

        2, 1+, 1, Zero-nonW - No BT support


   - USB Connectivity 
     -----------------
        400               * Two USB 3.2gen1 5.0Gbps ports and one USB 2.0 port similar to the Rpi4 (see below)

        CM4               * Two USB 2.0 A-connector ports are available as well as an additional 2 USB ports can be
                            made available via a 10pin header connection via the optional I/O board.
                          - No USB 3.0 ports are available as that connection to the CPU was reused for the PCI-e slot
                          - the micro-USB adapter on the CM4IO board is only used to upgrade the firmware on the CM4 only

        Rpi 4             : Two USB 3.0 ports (aka USB 3.2gen1) running at 5.0Gbps via one VIA Lab VL805 
                            (one controller) connected via PCI-Express.  Performance is said to be maxed out at
                            about 4Gpbs due to only having one PCI-Express line to feed the USB ASIC
                          : two USB 2.0 ports running at 480Mbps via the same VIA Lab VL805 (second controller) 
                          : One USB 2.0 OTG port (USB-C power connector)

        3B+, 3, 2, 1+     : Four USB 2.0 ports connected to a single SMSC LAN9514 480Mbps USB 2.0 hub chip
                            via the the main BCM283x SOC chip; this connection to the SOC chip is also shared with the 
                            wired Ethernet interface

        1B                : Two USB 2.0 ports connected to a single SMSC LAN9512 480Mbps USB 2.0 hub chip
                            from the main BCM2835 SOC chip; this connection to the SOC chip is also shared 
                            with the wired Ethernet interface

        Zero, 3A, 1A      : One  USB 2.0 port as On-the-Go (OTG) port via the single 480Mbps USB 2.0 controller
                            directly connected to the SOC chip


   - Serial port connectivity
     ------------------------
        Rpi documentation   https://www.raspberrypi.org/documentation/configuration/uart.md

        400, CM4, Rpi 4   * The Rpi4 offers 4 additional PL011 hardware serial ports using alternative dtoverlay 
                            setups with and without flow control support.  Enabling some of these overlays will take 
                            over and impact other pinout functions such as the I2C-0 bus, etc.  The enabling
                            of flow control on these ports will consume additional GPIO ports.  See
                               https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=244827&sid=9db91354b7e40132cb4f450bf8039f66
                            for more details as the standard Rpi UART documentation doesn't cover this yet.
                            The Rpi4 also has the other two serial ports as well.  See the below RPI models to 
                            understand those port offerings

        3B+,3B+,3,Zero W  - All Rpi units that come with Bluetooth Low Energy (LE) support come with two serials ports
                            via the Broadcom BCM43438 chip.  The PL011-based serial port which supports hardware flow 
                            control is mapped to support the BT system by default.  The second serial port called the 
                            "mini-uart" is a software emulated which is mapped to supporting the serial console function 
                            if enabled.  This emulated serial port has caveats as is variably clocked to the GPU part of 
                            the chip which creates reliability problems.  This second port also doesn't support flow control.
                            You can swap which UART serves which function depending on what function is more important to you

        2,1+,1,Zero-nonW  - One hardware PL-011 hardware UART with flow control pins is included


   - Storage physical format
     -----------------------
        CM4                       : With the CM4IO board, NVMe SSDs can be connected via an adapter though you cannot boot
                                    from this storage currently (as of 11/29/20) but I imagine this will change in time
                                  : Offers 0, 8, 16, or 32GB of eMMC onboard storage (faster than the CM3+ eMMC support)
                                  : Micro-SDXC card slot available on CM4-lite versions (without any eMMC storage installed 
                                    - same SD card support as standard Rpi4 versions

        400, 4,                   : Micro-SDXC card; non-UHS-II connector (cards with double row of pins)

        CM3+                      : 0 or 8GB of eMMC onboard storage
                                  : No uSD slot but I/O pins are on SO-DIMM connector

        CM3                       : 0 or 4GB of eMMC onboard storage
                                  : No uSD slot but I/O pins are on SO-DIMM connector

        3+, 3, 2, Zero-W, Zero,1+ : Micro-SDHC card; non-UHS-II connector (cards with double row of pins)

        1                         : full-sized SD card

        Compute1, Compute3        : 4GB eMMC onboard

        Not sure what class/kind of SD card you have running in your Pi?  Try out these CSD decoders:
           CSD v1.0: https://goughlui.com/static/csdecode.htm
           CSD v2.0: https://goughlui.com/static/csdecode2.htm


   - Storage booting support
     -----------------------
        CM4                    : Same support as the Rpi4 - booting off an NVME SSD via the PCIe slot
                                 is not supported today

        400, 4, 3+, 3          : Boot off microSD, USB, PXE (Rpi4 PXE support coming later)

        2,Zero-W, Zero,1+,1    : Booting via a the SD card


   - Onboard storage speed:
     ----------------------
        CM4                    : Onboard eMMC storage is substantially faster than any SD card but is still
                                 much slower than a NVME-based SSD attached via the PCI-e slot or a SATA-base 
                                 SSD attached via USB 3.0
                               - 8bit eMMC interface on CM4 is faster than the 4bit eMMC interface on CM3

        400, 4                 : Supports 400Mbps / 50Mbps transfer rates via SD "UHS-1" cards.  Performance
                                  varies wildly depending on SD card vendor (see URLs below)

                                 V-rated cards don't apply as that requires UHS-II or better cards

                                 Much higher performance can be had using USB 3.0 (625 Mbps) based flash 
                                 pen drives but performance varies wildly depending on vendor

        3+,3,2,Zero-W,Zero,1+  : Supports 200Mbps / 25Mbps transfer rates via SD "High Speed" cards
                                 by default (overclocking is possible for higher speeds at the risk of stability
                                 issues.  The Pi does not support 1.8V or U1 writes

        1                      : Supports 160Mbps / 20Mbps transfer rates via full-sized SD/MMC card


        Understanding which is the right SD technology for your Pi?  See
           http://stuffjasondoes.com/2018/07/26/raspberry-pi-3-b-sd-card-performance-for-value-analysis/

        Not all SD card manufacturers are equal read vs write speed wise.  Please see this URL for a good set 
        of real world benchmarks:

           https://www.jeffgeerling.com/blog/2018/raspberry-pi-microsd-card-performance-comparison-2018


   - Firmware support
     ----------------
        400, CM4, 4            : All initial firmware startup is read from a dedicated EEPROM chip

        All older Rpi versions : All firmware files are read from the SD card


   - Audio Connections
     -----------------
        400                : Audio can be via HDMI; no TRRS 3.5mm jack

        CM4,4,3+,3,2,1+,1  : stereo audio out via TRS 3.5mm jack
                           : Audio can be via HDMI or dedicated audio output

        Zero-W, Zero       : No TRS audio output


   - GPIO connectivity and features:
     -------------------------------
        CM4                     * 40pin header from the optional CM4IO board with the same support as the Rpi4

        400, 4                  : 40pin header 
                                : 5x SPI, 6x I2C, and 6x UART functions via the alternative pinout mappings
                                : Max GPIO switching speed of about 50.8 KHz

        CM3+                    : Full Broadcom connectivity available on SO-DIMM interface 

        3+,3,2,Zero-W,Zero,1+   : 40pin header
                                : one SPI, one I2C, one Serial UART
                                : Max GPIO switching speed of about 16.1 KHz on the 3B+

        1                       : 26pin header
                                : one SPI, one I2C, one Serial UART



   - Raspberry Pi Foundation Compute module I/O boards
     -------------------------------------------------
        CM4                : Pair of new high density connectors to the optional CM4IO board

        CM3+, CM3, CM2     : Uses the JEDEC DDR2 SO-DIMM connector


   - There are a LOT of 3rd party compute module I/O boards coming to the market these days
     especially for the CM4 board to do ALL kinds of things


   - PCI-e Expansion Slot support
     ----------------------------
        CM4                     : 1x PCI-e 2.0 1-lane slot via the optional CM4IO board
                                - Known to work with various USB3 controllers and NICs
                                - Known issues around not supporting video cards at the moment due to 
                                  PCIe "BAR" parameters


   - RTC Support
     -----------
        CM4                : The optional CM4IO board has an onboard PCF85063AT RTC chip with a coin-cell 
                             battery backup holder.  This is available via on i2c-10 address 0x51


   - Fan Connector
     -------------
        CM4 only           : The optional CM4IO board has a 4pin fan connector that supports +12v fans
                             with PWM control and TACH speed monitoring via the I2C bus (i2c-10 address 0x2f)


   - Power Connection and current requirements
     -----------------------------------------
        CM4                : Uses a barrel connector via the optional CM4IO board supporting +12v to 26v
                             (lower or higher voltages than +12v forbids the use of the PCIe connector, PSU,
                             and fan headers)
                       
        400, 4             : USB-C connector at 5.0v @ 3.0A providing 1.2A for USB devices.  The change 
                             to a new connector is due to that the legacy USB2 Micro-USB connector is 
                             aging and generally cannot supply the required 3.0A of current

                             NOTE: 2.5A is allowed if any attached USB devices consume less than 500MA

        CM4, 4, 3B+        : Support for Power over Ethernet using an additional PoE HAT board

          NOTE#2:  There was a known issue with the v1.1 revision of the Rpi 4 boards that their design
                   has an issue when using "E-type" USB-C cables which include built-in electronics
                   to negotiate voltage, current, and other capabilities.  These type of cables are 
                   mostly found as new laptop charger power bricks + cable for say Chromebooks, Apple
                   Macs, etc.  Until a new version of the Rpi4 is released to fix this, the work around 
                   here is to NOT use E-type power bricks and/or cables.  This was fixed in revision
                   v1.2 of the Rpi4 4GB only boards

        Rpi 3+, 3, 2, Zero-W, Zero, 1+, 1 :  use the USB 2.0 "micro" USB connector type
           3B+, 3, 2        : Micro-USB at 5.0v @ 2.5A
           1+, 1            : Micro-USB at 5.0v @ 1.8A
           Zero-W, Zero,1+,1 : Micro-USB at 5.0v @ 1.0A


   - Power consumption and management:
     ---------------------------------
        Different Rpi units consume different amounts of power depending on the number of CPU
        cores and other features the offer.  Generally speaking the Raspberry Pi Zero non-wireless is 
        probably the lowest power consumer closely matched with the Zero-W and then the v1-A version.
        Those are also some of the slowest versions available so the compromise of performance vs. 
        power vs. features is up to you!  Some of the below URLs have good power consumption charts
        to help you learn more.
        
        The Rpi 4 and 3+ have the MXL7704 power management chip which should make these units more 
        stable at sustained high loads.  It's also mentioned that the power consumption of the 4 and 
        3B+ are notably HIGHER than the model 3.  A high quality 3.0A power supplies is required
        for the Rpi v4 and 2.5A power supply for the 3+ is even *more required* than it was before.   

        The initial releases of the Rpi4 were reknown for thermal throttling due to high power 
        consumption.  New firmware releases in October and November 2019 have made significant 
        improvements here.  You can read more about that here:

           https://www.raspberrypi.org/blog/thermal-testing-raspberry-pi-4/

        It's also mentioned that the 3B+ can be more successfully DECLOCKed to 600Mhz possibly lower 
        the power consumption but this thread generally recommends to buy OLDER Rpi versions if 
        power consumption matters to you:

           https://www.raspberrypi.org/forums/viewtopic.php?t=139013


   - Operating temperatures / Cooling
     --------------------------------
        400                 : The unit has a metal shield which acts like a large heatsink for the SoC chip 
                              only (nothing for the RAM, Ethernet controller, etc.) and the bottom of the 
                              keyboard case has vent holes.  Initial reports say the unit doesn't do any
                              CPU throttling with some level of overclocking but time will tell.  I'm also
                              curious how warm some the keys might get.
                                
        CM4                 : Thermal requirements should be the same as the Rpi4

        4                   : The Rpi4 runs considerably hotter than the Rpi 3+ or earlier even at idle.
                              Some major power consumption improvements have been in the October and November
                              2019 firmware releases.  Real power draw and heat issues will depend on how you 
                              use your Pi but see the power management section below for details on temperatures 
                              and CPU throttling points.  Also review the benchmark links for more details on 
                              thermal measurements

        4, 3+               : The CPU now has a heat spreader on the CPU chip to better support cooling
                              without a heat sink.  It also has an improved power management system for 
                              being more stable at sustained high loads.  See the power management section 
                              for more details

        3,2,Zero-W,Zero,+,1 : These versions don't generally have any unique cooling features so
                              depending on the workloads, some people need to add heat sinks and/or
                              fans


     Operating System support:
     -------------------------
     400, CM4, 4, 3+, CM3+, CM3, 3, 2+, 2, 1+, 1, 0w, and 0:

        The officially supported Linux distro is "Raspberry Pi OS" (formally named "Raspbian") 
        which supports *ALL* versions of the Raspberry Pi hardware from the Rpi v1, the compute 
        modules, all the way to the new 8GB CM4.  As new Rpi hardware versions have been release, 
        you must use the correct minimum version of the OS which includes the required drivers.
        See https://en.wikipedia.org/wiki/Raspbian to better understand those versions.

     Raspbian has always been a 32bit only OS but when the Raspberry Pi 3 was released, the
     kernel was upgraded to 64bit but all the userland programs remained 32bit.  Now we have
     the Raspberry Pi 4 with 8GB and with it, a new native 64bit version of the Raspberry Pi
     OS.  The new version of the OS consumes more memory but it can also provide some significant
     performance improvements:

        Benchmarks with Raspberry Pi OS 64bit from May 2020:
        https://www.tomshardware.com/news/raspberry-pi-4-8gb-tested

        Some performance benchmarks from Jan 2020:
        https://medium.com/@matteocroce/why-you-should-run-a-64-bit-os-on-your-raspberry-pi4-bd5290d48947


    As of 5/30/20, the 64bit version of Raspberry Pi OS is in BETA only with various areas of
    hardware acceleration and other items still missing.  If you want to give it a try, see:

       https://www.raspberrypi.org/forums/viewtopic.php?t=275370


     Beyond that, there are a *LOT* other distros supporting the Raspberry Pi for either their
     style of Linux or for unique purpose-built reasons like:

           - Ubuntu
           - Fedora
           - Debian
           - Centos
           - ArchLinux for complete kernel+userland 64bit support
           - RetroPi for game emulation
           - etc


   - Cases for the Raspberry Pi
     -------------------------------
     There are literally HUNDREDS of 3rd party cases out there for the various Raspberry Pi SBC versions
     but here are some thoughts at least from the Raspberry Pi Foundation but I find the 3rd party ones
     better across the board.  See the appendix in this documentation for more discussion about good and
     bad cases, fans, etc:

        400        : The keyboard is the case

        CM4        : I'm not aware of any cases for the CM4 or CM4IO board yet but I'm sure they will
                     come

        4          : new case design for the dual micro-HDMI video; USB-C power connector, swapped 
                     RJ45 and 4xUSB connections; 40pin GPIO
  
        3+,3,2,1+  : full size HDMI video, TRRS audio/video, 4xUSB, 1xRJ45, micro-USB power connector, 
                    40pin GPIO

        1          : full size HDMI video, TRS audio, RCA composite video, 2xUSB, RJ45 network, 
                     micro-USB power connector, 20pin GPIO


   - Known hardware issues:
     ----------------------
     - Full list of Rpi board revisions
       https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md

     - Rpi 4 v1.0 PCB : not compatible with e-type USB-C cables : fixed in the Rpi4 4GB v1.2 boards

     - Rpi 4 v1.0 PCB : has known interference issues with Wifi and one of the HDMI ports when in 4k resolution

     - Known compatibility issue with USB 3.0 hubs and all Rpi (except Rpi4) USB 2.0 ports
       with full or low-speed USB devices - https://www.raspberrypi.org/documentation/hardware/raspberrypi/usb/README.md


   - Rpi SBC specification URLs:
     ---------------------------
     - A nice technical overview (but not 100% complete) of all the different boards with a table can be found here:
         http://socialcompare.com/en/comparison/raspberrypi-models-comparison

     - Raspberry Pi CM4 I/O board specs:
         https://www.raspberrypi.org/products/compute-module-4-io-board/?resellerType=home
         https://datasheets.raspberrypi.org/cm4io/cm4io-datasheet.pdf

     - Raspberry Pi 4 specs:
         https://www.raspberrypi.org/products/raspberry-pi-4-model-b/specifications/


   - Benchmarks on various Rpi hardware
     ----------------------------------
     - https://www.raspberrypi.org/magpi/raspberry-pi-4-specs-benchmarks/
        - lots of detail including power draw comparisons for all versions of Rpi boards

     - https://www.tomshardware.com/reviews/raspberry-pi-4-b,6193.html

     - https://www.raspberrypi.org/magpi/raspberry-pi-3-specs-benchmarks/

     - A complete 3B+ breakdown: 
       http://blog.pimoroni.com/a-deep-dive-into-the-raspberry-pi-3-b-hardware/

     - Run your own lightweight Pi benchmark (CPU, Memory, Storage, Internet, :
       https://github.com/aikoncwd/rpi-benchmark

1.a Choose a quality SD card and how to put a Raspbian image on it


Choosing which micro-SD card manufacturer and even the specific models of the SD card can 
really matter in terms of just outright booting up to also avoiding premature failure.   At a
high level, check out this URL for some SD card recommendations:
See those URLS for some specific SDHC technology options and benchmarks for various performance.  
I would highly recommend the following:

   - NOTE:  Newer Raspberry Pi units support booting from USB (Mass Storage Device - called MSD).
            This means you can boot from USB devices be it SSDs,hard drives (HDD), flash pendrives, 
            etc.  This means booting via a micro-SD is technically no longer required 

   - NOTE #2: PXE booting over the wired Ethernet network port is available on the Raspberry Pi 4, 
              3B+ and 3 but USB/MSD support is available on the 3


   - Use a quality brand name SD card like Sandisk, Samsung, etc. from reputable
     sellers.  There are just too many reports of either cheap cards and/or 
     counterfeit cards not giving the advertised capacity or failing very quickly.
     Using off-brand cards could prove unreliable (corruption, later full-on card 
     death, etc)

        - It's recommended to buy Class-10 cards for better performance and even more recently,
          buy a "A1" class card for this type of I/O usage.  Check out the following URL for 
          more details and how to benchmark your card:

             https://www.raspberrypi.org/blog/sd-card-speed-test/

        - It's recommended to buy a larger capacity SD card than you need : By using a larger quality 
          card, many SD cards can better leverage their (optional) built-in wear leveling functionality
          to make the card last longer before bad sectors begin to show up

        - (OPTIONAL) - If you have access to a Windows or Mac machine with an SD card reader, 
          it's highly encouraged to format any new SD card with the Official SD Association card 
          formatter programs available at: 

             https://www.sdcard.org/downloads/formatter_4/

          Why?  This tool will verify that the card's actual storage capacity, 
          identify any physical card issues, and then format it (removing any potential
          malware on the card as well).  After using this tool, you can install it in 
          your Linux computer to image the card with the Raspbian OS


  1. Put your purchased quality MicroSD card to existing working Linux computer's SD card reader.  
     This can be on your computer itself or connected via say a USB card reader.  If using a 
     micro-SD card, you might need an inexpensive full-sized SD to micro-SD card adapter (these
     sometimes even come with the new micro SD card).

  2. Run the command "dmesg" on you Linux computer to confirm SD card showed up.  
     On my computer, it shows up as /dev/mmcblk0

1.b Download the newest Raspbian OS release and install it


     Raspbian Buster named 2019-07-10-raspbian-buster-lite.zip is the current image as of 7/21/19.
     The previous Stretch image named 2017-08-16-raspbian-stretch-lite.zip is also available but
     is now officially on it's way out.  I would recommend to download the NEWEST image available
     to a reliable location on your computer.  

     NOTES:

        - NOTE #1:  There are three versions of Raspbian you can run:

          "Desktop and recommended software" - includes a full GUI interface (was previously called Pixel)
              which comes with a lot of other packages like Chromium, Libreoffice, etc

          "Desktop" - includes a full GUI interface and many other packages but is lighter weight
              aka it has a lot less programs pre-installed

          "Lite" - CLI only image (no GUI) which is considerably smaller and light weight
             - A fully patched Buster Lite image with all programs in this doc: 1.5GB used

          For Rpi installations that will never have a monitor attached to it and you'll most
          likely always SSH into it, I recommend to install the *Lite* version.  Why waste all
          that RAM and CPU cycles running the Xwindows system if you're never going to use it!
          If you want to use VNC to remotely control the Rpi via a GUI (and not via native SSH), 
          go ahead and install the "desktop" version.  This document assumes the Lite version is
          installed.


        - NOTE #2: If you're going to be using an Rpi 4, you MUST use the Buster version of Raspbian
                   to support this new hardware.  If you have a 3B+, your minimum version is Raspbian 
                   Stretch and it has to be newer than 2018-03-13.  

        - NOTE #3: If you don't use the correct minimum version of the OS,  it won't boot and instead, 
                   you will see 8 flashes at the rainbow screen via the HDMI output and then stop there)

        - NOTE #4:  Per the comments in 
          https://www.raspberrypi.org/blog/raspberry-pi-3-model-bplus-sale-now-35/ , Raspbian
          Jessie is no longer supported.  It seems that the Raspbian community follows the
          NON-LTS version of Debian schedule shown here:

             https://wiki.debian.org/DebianReleases#Production_Releases

          This means that all users should upgrade to Stretch ASAP to get updates, fixes, 
          security patches, etc


  1. At this stage, you have a few choices to get the Raspbian image installed on the SD card:

    1.a.  From Linux: You can use my image-raspbian-zip-to-rpi-sd-card.sh script that will 
          automatically uncompress and copy the resulting image to the SD card in one step

          To use this approach, do the following:

             cd /tmp
             wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/image-rpi-sdcard-multiformat.sh
             chmod 755 image-rpi-sdcard-multiformat.sh
             sudo mv image-rpi-sdcard-multiformat.sh /usr/local/sbin/

          Next, from the output of the "dmesg" command run above, edit the script and make
          sure the SD card device used in the $DESTDEV variable

          Run the command:

             #Installing Stretch Lite in this example
             sudo /usr/local/sbin/image-rpi-sdcard-multiformat.sh <path-to-image>/2019-06-20-raspbian-buster-lite.zip

          This command will take some time to complete depending on the speed of your SD card,
          your computer, etc.


    1.b.  From Linux: If you don't want to use the above script, you can install the image via a two step process:

             1. Uncompress the downloaded ZIPed image with the command:

                unzip 2019-06-20-raspbian-buster-lite.zip

             2. Now use the following command where "mmcblk0" is the name of your SD card device
                shown above from the bottom output of the "dmesg" command:  

                   dd if=2019-06-20-raspbian-buster-lite.img of=/dev/mmcblk0 bs=2M

    1.c.  From Windows or Mac: If you are using a Windows or Mac machine for the imagine process, 
          please read these alternative guidelines:

             https://www.raspberrypi.org/documentation/installation/installing-images/README.md

  2. Remove your newly imaged MicroSD card and install it into your Raspberry Pi.  On the Raspberry
     Pi 4,3+,3,2,ZeroW,Zero,1 install the SD card with the shiny electrical contacts pointing UP.

2. Cable up and power up your Rpi


  a. Connect your monitor via the HDMI port.  If you only have a VGA computer monitor, there
     are some HDMI to VGA converter devices that cost about $25.  I have one but I found the
     resulting video quality wasn't very good and it ironically spewed RF trash all across
     the VHF spectrum.  Sigh.


  b. OPTIONAL:  Connect your Ethernet cable if you have a Raspberry Pi Model B with an RJ45 
                jack or have a support USB to Ethernet adapter connected to any Raspberry Pi

        If you want to update your Raspberry Pi and install additional software, you'll need 
        and Internet connection.  

        IMPORTANT:
        ----------
        Please note that since your Rpi hasn't received any security hardening yet, there is 
        some risk here if it's connected to a network.  It's HIGHLY recommended that you put 
        your Rpi behind a home "router" or NAT device which doesn't have any direct SSH or 
        other port forwards pointing to the Raspberry Pi's IP address.  If you don't follow 
        this precaution, your Raspberry Pi could get hacked especially if you chose not to 
        disable the default "pi" account that has a well known password!


        To be written:  Add configuring a Raspberry Pi Zero W or Raspberry Pi 3 with Wifi-only 
                        (not using the wired connectivity)

               For the Rpi ZeroW, you can either connect a supported USB to Ethernet adapter 
               to add Wired Ethernet or you can place a configured wpa_supplicant.conf file in
               the SD card's /boot directory.  You'll also want to create an empty
               /boot/ssh file to have the Pi enable SSH access on first boot if you
               want to configure the Pi exclusively via a network connection (no HDMI
               and keyboard connected).

               If you need all this detail right now, there are other guides on the Internet 
               on getting this initially working.  Alternatively, email me and I can 
               help you.


  c. Connect up your powered USB hub to the Raspberry Pi

     1. Connect your USB keyboard and mouse to the USB hub; optionally, you can skip the
        USB hub and connect the KB and mouse directly to the Rpi


  d. Connect your USB sound card directly to the Rpi's USB ports (more on WHY this is required
     in a later section)


  e. Plug in the micro-USB cable power cable which is connected to an appropriate power
     brick to power on your Raspberry Pi.  WATCH the upper right hand corner to see if you
     see a yellow lightening bolt icon or if the red LED on the Rpi occasionally blinks.  
     Why?

        IMPORTANT
        ---------
        The official recommendation from the Raspberry Pi Foundation is to use a 5.1v (not 5.0v) 
        power supply that provides 3.0A of power for the Rpi v4, 2.5A for a Raspberry Pi3, or 1.0A
        for an Rpi Zero-W though a thick, short, and quality made USB cable.  

        I would say that all users *MUST* follow this recommendation for Raspberry Pi v2 and even 
        v1s as well.  Unreliable power is the #1 issue with Raspberry Pis so please don't just use 
        any old power brick with any old USB cable (which might have under-gauged wire and/or are 
        too long).  

        I personally tried using a "quality" LG power brick that stated 5.0v @ 1.8A and while it 
        worked for a while, I started seeing the red LED on the Pi to blink and yellow lightening 
        bolt icon show up up as I added more stuff to it (I2C LCD, USB soundcard, external USB HDD
        (externally powered), etc).  Instead of an expensive "Official Raspberry Pi" supply, I 
        bought a Pro-Elec model # 28-19338 5.1v @ 2.5A supply and it's working well.

        REMEMBER: Longer the USB cable, the high chance of power issues which show up as Raspberry 
                  Pi crashes, corrupt file systems and even permanently physically damaged SD cards!  
                  Long power cords are a BAD idea.

2.a. How to enable the HDMI port to always work even if the cable isn't connected


  If you boot a Raspberry Pi without an HDMI monitor connected, the OS turns off the HDMI port
  to save power.  This means that if you later connect an HDMI port while it's already booted, 
  it won't display anything.  If you want the HDMI port to always work even if the cable isn't
  connected, edit the /boot/config.txt file:

    - nano /boot/config.txt    (you can also use:   vim "/boot/config.txt" if you don't like/know vim)

    - Find the line that has:

        #hdmi_force_hotplug=1

      Remove the # character so it just shows

        hdmi_force_hotplug=1

  Save the file and your done.


     NOTE:  When the Raspberry Pi boots up, it communicates with the HDMI monitor to understand
            the monitor's best settings for the display output.  If you connect a monitor AFTER the 
            the display WILL come up but it might not look the best or might not be at the highest 
            resolution.  Either reboot the Pi with the monitor attached for the best display or
            alternatively, there are commands to try to improve the display manually such as:

              tvservice --explicit="DMT 35 HDMI"

            See the output of the command "tvservice --help" for more possibilities.

     NOTE#2: I've seen many times that if I connect an HDMI monitor to an already running Rpi,
             the OS will crash and you have to remove and re-connect the USB power cable.  This
             is because the initial power draw caused by the monitor (called "inrush current").
             This can be mitigated by properly connecting a set of large capacitors to the 
             +5.0v and +3.3v lines but that is beyond this document.  Google it.

2.b. How to disable Bluetooth and/or Wifi


    +----------------------------------------------------------------+
    | Optional:                                                      |
    |                                                                |
    |    Disabling Bluetooth and/or Wifi minimizes any interference  |
    |    issues with Wifi and also lowers the Rpi power consumption. |
    |    Disabling Bluetooth also returns the use of the on-board    |
    |    hardware serial port (UART) via the GPIO pins which is far  |
    |    more reliable.  Do NOT disable Bluetooth if you intend to   |
    |    use it with other Bluetooth devices like enabling BT serial |
    |    console or connectivity to a Kenwood TH-D74 HT for KISS     |
    |    packet / TNC  access.                                       |
    +----------------------------------------------------------------+

  With the introduction of the Raspberry Pi v3 and Zero W, the Pi team added both Wifi 
  and Bluetooth functionality.  I welcome the new wireless support but it also brings in 
  complexity, power consumption, etc. when you might only want wired Ethernet.  In 
  addition, the Rpi team had to make some disruptive compromises:

     - the original hardware serial console support via the Rpi's GPIO 14/15 pins to 
       /dev/ttyAMA0 was taken over by the Bluetooth interface instead.  The GPIO-pin based
       serial console is now offered via by an EMULATED serial port which is evidently *variably* 
       clocked based on the speed of the GPU which turns out to be very unreliable.  The changing 
       clock speed of the emulated serial port *will* impact the serial console port from operating 
       properly.  There are additional hardware-based URLS say on the Rpi4 and CM4 but for 
       older Raspberry Pi units, you need to decide what you want to do.

     - Note #1: Later versions of the Raspberry Pi OS moved the hardware UART connected via the GPIO 
                pins from device /dev/ttyAMA0 device to the /dev/ttyS0 device

     - Note #2: On the Rpi v4, it seems the use of the secondary HDMI port at higher resolutions 
                interfers with 2.4Ghz wifi channels less than Channel 4 and also any Bluetooth 
                signals.  Try using 1080 or 4k resolutions instead

     - Note #3: On the Rpi v3, it seems that simultaneous usage of the Rpi's Wifi and Bluetooth is 
                not very reliable.  You may see lots of disconnections and re-association on both the 
                Wifi and Bluetooth sides.  This might get improved over time or with later versions 
                of the Rpiv3 hardware

  If you don't have any need for the wifi interface, you can disable it:

     vi /boot/config.txt
     --
     dtoverlay=pi3-disable-wifi
     --


  If you don't have any need for the bluetooth interface, you can disable it:

     vi /boot/config.txt
     --
     dtoverlay=pi3-disable-bt
     --

     sudo systemctl disable hciuart.service
     sudo systemctl disable bluealsa.service
     sudo systemctl disable bluetooth.service


  GPIO Header Serial Console Access
  ---------------------------------
  If you want to restore serial console port access on GPIO pins 14 & 15 to use the Broadcom 
  hardware UART chip for reliable serial connections, see the following URL on how to enable a 
  "dtoverlay" in the /boot/config.txt file, see the following URL.  

     NOTE:  The Raspberry Pi 3B+ has the same limitations as the 3 in this respect


3. Boot up the new image and prepare to do initial security on it


3.a Create a new user and disable the Pi user

      
      Many Raspberry Pis connected to the Internet are getting compromised as people aren't 
      changing the default username and password


        CRITICAL NOTE:  It should be noted that though I could ssh into my Rpi2 as 
           a newly created user like "dranch" with my privately configured password, I could 
           *NOT* log in to the directly connected HDMI/keyboard console!  In troubleshooting 
           this, if I tried to type in my password in the username prompt, the wrong characters
           were popping up (like | or +, etc) on the screen when I typed them in!  To fix this 
           critical issue, see below to set the right keyboard configuration via:

           sudo raspi-config --> Localization Options --> Change Keyboard Layout --> Generic 104-key PC 
              --> Other --> For me, I need "English (US)" --> Now scroll back up and select "English (US)"
              --> "The default for the keyboard layout" --> No compose key --> Finish


        1. Login to your new Rpi as the user "pi" and create a new user with these command.  In this example, 
           we create the user "dranch" (please replace "dranch" with your desired username):

                 sudo adduser dranch

           1.a. Add this new user into the following UNIX groups:

                   sudo usermod -a -G audio,dialout,gpio,sudo,video dranch 

                These groups are needed for:
                - "audio" (allow users to access the soundcard)
                - "dialout" (allow serial port access - if needed)
                - "gpio" (allow access to the GPIO pins)
                - "sudo" (allow root access)
                - "video" group (allow diagnostic permissions to the GPU)


           1.b. If you already created this username before hand and are now adding some of 
                these Unix groups after the fact, you must log out and log back in to use 
                these new permissions.  Test and make sure you can both login using
                this new username and also run sudo commands

        2. Later (meaning NOT now), we will disable the "pi" account but we won't do it just yet


3.b Removing or disabling unwanted packages and services


   I recommend to remove the following packages to make your machine less bloated and more secure

       sudo dpkg -r avahi-daemon libnss-mdns

           What these packages do:

           avahi-daemon : This service is Linux's equivalent to Apple's Bonjour services advertisement 
                          protocol.  It's very chatty and creates a security risk. As such, I recommend
                          you remove it

3.c IPTABLES: Install and configure a simple but effective firewall


  +----------------------------------------------------------------------------------------------+
  | NOTE:                                                                                        |
  |       nftables vs iptables                                                                   |
  |                                                                                              |
  |       Starting with Raspbian Buster, the default BACKEND kernel firewall technology has      |
  |       moved the "nftables" system.  You can learn more about this at:                        |
  |                                                                                              |
  |          https://wiki.debian.org/nftables                                                    |
  |                                                                                              |
  |       It's important to recognize that it seems that Debian Buster's support here seems to   |
  |       be a transition release as the key "nft" program from the nftables package isn't even  |
  |       installed by default.  This means that Buster still expects users to use the iptables  |
  |       utility to configure firewall uses that ultimate programs the new netfilter backend.   |
  |                                                                                              |
  |       I will work on adding NATIVE support for nftables in time but until then, the long     |
  |       standing and well supported iptables remains fully compatible, secure, and is fully    |
  |       supported with all versions of Raspbian.                                               |
  +----------------------------------------------------------------------------------------------+

      Assuming your Raspberry Pi has Internet access (hopefully it's behind an existing firewall 
      to keep it safe until it's running it's own firewall), run:

          sudo apt-get update
          sudo apt-get install iptables-persistent
          #
          # Accept any needed package dependencies like "iptables-persistent" and "netfilter-persistent"


      Depending on your version of Raspbian, you might be presented with a set of color boxes prompting:
      
         "Save current IPv4 rules".  Select YES

         "Save current IPv6 rules".  Select YES


      Create an initial security based upon the rules from https://wiki.debian.org/iptables 
      #
      #  Please note that the above URL file points to the WRONG files installed by
      #     iptables-persistent
      #
      # (modified to allow SSH, not allow HTTP and HTTPS)
      #
      #   You can also find a copy of this file at:
      #   sudo wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/iptables/rules.v4

      1. cd /etc/iptables

         This directory should have been already created, if it it's not there, please create it with:  

            sudo mkdir /etc/iptables


      2. Make a copy of the pre-installed ruleset:

            sudo cp rules.v4 rules.v4.orig
            sudo cp rules.v6 rules.v6.orig


      3. Change the default firewall policies by running:

            #  If your not familiar with how to use the Vi editor, you can
            #  use Nano instead
            #
            # change the INPUT and FORWARD policy lines from "ACCEPT" to "DROP"
            #
            #   NOTE:  Please note that if you want your Raspberry Pi not to be completely 
            #          hidden on the Internet, consider using "REJECT" instead of "DROP" 
            #          in specific rulesets below the POLICY lines in the rules.v4 ruleset.  
            #          Packets that are ultimately REJECTED will get a rejection notice vs. 
            #          be silently dropped.   
            #
            #   NOTE #2: The setting of REJECT in these top policy lines is NOT allowed as 
            #            only ACCEPT and DROP are allowed here.  As such, leave these top
            #            policy lines to DROP for now
            

            #Fetch the IPv4 rules
            wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/iptables/rules.v4

               #Or fire up an editor and copy and past in the following below:
               sudo vi rules.v4


      4. If you plan on using IPv6 (it might be running and you don't even know it), create a 
         copy of the ruleset and create the new ruleset.  You'll need to make similar changes
         in this v6 file that you for v4

            #Fetch the IPv6 rules
            wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/iptables/rules.v6

               #Or fire up an editor and copy and past in the following below:
               sudo vi rules.v6


      5. Create a copy of the ruleset and create the new ruleset:

         This "rules.v4" file will be used to allow in various traffic and ultimately TEST all 
         firewall changes before they are made the default firewall upon every boot).  Add in the 
         the need rules (if not already present) you need/desire but just be sure you understand 
         what you're doing.  If you have questions, Google it first and if you still need help, 
         you can email me.

         The below firewall example includes:

            + ALLOWs incoming SSH connections on TCP port 22
            + ALLOWs incoming PING packets
            + ALLOWs incoming DHCP response packets for the Rpi to get a TCP/IP address
            + ALLOWs all outgoing connections and responses to other allowed sessions
            - DENYs incoming Samba / Windows File/Print traffic
            - DENYs all other incoming traffic

         Do the appropriate copy/pastes and any possible changes you might want:

sudo vi rules.v4
--
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allows all outbound traffic
# You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT

# Allows SSH connections 
#
#  Placing your Rpi on the raw Internet (no firewall in front of it) and having
#  SSH enabled is NOT recommended.  If you need this, I would recommend additional
#  protections (not covered in this document at the moment)
#    - change the default SSH port 22 to something else
#    - port knocking
#    - use SSH keys ONLY (no passwords)
#
# The --dport number is the same as in /etc/ssh/sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

# Now you should read up on iptables rules and consider whether ssh access 
# for everyone is really desired. Most likely you will only allow access from 
# certain IPs.

# Allow ping
#  note that blocking other types of ICMP packets is considered a bad idea by 
#  some remove -m ICMP --icmp-type 8 from this line to allow all kinds of icmp:
#  https://security.stackexchange.com/questions/22711
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

#Allow DHCP incoming addresses
-A INPUT -p udp --sport 67 --dport 68 -j ACCEPT

# Block but don't log local samba traffic - expand to whatever you need
-A INPUT -p udp --sport 138 --dport 138 -j DROP

# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Reject all other inbound - default deny unless explicitly allowed policy:
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT
--

      6. Options on how to activate new or modified rules 

          NOTE:  If you made any mistakes in the above ruleset file and if you activate 
                 the firewall without special precautions, you run the risk of loosing 
                 your network connection!  If this happens, you'll need to re-connect 
                 the Rpi via the local USB keyboard and HDMI monitor to restore access with:
         
                      Basic way to enable rulesets which can pose risk
                      iptables-restore < /etc/iptables/rules.v4.orig
         
           #1 - RECOMMENDED METHOD:
                 I encourage you to use my protected firewall-confirm.sh 
                 script.  This script will activate the firewall and then prompt you
                 to make sure things went OK.  If you don't respond in 30 seconds, 
                 the script will rollback to the previous working firewall ruleset.
                 This is very very helpful!
         
                    cd /tmp
                    wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/firewall-confirm.sh
                    sudo mv firewall-confirm.sh /usr/local/sbin/firewall-confirm.sh
                    sudo chmod 700 /usr/local/sbin/firewall-confirm.sh
         
                    Give it a try with the following and follow the prompts:

                      #1: cp /etc/iptables/rules.v4.orig /etc/iptables/rules.v4.checked
                      
                      #2: Run this command and it's key that the & character is included at the end
                          sudo /usr/local/sbin/firewall-confirm.sh &
         
                      #3: Type in the command "touch /tmp/fwok" within 30 days or the firewall will revert
                          back to the previous working version
         
                NOTE: AH6IX wrote in and told me about the included "iptables-apply" program that's
                      included with the primary iptables package.  That tool evidently does the same thing 
                      as my firewall-confirm.sh script script.  I haven't looked at this program yet but this 
                      might be a good (or better) way to go too.  

           #2 - Alternative method:

                Temporarily load in the new firewall rules
         
                   sudo iptables-restore < /etc/iptables/rules.v4


      7. By loading your new firewall rules, you hopefully you didn't just loose your network connection to 
         your Rpi (you wouldn't if you use my recommended firewall-confirm.sh script above) due to any typos.  
         Confirm you still have a working network connection by hitting the ENTER key a few times.  If you 
         see a bunch of new command line Bash prompts, things are good.  Look at the output of the command to 
         confirm things look like you expect them to:

            sudo iptables -vL
            --
            Chain INPUT (policy DROP 0 packets, 0 bytes)
             pkts bytes target     prot opt in     out     source               destination
                2   100 ACCEPT     all  --  lo     any     anywhere             anywhere
                0     0 REJECT     all  --  !lo    any     anywhere             127.0.0.0/8          reject-with icmp-port-unreachable
             5304  395K ACCEPT     all  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED
                3   180 ACCEPT     tcp  --  any    any     anywhere             anywhere             state NEW tcp dpt:ssh
                0     0 ACCEPT     icmp --  any    any     anywhere             anywhere             icmp echo-request
               33 10824 ACCEPT     udp  --  any    any     anywhere             anywhere             udp spt:bootps dpt:bootpc
             7188 1838K DROP       udp  --  any    any     anywhere             anywhere             udp spt:netbios-dgm dpt:netbios-dgm
            25831 1765K NFLOG      all  --  any    any     anywhere             anywhere             limit: avg 5/min burst 5 nflog-prefix  "iptables denied: "
            32958 2307K REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-port-unreachable

            Chain FORWARD (policy DROP 0 packets, 0 bytes)
             pkts bytes target     prot opt in     out     source               destination
                0     0 REJECT     all  --  any    any     anywhere             anywhere             reject-with icmp-port-unreachable

            Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
             pkts bytes target     prot opt in     out     source               destination
             3884  606K ACCEPT     all  --  any    any     anywhere             anywhere
            --


      8. If things look good, let's save the new firewall ruleset to become your default
         ruleset:

           8.a.  RECOMMENDED: firewall-confirm.sh approach:

                 If you're using the firewall-confirm.sh script and you've now confirmed the new 
                 firewall ruleset seems to work, save that new ruleset as your NEW fallback firewall 
                 ruleset:

                    sudo cp /etc/iptables/rules.v4 /etc/iptables/rules.v4.checked


           8.b.  Alternative approach:

                 #This essentially won't do anything as the rules.v4 firewall is already there but
                 # I put this as a FYI:
                 #
                 sudo sh -c "iptables-save > /etc/iptables/rules.v4"


      9. Now enable the firewall to start up upon every boot by adding the following
         lines in the key startup file:

           sudo vi /etc/network/if-pre-up.d/iptables
           --
            #!/bin/sh
            /sbin/iptables-restore < /etc/iptables/rules.v4
            /sbin/ip6tables-restore < /etc/iptables/rules.v6
           --


     10. Make the script executable with:

           sudo chmod +x /etc/network/if-pre-up.d/iptables
         

     11. To make sure things are working by default if your Rpi is rebooted, let's test it with a reboot!

            sudo /sbin/shutdown -r now


     12. Once the Rpi has rebooted, make sure you can SSH back into it, and ensure that the output of 
         the command:

            sudo iptables -vL
            sudo ip6tables -vL

         Make sure it the two key lines as well as any other specific rules you expect to 
         be there (be it DROP or REJECT depending on what you setup):

             Chain INPUT (policy DROP)
               and
             Chain FORWARD (policy DROP)


         If you cannot SSH into the Raspberry Pi, you probably made an error in the rules.v4 file.
         You will need to log into the Raspberry Pi via the console (HDMI monitor and keyboard),
         fix the firewall ruleset, and reload it.

      +------------------------------------------------------------------------------+
      | IMPORTANT:                                                                   |
      |           It's very important to understand that the above firewall ONLY     |
      |           allows in any v4 protocol and blocks all IPv6 traffic.  If you     |
      |           have a public IPv6 address and want to allow in traffic, you'll    |
      |           need to update the above firewall rules.                           |
      +------------------------------------------------------------------------------+

4. Rpi initial setup (OS patches), additional Security hardening, Rpi firmware upgrade)


Now that your Raspberry Pi has some initial protection, let's start configuring things:

  +---------------------------------------------------------------------------------+
  | NOTE:                                                                           |
  |      It's important that you run this command using your newly created username |
  |      and NOT being run as the "pi" user.  It matters!                           |
  +---------------------------------------------------------------------------------+

   1. Run the Raspbian OS configuration tool:

         sudo raspi-config


   2. Change the following areas:

      NOTE: the ORDER of making these changes *matters* so it's recommended to follow 
            these steps IN ORDER

      NOTE#2:  The raspi-config program has changed a LOT over they years and this following
               prompts reflect the layout and settings for Raspbian Buster.  If your version
               of raspi-config looks different or has items in different places, that's ok but
               you still need to set ALL these items:
             
         - Network Options
            - Hostname
              - Make the hostname something unique so you know which Linux machine you're on

            - Network interface names
              - Enable Predictable Network interface names --> NO

         - Boot options
             - Desktop / CLI
               - If you installed the "Lite" version of Raspberry Pi OS / Raspbian, you're NOT 
                 going to be running Xwindows and consuming all that RAM for the GUI.  A such, 
                 select "Console"

         - Localization options
              - Locale  (set to your desired local)

                   - I unselected "en_GB.UTF-8 UTF-8"  (Great Brittan)
                   - I selected "en_US.UTF-8 UTF-8"  (USA)
                     - When prompted, I then selected default locale: en_US.UTF-8

              +---------------------------------------------------------------------------------------+
              |  NOTE:  I've seen that after I change this setting in Raspbian Buster, the interface  |
              |         started complaining about missing map files and started doing strange things. |
              |         If you see this, I recommend to exit the configuration tool and reboot with   |
              |         "sudo /sbin/shutdown -r now" and after it comes back up, log back in and      |
              |         finish up on these steps                                                      |
              +---------------------------------------------------------------------------------------+

              - Timezone (set to your timezone)
                   - I selected America --> Los Angeles

              - Keyboard layout (this option is only seen when running raspi-config via
                the HDMI console):
                 
                   IMPORTANT: If you are in the United (US) and you're only presented with 
                              "English (UK)", select OTHER, then select "English (US)"

                    - Generic 104-key PC --> Other --> For me, I need "English (US)" --> 
                      Now scroll back up and select "English (US)" --> "The default for the 
                      keyboard layout" --> No compose key 

              - Wifi country
                   - If you have an Rpi v3 or Zero W, I selected "US United States"

         - Interfacing options
              - Camera     : If you plan on using a Raspberry PI camera, enable it

              - SSH        : I recommend to enable SSH

              - VNC        : If you installed the full version of Raspbian w/ GUI and intend to manage
                             it via a remote GUI, enable this

              - SPI        : If you have any SPI high speed devices and plan to use then, enable this
                             Fe-pi sound Hat users will need to enable this

              - I2C        : If you have any I2C low speed devices and plan to use them, enable this
                             Users wanting to add an RTC device will need to enable this

              - Serial     : If you plan on using the hardware serial port for say serial console,
                             either via bluetooth or the physical GPIO pins, enable this.
        
                             NOTE: If you're going to use a TNC-Pi TNC NOT in I2C mode, do NOT 
                                   enable this option

              - 1-wire     : If you plan on using the 1-wire slow speed devices (GPIO 4), enable this

              - Remote GPIO: If you plan on enabling the remote GPIO via pigpio network functionality,
                             enable this

         - Advanced options
              - "Expand the file system" - (OPTIONAL- This is usually automatically done upon first boot): 
                                           If you noticed when you first booted your Raspberry Pi, it 
                                           showed the text "Expanding the Filesystem on the SD card" and 
                                           as such, you won't need to run this step.  If you didn't see 
                                           this or missed it, select this option.  It will prompt you to 
                                           reboot once it's done

              - Memory Split: If you're running the Lite version of Raspbian with no GUI, you can reduce 
                              the the amount of RAM allocated to the video system to 16MB and give as 
                              much back to the OS.  I'm using 16MB

                
   3. If you've made any changes to your Rpi via raspi-config, it's time to reboot


   4. Once the Rpi boots back up, log in as your newly created user (in this example, user "dranch") 
      and not the "pi" user.  

      Did it work and you were able to login?  Great!  If not, you MUST fix this before moving on.

         NOTE: As mentioned above, I saw an issue here where I couldn't SSH in with the  
               password that was set for the newly created user when it was done on the 
               Rpi console.  This issue turned out to be an issue with the wrong keyboard 
               layout (default setting in Raspbian is "UK" and not "US") set in the OS.  
               Once I changed the mapping to US, I had to reset the password and things then
               worked ok.

4.a Harden the Raspbian installation


   5. If you're now logged in as your new user, make sure you can use the "sudo" command
      such as:

         sudo ls -la /root

      Did that work?  If not, you MUST fix this before moving on (see the usermod  command in the
      previous section)


   6. DELETE the "pi" user

        Now that you created a new login and tested this new username, let's now 
        delete the "pi" account as the existence of the account, even being locked out as
        this document previously recommended still remains a security risk:

           a. First make sure there isn't anything important in the /home/pi directory that
              you might want to keep:

                 sudo ls -la /home/pi

              If there is anything you want to keep, copy out to somewhere else first

           b. Now delete the "pi" account

                 sudo userdel -r pi

              You might see the output:

                  userdel: pi mail spool (/var/mail/pi) not found

              This is ok as it just means no previous email was found for the user "pi".  Ignore it.


   7. Disable auto-login (GUI versions of Raspberry OS):

         Double check: If you installed one of the GUI versions of Raspbian (not the Lite CLI-only 
         version), the system by default will auto-login the "pi" user to the LXDE desktop.  This 
         default is very insecure.  To disable this, run:

            sudo raspi-config

              In the menu, select "Boot Options" --> "Desktop / CLI" and select
              "Desktop GUI, requiring user to login"


   8. Remove any unneeded or unwanted applications

      Disable any other OS level daemons:
   
        #Disable NFS clients
        sudo systemctl disable nfs-client.target


      Depending on the version of OS you installed on your Rpi ("Desktop and recommended software" 
      (previously named "Pixel", "Desktop", or "Lite", you probably brought in a bunch of stuff you 
      won't need.  I recommend you uninstall what you don't need.  For example:

           The Desktop or Pixel version of Raspbian includes:

              - OpenOffice suite of document, spreadsheet, and presentation creation tools

              - Wolfram GUI scientific package is included on the Pixel version of Raspbian

              - The triggerhappy hotkey tool used for IR remote controls, etc

              # To remove these programs
              sudo apt-get remove --purge wolfram-engine libreoffice* nuscratch


        You can get a complete list of what other packages are installed in your Raspbian OS by 
        running:

           sudo dpkg -l | less

        +---------------------------------------------------------------------------+
        | IMPORTANT:                                                                |
        |                                                                           |
        |  Unless you know what each package does and understand it's dependencies, |
        |  DO NOT REMOVE IT                                                         |
        +---------------------------------------------------------------------------+


   9. Debian Stretch includes an auto-updating ability and while some people might like 
      and even NEED this concept here (aka.. lazy or inattentive people), it's probably 
      NOT good idea for amateur radio applications. I've just seen too many upgrades 
      cause problems and once something breaks, you have no idea why.  Once a system 
      has become broken (even unreachable), repairing it can be very difficult if not 
      impossible until fixed packages are released.  

      As such, I recommend you check the presence of the tool and remove it:

         dpkg -l | grep unattended-upgrades

            If the package is installed (not included with Raspbian Buster Lite), 
            remove it with the following steps.  If it's NOT installed, you can skip
            this section:

               sudo dpkg -r unattended-upgrades

            Next, there might be some left over cruft that needs cleaning:

               sudo systemctl disable apt-daily.timer
               sudo systemctl disable apt-daily.service


            Thoughts on Updates/upgrades:
            -----------------------------
            If you have multiple remote Rpi systems running at different locations, I'd 
            recommend to upgrade the most "accessible" *first* (including a reboot).  

            If and only if that upgrade does well, then you can kick off remote upgrades 
            for all your other deployed sites.  This can be done as simply as using SSH 
            and running the following commands to start an upgrade and reboot (with checking 
            the Unix exit code for each step).  You can also consider using automation systems 
            like Salt, Ansible, Puppet, etc.  but that's well beyond the scope of this document
      

  10. Now, let's make sure your machine is up to date.  Run the following commands when
      you have an Internet connection and a LOT of time (maybe late at night before you
      go to bed):

          All Raspberry Pi hardware:
          --------------------------
             sudo apt-get clean

             sudo apt-get update

             sudo apt-get autoremove
                -- You should see a bunch of things be free if you removed the Avahi daemon
                   as it drags in all kinds of bloated stuff

             sudo apt-get upgrade --no-install-recommends

             sudo apt-get dist-upgrade --no-install-recommends


          Raspberry Pi 4 hardware:
          ------------------------
          If you have a Rpi4, consider updating the firmware on the dedicated EEPROM:

             sudo apt install rpi-eeprom

             sudo rpi-eeprom-update

                - This will tell you if you need to do any updates or not

                - If you do need to do an update, run:

                     sudo rpi-eeprom-update -a


  11. Prepare a new script to occasionally purge old kernels

      Raspbian (aka Debian for Raspberry Pis) has a nasty habit of keeping around old kernels,
      especially the "rpi-update" kernels.  You can remove that bloat with the following script.  
      You can either download this script with:

          cd /tmp
          wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/remove-old-kernels.sh


       Or you can manually create the script by pasting in the following (getting it this way is
       not recommended to avoid copy/paste errors):

          vi /tmp/remove-old-kernels.sh
          --
          #!/bin/bash
   
          echo -e "\nListing old Raspbian based kernels that can be removed"
          dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' 
          #    | xargs sudo apt-get -y purge
          echo -e "\n"You can edit this script to add the following line to the above line to auto-purge these packages"

          echo -e "\nRemoving left over rpi-update kernel modules that are not used for the current `uname -r` kernel"
          cd /lib/modules
          ls -1 | grep -v `uname -r` | xargs rm -Rf
          --

       Now go ahead and put it in the right place, give it execution permissions and run it:
       
          sudo mv /tmp/remove-old-kernels.sh /usr/local/sbin/
          sudo chmod 700 /usr/local/sbin/remove-old-kernels.sh
          sudo  /usr/local/sbin/remove-old-kernels.sh

       After every so many times you run either:
             apt-get upgrade --no-install-recommends 
          or 
             apt-get dist-upgrade --no-install-recommends

       you'll want to run this remove-old-kernels.sh script


  12. NOT RECOMMENDED:
            Sometimes there is newer firmware for the Rpi and possibly move to a better, bleeding edge
            kernel, etc.   That will help resolve some technical issues.  If it's been recommended to 
            you to try it, go ahead and run:

               sudo rpi-update

      If the above program is not installed, do the following and then try again:

         sudo apt-get install rpi-update 


  13. If any new updates or new kernels were  installed, reboot to make all updates active

         sudo /sbin/shutdown -r now  


  14. OPTIONAL: Placing your Rpi on the raw Internet (no firewall in front of it) and having
      SSH enabled is generally NOT recommended.  If you need this, I would recommend 
      additional at least this following protection.  

         If your Raspberry Pi isn't going to be directly connected to the raw Internet (not 
         behind some form of a NAT/Router), you probably don't need to do this.


         a. change the default SSH port 22 to some other port number

            - Doing this offers some reduction in drive by attacks but not for full attacks 
              as port scanning will find your new port.  To change this, edit the SSH daemon 
              config file:

                 sudo vi /etc/ssh/sshd_config

                    - find the line that reads

                         #Port 22

                      and change it to say

                         Port 2222

         b. If you implemented the above IPTABLES firewall setup, you'll now need to update the 
            ruleset to allow port TCP port 2222.   Add that port into the various rules found in 
            the /etc/iptables/rules.v4 file.  Once updated, then  follow the process to use the 
            /usr/local/sbin/firewall-confirm.sh script to make that active.

               NOTE:  Consider allowing both port 22 and port 2222 to give you a transition
                      stage.  Once sshd is restarted and you reconnect on port 2222, again 
                      update the firewall and REMOVE the legacy 22 port rules.


         c. Restart the SSH service or reboot your Rpi to start using port 2222

            #To restart the service
            sudo systemctl restart ssh


         d. In a new window, SSH to your Raspberry Pi using the new 2222 port:

               ssh -p 2222 <remote IP address>


         e. If you implemented the above IPTABLES firewall, I'd recommend to update it
            again to REMOVE the original TCP port 22.   Delete that rule in the /etc/iptables/rules.v4 
            file and follow the process to use the /usr/local/sbin/firewall-confirm.sh script
            to make that active.


         f. (OPTIONAL): Use SSH keys ONLY (no passwords)

           - Removing passwords from being used to login makes brute force attacks almost 
             impossible as long as your version of sshd doesn't have bugs.  Can create very 
             large amount of log entries.  If you've already loaded in a public key into
             your $HOME/.ssh/authorized_keys file, you can then disable the use of passwords
             by editing the SSH server config and make sure the following two lines are 
             set:

                /etc/ssh/sshd_config
                --
                PasswordAuthentication no
                ChallengeResponseAuthentication no
                --

                While you've logged in via one terminal and you're root, run the command:

                   sudo systemctl restart ssh

                Now in another window, try SSHing in again and make sure everything works 100%.
                If things don't work, go back to the other terminal already with root access
                and either fix your issue or re-enable passwords in sshd, and restart the daemon
                it again
 

   Future / To-do:  Advanced security thoughts that I'll add into this doc some day

         - enable port knocking support (potentially removes the need to change port numbers or
           mandate SSH-keys
 
         - Enable tools like fail2ban to block remote IPs after X number of failed login attempts, 
           portscans, etc.

4.b Static IP Address for the Rpi

For those of you who wish to have your Raspberry Pi use a static IP address and not get it's address 
from DHCP, follow these instructions:

  NOTE:  The configuration of static IPs on Raspbian (now Raspberry Pi OS) has changed dramatically 
         over it's various releases from Wheezy, Jessie, Stretch, and now Buster.  For this section,
         I'm currently covering Buster ONLY.

   In Raspberry Pi OS (Buster and Stretch), the configuration of static IPs is actually configured 
   via the DHCPcd daemon (strange but true). 

      #scan down and find the eth0 interface area
      #  Remove the required #ed out lines
      #
      sudo vim /etc/dhcpcd.conf
      --
      interface eth0
      static ip_address=192.168.10.1/24
      static routers=192.168.10.1
      static domain_name_servers=192.168.10.1
      --

Once complete, reboot the Raspberry Pi with:

   sudo /sbin/shutdown -r now

   

5. Fixing some current Raspbian issues (Gotchas)


  1. Raspbian Jessie specific fixes (not for Buster or Stretch): 

     If you plan on using NFS on your Raspberry Pi (NOT recommended unless you know what you're 
     doing), it seems my Rpi v2 running Jessie as of 3/5/16 won't reboot if you use the 
     /sbin/shutdown or reboot or even "systemctl reboot" command.  Evidently this is a known issue 
     and is mentioned here:

        https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=763315

     To work around this, edit the /etc/init.d/rpcbind and /etc/init.d/nfs-common
     file and change their start up/down priorities from:

        # Default-Start:     S
        # Default-Stop:      0 1 6

     to:

        # Default-Start:     1 2 3 4 5
        # Default-Stop:      0 6

     Once that's in place, you need to reboot but maybe you can't.  As such, I 
     recommend you do the following:

        a. run this little script as root (sudo su)

           while [ true ]; do
           sync; sleep 1
           done

        b.  While that script is running, pull the USB power cord on the Rpi, 
            wait 5 seconds and replace the power


  2. Other gotchas and fixes will go HERE in the future if required
            

6. Configure temporary RAM file systems or OverlayFS to minimize SD card writes


As your Raspberry Pi runs normally, it will accumulate logs in the /var/log directory as
well as write other files as required (core dumps, etc).  This writing can be dangerous
as the SD card can fill up to 100% full and even over time, physically wear out the SD card
itself, or the SD card can become corrupt if the power is removed from the Rpi when it's
doing critical writes.  You have a few options to address this:

   1. RAM Drive:  Sending the log files to a RAM drive (non-persistent storage) removes this 
      wear-out risk but if your Raspberry Pi reboots, you loose all those logs.  This setting
      uses a fixed amount of RAM and won't consume all RAM.  This option does still keep the
      root or / file system read-write so there is still a risk of some minor level of file
      system corruption if the Rpi looses power but I say this risk is pretty low.

   -------
     OR
   -------

   2. OverLayFS: Newest versions of Raspbian (Buster November 2019 or newer) have a built- in
      feature to make the /root and/or the /boot partition read-only.  This provides even more 
      file system corruption protection than #1 above offers but if more and more writes accumulate 
      to the in-ram file system, it can consume all RAM and eventually crash the Raspberry Pi.   
      This technology is similar to writing to on-disk snapshots found in Linux's LVM system.  
      If you use this feature, you have to monitor the Raspberry Pi and ensure it's running ok
      over time.  You can find this setting in the raspi-config tool under:

         Advanced Options --> Overlay FS 

      You can read more about this feature here:

         http://comfilewiki.co.kr/en/doku.php?id=comfilepi:read-only_file_system_with_overlay

   -------
     OR
   -------

   3. Read-only SD card:  This option is the safest option for long term running 
      systems as the card should never go corrupt.  The downside here is if you ever want to 
      make permanent changes like apply patches to the OS, make config changes, etc, you have
      to reboot the system, make the file system read/write, do your changes, and then reboot
      the system again to make it read-only.


Using any of the above options is a decision you might not like if you need all those logs or 
say you're having instability issues and want to capture all logs to troubleshoot the issue.  Other 
alternatives can include:

   - Boot and use an external SSD or HDD for all storage needs.  This will prove to be both 
     faster and offer much longer life

   - Mount the /var/log and /tmp directories to an external USB device such as a USB HDD, SSD,
     or even a USB pendrive

   - Use a MUCH larger SD card than you require so the RPi can better wear level the writes
     across the SD card (still not a great idea in my opinion)


   +--------------------------------------------------------------------------------------------+
   | NOTE:                                                                                      |
   |     Regardless of what choice you make, I highly recommend you follow the Logrotate        |
   |     section below to manage and compress all log files so the file system doesn't fill up. |
   +--------------------------------------------------------------------------------------------+


I currently recommend you use Option #1 ramdrive approach as I've had great luck with that configuration
with Rpis that have good power supplies and pretty (but not perfect) power.  Lets get started 
with that.  

Run the "df" command and make sure you see key entries like:

  Buster based OSes using tmpfs:
  ------------------------------
  /run
  /run/lock


  Stretch based OSes using tmpfs:
  -------------------------------
  /run
  /run/lock
  /tmp
  /var/log/


Specifically, notice the use the "tmpfs" file system (or not) used for /run and /run/lock but not
for say "/".  The tmpfs entries are ram drives which is good but in say Buster, there are any explicit
entries for /var/log which means it's running on the root file system ("/") which means it's on the SD
card.  That's bad.  

What you ultimately want is something looking like the following from "df" for the Buster version:

   Filesystem        1K-blocks    Used Available Use% Mounted on
   devtmpfs          212620       0    212620   0% /dev
   tmpfs             245632       0    245632   0% /dev/shm
   tmpfs             245632    6532    239100   3% /run
   tmpfs               5120       4      5116   1% /run/lock
   tmpfs             245632       0    245632   0% /sys/fs/cgroup
   /dev/mmcblk0p1    258095   54604    203492  22% /boot
   tmpfs              49124       0     49124   0% /run/user/1001


The use of the tmpfs RAM drives is the normal setup on Jessie based Raspbian installs but it's NOT
the standard in Raspbian Buster or Stretch so we need to change that.  It's also important to check 
and if required, make new /tmp and /var/log directories go to the RAM drive and NOT on the SD card.

Enabling ramdrives has changed across the different versions of Raspbian but I try to detail the
different versions below:

   #NOTE:  In Raspbian Jessie and Stretch, the previous Wheezy approach of configuring 
   #       RAM drives (/etc/default/tmpfs) is broken.  As such and they have PERMANENTLY 
   #       moved back to the classic fstab approach 
   #
   #       - https://github.com/debian-pi/raspbian-ua-netinst/issues/210
   #
   # You can learn more specifics of operation in "man tmpfs"


# Buster / Stretch / Jessie OSes:  ADD the following two lines below all other lines
# in the file:
#
#    - The first line will create a 10MB ramdrive from your Rpi's total RAM space for storing log files. 
#      Usually 10MB is plenty from a Raspberry Pi with 1GB of RAM.  If you have a new Rpi4 with 2GB, 4GB
#      or even 8GB of RAM, you can choose to make this larger if you wish.  
#
#      *** You will see in a later section where you might want to temporarily INCREASE this space if you
#          wish to do some light compiling but you do not want to mount an external storage device like
#          a USB pendrive, SDD, or HDD drive
#
#    - The second line will create a 50MB ramdrive from your Rpi's total RAM space (usually 1GB of RAM
#      shared with the CPU as well and mount it on the "cat/log" directory off the root "/" file system.
#      *** If you wish to store more logs on your Rpi, you can increase this size but remember that you're
#          effectively stealing RAM away memory from the Linux kernel for use in a dedicated RAM drive 
      
sudo vi /etc/fstab
  --
  tmpfs           /tmp            tmpfs   defaults,noatime,mode=1777,size=10m   0   0
  tmpfs           /var/log        tmpfs   defaults,noatime,mode=0755,size=50m  0   0
  #
  #/var/lock is still handled via the tmpfs system to /run and /var/lock is a symlink to /run/lock
  #tmpfs           /var/lock       tmpfs   defaults,noatime,mode=0755,size=10m   0   0
  --

Don't reboot your Rpi just yet to activate these changes.. few more things to do first!


6.a. Next, Noatime File system optimization


Confirm or enable the "noatime" attribute to disable the recording the date and time whenever any and all files are ever 
looked at across on the file system.  Turning this feature off will help minimize file system writes on your 
root file system that's on the SD card.  

  #NOTE:  This might already be enabled for Raspbian Buster users but please double check 
          that it's present regardless

  vi /etc/fstab

     # For the Buster and Stretch based OSes, the fstab system uses UUIDs instead of partitions, etc.  
     # Your UUIDs will be *different* for your storage but regardless, find your specific line for the "/" 
     # root filesystem and make sure the "noatime" attribute is added
     --
     PARTUUID=92f034a6-02  /               ext4    defaults,noatime  0       1
     --

     # for Jessie, it should look something like:
     --
     /dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
     --


*** So now go ahead and reboot your Rpi right now using ***
      sudo /sbin/shutdown -r now


When it comes back up, log in and run "df".  Make sure those various mounts now are mounted to a 
"tmpfs" file system like:

   df
   --
   Filesystem     1K-blocks    Used Available Use% Mounted on
   /dev/root       14660888 1051092  12981572   8% /
   devtmpfs          241580       0    241580   0% /dev
   tmpfs             245908       0    245908   0% /dev/shm
   tmpfs             245908    3436    242472   2% /run
   tmpfs               5120       4      5116   1% /run/lock
   tmpfs             245908       0    245908   0% /sys/fs/cgroup
   tmpfs              51200     144     51056   1% /var/log    <------------------
   tmpfs              10240       0     10240   0% /tmp    <------------------
   /dev/mmcblk0p1    258096   39969    218127  16% /boot
   tmpfs              49180       0     49180   0% /run/user/1001
   --


7. Enable/Disable IPv6 upon booting


In a previous chapter, I recommended to lock down the IPv6 firewall when loaded upon boot.  
Unless you plan on using IPv6, you might has well explicitly DISABLE the IPv6 protocol 
COMPLETELY.  To confirm IPv6 is currently running, run the following command:

  ip address

Under the second interface, you'll see a line prefixed with "inet6" and starting with the 
address "fe80".  That's the host's IPv6 link local address which is a local-only address.  
The output of your host might include other lines showing IPv6 site-local (a real address), 
IPv6 privacy address (also real addresses), etc.

  --
  1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
      link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
      inet 127.0.0.1/8 scope host lo
         valid_lft forever preferred_lft forever
      inet6 ::1/128 scope host
         valid_lft forever preferred_lft forever
  2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
      link/ether b8:27:eb:25:32:fc brd ff:ff:ff:ff:ff:ff
      inet 192.168.0.22/24 brd 192.168.0.255 scope global enxb827eb2532fc
         valid_lft forever preferred_lft forever
      inet6 fe80::c8c1:a034:5b63:a614/64 scope link  <----------------------------
         valid_lft forever preferred_lft forever
  --


If you wish to outright DISABLE IPv6, edit the /etc/sysctl.conf file and change or ADD the 
following lines to the bottom of the file:

   sudo vi /etc/sysctl.conf
   --
   #Modified
   net.ipv6.conf.all.disable_ipv6 = 1
   net.ipv6.conf.default.disable_ipv6 = 1
   net.ipv6.conf.eth0.disable_ipv6 = 1
   net.ipv6.conf.lo.disable_ipv6 = 1
   --

Ok, if you disabled IPv6, you should reboot your Rpi again and once it's back up, log back into it and 
run the "ip address" command.  Make sure there aren't any "inet6" addresses showing up (even link-local ones).


[Chapter Gap]


9. OPTIONAL: Enable power management for attached USB HDDs


OPTIONAL:
---------
Doing compiling on the Raspberry Pi's local SD card can significantly wear out the flash card and make 
it fail prematurely.  If you have another Linux machine on your network, you can use NFS to do remote 
mounts but remotely mounted NFS shares doesn't work as for some reason, the "autoconf" stage of configuring 
the Makefiles fail.  As such, the only other option here is to compile things on a locally mounted 
file system.  Doing this on a Raspberry Pi's SD is bad as mentioned above.  A far better solution here 
is to use an external USB HDD or SSD.  With the Raspberry Pi v4's USB3 ports, the performance can be
much better than any file system on the microSD card or over the network.

The challenge with using spinning disk hard drives is that the Raspberry Pi defaults to leaving the 
drive spinning all the time and it will never spin down if it's not in use.  That can wear out your 
hard drive prematurely too (that and consume excess power).  To make sure the HD's auto-spin down 
feature is enabled, do the following:

   NOTE: One challenge here is that some hard drives behave different and not work with these settings.
         Most drives are standardized these days but if you're unlucky, you'll need to try out these 
         various commands and see if they need to be modified for your specific device


   a.  Powering your external hard drive

       +-------------------------------------------------------------------------------------------------+
       | IMPORTANT:                                                                                      |
       | ----------                                                                                      |
       | Some USB hard drives are purely powered via the USB bus but the Raspberry Pi CANNOT supply very |
       | much power via USB.  If your USB hard drive is like this, you MUST first connect the drive via  |
       | a *powered* USB hub (one that has a power brick connected to the wall).                         |
       |                                                                                                 |
       | If your external hard drive has it's own power brick, you can connect the hard drive directly   |
       | to the Raspberry Pi.                                                                            |
       +-------------------------------------------------------------------------------------------------+


   b.  Connect your USB hard drive to the Pi

       After connecting the hard drive, make sure you can figure out it's device name via the "dmesg"
       command.  I see the following and my desired drive and partition is "/dev/sda1":
       --
       [  360.177269] scsi 0:0:0:0: Direct-Access     IC35L080 AVVA07-0              PQ: 0 ANSI: 0
       [  360.186259] sd 0:0:0:0: [sda] 160836480 512-byte logical blocks: (82.3 GB/76.7 GiB)
       [  360.187426] sd 0:0:0:0: [sda] Write Protect is off
       [  360.187448] sd 0:0:0:0: [sda] Mode Sense: 33 00 00 00
       [  360.188544] sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
       [  360.207824] sd 0:0:0:0: Attached scsi generic sg0 type 0
       [  360.209560]  sda: sda1
       [  360.214723] sd 0:0:0:0: [sda] Attached SCSI disk 
       --

   c.  Install the hdparm utility:

          sudo apt-get install hdparm


   d.  Confirm that your HD APM level is set to 127 (not 128 or higher : default is 254)
       Any values of 127 or lower will allow the HD to power down if idle

          sudo /sbin/hdparm -B /dev/sda
          --
          /dev/sda:
           APM_level      = 254
          --

       That's a good output and it means the drive is running and has all power management
       disabled.


       NOTE:  If you get output like the following from the above test command:
              --
              /dev/sda:
               APM_level      = not supported
              --

              This most likely means the drive you're trying to use is very old


       NOTE#2:  If you get output like the following from that above test command:
              --
              /dev/sda:
              SG_IO: bad/missing sense data, sb[]:  70 00 05 00 00 00 00 0a 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
               APM_level      = not supported
              --

              This means the USB to SATA/PATA bridge chip in your USB to HDD adapter 
              is not passing all the IDE commands codes through.  There is most likely
              nothing you can do about this except use a different USB to HD adapter 
              or enclosure.  If it's a brand new bridge chip, maybe Linux needs more 
              time to add support for it but once that support is added, you most
              likely will have to upgrade your Linux distribution (with kernel) to 
              get the new support.

              One user also noted that the Western Digital WD Blue and WD Green series 
              of drives do NOT support APM_level which is evidently a known issue.  
              There is a 3rd party tool out there named "hd-idle" that might help you 
              work around this



   e.  Ok, let's do some more commands.  For example, let's see if the HD is spinning now:

       sudo /sbin/hdparm -C /dev/sda
       --
       /dev/sda:
        drive state is:  active/idle
       --


   f.  For a temporary power test, run the following command to change the APM power
       levels:

          sudo /sbin/hdparm -B 127 /dev/sda

       You can learn more about HD APM levels at:

          http://www.freeminded.org/index.php/2012/04/hdparm-power-down-drives-when-not-in-use/
          

   g. To permanently allow this drive to spin down when idle, change:

         vim /etc/hdparm.conf
         --
         #apm = 255
            to
         apm = 127
         --

   h. Btw, you can force the HD to spin down ASAP by running the command:
   
         sudo /sbin/hdparm -y /dev/sda
         --
         /dev/sda:
         issuing standby command
         --

      You can then use the "sudo /sbin/hdparm -C /dev/sda" command to see that the drive 
      is spun down by confirming it's in "standby".

   i. You can also force another timer in /etc/hdparm.conf to spindown the drive in 
      say 10 minutes
      --
      spindown_time = 120
      --


Ok, we'll use this hard drive later for compiling stuff.  For now, go ahead and let the HDD
spin down.  In the bottom of "Section 17 - Enable local storage for demanding builds", it 
includes scripts to both mount and unmount the drive for compiling needs as well as spin 
down the drive.


10. Hardening: Check and disabled unneeded services (the SystemD way)


   NOTE: a helpful SystemD cheatsheet for those who are interested
   #
   http://www.dynacont.net/documentation/linux/Useful_SystemD_commands/


   #I recommend to REMOVE Avahi (Bonjour) for it's network spamming (if you didn't already remove it's
   # package as recommended in a previous section.  If not, just disable it from running:
   sudo systemctl disable avahi-daemon.service


   #OPTIONAL recommended removals to make the machine more secure / reliable): 
   #
   #   Disable the Avahi mDNS system on the Rpi
   sudo update-rc.d -f avahi-daemon remove


   #OPTIONAL: disable bluetooth if you don't plan on using it
   #
   #   Disable Bluetooth on the Rpi
   sudo update-rc.d -f bluetooth remove
   

   # Disable the special key keyboard mapping tool
   sudo update-rc.d -f triggerhappy remove


   #Disable the Rsync daemon (might NOT be installed)- usually doesn't autostart without editing the /etc/default/rsync 
   # file anyway
   sudo update-rc.d -f rsync disable


   #IMPORTANT... please run and review
   #----------------------------------
   #show other running daemons and see if they need to be disabled
   systemctl | grep running


   #See what else might be configure to start at bootup (still applies to Raspbian Buster, etc)
   ls /etc/rc3.d/



11. OPTIONAL: Syslog Tuning


  a. (OPTIONAL) On Raspbian Jessie based systems as of 12/11/15, I would see /var/log/syslog errors 
     that show up like:

         rsyslogd-2007: action 'action 17' suspended, next retry is Fri Dec 11 15:18:31 2015 [try http://www.rsyslog.com/e/2007

     This is evidently due to the Xwindows xconsole not running (when you Rpi isn't running Xwindows 
     because you're probably running Raspbian Lite).  To fix this, edit the /etc/rsyslog.conf file, 
     find and delete the following stanza:
     --
     daemon.*;mail.*;\
        news.err;\
        *.=debug;*.=info;\
        *.=notice;*.=warn       |/dev/xconsole
     --
     If you still want to receive console errors, read the section BEFORE this xconsole  
     section and enable that which will send errors to console vty 8 instead


  b. I would also recommend to delete the following stanza as it's redundant, 
     and only consumes additional log space:

     sudo vi /etc/rsyslog.conf
     --
     *.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug
     --


  c. You'll find that Raspbian logs too much stuff to too many places.  I 
     recommend you follow this URL as step one:

        http://www.the-art-of-web.com/system/rsyslog-config/ 

     It's a little terse on what really needs to be done.

        sudo vi /etc/rsyslog.conf

        1.  Find the line:

               *.*;auth,authpriv.none        -/var/log/syslog

            and change it to the following (adds the ",mail")

               *.*;auth,authpriv,mail.none        -/var/log/syslog

        2. delete the lines:

            mail.info                     -/var/log/mail.info
            mail.warn                     -/var/log/mail.warn

        3. change the line

            mail.err                      /var/log/mail.err

              to

            mail.warn                     /var/log/mail.err

        4. Find the line:

             kern.*                        -/var/log/kern.log

           and right after it, add:

             kern.debug                    stop
               

     Once edited, restart syslog with:

         sudo service rsyslog restart

     And then delete the old, abandoned logs (or reboot as 
     all these logs are on the temporary RAM drive now):

         rm -f /var/log/debug*
  

11.a. Add ULOG to remove IPTABLES lines from /var/log/messages


If you enabled the IPTABLES firewall setup in the previous section and put your Raspberry
Pi on the direct Internet, you probably noticed it begins log too much stuff into too many 
log places.  Worse, if you have your hardened Raspberry Pi connected to the raw Internet 
and look at the contents of /var/log/messages or dmesg, you'll probably notice an absolute 
ton of attack traffic!  Scary stuff but if you followed the various recommendations of this 
doc, your system is now pretty safe.  

To clean up all these IPTABLES lines from filling up your name /var/log/messages and 
dmesg log files, you can enable the Ulog system to move these lines them to a dedicated 
log file(s).

Why do you have to do something special like this?  Good question but the crux of the issue 
is that the IPTABLES system in Linux logs everything to the "kernel" syslog facility which 
has a a LOT of ramifications.  It's unfortunately NOT possible to make it to use any of the 
Syslog LOCAL[0-7] facilities.  To work around this, one has to make a bunch of minor 
changes to redirect logs but it's not too difficult to do.  

I recommend you set this Ulog system up *AS IS* (aka no changes) since using other facility 
levels have other ramifications like sending messages to the console, dmesg, etc.  It's 
a pain to change and something I've never liked about IPTABLES when the old stateless IPCHAINS 
running on 2.6 and 2.4 kernels never did logging stuff like this.  Oh well.. that was then.. 
this is now so lets get this work around in place:


  1. Make sure your kernel has the netlink kernel modules which is required

     #Should find one kernel file 
     find /lib/modules/`uname -r`/kernel/net/netfilter/ | grep -e ip_conntrack_netlink.ko -e nf_conntrack_netlink
     --
     /lib/modules/5.4.51+/kernel/net/netfilter/nf_conntrack_netlink.ko
     --


     #You should find three or more library files
     sudo find / | grep -e libnfnetlink.so -e libnetfilter_conntrack.so -e libnetfilter_log.so
     --
     /usr/lib/arm-linux-gnueabihf/libnfnetlink.so.0.2.0
     /usr/lib/arm-linux-gnueabihf/libnetfilter_conntrack.so.3
     /usr/lib/arm-linux-gnueabihf/libnfnetlink.so.0
     /usr/lib/arm-linux-gnueabihf/libnetfilter_conntrack.so.3.7.0
     --

        #If some of the above packages are missing, you can explicitly install them with:
        #
        sudo apt-get install libnetfilter-log1 libnfnetlink0 libnetfilter-conntrack3


  2. Install ulogd2

      sudo apt-get install ulogd2


  3. Confirm the newly installed ulogd daemon has already been started

        ps ax | grep ulogd


  4. Now configure Ulog2 by editing it's config file

     Find the following lines in the configuration file and make them look like the following:

     sudo vi /etc/ulogd.conf
     --
     #Buster defaults to loglevel=3 which should be ok but if you want more detail
     loglevel=1

     [log1]
     group=0

     [log2]
     group=1

     [emu1]
     file="/var/log/ulogd_traffic-emu1.log"
     sync=1

     [emu2]
     file="/var/log/ulogd_traffic-emu2.log"
     sync=1
     --


  5. Restart Ulogd to get the new settings

      sudo service ulogd restart
    

  6. Alter your iptables firewall to use the new Ulogd system

       Edit the /etc/iptables/rules.v4 file and find the line:
       --
       -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
       --

       Replace it with:
       --
       -A INPUT -m limit --limit 5/min -j NFLOG --nflog-group 0 --nflog-prefix "iptables denied: "
       --

  7. Reload the firewall set following the previous recommendations in the Firewall section of this
     doc assuming your using my firewall reload script:

        /usr/local/sbin/firewall-confirm.sh &

     Assuming that went well, now things should be all logged in the /var/log/ulogd_traffic-emu1.log file and 
     no longer in your /var/log/syslog nor dmesg logs!


  If you're curious, you can learn more about Ulogd2 here:
  http://sparlampe.wordpress.com/2011/02/26/setting-up-ulog-on-debian-to-log-iptables-bypassing-dmesg/


In a few sections, I will add recommended log rotation and compression of the /var/log/ulogd_traffic-emu1.log
so it won't fill up the RAM drive.


12. Install the Postfix email server and Logwatch to get nightly system reports


To get daily reports of how your Raspberry Pi SBC is running, let's install a local-only 
email server and some log notification tools.  To do this, run the following command:
 
   #Some additional required packages will be installed as well
   #
   sudo apt-get install postfix logwatch bsd-mailx dnsutils openssl-blacklist


As the Postfix package installs, it will bring up a TUI interface and prompt you for specific 
settings for your environment.  Most likely, you'll want to select Postfix to be:

    "Internet with Smarthost"


This means that your Rpi will need to contact another email server to "relay"
the email to the Internet.  This "smarthost" is almost always your ISP and
most require this to control email spam.

In this example, the hostname I entered in is the following.  Change this to
match both your Rpi's system's hostname and domain name:
    
    rpi3.trinnet.net


Smarthost / SMTP relayhost (aka MX DNS record): 
--
When prompted for this, it's not that you put in the actual IP of the remote host 
but the DNS domain name that will accept email from your Rpi.  In my case, I would 
put in a hostname that has a DNS "MX" record (not a A record or a CNAME record) 
configured to accept email for my "trinnet.net" domain.  If you're not sure what 
should be, contact your ISP for the correct "MX" relay or "smarthost" hostname and 
domain name or full qualified domain name (FQDN).  For me, that's:
    
    trinnet.net
    

Next, you need to edit the /etc/aliases file to point all "root" user emails to go to a 
valid email address (off box).  This will be the desired valid email address where you'll 
# receive daily email reports from your Raspberry Pi.  For me, this is what I setup:

   sudo vi /etc/aliases
   --
   root:			<change all this to reflect your full email address>
   --

Once you edited the aliases file, run the command to activate the change:

    sudo newaliases


This command will silently compile this new alias information into the /etc/aliases.db 
database.  If it runs ok, it won't return any details but if there are errors, it will 
say so.


Testing
-------
On the upstream MX / SMTP relayhost configured above, it's required that it will accept
emails from your new Raspberry Pi.  For most ISP's MTAs (remote email servers that accept email), 
this won't be needed but if *you* sysadmin your own upstream "smarthost" or SMTP relay, you might
to need to update the "access" database (not the aliases) database.  If you do have to make changes 
to this "access" database, make sure to run the "newaccess" command to create a new version of the 
database and restart your email server.

Once you've update the access database, now test the Rpi's local email system by running:

   echo "test1 from `uname -n`" | mailx root

There won't be any output from the command line but you can see if there were any other issues
by looking at logs on your mail server (if you have access to your email server):

   sudo less /var/log/mail.log

You need to see a line saying something like "... dsn=2.0.0, status=sent (delivered to mailbox)"

Also check and see if this email was ultimately received on your chosen destination email address.  
If the email wasn't received, you need to check the local and remote email logs.  Do NOT proceed 
past this step until this is resolved if you want to get nightly notifications.

12.a. Add an email notification when your Rpi is rebooted


If the test email notification was received, now configure system send you an email whenever 
the Rpi is rebooted.  This is VERY helpful as it can help you diagnose non-desired system 
crashes, power issues, etc.  To do this, edit the /etc/rc.local file and add this command 
before the end of the file (before the "exit 0" line):

   NOTE:  The whole concept of /etc/rc.local is being deprecated for distros using 
          systemd.  There are workarounds to create a systemd target that acts like
          a classic /etc/rc.local script:

          https://unix.stackexchange.com/questions/471824/what-is-the-correct-substitute-for-rc-local-in-systemd-instead-of-re-creating-rc

   sudo vi /etc/rc.local
   --
   #Send a message to root when the Rpi reboots
   date | mailx -s "host: `uname -n` was rebooted" -- root
   --


13. Install the Logrotate log management system for log rotation and compression


Now that you have an email server running and are hopefully running an IPTABLES firewall 
with logging support going through Ulogd, etc, you need to manage your logs.  If you don't 
install this rotation system (usually installed by default), the RAM drive can get full 
and you'll loose important diagnostic logs, etc.  It's also important that if you create 
new log entries for say the IPTABLES Ulog system, these new files get managed.

To solve this, install the logrotate suite (if it isn't already):

   sudo apt-get install logrotate


Next, edit the /etc/logrotate.conf file to enable bzip compression 

   sudo vi /etc/logrotate.conf
   --
      - Un# out the line "#compress"

      - Add the following lines just below the "compress" line
        --
        # use bzip2 with higher compression than gzip
        compresscmd /bin/bzip2
        uncompresscmd /bin/bunzip2
        compressoptions -9
        compressext .bz2
        --

Now edit the /etc/logrotate.d/rsyslog file and add the following items at the TOP of 
the file (don't put these lines UNDER ANY SPECIFIC file stanza and delete any duplicate 
lines from any of the other stanzas in the file.  

   NOTE: If the "delaycompress" parameter is present anywhere in the file, comment the 
         line out by adding a "#" in front of it

   sudo vi /etc/logrotate.d/rsyslog
    --
	rotate 3
	daily
	missingok
	notifempty
	compress
	compresscmd /bin/bzip2
	uncompresscmd /bin/bunzip2
	compressoptions -9
	compressext .bz2
   --


Now, if you followed the instructions on the Ulogd section for IPTABLES logging above,
I recommend to rotate those logs as well.  Edit the /etc/logrotate.d/ulogd2 file
and add the following stanza:

    sudo vi /etc/logrotate.d/ulogd2
    --
    /var/log/ulogd_traffic-emu1.log
    {
            rotate 4
            weekly
            missingok
            notifempty
            size 10M
            compress
	    compresscmd /bin/bzip2
	    uncompresscmd /bin/bunzip2
	    compressoptions -9
	    compressext .bz2
            sharedscripts
            create 640 ulog adm
            postrotate
                invoke-rc.d ulogd2 reload > /dev/null
            endscript
    }
   --

Once you've made these changes, no other command are required.  The logrotate system 
is run by the cron system and it will automatically rotate the logs on it's regular 
schedule.


14. OPTIONAL: Install important sysadmin and monitoring packages?


Though completely optional, I would recommend to install some of these useful programs:

   vim     - better version of Vi
   tcpdump - network monitor
   lsof    - tool to see what ports / files are open on the machine
   gpm     - mouse program for cutting/pasting when in CLI mode
   telnet  - make simple outgoing TCP connections for various network tests
   minicom - a very useful serial terminal program to troubleshoot serial ports, TNCs, etc
   links   - a text-based web browser


   #Install them and their required dependencies
   #
   sudo apt-get install vim tcpdump lsof gpm telnet minicom links


      # If you install Vim, start using the "vim" command instead of the basic "vi" command yet
      # see screwy copy/paste issues via the mouse, manually type in the following to say 
      # /home/dranch/.vimrc (change the "dranch" username to be your username
      # or /root/.vimrc
      --
      set mouse=r
      set paste
      --

      Next, I would also recommend to ONLY run Gpm it when you're on the actual console (HDMI) 
      and only when it's needed.  As such, I recommend to disable gpm from starting at boot 
      time:
  
      sudo update-rc.d gpm remove


# Personal Preference: Enable Vim as system default text editor and not Nano
# 
#  http://raspberrypi.stackexchange.com/questions/5367/how-do-i-change-the-editor-used-by-visudo

   sudo update-alternatives --set editor /usr/bin/vim.basic


Next, if the /boot partition on your SD card ever gets corrupt, you can fix it if you install these
tools ahead of time (if not already):  

  Please note that the Raspbian Wheezy version of dosfstools is broken
  # http://www.raspberrypi.org/forums/viewtopic.php?p=495156

  sudo apt-get install dosfstools


Moving on, it would be good to confirm that your Raspberry Pi is stable and reliable with it's power supply,
etc.  The "stress" tool is a nice tool to create high loads to check to see if:

    - The RED power LED on the Rpi's board blinks indicating a power issue
    - You see a yellow lightening bolt in the upper right corner of the Rpi's HDMI console indicating a power issue
    - See if your Raspberry Pi crashes (could indicate either a power issue or something on the Rpi itself.. aka.. it's defective)

To try this test, do the following:

   1.  Install a basic load test program
        sudo apt-get install stress

   2.  Reboot your suspect Raspberry Pi and confirm the "Throttled" output shows "0x0"
        /opt/vc/bin/vcgencmd get_throttled

   3. Run the stress program for 2 minutes to load up your Rpi.  You can watch the RED led on your
      Raspberry Pi during this time to see if it blinks (that's bad):

        #For 4core Rpis like Rpi2, 3, 3+, 4
        stress --cpu 20 --io 20 --vm 6 --vm-bytes 25M --timeout 120s
 
        #For 1core Rpis like Rpi0, 0w, 1
        stress --cpu 5 --io 20 --vm 6 --vm-bytes 25M --timeout 120s


      The output from the stress tool would look something like:
      --
      stress: info: [1680] dispatching hogs: 20 cpu, 20 io, 6 vm, 0 hdd
   
      [...120 seconds later...]

      stress: info: [1680] successful run completed in 120
      --

   4. After the stress program is complete, confirm the load was high (for example, this stress command created a load of 
      36.62 on a Raspberry Pi 4 w/ 4GB RAM): 
        w

     If your Raspberry Pi crashes, you'll know for SURE that you have a problem that's load related.  You will need to 
     look at getting a better power supply, a better / shorter USB cable between the power supply and Raspberry Pi, etc

   5. Re-confirm if an undervolt situation occurred by confirming if you do or DON'T see a "0x0" output:
        /opt/vc/bin/vcgencmd get_throttled



There are other great testing / performance tools to consider:

      stress         - CPU and I/O loading tool
      hdparm         - storage configuration and basic I/O benchmark tool
      sysbench       - comprehensive benchmark tool
      speedtest-cli  - Internet and network benchmark tool
      rpi-benchmark  - comprehensive suite of benchmark tools tailored to Raspberry Pis
   

OPTIONAL: One of the more comprehensive benchmarks is the Rpi-benchmark.  You can read more about that here though
          it does drag in a LOT of other packages to do a complete run so you might be careful on available file 
          system space:

   https://github.com/aikoncwd/rpi-benchmark
   --
   cd /tmp
   wget https://github.com/aikoncwd/rpi-benchmark/raw/master/rpi-benchmark.sh
   chmod 755 rpi-benchmark.sh
   sudo mv rpi-benchmark.sh /usr/local/sbin/
   sudo /usr/local/sbin/rpi-benchmark.sh
   --


15. Pyshutdown: Building a shutdown button for an Rpi much like a PC's ATX power button


One of the more significant issues with the entire line of Raspberry Pi boards is that there is 
NO WAY to safely shutdown the OS w/o logging into the device via the console or SSH, etc first.  
Many alternative SBCs that compete with the RPi line include a little shutdown button on the board 
itself but the Rpi line doesn't.  I view this is as a *very* bad design as almost any OS can and 
WILL get partially corrupt it's filesystem when ungracefully shut down.  Yes, there are some complex
tricks to make the OS run as read-only from the file system (SD cards, eMMC, etc) but that is beyond
the scope of this doc.  Fortunately, it's not too hard to add a shutdown button to the Rpi and I
highly recommend you add one.

The first thing to to figure is out what GPIO pin to use.  This selection completely depends 
on the generation of Rpi you're using.  Looking at the 
22. Choosing GPIO pin for the radio PTT line section,
pick a GPIO pin for your setup.  I'm using the following pins for various purposes in this doc:

    Direwolf to Radio PTT on Rpi2:
      Rpi pin 37 (Broadcom GPIO 26) :: connect this to RS232 DB9 pin7 (this is the RS232 RTS signal)
      Rpi pin 39 (Broadcom for GND) :: connect this to RS232 DB9 pin5 (this is the RS232 GND signal)

    Direwolf DCD indicator on Rpi2:
      Rpi pin 33 (Broadcom GPIO 13) :: connect to anode of LED (long lead / larger metal inside LED)
      Rpi pin 34 GND                :: connect to cathode of LED (short lead / smaller metal inside LED)

    PiShutdown
      Rpi pin 18 (Broadcom GPIO 24) :: connect to 10k resistor, then one side of a momentary switch
      Rpi pin 20 - GND              :: Connect to other side of momentary switch


Historical note:  I used to use the solution at http://www.instructables.com/id/Simple-Raspberry-Pi-Shutdown-Button/ 
as an outline for this section and code BUT there were several issues with it and other designs found on
the Internet:

   - This specific design does not use a resistor to current protect the GPIO line.  This is a
     bad idea and can physically damage your Rpi due to sinking too much current though the monitoring 
     GPIO pin.  I recommend to use a 10k Ohm resistor in-line to the shutdown momentary switch to protect 
     the GPIO pin

   - The above script doesn't support a debouncing capability and I was experiencing false shutdowns
     due to I believe RF interference (RFI) issues.  A better solution is using the below solution from
     the following site with some modifications:

        https://www.raspberrypi.org/forums/viewtopic.php?f=32&t=133111

   - My version of the script requires you to HOLD DOWN the button for THREE seconds and then the Rpi will 
     gracefully shut down.  Much safer against accidental button pushes, debouncing, it's much more reliable.

   - This modified script includes improved system messaging 


Next, let's connect the shutdown button to the RPi's GPIO header.  It's important to first SHUTDOWN (not 
reboot) your Rpi with:

   sudo /sbin/shutdown -h now


Let the Rpi shut off (the activity LED will blink 10 times to indicate that the OS is down).  Now disconnect 
the USB power cable to the Rpi to remove all power to the Pi.  Now, wire up the following simple circuit 
(this example uses Broadcom GPIO 24):

   1. Rpi pin 18 (Broadcom GPIO 24) connected to a 10K Ohm resistor 
      (resistor color code: brown, black, orange, gold)

   2. Then other side of the resistor to a momentary switch/button

   3. Then other side of the momentary switch to GND such as Rpi pin 18 

   4. Make sure you built this reset button properly.  Use a good momentary switch, use good slim connectors 
      to make solid contact to the GPIO pins. Use electrical tape or better yet, heat-shrink tubing around 
      those pin connectors to avoid any short circuits to the other nearby GPIO pins, etc.

   
Once the button is wired up and connected to the correct GPIO pins on the Raspberry
Pi, go ahead and connect the USB power back to the Raspberry Pi to boot it up.

   NOTE: Just as a heads up for the curious, I connected a volt meter to physical 
         pins 16 and 18 upon initial power up.  At first, I saw 0 volts but as the 
         Rpi finished it's booting, I saw the voltage jump to +3.3v as expected.


Next up, lets first test that your button is connected and reading correctly

   a. Make sure you have the WiringPi utility installed

      sudo apt install wiringpi


   b. Download the following test script:

      cd /usr/local/bin/
      sudo wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/bin/monitor-gpio-state.sh


   c. Make the script executable:

      sudo chmod 755 /usr/local/bin/monitor-gpio-state.sh


   d. Now run the script which will run in 1 second loops.  Now push down and continue to hold down
      your button for at least one second and then release the button.  The script will show you which GPIO 
      pin changed by looking at the "V" aka "logic level" column.  An example looks like this which is changing
      Broadcom GPIO 24 aka physical GPIO pin 18:

      --
         | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
         22c22
         <  |     |     |    3.3v |      |   | 17 || 18 | 1 | OUT  | GPIO. 5 | 5   | 24  |
         ---
         >  |     |     |    3.3v |      |   | 17 || 18 | 0 | OUT  | GPIO. 5 | 5   | 24  |
         22c22
         <  |     |     |    3.3v |      |   | 17 || 18 | 1 | OUT  | GPIO. 5 | 5   | 24  |
         ---
      --

      Once you've confirmed your button push is being seen, hit control-c to exit the script
 

Ok, now to get the shutdown script going, do the following:

   a. Get the actual shutdown script on to the Rpi

      cd /tmp
      wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/pishutdown2.py
      sudo mv /tmp/pishutdown2.py /usr/local/sbin/pishutdown2.py
      sudo chmod 700 /usr/local/sbin/pishutdown2.py


   c. Edit the /usr/local/sbin/pishutdown2.py file and find the lines:

      sudo vi /usr/local/sbin/pishutdown2.py
      --
      #Find the line and change the GPIO pin to use what you chose from the above details
      # This is the Broadcom GPIO pin and NOT the physical Raspberry Pi pin.  See 
      # 
      INT = 24
      --


Next, edit the /etc/rc.local file as root:

  sudo vi /etc/rc.local
  
  find the line that says "exit 0" and just above it, add the lines:
  --
  echo "Starting pishutdown2.py script"
  echo "Starting pishutdown2.py script" | /usr/bin/systemd-cat
  python /usr/local/sbin/pishutdown2.py &
  if [ $? -ne 0 ]; then
     echo "pishutdown2.py script failed to start"
     echo "pishutdown2.py script failed to start" | /usr/bin/systemd-cat
  fi
  --


Now, let's test that the script can run.  To do so, run:

  sudo python /usr/local/sbin/pishutdown2.py

If things work properly, the script will just sit there, seemingly doing
nothing.  Ok, for the big test:  press and hold down the shutdown button for 
say 5 seconds and then let go.  Depending on the Raspberry Pi model you're using,
the green "activity" LED might start flickering.  On say the Raspberry Pi 0 Wifi
version, the green LED stays on for 8 seconds, then starts to flicker.  Eventually,
all Raspberry Pi boards should blink the green LED 10 times meaning the OS has been
shut down.  Woohoo... it works!  

So go and unplug the USB power connecting to your Rpi and then re-connect it after
say 5 seconds to boot things back up.  Once the Rpi is fully booted, let's the shutdown 
button setup a real world test.  Give the shutdown button a momentary push but DON'T hold 
it down.  The Raspberry Pi should simply stay running as you didn't hold down the button 
long enough.  Now for the real test, HOLD DOWN the button for at least three seconds and 
the Rpi should begin to gracefully shutdown the OS as mentioned above.  The Raspberry Pi 
should eventually blink it's GREEN activity LED 10 times and after that, the OS is 
shutdown.  At that point, only the RED led will stay lit for Rpi models that have that
LED.  If you had a volt meter connected to the Rpi pins, you would now measure the voltage 
at 1.03volts.  To boot your Rpi back up, remove the power connection, count five seconds, 
and then re-connect the Rpi's USB power cable.


Alternative shutdown solutions if you don't like this recommended solution (I would be 
curious why): 

   https://wiki.melbournemakerspace.org/projects/pishutdown

15.a. Broadcom HW Watchdog: Automatic reboots if the system becomes unresponsive


If your Raspberry Pi unit happens to lock up, crashes, or otherwise becomes non-responsive, 
a hardware watchdog has the ability to automatically "reset" the hardware for you.  The goal 
here is to have the Raspberry Pi brought back online instead of you having to manually reboot
it with a cycle the power.  

   NOTE:  Whenever the watchdog kicks in, you still run the chance of the the SD card's file 
          system getting corrupt.  This risk is no different than having to do a manual 
          power cycle

   +--------------------------------------------------------------------------------------------------+
   | IMPORTANT : 08/29/17 on Raspbian Stretch  (does not apply to Raspbian Buster)                    |
   |                                                                                                  |
   |            Per the thread at https://www.raspberrypi.org/forums/viewtopic.php?f=29;amp;t=147501  |
   |            it seems that there is confusion / issues with enabling the watchdog system via       |
   |            systemd vs. the previous watchdog daemon approach.  It seems the systemd approach     |
   |            is more granular and might be more compatible with the Linux Out of Memory (OOM       |
   |            killer (OOM) process but it doesn't seem to always work for system hangs.             |
   |                                                                                                  |
   |            It's unclear if enabling this via the watchdog package will conflict with             |
   |            the Systemd method.  As such, I don't know if I can recommend enabling this           |
   |            at this time. Raspbian Stretch uses the watchdog 5.15-2 package which is supposedly   |
   |            fixed but the documentation hasn't caught up.  I believe the proper solution now is   |
   |            to exclusively use the Systemd approach and NOT use the watchdog package.             |
   |                                                                                                  |
   | see:                                                                                             |
   |    https://unix.stackexchange.com/questions/346224/problem-with-systemd-starting-watchdog/346235 |
   |    https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=147501                            |
   |    https://github.com/debian-pi/raspbian-ua-netinst/pull/390                                     |
   +--------------------------------------------------------------------------------------------------+


To get this useful feature working, you need to follow a few key steps:

   1. Make sure the Broadcom watchdog kernel module is present:

         NOTE:  The path and the name of the kernel module for watchdog has changed over time 
                with the various Rpi kernel versions

         #Correct name in Raspbian Buster - kernel version: 5.9.x, 5.4.51+ or 4.19.50-v7+
         find /lib/modules/`uname -r` | grep wdt

         #Correct name in Raspbian Stretch - kernel version: 4.9.45
         find /lib/modules/`uname -r` | grep bcm2835

         #Correct name in Raspbian Jessie
         find /lib/modules/`uname -r` | grep bcm2835_wdt

         #Correct name in Raspbian Wheezy
         find /lib/modules/`uname -r` | grep bcm2708_wdog


   2. Confirm that the /dev/watchdog device is (or isn't) present

         ls -la /dev/watchdog
         --
         crw------- 1 root root 10, 130 Jun 29 20:53 /dev/watchdog
         --

      If it *IS* already present (aka the kernel module is loaded), you can skip down to step #3 
      below 

      or if it's not loaded where you see:
         --
         ls: cannot access /dev/watchdog: No such file or directory
         --

         You will need to follow the below steps to get it to automatically load


      To get the watchdog kernel module to load:

         2.A  For Raspbian Stretch ONLY via Systemd:

            1. edit /etc/systemd/systemd.conf
                  - change #RuntimeWatchdogSec= to RuntimeWatchdogSec=10
                  - uncomment #ShutdownWatchdogSec=10min

            2. This might now be obsolete: Temporarily follow the recommendations found in

               https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=147501

               Seems this recommendation is avoiding the SystemD approach 


         2.B. For Raspbian Jessie ONLY - Buster and Stretch do not need this due to the tighter 
                                 integration with Systemd

            1. Load the Broadcom watchdog kernel module at boot time:

               NOTE:  Systemd will also automatically load the kernel module when
                      it sees a change to the /etc/modules file

              #only for Jessie / 4.4.x kernels 
              sudo echo "bcm2835_wdt" >> /etc/modules


            2. Load the kernel module and make sure it loaded

               # This only for Jessie / 4.4.x kernels
               #  This doesn't create any harm on Stretch / 4.9.x kernels but also won't show up at all
               #
               sudo modprobe bcm2835_wdt

               sudo lsmod | grep bcm2835_wdt
               --
               bcm2835_wdt             4133  0
               --

               NOTE:  Notice the trailing "0" here.  This means it's not currently in use


         2.C Confirm that the /dev/watchdog device NOW is present

            ls -la /dev/watchdog
            --
            crw------- 1 root root 10, 130 Dec 12 16:01 /dev/watchdog 
            --


   3. All OS versions: Install the software side of things:

         sudo apt-get update
         sudo apt-get install watchdog


   4. Enable the software refresh daemon to start on boot (but it won't start just yet)

         # Raspbian Buster
         # --------------
         Confirmed things enable and auto-start fine


         # Raspbian Stretch
         # ---------------
         Confirmed things enable and auto-start fine


         #  Raspbian Jessie
         # ---------------
         #  At the moment, this watchdog package is not 100% Systemd compatible.  If you tried to run:
         #
         #    sudo systemctl enable watchdog
         #
         #  You would see various errors like 
         #
         #    The Systemd unit files have no [Install] section. They are not meant to be enabled
         #    using systemctl.  Possible reasons for having this kind of units are:
         #
         #    1) A unit may be statically enabled by being symlinked from another unit's
         #       .wants/ or .requires/ directory.
         #    2) A unit's purpose may be to act as a helper for some other unit which has
         #       a requirement dependency on it.
         #    3) A unit may be started when needed via activation (socket, path, timer,
         #       D-Bus, udev, scripted systemctl call, ...).

             To fix this in Raspbian Jessie, edit the /lib/systemd/system/watchdog.service file and 
             in the [Install] section, add the line:

                WantedBy=multi-user.target


    5. Edit the /etc/watchdog.conf file and un-# out the following lines:

         sudo vim /etc/watchdog.conf
         --
         max-load-1             = 24
         max-load-5             = 18
         max-load-15            = 12
         watchdog-device        = /dev/watchdog
         --

         NOTE:  Other interesting things to "watch" are included in here such as ping monitors for the
                network, etc.  Consider enabling other items if you can trust them.


    6. Go ahead and enable and start this service when the system boots

         #Buster and Stretch version of OSes
         #
         sudo systemctl enable watchdog
         sudo systemctl start watchdog.service


       6.a Jessie ONLY: make sure the watchdog kernel module is now being used by showing a "1" at the end

         #The watchdog feature is built into the Raspbian Buster and Stretch kernels
         #
         sudo lsmod | grep bcm2835_wdt
         --
         bcm2835_wdt             4133  1
         --


    7. I would recommend to now reboot the Rpi and after it's rebooted, log in and repeat
       step #2 to ensure the watchdog is running again with:

          systemctl | grep watchdog


    8. If you followed the email section elsewhere in this doc, the "root" user should also 
       receive an email that the Rpi was rebooted if the watchdog ever kicks in


That's all it took (I'd recommend to do a reboot to ensure it gets enabled every time).   
To test the watchdog itself, there are two ways to do it and I recommend to test BOTH 
scenarios:

      a. RECOMMENDED: Cause a kernel panic.  This WILL crash your Rpi and potentially cause 
         file system corruption but it's important to do this test.  This command line will try to 
         minimize that risk:

            1. Turn on the HDMI monitor so you can see the login prompt

            2. become root with running "sudo su"

            3. Crash the Linux kernel (normally the system would forever stay in this state)
               and make sure the machine reboots 60 seconds later:

                  sync; sleep 2; sync; sudo bash -c "echo c > /proc/sysrq-trigger"

            4. You should see a panic message on the HDMI screen and within 10 seconds, the
               Raspberry Pi should automatically reboot.  If it doesn't reboot, review your
               changes as recommended in this section.


      B. Forkbomb the Raspberry Pi into very high load.  This WILL crash your Rpi and 
         potentially cause file system corruption but it's important to do this test.  This 
         command line will try to minimize that risk:

         1. prevent swapping to the SD card!
         sudo systemctl stop dphys-swapfile.service

         2. Root file system is still R/W but lets make it as clean as possible
         # then start the bomb (this is a one line command designed to crash your Rpi)
         sync; sync; sync; : (){ :|:& };:
  
         3. Shortly after starting the bomb (maybe 15 seconds), the system should automatically 
         reboot,  If it doesn't reboot, review your changes as recommended in this section.


16. Install the required tool-chains to be able to build Linux programs


To build some of the AX.25 packet programs that are either not available in the Debian 
repositories or to build newer versions, you need to install various compiler tool chains.  
Let's do that now with:

   #Install the required programs and any of their dependencies
   #
   sudo apt update
   sudo apt install build-essential autoconf automake libtool checkinstall git


17. (OPTIONAL) Enable local storage for demanding builds


It's generally required on any Linux system that you have a large enough /tmp file system 
to do compiles.  Why /tmp?  Some programs like Direwolf, Node.js, etc. require a lot more 
space than 512MB or 1GB of RAM in the Rpi itself when you compile them.  When some of 
these compiling jobs run low on RAM, they automatically overflow the building objects 
to the /tmp file system.  If this overflow to /tmp happens without having a large enough
overflow space, you will (at minimum) significantly reduce the life of your SD card due to 
many writes.  Worst case, the /tmp will fill up and the build will fail and the OS could
crash.  I know because I killed one SD card this way!

So you You might be thinking: "Why can't I just build this stuff on my Raspberry Pi's SD 
card"?

The answer is "you can" but you run the real risk that if you do it enough times, you WILL
actually permanently damage the SD card.  Why?  SD cards are generally intended for writing 
data a few times but READ many times for use cases like digital cameras, music players, etc.  
Compiling code can actually be writing a LOT of data in the same place and if those writes 
are intensely focused in the same storage region, the flash cell there can wear out and fail.  

The ways to work around this include:

   - NOT RECOMMENDED : Use a much larger SD card.  Raspbian can fit on a 4GB SD card but that 
     won't give you much space to do anything.  It's this remaining space that would used for 
     compiles which would focus all the writes in that small area, and potentially fail the 
     flash cells there.  Consider using a 16GB or 32GB card at minimum if you really must do 
     builds on SD cards.  If you go this route, I recommend re-read 
     "section 6. Configure temporary RAM file systems to minimize writes" and increase /tmp 
     to at least 50MB.

   - More Recommended:  Use a USB flash pendrive to mount /tmp.  These kind of storage devices 
     are somewhat more suited (but still not great) for more writes.  The reason for this is 
     they have something called "wear leveling" (some microSD cards have this now too) to 
     distribute the writes throughout the flash cells on it's media.  Not all flash pendrives 
     are equal in terms of compatibility, performance, reliability, or even have this wear
     leveling support.  Arguably Linux is very forgiving here and most pendrives will work 
     fine.  I would recommend to use nothing smaller than a 8GB pendrive.

   - RECOMMENDED: 
     ------------
     Use an external Solid State drive (SDD) or hard disk drive (HDD) connected
     to the USB port.  These devices are designed for handling lots of writes over time.  
     Some of these drives don't come with their own power and assume the computer will supply 
     all it's power needs.  If you don't already know, the Raspberry Pi CANNOT SUPPLY ENOUGH 
     POWER via it's USB ports (the Raspberry Pi 4 is a little better here).  This ultimately 
     means you need to connect a powered USB hub to your Raspberry Pi and connect the external
     USB HDD or SDD to that hub.  A powered USB hub is a hub that comes with it's own external 
     power brick for handling power loads.


To support larger /tmp and general build area storage, I recommend going the external HDD/SDD
route described below:

   Assumptions:

   1. Your external USB Flash pendrive / HDD / SDD needs to be formatted with a Linux
      File system.  It should NOT a FAT16, FAT32 (VFAT), ExFAT, etc formatted file system.  See below
      on how to reformat your device if required.

   2. These are temporary settings and are to get you compiling things for one boot
      of your Raspberry Pi.  They are NOT required for every boot of your Raspberry Pi.
      This means if you want to do other compiles in the future, these steps are required to be 
      re-run every reboot.  

   3. There is no need to unmount /tmp before you shutdown your Raspberry Pi.  You can 
      just mount the USB HD on top of the existing /tmp mount.  When you're done and 
      unmount the USB HD, the previous mount will be still there


In this example, I'm mounting and unmounting the drive via a script.  You can choose to download and
modify this script which supports syntax differences for Raspbian Buster, Stretch, Jessie, and even
Wheezy as well as both simple primary partition schemes and LVM enabled partitioning.  This script
should just work for simple setups but you'll need to edit the script it for any advanced needs:

   cd /tmp
   wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/mount-usb-hd.sh
   wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/umount-usb-hd.sh
   wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/spindown-usb-hd.sh
   chmod 700 mount-usb-hd.sh umount-usb-hd.sh spindown-usb-hd.sh
   sudo chown root mount-usb-hd.sh umount-usb-hd.sh spindown-usb-hd.sh
   sudo mv /tmp/mount-usb-hd.sh /tmp/umount-usb-hd.sh spindown-usb-hd.sh /usr/local/sbin


Now go ahead and connect the SDD/HDD to your Rpi's USB port and wait 10 seconds.  Then run the 
"dmesg" command where you should see something like:
   --
   [Sun Jul  7 09:42:31 2019] scsi 0:0:0:0: Direct-Access     ST325031 0AS                   PQ: 0 ANSI: 5
   [Sun Jul  7 09:42:31 2019] sd 0:0:0:0: [sda] 488281250 512-byte logical blocks: (250 GB/233 GiB)
   [Sun Jul  7 09:42:31 2019] sd 0:0:0:0: [sda] Write Protect is off
   [Sun Jul  7 09:42:31 2019] sd 0:0:0:0: [sda] Mode Sense: 28 00 00 00
   [Sun Jul  7 09:42:31 2019] sd 0:0:0:0: [sda] No Caching mode page found
   [Sun Jul  7 09:42:31 2019] sd 0:0:0:0: [sda] Assuming drive cache: write through
   [Sun Jul  7 09:42:31 2019] sd 0:0:0:0: Attached scsi generic sg0 type 0
   [Sun Jul  7 09:42:31 2019]  sda: sda1
   [Sun Jul  7 09:42:31 2019] sd 0:0:0:0: [sda] Attached SCSI disk
   --


Ok, so I have an important question for you:

   Have you ever used this storage device under Linux?  

If not, it's probably formatted with either the VFAT or ExFAT Windows file systems.  That won't work 
for Linux so we need to ERASE your drive, partition it, and then REFORMAT it.  Make sure you're OK 
with removing all the data off this drive or STOP following this section *now*!  Assuming you're OK 
with the erasing of the drive and your drive drive is "/dev/sda" as shown in the example above, let's 
use the newer style "parted" command to see what file system type is on your drive:

   sudo parted /dev/sda print
   --
   Model: ST325031 0AS (scsi)
   Disk /dev/sda: 250GB
   Sector size (logical/physical): 512B/512B
   Partition Table: msdos
   Disk Flags:

   Number  Start   End    Size   Type     File system  Flags
    1      1049kB  250GB  250GB  primary  fat32
   --

Let's delete that partition and create a new Linux one.  To do that, let's use parted in interactive
mode:

  sudo parted /dev/sda
  --
  GNU Parted 3.2
  Using /dev/sda
  Welcome to GNU Parted! Type 'help' to view a list of commands.
  (parted) ?
  --

     Let's get the partition numbers out of the program using the "print" command.  As you can see here,
     we have the "1" partition that we'll want to delete:
        --
        (parted) print
        Model: ST325031 0AS (scsi)
        Disk /dev/sda: 250GB
        Sector size (logical/physical): 512B/512B
        Partition Table: msdos
        Disk Flags:

        Number  Start   End    Size   Type     File system  Flags
         1      1049kB  250GB  250GB  primary  fat32
        --

     Ok, let's delete the old partition and create a new one:
        --
        rm 1
        --

    Ok, now let's use the modern GPT style of partition tables (compared to the legacy MBR type):
       --
       (parted) mklabel gpt
       Warning: The existing disk label on /dev/sda will be destroyed and all data on this disk will be lost. Do you want to continue?
       Yes/No? yes
       --

    Ok, now let's create a single large partition using the EXT4 file system and the maximum drive size as show above shown as "250GB":
       --
       mkpart primary ext4 0GB 250GB
       --

    Check your work by using the "print" command:
       --
       Model: ST325031 0AS (scsi)
       Disk /dev/sda: 250GB
       Sector size (logical/physical): 512B/512B
       Partition Table: gpt
       Disk Flags:

       Number  Start   End    Size   File system  Name     Flags
        1      1049kB  250GB  250GB  ext4         primary
       --

   Ok, looks good so use the "quit" command to exit partd.  Now let's format the drive with the following command.  When (or if 
   prompted), give a "y" to confirm you want to format the partition.  The actual formatting will take various amounts of time
   depending on the size and performance of your drive:
      --
      /sbin/mkfs.ext4 /dev/sda1

      mke2fs 1.44.5 (15-Dec-2018)
      /dev/sda1 contains a vfat file system
      Proceed anyway? (y,N) y
      Creating filesystem with 61034752 4k blocks and 15261696 inodes
      Filesystem UUID: b83c5909-3fdd-4ef0-af0c-a6d0f1ac20b2
      Superblock backups stored on blocks:
              32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
              4096000, 7962624, 11239424, 20480000, 23887872

      Allocating group tables: done
      Writing inode tables: done
      Creating journal (262144 blocks): done
      Writing superblocks and filesystem accounting information: done
      --
      
Ok, now we need to install the LVM tools just in case your existing SDD/HDD was already 
formatted with a LVM partitioning layout:

   apt-get install lvm2


Now you're ready to mount the drive:

   sudo /usr/local/sbin/mount-usb-hd.sh


If this is the first time you've followed this guide, you'll be given some instructions to
do:
   --
   Stage 2 - /tmp/usr/src/archive does not exist on USB HD.  Create this directory path with the command:
   sudo mkdir -p /tmp/usr/src/archive/Rpi-scratch
   sudo umount /tmp
   --

If you see that, then follow those commands by simpling typing in:
   --
   sudo mkdir -p /tmp/usr/src/archive/Rpi-scratch
   sudo umount /tmp
   --

  NOTE:  If you get a busy error when unmounting /tmp, make sure you're not currently cd'ed 
         into the /tmp directory and then try the umount command again.



Now run the command again:
   
   sudo /usr/local/sbin/mount-usb-hd.sh


Essentially, this mount script above mount a partition onto /tmp and creates some symlinks to
/usr/src/archive for a build area.  In my specific example, what is does is the following with a bunch
of error checking, etc:
  
  #   Attach the USB HD
  #   mount /dev/mapper/vg_dranchlt3-lv_root /mnt/lvm/root 
  #   mkdir -p /mnt/lvm/root/home/
  #   ln -s /mnt/lvm/root/usr/src/archive/ /usr/src/archive
  #   mount /dev/mapper/vg_dranchlt3-lv_root /tmp
  #   rm /usr/src/archive
  #   ln -s /tmp/usr/src/archive/ /usr/src/archive


Finally, a few things to consider:

  1. Since this script mounts a /tmp volume on the HDD and as such, the drive might ever get idle enough
     to spin down.  It's recommended to either set the drive to a more aggressive APM level or run the 
     umount script when you don't need the drive. 

  2. if you ever want to unmount the drive at any time, just do the following:

     a. Make sure that you don't have any shell logins in any of the directories on the mounted drive 
        (including the base shell after you used "sudo") or the umount will refuse the request

     b. run "sudo /usr/local/sbin/umount-usb-hd.sh" which will umount the drive and then 
        spin down the drive

17.a (OPTIONAL): Create remote NFS mounts for compile scratch space (save the SD card)


  +-----------------------------------------------------------------------------------------------------------------+
  | IMPORTANT                                                                                                       |
  | ---------                                                                                                       |
  | It seems that you CANNOT use autoconf (at least v2.69-8) over NFS                                               |
  | Centos5 or Centos6: - https://bugzilla.redhat.com/show_bug.cgi?id=494042                                        |
  | http://gnu-autoconf.7623.n7.nabble.com/autoconf-hangs-due-to-autom4te-cache-and-NFS-problem-on-AIX-td10656.html |
  |                                                                                                                 |
  |  Work around:  You MUST build your source code to a local file system to the system be it the SD card           |
  |                (NOT RECOMMENDED) or attach a USB SDD or HDD (RECOMMENDED)                                       |
  |                                                                                                                 |
  |                See the previous section for how to use the USB HDD/SSD approach                                 |
  +-----------------------------------------------------------------------------------------------------------------+

      I'm leaving this section in place just in case some people are curious on the NFS steps
 

#Install NFS client programs
sudo apt-get install nfs-common

#This is required for mounting remote legacy NFS machines - the error seen is:
# 
#   mount.nfs: rpc.statd is not running but is required for remote locking.
#
update-rc.d -f rpcbind enable
service rpcbind start

#Update the remote NFS server's /etc/exports file and run "exportfs -avr" on it

#On the local machine, edit the /etc/default/nfs-common file and change the line to:


# Create the mounting script - change it to suit your environment
#
#   NOTE:   This script is specific to my environment -Please edit to suit your 
#           environment
#

# /usr/local/sbin/mount-hampacket2-nfs.sh
--
#!/bin/bash

if [ ! -d /mnt/nfs ]; then
   mkdir /mnt/nfs
fi
#change the hampacket host to match your own internal NFS server
mount -t nfs hampacket2:/usr/src/archive/RPi /mnt/nfs
mount -t nfs hampacket2:/usr/src/archive/RPi/tmp /mnt/nfs
--


I've written a script to do this if you wish to review and modify to suite your needs:

   cd /tmp
   wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/mount-hampacket2-nfs.sh
   chmod 700 mount-hampacket2-nfs.sh
   sudo chown root mount-hampacket2-nfs.sh
   sudo mv mount-hampacket2-nfs.sh /usr/local/sbin


18. Build VE7FET AX.25 packages from git


Why use the VE7FET AX.25 packages and not the official AX.25 packages? My reasoning is fully documented here:

NOTE:
----
   But... (there's always a "but")... things have been changing a bit.  Back in late August 2019, 
   there had been some very disruptive changes coming in from the Debian Stretch distro versions 
   which broke things.  At the same time, the VE7FET AX.25 sources had created conflicts with
   man page locations which broke deb packaging.  A LOT of changes have come into the VE7FET repo 
   to resolve these issues and I believe things should be ok now.


Anyway, assuming you've setup the scratch compile space and /tmp overflow from previous sections, 
let's get started in building out the AX.25 packet system:

   #If you didn't already create this directory on your mounted SDD/HDD:
   #
   sudo mkdir -p /usr/src/archive
   sudo chown $USER /usr/src/archive
   mkdir -p /usr/src/archive/Rpi-scratch/
   sudo chown $USER /usr/src/archive/Rpi-scratch/
   

18.a Install libax25:


Download the current VE7FET sources for AX.25.  If you want to know why I recommend these AX.25
sources vs say the the official AX.25 sources, see:

   http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html#3.ax25tools


Ok, let's get started:

      #Use the new directory
      cd /usr/src/archive/Rpi-scratch/

      #If this is the first time downloading the repo
      git clone https://github.com/ve7fet/linuxax25.git

      #If you've already downloaded it before, let's update the repo
      cd linuxax25/libax25/
      git pull


Ok, now enter the libax25 directory (if you aren't already there):

      cd linuxax25/libax25/


Next, we need to install the Zlib and zlib-dev libraries as programs in this package requires it
if it's not already installed:

   sudo apt-get install zlib1g zlib1g-dev


Now let's pre-configure the code:

   NOTE: Running this command can seemingly look hung for 20 seconds before it starts to show output.
         It IS running and it's completion is dependent on the performance of your Raspberry Pi

         autoreconf --install


   NOTE#2:
       If you received an error above about "autoreconf", you probably skipped 
       ahead and DIDN'T follow "Section 16 Install the required compiler tool chains 
       to be able to build Linux programs".  Go back and do that first!


Assuming the above command worked after say 30 seconds, now do the following:

   # NOTE:  File placement opinion: You will notice I'm placing the files in /usr and /etc and NOT
            in say /usr/local, /usr/local/etc, /opt, etc.  My personal philosophy here is the 
            following:

               - If a program is packaged, it should go into the standard /usr, /lib, /etc, paths.
               - If a program is NOT packaged, it goes into /usr/local, /usr/local/lib, etc.  

            If you don't agree with my approach, feel free to change the paths to whatever you prefer
                    

   # Now configure the package 
   ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var

   # Now build the sources: 
   #   the -j8 is for Rpi v4, 3+, and 3 with four cores
   #   use -j2 for Rpi 2, Zero-W, Zero, and 1 with one core
   make -j8


Ok, let's prepare to package it.  First do a work around trick for a checkinstall bug which incorrectly 
reads RPM spec files:

   CRITICAL:
   ----------
   mv libax25.spec libax25.spec.old


Next, optionally do temporarily work around a known GLIBC conflict  (see below NOTES for more details)
for Raspbian Stretch or Jessie:

   +------------------------------------------------------------------------------------+
   | NOTE:  Do NOT do this on Raspberry Pi OS "Buster" or the configure stage will FAIL |
   +------------------------------------------------------------------------------------+
   
   sudo mv /usr/include/netax25/ax25.h /usr/include/netax25/ax25.h.old


Next, determine what version of libax25 sources you have

      grep " VERSION" config.h

   As of 9/24/20, it shows:
   --
   #define VERSION "1.1.3"
   --

Now run the checkinstall program but substitute in the correct version if required
and package things up:

   sudo checkinstall --pkgname libax25 --pkgversion 1.1.3 --pkgrelease 1 --pkggroup \
hamradio --pkgsource https://github.com/ve7fet/linuxax25 --maintainer \
ve7fet@users.noreply.github.com --provides "ax25" --requires zlib1g


When prompted for "Should I create a default set of package docs", Select Y


Next, when prompted for the description, enter in the following:
   --
   Library for amateur radio packet radio applications using the AX.25, Netrom, ROSE, etc protocols
   --

Hit ENTER again to accept the description


Next, confirm the checkinstall fields all look ok and similar to the following:
--
0 -  Maintainer: [ ve7fet@users.noreply.github.com ]
1 -  Summary: [ Library for amateur radio packet radio applications using the AX.25, Netrom, ROSE, etc protocols ]
2 -  Name:    [ libax25 ]
3 -  Version: [ 1.1.3 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ hamradio ]
7 -  Architecture: [ armhf ]
8 -  Source location: [ https://github.com/ve7fet/linuxax25 ]
9 -  Alternate source location: [  ]
10 - Requires: [ zlib1g ]
11 - Provides: [ ax25 ]
12 - Conflicts: [  ]
13 - Replaces: [  ]
--

Hit ENTER to start the packaging and then attempt to install the package (hint.. it WILL fail but
   there is a reason).  After reviewing these NOTEs, please see next steps

   +----------------------------------------------------------------------------+
   | NOTE #1: - checkinstall errors                                             |
   |                                                                            |
   |       If you notice that all kinds of strange of spaces are winding up     |
   |       in the output above (say the "name" field) or 1%{?dist} in the       |
   |       "release" field, this means you didn't rename the .spec file as      |
   |       mentioned above!  Rename the .spec file and try again                |
   +----------------------------------------------------------------------------+


Resolving package installation failure:

   - You most likely will see checkinstall fail with:

        --
        Building Debian package...OK
        Installing Debian package... FAILED!
        *** Failed to install the package
        Do you want to see the log file?  [y]: n
        Erasing temporary files...OK
        Writing backup package...OK
        OK
        Deleting temp dir...OK
        --

     It seems that a recent VE7FET commit in the VE7FET GIt repo have restored previously
     known glibc conflicts.  What is that you ask?  

     If you're using either the VE7FET repo code or the "Official AX25" repo code 
     or even the old Raspbian distro-included AX.25 packages, the .deb packaging 
     creation stage will succeed but the actual package INSTALL phase will FAIL 
     due to a conflict with the /usr/include/netax25/ax25.h file which is present
     in both the Glibc package and this libax25 package. You can read more but 
     this bug at https://github.com/ve7fet/linuxax25/issues/1 .  To work around 
     this, you can do a safe force-overwrite the conflicting file with the following 
     command:

             sudo dpkg --force-overwrite --install libax25_1.1.3-1_armhf.deb

   +-----------------------------------------------------------------------------------------------------------------+
   | NOTE #2 - Future patching issues:                                                                               |
   |                                                                                                                 |
   |      Related to the package installation issue above, this long standing Glibc conflict issue with the libax25  |
   |      package was seemingly fixed and then re-broken in the Aug 2018 version of the VE7FET AX25 sources repo.    |
   |      If you're using either an impacted version of the VE7FET repo, a version of the Official AX.25 repo,  or   |
   |      the official Raspbian repos which have VERY old code in them,  this work-around script below will still be |
   |      needed.                                                                                                    |
   |                                                                                                                 |
   |      Background:                                                                                                |
   |      As you operate your Raspberry Pi through the months and years, it's important that you keep up on security |
   |      and other bug fix updates.   You will eventually need to install glibc/libc updates included with the      |
   |      Raspberry Pi OS / Raspbian / whatever Linux distro you installed which *WILL* unfortunately conflict       |
   |      around the libax25 package similar to the NOTEs above.  That package installation error will look          |
   |      something like the following:                                                                              |
   |                                                                                                                 |
   |         Preparing to unpack .../libc6-dev_2.24-11+deb9u3_armhf.deb ...                                          |
   |         Unpacking libc6-dev:armhf (2.24-11+deb9u3) over (2.24-11+deb9u1) ...                                    |
   |         dpkg: error processing archive /var/cache/apt/archives/libc6-dev_2.24-11+deb9u3_armhf.deb (--unpack):   |
   |         trying to overwrite '/usr/include/netax25/ax25.h', which is also in package libax25 1.0.5-1             |
   |                                                                                                                 |
   |                                                                                                                 |
   |      To resolve this conflict, I've written a script to make the Raspbian updates work more smoothly:           |
   |                                                                                                                 |
   |         #Download and place this script                                                                         |
   |         cd /tmp                                                                                                 |
   |         wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/update-glibc-ax25-workaround.sh |
   |         chmod 700 update-glibc-ax25-workaround.sh                                                               |
   |         sudo chown root update-glibc-ax25-workaround.sh                                                         |
   |         sudo mv update-glibc-ax25-workaround.sh /usr/local/sbin/                                                |
   |                                                                                                                 |
   |      Next, you need to find the libax25 .deb package you built above and make it always available for the       |
   |      script you just downloaded to find  it.  My instructions recommend to build all those AX25 packages on an  |
   |      external USB HDD but you probably don't want that mounted 24/7.  For this setup, I do the following:       |
   |                                                                                                                 |
   |            # change the username here to reflect your username                                                  |
   |            mkdir /home/dranch/libax25/                                                                          |
   |                                                                                                                 |
   |            # cd to wherever you built the VE7FET AX.25 packages and find the libax25 deb file                   |
   |            cp -v /usr/src/archive/Rpi-scratch/linuxax25/libax25/libax25_*.deb /home/dranch/libax25/             |
   |                                                                                                                 |
   |                                                                                                                 |
   |        Finally, edit the downloaded /usr/local/sbin/update-glibc-ax25-workaround.sh script's "FET_LIBAX25_PATH" |
   |        variable to point to the directory where the libax25 package is available.  For example:                 |
   |                                                                                                                 |
   |            vim /usr/local/sbin/update-glibc-ax25-workaround.sh                                                  |
   |            --                                                                                                   |
   |            #Change this to your desired path                                                                    |
   |            FET_LIBAX25_PATH="/home/dranch/libax25"                                                              |
   |            --                                                                                                   |
   |                                                                                                                 |
   |      After that, when you're asked to update the glibc package as part of a regular OS update but the process   |
   |      fails, simply run this script:                                                                             |
   |                                                                                                                 |
   |         sudo /usr/local/sbin/update-glibc-ax25-workaround.sh                                                    |
   |                                                                                                                 |
   |      This script will first download the newer glibc/libc packages from the Raspberry Pi OS / Raspbian repo,    |
   |      force install those packages FIRST then re-install the libax25 package and then exit.  Once that's         |
   |      completed, you can again run:                                                                              |
   |                                                                                                                 |
   |         sudo apt-get upgrade --no-install-recommends                                                            |
   |                                                                                                                 |
   |      and your machine will now download and install all the remaining packages  You should be good to go at     |
   |      that!                                                                                                      |
   +-----------------------------------------------------------------------------------------------------------------+


CRITICAL STEP:
--------------
   With a recent toxic release of the AX.25 packages from Debian, it became very obvious that Debian's APT    
   repo system makes no distinction between this locally built VE7FET AX.25 package and the Debian built (and 
   toxic) AX.25 packages.  To protect your system from having the Debian APT system overwriting your built    
   packages, run the following command:                                                                       

      sudo apt-mark hold libax25


Ok, the base library for AX.25 should be installed!  

If you manually want to install this newly built libax25 package on some other machine, simply copy of the .deb 
package to that other machine and run:

   sudo dpkg --install libax25_1.1.3-1_armhf.deb

18.b Install ax25-apps:


Ok, the next few steps are going to be a lot easier.  First, this next package's source was already downloaded 
via the previous git command for libax25.  To compile this package, we first need to install the Ncurses 
libraries as the "call" program requires it:

   #Raspberry Pi OS:
   sudo apt-get install libncursesw6 libncursesw6-dev 

     NOTE: As of 7/7/19, the libncursesw6-dev package seems to be missing in Raspbian Buster.  To work
           around this issue, install the previous do the following:

           sudo apt-get install libncursesw5 libncursesw5-dev


Next, go into the source directory and start building:

   cd /usr/src/archive/Rpi-scratch/linuxax25/ax25apps

   NOTE: Running this command can seemingly look hung for 20 seconds before it starts to show output.
         It IS running and it's completion is dependent on the performance of your Raspberry Pi

         autoreconf --install

   #Now configure the package 
   ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var


   # Now build the sources: 
   #   the -j8 is for Rpi v4, 3+, and 3
   #   use -j2 for Rpi 2, Zero-W, Zero, and 1
   make -j8


Now again apply the work-around for checkinstall bug incorrectly reading RPM spec files:

   CRITICAL NOTE:
   --------------
   mv ax25apps.spec ax25apps.spec.old

   #work around a busted makefile - still required in Raspbian Buster, Stretch, etc
   sudo /bin/mkdir -p /var/ax25/ax25rtd

   #Determine what version of libax25 you have
   grep " VERSION" config.h

      As of 6/30/19, it shows:
      --
      #define VERSION "2.0.1"
      --

Now run the checkinstall program but substitute in the correct version if required
and package things up:

   sudo checkinstall --pkgname ax25-apps --pkgversion 2.0.1 --pkgrelease 1 --pkggroup \
hamradio --pkgsource https://github.com/ve7fet/linuxax25 --maintainer \
ve7fet@users.noreply.github.com --provides ax25 --requires libax25,libncurses6 make install 


  When prompted for "Should I create a default set of package docs", Select Y


Next, when prompted for the description, enter in the following:
--
This package provides specific user applications for hamradio that use AX.25 Net/ROM or ROSE network protocols
--

Hit ENTER again to accept the description

Next, confirm the checkinstall fields all look ok and similar to the following:
--
0 -  Maintainer: [ ve7fet@users.noreply.github.com ]
1 -  Summary: [ This package provides specific user applications for hamradio that use AX.25 Net/ROM or ROSE network protocols ]
2 -  Name:    [ ax25-apps ]
3 -  Version: [ 2.0.1 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ hamradio ]
7 -  Architecture: [ armhf ]
8 -  Source location: [ https://github.com/ve7fet/linuxax25 ]
9 -  Alternate source location: [  ]
10 - Requires: [ libax25 ]
11 - Provides: [ ax25 ]
12 - Conflicts: [  ]
13 - Replaces: [  ]
--

Hit ENTER to start the packaging and checkconfig will now automatically install the package 
for you. 

   +----------------------------------------------------------------------------+
   | NOTE #1:                                                                   |
   |       If you notice that all kinds of strange of spaces are winding up     |
   |       in the output above (say the "name" field) or 1%{?dist} in the       |
   |       release field, this means you didn't rename the .spec file as        |
   |       mentioned above!  Rename the .spec file and try again                |
   +----------------------------------------------------------------------------+

After that, you should be good.  If you are doing this installation with an older 
version VE7FET ax25-apps (no longer needed as of 6/30/18), the default configuration 
example files might not be installed.  To check, do the following:

   ls -la /etc/ax25


If you don't see the ax25ipd.conf, ax25mond.conf, and ax25rtd.conf example config files, 
run the following commands:

      sudo mkdir /etc/ax25
      sudo cp -n /usr/share/doc/ax25apps/conf/ax25ipd.conf.dist /etc/ax25/ax25ipd.conf
      sudo cp -n /usr/share/doc/ax25apps/conf/ax25mond.conf.dist /etc/ax25/ax25mond.conf
      sudo cp -n /usr/share/doc/ax25apps/conf/ax25rtd.conf.dist /etc/ax25/ax25rtd.conf


   # If the above copy commands fail finding the *.dist files, this means you're probably 
   # ether using:
   #    - older version of VE7FET repo
   #    - an older Official AX25 repo
   #    - the very old Raspbian packages.
   #

   +----------------------------------------------------------------------------+
   | CRITICAL NOTE:                                                             |
   |      With a recent toxic release of the AX.25 packages from Debian, it     |
   |      became obvious that Debian's APT system makes no distinction between  |
   |      this home-built VE7FET package and the old Debian built (and toxic)   |
   |      packages.  To protect your system from overwriting your built         |
   |      packages, run the following command:                                  |
   |                                                                            |
   |         sudo apt-mark hold ax25-apps                                       |
   |                                                                            |
   +----------------------------------------------------------------------------+

If you manually want to install the built package on some other machine, use the 
following command on that other machine once the package is copied over:

   sudo dpkg --install ax25-apps_2.0.1-1_armhf.deb

  then if using an older VE7FET based package like mentioned above, don't forget:

      sudo cp -n /usr/share/doc/ax25apps/conf/ax25ipd.conf.dist /etc/ax25/ax25ipd.conf
      sudo cp -n /usr/share/doc/ax25apps/conf/ax25mond.conf.dist /etc/ax25/ax25mond.conf
      sudo cp -n /usr/share/doc/ax25apps/conf/ax25rtd.conf.dist /etc/ax25/ax25rtd.conf

18.c Install ax25-tools


Ok, one more package to install.  The sources for the package were already downloaded via 
the previous git command so let's get started:

   cd /usr/src/archive/Rpi-scratch/linuxax25/ax25tools

   NOTE: Running this command can seemingly look hung for 20 seconds before it starts to show output.
         It IS running and it's completion is dependent on the performance of your Raspberry Pi

      autoreconf --install

   #Now configure the package 
   ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --datadir=/usr/share --datarootdir=/usr/share

   # Now build the sources: 
   #   the -j8 is for Rpi v4, 3+, and 3
   #   use -j2 for Rpi 2, Zero-W, Zero, and 1
   make -j8


CRITICAL STEP:
--------------
Now work around the checkinstall bug incorrectly reading RPM spec files:

   mv ax25tools.spec ax25tools.spec.old


#Determine what version of libax25 you have

   grep " VERSION" config.h

      As of 9/24/20, it shows:
      --
      #define VERSION "1.0.5"
      --


Now run the checkinstall program but substitute in the correct version if required
and package things up:

   sudo checkinstall --pkgname ax25-tools --pkgversion 1.0.5 --pkgrelease 1 --pkggroup \
hamradio --pkgsource https://github.com/ve7fet/linuxax25 --maintainer \
ve7fet@users.noreply.github.com --provides ax25 --requires libax25,zlib1g make install


When prompted for "Should I create a default set of package docs", Select Y

Next, when prompted for the description, enter in the following:
--
This package provides specific amateur radio packet radio tools for applications that use AX.25 Net/ROM or ROSE network protocols
--

Hit ENTER again to accept the description

Next, confirm the checkinstall fields all look ok and similar to the following:
--
0 -  Maintainer: [ ve7fet@users.noreply.github.com ]
1 -  Summary: [ This package provides specific user applications for hamradio that use AX.25 Net/ROM or ROSE network protocols ]
2 -  Name:    [ ax25-tools ]
3 -  Version: [ 1.0.5 ]
4 -  Release: [ 1 ]
5 -  License: [ GPL ]
6 -  Group:   [ hamradio ]
7 -  Architecture: [ armhf ]
8 -  Source location: [ https://github.com/ve7fet/linuxax25 ]
9 -  Alternate source location: [  ]
10 - Requires: [ libax25,zlib ]
11 - Provides: [ ax25 ]
12 - Conflicts: [  ]
13 - Replaces: [  ]
--

Hit ENTER to start the packaging and checkconfig will now automatically install the package 
for you. 

   +----------------------------------------------------------------------------+
   | NOTE #1:                                                                   |
   |       If you notice that all kinds of strange of spaces are winding up     |
   |       in the output above (say the "name" field) or 1%{?dist} in the       |
   |       release field, this means you didn't rename the .spec file as        |
   |       mentioned above!  Rename the .spec file and try again                |
   +----------------------------------------------------------------------------+

   +----------------------------------------------------------------------------+
   | NOTE #2:                                                                   |
   |      If you're running an older version of the VE7FET repo, you might see  |
   |      various conflicts around man pages.  This below issue detailed below  |
   |      should be resolved by the Aug 2018 version of the VE7FET repo.        |
   |                                                                            |
   |      If you must stay with an older version of the repo, you might need to |
   |      use the "official AX25" repo or the very old Raspbian packages instead|
   |                                                                            |
   |      Details:                                                              |
   |      The above checkinstall command MIGHT fail at the "Installing Debian   |
   |      package" stage due to install due to a recently introduced set of     |
   |      conflicts with axports.5.gz, nrports.5.gz and rsports.5.gz manual     |
   |      files.  The newest versions of the VE7FET repo have fixed this but if |
   |      you have this conflict, I recommend to do a forced overwrite of the   |
   |      conflicting files with the following command:                         |
   |                                                                            |
   |   sudo dpkg --force-overwrite --install ax25-tools_1.0.5-1_armhf.deb       |
   |                                                                            |
   | You can read more but this bug at:                                         |
   |       https://github.com/ve7fet/linuxax25/issues/1                         |
   +----------------------------------------------------------------------------+


After that, you should be all done with the AX25 stuff!  

If you are doing this installation with an older version VE7FET ax25-tools, the 
default configuration example files might not be installed.  To check, do the following:

   ls -la /etc/ax25


If you don't see files like ax25d.conf, axports, axspawn.conf, nrbroadcast, nrports, rsports, 
rxecho.conf, and ttylinkd.conf files, run the following commands:

      sudo cp -n /usr/share/doc/ax25tools/conf/ax25d.conf.dist /etc/ax25/ax25d.conf
      sudo cp -n /usr/share/doc/ax25tools/conf/axports.dist /etc/ax25/axports
      sudo cp -n /usr/share/doc/ax25tools/conf/axspawn.conf.dist /etc/ax25/axspawn.conf
      sudo cp -n /usr/share/doc/ax25tools/conf/nrbroadcast.dist /etc/ax25/nrbroadcast
      sudo cp -n /usr/share/doc/ax25tools/conf/nrports.dist /etc/ax25/nrports
      sudo cp -n /usr/share/doc/ax25tools/conf/rsports.dist /etc/ax25/rsports
      sudo cp -n /usr/share/doc/ax25tools/conf/rxecho.conf.dist /etc/ax25/rxecho.conf
      sudo cp -n /usr/share/doc/ax25tools/conf/ttylinkd.conf.dist /etc/ax25/ttylinkd.conf


   # If the above copy commands fail finding the *.dist files, this means you're using a
   # very old VE7FET repo, an older Official AX25 repo, or the very old Raspbian packages.

   +----------------------------------------------------------------------------+
   | CRITICAL NOTE:                                                             |
   |      With a recent toxic release of the AX.25 packages from Debian, it     |
   |      became obvious that Debian's APT system makes no distinction between  |
   |      this home-built VE7FET package and the old Debian built (and toxic)   |
   |      packages.  To protect your system from overwriting your built         |
   |      packages, run the following command:                                  |
   |                                                                            |
   |         sudo apt-mark hold ax25-tools                                      |
   |                                                                            |
   +----------------------------------------------------------------------------+

If you manually want to install the built package on some other machine, use the 
following command on that other machine once the package is copied over:

   sudo dpkg --install ax25-tools_1.0.5-1_armhf.deb


If using an older VE7FET based package like mentioned above, don't forget:

      sudo cp -n /usr/share/doc/ax25tools/conf/ax25d.conf.dist /etc/ax25/ax25d.conf
      sudo cp -n /usr/share/doc/ax25tools/conf/axports.dist /etc/ax25/axports
      sudo cp -n /usr/share/doc/ax25tools/conf/axspawn.conf.dist /etc/ax25/axspawn.conf
      sudo cp -n /usr/share/doc/ax25tools/conf/nrbroadcast.dist /etc/ax25/nrbroadcast
      sudo cp -n /usr/share/doc/ax25tools/conf/nrports.dist /etc/ax25/nrports
      sudo cp -n /usr/share/doc/ax25tools/conf/rsports.dist /etc/ax25/rsports
      sudo cp -n /usr/share/doc/ax25tools/conf/rxecho.conf.dist /etc/ax25/rxecho.conf
      sudo cp -n /usr/share/doc/ax25tools/conf/ttylinkd.conf.dist /etc/ax25/ttylinkd.conf

18.c.1 - Issues with Predictable Network interface names and Linux AX25

   +---------------------------------------------------------------------------------------+
   | CRITICAL: Work around for significant Predicable Interface naming bug with AX.25      |
   +---------------------------------------------------------------------------------------+
   |                                                                                       |
   |    I have confirmed that with Raspbian Stretch (unclear on Buster at the moment),     |
   |    there is some sort of naming issues it's newly enabled "predictable" network       |
   |    interface names.  What is this?  When enabled and you run the command "ifconfig"   |
   |    or "ip addr", you will no longer see Ethernet interfaces with the classic names    |
   |    like "eth0"  but instead, you'll see something very long like "enxb827eb5f05"      |
   |    based on how the system is connected to that Ethernet interface (PCI this, USB     |
   |    that, etc.  How's that for catchy?  For now known reasons to the AX.25 kernel      |
   |    maintainers, the "sa_data" kernel data structure in both the stock Raspbian AX.25  |
   |    package code and the 3rd party VE7FET AX.25 code will give errors like the         |
   |    following when ANY *network* interface name (AX.25 interface, Ethernet interface,  |
   |    is longer than 13 characters is used with AX.25 programs like "beacon":            |
   |                                                                                       |
   |       SIOCGIFHWADDR: No such device                                                   |
   |                                                                                       |
   |    Other AX25 programs like Linpac will crash upon start with:                        |
   |                                                                                       |
   |       /usr/bin/linpac: line 181:  9811 Segmentation fault   $PKG_BINDIR/linpac $*     |
   |                                                                                       |
   |    Fortunately, if you disable predictable network interface names, things work fine. |
   |    To do this, do the following steps if you didn't already disable this in the above |
   |    section 4. Rpi initial setup (OS patches), additional Security hardening, Rpi      |
   |    firmware upgrade).  Alternatively, you can manually disable predictable names      |
   |    with:                                                                              |
   |                                                                                       |
   |       sudo vi /boot/cmdline.txt                                                       |
   |       --                                                                              |
   |       #append the following to the end of the one line in this file                   |
   |       net.ifnames=0 biosdevname=0                                                     | 
   |       --                                                                              |
   |                                                                                       |
   |    Now reboot your Raspberry Pi, log back in and run the command "ifconfig" or        |
   |    "ip addr" and confirm your Ethernet interface name is now say eth0, wlan0, etc.    |
   |    Things should work from there on out. Btw, if Linpac did crash on you,  your       |
   |    terminal might be screwed up and not working properly after that.To fix that, run  |
   |    the commands:                                                                      |
   |                                                                                       |
   |       stty sane                                                                       |
   |       rm -f rm /var/lock/LinPac.0                                                     |
   +---------------------------------------------------------------------------------------+

19. Hardware vs. Software TNC


Ok, now FINALLY on to real packet stuff.  This very Raspberry Pi centric document focuses 
on installing and using the Direwolf software TNC.  It offers the reader a way to create a 
cheaper yet superior TNC solution for AX.25 packet decodes compared to almost any hardware 
TNC on the market (past or present) including comparisons to TNCs like:

   - TNC-PI (the same PIC micro-controller as TNC-X TNC on a Raspberry Pi HAT board)
   - TNC-X (a PIC micro-controller based TNC)
   - Kantronics KPC (version 2, 3, 3+, KAM, etc)
   - Timewave / AEA PK96 TNCs)
   - Kenwood D710, D72, and D74 TNCs
   - MFJ 1270 / 1272 TNC2 TNCs
   - PacComm TNCs


With that said, this documentation and the included AX25 startup scripts *DO* support:
   - Coastal Chipworks TNC-Pi board via the GPIO header 
   - Kenwood D710 KISS TNC via serial port
   - Kenwood D74 handheld via a Bluetooth serial connection

This support is either mentioned indirectly in this document's appendix and/or within the 
/etc/ax25/ax25-up.new packet bring up script itself.  No doubt, soldering up a TNC-Pi kit is a 
fun project and offers a reliable packet TNC.   Doing packet via Bluetooth on a Kenwood D74 HT 
is also pretty sexy but regardless of each solution, Direwolf's on-air decode performance is 
unparalleled and as such, I would STILL recommend that you just use the software-TNC to 
get the best possible performance!

   NOTE:  If you intended to use a Coastal Chipworks TNC-Pi, Kenwood D710 / D74, or any other 
          hardware KISS TNC, there is NO reason to follow this document's sections to configure 
          a sound card or build / install the Direwolf TNC program, etc.  You can simply SKIP 
          AHEAD to Chapter 25 to take it from there.  

          It's also worth mentioning that if you are looking for running an APRS setup and won't 
          be running the direwolf sw-TNC (which includes complete APRS and APRS-IS support), 
          you'll need to install a different APRS application as Direwolf CANNOT be used with
          hardware TNCs.  A good APRS client alternative is the APRX (for being a server) or 
          Xastir for a combined server and GUI client.  I have both application installations 
          detailed in my HamPacket documentation though that doc is intended for Redhat style
          Linux systems:

             http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html


20. Choosing and setting up the Sound device

   
Ok, assuming you're going with the Direwolf software-TNC approach, you first need to pick a 
soundcard to use and get it tuned up.  The Raspberry Pi v4,3+,3,2,ZeroW,Zero,1 boards do NOT 
include a microphone or audio line-in jack so you MUST buy an external sound device.  Read the 
Direwolf User Guide for other recommended devices but I recommend one of these two devices:

   RECOMMENDED - Fe-Pi v2.0 HAT board : this board avoids the known Raspberry Pi USB "DWC" / 
                 Direwolf "dead air" transmit audio delay issue found on the legacy Rpi USB stack.  
                 This issue occurred on all Raspberry Pi board versions running the Raspberry Pi or
                 Raspbian OS until the "Buster" which supports a 100% effective workaround.
                 Users no longer need to use the previously recommended OSS to ALSA wrapper with 
                 this I2S based option.

                 NOTE#1: As of 12/23/20, a HAT board 95% similar to the Fe-Pi I2S HAT is available
                         from the makers of the Nexus DR-X kit.  The only difference is that the 
                         TRRS headphone jack isn't solder on by default.  I already highly recommend 
                         the Nexus DR-X kit for connecting your radios to the Raspberry Pi (includes 
                         a built-in power supply and RTC - read below for more details) so I think this
                         is a WIN-WIN.  If you only want to buy the Fe-Pi like sound device HAT, send 
                         them an email.

                 NOTE#2: As of 11/21/20, the Fe-Pi.com and Tindie sites say this board is now 
                       RETIRED and no longer available.


      - Alternative non-USB sound devices to the Fe-Pi board:

         - Audio Injector
           https://smile.amazon.com/Audio-Injector-Zero-sound-Raspberry/dp/B075V1VNDD
               https://github.com/Audio-Injector/stereo-and-zero/

               This might be a good alternative to the Fe-Pi but it uses bulky RCA connectors.
               You can source different connectors if you want


      $12 US - Fe-Pi I2S Sound device (not USB) available at:

         New Fe-Pi like HAT (no headphone jack): 
            http://wb7fhc.com/about-the-fe-pi.html

         Original Now EOLed Fe-Pi
            https://www.tindie.com/products/kuupaz/fe-pi-audio-z-v2/
              or
            https://fe-pi.com/products/fe-pi-audio-z-v2

      Need other reasons why to buy this board over a USB-based sound device??  I still think this Fe-Pi board 
      is superior to say a Syba CM-119 USB device for several reasons:

         1. Fe-Pi uses the dedicated I2S audio bus so there aren't any USB issues (see the below
            Syba section for specific URLs, any I/O loading issues on the USB bus or USB power 
            issues

         2. No longer relevant: Fe-PI doesn't need to use the legacy OSS hack with Direwolf to 
            minimize the random dead TX time on Raspberry Pi based USB controllers (seeming no 
            longer occurs on the Rpi4 either)

         3. Fe-Pi has slightly better audio specs:

              Line-in ADC > 90 dB SNR and -72 dB THD+N
              Line-Out > 100 dB SNR and -85 dB THD+N


           In comparison, the recommended Syba CM119 USB solution has:

              Line-in ADC >  83 dB SNR and -76 dB THD+N
              DAC Line-Out > 94 dB SNR and -71 dB THD+N   (32 Ohm impedance)

         4. Fe-Pi offers a stereo input (2 channel) vs most sound device's mono (1 channel)
            This could allow you to connect two radios to a single Direwolf instance if you wish

         5. Fe-Pi offers the ability to connect different devices via the microphone vs. line-in 
            jack and the mixer can switch between the inputs electronically

         6. Fe-Pi offers a line-in jack for better impedance matching

         7. Fe-Pi offers various digital audio filtering which are features compared to the 
            simple Syba unit (not really need for Direwolf though)

         8. Very small Pi-Zero physical HAT format using the 40pin header for more reliable 
            electrical connections.  Small format allows for standard 3.5mm audio connectors
            to fix within an Rpi case


         For higher audio fidelity needs (say a music player / Kodi / DLNA box), it's also:

            9. Offers a 5 band hardware equalizer (called "DAP" in alsamixer)


      The Syba CM119 does have the benefit of:

         a. CM119 has 8 GPIO pins available to the user if they are willing to solder wires and level shifts to them

         b. LED activity indicator


   Basic USB-based devices:
   ------------------------
      $7 US - Syba SD-CM-UAUD basic sound device which can be had for $7
              https://www.amazon.com/s?field-keywords=SD-CM-UAUD

              Direwolf DEAD AIR ISSUE (RESOLVED): 
                               There is a known Direwolf issue with USB soundcards on older Raspberry Pi boards
                               (3+ and older):  
                                  https://github.com/wb2osz/rpi-usb-audio-bug 
                                     and
                                  https://bugs.launchpad.net/raspbian/+bug/1819560  

                               This "key up but have variable Dead TX air time until the modem sounds played" issue 
                               does not happen on X86 machines.  This issue now has a fix and should be in the 
                               mainline Linux kernel since about 2021 but until then, there is also a different yet 
                               effective workarounds.

                               What's the issue?
                               -----------------
                               What happens here is that Direwolf will key up the radio via the configured 
                               GPIO pin but the soundcard will wait some random amount of delay before 
                               playing the TNC modem tones.  Some of these delays can be up to 2 seconds!  It's 
                               reported that the Raspberry Pi 4 with it's completely new USB chip and software 
                               stack (all previous generation Raspberry Pi models use the same older SOC built-in 
                               USB chip) does NOT exhibit this issue.  

                               The easy and RECOMMEND workaround for this issue on the older Raspberry Pi modems 
                               is to either:
                                  - Use the newer DWC2 USB stack
                                  - Use the OSS sound stack ALSA wrapper
                               More details below


   NOT RECOMMENDED but works USB sound device:
                             - If you're looking for something even cheaper, you might try using 
                               one of these inexpensive CM108 USB-based sound devices as they've been 
                               reported to work for many people.  Unlike the recommended Syba USB unit 
                               mentioned above, these devices don't always include any microphone input level 
                               control, any audio filters or even include a plastic enclosure to protect 
                               the electronics.  You'll need to add an additional input control like a 
                               resistive input volume potentiometer, etc.  My other concern with using 
                               these inexpensive boards like this is that they can be changed at any time 
                               for different chips at any time and you won't know it:

                               Here is a URL for more details:
                               http://www.marrold.co.uk/2018/04/converting-cm108-usb-fob-for-amateur.html

   NOTE: 
   -----
      Raspberry Pi 3+ and older boards don't do well with higher sampling sound cards running
      at say 192Khz, etc.  Use a 48Khz sampling soundcard for direwolf:

         https://www.raspberrypi.org/documentation/hardware/raspberrypi/usb/README.md


   Amateur Radio focused USB-based sound devices (Allstar interfaces):
   -------------------------------------------------------------------
      - There are families of of sound devices using either the CM119 sound chip that's also found 
        in say the Syba sound device or other chips focused on providing a more "integrated" offering
        with minimizing the requirement of creating custom cabling.  These type of devices are commonly
        called "Allstar" devices which is an analog Radio over IP (RoIP) technology similar to Echolink
        and IRLP:

            Nexus DR-X - an audio routing + RTC device + Buck/Boost power supply intended to connect an
            $68     external sound device (Fe-Pi is recommended) to either an Amateur Radio's 6pin jack 
                    or RJ45 microphone jack (with or without Fe-Pi like I2S sound device) with electronic
                    mixer controls only - includes a layer case:
                    https://wb7fhc.com/nexus-dr-x.html

            RIM and RIM-Lite - USB to commercial radio audio connections for setups for Motorola, Alinco,
                     Scom, RLC, etc:
                     http://www.repeater-builder.com/products/usb-rim-lite.html

            DRA-36 - A USB to either 6pin "DATA" cable or DB9 TNC2 cable + PTT device (kit or fully built)
            $51      only : kit is intended to connect directly to an Amateur Radio's 6pin jack with physical 
                     pots for audio adjustments - includes a separate case:
                     http://www.masterscommunications.com/

            DINAH - A USB to 6pin "DATA" cable sound + PTT device intended to connect directly to an Amateur 
            $35     Radio's 6pin jack with electronic mixer controls only - includes a separate case:
                    https://hamprojects.info/dinah/#cmtoc_anchor_id_9

            DRAWS - A Raspberry PI HAT to dual 6pin "DATA" cable + PTT device + GPS receiver + RTC + Buck/Boost
            $150    power supply intended to connect directly to an Amateur Radio's jack with electronic mixer
                    controls only - case not included
                    http://nwdigitalradio.com/draws/
        

NOTE#2: 
    Other sound devices might work but it's known that Direwolf is sensitive to USB devices
    and not all work correctly.  The Syba unit is proven reliable and also doesn't spew RF 
    noise on 144.000MHz!  


Tangent:  Why am I talking about "noise on 144.000Mhz?  Take a hand held amateur radio, 
          change it's VFO to 144.000Mhz and walk around your home.  You'll probably find many 
          strong signals (birdies).  Why?  Many devices and sound cards have a poorly shielded 
          12Mhz crystal oscillators which is very very common in modern electronics.  Why does 
          that matter to you? The 12th harmonic of 12Mhz is 144MHz!  Tangent over.

20.a Setup the Fe-Pi I2S soundcard


The Fe-Pi HAT board is a dedicated sound HAT board that uses the Raspberry Pi's built-in and 
dedicated I2S bus.  This audio-specific bus offers a more dedicated connection than say 
USB offers on the Raspberry Pi 3+ and older boards.  In addition to the connectivity improvement,
these boards also offer direct stereo LINE-IN and LINE-OUT connections for improved signals.

To get a Fe-Pi board working, you have to do more than just connect the board but it's not hard:

   1. Driver support is included since Linux kernel 4.9.13 (Raspbian Jessie / 8.x or newer).  You 
      can also get newer kernels by running "sudo rpi-update" tool

   2. You have to make a quick change to the Rpi boot process to enable the HAT board at the 
      Broadcom SOC level.  Do the following: 

         sudo vim /boot/config.txt
  
            Find a line that includes the word "dtoverlay"

            Add a line below it that has:

               dtoverlay=fe-pi-audio

   3. Reboot the Rpi

      sudo /sbin/shutdown -r now

   4. Once the Rpi boots back up, login and run the following command to confirm the board
      is recognized:

         dmesg | grep -i fe-pi
         --
         [    8.007458] snd-fe-pi-audio soc:sound: ASoC: CODEC DAI sgtl5000 not registered - will retry
         [    8.010476] snd-fe-pi-audio soc:sound: ASoC: CODEC DAI sgtl5000 not registered - will retry
         [    8.487658] snd-fe-pi-audio soc:sound: ASoC: CODEC DAI sgtl5000 not registered - will retry
         [    8.488264] snd-fe-pi-audio soc:sound: ASoC: CODEC DAI sgtl5000 not registered - will retry
         [    8.664517] snd-fe-pi-audio soc:sound: sgtl5000 <-> 3f203000.i2s mapping ok
         --

   5. OPTIONAL: 
      When you enable the fe-pi-audio overlay, you're also enabling the Rpi's I2C subsystem so that alsamixer
      can control the sound chip's mixer settings.  If you have the i2cdetect utility installed (fully described 
      in the 16x4 LCD section),  run the "sudo i2cdetect -y 1" command where you should see the Fe-Pi on 
      the 0x0a address as "UU" meaning it's in use:

             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
        00:          -- -- -- -- -- -- -- UU -- -- -- -- -- 
        10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
        20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
        30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
        40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
        50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
        60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
        70: -- -- -- -- -- -- -- --  

Once the board is recognized, go ahead and follow the next soundcard centric sections to test the board.

20.b Identify and test the USB soundcard


Anyway, to start, have your sound device connected up:

   NOTE:  If using a USB sound device, plug it into the Raspberry Pi directly
          (do NOT connect it via a USB hub as there is a known issue with the Direwolf 
          program and USB packet latencies introduced.  

   NOTE#2: If using a Syba USB-based sound device, there is a small green LED on it:

           On SOLID: device is initialized but doing nothing

           Blinks slowly:  device is recording audio

           Blinks quickly: device is playing audio


Let's now identify your sound device:

   #First, install some ALSA utilities (if not already installed)
   sudo apt-get install alsa-utils

   #To view all output capable sound devices:
   aplay -l 

Look for all the devices that show with a "plughw" option.  What I see is the following on 
an Rpi 3+:
   --
   plughw:CARD=ALSA,DEV=0           <-------------- Rpi built-in audio output
       bcm2835 ALSA, bcm2835 ALSA
       Hardware device with all software conversions

   plughw:CARD=ALSA,DEV=1
       bcm2835 ALSA, bcm2835 IEC958/HDMI
       Hardware device with all software conversions
   
   plughw:CARD=Device,DEV=0         <-------------- USB based soundcard
       C-Media USB Audio Device, USB Audio
       Hardware device with all software conversions

   plughw:CARD=Audio,DEV=0          <-------------- Fe-Pi I2S based soundcard
       Fe-Pi Audio,
       Hardware device with all software conversions
   --


If you're going to be using multiple soundcards, you need to understand about ALSA soundcard
enumeration which is well detailed here:

   https://github.com/dh1tw/remoteAudio/wiki/Persistent-USB-Mapping-of-Audio-devices-(Linux)

That link will help you setup UDEV rules and what not to be able to reliably connect to the
same sound card ever time.  If you're just using one soundcard, then you won't really care 
about the enumeration stuff and that's what this doc will assume for now.

Next, if you're curious on getting more details on your soundcard, you can display the 
soundcard's native sampling rates with this command:

   sudo lsusb -vv | grep -e Audio -e tSamFreq | grep -v -e Descriptor -e bInterfaceClass

On my USB based Syba sound device, I see the following sampling rates.  The Fe-Pi board
doesn't seem to show anything:
   --
   iProduct                1 C-Media USB Audio Device
        tSamFreq[ 0]        48000
        tSamFreq[ 1]        44100
        tSamFreq[ 0]        48000
        tSamFreq[ 1]        44100
   --

That above output means this sound card can either natively support 48Khz or 44.1Khz input
sampling.  Alternatively if you have a PCI-based card (doesn't work for USB or Fe-Pi base
soundcards) or you're doing all this in a virtual machine, use:

   sudo alsa-info --stdout | grep -A 12 -e "Codec:" -e "Audio Input" 


Next test, let's record from the sound card for 10 seconds and puts a 960Kbyte file into the 
/tmp area:

   Fe-Pi-based soundcard test:
   --------------------------
      arecord -D plughw:CARD=Audio,DEV=0 -t wav -f S16_LE -r 48000 -d 10 /tmp/test.wav

      NOTE:  There are not any LEDs on the Fe-Pi to indicate activity


   USB-based soundcard test:
   -------------------------
      arecord -D plughw:CARD=Device,DEV=0 -t wav -f S16_LE -r 48000 -d 10 /tmp/test.wav

      NOTE:  A Syba sound device's green LED will go from a solid on, to blinking slowly
             for 10 seconds and then go back to being on solid


If this works ok, you should see the output:

   Recording WAVE '/tmp/test.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono


Next test, if you have speakers connected to the Rpi's HDMI monitor (default) or the speaker out jack 
on the Pi itself, built-in speakers, you can listen to the recorded file via  the "Default" soundcard 
output.  If there aren't any speakers connected to the Rpi, you can use tools like scp to send the 
file to another computer that DOES have speakers connected

   #First, test with a known good audio file going to either your HDMI monitor or the Rpi's built-in
   # output only sound card:
   #
   aplay /usr/share/sounds/alsa/Front_Center.wav

You should see something like the following on the command line:

   Playing WAVE '/usr/share/sounds/alsa/Front_Center.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono


If you don't hear anything, make sure:

   - if HDMI audio, the sound is turned up on the monitor

   - if using the Rpi speaker out, use amplified speakers or a headphones 

   - Change the audio routing:
      amixer cset numid=3 1   #analog jack
      amixer cset numid=3 2   #HDMI jack

Ok, now try playing  the file you just recorded from the steps above with:

   aplay /tmp/test.wav

   # You probably didn't hear anything because there wasn't a microphone connected to the
   # sound device.  That's ok as long as it didn't give any errors


To play the same files through the newly added sound device (assuming you temporally 
connected speakers to the output jacks of that board), do:

   Fe-Pi I2S USB sound card:
   -------------------------
   aplay -Dplughw:CARD=Audio,DEV=0 /usr/share/sounds/alsa/Front_Center.wav
      and
   aplay -Dplughw:CARD=Audio,DEV=0 /var/log/test.wav

 Or 

   Syba USB sound card (the device's green LED will go from a solid on, to blinking slowly
             for a dew seconds and then go back to being on solid)
   ---------------------------------------------------------------------------------------
   aplay -Dplughw:CARD=Device,DEV=0 /usr/share/sounds/alsa/Front_Center.wav
      and
   aplay -Dplughw:CARD=Device,DEV=0 /var/log/test.wav


If you select the wrong ALSA device, you might see the error:

     aplay: set_params:1239: Channels count non available


You can now mix and match commands and combine with the Unix "pipe" feature.  Here, we output from 
Rpi's built-in output only headphone jack and into say a Syba USB sound card:

20.c Setting up the Sound Card levels for 1200BAUD AFSK Packet Radio


This example is using a Alinco DJ-580 HT with a simple GPIO to PTT circuit similar to the 
one shown here (more about this later):

   http://www.dunmire.org/projects/DigitalCommCenter/soundmodem/mySoundCardInterface.png


The PTT connection is connected to physical GPIO pin: 

      Rpi pin 37 (Broadcom GPIO 26) :: connect this to the PTT circuit or RS232 DB9 pin7 (this is the RS232 RTS signal)
      Rpi pin 39 ( electrical GND ) :: connect this to the PTT circuit or RS232 DB9 pin5 (this is the RS232 GND signal)


I initially set the Alinco DJ-580 volume knobs to:

      SQL knob          : 0.0 out of 10    (squelch fully open)
      Output Volume knob: 2.9 out of 10

20.d. Soundcard Mixer settings


The following audio level setting are an example of properly tuned levels for my specific setup 
(Syba and Alinco HT).  Please review the next section to better understand how to test your own
levels.

With the HT turned on and the SQL/VOL knobs set above, run the command:

   #We want to run this as root to set the main system levels
   sudo alsamixer


Now, when doing mixer changes, it's VERY helpful to hear the changes live to get the initial 
audio levels right.  To do this, try connecting a music device like your smartphone via it's 
headphone jack (hopefully yours still has this great interface yet simple interface) to your 
chosen Rpi's sound card INPUT jack via a male to male 3.5mm TRS cable.  Now connect your playback
speakers or headphone to the output jack (Fe-Pi recommended: green 3.5mm TRS jack).

Now start playing some known music on your smartphone and then run one of these commands
to get the Raspberry Pi to start simultaneously recording and playing the audio back:

   #
   #  Don't forget the trailing "-" at the end of the command line (this is the STDOUT 
   #   system)


#Fe-pi USB device : audio in and audio out on the Fe-Pi - this will record and playback forever
#  until you hit control-c
#
   arecord -D plughw:CARD=Audio,DEV=0 -t wav -f S16_LE -r 48000 - | \
aplay -Dplughw:CARD=Audio,DEV=0 -

   or 

#Syba USB device : audio in and audio out on the Syba - this will record and playback forever
#  until you hit control-c
   arecord -D plughw:CARD=Device,DEV=0 -t wav -f S16_LE -r 48000 - | \
aplay -Dplughw:CARD=Device,DEV=0 -


Ok, now run the command "alsamixer".  In this ncurses user interface example, use the following 
keys to navigate the tool:

  - The "F6" key is used to select the correct sound card 

       In these examples, I cover both the: 

           Syba USB-connected sound card: C-Media USB Audio Device

           Fe-Pi I2S-connected sound card: C-Media USB Audio Device


  - The "F3" key to select the "playback" or Output interface on the sound device
    ----------------
    OUTPUT interface
    ----------------

     - Fe-pi: The Fi-Pi is a very powerful I2S-connected soundcard compared to say the quality 
            Syba USB-connected sound card with built-in hardware output equalizers and mixers but 
            it's also complex (has 24 controls on the Playback screen).  The Fe-Pi is also a bit 
            weird on where it puts its controls.  As such, I'll describe each function:

            Electrically:  the Fe-Pi offers both stereo LINE-OUT audio jacks via the GREEN and PINK
                           3.5mm three-conductor TRS jack as well as a HEADPHONE output via the BLACK 
                           four-pin TRRS jack.  I recommend to use the LINE-OUT jack if you the audio
                           levels can work for you (more below)

            Mixer Configuration:  The Fi-Pi offers a LOT of functionality that most sound devices 
                                  don't expose.  Below is what I reverse engineered out of it's 
                                  settings but the data sheet for it's sound chip also provides 
                                  deeper detail if you wish to read it:

                                     https://www.nxp.com/docs/en/data-sheet/SGTL5000.pdf


            - Use the cursor keys to move left and right and starting on the far left and going 
              to the right:

               - "headphone db gain" : Audio playback via the black 4-conductor TRRS connector
                                       ** hit the "m" key to MUTE aka disable it as we are going to 
                                          use the green LINE-IN jack instead)

               - "headphone mux"     : not 100% sure what this is  - options are "DAC" and "LINE_IN"

                                       ** CRITICAL**: use the up/down arrow keys to select "DAC" or
                                             *        everything coming in through "line_in" will
                                             *        go out the "headphone" jack, bypassing 
                                             *        everything in your alsa mixer settings!

               - "headphone Playback ZC" : not 100% sure what this is 
                                           ** hit the "m" key to MUTE aka disable it

               - "PCM" : This is a master output volume that seems to control both the headphone
                         and line-in output.  This can make very large changes to the audio levels.

                             ** RIGHT CHANNEL: Set level to: 75
                             ** LEFT  CHANNEL: Set level to:  0

                     +--------------------------------------------------------------------------------+
                     | Audio Level note:                                                              |
                     |                                                                                |
                     |     The Fe-Pi's line-out audio levels are much lower compared to the headphone |
                     |     as the headphone output has amplification. This is *EXPECTED*.  If your    |
                     |     radio's input requires higher levels than what a setting of LineOut of 100 |
                     |     and then a PCM level of "100" here:                                        |
                     |                                                                                |
                     |        - Check to see if your radio's audio IN has a gain control.  For        |
                     |          example, Kenwood V71 and D710 radios have an input gain setting but   |
                     |          it can ONLY be set via a Windows utility                              |
                     |                                                                                |
                     |        - You might need to switch and use the Headphone jack output instead.   |
                     |          Remember to lower the levels here first before switching to           |
                     |          "headphone" so you don't overdrive anything.                          |
                     +--------------------------------------------------------------------------------+

                     Nexus DR-X HAT users:  Each channel here is one of the two radio connections on 
                                            the Nexus board (left or right).  As such, so you will 
                                            probably want both levels to be non-zero



               - "LineOut" : This is a STEREO volume for the line-out hack and it's control seems to 
                             make very minor level changes.  Depending on how you wire up the 
                             soundcard to your radio, turn up only one channel (say the RIGHT-side 
                             channel):
                             ** RIGHT CHANNEL: Set level to: 58
                             ** LEFT  CHANNEL: Set level to:  0

                             To maximize your OUTPUT audio level, set this first to 100 and then increase
                             the PCM level to 100.  Please note that running the sound device at 100
                             can create undesired distortion.  If your running into this, please read
                             the note above about possibly switching to the headphone jack out instead.

                             Nexus users:  Each channel here is one of the two radio connections on 
                                           the Nexus board (left or right).  As such, so you will 
                                           probably want both levels to be non-zero


               - "Mic"    : not 100% sure what this is since we're in the PLAYBACK section of the mixer
                            ** Set to 0

               - "Capture Attenuate" : adds a -6db attenuator on the microphone input (not sure why
                                       this is in the playback section
                                       ** hit the "m" key to MUTE aka disable it

               - "Capture Mux" : determine what input port to listen to : options are "MIC_IN and LINE_IN"
                  *IMPORTANT*    ** Use the up/down arrow keys to select "LINE_IN"

               - "Capture ZC" : not 100% sure what this is
                                ** hit the "m" key to MUTE aka disable it

               - "AVC"        : not 100% sure what this is
                                This control has some interaction with the "AVC hard limiter" control
                                ** leave at default: 0 or hit the M key to MUTE it **

               - "AVC hard limiter" : not 100% sure what this is
                                      Used when "Digital Input Mux" is set to DAP
                                      When "AVC" is set to 0 and this setting it set to to "m" for MUTE, 
                                      all DAP audio playback stops
                                      ** leave at default: 0

               - "AVC integrator response" : not 100% sure what this is
                                             ** leave at default: 33

               - "AVC max gain : not 100% sure what this is
                                 ** leave at default: 0

               - "AVC threshold : not 100% sure what this is
                                  ** leave at default: 0

               - "BASS 0" : Use when "Digital Input Mux" is set to DAP
                            Sound Equalization: Deep Bass
                            ** leave at default: 49

               - "BASS 1" : Use when "Digital Input Mux" is set to DAP
                            Sound Equalization: Mid Bass
                            ** leave at default: 49

               - "BASS 2" : Use when "Digital Input Mux" is set to DAP
                            Sound Equalization: Midrange
                            ** leave at default: 49

               - "BASS 2" : Use when "Digital Input Mux" is set to DAP
                            Sound Equalization: Low treble 
                            ** leave at default: 49

               - "BASS 2" : Use when "Digital Input Mux" is set to DAP
                            Sound Equalization: High Trebble   
                            ** leave at default: 49

               - "DAP Mix Mux" : not 100% sure what this is (options: ADC, I2S)
                                 ** leave at default: ADC

               - "DAP Main Channel" : Volume control when "Digital Input Mux" is set to DAP
                                       ** leave at default: 50

               - "DAP Mix Channel" : Mix control to add in DAP audio control when "Digital 
                                     Input Mux" is set to DAP Depending on what the "DAP 
                                     Mux Channel" is set it, the level of 0, starts with
                                     that signal (say ADC) and as you increase the level, 
                                     it adds in the other DAP controlled signal (say I2S) 
                                     which adds both volume and delays 
                                     ** leave at default: 0 **

               - "DAP Muxl" : not 100% sure what this is (options: ADC, I2S)
                                     ** leave at default: ADC **

               - "Digital Input Mux" : not 100% sure what this is (options: I2S, Rsrvd, DAP)
                   *Important*         NOTE: there seems to be some audio delay (buffering) 
                                             between the I2S and DAP selection - I2S seems to 
                                             be a little less latency

                                       NOTE2: the DAP option seems to be a "colored" audio with 
                                              "brighter" or higher frequency audio output with 
                                              a lot more mid-range sound

                                      NOTE3: When on the DAP settings, the BASS 0-4 parameters 
                                             controls the various bass, mid, and treble levels
                                       ** leave at default: I2S

  
     - Syba:  The Syba USB-connected sound device is a reasonable quality sound device that 
              provides consistent results

         Set the "speaker" level at 00:19 depending on on how you've wired your sound device to 
            your radio.  Here, I am recommending to set the LEFT channel to "0" output and the
            RIGHT channel to a level of "19".  Also ensure the output is "activated". That's 
            shown as 00 in the bottom box of the vertical slider).  If it shows "MM", hit the 
            "m" key to UN-MUTE.

         Set the "Mic" (this is the monitor feature if it's shown there at all) to MUTED by 
            hitting the "m" key (that's shown as MM in the bottom box of the vertical slider) 

         Auto Gain control - (if shown on your specific sound card) is selected (that's 00)   
            [need to understand if this should be on or off - use "m" to disable]


  - The "F4" key to select the "Capture" or Input interface on the sound device
    ---------------
    INPUT interface
    ---------------
      Fe-pi: The Fi-Pi is a very powerful soundcard compared to say the Syba sound card with built-in 
            hardware input equalizers and mixers but it's also complex (has 12 controls on the Capture screen).
            It's also  also a bit weird of where it puts its controls.  As such, I'll describe each function:

            Electrically:  the Fe-Pi offers both LINE-IN audio jacks via the pink 3.5mm three-conductor 
                           TRS jack or MICROPHONE via the black four-pin TRRS jack.  I recommend to use 
                           the LINE-IN jack


            - Use the cursor keys to move left and right and starting on the far left and going to the 
              right:

               - "mic db gain" : Audio input level via the black 4-conductor TRRS connector
                                 Default is 0
                                 ** Leave to default: 0 as we are going to use the green LINE-IN jack instead)

               - "capture" : Primary audio input level control
                             Default is 80 
                            
                             CRITICAL:  Hit the space bar to make this item show "L R CAPTURE" in RED letters

                               ** RIGHT CHANNEL: Set level to: 80
                               ** LEFT  CHANNEL: Set level to:  0

                             Nexus users:  Each channel here is one of the two radio connections on 
                                           the Nexus board (left or right).  As such, so you will 
                                           probably want both levels to be non-zero

               - "AVC integrator response" : Same control as on the Playback screen
                                             ** leave at same value as on playback screen: 33 **

               - "AVC max gain : Same control as on the Playback screen
                                 ** leave at same value as on playback screen: 0 **

               - "AVC threshold : Same control as on the Playback screen
                                  ** leave at same value as on playback screen: 0 **

               - "BASS 0" : Same control as on the Playback screen
                            ** leave at same value as on playback screen: 49 **

               - "BASS 1" : Same control as on the Playback screen
                            ** leave at same value as on playback screen: 49 **

               - "BASS 2" : Same control as on the Playback screen
                            ** leave at same value as on playback screen: 49 **

               - "BASS 3" : Same control as on the Playback screen
                            ** leave at same value as on playback screen: 49 **

               - "BASS 4" : Same control as on the Playback screen
                            ** leave at same value as on playback screen: 49 **

               - "DAP Main channel" : Same control as on the Playback screen
                                      ** leave at same value as on playback screen: 0 **

               - "DAP Mix Channel: : Same control as on the Playback screen
                                     ** leave at same value as on playback screen: 50 **


      Syba sound device:
         Set the "Capture" to a level of 31 and make sure you can see the word "Capture" by 
         using the space bar


  - The "F5" key to select "All controls"

      Some specific sound cards don't show any specific AGC (Automatic Gain) controls in the 
      "F3 - playback" window but they show them here so it's best to double check here


  - Hit the Escape key to exit and leave the current audio level settings in place


CRITICAL: 
---------
Once you have the soundcard initially tuned up, save the soundcard settings and levels 
as the root user since we'll be running direwolf as root:

   sudo alsactl store

This will store all of these mixer settings into the /var/lib/alsa/asound.state file

20.e. Confirm Clean Silence from the Soundcard


This check is needed as a *lot* of USB sound devices will pass on noise from dirty power 
sources through your radio in the form of dirty audio.  Noisy audio will severely harm the 
software TNC's digital signal processing.  To properly check for this, do the following:

     a. Create an empty (and noise free) 15 second WAV file - output file should be about 240kbytes


        #RECOMMENDED: Recording from the soundcard interface while nothing is connected to it  

           Fe-Pi-based soundcard test:
           --------------------------
              arecord -D plughw:CARD=Audio,DEV=0 -t wav -f S16_LE -r 48000 -d 15 /tmp/15sec-silence.wav

              NOTE:  There are not any LEDs on the Fe-Pi to indicate activity


           USB-based soundcard test:
           -------------------------
              arecord -D plughw:CARD=Device,DEV=0 -t wav -f S16_LE -r 48000 -d 15 /tmp/15sec-silence.wav

              NOTE:  A Syba sound device's green LED will go from a solid on, to blinking slowly
                     for 10 seconds and then go back to being on solid

         
        #NOT Recommended - This recording approach function might be broken with recent versions of 
                           Raspbian where it creates a loud clicking sound on recording

              arecord -c 2 -d 15 -f S16_LE -r 48000 -t wav -D null /tmp/15sec-silence.wav



        You should see the following output:

           Recording WAVE '/tmp/15sec-silence.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo


     b. Temporarily disconnect the packet radio from the soundcard's chosen playback jack, 
        connect in a pair of headphones to the soundcard, and listen to the playback the silence 
        sound file:


           Fe-Pi-based soundcard test:
           ---------------------------
           aplay -Dplughw:CARD=Audio,DEV=0 /tmp/15sec-silence.wav


           USB-based soundcard test:
           -------------------------
           aplay -Dplughw:CARD=Device,DEV=0 /tmp/15sec-silence.wav


        You should see the following output:
 
           Playing WAVE '/tmp/15sec-silence.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo


        Carefully listening to the audio, you should first hear the noise floor increase a little bit 
        in the headphones but:

             - There should be no whine, buzzing, or clicking.  The audio should be completely noise 
               free.   If it's NOT, you must work to improve that audio.. check the output mixer settings, 
               try a different sound device, etc.

          NOTE:  If trying to use the NUL approach above, Raspbian Buster(06/30/19) and Jessie (08/29/17)
                 seems to create a very pronounced TICKING sound on the created recordings.  This is created 
                 on a both a Raspberry Pi and an X86 Centos box.  Inspecting the file in Audacity shows the 
                 ticks so I think there is a bug in the "arecord" program,   


20.f - Setting the right audio levels for AFSK packet tones


Now that you're familiar how to change the levels on the soundcard side, I recommend to
read and then re-read:

   http://www.febo.com/packet/layer-one/transmit.html 

Read the "The No-Test-Equipment Packet Adjustment System" section to learn how to 
tune your packet signal levels.  The "no-Test-Equipment packet adjustment system" section 
will get your radio's AFSK1200 levels to be pretty close to perfect.  Remember, the adjusting these 
levels is a combination of the levels coming in/out of your radio as well as the soundcard 
levels coming out of the Raspberry Pi's soundcard.  You MUST adjust both sides to have and 
effective and functioning packet station.  

   NOTE:  While this will work pretty well for 1200bps signals, it WON'T work very well
          for 9600bps G3RUH FSK signals.  You'll need more accurate tools than your ears!

Once you have the soundcard side tuned up, save the new soundcard levels:

   sudo alsactl store

It's worth noting that if you aren't going to be using this document's startup 
scripts, be sure to use:

   sudo alsactl restore

in your scripts to reliably restore the soundcard levels.  The level settings are
stored in /var/lib/alsa/asound.state when run with "sudo".


21. BEWARE of the soundcard and radio microphone bias DC voltage


IMPORTANT: Microphone Bias Voltage:
-----------------------------------
Before you connect any radio to your soundcard, it's CRITICAL that you check to 
see if:

   1) Your soundcard's input jack does or doesn't provides a "bias" voltage 
      for condenser-type microphones (microphone jacks probably do; line-out ports
      probably don't)

   2) Your radio's microphone jack does or doesn't provide a "bias" voltage for
      condenser-type microphones (it probably does)

On my Syba USB soundcard, it puts out +5.0v on the tip of the mono-style microphone 
jack.  I've checked with the CM108 schematics and programming API and this voltage 
cannot be turned off via software.  As such, it's CRITICAL that you connect a 10uF 
capacitor between the soundcard's microphone input and your radio's audio output.  
A ceramic capacitor is preferred but an electrolytic capacitor will work fine and   
this will isolate this DC voltage offset.

   NOTE: 
        if you use an electrolytic style cap, make sure the POSITIVE lead is 
        connected to the sound-card side (the site that's providing the voltage)

Once you've checked the soundcard microphone side, now check the radio's microphone
jack as well and if it also creates a bias voltage, it too will need a capacitor.


22. Choosing GPIO pin for the radio PTT line


To interface the Rpi to your radio, you need to select which GPIO pin on the Rpi's 
header your going to use to key up the radio.  

It's VERY important to note that some GPIO pins on the Raspberry Pi are pulled HIGH (+3.3v) by 
default but it can depend on your Raspberry Pi version as well as it's kernel version.  This 
is obviously complicated but it's important to understand this because by using one of these pins, 
your radio won't key up when your Raspberry Pi is rebooting or is down.  Very important!

You can read more about this here:
   https://www.raspberrypi.org/forums/viewtopic.php?t=35321


On the Raspberry Pi 3+ and Rpi v2, these GPIO pins are initialized HIGH:
   --
   GPIO 2
   GPIO 3
   GPIO 4 
   GPIO 7
   GPIO 8 
   possibly GPIO 14 too

You can learn more about what pins are initiated HIGH here:

   Raspberry Pi Model A, B, B+, the Compute Modules, and the Raspberry Pi Zero
   ARM Peripheral spec sheet
   --
   https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/README.md -->
     https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf


   Newer Raspberry Pi versions and their specific data sheets:
   --
   https://www.raspberrypi.org/documentation/hardware/raspberrypi/


If you were to use one of these pins with the simple PTT transistor circuit mentioned 
above/below, you'd find that whenever your Rpi is rebooting or is powered yet off, it 
would leave your radio keyed up (PTT asserted)!  That's very BAD!  So... I advice to 
NOT use one of those GPIO pins mentioned above.


Ok, then what GPIO pins should you use?  Well, the Rpi line of SBCs can have it's 
various GPIO pins connected to several other "alternative" functions available in the 
Broadcom SOC ASIC depending on it's pin "mode".  Unfortunately, there are *LOTS* of 
incorrect information out on the Internet on this topic as many sites don't show the 
alternative modes for each of the pins.  

Below is one of the better GPIO pin diagrams out on the web showing the different pins 
and their various modes.  Pay specific attention to the different *colors*:

   RECOMMENDED 
   Rpi pinout graphic (doesn't include the new Rpi 4 alternative layouts if you care)
   ----------------------------------------------------------------------------------
   http://pinout.xyz/

      For those of you running the full desktop version of Raspberry Pi OS (not the lite)
      version, try running the command "pinout" on the command line to see an Ncurses
      diagram of your GPIO pins


   Here are some other good URLs to check out for different overlay maps on different models
   of Raspberry Pi (official documentation):

     - https://www.raspberrypi.org/documentation/usage/gpio/

     - Raspberry Pi B+ and Raspberry Pi-2:
       https://keytosmart.com/wp-content/uploads/2014/07/Raspberry-Pi-GPIO-Layout-Model-B-Plus.png


Per the Direwolf documentation, it has the following recommendations:

   Raspberry Pi physical pin 11 - Broadcom GPIO 17
   Raspberry Pi physical pin 15 - Broadcom GPIO 22
   Raspberry Pi physical pin 16 - Broadcom GPIO 23
   Raspberry Pi physical pin 18 - Broadcom GPIO 24
   Raspberry Pi physical pin 22 - Broadcom GPIO 25


   The Raspberry Pi 4, 3+, 3, 2, Zero-W, Zero, and A/B+ have the larger 40pin connector 
   with additional GPIO pins:

   Raspberry Pi physical pin 29 - Broadcom GPIO  5
   Raspberry Pi physical pin 31 - Broadcom GPIO  6
   Raspberry Pi physical pin 32 - Broadcom GPIO 12
   Raspberry Pi physical pin 33 - Broadcom GPIO 13
   Raspberry Pi physical pin 35 - Broadcom GPIO 19
   Raspberry Pi physical pin 36 - Broadcom GPIO 16
   Raspberry Pi physical pin 37 - Broadcom GPIO 26  <----- My PTT recommendation
   Raspberry Pi physical pin 38 - Broadcom GPIO 20
   Raspberry Pi physical pin 40 - Broadcom GPIO 21


As such, I'm using the following GPIO connection for the PTT control on my Rpi that don't 
have any other alternative mode functionality:

    Rpi pin37 (Broadcom GPIO 26) :: connect this to the PTT circuit 
    Rpi pin39 ( electrical GND ) :: connect this to the PTT circuit


BTW, there is an optional feature in Direwolf to set a GPIO pin when a valid 
packet HDLC signal is detected (this is called the DCD indicator).  I recommend you 
connect an LED and a 500ohm resistor to a GPIO pin to use it.  Its a very helpful 
indicator!


So I'm using the following different GPIO pins on my Rpi3 for various uses:

    Direwolf PTT on Rpi2:
      Rpi pin 37 (Broadcom GPIO 26) :: connect this to the PTT circuit
      Rpi pin 39 ( electrical GND ) :: connect this to the PTT circuit

    Direwolf DCD on Rpi2:
      Rpi pin 33 (Broadcom GPIO 13) :: connect to cathode of LED (short lead / smaller metal inside LED)
      Rpi pin 34 - GND              :: connect to anode of LED (long lead / larger metal inside LED)

    PiShutdown button:
      Rpi pin 18 (Broadcom GPIO 24) :: connect to 10k resistor, then one side of a momentary switch
      Rpi pin 20 - GND              :: Connect to other side of momentary switch


   +---------------------------------------------------------------------------------+
   | Reminder:                                                                       |
   |                                                                                 |
   |   It's critical that whatever username runs the direwolf program, that user is  |
   |   given the required Unix permissions to access the GPIO pins.  This is covered |
   |   in Section 3.1.b using the "usermod" Unix command.  Without this, Direwolf    |
   |   will simply just not key up your radio and you'll never know why!             |
   +---------------------------------------------------------------------------------+



23. Connecting your Radio to the Soundcard with tips

The choice of which radio to use for packet radio depends on several factors:

   1. Your budget
   2. Do you want 1200bps packet (APRS and most packet) or faster (2400bps, 4800bps, 9600bps, etc)
   3. How reliable do you want your station
   4. How much hair do you want left on your head after you complete this project


Generally speaking, I recommend to ONLY use a mobile radio running at 25w with a 6pin DATA jack on 
the rear of the radio.  This increases your budget (item #1 above) but it dramatically helps
you on items #2, #3, and #4 above!   Some possible recommendations can be found here:

   https://groups.io/g/nwaprs/wiki/3574

Take that list with a gain of salt as it also mentioned Baofeng radios which are notorious to
cause all kinds of issues with packet.


Anyway, on to connecting your chosen radio to your soundcard.  There are multiple ways to connect 
the RPi to your radio's PTT line depending on the radio, etc.  An ideal solution is to use an 
opto-isolated circuit such as:

   https://www.nf8m.com/nf8m/rig-control-and-keying/

This would be easily connected to a Raspberry Pi's GPIO pins.  Alternatively, I've used
this simple transistor circuit with my Kenwood TH-F6A HT::

   http://www.dunmire.org/projects/DigitalCommCenter/soundmodem/mySoundCardInterface.png

   +---------------------------------------------------------------------------------------+
   | CRITICAL NOTE:                                                                        |
   | --------------                                                                        |
   | Every radio is different and the above connections will need to be changed to         |
   | conform to your specific radio.  For example, I've since moved to using a Alinco      |
   | DJ-580 and it's PTT connections are RADICALLY different than the Kenwood.  Unless you |
   | modify the connections to suit your radio (ensure key DC blocking capacitors are in   |
   | place as mentioned above), you run the very real risk of damaging your USB sound card |
   | *and* the radio itself!                                                               |
   +---------------------------------------------------------------------------------------+


Other potential options:

   - Use the Easy Digi isolation kit which includes an opto-isolator for PTT which also includes
     audio isolation transformers.  

        https://www.ebay.com/sch/i.html?_from=R40&_trksid=p2380057.m570.l1313.TR0.TRC0.H0.Xeasydigi.TRS0&_nkw=easydigi&_sacat=0

     This kit solution works well for HF and 1200bps AFSK packet but it will NOT work for say 
     4800bps QPSK or 9600bps G3RUH FSK packet (or faster) as the transformers limit the audio 
     passband bandwidth too much.


   - Another option to consider is to build the time-limited PTT circuit that's found in Direwolf's
     Raspberry-Pi-APRS.pdf doc found at

        https://github.com/wb2osz/direwolf/blob/master/doc/Raspberry-Pi-APRS.pdf

     This is an extra-safe design as the design itself will prevent any hung transmitter
     situations due to including a 555 timer!


   - A nicer solution is to get a nice PCB version of WB2OSZ's circuit above which is 
     available for order here as designed by James N7SET:

        https://github.com/jaymzx/RPi-WD-Packet-Interface


   - You could then put either these two circuits or the little PCB on a Raspberry Pi proto HAT:

        https://www.adafruit.com/products/2310

     and you'll then have a very slick setup that you can easily move from Raspberry Pi to 
     Raspberry Pi!


   - Signalink USB sound devices

        These devices are very popular with HAMs as they can work with many different radio combinations.
        All Signalink units include isolation transformers for mitigating ground loops, galvanic hum, etc.
        Older generation Signalink units used transformers that block WIDE modes like G3RUH 9600bps FSK packet
        and VARA Wide.  Overall, I find the Signalink units overly expensive for what they are and their
        pseudo-VOX PTT solution and the variable TX delay knob can create a lot of issues

        
   - One of the more ultimate solutions are:

        Nexus DR-X kit with a Fe-Pi sound card:  http://wb7fhc.com/reserve-your-dr-x.html
          - dual radio support, also includes a RTC clock and a wide voltage converter for powering the Rpi

        NW Digital DRAWS (complete HAT): http://nwdigitalradio.com/draws/
          - dual radio support, also includes a GPS with PPS support, RTC clock and a wide voltage converter 
            for powering the Rpi, and extender header with some GPIO pins and two ADC inputs


Now that you've created the required radio interface cable to connect the radio to sound the 
soundcard CONSIDERING:

   - You've ensured that the microphone jacks on both the radio AND the soundcard don't have 
     a DC bias voltage (above).  If they do, it's CRITICAL that you install a small DC blocking 
     capacitor on both lines to remove those voltages

   - On the radio, make sure the squelch is all the way open (static noise all the time) and 
     that the output speaker volume on the radio is LOW (but not off) to start off with

   - If you're using an HT type radio, make sure that you disable any "RX power saver" as 
     well as the Automatic power off features of the radio.  If you don't disable both of these, 
     the radio will either miss part of the beginning packets and/or have the radio go to 
     sleep on you!

24. Compile, Configure, and Test Direwolf


Assuming your external SDD/HDD storage is still mounted per the previous document section, lets 
now compile up the newest version of Direwolf!


  NOTE:  If you intend to run a remote Direwolf iGate that might have unreliable Internet connectivity), 
         it's highly recommended to setup an RTC (real time clock) to let Direwolf properly timeout
         old packets.  Please see the RTC section later in this document on how to do this


  a. First install the required dependencies to build the minimal Direwolf 

        sudo apt-get install libasound2-dev unzip libudev-dev

     If you want to include GPS support for later support of connecting an external GPS for
     position, date/time, etc, then add the following additional packages:

        sudo apt-get install gpsd libgps-dev


     +--------------------------------------------------------------------------------------------+
     | IMPORTANT:                                                                                 |
     |                                                                                            |
     |      Impacts Raspbian Buster and Stretch:                                                  |
     |                                                                                            |
     |      If you disabled IPv6 on your system per the section above, you might run into an      |
     |      error installing or updating gpsd.   This is a known bug per:                         |
     |                                                                                            |
     |           https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=818332                         |
     |                                                                                            |
     |      To work around this, do the following (per the bug report):                           |
     |                                                                                            |
     |         Edit the /lib/systemd/system/gpsd.socket file and remove or comment out the line:  |
     |                                                                                            |
     |            ListenStream=[::1]:2947                                                         |
     |                                                                                            |
     |         then run to retry the package config:                                              |
     |                                                                                            |
     |            sudo apt-get -f install                                                         |
     +--------------------------------------------------------------------------------------------+

  b.  Enter the compiling area and make it writable by users in the "adm" group

         cd /usr/src/archive/Rpi-scratch/
         mkdir direwolf
         cd direwolf


  c. Get a copy of the Direwolf sources
 
     You have two choices here to the version of Direwolf:

        - RECOMMENDED: The mainline release version of Direwolf is v1.6 as of 01/01/21.  This new version
          has many new features such as FX.25, AIS Reception on appropriate marine frequencies, and a ton 
          of fixes and improvements including known color issues with it on newer Linux distributions 
          (Raspbian Buster).  You can find it and any newer mainline releases at:

             https://github.com/wb2osz/direwolf/releases 


        - The "dev" or development branch of Direwolf is v1.7 as of 11/29/20.  This development release is 
          very new and while it does offer some interesting improvements over v1.6 today, it's NOT stable.  
          As the "dev" branch develops, I'm sure my recommendation will swing back to the Dev branch for 
          those who need / want to try it.

        
     c.1: RECOMMENDED: Get the Release (master) branch version
        +-------------------------------------------------------------------------------------------+
        | RECOMMENDED:                                                                              |
        |                                                                                           |
        |   The newest Direwolf code in the "master" branch is v1.6 which now uses the cmake build  |
        |   system.                                                                                 |
        +-------------------------------------------------------------------------------------------+

            git clone https://github.com/wb2osz/direwolf.git
            cd direwolf
            git branch -r
            git checkout master
            cd ..

     ------
       OR
     ------

     c.2: NOT RECOMMENDED: Get the DEV branch version
        +-----------------------------------------------------------------------------------------+
        | NOT RECOMMENDED:                                                                        |
        |                                                                                         |
        |   The newest Direwolf code in the DEV branch is v1.7.  This version currently does      |
        |   have some interesting new features but they are NOT stable at this time               |
        +-----------------------------------------------------------------------------------------+

            git clone https://github.com/wb2osz/direwolf.git
            cd direwolf
            git branch -r
            git checkout dev
            cd ..

24.a. Direwolf Dead TX airtime workarounds

     If you're using a USB based sound device (not an I2S-based sound device like a Fe-Pi) on older Raspberry Pi 
     model (RPi 3B+, 3, 2, Zero-W, Zero, 1, but NOT the RPi4 or newer Raspberry Pi hardware), there is a known issue 
     of Direwolf transmitting random amounts of "dead airtime" before actual modem sounds play over the
     air.  You can read more about this Raspberry Pi USB DWC bug at:

        https://github.com/raspberrypi/linux/issues/3883
           and
        https://github.com/wb2osz/rpi-usb-audio-bug
        https://github.com/wb2osz/direwolf/issues/194
        https://bugs.launchpad.net/raspbian/+bug/1819560

     To summarize the issue, the Linux kernel in Raspberry Pi / Raspbian OS versions has a modified USB stack
     that has a specific USB bug impacting sound card devices.  This bug has been fixed in bleeding edge kernels
     (newer than 5.4.70) but this is going to take until Jan 2021 or later to come as a Raspberry Pi OS update.
     

     NOTE: It was previously mentioned in this doc and no longer recommended that to work around this "Dead TX 
           airtime" issue, older Rpi HW owners could use a work-around using the legacy OSS sound system (the 
           Linux sound server before ALSA).  Unfortunately, this legacy OSS support was accidentally disabled 
           from the Raspberry Pi OS kernel (was recently re-added in (see URLs above) but going the OSS route
           is still NOT recommended.


     There are several options to address this USB-only issue:

        Option #1: RECOMMENDED: Use the DWC2 USB kernel module for users using a USB sound device:
                 
                   Rpi 0, 1, 2, 3, 3+ users running Raspberry Pi OS "Buster" version can try using the alternative 
                   "DWC2" USB stack which the default USB stack used by the Rpi4 new hardware.  To try this, it's 
                   first recommended to first make a backup of your SD card (a method is recommended in the appendix 
                   of this doc).  Once you're ready, edit the /boot/config.txt file and find one of the multiple 
                   possible lines starting with "dtoverlay".  Add the following line:

                      sudo vim /boot/config.txt
                      --
                      dtoverlay=dwc2
                      --

                   Once added, reboot your Raspberry Pi, log into your pi and run the command:

                      lsmod | grep dwc2

                  to confirm you're using the new USB kernel module.  If this last command didn't find it
                  loaded, you've done something wrong and you need to re-check your work, fix the issue, and
                  again reboot.


        Option #2: Regain OSS support via a bleeding edge kernel version:
                   Users running Raspberry Pi OS Buster, Stretch, and Jessie can switch to using the 
                   bleeding edge kernels using the "rpi-update" tool to get both the DWC_OTG fixes 
                   finally solve ALSA sound issues as well as bring the return of the OSS sound system.  
                   Once the 5.4.70 kernel for the Buster OS comes to a mainline release (~Jan 2021), 
                   Raspberry Pi Buster users will no longer need the bleeding edge kernels.  The Stretch 
                   and Jessie distros will NEVER get these fixes in a mainline kernel update so you'll
                   need to stick with the bleeding edge kernels.  Please make a backup of your SD card 
                   before you try this.

        Option #3: Use the Legacy OSS sound stack:
                   It seems that the original Linux sound system (OSS) is not affected by this DWC 
                   USB issue and thus, fixes the issue.  The problem here is that in modern Raspberry Pi
                   OS versions, this option was accidentally disabled in the mainline kernel.  If users want 
                   to go this route, you will either need to use a bleeding edge built kernel mentioned in 
                   Option #2 above or compile your own kernel.  Building a new kernel isn't too hard
                   and there are many guides out there on the Internet how to do it but it does take time.
                   If you've never built a kernel, I recommend this as you'll learn alot.


        NOT RECOMMENDED:  Option #2 / Option #3: OSS workaround for kernels that have the OSS support included 
                          for Direwolf release 1.6 or newer:
           
           If you're curious: read https://groups.io/g/direwolf/message/3644 for more information on this change

           OSS Option #1: create and apply a simple patch 
           ----------------------------------------------
           a.1.a - Enter the Direwolf 1.6 sources directory

              cd /usr/src/archive/Rpi-scratch/direwolf/direwolf

           a.1.b - create the file "direwolf-cmake-oss.patch" and put the following contents into it:
           --
--- CMakeLists.txt.orig 2019-12-22 09:19:09.329897884 -0800
+++ CMakeLists.txt      2019-12-22 09:19:27.828061636 -0800
@@ -202,7 +202,7 @@
 endif()

 if(LINUX)
-  find_package(ALSA REQUIRED)
+  find_package(ALSA)
   if(ALSA_FOUND)
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_ALSA")
   endif()
           --

           a.1.c Apply the patch with:

                  patch -p0 < direwolf-cmake-oss.patch


           OSS Option #2: NOT RECOMMENDED - manually edit the CMakeLists.txt file in the root Direwolf source code directory 
           -----------------------------------------------------------------------------------------------------------------
           a.2.a Enter the Direwolf 1.6 sources directory

              cd /usr/src/archive/Rpi-scratch/direwolf/direwolf

           a.2.b create the file direwolf-cmake-oss.patch and put in the following contents:

              find the line:
              --
              find_package(ALSA REQUIRED)
              --

             change it to read:
             --
             find_package(ALSA)
             --
            

     A.3 NOT RECOMMENDED: OSS workaround for kernels that have the OSS support: Direwolf release 1.5 or older:

           Edit the Makefile.linux file found in the root Direwolf source code directory and comment out 
           (aka add the # character front of the line).  Edit the Makefile.linux file in the root Direwolf source code 
           directory and find the line:
           --
           alsa = 1
           --

           Change it to read:
           --
           #alsa = 1
           --


  24.B.  Check the libgps version
  -------------------------------
     To properly identify package dependencies, we need to be aware which version of the libgps package
     you have installed.  Generally speaking, this is what you should see:

                - The "Sid" aka "unstable" version of Raspbian versions it's libgps library "libgps26"
                - The "Buster"  version of Raspbian versions it's libgps library "libgps23"
                - The "Stretch" version of Raspbian versions it's libgps library "libgps22" 
                - The "Jessie"  version of Raspbian versions it's libgps library "libgps21" 
                - The "Wheezy"  version of Raspbian versions it's libgps library "libgps21" 

                Because of this, the resulting Direwolf package built for one OS version is not usable for 
                the other OS version. You can run the following command to see what version is installed on 
                your Rpi:

                    dpkg -l | grep libgps


  Prepare to compile Direwolf:
  ----------------------------
  24.c.1 RECOMMENDED: Direwolf 1.6 AND LATER VERSIONS ONLY: Prep the system and sources

        #Install cmake 
        #
        sudo apt install cmake 


        #Just to make sure you're in the right dir
        #
        cd /usr/src/archive/Rpi-scratch/direwolf/direwolf/


        # Review the CMakeLists.txt file and make sure it has the correct version of libgps specified.
        #  If it doesn't, update the the string "libgps23" found in the following line:

        vim CMakeLists.txt
        --
        SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libasound2,libgps23")
        --


        # Create the Cmake build area
        #
        mkdir build
        cd build


        # Time to build Direwolf and you have a choice based on the above dead-airtime workarounds
        # mentioned above:

           # RECOMMENDED - build with ALSA sound support (default)
              #  If you're compiling in ALSA support (only use on RPi4 or new newer Raspberry Pi hardware, 
              #  DWC2 kernel module enabled Pis (read more above), using non-USB audio devices, 
              #  or running Direwolf on X86-based machines
              #
              #NOTE: Yes, these two trailing periods on the command below ARE are required
              #
              cmake ..

              #The above command should complete without any errors

           ----
            or
           ----

           # NOT-RECOMMENDED: OSS (non-ALSA) based audio workaround: 
           #        If you intend to use the legacy OSS sound support for using Direwolf with USB-based sound 
           #        devices on older Raspberry Pis like RPI 3B+ or older hardware (not required X86 based computers):
           #
           cmake -DCMAKE_DISABLE_FIND_PACKAGE_ALSA=TRUE ..


  OPTIONAL: Prepare Stage #2 to compile Direwolf:
  -----------------------------------------------
     You can OPTIONALLY update the APRS object database before compiling

     Direwolf v1.6 and newer ONLY:
     -----------------------------
        # yes, this is a "make" command and not Cmake
        #
        make update-data

     ----
      or 
     ----

     Direwolf 1.5 AND PREVIOUS versions only: 
     ----------------------------------------
        #Just to make sure you're in the right dir
        cd /usr/src/archive/Rpi-scratch/direwolf

        #update all the symbol data, etc (yes, this is a Make command and not Cmake)
        make tocalls-symbols


  ALL Direwolf versions: Compile Direwolf (all Direwolf versions and all TX-dead airtime work arounds):
  ----------------------------------------------------------------------------------------------------
  24.d. Compile Direwolf (all versions or work arounds)

     Let's now compile the Direwolf sources using all available cores on your Raspberry Pi.
     If you are using an Rpi Zero-W, Zero, or v1, use "-j2" instead'

       d.1 For Direwolf 1.6 and later using Cmake (on a 4-core Raspberry Pi4, 3+, or 3):

          make -j8

      ----
       or
      ----

       d.2 For Direwolf 1.6 and later using Cmake (on a 1-core Raspberry Pi2, 1+, 1, Zero-W, or Zero):

          make -j2

      ----
       or
      ----
       
       d.3  For Direwolf 1.5 or previous versions:

          make -f Makefile.linux -j8


  ----------------------------------------------------------------------------------------------------------
  Direwolf Packaging:
  ----------------------------------------------------------------------------------------------------------

  24.e. Package and install Direwolf (all versions and permutations of Direwolf installs mentioned in this chapter)

     e.1 If you already had a /etc/ax25/direwolf.conf file installed, lets make a backup of it just in case.
         If this is a fresh install, you can just skip this step
  
            sudo mkdir /etc/ax25/Old
            sudo cp /etc/ax25/direwolf.conf /etc/ax25/Old/direwolf.conf-`date +%m%d%y`



    e.2  Direwolf 1.5 AND OLDER VERSIONS ONLY

            I recommend to use the checkinstall program to both package Direwolf and install the resulting package
            instead of just using the too-simplistic "make install" approach.  It's not a perfect tool but it works
            well enough:

               NOTE:  The default version of checkinstall included with Raspbian is NOT compatible with Cmake-based 
                      projects such as Direwolf 1.6 per https://github.com/opencv/opencv/issues/8897 .  This issue
                      is fixed in checkinstall Git branch or v1.6.3 or newer but Raspbian doesn't have that version.

           Since you have compiled Direwolf for Raspbian directly and are NOT using the pre-built Raspbian 
           repos, you need to delete the RPM spec file to work around a known bug in the checkinstall program:

              cd /usr/src/archive/Rpi-scratch/direwolf/direwolf/
              rm direwolf.spec

           Next, run the following commands:

               These steps are only required for Direwolf v1.5 installs using the checkinstall tool:
               #
               sudo mkdir -p /usr/share/doc/direwolf/examples
               sudo ln -s /usr/share/doc/direwolf /usr/share/direwolf
               sudo mkdir -p /usr/share/direwolf/pixmaps
               sudo mkdir -p /usr/man/man1

           Ignore any warnings/errors that might be given


    24.f All Direwolf versions: Confirm the real version of Direwolf you just compiled:

         - Direwolf 1.6 and NEWER users:
            
            cd /usr/src/archive/Rpi-scratch/direwolf/direwolf/
            grep -r "direwolf_VERSION_" CMakeLists.txt
        
            As of 10/28/20, it shows the version as "1.6.0" in the very top three lines:
            --
            set(direwolf_VERSION_MAJOR "1")
            set(direwolf_VERSION_MINOR "6")
            set(direwolf_VERSION_PATCH "0")
            set(direwolf_VERSION_SUFFIX "")
            --
            (you can ignore the other lines in this output)

         ----
          or
         ----

         - Direwolf 1.5 and OLDER users:

            grep "VERSION" version.h


         - Direwolf 1.7 Dev branch users:

            If you built the "dev" branch of any Direwolf version, there is one more field to check for:

               grep "Dire Wolf DEVELOPMENT" src/direwolf.c
        
                  As of 8/8/20, it shows:
                  --
                  dw_printf ("Dire Wolf DEVELOPMENT version %d.%d %s (%s)\n", MAJOR_VERSION, MINOR_VERSION, "G", __DATE__);
                  --

              That means this is Direwolf version 1.7 Beta test version "G"


    24.g Let's package up and install the new Direwolf:

              +---------------------------------------------------------------------------------------------------------+
              | INFO: Users coming from Direwolf 1.5 and upgrading to Direwolf v1.6:                                    |
              |                                                                                                         | 
              |    Direwolf 1.6 users:                                                                                  |
              |       Direwolf 1.6 moved to the Cmake system which is incompatible with the checkinstall tool as it     |
              |       currently SEGFAULTS when trying to process the build process:                                     |
              |                                                                                                         |
              |          Makefile:526: recipe for target 'cmake_check_build_system' failed                              |
              |          make: *** [cmake_check_build_system] Segmentation fault                                        |
              |                                                                                                         |
              |    This checkinstall issue was mentioned in https://github.com/opencv/opencv/issues/8897 and has been   |
              |    fixed but I am now recommending to use the native Cmake method of packaging.                         |
              +---------------------------------------------------------------------------------------------------------+


        Pick ONE of the following approaches:
        
          +--------------------------------------------------------------------------------------------------------+
          | NOTE:                                                                                                  |
          |       I know offering multiple options here makes things more confusing but different users might have |
          |       different needs so I give the options here.  Please contact me if you need help understanding    |
          |       and I'm trying to make sure this wording is as strait forward as possible                        |
          +--------------------------------------------------------------------------------------------------------+


           g.2.a  Direwolf 1.6 and Newer release:

                 Run the following command to package and install the newly compiled Direwolf code:

                    cd /usr/src/archive/Rpi-scratch/direwolf/direwolf/build 
                    cpack -G DEB
                    sudo apt install ./direwolf-1.6*.deb 


                 IMPORTANT:   
                 ----------
                 It's recommended to mark the Direwolf package as HOLD so future Raspbian OS updates won't mess with it:

                      sudo apt-mark hold direwolf



                 Next up: File locations: 
                      I choose to put the direwolf.conf file in /etc/ax25 directory to make it a system-wide
                      configuration file.  I personally feel this direwolf.conf file is an infrastructure 
                      level configuration file (just like configuring Ethernet or Wifi interfaces) so this belongs 
                      in /etc somewhere.  If you disagree with my approach and prefer putting this conf file 
                      in say /home/pi, that's fine but make sure you update all the various configuration and 
                      execution scripts to match.

                    # Go ahead and copy over the key config files:

                      sudo cp /usr/share/doc/direwolf/conf/* /etc/ax25/
                      sudo cp /usr/share/doc/direwolf/scripts/* /etc/ax25/


           -----
            or
           -----

           g.2.b Direwolf 1.5 and OLDER releases only:

              1. For users using the standard ALSA support (Rpi 4 or newer board, Fe-Pi sound devices, X86 computers), 
                 I've used the "pkgrelease = 1" to indicate the use of "Standard ALSA support":

                 NOTE:   You must update the version of libgps found above into the details below to match your 
                         distro's included version -- the below example is defaulting to libgps23

                 sudo checkinstall --pkgname direwolf --pkgversion 1.5 --pkgrelease 1 --pkggroup \
                 hamradio --pkgsource https://github.com/wb2osz/direwolf --maintainer \
                 wb2osz@users.noreply.github.com --provides "tnc" --requires libasound2,libgps23 \
                 make install

              -----
               OR
              -----

              2. For users using the OSS support wrapper (Rpi 3+, 3, 2, 1, Zero-W, Zero only), I've used the 
                 "pkgrelease = 2" to indicate the use of OSS support and removed libasound2 as a requirement:

                 NOTE:   You must update the version of libgps to match your distro's version

                 sudo checkinstall --pkgname direwolf --pkgversion 1.5 --pkgrelease 2 --pkggroup \
                 hamradio --pkgsource https://github.com/wb2osz/direwolf --maintainer \
                 wb2osz@users.noreply.github.com --provides "tnc" --requires libgps23 \
                 make install


            The checkinstall program will then prompt you with the following:

              Should I create a default set of package docs?  

                 Type in "Y" and hit enter


              When you see the prompt for "Description for the package:", type in:
                 --
                 DireWolf is an AX25 soundcard TNC, digipeater, APRS server, Igate, APRStt gateway, via serial, tcpkiss, or AGW sockets
                 --


              Validate the display output from checkinstall:
              --
              0 -  Maintainer: [ wb2osz@users.noreply.github.com ]
              1 -  Summary: [ DireWolf is an AX25 soundcard TNC, digipeater, APRS server, Igate, APRStt gateway, via serial, tcpkiss, or AGW sockets ]
              2 -  Name:    [ direwolf ]
              3 -  Version: [ 1.5 ]
              4 -  Release: [ 1 ]
              5 -  License: [ GPL ]
              6 -  Group:   [ hamradio ]
              7 -  Architecture: [ armhf ]
              8 -  Source location: [ https://github.com/wb2osz/direwolf ]
              9 -  Alternate source location: [  ]
              10 - Requires: [ libasound2,libgps23 ]
              11 - Provides: [ tnc ]
              12 - Conflicts: [  ]
              13 - Replaces: [  ]
              --


              If the output from checkinstall looks similar to what you inputted, hit ENTER to begin the packaging and final install


           g.2.c Direwolf v1.5 and checkinstall users only: Copy over an example direwolf.conf file:

                 If this is a new Direwolf install and you want an example direwolf.conf file put in place, 
                 you need to run another command as the file is not automatically packaged in with checkinstall.  
                 Run the following to install a an example direwolf.conf file:

                    sudo make install-conf
                    cd /root
                    sudo mv direwolf.conf sdr.conf telem-m0xer-3.txt telem-*.conf dw-start.sh /etc/ax25/


                 NOTE #1:  File locations: 
                      I choose to put the direwolf.conf file in /etc/ax25 directory to make it a system-wide
                      configuration file.  I personally feel this direwolf.conf file is an infrastructure 
                      level configuration (just like configuring Ethernet or Wifi interfaces) so this belongs 
                      in /etc somewhere.  If you disagree with my approach and prefer putting this conf file 
                      in say /home/pi, that's fine but make sure you update all the various configuration and 
                      execution scripts to match.


                 NOTE #2:  Disk Full errors:
                     If you get a "disk full" error here when checkinstall tries try to install things, it 
                     most likely means either the current file system you're doing your builds on or /tmp
                     became full (out of space).  While it's not technically required, I say you should have 
                     followed the previous section on creating a temporary /tmp mount point by using a local USB SDD/HDD 
                     drive or even a USB pendrive.  An NFS mount works for Direwolf too if you know how to do that.   
 
                     If you cannot setup an external mount, you can try increasing the running Raspbian 
                     "tmpfs" RAM drive size for /tmp (the stock 10MB is not enough).  You can try increasing
                     the /tmp file system up to 100MB.  Do this with the following:
 
                       # Temporary TMP space RAM drive resize
                       # ------------------------------------
                       sudo umount /tmp
                       sudo mount -t tmpfs -o size=104857600,mode=1777 overflow /tmp
  
                     The new Raspberry Pi 4 has versions that include 2GB and even 4GB of RAM.  Those will be
                     far more future proofed in this respect but will also consume more power which might
                     be an issue for some.  Please remember that a Raspberry Pi 4-1G, 3+, 3, or 2u only have 
                     1GB of RAM available.  Raspberry Pi Zero-W, Zero, v1B only have 512MB of RAM and the v1A only 
                     has 256MB.  I do NOT recommend to increase the /tmp file system go over 50% of that available 
                     memory and ONLY do so only temporarily.


                 NOTE #3: checkinstall errors:
                     If you notice that all kinds of strange of spaces are winding up in the output above 
                     (say the "name" field) or 1%{?dist} in the release field, this means you didn't rename the 
                     spec file as mentioned above!  Rename the .spec file and try again           


                 NOTE #4:  Mentioned already above but if you get an errors like:

                        install: cannot create directory /usr/share/direwolf: No such file or directory

                     then this means you probably didn't follow the section above as well as download 
                     and install the Makefile patch applied above.  If you ran that above patch file 
                     or you did and it didn't work for whatever reason, you can alternatively run the 
                     following commands and then try the checkconfig command again.  (I'm not sure why 
                     that patch doesn't 100% work but it doesn't hurt to run these commands regardless):

                        sudo mkdir /usr/share/doc/direwolf
                        sudo ln -s /usr/share/doc/direwolf /usr/share/direwolf
                        sudo mkdir -p /usr/share/doc/direwolf/examples
                        sudo mkdir -p /usr/man/man1
   
                     Now try the "checkinstall" program again as stated above


                 If everything went well, the checkconfig program will automatically create and install the 
                 resulting .deb package for you.  It will also save a copy of the built .deb package in the 
                 /usr/src/archive/Rpi-scratch/direwolf/direwolf-1.5 directory.  

                 If you had already installed a previous version of Direwolf, check that the /etc/ax25/direwolf.conf 
                 file still contains all your expected changes and wasn't reset to defaults.  If it was reset, 
                 you can restore the previous backup config file that was put in /etc/ax25/Old.


           h.  All versions of Direwolf

                 Now that you've been able to create a Debian package of Direwolf, you can copy this build .deb package 
                 to other Raspberry Pis and install it on different Raspberry Pi's assuming those other Rpis are:

                    - Running the same CPU type (RPi v0 and v1's CPU is different from Rpi v2/3/4)
                    - Running the same OS version of Raspbian (Buster, Stretch, Jessie, Wheezy)
                    - You've also installed the other required packages for Direwolf on those systems


                 To install that deb package once it's copied to that other Rpi, you would use the following 
                 command:

                   NOTE:   The example configuration file aren't included in the checkinstall based deb package
                           so those will have to be copied over manually into /etc/ax25/


                   #To do the install on to other Rpis once the .deb package is copied over to them:

                      sudo dpkg --install direwolf_1.6-1_armhf.deb
                      sudo cp /usr/share/doc/direwolf/conf/* /etc/ax25/
                      sudo cp /usr/share/doc/direwolf/scripts/* /etc/ax25/

24.i. Configuring Direwolf


To configure Direwolf, edit the /etc/ax25/direwolf.conf file and set the following 
parameters for your specific needs.  This guide specifically ONLY enables basic KISS
TNC functionality to the Linux AX.25 protocol stack.  Direwolf can do a lot more
for APRS uses internally but that's beyond the scope of this document.  For additional 
parameters, please read:

   - General setup: PDF found in /usr/share/doc/direwolf/User-Guide.pdf

   - APRS specific setup: Raspberry-Pi-APRS.pdf and Successful-APRS-IGate-Operation.pdf
   

Anyway, let's configure Direwolf:

      Change the following line to reflect the correct sound device for your computer.  
      We have a few choices here so lets work our way through it:

      sudo vi /etc/ax25/direwolf.conf


      Input / Output sound device :: this is an ALSA device name.  Not PulseAudio or 
                                     PortAudio name 

         - ALSA support:
           If you're using Direwolf with a Fe-pi based sound device, simply enter in the 
           matching found sound device as shown from the "aplay -l" command.  In this 
           example, I've left the Raspberry Pi's built-in soundcard (playback only) still
           operational and make the Fe-Pi seen as the second available sound device.  Remove
           the "#" in front of the ADVICE line and make it look like:

              ADEVICE  plughw:1,0

          +----------------------------------------------------------------------------------------+
          | Direwolf "dead air" workaround support:                                                |
          +----------------------------------------------------------------------------------------+
          | Some versions of the Raspberry Pi OS with specific versions of the Raspberry Pi has    |
          | a known issue of keying up your radio and just WAITING some period of time before      |
          | sending the modem tones.  This section talks to several options to address this issue. |
          |                                                                                        |
          |                                      ------------                                      |
          |                                                                                        |
          | - RECOMMENDED: If you're using a USB based sound device on an older Raspberry Pi model |
          |      older than an RPi4 aka a RPi 3B+, 3, 2, Zero-W, Zero, or 1 SBCs, it's recommended |
          |      to try the use the new "DWC2" USB overlay fix (see above for more details).       |
          |                                                                                        |
          |                                                                                        |
          |   LESS RECOMMENDED: If the DWC2 approach doesn't work for your needs (say breaks other |
          |      things), you can try to use the "ALSA OSS" wrapper" work around. This still helps |
          |      then audio delay or "TX audio silence" bug.                                       |
          |                                                                                        |
          |   - To use this work around, you must re-compile direwolf where ALSA based support is  |
          |     DISABLED.  If you didn't recompile Direwolf, this won't work                       |
          |                                                                                        |
          |      - Next, run this command to install a required module:                            |
          |                                                                                        |
          |           sudo apt-get install alsa-oss                                                |
          |                                                                                        |
          |      - NOTE about PulseAudio's "padsp":                                                |
          |             There is also the padsp tool which is apart of the pulseaudio-utils        | 
          |               package for OSS emulation for PulseAudio.  I am not describing this      | 
          |               tool here as PulseAudio for Raspberry OS was added mid-stream for the    |
          |               Buster release and it also requires the Xwindows GUI to be running       |
          |               where as the ALSA emulation works fine for the command line              |
          |                                                                                        |
          |   - Next, you need to create a virtual ALSA device. In this example, I've left the     |
          |     built-in Raspberry Pi soundcard operational and use an external Syba USB sound     |
          |     device as the second available sound device:                                       |
          |                                                                                        |
          |      - Create the .asoundrc file in the home directory of the username that will be    |
          |        running Direwolf such as "pi" or "root". Add the following lines where you put  |
          |        in the matching ALSA sound device as found via running "aplay -l" tool          |
          |                                                                                        |
          |           #example for direwolf being run as the "root" user:                          |
          |           #                                                                            |
          |           sudo vim /root/.asoundrc                                                     |
          |           --                                                                           |
          |           pcm.dsp0 {      type plug      slave.pcm "hw:2,0" }                          |
          |           --                                                                           |
          |                                                                                        |
          |   - Next, edit the /etc/ax25/direwolf.conf file, remove the "#" in front of the        |
          |     ADVICE line and make it look like:                                                 |
          |                                                                                        |
          |      ADEVICE  /dev/dsp0                                                                |
          |                                                                                        |
          |                                                                                        |
          |   - Finally, when you start Direwolf, you need to start it with the following:         |
          |                                                                                        |
          |        aoss direwolf <various command line options>                              |
          |                                                                                        |
          |     See more examples in the next sub-section.                                         |
          +----------------------------------------------------------------------------------------+
        

      Next change the CALLSIGN line:

              MYCALL N0CALL
      to
              MYCALL <enter in your callsign here with SSID - I'm using KI6ZHD-6>
      --

      change the line (this mostly documents the default) but:

         MODEM 1200 - for AFSK 1200 baud packet
         E+         - the default AFSK1200 modem for lower power CPUs
         /3         - divide 48000 sound card sampling rate by three (lowers CPU load)

             MODEM 1200
      to
             MODEM 1200 E+ /3

      --
      change the PTT line (for my specifically chosen GPIO pin) : You must specify the BROADCOM 
      signally line and not the physical Raspberry Pi pin:
             #PTT GPIO 25
      to
             PTT GPIO 26
      --
      optionally consider to enable a GPIO pin for the DCD signal
             #DCD GPIO 25
      to
             DCD GPIO 13
      --

      Under the "PTT" or "DCD" GPIO line, add the following parameters.  These 
      settings impact the key-up and key-down speed of your specific radio.  A setting 
      of 40 means 400ms which is VERY conservative (most radios are like 100-150ms).  
      The 5 sets 50ms of a post audio transmission delay as well.  You ideally want these 
      values to be as fast as possible but this will require tuning on your part, most likely
      using a service monitor or oscilloscope:

                 TXDELAY 40
                 TXTAIL 5

        NOTE: If the TXTAIL setting is too short, I've seen where an AX.25 
              connection cannot gracefully disconnect via issuing the "b" (bye) command
              on a remote KPC3 TNC.  I had to change the TXTAIL variable from 10ms to 
              50ms to get things to work properly!

              Please see the following for more details on tuning your various RF levels 
              and timing:
              
                 http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html#6d.tuning-direwolf

      --

      Unless you plan on using the TCP KISS (not the same as "serial KISS") 
      feature or the AGW/PE API support  (Direwolf does *not* support connected 
      sessions for things like Outpost, etc), then plan on disabling both of these:

             AGWPORT 8000
             KISSPORT 8001
      to
             AGWPORT 0
             KISSPORT 0
      --

      Depending on your use of your packet station, you might want to enable the
      FIX_BITS section to be either APRS centric or classic AX.25 "packet" centric error 
      prediction:

        - The first parameters of 1 or 2 is the number of bits Direwolf will try to 
          correct

        - the second parameter of the FIX_BITS option setting to "AX25" essentially disables 
          the APRS-centric hinting within Direwolf.  This is useful if you're a classic 
          "connected" packet user on a classic packet frequency and not on an APRS frequency.
          Please see the Direwolf UserGuide for more detail:

            FIX_BITS 1 AX25

     --

     GPS locations beacon for using on APRS:

        It's a good idea that your packet system beacons it's location on the chosen frequency
        and if you plan to IGATE from APRS-IS to RF, it's required.  When setting the location, 
        consider if your station is NOT expected to move or not.  Why?  I encourage you to:

       a. Configure a static location vs using fixed GPS coordinates.  Why? Avoid GPS noise which 
          might shift your location around from position to position.  This is VERY common when
          people use cheap GPSes or have GPS receivers inside their homes.  This can create a 
          LOT of useless APRS traffic on frequency.

          Direwolf supports both decimal degrees (-71.34717) format using the "." character (and 
          negative values) as well as the degrees.minutes.seconds (71^20.83W) format using the "^" 
          character (and the E/W indicator)

       b. I'd recommend to only beacon once an hour if your station is always up and available.
          Direwolf's PBEACON or Position Beacon has the following syntax:

           delay         - delays the initial transmission of the packet 15 seconds after direwolf startup
           every         - beacons every 60 minutes
           sentto        - if NOT specified, beacon will go out on ALL interfaces (RF and Igate)
           messaging     - set to 1 only if your station can receive and respond to APRS messages (default is 0)
           symbol        - using the house symbol per http://www.aprs.org/symbols/symbols-new.txt
           lat / long    - position
           power         - 5watts
           height (HAAT) - 20ft off the ground
           gain          - 7dbi gain on 20m into a co-linear vertical antenna

              power / height / gain of transmitter in increments of the following (you can't put in any other values) 

           Looking at the table at http://aprsisce.wikidot.com/phg , you can see what to best match your 
           setup for a PHG circle:

               phgd Code:      0    1    2     3     4     5     6     7     8      9 Units
               Power:          0    1    4     9    16    25    36    49    64     81 watts
               Height:        10   20   40    80   160   320   640  1280  2560   5120 feet
               Gain:           0    1    2     3     4     5     6     7     8      9 dB
               Directivity: omni   45   90   135   180   225   270   315   360 	  n/a degrees
 
           For my home setup, I'm using the following.  You need to find and put in your own location:

              PBEACON delay=00:15 every=60 SYMBOL=/- lat=37^20.00N lon=121^00.00W power=4 height=20 gain=6 comment="was KI6ZHD Change me, CA" via=WIDE1-1


       c. As a quick test for Direwolf's PTT and transmit functions, create the following 
          APRS Object beacon that transmits every minute:

          #Create a test object beacon that will be transmitted every 60 seconds that will be located north of Boston, MA in the town of Middleton
          #  Should show up here if your Object is heard by a local Igate - https://aprs.fi/#!addr=FN42MO08AA
          OBEACON delay=0:01 every=1 overlay=S symbol="digi" lat=42^37.00N long=071^00.00W power=50 height=20 gain=4 OBJNAME=TESTBCN comment="test beacon" via=WIDE1-1


       +---------------------------------------------------------+
       | Optional:                                               |
       |           Enabling APRS IGate functionality in Direwolf |
       +---------------------------------------------------------+

       d. APRS Igate: 

          If you intend on setting up an APRS Igate, below are the settings to create a receive-only RF to 
          APRS-IS Igate for general packets.  This also includes gating APRS-IS messages to RF for APRS 
          messages.  In the /etc/ax25/direwolf.conf file, find the following commented lines. Uncomment 
          them and change them to reflect your callsign, etc

          NOTE:  All of these setting assume your Raspberry Pi has Internet access.  If it doesn't have 
                 Internet access, there is no reason to setup Igating.  Direwolf should work just fine 
                 for local uses

          NOTE2: The APRS-IS system MUST have your station's location as set above in the "PBEACON" 
                 (Position Beacon) entry above.  If it's not set (and pretty accurate), things either 
                 won't work at all or you'll get data from APRS-IS that isn't appropriate for your area

          --
          # Enable Igate connectivity - connects go on TCP port 14580
          #  If you are in other locations in the world, choose a closer APRS-IS pool listed at http://aprsisce.wikidot.com/port-aprs-is
          #
          IGSERVER noam.aprs2.net

          # Specify your CALLSIGN, SSID, and APRS passcode
          # Contact KI6ZHD if you can't figure out how to generate a APRS passcode for your callsign
          #
          IGLOGIN N0CALL-6 <your callsign passcode here>

          #Enable Igate to RF transmissions on Direwolf "channel 0" being sent to the local WIDE1-1 
          #
          IGTXVIA 0 WIDE1-1

          #Direwolf v1.4 defaults with an IGFILTER setting equivalent to having the APRS-IS system
          # sending you APRS "Item" objects within 30km of your location with "IGFILTER i/30".
          #
          # You might want to apply a more custom filter for what packets will be received from the 
          # APRS-IS server.  Read about filters here:  http://www.aprs-is.net/javaprsfilter.aspx
          # In this example, I only want to receive APRS messages that are intended for stations
          # within 10km of my station's location
          #
          IGFILTER m/10

          #In addition to the APRS-IS system only sending you data you want, sometimes it will
          # still send too much or unexpected data.  It's recommend to also setup a CLIENT side
          # APRS filter within Direwolf.  In this example, we will transmit only APRS "messages" 
          # Direwolf on channel 0
          #
          FILTER IG 0 t/m

          # To avoid sending out too much data which might overheat your radio, discharge your battery
          # too quickly, etc, I recommend to enable the packet rate limiter.  This example will only
          # allow 6 packets in 1 minute or 10 packets within 5 minutes.  Any packets that will be
          # dropped due to the rate limit is logged.  If you want to allow more packets, increase
          # these specific configuration items to suit your needs
          #
          IGTXLIMIT 6 10
          --

24.j. Testing Direwolf


Test out Direwolf in it's stand alone more and enable all it's settings to better 
tune it's levels

      #Other options you might be interested in
      #-q d : suppress APRS decodes
      #-q h : suppress heard levels
      #-t 0 : disable colors
      #-d o : show output for asserting DCD and PTT lines
      #-a n : print out number of samples for N sections
      
      RECOMMENDED: For normal ALSA users:
         sudo direwolf -t 0 -d o -a 100 -c /etc/ax25/direwolf.conf


      Older RPI users attempting to use the non-recommenced OSS wrapper approach:
      -----------------------------------------------------------
      NOT RECOMMENDED: For ALSA-OSS wrapper users on older Rpi hardware with USB sound devices:

         sudo aoss direwolf -t 0 -d o -a 100 -c /etc/ax25/direwolf.conf

             If you get an error of:
     
               Can't read from audio device: Input/output error
               Terminating after audio input failure.

             Confirm you created the required .asoundrc file in the home directory of the username
             you're running Direwolf as (see the above sub-section).  


    HINT:  If you started Direwolf with it's coloring enabled and now all your 
           console text is blinking, you can use the command "tput reset" to 
           clear things out.  


  When Direwolf is running, there are two key things to monitor

    1. The sampling rate matches the configured rate.  If it deviates beyond the 
       expected rate too much, things won't work at all.  

          ADEVICE0: Sample rate approx. 44.1 k, 0 errors, receive audio level CH0 92

    2. Direwolf reported audio levels is roughly around a level of 50 on average 
       for various heard remote stations.  For example, here is one packet my station heard:

         K6FB-1 audio level = 57(26/14)   [NONE]   ___||||||

           How to read this above line:

               - K6FB-1 is the station heard

               - "57" is the heard audio level of this packet 
                      : goal here is to have all station be around a level of "50"

               - "26" is the heard audio level of this packet's "MARK" tone 
                      : ideally should be the same as the "SPACE" tone.  Major differences
                      : in these numbers indicate "twist".  Direwolf deals with this well but
                      : many legacy TNCs cannot (see Febo site to understand more)
               
               - "14" is the heard audio level of this packet's "SPACE" tone 
                      : ideally should be the same as the "MARK" tone.  Major differences
                      : in these numbers indicate "twist".  Direwolf deals with this well but
                      : many legacy TNCs cannot (see Febo site to understand more)
               

    3. With the test beacon running every minute, you should see a log item like the following
       (using your configured callsign and SSID):

          [0L] KI6ZHD-6>APDW14,WIDE1-1:;TESTBCN  *111111z4237.00NS07100.00W#PHG7140test beacon

       If you don't see your radio transmit every minute, you might have a wiring issue.  To 
       test things a bit more, disconnect the PTT GPIO pin from the Raspberry Pi and connect
       an LED in series with a 1k resistor:

          - connect to cathode of LED (short lead / smaller metal inside LED) to GPIO pin
          - connect to anode of LED (long lead / larger metal inside LED) to GND pin

       You should see the LED light up every 60 seconds.  If you don't, recheck your 
       configuration until you get things working.

    4. Once things are working, edit your direwolf.conf file and disable the test OBEACON
       object line

24.k. Testing APRS-IS filters with TELNET


Interactive APRS-IS filter testing over the Internet:  

   OPTIONAL: 
   ---------
   Configuring and tuning appropriate APRS-IS filters to:

      - Ensure you're not gating too much data

      - Not congesting the local APRS RF frequency, etc. 

   is NOT trivial nor simple.  It really takes a lot of experimentation until you get the hang of 
   it.  Fortunately, you can do interactive filter testing without using Direwolf simply with the 
   "telnet" program.  For example, if you wanted to test receive APRS-IS APRS messages within 5km 
   of your location.  To test this, you'd run the following commands:

      #You must substitute in your specific callsign, SSID, APRS passcode, and decimal based 
      #location just like you configured above in your direwolf.conf file:

      NOTE:  The "#" character in front of the filter lines are REQUIRED for them to be accepted
      by the APRS-IS server
      --
      telnet rotate.aprs.net 14580
      user n0call-6 pass <your callsign passcode here> vers TestSoftware 1.0
      n0call-6>APDW14,TCPIP:=3710.62N/12059.99W-
      #filter m/5
      #filter t/m
      --

25. Configure the AX.25 system


Now that you have the Direwolf TNC running, let's also enable Linux's native AX.25 stack for
advanced packet functionality.  This is NOT required if you only want to do APRS or AGW-based 
TCP/IP connectivity within Direwolf but it does allow you to perform all kinds of advanced 
packet functions as well as play with classic AX.25 packet.  Interested? Ok, let's set it up:

   a. cd /etc/ax25

   b. Edit the /etc/ax25/axports file by running the following commands and change it 
      to reflect your own settings:  

      sudo cp axports axports.orig

      sudo vi axports
      --
      - Comment out or delete all the port definitions except "vhfdrop" at the bottom of the file

      - On the "vhfdrop" line, the next field is the callsign and SSID.  I'm using "KI6ZHD-6" 
        as I already have other packet stations on KI6ZHD (aka KI6ZHD-0), KI6ZHD-1, KI6ZHD-2, etc.
        This callsign+ssid MUST be unique on that connected radio's frequency.

      - The next field is the Data Terminal Equipment (DTE) speed which is the speed between
        the computer and the TNC.  This is generally set to be a FASTER rate than your Data 
        Communications Equipment (DCE) speed like 1200bps packet.  I would recommend to set this
        to "19200" which means 19200bps though with Direwolf, it's totally meaningless

      - The next field is the PACLEN (packet length) or maximum transmission unit (MTU).
        Increasing this value allows more data will flow per packet (with risk).  Depending on 
        the quality/power of your radio, antenna, other nearby stations you wish to communicate 
        with.  Larger PACLEN settings will provide higher performance assuming you don't have 
        many retries.  If you have a weak link and thus more retries, larger values will slow 
        things down.  Changing this value is a compromise that you must find.  The value of 128
        is a reasonable default and the maximum value is 255.

         NOTE:  If you plan on running Netrom, the maximum PACLEN you can use is 236

      - The next field is the WINDOW field which is related to the PACLEN field.  This value 
        controls the number of packets your station can send until it waits for an acknowledgment
        that your packets were received ok.  The more packets sent in a window, the faster the
        throughput BUT there is a risk.  With AX.25 v2.1, if one of those packets is corrupted,
        the entire window worth of packets will be resent!  That can REALLY slow things down if
        you have many retries.  The default of 2 is fairly conservative and I generally recommend
        a value of 4 if your links are pretty strong and reliable.

      - The last field is a comment field.  You can put anything in here that helps identify 
        this AX.25 device

      The line should look like the following for me (make the required changes for your setup):

         vhfdrop KI6ZHD-6 19200 236 4 TNC setup on 145.050Mhz
      --


   c. Download my two example AX.25 startup scripts

      As part of my setup, I have several AX.25 startup and shutdown scripts available.
      I recommend that you look them over and make them your own to fit your needs.

      cd /tmp
      wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/ax25/ax25-up.new
      wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/ax25/ax25-up.new2
      wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/ax25/ax25-down
      chmod 744 ax25-*
      sudo mv ax25-* /etc/ax25


   d. Install some required Raspbian packages that are needed for these scripts

      #Need killall and ifconfig  (if not already installed)
      sudo apt-get install psmisc net-tools


   e. You will need to do minor edits the ax25-up.new file to suit your needs but 
      the key parameters to change are:

        cd /etc/ax25
        sudo vim ax25-up.new
        --
        #Change these two key parameters to match that of your direwolf.conf
        #  Please note the ADDITIONAL zero here for each parameter as the two files
        #  use different units
        TXDELAY=400
        TXTAIL=50

      +---------------------------------------------------------------------------------+
      | IMPORTANT:                                                                      |
      |                                                                                 |
      | You'll recognize that these are the same items as configured in Direwolf.conf.  |
      | Please read the Direwolf tuning section above and make sure THESE settings here |
      | align with the settings you put in the direwolf.conf file                       |
      +---------------------------------------------------------------------------------+

      Please understand that the AX.25 parameters configured in the ax25-up.new script 
      will OVERRIDE the parameters originally configured in /etc/ax25/direwolf.conf.  
      It's recommended to have the TXDELAY and TXTAIL parameters in both files aligned
      for clarity sake.


26. Bring up the AX.25 system with a script


Assuming that everything is configured from all the steps above, start up the
Linux AX.25 stack with the following command:

  sudo /etc/ax25/ax25-up.new


That command should look something like the following and if you have the speaker
still connected to the configured sound card, you should eventually hear a packet
burst!  You should see this on your screen as it starts up as well as in
/var/log/packet.log

   --
   ax25-up.new starting up

   Sun 30 Jun 2019 04:39:26 PM PDT
   axudp port not enabled in /etc/ax25/axports.. skipping
   TNC Type: direwolf
   Restoring audio levels on soundcard
   Starting direwolf (OSS support)A
   Dire Wolf DEVELOPMENT version 1.6 C (Jul 14 2019)
   Includes optional support for:  gpsd
   Reading config file /etc/ax25/direwolf.conf
   Audio device for both receive and transmit: /dev/dsp0  (channel 0)
   Channel 0: 1200 baud, AFSK 1200 & 2200 Hz, E+, 44100 sample rate / 3.
   Disabled AGW network client port.
   Disabled KISS network client port.
   Virtual KISS TNC is available on /dev/pts/0
   Created symlink /tmp/kisstnc -> /dev/pts/0

   Installing one KISS connection on PTY port /tmp/kisstnc
   PTS0 device: /dev/pts/2
   Setting advanced Linux AX25 stack settings - part 1
      Values only shown in /var/log/packet.log file via Direwolf's STDOUT)
   KISS protocol set TXDELAY = 40 (*10mS units = 400 mS), port 0
   KISS protocol set TXtail = 5 (*10mS units = 50 mS), port 0
   KISS protocol set Persistence = 63, port 0
   KISS protocol set SlotTime = 10 (*10mS units = 100 mS), port 0
   KISS protocol set FullDuplex = 0, port 0
   Displaying current system kissparms
   --
   AX25 protocol mode (0=Norm* 1=Extd)                : 0
   AX25 backoff type (0=Linear 1=Expon*)              : 1
   AX25 connect mode (0=none 1=network 2=all*)        : 2
   AX25 Extd window size (num of unacked packets 32*) : 32
   AX25 idle timeout (idle session timeout in M 20*)  : 0
   AX25 AXIP mode (0=Datagram* 1=VirtConnection)      : 0
   AX25 max packet size (256*)                        : 256
   AX25 max packet retry count (10*)                  : 10
   AX25 protcol version (DAMA Slave)                  : 0
   AX25 STD window size (num of unacked packets 2* )  : 2
   AX25 T1 timer (unacked packet retry 10000mS*)      : 10000
   AX25 T2 timer (wait for 2nd RX packet 3000mS*)     : 3000
   AX25 T3 timer (link still up check 300000mS*)      : 300000

   Port vhfdrop attached to ax0
   Listen started and displaying on tty8

   Listen started and logging to /var/log/ax25-listen.log
   Preparing for ax25-up.new2 - sleep for 4 seconds
   -----------------------
   ax25-up.new2 starting up

   Sun 30 Jun 2019 04:39:40 PM PDT

   beacon started

   mheardd Started

   ax25-up.new2 done
   --


You can also see the same as well as some addition details from Direwolf by looking 
in the /var/log/packet.log file


To manually shutdown your packet station, run the command:

   sudo /etc/ax25/ax25-down
   --
   Shutting down Linpac
   linpac: no process found
   nodesave: no NET/ROM port data configured
   N/R routes saved
   Ending beacon - 29259
   Ending mheardd - 29261
   Ending listen - 29245 29244
   Stopping Kissattach
   spattach: no process found
   Detach Ax/Nr/Sp Devices
   ls:: ERROR while getting interface flags: No such device
    ls: stopped
   Stopping mkiss
   mkiss: no process found
   Stopping Direwolf
   Ax25 Stopped
   --

26.a. Linux AX.25 stack testing:


Ok.. we're getting close to having a fully functional packet setup.  Now grab another amateur radio and 
put it on the same frequency as your Direwolf packet radio frequency.  Now do the following:

   a. On the monitoring HT, key up the radio and verbally call out your callsign to make
      things legal (at least here in the US for Part 97 rules)

   b. Manually push the PTT button on your *Direwolf radio* and listen to the empty FM modulation 
      on this second radio.  There should NOT be --any-- hiss, whine, or any other noise.  This 
      should have already been tested in the previous section but just in case you skipped that 
      section, you need do this test now.  If there is any issues with your transmitted signal, 
      you need to resolve that now with better cable routing, cabling (shielded), the use of the
      correct mix RFI toroids, etc. If you don't resolve this, your transmissions won't be decoded 
      very well or at all!

   IMPORTANT:

   c. Type in the following command (assuming your /etc/ax25/axports device name is
      "vhfdrop") while holding down the "monitor" button (disables squelch on your monitoring 
      HT:  

         beacon -s vhfdrop "this is a test-this is a test-this is a test-this is a test-"

      At first, you will hear static noise all the time which is normal since you're using the 
      "monitor" button which disables the squelch feature on your radio.  This usually also 
      temporarily disables any RX power saving settings on your HT.   

      You should soon hear a longer AFSK1200bps AX.25 packet with an audio level that should 
      be not too loud, be 100% clear, non-distorted / no clipping qualities, with no background 
      noise, whine, or clicking sounds.  If you heard any of these artifacts, I again recommend 
      to read this excellent URL on how to tune your TNC's transmission levels to ensure you have 
      a solid signal:

         https://www.febo.com/packet/layer-one/transmit.html


   d. Next, try making a fictitious AX.25 connected session:

         call vhfdrop n0call

      You should see the following text in the terminal window:
         --
         GW4PTS AX.25 Connect 2.0.1
         Trying...
         --

      You should have heard AFSK1200 packet sounds trying to reach that remote, fictitious 
      callsign.  If you did hear the audio, type in control-c to exit.  If you instead see 
      "call: no AX.25 port data configured", you probably made a mistake in the 
      /etc/ax25/axports file.  Make sure that your "vhfdrop" line in that file is the VERY 
      last line in the file and all preceding lines start with a # character.


   e. Next, see if you can hear some AX.25 traffic.  Assuming say the local APRS frequency
      is busy in your area (144.390Mhz here in the US), QSY your Direwolf connected radio to 
      that frequency and issue the command:

         sudo listen -arp vhfdrop

      If your radio is working properly and have your audio levels set right, you should see 
      all kinds of traffic such as:
      --
      vhfdrop: fm KJ6IX-9 to S8USPQ via ALDER* N6ZX-3* WIDE2* ctl UI pid=F0(Text) len 13
      `/H3l"1R/"D7}
      vhfdrop: fm KE6AFE to APS250 via WR6ABD* NCA1* ctl UIv pid=F0(Text) len 64
      @301626z3658.93N/12200.92W_169/000g000t059r000p000P000h83b10154
      vhfdrop: fm K6ODX to APOT30 via WA6YLB-7* N6ZX-3* WIDE2* ctl UI pid=F0(Text) len 50
      /162640h3637.13N/11936.63W>000/050/A=000319ENROUTE
      vhfdrop: fm K6TJS to APU25N via WR6ABD* ctl UI pid=F0(Text) len 74
      @301626z3703.50N/12048.48W_329/008g017t067r000P000p000h74b10093/ {UIV32N}
      --

      Type in control-c to exit the listen program


27. Enable log rotation for packet logs


Now that your system has a working packet radio system and we're going to enable it upon
every boot, you'll need to rotate the generate logs so they don't fill the RAM drive:


# add log rotation for ax25-listen log
sudo vi /etc/logrotate.d/ax25-listen
--
/var/log/ax25-listen.log {
	rotate 3
	daily
	missingok
	notifempty
        copytruncate
        size 10M
	compress
	compresscmd /bin/bzip2
	uncompresscmd /bin/bunzip2
	compressoptions -9
	compressext .bz2
}
--

# add log rotation for the packet.log that records the start/stop and direwolf
sudo vi /etc/logrotate.d/packet
--
/var/log/packet.log {
	rotate 3
	daily
	missingok
	notifempty
        copytruncate
        size 10M
	compress
	compresscmd /bin/bzip2
	uncompresscmd /bin/bunzip2
	compressoptions -9
	compressext .bz2
}
--

NOTE: It's important to use the "copytruncate" command for some logs as these 
      files are getting appended from various Unix redirects and NOT syslog.  
      Since you cannot send say SIGUSR1 to re-evaluate their new file handle 
      for the newly created file

NOTE2: Once these two files are added, the logrotate system will automatically
       start using them the next time the cron system runs logrotate


28. Install Linpac and ax25mail-utils for Connected and UnConnected packet QSOs and PBBS

   ------------------------
   OPTIONAL for APRS users:  
   ------------------------

   Linpac is a classic packet program for Linux that runs in an Ncurses terminal window 
   which is similar to the Pakkratt or PKGold programs for DOS.  It supports multiple 
   simultaneous keyboard to keyboard chats, sending unproto or UI packets through digi 
   paths, sending and receiving packet messages, etc.  You can learn more about it here:

      https://sourceforge.net/projects/linpac/


Ok, interested?  Good!  There is two ways to install Linpac today:

   +---------------------------------------------------------------------------------------+
   | NOTE: Significant issue with AX.25 and Raspbian Buster / Stretch (mentioned above)    |
   |                                                                                       |
   |    I have confirmed that with Raspbian Stretch, there is some sort of conflict with   |
   |    it's newly enabled predictable network interface names.  What are those?  If you   |
   |    run the command "ifconfig" or "ip addr", you will no longer see Ethernet           |
   |    interfaces with names like "eth0", "eth1", etc.   Instead, you'll see names like   |
   |    "enxb827eb5f05".  For known reasons, Raspbian allowed very long interface names    |
   |    and in the AX.25's sa_data kernel data structure, both the stock Raspbian AX.25    |
   |    .debs and the 3rd party VE7FET ax.25 debs will give errors like the following when |
   |    ANY network interface name is longer than 13 characters:                           |
   |                                                                                       |
   |       SIOCGIFHWADDR: No such device                                                   |
   |                                                                                       |
   |    ANY AX.25 programs like beacon or Linpac will fail.  Linpac will crash with:       |
   |                                                                                       |
   |       /usr/bin/linpac: line 181:  9811 Segmentation fault   $PKG_BINDIR/linpac $*     |
   |                                                                                       |
   |    Fortunately, if you disable predictable network interface names, things work fine. |
   |    To do this, do the following steps:                                                |
   |                                                                                       |
   |       sudo vi /boot/cmdline.txt                                                       |
   |       --                                                                              |
   |       #append the following to the end of the one line in this file                   |
   |       net.ifnames=0 biosdevname=0                                                     | 
   |       --                                                                              |
   |                                                                                       |
   |    Reboot your Raspberry Pi and things will work from there on out. Btw, if Linpac    |
   |    crashed on you,  your terminal might be screwed up and not working properly.       |
   |    To fix that, run the commands:                                                     |
   |                                                                                       |
   |       stty sane                                                                       |
   |       rm -f rm /var/lock/LinPac.0                                                     |
   +---------------------------------------------------------------------------------------+


   +---------------------------------------------------------------------------------------+
   | Critical / Mandatory NOTE:                                                            |
   |                                                                                       |
   |   As of Raspbian 9 / Debian 9 Stretch, this distribution has upgraded the version     |
   |   of the GCC compiler that BREAKS Linpac with versions LESS than 0.25.  You will see  |
   |   the issue where you'll start Linpac and get "Segmentation faults" at various points |
   |   in the program.  This issue is being tracked here:                                  |
   |                                                                                       |
   |      https://sourceforge.net/p/linpac/discussion/54078/thread/6b0c20d6/?limit=50#17de |
   |                                                                                       |
   |   As such, it's MANDATORY that you upgrade to at LEAST Linpac version 0.25 or apply   |
   |   at least the  patch in the URL above.                                               |
   +---------------------------------------------------------------------------------------+

   #NOTE #3:  There might be issues with these binaries looking for the program "axlisten"
   #          instead of "listen".  This is due to the fact that Debian changed the name of these 
   #          ax25 programs but the AX.25 repo this document builds from did NOT change
   #          their name.  I will research this where the fix could be simple symlinks
   #          to a recommendation of removing the VE7FET AX.25 programs and installing
   #          Raspbian stock ax.25 programs.  TBD

28a. Compile and Install Ax25mail-utils


   This package is used by Linpac to exchange BBS messages with nearby FBB BBSes.  This package
   is technically not required for Linpac to function but I would recommend to install it to
   have a complete setup.

     +-----------------------------------------------------------------------------------------------+
     | NOTE:                                                                                         |
     |     The BBS message relaying functionality of Linpac and ax25mail-utils is known to           |
     |     be buggy.  It can work in some circumstances ONLY with remote FBB BBSes or KPC3 PBBSes    |
     |     but you shouldn't get your hopes up with this functionality with Linpac today.            |
     +-----------------------------------------------------------------------------------------------+



   - ** RECOMMENDED **: Building Linpac and ax25mail-utils from sources:

     It's best to build Linpac from sources to get the newest fixes.  Below are the needed 
     steps on how to build the newest version of ax25mail-utils and Linpac from sources.   If you 
     choose do install Linpac binaries via the Raspbian repos mentioned above, please skip this 
     build section and go to the configure section below.


     Assuming a USB HD is mounted per the previous section

     Get the newest ax25mail-utils sources  - 0.13 is current  as of 6/30/19
        https://sourceforge.net/projects/ax25mail/files/ax25mail-utils/

      cd /usr/src/archive/Rpi-scratch
      mkdir Ax25mail-utils
      cd Ax25mail-utils
      wget http://sourceforge.net/projects/ax25mail/files/ax25mail-utils/0.13/ax25mail-utils-0.13.tar.gz


   Ok, let's build and install the ax25mail-utils program

      tar xzvf ax25mail-utils-0.13.tar.gz
      cd ax25mail-utils-0.13

      ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var

      #Compile the sources using all four cores on your RPi 4, 3+, 3
      #  If you have an Rpi Zero-W, Zero, or v1, use "-j2" instead
      make -j8

   Now let's package and install it:

      sudo checkinstall --pkgname ax25mail-utils --pkgversion 0.13 --pkgrelease 1 --pkggroup \
      hamradio --pkgsource https://sourceforge.net/projects/ax25mail --maintainer \
      ki6zhdattrinityos.com --provides ax25mail-utils --requires ax25-tools,perl \
      make install

   Follow the checkinstall prompts:

          Should I create a default set of package docs?  

             Type in "Y" and hit enter

          Description for the package: 
          --
          A set of utilities for packet radio mail exchange with the BBS. For use with the Linpac terminal programs as well as others
          --

   Validate the output:
   --
   0 -  Maintainer: [ ki6zhdattrinityos.com ]
   1 -  Summary: [ A set of utilities for packet radio mail exchange with the BBS. For use with the Linpac terminal programs as well as others ]
   2 -  Name:    [ ax25mail-utils ]
   3 -  Version: [ 0.13 ]
   4 -  Release: [ 1 ]
   5 -  License: [ GPL ]
   6 -  Group:   [ hamradio ]
   7 -  Architecture: [ armhf ]
   8 -  Source location: [ https://sourceforge.net/projects/ax25mail ]
   9 -  Alternate source location: [  ]
   10 - Requires: [ ax25-tools,perl ]
   11 - Provides: [ ax25mail-utils ]
   12 - Conflicts: [  ]
   13 - Replaces: [  ]
   --

   If your output looks similar to your screen, hit ENTER to begin the packaging.
   checkconfig will automatically install the package for you. If you manually 
   want to install it say on another machine, use the following (configuration files 
   aren't included in the checkinstall based deb)

   sudo dpkg --install ax25mail-utils_0.13-1_armhf.deb

   +----------------------------------------------------------------------------+
   | CRITICAL NOTE:                                                             |
   |      With a recent toxic release of the AX.25 packages from Debian, it     |
   |      became obvious that Debian's APT system makes no distinction between  |
   |      this home-built package and the old Debian built package.  To protect |
   |      system from overwriting your built packages, run the following        | 
   |      command:                                                              |
   |                                                                            |
   |         sudo apt-mark hold ax25mail-utils                                  |
   |                                                                            |
   +----------------------------------------------------------------------------+


   - NOT RECOMMENDED approach:  
         You can either install pre-built binaries from the Raspbian repositories 
         by doing the following but there are KNOWN issues with that older :

            #Make sure you get the Linpac 0.25 version or newer with this release of ax25mail-utils
            sudo apt-get update
            sudo apt-get install linpac ax25mail-utils


28b. Compile and Install Linpac


Ok, now let's now move on and build and configure Linpac:

   #RECOMMENDED - gets the newest DEVELOP release 
   Get the newest pre-release version of Linpac - 0.28 is current as of 03/27/20:

      cd /usr/src/archive/Rpi-scratch
      mkdir Linpac
      cd Linpac
      git clone https://git.code.sf.net/p/linpac/linpac linpac-linpac
      cd linpac-linpac
      git checkout develop
      git pull #only needed if you had already cloned the repo before)

      #This step will just sit there for 10 seconds but it will work
      autoreconf --install
      ./configure --prefix=/usr
      
      #Now skip down a little bit to the compile part of this section


   #LESS RECOMMENDED - This downloads the last release version which is quite old
     Get the newest RELEASE version of Linpac - 0.25 is current as of 12/10/17:

      cd /usr/src/archive/Rpi-scratch/
      wget http://downloads.sourceforge.net/project/linpac/LinPac/0.25/linpac-0.25.tar.gz
      tar xzvf linpac-0.25.tar.gz
      cd linpac-0.25

      #Prepare the package to be compiled - takes about 31 seconds on a Rpi3
      ./configure --prefix=/usr

      #Now skip down a little bit to the compile part of this section


        NOT RECOMMENDED: 
        ----------------
        If you are trying to build Linpac 0.24 or older for Raspbian (NOT recommended - 
        please use 0.25 if at all possible), you MUST download and apply a patch from 
        Martin Cooper KD6YAM to resolve recently exposed POSIX issues:

           wget https://sourceforge.net/p/linpac/discussion/54078/thread/6b0c20d6/17de/attachment/segfault-patch.diff
           patch -p1 < segfault-patch.diff


Now let's compile / install Linpac:

   #Compile the sources 

      # RPi 4, 3+, 3 boards with 4 cores :: takes about 31 seconds on a Rpi3
      make -j8
  
      # Rpi 2, 1, Zero-W, or Zero with 1 core, 
      make -j2


  CRITICAL:  There seems to be some strange bugs with Linpac's installer on Debian Buster, Stretch, and  Jessie 
          where it's not creating some directories for the first time install.  If you've already installed 
          Linpac before on this particular machine, you don't have to do this step.  If this is a NEW install,
          the following commands will help work around the issue before you start the next packaging step:

            sudo /bin/mkdir -p "/usr/share/linpac/contrib"
            sudo /bin/mkdir -p "/usr/share/doc/linpac/czech"
            sudo /bin/mkdir -p "/usr/share/linpac/macro/cz"
            sudo /bin/mkdir -p "/usr/libexec/linpac"

   
   Now figure out what version of Linpac you're installing and be prepared to use that version number below:

      grep " VERSION" config.h

         As of 12/29/19, it shows:
         --
         #define VERSION "0.27"
         --


   Now let's package and install Linpac - Be sure to update the version number learned above in the command
   here:

      For Raspbian version Buster (Debian 10.x) ONLY:
      -----------------------------------------------
         sudo checkinstall --pkgname linpac --pkgversion 0.28 --pkgrelease 1 --pkggroup \
         hamradio --pkgsource https://sourceforge.net/projects/linpac/files/LinPac/ --maintainer \
         ki6zhdattrinityos.com --provides linpac --requires libax25,ax25-apps,ax25-tools,libncurses6 make install


      For Raspbian versions Stretch (Debian 9.x) or Jessie (Debian 8.x):
      ------------------------------------------------------------------
         sudo checkinstall --pkgname linpac --pkgversion 0.28 --pkgrelease 1 --pkggroup \
         hamradio --pkgsource https://sourceforge.net/projects/linpac/files/LinPac/ --maintainer \
         ki6zhdattrinityos.com --provides linpac --requires libax25,ax25-apps,ax25-tools,libncurses5 make install


   Follow the checkinstall prompts:

          Should I create a default set of package docs?  

             Type in "Y" and hit enter

          Description for the package: 
          --
          A modular TUI-based packet radio terminal with concurrent connected/unconnected sessions and a built-in messaging client 
          --

   Validate the output (example is given for Raspbian Buster):
   --
   0 -  Maintainer: [ ki6zhdattrinityos.com ]
   1 -  Summary: [ Linpac is a modular console-oriented packet radio terminal for Linux with a built-in messaging client. ]
   2 -  Name:    [ linpac ]
   3 -  Version: [ 0.28 ]
   4 -  Release: [ 1 ]
   5 -  License: [ GPL ]
   6 -  Group:   [ hamradio ]
   7 -  Architecture: [ armhf ]
   8 -  Source location: [ https://sourceforge.net/projects/linpac/files/LinPac/ ]
   9 -  Alternate source location: [  ]
   10 - Requires: [ libax25,ax25-apps,ax25-tools,libncurses6 ]
   11 - Provides: [ linpac ]
   12 - Conflicts: [  ]
   13 - Replaces: [  ]
   --

If your output looks similar to your screen, hit ENTER to begin the packaging and install
the resulting package

   +-----------------------------------------------------------------------------+
   | CRITICAL NOTE:                                                              |
   |      With a recent change to Raspbian 9 / Debian 9 Stretch, changes to      |
   |      the version of GCC has made the pre-build version available in the apt |
   |      repos TOXIC (will crash on your system).  To protect your system from  |
   |      having Apt overwriting your newly compiled version of Linpac, run the  |
   |      following command to have apt IGNORE the repo-made version:            |
   |                                                                             |
   |         sudo apt-mark hold linpac                                           |
   |                                                                             |
   |      Linpac 0.25 resolves this issue and I've requested the debian-hams     |
   |      packaging team to release Linpac 0.25 for Stretch and Jessie as of     |
   |      12/11/17.                                                              |
   +-----------------------------------------------------------------------------+

   If your output looks similar to your screen, hit ENTER to begin the packaging.
   checkconfig will automatically install the package for you 

     NOTE: If you manually want to install this newly compiled and packaged version of Linpac
           on some other Rpi running the same OS version, use the following 
           (configuration files aren't included in the checkinstall based deb)

           sudo dpkg --install linpac_0.28-1_armhf.deb

28.c. Configure Linpac


   +-------------------------------------------------------------------------------------------+
   | IMPORTANT:                                                                                |
   |                                                                                           |
   | Before you get started, it's very important that you completed the above "Linux AX.25     |
   | stack testing" testing section to confirm your AX.25 stack is properly working.  Without  |
   | a proper setup, I've seen Linpac give Segmentation fault and other weird issues.          |
   +-------------------------------------------------------------------------------------------+


A few things you need to know first in configuring Linpac:

   If you want to see and use the built-in AX.25 Linux traffic monitor "listen" which is VERY useful, 
   you either need to:

     a. need to run Linpac as root  (what I am doing in this doc for now but isn't a great
        security model)

     b. make the ax.25 listen program ( /usr/bin/listen ) SUID root

     c. Compile, setup and configure the "ax25spyd" program as a proxy (not documented here but you
        can read how to build that here:

           http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html#10a.ax25-ax25spyd)


Anyway, let's focus on the core Linpac program for now:

   1. Create the mail holding area

      sudo mkdir -p /var/ax25/mail


   2. These instructions are currently assuming you're going to run Linpac as root.  If you
      are NOT going to run Linpac as root and instead, run as a regular user, you'll need
      to do two other steps:

         #To have the listen function work properly, also consider doing the following 
         #   has security concerns though
         sudo chmod 4755 /usr/bin/listen

   3. Make sure you have root permissions via running the command as the setup wizard
      has issues with being run with sudo:

         sudo chown $USER /var/ax25/mail

   4. Now start Linpac by running the command 
      --
      linpac
      --

   5. When prompted for your callsign, enter in your callsign WITHOUT any SSID.   For me, I 
      typed in:

         ki6zhd


   6. When prompted for your home BBS callsign, you should to enter in something.  It needs to be a 
      valid or at least valid-looking packet BBS address.  It should be noted that this is only used 
      when the ax25mail-utils package is installed and configured.  If the ax25mail-utils package is not 
      installed, this automated packet mail relay feature of Linpac won't function.  It's not a big
      deal if you don't enable this feature but you still need to put in something or the Linpac
      installer won't complete.  It should also be noted that Linpac and the message relay system ONLY 
      supports F6FBB BBS type system today.  It doesn't understand the prompts of other alternative
      BBSes like JNOS, KPC3 PBBS, etc.  

      For this example, I'm using:

         N0ARY-1

      This is my local, full service BBS.  Don't worry about these settings as they won't start polling 
      for packet messages, etc. until configured later.  You can learn more about BBS hierarchical 
      addressing here:

         http://www.choisser.com/packet/part07.html


   7. When prompted for "name of port to connect to" (used to connect to your real or fictitious BBS), 
      you need to specify your AX.25 port configured in /etc/ax25/axports.  For this example, I am 
      using "vhfdrop".   Please note.. that's different than the Linpac default of "vhfport"


   8. When prompted for "the digipeaters used to connect", I just hit enter to mean NO digipeaters
      as I can hear my local BBS directly


   9. When prompted for "Enter the full hierarchical address", put in a correct looking packet
      address.  For my example, I'm using "#NCA.CA.USA.NOAM" for my specific path which means:
      
         - Northern California
         - California
         - United States of America
         - North America

      Notice it's EXCLUDING the name of the actual BBS.  See the above URL for more details and 
      understanding of other geo-centric addresses.


  10. At this point, a set of configurations will go into /root/LinPac/ and the Linpac program
      should start up with a black background and a green bar towards the top of the screen.
      Unfortunately, the system is not quite ready to support running Linpac and you'll see 
      various errors upon start up.  So exit Linpac for now by typing in:

         :sys

      (yes, you need to include the colon as that's part of Linpac's command syntax).  After exiting, 
      we need to further continue to configure Linpac


  11. Now edit /root/Linpac/macro/init.mac and find the lines that start with:

         sudo vi /root/LinPac/macro/init.mac

      If you're running Linpac as a non-root user, you would edit your own config file with:

         sudo vi /home/$USER/LinPac/macro/init.mac


      Now find the line that has your callsign in it.  For example, my setup has:
         --
         mycall@1 KI6ZHD
         --

      In this example, I ONLY only want to associate the KI6ZHD-6 callsign+SSID combo and NOT
      the KI6ZHD (aka KI6ZHD-0) combo to the F1 and F2 keyboard keys (by default, Linpac will assign
      the previously entered CALLSIGN to all eight F1-F8 keyboard assignments.  Notice I'm using
      two F-keys for the mapping of SSID to terminal "view" or F-key views.  In this example, 
      Linpac will allow one incoming connection going to SSID KI6ZHD-6 on the F1 terminal but if
      a different packet radio station tries to connect to you, it will assign that connection to 
      the F2 terminal.  This effectively makes Linpac able to support simultaneous QSOs to the same 
      callsign+SSID like KI6ZHD-6!  That's NOT a common capability for packet radio software and
      most systems would just say that KI6ZHD-6 is busy.  Pretty slick!  To support this this setup, 
      edit these lines to read:

        mycall@1 KI6ZHD-6
        mycall@2 KI6ZHD-6

      I then insert ";;" in front of the other "mycall" lines to comment them out (disabling them).
      If you want to have other CALLSIGNS+SSIDs associated to other F-keys, enter them in now.


      Thoughts on SSIDs
      -----------------
      It's important to note that depending on the specific packet radio frequency you intend to 
      operate on, there can be different SSID allocation schemes in use.  There are only defacto 
      standards user here and schemes will vary from region to region.  A few points here:

         - Do not configure any SSIDs in Linpac that are also configured in the /etc/ax25/direwolf.conf 
           file if you're using Direwolf

         - If you're going to be operating your station on an APRS frequency, make sure that Linpac 
           isn't using one of the common APRS SSIDs.  APRS SSIDs have special meanings and most commonly
           are configured in the direwolf.conf file.   If you intend to use the built-in APRS functionality 
           in Direwolf itself, you can see what different APRS SSIDs are recommended here:

              http://aprs.org/aprs11/SSIDs.txt

         - For classic connected packet radio use, the SSIDs also differ from region to region.  In Northern 
           California on 145.050Mhz, we've standardized on:

            SSID :: Description
            -----::--------------------------------------------
              -0 :: (aka.. no SSID) direct human to human / keyboard to keyboard chat
              -1 :: PBBS mailboxes
              -2 :: not specifically used
              -3 :: not specifically used
              -4 :: not specifically used
              -5 :: netrom nodes and digipeaters
              -6 :: not specifically used
              -7 :: netrom nodes and digipeters (alternate)
              -8 :: not specifically used
              -9 :: not specifically used
             -10 :: for Winlink nodes
             ----

             NOTE:
             -----
             -11 through -15 are generally NEVER used since NETROM connections will automatically use
             these high SSID numbers starting with -15 when creating secondary connections.  For each 
             hope, netrom will continue subtracting from the SSID number through the lower SSIDs to 
             manage link by link connections

   11.  If you plan on making any UNPROTO messages, consider editing the "undest" line to include
        your name and any required digipeaters.  In this example, I'm using the following.  Notice
        the undest line includes quotes.  Those are REQUIRED if you're going to use a chain of
        digipeaters

           unsrc KI6ZHD-6
           undest "David KLPRC3 KBERR KRDG KBERR KVOLC KBETH TAH0E"


   12. Configuring other aspects of Linpac is beyond this document but you might
       consider to update the Linpac display parameters to be a little more attractive 
       but these settings are both a personal preference and what fits my screen.

         statline 15
         chnline 30
         infoline 5
         swapedit
         redraw
       
         NOTE:  If you start Linpac say from within screen session (shown later in this document) and 
                the display looks all squashed up and ultimately see an error:

                   "invalid value"

                Linpac is complaining talking about these various statline, chnline, infoline line 
                count numbers above depending on your terminal.  Try reducing some of the line count 
                sizes for say the "chnlin" value to a smaller number


       You can find more advanced Linpac configuration tips at:

          http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html#11b.linpacconfig


   13. Finally, I recommend to start Linpac via the included shell script found in 
       /usr/share/linpac/contrib/start-linpac.sh which runs Linpac within a screen terminal session.  
       If you want to use this script, you'll also need to do two things:

          a. Install the screen package with:
   
             sudo apt-get install screen

          2. As we are running linpac as the root user, edit the script 
             /usr/share/linpac/contrib/start-linpac.sh and change the line that reads:
                --
                screen -c $HOME/.screenrc-svxlink -S linpac sudo linpac
                --

             to

                --
                screen -d -m -S linpac sudo linpac
                #screen -d -r linpac
                --

            It's important to have that last line commented out or screen will try to reconnect
            to the current TTY but no one is logged in!

28.d. Using Linpac via screen


Linpac is a powerful, Ncurses based packet program but the full use of it is beyond this
document.  Please read all of the documents available on your Raspberry Pi in the
/usr/share/doc/linpac/ directory or at https://sourceforge.net/p/linpac/linpac/ci/master/tree/doc/ .
you can find more tips at 
http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html#11b.linpacconfig

Anyway, to get you started, once you SSH into your Raspberry Pi and configure your packet system
to auto-start upon boot (starts Linpac too), you'll be able to connect to the "screened" Linpac 
session at any time.  For now, start up Linpac and then re-attach to it's screen session:

   sudo /usr/share/linpac/contrib/start-linpac.sh
   sudo screen -dr linpac

At this point, you should see the Linpac main interface where:

   - At the top are the commands to send to either Linpac or to the remote station you've
     connected to
   - In the middle is the text your station receives from the remote station
   - At the bottom is all the packets your system is hearing


A few quick commands to get you around:

   - To connect to a remote station, say the remote "lprc3" node that in my area, I would issue 
     the following command INCLUDING the first ":" character too:

        :c lprc3

     The system should then connect and you'll see the text coming in from the remote system!

   - To force a disconnection of the current session, use:

        :d 

   - If you configured Linpac to use to different SSIDs, you can use the respective
     F1, F2, F3, etc keys to use which can either initiate or receive multiple, simultaneous 
     connections.  The F10 key is dedicated to sending and monitoring unproto or UI packets
     for unconnected chats, etc.

   - To disconnect from the current screen session but leave Linpac running, simply issue the 
     screen command:

        control-a d

     and you'll disconnect from the session but it keeps running.  Cool huh!

   - If you want to shutdown Linpac instead of disconnecting from it's screen, you'd instead issue 
     the following Linpac command (yes, you need the double slashes):

      //q


29. Auto start the packet system and advanced services


Ok.. so the packet system is up and running and you want it to start upon every boot.  Cool!
To do that, do the following:

   1. Edit the /etc/rc.local file and just above the line reading "exit 0", add the following 
      lines:

      sudo vi /etc/rc.local
      --
      echo -e "\nStarting packet system"
      /etc/ax25/ax25-up.new &
      --

   2. Next, if you want to auto-start some of the additional packet services including Linpac, 
      edit the /etc/ax25/ax25-up.new file and at the bottom of the script, remove the #ed out 
      line that runs the follow-on /etc/ax25/ax25-up.new2 script:

         sudo vi /etc/ax25/ax25-up.new
         --
         #remove the # in front of this line to now let it run
         /etc/ax25/ax25-up.new2 $TNCTYPE
         --

   3. Now let's edit the /etc/ax25/ax25-up.new2 script and at least enable beacons and to have
      Linpac to auto-start.  If you've configure any other AX.25 services, you can remove the 
      #s in those lines to have them auto start too.  For now, let's do beacons and Linpac:

         sudo vi /etc/ax25/ax25-up.new2
         --
         #Find the beacon section and change the CALSIGN+SSID, CALLSIGN and status text to match 
         #your own callsign, desired SSID, beacon text, etc:
         #
         /usr/sbin/beacon \
         -c ki6zhd-6 \
         -d 'info KI6ZHD' \
         -t 15 \
         vhfdrop \
         "low-level KB2KB netrom node in Santa Clara  "
         --

         #Make sure the Linpac section is present.  If not add it
         --
         # Start LinPac
         #
         if [ -f /root/LinPac/macro/init.mac ]; then
            /usr/share/linpac/contrib/start-linpac.sh
            if [ $? -ne 0 ]; then
               echo -e "LinPac failed to start"
               echo -e "LinPac failed to start" >> $LOG
              else
               echo -e "\nLinPac Started"
               echo -e "\nLinPac Started" >> $LOG
            fi
         fi

That's it!  All the basics of your packet station should be working and ready to auto-start when
you boot your RPi!  So.. let's test it.  Shutdown the Rpi with the shutdown button (if you followed
that section) or run the command:

   sudo /sbin/shutdown -h now

Wait for the Rpi to shutdown and watch the Rpi's green LED blink 10 times and then go completely
off to mean it's safe to remove the power.  Remove the power, wait 5 seconds, and re-connect it.  
When the Rpi comes back up, log back into the Rpi a look for:

   - If you're using a Syba USB soundcard, check that it's green LED is quickly blinking.  You'll
     noticed that after the first transmission from Direwolf, the LED will blink slower.  This
     is expected.
         
   - Running "ifconfig" will show the "ax0" interface

   - Run the following commands to make sure they are running:

      ps aux | grep pishutdown

      ps aux | grep direwolf

      ps ax | grep listen    #There will be three of these

      ps ax | grep linpac

      ps ax | grep beacon

      ps ax | grep mheardd


If all of these process are listed.. you're set!   Now, time to get things working with out a 
wired connection... on to Wifi!


30. Configuring your Rpi to either connect to an existing Wifi AP or act as a Wifi AP for providing local connectivity:


+------------------------------------------------------------------------+
| Raspbian Buster:  Simultaneous client and AP operation to be validated |
+------------------------------------------------------------------------+

Configuring a Raspberry Pi 4,3+,3,Zero-W to act as either a standard Wifi client connecting to 
an existing Wifi AP --or-- have it act as a full Wifi access Point isn't too difficult.  This 
section will tell you how a Wifi-enabled Rpi can do both functions SIMULTANEOUSLY.   The Wifi 
range is pretty decent considering that the Rpi only have either a small PCB or small chip 
antenna.  If you want better range, consider doing a hardware modification to add a u.fl connector 
and use an external Wifi antenna (mentioned below - not possible on the Rpi 4, 3B+, and Zero-W):

   NOTE: Previous doc versions focused on working with an RTL8192CUS based Wifi device but this 
         has been dropped

            https://www.adafruit.com/products/1030

         The above work is now mostly unneeded now as the Raspberry Pi line now has Wifi built in.  
         Also and unfortunately, the Linux support for Realtek RTL8192 within the hostapd program 
         is NOT in the mainline release nor does it sound like it EVER will be (been this way for 
         years now).  Add in that there is a lot of conflicting and stale setup information out on 
         the web of how to do it and it's become a bit of nightmare to setup.  I've kept this older 
         detail in a later section in this doc farther down in a "deprecated" section but with the 
         new Rpi v3 / Rpi Zero W and their built-in Wifi hardware, I wouldn't recommend to go the 
         RTL8192CUS route anymore.  Save yourself time and money and just buy a new Raspberry Pi!

30.a Configure your Rpi to connect to an existing Wifi AP for network access

Connecting to an existing Wifi AP from a Wifi-capable Raspberry Pi is quite easy from the command line
and actually can be done one of two ways:

   Raspberry Pi OS (Buster version):

      - Method 1: Configure Wifi before you first boot your Raspberry Pi:

         - Create the file /boot/wpa_supplicant.conf with APPENDING the following info this file.  
           You *MUST* replace various settings for your specific region 
           (per https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes ), Wifi SSID name, and 
           Wifi SSID key:
              --
              country=US
              network={
                  ssid="NETWORK-NAME"
                  psk="NETWORK-PASSWORD"
              }
              --

        - Once you boot your Raspberry Pi, this file will be automatically copied into /etc/wpa_supplicant/wpa_supplicant.conf
          and will configure Wifi services to auto-start


      - Method 2: Configure Wifi via the console using an HDMI display and a keyboard

         - Create the file /etc/wpa_supplicant/wpa_supplicant.conf with APPENDING the following into
           this file.  You *MUST* replace various settings for your specific region (per 
           https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes ), Wifi SSID name, and 
           Wifi SSID key:
              --
              country=US
              network={
                  ssid="NETWORK-NAME"
                  psk="NETWORK-PASSWORD"
              }
              --

           - If you are unaware of what your Wifi SSID is, you can run this command to get a list of 
             APs in range:

                iwlist wlan0 scanning | grep ESSID

           - Once configured, try manually bringing up the Wifi interface and see if it got an IP
             address with the following commands:

                sudo wpa_cli -i wlan0 reconfigure
                ifconfig wlan0

           - If that worked, now reboot your Pi and make sure wifi comes up as expected 

                sudo /sbin/shutdown -r now

30.b Configure your Rpi to act as a Wifi AP using the built-in Raspberry Pi 3 Wifi support


With the debut of the Raspberry Pi 3 and Rpi Zero W, these new SBC versions and all versions 
since support built-in 802.11AC or 802.11N Wifi and Bluetooth 5.0, 4.2, and 4.1.  The initial versions
of Wifi hardware only the 802.11 2.4Ghz band but the v4 and 3+ added 5.0Ghz support.  The only 
downsides to this built-in wireless support in my opinion is:

   - The stock antenna on the Rpi3,3+,and Zero-W is considered to be pretty good.  The Rpi3's "chip 
     antenna" was only considered decent which means your Wifi distance and speed will be limited.  
     You can find this white antenna chip on your Rpi3 just to the right of the 40pin header when 
     the HDMI port is facing you.  The stock antenna's range isn't bad but can't be greatly improved 
     with hacking the Rpi v3's hardware a bit by soldering on a U.FL connector and using an external 
     Wifi antenna.  More on that later.  Please note that this option is NOT possible on the 
     4,3B+,Zero-W  as they removed the solder pads.  

   - There aren't any Wifi or BT network traffic LEDs to indicate that the AP is active, being used, 
     etc


Anyway, for now, let's move forward with first enabling the Rpi to act as a Wifi AP ONLY 
(aka.. (infrastructure mode"):

   Assumptions
   -----------
   Like everything Linux, there are several ways to do everything.  Here are the design choices
   this document is making:

   Use an existing AP or  If you're using Wifi on your Rpi today being it's primary Internet connection, 
     or become* an AP:    these steps will BREAK that network connection.  This doc will make the Rpi act 
                          like it's an access point but below, I have added where the Rpi can act BOTH as
                          an AP but also connect to an existing AP *simultaneously*.  In the future, I might
                          add a physical switch connected to GPIO pins to allow you to choose how the Rpi 
                          will exclusively act but that's not documented here yet (is mentioned in my old
                          Rpi doc available at: 

                             http://www.trinityos.com/HAM/Rpi-APRS-project/RPi-setup-details/rpi3-setup.txt

      This doc section:   Based on recommendations from 
                          https://frillip.com/using-your-raspberry-pi-3-as-a-wifi-access-point-with-hostapd/
                          but I've added informational and troubleshooting commands, modernized it's 
                          commands to use native Systemd commands and added IPTABLES firewall sections to 
                          protect your system

      IP Addressing:      This doc will use the 192.168.10.1/24 network on the Wifi network

      Local or Internet:  My initial intention for wireless access is to get my smart phone to SSH
                          into the Raspberry Pi directly.  This section is to NOT provide Internet access 
                          to any of the Wifi devices connected via the Raspberry Pi's Wifi.  Adding this 
                          routing functionality is actually pretty easy (NAT or bridging) but it's not 
                          covered here.

      Stateful Firewalls: It enables firewalling which is always an important security practice

      DHCP and DNS:       For my lightweight uses, I'm going to use hostapd and dnsmasq.  Other 
                          HOWTOs on the internet use ISC's DHCPd server and ISC's Bind DNS servers but they 
                          are additional packages to install and using ISC's industrial strength programs 
                          are major overkill for this simpler use-case

                          

To start off with, let's make sure Linux sees the Wifi hardware.  Run the command:

   dmesg | grep brcmfmac

and you should see something similar to these Wifi details:
   --
   brcmfmac: brcmf_c_preinit_dcmds: Firmware version = wl0: May 27 2016 00:13:38 version 7.45.41.26 (r640327) FWID 01-df77e4a7
   --


   NOTE:  If you see don't see anything, try again just running "dmesg" and if you're only seeing lines like 
          the following, you're best off just rebooting your Raspberry Pi for now and again looking at the 
          output to confirm the Wifi chip is seen.  Btw, this IPTABLES "log noise" can  be fixed by enabling 
          ulogd logging by following that previous section in this doc).  Here is an example of this "log 
          noise" that you might see:
   --
   iptables denied: IN=eth0 OUT= MAC=ff:ff:ff:ff:ff:ff:60:57:18:ca:a3:32:08:00:45:00:00:4e:20:63:00:00:80:11:97:71 SRC=192.168.0.123 DST=192.168.0.255 LEN=78 TOS=0x00 PREC=0x00
TTL=128 ID=8291 PROTO=UDP SPT=137 DPT=137 LEN=58
   --


If the wifi hardware was seen, it's most likely the OS has automatically created the "wlan0" interface.  Run the 
following command to confirm you see the "wlan0" interface:

   /sbin/ifconfig -a

--
wlan0: flags=4099  mtu 1500
        ether b8:27:eb:0a:50:6e  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
--

There isn't an IP address on it right now which is perfectly fine.  Let's also confirm the Wifi device 
can be interrogated:

   iwconfig wlan0
   --
   wlan0     IEEE 802.11  ESSID:off/any
             Mode:Managed  Access Point: Not-Associated   Tx-Power=31 dBm
             Retry short limit:7   RTS thr:off   Fragment thr:off
             Encryption key:off
             Power Management:on
   --

   or the command "iw dev"


In the next steps, you need to understand that the Stretch and Jessie versions of Raspbian uses  
the SystemD style of Linux system management.  This means everything in Linux is COMPLETELY changed 
the way that the Linux network stack gets configured.  Love it or hate it.. it's here.  Raspbian also
now uses the dhcpcd (read that as DHCP *client*) process for all network interfaces (strangely enough..
even for static IP addresses!).

    Yes.. I know what you're thinking.. .. what does DHCP have to do with static IP addresses?! 
    I agree with you that it's totally backwards but it's TRUE.  Take up your complaint with with 
    the SystemD guys and not me. 


Back to it, you first need to install some key software:

   #Update your software list
   sudo apt-get update

   #Accept all additional package dependencies
   sudo apt-get install dnsmasq hostapd rfkill


Next, you need to enable the dhcpcd service and configure a static IP of 192.168.10.1/24 on the 
wlan0 interface.  If you'd like to use a different TCP/IP subnet, make your changes here and as 
appropriate in all future configuration stanzas.  Step one is to to NOT try to get a DHCP client IP 
address on the wlan0 interface.  Add the following line at the bottom of the file:

   Raspbian Stretch ONLY:
      sudo vim /etc/dhcpcd.conf
      --
      interface wlan0
      static ip_address=192.168.10.1/24
      static routers=192.168.10.1
      --


   Raspbian Jessie ONLY (Not stretch):
      sudo vim /etc/dhcpcd.conf
      --
      denyinterfaces wlan0
      --


Pre Raspbian Stretch users:
---------------------------
  Edit the interfaces file to create a static IP for the wlan interface.  Specifically, 
  you might need to alter the lines to reflect what you want to use:


   Raspbian Stretch ONLY:
      Do NOT edit the /etc/network/interfaces file at all!


   Raspbian Jessie ONLY (NOT Stretch):
      sudo vim /etc/network/interfaces
      --
      allow-hotplug wlan0  
      iface wlan0 inet static  
          address 192.168.10.1
          netmask 255.255.255.0
          network 192.168.10.0
          broadcast 192.168.10.255
      #    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
   --


   IGNORE ME- I'm leaving this legacy entry in this document for now to ensure I don't see any 
              strange behavior and might need to re-add it:

              disable SystemD from trying to associate to any local APs:
              --
              #Find the line that looks like the following and it DOESN'T have a # in front of it
              allow-hotplug wlan0
              --


Ok, now let's activate this base wlan0 configuration.  Run the following commands:

   #restart the dhcpcd client
   sudo systemctl restart dhcpcd.service

   #Reset the wireless interface
   sudo systemctl restart systemd-networkd.service

   #Remove any disabling of the wlan interface
   sudo rfkill unblock 0


At this point, not a whole lot will be changed as the wireless interface still doesn't have any
network associations but

   Raspbian Stretch:
      Won't show any IP address in the output of "ifconfig -a" just yet
      

   Raspbian Jessie:
      If you run "ifconfig -a" should show the 192.168.10.1 IP address on the interface.



Now it's time to configure hostapd which makes the wireless device enter "Access Point" mode.

   NOTE:  Raspbian Stretch doesn't copy over the default configuration file by default but
          if you want to start with that you can issue the command:

             sudo zcat /usr/share/doc/hostapd/examples/hostapd.conf.gz > /etc/hostapd/hostapd.conf

   NOTE2:  There are a LOT of configuration options in the default /etc/hostapd/hostapd.conf
           file.  If you know EXACTLY what all these items do, feel free to customize the settings
           but I've only tested the below changes:


   sudo vim /etc/hostapd/hostapd.conf
--
# The Rpi3s default wifi interface
interface=wlan0

# Use the nl80211 driver which includes support for the Broadcom brcmfmac hardware driver
driver=nl80211

# This is the name of the Wifi network you're creating.  Change this to be what you want
#  but it MUST be a MINIMUM of 8 characters and a MAXIMUM of 63 characters.  Consider 
#  using your callsign
#
ssid=YOU-NEED-TO-CHANGE-ME

# Change this to the correct country you're in - I'm in the US
country_code=US

# Use the 2.4GHz band and disable legacy 802.11b which slows the network down
hw_mode=g

#  ACS support not enabled in the nl80211 driver for hostapd 2.3 so you cannot
#  use channel=0.  As such, try to determine the least used channel around you 
#  It might be worth noting that HAMs with our amateur radio license give us
#  special high power privileges on channel 1.  Though you'll need a high power 
#  Wifi amp to use it, you might as well start there
#
#  You can also use the next sections recommendations to see what might be 
#  a better channel to use but for now, use channel 1
channel=1

# Accept all MAC addresses
macaddr_acl=0

# Use WPA authentication ONLY
auth_algs=1

# Require clients to know the network name
ignore_broadcast_ssid=0

# Enable Wireless MultiMedia class of service (WMM)
wmm_enabled=1

# Enable 802.11n support
ieee80211n=1

# Enable 40MHz channels with 20ns guard interval
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]

# Use WPA2 wireless security only
wpa=2

# The network passphrase
wpa_passphrase=YOU-NEED-TO-CHANGE-THIS

# Use a pre-shared key
wpa_key_mgmt=WPA-PSK

# Use AES, instead of TKIP
rsn_pairwise=CCMP
--

30.c Temporarily testing the AP Wifi system out


Ok, you should have the basis of a working Wifi setup.  To test it, try running the hostapd service
manually by running the following:

   sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf &
   --
   Configuration file: /etc/hostapd/hostapd.conf
   Failed to create interface mon.wlan0: -95 (Operation not supported)
   wlan0: interface state UNINITIALIZED->COUNTRY_UPDATE
   wlan0: Could not connect to kernel driver
   Using interface wlan0 with hwaddr b8:27:eb:0a:50:6e and ssid "ki6zhd-ap"
   wlan0: interface state COUNTRY_UPDATE->ENABLED
   wlan0: AP-ENABLED
   --

   If you see something like the above where it ends in "wlan0: AP-ENABLED", things are looking GOOD.  
   You can also run "ifconfig wlan0" which should now have an IP address on it:

      ifconfig wlan0
      --
      wlan0: flags=4163  mtu 1500
        inet 192.168.10.1  netmask 255.255.255.0  broadcast 192.168.10.255
        ether b8:27:eb:0a:50:6e  txqueuelen 1000  (Ethernet)
        RX packets 52  bytes 7688 (7.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 14  bytes 1787 (1.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
      --
   
   Go ahead and try enabling Wifi on your desired Wifi client device (like a smartphone) where
   it should see your new Rpi based Access point as named above.  If you do see it, that's good but 
   don't bother trying to connect to it just yet as DHCP isn't configured on your Raspberry Pi just 
   yet.  If you do try, your remote Wifi device should associate but hang on waiting to get an IP 
   address.

   If the test was successful, Type in the following to foreground the hostapd program and then exit it:
   --
   fg %1
   control-c
   --


   If the above tests DIDN'T WORK, you can try a few things:

     1) You might have an incompatible Wifi channel configured.  Maybe you're seeing
        ""ACS: Unable to collect survey data" where you've configured Automatic Channel Selection 
        (ACS).  Unfortunately, ACS does not work in hostapd v2.3 and the nl80211 driver so a 
        setting of "channel=0" or "channel=acs_survey" will *not* work.  Set a channel of say
        1 through 11.

     2) run the "raspi-config" program and make sure the following areas are properly set
        for your region (I'm in the US):

           Internationalization Options
              |
              +--> Change Wi-fi Country --> US


     3) Update your RPi v3's firmware using "rpi-update".  Once complete, reboot your Rpi v3
        or Rpi Zero W and try the above steps again


Assuming things worked OK in the above tests, we now need to enable this configuration file.  Edit the 
following file, and remove the # in front of the following line:

   sudo vim /etc/default/hostapd
   --
   DAEMON_CONF="/etc/hostapd/hostapd.conf"
   --

   +---------------------------------------------------------------------------------------+
   | Channel Tuning:                                                                       |
   |                                                                                       |
   |  If you're worried about the Wifi channel you selected above, you can look at look at |
   |  what other wifi networks are around you and their signal strength by running:        |
   |                                                                                       |
   |      iwlist wlan0 scanning | less                                                     |
   +---------------------------------------------------------------------------------------+


Back to it... now we need to configure DNSMasq:

   +----------------------------------------------------------------------------------------------------+
   | NOTE: New recent issue - 10/26/17                                                                  |
   |                                                                                                    |
   |    There has been a recent issue seemingly introduced with a recent Raspbian patch where           |
   |    dnsmasq won't start.  Specifically, the error you'll see is:                                    |
   |                                                                                                    |
   |       dnsmasq: failed to create listening socket for 192.168.10.1: Cannot assign requested address |
   |                                                                                                    |
   |    The issue seems to be a race condition where hostapd isn't required to be fully up before       |
   |    dnsmasq comes up.  A temporary solution is to # out the line "bind-interfaces" line in the      |
   |    dnsmasq.conf file below.  I am actively researching how to fix this within SystemD but this     |
   |    may take some time.                                                                             |
   +----------------------------------------------------------------------------------------------------+

   NOTE#2:  There are a LOT of configuration options in the default dnsmasq.conf file.
            If you know what all these items do, feel free to customize the settings
            but I've only tested the below changes

   NOTE#3: Be sure to change the IP address here to match the static IP address 
           you set above

  sudo vim /etc/dnsmasq.conf 
  --
  # Don't resolved non-FQDN hostnames  
  domain-needed        

  # Never forward addresses in the non-routed address spaces.  
  bogus-priv           

  # Use interface wlan0  
  interface=wlan0             

  # Explicitly specify the address to listen on  
  listen-address=192.168.10.1  

  #Disable DNS and DHCP from running on the wired Ethernet interface
  no-dhcp-interface=eth0

  # Bind only to the defined interface so other interfaces don't get unwanted traffic
  #
  #   This is INTENTIONALLY commented out per the comment above
  #
  #bind-interfaces      

  # Assign IP addresses between 192.168.10.100 and 192.168.10.150 with a 4 hour lease time 
  dhcp-range=192.168.10.100,192.168.10.150,255.255.255.0,4h

  #NOT sure if we need this - dnsmasq should use DNS servers it sees in the resolv.conf file
  #server=8.8.8.8       # Forward DNS requests to Google DNS  
  --


Next, if you configured the IPTABLES firewall from the section above, you'll need to 
update the firewall ruleset to now enable DHCP for the wlan0 interface.  It's also worth
noting that I'm *NOT* enabling NAT here to allow Wifi devices to access say the Internet
via the Rpi's wired eth0 interface.  This is NOT not the purpose of this document. 

   NOTE: if you really want to do that, review the previous iptables section which actually
         has the require lines commented out.  Then, carefully the bottom of the next section 
         area at the bottom of this section on how to complete the setup


Anyway, let's make the minimum changes to allow DHCP on wlan0 by do the following:

   #First, make a backup of the running rules now
   sudo cp /etc/iptables/rules.v4 /etc/iptables/iptables.checked

   #enable the following line in the rules.v4 file and ADD the following
   # line BELOW the line:
   #
   #     -A INPUT -p udp -m udp --sport 67 --dport 68 -j ACCEPT

   sudo vim /etc/iptables/rules.v4
   --
   -A INPUT -p udp -m udp -i wlan0 --sport 68 --dport 67 -j ACCEPT
   --

Load the new ruleset with the following commands (previously discussed in
the IPTABLES section):

   sudo su
   /usr/local/sbin/firewall-confirm &
   touch /tmp/fwok
   exit

If that worked ok, let's make this new firewall ruleset the new default:

   sudo cp /etc/iptables/rules.v4 /etc/iptables/iptables.checked

30.d Final testing of the Wifi system


Ok, we should be set for a full test to make sure the Raspberry Pi acts as a full Wifi AP:

  1. Temporarily start up hostapd and dnsmasq

     #Running these commands won't give any specific output
     #Do the individual commands to avoid some strange behavior on Stretch
     sudo systemctl stop hostapd
     sudo systemctl start hostapd
     sudo systemctl restart dnsmasq

  2. Run "ifconfig" and confirm you see:

     2.a - does the wlan0 interface exist?
     2.b - does it have the expected IP address on it (192.168.10.1) in this example

  3. Run "iwconfig" and confirm you see:

     3.a - does the wlan0 interface exist?
     3.b - does it show "Mode:Master" meaning it's in Access point mode?


Assuming all of the tests above PASSED above, now go back to your desired Wifi 
device (smartphone, etc) and try to associate to your Raspberry Pi AP using the 
configured Rpi's configured SSID and WPA2 passphrase:

    - Did the device associate on the Wifi level (connected but didn't get an 
      IP address just yet)?

    - Did it get an IP address?  On my Android device, go into the Android system
      settings, go to the Wifi setup area and in there, I click on the three vertical
      ". . ." icon in the very upper right part of the screen.  There I select 
      "Advanced Wifi", and scroll down to the very bottom until I see the Wifi Ethernet
      MAC address and it's IP address.  In this example, I see 192.168.10.127 which
      is in the expected range!

    - I now recommend to install use an SSH client on your device to connect to the Raspberry
      Pi at 192.168.10.1.  I use the Android ConnectBot which works pretty well except it's
      use of the F-keys is broken.  You might consider using JuiceSSH as an alternative.

      Using the username and password you created in an earlier section of this doc, can
      you log in?

         NOTE:  Using your smartphone as a display and a keyboard will work
                in a pinch but it's pretty cumbersome and doesn't work well
                for full-screen programs like Linpac.  Consider buying 
                a compact bluetooth keyboard and pairing it with your
                smartphone.  At this point, you should be able to hide 
                the virtual keyboard on your smartphone and use the BT 
                keyboard for all your input needs.  Pretty slick!


If everything worked up to this point and you want this Wifi Ap system to work 
at every boot up, let's enable it permanently:

   #Enable the Systemd services to start on boot
   sudo systemctl enable hostapd
   sudo systemctl enable dnsmasq


Ok.. now reboot your Raspberry Pi with either:

   sudo /sbin/shutdown -h now

      or

   Press the shutdown button you build and created in the previous section
   of this doc

Wait until the green LED on the Rpi blinks 10 times quickly and then goes out.
Now remove power from the Raspberry Pi.  Next, check that on your remote Wifi device,
you no longer see your Rpi's Wifi SSID.

Now re-connect the USB power to the Raspberry Pi:

   - Do you see the Rpi Wifi SSID?

   - Try connecting to it and make sure that the Wifi system came back 
     up as you'd expect!


  NOTE:  Check out the HW-Tricks section below in this doc on how you can change 
         the onboard RPI v3 LEDs from being the SD card read/write activity indicator
         to say Wifi network activity, etc.  Pretty slick!  Just too bad there is
         only one LED to use!

  +--------------------------------------------------------------------+
  | TBD: Similar to the old wireless section shown below, add a switch |
  | #1   on a few GPIO pins to switch the Wifi connection between      |
  |      acting as an AP vs. act like a wireless client and associate  |
  |      to a nearby AP                                                |
  +--------------------------------------------------------------------+

  +--------------------------------------------------------------------+
  | TBD: Notes on how to add an external Wifi antenna to the Rpi v3    |
  | #2   (not 3B+) for better reach - read more for now at             |
  |                                                                    |
  |  https://hackaday.io/project/10091-raspberry-pi-3-external-antenna |
  +--------------------------------------------------------------------+
   

OPTIONAL:
---------
Per the beginning paragraph in that section, this setup does NOT provide the associated
wifi devices any Internet access.  You *can* optionally enable IP forwarding on your Rpi3
which will share it's Internet access to all associated Wifi devices.  I'm not going to detail 
this as it's not my goal but if you want to enable it, you'll need to

   -  enable IP forwarding by adding the line "net.ipv4.ip_forward=1" to the /etc/sysctl.conf 
      file.  You can temporarily test this by running the command:
         sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

   - uncomment out the masquerade NAT rule in the iptables ruleset.  See the above referenced
     rules.v4-test file and remove the # in front of the relevant three lines and then enable
     the temporary ruleset with:

          sudo iptables-restore < rules.v4-test

   - If everything works, make sure you enable the new firewall ruleset to 
     load every time with:

       sudo iptables-save < /etc/iptables/rules.v4

30.e Configure simultaneous Wifi client and Wifi AP connectivity


+----------------------------------------------------------------------------------+
| IMPORTANT:                                                                       |
|            This section is a work in progress and it currently does NOT work and |
|            actually breaks all Wifi access.                                      |
|                                                                                  |
| +--------------------------------------------------+                             |
| | CURRENT STATUS -- Sort of works, sort of broken  |                             |
| |                   see the bottom of this section |                             |
| +--------------------------------------------------+                             |
+----------------------------------------------------------------------------------+

+----------+
| OPTIONAL |
+----------+
   One excellent feature of the new Raspberry Pi3/ZeroW hardware is that it's Wifi system can 
   act as both a Wifi client and be a Wifi access point *at the same time*.  This will let you
   connect to the Rpi either directly or through an AP (which usually has Internet access).

To get this "second" connection working, we need some information first.  We need the Ethernet
MAC address of your specific Rpi's wifi chip.  To do that, run:

   root@rpi0w:/etc/hostapd# ifconfig wlan0

   You should see:
   --
   wlan0: flags=4163  mtu 1500
        inet 192.168.10.1  netmask 255.255.255.0  broadcast 192.168.10.255
        ether b8:27:eb:79:82:2c  txqueuelen 1000  (Ethernet)
        RX packets 344  bytes 24486 (23.9 KiB)
        RX errors 0  dropped 1  overruns 0  frame 0
        TX packets 266  bytes 33726 (32.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
   --

See that "b8:27:eb:79:82:2c" string?  That's the MAC we'll need.  

IMPORTANT:
----------
Now, from this point forward, I *highly* recommend you either do this configuration on the Rpi's 
console (connected HDMI monitor and keyboard) or via a wired USB-based Ethernet connection.
If you don't do this, you might loose connection and then break your access to the Rpi.


NOTE:
-----
   We need to create another wifi device to act as the new wifi AP device.  This changes the 
   above sections naming conventions as we'll now have:

      wlan0 - Interface used for connecting to your local AP (this is standard)
      ap0   - Interface used for devices connecting TO the Rpi

   One thing I did notice in writing this section up is that the previous section to make
   the Rpi act as an AP, it output of "iw dev" shows the wlan0 device STILL as a wifi client
   (managed) when in fact it was acting as an AP.  I also noticed that you CANNOT have two
   "managed" devices aliased to the same physical device.  In the future, I might reverse
   everything around in the above section but for now, I'm not going to do that.
   


Let's create the "ap0" device name by editing the right Udev file:

   sudo vim /etc/udev/rules.d/70-persistent-net.rules
   --
   #Add the following line with substituting in your correct MAC address in both places
   #
   SUBSYSTEM=="ieee80211", ACTION=="add|change", ATTR{macaddress}=="b8:27:eb:79:82:2c", KERNEL=="phy0", \
RUN+="/sbin/iw phy phy0 interface add ap0 type __ap", \
RUN+="/bin/ip link set ap0 address b8:27:eb:79:82:2c"
   --


Next, we are going to STOP using dhcpcd on wireless interfaces but if you plan on connecting an 
Ethernet USB-dongle to the Rpi, I add the "eth0" statement to the /etc/dhcpcd.conf file and 
towards the end:
   --
   #These #s will disable the previous wlan0 DHCP scope as configured in the previous section
   #interface wlan0
   #static ip_address=192.168.10.1/24
   #static routers=192.168.10.1
   #static domain_name_servers=8.8.8.8

   #This will enable DHCP on the eth0 interface
   interface eth0
   --


Now, edit the /etc/dnsmasq.conf file and now make the lines read:
   --
   domain-needed
   bogus-priv
   #If you plan on allowing Rpi-connected Wifi devices to get 
   # internet access from the Rpi itself, comment out the next line
   no-resolv
   interface=lo,ap0
   listen-address=192.168.10.1
   no-dhcp-interface=lo,eth0,wlan0
   #We now need this option
   bind-interfaces
   dhcp-range=192.168.10.100,192.168.10.150,4h
   --


Now, edit the /etc/hostapd/hostapd.conf file and now make the lines read:
   --
   interface=ap0
   driver=nl80211
   ssid=YOU-NEED-TO-CHANGE-ME
   #Change this if you aren't in the US
   country_code=US
   hw_mode=g
   channel=1
   macaddr_acl=0
   auth_algs=1
   wmm_enabled=0
   ieee80211n=1
   ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
   wpa=2
   wpa_passphrase=YOU-NEED-TO-CHANGE-THIS
   wpa_key_mgmt=WPA-PSK
   wpa_pairwise=CCMP
   --
   
   
Next, we need to change the the /etc/wpa_supplicant/wpa_supplicant.conf file to connect your 
local Wifi AP (when it's in range):
   --
   #Change this if you aren't in the US
   country=US
   ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
   update_config=1

   #Your first AP you might want to connect to if it's in range
   #Change the SSID and PSK lines to match that AP's credentials
   network={
       ssid="YourSSID1"
       psk="YourPassphrase1"
       id_str="AP1"
   }

   #Your second AP you might want to connect to if it's in range
   #Change the SSID and PSK lines to match that AP's credentials
   network={
       ssid="YourSSID2"
       psk="YourPassphrase2"
       id_str="AP2"
   }
   --


Now connecting all this together, edit the /etc/network/interfaces file

   --
   auto lo
   auto ap0
   auto wlan0

   iface lo inet loopback

   #If you plan on having an Ethernet USB-dongle attached
   auto eth0
   allow-hotplug eth0
   iface eth0 inet dhcp

   allow-hotplug ap0
   iface ap0 inet static
       address 192.168.10.1
       netmask 255.255.255.0
       hostapd /etc/hostapd/hostapd.conf

   allow-hotplug wlan0
   iface wlan0 inet manual
       wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf

   iface AP1 inet dhcp
   iface AP2 inet dhcp
   --


Now, per the details at 
https://albeec13.github.io/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/
there is a race condition of the wlan0 interface coming up first and blocking the ap0 interface
from loading.  For now, here is the cited work around but I bet there is a way to delay this
wlan0 bring up via Systemd (needs some research):

   /usr/local/sbin/start-ap-managed-wifi.sh
   --
   #!/bin/bash
   echo "running start-ap-managed-wifi.sh -- 30sec delay"
   sleep 30
   sudo ifdown --force wlan0 && sudo ifdown --force ap0 && sudo ifup ap0 && sudo ifup wlan0
   #IPMASQ NAT rules removed
   --

   Now make it executable with:
   chmod 700 /usr/local/sbin/start-ap-managed-wifi.sh

To make this script run at boot, add the following to the /etc/rc.local file:

   --
   #Bring up the Wifi workaround script
   /usr/local/sbin/start-ap-managed-wifi.sh &
   --


Assuming you setup the Iptables firewall per this document, you'll need to allow:

  - allow DHCP client traffic on the new ap0 interface
  - allow DHCP server traffic on the wlan0 interface
  - allow DNS client traffic on the new ap0 interface
  - SSH traffic was already allowed on all interfaces before

Edit the /etc/iptables/rules.v4 file and add the following lines:

   -A INPUT -p udp -m udp -i ap0 --sport 68 --dport 67 -j ACCEPT
   -A INPUT -p tcp -m tcp -i ap0 --dport 53 -j ACCEPT
   -A INPUT -p udp -m udp -i ap0 --dport 53 -j ACCEPT
   -A INPUT -p udp -m udp -i wlan0 --sport 67 --dport 68 -j ACCEPT

Now go re-run the firewall-confirm.sh script to activate those changes.  If you don't
remember how to use that script, re-read the end of that section now so you don't
lock yourself out of your own Pi!


Based on the guide found at:

   https://albeec13.github.io/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/

+---------------------------------------------------------------------------------------------+
| CURRENT STATUS -- Sort of broken                                                            |
|                                                                                             |
|   I currently use a USB to Ethernet adapter to run updates, etc. as wlan0 operation         |
|   is currently unreliable                                                                   |
|                                                                                             |
| * So what's busted?                                                                         |
|                                                                                             |
|   Upon boot, the ap0 interface comes up fine and I can both associate to it and             |
|   SSH into the Rpi0w.  The strange thing is that the wlan0 interface doesn't automatically  |
|   come up.  If I issue:                                                                     |
|                                                                                             |
|      sudo ifconfig wlan0 up                                                                 |
|                                                                                             |
|   everything then seems to work.. for a while.  After some random period of time            |
|   any association in the ap0 interface seems to stop responding (say from a smartphone      |
|   to the Rpi0w).  If I then cycle the Wifi on my phone, I can re-establish a connection     |
|   to the Rpi0w but now, the association from the rpi0w to remote AP via the wlan0 interface |
|   keeps flapping over and over.                                                             |
|                                                                                             |
|   To stop this, I have to either reboot (to disable the wlan0 interface from coming up)     |
|   edit the /etc/network/interfaces file and disable the two AP lines like:                  |
|                                                                                             |
|      #iface AP1 inet dhcp                                                                   |
|      #iface AP2 inet dhcp                                                                   |
|                                                                                             |
|      sudo ifconfig wlan0 down                                                               |
+---------------------------------------------------------------------------------------------+


31. DEPRECATED: Configure your Rpi Wifi in Adhoc mode using the RTL8192 Wifi devices


   +------------------------------------------------------------------------------------------+
   | IMPORTANT: 09/04/17 (was 08/14/16)                                                       |
   |                                                                                          |
   | This entire section and all of it's sub-sections are DEPRECATED!                         |
   |                                                                                          |
   | Why?  The RTL8192 code support for Linux has never been properly maintained and is most  |
   | likely probably completely broken now Raspbian Stretch and Jessie .  Consider buying a   |
   | Rpi v3 or Zero W with built-in Wifi instead and read the above section on how to get it  |
   | going.                                                                                   |
   |                                                                                          |
   |  Keeping this section around for posterity and it might help some Raspbian Wheezy users  |
   +------------------------------------------------------------------------------------------+

Configure your Rpi Wifi in Adhoc mode using the RTL8192 Wifi devices
--------------------------------------------------------------------

   - I have a Wifi device that has the 8192cu chipset but so many sites only talk to Atheros 
     (ath9k) and Broadcom (b43) chipsets and rarely give details about Realtek chips.  Why?
     It seems that Realtek has never really support with Linux.  

   - Various websites go and recommend to configure the use of the rtl871xdrv driver and not the rtl8192cu 
     driver that comes with the Raspbian distro but never say WHY

   - Many websites on the Internet to using a custom hostapd binary install from unknown sources to fix 
     known/broken code in the linux kernels 

   - Older pages talk about using different mechanisms to configure Linux to be a Wifi AP:

      - hostapd vs wicd
      - using bridging vs routing (uses iptables)
      - dnsmasq vs dhcpd

This is crazy!  Why is this?  Well, a few things I've learned in Aug, 2016:

   - It seems that Realtek never bothered to offer support of hostapd after they initially 
     contributed to the linux kernel and hostapd 0.8.x back in 2012:
     http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=1&PNid=48&PFid=48&Level=5&Conn=4&DownTypeID=3&GetDown=false&Downloads=true#RTL8188CUS

   - Beyond Realtek's initial support for some chips in the RTL 871x driver (no idea why the 
     different chip family number), it seems that the RTL8188cus drivers supports *all* rtl81xx 
     based support (including the rtl8188 and rtl8192cu).  A great write up on the background of
     all this can be found here:

        https://github.com/pritambaral/hostapd-rtl871xdrv
         and
        https://github.com/dz0ny/rt8192cu


Anyway, the very top of this post https://www.raspberrypi.org/forums/viewtopic.php?p=462982 talks to a scripted
setup to bring in new drivers for the TP-Link TL-WN725N V2 which uses the RTL8192cus chip.  This will work just fine
for my UL-Link device.



   # Recommended: hostapd and dnsmasq

      HostAP and a LB-Link BL-LW05-AR5 802.11n USB wifi device
        https://bogeskov.dk/UsbAccessPoint.html

   Other helpful sites:
   
      https://help.ubuntu.com/community/WifiDocs/WirelessAccessPoint
           and
      http://lcdev.dk/2012/11/18/raspberry-pi-tutorial-connect-to-wifi-or-create-an-encrypted-dhcp-enabled-ad-hoc-network-as-fallback/#comment-640
           and
      http://xmail.selfip.org/wordpress/?p=1
           and
      http://unix.stackexchange.com/questions/44851/setting-up-ad-hoc-in-debian-with-dhcp


The general recommendation for a Rpi based AP is to use hostapd and dnsmasq.  If you need more
advanced capabilities, you can consider replacing dnsmasq with the ISC dhcpd service instead

   https://learn.adafruit.com/downloads/pdf/setting-up-a-raspberry-pi-as-a-wifi-access-point.pdf


Anyway, for now, let's move forward with the Hostap + dnsmasq approach

31.a Picking what Wifi hardware to use:


   +-------------------------------------------+
   | 08/14/16                                  |
   | This section is DEPRECATED as the RTL8192 |
   | is not well maintained.  Consider buying  |
   | a Rpi v3 with built-in Wifi instead and   |
   | read the above section                    |
   +-------------------------------------------+


Not all Wifi chipsets are supported by Linux so it's important that you buy HW that will both
work under Linux but also support AP mode (not all HW does).  It's generally recommended to buy
a Wifi device that uses the Realtek RTL8188CUS chipset.  See http://elinux.org/RPi_USB_Wi-Fi_Adapters
for a comprehensive list of devices that are known to work.

Let's confirm the hardware you have is compatible so go ahead and plug in your Wifi dongle into 
a powered USB hub that's connected to your Rpi

#   NOTE:  Do **NOT** plug the dongle directly into your Rpi or it will most likely reboot
#          due to the excessive power draw.  You *must* use an alternative way to power the
#          AP dongle (such as a USB powered hub or maybe you're using a Wifi HATT with external
#          power support


First, confirm your Wifi USB device is seen by running:

   dmesg | less

This is what one of these very small USB Wifi nubs look like from Edimax:
http://www.savagehomeautomation.com/raspi-edimax-ew-7811un
--
[667667.424884] usb 1-1.2.1: New USB device found, idVendor=7392, idProduct=7811
[667667.424928] usb 1-1.2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[667667.424949] usb 1-1.2.1: Product: 802.11n WLAN Adapter
[667667.424968] usb 1-1.2.1: Manufacturer: Realtek
[667667.424998] usb 1-1.2.1: SerialNumber: 00e04c000001
[667668.197127] usbcore: registered new interface driver rtl8192cu
--

This is what one of these larger LB-Link BL-LW05-AR5 802.11n Wifi dongles with an attached 5dbi large Wifi antenna 
looks like:
--
[606160.906330] usb 1-1.3.1: new high-speed USB device number 6 using dwc_otg
[606161.008090] usb 1-1.3.1: New USB device found, idVendor=0bda, idProduct=8176
[606161.008121] usb 1-1.3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[606161.008138] usb 1-1.3.1: Product: 802.11n WLAN Adapter
[606161.008154] usb 1-1.3.1: Manufacturer: Realtek
[606161.008188] usb 1-1.3.1: SerialNumber: 00e04c000001
[606161.231855] usbcore: registered new interface driver rtl8192cu
[606161.861557] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
--



Next, see if the OS has automatically created the "wlan0" interface:

   /sbin/ifconfig 

--
wlan0     Link encap:Ethernet  HWaddr 44:33:4c:58:dd:fa
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
--


LEGACY notes for Realtek RTL8192cu support on Raspbian Wheezy (NOT recommended):
--
    If you use a Wifi USB dongle using the Realtek RTL8192cu (aka RTL8188CUS) chipset like
    the tiny Edimax EW-7811n device and you're using Raspbian Wheezy (not Jessie), you're 
    going need to read this below URL.  Specifically, as of 06/07/15, hostapd 1.0-3+deb7u2 
    was broken for the RTL8192 chip but was resolved in Jessie.  It's possible to  update 
    the hostap binary to fix this
   
       http://blog.sip2serve.com/post/38010690418/raspberry-pi-access-point-using-rtl8192cu
    
    This URL also gives more details and a possibly more supportable approach: 

       https://communities.intel.com/thread/60690

    Here are some of my legacy notes for this older install:

       If using a Realtek 8192 device, you need an alternative hostapd daemon:

          sudo mv /usr/sbin/hostapd /usr/sbin/hostapd.orig

       Next, you need to download the updated hostapd binary but it's too large to fit
       in the /tmp RAM drive.  As such, lets put it elsewhere:

          cd /var/tmp
          wget http://adafruit-download.s3.amazonaws.com/adafruit_hostapd_14128.zip

          Or and alternative download site:
             wget http://www.daveconroy.com/wp3/wp-content/uploads/2013/07/hostapd.zip

          unzip adafruit_hostapd_14128.zip
          sudo mv hostapd /usr/sbin
          sudo chmod 755 /usr/sbin/hostapd
          rm adafruit_hostapd_14128.zip
--

31.b Wifi AP with Direwolf


   +-------------------------------------------+
   | 08/14/16                                  |
   | This section is DEPRECATED as the RTL8192 |
   | is not well maintained.  Consider buying  |
   | a Rpi v3 with built-in Wifi instead and   |
   | read the above section                    |
   +-------------------------------------------+


Ok, assuming you're using *Raspbian Jessie* here, let's install the required software:

   sudo apt-get update
   sudo apt-get install firmware-realtek dnsmasq hostapd



Next, confirm the Wifi device can be interrogated:

   sudo iwconfig
   --
   wlan0     unassociated  Nickname:""
             Mode:Auto  Frequency=2.412 GHz  Access Point: Not-Associated
             Sensitivity:0/0
             Retry:off   RTS thr:off   Fragment thr:off
             Encryption key:off
             Power Management:off
             Link Quality:0  Signal level:0  Noise level:0
             Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
             Tx excessive retries:0  Invalid misc:0   Missed beacon:0

   lo        no wireless extensions.

   ax0       no wireless extensions.

   eth0      no wireless extensions.
   --

Confirm that your Wifi device can act as an AP as not all can as described above
If this command doesn't report back with a "0", you need to use a different Wifi 
USB device:

   sudo iwconfig wlan0 mode master
   echo $?

   If your HW doesn't' report a "0" above, read the above URLS as well as
   this HW identification URL:

      https://help.ubuntu.com/community/WifiDocs/MasterMode


AP or client mode
-----------------
There are a few ways to do this but I chose to use a GPIO switch to select if the 
Wifi should be an AP or a client.  In researching around, it sounds like some Realtek
devices can actually support AP and Client mode at the same time (STA+AP):

   http://randomstuffidosometimes.blogspot.com/2016/03/rtl8192cu-and-rtl8188cus-in-station-and.html

That's overkill for my needs but I thought I'd mention it.  Anyway, we need to disable 
the OS from starting the wlan0 device by default.  With changing this, we can start this 
function from /etc/rc.local.

   #For Jessie
   sudo systemctl disable hostapd

   #For Wheezy
   sudo update-rc.d hostapd disable


Now create and edit the /etc/hostapd/hostapd config file

   zcat /usr/share/doc/hostapd/examples/hostapd.conf.gz > /etc/hostapd/hostapd.conf


Now edit the file with the following settings:

   vim /etc/hostapd/hostapd.conf
   --
   #Wireless device name
   interface=wlan0

   #The bridge interface to connect to eth0
   bridge=br0

   #Wifi device driver depends on your USB device found above
   #  I'm using the LD-Link BL-LW05-AR5 device
   #
   #  EXPERIMENT - 08/13/16 - for a rtl8192cu device, do NOT specify ANY driver
   #                          and let it auto-discover
   #driver=rtl871xdrv
   #driver=rtl8192cu

   #Control interface for hostapd
   ctrl_interface=/var/run/hostapd

   #SSID announcement for this device - change this to be whatever you want
   ssid=ki6zhd

   #Specific country you are locate in - this is for the Unite States
   country_code=US

   #limit the allowed frequencies to specified country
   ieee80211d=1

   #This allows 802.11G but this will impact the performance of 802.11N networks
   #  If Wifi compatibility is more important than performance; set this to "g"
   hw_mode=g

   #enable 802.11n if your hardware supports it
   ieee80211n=1

   #Select the least used Wifi channel in your area - ch 0 will auto-select on the
   #  most available channel - alternatively, use 1,6,11 for the US
   channel=0

   #How often to send SSID broadcasts
   beacon_int=100

   #Station MAC address -based authentication
   # 0 = accept unless in deny list
   # 1 = deny unless in accept list
   macaddr_acl=0

   #If you want to hide your SSID broadcasts, set this to 1
   ignore_broadcast_ssid=0

   #allow WPA/WPA2 only - # 1=wpa, 2=wep, 3=both
   auth_algs=1

   #enable WPA2 only
   wpa=2

   #enable multi-media priority
   wmm_enabled=1

   #disassociate remote sessions that are taking on high errors
   #  enable this for better battery life; disable this to keep the link up at all costs
   #disassoc_low_ack=1

   #The WPA2 64 character HEX key or 8 to 63 character passphrase for your network
   #wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
   wpa_passphrase=YOURPASSPHASE

   #Use PSK and not EAP
   wpa_key_mgmt=WPA-PSK

   #Use AES encryption
   rsn_pairwise=CCMP

   #Support high performance wifi
   #  HT40+ : support both 20 MHz and 40 MHz BW with secondary channel ABOVE the primary channel
   #  HT40- : support both 20 MHz and 40 MHz BW with secondary channel BELOW the primary channel
   #  SHORT-GI-40 : Short GI for 40 MHz
   #  RX-STBC12 : one or two spatial streams
   #
   ht_capab=[HT40+][HT40-][SHORT-GI-40][RX-STBC12]

   #Don't refuse association with remote client if they don't support HT Phy negotiation
   require_ht=0
   --


Now update the SysV config startup script to load a custom config file:

  sudo vi /etc/default/hostapd
  --
  DAEMON_CONF="/etc/hostapd/hostapd.conf"
  --


# Next, edit the /etc/network/interfaces file
--
auto lo eth0 wlan0
iface wlan0 inet static
  address 10.10.10.1
  netmask 255.255.255.0
#allow-hotplug wlan0
--


POTENTIALLY OBSOLETE section - WHEEZY
  - Skip this section for now
---------------------------------------------------------------------------------------
--
Next, it's very important to disable Network-Manager from trying to manage this device 
From the output of the "ifconfig" command above, note the MAC address of your Wifi device
and change the MAC address in this file
#
vim /etc/NetworkManager/NetworkManager.conf
--
[keyfile]
unmanaged-devices=mac:44:33:4c:58:dd:fa
--


Set your Geo

   iw reg set US


Next. we need to configure the Bridge interface which will link the eth0 and wlan0 interfaces
together.  Add the following lines to the interfaces file and you can change the management IP 
address of this bridge group to whatever subnet you like:

vim /etc/network/interfaces
   --
   auto br0
   iface br0 inet static
           address 192.168.1.1
           netmask 255.255.255.0
           network 192.168.1.0
           broadcast 192.168.1.255
           bridge_ports none
           bridge_fd 1
           bridge_hello 1
           bridge_stp on
   --

Go ahead and manually start it with:

   ifup br0


#If things don't work right, try debugging with:
service hostapd stop
hostapd -dd /etc/hostapd/hostapd.conf


#----------------------------------------------------------------
# Legacy Wifi Ad-Hoc approach (works with Motorola Droid2 running Android GingerBread
# (does not work with LG G3 running Android Kitkat or Lolipop
#
#    see /usr/local/sbin/start-wireless-adhoc.sh for all details
#----------------------------------------------------------------

apt-get install dnsmasq dnsmasq-base dnsmasq-utils
#We only want it to start manually
update-rc.d dnsmasq remove

vim /etc/dnsmasq.conf
--
interface=wlan0
no-dhcp-interface=eth0
domain=rpi-trinnet.net
dhcp-range=10.10.10.10,10.10.10.150,255.255.255.0,12h
--

#Make the required dnsmask dir if it was removed
mkdir /var/run/dnsmasq/



sudo nano /etc/network/interfaces
--
#if there is any other line that has "auto lo" in it, REMOVE it

auto lo eth0 wlan0
iface lo inet loopback

iface eth0 inet dhcp

#This is intentionally set to manual to support the selection of client or server AP mode
iface wlan0 inet manual

allow-hotplug wlan0
--


Verify / Update the system's hostname:

  - Edit the /etc/hostname file and put the name of your raspberry Pi in there.  For example,
    I'm naming my unit "rpi3" so the line would read:

     rpi3


  - Next, edit the file /etc/hosts and update the line that has "127.0.0.1" to reflect your 
    desired raspberry pi fully qualified hostname (FQDN).  For example, I'm naming my unit 
    "rpi3.trinnet.net" so the line would read:

        127.0.0.1    rpi3.trinnet.net    rpi3    localhost


  - Now add your desired Rpi's hostname alias for local wireless network address

  - Add addresses to reflect any IP addresses enabled in the /etc/ax25/ax25ipd.conf file
     --
     1.1.1.1                 f3kt-0 f3kt.dyndns.org
     88.149.155.158          iz3lsv-0
     1.1.1.1                 on4hu-0 on4hu.be
     1.1.1.1                 k4gbb-0 k4gbb.servftp.com
     --

  - Confirm that the host recognizes it's new hostname with running:

       hostname -f


#Update the FBB stuff
  update the details in /etc/ax25/fbb/beacon0.sys

  port.sys needs updating too --RESEARCH--

  dir /etc/ax25/fbb needs sed search/replace for all CAPS F6BVP


#Update the default editor
update-alternatives --config editor

# ----------------


#Now configure your primary Wifi interface
ifconfig wlan0 down
sudo wpa_cli

#  Note: if this program won't start, pull out the USB Wireless device and put it 
#        back in again that should re-prod NetworkManager to get it running


#Now, get the name of any pre-configured wireless devices and put them into the 
# start-adhoc script
wpa_cli
 --> scan
 --> scan-results
 --> add_network
     --> set_network 0 ssid "enter-your-previously-shown-BSSID-here"
     --> set_network 0 psk "enter-your-wpa2-key-here"
     --> enable_network 0
     --> save_config


Get a copy of /usr/local/sbin/start-adhoc.sh


chmod 700 /usr/local/sbin/start-adhoc.sh


32. Various Rpi management, LED and Bluetooth tricks on the Rpi v3

This section covers various little sub-projects including:

   - Hardware review
   - Changing the behavior of the Rpi LEDs
   - Setting up Bluetooth for serial port access to a Kenwood TH-D74 radio

32.a - Monitoring the Raspberry Pi hardware and other scripts


I've posed various scripts to manage the hardware of your Raspberry Pi:

   - Monitor the CPU clocking, hardware temps, and serial number of your Raspberry Pi

     Get the script and required tools by running:

        #Install the classic calculator to support doing numeric conversions
        sudo apt install bc

        cd /tmp
        wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/bin/review-rpi-cpu.sh
        chmod 755 review-rpi-cpu.sh
        sudo mv review-rpi-cpu.sh /usr/local/bin


     Now try running it:
    
        /usr/local/bin/review-rpi-cpu.sh
        --
        Current CPU speed governor: (valid is 'powersave', 'ondemand'):
        ondemand

        Current CPU frequency:
        600000

        Max allowed frequency
        1200000

        SOC Temp (in Celsius) - DD.ddd
        48850
        GPU temp
        temp=49.4'C

        Rpi Serial number, model firmware and Warranty bit (MSB):
        Serial          : 000000005851234b
        Revision        : a22082
           value of a22082 is Pi 3 Model B - 1GB - made at Embest, China
        Broadcom firmware version:
        Aug 22 2017 14:20:40
        Copyright (c) 2012 Broadcom
        version eb51b8b84ec11d98562dfbb7be53cdd216c0ea4c (clean) (release)
    
        Confirm system will clock up to max CPU speed (turbo mode) by loading the CPUs and report new CPU frequency when at load
        1200000

        Done
        --


   Here are more scripts are available for doing specific tasks (some already mentioned in previous
   sections of this doc):

      - Ensure the new IPTABLES firewall takes place and doesn't lock you out (covered in the firewall 
        section of this document):
        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/firewall-confirm.sh

      - Clean up the file system a bit and remove old kernels
        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/filesystem-cleanup.sh
        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/remove-old-kernels.sh

      - Blank empty space for smaller system backups and take an image copy of your removed Rpi 
        micro-SD card for backup reasons
        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/zeroize-filesystem.sh
        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/image-rpi-sd-card.sh

      - Mounting and Unmounting external USB hard drive with a Linux LVM/EXT3 file system
        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/mount-usb-hd.sh
        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/mount-umount-lvm-partition.sh


Look in http://www.trinityos.com/HAM/CentosDigitalModes/RPi/ to see other potentially interesting 
scripts and tools as I post them!

32.b - LED tricks with the onboard Raspberry Pi LEDs


With the Rpi v3, the purpose of the red led (power) and green led (sd card)
is now programmable.  Specifically, with the green LED, you can can indicate any
of the following functions.  In this specific case, you can use the green
LED to show Wifi activity:

   #show the possible options with the current firmware (changes over time)
   cat /sys/class/leds/led0/trigger

   * Anything wrapped with [ ] means it's active

     none - does nothing
     kbd-scrollock  - status from the controlling keyboard
     kbd-numlock    - status from the controlling keyboard
     kbd-capslock   - status from the controlling keyboard
     kbd-kanalock   - status from the controlling keyboard
     kbd-shiftlock  - status from the controlling keyboard
     kbd-altgrlock  - status from the controlling keyboard
     kbd-ctrllock   - status from the controlling keyboard
     kbd-altlock    - status from the controlling keyboard
     kbd-shiftllock - status from the controlling keyboard
     kbd-shiftrlock - status from the controlling keyboard
     kbd-ctrlllock  - status from the controlling keyboard
     kbd-ctrlrlock  - status from the controlling keyboard
     [mmc0]         - activity on the microSD card slot
     mmc1           - activity on the Wifi interface
     timer          - monitor the timer 
     oneshot        - not sure on this one
     heartbeat      - monitor the broadcom watchdog timer
     backlight      - status of the DSI backlight
     gpio           - monitor a specific GPIO pin
     cpu0           - status of cpu0
     cpu1           - status of cpu1
     cpu2           - status of cpu2
     cpu3           - status of cpu3
     default-on     - on 100%
     input          - not sure what this is
     rfkill0        - show if the BT signal is admin disabled via rfkill
     rfkill1        - show if the wifi signal is admin disabled via rfkill


  To change the green LED to show Wifi activity instead of microSD activity, 
  issue the command:

    echo mmc1 > /sys/class/leds/led0/trigger

  This will be a temporary setting and the Rpi will revert to it's stock behavior
  after a reboot.  If you want to make this change permanent, add this command
  to the /etc/rc.local script.

32.c - Setting up Bluetooth on the Rpi for using Bluetooth keyboards


OPTIONAL: 

This section covers how to associate to Bluetooth keyboard to interact with the Rpi 
while viewing the display via the HDMI port.  This is all assuming you DIDN'T disable 
the bluetooth support on your Raspberry Pi (Rpi0W, 3, 3+, 4) via the raspi-config 
program in a previous chapter of this doc.

   NOTE:   If you want a BT keyboard to be used with your smartphone to control
           SSH sessions to your Raspberry Pi, you need to pair the keyboard to your 
           *smartphone* instead (not the Rpi itself).


   +------------------------------------------------------------------------------+
   | IMPORTANT DETAIL: 09/04/17                                                   |
   |                                                                              |
   | I have read in multiple places that the combo Wifi+Bluetooth support on the  |
   | RPi running simultaneously is not very reliable under load.  You might see   |
   | many disassociations and re-associations on the Wifi and/or Bluetooth side   |
   | when either system is busy.  It sounds like this could be limitations on the |
   | Raspberry Pi hardware but I personally haven't encountered this.  Maybe this |
   | issue can be fixed through newer firmware for the Raspberry Pi but I haven't |
   | seen much movement here.  Beware!                                            |
   +------------------------------------------------------------------------------+
   

   #Status of the BT interface
   #
   sudo hciconfig -a
   --
   hci0:   Type: BR/EDR  Bus: UART
           BD Address: B8:27:EB:xx:xx:xx  ACL MTU: 1021:8  SCO MTU: 64:1
           UP RUNNING
           RX bytes:717 acl:0 sco:0 events:42 errors:0
           TX bytes:1532 acl:0 sco:0 commands:42 errors:0
           Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
           Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
           Link policy: RSWITCH SNIFF
           Link mode: SLAVE ACCEPT
           Name: 'rpi3'
           Class: 0x000000
           Service Classes: Unspecified
           Device Class: Miscellaneous,
           HCI Version: 4.1 (0x7)  Revision: 0xb6
           LMP Version: 4.1 (0x7)  Subversion: 0x2209
           Manufacturer: Broadcom Corporation (15)
   --


   #You can also display the local MAC address with this interactive program
   #
   sudo bluetoothctl
      list
      exit
      
  
   #See any pairable bluetooth devices around you (try setting one of your nearby
   # bluetooth devices into discovery mode and give this command a try:
   #
   hcitool scan
   --
   Scanning ...
        00:1F:22:44:17:18       Ultrathin Keyboard Mini
   --


   From this point there are TWO ways to use Bluetooth:

      - The Raspberry Pi reaches out to the remote BT device to connect

      - The remote BT device reaches out to the Rpi to connect


   Here is an example Have the Rpi reach out and attach to a remote BT device (a keyboard):
   --
   # To pair to this BT wireless keyboard, use the following command which is more of an 
   # interactive command prompt:
   #
   sudo /usr/bin/bluetoothctl

      #Issue the following commands

      #Show available BT controllers
      list

      #Give more details on the local controller (change this example MAC address to match yours)
      show B8:27:EB:AA:AA:91

      #Show what might already be paired
      devices

      #Enable BT pairing

      agent on
      default-agent

      #Scan for available BT devices
      scan on

      # Initiate the pairing to the keyboard found above (change the BT mac address with
      # the device found in your area
      #
      #   NOTE: If you cannot read the displayed "Passkey" text, you need to 
      #         change your terminal's background font color to something other than white.
      #         Alternatively, try copying that line and pasting it into a different terminal
      #         window to see if you can read it
      #         
      pair 00:1F:22:35:17:18

      #  If challenged for a "PIN code", enter that "PIN code" on your BT keyboard 
      #  and press ENTER on the bluetooth keyboard

      #Remember the device
      trust 00:1F:22:35:17:18

      #reconnect to the device on reboot
      connect 00:1F:22:35:17:18

      #to permanently remove a pairing
      disconnect 00:1F:22:35:17:18
      remove 00:1F:22:35:17:18

      #to exit bluetoothctl but leave BT fully working 
      exit

32.d - Setting up a serial console using a Bluetooth connection


-------------------------------------------------------------------------------------------
WIP: This section is still being worked on : this all works but the automatic startup after 
     a reboot is not completed
-------------------------------------------------------------------------------------------


Serial consoles are a way to login and troubleshoot your system when the usual network type access via
say local HDMI console, eth0, Wifi, etc. is not working or not available.  With Linux serial console, 
there are TWO general types of consoles:

   - consoles with the kernel booting details - this is ONLY available via the GPIO-pin based
     serial port

   - console without the kernel booting details - this can be on any serial port including bluetooth
     connections, USB to serial adapters, etc


NOTE:  This section CONFLICTS with the TNC-Pi section mentioned later in this document as the TNC-Pi
       uses the GPIO serial pins for it's default configuration.  You CAN configure the TNC-Pi to 
       alternatively use the I2C-bus for communications but that's not detailed in this document.


NOTE#2: This section does NOT check nor test any other uses of Bluetooth such as Bluetooth audio, etc.
        If you do run into issues, I can try to give you a hand to address your issue but it's possible
        that both Bluetooth serial and Bluetooth audio running at the same time might not be possible.


Some details from this section came from the following URL:

   https://hacks.mozilla.org/2017/02/headless-raspberry-pi-configuration-over-bluetooth/

   This documentation expanded upon it to make the connections more secure as well as provide
   troubleshooting steps along the way to make sure things are working as expected


To get a Bluetooth serial console session (without kernel booting text) working, follow these steps:


   1. Enable the serial console option on the Rpi via the raspi-config tool

           sudo raspi-config --> Interface Options --> Serial Port --> YES --> Ok --> Finish

           On older Raspbian releases, you would find this in :
              sudo raspi-config --> Advanced Options --> Serial --> YES --> Ok --> Finish


   2. IMPORTANT:  reboot your Raspberry Pi to make sure everything gets enabled


   3. Install some security tools for Bluetooth

      sudo apt install bluez bluez-test-scripts
      cd /usr/share/doc/bluez-test-scripts/examples
      sudo gunzip simple-agent.gz
      sudo cp simple-agent simple-agent.py


   4. Confirm you're seeing both the hardware UART and the software UART:

      NOTE:  the number of serial ports on your Rpi depends on which Rpi model you're using.
             For example, below is valid for a Raspberry Pi 3B+ or a Raspberry Pi 0-W:

         ls -la /dev/serial?
         --
         lrwxrwxrwx 1 root root 5 Apr 16 10:43 /dev/serial0 -> ttyS0
         lrwxrwxrwx 1 root root 7 Apr 16 10:43 /dev/serial1 -> ttyAMA0
         --

      In modern versions of the Raspberry Pi OS "Buster", the /dev/serial/ttyAMA0 device is the on-board 
      *hardware* UART mapped to be used with Bluetooth services.  

         NOTE: Some of the newer Raspberry Pi models like the Rpi4 and CM4 have additional hardware UARTs 
               but they aren't available unless you enable alternative DevTree configuration and thus you 
               swap out the use of valuable GPIO, I2C, etc. options for these UART connections.  

      The /dev/ttyS0 is what's call the "mini-uart" or *software* emulated serial port.  This is the serial
      port connected to the GPIO pins.  For serial console needs, this software emulation is usually ok but
      it CAN experience issues.  If the AMA0 device is NOT seen, you need to try using the "sudo raspi-config" 
      step shown above again, check your settings, and then reboot.


   5. Confirm the kernel messages sent to the GPIO-pin based serial console is enabled AND enabled on the 
      correct port.  Look at the /boot/cmdline.txt file and confirm the following text is there:

         console=serial0,115200

      If you don't see it, I recommend you try step #1 above again.  If that still doesn't work, you can manually 
      add the text in.  As an example, this is what I have in my system running Raspberry Pi OS "Buster" version:

         dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=4351cdc6-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait



   5. Make sure there is a getty daemon configured to use /dev/ttyAMA0

      ps aux | grep getty
 
      If you see something like the following with the "ttyAMA0" device in the output, you're good:
         --
         root       543  0.0  0.3   6600  1828 ttyS0    Ss+  07:17   0:00 /sbin/agetty -o -p -- \u --keep-baud 115200,38400,9600 ttyS0 vt220
         root       546  0.0  0.3   4292  1752 tty1     Ss+  07:17   0:00 /sbin/agetty -o -p -- \u --noclear tty1 linux
         --

      If you don't see the ttyS0 text, re-check the enabling of the serial console above and reboot your Rpi and try again.  



   6. Confirm the Bluetooth system is now working:

      - Either use the command "hcitool dev" to get brief details 

            --
            Devices:
            hci0	B8:27:EB:xx:xx:xx
            --

         or use "hciconfig" to get deeper details:
   
            sudo hciconfig -a

            --
            hci0:   Type: BR/EDR  Bus: UART
                    BD Address: B8:27:EB:xx:xx:xx  ACL MTU: 1021:8  SCO MTU: 64:1
                    UP RUNNING
                    RX bytes:717 acl:0 sco:0 events:42 errors:0
                    TX bytes:1532 acl:0 sco:0 commands:42 errors:0
                    Features: 0xbf 0xfe 0xcf 0xfe 0xdb 0xff 0x7b 0x87
                    Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
                    Link policy: RSWITCH SNIFF
                    Link mode: SLAVE ACCEPT
                    Name: 'rpi3'
                    Class: 0x000000
                    Service Classes: Unspecified
                    Device Class: Miscellaneous,
                    HCI Version: 4.1 (0x7)  Revision: 0xb6
                    LMP Version: 4.1 (0x7)  Subversion: 0x2209
                    Manufacturer: Broadcom Corporation (15)
            --

      If you DON'T see any controller information from either command, try running the following 
      commands to see if there might be some conflicting daemons running.  If these processes 
      are running, you won't be able to even see the Bluetooth controller (lame):

        sudo systemctl | grep ttyAMA0

          Do you see anything like the following below?
          --
          sys-devices-platform-soc-20201000.serial-tty-ttyAMA0.device      
               loaded active plugged   /sys/devices/platform/soc/20201000.serial/tty/ttyAMA0

          serial-getty@ttyAMA0.service 
               loaded active running   Serial Getty on ttyAMA0 
          --

             If you do see those ttyAMA0 lines, run the following commands:

                sudo systemctl stop serial-getty@ttyAMA0.service
                sudo systemctl disable serial-getty@ttyAMA0.service
                

   7. Modify the SystemD Bluetooth startup scripts to enable LEGACY compatibility needed for 
      serial support

      I can confirm this "legacy" bluetooth mode is STILL required in Raspberry Pi OS Buster with 
      the 5.10.17 kernel and bluez_5.50-1.2~deb10u1+rpt2 package


      7.a. To enable legacy bluetooth support, you need to modify the Systemd unit file and add 
           the "-c" option:

         sudo vim /lib/systemd/system/bluetooth.service
         --
         ExecStart=/usr/lib/bluetooth/bluetoothd -C
         ExecStartPost=/usr/bin/sdptool add SP
         ExecStartPost=/bin/hciconfig hci0 auth
         ExecStartPost=/bin/hciconfig hci0 encrypt
         ExecStartPost=/bin/hciconfig hci0 piscan
         --

      7.b.  Create a new systemd unit

          To associate the Bluetooth connection to a serial service, we need to enable the rfcomm
          program.   I am using the "-A" Authentication, "-E" Encrypted", and "-S" Secure options
          for the best security possible.  

             NOTE: The "-S" option will ONLY work if you used the simple-agent.py tool.  If you didn't, 
                   the use of -S here will BREAK the pairing entry on the linux side and you'll have to 
                   DELETE that pairing and start over.  It will NEVER work unless you do that

             NOTE #2: While I don't recommend it, you can add "-a pi" and change the "pi" username
                      to whatever username you want to automatically login without any password

          sudo vim /etc/systemd/system/rfcomm.service
          --
          [Unit]
          Description=RFCOMM service
          After=bluetooth.service
          Requires=bluetooth.service

          [Service]
          ExecStart=/usr/bin/rfcomm -A -E -S watch hci0 1 getty rfcomm0 115200 vt100

          [Install]
          WantedBy=multi-user.target
          --

      7.c. Restart the Bluez bluetooth control plane

           sudo systemctl daemon-reload
           sudo systemctl restart bluetooth.service
           sudo systemctl enable rfcomm
           sudo systemctl start rfcomm

      7.d. Confirm Bluez is now running with the "-C" option as well as the other options are running

           ps aux | grep -e bluetoothd -e rfcomm
           --
           root      1187  0.0  0.0      0     0 ?        S<   Apr22   0:00 [krfcommd]
           root      3579  0.1  0.9   9876  4776 ?        Ss   14:37   0:00 /usr/lib/bluetooth/bluetoothd -C
           root      3608  0.0  0.2   2088  1240 ?        Ss   14:37   0:00 /usr/bin/rfcomm -A -E -S watch hci0 1 getty rfcomm0 115200 vt100
           --

   8. Review currently enabled BT features

            #view all basic settings
            sudo /bin/hciconfig hci0
            --
            hci0:	Type: Primary  Bus: UART
            BD Address: B8:27:EB:xx:xx:xx  ACL MTU: 1021:8  SCO MTU: 64:1
            UP RUNNING 
            RX bytes:3272 acl:0 sco:0 events:187 errors:0
            TX bytes:7056 acl:0 sco:0 commands:187 errors:0
            --

         and 

            #view all extended BT profile settings
            sudo /usr/bin/bluetoothctl show
            --
            Controller B8:27:EB:xx:xx:xx (public)
            Name: rpi0w-2
            Alias: rpi0w-2
            Class: 0x00000000
            Powered: yes
            Discoverable: no
            Pairable: yes
            UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
            UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
            UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
            UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
            UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
            Modalias: usb:v1D6Bp0246d0532
            Discovering: no
            --

         Notice that the controller is "powered", NOT discoverable, it IS pairable, and it's
         NOT discovering (looking to pair to other devices like keyboards, etc)


   9. Confirm all new settings are operational:

         #Notice there is now "PSCAN ISCAN AUTH ENCRYPT" attributes enabled
         sudo /bin/hciconfig hci0
         --
         hci0:	Type: Primary  Bus: UART
                   BD Address: B8:27:EB:xx:xx:xx  ACL MTU: 1021:8  SCO MTU: 64:1
                   UP RUNNING PSCAN ISCAN AUTH ENCRYPT 
                   RX bytes:3300 acl:0 sco:0 events:191 errors:0
                   TX bytes:7107 acl:0 sco:0 commands:191 errors:0
         --

      and

         #Notice the BT is now showing "pairable" 
         sudo /usr/bin/bluetoothctl show
         --
         Controller B8:27:EB:xx:xx:xx (public)
         Name: rpi0w-2
         Alias: rpi0w-2
         Class: 0x00000000
         Powered: yes
         Discoverable: yes
         Pairable: yes
         UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
         UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
         UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
         UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
         UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
         Modalias: usb:v1D6Bp0246d0532
         Discovering: no
         --
 

  10.  Create a Bluetooth secure authentication script

          sudo vim /usr/local/sbin/bt-do-secure-pairing.sh
          --
          #!/bin/bash

          # 04/24/21

          echo -e "\nBegin secure pairing with remote device.  Hit control-c to exit once complete\n"
          /usr/bin/bluetoothctl pairable on
          /usr/bin/bluetoothctl discoverable on

          echo " "
          sudo python3 /usr/share/doc/bluez-test-scripts/examples/simple-agent.py

          echo -e "\nOnce Pairing completed.  Disabling pairing and discoverable mode:"
          
          /usr/bin/bluetoothctl pairable off
          /usr/bin/bluetoothctl discoverable off
          echo -e "\nScript is exiting\n"
          --

          #Make it executable
          sudo chmod 700 /usr/local/sbin/bt-do-secure-pairing.sh
          

  11.  Run bluetooth secure authentication script

          sudo /usr/local/sbin/bt-do-secure-pairing.sh

             # You will see some warnings but it should run fine
             --
             /usr/share/doc/bluez-test-scripts/examples/simple-agent.py:156: PyGIDeprecationWarning: GObject.MainLoop is deprecated; use GLib.MainLoop instead
  mainloop = GObject.MainLoop()
             Agent registered
             --

       NOTE #1: Be ready to come back to this window to accept the pairing coming in the next few steps

       NOTE #2:  You CANNOT run this script in the background as you will have to approve the bluetooth paring.
              More on this below


  12.  Let's get your BT device paired:
       
       a. On your Android phone under System settings --> Connections --> Bluetooth --> Network
          and find your Rpi in the list.  Select your Raspberry Pi entry to start the pairing

       b. You should see something like the following:
          --
          Bluetooth pairing request:

             Passkey: 
             Pair with rpi0w-2?
                Cancel or OK?
          --
          Select OK

       c. Back on the main terminal on your Raspberry Pi where you started the "simple-agent.py" program, 
          you should see the following prompt:
          --
          RequestConfirmation (/org/bluez/hci0/dev_58_B1_0F_XX_XX_XX, 553510)
          Confirm passkey (yes/no):
          --

          Type in "yes" and hit enter to ACCEPT the pairing request

       d. At this point, a few seconds will pass and the Raspberry Pi should now be listed
          as paired.  If this doesn't happen, you need to recheck your steps from above
          but this MUST happen or you cannot move forward


  13.  Now that pairing is complete, exit the bt-do-secure-pairing.sh script

       a. On the Raspberry Pi where you are running the "bt-do-secure-pairing.sh", now hit control-c
          to exit that process as well as disable future pairing and remove your Raspberry Pi from being
          discoverable.  You will see the following error but don't worry about it
          --
          ^CTraceback (most recent call last):
            File "/usr/share/doc/bluez-test-scripts/examples/simple-agent.py", line 180, in  mainloop.run()
            File "/usr/lib/python3/dist-packages/gi/overrides/GLib.py", line 498, in run super(MainLoop, self).run()
            File "/usr/lib/python3.7/contextlib.py", line 119, in __exit__ next(self.gen)
            File "/usr/lib/python3/dist-packages/gi/_ossighelper.py", line 251, in register_sigint_fallback signal.default_int_handler(signal.SIGINT, None)
          KeyboardInterrupt

          Pairing completed.  Disabling pairing and discoverable mode:
          Changing pairable off succeeded
          Changing discoverable off succeeded

          Script is exiting
          --


  14.  Curious what your pairing info looks like, try this:

       Run this command to see details about your pairing record.  You will need to put
       in the correct MAC address corresponding to the device you want to look at.  In
       this example, I'm going to look at BOTH devices.  

          sudo /usr/bin/bluetoothctl devices
          --
          Device 9C:FC:E8:XX:XX:XX LAPTOP-F63LDUTG
          Device 58:B1:0F:XX:XX:XX David's Galaxy device
          --


       Here is the Galaxy phone first:

          sudo /usr/bin/bluetoothctl info 58:B1:0F:XX:XX:XX
          --
          Device 58:B1:0F:XX:XX:XX (public)
          Name: David's Galaxy Device
          Alias: David's Galaxy Device
          Class: 0x005a020c
          Icon: phone
          Paired: yes
          Trusted: yes
          Blocked: no
          Connected: no
          LegacyPairing: no
          --

          NOTE:  Notice that the pairing is listed as "trusted".  That's important for
                 secure bluetooth sessions


       Here is a Windows 10 laptop just for comparison sake (notice there is a LOT more
       available information captured here via UUID items):

          sudo /usr/bin/bluetoothctl info 9C:FC:E8:XX:XX:XX
          --
          Device 9C:FC:E8:XX:XX:XX (public)
          Name: LAPTOP-F63LXXXX
          Alias: LAPTOP-F63LXXXX
          Class: 0x002a010c
          Icon: computer
          Paired: yes
          Trusted: yes
          Blocked: no
          Connected: no
          LegacyPairing: no
          UUID: Service Discovery Serve.. (00001000-0000-1000-8000-00805fxxxxxx)
          UUID: Audio Source              (0000110a-0000-1000-8000-00805fxxxxxx)
          UUID: Audio Sink                (0000110b-0000-1000-8000-00805fxxxxxx)
          UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805fxxxxxx)
          UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805fxxxxxx)
          UUID: PANU                      (00001115-0000-1000-8000-00805fxxxxxx)
          UUID: Handsfree                 (0000111e-0000-1000-8000-00805fxxxxxx)
          UUID: Handsfree Audio Gateway   (0000111f-0000-1000-8000-00805fxxxxxx)
          UUID: PnP Information           (00001200-0000-1000-8000-00805fxxxxxx)
          UUID: Vendor specific           (c7f94713-891e-496a-a0e7-983a09xxxxxx)
          Modalias: bluetooth:v0006p0001d0A00
          --


  15.  Next up, install a Bluetooth Serial terminal and connect to your Rpi

       a. On your Android phone, you now need to install a Bluetooth serial terminal application

          I can recommend the "Serial Bluetooth Terminal" app by Kai Moriach on the Google Play store 
          as it's simple, intuitive and seems to do what you would expect.  There are *MANY* other 
          programs out there but most of them are not suitable for being a "console terminal"

          This recommended app has a graphic of a yellow DB9 RS232 plug with a bluetooth icon on it 
          pointing to the right.

             - I don't have recommendations for Apple iPhones - email me if you find a good app)

             - I currently don't have any instructions for other OSes but here are some links I found:
               Linux:
                      none yet
               Windows: 
                  1. Understanding the weird behavior of Windows and dual com ports
                     https://blog.bachi.net/?p=9700

                  2. How to configure the COM ports to match against BT pairings
                      https://www.collideabq.com/2016/04/28/bluetooth-serial-connection-with-windows-10/
                        - Highlights additional steps to mate the BT pairing to a COM port
                        - recommends one terminal program on the Microsoft store
               Mac:
                      none yet

       b. Start up the newly installed "Serial Bluetooth Terminal" app

       c. In the upper left corner, click on the four horizontal bar icon (settings) and select:

          c.1. Settings
                  Terminal tab
                     Display mode: Terminal
                     Show timestamps: off
                  Send:
                     Local Echo: off

          c.2. Devices - In the shown paired devices list, find your newly paired Raspberry Pi entry 
               and select it

               If everything works, you should see in the app:
               --
               Connecting to <your raspberry pi's name>
               Connected

               Raspbian GNU/Linux 10 hostname rfcomm0

               hostname login: 
               --


               On the Raspberry Pi's "rfcomm" process side, you should see:
               --
               Connection from 58:B1:0F:XX:XX:XX to /dev/rfcomm0
               Press CTRL-C for hangup
               --

          d. Try logging in with your Raspberry Pi credentials and you should be able to get down
             to a shell prompt!

          e. If that works, that's great!  Now I recommend to log out from the shell session using
             "exit" and then touch the "plug" icon to the left of the trashcan icon on the Bluetooth 
             serial console app to disconnect the low level bluetooth session


TBD:
----
  - Consider Enable discoverable / pairable via a GPIO connected button




# Bluetooth Appendix information
# ------------------------------

The state of bluetooth security is quirky and sometimes kludgy at times.  Here are some of my
misc notes on some behaviors I've seen:

   - If you don't care about bluetooth security authentication and encryption, you can SKIP 
     the above step running "simple-agent.py" security agent.  To do so, you could consider the 
     following:

        /bin/hciconfig hci0 sspmode 1

       NOTE: "sspmode 0" will present a PIN challenge to the BT client but it never complete the pairing
             WITHOUT the simple-agent.py to acknowledge the request and them marking the pairing as
             "trusted"


   - I don't know what "secmgr" option is and it's mentioned in the man page but isn't supported in the
     actual hciconfig tool:

        /bin/hciconfig hci0 secmgr

   - Other thoughts on Bluetooth transport security:

     weakest: this doesn't use authentication or encryption or require trusted pairings but it works
              /usr/bin/rfcomm watch hci0 1 getty rfcomm0 115200 vt100


     stronger: enables authentication and encryption but doesn't require the simple-agent.py tool
             /usr/bin/rfcomm -A -E watch hci0 1 getty rfcomm0 115200 vt100

     strongest: requires the simple-agent.py tool to not only create interactive pairing prompts on both
                the BT client and server, but does other things to the pairing.  If you try this "-S" option
                with a pairing that NOT done with the "simple-agent.py", that pairing will become corrupted
                and be no longer usable for ANY sessions.  You will have to delete that pairing on the Linux 
                side and start over:
                /usr/bin/rfcomm -A -E -S watch hci0 1 getty rfcomm0 115200 vt100

   
   - Details on the simple-agent.py and some of it's advanced modes:
      https://www.raspberrypi.org/forums/viewtopic.php?t=195090
    
            ./simple-agent.py                    - the default mode here is to acknowledge the pairing on the Linux 
                                                   side with only an interactive accept-only prompt on the client
    
            ./simple-agent.py -c NoInputNoOutput - this is the same "sspmode 1"; instantly pairs the client to server
                                                   without any prompting, any PIN, etc
    
            ./simple-agent.py -c DisplayOnly     - Requires acknowledgement of the pairing PIN code on the client side 
                                                   as well as requiring a Yes/No PIN acceptance prompt on the server side
    
            More secure but very more cumbersome
            ./simple-agent.py -c KeyboardOnly    - this requires you type in the paring PIN on the Linux side that is 
                                                   then displayed on the client side
    
            ./simple-agent.py -c DisplayYesNo    - this requires you acknowledge the pairing on the server side only
    
            ./simple-agent.py -c KeyboardDisplay - acknowledge the pairing PIN code on the client side with a Yes/No 
                                                   interactively confirmation of the PIN on the serverside


   - If you ever delete the BT pairing from your phone (client) or you enable "secure connections" on the Linux side, 
     you'll need to delete the stored pairing from the server / Linux side with:

     #Show all current stored BT pairings
     /usr/bin/bluetoothctl devices

     #Delete a specific pairing
     /usr/bin/bluetoothctl remove <BT MAC ADDRESS of your phone>
     bluetoothctl remove xx:xx:xx:xx:xx:xx

32.e - Setting up Bluetooth on the Rpi for pairing to a Kenwood D74 KISS TNC

   ----------------------------------------------------------------------------
    All of the steps in this section are required to be followed before
    pairing and operation of the D74's KISS TNC is possible
   ----------------------------------------------------------------------------

   To get started, you need to get the D74 setup:

      1. On the D74, turn on the radio and use the A/B button to select the BOTTOM 
         VFO or VFO-B as this is the only VFO that the built-in TNC works on.

      2. Tap the function + 5 key until the D74's display says "KISS 12"

      3. For now, put the radio into high power mode by pressing F + Menu
         until the display shows "H" for HIGH power

      4. Enable the D74 Bluetooth engine by pushing:
         Menu -> Configuration -> Bluetooth -> Bluetooth: ON


   Ok, the radio is now ready to go so on to the Raspberry Pi!  Now you
   need to make sure the Raspberry 0w, 3, or 3B+ has it's bluetooth setup
   right (and bluetooth is enabled if you previously disabled it):

   sudo /usr/bin/bluetoothctl

      #Issue the following commands

      #Show available BT controllers
      list

      #Give more details on the local controller (change this example MAC address to match yours)
      show B8:27:EB:AA:AA:91

      #Show what might already be paired
      devices

      #Enable Bluetooth pairing
      agent on
      default-agent

      #Scan for available BT devices
      scan on

      # At this point, you're going to want to WAIT until you see the D74's BT MAC show up in
      # the scan output.  After 10-20 seconds, the D74's BT mac address should show up on the 
      # command line tool looking like:
      #
      #    [NEW] Device 24:71:89:96:de:AB TH-D74
      #
      # This output MUST show up before you move on and actually do a pairing or # the program 
      # will give the error:
      #
      #   Device 24:71:89:96:de:AB  not available


      # Now initiate the pairing mode on the D74 with going into:
      #
      #   Menu --> Configuration -> Bluetooth -> Pairing Mode
      #

      # Now issue the command to start the pairing:
      pair 24:71:89:96:DE:AB

      # You should now see on the D74's display, the BT pairing code.  The bluetoothctl program
      #  should prompt you with offering AUTO-ENTER in the BT passcode such as:
      #
      #    Request confirmation
      #    [agent] Confirm passkey 285481 (yes/no): yes

      # Accept the pairing by typing in in "yes" (without the quotes and don't just use "y") and hit enter

         yes

      # *CRITICAL*: On the TH-D74, quickly hit the upper right button for the Bluetooth Pair's "OK".  If
      # you do this in time, the D74 should say:
      #
      #    Information:   Pairing is completed.  
      #
      # Select "OK" on the D74 to dismiss this script

      # On the Rpi, you should see:
      #
      #   [agent] Confirm passkey 285481 (yes/no): yes
      #   [CHG] Device 24:71:89:96:de:AB UUIDs: 00001101-0000-1000-8000-00805f9b34fb
      #   [CHG] Device 24:71:89:96:de:AB UUIDs: 00001112-0000-1000-8000-00805f9b34fb
      #   [CHG] Device 24:71:89:96:de:AB ServicesResolved: yes
      #   [CHG] Device 24:71:89:96:de:AB Paired: yes
      #   Pairing successful
      #   [CHG] Device 24:71:89:96:de:AB ServicesResolved: no
      #   [CHG] Device 24:71:89:96:de:AB Connected: no

      
      # Don't worry about it showing "Connected: no", this is normal

      # Now Save this pairing permanently with 
      trust 24:71:89:96:DE:AB

      # You should see the trust acknowledgment with:
      #
      #   Changing 24:71:89:96:DE:AB trust succeeded 


      # For whatever reason, if you wanted to remove the D74 pairing such as if you upgraded the 
      # D74's firmware and though you made a backup with the Kenwood MCP program, it didn't save
      # any BT pairings and now you have to re-pair the radio, you can do:
      #  remove 24:71:89:96:DE:AB


      # Ok, you should be good now!  For those who are curious, you can learn a little more about 
      # these Bluetooth UUIDs with:
      #
         info 24:71:89:96:de:AB
         --
         Device 24:71:89:96:de:AB
                 Name: TH-D74
                 Alias: TH-D74
                 Class: 0x620204
                 Icon: phone
                 Paired: yes
                 Trusted: yes
                 Blocked: no
                 Connected: no
                 LegacyPairing: no
                 UUID: Serial Port               (00001101-0000-1000-8000-00805f9b34fb)
                 UUID: Headset AG                (00001112-0000-1000-8000-00805f9b34fb)
                 RSSI: -71
                 TxPower: 4
         --



      # Notice a few things the above bluetooth output:
      #
      #   1. The two UUIDs shown above
      #
      #   2. It went from ServicesResolved: Yes" to "ServicesResolved: no"
      #
      #   For Item #1 above, that's showing the found bluetooth "services" from the remote 
      #   BT device.  Let's learn more about those services by issuing the next command 
      #   to see what detailed BT services the D74 offers.  The important information you 
      #   get from this output is:
      #
      #      The top entry is for the Audio side using Bluetooth profiles: 
      #           0x1112 (input) and 0x1203 (output) on Bluetooth channel #1
      #
      #      The second entry is for the serial port using Bluetooth profile:
      #           "Serial Port" (0x1101) on channel #2
      
      # In different Unix terminal window than where you are currently running the 
      # program "bluetoothctl", issue the command:

         sdptool browse 24:71:89:96:DE:AB

      # Here, you'll see all kinds of details:
         --
         Browsing 24:71:89:96:DE:AB ...
         Service RecHandle: 0x10000
         Service Class ID List:
           "Headset Audio Gateway" (0x1112)
           "Generic Audio" (0x1203)
         Protocol Descriptor List:
           "L2CAP" (0x0100)
           "RFCOMM" (0x0003)
             Channel: 1
         Language Base Attr List:
           code_ISO639: 0x656e
           encoding:    0x6a
           base_offset: 0x100
         Profile Descriptor List:
           "Headset" (0x1108)
             Version: 0x0102

         Service Name: Serial Port
         Service RecHandle: 0x10001
         Service Class ID List:
           "Serial Port" (0x1101)
         Protocol Descriptor List:
           "L2CAP" (0x0100)
           "RFCOMM" (0x0003)
             Channel: 2
         Language Base Attr List:
           code_ISO639: 0x656e
           encoding:    0x6a
           base_offset: 0x100
         Profile Descriptor List:
           "Serial Port" (0x1101)
             Version: 0x0100
         --

      # As you can see above, the D74 is offering both audio in/out, and a serial port.  That's good!
      # You'll also notice in the bluetoothctl window, it showed that it connected and disconnected:
        --
        [CHG] Device 24:71:89:96:DE:AB Connected: yes
        [CHG] Device 24:71:89:96:DE:AB Connected: no
        --

      # Assuming that all worked, type in "exit" in the terminal window running the bluetoothctl tool 


      # Now for the bad part for item #2.  Let's confirm some things ARE or AREN'T properly working 
      # on your Raspberry Pi.  Try running the following command:

         sudo sdptool browse local
         --
         Failed to connect to SDP server on FF:FF:FF:00:00:00: No such file or directory
             or
         Failed to connect to SDP server on FF:FF:FF:00:00:00: Permission denied
             or
         Failed to connect to SDP server on FF:FF:FF:00:00:00: Connection refused
         --

      # Did the command fail?  If so, you probably have have version 5.x of the "bluez" Linux Bluetooth stack.  
      # It's known to be broken for the sdptool but a work around is available.  You can read more about 
      # this here:
      #
      #    https://raspberrypi.stackexchange.com/questions/41776/failed-to-connect-to-sdp-server-on-ffffff000000-no-such-file-or-directory
      #
      # The work around is to edit the following file:
    
         vim /etc/systemd/system/dbus-org.bluez.service

         # Find the "ExecStart" line and append "-C" to the end of that line to enable Compatibility mode


     # Now tell Systemd to recognize the modified configuration files and to restart
     # the Bluetooth service

        sudo systemctl daemon-reload
        sudo systemctl restart bluetooth


     # With the Bluetooth service restarted, it now created a new system device.  Confirm the SDP device
     # was created with running:

       ls -la /var/run/sdp
       --
       srw-rw---- 1 root root 0 Dec 24 10:53 /var/run/sdp
       --


     # Again, try the sdptool command and hopefully it now works:
    
        sudo sdptool browse local
        --
        Browsing FF:FF:FF:00:00:00 ...
        Service RecHandle: 0x10000
        Service Class ID List:
          "PnP Information" (0x1200)
        Profile Descriptor List:
          "PnP Information" (0x1200)
            Version: 0x0103

        Browsing FF:FF:FF:00:00:00 ...
        Service Search failed: Invalid argument
        Service Name: Generic Access Profile
        Service Provider: BlueZ
        Service RecHandle: 0x10001
        Service Class ID List:
          "Generic Access" (0x1800)
        Protocol Descriptor List:
          "L2CAP" (0x0100)
            PSM: 31
          "ATT" (0x0007)
            uint16: 0x0001
            uint16: 0x0005

        Service Name: Generic Attribute Profile
        Service Provider: BlueZ
        Service RecHandle: 0x10002
        Service Class ID List:
          "Generic Attribute" (0x1801)
        Protocol Descriptor List:
          "L2CAP" (0x0100)
            PSM: 31
          "ATT" (0x0007)
            uint16: 0x0006
            uint16: 0x0009

        Service Name: AVRCP CT
        Service RecHandle: 0x10003
        Service Class ID List:
          "AV Remote" (0x110e)
          "AV Remote Controller" (0x110f)
        Protocol Descriptor List:
          "L2CAP" (0x0100)
            PSM: 23
          "AVCTP" (0x0017)
            uint16: 0x0103
        Profile Descriptor List:
          "AV Remote" (0x110e)
            Version: 0x0106

        Service Name: AVRCP TG
        Service RecHandle: 0x10004
        Service Class ID List:
          "AV Remote Target" (0x110c)
        Protocol Descriptor List:
          "L2CAP" (0x0100)
            PSM: 23
          "AVCTP" (0x0017)
            uint16: 0x0103
        Profile Descriptor List:
          "AV Remote" (0x110e)
            Version: 0x0105
        --

        # TO BE CONFIRMED if this is NEEDED (I don't think it is)
        #   It's mentioned that the permissions of this /var/run/sdp need to be "other" read and
        #   writable.  To do that, issue the command:
        #
        chmod 666 /var/run/sdp



     # At this point, let's try connecting to the D74 with the following MANUAL test.  This test
     #  will read the output of the GPS and send it to the Bluetooth interface
     #
     #  1. On the D74, go into Menu --> GPS --> Basic Settings --> 
     #        Built-in GPS: On
     #        PC Output: On
     #
     #  2. On the D74, go into Menu --> Configuration --> Interface --> 
     #        PC Output  (GPS): Bluetooth
     #        PC OUtput (APRS): Bluetooth
     #        KISS            : Bluetooth
     #        DV/DR           : Bluetooth
     #
     #  3. On the D74, don't have it in any "mode" where either VFO shows "APRS12" or "KISS12"


     # Let's have the Rpi connect to the D74's serial port (channel 2):

        sudo rfcomm connect hci0 24:71:89:96:DE:AB 2

     # At this point, you should see the LCD on the TH-D74 light up with a notification saying 
     # "Connected Bluetooth Device".  You won't see anything else in this terminal window as 
     # this program doesn't display anything.  If you don't get the connected message and you
     # try using control-c and try the command again yet now get:

       --
       Can't connect RFCOMM socket: Device or resource busy
       --

     # You probably typed in the wrong MAC address.  You'll have to wait for the command to
     # time out or just reboot the Rpi.  
     #
     #   Btw, sometimes I've never been able to get the command to work again without rebooting
     #   the Pi.  It's frustrating and I haven't found any other ways to clear out that old
     #   state.  If you find a reliable way, please let me know!


     # Assuming the above commands worked ok, open a new terminal windows and run the command:

        sudo cat /dev/rfcomm0


     # In this window, you should now see NEMA GPS Sentence output like:
       --
       $GPGGA,041220.00,3720.610570,N,12159.995950,W,1,09,1.1,21.9,M,-28.4,M,,*6F
       $GPRMC,041221.00,A,3720.610575,N,12159.995951,W,0.0,0.0,281217,15.0,W,A*0A
       $GPGGA,041221.00,3720.610575,N,12159.995951,W,1,09,1.1,21.9,M,-28.4,M,,*6A
       $GPRMC,041222.00,A,3720.610582,N,12159.995950,W,0.0,0.0,281217,15.0,W,A*00
       $GPGGA,041222.00,3720.610582,N,12159.995950,W,1,09,1.1,21.9,M,-28.4,M,,*60
       . . .
       --
 
     # If you see that, awesome, you've confirmed Bluetooth to the D74 is working!  
     # Type in control-C in the "rfcomm connect" window to disconnect the 
     # bluetooth system as well as in the "sudo cat /dev/rfcomm" window 

       +-------------------------------------------------------------------------------+
       |NOTE:  I can reliably reproduce a bug in the D74 firmware v1.06 that if you    |
       |       have the GPS output enabled and you simply leave the "rfcomm connect"   |
       |       command running, the GPS icon on the D74 will eventually stop blinking  |
       |       and the front interface on the D74 will eventually stop responding.     |
       |       Everything will be fine if you don't create the Bluetooth connection.   |
       |       In about 60 seconds, the D74 will reboot.  Beyond the automatic reboot, |
       |       The only other way to regain control of the HT is to pull the battery!  |
       |                                                                               |
       |       D74 firmware v1.07 was released today, 12/27/17 and it sounds like      |
       |       Kenwood have fixed this specific issue but I haven't confirmed this yet |
       +-------------------------------------------------------------------------------+

    
     #  Next up, try dynamic Bluetooth binding.  To do this, issue the following command
     #  in one window:

        sudo rfcomm bind hci0 24:71:89:96:DE:AB 2

     # Notice the command ran and it instantly put you back that the Unix prompt.  Also notice 
     # the D74 didn't light up the LCD and state "Connected Bluetooth Device".  This is GOOD!
     # The system is now in standby.  Now open another window and run:

        sudo cat /dev/rfcomm0 

     # NOW you should have seen the Bluetooth message on the D74 and you're getting NEMA GPS 
     # sentence details in this window.  Now type in control-c in this window and you'll 
     # instantly see the bluetooth icon on the D74 go out.  If you run the command again,
     # it will instantly re-associate to the D74.  Awesome!

     # To shutdown this dynamic Bluetooth association, run the command:

        rfcomm release hci0


     NOTE:
     -----
     # It's worth mentioning that you can also put the D74 either into the "APRS12" or "KISS12"
     # mode and put bottom VFO (VFO-B) on a packet frequency say like 144.390 for APRS or 145.050
     # for keyboard-2-keyboard chat here in Northern California, the Bluetooth interface will send
     # this traffic too!  That assumes you configured the other D74 menus items as mentioned above



     That's it.. you've proved all the basics are working!  The next step is to get the Linux
     AX.25 stack working with it.  The plan is to integrate this functionality into the 
     /etc/ax25/ax25-up.new script but, for now, I've created a basic script called
     bt-kiss-bringup.sh available below that does the basic bring up steps:

        http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/bt-kiss-bringup.sh
    
     Put the D74 into KISS12 mode by toggling the Function-APRS button (that's the 5 key) 
     twice and you'll see the "KISS 12" icon in the upper middle right of the D74's display.
     Then edit this bt-kiss-bringup.sh script to match your specific D74's bluetooth MAC 
     address and run it.  Things should come automatically!
     
     Cool!  Btw, one more point:
     +-----------+
     | IMPORTANT |
     +-----------+
     DISABLE the GPS sentence output we enabled before as you probably won't need it
     and it will either run down your battery or crash older D74 firmwares:

        D74 Menu --> GPS --> Basic Settings --> PC Output: OFF


  Other Linux Bluetooth notes:
  ----------------------------
  Tips on supporting bluetooth audio devices (output only speakers, input/output 
  headsets, et) on your RPI v3:

   NOTE:  This URL recommends to install PulseAudio for full featured Bluetooth support.
          Since this document focuses on being a minimalist GUI-less environment, this
          isn't the direction I recommend for packet uses:

             http://youness.net/raspberry-pi/how-to-connect-bluetooth-headset-or-speaker-to-raspberry-pi-3

   NOTE #2: As of 12/4/20, the Raspberry Pi OS now includes PulseAudio by default in it's
            GUI-enabled versions of the distro.  This hopefully now means any previously 
            seen issues with PulseAudio on the Raspberry Pi have been resolved.

   
   Older details from the same author for older versions of Raspbian that uses ALSA.
   This URL might be a better fit for our simple needs:
   
      http://youness.net/raspberry-pi/bluetooth-headset-raspberry-pi


  Problems devices not reconnecting on reboot, see the proposed SystemD script at:
    https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=138145&start=100


33. Enable NTP for accurate date/time

Accurate time and Location - Using Adding GPS location and GPS-based NTP time support

Basic time keeping: Modern versions of Raspbian that use SystemD moved away from the 
classic "ntpd" service and now use timesyncd or Chrony.  For now, let's keep things 
simple and ensure that timesyncd is working if that's all you need.

Assuming you have a working network connection, test your setup:

   Buster or Stretch:
   -----------------
   timedatectl
   --
                     Local time: Fri 2020-11-13 17:10:03 PST
                 Universal time: Sat 2020-11-14 01:10:03 UTC
                       RTC time: Sat 2020-11-14 01:10:03
                      Time zone: America/Los_Angeles (PST, -0800)
      System clock synchronized: yes <----------------------------------------
                    NTP service: active
                RTC in local TZ: no
   --

      - In that output above, you're looking for "NTP synchronized: yes".  If that says NO, 
        try running:

           systemctl status systemd-timesyncd.service


        If there are issues, please review the config at /etc/systemd/timesyncd.conf

   Jessie:
   --------
   tbd


33.b. Configure a USB-based GPS receiver with GPSD for position and optional time


Instead of getting accurate date/time from the Internet, you can connect a GPS receiver 
to your Raspberry Pi to get highly accurate date/time without buying a real time clock
(RTC).  In addition, you can use the location for say being a roaming APRS client.

  +---------------------------------------------------------------------------------+
  | A note on picking a good GPS receiver:                                          |
  |                                                                                 |
  |     You get what you pay for!  I bought an inexpensive USB GPS unit but         |
  |     it would never lock on more than one or two satellites when inside my home  |
  |     and that would take like ten minutes to do!  Compare that to a quality      |
  |     smartphone  which could get full lock within 60 seconds.  I'm currently     |
  |     having decent luck with the following $26 USB-attached device:              |
  |                                                                                 |
  |     https://www.amazon.com/GlobalSat-BU-353-S4-USB-Receiver-Black/dp/B008200LHW |
  |                                                                                 |
  |     This SiRF-IV based receiver unit gets a good lock within my home, seems     |
  |     to be reliable and offers quick Sat lock BUT.. it also seems to spew out    |
  |     all kinds of RF noise on 144.000Mhz.  Beware!                               |
  |                                                                                 |
  |     If you have a recommended, not too expensive GPS receiver unit that's more  |
  |     RF quiet, please email me on your recommendation!                           |
  +---------------------------------------------------------------------------------+
  

Assuming you have a USB-based GPS receiver (or a serial-port based GPS receiver with a 
serial to USB adapter), follow these steps:

To get started, plug in your the USB based GPS device to determine what device name it 
gets by running either:

   dmesg
    or
   sudo journalctl

   I see:
   --
   [262398.233128] usb 1-1.3.3: new full-speed USB device number 8 using dwc_otg
   [262398.335505] usb 1-1.3.3: New USB device found, idVendor=067b, idProduct=2303
   [262398.335528] usb 1-1.3.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
   [262398.335541] usb 1-1.3.3: Product: USB-Serial Controller D
   [262398.335554] usb 1-1.3.3: Manufacturer: Prolific Technology Inc.
   [262398.372576] usbcore: registered new interface driver usbserial
   [262398.372686] usbcore: registered new interface driver usbserial_generic
   [262398.372769] usbserial: USB Serial support registered for generic
   [262398.377356] usbcore: registered new interface driver pl2303
   [262398.377549] usbserial: USB Serial support registered for pl2303
   [262398.377696] pl2303 1-1.3.3:1.0: pl2303 converter detected
   [262398.383001] usb 1-1.3.3: pl2303 converter now attached to ttyUSB0
   --


Now find it's alternative serial device name:

   ls -la /dev/serial/by-id


For me, I see the following LONG string (the whole thing is needed):

   lrwxrwxrwx 1 root root 13 Sep  4 17:28 usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 -> ../../ttyUSB0


So, the serial/by-id name is "usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0".  
That's a pretty long string but using that will make things easy on the long run.  Let's keep going.


Now install the required GPS software:

   sudo apt-get update

   #Unfortunately, you must install all the additional package dependencies here 
   # (something like +60 new packages [108MB space used] is required)
   #
   sudo apt-get install gpsd gpsd-clients libgps-dev


We now need to configure gpsd to use the new device in the future.  The easiest way to do that is just start
the service manually to start:

   sudo systemctl enable gpsd



Now lets test the new daemon it for a single run in the foreground.  To do so, we first need to shutdown
any running gpsd processes:

   sudo systemctl stop gpsd
   sudo systemctl stop gpsd.socket


Next, we have to work around SystemD doing the wrong thing here.  By default, SystemD creates a network
socket on port 2947 but ironically, when gpsd wants to start, it sees the port as busy and refuses to
start!

    #Confirm that gpsd isn't running but the GPS socket is still listening (thanks to Stretch's version 
    # of SystemD.. NOT) - I don't see this on Buster though:
    #
    ps aux | grep gpsd
    sudo lsof -nPi | grep 2947

       #If you see that the socket is still listening, you can shutdown the listening socket here
       sudo systemctl stop gpsd.socket
       sudo lsof -nPi | grep 2947


   NOTE:  One more permanent solution to avoid this Systemd listening socket situation, is to edit the 
          /lib/systemd/system/gpsd.socket file and change the following line.  This change can also 
          help EXTERNAL applications (specifically programs running on a different computer that's not
          on your Raspberry Pi) that are trying to connect to this GPS software server:

          sudo vim /lib/systemd/system/gpsd.socket
          --
          #Find the line
          ListenStream=127.0.0.1:2947

           change it to

          ListenStream=0.0.0.0:2947
          --


Ok, let's do a manual test of your GPS.  Run gpsd from the command line with the device-by-id string
found from above.  For my setup, I would run the following:

   # Understanding the options I'm using here:

   #    -N       : don't become a daemon, stay running in the foreground which is good for troubleshooting
   #    -D3      : increases the debugging output
   #    -n       : disables power savings on your GPS device (if it supports it)
   #    <device> : manually specify the serial device name

   sudo gpsd -N -D3 -n /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0

   You should see something like the following:
   --
   gpsd:INFO: launching (Version 3.11)
   gpsd:INFO: listening on port gpsd
   gpsd:INFO: stashing device /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 at slot 0
   gpsd:INFO: opening GPS data source type 3 at '/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0'
   gpsd:INFO: gpsd_activate(2): activated GPS (fd 6)
   gpsd:INFO: KPPS checking /sys/devices/virtual/pps/pps0/path, /dev/ttyUSB0
   gpsd:INFO: KPPS device not found.
   gpsd:INFO: NTPD ntpshm_link_activate: 1
   gpsd:INFO: device /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 activated
   gpsd:INFO: running with effective group ID 20
   gpsd:INFO: running with effective user ID 114
   gpsd:INFO: startup at 2016-10-11T22:59:01.000Z (1476226741)
   gpsd:INFO: speed 4800, 8N1
   gpsd:INFO: /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 identified as type NMEA0183, 2.654767 sec @ 4800bps
   gpsd:WARN: can't use GGA time until after ZDA or RMC has supplied a year.
   gpsd:INFO: /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 identified as type SiRF, 4.151043 sec @ 4800bps
   gpsd:INFO: Sats used (8):                                                                                                                         
   gpsd:INFO: PRN=  8 az=289 el=36 (-0.764941, 0.263390, 0.587785)                                                                                   
   gpsd:INFO: PRN= 10 az= 16 el=65 (0.116489, 0.406247, 0.906308)                                                                                    
   gpsd:INFO: PRN= 18 az= 60 el=44 (0.622967, 0.359670, 0.694658)                                                                                    
   gpsd:INFO: PRN= 27 az=241 el=46 (-0.607562, -0.336777, 0.719340)                                                                                  
   gpsd:INFO: PRN= 32 az=195 el=65 (-0.109382, -0.408218, 0.906308)                                                                                  
   gpsd:INFO: PRN= 14 az=199 el=47 (-0.222037, -0.644842, 0.731354)                                                                                  
   gpsd:INFO: PRN= 24 az= 60 el=18 (0.823639, 0.475528, 0.309017)                                                                                    
   gpsd:INFO: PRN= 21 az=126 el=32 (0.686085, -0.498470, 0.529919)                                                                                   
   gpsd:WARN: SiRF: warning, write of control type 80 while awaiting ACK for a6.                                                                     
   gpsd:WARN: SiRF: warning, write of control type a6 while awaiting ACK for 80.                                                                     
   gpsd:INFO: Sats used (4):                                                                                                                         
   gpsd:INFO: PRN= 10 az= 18 el=64 (0.135464, 0.416916, 0.898794)                                                                                    
   gpsd:INFO: PRN= 18 az= 61 el=43 (0.639656, 0.354567, 0.681998)                                                                                    
   gpsd:INFO: PRN= 21 az=127 el=32 (0.677281, -0.510368, 0.529919)                                                                                   
   gpsd:INFO: PRN= 32 az=196 el=66 (-0.112112, -0.390980, 0.913545)                                                                                  
   gpsd:INFO: Sats used (9):
   --

The important lines to see there is the "Sats used" lines.  You need a minimum of "3" and if you have that or more, 
you should be good!  Other information lines will display and continue to come but but gpsd is successfully running.  


   It's important to understand that the above command will NOT start spewing out NMEA sentences.  It will
   show key start-up details and then go quiet.


The key items to see in that output is:

   1. device <serial-by-id> activated

   2. startup at <timestamp>

   3. My GPS was identified as type SiRF


Go ahead and hit control-c to stop this manual gpsd process.  Btw, when you exit the command, notice the output:

   --
   ^Cgpsd:WARN: received terminating signal 2.
   gpsd:WARN: SiRF: warning, write of control type 88 while awaiting ACK for a6.
   gpsd:WARN: SiRF: warning, write of control type 81 while awaiting ACK for 88.
   gpsd:INFO: closing GPS=/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 (6)
   gpsd:WARN: exiting.
   gpsd:WARN: shmctl for IPC_RMID failed, errno = 1 (Operation not permitted
   --

That last line will be important if you want to set time by the GPS.  More on that later.


   OPTIONAL:  You can choose to put the GPS into NEMA mode to be able to read the raw output heard:

      gpsctl -f -n /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0
   
      You should see the following output and the command should complete and go back to the Unix prompt
      --
      gpsctl:SHOUT: switching to mode NMEA.
      --

Now try running this ncurses-based GPS display program (works well over an SSH terminal):

   gpsmon -n /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0
   
      +---------------------------------------------------------------------------------------------+
      | NOTE:  I've seen a few times that when I run this command, I just get a blank screen even   |
      |        after leaving the program just sitting there for like 10 seconds.  Even if I rerun   |
      |        the command a few times, it stays blank but if I again yet restart it, it then comes |
      |        up ok.  I think the issue is due to the program trying to negotiate GPS vs binary    |
      |        mode as things coming up with "-n" seems to make it more reliable.                   |
      +---------------------------------------------------------------------------------------------+


   You should see a TUI (textual user interface) screen printing both top level details from your 
   GPS on the top with the incoming streaming NMEA data on the bottom.  Some of the key fields to 
   look for:

      Top box:   
      --------
         Pos (position) : your GPS's position and altitude : this should NOT be changing much if
                          at all

         Time           : Date and time is accurate for the UTC timezone

         Fix            : Which satellites your GPS has locked onto; You must have at least 3 more 
                          satellites to get a mostly accurate location


      Lower Right box:   
      ----------------
         Firmware version: When your GPS was last updated from the manufacturer
         Visible List    : A list of the satellites your GPS sees


      The longer you run the program, the more accurate the details will become


      Example bottom NMEA streaming data
      --
      (40) $GPGSV,3,3,10,15,03,041,,16,00,236,*7A\x0d\x0a
      (72) $GPRMC,224315.000,A,3720.6148,N,12159.9942,W,0.00,167.23,141016,,,A*78\x0d\x0a
      (77) $GPGGA,224316.000,3720.6148,N,12159.9942,W,1,05,1.9,26.2,M,-25.7,M,,0000*5D\x0d\x0a
      (49) $GPGSA,A,3,10,32,27,21,18,,,,,,,,6.6,1.9,6.3*30\x0d\x0a
      (72) $GPRMC,224316.000,A,3720.6148,N,12159.9942,W,0.00,167.23,141016,,,A*7B\x0d\x0a
      (77) $GPGGA,224317.000,3720.6148,N,12159.9942,W,1,05,1.9,26.2,M,-25.7,M,,0000*5C\x0d\x0a
      (49) $GPGSA,A,3,10,32,27,21,18,,,,,,,,6.6,1.9,6.3*30\x0d\x0a
      (72) $GPRMC,224317.000,A,3720.6148,N,12159.9942,W,0.00,167.23,141016,,,A*7A\x0d\x0a
      (77) $GPGGA,224318.000,3720.6148,N,12159.9942,W,1,05,1.9,26.2,M,-25.7,M,,0000*53\x0d\x0a
      (49) $GPGSA,A,3,10,32,27,21,18,,,,,,,,6.6,1.9,6.3*30\x0d\x0a
      --

It's worth mentioning that there are a LOT of other GPS-like satellites flying above us these days.
According to http://www.catb.org/gpsd/NMEA.html#_talker_ids , there are at least (12) other systems!
   

NOTE on poor GPS receivers:

       In the above display, make sure the DATE is correct.  As mentioned at the top of this section,
       a different USB-based GPS receiver I had was showing the following bogus date (in the future!):
       
          2036-06-03T02:35:12.000Z

       This was very strange and per the man page for "gpsd" under the Accuracy section, it states 
       this is a known issue with older GPS chips.  If I took the GPS receiver outside with a WIDE, 
       clear view of the sky, it would fix itself and report the details.  This essentially proved 
       that this cheap USB receiver wasn't very sensitive (or very good) at all!


       A potential work around to this busted time/date issue, you can do the following (or better yet, 
       just get a better GPS receiver):

          sudo fake-hwclock save
          systemctl enable fake-hwclock

       This hack resolve this for the Rpi's next reboot.  See the following URL for more details: 
       http://gis.stackexchange.com/questions/157249/gpspipe-returns-correct-timestamp-but-wrong-date-21-dec-1995
       Ultimately, this workaround DIDN'T work for me all the time.  What did work for me is to move 
       my GPS setup from inside my home to outside with a clear view of the sky.  


If all the above test steps work, good job.  You're almost done!  Now you need to edit the /etc/default/gpsd 
file to make a few more changes, 

   1. Find the line that says USBAUTO.  This setting will let gpsd interrogate any new USB devices to see
      if they are GPS receivers or not.  I generally *never* recommend auto anything as it can interfere
      with other programs.  I recommend to make the line read:

         USBAUTO="false"

   2. Find the line that says "DEVICES="" and update it to reflect your proper device-by-id serial port.  In my case:

         DEVICES="/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0"
    
   3. OPTIONAL: You might need to specify "-n" as an optional parameter for your specific GPS but it has
      power draw implications (if you run your Rpi from battery).  From the man page:
   
   #       -n : Don't wait for a client to connect before polling whatever GPS is associated 
   #            with it. Some RS232 GPSes wait in a standby mode (drawing less power) when the 
   #            host machine is not asserting DTR, and some cellphone and handheld embedded GPSes 
   #            have similar behaviors. Accordingly, waiting for a watch request to open the device 
   #            may save battery power. (This capability is rare in consumer-grade devices).

         GPSD_OPTIONS="-n"


Ok, go ahead and save your changes and exit the editor.  Now try to start the GPS service with:

   sudo systemctl start gpsd

If all goes well, you'll just be dropped back to the command prompt without any specific output.  To 
confirm things started ok, run the command:

   ps aux | grep gps

   Which you should see something like:
   --
   gpsd     11074  0.6  0.8  13928  7224 ?        S<s  16:47   0:00 /usr/sbin/gpsd -N /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0
   --

This shows that the gpsd process is running.  Good, now try out a gpsd client to talk to the gpsd server.  
Try running the program:

      gpsmon

         or alternatively for NEMA only mode:
 
      gpsmon -n

   Either of these commands should look and work just like the manual run we did above.  For an even nicer display, try
   cgps:

      - This program offers a slightly simpler, cleaner view to the number of satellites being used 
        in the left-side box under the "Used" column

      or 

   xgps 
      If you're running the GUI version of Raspbian with the full Xwindows GUI on the HDMI console *or* are 
      SSHing into the Rpi from an Xwindows GUI computer with SSH X-forwarding enabled, this program
      will show a nice graphical representation of the received satellites with color coding 
      based upon their signal strength.  
      system running through SSH


If you want gpsd to automatically start upon boot, use the command:

   sudo systemctl enable gpsd


NOTES:

   - If you want to disable gpsd from auto-starting when the GPS is connected 
     to the USB bus, see:

        http://astrobeano.blogspot.com/2012/10/pharosmicrosoft-gps-360-on-raspberry-pi.html 


33.c. Adding NTP support via GPS and/or Internet access


Stock Raspberry Pi SBCs don't include a real time clock as it would add too much
to the cost of a base model Raspberry Pi SBC.  It's easy enough to add an inexpensive 
RTC and that's fully covered in a previous chapter in this doc.  If you don't want to install
an RTC, this simply means that when the Rpi boots, the date and time will always be WRONG
until it's updated by something.  

It's ideal to get that new time set as early as possible so the system creates properly dated
logs, etc.  One method to get a reliable date/time is via NTP (network time protocol) 
be it from the Internet (shown above) or more interestingly from a GPS data feed!

  NOTE:  If you intend to run a Raspberry Pi as an iGate and you have:
            - The rpi doesn't have accurate date/time (was rebooted and didn't have it's 
              date/time corrected)
            - Initially had working Internet connection and it later broke
            - Has been up and running for weeks

         At that point and the Internet connection is later restored, Direwolf will 
         evidently digipeat all the queued up APRS traffic heard from RF into APRS-IS land!  
         Not a great situation to be igating weeks old packets!   The fix here is to have an 
         accurate clock on your Rpi.  The easiest way to do this is to install an inexpensive
         RTC!


  NOTE #2: There are SEVERAL ways to solve "time" on Linux but I'll chime in on their solutions:

    - ntpd:        This is the classic Linux time service and while more complex than the others,
                   it's also the most advanced.  It allows to be connected to multiple concurrent 
                   Internet based ntp servers for redundancy.  In addition, ntpd also allows to get 
                   the date and time from other sources such as a GPS receiver and merge all of
                   these time sources into one pool and automatically pick which source has the most
                   accurate time.  

    - timedatectl: systemd enabled Linux distros have moved away from classic solutions like ntpd, 
                   newer alternatives like crony and now this control program to configure it.  
                   At the time I wrote this chapter, systemd's timedatectl DID NOT support setting 
                   and synchronizing time from a GPS as well as support a GPS's 1-PPS signal.  THIS 
                   is why I did NOT opt for setting things up in this section via the systemd way. 

    - chrony:      At the time I wrote this chapter, the chrony solution DID NOT support setting 
                   and synchronizing time from a GPS as well as support a GPS's 1-PPS signal.



34.a - Add the NTP binaries and initially set the time/date

   # install the ntpdate program which allows immediate time/date setting vs using
   #   ntpd approach with slews in the new time/date over a period of days or week
   #
   sudo apt-get install ntp ntpdate


   # On Raspbian Stretch system, the default 

   #Stop the newly installed and started ntpd from running for a moment
   #
   sudo systemctl stop ntp


   #Set the date/time assuming so you have a sane starting point for ntpd
   #
   #   - You currently have a working internet connection 
   #   - The NTP servers specified in the stock ntp.conf file are reachable
   #
   # This command can take up to 20 seconds to print anything.. be patient
   sudo ntpdate -b `grep -e ^server -e ^pool /etc/ntp.conf | head --lines=1 | awk '{print $2}'`

   From the above command, after say 20 seconds, you should see a response like:
     --
     21 Jul 16:41:41 ntpdate[2656]: step time server 104.131.155.175 offset -0.009051 sec
     --


34.b. - Enable ntpd to get time from gpsd

   #Ok, let's make a backup of your ntp.conf and enable ntp to support it
   #
   sudo mkdir /etc/Old
   sudo cp /etc/ntp.conf /etc/Old/ntp.conf-bak

   #Next, make a drift directory which helps the system more quickly remember the behavior
   #of your specific GPS
   sudo mkdir -p /var/lib/ntp

   #Now edit the ntp.conf file to enable GPS PPS mode
   #  The SHM keyword or "SHard Memory" keyword is an alias to the "type 28" reference clock created by gpsd
   #
   #  1. Put the following lines ABOVE the stock Debian NTP server definitions
   #  2. Append the "prefer" keyword to the pre-populated Debian NTP servers
   
   sudo vim /etc/ntp.conf
   --
   server 127.127.28.0 minpoll 4 maxpoll 4
   fudge 127.127.28.0 time1 0.000 refid SHM stratum 15

   # Drift file.  Put this in a directory which the daemon can write to.
   # No symbolic links allowed, either, since the daemon updates the file
   # by creating a temporary in the same directory and then rename()'ing
   # it to the file.
   driftfile /var/lib/ntp/drift
   --

34.c - Start up ntpd and let things sit. 

          #For Raspbian Stretch
          sudo systemctl start ntp

          #For Raspbian Jessie
          sudo systemctl start ntpd

       When I say sit, I mean have it running for at LEAST 10 minutes (assuming your GPS was getting
       a strong lock on it's various satellites.  The weaker it's reception, the longer this can take
       (if it ever works).  You can run the commands "gpsmod" or "cgps" to monitor the lock of the GPS.   
       Once your GPS has lock with at lease THREE satellites, you can move to the next step:


34.d - While gpsmon or cgps is still running, run the following command in another window
       (yes, gpsmon or cgps MUST be running in another window for this to work):

          sudo systemctl start ntp

34.e - Run the following command to print the output of the ntp system:

          ntpq -p
          --
          root@rpi3:/etc# ntpq -p
          remote           refid      st t when poll reach   delay   offset  jitter
          ==============================================================================
           SHM(0)          .SHM.           15 l    -   16    0    0.000    0.000   0.000
          +104.131.53.252  18.26.4.105      2 u   50   64    1   84.325   13.006   0.928
          *time-a.timefreq .ACTS.           1 u   49   64    1   49.129   -2.399   0.746
          +cpe-70-114-179- 45.35.50.61      3 u   48   64    1   77.391    0.880   3.212
          +ha3.smatwebdesi 216.229.0.179    2 u   47   64    1   53.979   -2.988   0.646
          --

    In the above output, the host with the "*" is the selected network time server.  If you 
    only see SHM to SHM, somethings isn't working right.  In troubleshooting, there might 
    be an issue with the GPS being accessed by gpsd.  To fix this, run:

       sudo usermod -aG dialout nobody

    You ultimately want to see something like the below output that shows
        SHM to GPS

   Additional troubleshooting:

      - There could be problems where it's not polling very often (notice the 71m delay)
        Sometimes if another program is running like cgps, then ntpd works.  Hmmm..
        I've seen this play both ways
 
        $ ntpq -p
             remote           refid      st t when poll reach   delay   offset  jitter
        ==============================================================================
        +carbon.neersigh 200.98.196.212   2 u  172  256  373   85.801    0.216  22.702
        +jarvis.arlen.io 164.244.221.197  2 u   46  256  377   48.269    1.420  21.650
        -time01.muskegon 204.9.54.119     2 u  100  256  377   74.713    6.046  53.822
        *time.tritn.com  66.220.9.122     2 u  182  256  377   20.031   -0.125   0.134
         SHM(0)          .GPS.            0 l  71m   64    0    0.000  399.598   0.000
         SHM(1)          .GPS1.           0 l    -   64    0    0.000    0.000   0.000


Other Great NTP + GPS urls:

   http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html

   https://frillip.com/raspberry-pi-stratum-1-ntp-server/


[Chapter Gap]


48. Review the boot up logs to make sure things are working as expected


Before you claim success on your new Raspberry Pi setup, I recommend you review the system bootlogs to make
sure you're not having some hidden errors.   

   +----------------------------------------------------------------------------------+
   | NOTE:                                                                            |
   |       This is probably going to be needed to be redone from time to time as you  |
   |       apply OS patches to your system.  I've already seen several OS patches     |
   |       BREAK things on my working Stretch install in the areas of dnsmasq and     |
   |       iptables.  Not cool but it's happening regardless and this is the only     |
   |       real way to make sure that things are remaining OK.                        |
   +----------------------------------------------------------------------------------+


To do this, simply do:

   sudo /sbin/shutdown -r now

Let the Raspberry Pi reboot and once it's back up, log into it and then run:

   sudo journalctl

Spend some time and review at LEAST the items that are bolded or color coded.  I'll openly mention that there
are errors in there on my system that seem to be bugs in Raspbian Stretch and/or the Linux kernel today.  
Hopefully those will be addressed over time but none of them seem to be fatal.   It will also be a good idea
to review the /var/log/messages and /var/log/syslog files though most of those log entries should be duplicates
of what's now captured in the SystemD log journal.


49. Backup your MicroSD card


This section will let you make complete image backups of you Raspberry Pi SD card to 
a heavily compressed file on another computer.  If you ever accidentally delete a file,
a directory, or have your SD card get corrupted, you can restore from this image!


  a. Shutdown the Rpi with:

       /sbin/shutdown -h now


  b. Unplug the power cord from the Rpi


  c. Eject the MicroSD card from the Rpi and install it into a different 
     Linux machine's card reader while that machine is fully booted


  d. run the "dmesg" command on that Linux computer to confirm SD card device as being seen
     and to also identify what SD card reader's device name is.  For my machine, I see it 
     as device: /dev/mmcblk0


  e. The following steps will make a backup image and make as small as possible.  If you're
     only looking to copy on SD card to another, you can skip this step.

     e.1. Install the xz compression utility

          #These commands assume the other Linux computer is running a Debian-like OS
          sudo apt-get install xz pxz

     e.2  Identify the REAL size of the SD card

              Here, you can see that m card is 15931539456 bytes large 

              sudo fdisk -lu /dev/mmcblk0
              --
              Disk /dev/mmcblk0: 15.9 GB, 15931539456 bytes
              4 heads, 16 sectors/track, 486192 cylinders, total 31116288 sectors
              Units = sectors of 1 * 512 = 512 bytes
              Sector size (logical/physical): 512 bytes / 512 bytes
              I/O size (minimum/optimal): 512 bytes / 512 bytes
              Disk identifier: 0x92f034a6

                      Device Boot      Start         End      Blocks   Id  System
              /dev/mmcblk0p1            8192       93813       42811    c  W95 FAT32 (LBA)
              Partition 1 does not end on cylinder boundary.
              /dev/mmcblk0p2           94208    31116287    15511040   83  Linux
              Partition 2 does not end on cylinder boundary
              --

     3.e. Mount the SD card with:

          sudo mkdir -p /media/sd-card/p1
          sudo mkdir -p /media/sd-card/p2
          sudo mount /dev/mmcblk0p1 /media/sd-card/p1
          sudo mount /dev/mmcblk0p2 /media/sd-card/p2


     e.4. Clear out all unallocated space in the file system for max compression

          #Use my pre-written script as a baseline and tune to meet your needs
          #
          wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/zeroize-filesystem.sh

          or manually run the commands:

             #Fill up and clear out the "boot" partition - this will be fast (7 seconds)
             sudo time dd if=/dev/zero of=/media/sd-card/p1/bigfile.dd bs=1M
             sudo rm -f /media/sd-card/p1/bigfile.dd

             #Fill up and clear out the "root" partition - this will be considerably slower
             # To fill 14.1GB of free space, it took my system 29minutes.
             sudo time dd if=/dev/zero of=/media/sd-card/p2/bigfile.dd bs=1M
             sudo rm -f /media/sd-card/p2/bigfile.dd


     e.5. Unmount the card partitions

          sudo umount /media/sd-card/p1/
          sudo umount /media/sd-card/p2/


  f. Create a binary image of the SD card with the "dd" tool:

        # Go ahead and change the filename from "ki6zhd-jessie-w-linpac.dd.gz" to 
        #   reflect your callsign, Raspbian version, and anything else you want

        #This tool uses XZ compression by default which maximizes compression but is very slow
        #
        wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/backup-rpi-sdcard.sh
        ./backup-rpi-sdcard.sh ki6zhd-16gb-stretch-w-linpac-090417.dd.xz

        #if you want to do it manually:
           cd <a directory you place your backup stuff in>
           sudo time dd if=/dev/mmcblk0 bs=1M | xz -9 > ki6zhd-16gb-stretch-w-linpac-090417.dd.xz

     NOTE: This command will not give any output until the process is complete
           and it can take quite a while to do depending on the size of your SD card and
           the speed of your system.  A 16GB card took 51 minutes to copy and compress.

     NOTE2: A 16GB MicroSD card with 3.08GB worth of files on it dd's to a raw
           file size of 15560867840 bytes  (15.56GB).  After xz compression, it was 
           only 395MB.  That's an impressive reduction!


  g. Ok, you have your backup!  Now remove the SD card from this secondary Linux machine and put 
     it back into your Raspberry Pi


  h. Power back up your Raspberry Pi and everything is as it was but now you have a backup

  i. If you'd like to put a copy of this newly created SD image onto another SD card

     i.1. Make sure this new SD card is the same size OR bigger (use the fdisk command shown above to
          see it's size in blocks)

     i.2. Put the new, empty SD card into this other Linux computer and use the command:

        # Use the file name from what you entered above
        unxz -9c ki6zhd-jessie-w-linpac.dd.xz | dd of=/dev/mmcblk0 bs=1M

           NOTE: This command will not give any output until the process is complete
                 and it can take in upwards of 10 minutes or more depending on the size
                 of your SD card and the speed of your card reader


49.a. Restore individual files or completely from your MicroSD backup

Once you've fully backed up your Raspberry Pi's SD card, you have some insurance from file 
system corruption (power glitches) SD card failures (too many writes over it's lifetime), and
human error (you deleted the wrong file, etc).


Full microSD image backup restore:

   If you want to restore the entire image you made, the whole process is just like when you first
   imaged the SD card for your Raspberry Pi.  Multiple approaches is covered in Section 1 of this 
   document but I personally recommend to use my image-rpi-sdcard-multiformat.sh script since it
   supports the might better XZ compression format.   Getting this script and using it is fully
   addressed in that chapter


Individual file restore:

   Restoring individual files from a "dd" image is a little more complex but isn't too hard.
   In this example, I'm going to assume assume you want to restore the /etc/passwd file from the 
   following compressed backup file but substitute in your specific backup filename:

      ki6zhd-16gb-stretch-w-linpac-090417.dd.xz


   1. If not already installed from following Chapter 1, install the multi-threaded XZ program 
      as it will make the decompression process go MUCH faster:

         sudo apt install pixz

   2. You need to first decompress the backup image file as there is current no way to follow these 
      steps with inline compression.  I assume you're going to want to keep the compressed file
      so you don't have to re-compress it afterwards.  You need to make sure you have enough storage
      space to BOTH support the duplicated compressed backup file AND it's decompressed copy

      a.  Create a copy of the compressed backup file

             cp ki6zhd-16gb-stretch-w-linpac-090417.dd.xz ki6zhd-16gb-stretch-w-linpac-090417-2.dd.xz

      b. uncompress the file : this will be SLOW (on a Intel i7-7600U CPU @ 2.80GHz, this took 1.5 
         minutes to decompress the 877MB file) 

            time pixz -d ki6zhd-16gb-stretch-w-linpac-090417-2.dd.xz


   3. Once decompressed, we need to look at the image's partition table to get some key details:

      NOTE:  There are lots of ways to mount "loop" file systems such as with losetup, kpartx, etc but all 
             of these options require more programs to be installed and you also don't learn how this all
             works.  So, for now, I'm just going to use the basic and included "fdisk" and "mount" commands:


      /sbin/fdisk -lu ki6zhd-16gb-stretch-w-linpac-090417-2.dd
         --
         Disk ki6zhd-16gb-stretch-w-linpac-090417-2.dd: 14.86 GiB, 15931539456 bytes, 31116288 sectors
         Units: sectors of 1 * 512 = 512 bytes
         Sector size (logical/physical): 512 bytes / 512 bytes
         I/O size (minimum/optimal): 512 bytes / 512 bytes
         Disklabel type: dos
         Disk identifier: 0x92f034a6
      
         Device                                    Boot Start      End  Sectors  Size Id Type
         ki6zhd-16gb-stretch-w-linpac-123017-2.dd1       8192    93813    85622 41.8M  c W95 FAT32 (LBA)
         ki6zhd-16gb-stretch-w-linpac-123017-2.dd2      94208 31116287 31022080 14.8G 83 Linux
         --

      The important information here is:
         - the "sector size" is 512
         - the first partition for booting starts at offset "8192"
         - the second partition for the Linux file system starts at offset "94208"


   4. Ok, time to do a little basic math to calculate where the real partition starts.  You will need to 
      substitute your backup image's values and do your own math to get the correct values:

         a. partition #1:  512 * 8192  = 4194304
   
         b. partition #2:  512 * 94208 = 48234496
      

   5. Let's mount the needed partition:



      NOTE:  if you're using Ubuntu 20.04 or similar with it's built in "snap" support, your system is 
             already using a LOT of /dev/loop devices.  For example, here is the output of "df" from my 
             system:
             --
             $ df
             Filesystem     1K-blocks      Used Available Use% Mounted on
             udev             8040392         4   8040388   1% /dev
             tmpfs            1613988      2636   1611352   1% /run
             /dev/nvme0n1p2 479152840 121894624 332848824  27% /
             tmpfs            8069936         0   8069936   0% /dev/shm
             tmpfs               5120        24      5096   1% /run/lock
             tmpfs            8069936         0   8069936   0% /sys/fs/cgroup
             /dev/loop0          9344      9344         0 100% /snap/canonical-livepatch/98
             /dev/loop3        101632    101632         0 100% /snap/core/10958
             /dev/loop5        223232    223232         0 100% /snap/gnome-3-34-1804/60
             /dev/loop7        224256    224256         0 100% /snap/gnome-3-34-1804/66
             /dev/loop8        166784    166784         0 100% /snap/gnome-3-28-1804/145
             /dev/loop9         52352     52352         0 100% /snap/snap-store/498
             /dev/loop10       145920    145920         0 100% /snap/arduino/50
             /dev/loop12        56832     56832         0 100% /snap/core18/1997
             /dev/loop13        66432     66432         0 100% /snap/gtk-common-themes/1514
             /dev/loop15        33152     33152         0 100% /snap/snapd/11588
             /dev/loop14       267008    267008         0 100% /snap/kde-frameworks-5-core18/32
             /dev/loop16        52352     52352         0 100% /snap/snap-store/518
             /dev/nvme0n1p1    523248      8020    515228   2% /boot/efi
             tmpfs            1613984       172   1613812   1% /run/user/1000
             /dev/loop18       190976    190976         0 100% /snap/arduino/56
             /dev/loop19        66688     66688         0 100% /snap/gtk-common-themes/1515
             /dev/loop20        63232     63232         0 100% /snap/core20/975
             /dev/loop21       275200    275200         0 100% /snap/gimp/367
             /dev/loop22       249856    249856         0 100% /snap/gnome-3-38-2004/39
             /dev/loop6         32896     32896         0 100% /snap/snapd/11841
             /dev/loop23       101376    101376         0 100% /snap/core/11081
             /dev/loop1        283392    283392         0 100% /snap/gimp/372
             /dev/loop11         9344      9344         0 100% /snap/canonical-livepatch/99
             /dev/loop2         63232     63232         0 100% /snap/core20/1026
             /dev/loop17        56832     56832         0 100% /snap/core18/2066
             --

             As such, I've found my system only wants to mount one file system at at a time.  If
             I try to mount the second partition on say , I get the error:
             --
             mount: /mnt/dd1/: overlapping loop device exists for /usr/src/archive/RPi/Images/ki6zhd-16gb-stretch-w-linpac-123017-2.dd
             --


         Anyway, go ahead and mount the second partition which has the /etc/passwd file:

            sudo mkdir /mnt/dd1
            sudo mount -t ext4 -o loop,offset=48234496 ki6zhd-16gb-stretch-w-linpac-090417-2.dd /mnt/dd1/


         For completeness, let's say you wanted to copy a file out of the backup image's /boot file system.
         Here, you'd use a different file system type (vfat) and use the correct partition offset:

            sudo mkdir /mnt/dd2
            sudo mount -t vfat -o loop,offset=4194304 ki6zhd-16gb-stretch-w-linpac-090417-2.dd /mnt/dd2/

            NOTE:  If you get an error here similar to the one above, you need to UNMOUNT the first file system
                   with a "sudo umount /mnt/dd1" first


   6. Copy over the file needed for recovery

         Ok, if the above command didn't give you an error, you can copy out your needed file.  In this example,
         I'm copying out the /etc/passwd file into /tmp

            cp /mnt/dd2/etc/passwd /tmp/


   7. Ok.. done.. you've recovered your file!   Let's clean up:

      a. Unmount the mounted recovery file system
            sudo umount /mnt/dd1

      b. delete the uncompressed copy of the original backup
           sudo rm ki6zhd-16gb-stretch-w-linpac-090417-2.dd 


[Chapter Gap]


60. Optional projects to add to your Raspberry Pi / APRS / Packet Project


This section covers various little sub-projects including:

   - Setting up a 20x4 LCD screen

60.a. Setup a 20x4 LCD via I2C to display various system details

The goal of this project was to add and LCD display to my Raspberry Pi to know what's
going on in it at a glance.  There are many options here be it 16 character by 2 line 
(16x2) LCDs, 20x4 LCDs, little LCD or OLED displays, etc.  I wanted to display more 
information at one time so I opted for one of these

   $8.75 - Blue Serial IIC/I2C/TWI 2004 204 20X4 Character LCD Module Display For Arduino
   https://www.ebay.com/itm/321923408888

This is an inexpensive 20x4 Blue LCD that's about the same size as a Raspberry Pi.  
This LCD is driven off a four wire I2C connection instead of running it off many GPIO
pins.  This is a 5volt display but even though the Raspberry Pi is a 3.3v device, the Rpi
offers +5v pins as well so it can drive it just fine.

   NOTE:  It's important to connect LCD to 5.0v pin on the Rpi and not 3.3v pin. If you
          use the 3.3v supply, you won't be able to read the text on the display


To get started, you first need to run the setup tool and enable the I2C bus:

  sudo raspi-config

     Goto :

         - Interfacing options
              - I2C        : If you have any I2C low speed devices and plan to use them, enable this

Exit the program to save the new settings and shutdown your Rpi with:

   sudo /sbin/shutdown -h now


Now unplug the power from your Rpi and wire up the display.  For me, I used:

   http://pinout.xyz/
   --
   Rpi pin                      LCD pin
   --------+------------------+--------
      2    :    +5V display   :   VCC
      3    :    I2C DATA      :   SDA
      5    :    I2C Clock     :   SCL
      6    :      ground      :   GND

   --

Now power back up the Rpi with the connected display.  The display's backlight 
should light up but nothing be on the display.  If you see a bunch of rectangle 
blocks, that's OK for now.   Once the Rpi is back up and you SSHed back into it, 
install some key I2C packages:

   sudo apt-get install i2c-tools python-smbus


Once those tools are installed, try running the following command to see if the
I2C display is detected:

   # detect all I2C IDs on the second I2C bus:
   sudo i2cdetect -y 1

        0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
   00:          -- -- -- -- -- -- -- -- -- -- -- -- --
   10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3f
   40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --


As you can see here, my LCD display has an I2C address of 0x3f.  If you see a "UU" in 
the address spot where you expect your RTC address, this means that the I2C address in 
use.   Maybe your Raspberry Pi distro already recognized it and has configured it for 
something else.

Now we need to get an example program going to confirm the LCD
works ok.  I would start with this project that worked for me.
There are lots of them out there though.

   NOTE:
   -----
   I've seen that many programs just barely show any text on the LCD display
   If you look very closely, at an angle, you'll be able to tell the text is 
   but it's way too faint.  As I was troubleshooting this, I randomly stumbled 
   into another program that would show all the text in a clear, bright fashion!
   Seems this LCDs have seemingly TWO brightness levels but this one program
   is mistakenly showing the text in ultra-bright mode.  Good to know things work
   but it's the wrong function.  It ultimately turned out that my issue was that
   the LCD's VCC line was connected to the Raspberry Pi's 3.3v pin and not the +5.0v 
   pin.  Once I made that switch, I could read all the original text.  

So go get a test program:

   #This fork of another user's program works well
   #   It 100% initializes well and shows text and graphics the first time, every time
   #

   #RPi_I2C_driver.py 
   https://gist.github.com/amateusz/fa985d170e9621e92bd5093a3826594b/raw/67b0c364da4137633c73de800fc9efa15f991173/RPi_I2C_driver.py

   #example.py
   wget https://gist.github.com/amateusz/fa985d170e9621e92bd5093a3826594b/raw/67b0c364da4137633c73de800fc9efa15f991173/examples.py


Now edit the "RPi_I2C_driver.py" and change I2C address to match your display's I2C address 
(mine is 0x3f) and LCD dimensions to 20,4:

   54c54
   < ADDRESS = 0x27
   ---
   > ADDRESS = 0x3f
   57c57
   < DIMENSIONS = (16, 2)
   ---
   > DIMENSIONS = (20, 4)


Ok, give the program a try:

   sudo python examples.py


This program should:

   - light up the backlight
   - Show some text
   - Show a smiley face icon
   - Show a filling bar from the left to the right
   - Show a smiley face icon
   - turn the backlight off


If that worked, you're in business!  We'll need to use in later so let's move it to somewhere
permanent:

   sudo mv RPi_I2C_driver.py examples.py /usr/local/sbin/


Now I imagine you want to do something more useful with the LCD.  In the discussion thread at

   https://www.raspberrypi.org/forums/viewtopic.php?t=190570

There was an example program posted at https://www.dropbox.com/s/lxdprouv6i8d1re/LCD_16x2_I2C.zip?dl=0
which runs a basic clock.  Unfortunately, this code doesn't seemingly initialize the LCD 
properly 100% of the time so I load each of the two above programs to get things working.  

I then enhanced the program to include the above mentioned display items with showing:

   - The Month-Day datestamp    Local time AM/PM
   - The status of the Internet connection (pinging 8.8.8.8) and
     the status of the NTP session (do we have Internet time)
   - The current running callsign and the number of received AX25 packets
   - The system load with 1min / 5min / 15min details

You can grab a copy of my modified script here:

   wget http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/lcdui-modified.py
   sudo mv lcdui-modified.py /usr/local/sbin/


If you downloaded my modified file, give it a trial run with:

   sudo python lcdui-modified.py


You can find other examples of programs here:

  #C and Python examples : Missing URL for libraries
  https://www.sunfounder.com/learn/sensor-kit-v2-0-for-raspberry-pi-b-plus/lesson-30-i2c-lcd1602-sensor-kit-v2-0-for-b-plus.html


If that runs well, have it start at boot up with adding the following to the /etc/rc.local file:

   --
   echo -e "\nStarting up LCD on I2C address: 0x37"
   #this test script seems to initialize the LCD properly every time
   python /usr/local/sbin/examples.py
   #This is the running program but doesn't aways init properly
   python /usr/local/sbin/lcdui-modified.py &
   --

60.b. Setup a DS3231 battery backed up real time clock (RTC) with temperature sensor

This section covers how to add a DS3231 realtime clock (RTC) to your Raspberry Pi to allow it
to automatically set the system's date/time upon initial power up.  There are a lot of different
RTC kits, HATs, and other solutions out there which might use a PCF8523 chip, a better DS1307 chip, 
the much better DS3231 chip, or possibly some other chip.  Your RTC might also use a different I2C 
addresses, etc. so you might need to adapt these steps below to your specific RTC hardware.

It's also important to understand this section builds upon the steps previously mentioned in the 
"connecting an LCD to your Rpi" section.  As such, you must least install the key I2C programs 
in that previous section FIRTST before following this section.


Background: You might be thinking to yourself, "Why do I need an DS3231 RTC device if I already 
            have a GPS running which can set the clock?".  That's a good question but consider 
            this:

          1. An DS3231 RTC consumes almost no power and its always running even when your Rpi is
             not powered.  It will give the Raspberry Pi system the correct date/time upon 
             initial boot for accurate logging.  Using a GPS to set your system's dated/time takes 
             much longer to get the date/time and then reflect in your system's logs, etc.

          2. If your setup is in a static location or have poor GPS satellite reception, 
             why waste the power on a GPS receiver worse, suffer GPS position jitter (your 
             position keeps moving around).  Instead, just statically set your location in 
             the APRS application

          3. Why not have both?  :-)


The specific DS3231 RTC unit I bought is this one:

   # NOTE: this URL buys THREE units for $7 including the batteries ($2.30 US/ea)!  That's a
   # great deal though these are evidently Chinese boards with a questionable sourcing of these 
   # Dallas chips (possibly counterfeit?)
   # 
      http://www.ebay.com/itm/231880855190

   # In comparison, Adafruit sells a board with what should be a true Dallas part for $13.95 US 
   # which doesn't # include a battery (yet another $0.95).  That's 6.5x more expensive but it's 
   # probably both the better quality part and ethical purchase (not ripping off Dallas Semiconductor)
   # 
      https://www.adafruit.com/?q=DS3231

   # If you're curious about these knockoff boards, you can read more say here:
   #
      http://dangerousprototypes.com/blog/2016/01/15/using-a-2-ds3231-rtc-at24c32-eeprom-from-ebay/


Anyway, assuming you have your little RTC and also you enabled the I2C bus per the previous section 
for the LCD display (if not, read up on that now and come back here), shutdown your Rpi with:

   sudo /sbin/shutdown -h now


Now unplug the power from your Rpi and wire up the RTC.  This wiring is very similar to the
the LCD setup above but this RTC chip uses the +3.3v voltage instead.  I've read conflicting 
information where some sites say you can power it with +5.0v as well.  I've personally tested 
and have things working with the +3.3v line only.  You also might consider wiring things up
through a little Raspberry Pi breadboard like this:

   https://fe-pi.com/products/proto-z-v1

   IMPORTANT:  This specific fe-pi proto board connects the three pins together just like a 
               breadboard on BOTH sides of the PCB.  These are NOT just individual holes with 
               solder grommets as I had expected.  I missed that and I completely screwed up 
               one board and had to use an Exacto knife to cut the traces on both sides of 
               the board to un-short my board!


I2C bus wiring:

   I2C buses can be wired either in a serial or parallel fashion.  In this setup, I connected 
   the Raspberry Pi to a breadboard.  On the breadboard, I connected up both the RTC as well 
   as connected jumper cables to the LCD display in PARALLEL.  Works well.


Here is a nice website for showing the standard and alternative Rpi header pinouts:

   http://pinout.xyz/
  
   Rpi physical 
     pin                         RTC pin
   --------+------------------+--------
      1    :   +3.3v power    :   VCC
      3    :    I2C DATA      :   SDA
      5    :    I2C Clock     :   SCL
      6    :      ground      :   GND


Once everything is wired up, power back up the Rpi with the RTC board connected.  If you 
bought the same DS3231 RTC as I did, the LED on the unit should light up.  Once the Rpi 
booted back up, log in and install some key I2C packages (if not already installed):

   sudo apt-get install i2c-tools python-smbus


Once those tools are installed, try running the following command to see if the
I2C-based RTC is detected:

   sudo i2cdetect -y 1
   --
        0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
   00:          -- -- -- -- -- -- -- -- -- -- -- -- --
   10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3f
   40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
   60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
   70: -- -- -- -- -- -- -- --
   --


In the above output, you can see:

   0x37 : LCD display on I2C Bus 1 - described in the previous chapter
   0x57 : DS3231 RTC's internal 32K EEPROM 
   0x68 : DS3231 RTC 

If you see a "UU" in the address spot where you expect the RTC 0x68 address, this means that 
the RTC and it's I2C address is already in use!   That most likely means your Raspberry 
Pi distro already recognized the RTC and has configured it (that's what happened to me).  
That's a good thing but to confirm that in-use point, try running:

   ls -la /dev/rtc0


If that command comes back with something like the following, your system is already up
and running (aka.. you're done!):

   crw------- 1 root root 253, 0 Dec 31  1969 /dev/rtc0


  If this doesn't show up, you're going to need to configure a few things to get it
  recognized so keep reading and specifically read the "Setting up from scratch" section below.  

  If it DOES already show up,  I still recommend you also try running the following command:

     dmesg | grep rtc

  Confirm the output looks like this to confirm things are indeed setup properly:

  --
  [    9.133480] rtc-ds1307 1-0068: SET TIME!
  [    9.137606] rtc-ds1307 1-0068: rtc core: registered ds3231 as rtc0
  --


  Now, things might work but if you look closely, does your output show the "ds3231" 
  above or does it show "ds1307" instead like this output below:
    --
    [    9.049339] rtc-ds1307 1-0068: rtc core: registered ds1307 as rtc0
    [    9.049408] rtc-ds1307 1-0068: 56 bytes nvram
    --

  If it has the INCORRECT string "registered ds1307" text, maybe your RTC is really a ds1307 
  chip or it was incorrectly recognized.  The behavior for this output seems to be inconsistent but 
  it's actually the ds1307 kernel module that supports BOTH the ds1307 and ds3231 devices but the 
  ds3231 invocation can give you more features.  If you believe it should be a "ds3231", you'll need 
  to update your /boot/config.txt file as instructed below to gain access to some of this chip's 
  advanced features like temperature sensors, flash ROM, etc.


Configuring your I2C RTC if not already recognized
--------------------------------------------------
If things didn't get auto-setup for you as mentioned above, that probably just means your specific 
RTC board might be at different I2C address.  No big deal.  All you'll need to do is research what 
I2C addresses your specific RTC board will show up as from the seller.  If you don't see ANYTHING 
in the above "i2cdetect" command output, you need to make sure:

   -  the I2C bus is turned on in the raspi-config tool (see Section #4 of this doc)

   -  check your wiring from the Rpi to the RTC module, etc.  You might also try running the i2cdetect
      command on the other I2C bus (try I2C bus 0)


Assuming your RTC wasn't already recognized (not showing a UU), let's give it a temporary test by 
running the following commands to get the kernel module to load and connect to the device on 
I2C bus 1 (Raspberry Pi v1 owners will need to use bus 0 instead):

   # You must use su command here and NOT sudo to run the entire command as it's passing multiple 
   # parameters
   #
   #  Change the "0x68" to match the I2C ID of your specific RTC
   #
   sudo su
   echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
   exit

If you get an error like "bash: echo: write error: Invalid argument", your RTC chip
is probably already being used.  Now check the output of "sudo i2cdetect -y 1" again.
If the command didn't give any errors and hopefully shows your RTC device's address now
being shown as "UU" or "in-use. That means Linux loaded the DS1307 kernel module (that 
module also supports the DS3231 chip).  Confirm the module is loaded by running:

   lsmod | grep ds
   --
   rtc_ds1307             13908  0
   hwmon                  10552  1 rtc_ds1
   --


Also make sure the RTC device was created as well:

   ls -la /dev/rtc*
   --
   lrwxrwxrwx 1 root root      4 Nov 20 17:05 /dev/rtc -> rtc0
   crw------- 1 root root 253, 0 Nov 20 17:05 /dev/rtc
   --

Assuming you see the "UU", let's now see if you can read the time from it:

   #Simply READ from the chip
   sudo hwclock -r -f /dev/rtc0
   --
   1999-12-31 23:44:08.906751-0800
   --


If you see all that... Awesome!  Now if your output was like mine, it seems to work but 
it might have the WRONG date and time. That's ok as it's brand new and it might not have 
even been programmed.  Assuming you Raspberry Pi has been configured to get it's time 
by being an NTP client per the previous chapter (highly recommend and also see WHY I'
m using ntpdate vs say other tools as well), setting the RTC time perfectly will be easy.

You should confirm you DO have good NTP lock via some remote time servers.  Here is what 
I see for my system.  The remote host with a "*" is the current system used for time:

   ntpq -c peers
   --
        remote           refid      st t when poll reach   delay   offset  jitter
   ==============================================================================
    SHM(0)          .GPS.           15 l    -   16    0    0.000    0.000   0.000
    0.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.001
    1.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.001
    2.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.001
    3.debian.pool.n .POOL.          16 p    -   64    0    0.000    0.000   0.001
   +eterna.binary.n 204.9.54.119     2 u  707 1024  377   52.846    2.335 143.338
   +time.tritn.com  63.145.169.3     2 u  149 1024  377   26.745    0.763   6.440
   +christensenplac 200.98.196.212   2 u  147 1024  373   87.077    2.070   9.090
   -40.85.153.82    45.76.244.193    3 u   62 1024  377   16.602    2.725  22.823
   *rolex.netservic .kPPS.           1 u  825 1024  177   82.314   -3.493  11.500
   --

   You can also use the more Systemd command timedatectl

   timedatectl
   --
                  Local time: Sat 2021-04-17 17:01:01 PDT
              Universal time: Sun 2021-04-18 00:01:01 UTC
                    RTC time: Sun 2021-04-18 00:01:02
                   Time zone: America/Los_Angeles (PDT, -0700)
   System clock synchronized: yes
                 NTP service: active
             RTC in local TZ: no
   --


Ok, assuming you have a good date/time, let's update the DS3231 RTC's clock.  It's as 
easy as running the previous command but now we're going to WRITE to it.  Running this 
command won't give any output as it completes.  The second command here will then read 
from the chip and confirm the correct date/time:

   sudo hwclock -w -f /dev/rtc0
   #no output given


Now read from the RTC and make sure it has the right time and date:

   sudo hwclock -r -f /dev/rtc0
   --
   Mon 18 Feb 2019 03:23:22 PM PST  -0.247576 seconds
   --


Great!  Now you've set the time on it and confirmed it's correct!  Now if you're curious how 
accurate the RTC is compared to NTP over time, you can try running commands like this 
one at any time where "hw-time" is the RTC and the "system-time" is the NTP set Raspberry 
Pi time.  Btw, "ppm" is essentially errors in "Parts Per Million":

   #Print out any time differences every 10 seconds
   sudo hwclock -c -f /dev/rtc0
   --
   hw-time      system-time         freq-offset-ppm   tick
   1511382606   1511382605.521373
   1511382618   1511382617.521630                21      0
   1511382629   1511382628.522096                31      0
   1511382640   1511382639.521910                16      0
   --

   Enter in control-c to exit the program


Now all you have to do is enable the RTC kernel module to load up at boot time.  To do this, 
edit the /boot/config.txt file.  In that file, find the line that reads something like:

   #dtoverlay=lirc-rpi

   Below this line, create a new line that reads the following (you can have multiple active "dtoverlay"
   lines in this file btw:

      dtoverlay=i2c-rtc,ds3231


Next, it's recommended to remove the stock Raspberry Pi "fake" hardware clock package if
you intend to always keep this RTC module connected to your Rpi.  You can do that with:

   sudo apt-get remove fake-hwclock


Next up, for most Raspberry Pi OS users that use a systemd-enabled OS, you need to 
edit one more file and COMMENT out a few lines

   sudo vim /lib/udev/hwclock-set

   Find the following lines (usually starting at line 7):
   --
   if [ -e /run/systemd/system ] ; then
       exit 0
   fi
   --

     and comment all three lines out so they look like

   --
   #if [ -e /run/systemd/system ] ; then
   #    exit 0
   #fi
   --

That should be it!  To test it, go ahead and reboot your Raspberry Pi.  If things work correctly,
log back into your Rpi and try running the command "dmesg -T" and you should see all the kernel 
boot lines with the correct time/date from the very beginning.  You should also see the rtc driver 
loaded up in that output of "dmesg".


BONUS:  Temperature sensor on DS3231 RTCs!
------------------------------------------
A DS3231 RTC chip (not a DS1307) also includes a highly accurate temperature sensor which is 
included for it to keep far more accurate time compared to NON-temperature compensated RTCs.  
Assuming you configured and rebooted your Rpi to use the DS3231 chip vs the basic ds1307 
non-temperature compensated module, you can read the temperature from the DS3231 RTC.

Use this command to determine which OS device will report the temperature sensor:

   sudo find /sys/devices/ | grep 0068 | grep temp1_input
   --
   /sys/devices/platform/soc/3f804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input
   --


Assuming you got a response similar to above, try cat'ing that file to get a temperature 
reading in Celsius:

   cat /sys/devices/platform/soc/3f804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input
   --
   24750
   --

If the above didn't work, read below.  For a working example, I used the following command 
but you might need to "cat" the output of what was found above:

   Rpi3:
   ----
   cat /sys/devices/platform/soc/3f804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input
   
   23250
   --

   Rpi Zero-W
   --
   cat /sys/devices/platform/soc/20804000.i2c/i2c-1/1-0068/hwmon/hwmon1/temp1_input

   24500
   --


That output is showing it's 23.250 degrees Celsius (73.850 degrees Fahrenheit).  If you have the 
"bc" package installed, you can convert to Fahrenheit with this one line command:

   #Update this variable to reflect your specific valid device as described above
   RTCTEMP="/sys/devices/platform/soc/20804000.i2c/i2c-1/1-0068/hwmon/hwmon1/temp1_input"

   echo "scale=2; (`cat $RTCTEMP` / 1000.0) * (9/5) + 32" | bc -l


   The output of those two lines should look like something like:
   --
   76.10
   --


If you get a response but the temp seems too high, check the placement of the RTC.  Is it close 
to a heat generator like the RPI's CPU?  If so, try moving it to a different place away from any 
heat generators.


If you get an error polling for the temperature, it's possible that one of a few things happened:

  1. You didn't enter in the right I2C address in the "cat" command.  Try finding the right address 
     with the following command:

          sudo find /sys/devices/ | grep 0068 | grep temp1_input

     On some systems, I got the response:

          /sys/devices/platform/soc/20804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input

     that means I need to give the command:

         cat /sys/devices/platform/soc/20804000.i2c/i2c-1/1-0068/hwmon/hwmon0/temp1_input


  2. You forgot to reboot your system to use the ds3231 personality of the kernel module

  3. Your DS3231 is a counterfeit board (very common when buying cheap Ebay / AliExpress / etc RTC 
     devices.  Please read the URLs in the beginning of this section to learn more on what you get
     when you pay very little

  4.  Raspbian has auto-configured your RTC setup yet is loading the WRONG RTC driver.  Check your 
      /boot/config.txt file and on the "dtoverlay" line, make sure it reads:

         dtoverlay=i2c-rtc,ds3231

      Not "dtoverlay=i2c-rtc,ds1307"

      If you had to change this, reboot your Raspberry Pi for the changes to go into effect.


60.c. Raspberry Pi cases, cooling and setting up a temperature controlled fan


Most Raspberry Pi board versions don't need any special cooling and/or heatsinks except when running 
with very high CPU load or operating in very high ambient temperatures.  The Raspberry Pi 4 is 
different as it's higher performance CPU creates a lot more heat and really needs a fan to operate 
without slowing down the CPU.


Cases:  Any Raspberry Pi really need a case to protect it from any potential physical damage as 
        well as possible ESD (electro-static discharge) damage.  There are 100s of case options out 
        there but MANY aren't very good.  Please consider the following:


        - 100% enclosed cases:  
          --------------------
          Some vendors offer fully enclosed cases made from plastic over even metal without ANY 
          ventilation holes, any fans, etc.  If it's a plastic case such as the official Raspberry 
          Pi Foundation's case, I find this is a terrible option as your Raspberry Pi will just 
          bake inside it.  Metal cases might better dissipate some of the heat but not as much
          as you might think.  For very low CPU loaded Raspberry Pi uses, maybe this is ok for 
          your needs but your Raspberry Pi might be throttling it's CPU speed from time to time.  
          Some people argue that the case gaps around the USB, RJ45 Ethernet jack, HDMI jack, and 
          USB power ports will provide enough airflow but I would argue you can easily drill in a 
          bunch of ventilation holes on the top cover to improve it's cooling as well.  Here is 
          on good video showing this terrible design choice with showing various measurements and
          how thermal throttling can dramatically slow the performance of your Rpi (4x slower!):

             https://www.youtube.com/watch?v=AVfvhEJ9XD0

        
        - Cases with heatsinks but no fan: 
          --------------------------------
          Heatsinks can help keep the chips cooler but many cheap cases use such cheap thermal tape 
          that it actually HURT the chip's temperature.  Buy your case from a quality vendor to 
          hopefully avoid this situation.  Also remember that the case needs ventilation (read 
          above) to allow the heatsinks to dissipate the heat


        - Metal cases with no fan: 
          ------------------------
          There are some nice metal cases out there that might be better than a plastic case for
          dissipating some of the heat but this won't work very well.  There are also some versions
          that extrude some of the top metal all the way down to make contact with the main CPU
          and other chips to act as a massive heat sink.  Some examples of this type of case are the
          FLIRC (No GPIO pin access - leave the top plastic cover OFF for better cooling), the Cooler 
          Master Pi Case 40 (has GPIO pin access), etc.  These type of cases can offer VERY good cooling 
          with no noise *if* they make good thermal contact with the RPI's chips.  I recommend to use 
          some good thermal grease on these extruded points, assemble, then disassemble, and inspect the 
          grease dispersion on the chip to see how well it actually makes contact.

          IMPORTANT Wifi   ANY metal case will DRAMATICALLY reduce the Wifi range of your Rpi as it's
               note:       going to shield the RF signals.  Many amateur radio users WANT this shielding
                           to avoid stray RF noise coming out of the Rpi but if so, you need to use the
                           wired ethernet jack, an external USB-based Wifi dongle, or possibly hack your
                           Rpi to add an external wifi antenna


        - Cases with or without heatsinks with a permanently-on fan
          ----------------------------------------------------------
          These plastic or metal cases can really help keep a Rpi cooler but all of the above
          ventilation points above apply as the fan needs airflow to really work.  A downside of many
          cheaper offerings is that many come with cheap "sleeve" bearing design fans which will fail 
          to keep spinning after say a year of operation.  Better fans will come with ball bearings or 
          alternative designs and these fans can last a LOT longer.  Next, the speed and resulting fan 
          noise from these always-on fan / fans can sometimes be managed by connecting the fan's power 
          leeds to either the +5.0v or +3.3v power pin.

          ----------------------
          Fan maintenance note:  
          ----------------------
          Any device with a fan WILL accumulate dust and dirt inside it as air flows over the board.  
          It's highly recommended to periodically clean out the inside of your Raspberry Pi's case
          and option heatsinks.  I also recommend to carefully clean the individual fan blades with
          a q-tip if it's really dirty.


        - Cases with or without heatsinks with a temperature controlled fan
          -----------------------------------------------------------------
          There are newer fan options for the Raspberry Pi that are temperature controlled where
          the fan is OFF until it exceeds a specific temperature.  These are special THREE pin fans 
          (power, ground, and PWM pin) and this cannot be directly done with the classic two-pin
          fans.  These kinds of fans are not expensive.  For example:

             - 25mm x 25mm x 8mm +5v fan with one low profile heatsink:
                $5 US - https://www.raspberrypi.org/products/raspberry-pi-4-case-fan/

                NOTE:  This solution is intended to be used with the official Raspberry Pi Foundation's
                       Rpi4 case but you can buy this just to get the fan.  It's also worth mentioning
                       that this setup does help but it's not great as there still isn't enough ventilation.
                       I encourage you to watch say ETA Prime's YouTube video on this very point:

                          https://www.youtube.com/watch?v=mJtmQsptQvw

             - 30mm x 30mm x 8mm +5v fan shim
                $12 US - https://www.adafruit.com/product/4316
             
             
        - DIY temperature controlled fan
          ------------------------------
          If you would like add this kind of control with your existing two-pin fans, you ideally
          need a small transistor, diode, and resistor for a complete solution:

                https://scarff.id.au/blog/2021/circuit-for-temperature-controlled-dual-fan-raspberry-pi-case/

             Don't want to build your own?  You can buy little pre-made boards:
                https://www.tindie.com/products/jeremycook/ez-fan2-tiny-raspberry-pi-fan-controller/?pt=ac_prod_search
                 or
                https://www.seeedstudio.com/Grove-MOSFET.html


Fans with TACH signals:
-----------------------
It should be noted that the Raspberry Pi doesn't support any fans with TACH signaling to show the fan's current spinning
RPM rate.  This is unfortunate as it's an important way to find out if a fan is failing or has outright has failed (no 
longer spins).  Knowing this kind of information is hugely important with industrial servers but can be important for your
Rpi too!  There are ways to add TACH support:

   - EMC2101 fan controller chip:
     https://learn.adafruit.com/emc2101-fan-controller-and-temperature-sensor?view=all

   - DIY fan controller - add an Arduino, required components, and sketch source code


[Chapter Gap]

70. Stuff that still needs to be added or updated


N7NIX Dan tracker
-----------------
Need to consider the integration of the DanTracker document at:

    hampacket2:/usr/src/archive/RPi/n7nix-udrtracker-install.txt 

into this doc.  The challenge here is that this valuable program's source code 
has long been abandoned.

   DanTracker currently does NOT support gpsd and
   - only supports GPSes on /dev/ttyUSB*
   - only supports NEMA GPSes
   - does not initialize SiRF GPSes to send NEMA
   - does support for setting the time via GPS once a day

  Concerns:
  - even if I disable DanTracker GPS and gpsd and just run:
    cat /dev/ttyUSB0 > /dev/null
    the impact hits direwolf where it under-samples and then fails to do decodes:

          Past 100 seconds, 4275495 audio samples, 0 errors.


  #Update the config - Dantracker currently ONLY supports devices like ttyUSB0 
  # (not /dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller_D-if00-port0 )
  
  vi /etc/tracker/aprs_tracker.ini
  --
  port = /dev/ttyUSB0
  --


  #You have to get the GPS running in NEMA mode first
  sudo gpsd -N -D3 -n /dev/ttyUSB0 

  /etc/tracker/tracker-up


  To view the current system, use:

     http://192.168.0.10:8080/tracker.html
         or
     http://192.168.0.10:8081/spy.html



  # Is this needed for N7NIX DanTracker?

  /etc/init.d/prepare-dirs
  --
  #!/bin/bash
  #
  ### BEGIN INIT INFO
  # Provides:          prepare-dirs
  # Default-Start:     2 3 4 5
  # Default-Stop:      0 1 6
  # Required-Start:
  # Required-Stop:
  # Short-Description: Create /var/log/nginx directory on tmpfs at startup
  # Description:       Create /var/log/nginx directory on tmpfs at startup
  ### END INIT INFO

  DIR=/var/log/lighttp

  #
  # main()
  #
  case "${1:-''}" in
    start)
      # create the /var/log/nginx needed by webserver
      if [ ! -d ${DIR} ]; then
        mkdir ${DIR}
        chmod 755 ${DIR}
      fi
      ;;
    stop)
      ;;
    restart)
     ;;
    reload|force-reload)
     ;;
    status)
     ;;
    *)
     echo "Usage: $SELF start"
     exit 1
     ;;
  esac
  --

  chmod 755 /etc/init.d/prepare-dirs
  update-rc.d prepare-dirs defaults 01 99


  # ------------------------------------------------------------------------
  Check out http://dantracker.tk/tracker.html for more RPi optimizations, etc
  # ------------------------------------------------------------------------



# This note is only relevant for F6BVP's based Rpi image (obsolete)

   You can update the various F6BVP code, AX25 stack, etc. from the included scripts:

   cd /usr/local/src/
      Instax25.new  
      updAX25  
      updfbb  
      updfpac



#Other ideas.. make the whole SD card read only

  https://hallard.me/raspberry-pi-read-only/


# Maybe install Xastir - old though - currently at 2.0.4
  apt-get install Xastir


# ---------------------------------------------------------------
# Possibly Deprecated
# ---------------------------------------------------------------


# ---------------------------------------------------------------
?Still needed for Jessie?

# /var/log items go into the tmpfs ram drive anyway

Suppress 1000s of cron lines like the following in /var/log/auth.log
#
#   Jan 30 18:49:01 ota3 CRON[14054]: pam_unix(cron:session): session opened for user zzz by (uid=0)
#   Jan 30 18:49:03 ota3 CRON[13055]: pam_unix(cron:session): session closed for user root

edit /etc/pam.d/common-session-noninteractive

At the end of the file, find the line:

   session required pam_unix.so

and now add the following line ABOVE it

   session [success=1 default=ignore] pam_succeed_if.so service in cron quiet use_uid


80. Todo


03/06/15 - Add NTP via GPS support -  http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html
11/21/15 - ULOG w/ firewall log rotate


90. Special Topics


90.a - Use a Coastal Chipworks TNC-Pi on your Raspberry Pi


The above mentioned /etc/ax25/ax25-up.new script DOES have support for the TNC-Pi.  All you need
to do is edit the script to use the TNC-Pi routines vs. the Direwolf ones.  It should just work.


   1. - On the TNC-Pi board, does it have Jumpers JP2 and JP3 right next to the Rpi GPIO pin header?  
        If so, they both MUST be in-place to communicate to the TNC-Pi to change it's settings (for 
        either serial OR I2C mode).  They must remain there if the TNC-Pi is to use the serial port
        interface or REMOVED if you're going to use the TNC-Pi via the I2C bus

   2. - If you have a Raspberry Pi v3, you MUST make two changes to the setup to swap the serial
        port for use with the Bluetooth interface (required for using the TNC-PI in serial or I2C
        mode)

           Edit the /boot/config.txt file and add these two lines:

              dtoverlay=pi3-miniuart-bt
              core_freq=250

           You can read more about these changes here: 
           http://raspberrypi.stackexchange.com/questions/45570/how-do-i-make-serial-work-on-the-raspberry-pi3

   3. - You need to enable the serial port on the Rpi with the following steps but unfortunately, 
        this approach both enables the serial port AND the serial console support at the same time.  We
        don't want the serial console support so that part has to be undone:

           sudo raspi-config --> Interface Options --> Serial Port --> YES --> Ok --> Finish

           On older Raspbian releases, you would find this in :
              sudo raspi-config --> Advanced Options --> Serial --> YES --> Ok --> Finish

        Select YES to reboot your Raspberry pi


   4. - Make sure the serial console is not enabled

      Look at the /boot/cmdline.txt file and Look for the string: 

         console=serial0,115200

      If you see it, you'll need to edit the file with sudo rights, remove that portion of text, save 
      the file and get ready to reboot the Rpi


   5. - Now reboot your rpi with: 

      sudo /sbin/shutdown -r now


   6. - Make sure the /dev/ttyAMA0 serial port is recognized

      ls -la /dev | grep AMA
      --
      lrwxrwxrwx  1 root root           7 Nov  6 09:44 serial0 -> ttyAMA0
      crw-rw----  1 root dialout 204,  64 Nov  6 09:44 ttyAMA0
      --

      If it's NOT seen, you need to try using the "sudo raspi-config" step again


   7. - Make sure there aren't any console sessions configured to use /dev/ttyAMA0

      ps aux | grep getty
 
      If you see something like the following, you need to fix this
         --
         root      1077  0.8  0.1   4112  1764 ttyAMA0  Ss+  08:24   0:18 /sbin/agetty --keep-baud 115200 38400 9600 ttyAMA0 vt102
         --

      Disable the getty running on /dev/ttyAMA0 permanently the Jessie / SystemD way with:

         sudo systemctl stop serial-getty@ttyAMA0.service
         sudo systemctl disable serial-getty@ttyAMA0.service


   8. - Make sure there aren't any AX25 interfaces already loaded

      ifconfig | grep ax

          If there are, use the command "sudo ifconfig ax0 down" to shut them down


   9. - Make sure there aren't any KISS applications already running:

      ps aux | grep kiss

      Use the command "sudo killall kissattach" to kill any running kissattach commands (also removes any mkiss commands too)


   10. - Download the newest TNC-Pi get/set tools

      sudo mkdir /usr/src/pitncgetset
      cd /usr/src/pitncgetset

      # Get the newest John Wiseman G8BPQ code - current as of 08/30/18
      #
      wget http://www.cantab.net/users/john.wiseman/Downloads/PITNCParamsApr18.zip
      wget http://www.cantab.net/users/john.wiseman/Downloads/i2ckiss.zip

        # If the above links don't work, try looking for a different version of 
        # the "PITNCParams" filename.  You can also try downloading it at the following 
        # URL but that link doesn't always seem have the newest available code:

             http://www.tnc-x.com/pitnc.zip 
               and 
             http://www.tnc-x.com/i2ckiss.zip

               or another alternative: https://dl.dropboxusercontent.com/u/31910649/i2ckiss
      

   11. - Uncompress and make sure the pitncgetset binaries are executable

      #Uncompress the archive
      sudo unzip pitncgetset.zip

      chmod 750 pitnc_setparams pitnc_getparams


   12. - Check the /dev/ttyAMA0 serial port to make sure it's ok.  Disconnect the DB9 connection going from the TNC-Pi 
         to your radio.  Now run the following command (you can use control-C to stop it) and you should see NOTHING.  
         If you see garbage on the screen (something like the following):

            sudo cat /dev/ttyAMA0
            ����������������������������������������������������������������

         That's bad.  I recommend to shut down your TNC-Pi with "sudo /sbin/shutdown -h now", wait to see the green 
         power LED blink 7 times.  Now REMOVE the power connection from the Raspberry Pi for 30 seconds and then 
         reconnect power.  Again try the above command and make sure NO garbage or any out text output is coming


   13. - Try running the pitnc_getparams program:

         - If running on a TNC-Pi v1 board:

            ./pitnc_getparams 0 0
  
         - if running on a TNC-Pi v2 board:

            ./pitnc_getparams 1 0


      You should see something like:

         Using Serial port /dev/ttyAMA0

            PIC Software Version           0
         01 TXDelay - Zero means use ADC  25
         02 Persistance                  250
         03 Slottime (in 10 mS)            6
         04 TXTail                         2
         05 Full Duplex - Not used         0
         06 Our Channel (Hex)             00
         07 I2C Address (0 = async) Hex   00
            ADC Value                     30
         8 0 19 fa 6 2 0 0 0 1e f1 c0 sum 0


   14. - Making changes to the TNC-Pi via I2C

      - After making any changes to the TNC-Pi's register, you need to reboot the unit.  To do so, run the 
        I2C command:

           ./pitnc_getparams 15 2



   If you want to try to use the TNC-Pi in I2C mode (frees up the onboard /dev/ttyAMA0 serial port), 
   here are some additional things to check:

     14.a - You will need to change the "I2C address" using the above commands to enable I2C mode, power down the 
            Rpi and take off the TNC-PI JP2 and JP3 jumpers (if you have an older TNC-Pi board)


     14.b - see if the I2C drivers are installed:

        lsmod | grep i2c
        --
        i2c_bcm2708             4834  0
        i2c_dev                 5859  0
        --

        Both entries MUST be there


     14.c - make sure the i2ctools are installed

          sudo apt-get install i2c-tools


     14.d - Make sure the I2C bus can be found

         make sure the you see bus #1 (should show something like: i2c-1   i2c   3f804000.i2c   I2C adapter)
    
            sudo i2cdetect -l
  

     14.e  - See if you can see the TNC-Pi in I2C mode on address 15:

        --
        sudo i2cdetect 1

        WARNING! This program can confuse your I2C bus, cause data loss and worse!
        I will probe file /dev/i2c-1.
        I will probe address range 0x03-0x77.
        Continue? [Y/n]
             0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
        00:          -- -- -- -- -- -- -- -- -- -- -- -- --
        10: -- -- -- -- -- 15 -- -- -- -- -- -- -- -- -- --
        20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
        30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
        40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
        50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
        60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
        70: -- -- -- -- -- -- -- --
        --

        The output above shows NOTHING which means it's not correct.  

           Troubleshooting items to be added


     14.f - Enable I2Ckiss

          Assuming you want to use the TNC-Pi in I2C mode with the Linux AX.25 stack, you would 
          then run the command:

             i2ckiss 1 15 vhfdrop 10.0.0.2


     The rest of configuring the AX.25 stack is configured in the above mentioned /etc/ax25/ax25-up.new
     script.  That script DOES support the TNC-Pi setup with some simple changes.  Read and edit the
     script to suit your needs.


     Ps.  Here is an older thread will take you through a way to get things working via the I2C bus 
          and not the serial port which might get you going:

          https://groups.yahoo.com/neo/groups/Raspberry_Pi_4-Ham_RADIO/conversations/topics/4755

90.b - Use a Kenwood D710 KISS TNC with your Raspberry Pi

Are you looking to use a Kenwood D710 packet TNC (or really any KISS TNC) with your Raspberry Pi and 
NOT say a soundcard based TNC?  If so, you're in luck!  Nearly everything is ready to go in this project 
to use your D710 as your packet TNC.  

   NOTE: If you're looking to use a different KISS TNC with your Raspberry Pi, it should be pretty easy
         to modify the setup to replace the D710 tool with a generic "KISS ON" script.  Email me if you
         need help


To enable D710 support, try the following steps.  I've tested this and it works with my D710:

   #0. Open a terminal window on your Rpi

   #1. Become root
   sudo su

   #2. Download and build a very good D710 configuration tool
   cd /tmp
   wget -O tmd710_tncsetup.c https://raw.githubusercontent.com/fmarier/tmd710_tncsetup/master/tmd710_tncsetup.c
   gcc -o /usr/local/bin/tmd710_tncsetup tmd710_tncsetup.c

   #3. Identify your USB to serial port - unplug it and re-plug it into your Raspberry Pi and run these commands
   dmesg | tail --lines 10 | awk -F"now attached to " '{print $2}' | grep ttyUSB

   #4. Edit the /etc/ax25/ax25-up.new script file and change the following to read as follows

      TNCTYPE=d710

   #5. Update this line to whatever is the serial port name connected to the D710 head's TNC port.  For example, 
       this is what I'm using 

      D710SER="/dev/ttyUSB0"

     +---------------------------------------------------------------------------------------------+
     | CRITICAL: Using the long device names found by the predictable serial interface system via  |  
     | 11/22/20 /dev/serial/by-id gives segmentation faults when running the required kissattach   |
     |          program used for packet radio.  If you aren't going to use packet radio, don't     |
     |          worry about it.  If you ARE setting up packet radio, this issue has been reported  |
     |          and confirmed as an issue in the libax25 and ax25-tools packages from the VE7FET   |
     |          or official AX.25 repos                                                            |
     |                                                                                             |
     |         For now, DO *NOT* use the /dev/serial/by-id style name at this time with used with  |
     |         the Linux AX.25 kissattach program at this time                                     |
     +---------------------------------------------------------------------------------------------+

   #6. Edit the /etc/ax25/axports file and on the line starting with the name of your configured tnc such as "vhfdrop", 
       change the speed from "19200" to "9600"

   #7. Turn on your D710 with an antenna attached to the main radio body and the D710 head itself, go into the menus and 
       set AUX menu item 528 "COM Port Baudrate" to 9600.  Why?  the D710 configuration tool used here only works at 9600

   #8. On the D710 head itself, power off the entire radio and turn it back on.  This is to make the TNC take the new serial 
       speed setting
  
   #9. That's it and the rest of the packet instructions in this doc should just work


If things don't work right, I would recommend to start with a few troubleshooting steps:

   0. Make sure your Rpi has an internet connection

   1. Open a terminal window on the RPi

   2. Shutdown the ax25 system just in case with "sudo /etc/ax25/ax25-down.sh"

   3. Install minicom with:
      sudo apt update
      sudo apt install minicom

   4. Run minicom by typing in "sudo minicom" in the terminal window

   5. In Minicom, use the key sequence Control-a and then "o" (that's an Oh) to get into the Minicom menus.  In there, 
      go to the serial port setup and change the "Serial device" to your proper device such as "/dev/ttyUSB0", and change 
      the speed to 9600,8n1.  Once done there, hit enter to go back one menu, select "Save as DFL", hit enter, select "Exit"

   6. In Minicom, use the key sequence Control-A and then "x" to exit minicom.  This is usually done to avoid weird issues 
      with Minicom and changing serial port speeds

   7. On your D710 head, tap the lower right "tnc" soft-key until the very top left TNC status area goes blank

   8. Restart minicom

   9. On your D710 head, tap the lower right "tnc" soft-key (bottom of the very right vertical buttons) and keep taping that 
      soft-key until very top left LCD "TNC status" area goes from blank to "aprs12" to "packet12"

  10. At that point, you should see something similar the following in minicom:
      --
      Kenwood Radio Modem
      AX.25 Level 2 Version 2.0
      Release 09/Mar/11 3Chip ver 1.02
      Checksum $1859
      cmd:
      --

  11. If you hit enter, you should get a response back of "cmd:".  If you don't, you need to troubleshoot your setup until this works.

      Ps.  Notice the TNC firmware version shown above.  It's recommended to be running v1.02 which is the newest version 
           of the firmware available here: https://www.kenwood.com/i/products/info/amateur/software_download.html

91 - Custom Kernel Compiling the Raspberry Pi OS way


[ Work in progress ]

As part of a working effort with Bernard F6BVP, we are looking to install custom kernel modules 
for modern Raspbian kernels that REVERT known toxic changes to the following modules:

   ax25
   netrom
   rose

WARNING:

   This effort is NOT for Linux newbies and will take hours to complete due to the size of the 
   build


REQUIREMENTS: 

   1. An external storage device - I recommend at least 32GB of space on either an SSD or spinning HD.
      Do NOT do these builds on the Raspberry Pi's SD card as you *will* permanently damage and crash 
      the SD card.  This is due to the punishing level of writes which SD cards are not designed to
      support.  You've been warned.

   2. You are either using the Stretch version of Raspbian-Lite or have disabled the GUI system from 
      startup via the raspi-config.  This is required to maximize the amount of available RAM for
      the build.

   3. You have minimized the amount of RAM allocated to the video system.  This is covered in the 
      beginning chapters of this doc using raspi-config.

   4. You have mounted an external /tmp partition to support overflowing of any build objects.  This
      is automatically done in my mount-usb-hd.sh available at:

         http://www.trinityos.com/HAM/CentosDigitalModes/RPi/usr/local/sbin/mount-usb-hd.sh

   5. IMPORTANT:
      I noticed when I was doing a kernel build, I was seeing the "overTemp" icon (a red thermometer) 
      blinking in the upper right corner of the HDMI console display!  The compile was seemingly running
      ok but obviously the Rpi was throttling it's performance.  I didn't place any heat sinks on my Rpi 3B+ 
      but to support these builds, I placed a small +5V fan to blow air on it and the icon went away.

   6. You have lots of time to let the builds do their thing as there is a LOT of code in the Linux
      kernel and *all* Raspberry Pi hardware (even the newest RPI v3B+) is generally SLOW for work
      like this.


Mount the storage:

   1. Mount the external storage manually or via my "mount-usb-hd.sh" script

      ./mount-usb-hd.sh
      --
      Initializing mount directories if required: /tmp/root /tmp/home
      Debian 8 or 9.0 - Jessie / Stretch : SystemD style

      Drive sda is LVM partitioned

      Logical volumes not enabled, starting
        PARTIAL MODE. Incomplete logical volumes will be processed.
        3 logical volume(s) in volume group "vg_dranchlt3" now active
      mounting /tmp/ with LVM
      mounting /tmp/home

      /usr/src/archive is present
      /usr/src/archive/Rpi-scratch is present... ready to go!
      --

   2. Move into the external drive

      cd /usr/src/archive/Rpi-scratch


Install any required build tools and other dependencies:

   NOTE:  Most of the required GCC tool chains, etc. are already pre-installed
          in Raspbian

   sudo apt-get install git bc


Get the Raspbian kernel code

   The command you run depends on the version of code you want to compile:

      mkdir kernel
      cd kernel

      #Mainline 4.14.x code
      git clone --depth=1 https://github.com/raspberrypi/linux

        #The above clone command with the "--depth 1" option downloads the newest 4.14 code and it
        # took 1min48sec and 1.1GB space on a Rpi 3B+ with a cablemodem connection


      NOTE#2:  If you wish a specific kernel branch w/o downloading everything (say the 4.1.x line
               which ended at 4.1.21), you would run:

                  git clone --depth=1 --branch rpi-4.1.y https://github.com/raspberrypi/linux

              This took 1min 13sec and 833MB of space on a Rpi 3B+ with a cablemodem connection

     NOTE #3:  If you wish to build ANY of the older kernels, do NOT include the original URL's 
               "--depth=1" option.  This command took 46min and 3.92GB space on a Rpi 3B+ with a 
               cablemodem connection


   Once downloaded, you can see what kernel version you would build by running the following
   command (I would build the 4.14.95 version by default):

      #Look at the top of the file for the versions
      less linux/Makefile
 

Build a stock 4.14.x kernel to ensure everything works:

   #This assumes you are building for a Rpi 2 or newer (this will NOT work for an RPI v0 or v1)
   # This took 14 seconds to complete
   cd linux
   KERNEL=kernel7
   make bcm2709_defconfig

   #This step took 76 minutes on a RPI v3B+ to build 4.14.95
   time make -j4 zImage modules dtbs
   --
   [all the build stuff removed]

   real    76m32.336s
   user    283m40.400s
   sys     16m41.059s
   --


Confirm what kernel files you already have installed:

   #Show the current kernel you're running:
   uname -a
   --
   Linux rpi3plus 4.14.93-v7+ #1191 SMP Wed Jan 16 11:53:33 GMT 2019 armv7l GNU/Linux
                  ^^^^^^^^^^^                                            ^^
   --

   #List the current kernel modules for current and previous kernels
   ls -la /lib/modules/
   --
   total 32
   drwxr-xr-x  8 root root 4096 Jan 19 10:14 .
   drwxr-xr-x 16 root root 4096 Jun 26  2018 ..
   drwxr-xr-x  3 root root 4096 Aug  4 14:21 4.14.59+
   drwxr-xr-x  3 root root 4096 Aug  4 14:21 4.14.59-v7+
   drwxr-xr-x  3 root root 4096 Dec  8 12:35 4.14.79+
   drwxr-xr-x  3 root root 4096 Dec  8 12:35 4.14.79-v7+
   drwxr-xr-x  3 root root 4096 Jan 19 10:14 4.14.93+
   drwxr-xr-x  3 root root 4096 Jan 19 10:14 4.14.93-v7+  <------------------------
   --

   #List the current and previous kernels
   ls -la /boot
   --
   total 17079
   drwxr-xr-x  3 root root    2560 Dec 31  1969 .
   drwxr-xr-x 23 root root    4096 Aug  4 14:17 ..
   -rwxr-xr-x  1 root root   23315 Jan 19 10:14 bcm2708-rpi-0-w.dtb
   -rwxr-xr-x  1 root root   22812 Jan 19 10:14 bcm2708-rpi-b.dtb
   -rwxr-xr-x  1 root root   23071 Jan 19 10:14 bcm2708-rpi-b-plus.dtb
   -rwxr-xr-x  1 root root   22589 Jan 19 10:14 bcm2708-rpi-cm.dtb
   -rwxr-xr-x  1 root root   24115 Jan 19 10:14 bcm2709-rpi-2-b.dtb
   -rwxr-xr-x  1 root root   25311 Jan 19 10:14 bcm2710-rpi-3-b.dtb
   -rwxr-xr-x  1 root root   25914 Jan 19 10:14 bcm2710-rpi-3-b-plus.dtb
   -rwxr-xr-x  1 root root   24087 Jan 19 10:14 bcm2710-rpi-cm3.dtb
   -rwxr-xr-x  1 root root   52296 Jan 19 10:14 bootcode.bin
   -rwxr-xr-x  1 root root     142 Jul 11  2018 cmdline.txt
   -rwxr-xr-x  1 root root    1601 Jun 26  2018 config.txt
   -rwxr-xr-x  1 root root   18693 Dec  8 12:36 COPYING.linux
   -rwxr-xr-x  1 root root      41 Jan 19 10:14 .firmware_revision
   -rwxr-xr-x  1 root root    2628 Jan 19 10:14 fixup_cd.dat
   -rwxr-xr-x  1 root root    6695 Jan 19 10:14 fixup.dat
   -rwxr-xr-x  1 root root    9895 Dec  8 12:35 fixup_db.dat
   -rwxr-xr-x  1 root root    9875 Jan 19 10:14 fixup_x.dat
   -rwxr-xr-x  1 root root     145 Jun 26  2018 issue.txt
   -rwxr-xr-x  1 root root 4943016 Jan 19 10:14 kernel7.img  <------------------------
   -rwxr-xr-x  1 root root 4695264 Jan 19 10:14 kernel.img
   -rwxr-xr-x  1 root root    1494 Dec  8 12:35 LICENCE.broadcom
   -rwxr-xr-x  1 root root   18974 Jun 26  2018 LICENSE.oracle
   drwxr-xr-x  2 root root   13312 Jan 19 10:14 overlays
   -rwxr-xr-x  1 root root  682532 Jan 19 10:14 start_cd.elf
   -rwxr-xr-x  1 root root 2869028 Jan 19 10:14 start.elf
   -rwxr-xr-x  1 root root 3955716 Jan 19 10:14 start_x.elf
   --

   #Confirm you have enough space in /boot
   df
   --
   Filesystem                       1K-blocks     Used Available Use% Mounted on
   /dev/root                         15240048  1859012  12729236  13% /
   devtmpfs                            495480        0    495480   0% /dev
   tmpfs                               500088        0    500088   0% /dev/shm
   tmpfs                               500088    19160    480928   4% /run
   tmpfs                                 5120        4      5116   1% /run/lock
   tmpfs                               500088        0    500088   0% /sys/fs/cgroup
   /dev/mmcblk0p1                       43539    17478     26061  41% /boot  <------------------------
   tmpfs                               100016        0    100016   0% /run/user/1001
   /dev/mapper/vg_dranchlt3-lv_root  51475068  8763180  40074064  18% /tmp
   /dev/mapper/vg_dranchlt3-lv_home 249515908 21266576 215551528   9% /tmp/home



Install the new kernel you just compiled:

   #This takes about 30 seconds for all of these steps
   sudo make modules_install
   sudo cp arch/arm/boot/dts/*.dtb /boot/
   sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
   sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
   sudo cp arch/arm/boot/zImage /boot/$KERNEL.img


Confirm what you now have installed:

   #List the current kernel modules for current and previous kernels
   ls -la /lib/modules/
   --
   total 36
   drwxr-xr-x  9 root root 4096 Jan 27 13:26 .
   drwxr-xr-x 16 root root 4096 Jun 26  2018 ..
   drwxr-xr-x  3 root root 4096 Aug  4 14:21 4.14.59+
   drwxr-xr-x  3 root root 4096 Aug  4 14:21 4.14.59-v7+
   drwxr-xr-x  3 root root 4096 Dec  8 12:35 4.14.79+
   drwxr-xr-x  3 root root 4096 Dec  8 12:35 4.14.79-v7+
   drwxr-xr-x  3 root root 4096 Jan 19 10:14 4.14.93+
   drwxr-xr-x  3 root root 4096 Jan 19 10:14 4.14.93-v7+
   drwxr-xr-x  3 root root 4096 Jan 27 13:26 4.14.95-v7+  <-------------------
   --

   #List the current and previous kernels
   ls -la /boot
   --
   total 17226
   drwxr-xr-x  3 root root    3072 Dec 31  1969 .
   drwxr-xr-x 23 root root    4096 Aug  4 14:17 ..
   -rwxr-xr-x  1 root root   23315 Jan 27 13:26 bcm2708-rpi-0-w.dtb  <-------------------
   -rwxr-xr-x  1 root root   22812 Jan 27 13:26 bcm2708-rpi-b.dtb  <-------------------
   -rwxr-xr-x  1 root root   23071 Jan 27 13:26 bcm2708-rpi-b-plus.dtb  <-------------------
   -rwxr-xr-x  1 root root   22589 Jan 27 13:26 bcm2708-rpi-cm.dtb  <-------------------
   -rwxr-xr-x  1 root root   24115 Jan 27 13:26 bcm2709-rpi-2-b.dtb  <-------------------
   -rwxr-xr-x  1 root root   25311 Jan 27 13:26 bcm2710-rpi-3-b.dtb  <-------------------
   -rwxr-xr-x  1 root root   25914 Jan 27 13:26 bcm2710-rpi-3-b-plus.dtb  <-------------------
   -rwxr-xr-x  1 root root   24087 Jan 27 13:26 bcm2710-rpi-cm3.dtb  <-------------------
   -rwxr-xr-x  1 root root   17513 Jan 27 13:26 bcm2835-rpi-a.dtb  <-------------------
   -rwxr-xr-x  1 root root   17629 Jan 27 13:26 bcm2835-rpi-a-plus.dtb  <-------------------
   -rwxr-xr-x  1 root root   17659 Jan 27 13:26 bcm2835-rpi-b.dtb  <-------------------
   -rwxr-xr-x  1 root root   17916 Jan 27 13:26 bcm2835-rpi-b-plus.dtb  <-------------------
   -rwxr-xr-x  1 root root   17792 Jan 27 13:26 bcm2835-rpi-b-rev2.dtb  <-------------------
   -rwxr-xr-x  1 root root   17617 Jan 27 13:26 bcm2835-rpi-zero.dtb  <-------------------
   -rwxr-xr-x  1 root root   17822 Jan 27 13:26 bcm2835-rpi-zero-w.dtb  <-------------------
   -rwxr-xr-x  1 root root   18448 Jan 27 13:26 bcm2836-rpi-2-b.dtb  <-------------------
   -rwxr-xr-x  1 root root   18266 Jan 27 13:26 bcm2837-rpi-3-b.dtb  <-------------------
   -rwxr-xr-x  1 root root   52296 Jan 19 10:14 bootcode.bin
   -rwxr-xr-x  1 root root     142 Jul 11  2018 cmdline.txt
   -rwxr-xr-x  1 root root    1601 Jun 26  2018 config.txt
   -rwxr-xr-x  1 root root   18693 Dec  8 12:36 COPYING.linux
   -rwxr-xr-x  1 root root      41 Jan 19 10:14 .firmware_revision
   -rwxr-xr-x  1 root root    2628 Jan 19 10:14 fixup_cd.dat
   -rwxr-xr-x  1 root root    6695 Jan 19 10:14 fixup.dat
   -rwxr-xr-x  1 root root    9895 Dec  8 12:35 fixup_db.dat
   -rwxr-xr-x  1 root root    9875 Jan 19 10:14 fixup_x.dat
   -rwxr-xr-x  1 root root     145 Jun 26  2018 issue.txt
   -rwxr-xr-x  1 root root 4930840 Jan 27 13:26 kernel7.img  <-------------------
   -rwxr-xr-x  1 root root 4695264 Jan 19 10:14 kernel.img
   -rwxr-xr-x  1 root root    1494 Dec  8 12:35 LICENCE.broadcom
   -rwxr-xr-x  1 root root   18974 Jun 26  2018 LICENSE.oracle
   drwxr-xr-x  2 root root   13312 Jan 27 13:26 overlays  <-------------------
   -rwxr-xr-x  1 root root  682532 Jan 19 10:14 start_cd.elf
   -rwxr-xr-x  1 root root 2869028 Jan 19 10:14 start.elf
   -rwxr-xr-x  1 root root 3955716 Jan 19 10:14 start_x.elf
   --

   #Confirm you have enough space in /boot
   df
   --
   Filesystem     1K-blocks    Used Available Use% Mounted on
   /dev/root       15240048 1915832  12672416  14% /
   devtmpfs          495480       0    495480   0% /dev
   tmpfs             500088       0    500088   0% /dev/shm
   tmpfs             500088   12908    487180   3% /run
   tmpfs               5120       4      5116   1% /run/lock
   tmpfs             500088       0    500088   0% /sys/fs/cgroup
   /dev/mmcblk0p1     43539   17632     25908  41% /boot
   tmpfs             100016       0    100016   0% /run/user/1001
   --


Ok, reboot the Raspberry Pi, log back into it and see what kernel version you're 
now running:
   --
   /sbin/shutdown -r now

   #Log back in after it's rebooted 

   #Check to see which version you're now running

   uname -a
   --
   Linux rpi3plus 4.14.95-v7+ #1 SMP Sun Jan 27 12:58:59 PST 2019 armv7l GNU/Linux
                  ^^^^^^^^^^^                                         ^^
   --

   Success!  We're now running 4.14.95 for the ARM v7 CPU


Ok, so why did I write all this up?  Let's assume you want to build a SPECIFIC kernel
version like 4.1.21 kernel, you would want to issue:

   git clone --depth=1 --branch rpi-4.1.y https://github.com/raspberrypi/linux

   #Then you have to create two workarounds for this specific older build on the newer Stretch OS
   cp include/linux/compiler-gcc5.h include/linux/compiler-gcc6.h

   and in the Makefile
   --
   
KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                   -fno-strict-aliasing -fno-common \
                   -Werror-implicit-function-declaration \
                   -Wno-format-security -Wno-error=unused-but-set-variable \
                   -std=gnu89
--

   #It also seems the build has to be done in separate steps
   time make -j4 zImage modules dtbs
   time make -j4 modules 
   time make -j4 dtbs

   Then do the rest of the build as usual which took 18min 37sec on a Rpi 3B+

--
   

100. Errata

Page Views since 05/11/21:

Flag Counter

# 05/31/21 - Added a new section on cases, fans, and temperature control
#          - updated the ntp and time with gpsd sections a bit
#          - Added a section of how to full or partial restores from your SD backup
#          - Added another GPIO pinout url
#          - Updated the index a little bit
#          - Did another spellcheck run

# 05/29/21 - indexed the hardware section for better linking 

# 05/12/21 - Fixed some minor HTTPS issues

# 05/11/21 - Revamped the legacy OSS Direwolf Dead Airtime TX support section 
           - Added mention of Signalink units and isolation transformers
           - Disabled the caching of this page so people will always get the newest
             version
           - Added a webhits tracker just to see how much the doc is really used by people

# 04/26/21 - Added some more bluetooth checks and examples; added notes for Windows 
#            clients

# 04/24/21 - Made the bluetooth serial console operational across reboots

# 04/22/21 - Added a new serial console over bluetooth section 

# 04/18/21 - Updated the shutdown button section to include some GPIO pin 
#            status and monitoring tools, improved the shutdown button testing, etc

# 04/16/21 - Updated the RTC section to be a little more clear on some steps as well
             as fixes for some high temperature scenarios

# 04/14/21 - Minor tweaks to the sudo vim /etc/watchdog.conf

# 04/12/21 - Make recommendation for users to be more selective on OS updates using
#            apt-get dist-upgrade --no-install-recommends

# 03/28/21 - Some improvements to the RTC section regarding I2C setup and troubleshooting
           - Added a mention in the Fe-Pi section about it's presence on the I2C bus

# 02/22/21 - Fixed the APRS LCD screen rotation

# 02/07/21 - Minor comment changes to the IPv6 workaround for GPSd

# 02/02/21 - Fixed the Direwolf DCD LED wiring hook up.  Thanks to Fred N7FMH for this one

# 01/18/21 - Some improvements made to the review-rpi-cpu.sh script
#          - Added mention of the RIM-Lite sound devices

# 01/01/21 - Noted that the USB-C power issue on Rpi4 boards was fixed in the Rpi4
#            v1.2 hardware revision

# 12/31/20 - Updated the warning about long /dev/serial/by-id names when editing
#            the /etc/ax25/ax25-up.new script

# 12/30/20 - Updated the Linpac section to push the "NOT RECOMMENDED" install using the Deb repo 
#            approach to the very bottom to minimize confusion

# 12/28/20 - Added some misc cleanups

# 12/24/20 - Added a mention that a similar I2S board like the FePi units are 
#            available from the Nexus DR-X people
#          - Added the inclusion the Masters Communications DRA-36 USB sound device

# 12/14/20 - Added a note about maximum PCM audio level output from the Fe-Pi
#            as well as how some radios have input gain settings

# 12/04/20 - Minor updates to the Direwolf section
#          - Added a note that Raspberry Pi OS now installs PulseAudio by default
#             which is a benefit for Bluetooth audio users

# 12/02/20 - Added details on how to interpret Direwolf level output and 
#            what it means in terms of "twist", etc.

# 11/29/20 - Cleared up some steps for building Direwolf between v1.6 and v1.5
#          - Updated the direwolf section index numbering
#          - Updated the DWC2 USB kernel module details to be clearer

# 11/23/20 - Added a section on alternative OS distros

# 11/22/20 - Added a new CRITICAL issue around long predictable /dev/serial/by-id names 
#            and kissattach for say serial connected KISS TNCs, etc
#          - Clarified the "Work around for significant Predicable Interface naming bug with AX.25"
#            section

# 11/21/20 - Added Kenwood D710 KISS TNC support to the setup
           - Added notes that the Fe-Pi Audio Z v2 HAT board seems to be EOLed

# 11/13/20 - Tuned the Fe-Pi mixer settings; more hints around the Nexus DR-X and
             NW Digital boards

# 11/10/20 - Added more details for the CM3+

# 11/04/20 - Added the new Raspberry Pi 400 specs and other HW spec cleanups

# 10/31/20 - Added a direct link to the Direwolf dead TX workaround section

# 10/29/20 - Updated the Direwolf instructions to reflect the new final 1.6 release
              - removed unneeded patches for Direwolf 1.6 beta 
           - Substantial updates to the hardware section with more clarity around the 
             Compute Module 4 (CM4) and CM4IO
           - Added notes around rc.local deprecation on systemd-enabled OSes

# 10/27/20 - Added mention of other sound devices like the DINAH, DRAWS, Nexus DR-X, etc

# 10/20/20 - Added details on the new Raspberry pi 4 Compute module and I/O board
           - Added some gross HTML code at the top of this page for image rotation; 
             Please let me know if this doesn't look right on your browser

# 10/11/20 - Updated the Direwolf section to detail various options for users to
             avoid the dead TX airtime DWC / direwolf issue

# 10/07/20 - Updated the Direwolf TX dead-air issue and added updates on the OSS 
             workaround but also added fix details and NEW possible work arounds

# 10/06/20 - Fixed a incorrectly specified /etc/asoundrc filename

# 09/30/20 - Added CSD decoder URLs in the uSD hardware section

# 09/24/20 - Did a significant review, re-formatting, and improved steps for many sections
             across the entire doc
           - Added download links for the iptables rulesets
           - Added a section on assigning static IPs for eth0
           - Minor index formatting fixes

# 09/08/20 - Updated the 20d.soundcard-mixer section a bit to recommend users to ONLY
             turn up the output to the soundcard channel (LEFT or RIGHT) connected to the 
             radio and put the other level to 0.
           - Improved some of the working and formatting of this soundcard-mixer section 
              
# 09/07/20 - Minor updates

# 08/26/20 - Added "30.a Configure your Rpi to connect to an existing Wifi AP for network access"

# 08/08/20 - Added mentions of Debian Unstable aka Sid to building Direwolf

# 07/26/20 - Added a recommendation to only use Class-10 SD cards and a URL of how to learn
             more and benchmark your chosen card
           - Added a link to the sound chip for the Fe-Pi
           - Added more critical notes around the Fe-Pi's "headphone mux" setting

# 07/23/20 - Added some aoss-style Direwolf troubleshooting steps

# 07/13/20 - Added a small blurb on picking a radio for your setup and what to be aware of

# 06/17/20 - Minor improvements to the Direwolf OSS workaround section

# 06/05/20 - Minor index changes

# 06/01/20 - Added a possible alternative I2S soundcard to the Fe-Pi AudioZ

# 05/29/20 - Added mention of the new 8GB Raspberry Pi 4, newly renamed Raspberry Pi OS (was 
             Raspbian), and mention of the upcoming native 64bit Raspberry Pi OS version

# 05/25/20 - Updated the Rpi SD image section as the SD card backup section to move from
             the image-raspbian-zip-to-rpi-sd-card.sh script to image-rpi-sdcard-multiformat.sh
             which supports multiple formats

# 05/08/20 - Fixed the Direwolf Cpack patch

# 04/15/20 - Added a Direwolf Cpack fix to address the incorrect 0.1.1 version issue
           - Fixed typo with applying Direwolf OSS patch

# 04/14/20 - Added spec URLs for what GPIO pins are initialized high/low in the PTT GPIO section

# 04/13/20 - Added a kissparms setting in the /etc/ax25/ax25-up.new script to disable the CRC 
#            which hurts the initial packet connection upon reboot

# 04/05/20 - Fixed the wrong command to make the listen program SUID root
#          - Added the disabling of Wifi
#          - made the disabling of Bluetooth more comprehensive
#          - Added links to a recommended installed package
#          - Added a section on how to only use SSH keys and disable passwords 

# 04/02/20 - Changed the aplay test example to be more generic to find more hardware possibilities

# 03/31/20 - Fixed the updating of tocalls for Direwolf

# 03/27/20 - Fix duplicate HTML section tags for the Linpac section

# 03/08/20 - Updated section 6 on SD card protection to mention two new options.  Once is to enable
#            the new OverLayFS option or make the SD card read-only
#          - Improvements to the watchdog section
#          - Other minor wording improvements

# 03/07/20 - Updated the full hostapd.conf file to deal with new incompatibilities with 
#            rts and fragmentation settings

# 03/02/20 - Added notes on which boards run which kernel file images

# 01/17/20 - Updated the Rpi stability testing section a little using "stress"

# 01/12/20 - Updated Direwolf DEV to 1.6D and updated the build section to better support the OSS
             sound card workaround as well as be more consistent

# 12/29/19 - Updated the Linpac develop release to 0.27

# 12/21/19 - Added libudev-dev to the Direwolf section as a preparation for Direwolf 1.6 when
             it releases

# 12/15/19 - Clarifications on the Rpi v3 wifi connection being direct and NOT thought the 
             USB bus

# 12/14/19 - Added a serial port section to the Rpi hardware differences section

# 12/08/19 - Updated the Direwolf section to support the new Direwolf 1.6 Cmake system
           - Updated the soundcard test section to test either the Fe-Pi or USB soundcard options
           - Started moving the documentation to use "apt" instead of "apt-get"

# 12/02/19 - Added mentions of new November firmware that lowers the Rpi4 power consumption
             as well as new reports of Wifi interference with different HDMI display resolutions

# 11/30/19 - Fixed an important missing "2" in the pishutdown2.py call in rc.local

# 11/10/19 - Added how to check out Direwolf's DEV branch via git

# 11/09/19 - Hardware section update to mention that the Rpi4 now has all Broadcom firmware
             on a dedicated eeprom chip vs. all previous Rpi firmwares were stored on the 
             SD card
           - Mention in the RTC and Direwolf section how an RTC clock can avoid very old 
             APRS packets from getting igated weeks later

# 10/10/19 - Typo cleanups

# 08/29/19 - Updated Rpi3 specs

# 08/27/19 - Added Rpi 1+ hardware specs

# 08/09/19 - Added the analyze-direwolf-packetlog.sh script into the archive for users 
             who like to learn more about what Direwolf is hearing.  Use the new 
             run-aprs-analysis.sh script to run nightly via cron

# 07/26/19 - Some cleanup in the firewall section and removed the unused 
             rules.v4-test step

# 07/24/19 - Some additional cleanups and improvements to the gpsd section say not
             to auto-detect new GPS units, etc.

# 07/22/19 - Added the "v" option to the firewall verification section to be more clear

# 07/21/19 - Updated various sections including RTC and GPS sections a bit
           - Made updates about the initial raspi-config setup working strange for
             Buster after changing the Locale encoding and doing a reboot might be wise
             before continuing on

# 07/21/19 - Updated the DS3231 RTC section on understanding more about counterfeit DS3231
             boards, where to get boards with real chips, and another check if your RTC
             is running on a different I2C bus
           - Updated the downloaded Raspbian Buster image which is now using the officially
             released Debian Buster URLs; as some specific fixes for dual monitors, etc.

# 07/20/19 - Added an extensive note on the fact that NFTABLES has become the default firewall 
             technology starting in Raspbian Buster over iptables.  This seems to be in a state
             of transition in Buster as key things are missing to be a complete nftables solution.
             I will add support for this in time but IPTABLES seems to still be the primary 
             interface in Buster to configure firewalls and it remains fully supported.

# 07/19/19 - Updated the manual-ampr-start.sh script with the new reduced AMPR address range

# 07/18/19 - Rpi hardware USB updates

# 07/17/19 - Minor index fixes

# 07/16/19 - Added another URL on buying quality micro-SD cards
           - major aspell spell checking run done

# 07/14/19 - Extensive soundcard section update to add full setup on the Fe-Pi I2S 
             sound device and why
           - Added Direwolf OSS work around support for USB-based sound devices
           - updated the ax25-up.new script to include checks and start the Direwolf OSS 
             workaround if required
           - Added a summary of differences in the hardware section

# 07/13/19 - Added a known USB hardware issue section
           - Added details on the used USB controllers with different Rpi hardware

# 07/10/19 - Added a note about a known problem with E-type USB-C power cables
             with the Rpi4
           - Added more modern terminology (Wifi-6) and USB 3.2 Gen 1

# 07/08/19 - Added more details in the external USB drive section

# 07/07/19 - Added a note around the missing libncursesw6-dev library
           - Added a sub-section on formatting your external storage device with a
             Linux file system
           - Updated the mount-usb-hd.sh script to be cleaner
           - Renamed the scratch storage area to /usr/src/archive/Rpi-scratch 
             instead of the previous Rpi2-scratch

# 07/04/19 - Updated the tmpfs RAM drive section to be more clear
           - Added a missing point to put the ax25mail-utils package updates
             on-hold to avoid the Raspbian repos from overwriting it

# 07/03/19 - Minor update in the Rpi hardware comparison section

# 07/02/19 - Updated the HDD idle and mount/umount sections a bit
           - More formatting cleanups

# 06/30/19 - Updated the watchdog section
           - Updated and added the use of the umount-usb-hd.sh and spindown-usb-hd.sh scripts
           - Upgraded Direwolf to version DEV 1.6C for Raspbian Buster

# 06/29/19 - Beginning support for the Raspberry Pi 4 and Buster
           - Major update to the Raspberry Pi HW differences section
           - Added support for initial IPv6 firewall rules
           - Make the formatting of this document a little less ugly

# 06/15/19 - Updated the /usr/local/bin/review-rpi-cpu.sh to better show the
             Rpi health bitmap, included C to F temp conversion, etc

# 06/12/19 - Clarified the warning when installing the libax25 package using 
             force-overwrite

# 05/11/19 - Added a link discussing all the alternative GPS-like satellite 
             systems running
           - Added a link for a cheaper CM108 sound device

# 03/24/19 - Added automake to support other debian related OSes (Mint)
           - Updated the ve7fet section to use shorter checkconfig descriptions
           - Updated the ve7fet libax25, ax25apps, and ax25tools versions
           - added th suid root work around for Linpac users not running ax25spyd
           - added a ax25spyd URL

# 03/16/19 - Removed the legacy installconf steps as they were confusing users

# 03/08/19 - Cleaned up the intro section and some index links

# 02/25/19 - Updated the update-glibc-ax25-workaround.sh notes

# 02/18/19 - Updated the RTC section to reflect that newer Raspbian versions somewhat
             correctly auto-configure DS3231 RTCs but not to support the temperature 
             sensors, etc.  Made other cleanups here as well.

# 02/10/19 - Updated notes on the AX.25 packages with the VE7FET repo, the Official AX.25
             repo, and Debian repos
           - Updated the linpac section to build from the Git develop branch
           - Updates to the Linpac section to add more sub-sections to build ax25mail-utils

# 01/27/19 - Added a new special topic on building new kernels.  This section is a work 
             in progress to support installing custom-built kernel modules for the ax.25
             system

# 12/29/18 - Added a link on USB soundcard enumeration

# 12/28/18 - Added a quick /tmp RAM drive expansion for packaging Direwolf
           - Cleaned up the index, aligned sub-topics, etc

# 12/07/18 - Basic reminder if autoreconf doesn't work, users didn't follow section 16 first

# 11/16/18 - Added the Raspberry Pi 3A+ to the specs area and cleaned up the section a little

# 11/10/18 - Updated to the ax25-up.new script that includes tuning of the AX.25 window sizes
             and other parameters

# 11/04/18 - Updated the Direwolf section to use a shorter description during the checkinstall 
#            packaging
#          - Added workarounds for increasing the /tmp file system when packaging direwolf

# 11/03/18 - Updated the watchdog section 

# 10/25/18 - Updated review-rpi-cpu.sh to include low power and CPU throttling counts

# 10/23/18 - Minor updates to the audio card packet level section

# 10/21/18 - Updated the ax25-up.new and ax25-up.new2 scripts to support new VE7FET changes to listen
#            and other improvements
#          - Updated the libax25 section to note that the use of the update-glibc-ax25-workaround.sh 
#            script is no longer needed if you're using the Aug 2018 version of the VE7FET repo
#          - Made several changes to the ax25-up.new script
#          - Minor index formatting fixes

# 10/20/18 - Major updates to the AX25 package builds from VE7FET to adapt to the removed 
#            "installconf" section
#          - Added missing step before compiling the AX25 packages to enter the 
#            /usr/src/archive/Rpi2-scratch/ directory
#          - Updated the note in the libax25 compile section since it seems the VE7FET
#            repo has been repaired.
#          - Added more formatting for the ax25 packages and made more clarifying comments

# 10/19/18 - Minor updates talking about when needing the Glibc patch workaround script 

# 10/18/18 - Significantly updated the "Enable local storage for demanding builds" section for new
#            Linux users

# 10/17/18 - Updated the optional USB HDD mount script section

# 10/11/18 - Update to Direwolf 1.5 final release

# 09/21/18 - Added a link for a decent 12v to 5v UBEC power source

# 09/09/18 - Added IPv6 firewall examples in the directory structure at
#            http://www.trinityos.com/HAM/CentosDigitalModes/RPi/etc/iptables/

# 09/06/18 - Added a note about IPv6 firewalls and how to do initial tests.  This document
#            does not fully cover IPv6 yet though I've added a minimal /etc/iptables/rules.v6
#            ruleset in the RPi directory snapshot

# 08/30/18 - Updated the TNC-Pi section to being up i2ckiss, etc.
#          - Improved the TNC-Pi section formatting a little 

# 08/28/18 - Remove avahi-daemon and expanded on the SSH section to include updating the
#            firewall to handle the change in port numbers

# 08/04/18 - Minor changes to the Rpi hardware section

# 07/20/18 - Added a comment in the TNC-Pi section to reboot the TNC after making any
#            register changes

# 07/19/18 - Added a note that a .deb force install is now needed for the ax25-tools
#            package due to three conflicting MAN page files
#          - Added a reminder in the picking a GPIO pin section about making sure the 
#            user has set the required GPIO Unix permissions

# 07/10/18 - Updated a URL for Raspbian and Bluetooth support

# 06/26/18 - Typo for section 70

# 05/24/18 - Some ax25 compile section cleanups

# 05/17/18 - Added a note about this doc is tested with Direwolf 1.4 but if newer versions of
#            Direwolf are available, I recommend to give them a try
#          - Fixed a broken index link

# 05/15/18 - Updated the download URL for the TNC-Pi utility

# 04/21/18 - Enhanced the iptables-ulog section to install any missing packages
#          - other typo fixes

# 04/05/18 - Added notes about enabling Wifi or SSH on a fresh install of Raspbian to enable remote
#             over-the-network only configuration

# 03/24/18 - Updated Direwolf

# 03/23/18 - More Hardware section formatting improvements

# 03/18/18 - Added a note in the AX.25 library section on how to use the update-glibc-ax25-workaround.sh
#            script when new glibc/libc updates come which cause upgrade failures

# 03/17/18 - Updated the Wifi AP+Client section a bit to include firewall updates, still kinda
#            broken but AP mode is working ok
#          - Updated the Differences in Raspberry Pi models to add the 3B+ and made the section 
#            a little clearer
#          - noted that the 3B+ doesn't support connecting a wifi u.fl connector for external 
#            antennas
#          - add a link to EOL dates for Raspbian (Jessie went EOL early)
#          - Updated the update-glibc-ax25-workaround.sh script a bit
#          - Updated the packet to Kenwood D74 section a bit
#          - Fixed some jump links

# 03/08/18 - Added dual/simultaneous wifi client AP access and AP mode 

# 02/03/18 - Enhanced the Bluetooth section a bit and updated the bt-kiss-bringup.sh script

# 01/25/18 - Noted that the official SD formatter program is now available for Mac too

# 01/19/18 - Added a few URLs for an opto-isolated PTT circuits

# 01/12/18 - Updated in the index a bit

# 01/05/18 - Intentionally included the #ed out bind-interfaces line in the dnsmasq.conf file
#            so that Dnsmasq can start and run to give IP addresses to Wifi users
#          - Added additional thoughts on installing Raspbian Pixel vs Raspbian Lite
#          - Added some specific recommendations to NOT connect your Rpi directly to the Internet
#            or have a port SSH port forward going to it until you harden it's configuration with
#            say exclusively using SSH keys and disabling SSH passwords, installing Fail2ban, etc.
#          - Made the recommendation to DELETE the "pi" user once the new account is working
#            for better security
#          - Updated the URL for buying a Syba USB sound device

# 12/31/17 - Added a link to the new bt-kiss-bringup.sh script to bring up AX.25 on a D74 HT
#          - Enhanced section 19 to say that if you aren't going to use Direwolf and, instead
#            are going to use a TNC-Pi or D74, skip to section 25 to get that going
           
# 12/30/17 - Updated the OS installation chapter to recommend installing Raspbian Stretch at all
#            costs.  
#          - Updated the details on the different hardware versions of the Rpi 

# 12/28/17 - IMPORTANT:
#            ----------
#            Added note that changes in some Linux distributions (Debian Stretch on x86 CPUs)
#            are making making the VE7FET AX.25 sources to go toxic but the Official AX.25 sources are 
#            working fine.  That's not to say there aren't important fixes in the VE7FET repo that 
#            aren't in the Official AX25 repo either.  For now, the VE7FET repo is fine for Raspbian 
#            Stretch but time might prove a switch might be required.  Stay tuned.
#
#          - Added libncursesw5-dev to compile ax25-apps
#          - Added a note about NOT to move the ax25.h GLIBC file if using Debian Buster

# 12/27/17 - Updated the Bluetooth section to support connecting to a Kenwood D74
#            as well as added some more advanced bluetooth commands
#          - Updated the first time power up section to monitor power brownouts via
#            seeing a yellow lightening bolt in the the upper right corner of the HDMI
#            display or the red power LED blinking.  Mentioned an inexpensive 5.1v @ 2.5A
#            power supply
#          - Added the useful tool "stress" for checking Rpi power brownouts
#          - Updated the different Rpi comparison section a bit

# 12/16/17 - New release

# 12/11/17 - Updated the Linpac version to 0.25

# 12/08/17 - Fixed some spelling errors

# 12/07/17 - Move the ax25mailutils and linpac downloads steps a bit

# 11/22/17 - Added top pictures of the LCD and RTC with click-on zoom
#          - Added reading the temp off the DS3231 RTC

# 11/20/17 - Added a new appendix section to display date, time, Internet health check, heard AX25 
#            packets, and CPU load to an I2C driven 20x4 LCD display
#          - Added a new appendix section to have the Rpi set it's date via an I2C driven
#            DS3231 RTC.  

# 11/17/17 - Updated the USB APM section and added a script to manually spin down the drive

# 11/05/17 - New publish

# 11/01/17 - Updated the Linpac configuration section regarding SSIDs to be a bit clearer

# 10/31/17 - Clarifications on BBS hierarchical addressing in Linpac

# 10/30/17 - Align the axports file to use a speed of 19200 though it doesn't really matter here
#          - Mentioned that WD Blue and WD Green series drives also do NOT support APM_level 

# 10/26/17 - Added a new hostapd issue and work around where dnsmasq won't come up 

# 10/25/17 - Added a new review the bootup logs chapter to confirm that the system is booting up without
#            errors.  Recommended to periodically do after applying OS patches to make sure things didn't
#            break
#          - Fixed some HTML character encoding issues like &, etc

# 10/22/17 - Removed the delaycompress option from all the logrotate configuration files
#          - Fixed the logrotate section to properly manage the ulogd_traffic-emu1.log file

# 10/21/17 - Added an attribute for the Linpac patch from Martin Cooper KD6YAM

# 10/16/17 - Added critical steps to enable HOLDS on the libax25, ax25-apps, ax25-tools, and Linpac
#            packages which are currently known TOCIC in the Deb repos.  Without these "holds" in place,
#            your locally built packages will get overwritten with the known toxic versions
#          - Updated the Linpac section to apply a new patch to avoid some issues when built with newer 
#            versions of GCC.  This patch will soon be integrated into Linpac 0.25
        
# 10/15/17 - Changed out to a new pishutdown2.py script that includes debouncing to avoid false shutdowns
#            due to say RFI, etc.
#          - Added that users now need to disable apt-daily.service to avoid automatic updates
#            in addition to removing the unattended-upgrades package

# 10/12/17 - Added package requirements to run ax25-up.new scripts

# 10/08/17 - Fixed a missing permission stage for creating /usr/src/archive
#          - moved up the zlib1g requirement for the base libax25 package
#          - updated details on the predictable network interface names issue
#          - Some additional Direwolf checkinstall cleanups for vanilla Debian

# 09/29/17 - Fixed a cut/paste issue for installing ax25mail-utils-0.13

# 09/26/17 - Fixed some incorrect AX.25 interface names named "vhfport" when they should have been
#            vhfdrop
#          - Philosophy mention of why the direwolf.conf is in /etc/ax25
#          - added missing zlib dependencies for ax25-tools

# 09/05/17 - Increase the RAM drives for /tmp to 10MB and /var/log/ to 50MB
#          - Added a log rotation max size limit of 10M to the /var/log/packet, ax25-listen.log, 
#            and ulogd_traffic-emu1.log files
#          - Significant changes to the Wifi AP section to be compatible with Stretch
#          - Added an important warning about possible wifi vs. bluetooth reliability issues
#          - Added a recommended USB-based GPS receiver
#          - Retooled and enhanced the image backup section a bit
#          - Updated the intro section

# 09/02/17 - Added a CRITICAL work around for AX.25 and Persistent Interface naming issues
#          - Added alternative media idea to send logs to instead of the temporary RAM drive
#          - added a GPSD fix if IPv6 is disabled
#          - Added steps to install linpac and ax25mail-utils from apt-get 
#          - mentioned there might be issues with using the Linpac binaries and the VE7FET ax.25
#            repo
#          - Enabled another F-key in the example for Linpac
#          - Added a final testing section
#          - Updated the ax25-up.new and ax25-up.new2 scripts to add more testing, Linpac start,
#            etc

# 08/29/17 - Added openssl-blacklist to the Email/Postfix section
#          - Made logrotate it's own section and renumbered all other sections to fit
#          - Added the Ulogd logs into the logrotate system
#          - Added key missing "--" in the mailx test
#          - Noted that Watchdog support in Stretch is questionable; will revisit

# 08/28/17 - Signification improvements in documentation, clearer steps throughout, etc.
#          - Added that simultaneous wifi and BT support on the Rpi v3 doesn't work well
#          - Corrected sudo command for iptables-save compound command
#          - Added how to use alternative SSH listening ports 
#          - Added a key note that no IPv6 firewall is created and to disable IPv6 for now
#          - Completed the ulogd section and using the new NFLOG approach so no more iptables
#            filter hits in the /var/log/syslog nor dmesg logs!

# 08/27/17 - Added a top note that I will be updating this document to support Raspbian Stretch
#            as time permits

# 08/21/17 - Various fixes as reported from KI6NJF : appending new unix groups to existing groups; 
#            disable auto-login added some clarification on hard drive spindown issues; missing 
#            '" root' on the mailx command on reboots; mentioned notes of not needing to unmount
#            /tmp; moved the packet monitor to TTY8

# 08/20/17 - Added an option section in the Direwolf.conf section on how to enable APRS-IS RX-only Igate
#            and MSG only TX-Igate functionality
#          - Added a section on how to interactively test APRS-IS filters with TELNET
#          - Updated the Direwolf compiling section to reflect improvements and a repaired Direwolf-1.4-patch
#            file
#          - updated the /usr/local/sbin/mount-usb-hd.sh script to use non LVM-partitioned USB HDs
#          - Mentioned an alternative tool "iptables-apply" to safely enable to firewall rulesets
#          - fixed some index numbering in the IPTABLES section and corrected some HTML formatting
#            issues for < characters

# 08/06/17 - Minor formatting cleanups for the index and other sections; spell check run

# 08/05/17 - Renamed section 1 to reflect it's contents a bit better

# 07/23/17 - New intro section
#          - Added a new tricks.management section about other scripts to monitor the Rpi's
#            CPU and temp and other useful sysadmin scripts

# 07/05/17 - Extensively updated the Wifi AP and Linpac sections
#          - Updated the pyshutdown GPIO button section
#          - more clearly deprecated the legacy rtl8192 wifi sections

# 06/03/17 - Enhanced the manual-ampr-start.sh script with the new ampr-ripd 2.2 and other cleanups

# 04/27/17 - Updated Direwolf to 1.4 (final release version)

# 04/24/17 - Added a test OBEACON object

# 04/20/17 - Updated the Direwolf build a bit

# 04/07/17 - Corrected required Direwolf checkinstall packages as we don't need the -dev versions

# 03/16/17 - updated checkconfig package description to be all on one line

# 03/09/17 - Updated the SD card imaging section to recommend using larger card sides, pre-format it,
#          - Updates on the Rpiv3 vs Rpiv2 boards
#          - Updated GPS setup section

# 02/28/17 - Added a URL for Bluetooth audio support

# 02/26/17 - Added a note to remove the unattended-upgrades package

# 02/21/17 - Updated setting the proper hostname and FQDN for the Rpi

# 02/20/17 - Added systemd logging to the pyshutdown section to better monitor when it's
#            being activated

# 01/13/17 - Added sending an email to root when the pi is rebooted
#          - Updated the watchdog section a bit

# 12/12/16 - Added HW watchdog support
#          - Added the beginnings of ulogd2 support to send iptables log lines to
#            a different file

# 12/10/16 - Added specific links for the firewall-confirm.sh script
#          - added the removal of the Avahi daemon

# 11/27/16 - Added libgps-dev to add gps support to direwolf
#          - Add some clarifying points for compiling Direwolf 1.4 Alpha

# 11/06/16 - Added a short section on HW vs SW TNCs 
#          - Added an appendix on supporting the TNC-Pi HAT HW TNC

# 10/23/16 - Updated the postfix relayhost section

# 10/22/16 - Added missing gpio group to new user creation

# 10/20/16 - Added in a lot of missing sudo command in the firewall section
#          - Enabled a beacon into Direwolf itself to indicate the system's
#            position
#          - added dnsutils as another package to install in the postfix section

# 10/19/16 - Combined the LED and Bluetooth tricks section

# 10/17/16 - Added NTP support 
#          - Added the beginnings of i2c-tncpi support to the ax25-up.new script
#          - Added a ax25 testing subsection
#          - Added a silent audio quality check section 

# 10/14/16 - Updated the GPS section to support Jessie
#          - Updated the SD card backup section to make duplicate cards

# 10/13/16 - Updated intro to talk about the Rpi v3 hardware

# 10/12/16 - More clarity on Direwolf sound device naming
#          - Added "audio" unix group to the new user creation
#          - More thoughts on recommended security hardening (TBD)

# 10/11/16 - Fixed the incorrect command usermode (should be usermod)

# 10/03/16 - Updated section 4's name a bit
#          - Added routing to clean up old rpi-update kernel modules

# 09/29/16 - Swapped some of the sections around for the PTT circuit

# 09/15/16 - Updated to direwolf 1.3 release from -F beta version
#            also improved the installation steps and the Makefile.linux
#          - Increased the tmsfs size for /tmp from 1Mbyte to 10Mbyte
#
# 09/14/16 - Wifi support completed
#          - Added a new Bluetooth cheatsheet section
#
# 09/11/16 - Initial Wifi for Rpi v3 support started

# 09/08/16 - Updates from W6ELA
#            - Added URLs for proper TXDELAY tuning
#            - Started a new section on configuring the Wifi AP using the Rpi3 wifi and
#              deprecating the RTL8192 support (hacky, poorly supported, etc)

# 08/26/16 - Added the video unix group 
#          - Added a link to tuning your packet levels

# 08/17/16 - Moved up the connecting your radio and Wifi AP sections

# 08/14/16 - Working on adding Raspbian Jessie based Wifi AP support

# 08/07/16 - Added a note about allowing the HDMI port to always be enabled

# 08/06/16 - Added the PiShutdown section
#          - Added more details on GPIO pinouts, selection for Direwolf DCD

# 08/04/16 - Added the part number to the Syba soundcard recommendation

# 08/01/16 - HTMLized the document

# 05/22/16 - reordered the initial security section
#          - implemented the firewall-confirm.sh script
#          - Changed the method to lock the pi account, groupadds, etc

# 05/06/16 - Added a point to install rpi-update if it's not installed already

# 04/30/16 - Added to the HDD powerdown section

# 04/15/16 - Added an alternative way to find sound card input sampling rates
#          - Added rough notes to set NTP time ASAP

# 03/16/16 - Added recommend to create a new sudo-enabled account and DISABLE 
#            the pi account

# 03/06/16 - Added an additional todo item

# 03/05/16 - Added a gotcha section on how to fix an Rpi not being able to reboot

# 03/04/16 - Added references to alternative / pre-build Rpi images

# 02/27/16 - Added a new interactive GPIO pinout website URL

# 12/12/15 - Added DHCP client support to the firewall

# 12/11/15 - Updated iptables example to drop but not log chatty network traffic
#          - Added changes to the /etc/rsyslog.conf file for a broken setting that
#            creates a huge amount of of logs as well as other overly chatty logs
#            and duplication
#          - Added a critical fix for proper keyboard mappings to log in via the 
#            local HDMI console

# 12/10/15 - Updated logrotate configs to be more aggressive

# 12/06/15 - Added a note on the FIX_BITS option

# 11/30/15 - Fixed raspi-config typo

# 11/29/15 - Updated the Linpac section
#          - Updated the /etc/ax25/ax25-up.new2 script

# 11/28/15 - More clear wording about needing to adapt the PTT circuit for peoples
#            specific radio
#          - Mentioned that the settings in /etc/ax25/ax25-up.new override settings 
#            originally loaded in direwolf.conf
#          - Added Linpac

# 11/26/15 - Recommend to create a new user account and DISABLE the default "pi" 
#            account
#          - Formatting improvements

# 11/24/15 - Added a critical point about microphone bias voltages from soundcards 
#            and radios

# 11/21/15 - Added an iptables section to secure the Rpi as soon as possible
#          - Dump more packages upon first install

# 11/07/15 - Added index; revamping all sections sequentially

# 10/21/15 - Added HD APM ; shutdown button

# 10/14/15 - initial version (based on the old Wheezy doc)