Skip to content


Repository files navigation

Millennium Manager - mm_manager

Manager for Nortel Millennium Payphones

Codacy Badge



The Nortel Millennium payphones utilize a Manager to facilitate installation, reporting, call cost rating, and credit card processing. This Millennium payphone calls into the Manager using a 1200-baud phone modem. Unlike some other COCOT payphones, the Manager never calls the payphone.


mm_manager runs on Windows, Linux, and MacOS X.

The mm_manager has been tested with a Nortel Multi-Pay (coin, credit card) Terminal with both V1.0 Control PCP (Through-hole, 1.20 firmware) and V1.1 Control PCP (Surface-mount, 2.11 firmware.) It partially works with other terminal types and firmware versions, see table for limitations:

Firmware Version MTR Terminal Type Languages Notes
NQA1X01 2.20 MP/MC English / Spanish Fully working
NOK1X03 2.13 MP/MC/TTY ?
NLA1X05 2.12 ?
NKA1X02 2.11 MP/MC English / Spanish Fully working
NKA1X05 2.11 MP/MC ?
NCA1X03 2.0 MP/MC/DJ Fully working
NPA1S01 1.20 MP/MC English / Spanish Fully working
NNK1F05 1.13 MP/MC/TTY English / French Fully working
NBA1F02 1.9 MP/MC English / French Fully working
NNA1F02 1.9 MP/MC/TTY English / French Fully working
NBJ1S03 1.9 Desk English / Spanish Fully working
NBE1J01 1.9 Card-only English / Japanese Provisions but can’t rate calls.
06CAA17 1.7 MP/MC Appears working except for chip cards, but Mandatory Table Alarm is present.
06JAA03 1.7 MP/MC English / Japanese Fully working except for chip cards
12AAV08 1.7 MP/MC ?
NAA1S05 1.7 MP/MC ?
NPE1S01 1.20 Coin Basic Fully working
NAD4K02 1.7 Coin Basic ?
NAD4S02 1.7 Coin Basic ?
NAJ2S05 1.7 Desk Fully working except for chip cards
06CBBX1 1.7 Card-only English / Spanish Fully working except for chip cards
PBAXS05 1.7 MP/MC/International Not working

Items Needed

  1. Nortel Millennium Terminal running stock firmware (v1.20 or v2.20 is best, but other versions may work.) Some Millennium Terminals purchased from online phone stores may have been re-programmed with “demo” firmware that does not need a Manager. If you have one of these phones, you’ll have to program the phone back to stock firmware.
  2. 24VDC @500mA Power Supply for Millennium Terminal
  3. 4-pin plug-in screw terminal block to connect 24VDC power and Tip/Ring to the terminal.
  4. Two phone lines (one for mm_manager, one for the Millennium terminal.) They can be real POTS lines, or lines from your own PBX, but the Millennium should be able to dial the manager with a 1- to 15-digit number.
  5. 1200-baud or faster modem that supports Bell 212A modulation. I like the Lenovo 56K USB modems, but any 56K modem with Conexant chipset should work. Note for Linux users - Conexant soft-modems have never had a fully open-source driver, and the out-of-tree driver has not been maintained since kernel v2.4 - something like the US Robotics 5637 or another "real" modem where the device actually is responsible for encoding and decoding the data works well.
  6. mm_manager software and a Windows, Linux machine (Raspberry Pi works great) or MacOS machine. This machine should be available 24x7 so the terminal can call in when needed.
  7. All terminals except desk: T-Key such as the Jonard JIC-719A to open the payphone. I don’t recommend the flat, stamped T-keys as they are prone to bending.
  8. All terminals except desk: Keys for your terminal’s upper and lower locks, if locks are present.
  9. Desk Terminal Only: A “Key Card” to enter the craft access menu. This can be any credit card– best to use an expired one. Specify the first 10-digits of the credit card number to mm_manager with the -k option. The default key card number is 4012888888. You can also program a magnetic stripe card with that number.

mm_manager Installation and Usage

Simply download the source files and example tables from GitHub.

Linux and MacOS

