Close
0%
0%

Home_LAB

Network Lab

Similar projects worth following
My HomeLAB is a hands-on network, firewall, and virtualization lab built from repurposed enterprise hardware, including a Cisco Catalyst 3850, SonicWall NSA 2650, Cisco ASA 5525-X, UniFi access points, and a Dell PowerEdge R740 running Proxmox. The project focuses on learning real-world networking through VLANs, routing, DNS filtering, firewall policies, wireless networking, virtualization, and security testing. A major part of the lab is the Cisco ASA 5525-X, which has been converted into a dual-boot appliance capable of running both Cisco ASA firmware and pfSense. pfSense currently provides DNS resolution and filtering through Unbound and pfBlockerNG, while the Proxmox server hosts services including FreePBX, macOS Tahoe 26.5.2, Ubuntu Server, and a dedicated Minecraft Bedrock server.
  • 2 × SonicWALL NSA 2650
  • 1 × Cisco ASA 5525-X Running pFsense
  • 1 × Cisco ISR4431/K9 w/ NIM-2GE-CU-SFP booster_performance, securityk9, appxk9, hseck9-ALT
  • 2 × Cisco CP-8845 VoIP Phone Enterprise Firmware
  • 1 × Cisco WS-C3850-48U-L w/ NM-4-1G

View all 11 components

  • The current state

    Rhea Rae08/06/2026 at 20:22 0 comments

    I finally had a chance to get my Catalyst 3850 12X 48 UPOE in to the main rack and configured a temporary Trunk so I can slowly migrate my first catalyst then install the first catalyst into the new upstairs rack which currently has no PoE only a dumb switch atm, after migration I will have PoE upstairs :)

    -RR

  • Fixing Spider-Man’s Resolution in the Gaming VM

    Rhea Rae08/02/2026 at 14:17 0 comments

    After getting my Windows 11 gaming VM running through Sunshine and Moonlight, I ran into a resolution problem while testing Marvel’s Spider-Man Remastered. The game would not let me select 1920×1080 or 2560×1440, and the highest available option was only around 1360×768. This was confusing because Windows was already using the NVIDIA VGX virtual display at 2560×1440, with an active signal resolution of 2560×1600 at approximately 60 Hz. I confirmed that the NVIDIA VGX display was already set as the main display, so the game was not simply opening on the lower-resolution Proxmox display.

    The problem turned out to be the list of resolutions being reported by the NVIDIA VGX virtual monitor. Windows could operate the desktop at a higher resolution, but the virtual monitor’s EDID was not properly advertising common display modes such as 1920×1080, 2560×1440, and 2560×1600 to games. Spider-Man was reading that incomplete resolution list and limiting the available options. I first tried creating custom resolutions through the NVIDIA Control Panel, but the Customize menu would not allow me to enter them manually.

    I solved the problem by using Custom Resolution Utility, also known as CRU. Before making any changes, I created a stopped Proxmox snapshot of the gaming VM so I would have a safe recovery point. In CRU, I selected the active NVIDIA VGX display and added detailed resolutions for 1920×1080, 2560×1440, and 2560×1600 at 60 Hz using the Automatic PC timing option. I left the existing resolutions in place, saved the configuration, and restarted Windows so the new EDID override would load.

    After the restart, Spider-Man finally detected the correct higher-resolution options. I selected 2560×1440 because it matches the 16:9 aspect ratio of the television and Moonlight client display. The visual improvement was immediately noticeable. The image became much sharper, textures looked clearer, and the overall graphics quality finally reflected what the Tesla P100 was capable of producing.

    This confirmed that the problem was not caused by the Tesla P100, Sunshine, Moonlight, or Spider-Man itself. The issue was the incomplete resolution list being advertised by the NVIDIA VGX virtual display. The gaming VM is now running Spider-Man at 2560×1440 at approximately 60 Hz using the Tesla P100’s full 16 GB of VRAM, and the game looks dramatically better than it did at 1360×768.

    Side note is also that its capable of 4K as well however i currently game at 1440. 

    -RR

  • I Turned a Tesla P100 Into a Remote Gaming GPU

    Rhea Rae08/01/2026 at 21:35 0 comments

    Today I completed one of the more unusual parts of my Dell PowerEdge R740 project: I turned a headless NVIDIA Tesla P100 into the GPU for a fully functional Windows 11 remote-gaming VM.

    The finished system can stream a 1920×1080 Windows gaming desktop from my R740 to an older laptop using Sunshine and Moonlight. Video, audio, keyboard, and mouse input all work correctly. I connected the laptop to my upstairs television and successfully played Minecraft with the graphics settings turned all the way up.

    The experience was smooth enough that the old laptop effectively became a thin gaming client. My R740 performs the actual game rendering, while the laptop only has to decode the video stream, display it, and send my controls back to the VM.

    This was not a plug-and-play installation. The Tesla P100 was designed as a data-center compute accelerator rather than a consumer gaming card. It has 16 GB of high-bandwidth HBM2 memory, but it does not have any physical video outputs. Its normal compute-oriented configuration also does not automatically provide the Windows display environment expected by games and game-streaming software.

    To make it work, I had to solve several separate problems involving PCIe passthrough, Windows driver mode, NVIDIA licensing profiles, virtual-display resolution, Sunshine and Moonlight networking, and Windows’ handling of multiple virtual displays.

    My host and VM configuration

    My host is a Dell PowerEdge R740 running Proxmox VE. It currently has two Intel Xeon Gold 6138 processors, 128 GB of ECC DDR4 memory, and multiple NVIDIA Tesla P100 16 GB PCIe cards.

    I created a dedicated Windows gaming system as Proxmox VM 106 with the following configuration:

    • Windows 11 Pro
    • Q35 machine type
    • OVMF/UEFI firmware
    • TPM 2.0
    • One socket with eight host CPU cores
    • 16 GB of fixed RAM
    • Memory ballooning disabled
    • VirtIO SCSI Single controller
    • SSD emulation enabled
    • Discard and I/O thread enabled
    • Virtual disk stored on my wdblue-ssd LVM-thin storage pool
    • Initial virtual disk size of 150 GB
    • Virtual disk later expanded to approximately 500 GB
    • Network connection through vmbr0
    • Full Tesla P100 PCIe passthrough
    • Default Proxmox virtual display retained as a recovery console

    The Tesla P100 assigned to the gaming VM was detected by the Proxmox host at:

    0000:d8:00.0

    I attached it to VM 106 with:

    qm set 106 -hostpci0 0000:d8:00.0,pcie=1

    I enabled the PCI Express and ROM-Bar options. I left “All Functions” and “Primary GPU” disabled, and I retained the default Proxmox virtual display.

    Keeping the Proxmox display turned out to be important. Because the Tesla P100 has no monitor connector, the Proxmox console gave me a fallback display that I could still access whenever the NVIDIA virtual display was unavailable or incorrectly configured.

    This is full PCIe passthrough of a physical P100. I am not splitting the GPU into multiple smaller vGPU instances. The NVIDIA GRID software inside Windows provides the WDDM driver and NVIDIA VGX virtual-display stack required to use the headless GPU as a remote graphics workstation.

    Getting the P100 into Windows graphics mode

    Inside Windows, I installed NVIDIA GRID guest driver version 539.72:

    539.72_grid_win10_win11_server2019_server2022_dch_64bit_international.exe

    After completing an Express installation and restarting the VM, Windows recognized the card as:

    NVIDIA Tesla P100-PCIE-16GB

    The Tesla was operating under Windows Display Driver Model mode rather than remaining in its compute-focused TCC mode. NVIDIA Control Panel worked, and the driver created an NVIDIA VGX virtual monitor.

    The initial license information reported:

    • Product: NVIDIA Virtual Applications
    • License status: Licensed
    • Expiry: N/A

    Windows could see the complete 16 GB of P100 video memory. This is not a small emulated graphics adapter—the VM has direct access to the real P100 and its entire memory capacity.

    However, I discovered that the NVIDIA Virtual Applications...

    Read more »

  • AI

    Rhea Rae08/01/2026 at 12:43 0 comments

    3x NVIDIA P100 16gb, Dell R740 128gb DDR4

  • NVIDIA Tesla P100

    Rhea Rae07/25/2026 at 21:44 0 comments

  • Unit acquired :)

    Rhea Rae07/20/2026 at 18:38 0 comments

    tbh prolly the best 100$ I have spent yet .

    -RR

  • A New Not New Switch Has My Attention...

    Rhea Rae07/16/2026 at 20:13 0 comments

    I know there are much newer and faster switches available today. There are Catalyst 9300s, Nexus switches, and plenty of white-box options that outperform the 3850 in almost every way.

    But I have a soft spot for the Catalyst 3850 series.

    Over the past several months I've configured, repaired, reset, tested, and sold hundreds of them at work. They've become one of those pieces of hardware that I know inside and out. They're reliable, well-built, and still more than capable for a homelab.

    That's why finding a WS-C3850-12X48U-L caught my attention. It has all the things I already like about the 3850 platform, but with twelve multigigabit copper ports that make it a little more unique. 1, 2.5, 5 and 10G!

    Is it the most practical switch I could buy? Probably not.

    Is it the one I want? Absolutely.

    -RR

  • Home Lab Project Status Update – July 2026

    Rhea Rae07/13/2026 at 22:02 0 comments

    A lot has happened with the home lab since my last proper update. Some of it went exactly the way I hoped, some of it definitely did not, and a few parts turned into much bigger projects than I originally expected.

    The whole lab started because I wanted to move my FreePBX phone server off my main PC. I did not begin this with some perfectly designed master plan. I had access to a Dell PowerEdge R740, I knew it had a lot of potential, and I wanted to see what I could build with it.

    That $50 server has now become the center of an actual working network. It runs virtual machines, Minecraft servers, a phone system, a local AI server, macOS, Linux systems, and other testing environments. Around it, I now have two Cisco Catalyst 3850 switches, a SonicWall firewall, a pfSense system, UniFi access points, cameras, internal Cisco phones, backup storage, and a growing amount of monitoring and automation.

    The lab is still not finished, and honestly, I do not think a home lab is ever really finished. Every time I complete one part, it gives me three more ideas.

    The Dell PowerEdge R740

    The main server is still my Dell PowerEdge R740, and it has received some major upgrades.

    When I first got the R740, it had two Intel Xeon Silver 4112 processors. Those are four-core processors, so the server originally had eight physical CPU cores total. It was usable, but it was nowhere near what the R740 platform was capable of doing.

    I replaced both of those processors with two Intel Xeon Gold 6138 processors. Each Gold 6138 has twenty physical cores and forty threads. The server now has forty physical CPU cores and eighty threads in total.

    That CPU swap completely changed the server.

    Before the upgrade, I could run virtual machines, but I had to be much more careful about how many CPU cores I assigned. After the upgrade, I could give the AI server, Minecraft servers, macOS VM, FreePBX, and other systems enough processing power without immediately running out of resources.

    The memory was also upgraded. The server originally had 64 GB of ECC DDR4 memory. I added another 64 GB, bringing it to 128 GB total.

    That extra memory was just as important as the CPU upgrade. Virtual machines use RAM quickly. The macOS VM has a large amount assigned to it, the AI server needs memory for models, the Minecraft servers each need their own allocation, and the Proxmox host still needs room to operate.

    With 128 GB installed, I have much more space to experiment without constantly shutting down one system to start another.

    I also upgraded the server to dual 1100-watt power supplies. Both power supplies are now installed, detected, and working properly. This gives the R740 the correct power capability for the processors, storage, PCIe cards, and GPU hardware I am installing.

    The server is running Proxmox VE, with iDRAC9 Enterprise handling remote management. I can monitor the hardware, view temperatures, manage power, access the console, and work on the server without always needing to be physically in front of it.

    The R740 has gone from being an inexpensive used server into a very capable virtualization and compute platform.

    The Graphics Card That Did Not Work

    The GPU side of this project did not start smoothly.

    The first graphics card I tried was an AMD Radeon Pro WX 5100 that I bought through eBay. The card did not work in the R740. At first, I was not sure whether the problem was the card, the server riser, the power configuration, the PCIe slot, or some Dell BIOS setting.

    I tested different server slots, checked iDRAC, checked the BIOS, inspected the risers, and went through the server configuration.

    Eventually, I removed the card from the R740 and installed it in my main PC as a final test. It still did not work.

    After looking more closely at the card, I found visible orange and brown discoloration near the shroud and circuit board. When I went back to the original listing photographs, the discoloration could also be seen there,...

    Read more »

  • _UPGRADE

    Rhea Rae07/11/2026 at 15:48 0 comments

    Now 128 Gb SK hynix DDR4 ECC RDIMM 2666 Ram. Spare GTX 980 for testing. Ordered GPU riser slot 1A for future 2nd powered GPU tests. This unit includes 2x Xeon Gold 6138 CPU upgraded from Silver CPU's.

  • Virtual Hackintosh running on Dell PowerEdge R740

    Rhea Rae07/03/2026 at 17:51 0 comments

