Categories
EPC EUTRAN LTE Mobile Networks Python RFCs & Standards SIM Cards Software

PLMN Identifier Calculation (MCC & MNC to PLMN)

How to encode and decode MCC and MNC as PLMN Identifiers

The PLMN Identifier is used to identify the radio networks in use, it’s made up of the MCC – Mobile Country Code and MNC – Mobile Network Code.

But sadly it’s not as simple as just concatenating MCC and MNC like in the IMSI, there’s a bit more to it.

In the example above the Tracking Area Identity includes the PLMN Identity, and Wireshark has been kind enough to split it out into MCC and MNC, but how does it get that from the value 12f410?

This one took me longer to work out than I’d like to admit, and saw me looking through the GSM spec, but here goes:

PLMN Contents: Mobile Country Code (MCC) followed by the Mobile Network Code (MNC).
Coding: according to TS GSM 04.08 [14].

If storage for fewer than the maximum possible number n is required, the excess bytes shall be set to ‘FF’. For instance, using 246 for the MCC and 81 for the MNC and if this is the first and only PLMN, the contents reads as follows: Bytes 1-3: ’42’ ‘F6′ ’18’ Bytes 4-6: ‘FF’ ‘FF’ ‘FF’ etc.

TS GSM 04.08 [14].

Making sense to you now? Me neither.

Here’s the Python code I wrote to encode MCC and MNCs to PLMN Identifiers and to decode PLMN into MCC and MNC, and then we’ll talk about what’s happening:

def Reverse(str):
    stringlength=len(str)
    slicedString=str[stringlength::-1]
    return (slicedString)

def DecodePLMN(plmn):
    print("Decoded PLMN: " + str(plmn))
    mcc = Reverse(plmn[0:2]) + Reverse(plmn[2:4]).replace('f', '')
    print("Decoded MCC: " + mcc)
    mnc = Reverse(plmn[4:6])
    print("Decoded MNC: " + mnc)
    return mcc, mnc

def EncodePLMN(mcc, mnc):
    plmn = list('XXXXXX')
    plmn[0] = Reverse(mcc)[1]
    plmn[1] = Reverse(mcc)[2]
    plmn[2] = "f"
    plmn[3] = Reverse(mcc)[0]
    plmn[4] = Reverse(mnc)[0]
    plmn[5] = Reverse(mnc)[1]
    plmn_list = plmn
    plmn = ''
    for bits in plmn_list:
        plmn = plmn + bits
    print("Encoded PLMN: " + str(plmn))
    return plmn

DecodePLMN('05f539')
EncodePLMN('505', '93')

In the above example I take MCC 505 (Australia) and MCC 93 and generate the PLMN ID 05f539.

The first step in decoding is to take the first two bits (in our case 05 and reverse them – 50, then we take the third and fourth bits (f5) and reverse them too, and strip the letter f, now we have just 5. We join that with what we had earlier and there’s our MCC – 505.

Next we get our MNC, for this we take bytes 5 & 6 (39) and reverse them, and there’s our MNC – 93.

Together we’ve got MCC 505 and MNC 93.

The one answer I’m still looking for; why not just encode 50593? What is gained by encoding it as 05f539?

2 replies on “PLMN Identifier Calculation (MCC & MNC to PLMN)”

https://www.cisco.com/c/en/us/td/docs/wireless/asr_5000/21-11_6-5/GTPP-Reference/21-11-GTPP-Reference/21-11-GTPP-Reference_chapter_01001.html#reference_4aed2774-e602-4d96-b921-7d3a0b0ba00f

Look at: “The following subclauses specify the coding of the different identities. For each identity, if an Administration decides to include only two digits in the MNC, then bits 5 to 8 of octet 7 are coded as “1111”. ”

In some coutries (like US) MNC is 3 digits not 2 and there is no f in PLMN_ID

Leave a Reply

Your email address will not be published. Required fields are marked *