From the shell, type:

cmake .

to compile mm_manager, and several utilities.


Compile mm_manager with Microsoft Visual Studio 2019 or later with CMake, using “Open Folder.”


usage: mm_manager [-vhmq] [-f <filename>] [-i "modem init string"] [-l <logfile>] [-p <pcapfile>] [-a <access_code>] [-k <key_code>] [-n <ncc_number>] [-d <default_table_dir] [-t <term_table_dir>] [-u <port>]
        -a <access_code> - Craft 7-digit access code (default: CRASERV)
        -b <baudrate> - Modem baud rate, in bps.  Defaults to 19200.
        -c - Always download complete table set.
        -d <default_table_dir> - default table directory.
        -e <error_inject_type> - Inject error on SIGBRK.
        -f <filename> modem device or file
        -h this help.
        -i "modem init string" - Modem initialization string.
        -k <key_code> - Desk Terminal 10-digit key card code (default: 4012888888)
        -l <logfile> - log bytes transmitted to and received from the terminal.  Useful for debugging.
        -m use serial modem (specify device with -f)
        -n <Primary NCC Number> [-n <Secondary NCC Number>] - specify primary and optionally secondary NCC number.
        -p <pcapfile> - Save packets in a .pcap file.
        -q - Don't display sign-on banner.
        -r - Rating test mode: Amount charged determined by last 4 digits of dialed number.
        -s - Download only minimum required tables to terminal.
        -t <term_table_dir> - terminal-specific table directory.
        -u <port> - Send packets as UDP to <port>.
        -v verbose (multiple v's increase verbosity.
        -w - don't monitor the modem for carrier loss.

Millennium Terminal Hardware Installation

Phone Line

The Nortel Millennium payphones require a standard POTS line, with answer supervision in the form of polarity reversal to indicate that the far end has answered the call. This is required for the Millennium to know when to collect or refund coins. Most SIP ATAs and Cisco Voice Routers can be configured for polarity reversal. If your phone line does not support polarity reversal, an answer supervision detection module is available from Nortel.

If you are using VoIP, make sure to use the u-law PCM codec, disable silence suppression, disable comfort noise generation, and disable echo cancellation. This is required to condition the line for modem operation. You may also need to increase the jitter buffer size, and use a fixed jitter buffer, rather than adaptive.

Power Supply

The Nortel Millennium terminal requires 24VDC at 500mA to supply power to the phone. Only limited functionality is provided for emergency service when this power is not present.

Other Terminal Installation Notes

The Millennium Terminal is an advanced payphone that contains a multitude of sensors to determine if the phone is installed and operating properly. This includes sensors to make sure that a coin box is installed, and also a sensor to ensure the coin vault door is in place. If your Millennium does not have a coin box, please obtain one. The coin boxes are standard Western Electric / Northern Electric Single Slot, readily available. In a pinch, the coin box sensor switch can be taped in the closed position. The same goes for the coin vault door. The coin vault door must be in place and locked. If your phone is missing the coin vault lock, as is quite common for these phones purchased on the second-hand market, please obtain the correct lock, or tape the switch closed.

If these sensors are not happy, the phone will alarm, and will go “Out of Service.”

Millennium Terminal Provisioning

Provisioning the Millennium Terminal is accomplished through the craft access menu on the terminal itself. For this, you will need the terminal’s access code, and a PIN. The default Access Code is 2727378 (CRASERV).

With the upper housing of the phone locked, take the handset off the cradle and replace it. Then key in 2727378 (CRASERV.) You will be prompted for a PIN, use anything above 50000, like 55555. Unlock the upper housing with a T-Key when prompted. You do not need to open the upper housing.

Generate NPA and LCD tables (see below,) unless you want to use the default tables included with mm_manager.

Start mm_manager:

./mm_manager -m -n 18005551234 -f /dev/ttyACM0 -vv -l install.dlog -p install.pcap


18005551234 should be replaced by the phone number of your Manager (1-15 digits).

`/dev/ttyACM0` should be replaced by your modem device.  For Windows, it will be something like `\\.\COMx` where ‘`x`’ is the COM port number of your modem.

install.dlog is a log file that contains all of the data received and sent by the manager.

install.pcap is a packet capture that can be loaded into [Wireshark]( for debugging.

Follow the Terminal’s on-screen prompts to install.

Key in this Terminal’s telephone number (10-digits) NPA-NXX-XXXX.

Key in this Terminal’s 10-digit serial number (1234567890 is fine.)

Key in the Manager’s phone number (I use 1-800-555-1234, which I intercept in the Asterisk dialplan and send to the modem connected to the computer running mm_manager.)

Configuration Tables

Communication with the Nortel Millennium involves sending and receiving tables. Tables are numbered 1 through 155, and contain configuration information sent to the terminal or query / status information received from the terminal. Tables are of fixed size, depending on the type of table.

Each packet response from the Manager includes the Terminal’s phone number, followed by a byte containing the Table ID of the current table being sent by the Manager. Multiple tables may be packed into a single packet (the maximum packet table payload length is 245 bytes.)

In the case of large table download (> 245 bytes) to the Millennium terminal, the table payload is split into 245-byte chunks, but the Table ID is only included in the first packet.

The following are some of the tables used by the Millennium terminal. They should be customized (using a hex editor) for your specific phone. Some parameters (like NCC numbers and Access Code) can be changed via command-line parameters to mm_manager.

Some of the important tables for configuring a Millennium terminal include:

Table ID (DEC) Table ID (Hex) Description Length Notes
10 0xa Terminal Status 10 TSTATUS - pp. 2-636
13 0xd End of Data Message 0 Manager sends no data.
14 0x0e Table Update ACK 1 Terminal -> Manager
18 0x12 Terminal Table Data Update 0 TERMDAT - pp. 2-528
20 0x14 Date/Time Synchronization 7 Time Sync
21 0x15 Terminal Access Parameters 47 TERM - pp. 2-492: Contains our number and primary/sec NCC#, call in start date, time, interval, CDR threshold.
26 0x1a Feature Configuration – Universal 71 FEATRU - pp. 2-151
29 0x1d Advertising Prompts 480 ADMESS - pp. 2-5
30 0x1e User Interface Parameters Universal 67 USERPRM - pp. 2-669
31 0x1f Installation/Servicing Parameters 36 INSTSV - pp. 2-235
32 0x20 Communication Statistics and Configuration Parameters 32 COMMST - pp. 2-86
33 0x21 Modem Parameters 35 MODEM - pp. 2-279
34 0x22 Call Statistics Parameters 18 CALLST - pp. 2-36
35 0x23 Time/Call-In Parameters 20 TERM table, pp. 2-517
36 0x24 Time Synchronization Request 0 TTMSYNC
38 0x26 Terminal Cash Box Status 62 TCASHST - pp. 2-420
44 0x2c Terminal Upload Attention 1 TUPLOAD - pp. 2-656

TTBLREQ - pp. 2-651

50 0x32 Coin Validation Parameters 104 COINVL - pp. 2-79
51 0x33 Cash Box


70 TCOLLCT - pp. 2-
55 0x37 Enhanced Repertory Dialer List 570 RDLIST - pp. 2-329
58 0x3a Service Level 25 SERVLEV - pp. 2-349
60 0x3c Terminal Software Version 27 TSWVERS - pp. 2-647
62 0x3e Dialing Rules 352 DIALRL - pp. 2-107

32 bytes: Fixed Format Data

180 bytes: Numbering Plan Rules

140 bytes: Display Formatting

72 0x48 Spare Table 1000 SPARE - pp. 2-356 NOTE: This is a required table for V1.3 PCP, but not used on V1.0.
73 0x49 Rate Table 1191 RATE - pp. 2-321
French VFD Text 8000 French: V1.3 Only

0x74001 offset in U2 ROM.

85 0x55 Expanded Visual Prompts Language A 8000 English: V1.3 Only

Qty 400: 20-line VFD strings

0x71B5A offset in U2 ROM.

Japanese VFD Text 8000 Japanese: V1.3 Only

0x7A001 offset in U2 ROM.

86 0x56 Expanded Visual Prompts Language B 8000 Spanish: V1.3 Only

Qty 400: 20-line VFD strings

0x77001 offset in U2 ROM.

92B 0x5c 180 Number Call Screening List 3060 CALLSCRN (Call Screening List) pp. 2-33, and FREE (Free Call) pp. 2-187
93 0x5d Smart Card Parameters Table 224 SMCARD - pp. 2-351
134 0x86 Expanded Card Table (32 Entries) 1152 CARD - pp. 2-57
135 0x87 Expanded Carrier Table (33 Entries) 1108 CARRIER - pp. 2-69
136-149 0x88-0x95 Double Compressed LCD Tables 1-14 202 LCD (Local Call Determination) - pp. 2-248
150 0x96 Set Based Rating NPA Table 400 RATENPA - pp. 2-327
151 97 Set Based Rating - International Table 603 RATEINT - pp. 2-326
154,155 0x9a,0x9b Double Compressed LCD Tables 15,16 202 LCD (Local Call Determination) - pp. 2-248

Generating NPA and LCD tables

Python3 scripts are included to generate NPA and LCD tables automatically, using spreadsheets available from the North American Numbering Plan Administrator. For Canada, spreadsheets are available from the Canadian Numbering Administrator. These scripts require the Python3 libraries: pandas, requests, and xmltodict to be installed.

To generate an NPA table that classifies US and Canadian numbers as domestic:

./ --countries US CANADA

The script is used to generate LCD tables for a given NPA-NXX in the United States. LCD tables generated using this script will properly classify Local, Intra-LATA and Inter-LATA calls. This script does not work in Canada as all of Canada is a single LATA.

For example, to generate LCD tables for San Jose, California, USA for a terminal with phone number of (408) 535-XXXX :

./ --npa=408 --nxx=535

To generate LCD tables for Ottawa, Canada, use

./ --npa 613 --nxx 562

Terminal-Specific Tables

mm_manager has the ability to support multiple terminals with different provisioning. mm_manager searches for configuration tables as follows:

  1. tables/NPANXXXXXX - where NPANXXXXXX is the 10-digit Terminal ID (phone number.)

  2. tables/<model-specific-dir> - where <model-specific-dir> is one of:

    multipay, card_only, desk, coin, inmate.

  3. tables/default - will be used as a last resort if tables cannot be found in the previous directories.

mm_manager stores the last table update date/time in the terminal-specific directory. This allows for quicker iteration during testing by using "force download" in the terminal’s craft interface. This will download only the table that changed and a few tables that are generated within mm_manager itself.

Terminal-specific Table Example

Two multipay terminals with different Advertising messages, and otherwise configured the same:

tables/4085359990/mm_table_1d.bin - Advertising messages for terminal ID 4085359990

tables/4085359995/mm_table_1d.bin - Advertising messages for terminal ID 4085359995

tables/default/ - All of the default tables are in this directory (including mm_table_1d.bin)

mm_manager Utilities

Utility Description
mm_admess Dump Advertising Messages table
mm_areacode Dump Set-based rating (NPA) table, MTR 1.20, 2.x
mm_callin Dump Call-in Parameters table
mm_callscrn Dump Call Screening List
mm_callstat Dump Call Statistics Parameters table
mm_card Dump Credit Card / Smart Card table MTR 1.20, 2.x
mm_card_mtr1 Dump Credit Card / Smart Card table MTR 1.7, 1.9
mm_carrier.exe Dump Carrier table MTR 1.20, 2.x
mm_carrier_mtr1 Dump Carrier table MTR 1.7, 1.9
mm_coinvl Dump Coin Validator table
mm_commstat Dump Communications Statistics Parameters table
mm_convert_callscrn_mtr2_to_mtr1 Convert MTR 1.20/2.x Call Screening List to MTR 1.7, 1.9.
mm_convert_card_mtr2_to_mtr1 Convert MTR 1.20/2.x Card Table to MTR 1.7, 1.9.
mm_dlog2pcap Convert mm_manager dialog output to pcap format for visualization with WireShark.
mm_fconfig Dump Feature Configuration Options table
mm_instsv Dump Installation / Servicing table
mm_lcd Dump LCD tables (supports uncompressed, compressed, and double-compressed tables)
mm_luhn Generate / Check magnetic card Luhn check digit
mm_rate Dump Rate table
mm_rateint Dump International Set-based rating table (MTR 1.20. 2.x)
mm_rdlist Dump Repertory Dialer list
mm_smcard Dump Smart Card (TeleCard) table
mm_table_cutter Extract ROM tables from firmware binaries
mm_userif Dump User Interface Parameters table

Low-Level Protocol

The low-level protocol sent over the modem is a stream of bytes framed within START and END bytes.

02 1-byte 1-byte N bytes... 2-bytes * 03

*CRC-16 IBM with the 0xA001 polynomial per this site. Includes all bytes including START through the DATA.

FLAG Bits:

7 6 5 4 3 2 1 0

Separate sequence numbers are counted for each of tx_seq and rx_seq. ACKs should always be sent with the same sequence as the last received Rx packet. Tx seq is incremented after every successful packet transmission, and reset when the terminal disconnects.


Dialog Transcripts

mm_manager can log all bytes sent to or received from a Millennium terminal using the -l <logfile.dlog> option. This can be used to record a transcript of the session, that can be “played back” to mm_manager by specifying this file to the -f option, without supplying -m (modem.) This allows quick iteration when debugging and testing mm_manager, as a real Millennium terminal is not needed.

One useful trick is to parse the transcript with mm_manager, and save it to a file. Then the code can be modified and improved and tested by re-running the transcript through mm_manager and comparing it with the previous run using a tool such as tkdiff.


mm_manager can save all packets sent and received to a packet capture (.pcap) file for viewing in Wireshark using the -p <pcapfile.pcap> option. This .pcap file can be opened with Wireshark, and dissected using the Millennium LUA Dissector Plugin.

In addition, mm_manager can send all packets via UDP to the localhost port 27273 (“CRASE”) so Wireshark can view them in real-time while communicating with a terminal.

Filing Bug Reports

If you find a bug, please provide the following information when you report the bug on GitHub:

  1. Please make sure you run mm_manager with the -l <filename> option to generate the session transcript of all the data sent to and from the manager. Please attach this file to your bug report.
  2. Use mm_manager’s -p <pcapfile.pcap> option to save a packet capture and attach this file to your bug report.
  3. Please provide information about the type of Millennium phone you have and what ROM version it’s running. Some of this information is displayed by mm_manager after it connects to the phone.
  4. Please provide details about the operating system you are using, what kind of modem you are using, and if you are using a serial modem, what type of serial port you are using (built-in PC serial port, USB serial port, etc.)
  5. Please provide details about the phone lines you are using: Are they VoIP, POTS, going through your own PBX, or going over the PSTN? Analog and TDM switches are preferable to VoIP, if at all possible.
  6. Steps to reproduce the issue.

Known Issues

  1. When installing a Millennium Terminal, the answer supervision test will call the Manager, and disconnect. It may take a few seconds for mm_manager’s modem to detect this condition and go back on-hook. You may want to wait a few seconds after the test completes before proceeding with the installation.
  2. Some older firmware versions will fail to install on the first try. They will usually install correctly on a retry.
  3. Lots of tables are not well understood. Please help figure more out if you can.

Further Work Needed (Feel free to help!)

  1. Improve modem robustness.
  2. Lots of other things, please file bugs as you find them.


Nortel Millennium on Wikipedia

Chaos Computer Club Muenchen

muccc / millennium on GitHub

Description of Millennium Tables

millenniium-panel on GitHub

Armeniki’s Nortel Millennium information on GitHub

Millennium Database Design Report MSR 2.1

Millennium Multi-Pay Terminal Installation, Operation, and Maintenance Guide

Millennium Desk Terminal: Installing and Repairing Terminal Hardware