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 |
- 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.
- 24VDC @500mA Power Supply for Millennium Terminal
- 4-pin plug-in screw terminal block to connect 24VDC power and Tip/Ring to the terminal.
- 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. - 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.
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.- 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.
- All terminals except desk: Keys for your terminal’s upper and lower locks, if locks are present.
- 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.
Simply download the source files and example tables from GitHub.
From the shell, type:
cmake .
make
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.
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.
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.
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.”
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
Where:
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](https://github.com/hharte/mm_manager/tree/master/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
.)
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
Collection |
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 |
- Page number references are to Millennium Database Design Report MSR 2.1.
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:
./generate_npa.py --countries US CANADA
The generate_lcd_lata.py
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 :
./generate_lcd_lata.py --npa=408 --nxx=535
To generate LCD tables for Ottawa, Canada, use generate_lcd_lir.py
:
./generate_lcd_lir.py --npa 613 --nxx 562
mm_manager
has the ability to support multiple terminals with different provisioning. mm_manager
searches for configuration tables as follows:
-
tables/NPANXXXXXX
- whereNPANXXXXXX
is the 10-digit Terminal ID (phone number.) -
tables/<model-specific-dir>
- where<model-specific-dir>
is one of:multipay, card_only, desk, coin, inmate
. -
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.
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
)
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 |
The low-level protocol sent over the modem is a stream of bytes framed within START and END bytes.
START | FLAG Byte | LEN (includes END) | DATA | CRC-16 | END |
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 |
? | ? | DISCONNECT | ERROR | ACK | RETRY | Sequence |
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.
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.
If you find a bug, please provide the following information when you report the bug on GitHub:
- 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. - Use mm_manager’s
-p <pcapfile.pcap>
option to save a packet capture and attach this file to your bug report. - 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. - 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.)
- 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.
- Steps to reproduce the issue.
- 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.
- Some older firmware versions will fail to install on the first try. They will usually install correctly on a retry.
- Lots of tables are not well understood. Please help figure more out if you can.
- Improve modem robustness.
- Lots of other things, please file bugs as you find them.
Nortel Millennium on Wikipedia
Description of Millennium Tables
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