View all 24 project logs

  • 1
    Cisco CP-8845 Enterprise SIP Configuration for FreePBX — Complete TFTP Setup Guide

    Cisco CP-8845 Enterprise SIP Configuration for FreePBX — Complete TFTP Setup Guide

    CONNECTING A CISCO CP-8845 ENTERPRISE PHONE TO FREEPBX
    DETAILED STEP-BY-STEP INSTRUCTIONS

    REVISION NOTE

    This copy was cleaned up after a successful second Cisco 8845 setup. It corrects the TFTP_OPTIONS line, clarifies CP-8845/8800-series wording, adds a note for systems where the normal user cannot use sudo, and uses tftp:tftp ownership for TFTP-served files to match the working setup.

    IMPORTANT SCOPE NOTE

    This guide explains how to register a Cisco CP-8845 that is already running Cisco Enterprise SIP firmware directly to a FreePBX/Asterisk PJSIP extension.

    The working lab setup used for developing this procedure was a Cisco CP-8845 running Enterprise SIP firmware. The CP-8841 and CP-8845 are members of the same Cisco 8800 Enterprise phone family and use the same basic TFTP and SEP configuration process. The CP-8841 was not the exact physical model used for the original test, so a firmware-specific menu name may differ slightly.

    This is not an Enterprise-to-MPP firmware conversion guide. The phone remains on Enterprise SIP firmware. You do not need to enter a Webex activation code, claim the phone to Cisco cloud services, or purchase an MPP conversion license merely to register it to FreePBX using this method.

    This guide covers local phone registration and internal calling. Connecting FreePBX to a public telephone provider requires a separate SIP trunk, inbound route, outbound route, emergency-calling configuration, and appropriate security precautions.

    PRIVACY AND SECURITY WARNING

    The finished SEP configuration file contains the SIP authentication password in plain text. TFTP also transfers files without encryption.

    Only run the TFTP service on a trusted private network. Never expose UDP port 69 directly to the internet. Never publish a completed SEP file containing real credentials.

    Before posting screenshots, files, packet captures, or logs publicly, remove or replace all of the following:

    - Real IP addresses
    - Phone MAC addresses
    - Extension numbers
    - SIP authentication usernames
    - SIP passwords or secrets
    - Personal names
    - Caller ID information
    - Telephone numbers
    - Hostnames
    - Serial numbers
    - SIP trunk credentials
    - Public IP addresses
    - Any internal domain names

    All addresses and identifiers shown in examples below are placeholders or documentation examples. Replace them with values from your own network.

    ======================================================================
    SECTION 1 - WHAT YOU NEED
    ======================================================================

    You need the following:

    1. A Cisco CP-8845, or another compatible Cisco 8800-series Enterprise SIP phone, already running Enterprise SIP firmware.
    2. A working FreePBX server.
    3. A network connection between the phone, the TFTP server, and FreePBX.
    4. A PoE switch, PoE injector, or the correct external power supply for the phone.
    5. DHCP service on the phone network.
    6. A TFTP server.
    7. One unused FreePBX PJSIP extension.
    8. The phone's 12-character MAC address.
    9. Administrative access to FreePBX.
    10. Command-line access to the Linux machine that will run TFTP.

    For the first setup attempt, place the phone and FreePBX on the same ordinary LAN or VLAN. Do not begin with NAT, a remote site, a VPN, a dedicated voice VLAN, or complicated access-control rules. First prove that the phone can download its file and register locally. Add network complexity afterward.

    The original working arrangement was:

    Cisco Enterprise phone
            |
            | Ethernet and PoE
            |
    Local network switch
            |
            +---- FreePBX/Asterisk
            |
            +---- TFTP service

    The TFTP service can run directly on the FreePBX host or on another trusted computer. The working setup used a Linux TFTP service and the directory /srv/tftp.

    ======================================================================
    SECTION 2 - IDENTIFY THE PHONE AND CONFIRM ENTERPRISE SIP FIRMWARE
    ======================================================================

    STEP 2.1 - Power on the phone

    Connect the phone to a PoE-capable Ethernet port or connect the correct external power supply. Allow it to finish booting.

    STEP 2.2 - Find the MAC address

    The MAC address may be printed on a label on the bottom of the phone. It can also normally be viewed from the phone's status or product-information menus.

    A MAC address contains 12 hexadecimal characters.

    Example only:

    00:11:22:AA:BB:CC

    Remove the colons, dashes, or spaces:

    001122AABBCC

    Convert letters to uppercase.

    The Cisco configuration filename will be:

    SEP001122AABBCC.cnf.xml

    The actual format is always:

    SEP + PHONE_MAC_WITHOUT_SEPARATORS + .cnf.xml

    The filename must contain exactly 12 MAC characters after SEP.

    Correct example:

    SEP001122AABBCC.cnf.xml

    Incorrect examples:

    SEP00:11:22:AA:BB:CC.cnf.xml
    sep001122aabbcc.cnf.xml
    SEP-001122AABBCC.cnf.xml
    SEP001122AABBCC.xml
    SEP001122AABBCC.cnf.XML

    Linux filenames are case-sensitive. Use uppercase SEP and uppercase MAC characters.

    STEP 2.3 - Confirm that the installed phone load is Enterprise SIP

    Open the phone's Applications menu and locate Product Information, Status, or Firmware Information. The exact menu name can vary.

    An Enterprise SIP load normally has a name beginning with something similar to:

    sip88xx...

    Do not follow MPP instructions that tell you to open a phone web page and configure Voice > Ext 1. That is an MPP workflow. Enterprise firmware normally receives its SIP account configuration through TFTP.

    If the phone is showing an activation-code or service-domain screen, do not enter a random code. Manual TFTP provisioning bypasses that hosted activation workflow.

    ======================================================================
    SECTION 3 - RECORD THE VALUES YOU WILL NEED
    ======================================================================

    Before creating anything, collect these values from your own system.

    PHONE_MAC_NO_SEPARATORS
    The phone's 12-character MAC address with no punctuation and with uppercase letters.

    PBX_IP_ADDRESS
    The local IP address of the FreePBX server.

    TFTP_IP_ADDRESS
    The local IP address of the machine running TFTP. If TFTP runs on FreePBX, this is normally the same as PBX_IP_ADDRESS.

    EXTENSION_NUMBER
    The new FreePBX extension assigned to this phone.

    AUTH_USERNAME
    The PJSIP authentication username. In a normal FreePBX extension, this is usually the same as EXTENSION_NUMBER.

    SIP_SECRET
    The PJSIP extension password generated or entered in FreePBX.

    DISPLAY_NAME
    The text that should appear on the phone.

    TIME_ZONE_STRING
    The Cisco time-zone string appropriate for the installation.

    NTP_SERVER
    A reachable Network Time Protocol server. A local NTP server is ideal, but a reachable public NTP hostname can also be used.

    Write these values somewhere private. Do not post them.

    For the first test, use a SIP secret made from letters and numbers. XML reserves characters including ampersand, less-than, and greater-than signs. Those characters must be escaped correctly inside XML. An alphanumeric password avoids a false failure during initial testing. After the phone is working, a more complex secret can be used as long as it is encoded correctly in the XML.

    ======================================================================
    SECTION 4 - CREATE THE FREEPBX PJSIP EXTENSION
    ======================================================================

    STEP 4.1 - Sign in to FreePBX

    Open the FreePBX administration interface in a browser and sign in with an administrator account.

    STEP 4.2 - Open the Extensions module

    On the FreePBX installation used for the working setup, Extensions was located under:

    Connectivity > Extensions

    Some FreePBX releases place it under:

    Applications > Extensions

    Open the Extensions page wherever it appears in your version.

    STEP 4.3 - Add a PJSIP extension

    Choose:

    Add New PJSIP Extension

    Do not create a chan_sip extension for this procedure. Use PJSIP.

    STEP 4.4 - Enter the extension information

    Set the following basic fields:

    User Extension:
    Enter an unused internal extension number.

    Display Name:
    Enter the label or user name that should identify the phone.

    Secret:
    Generate or enter a strong SIP password. Copy it exactly because it will be placed in the SEP XML file.

    The exact field names can vary slightly by FreePBX version.

    STEP 4.5 - Review the important PJSIP settings

    For a straightforward local registration, use or verify these values:

    Extension type:
    PJSIP

    Transport:
    UDP

    SIP signaling port:
    5060

    Max Contacts:
    1

    DTMF mode:
    RFC4733 or RFC

    Media encryption:
    None for the first local test

    Codec:
    Allow ulaw, also called G.711 mu-law, for the first test

    Voicemail:
    Optional

    Voicemail access code:
    *97 is commonly used for the phone's own mailbox

    Authentication username:
    Normally the extension number

    The FreePBX defaults for a local PJSIP extension are usually suitable. Avoid changing NAT, rewrite-contact, force-rport, RTP-symmetric, or direct-media settings unless the network design requires it. The original local setup did not require unusual NAT workarounds.

    STEP 4.6 - Submit the extension

    Click Submit.

    STEP 4.7 - Apply the configuration

    Click the red Apply Config button at the top of FreePBX.

    Do not skip Apply Config. The extension may appear in the GUI but will not be loaded fully into Asterisk until the configuration is applied.

    STEP 4.8 - Confirm the PJSIP port and RTP range

    Open:

    Settings > Asterisk SIP Settings

    Confirm that PJSIP is listening on the transport and port you intend to use. This guide uses UDP port 5060.

    Also confirm the RTP media-port range. A common FreePBX range is:

    10000 through 20000 UDP

    The XML template later in this guide uses that range. If your FreePBX server uses a different RTP range, change the XML to match it.

    STEP 4.9 - Optional but useful: test the extension with a softphone

    Before troubleshooting the Cisco phone, register a normal SIP softphone to the new extension.

    Use:

    Server:
    PBX_IP_ADDRESS

    Username:
    AUTH_USERNAME

    Password:
    SIP_SECRET

    Transport:
    UDP

    Port:
    5060

    If the softphone cannot register, the problem is on the FreePBX, credential, firewall, or network side. Fix that before involving Cisco XML provisioning.

    ======================================================================
    SECTION 5 - INSTALL AND CONFIGURE THE TFTP SERVER
    ======================================================================

    These commands are for Debian, Ubuntu, or a Debian-based FreePBX installation. They match the Linux TFTP method used in the working setup.

    If your FreePBX host uses a different operating system, run TFTP on another trusted Linux machine and point the Cisco phone to that machine. The SEP file can still direct SIP signaling to the separate FreePBX address.

    STEP 5.1 - Open a Linux shell

    Connect to the TFTP machine locally or with SSH.

    Privilege note:
    Most commands in this section use sudo. If your normal Linux user is not in sudoers, become root first with:

    su -

    or log in as root from the VM console. When already logged in as root, run the commands without sudo.

    STEP 5.2 - Update the package list

    Run:

    sudo apt update

    STEP 5.3 - Install tftpd-hpa

    Run:

    sudo apt install -y tftpd-hpa

    The package may automatically create a user named tftp.

    STEP 5.4 - Create the TFTP root directory

    Run:

    sudo install -d -o tftp -g tftp -m 0755 /srv/tftp

    This creates:

    /srv/tftp

    and assigns the TFTP service account as the owner.

    STEP 5.5 - Configure tftpd-hpa

    Open the configuration file:

    sudo nano /etc/default/tftpd-hpa

    Replace its contents with:

    TFTP_USERNAME="tftp"
    TFTP_DIRECTORY="/srv/tftp"
    TFTP_ADDRESS="0.0.0.0:69"
    TFTP_OPTI

    Explanation:

    TFTP_USERNAME
    Runs the service as the restricted tftp user.

    TFTP_DIRECTORY
    Sets /srv/tftp as the root directory visible to TFTP clients.

    TFTP_ADDRESS
    Listens on UDP port 69 on all local interfaces.

    --secure
    Prevents clients from escaping the configured TFTP root.

    --verbose
    Produces useful logging during setup.

    Save the file.

    In nano:

    Press Ctrl+O
    Press Enter
    Press Ctrl+X

    STEP 5.6 - Enable and restart TFTP

    Run:

    sudo systemctl enable tftpd-hpa
    sudo systemctl restart tftpd-hpa

    STEP 5.7 - Check the service status

    Run:

    sudo systemctl status tftpd-hpa

    The service should show active or running.

    Press q to leave the status screen.

    STEP 5.8 - Confirm that UDP port 69 is listening

    Run:

    sudo ss -lunp | grep ':69'

    You should see a listener on UDP port 69.

    STEP 5.9 - Create a basic test file

    Run:

    echo "TFTP test successful" | sudo tee /srv/tftp/test.txt

    Set readable permissions:

    sudo chmod 0644 /srv/tftp/test.txt

    STEP 5.10 - Test TFTP from another machine when possible

    Install a TFTP client on another machine and request:

    test.txt

    The exact client command depends on the operating system.

    A successful test proves:

    - The service is running.
    - The TFTP directory is correct.
    - The network path is working.
    - The firewall is not blocking the request.
    - The file permissions are readable.

    Do not continue until TFTP works independently of the phone.

    STEP 5.11 - Check the host firewall

    If a firewall is enabled on the TFTP or FreePBX machine, allow TFTP only from the trusted phone subnet.

    The initial request uses UDP port 69. TFTP data transfer then uses a separate UDP flow, so a normal stateful firewall must allow the related return traffic.

    Do not create an internet-facing port-forward for TFTP.

    ======================================================================
    SECTION 6 - CREATE dialplan.xml
    ======================================================================

    The phone can reference a separate dial plan file. The working setup used a simple generic dial plan so the phone would send digits after a short timeout.

    STEP 6.1 - Create the file

    Run:

    sudo nano /srv/tftp/dialplan.xml

    STEP 6.2 - Paste the following exactly

    <?xml version="1.0" encoding="UTF-8"?>
    <DIALTEMPLATE>
      <TEMPLATE MATCH="*" Timeout="5" User="Phone"/>
    </DIALTEMPLATE>

    STEP 6.3 - Save the file

    In nano:

    Press Ctrl+O
    Press Enter
    Press Ctrl+X

    STEP 6.4 - Set ownership and permissions

    Run:

    sudo chown tftp:tftp /srv/tftp/dialplan.xml
    sudo chmod 0644 /srv/tftp/dialplan.xml

    Explanation of the rule:

    MATCH="*"
    Accepts a generic sequence of dialed digits.

    Timeout="5"
    Waits five seconds after the last digit before sending the number.

    User="Phone"
    Tells the phone to process the pattern as a phone dial string.

    This is intentionally simple. A more refined Cisco dial plan can later be created for immediate dialing of known extension lengths and service codes.

    ======================================================================
    SECTION 7 - CREATE THE MAC-SPECIFIC SEP CONFIGURATION FILE
    ======================================================================

    STEP 7.1 - Build the exact filename

    Use:

    SEP + PHONE_MAC_NO_SEPARATORS + .cnf.xml

    Example only:

    Phone MAC:
    00:11:22:AA:BB:CC

    Filename:
    SEP001122AABBCC.cnf.xml

    Do not use the example filename for your phone.

    STEP 7.2 - Create the file

    Replace PHONE_MAC_NO_SEPARATORS in the command below with the actual 12-character MAC address.

    sudo nano /srv/tftp/SEPPHONE_MAC_NO_SEPARATORS.cnf.xml

    For example, if the documentation-only MAC were 001122AABBCC, the command would be:

    sudo nano /srv/tftp/SEP001122AABBCC.cnf.xml

    STEP 7.3 - Paste the complete XML template

    Paste everything from the next line through the closing </device> tag.

    <?xml version="1.0" encoding="UTF-8"?>
    <device>
      <deviceProtocol>SIP</deviceProtocol>

      <devicePool>
        <dateTimeSetting>
          <dateTemplate>M-D-Ya</dateTemplate>
          <timeZone>TIME_ZONE_STRING</timeZone>
          <ntps>
            <ntp>
              <name>NTP_SERVER</name>
              <ntpMode>Unicast</ntpMode>
            </ntp>
          </ntps>
        </dateTimeSetting>

        <callManagerGroup>
          <members>
            <member priority="0">
              <callManager>
                <ports>
                  <ethernetPhonePort>2000</ethernetPhonePort>
                  <sipPort>5060</sipPort>
                  <securedSipPort>5061</securedSipPort>
                </ports>
                <processNodeName>PBX_IP_ADDRESS</processNodeName>
              </callManager>
            </member>
          </members>
        </callManagerGroup>
      </devicePool>

      <sipProfile>
        <sipProxies>
          <backupProxy></backupProxy>
          <backupProxyPort></backupProxyPort>
          <emergencyProxy></emergencyProxy>
          <emergencyProxyPort></emergencyProxyPort>
          <outboundProxy></outboundProxy>
          <outboundProxyPort></outboundProxyPort>
          <registerWithProxy>true</registerWithProxy>
        </sipProxies>

        <sipCallFeatures>
          <cnfJoinEnabled>true</cnfJoinEnabled>
          <callForwardURI>x-serviceuri-cfwdall</callForwardURI>
          <callPickupURI>x-cisco-serviceuri-pickup</callPickupURI>
          <callPickupListURI>x-cisco-serviceuri-opickup</callPickupListURI>
          <callPickupGroupURI>x-cisco-serviceuri-gpickup</callPickupGroupURI>
          <meetMeServiceURI>x-cisco-serviceuri-meetme</meetMeServiceURI>
          <abbreviatedDialURI>x-serviceuri-abbrdial</abbreviatedDialURI>
          <rfc2543Hold>false</rfc2543Hold>
          <callHoldRingback>2</callHoldRingback>
          <localCfwdEnable>true</localCfwdEnable>
          <semiAttendedTransfer>true</semiAttendedTransfer>
          <anonymousCallBlock>2</anonymousCallBlock>
          <callerIdBlocking>2</callerIdBlocking>
          <dndControl>0</dndControl>
          <remoteCcEnable>true</remoteCcEnable>
        </sipCallFeatures>

        <sipStack>
          <sipInviteRetx>6</sipInviteRetx>
          <sipRetx>10</sipRetx>
          <timerInviteExpires>180</timerInviteExpires>
          <timerRegisterExpires>3600</timerRegisterExpires>
          <timerRegisterDelta>5</timerRegisterDelta>
          <timerKeepAliveExpires>120</timerKeepAliveExpires>
          <timerSubscribeExpires>120</timerSubscribeExpires>
          <timerSubscribeDelta>5</timerSubscribeDelta>
          <timerT1>500</timerT1>
          <timerT2>4000</timerT2>
          <maxRedirects>70</maxRedirects>
          <remotePartyID>true</remotePartyID>
          <userInfo>None</userInfo>
        </sipStack>

        <autoAnswerTimer>1</autoAnswerTimer>
        <autoAnswerAltBehavior>false</autoAnswerAltBehavior>
        <autoAnswerOverride>true</autoAnswerOverride>
        <transferOnhookEnabled>false</transferOnhookEnabled>
        <enableVad>false</enableVad>

        <preferredCodec>g711ulaw</preferredCodec>
        <dtmfAvtPayload>101</dtmfAvtPayload>
        <dtmfDbLevel>3</dtmfDbLevel>
        <dtmfOutofBand>avt</dtmfOutofBand>
        <alwaysUsePrimeLine>false</alwaysUsePrimeLine>
        <alwaysUsePrimeLineVoiceMail>false</alwaysUsePrimeLineVoiceMail>
        <kpml>3</kpml>
        <natEnabled>false</natEnabled>
        <natAddress></natAddress>

        <phoneLabel>DISPLAY_NAME</phoneLabel>
        <stutterMsgWaiting>1</stutterMsgWaiting>
        <callStats>true</callStats>
        <silentPeriodBetweenCallWaitingBursts>10</silentPeriodBetweenCallWaitingBursts>
        <disableLocalSpeedDialConfig>false</disableLocalSpeedDialConfig>

        <startMediaPort>10000</startMediaPort>
        <stopMediaPort>20000</stopMediaPort>

        <sipLines>
          <line button="1" lineIndex="1">
            <featureID>9</featureID>
            <featureLabel>EXTENSION_NUMBER</featureLabel>
            <proxy>USECALLMANAGER</proxy>
            <port>5060</port>
            <name>EXTENSION_NUMBER</name>
            <displayName>DISPLAY_NAME</displayName>

            <autoAnswer>
              <autoAnswerEnabled>0</autoAnswerEnabled>
            </autoAnswer>

            <callWaiting>3</callWaiting>
            <authName>AUTH_USERNAME</authName>
            <authPassword>SIP_SECRET</authPassword>
            <sharedLine>false</sharedLine>
            <messageWaitingLampPolicy>1</messageWaitingLampPolicy>
            <messagesNumber>*97</messagesNumber>
            <ringSettingIdle>4</ringSettingIdle>
            <ringSettingActive>5</ringSettingActive>
            <contact>EXTENSION_NUMBER</contact>

            <forwardCallInfoDisplay>
              <callerName>true</callerName>
              <callerNumber>true</callerNumber>
              <redirectedNumber>false</redirectedNumber>
              <dialedNumber>true</dialedNumber>
            </forwardCallInfoDisplay>
          </line>
        </sipLines>

        <voipControlPort>5060</voipControlPort>
        <dscpForAudio>184</dscpForAudio>
        <ringSettingBusyStationPolicy>0</ringSettingBusyStationPolicy>
        <dialTemplate>dialplan.xml</dialTemplate>
      </sipProfile>

      <commonProfile>
        <phonePassword></phonePassword>
        <backgroundImageAccess>true</backgroundImageAccess>
        <callLogBlfEnabled>1</callLogBlfEnabled>
      </commonProfile>

      <loadInformation></loadInformation>

      <vendorConfig>
        <disableSpeaker>false</disableSpeaker>
        <disableSpeakerAndHeadset>false</disableSpeakerAndHeadset>
        <pcPort>0</pcPort>
        <settingsAccess>1</settingsAccess>
        <voiceVlanAccess>0</voiceVlanAccess>
        <autoSelectLineEnable>0</autoSelectLineEnable>
        <sshAccess>0</sshAccess>
        <loggingDisplay>1</loggingDisplay>
      </vendorConfig>

      <networkLocale>US</networkLocale>
      <deviceSecurityMode>1</deviceSecurityMode>
      <transportLayerProtocol>2</transportLayerProtocol>

      <capfAuthMode>0</capfAuthMode>
      <capfList>
        <capf>
          <phonePort>3804</phonePort>
        </capf>
      </capfList>

      <certHash></certHash>
      <encrConfig>false</encrConfig>
    </device>

    STEP 7.4 - Replace every placeholder

    Replace:

    TIME_ZONE_STRING
    with the appropriate Cisco time-zone string.

    NTP_SERVER
    with a reachable NTP server hostname or address.

    PBX_IP_ADDRESS
    with the local IP address of FreePBX.

    DISPLAY_NAME
    with the label to show on the phone.

    EXTENSION_NUMBER
    with the FreePBX extension number.

    AUTH_USERNAME
    with the PJSIP authentication username.

    SIP_SECRET
    with the exact PJSIP extension secret.

    Do not leave any placeholder text in the finished file.

    Do not include angle brackets around replacement values.

    Incorrect:

    <processNodeName><192.0.2.10></processNodeName>

    Correct example:

    <processNodeName>192.0.2.10</processNodeName>

    The address 192.0.2.10 is reserved for documentation. Use the real local address of your own FreePBX server.

    STEP 7.5 - Understand the most important XML fields

    <deviceProtocol>SIP</deviceProtocol>
    Tells the phone to use SIP.

    <processNodeName>PBX_IP_ADDRESS</processNodeName>
    Tells the phone where the SIP server is.

    <registerWithProxy>true</registerWithProxy>
    Tells the phone to register to that server.

    <proxy>USECALLMANAGER</proxy>
    Tells the line to use the server defined in the call-manager group.

    <port>5060</port>
    Uses SIP port 5060.

    <name>EXTENSION_NUMBER</name>
    Sets the line identity.

    <authName>AUTH_USERNAME</authName>
    Sets the SIP authentication username.

    <authPassword>SIP_SECRET</authPassword>
    Sets the SIP authentication password.

    <transportLayerProtocol>2</transportLayerProtocol>
    Selects UDP for Cisco Enterprise SIP provisioning.

    <preferredCodec>g711ulaw</preferredCodec>
    Uses G.711 mu-law as the preferred audio codec.

    <startMediaPort>10000</startMediaPort>
    <stopMediaPort>20000</stopMediaPort>
    Sets the RTP range expected by the phone. This must agree with FreePBX.

    <dialTemplate>dialplan.xml</dialTemplate>
    Tells the phone to download the separate dialplan.xml file.

    <loadInformation></loadInformation>
    Leaves the firmware-load field blank. This is intentional when the phone already has usable Enterprise SIP firmware. It prevents the phone from being told to fetch a firmware package that is not present.

    <voiceVlanAccess>0</voiceVlanAccess>
    Keeps the initial setup simple and avoids depending on a voice VLAN.

    STEP 7.6 - Save the XML file

    In nano:

    Press Ctrl+O
    Press Enter
    Press Ctrl+X

    STEP 7.7 - Set ownership and permissions

    Replace the filename with the real MAC-specific filename and run:

    sudo chown tftp:tftp /srv/tftp/SEPPHONE_MAC_NO_SEPARATORS.cnf.xml
    sudo chmod 0644 /srv/tftp/SEPPHONE_MAC_NO_SEPARATORS.cnf.xml

    STEP 7.8 - Validate the XML syntax

    Replace the filename and run:

    python3 - <<'PY'
    import xml.etree.ElementTree as ET
    ET.parse("/srv/tftp/SEPPHONE_MAC_NO_SEPARATORS.cnf.xml")
    ET.parse("/srv/tftp/dialplan.xml")
    print("Both XML files parsed successfully.")
    PY

    If the command prints:

    Both XML files parsed successfully.

    the basic XML structure is valid.

    If it prints an error, note the line and column number. Reopen the file and correct the malformed tag, unescaped character, missing closing tag, or pasted formatting problem.

    STEP 7.9 - Check the TFTP directory

    Run:

    ls -l /srv/tftp

    You should see at least:

    dialplan.xml
    SEPPHONE_MAC_NO_SEPARATORS.cnf.xml
    test.txt

    The real SEP filename must use the phone's actual MAC address.

    ======================================================================
    SECTION 8 - CONFIGURE THE PHONE TO USE THE TFTP SERVER
    ======================================================================

    The exact wording can differ slightly by Enterprise firmware release.

    STEP 8.1 - Open the phone settings

    Press the Applications button.

    STEP 8.2 - Open administrator settings

    Open:

    Admin settings

    or:

    Administrator Settings

    STEP 8.3 - Open network settings

    Open:

    Network setup

    STEP 8.4 - Open Ethernet settings

    Open:

    Ethernet setup

    STEP 8.5 - Open IPv4 settings

    Open:

    IPv4 setup

    STEP 8.6 - Enable Alternate TFTP

    Find:

    Alternate TFTP

    Set it to:

    Yes

    STEP 8.7 - Enter the TFTP address

    Find:

    TFTP Server 1

    Enter:

    TFTP_IP_ADDRESS

    This is the address of the machine running tftpd-hpa.

    If TFTP runs directly on FreePBX, enter the FreePBX local IP address.

    STEP 8.8 - Save or apply the setting

    Use the phone's Apply, Save, or Set softkey.

    STEP 8.9 - Reboot the phone

    Restart the phone from its menu or briefly remove and restore power.

    Do not repeatedly interrupt power while firmware or configuration activity is occurring.

    ALTERNATIVE FOR MULTIPLE PHONES

    For one phone, manual Alternate TFTP is the simplest method.

    For multiple phones, DHCP option 150 can advertise the TFTP server automatically. Do not change DHCP option 150 during the first single-phone test unless you already understand the DHCP configuration.

    ======================================================================
    SECTION 9 - WATCH THE TFTP REQUESTS
    ======================================================================

    Do not guess whether the phone downloaded the file. Watch the server.

    STEP 9.1 - Open the TFTP service log

    On the TFTP server, run:

    sudo journalctl -u tftpd-hpa -f

    Leave this window open.

    STEP 9.2 - Restart the phone

    Reboot the Cisco phone.

    STEP 9.3 - Look for the MAC-specific request

    You should see the phone request a filename similar to:

    SEPPHONE_MAC_NO_SEPARATORS.cnf.xml

    For a documentation-only MAC, it might look like:

    SEP001122AABBCC.cnf.xml

    The phone may also request other files, such as:

    XMLDefault.cnf.xml
    dialplan.xml
    locale files
    ring-list files
    trust-list files
    certificate files
    firmware files

    A missing optional file is not automatically fatal.

    The critical sequence is:

    1. The phone requests its exact SEP file.
    2. The TFTP server finds and transfers that file.
    3. The phone requests dialplan.xml.
    4. The phone begins sending SIP traffic to FreePBX.

    STEP 9.4 - Use packet capture when the log is unclear

    Run:

    sudo tcpdump -ni any '(udp port 69) or (udp port 5060)'

    This displays TFTP and SIP traffic.

    A successful TFTP request proves the phone can reach the server.

    SIP packets to FreePBX prove that the phone accepted enough of the configuration to begin registration.

    Press Ctrl+C to stop tcpdump.

    ======================================================================
    SECTION 10 - WATCH REGISTRATION IN ASTERISK
    ======================================================================

    STEP 10.1 - Open the Asterisk CLI

    On the FreePBX server, run:

    sudo asterisk -rvvvvv

    The multiple v characters increase console verbosity.

    STEP 10.2 - Enable PJSIP packet logging

    At the Asterisk prompt, run:

    pjsip set logger on

    STEP 10.3 - Reboot the phone again if necessary

    Restart the phone while watching the Asterisk CLI.

    STEP 10.4 - Look for SIP REGISTER messages

    A normal registration exchange commonly looks like this conceptually:

    1. Phone sends REGISTER.
    2. FreePBX returns a 401 authentication challenge.
    3. Phone sends another REGISTER with digest authentication.
    4. FreePBX accepts it.
    5. The endpoint receives an active contact.

    One initial 401 response is normal. It is part of SIP digest authentication.

    A continuous loop of 401 or 403 responses is not normal and usually means the username or password is wrong.

    STEP 10.5 - Display PJSIP endpoints

    Run:

    pjsip show endpoints

    Find the extension.

    STEP 10.6 - Display the specific endpoint

    Run:

    pjsip show endpoint EXTENSION_NUMBER

    Replace EXTENSION_NUMBER with the actual extension.

    STEP 10.7 - Display registered contacts

    Run:

    pjsip show contacts

    The Cisco phone should appear as an available contact after successful registration.

    STEP 10.8 - Disable packet logging when finished

    Run:

    pjsip set logger off

    STEP 10.9 - Leave the Asterisk CLI

    Run:

    exit

    Do not post an unredacted PJSIP log. SIP logs may reveal extension numbers, IP addresses, caller information, and authentication details.

    ======================================================================
    SECTION 11 - CONFIRM SUCCESS ON THE PHONE
    ======================================================================

    A successful result should show the configured extension or display label on line button 1.

    The phone should stop displaying messages such as:

    Registering
    Unprovisioned
    Phone not registered
    Service unavailable

    The exact status text varies by firmware.

    A complete success sequence is:

    1. The phone receives an IP address from DHCP.
    2. The phone knows the TFTP server address.
    3. The phone requests its SEP file.
    4. The phone downloads the SEP file.
    5. The phone downloads dialplan.xml.
    6. The phone sends a REGISTER request to FreePBX.
    7. FreePBX challenges the phone.
    8. The phone authenticates successfully.
    9. FreePBX shows an active PJSIP contact.
    10. The extension label appears on the phone.
    11. Internal calls work in both directions.
    12. Audio works in both directions.

    ======================================================================
    SECTION 12 - TEST INTERNAL CALLING
    ======================================================================

    Use a second FreePBX extension for testing. The second endpoint can be:

    - Another Cisco phone
    - A normal SIP desk phone
    - A SIP softphone
    - A mobile softphone connected to the same trusted LAN

    STEP 12.1 - Register the second extension

    Make sure FreePBX shows the second endpoint as registered.

    STEP 12.2 - Call from the Cisco phone

    Dial the second extension.

    Because the generic dial plan waits for a timeout, the call may begin approximately five seconds after the final digit.

    STEP 12.3 - Answer the second endpoint

    Confirm:

    - The destination rings.
    - Caller ID appears.
    - The call connects.
    - Audio works from Cisco to the other endpoint.
    - Audio works from the other endpoint to Cisco.

    STEP 12.4 - Call the Cisco phone

    From the second endpoint, dial the Cisco extension.

    Confirm that the Cisco phone rings and answers.

    STEP 12.5 - Test phone functions

    Test:

    - Hold
    - Resume
    - Blind transfer
    - Attended transfer
    - DTMF digits
    - Voicemail access with *97, if voicemail is enabled
    - Message-waiting lamp, if voicemail is configured

    Do not configure an external telephone provider until internal registration and two-way audio are stable.

    ======================================================================
    SECTION 13 - TROUBLESHOOTING IN THE CORRECT ORDER
    ======================================================================

    Do not change several unrelated settings at once. Follow the traffic in order:

    DHCP
    then TFTP
    then XML parsing
    then SIP signaling
    then authentication
    then RTP audio

    ----------------------------------------------------------------------
    PROBLEM 1 - THE PHONE DOES NOT RECEIVE AN IP ADDRESS
    ----------------------------------------------------------------------

    Check:

    1. The switch port is active.
    2. PoE is stable.
    3. The Ethernet cable is good.
    4. DHCP is available on that VLAN.
    5. The switch port is in the intended access VLAN.
    6. The phone is not expecting an inaccessible voice VLAN.
    7. The phone's IPv4 settings are using DHCP.

    Do not troubleshoot SIP until the phone has a valid local IP address, subnet mask, gateway, and TFTP address.

    ----------------------------------------------------------------------
    PROBLEM 2 - THE PHONE NEVER CONTACTS TFTP
    ----------------------------------------------------------------------

    Check:

    1. Alternate TFTP is set to Yes.
    2. TFTP Server 1 contains the correct TFTP_IP_ADDRESS.
    3. The phone can route to that address.
    4. tftpd-hpa is running.
    5. UDP port 69 is listening.
    6. The host firewall allows local TFTP traffic.
    7. The phone and server are not separated by a blocked VLAN policy.
    8. The TFTP service is bound to the correct interface.

    Run:

    sudo systemctl status tftpd-hpa
    sudo ss -lunp | grep ':69'
    sudo tcpdump -ni any 'udp port 69'

    If tcpdump shows no packets from the phone, the phone does not know the correct TFTP address or the network path is blocked.

    ----------------------------------------------------------------------
    PROBLEM 3 - TFTP SAYS FILE NOT FOUND
    ----------------------------------------------------------------------

    This is usually a filename problem.

    Verify:

    1. The MAC address is correct.
    2. All separators were removed.
    3. The MAC has exactly 12 characters.
    4. SEP is uppercase.
    5. The MAC letters are uppercase.
    6. The suffix is exactly .cnf.xml.
    7. The file is in /srv/tftp.
    8. The file is readable.
    9. There is no hidden .txt extension.

    Run:

    ls -lb /srv/tftp

    This reveals unusual spaces or escaped characters in filenames.

    The correct format is:

    SEPPHONE_MAC_NO_SEPARATORS.cnf.xml

    Example only:

    SEP001122AABBCC.cnf.xml

    ----------------------------------------------------------------------
    PROBLEM 4 - THE PHONE DOWNLOADS THE SEP FILE BUT REMAINS UNPROVISIONED
    ----------------------------------------------------------------------

    First validate the XML:

    python3 - <<'PY'
    import xml.etree.ElementTree as ET
    ET.parse("/srv/tftp/SEPPHONE_MAC_NO_SEPARATORS.cnf.xml")
    print("SEP XML is valid.")
    PY

    Then check:

    1. <deviceProtocol>SIP</deviceProtocol> exists.
    2. <processNodeName> contains the correct PBX address.
    3. <registerWithProxy>true</registerWithProxy> exists.
    4. <proxy>USECALLMANAGER</proxy> exists.
    5. <name> contains the extension.
    6. <authName> contains the PJSIP auth username.
    7. <authPassword> contains the exact secret.
    8. <transportLayerProtocol>2</transportLayerProtocol> exists for UDP.
    9. All placeholder words were replaced.
    10. The SIP secret does not contain an unescaped XML character.
    11. The file was saved as plain text and not rich text.
    12. The line endings and encoding are normal UTF-8 text.

    Restart the phone after correcting the file.

    ----------------------------------------------------------------------
    PROBLEM 5 - THE PHONE DISPLAYS "ERROR VERIFYING CONFIG INFO"
    ----------------------------------------------------------------------

    Possible causes include:

    - Malformed XML
    - A copied smart quote or hidden formatting character
    - An unescaped special character in the password
    - Old trust information from a previous Cisco Unified Communications Manager
    - An invalid or unavailable firmware load name
    - A configuration section not accepted by that firmware release

    Actions:

    1. Validate the XML with Python.
    2. Temporarily use an alphanumeric SIP secret.
    3. Leave <loadInformation></loadInformation> blank.
    4. Remove any certificate or firmware references you added manually.
    5. Confirm the filename is correct.
    6. Reboot the phone.
    7. Watch the TFTP log to confirm the corrected file is downloaded.
    8. Clear old phone security settings if necessary.

    On many Enterprise 8800 phones, old security information can be cleared from a path similar to:

    Applications
    Admin settings
    Reset settings
    Security

    Menu wording varies.

    Use a full factory reset only after the less destructive checks have failed.

    ----------------------------------------------------------------------
    PROBLEM 6 - THE PHONE DOWNLOADS THE XML BUT SENDS NO SIP REGISTER
    ----------------------------------------------------------------------

    Run:

    sudo tcpdump -ni any 'udp port 5060'

    Then restart the phone.

    If no SIP packet appears:

    1. Check PBX_IP_ADDRESS in <processNodeName>.
    2. Confirm FreePBX uses UDP port 5060.
    3. Confirm <transportLayerProtocol>2</transportLayerProtocol>.
    4. Confirm <registerWithProxy>true</registerWithProxy>.
    5. Confirm <proxy>USECALLMANAGER</proxy>.
    6. Confirm the phone accepted the XML rather than rejecting it.
    7. Check the phone's status messages.
    8. Clear stale security configuration if the phone was previously attached to CUCM.

    ----------------------------------------------------------------------
    PROBLEM 7 - ONE 401 RESPONSE APPEARS
    ----------------------------------------------------------------------

    One 401 response during registration is normal.

    The expected process is:

    REGISTER
    401 challenge
    authenticated REGISTER
    success

    Do not treat the first 401 as a failure by itself.

    ----------------------------------------------------------------------
    PROBLEM 8 - REPEATED 401 OR 403 RESPONSES
    ----------------------------------------------------------------------

    Repeated authentication failures normally mean the credentials do not match.

    Recheck:

    1. EXTENSION_NUMBER
    2. AUTH_USERNAME
    3. SIP_SECRET
    4. Capitalization
    5. Leading or trailing spaces
    6. Special XML characters
    7. Whether Apply Config was clicked in FreePBX
    8. Whether the extension is PJSIP rather than chan_sip
    9. Whether the phone is contacting the correct PBX

    Copy the secret again from FreePBX and paste it carefully into the XML.

    After editing:

    sudo systemctl restart tftpd-hpa

    A TFTP restart is usually not required for a file-content change, but it is harmless during controlled troubleshooting.

    Then reboot the phone.

    ----------------------------------------------------------------------
    PROBLEM 9 - THE PHONE REGISTERS BUT CANNOT CALL
    ----------------------------------------------------------------------

    Check:

    1. The destination extension is registered.
    2. The dialed digits are being sent after the timeout.
    3. dialplan.xml downloaded successfully.
    4. The FreePBX dial plan was applied.
    5. The extension is not restricted by a custom context.
    6. The phone is dialing the correct internal extension length.
    7. Asterisk shows the INVITE request.
    8. The call is not being rejected by an outbound-route pattern.

    Watch:

    sudo asterisk -rvvvvv

    Then:

    pjsip set logger on

    Place the call and read the SIP response.

    ----------------------------------------------------------------------
    PROBLEM 10 - CALLS CONNECT BUT THERE IS NO AUDIO
    ----------------------------------------------------------------------

    Registration uses SIP. Audio uses RTP. A phone can register perfectly while RTP is blocked.

    Check:

    1. The XML RTP range matches FreePBX.
    2. The FreePBX firewall allows the RTP range from the phone network.
    3. The phone and PBX have valid routes to each other.
    4. There is no NAT between them during the initial test.
    5. SIP ALG is disabled on any router in the path.
    6. The correct codec is enabled on both endpoints.
    7. Direct media is not creating an unreachable endpoint-to-endpoint path.

    The template uses:

    UDP 10000 through 20000

    To observe RTP, run a capture such as:

    sudo tcpdump -ni any 'udp portrange 10000-20000'

    During a call, packets should flow in both directions.

    ----------------------------------------------------------------------
    PROBLEM 11 - AUDIO WORKS IN ONLY ONE DIRECTION
    ----------------------------------------------------------------------

    One-way audio normally means one endpoint cannot route RTP back to the other.

    Check:

    1. Subnet masks
    2. Default gateways
    3. VLAN access rules
    4. Host firewall rules
    5. NAT settings
    6. SIP ALG
    7. RTP symmetric settings if NAT is actually present
    8. Whether Asterisk is advertising an incorrect address

    Return both devices to one simple LAN for testing.

    ----------------------------------------------------------------------
    PROBLEM 12 - DTMF DIGITS DO NOT WORK
    ----------------------------------------------------------------------

    In FreePBX, use RFC4733 or RFC DTMF signaling.

    The XML contains:

    <dtmfAvtPayload>101</dtmfAvtPayload>
    <dtmfOutofBand>avt</dtmfOutofBand>

    Confirm the endpoint is not forcing in-band DTMF.

    ----------------------------------------------------------------------
    PROBLEM 13 - THE PHONE TIME IS WRONG
    ----------------------------------------------------------------------

    Check:

    1. NTP_SERVER is reachable.
    2. DNS works if the NTP value is a hostname.
    3. TIME_ZONE_STRING is correct for the phone firmware.
    4. The phone can reach UDP port 123.
    5. The date template is acceptable.

    Correct the SEP file and reboot the phone.

    ----------------------------------------------------------------------
    PROBLEM 14 - THE PHONE TRIES TO DOWNLOAD FIRMWARE
    ----------------------------------------------------------------------

    If the phone requests a firmware file that you do not possess, check <loadInformation>.

    For a phone already running usable Enterprise SIP firmware, leave it blank:

    <loadInformation></loadInformation>

    Do not insert a random firmware filename.

    A Cisco firmware update normally requires a complete matching package, including all files referenced by the load. An incomplete firmware set can leave the phone unable to complete boot or upgrade.

    ----------------------------------------------------------------------
    PROBLEM 15 - THE PHONE STILL USES AN OLD CONFIGURATION
    ----------------------------------------------------------------------

    The phone may cache configuration or retain old CUCM security information.

    Try, in order:

    1. Confirm the server file was actually changed.
    2. Reboot the phone.
    3. Watch TFTP to verify it downloaded the file again.
    4. Clear security settings from the phone's reset menu.
    5. Factory-reset only if necessary.
    6. Re-enter Alternate TFTP after the reset.
    7. Watch the complete boot process again.

    ======================================================================
    SECTION 14 - FACTORY RESET PROCEDURE
    ======================================================================

    Do not factory-reset the phone merely because the first attempt failed. First check TFTP, filename, XML syntax, credentials, and old security settings.

    A factory reset clears locally stored phone settings and may require Alternate TFTP to be entered again.

    For many Cisco 8800 Enterprise phones:

    1. Disconnect power from the phone.
    2. Wait approximately five seconds.
    3. Press and hold the # key.
    4. Reconnect power while continuing to hold #.
    5. Wait until the line, headset, mute, or speaker indicators show the reset-ready pattern.
    6. Release #.
    7. Enter:

    123456789*0#

    8. Allow the reset to complete.
    9. Do not remove power during the reset.
    10. After booting, configure Alternate TFTP again.
    11. Restart the phone and watch the TFTP logs.

    Indicator behavior can differ slightly by hardware revision or firmware.

    ======================================================================
    SECTION 15 - ADDING A SECOND CISCO PHONE
    ======================================================================

    Each physical phone should have its own:

    - PJSIP extension
    - Authentication username
    - SIP secret
    - MAC-specific SEP file

    Do not use one SEP filename for multiple phones.

    STEP 15.1 - Create a second PJSIP extension

    Use FreePBX Extensions and apply the configuration.

    STEP 15.2 - Copy the working file

    Run:

    sudo cp /srv/tftp/SEPFIRST_PHONE_MAC.cnf.xml /srv/tftp/SEPSECOND_PHONE_MAC.cnf.xml

    STEP 15.3 - Edit the second file

    Run:

    sudo nano /srv/tftp/SEPSECOND_PHONE_MAC.cnf.xml

    Change:

    - EXTENSION_NUMBER
    - AUTH_USERNAME
    - SIP_SECRET
    - DISPLAY_NAME

    The PBX and NTP addresses can remain the same if both phones use the same servers.

    STEP 15.4 - Set permissions

    Run:

    sudo chown tftp:tftp /srv/tftp/SEPSECOND_PHONE_MAC.cnf.xml
    sudo chmod 0644 /srv/tftp/SEPSECOND_PHONE_MAC.cnf.xml

    STEP 15.5 - Validate the file

    Run:

    python3 - <<'PY'
    import xml.etree.ElementTree as ET
    ET.parse("/srv/tftp/SEPSECOND_PHONE_MAC.cnf.xml")
    print("Second phone XML is valid.")
    PY

    STEP 15.6 - Point the second phone to TFTP

    Set Alternate TFTP and TFTP Server 1, then reboot.

    STEP 15.7 - Test phone-to-phone calling

    Call each extension from the other. Confirm two-way audio, hold, transfer, and DTMF.

    ======================================================================
    SECTION 16 - OPTIONAL IMPROVEMENTS AFTER THE BASIC SETUP WORKS
    ======================================================================

    Only make these changes after the phone is registered and internal calls work.

    1. Replace the generic dialplan.xml with rules for known extension lengths.
    2. Add DHCP option 150 for automatic TFTP discovery.
    3. Place the phones on a dedicated voice VLAN.
    4. Add switch QoS policies.
    5. Configure voicemail and message-waiting indication.
    6. Add line keys, speed dials, or busy-lamp fields.
    7. Add a SIP trunk for external calls.
    8. Configure inbound and outbound routes.
    9. Configure emergency calling correctly.
    10. Restrict TFTP access to the phone VLAN.
    11. Back up the sanitized template separately from files containing real secrets.
    12. Document each phone's MAC-to-extension assignment privately.

    Do not expose a SIP extension directly to the public internet merely to make remote registration convenient. Use a properly secured network design.

    ======================================================================
    SECTION 17 - FINAL VERIFICATION CHECKLIST
    ======================================================================

    PHONE AND NETWORK

    [ ] The phone has power.
    [ ] The Ethernet link is active.
    [ ] The phone receives a valid IP address.
    [ ] The phone has the correct subnet mask.
    [ ] The phone has a valid gateway.
    [ ] The phone can reach the TFTP server.
    [ ] The phone can reach FreePBX.
    [ ] The initial test does not depend on NAT or a voice VLAN.

    FREEPBX

    [ ] A PJSIP extension exists.
    [ ] The extension number is correct.
    [ ] The auth username is correct.
    [ ] The SIP secret is known.
    [ ] UDP transport is enabled.
    [ ] PJSIP is listening on port 5060.
    [ ] ulaw is allowed.
    [ ] The RTP range is known.
    [ ] Apply Config was clicked.

    TFTP

    [ ] tftpd-hpa is installed.
    [ ] The service is active.
    [ ] UDP port 69 is listening.
    [ ] /srv/tftp exists.
    [ ] test.txt can be downloaded.
    [ ] dialplan.xml exists.
    [ ] The MAC-specific SEP file exists.
    [ ] The SEP filename exactly matches the phone MAC.
    [ ] Files are readable.
    [ ] TFTP is not exposed to the internet.

    XML

    [ ] All placeholders were replaced.
    [ ] The PBX address is correct.
    [ ] The extension is correct.
    [ ] The auth username is correct.
    [ ] The SIP secret is correct.
    [ ] The display label is correct.
    [ ] The RTP range matches FreePBX.
    [ ] transportLayerProtocol is 2 for UDP.
    [ ] loadInformation is blank unless a complete firmware package is intentionally provided.
    [ ] Python parses both XML files successfully.

    PHONE CONFIGURATION

    [ ] Alternate TFTP is Yes.
    [ ] TFTP Server 1 is correct.
    [ ] The phone was rebooted.
    [ ] The phone requested its exact SEP file.
    [ ] The phone downloaded dialplan.xml.
    [ ] The phone sent SIP REGISTER traffic.
    [ ] FreePBX shows an active PJSIP contact.
    [ ] The line label appears on the phone.

    CALL TEST

    [ ] The Cisco phone can call another internal extension.
    [ ] Another extension can call the Cisco phone.
    [ ] Audio works in both directions.
    [ ] Hold and resume work.
    [ ] Transfer works.
    [ ] DTMF works.
    [ ] Voicemail access works, if configured.

    ======================================================================
    SECTION 18 - SAFE INFORMATION TO PROVIDE WHEN ASKING FOR HELP
    ======================================================================

    When requesting troubleshooting help, provide sanitized versions of:

    1. The phone model.
    2. The active firmware-load name.
    3. The exact status message shown on the phone.
    4. Whether the phone receives an IP address.
    5. Whether TFTP logs show the SEP request.
    6. The exact requested filename, with most of the MAC replaced.
    7. Whether the TFTP transfer succeeds or says file not found.
    8. Whether dialplan.xml is requested.
    9. Whether Asterisk sees a REGISTER request.
    10. The SIP response code, such as 401, 403, or 404.
    11. Whether pjsip show contacts displays the phone.
    12. Whether a call connects.
    13. Whether audio is absent or one-directional.

    Remove:

    - Passwords
    - Authorization headers
    - Full MAC addresses
    - Real IP addresses
    - Names
    - Telephone numbers
    - Public addresses
    - Trunk credentials

    ======================================================================
    SECTION 19 - THE WORKING METHOD IN ONE COMPACT SEQUENCE
    ======================================================================

    The complete process that produced a working Cisco Enterprise 8800-series phone on FreePBX was:

    1. Confirm the phone was running Enterprise SIP firmware.
    2. Record the phone MAC address.
    3. Create a FreePBX PJSIP extension.
    4. Copy the extension number, auth username, and secret.
    5. Apply the FreePBX configuration.
    6. Install tftpd-hpa.
    7. Set /srv/tftp as the TFTP root.
    8. Enable verbose TFTP logging.
    9. Create dialplan.xml.
    10. Create SEP<MAC>.cnf.xml.
    11. Set deviceProtocol to SIP.
    12. Set processNodeName to the FreePBX address.
    13. Set the line name and authName to the extension credentials.
    14. Set authPassword to the PJSIP secret.
    15. Set the SIP port to 5060.
    16. Set transportLayerProtocol to 2 for UDP.
    17. Leave loadInformation blank because Enterprise SIP firmware was already installed.
    18. Validate the XML.
    19. Enable Alternate TFTP on the phone.
    20. Enter the TFTP server address.
    21. Reboot the phone.
    22. Watch the phone request its exact SEP file.
    23. Watch the phone request dialplan.xml.
    24. Watch Asterisk receive REGISTER.
    25. Correct any filename, XML, or credential mismatch.
    26. Confirm the phone appeared under pjsip show contacts.
    27. Place internal test calls.
    28. Confirm two-way audio.
    29. Add advanced features only after the basic registration was stable.

    END OF GUIDE

  • 2
    Adding a Second Cisco 8845 Enterprise SIP Phone to FreePBX

    This guide documents how to add a second Cisco CP-8845 Enterprise SIP phone to an existing FreePBX/Asterisk setup using TFTP-based Cisco XML provisioning.

    Sensitive/private values have been replaced with placeholders.

    Placeholder Legend
    ------------------
    <FREEPBX_IP>             = IP address of the FreePBX/Asterisk server
    <TFTP_DIR>               = TFTP root directory, usually /srv/tftp
    <OLD_PHONE_SEP_FILE>     = Existing working phone config, e.g. SEPXXXXXXXXXXXX.cnf.xml
    <NEW_PHONE_MAC>          = MAC address of the second phone with no colons/dots, uppercase
    <NEW_PHONE_SEP_FILE>     = SEP<NEW_PHONE_MAC>.cnf.xml
    <EXTENSION_1>            = Existing working phone extension
    <EXTENSION_2>            = New second phone extension
    <EXTENSION_2_SECRET>     = SIP secret/password for the new extension
    <PHONE_SWITCHPORT>       = Switch port where the second phone is connected
    <VOICE_OR_DATA_VLAN>     = VLAN used for the phone, if applicable

    Network/Provisioning Overview
    -----------------------------
    The second Cisco 8845 was connected to a Cisco switch port with PoE.

    The phone booted, received an IP address, and was visible through CDP.

    A working XML config from the first Cisco 8845 was copied and renamed for the second phone's MAC address.

    The copied XML file was edited so the second phone registered as its own FreePBX extension.

    The second phone was then manually pointed at the FreePBX/TFTP server using Alternate TFTP.

    After rebooting, the second phone pulled its config, registered to FreePBX, and was able to call the first phone.

    Step 1 - Configure the Switch Port for the Phone
    -----------------------------------------------
    On the Cisco switch, configure the port as a simple access port first.
    This keeps the setup simple while testing registration.

    Example:

    enable
    conf t

    interface <PHONE_SWITCHPORT>
     description CISCO_8845_PHONE_2
     switchport mode access
     switchport access vlan <VOICE_OR_DATA_VLAN>
     spanning-tree portfast
     power inline auto
     no shutdown

    end
    write memory

    Verify the port and PoE:

    show interfaces status | include <PHONE_SWITCHPORT>
    show power inline <PHONE_SWITCHPORT>
    show mac address-table interface <PHONE_SWITCHPORT>

    Check CDP details if supported:

    show cdp neighbors <PHONE_SWITCHPORT> detail

    Expected useful output:
    - Device ID beginning with SEP
    - Platform: Cisco IP Phone 8845
    - Phone IP address
    - Firmware load, usually sip8845_65.xxxxx.loads
    - Power draw in watts

    Step 2 - Record the Phone's SEP/MAC Identity
    -------------------------------------------
    Cisco Enterprise phones look for a MAC-specific XML file.

    The filename format is:

    SEP<NEW_PHONE_MAC>.cnf.xml

    Example format only:

    SEPAAAAAAAAAAAA.cnf.xml

    Important:
    - Use uppercase letters.
    - Remove colons or dots from the MAC address.
    - Keep the SEP prefix.
    - Keep the .cnf.xml extension.

    If CDP shows:

    Device ID: SEPAAAAAAAAAAAA

    then the phone config file should be:

    SEPAAAAAAAAAAAA.cnf.xml

    Step 3 - Create the New FreePBX Extension
    ----------------------------------------
    In the FreePBX web interface:

    Applications -> Extensions -> Add Extension -> Add New PJSIP Extension

    Create a new extension for the second phone.

    Example fields:

    User Extension: <EXTENSION_2>
    Display Name: Cisco8845-2
    Secret: <EXTENSION_2_SECRET>

    Then click:

    Submit
    Apply Config

    Important:
    The extension Secret must match the <authPassword> value in the Cisco XML config.

    Step 4 - Locate the Existing Working Cisco Phone Config
    ------------------------------------------------------
    SSH or console into the FreePBX server.

    Become root if needed.

    Search for existing Cisco SEP config files:

    find / -maxdepth 4 -type f \( -name "SEP*.cnf.xml" -o -name "XMLDefault.cnf.xml" \) 2>/dev/null

    In this setup, the working files were stored in:

    <TFTP_DIR>

    Common example:

    /srv/tftp

    Change into the TFTP directory:

    cd <TFTP_DIR>

    List existing phone config files:

    ls -lh SEP*.cnf.xml

    You should see the existing working phone config:

    <OLD_PHONE_SEP_FILE>

    Step 5 - Copy the First Phone Config for the Second Phone
    --------------------------------------------------------
    Copy the known-good first phone config and rename it for the second phone:

    cp <OLD_PHONE_SEP_FILE> <NEW_PHONE_SEP_FILE>

    Example format only:

    cp SEPAAAAAAAAAAAA.cnf.xml SEPBBBBBBBBBBBB.cnf.xml

    Verify both files exist:

    ls -lh SEP*.cnf.xml

    Step 6 - Fix File Ownership and Permissions
    -------------------------------------------
    Make the new file readable by the TFTP service.

    On many FreePBX/Linux systems using tftpd-hpa:

    chown tftp:tftp <NEW_PHONE_SEP_FILE>
    chmod 644 <NEW_PHONE_SEP_FILE>

    Verify:

    ls -lh <NEW_PHONE_SEP_FILE>

    Expected permissions:

    -rw-r--r-- 1 tftp tftp ...

    Step 7 - Edit the New Phone XML Config
    --------------------------------------
    Open the new file:

    nano <NEW_PHONE_SEP_FILE>

    Search for the old extension:

    CTRL+W
    <EXTENSION_1>
    Enter

    Change the identity fields from the first extension to the second extension.

    Typical fields to change:

    <featureLabel><EXTENSION_2></featureLabel>
    <name><EXTENSION_2></name>
    <displayName>Cisco8845-2</displayName>
    <contact><EXTENSION_2></contact>
    <authName><EXTENSION_2></authName>
    <authPassword><EXTENSION_2_SECRET></authPassword>

    The most important fields are:

    <name><EXTENSION_2></name>
    <authName><EXTENSION_2></authName>
    <authPassword><EXTENSION_2_SECRET></authPassword>

    The display fields are optional but recommended:

    <featureLabel><EXTENSION_2></featureLabel>
    <displayName>Cisco8845-2</displayName>
    <contact><EXTENSION_2></contact>

    Do not leave the old phone extension in the new phone config unless it is intentionally part of another setting.

    Step 8 - Check for Leftover Old Extension References
    ---------------------------------------------------
    After saving the XML file, check that the first phone extension was removed from the second phone config:

    grep -n "<EXTENSION_1>" <NEW_PHONE_SEP_FILE>

    Ideally this returns nothing.

    Check that the new extension exists in the file:

    grep -n "<EXTENSION_2>" <NEW_PHONE_SEP_FILE>

    Check important identity/auth fields:

    grep -n "displayName\|featureLabel\|name\|contact\|authName\|authPassword" <NEW_PHONE_SEP_FILE>

    Do not share or publicly post the authPassword value.

    Step 9 - Restart the TFTP Service
    ---------------------------------
    Restart TFTP:

    systemctl restart tftpd-hpa

    Check status:

    systemctl status tftpd-hpa --no-pager

    Expected:
    Active: active (running)

    If the service name differs, find the TFTP service:

    systemctl list-units --type=service | grep -i tftp

    Step 10 - Confirm the FreePBX Extension Exists in Asterisk
    ---------------------------------------------------------
    Open the Asterisk CLI:

    asterisk -rvvv

    Check the new endpoint:

    pjsip show endpoint <EXTENSION_2>

    Before the phone registers, it may show:

    Unavailable

    That is okay. It means the extension exists but the phone has not registered yet.

    Exit Asterisk when done:

    exit

    Step 11 - Set the Phone's TFTP Server
    ------------------------------------
    On the Cisco 8845 phone:

    Applications -> Admin Settings -> Network Setup -> Ethernet Setup -> IPv4 Setup

    Set:

    Alternate TFTP: On
    TFTP Server 1: <FREEPBX_IP>

    Save/apply the settings and reboot the phone.

    This was the key step that made the second phone work. The phone had network connectivity, but it did not pull the correct config until it was pointed at the correct TFTP server.

    Step 12 - Watch the Phone Pull Its TFTP Config
    ---------------------------------------------
    On the FreePBX server, watch the TFTP logs:

    journalctl -u tftpd-hpa -f

    Reboot the phone.

    Expected request:

    <NEW_PHONE_SEP_FILE>

    Example format only:

    SEPBBBBBBBBBBBB.cnf.xml

    The phone may also request other files such as:
    - XMLDefault.cnf.xml
    - locale files
    - dialplan files
    - ringlist files
    - CTL/ITL-related files

    The important file is the MAC-specific SEP config.

    Optional TFTP Traffic Test
    --------------------------
    If journalctl does not show anything, use tcpdump:

    tcpdump -ni any host <PHONE_IP> and port 69

    Then reboot the phone again.

    If traffic appears, the phone is attempting TFTP.
    If no traffic appears, the phone is probably not pointed at the correct TFTP server or is not reaching the FreePBX server.

    Step 13 - Verify SIP Registration
    --------------------------------
    Open the Asterisk CLI:

    asterisk -rvvv

    Check registered contacts:

    pjsip show contacts

    Check the second phone:

    pjsip show endpoint <EXTENSION_2>

    Expected result:
    The second phone should show as available/registered, with a contact URI from the phone's IP address.

    Example format only:

    Contact: <EXTENSION_2>/sip:<EXTENSION_2>@<PHONE_IP>:5060  Avail

    Step 14 - Test Calling
    ----------------------
    From the first phone, dial:

    <EXTENSION_2>

    From the second phone, dial:

    <EXTENSION_1>

    Successful result:
    Both Cisco 8845 phones can call each other internally through FreePBX.

    Step 15 - Back Up the Working Configs
    ------------------------------------
    Once both phones work, back up the known-good XML files:

    cd <TFTP_DIR>
    mkdir -p backups
    cp <OLD_PHONE_SEP_FILE> backups/<OLD_PHONE_SEP_FILE>.working
    cp <NEW_PHONE_SEP_FILE> backups/<NEW_PHONE_SEP_FILE>.working
    ls -lh backups

    This makes it easy to roll back if future VLAN, firmware, or XML changes break registration.

    Troubleshooting Notes
    ---------------------

    Problem:
    Phone powers on and gets an IP, but does not register.

    Likely causes:
    - Alternate TFTP is not enabled.
    - TFTP Server 1 is not set to <FREEPBX_IP>.
    - The SEP filename does not match the phone MAC.
    - The XML file still has the first phone extension.
    - The authPassword does not match the FreePBX extension Secret.
    - Extension was created but FreePBX Apply Config was not clicked.

    Problem:
    Asterisk shows endpoint as Unavailable.

    Meaning:
    The extension exists, but the phone is not registered yet.

    Check:
    pjsip show contacts
    pjsip show endpoint <EXTENSION_2>

    Problem:
    TFTP logs show no phone requests.

    Check:
    - Phone Alternate TFTP setting
    - Phone IP address
    - Network/VLAN reachability
    - Firewall rules
    - TFTP service status
    - tcpdump on UDP port 69

    Problem:
    Phone pulls XML but still does not register.

    Check:
    - <name>
    - <authName>
    - <authPassword>
    - FreePBX PJSIP Secret
    - SIP server/processNodeName/proxy values in XML
    - Whether the phone is using the intended config file

    Problem:
    Second phone registers as the first phone.

    Cause:
    The copied XML still contains <EXTENSION_1> or old auth information.

    Fix:
    Edit the second phone XML and replace the line identity/auth fields with <EXTENSION_2>.

    Final Working Result
    --------------------
    The second Cisco 8845 was successfully added by:

    1. Connecting it to a PoE switch port.
    2. Confirming the phone with CDP.
    3. Creating a new PJSIP extension in FreePBX.
    4. Copying the first working Cisco 8845 XML file.
    5. Renaming the XML file to match the second phone's SEP/MAC ID.
    6. Editing the XML for the second extension and display name.
    7. Matching the XML authPassword to the FreePBX extension Secret.
    8. Fixing TFTP file ownership and permissions.
    9. Restarting TFTP.
    10. Setting the phone's Alternate TFTP server to the FreePBX IP.
    11. Rebooting the phone.
    12. Confirming both phones could call each other internally.

    This completes the second Cisco 8845 Enterprise SIP phone setup on FreePBX.

View all instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates