From a23ab78e9f1cdefdf407a22eb16f4e01893dea46 Mon Sep 17 00:00:00 2001 From: nickvsnetworking Date: Tue, 19 Dec 2023 09:34:39 +1100 Subject: [PATCH 1/4] NIDD optional AVPs --- lib/database.py | 7 ++++++- lib/diameter.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/lib/database.py b/lib/database.py index b641570..84170d2 100755 --- a/lib/database.py +++ b/lib/database.py @@ -29,7 +29,7 @@ class APN(Base): __tablename__ = 'apn' apn_id = Column(Integer, primary_key=True, doc='Unique ID of APN') apn = Column(String(50), nullable=False, doc='Short name of the APN') - ip_version = Column(Integer, default=0, doc="IP version used - 0: ipv4, 1: ipv6 2: ipv4+6 3: ipv4 or ipv6 [3GPP TS 29.272 7.3.62]") + ip_version = Column(Integer, default=0, doc="IP version used - 0: ipv4, 1: ipv6 2: ipv4+6 3: ipv4 or ipv6 4: [3GPP TS 29.272 7.3.62]") pgw_address = Column(String(50), doc='IP of the PGW') sgw_address = Column(String(50), doc='IP of the SGW') charging_characteristics = Column(String(4), default='0800', doc='For the encoding of this information element see 3GPP TS 32.298 [9]') @@ -40,6 +40,11 @@ class APN(Base): arp_preemption_capability = Column(Boolean, default=False, doc='Allocation and Retention Policy - Capability to Preempt resources from other Subscribers') arp_preemption_vulnerability = Column(Boolean, default=True, doc='Allocation and Retention Policy - Vulnerability to have resources Preempted by other Subscribers') charging_rule_list = Column(String(18), doc='Comma separated list of predefined ChargingRules to be installed in CCA-I') + nidd_scef_id = Column(String(100), default=None, doc="ID of SCEF to be used for NIDD for NB-IoT") + nidd_scef_realm = Column(String(100), default=None, doc='Realm of the SCEF for NIDD for NB-IoT') + nidd_mechanism = Column(Integer, default=None, doc="Mechanism used to transfer Non-IP-Data: SGi-BASED-DATA-DELIVERY (0) or SCEF-BASED-DATA-DELIVERY (1)") + nidd_rds = Column(Integer, default=None, doc="Indicates if Reliable Data Service is enabled or disabled for this APN: DISABLED (0) or ENABLED (1)") + nidd_preferred_data_mode = Column(Integer, default=None, doc="Preferred-Data-Mode: Data over User Plane Preferred (0) or Data over Control Plane Preferred (1)") last_modified = Column(String(100), default=datetime.datetime.now(tz=timezone.utc), doc='Timestamp of last modification') operation_logs = relationship("APN_OPERATION_LOG", back_populates="apn") diff --git a/lib/diameter.py b/lib/diameter.py index f1ec9da..b3bb125 100644 --- a/lib/diameter.py +++ b/lib/diameter.py @@ -1292,6 +1292,48 @@ def Answer_16777251_316(self, packet_vars, avps): APN_context_identifer = self.generate_vendor_avp(1423, "c0", 10415, self.int_to_hex(APN_context_identifer_count, 4)) APN_PDN_type = self.generate_vendor_avp(1456, "c0", 10415, self.int_to_hex(int(apn_data['ip_version']), 4)) + #If int(apn_data['ip_version']) == 4 (Non-IP) then this is NB-IoT and we need to add the NB-IoT specific parameters + if int(apn_data['ip_version']) == 4: + NIDD_Parameters = '' + + #Add Non-IP-PDN-Type-Indicator + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1681, "c0", 10415, self.int_to_hex(1), 4) + + #Add SCEF ID + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(3125, "c0", 10415, self.string_to_hex(str(apn_data['nidd_scef_id']))) + except: + pass + + #Add SCEF Realm + try: + #Check SCEF Realm is not empty + if apn_data['nidd_scef_realm'] != '': + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1684, "c0", 10415, self.string_to_hex(str(apn_data['nidd_scef_realm']))) + except: + pass + + #Add Reliable Data Indicator + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1697, "c0", 10415, self.int_to_hex(int(apn_data['nidd_rds']), 4)) + except: + pass + + #Add Preferred Data Mode + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1686, "c0", 10415, self.int_to_hex(int(apn_data['nidd_preferred_data_mode']), 4)) + except: + pass + + #Add Non-IP-Data-Delivery-Mechanism + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1682, "c0", 10415, self.int_to_hex(int(apn_data['nidd_mechanism']), 4)) + except: + pass + + else: + NIDD_Parameters = '' + self.logTool.log(service='HSS', level='debug', message="Setting APN AMBR", redisClient=self.redisMessaging) #AMBR AMBR = '' #Initiate empty var AVP for AMBR @@ -1345,7 +1387,7 @@ def Answer_16777251_316(self, packet_vars, avps): MIP6_Agent_Info = '' APN_Configuration_AVPS = APN_context_identifer + APN_PDN_type + APN_AMBR + APN_Service_Selection \ - + APN_EPS_Subscribed_QoS_Profile + Served_Party_Address + MIP6_Agent_Info + PDN_GW_Allocation_Type + VPLMN_Dynamic_Address_Allowed + + APN_EPS_Subscribed_QoS_Profile + Served_Party_Address + MIP6_Agent_Info + PDN_GW_Allocation_Type + VPLMN_Dynamic_Address_Allowed + NIDD_Parameters APN_Configuration += self.generate_vendor_avp(1430, "c0", 10415, APN_Configuration_AVPS) From d54f8c1bb7faa83ab5efa830a8180e04c86891ba Mon Sep 17 00:00:00 2001 From: davidkneipp Date: Tue, 19 Dec 2023 12:14:16 +1000 Subject: [PATCH 2/4] Update database.py increase column size for nidd strings --- lib/database.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/database.py b/lib/database.py index 84170d2..7a801ae 100755 --- a/lib/database.py +++ b/lib/database.py @@ -40,8 +40,8 @@ class APN(Base): arp_preemption_capability = Column(Boolean, default=False, doc='Allocation and Retention Policy - Capability to Preempt resources from other Subscribers') arp_preemption_vulnerability = Column(Boolean, default=True, doc='Allocation and Retention Policy - Vulnerability to have resources Preempted by other Subscribers') charging_rule_list = Column(String(18), doc='Comma separated list of predefined ChargingRules to be installed in CCA-I') - nidd_scef_id = Column(String(100), default=None, doc="ID of SCEF to be used for NIDD for NB-IoT") - nidd_scef_realm = Column(String(100), default=None, doc='Realm of the SCEF for NIDD for NB-IoT') + nidd_scef_id = Column(String(512), default=None, doc="ID of SCEF to be used for NIDD for NB-IoT") + nidd_scef_realm = Column(String(512), default=None, doc='Realm of the SCEF for NIDD for NB-IoT') nidd_mechanism = Column(Integer, default=None, doc="Mechanism used to transfer Non-IP-Data: SGi-BASED-DATA-DELIVERY (0) or SCEF-BASED-DATA-DELIVERY (1)") nidd_rds = Column(Integer, default=None, doc="Indicates if Reliable Data Service is enabled or disabled for this APN: DISABLED (0) or ENABLED (1)") nidd_preferred_data_mode = Column(Integer, default=None, doc="Preferred-Data-Mode: Data over User Plane Preferred (0) or Data over Control Plane Preferred (1)") From c9a2ba18c24c8ab04bfafa6343704a9bc36d12e7 Mon Sep 17 00:00:00 2001 From: davidkneipp Date: Tue, 19 Dec 2023 12:20:03 +1000 Subject: [PATCH 3/4] Update database.py Add conditional field for nbiot in apn --- lib/database.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/database.py b/lib/database.py index 7a801ae..ca19437 100755 --- a/lib/database.py +++ b/lib/database.py @@ -40,6 +40,7 @@ class APN(Base): arp_preemption_capability = Column(Boolean, default=False, doc='Allocation and Retention Policy - Capability to Preempt resources from other Subscribers') arp_preemption_vulnerability = Column(Boolean, default=True, doc='Allocation and Retention Policy - Vulnerability to have resources Preempted by other Subscribers') charging_rule_list = Column(String(18), doc='Comma separated list of predefined ChargingRules to be installed in CCA-I') + nbiot = Column(Boolean, default=0, doc="Whether this APN provides NBIoT") nidd_scef_id = Column(String(512), default=None, doc="ID of SCEF to be used for NIDD for NB-IoT") nidd_scef_realm = Column(String(512), default=None, doc='Realm of the SCEF for NIDD for NB-IoT') nidd_mechanism = Column(Integer, default=None, doc="Mechanism used to transfer Non-IP-Data: SGi-BASED-DATA-DELIVERY (0) or SCEF-BASED-DATA-DELIVERY (1)") From fb530b7b337f3bcec1b3d17ca2c35264a967e162 Mon Sep 17 00:00:00 2001 From: davidkneipp Date: Tue, 19 Dec 2023 12:25:27 +1000 Subject: [PATCH 4/4] Update diameter.py Add conditional check for nbiot enabled in ULA --- lib/diameter.py | 89 ++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/lib/diameter.py b/lib/diameter.py index b3bb125..ccec483 100644 --- a/lib/diameter.py +++ b/lib/diameter.py @@ -1291,48 +1291,53 @@ def Answer_16777251_316(self, packet_vars, avps): #Sub AVPs of APN Configuration Profile APN_context_identifer = self.generate_vendor_avp(1423, "c0", 10415, self.int_to_hex(APN_context_identifer_count, 4)) APN_PDN_type = self.generate_vendor_avp(1456, "c0", 10415, self.int_to_hex(int(apn_data['ip_version']), 4)) + NIDD_Parameters = '' - #If int(apn_data['ip_version']) == 4 (Non-IP) then this is NB-IoT and we need to add the NB-IoT specific parameters - if int(apn_data['ip_version']) == 4: - NIDD_Parameters = '' - - #Add Non-IP-PDN-Type-Indicator - NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1681, "c0", 10415, self.int_to_hex(1), 4) - - #Add SCEF ID - try: - NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(3125, "c0", 10415, self.string_to_hex(str(apn_data['nidd_scef_id']))) - except: - pass - - #Add SCEF Realm - try: - #Check SCEF Realm is not empty - if apn_data['nidd_scef_realm'] != '': - NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1684, "c0", 10415, self.string_to_hex(str(apn_data['nidd_scef_realm']))) - except: - pass - - #Add Reliable Data Indicator - try: - NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1697, "c0", 10415, self.int_to_hex(int(apn_data['nidd_rds']), 4)) - except: - pass - - #Add Preferred Data Mode - try: - NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1686, "c0", 10415, self.int_to_hex(int(apn_data['nidd_preferred_data_mode']), 4)) - except: - pass - - #Add Non-IP-Data-Delivery-Mechanism - try: - NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1682, "c0", 10415, self.int_to_hex(int(apn_data['nidd_mechanism']), 4)) - except: - pass - - else: - NIDD_Parameters = '' + try: + nbIotEnabled = apn_data.get('nbiot', False) + #If int(apn_data['ip_version']) == 4 (Non-IP) then this is NB-IoT and we need to add the NB-IoT specific parameters + if nbIotEnabled and int(apn_data['ip_version']) == 4: + + #Add Non-IP-PDN-Type-Indicator + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1681, "c0", 10415, self.int_to_hex(1), 4) + + #Add SCEF ID + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(3125, "c0", 10415, self.string_to_hex(str(apn_data['nidd_scef_id']))) + except: + pass + + #Add SCEF Realm + try: + #Check SCEF Realm is not empty + if apn_data['nidd_scef_realm'] != '': + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1684, "c0", 10415, self.string_to_hex(str(apn_data['nidd_scef_realm']))) + except: + pass + + #Add Reliable Data Indicator + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1697, "c0", 10415, self.int_to_hex(int(apn_data['nidd_rds']), 4)) + except: + pass + + #Add Preferred Data Mode + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1686, "c0", 10415, self.int_to_hex(int(apn_data['nidd_preferred_data_mode']), 4)) + except: + pass + + #Add Non-IP-Data-Delivery-Mechanism + try: + NIDD_Parameters = NIDD_Parameters + self.generate_vendor_avp(1682, "c0", 10415, self.int_to_hex(int(apn_data['nidd_mechanism']), 4)) + except: + pass + + else: + NIDD_Parameters = '' + + except Exception as e: + self.logTool.log(service='HSS', level='error', message=f"Error preparing NIDD parameters: {traceback.format_exc()}", redisClient=self.redisMessaging) self.logTool.log(service='HSS', level='debug', message="Setting APN AMBR", redisClient=self.redisMessaging) #AMBR @@ -3636,4 +3641,4 @@ def Request_16777252_324(self, imei, imsi): response = self.generate_diameter_packet("01", "c0", 324, 16777252, self.generate_id(4), self.generate_id(4), avp) #Generate Diameter packet - return response \ No newline at end of file + return response