Skip to content
This repository has been archived by the owner on Mar 8, 2024. It is now read-only.

Commit

Permalink
corenet: fix some gNB NGSetup stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
p1-bmu committed Apr 30, 2020
1 parent 5830e3b commit ffe38db
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 68 deletions.
11 changes: 6 additions & 5 deletions pycrate_corenet/HdlrGNB.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,12 @@ def start_ngap_proc(self, ProcClass, **IEs):
def get_ngsetup_ies_from_cfg(self):
"""return the dict of IEs for the NGSetupResponse from the Config dict
"""
ies = {'AMFName' : self.Server.ConfigNG['AMFName'],
'PLMNSupportList' : cplist(self.Server.ConfigNG['PLMNSupportList']),
'RelativeAMFCapacity': self.Server.ConfigNG['RelativeAMFCapacity'],
'ServedGUAMIList' : cplist(self.Server.ConfigNG['ServedGUAMIList']),
}
ies = {
'AMFName' : self.Server.ConfigNG['AMFName'],
'PLMNSupportList' : plmnsupplist_to_asn(self.Server.AMF_PLMNSupp),
'RelativeAMFCapacity': self.Server.ConfigNG['RelativeAMFCapacity'],
'ServedGUAMIList' : guamilist_to_asn(self.Server.AMF_GUAMI),
}
if 'UERetentionInformation' in self.Server.ConfigNG:
ies['UERetentionInformation'] = self.Server.ConfigNG['UERetentionInformation']
return ies
Expand Down
6 changes: 3 additions & 3 deletions pycrate_corenet/ProcCNNgap.py
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,7 @@ class NGAPNGSetup(NGAPNonUESigProc):
# Custom decoders
Decod = {
'ini': ({
'GlobalRANNodeID': ngranid_to_hum,
'GlobalRANNodeID': globranid_to_hum,
'SupportedTAList': supptalist_to_hum,
},
{}),
Expand All @@ -1282,12 +1282,12 @@ def recv(self, pdu):
else:
self.GNB.Config = cpdict(self.GNBInfo)
tais = []
for (tac, bcastplmnlist) in self.GNBInfo['SupportedTAList']:
for (tac, bcastplmnlist) in self.GNBInfo['SupportedTAList'].items():
for (plmn, _) in bcastplmnlist:
tais.append( (plmn, tac) )
self.GNB.Config['TAIs'] = tais
self.GNB.ID = self.GNBInfo['GlobalRANNodeID']
# prepare the SNGSetupResponse
# prepare the NGSetupResponse
IEs = self.GNB.get_ngsetup_ies_from_cfg()
self.encode_pdu('suc', **IEs)
self._log('INF', 'gNB NG setup successfully')
Expand Down
105 changes: 54 additions & 51 deletions pycrate_corenet/Server.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,31 +133,44 @@ class CorenetServer(object):
#
# main PLMN served
PLMN = '00101'
# equivalent PLMNs served, used for Iu and S1 interface
# None or list of PLMNs ['30124', '763326', ...]
EQUIV_PLMN = None


### AMF-related config
#
# AMF RegionID, SetID and Pointer
AMF_RID = 1
AMF_SID = 1
AMF_PTR = 0
# list of PLMN and slices supported
# a sliceSupportList is basically a Sequence of S-NSSAI
# AMF ID for each served PLMN
# PLMN (str): AMF ID 3-tuple (RegionID uint8, SetID uint10, Pointer uint6)
AMF_GUAMI = {
PLMN: (1, 1, 0),
}
#
# arbitrary dict of indexed slices identifiers
# S-NSSAI is at least an SST (uint8) and eventually an SD (uint24)
AMF_SNSSAI = {
0 : (0x00, ), # default S-NSSAI
1 : (0x01, ),
2 : (0x02, ),
21 : (0x02, 0x000001),
}
AMF_PLMNSupp = [
(PLMN, [AMF_SNSSAI[0]]),
#($plmn1, [AMF_SNSSAI[1]]),
#($plmn2, [AMF_SNSSAI[2], AMF_SNSSAI[21]])
]
# list of slice supported for each served PLMN
AMF_PLMNSupp = {
PLMN: [AMF_SNSSAI[0]],
#$plmn1: [AMF_SNSSAI[1]],
#$plmn2: [AMF_SNSSAI[2], AMF_SNSSAI[21]],
}
#
# MME GroupID and Code
MME_GID = 1
MME_CODE = 1
# NG connection AMF parameters
ConfigNG = {
'AMFName' : 'CorenetAMF',
'RelativeAMFCapacity': 10,
#'UERetentionInformation': 'ues-retained',
}


### IuCS, IuPS and S1 common parameters
#
# equivalent PLMNs served, used for Iu and S1 interface
# None or list of PLMNs ['30124', '763326', ...]
EQUIV_PLMN = None
#
# emergency number lists
# None or list of 2-tuple [(number_category, number), ...]
Expand All @@ -168,26 +181,13 @@ class CorenetServer(object):
# ({'Police', 'Ambulance', 'Fire'}, '112112'),
# ({'Marine', 'Mountain'}, '112113')]
EMERG_NUMS = None


### MME-related config
#
# NG connection AMF parameters
ConfigNG = {
'AMFName' : 'CorenetAMF',
'PLMNSupportList' : [
{'pLMNIdentity': plmn_str_to_buf(plmn),
'sliceSupportList': [
{'s-NSSAI': {'sST': uint_to_bytes(snssai[0], 8), 'sD': uint_to_bytes(snssai[1], 24)}} if len(snssai) > 1 else \
{'s-NSSAI': {'sST': uint_to_bytes(snssai[0], 8)}} for snssai in snssais],
} for (plmn, snssais) in AMF_PLMNSupp],
'RelativeAMFCapacity': 10,
'ServedGUAMIList' : [
{'gUAMI': {
'pLMNIdentity': plmn_str_to_buf(PLMN),
'aMFRegionID' : (AMF_RID, 8),
'aMFSetID' : (AMF_SID, 10),
'aMFPointer' : (AMF_PTR, 6)}},
],
#'UERetentionInformation': 'ues-retained',
}
# MME GroupID and Code
MME_GID = 1
MME_CODE = 1
#
# S1 connection MME parameters
ConfigS1 = {
Expand All @@ -201,6 +201,9 @@ class CorenetServer(object):
'EquivPLMNList' : EQUIV_PLMN,
'EmergNumList' : EMERG_NUMS,
}


### MSC/VLR/SGSN-related config
#
# HNBAP connection GW parameters (keep it empty)
ConfigHNBAP = {}
Expand All @@ -218,18 +221,21 @@ class CorenetServer(object):
}

#--------------------------------------------------------------------------#
# HNB and ENB parameters
# HNB, ENB and GNB parameters
#--------------------------------------------------------------------------#
#
# Home-NodeB and eNodeB, indexed by (PLMN, CellId)
# the RAN dict can be initialized with {(PLMN, CellId): None} at setup
# this provide a whitelist of allowed basestations.
# Connection from RAN equipments:
# Home-NodeB, eNodeB and gNodeB indexed by their global ID
# (PLMN, CellId) for home-NodeB and eNodeB
# (PLMN, CellType, CellId) for gNodeB
# the RAN dict can be initialized with {(PLMN, *Cell*): None} here
# this provides a whitelist of allowed basestations.
RAN = {}
#
# Otherwise, this is a flag to allow any RAN equipment to connect the server
# in case its PLMN is in the RAN_ALLOWED_PLMN list.
# If enabled, RAN dict will be populated at runtime
# If disabled, RAN keys (PLMN, CellId) needs to be setup by configuration
# If disabled, RAN keys (PLMN, *Cell*) needs to be setup by configuration (see above)
RAN_CONNECT_ANY = True
#
# This is the list of accepted PLMN for RAN equipment connecting,
Expand Down Expand Up @@ -709,16 +715,16 @@ def handle_stream_msg(self, sk):
Cause=('protocol', 'transfer-syntax-error'))
pdu_tx = Err.send()
else:
pdu_rx = PDU_S1AP()
if enb.TRACE_ASN_NGAP:
enb._log('TRACE_ASN_NGAP_UL', PDU_NGAP.to_asn1())
pdu_rx = PDU_NGAP()
if gnb.TRACE_ASN_NGAP:
gnb._log('TRACE_ASN_NGAP_UL', PDU_NGAP.to_asn1())
asn_ngap_release()
if sid == gnb.SKSid:
# non-UE-associated signalling
pdu_tx = gnb.process_ngap_pdu(pdu_rx)
else:
# UE-associated signalling
pdu_tx = enb.process_ngap_ue_pdu(pdu_rx, sid)
pdu_tx = gnb.process_ngap_ue_pdu(pdu_rx, sid)
for pdu in pdu_tx:
self.send_ngap_pdu(gnb, pdu, sid)
#
Expand Down Expand Up @@ -951,16 +957,13 @@ def _parse_ngsetup(self, pdu):
# PLMN,
# ID type (gNB-ID, macroNgENB-ID, shortMacroNgENB-ID, longMacroNgENB-ID or n3IWF-ID),
# ID bit-string value
ranid = ngranid_to_hum(ie['value'][1])
plmn = ranid[0]
ranid = ranid[1:]
ranid = globranid_to_hum(ie['value'][1])
break
if plmn is None or ranid is None:
if ranid is None:
self._log('WNG', 'invalid NGAP PDU for setting up the gNB NGAP link: '\
'missing PLMN and RAN-ID')
return
# decode PLMN and CellID
return plmn, ranid
return ranid

def _send_ngsetuprej(self, sk, cause):
IEs = [{'criticality': 'ignore',
Expand Down
84 changes: 75 additions & 9 deletions pycrate_corenet/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ def inet_ntoa_cn(pdntype, buf, dom='EPS'):

# routines for dealing with structures for NGAP

def ngranid_to_hum(cho):
def globranid_to_hum(cho):
"""returns a 3-tuple:
- plmn id (str)
- node type (str)
Expand Down Expand Up @@ -610,6 +610,29 @@ def ngranid_to_hum(cho):
)
return None

def globranid_to_asn(granid):
if granid[1] == 'gNB-ID':
return (
'globalGNB-ID', {
'pLMNIdentity' : plmn_str_to_buf(granid[0]),
'gNB-ID' : (granid[1], granid[2])
}
)
elif granid[1] == 'n3IWF-ID':
return (
'globalN3IWF-ID', {
'pLMNIdentity' : plmn_str_to_buf(granid[0]),
'n3IWF-ID' : (granid[1], granid[2])
}
)
else:
return (
'globalNgENB-ID', {
'pLMNIdentity' : plmn_str_to_buf(granid[0]),
'ngENB-ID' : (granid[1], granid[2])
}
)

def bcastplmn_to_hum(seq):
"""returns a 2-tuple:
- plmn id (str)
Expand All @@ -628,10 +651,12 @@ def supptalist_to_hum(seqof):
- TAC (uint24, was uint16 in S1AP)
- list of broadcasted PLMN 2-tuple (see bcastplmn_to_hum)
"""
return [(
bytes_to_uint(seq['tAC'], 24),
[bcastplmn_to_hum(bcastplmn) for bcastplmn in seq['broadcastPLMNList']]) \
for seq in seqof]
# warning: in case of duplicate TAC, this will override GNB TAC of the first one(s)
return {
bytes_to_uint(seq['tAC'], 24) : [
bcastplmn_to_hum(bcastplmn) for bcastplmn in seq['broadcastPLMNList']] \
for seq in seqof
}

def supptalist_to_asn(supptalist):
return [
Expand All @@ -645,10 +670,51 @@ def supptalist_to_asn(supptalist):
{'s-NSSAI': {
'sST': uint_to_bytes(snssai[0], 8)}} \
for snssai in snssailist]
} for (plmn, snssailist) in bcastplmnlist]}
for (tac, bcastplmnlist) in supptalist
]

} for (plmn, snssailist) in bcastplmnlist]
} for (tac, bcastplmnlist) in sorted(supptalist.items())
]

def guamilist_to_hum(seqof):
# warning: in case of duplicate PLMN, this will override AMF ID of the first one(s)
return {
plmn_buf_to_str(guami['gUAMI']['pLMNIdentity']): (
guami['gUAMI']['aMFRegionID'][0],
guami['gUAMI']['aMFSetID'][0],
guami['gUAMI']['aMFPointer'][0]
) for guami in seqof
}

def guamilist_to_asn(guamilist):
return [
{'gUAMI': {
'pLMNIdentity': plmn_str_to_buf(plmn),
'aMFRegionID' : (rid, 8),
'aMFSetID' : (sid, 10),
'aMFPointer' : (ptr, 6)
}
} for (plmn, (rid, sid, ptr)) in sorted(guamilist.items())
]

def plmnsupplist_to_hum(seqof):
# warning: in case of duplicate PLMN, this will override S-NSSAI of the first one(s)
return {
plmn_buf_to_str(seq['pLMNIdentity']): [
(bytes_to_uint(snssai['s-NSSAI']['sST'], 8), bytes_to_uint(snssai['s-NSSAI']['sD'], 24)) \
if len(snssai['s-NSSAI']) > 1 else \
(bytes_to_uint(snssai['s-NSSAI']['sST'], 8), ) \
for snssai in seq['sliceSupportList']
]
for seq in seqof
}

def plmnsupplist_to_asn(plmnsupplist):
return [
{'pLMNIdentity': plmn_str_to_buf(plmn),
'sliceSupportList': [
{'s-NSSAI': {'sST': uint_to_bytes(snssai[0], 8), 'sD': uint_to_bytes(snssai[1], 24)}} if len(snssai) > 1 else \
{'s-NSSAI': {'sST': uint_to_bytes(snssai[0], 8)}} for snssai in snssais],
} for (plmn, snssais) in sorted(plmnsupplist.items())
]

#------------------------------------------------------------------------------#
# ASN.1 object handling facilities
Expand Down

0 comments on commit ffe38db

Please sign in to comment.